xref: /qemu/hw/intc/loongarch_extioi_common.c (revision 5a3e068d411c563d924f5eb40f82e91aaca1eaed)
16b69f778SBibo Mao /* SPDX-License-Identifier: GPL-2.0-or-later */
26b69f778SBibo Mao /*
36b69f778SBibo Mao  * Loongson extioi interrupt controller emulation
46b69f778SBibo Mao  * Copyright (C) 2024 Loongson Technology Corporation Limited
56b69f778SBibo Mao  */
6272c467aSBibo Mao #include "qemu/osdep.h"
7272c467aSBibo Mao #include "qemu/module.h"
8272c467aSBibo Mao #include "qapi/error.h"
9272c467aSBibo Mao #include "hw/qdev-properties.h"
10272c467aSBibo Mao #include "hw/intc/loongarch_extioi_common.h"
11272c467aSBibo Mao #include "migration/vmstate.h"
126b69f778SBibo Mao 
136b69f778SBibo Mao static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
146b69f778SBibo Mao {
156b69f778SBibo Mao     LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)dev;
16*5a3e068dSBibo Mao     MachineState *machine = MACHINE(qdev_get_machine());
17*5a3e068dSBibo Mao     MachineClass *mc = MACHINE_GET_CLASS(machine);
18*5a3e068dSBibo Mao     const CPUArchIdList *id_list;
19*5a3e068dSBibo Mao     int i;
206b69f778SBibo Mao 
21*5a3e068dSBibo Mao     assert(mc->possible_cpu_arch_ids);
22*5a3e068dSBibo Mao     id_list = mc->possible_cpu_arch_ids(machine);
23*5a3e068dSBibo Mao     s->num_cpu = id_list->len;
24*5a3e068dSBibo Mao     s->cpu = g_new0(ExtIOICore, s->num_cpu);
25*5a3e068dSBibo Mao     if (s->cpu == NULL) {
26*5a3e068dSBibo Mao         error_setg(errp, "Memory allocation for ExtIOICore faile");
276b69f778SBibo Mao         return;
286b69f778SBibo Mao     }
29*5a3e068dSBibo Mao 
30*5a3e068dSBibo Mao     for (i = 0; i < s->num_cpu; i++) {
31*5a3e068dSBibo Mao         s->cpu[i].arch_id = id_list->cpus[i].arch_id;
32*5a3e068dSBibo Mao         s->cpu[i].cpu = CPU(id_list->cpus[i].cpu);
33*5a3e068dSBibo Mao     }
346b69f778SBibo Mao }
356b69f778SBibo Mao 
36ff09444aSBibo Mao static int loongarch_extioi_common_pre_save(void *opaque)
37ff09444aSBibo Mao {
38ff09444aSBibo Mao     LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque;
39ff09444aSBibo Mao     LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_GET_CLASS(s);
40ff09444aSBibo Mao 
41ff09444aSBibo Mao     if (lecc->pre_save) {
42ff09444aSBibo Mao         return lecc->pre_save(s);
43ff09444aSBibo Mao     }
44ff09444aSBibo Mao 
45ff09444aSBibo Mao     return 0;
46ff09444aSBibo Mao }
47ff09444aSBibo Mao 
486b69f778SBibo Mao static int loongarch_extioi_common_post_load(void *opaque, int version_id)
496b69f778SBibo Mao {
50272c467aSBibo Mao     LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque;
51272c467aSBibo Mao     LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_GET_CLASS(s);
52272c467aSBibo Mao 
53272c467aSBibo Mao     if (lecc->post_load) {
54272c467aSBibo Mao         return lecc->post_load(s, version_id);
55272c467aSBibo Mao     }
56272c467aSBibo Mao 
57272c467aSBibo Mao     return 0;
586b69f778SBibo Mao }
596b69f778SBibo Mao 
606b69f778SBibo Mao static const VMStateDescription vmstate_extioi_core = {
616b69f778SBibo Mao     .name = "extioi-core",
626b69f778SBibo Mao     .version_id = 1,
636b69f778SBibo Mao     .minimum_version_id = 1,
646b69f778SBibo Mao     .fields = (const VMStateField[]) {
656b69f778SBibo Mao         VMSTATE_UINT32_ARRAY(coreisr, ExtIOICore, EXTIOI_IRQS_GROUP_COUNT),
666b69f778SBibo Mao         VMSTATE_END_OF_LIST()
676b69f778SBibo Mao     }
686b69f778SBibo Mao };
696b69f778SBibo Mao 
706b69f778SBibo Mao static const VMStateDescription vmstate_loongarch_extioi = {
716b69f778SBibo Mao     .name = "loongarch.extioi",
726b69f778SBibo Mao     .version_id = 3,
736b69f778SBibo Mao     .minimum_version_id = 3,
74ff09444aSBibo Mao     .pre_save  = loongarch_extioi_common_pre_save,
756b69f778SBibo Mao     .post_load = loongarch_extioi_common_post_load,
766b69f778SBibo Mao     .fields = (const VMStateField[]) {
776b69f778SBibo Mao         VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOICommonState,
786b69f778SBibo Mao                              EXTIOI_IRQS_GROUP_COUNT),
796b69f778SBibo Mao         VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOICommonState,
806b69f778SBibo Mao                              EXTIOI_IRQS_NODETYPE_COUNT / 2),
816b69f778SBibo Mao         VMSTATE_UINT32_ARRAY(enable, LoongArchExtIOICommonState,
826b69f778SBibo Mao                              EXTIOI_IRQS / 32),
836b69f778SBibo Mao         VMSTATE_UINT32_ARRAY(isr, LoongArchExtIOICommonState,
846b69f778SBibo Mao                              EXTIOI_IRQS / 32),
856b69f778SBibo Mao         VMSTATE_UINT32_ARRAY(ipmap, LoongArchExtIOICommonState,
866b69f778SBibo Mao                              EXTIOI_IRQS_IPMAP_SIZE / 4),
876b69f778SBibo Mao         VMSTATE_UINT32_ARRAY(coremap, LoongArchExtIOICommonState,
886b69f778SBibo Mao                              EXTIOI_IRQS / 4),
896b69f778SBibo Mao         VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOICommonState,
906b69f778SBibo Mao                              num_cpu, vmstate_extioi_core, ExtIOICore),
916b69f778SBibo Mao         VMSTATE_UINT32(features, LoongArchExtIOICommonState),
926b69f778SBibo Mao         VMSTATE_UINT32(status, LoongArchExtIOICommonState),
936b69f778SBibo Mao         VMSTATE_END_OF_LIST()
946b69f778SBibo Mao     }
956b69f778SBibo Mao };
966b69f778SBibo Mao 
976b69f778SBibo Mao static const Property extioi_properties[] = {
986b69f778SBibo Mao     DEFINE_PROP_UINT32("num-cpu", LoongArchExtIOICommonState, num_cpu, 1),
996b69f778SBibo Mao     DEFINE_PROP_BIT("has-virtualization-extension", LoongArchExtIOICommonState,
1006b69f778SBibo Mao                     features, EXTIOI_HAS_VIRT_EXTENSION, 0),
1016b69f778SBibo Mao };
102272c467aSBibo Mao 
103272c467aSBibo Mao static void loongarch_extioi_common_class_init(ObjectClass *klass, void *data)
104272c467aSBibo Mao {
105272c467aSBibo Mao     DeviceClass *dc = DEVICE_CLASS(klass);
106272c467aSBibo Mao     LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass);
107272c467aSBibo Mao 
108272c467aSBibo Mao     device_class_set_parent_realize(dc, loongarch_extioi_common_realize,
109272c467aSBibo Mao                                     &lecc->parent_realize);
110272c467aSBibo Mao     device_class_set_props(dc, extioi_properties);
111272c467aSBibo Mao     dc->vmsd = &vmstate_loongarch_extioi;
112272c467aSBibo Mao }
113272c467aSBibo Mao 
114272c467aSBibo Mao static const TypeInfo loongarch_extioi_common_types[] = {
115272c467aSBibo Mao     {
116272c467aSBibo Mao         .name               = TYPE_LOONGARCH_EXTIOI_COMMON,
117272c467aSBibo Mao         .parent             = TYPE_SYS_BUS_DEVICE,
118272c467aSBibo Mao         .instance_size      = sizeof(LoongArchExtIOICommonState),
119272c467aSBibo Mao         .class_size         = sizeof(LoongArchExtIOICommonClass),
120272c467aSBibo Mao         .class_init         = loongarch_extioi_common_class_init,
121272c467aSBibo Mao         .abstract           = true,
122272c467aSBibo Mao     }
123272c467aSBibo Mao };
124272c467aSBibo Mao 
125272c467aSBibo Mao DEFINE_TYPES(loongarch_extioi_common_types)
126