qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v10 4/5] arm: SoC model for Calxeda Highbank


From: Peter Maydell
Subject: Re: [Qemu-devel] [PATCH v10 4/5] arm: SoC model for Calxeda Highbank
Date: Wed, 18 Jan 2012 19:26:36 +0000

On 18 January 2012 19:06, Mark Langsdorf <address@hidden> wrote:
> On 01/18/2012 08:53 AM, Peter Maydell wrote:
>> On 18 January 2012 14:35, Mark Langsdorf <address@hidden> wrote:
>>> I can set the smp_loader code so that I can boot 2 cpus
>>> and verify their existence in /proc/cpuinfo, but I can't
>>> get 3 cpus to boot at all, no matter how I hack the existing
>>> arm_boot code.
>>
>> Right, multiple secondary cores requires multiple addresses
>> to be polled which we don't support in arm_boot.c at the moment.
>
> How would multiple polling supposed to work?

You need several separate bits of code, to put each secondary
core in a different loop polling a different address.
(If you have access to your own bootloader sources you should
be able to see how it does it :-))

> I've tried changing
> http://lxr.linux.no/#linux+v3.2.1/arch/arm/mach-highbank/highbank.c#L71
> to point to a fixed address (0x50), and the boot loader still fails
> if there are 2 or more secondary CPUs.

Yeah, that's insufficient, because the highbank kernel doesn't
have an equivalent of this bit of code for versatile et al:
http://lxr.linux.no/#linux+v3.2.1/arch/arm/plat-versatile/headsmp.S
...which puts all the cores back into yet another pen so they
can be released to the main kernel secondary_startup entry
point singly as they are required. On versatile when the flags
register is written, every secondary CPU comes out of the bootloader
pen simultaneously, so we have to catch them all again like this.
Highbank, as far as I can tell, has the boot loader provide a
mechanism for letting the kernel release just one core, so the
highbank kernel can simply ask for the cores one at a time and
direct them straight from the bootloader to secondary_startup.

This is essentially pushing some of this logic from the kernel into
the bootloader, which is arguably cleaner but does make this
boot code more complicated.

> I've figured out that do_cpu_reset() is only called once, even
> though that seems a bit strange to me.

It should be called once per core -- we register it with
qemu_register_reset() for each core at the bottom of arm_load_kernel().
The reason it isn't in your case is a bug in highbank.c -- you should
be passing first_cpu as the first parameter to arm_load_kernel().
In fact you're passing in env, which happens to be the last cpu,
so the loop in arm_load_kernel() registers the reset handler for
the last CPU only. (I think the only reason this bug didn't cause
complete failure to boot is that you have a info->loader_start of 0
which happens to be where the core will come out of reset anyway.)

> I've tried the following
> in my local secondary_hook call:
>
>    switch (info->nb_cpus) {
>    case 4:
>        stl_phys_notdirty(0x70, 0);
>    case 3:
>        stl_phys_notdirty(0x60, 0);
>    case 2:
>        stl_phys_notdirty(0x50, 0);
>        env->regs[15] = 0x100;
>        break;
>    }
>
> which works fine with 2 cpus, but fails to boot both
> secondary cpus if there are 3 total cpus.

This is necessary but not sufficient, I think.

-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]