xref: /qemu/hw/intc/arm_gicv3_common.c (revision da34e65cb4025728566d6504a99916f6e7e1dd6a)
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 
238ef94f0bSPeter Maydell #include "qemu/osdep.h"
24*da34e65cSMarkus Armbruster #include "qapi/error.h"
25ff8f06eeSShlomo Pongratz #include "hw/intc/arm_gicv3_common.h"
26ff8f06eeSShlomo Pongratz 
27ff8f06eeSShlomo Pongratz static void gicv3_pre_save(void *opaque)
28ff8f06eeSShlomo Pongratz {
29ff8f06eeSShlomo Pongratz     GICv3State *s = (GICv3State *)opaque;
30ff8f06eeSShlomo Pongratz     ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s);
31ff8f06eeSShlomo Pongratz 
32ff8f06eeSShlomo Pongratz     if (c->pre_save) {
33ff8f06eeSShlomo Pongratz         c->pre_save(s);
34ff8f06eeSShlomo Pongratz     }
35ff8f06eeSShlomo Pongratz }
36ff8f06eeSShlomo Pongratz 
37ff8f06eeSShlomo Pongratz static int gicv3_post_load(void *opaque, int version_id)
38ff8f06eeSShlomo Pongratz {
39ff8f06eeSShlomo Pongratz     GICv3State *s = (GICv3State *)opaque;
40ff8f06eeSShlomo Pongratz     ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s);
41ff8f06eeSShlomo Pongratz 
42ff8f06eeSShlomo Pongratz     if (c->post_load) {
43ff8f06eeSShlomo Pongratz         c->post_load(s);
44ff8f06eeSShlomo Pongratz     }
45ff8f06eeSShlomo Pongratz     return 0;
46ff8f06eeSShlomo Pongratz }
47ff8f06eeSShlomo Pongratz 
48ff8f06eeSShlomo Pongratz static const VMStateDescription vmstate_gicv3 = {
49ff8f06eeSShlomo Pongratz     .name = "arm_gicv3",
50ff8f06eeSShlomo Pongratz     .unmigratable = 1,
51ff8f06eeSShlomo Pongratz     .pre_save = gicv3_pre_save,
52ff8f06eeSShlomo Pongratz     .post_load = gicv3_post_load,
53ff8f06eeSShlomo Pongratz };
54ff8f06eeSShlomo Pongratz 
55ff8f06eeSShlomo Pongratz void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
56ff8f06eeSShlomo Pongratz                               const MemoryRegionOps *ops)
57ff8f06eeSShlomo Pongratz {
58ff8f06eeSShlomo Pongratz     SysBusDevice *sbd = SYS_BUS_DEVICE(s);
59ff8f06eeSShlomo Pongratz     int i;
60ff8f06eeSShlomo Pongratz 
61ff8f06eeSShlomo Pongratz     /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
62ff8f06eeSShlomo Pongratz      * GPIO array layout is thus:
63ff8f06eeSShlomo Pongratz      *  [0..N-1] spi
64ff8f06eeSShlomo Pongratz      *  [N..N+31] PPIs for CPU 0
65ff8f06eeSShlomo Pongratz      *  [N+32..N+63] PPIs for CPU 1
66ff8f06eeSShlomo Pongratz      *   ...
67ff8f06eeSShlomo Pongratz      */
68ff8f06eeSShlomo Pongratz     i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu;
69ff8f06eeSShlomo Pongratz     qdev_init_gpio_in(DEVICE(s), handler, i);
70ff8f06eeSShlomo Pongratz 
71ff8f06eeSShlomo Pongratz     s->parent_irq = g_malloc(s->num_cpu * sizeof(qemu_irq));
72ff8f06eeSShlomo Pongratz     s->parent_fiq = g_malloc(s->num_cpu * sizeof(qemu_irq));
73ff8f06eeSShlomo Pongratz 
74ff8f06eeSShlomo Pongratz     for (i = 0; i < s->num_cpu; i++) {
75ff8f06eeSShlomo Pongratz         sysbus_init_irq(sbd, &s->parent_irq[i]);
76ff8f06eeSShlomo Pongratz     }
77ff8f06eeSShlomo Pongratz     for (i = 0; i < s->num_cpu; i++) {
78ff8f06eeSShlomo Pongratz         sysbus_init_irq(sbd, &s->parent_fiq[i]);
79ff8f06eeSShlomo Pongratz     }
80ff8f06eeSShlomo Pongratz 
81ff8f06eeSShlomo Pongratz     memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
82ff8f06eeSShlomo Pongratz                           "gicv3_dist", 0x10000);
83ff8f06eeSShlomo Pongratz     memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s,
84ff8f06eeSShlomo Pongratz                           "gicv3_redist", 0x20000 * s->num_cpu);
85ff8f06eeSShlomo Pongratz 
86ff8f06eeSShlomo Pongratz     sysbus_init_mmio(sbd, &s->iomem_dist);
87ff8f06eeSShlomo Pongratz     sysbus_init_mmio(sbd, &s->iomem_redist);
88ff8f06eeSShlomo Pongratz }
89ff8f06eeSShlomo Pongratz 
90ff8f06eeSShlomo Pongratz static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
91ff8f06eeSShlomo Pongratz {
92ff8f06eeSShlomo Pongratz     GICv3State *s = ARM_GICV3_COMMON(dev);
93ff8f06eeSShlomo Pongratz 
94ff8f06eeSShlomo Pongratz     /* revision property is actually reserved and currently used only in order
95ff8f06eeSShlomo Pongratz      * to keep the interface compatible with GICv2 code, avoiding extra
96ff8f06eeSShlomo Pongratz      * conditions. However, in future it could be used, for example, if we
97ff8f06eeSShlomo Pongratz      * implement GICv4.
98ff8f06eeSShlomo Pongratz      */
99ff8f06eeSShlomo Pongratz     if (s->revision != 3) {
100ff8f06eeSShlomo Pongratz         error_setg(errp, "unsupported GIC revision %d", s->revision);
101ff8f06eeSShlomo Pongratz         return;
102ff8f06eeSShlomo Pongratz     }
103ff8f06eeSShlomo Pongratz }
104ff8f06eeSShlomo Pongratz 
105ff8f06eeSShlomo Pongratz static void arm_gicv3_common_reset(DeviceState *dev)
106ff8f06eeSShlomo Pongratz {
107ff8f06eeSShlomo Pongratz     /* TODO */
108ff8f06eeSShlomo Pongratz }
109ff8f06eeSShlomo Pongratz 
110ff8f06eeSShlomo Pongratz static Property arm_gicv3_common_properties[] = {
111ff8f06eeSShlomo Pongratz     DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1),
112ff8f06eeSShlomo Pongratz     DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
113ff8f06eeSShlomo Pongratz     DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
114ff8f06eeSShlomo Pongratz     DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
115ff8f06eeSShlomo Pongratz     DEFINE_PROP_END_OF_LIST(),
116ff8f06eeSShlomo Pongratz };
117ff8f06eeSShlomo Pongratz 
118ff8f06eeSShlomo Pongratz static void arm_gicv3_common_class_init(ObjectClass *klass, void *data)
119ff8f06eeSShlomo Pongratz {
120ff8f06eeSShlomo Pongratz     DeviceClass *dc = DEVICE_CLASS(klass);
121ff8f06eeSShlomo Pongratz 
122ff8f06eeSShlomo Pongratz     dc->reset = arm_gicv3_common_reset;
123ff8f06eeSShlomo Pongratz     dc->realize = arm_gicv3_common_realize;
124ff8f06eeSShlomo Pongratz     dc->props = arm_gicv3_common_properties;
125ff8f06eeSShlomo Pongratz     dc->vmsd = &vmstate_gicv3;
126ff8f06eeSShlomo Pongratz }
127ff8f06eeSShlomo Pongratz 
128ff8f06eeSShlomo Pongratz static const TypeInfo arm_gicv3_common_type = {
129ff8f06eeSShlomo Pongratz     .name = TYPE_ARM_GICV3_COMMON,
130ff8f06eeSShlomo Pongratz     .parent = TYPE_SYS_BUS_DEVICE,
131ff8f06eeSShlomo Pongratz     .instance_size = sizeof(GICv3State),
132ff8f06eeSShlomo Pongratz     .class_size = sizeof(ARMGICv3CommonClass),
133ff8f06eeSShlomo Pongratz     .class_init = arm_gicv3_common_class_init,
134ff8f06eeSShlomo Pongratz     .abstract = true,
135ff8f06eeSShlomo Pongratz };
136ff8f06eeSShlomo Pongratz 
137ff8f06eeSShlomo Pongratz static void register_types(void)
138ff8f06eeSShlomo Pongratz {
139ff8f06eeSShlomo Pongratz     type_register_static(&arm_gicv3_common_type);
140ff8f06eeSShlomo Pongratz }
141ff8f06eeSShlomo Pongratz 
142ff8f06eeSShlomo Pongratz type_init(register_types)
143