1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#ifndef HW_ARM_GICV3_COMMON_H
25#define HW_ARM_GICV3_COMMON_H
26
27#include "hw/sysbus.h"
28#include "hw/intc/arm_gic_common.h"
29
30
31
32
33
34
35#define GICV3_MAXIRQ 1020
36#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)
37
38
39#define GICV3_TARGETLIST_BITS 16
40
41
42#define GIC_MIN_BPR 0
43
44#define GIC_MIN_BPR_NS (GIC_MIN_BPR + 1)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60#define GICV3_BMP_SIZE (DIV_ROUND_UP(GICV3_MAXIRQ, 32))
61
62#define GIC_DECLARE_BITMAP(name) \
63 uint32_t name[GICV3_BMP_SIZE]
64
65#define GIC_BIT_MASK(nr) (1U << ((nr) % 32))
66#define GIC_BIT_WORD(nr) ((nr) / 32)
67
68static inline void gic_bmp_set_bit(int nr, uint32_t *addr)
69{
70 uint32_t mask = GIC_BIT_MASK(nr);
71 uint32_t *p = addr + GIC_BIT_WORD(nr);
72
73 *p |= mask;
74}
75
76static inline void gic_bmp_clear_bit(int nr, uint32_t *addr)
77{
78 uint32_t mask = GIC_BIT_MASK(nr);
79 uint32_t *p = addr + GIC_BIT_WORD(nr);
80
81 *p &= ~mask;
82}
83
84static inline int gic_bmp_test_bit(int nr, const uint32_t *addr)
85{
86 return 1U & (addr[GIC_BIT_WORD(nr)] >> (nr & 31));
87}
88
89static inline void gic_bmp_replace_bit(int nr, uint32_t *addr, int val)
90{
91 uint32_t mask = GIC_BIT_MASK(nr);
92 uint32_t *p = addr + GIC_BIT_WORD(nr);
93
94 *p &= ~mask;
95 *p |= (val & 1U) << (nr % 32);
96}
97
98
99static inline uint32_t *gic_bmp_ptr32(uint32_t *addr, int nr)
100{
101 return addr + GIC_BIT_WORD(nr);
102}
103
104typedef struct GICv3State GICv3State;
105typedef struct GICv3CPUState GICv3CPUState;
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125#define GICV3_G0 0
126#define GICV3_G1 1
127#define GICV3_G1NS 2
128
129
130
131
132
133
134#define GICV3_S 0
135#define GICV3_NS 1
136
137typedef struct {
138 int irq;
139 uint8_t prio;
140 int grp;
141} PendingIrq;
142
143struct GICv3CPUState {
144 GICv3State *gic;
145 CPUState *cpu;
146 qemu_irq parent_irq;
147 qemu_irq parent_fiq;
148
149
150 uint32_t level;
151
152 uint32_t gicr_ctlr;
153 uint64_t gicr_typer;
154 uint32_t gicr_statusr[2];
155 uint32_t gicr_waker;
156 uint64_t gicr_propbaser;
157 uint64_t gicr_pendbaser;
158
159 uint32_t gicr_igroupr0;
160 uint32_t gicr_ienabler0;
161 uint32_t gicr_ipendr0;
162 uint32_t gicr_iactiver0;
163 uint32_t edge_trigger;
164 uint32_t gicr_igrpmodr0;
165 uint32_t gicr_nsacr;
166 uint8_t gicr_ipriorityr[GIC_INTERNAL];
167
168
169 uint64_t icc_ctlr_el1[2];
170 uint64_t icc_pmr_el1;
171 uint64_t icc_bpr[3];
172 uint64_t icc_apr[3][4];
173 uint64_t icc_igrpen[3];
174 uint64_t icc_ctlr_el3;
175
176
177
178
179
180 PendingIrq hppi;
181
182 bool seenbetter;
183};
184
185struct GICv3State {
186
187 SysBusDevice parent_obj;
188
189
190 MemoryRegion iomem_dist;
191 MemoryRegion iomem_redist;
192
193 uint32_t num_cpu;
194 uint32_t num_irq;
195 uint32_t revision;
196 bool security_extn;
197 bool irq_reset_nonsecure;
198
199 int dev_fd;
200 Error *migration_blocker;
201
202
203
204
205
206
207 uint32_t gicd_ctlr;
208 uint32_t gicd_statusr[2];
209 GIC_DECLARE_BITMAP(group);
210 GIC_DECLARE_BITMAP(grpmod);
211 GIC_DECLARE_BITMAP(enabled);
212 GIC_DECLARE_BITMAP(pending);
213 GIC_DECLARE_BITMAP(active);
214 GIC_DECLARE_BITMAP(level);
215 GIC_DECLARE_BITMAP(edge_trigger);
216 uint8_t gicd_ipriority[GICV3_MAXIRQ];
217 uint64_t gicd_irouter[GICV3_MAXIRQ];
218
219
220
221 GICv3CPUState *gicd_irouter_target[GICV3_MAXIRQ];
222 uint32_t gicd_nsacr[DIV_ROUND_UP(GICV3_MAXIRQ, 16)];
223
224 GICv3CPUState *cpu;
225};
226
227#define GICV3_BITMAP_ACCESSORS(BMP) \
228 static inline void gicv3_gicd_##BMP##_set(GICv3State *s, int irq) \
229 { \
230 gic_bmp_set_bit(irq, s->BMP); \
231 } \
232 static inline int gicv3_gicd_##BMP##_test(GICv3State *s, int irq) \
233 { \
234 return gic_bmp_test_bit(irq, s->BMP); \
235 } \
236 static inline void gicv3_gicd_##BMP##_clear(GICv3State *s, int irq) \
237 { \
238 gic_bmp_clear_bit(irq, s->BMP); \
239 } \
240 static inline void gicv3_gicd_##BMP##_replace(GICv3State *s, \
241 int irq, int value) \
242 { \
243 gic_bmp_replace_bit(irq, s->BMP, value); \
244 }
245
246GICV3_BITMAP_ACCESSORS(group)
247GICV3_BITMAP_ACCESSORS(grpmod)
248GICV3_BITMAP_ACCESSORS(enabled)
249GICV3_BITMAP_ACCESSORS(pending)
250GICV3_BITMAP_ACCESSORS(active)
251GICV3_BITMAP_ACCESSORS(level)
252GICV3_BITMAP_ACCESSORS(edge_trigger)
253
254#define TYPE_ARM_GICV3_COMMON "arm-gicv3-common"
255#define ARM_GICV3_COMMON(obj) \
256 OBJECT_CHECK(GICv3State, (obj), TYPE_ARM_GICV3_COMMON)
257#define ARM_GICV3_COMMON_CLASS(klass) \
258 OBJECT_CLASS_CHECK(ARMGICv3CommonClass, (klass), TYPE_ARM_GICV3_COMMON)
259#define ARM_GICV3_COMMON_GET_CLASS(obj) \
260 OBJECT_GET_CLASS(ARMGICv3CommonClass, (obj), TYPE_ARM_GICV3_COMMON)
261
262typedef struct ARMGICv3CommonClass {
263
264 SysBusDeviceClass parent_class;
265
266
267 void (*pre_save)(GICv3State *s);
268 void (*post_load)(GICv3State *s);
269} ARMGICv3CommonClass;
270
271void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
272 const MemoryRegionOps *ops);
273
274#endif
275