Hi Philippe, On Thu, Dec 19, 2019 at 7:51 PM Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> Extract the common code from the TYPE_AW_A10_PIT device into a new > abstract device: TYPE_AW_COMMON_PIT, then use it as parent, so we > inherit the same functionalities. > > Signed-off-by: Philippe Mathieu-Daudé <f4...@amsat.org> > --- > At this point, the only fields we can modify are the timer_count > and the region_size. Not enough to implement the H3 timer, since > we need to move the WDOG register. Still some progress, so Niek > can continue ;) > --- > include/hw/timer/allwinner-a10-pit.h | 1 + > hw/timer/allwinner-a10-pit.c | 50 +++++++++++++++++++++++----- > 2 files changed, 43 insertions(+), 8 deletions(-) > > diff --git a/include/hw/timer/allwinner-a10-pit.h > b/include/hw/timer/allwinner-a10-pit.h > index 9e28c6697a..8453a62706 100644 > --- a/include/hw/timer/allwinner-a10-pit.h > +++ b/include/hw/timer/allwinner-a10-pit.h > @@ -4,6 +4,7 @@ > #include "hw/ptimer.h" > #include "hw/sysbus.h" > > +#define TYPE_AW_COMMON_PIT "allwinner-timer-controller" > #define TYPE_AW_A10_PIT "allwinner-A10-timer" > So for the Allwinner H3, that means we'll need another TYPE_AW_H3_PIT definition? > > #define AW_PIT_TIMER_MAX 6 > diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c > index f2ac271e80..ad409b96a1 100644 > --- a/hw/timer/allwinner-a10-pit.c > +++ b/hw/timer/allwinner-a10-pit.c > Perhaps we can rename the hw/timer/allwinner-a10-pit.c to a generic name, for example hw/timer/allwinner-pit.c ? > @@ -54,6 +54,20 @@ > #define AW_A10_PIT(obj) \ > OBJECT_CHECK(AllwinnerTmrCtrlState, (obj), TYPE_AW_A10_PIT) > > +typedef struct AllwinnerTmrCtrlClass { > + /*< private >*/ > + SysBusDeviceClass parent_class; > + /*< public >*/ > + > + size_t timer_count; > + size_t region_size; > +} AllwinnerTmrCtrlClass; > + > +#define AW_TIMER_CLASS(klass) \ > + OBJECT_CLASS_CHECK(AllwinnerTmrCtrlClass, (klass), > TYPE_AW_COMMON_PIT) > +#define AW_TIMER_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(AllwinnerTmrCtrlClass, (obj), TYPE_AW_COMMON_PIT) > + > static void a10_pit_update_irq(AllwinnerTmrCtrlState *s) > { > int i; > @@ -303,19 +317,20 @@ static void a10_pit_timer_cb(void *opaque) > } > } > > -static void a10_pit_init(Object *obj) > +static void aw_pit_instance_init(Object *obj) > { > AllwinnerTmrCtrlState *s = AW_A10_PIT(obj); > + AllwinnerTmrCtrlClass *c = AW_TIMER_GET_CLASS(s); > SysBusDevice *sbd = SYS_BUS_DEVICE(obj); > uint8_t i; > > - s->timer_count = AW_A10_PIT_TIMER_NR; > + s->timer_count = c->timer_count; > > for (i = 0; i < s->timer_count; i++) { > sysbus_init_irq(sbd, &s->timer[i].irq); > } > memory_region_init_io(&s->iomem, OBJECT(s), &a10_pit_ops, s, > I am curious how to support the different WDOG0 registers for the Allwinner H3 while keeping the A10 functionality also working :-) Will you give the TYPE_AW_H3_PIT its own MemoryRegionOps with read/write? > - TYPE_AW_A10_PIT, 0x400); > + TYPE_AW_A10_PIT, c->region_size); > sysbus_init_mmio(sbd, &s->iomem); > > for (i = 0; i < s->timer_count; i++) { > @@ -328,26 +343,45 @@ static void a10_pit_init(Object *obj) > } > } > > -static void a10_pit_class_init(ObjectClass *klass, void *data) > +static void aw_timer_class_init(ObjectClass *klass, void *data) > { > DeviceClass *dc = DEVICE_CLASS(klass); > > dc->reset = a10_pit_reset; > dc->props = a10_pit_properties; > - dc->desc = "allwinner a10 timer"; > + dc->desc = "Allwinner Timer Controller"; > dc->vmsd = &vmstate_a10_pit; > } > > +static const TypeInfo allwinner_pit_info = { > + .name = TYPE_AW_COMMON_PIT, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_init = aw_pit_instance_init, > + .instance_size = sizeof(AllwinnerTmrCtrlState), > + .class_init = aw_timer_class_init, > + .class_size = sizeof(AllwinnerTmrCtrlClass), > + .abstract = true, > +}; > + > +static void a10_pit_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + AllwinnerTmrCtrlClass *atc = AW_TIMER_CLASS(klass); > + > + dc->desc = "Allwinner A10 Timer Controller"; > + atc->timer_count = AW_A10_PIT_TIMER_NR; > + atc->region_size = 0x400; > +} > + > static const TypeInfo a10_pit_info = { > .name = TYPE_AW_A10_PIT, > - .parent = TYPE_SYS_BUS_DEVICE, > - .instance_size = sizeof(AllwinnerTmrCtrlState), > - .instance_init = a10_pit_init, > + .parent = TYPE_AW_COMMON_PIT, > .class_init = a10_pit_class_init, > }; > > static void a10_register_types(void) > { > + type_register_static(&allwinner_pit_info); > type_register_static(&a10_pit_info); > } > > -- > 2.21.0 > > -- Niek Linnenbank