On Thu, Oct 13, 2016 at 11:52:40AM +0200, Igor Mammedov wrote:
> ACPI ID is 32 bit wide on CPUs with x2APIC support.
> Extend 'id' property to support it.
> 
> Signed-off-by: Igor Mammedov <imamm...@redhat.com>
> ---
> v3:
>    keep original behaviour where 'id' is readonly after
>    object is realized (pbonzini)
> ---
[...]
> diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
> index 8d01c9c..30f2af0 100644
> --- a/hw/intc/apic_common.c
> +++ b/hw/intc/apic_common.c
> @@ -428,7 +429,6 @@ static const VMStateDescription vmstate_apic_common = {
>  };
>  
>  static Property apic_properties_common[] = {
> -    DEFINE_PROP_UINT8("id", APICCommonState, id, -1),
>      DEFINE_PROP_UINT8("version", APICCommonState, version, 0x14),
>      DEFINE_PROP_BIT("vapic", APICCommonState, vapic_control, 
> VAPIC_ENABLE_BIT,
>                      true),
> @@ -437,6 +437,49 @@ static Property apic_properties_common[] = {
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> +static void apic_common_get_id(Object *obj, Visitor *v, const char *name,
> +                               void *opaque, Error **errp)
> +{
> +    APICCommonState *s = APIC_COMMON(obj);
> +    int64_t value;
> +
> +    value = s->apicbase & MSR_IA32_APICBASE_EXTD ? s->initial_apic_id : 
> s->id;
> +    visit_type_int(v, name, &value, errp);
> +}

Who exactly is going to read this property and require this logic
to be in the property getter?

Do we really need to expose this to the outside as a magic
property that changes depending on hardware state? Returning
initial_apic_id sounds much simpler.

> +
> +static void apic_common_set_id(Object *obj, Visitor *v, const char *name,
> +                               void *opaque, Error **errp)
> +{
> +    APICCommonState *s = APIC_COMMON(obj);
> +    DeviceState *dev = DEVICE(obj);
> +    Error *local_err = NULL;
> +    int64_t value;
> +
> +    if (dev->realized) {
> +        qdev_prop_set_after_realize(dev, name, errp);
> +        return;
> +    }
> +
> +    visit_type_int(v, name, &value, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
> +    s->initial_apic_id = value;
> +    s->id = (uint8_t)value;

Do we really need to change s->id here too? Won't it be set
automatically to initial_apic_id on reset?

I'm asking this because making it read/write only initial_apic_id
would make it easier to eventually convert the property to a
field-based getter/setter API (maybe even keep it using the
static property system).

Or, even better: do we really need a writeable property named
"id" at all? Is there any valid use case for the user to set it
directly? We could make the code that creates the APIC set
apic->initial_apic_id directly (or use a clearer
"initial-apic-id" property name).

> +}
> +
> +static void apic_common_initfn(Object *obj)
> +{
> +    APICCommonState *s = APIC_COMMON(obj);
> +
> +    s->id = s->initial_apic_id = -1;
> +    object_property_add(obj, "id", "int",
> +                        apic_common_get_id,
> +                        apic_common_set_id, NULL, NULL, NULL);

If you are going to add new properties, please register them
using object_class_property_add*().

> +}
> +
>  static void apic_common_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -456,6 +499,7 @@ static const TypeInfo apic_common_type = {
>      .name = TYPE_APIC_COMMON,
>      .parent = TYPE_DEVICE,
>      .instance_size = sizeof(APICCommonState),
> +    .instance_init = apic_common_initfn,
>      .class_size = sizeof(APICCommonClass),
>      .class_init = apic_common_class_init,
>      .abstract = true,
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 13505ab..b4b4342 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -2872,7 +2872,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error 
> **errp)
>                                OBJECT(cpu->apic_state), &error_abort);
>      object_unref(OBJECT(cpu->apic_state));
>  
> -    qdev_prop_set_uint8(cpu->apic_state, "id", cpu->apic_id);
> +    qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
>      /* TODO: convert to link<> */
>      apic = APIC_COMMON(cpu->apic_state);
>      apic->cpu = cpu;
> -- 
> 2.7.4
> 

-- 
Eduardo

Reply via email to