hw/intc/loongarch_extioi: Add reset support

Add reset support with extioi irqchip, and register reset callback
support with new API resettable_class_set_parent_phases(). Clear
internal HW registers and SW state when virt machine resets.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Song Gao <gaosong@loongson.cn>
This commit is contained in:
Bibo Mao 2025-03-07 10:12:09 +08:00
parent 36ad84ecb2
commit 86e4a64751
2 changed files with 42 additions and 0 deletions

View file

@ -108,6 +108,43 @@ static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
} }
} }
static void loongarch_extioi_common_reset_hold(Object *obj, ResetType type)
{
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_GET_CLASS(obj);
LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(obj);
ExtIOICore *core;
int i;
if (lecc->parent_phases.hold) {
lecc->parent_phases.hold(obj, type);
}
/* Clear HW registers for the board */
memset(s->nodetype, 0, sizeof(s->nodetype));
memset(s->bounce, 0, sizeof(s->bounce));
memset(s->isr, 0, sizeof(s->isr));
memset(s->enable, 0, sizeof(s->enable));
memset(s->ipmap, 0, sizeof(s->ipmap));
memset(s->coremap, 0, sizeof(s->coremap));
memset(s->sw_pending, 0, sizeof(s->sw_pending));
memset(s->sw_ipmap, 0, sizeof(s->sw_ipmap));
memset(s->sw_coremap, 0, sizeof(s->sw_coremap));
for (i = 0; i < s->num_cpu; i++) {
core = s->cpu + i;
/* EXTIOI with targeted CPU available however not present */
if (!core->cpu) {
continue;
}
/* Clear HW registers for CPUs */
memset(core->coreisr, 0, sizeof(core->coreisr));
memset(core->sw_isr, 0, sizeof(core->sw_isr));
}
s->status = 0;
}
static int loongarch_extioi_common_pre_save(void *opaque) static int loongarch_extioi_common_pre_save(void *opaque)
{ {
LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque; LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque;
@ -180,9 +217,13 @@ static void loongarch_extioi_common_class_init(ObjectClass *klass,
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass); LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
device_class_set_parent_realize(dc, loongarch_extioi_common_realize, device_class_set_parent_realize(dc, loongarch_extioi_common_realize,
&lecc->parent_realize); &lecc->parent_realize);
resettable_class_set_parent_phases(rc, NULL,
loongarch_extioi_common_reset_hold,
NULL, &lecc->parent_phases);
device_class_set_props(dc, extioi_properties); device_class_set_props(dc, extioi_properties);
dc->vmsd = &vmstate_loongarch_extioi; dc->vmsd = &vmstate_loongarch_extioi;
hc->plug = loongarch_extioi_cpu_plug; hc->plug = loongarch_extioi_cpu_plug;

View file

@ -94,6 +94,7 @@ struct LoongArchExtIOICommonClass {
SysBusDeviceClass parent_class; SysBusDeviceClass parent_class;
DeviceRealize parent_realize; DeviceRealize parent_realize;
ResettablePhases parent_phases;
int (*pre_save)(void *s); int (*pre_save)(void *s);
int (*post_load)(void *s, int version_id); int (*post_load)(void *s, int version_id);
}; };