[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 3/5] target-i386: call x86_cpu_realize() after A
From: |
liu ping fan |
Subject: |
Re: [Qemu-devel] [PATCH 3/5] target-i386: call x86_cpu_realize() after APIC is initialized. |
Date: |
Wed, 11 Jul 2012 15:35:20 +0800 |
On Tue, Jul 10, 2012 at 9:35 PM, Igor Mammedov <address@hidden> wrote:
> On 07/09/2012 02:57 PM, Andreas Färber wrote:
>>
>> Am 09.07.2012 12:59, schrieb igor:
>>>
>>> On 06/20/2012 03:35 PM, Andreas Färber wrote:
>>>>
>>>> Am 20.06.2012 14:59, schrieb Igor Mammedov:
>>>>>
>>>>> It's not correct to make CPU runnable (i.e. calling x86_cpu_realize())
>>>>> when not all properties are set (APIC in this case).
>>>>>
>>>>> Fix it by calling x86_cpu_realize() at board level after APIC is
>>>>> initialized, right before cpu_reset().
>>>>>
>>>>> Signed-off-by: Igor Mammedov <address@hidden>
>>>>> ---
>>>>> hw/pc.c | 1 +
>>>>> target-i386/helper.c | 2 --
>>>>> 2 files changed, 1 insertion(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/hw/pc.c b/hw/pc.c
>>>>> index 8368701..8a662cf 100644
>>>>> --- a/hw/pc.c
>>>>> +++ b/hw/pc.c
>>>>> @@ -948,6 +948,7 @@ static X86CPU *pc_new_cpu(const char *cpu_model)
>>>>> env->apic_state = apic_init(env, env->cpuid_apic_id);
>>>>> }
>>>>> qemu_register_reset(pc_cpu_reset, cpu);
>>>>> + x86_cpu_realize(OBJECT(cpu), NULL);
>>>>> pc_cpu_reset(cpu);
>>>>> return cpu;
>>>>> }
>>>>> diff --git a/target-i386/helper.c b/target-i386/helper.c
>>>>> index c52ec13..b38ea7f 100644
>>>>> --- a/target-i386/helper.c
>>>>> +++ b/target-i386/helper.c
>>>>> @@ -1161,8 +1161,6 @@ X86CPU *cpu_x86_init(const char *cpu_model)
>>>>> return NULL;
>>>>> }
>>>>>
>>>>> - x86_cpu_realize(OBJECT(cpu), NULL);
>>>>> -
>>>>> return cpu;
>>>>> }
>>>>>
>>>>
>>>> This will require changes in linux-user and possibly bsd-user. Having a
>>>> cpu_realize() would probably help with avoiding #ifdef'ery.
>>>> Unfortunately deriving CPUState from DeviceState proves a bit difficult
>>>> in the meantime (it worked at one point, now there's lots of circular
>>>> header dependencies), and realize support for Object got stopped.
>>>>
>>> As alternative to keep, I could leave x86_cpu_realize() in
>>> cpu_x86_init() and keep pc_cpu_reset() in pc_new_cpu(). That will result
>>> in calling cpu_reset() 3 instead of 2 times.
>>> Later when apic_init is moved inside cpu.c, a pc_cpu_reset() in
>>> pc_new_cpu() would be unnecessary and could be cleaned up then.
>>
>>
>> Let me explain in more detail what I was thinking about: cpu_init() and
>> cpu_x86_init() today return an initialized/realized object. I don't want
>> bugs to creep into the user emulators because someone is not aware that
>> x86 is semantically differing from all other targets.
>>
>> What I did for a qemu-rl78 machine is to inline cpu_rl78_init() so that
>> I could put code in between, i.e., for x86: object_new(), APIC/BSP
>> stuff, x86_cpu_realize(). That way any addition to the realize function
>> will still affect the user emulators.
>> The downside is that when we add x86 CPU subclasses we'd have to
>> remember to update two places. The solution to that would be to split
>> out a x86_cpu_new() function used from cpu_x86_init() and wherever you
>> need it for the PC machine. Then the code is still maintainable in one
>> central place and you get to do your APIC cleanups, and we don't depend
>> on a central realize implementation or device parent, what do you think?
>
>
> If you mean x86_cpu_new() == pc_new_cpu() that calls cpu_x86_init(),
> then I'd like get rid of pc_new_cpu() completely, eventually replacing it by
> cpu_x86_init() in hw/pc.c:pc_cpus_init(), something like this:
>
> -static X86CPU *pc_new_cpu(const char *cpu_model)
> -{
> - X86CPU *cpu;
> - CPUX86State *env;
> -
> - cpu = cpu_x86_init(cpu_model);
> - if (cpu == NULL) {
> - fprintf(stderr, "Unable to find x86 CPU definition\n");
> - exit(1);
> - }
> - env = &cpu->env;
> - if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) {
> - env->apic_state = apic_init(env, env->cpuid_apic_id);
> - }
> - cpu_reset(CPU(cpu));
> - return cpu;
> -}
> -
> void pc_cpus_init(const char *cpu_model)
> {
> int i;
> @@ -950,7 +932,7 @@ void pc_cpus_init(const char *cpu_model)
> }
>
> for(i = 0; i < smp_cpus; i++) {
> - pc_new_cpu(cpu_model);
> + cpu_x86_init(cpu_model);
> }
> }
>
> goal I'm aiming at is to have a working cpu object that could be created
> using qdev_device_add without any adhoc calls. So in the end cpu_x86_init()
> should become object_new(x86_cpu), [set props], realize() and nothing else.
Could we think apic's "creation + realize" as part of
x86_cpu_realize(), but not [set props]?
For the concept of building sub log unit inside chip.
Regards,
pingfan
> And maybe in some far future removing cpu_init -> cpu_x86_init() completely.
> That would give us a single implementation of CPU one place (cpu.c)
> --
> -----
> Regards,
> Igor
>
>
>