[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common
From: |
Alexey Kardashevskiy |
Subject: |
Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common |
Date: |
Wed, 07 Aug 2013 16:06:44 +1000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 |
On 08/06/2013 07:53 PM, Andreas Färber wrote:
> Am 06.08.2013 10:27, schrieb Alexey Kardashevskiy:
>> The upcoming XICS-KVM support will use bits of emulated XICS code.
>> So this introduces new level of hierarchy - "xics-common" class. Both
>> emulated XICS and XICS-KVM will inherit from it and override class
>> callbacks when required.
>>
>> The new "xics-common" class implements:
>> 1. replaces static "nr_irqs" and "nr_servers" properties with
>> the dynamic ones and adds callbacks to be executed when properties
>> are set.
>> 2. xics_cpu_setup() callback renamed to xics_common_cpu_setup() as
>> it is a common part for both XICS'es
>> 3. xics_reset() renamed to xics_common_reset() for the same reason.
>>
>> The emulated XICS changes:
>> 1. instance_init() callback is replaced with "nr_irqs" property callback
>> as it creates ICS which needs the nr_irqs property set.
>> 2. the part of xics_realize() which creates ICPs is moved to
>> the "nr_servers" property callback as realize() is too late to
>> create/initialize devices and instance_init() is too early to create
>> devices as the number of child devices comes via the "nr_servers"
>> property.
>> 3. added ics_initfn() which does a little part of what xics_realize() did.
>>
>> Signed-off-by: Alexey Kardashevskiy <address@hidden>
>
> This looks really good, except for error handling and introspection
> support - minor nits.
>
>> ---
>> hw/intc/xics.c | 190
>> +++++++++++++++++++++++++++++++++++---------------
>> include/hw/ppc/xics.h | 11 ++-
>> 2 files changed, 143 insertions(+), 58 deletions(-)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index 20840e3..95865aa 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -30,6 +30,112 @@
>> #include "hw/ppc/spapr.h"
>> #include "hw/ppc/xics.h"
>> #include "qemu/error-report.h"
>> +#include "qapi/visitor.h"
>> +
>> +/*
>> + * XICS Common class - parent for emulated XICS and KVM-XICS
>> + */
>> +
>> +static void xics_common_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
>> +{
>> + CPUState *cs = CPU(cpu);
>> + CPUPPCState *env = &cpu->env;
>> + ICPState *ss = &icp->ss[cs->cpu_index];
>> +
>> + assert(cs->cpu_index < icp->nr_servers);
>> +
>> + switch (PPC_INPUT(env)) {
>> + case PPC_FLAGS_INPUT_POWER7:
>> + ss->output = env->irq_inputs[POWER7_INPUT_INT];
>> + break;
>> +
>> + case PPC_FLAGS_INPUT_970:
>> + ss->output = env->irq_inputs[PPC970_INPUT_INT];
>> + break;
>> +
>> + default:
>> + error_report("XICS interrupt controller does not support this CPU "
>> + "bus model");
>
> Indentation is off.
>
>> + abort();
>
> I previously wondered whether it may make sense to add Error **errp
> argument to avoid the abort, but this is only called from the machine
> init, right?
Right. If it fails, nothing for the caller to decide.
>> + }
>> +}
>> +
>> +void xics_prop_set_nr_irqs(Object *obj, struct Visitor *v,
>> + void *opaque, const char *name, struct Error
>> **errp)
>
> You should be able to drop both "struct"s.
Yeah, fixed. This is just how the ObjectPropertyAccessor type is defined.
>> +{
>> + XICSState *icp = XICS_COMMON(obj);
>> + XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
>> + Error *error = NULL;
>> + int64_t value;
>> +
>> + visit_type_int(v, &value, name, &error);
>> + if (error) {
>> + error_propagate(errp, error);
>> + return;
>> + }
>> +
>> + assert(info->set_nr_irqs);
>
>> + assert(!icp->nr_irqs);
>
> For reasons of simplicity you're only implementing these as one-off
> setters. I think that's acceptable, but since someone can easily try to
> set this property via QMP qom-set you should do error_setg() rather than
> assert() then. Asserting the class methods is fine as they are not
> user-changeable.
>
>> + assert(!icp->ics);
>> + info->set_nr_irqs(icp, value);
>> +}
>> +
>> +void xics_prop_set_nr_servers(Object *obj, struct Visitor *v,
>> + void *opaque, const char *name, struct Error
>> **errp)
>> +{
>> + XICSState *icp = XICS_COMMON(obj);
>> + XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
>> + Error *error = NULL;
>> + int64_t value;
>> +
>> + visit_type_int(v, &value, name, &error);
>> + if (error) {
>> + error_propagate(errp, error);
>> + return;
>> + }
>> +
>> + assert(info->set_nr_servers);
>
>> + assert(!icp->nr_servers);
>
> Ditto.
>
>> + info->set_nr_servers(icp, value);
>> +}
>> +
>> +static void xics_common_initfn(Object *obj)
>> +{
>> + object_property_add(obj, "nr_irqs", "int",
>> + NULL, xics_prop_set_nr_irqs, NULL, NULL, NULL);
>> + object_property_add(obj, "nr_servers", "int",
>> + NULL, xics_prop_set_nr_servers, NULL, NULL, NULL);
>
> Since this property is visible in the QOM tree, it would be nice to
> implement trivial getters returns the value from the state fields.
Added. How do I test it? "info qtree" prints only
DEVICE_CLASS(class)->props which is null in this case.
>> +}
>> +
>> +static void xics_common_reset(DeviceState *d)
>> +{
>> + XICSState *icp = XICS_COMMON(d);
>> + int i;
>> +
>> + for (i = 0; i < icp->nr_servers; i++) {
>> + device_reset(DEVICE(&icp->ss[i]));
>> + }
>> +
>> + device_reset(DEVICE(icp->ics));
>> +}
>> +
>> +static void xics_common_class_init(ObjectClass *oc, void *data)
>> +{
>> + DeviceClass *dc = DEVICE_CLASS(oc);
>> + XICSStateClass *xsc = XICS_COMMON_CLASS(oc);
>> +
>> + dc->reset = xics_common_reset;
>> + xsc->cpu_setup = xics_common_cpu_setup;
>> +}
>> +
>> +static const TypeInfo xics_common_info = {
>> + .name = TYPE_XICS_COMMON,
>> + .parent = TYPE_SYS_BUS_DEVICE,
>> + .instance_size = sizeof(XICSState),
>> + .class_size = sizeof(XICSStateClass),
>> + .instance_init = xics_common_initfn,
>> + .class_init = xics_common_class_init,
>> +};
>>
>> /*
>> * ICP: Presentation layer
>> @@ -443,6 +549,13 @@ static const VMStateDescription vmstate_ics = {
>> },
>> };
>>
>> +static void ics_initfn(Object *obj)
>> +{
>> + ICSState *ics = ICS(obj);
>> +
>> + ics->offset = XICS_IRQ_BASE;
>> +}
>> +
>> static int ics_realize(DeviceState *dev)
>> {
>> ICSState *ics = ICS(dev);
>> @@ -472,6 +585,7 @@ static const TypeInfo ics_info = {
>> .instance_size = sizeof(ICSState),
>> .class_init = ics_class_init,
>> .class_size = sizeof(ICSStateClass),
>> + .instance_init = ics_initfn,
>> };
>>
>> /*
>> @@ -651,47 +765,32 @@ static void rtas_int_on(PowerPCCPU *cpu,
>> sPAPREnvironment *spapr,
>> /*
>> * XICS
>> */
>> +void xics_set_nr_irqs(XICSState *icp, uint32_t nr_irqs)
>> +{
>> + icp->ics = ICS(object_new(TYPE_ICS));
>> + object_property_add_child(OBJECT(icp), "ics", OBJECT(icp->ics), NULL);
>
> Why create this single object in the setter? Can't you just create this
> in the common type's instance_init similar to before but using
> object_initialize() instead of object_new() and
> object_property_set_bool() in the realizefn?
I cannot create in the common code as there are TYPE_ICS and TYPE_ICS_KVM
(oops, KVM is at the end, will fix it) types.
And I would really want not to create it in instance_init() as I want to
have the object created and all its properties initialized in one place.
> NULL above also shows that your callback should probably get an Error
> **errp argument to propagate any errors to the property and its callers.
Yep, will fix that.
--
Alexey
- [Qemu-ppc] [PATCH 1/6] target-ppc: Add helper for KVM_PPC_RTAS_DEFINE_TOKEN, (continued)
- [Qemu-ppc] [PATCH 1/6] target-ppc: Add helper for KVM_PPC_RTAS_DEFINE_TOKEN, Alexey Kardashevskiy, 2013/08/06
- [Qemu-ppc] [PATCH 2/6] xics: add pre_save/post_load/cpu_setup dispatchers, Alexey Kardashevskiy, 2013/08/06
- [Qemu-ppc] [PATCH 3/6] xics: move registration of global state to realize(), Alexey Kardashevskiy, 2013/08/06
- [Qemu-ppc] [PATCH 4/6] xics: minor changes and cleanups, Alexey Kardashevskiy, 2013/08/06
- [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common, Alexey Kardashevskiy, 2013/08/06
- Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common, Andreas Färber, 2013/08/06
- Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common,
Alexey Kardashevskiy <=
- Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common, Andreas Färber, 2013/08/07
- Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common, Alexey Kardashevskiy, 2013/08/07
- Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common, Andreas Färber, 2013/08/07
- Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common, Alexey Kardashevskiy, 2013/08/07
- Re: [Qemu-ppc] [PATCH 5/6] xics: split to xics and xics-common, Andreas Färber, 2013/08/08
[Qemu-ppc] [PATCH 6/6] xics-kvm: Support for in-kernel XICS interrupt controller, Alexey Kardashevskiy, 2013/08/06