1 | /* |
2 | * ARM GICv3 emulation: Redistributor |
3 | * |
4 | * Copyright (c) 2015 Huawei. |
5 | * Copyright (c) 2016 Linaro Limited. |
6 | * Written by Shlomo Pongratz, Peter Maydell |
7 | * |
8 | * This code is licensed under the GPL, version 2 or (at your option) |
9 | * any later version. |
10 | */ |
11 | |
12 | #include "qemu/osdep.h" |
13 | #include "qemu/log.h" |
14 | #include "trace.h" |
15 | #include "gicv3_internal.h" |
16 | |
17 | static uint32_t mask_group(GICv3CPUState *cs, MemTxAttrs attrs) |
18 | { |
19 | /* Return a 32-bit mask which should be applied for this set of 32 |
20 | * interrupts; each bit is 1 if access is permitted by the |
21 | * combination of attrs.secure and GICR_GROUPR. (GICR_NSACR does |
22 | * not affect config register accesses, unlike GICD_NSACR.) |
23 | */ |
24 | if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) { |
25 | /* bits for Group 0 or Secure Group 1 interrupts are RAZ/WI */ |
26 | return cs->gicr_igroupr0; |
27 | } |
28 | return 0xFFFFFFFFU; |
29 | } |
30 | |
31 | static int gicr_ns_access(GICv3CPUState *cs, int irq) |
32 | { |
33 | /* Return the 2 bit NSACR.NS_access field for this SGI */ |
34 | assert(irq < 16); |
35 | return extract32(cs->gicr_nsacr, irq * 2, 2); |
36 | } |
37 | |
38 | static void gicr_write_set_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs, |
39 | uint32_t *reg, uint32_t val) |
40 | { |
41 | /* Helper routine to implement writing to a "set-bitmap" register */ |
42 | val &= mask_group(cs, attrs); |
43 | *reg |= val; |
44 | gicv3_redist_update(cs); |
45 | } |
46 | |
47 | static void gicr_write_clear_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs, |
48 | uint32_t *reg, uint32_t val) |
49 | { |
50 | /* Helper routine to implement writing to a "clear-bitmap" register */ |
51 | val &= mask_group(cs, attrs); |
52 | *reg &= ~val; |
53 | gicv3_redist_update(cs); |
54 | } |
55 | |
56 | static uint32_t gicr_read_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs, |
57 | uint32_t reg) |
58 | { |
59 | reg &= mask_group(cs, attrs); |
60 | return reg; |
61 | } |
62 | |
63 | static uint8_t gicr_read_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs, |
64 | int irq) |
65 | { |
66 | /* Read the value of GICR_IPRIORITYR<n> for the specified interrupt, |
67 | * honouring security state (these are RAZ/WI for Group 0 or Secure |
68 | * Group 1 interrupts). |
69 | */ |
70 | uint32_t prio; |
71 | |
72 | prio = cs->gicr_ipriorityr[irq]; |
73 | |
74 | if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) { |
75 | if (!(cs->gicr_igroupr0 & (1U << irq))) { |
76 | /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */ |
77 | return 0; |
78 | } |
79 | /* NS view of the interrupt priority */ |
80 | prio = (prio << 1) & 0xff; |
81 | } |
82 | return prio; |
83 | } |
84 | |
85 | static void gicr_write_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs, int irq, |
86 | uint8_t value) |
87 | { |
88 | /* Write the value of GICD_IPRIORITYR<n> for the specified interrupt, |
89 | * honouring security state (these are RAZ/WI for Group 0 or Secure |
90 | * Group 1 interrupts). |
91 | */ |
92 | if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) { |
93 | if (!(cs->gicr_igroupr0 & (1U << irq))) { |
94 | /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */ |
95 | return; |
96 | } |
97 | /* NS view of the interrupt priority */ |
98 | value = 0x80 | (value >> 1); |
99 | } |
100 | cs->gicr_ipriorityr[irq] = value; |
101 | } |
102 | |
103 | static MemTxResult gicr_readb(GICv3CPUState *cs, hwaddr offset, |
104 | uint64_t *data, MemTxAttrs attrs) |
105 | { |
106 | switch (offset) { |
107 | case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f: |
108 | *data = gicr_read_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR); |
109 | return MEMTX_OK; |
110 | default: |
111 | return MEMTX_ERROR; |
112 | } |
113 | } |
114 | |
115 | static MemTxResult gicr_writeb(GICv3CPUState *cs, hwaddr offset, |
116 | uint64_t value, MemTxAttrs attrs) |
117 | { |
118 | switch (offset) { |
119 | case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f: |
120 | gicr_write_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR, value); |
121 | gicv3_redist_update(cs); |
122 | return MEMTX_OK; |
123 | default: |
124 | return MEMTX_ERROR; |
125 | } |
126 | } |
127 | |
128 | static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset, |
129 | uint64_t *data, MemTxAttrs attrs) |
130 | { |
131 | switch (offset) { |
132 | case GICR_CTLR: |
133 | *data = cs->gicr_ctlr; |
134 | return MEMTX_OK; |
135 | case GICR_IIDR: |
136 | *data = gicv3_iidr(); |
137 | return MEMTX_OK; |
138 | case GICR_TYPER: |
139 | *data = extract64(cs->gicr_typer, 0, 32); |
140 | return MEMTX_OK; |
141 | case GICR_TYPER + 4: |
142 | *data = extract64(cs->gicr_typer, 32, 32); |
143 | return MEMTX_OK; |
144 | case GICR_STATUSR: |
145 | /* RAZ/WI for us (this is an optional register and our implementation |
146 | * does not track RO/WO/reserved violations to report them to the guest) |
147 | */ |
148 | *data = 0; |
149 | return MEMTX_OK; |
150 | case GICR_WAKER: |
151 | *data = cs->gicr_waker; |
152 | return MEMTX_OK; |
153 | case GICR_PROPBASER: |
154 | *data = extract64(cs->gicr_propbaser, 0, 32); |
155 | return MEMTX_OK; |
156 | case GICR_PROPBASER + 4: |
157 | *data = extract64(cs->gicr_propbaser, 32, 32); |
158 | return MEMTX_OK; |
159 | case GICR_PENDBASER: |
160 | *data = extract64(cs->gicr_pendbaser, 0, 32); |
161 | return MEMTX_OK; |
162 | case GICR_PENDBASER + 4: |
163 | *data = extract64(cs->gicr_pendbaser, 32, 32); |
164 | return MEMTX_OK; |
165 | case GICR_IGROUPR0: |
166 | if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) { |
167 | *data = 0; |
168 | return MEMTX_OK; |
169 | } |
170 | *data = cs->gicr_igroupr0; |
171 | return MEMTX_OK; |
172 | case GICR_ISENABLER0: |
173 | case GICR_ICENABLER0: |
174 | *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_ienabler0); |
175 | return MEMTX_OK; |
176 | case GICR_ISPENDR0: |
177 | case GICR_ICPENDR0: |
178 | { |
179 | /* The pending register reads as the logical OR of the pending |
180 | * latch and the input line level for level-triggered interrupts. |
181 | */ |
182 | uint32_t val = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level); |
183 | *data = gicr_read_bitmap_reg(cs, attrs, val); |
184 | return MEMTX_OK; |
185 | } |
186 | case GICR_ISACTIVER0: |
187 | case GICR_ICACTIVER0: |
188 | *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_iactiver0); |
189 | return MEMTX_OK; |
190 | case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f: |
191 | { |
192 | int i, irq = offset - GICR_IPRIORITYR; |
193 | uint32_t value = 0; |
194 | |
195 | for (i = irq + 3; i >= irq; i--) { |
196 | value <<= 8; |
197 | value |= gicr_read_ipriorityr(cs, attrs, i); |
198 | } |
199 | *data = value; |
200 | return MEMTX_OK; |
201 | } |
202 | case GICR_ICFGR0: |
203 | case GICR_ICFGR1: |
204 | { |
205 | /* Our edge_trigger bitmap is one bit per irq; take the correct |
206 | * half of it, and spread it out into the odd bits. |
207 | */ |
208 | uint32_t value; |
209 | |
210 | value = cs->edge_trigger & mask_group(cs, attrs); |
211 | value = extract32(value, (offset == GICR_ICFGR1) ? 16 : 0, 16); |
212 | value = half_shuffle32(value) << 1; |
213 | *data = value; |
214 | return MEMTX_OK; |
215 | } |
216 | case GICR_IGRPMODR0: |
217 | if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) { |
218 | /* RAZ/WI if security disabled, or if |
219 | * security enabled and this is an NS access |
220 | */ |
221 | *data = 0; |
222 | return MEMTX_OK; |
223 | } |
224 | *data = cs->gicr_igrpmodr0; |
225 | return MEMTX_OK; |
226 | case GICR_NSACR: |
227 | if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) { |
228 | /* RAZ/WI if security disabled, or if |
229 | * security enabled and this is an NS access |
230 | */ |
231 | *data = 0; |
232 | return MEMTX_OK; |
233 | } |
234 | *data = cs->gicr_nsacr; |
235 | return MEMTX_OK; |
236 | case GICR_IDREGS ... GICR_IDREGS + 0x2f: |
237 | *data = gicv3_idreg(offset - GICR_IDREGS); |
238 | return MEMTX_OK; |
239 | default: |
240 | return MEMTX_ERROR; |
241 | } |
242 | } |
243 | |
244 | static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset, |
245 | uint64_t value, MemTxAttrs attrs) |
246 | { |
247 | switch (offset) { |
248 | case GICR_CTLR: |
249 | /* For our implementation, GICR_TYPER.DPGS is 0 and so all |
250 | * the DPG bits are RAZ/WI. We don't do anything asynchronously, |
251 | * so UWP and RWP are RAZ/WI. And GICR_TYPER.LPIS is 0 (we don't |
252 | * implement LPIs) so Enable_LPIs is RES0. So there are no writable |
253 | * bits for us. |
254 | */ |
255 | return MEMTX_OK; |
256 | case GICR_STATUSR: |
257 | /* RAZ/WI for our implementation */ |
258 | return MEMTX_OK; |
259 | case GICR_WAKER: |
260 | /* Only the ProcessorSleep bit is writeable. When the guest sets |
261 | * it it requests that we transition the channel between the |
262 | * redistributor and the cpu interface to quiescent, and that |
263 | * we set the ChildrenAsleep bit once the inteface has reached the |
264 | * quiescent state. |
265 | * Setting the ProcessorSleep to 0 reverses the quiescing, and |
266 | * ChildrenAsleep is cleared once the transition is complete. |
267 | * Since our interface is not asynchronous, we complete these |
268 | * transitions instantaneously, so we set ChildrenAsleep to the |
269 | * same value as ProcessorSleep here. |
270 | */ |
271 | value &= GICR_WAKER_ProcessorSleep; |
272 | if (value & GICR_WAKER_ProcessorSleep) { |
273 | value |= GICR_WAKER_ChildrenAsleep; |
274 | } |
275 | cs->gicr_waker = value; |
276 | return MEMTX_OK; |
277 | case GICR_PROPBASER: |
278 | cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 0, 32, value); |
279 | return MEMTX_OK; |
280 | case GICR_PROPBASER + 4: |
281 | cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 32, 32, value); |
282 | return MEMTX_OK; |
283 | case GICR_PENDBASER: |
284 | cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 0, 32, value); |
285 | return MEMTX_OK; |
286 | case GICR_PENDBASER + 4: |
287 | cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 32, 32, value); |
288 | return MEMTX_OK; |
289 | case GICR_IGROUPR0: |
290 | if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) { |
291 | return MEMTX_OK; |
292 | } |
293 | cs->gicr_igroupr0 = value; |
294 | gicv3_redist_update(cs); |
295 | return MEMTX_OK; |
296 | case GICR_ISENABLER0: |
297 | gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value); |
298 | return MEMTX_OK; |
299 | case GICR_ICENABLER0: |
300 | gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value); |
301 | return MEMTX_OK; |
302 | case GICR_ISPENDR0: |
303 | gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value); |
304 | return MEMTX_OK; |
305 | case GICR_ICPENDR0: |
306 | gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value); |
307 | return MEMTX_OK; |
308 | case GICR_ISACTIVER0: |
309 | gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value); |
310 | return MEMTX_OK; |
311 | case GICR_ICACTIVER0: |
312 | gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value); |
313 | return MEMTX_OK; |
314 | case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f: |
315 | { |
316 | int i, irq = offset - GICR_IPRIORITYR; |
317 | |
318 | for (i = irq; i < irq + 4; i++, value >>= 8) { |
319 | gicr_write_ipriorityr(cs, attrs, i, value); |
320 | } |
321 | gicv3_redist_update(cs); |
322 | return MEMTX_OK; |
323 | } |
324 | case GICR_ICFGR0: |
325 | /* Register is all RAZ/WI or RAO/WI bits */ |
326 | return MEMTX_OK; |
327 | case GICR_ICFGR1: |
328 | { |
329 | uint32_t mask; |
330 | |
331 | /* Since our edge_trigger bitmap is one bit per irq, our input |
332 | * 32-bits will compress down into 16 bits which we need |
333 | * to write into the bitmap. |
334 | */ |
335 | value = half_unshuffle32(value >> 1) << 16; |
336 | mask = mask_group(cs, attrs) & 0xffff0000U; |
337 | |
338 | cs->edge_trigger &= ~mask; |
339 | cs->edge_trigger |= (value & mask); |
340 | |
341 | gicv3_redist_update(cs); |
342 | return MEMTX_OK; |
343 | } |
344 | case GICR_IGRPMODR0: |
345 | if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) { |
346 | /* RAZ/WI if security disabled, or if |
347 | * security enabled and this is an NS access |
348 | */ |
349 | return MEMTX_OK; |
350 | } |
351 | cs->gicr_igrpmodr0 = value; |
352 | gicv3_redist_update(cs); |
353 | return MEMTX_OK; |
354 | case GICR_NSACR: |
355 | if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) { |
356 | /* RAZ/WI if security disabled, or if |
357 | * security enabled and this is an NS access |
358 | */ |
359 | return MEMTX_OK; |
360 | } |
361 | cs->gicr_nsacr = value; |
362 | /* no update required as this only affects access permission checks */ |
363 | return MEMTX_OK; |
364 | case GICR_IIDR: |
365 | case GICR_TYPER: |
366 | case GICR_IDREGS ... GICR_IDREGS + 0x2f: |
367 | /* RO registers, ignore the write */ |
368 | qemu_log_mask(LOG_GUEST_ERROR, |
369 | "%s: invalid guest write to RO register at offset " |
370 | TARGET_FMT_plx "\n" , __func__, offset); |
371 | return MEMTX_OK; |
372 | default: |
373 | return MEMTX_ERROR; |
374 | } |
375 | } |
376 | |
377 | static MemTxResult gicr_readll(GICv3CPUState *cs, hwaddr offset, |
378 | uint64_t *data, MemTxAttrs attrs) |
379 | { |
380 | switch (offset) { |
381 | case GICR_TYPER: |
382 | *data = cs->gicr_typer; |
383 | return MEMTX_OK; |
384 | case GICR_PROPBASER: |
385 | *data = cs->gicr_propbaser; |
386 | return MEMTX_OK; |
387 | case GICR_PENDBASER: |
388 | *data = cs->gicr_pendbaser; |
389 | return MEMTX_OK; |
390 | default: |
391 | return MEMTX_ERROR; |
392 | } |
393 | } |
394 | |
395 | static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset, |
396 | uint64_t value, MemTxAttrs attrs) |
397 | { |
398 | switch (offset) { |
399 | case GICR_PROPBASER: |
400 | cs->gicr_propbaser = value; |
401 | return MEMTX_OK; |
402 | case GICR_PENDBASER: |
403 | cs->gicr_pendbaser = value; |
404 | return MEMTX_OK; |
405 | case GICR_TYPER: |
406 | /* RO register, ignore the write */ |
407 | qemu_log_mask(LOG_GUEST_ERROR, |
408 | "%s: invalid guest write to RO register at offset " |
409 | TARGET_FMT_plx "\n" , __func__, offset); |
410 | return MEMTX_OK; |
411 | default: |
412 | return MEMTX_ERROR; |
413 | } |
414 | } |
415 | |
416 | MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data, |
417 | unsigned size, MemTxAttrs attrs) |
418 | { |
419 | GICv3State *s = opaque; |
420 | GICv3CPUState *cs; |
421 | MemTxResult r; |
422 | int cpuidx; |
423 | |
424 | assert((offset & (size - 1)) == 0); |
425 | |
426 | /* This region covers all the redistributor pages; there are |
427 | * (for GICv3) two 64K pages per CPU. At the moment they are |
428 | * all contiguous (ie in this one region), though we might later |
429 | * want to allow splitting of redistributor pages into several |
430 | * blocks so we can support more CPUs. |
431 | */ |
432 | cpuidx = offset / 0x20000; |
433 | offset %= 0x20000; |
434 | assert(cpuidx < s->num_cpu); |
435 | |
436 | cs = &s->cpu[cpuidx]; |
437 | |
438 | switch (size) { |
439 | case 1: |
440 | r = gicr_readb(cs, offset, data, attrs); |
441 | break; |
442 | case 4: |
443 | r = gicr_readl(cs, offset, data, attrs); |
444 | break; |
445 | case 8: |
446 | r = gicr_readll(cs, offset, data, attrs); |
447 | break; |
448 | default: |
449 | r = MEMTX_ERROR; |
450 | break; |
451 | } |
452 | |
453 | if (r == MEMTX_ERROR) { |
454 | qemu_log_mask(LOG_GUEST_ERROR, |
455 | "%s: invalid guest read at offset " TARGET_FMT_plx |
456 | "size %u\n" , __func__, offset, size); |
457 | trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset, |
458 | size, attrs.secure); |
459 | /* The spec requires that reserved registers are RAZ/WI; |
460 | * so use MEMTX_ERROR returns from leaf functions as a way to |
461 | * trigger the guest-error logging but don't return it to |
462 | * the caller, or we'll cause a spurious guest data abort. |
463 | */ |
464 | r = MEMTX_OK; |
465 | *data = 0; |
466 | } else { |
467 | trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data, |
468 | size, attrs.secure); |
469 | } |
470 | return r; |
471 | } |
472 | |
473 | MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, |
474 | unsigned size, MemTxAttrs attrs) |
475 | { |
476 | GICv3State *s = opaque; |
477 | GICv3CPUState *cs; |
478 | MemTxResult r; |
479 | int cpuidx; |
480 | |
481 | assert((offset & (size - 1)) == 0); |
482 | |
483 | /* This region covers all the redistributor pages; there are |
484 | * (for GICv3) two 64K pages per CPU. At the moment they are |
485 | * all contiguous (ie in this one region), though we might later |
486 | * want to allow splitting of redistributor pages into several |
487 | * blocks so we can support more CPUs. |
488 | */ |
489 | cpuidx = offset / 0x20000; |
490 | offset %= 0x20000; |
491 | assert(cpuidx < s->num_cpu); |
492 | |
493 | cs = &s->cpu[cpuidx]; |
494 | |
495 | switch (size) { |
496 | case 1: |
497 | r = gicr_writeb(cs, offset, data, attrs); |
498 | break; |
499 | case 4: |
500 | r = gicr_writel(cs, offset, data, attrs); |
501 | break; |
502 | case 8: |
503 | r = gicr_writell(cs, offset, data, attrs); |
504 | break; |
505 | default: |
506 | r = MEMTX_ERROR; |
507 | break; |
508 | } |
509 | |
510 | if (r == MEMTX_ERROR) { |
511 | qemu_log_mask(LOG_GUEST_ERROR, |
512 | "%s: invalid guest write at offset " TARGET_FMT_plx |
513 | "size %u\n" , __func__, offset, size); |
514 | trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data, |
515 | size, attrs.secure); |
516 | /* The spec requires that reserved registers are RAZ/WI; |
517 | * so use MEMTX_ERROR returns from leaf functions as a way to |
518 | * trigger the guest-error logging but don't return it to |
519 | * the caller, or we'll cause a spurious guest data abort. |
520 | */ |
521 | r = MEMTX_OK; |
522 | } else { |
523 | trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data, |
524 | size, attrs.secure); |
525 | } |
526 | return r; |
527 | } |
528 | |
529 | void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level) |
530 | { |
531 | /* Update redistributor state for a change in an external PPI input line */ |
532 | if (level == extract32(cs->level, irq, 1)) { |
533 | return; |
534 | } |
535 | |
536 | trace_gicv3_redist_set_irq(gicv3_redist_affid(cs), irq, level); |
537 | |
538 | cs->level = deposit32(cs->level, irq, 1, level); |
539 | |
540 | if (level) { |
541 | /* 0->1 edges latch the pending bit for edge-triggered interrupts */ |
542 | if (extract32(cs->edge_trigger, irq, 1)) { |
543 | cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1); |
544 | } |
545 | } |
546 | |
547 | gicv3_redist_update(cs); |
548 | } |
549 | |
550 | void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns) |
551 | { |
552 | /* Update redistributor state for a generated SGI */ |
553 | int irqgrp = gicv3_irq_group(cs->gic, cs, irq); |
554 | |
555 | /* If we are asked for a Secure Group 1 SGI and it's actually |
556 | * configured as Secure Group 0 this is OK (subject to the usual |
557 | * NSACR checks). |
558 | */ |
559 | if (grp == GICV3_G1 && irqgrp == GICV3_G0) { |
560 | grp = GICV3_G0; |
561 | } |
562 | |
563 | if (grp != irqgrp) { |
564 | return; |
565 | } |
566 | |
567 | if (ns && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) { |
568 | /* If security is enabled we must test the NSACR bits */ |
569 | int nsaccess = gicr_ns_access(cs, irq); |
570 | |
571 | if ((irqgrp == GICV3_G0 && nsaccess < 1) || |
572 | (irqgrp == GICV3_G1 && nsaccess < 2)) { |
573 | return; |
574 | } |
575 | } |
576 | |
577 | /* OK, we can accept the SGI */ |
578 | trace_gicv3_redist_send_sgi(gicv3_redist_affid(cs), irq); |
579 | cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1); |
580 | gicv3_redist_update(cs); |
581 | } |
582 | |