xref: /qemu/hw/intc/arm_gicv3_common.c (revision 8ef94f0bc9167f246b41cb1188bf80dcd84b49fe)
1ff8f06eeSShlomo Pongratz /*
2ff8f06eeSShlomo Pongratz  * ARM GICv3 support - common bits of emulated and KVM kernel model
3ff8f06eeSShlomo Pongratz  *
4ff8f06eeSShlomo Pongratz  * Copyright (c) 2012 Linaro Limited
5ff8f06eeSShlomo Pongratz  * Copyright (c) 2015 Huawei.
6ff8f06eeSShlomo Pongratz  * Written by Peter Maydell
7ff8f06eeSShlomo Pongratz  * Extended to 64 cores by Shlomo Pongratz
8ff8f06eeSShlomo Pongratz  *
9ff8f06eeSShlomo Pongratz  * This program is free software; you can redistribute it and/or modify
10ff8f06eeSShlomo Pongratz  * it under the terms of the GNU General Public License as published by
11ff8f06eeSShlomo Pongratz  * the Free Software Foundation, either version 2 of the License, or
12ff8f06eeSShlomo Pongratz  * (at your option) any later version.
13ff8f06eeSShlomo Pongratz  *
14ff8f06eeSShlomo Pongratz  * This program is distributed in the hope that it will be useful,
15ff8f06eeSShlomo Pongratz  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16ff8f06eeSShlomo Pongratz  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17ff8f06eeSShlomo Pongratz  * GNU General Public License for more details.
18ff8f06eeSShlomo Pongratz  *
19ff8f06eeSShlomo Pongratz  * You should have received a copy of the GNU General Public License along
20ff8f06eeSShlomo Pongratz  * with this program; if not, see <http://www.gnu.org/licenses/>.
21ff8f06eeSShlomo Pongratz  */
22ff8f06eeSShlomo Pongratz 
23*8ef94f0bSPeter Maydell #include "qemu/osdep.h"
24ff8f06eeSShlomo Pongratz #include "hw/intc/arm_gicv3_common.h"
25ff8f06eeSShlomo Pongratz 
26ff8f06eeSShlomo Pongratz static void gicv3_pre_save(void *opaque)
27ff8f06eeSShlomo Pongratz {
28ff8f06eeSShlomo Pongratz     GICv3State *s = (GICv3State *)opaque;
29ff8f06eeSShlomo Pongratz     ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s);
30ff8f06eeSShlomo Pongratz 
31ff8f06eeSShlomo Pongratz     if (c->pre_save) {
32ff8f06eeSShlomo Pongratz         c->pre_save(s);
33ff8f06eeSShlomo Pongratz     }
34ff8f06eeSShlomo Pongratz }
35ff8f06eeSShlomo Pongratz 
36ff8f06eeSShlomo Pongratz static int gicv3_post_load(void *opaque, int version_id)
37ff8f06eeSShlomo Pongratz {
38ff8f06eeSShlomo Pongratz     GICv3State *s = (GICv3State *)opaque;
39ff8f06eeSShlomo Pongratz     ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s);
40ff8f06eeSShlomo Pongratz 
41ff8f06eeSShlomo Pongratz     if (c->post_load) {
42ff8f06eeSShlomo Pongratz         c->post_load(s);
43ff8f06eeSShlomo Pongratz     }
44ff8f06eeSShlomo Pongratz     return 0;
45ff8f06eeSShlomo Pongratz }
46ff8f06eeSShlomo Pongratz 
47ff8f06eeSShlomo Pongratz static const VMStateDescription vmstate_gicv3 = {
48ff8f06eeSShlomo Pongratz     .name = "arm_gicv3",
49ff8f06eeSShlomo Pongratz     .unmigratable = 1,
50ff8f06eeSShlomo Pongratz     .pre_save = gicv3_pre_save,
51ff8f06eeSShlomo Pongratz     .post_load = gicv3_post_load,
52ff8f06eeSShlomo Pongratz };
53ff8f06eeSShlomo Pongratz 
54ff8f06eeSShlomo Pongratz void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
55ff8f06eeSShlomo Pongratz                               const MemoryRegionOps *ops)
56ff8f06eeSShlomo Pongratz {
57ff8f06eeSShlomo Pongratz     SysBusDevice *sbd = SYS_BUS_DEVICE(s);
58ff8f06eeSShlomo Pongratz     int i;
59ff8f06eeSShlomo Pongratz 
60ff8f06eeSShlomo Pongratz     /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
61ff8f06eeSShlomo Pongratz      * GPIO array layout is thus:
62ff8f06eeSShlomo Pongratz      *  [0..N-1] spi
63ff8f06eeSShlomo Pongratz      *  [N..N+31] PPIs for CPU 0
64ff8f06eeSShlomo Pongratz      *  [N+32..N+63] PPIs for CPU 1
65ff8f06eeSShlomo Pongratz      *   ...
66ff8f06eeSShlomo Pongratz      */
67ff8f06eeSShlomo Pongratz     i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu;
68ff8f06eeSShlomo Pongratz     qdev_init_gpio_in(DEVICE(s), handler, i);
69ff8f06eeSShlomo Pongratz 
70ff8f06eeSShlomo Pongratz     s->parent_irq = g_malloc(s->num_cpu * sizeof(qemu_irq));
71ff8f06eeSShlomo Pongratz     s->parent_fiq = g_malloc(s->num_cpu * sizeof(qemu_irq));
72ff8f06eeSShlomo Pongratz 
73ff8f06eeSShlomo Pongratz     for (i = 0; i < s->num_cpu; i++) {
74ff8f06eeSShlomo Pongratz         sysbus_init_irq(sbd, &s->parent_irq[i]);
75ff8f06eeSShlomo Pongratz     }
76ff8f06eeSShlomo Pongratz     for (i = 0; i < s->num_cpu; i++) {
77ff8f06eeSShlomo Pongratz         sysbus_init_irq(sbd, &s->parent_fiq[i]);
78ff8f06eeSShlomo Pongratz     }
79ff8f06eeSShlomo Pongratz 
80ff8f06eeSShlomo Pongratz     memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
81ff8f06eeSShlomo Pongratz                           "gicv3_dist", 0x10000);
82ff8f06eeSShlomo Pongratz     memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s,
83ff8f06eeSShlomo Pongratz                           "gicv3_redist", 0x20000 * s->num_cpu);
84ff8f06eeSShlomo Pongratz 
85ff8f06eeSShlomo Pongratz     sysbus_init_mmio(sbd, &s->iomem_dist);
86ff8f06eeSShlomo Pongratz     sysbus_init_mmio(sbd, &s->iomem_redist);
87ff8f06eeSShlomo Pongratz }
88ff8f06eeSShlomo Pongratz 
89ff8f06eeSShlomo Pongratz static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
90ff8f06eeSShlomo Pongratz {
91ff8f06eeSShlomo Pongratz     GICv3State *s = ARM_GICV3_COMMON(dev);
92ff8f06eeSShlomo Pongratz 
93ff8f06eeSShlomo Pongratz     /* revision property is actually reserved and currently used only in order
94ff8f06eeSShlomo Pongratz      * to keep the interface compatible with GICv2 code, avoiding extra
95ff8f06eeSShlomo Pongratz      * conditions. However, in future it could be used, for example, if we
96ff8f06eeSShlomo Pongratz      * implement GICv4.
97ff8f06eeSShlomo Pongratz      */
98ff8f06eeSShlomo Pongratz     if (s->revision != 3) {
99ff8f06eeSShlomo Pongratz         error_setg(errp, "unsupported GIC revision %d", s->revision);
100ff8f06eeSShlomo Pongratz         return;
101ff8f06eeSShlomo Pongratz     }
102ff8f06eeSShlomo Pongratz }
103ff8f06eeSShlomo Pongratz 
104ff8f06eeSShlomo Pongratz static void arm_gicv3_common_reset(DeviceState *dev)
105ff8f06eeSShlomo Pongratz {
106ff8f06eeSShlomo Pongratz     /* TODO */
107ff8f06eeSShlomo Pongratz }
108ff8f06eeSShlomo Pongratz 
109ff8f06eeSShlomo Pongratz static Property arm_gicv3_common_properties[] = {
110ff8f06eeSShlomo Pongratz     DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1),
111ff8f06eeSShlomo Pongratz     DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
112ff8f06eeSShlomo Pongratz     DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
113ff8f06eeSShlomo Pongratz     DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
114ff8f06eeSShlomo Pongratz     DEFINE_PROP_END_OF_LIST(),
115ff8f06eeSShlomo Pongratz };
116ff8f06eeSShlomo Pongratz 
117ff8f06eeSShlomo Pongratz static void arm_gicv3_common_class_init(ObjectClass *klass, void *data)
118ff8f06eeSShlomo Pongratz {
119ff8f06eeSShlomo Pongratz     DeviceClass *dc = DEVICE_CLASS(klass);
120ff8f06eeSShlomo Pongratz 
121ff8f06eeSShlomo Pongratz     dc->reset = arm_gicv3_common_reset;
122ff8f06eeSShlomo Pongratz     dc->realize = arm_gicv3_common_realize;
123ff8f06eeSShlomo Pongratz     dc->props = arm_gicv3_common_properties;
124ff8f06eeSShlomo Pongratz     dc->vmsd = &vmstate_gicv3;
125ff8f06eeSShlomo Pongratz }
126ff8f06eeSShlomo Pongratz 
127ff8f06eeSShlomo Pongratz static const TypeInfo arm_gicv3_common_type = {
128ff8f06eeSShlomo Pongratz     .name = TYPE_ARM_GICV3_COMMON,
129ff8f06eeSShlomo Pongratz     .parent = TYPE_SYS_BUS_DEVICE,
130ff8f06eeSShlomo Pongratz     .instance_size = sizeof(GICv3State),
131ff8f06eeSShlomo Pongratz     .class_size = sizeof(ARMGICv3CommonClass),
132ff8f06eeSShlomo Pongratz     .class_init = arm_gicv3_common_class_init,
133ff8f06eeSShlomo Pongratz     .abstract = true,
134ff8f06eeSShlomo Pongratz };
135ff8f06eeSShlomo Pongratz 
136ff8f06eeSShlomo Pongratz static void register_types(void)
137ff8f06eeSShlomo Pongratz {
138ff8f06eeSShlomo Pongratz     type_register_static(&arm_gicv3_common_type);
139ff8f06eeSShlomo Pongratz }
140ff8f06eeSShlomo Pongratz 
141ff8f06eeSShlomo Pongratz type_init(register_types)
142