dev: Delete the authors list from files in src/dev.
[gem5.git] / src / dev / arm / gic_v3_cpu_interface.cc
1 /*
2 * Copyright (c) 2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2018 Metempsy Technology Consulting
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 #include "dev/arm/gic_v3_cpu_interface.hh"
42
43 #include "arch/arm/isa.hh"
44 #include "debug/GIC.hh"
45 #include "dev/arm/gic_v3.hh"
46 #include "dev/arm/gic_v3_distributor.hh"
47 #include "dev/arm/gic_v3_redistributor.hh"
48
49 const uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
50 const uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
51
52 Gicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
53 : BaseISADevice(),
54 gic(gic),
55 redistributor(nullptr),
56 distributor(nullptr),
57 cpuId(cpu_id)
58 {
59 hppi.prio = 0xff;
60 hppi.intid = Gicv3::INTID_SPURIOUS;
61 }
62
63 void
64 Gicv3CPUInterface::init()
65 {
66 redistributor = gic->getRedistributor(cpuId);
67 distributor = gic->getDistributor();
68 }
69
70 void
71 Gicv3CPUInterface::resetHppi(uint32_t intid)
72 {
73 if (intid == hppi.intid)
74 hppi.prio = 0xff;
75 }
76
77 void
78 Gicv3CPUInterface::setThreadContext(ThreadContext *tc)
79 {
80 maintenanceInterrupt = gic->params()->maint_int->get(tc);
81 }
82
83 bool
84 Gicv3CPUInterface::getHCREL2FMO() const
85 {
86 HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
87
88 if (hcr.tge && hcr.e2h) {
89 return false;
90 } else if (hcr.tge) {
91 return true;
92 } else {
93 return hcr.fmo;
94 }
95 }
96
97 bool
98 Gicv3CPUInterface::getHCREL2IMO() const
99 {
100 HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
101
102 if (hcr.tge && hcr.e2h) {
103 return false;
104 } else if (hcr.tge) {
105 return true;
106 } else {
107 return hcr.imo;
108 }
109 }
110
111 RegVal
112 Gicv3CPUInterface::readMiscReg(int misc_reg)
113 {
114 RegVal value = isa->readMiscRegNoEffect(misc_reg);
115 bool hcr_fmo = getHCREL2FMO();
116 bool hcr_imo = getHCREL2IMO();
117
118 switch (misc_reg) {
119 // Active Priorities Group 1 Registers
120 case MISCREG_ICC_AP1R0:
121 case MISCREG_ICC_AP1R0_EL1: {
122 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
123 return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
124 }
125
126 return readBankedMiscReg(MISCREG_ICC_AP1R0_EL1);
127 }
128
129 case MISCREG_ICC_AP1R1:
130 case MISCREG_ICC_AP1R1_EL1:
131
132 // only implemented if supporting 6 or more bits of priority
133 case MISCREG_ICC_AP1R2:
134 case MISCREG_ICC_AP1R2_EL1:
135
136 // only implemented if supporting 7 or more bits of priority
137 case MISCREG_ICC_AP1R3:
138 case MISCREG_ICC_AP1R3_EL1:
139 // only implemented if supporting 7 or more bits of priority
140 return 0;
141
142 // Active Priorities Group 0 Registers
143 case MISCREG_ICC_AP0R0:
144 case MISCREG_ICC_AP0R0_EL1: {
145 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
146 return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
147 }
148
149 break;
150 }
151
152 case MISCREG_ICC_AP0R1:
153 case MISCREG_ICC_AP0R1_EL1:
154
155 // only implemented if supporting 6 or more bits of priority
156 case MISCREG_ICC_AP0R2:
157 case MISCREG_ICC_AP0R2_EL1:
158
159 // only implemented if supporting 7 or more bits of priority
160 case MISCREG_ICC_AP0R3:
161 case MISCREG_ICC_AP0R3_EL1:
162 // only implemented if supporting 7 or more bits of priority
163 return 0;
164
165 // Interrupt Group 0 Enable register EL1
166 case MISCREG_ICC_IGRPEN0:
167 case MISCREG_ICC_IGRPEN0_EL1: {
168 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
169 return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
170 }
171
172 break;
173 }
174
175 case MISCREG_ICV_IGRPEN0_EL1: {
176 ICH_VMCR_EL2 ich_vmcr_el2 =
177 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
178 value = ich_vmcr_el2.VENG0;
179 break;
180 }
181
182 // Interrupt Group 1 Enable register EL1
183 case MISCREG_ICC_IGRPEN1:
184 case MISCREG_ICC_IGRPEN1_EL1: {
185 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
186 return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
187 }
188
189 value = readBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1);
190 break;
191 }
192
193 case MISCREG_ICV_IGRPEN1_EL1: {
194 ICH_VMCR_EL2 ich_vmcr_el2 =
195 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
196 value = ich_vmcr_el2.VENG1;
197 break;
198 }
199
200 // Interrupt Group 1 Enable register EL3
201 case MISCREG_ICC_MGRPEN1:
202 case MISCREG_ICC_IGRPEN1_EL3: {
203 ICC_IGRPEN1_EL3 igrp_el3 = 0;
204 igrp_el3.EnableGrp1S = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
205 MISCREG_ICC_IGRPEN1_EL1_S)).Enable;
206
207 igrp_el3.EnableGrp1NS = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
208 MISCREG_ICC_IGRPEN1_EL1_NS)).Enable;
209
210 value = igrp_el3;
211 break;
212 }
213
214 // Running Priority Register
215 case MISCREG_ICC_RPR:
216 case MISCREG_ICC_RPR_EL1: {
217 if ((currEL() == EL1) && !inSecureState() &&
218 (hcr_imo || hcr_fmo)) {
219 return readMiscReg(MISCREG_ICV_RPR_EL1);
220 }
221
222 uint8_t rprio = highestActivePriority();
223
224 if (haveEL(EL3) && !inSecureState() &&
225 (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
226 // Spec section 4.8.1
227 // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
228 if ((rprio & 0x80) == 0) {
229 // If the current priority mask value is in the range of
230 // 0x00-0x7F a read access returns the value 0x0
231 rprio = 0;
232 } else if (rprio != 0xff) {
233 // If the current priority mask value is in the range of
234 // 0x80-0xFF a read access returns the Non-secure read of
235 // the current value
236 rprio = (rprio << 1) & 0xff;
237 }
238 }
239
240 value = rprio;
241 break;
242 }
243
244 // Virtual Running Priority Register
245 case MISCREG_ICV_RPR_EL1: {
246 value = virtualHighestActivePriority();
247 break;
248 }
249
250 // Highest Priority Pending Interrupt Register 0
251 case MISCREG_ICC_HPPIR0:
252 case MISCREG_ICC_HPPIR0_EL1: {
253 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
254 return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
255 }
256
257 value = getHPPIR0();
258 break;
259 }
260
261 // Virtual Highest Priority Pending Interrupt Register 0
262 case MISCREG_ICV_HPPIR0_EL1: {
263 value = Gicv3::INTID_SPURIOUS;
264 int lr_idx = getHPPVILR();
265
266 if (lr_idx >= 0) {
267 ICH_LR_EL2 ich_lr_el2 =
268 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
269 Gicv3::GroupId group =
270 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
271
272 if (group == Gicv3::G0S) {
273 value = ich_lr_el2.vINTID;
274 }
275 }
276
277 break;
278 }
279
280 // Highest Priority Pending Interrupt Register 1
281 case MISCREG_ICC_HPPIR1:
282 case MISCREG_ICC_HPPIR1_EL1: {
283 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
284 return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
285 }
286
287 value = getHPPIR1();
288 break;
289 }
290
291 // Virtual Highest Priority Pending Interrupt Register 1
292 case MISCREG_ICV_HPPIR1_EL1: {
293 value = Gicv3::INTID_SPURIOUS;
294 int lr_idx = getHPPVILR();
295
296 if (lr_idx >= 0) {
297 ICH_LR_EL2 ich_lr_el2 =
298 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
299 Gicv3::GroupId group =
300 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
301
302 if (group == Gicv3::G1NS) {
303 value = ich_lr_el2.vINTID;
304 }
305 }
306
307 break;
308 }
309
310 // Binary Point Register 0
311 case MISCREG_ICC_BPR0:
312 case MISCREG_ICC_BPR0_EL1: {
313 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
314 return readMiscReg(MISCREG_ICV_BPR0_EL1);
315 }
316
317 value = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
318 break;
319 }
320
321 // Binary Point Register 1
322 case MISCREG_ICC_BPR1:
323 case MISCREG_ICC_BPR1_EL1: {
324 value = bpr1(isSecureBelowEL3() ? Gicv3::G1S : Gicv3::G1NS);
325 break;
326 }
327
328 // Virtual Binary Point Register 0
329 case MISCREG_ICV_BPR0_EL1: {
330 ICH_VMCR_EL2 ich_vmcr_el2 =
331 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
332
333 value = ich_vmcr_el2.VBPR0;
334 break;
335 }
336
337 // Virtual Binary Point Register 1
338 case MISCREG_ICV_BPR1_EL1: {
339 ICH_VMCR_EL2 ich_vmcr_el2 =
340 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
341
342 if (ich_vmcr_el2.VCBPR) {
343 // bpr0 + 1 saturated to 7, WI
344 value = ich_vmcr_el2.VBPR0 + 1;
345 value = value < 7 ? value : 7;
346 } else {
347 value = ich_vmcr_el2.VBPR1;
348 }
349
350 break;
351 }
352
353 // Interrupt Priority Mask Register
354 case MISCREG_ICC_PMR:
355 case MISCREG_ICC_PMR_EL1:
356 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
357 return readMiscReg(MISCREG_ICV_PMR_EL1);
358 }
359
360 if (haveEL(EL3) && !inSecureState() &&
361 (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
362 // Spec section 4.8.1
363 // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
364 if ((value & 0x80) == 0) {
365 // If the current priority mask value is in the range of
366 // 0x00-0x7F a read access returns the value 0x00.
367 value = 0;
368 } else if (value != 0xff) {
369 // If the current priority mask value is in the range of
370 // 0x80-0xFF a read access returns the Non-secure read of the
371 // current value.
372 value = (value << 1) & 0xff;
373 }
374 }
375
376 break;
377
378 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
379 ICH_VMCR_EL2 ich_vmcr_el2 =
380 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
381
382 value = ich_vmcr_el2.VPMR;
383 break;
384 }
385
386 // Interrupt Acknowledge Register 0
387 case MISCREG_ICC_IAR0:
388 case MISCREG_ICC_IAR0_EL1: {
389 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
390 return readMiscReg(MISCREG_ICV_IAR0_EL1);
391 }
392
393 uint32_t int_id;
394
395 if (hppiCanPreempt()) {
396 int_id = getHPPIR0();
397
398 // avoid activation for special interrupts
399 if (int_id < Gicv3::INTID_SECURE ||
400 int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
401 activateIRQ(int_id, hppi.group);
402 }
403 } else {
404 int_id = Gicv3::INTID_SPURIOUS;
405 }
406
407 value = int_id;
408 break;
409 }
410
411 // Virtual Interrupt Acknowledge Register 0
412 case MISCREG_ICV_IAR0_EL1: {
413 int lr_idx = getHPPVILR();
414 uint32_t int_id = Gicv3::INTID_SPURIOUS;
415
416 if (lr_idx >= 0) {
417 ICH_LR_EL2 ich_lr_el2 =
418 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
419
420 if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
421 int_id = ich_lr_el2.vINTID;
422
423 if (int_id < Gicv3::INTID_SECURE ||
424 int_id > Gicv3::INTID_SPURIOUS) {
425 virtualActivateIRQ(lr_idx);
426 } else {
427 // Bogus... Pseudocode says:
428 // - Move from pending to invalid...
429 // - Return de bogus id...
430 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
431 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
432 ich_lr_el2);
433 }
434 }
435 }
436
437 value = int_id;
438 virtualUpdate();
439 break;
440 }
441
442 // Interrupt Acknowledge Register 1
443 case MISCREG_ICC_IAR1:
444 case MISCREG_ICC_IAR1_EL1: {
445 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
446 return readMiscReg(MISCREG_ICV_IAR1_EL1);
447 }
448
449 uint32_t int_id;
450
451 if (hppiCanPreempt()) {
452 int_id = getHPPIR1();
453
454 // avoid activation for special interrupts
455 if (int_id < Gicv3::INTID_SECURE ||
456 int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
457 activateIRQ(int_id, hppi.group);
458 }
459 } else {
460 int_id = Gicv3::INTID_SPURIOUS;
461 }
462
463 value = int_id;
464 break;
465 }
466
467 // Virtual Interrupt Acknowledge Register 1
468 case MISCREG_ICV_IAR1_EL1: {
469 int lr_idx = getHPPVILR();
470 uint32_t int_id = Gicv3::INTID_SPURIOUS;
471
472 if (lr_idx >= 0) {
473 ICH_LR_EL2 ich_lr_el2 =
474 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
475
476 if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
477 int_id = ich_lr_el2.vINTID;
478
479 if (int_id < Gicv3::INTID_SECURE ||
480 int_id > Gicv3::INTID_SPURIOUS) {
481 virtualActivateIRQ(lr_idx);
482 } else {
483 // Bogus... Pseudocode says:
484 // - Move from pending to invalid...
485 // - Return de bogus id...
486 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
487 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
488 ich_lr_el2);
489 }
490 }
491 }
492
493 value = int_id;
494 virtualUpdate();
495 break;
496 }
497
498 // System Register Enable Register EL1
499 case MISCREG_ICC_SRE:
500 case MISCREG_ICC_SRE_EL1: {
501 /*
502 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
503 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
504 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
505 */
506 ICC_SRE_EL1 icc_sre_el1 = 0;
507 icc_sre_el1.SRE = 1;
508 icc_sre_el1.DIB = 1;
509 icc_sre_el1.DFB = 1;
510 value = icc_sre_el1;
511 break;
512 }
513
514 // System Register Enable Register EL2
515 case MISCREG_ICC_HSRE:
516 case MISCREG_ICC_SRE_EL2: {
517 /*
518 * Enable [3] == 1
519 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
520 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
521 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
522 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
523 */
524 ICC_SRE_EL2 icc_sre_el2 = 0;
525 icc_sre_el2.SRE = 1;
526 icc_sre_el2.DIB = 1;
527 icc_sre_el2.DFB = 1;
528 icc_sre_el2.Enable = 1;
529 value = icc_sre_el2;
530 break;
531 }
532
533 // System Register Enable Register EL3
534 case MISCREG_ICC_MSRE:
535 case MISCREG_ICC_SRE_EL3: {
536 /*
537 * Enable [3] == 1
538 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
539 * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
540 * RAO/WI)
541 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
542 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
543 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
544 */
545 ICC_SRE_EL3 icc_sre_el3 = 0;
546 icc_sre_el3.SRE = 1;
547 icc_sre_el3.DIB = 1;
548 icc_sre_el3.DFB = 1;
549 icc_sre_el3.Enable = 1;
550 value = icc_sre_el3;
551 break;
552 }
553
554 // Control Register
555 case MISCREG_ICC_CTLR:
556 case MISCREG_ICC_CTLR_EL1: {
557 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
558 return readMiscReg(MISCREG_ICV_CTLR_EL1);
559 }
560
561 value = readBankedMiscReg(MISCREG_ICC_CTLR_EL1);
562 // Enforce value for RO bits
563 // ExtRange [19], INTIDs in the range 1024..8191 not supported
564 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
565 // A3V [15], supports non-zero values of the Aff3 field in SGI
566 // generation System registers
567 // SEIS [14], does not support generation of SEIs (deprecated)
568 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
569 // PRIbits [10:8], number of priority bits implemented, minus one
570 ICC_CTLR_EL1 icc_ctlr_el1 = value;
571 icc_ctlr_el1.ExtRange = 0;
572 icc_ctlr_el1.RSS = 1;
573 icc_ctlr_el1.A3V = 1;
574 icc_ctlr_el1.SEIS = 0;
575 icc_ctlr_el1.IDbits = 1;
576 icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
577 value = icc_ctlr_el1;
578 break;
579 }
580
581 // Virtual Control Register
582 case MISCREG_ICV_CTLR_EL1: {
583 ICV_CTLR_EL1 icv_ctlr_el1 = value;
584 icv_ctlr_el1.RSS = 0;
585 icv_ctlr_el1.A3V = 1;
586 icv_ctlr_el1.SEIS = 0;
587 icv_ctlr_el1.IDbits = 1;
588 icv_ctlr_el1.PRIbits = 7;
589 value = icv_ctlr_el1;
590 break;
591 }
592
593 // Control Register
594 case MISCREG_ICC_MCTLR:
595 case MISCREG_ICC_CTLR_EL3: {
596 // Enforce value for RO bits
597 // ExtRange [19], INTIDs in the range 1024..8191 not supported
598 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
599 // nDS [17], supports disabling of security
600 // A3V [15], supports non-zero values of the Aff3 field in SGI
601 // generation System registers
602 // SEIS [14], does not support generation of SEIs (deprecated)
603 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
604 // PRIbits [10:8], number of priority bits implemented, minus one
605 ICC_CTLR_EL3 icc_ctlr_el3 = value;
606 icc_ctlr_el3.ExtRange = 0;
607 icc_ctlr_el3.RSS = 1;
608 icc_ctlr_el3.nDS = 0;
609 icc_ctlr_el3.A3V = 1;
610 icc_ctlr_el3.SEIS = 0;
611 icc_ctlr_el3.IDbits = 0;
612 icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
613 value = icc_ctlr_el3;
614 break;
615 }
616
617 // Hyp Control Register
618 case MISCREG_ICH_HCR:
619 case MISCREG_ICH_HCR_EL2:
620 break;
621
622 // Hyp Active Priorities Group 0 Registers
623 case MISCREG_ICH_AP0R0:
624 case MISCREG_ICH_AP0R0_EL2:
625 break;
626
627 // only implemented if supporting 6 or more bits of priority
628 case MISCREG_ICH_AP0R1:
629 case MISCREG_ICH_AP0R1_EL2:
630 // only implemented if supporting 7 or more bits of priority
631 case MISCREG_ICH_AP0R2:
632 case MISCREG_ICH_AP0R2_EL2:
633 // only implemented if supporting 7 or more bits of priority
634 case MISCREG_ICH_AP0R3:
635 case MISCREG_ICH_AP0R3_EL2:
636 // Unimplemented registers are RAZ/WI
637 return 0;
638
639 // Hyp Active Priorities Group 1 Registers
640 case MISCREG_ICH_AP1R0:
641 case MISCREG_ICH_AP1R0_EL2:
642 break;
643
644 // only implemented if supporting 6 or more bits of priority
645 case MISCREG_ICH_AP1R1:
646 case MISCREG_ICH_AP1R1_EL2:
647 // only implemented if supporting 7 or more bits of priority
648 case MISCREG_ICH_AP1R2:
649 case MISCREG_ICH_AP1R2_EL2:
650 // only implemented if supporting 7 or more bits of priority
651 case MISCREG_ICH_AP1R3:
652 case MISCREG_ICH_AP1R3_EL2:
653 // Unimplemented registers are RAZ/WI
654 return 0;
655
656 // Maintenance Interrupt State Register
657 case MISCREG_ICH_MISR:
658 case MISCREG_ICH_MISR_EL2:
659 value = maintenanceInterruptStatus();
660 break;
661
662 // VGIC Type Register
663 case MISCREG_ICH_VTR:
664 case MISCREG_ICH_VTR_EL2: {
665 ICH_VTR_EL2 ich_vtr_el2 = value;
666
667 ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
668 ich_vtr_el2.A3V = 1;
669 ich_vtr_el2.IDbits = 1;
670 ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
671 ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
672
673 value = ich_vtr_el2;
674 break;
675 }
676
677 // End of Interrupt Status Register
678 case MISCREG_ICH_EISR:
679 case MISCREG_ICH_EISR_EL2:
680 value = eoiMaintenanceInterruptStatus();
681 break;
682
683 // Empty List Register Status Register
684 case MISCREG_ICH_ELRSR:
685 case MISCREG_ICH_ELRSR_EL2:
686 value = 0;
687
688 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
689 ICH_LR_EL2 ich_lr_el2 =
690 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
691
692 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
693 (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
694 value |= (1 << lr_idx);
695 }
696 }
697
698 break;
699
700 // List Registers
701 case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
702 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
703 value = value >> 32;
704 break;
705
706 // List Registers
707 case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
708 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
709 value = value & 0xffffffff;
710 break;
711
712 // List Registers
713 case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
714 break;
715
716 // Virtual Machine Control Register
717 case MISCREG_ICH_VMCR:
718 case MISCREG_ICH_VMCR_EL2:
719 break;
720
721 default:
722 panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
723 misc_reg, miscRegName[misc_reg]);
724 }
725
726 DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
727 miscRegName[misc_reg], value);
728 return value;
729 }
730
731 void
732 Gicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
733 {
734 bool do_virtual_update = false;
735 DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
736 miscRegName[misc_reg], val);
737 bool hcr_fmo = getHCREL2FMO();
738 bool hcr_imo = getHCREL2IMO();
739
740 switch (misc_reg) {
741 // Active Priorities Group 1 Registers
742 case MISCREG_ICC_AP1R0:
743 case MISCREG_ICC_AP1R0_EL1:
744 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
745 return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
746 }
747
748 setBankedMiscReg(MISCREG_ICC_AP1R0_EL1, val);
749 return;
750
751 case MISCREG_ICC_AP1R1:
752 case MISCREG_ICC_AP1R1_EL1:
753
754 // only implemented if supporting 6 or more bits of priority
755 case MISCREG_ICC_AP1R2:
756 case MISCREG_ICC_AP1R2_EL1:
757
758 // only implemented if supporting 7 or more bits of priority
759 case MISCREG_ICC_AP1R3:
760 case MISCREG_ICC_AP1R3_EL1:
761 // only implemented if supporting 7 or more bits of priority
762 break;
763
764 // Active Priorities Group 0 Registers
765 case MISCREG_ICC_AP0R0:
766 case MISCREG_ICC_AP0R0_EL1:
767 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
768 return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
769 }
770
771 break;
772
773 case MISCREG_ICC_AP0R1:
774 case MISCREG_ICC_AP0R1_EL1:
775
776 // only implemented if supporting 6 or more bits of priority
777 case MISCREG_ICC_AP0R2:
778 case MISCREG_ICC_AP0R2_EL1:
779
780 // only implemented if supporting 7 or more bits of priority
781 case MISCREG_ICC_AP0R3:
782 case MISCREG_ICC_AP0R3_EL1:
783 // only implemented if supporting 7 or more bits of priority
784 break;
785
786 // End Of Interrupt Register 0
787 case MISCREG_ICC_EOIR0:
788 case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
789 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
790 return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
791 }
792
793 int int_id = val & 0xffffff;
794
795 // avoid activation for special interrupts
796 if (int_id >= Gicv3::INTID_SECURE &&
797 int_id <= Gicv3::INTID_SPURIOUS) {
798 return;
799 }
800
801 Gicv3::GroupId group = Gicv3::G0S;
802
803 if (highestActiveGroup() != group) {
804 return;
805 }
806
807 dropPriority(group);
808
809 if (!isEOISplitMode()) {
810 deactivateIRQ(int_id, group);
811 }
812
813 break;
814 }
815
816 // Virtual End Of Interrupt Register 0
817 case MISCREG_ICV_EOIR0_EL1: {
818 int int_id = val & 0xffffff;
819
820 // avoid deactivation for special interrupts
821 if (int_id >= Gicv3::INTID_SECURE &&
822 int_id <= Gicv3::INTID_SPURIOUS) {
823 return;
824 }
825
826 uint8_t drop_prio = virtualDropPriority();
827
828 if (drop_prio == 0xff) {
829 return;
830 }
831
832 int lr_idx = virtualFindActive(int_id);
833
834 if (lr_idx < 0) {
835 // No LR found matching
836 virtualIncrementEOICount();
837 } else {
838 ICH_LR_EL2 ich_lr_el2 =
839 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
840 Gicv3::GroupId lr_group =
841 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
842 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
843
844 if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
845 //if (!virtualIsEOISplitMode())
846 {
847 virtualDeactivateIRQ(lr_idx);
848 }
849 }
850 }
851
852 virtualUpdate();
853 break;
854 }
855
856 // End Of Interrupt Register 1
857 case MISCREG_ICC_EOIR1:
858 case MISCREG_ICC_EOIR1_EL1: {
859 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
860 return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
861 }
862
863 int int_id = val & 0xffffff;
864
865 // avoid deactivation for special interrupts
866 if (int_id >= Gicv3::INTID_SECURE &&
867 int_id <= Gicv3::INTID_SPURIOUS) {
868 return;
869 }
870
871 Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
872
873 if (highestActiveGroup() == Gicv3::G0S) {
874 return;
875 }
876
877 if (distributor->DS == 0) {
878 if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
879 return;
880 } else if (highestActiveGroup() == Gicv3::G1NS &&
881 !(!inSecureState() or (currEL() == EL3))) {
882 return;
883 }
884 }
885
886 dropPriority(group);
887
888 if (!isEOISplitMode()) {
889 deactivateIRQ(int_id, group);
890 }
891
892 break;
893 }
894
895 // Virtual End Of Interrupt Register 1
896 case MISCREG_ICV_EOIR1_EL1: {
897 int int_id = val & 0xffffff;
898
899 // avoid deactivation for special interrupts
900 if (int_id >= Gicv3::INTID_SECURE &&
901 int_id <= Gicv3::INTID_SPURIOUS) {
902 return;
903 }
904
905 uint8_t drop_prio = virtualDropPriority();
906
907 if (drop_prio == 0xff) {
908 return;
909 }
910
911 int lr_idx = virtualFindActive(int_id);
912
913 if (lr_idx < 0) {
914 // No matching LR found
915 virtualIncrementEOICount();
916 } else {
917 ICH_LR_EL2 ich_lr_el2 =
918 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
919 Gicv3::GroupId lr_group =
920 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
921 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
922
923 if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
924 if (!virtualIsEOISplitMode()) {
925 virtualDeactivateIRQ(lr_idx);
926 }
927 }
928 }
929
930 virtualUpdate();
931 break;
932 }
933
934 // Deactivate Interrupt Register
935 case MISCREG_ICC_DIR:
936 case MISCREG_ICC_DIR_EL1: {
937 if ((currEL() == EL1) && !inSecureState() &&
938 (hcr_imo || hcr_fmo)) {
939 return setMiscReg(MISCREG_ICV_DIR_EL1, val);
940 }
941
942 int int_id = val & 0xffffff;
943
944 // The following checks are as per spec pseudocode
945 // aarch64/support/ICC_DIR_EL1
946
947 // Check for spurious ID
948 if (int_id >= Gicv3::INTID_SECURE) {
949 return;
950 }
951
952 // EOI mode is not set, so don't deactivate
953 if (!isEOISplitMode()) {
954 return;
955 }
956
957 Gicv3::GroupId group =
958 int_id >= 32 ? distributor->getIntGroup(int_id) :
959 redistributor->getIntGroup(int_id);
960 bool irq_is_grp0 = group == Gicv3::G0S;
961 bool single_sec_state = distributor->DS;
962 bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
963 SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
964 bool route_fiq_to_el3 = scr_el3.fiq;
965 bool route_irq_to_el3 = scr_el3.irq;
966 bool route_fiq_to_el2 = hcr_fmo;
967 bool route_irq_to_el2 = hcr_imo;
968
969 switch (currEL()) {
970 case EL3:
971 break;
972
973 case EL2:
974 if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
975 break;
976 }
977
978 if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
979 break;
980 }
981
982 return;
983
984 case EL1:
985 if (!isSecureBelowEL3()) {
986 if (single_sec_state && irq_is_grp0 &&
987 !route_fiq_to_el3 && !route_fiq_to_el2) {
988 break;
989 }
990
991 if (!irq_is_secure && !irq_is_grp0 &&
992 !route_irq_to_el3 && !route_irq_to_el2) {
993 break;
994 }
995 } else {
996 if (irq_is_grp0 && !route_fiq_to_el3) {
997 break;
998 }
999
1000 if (!irq_is_grp0 &&
1001 (!irq_is_secure || !single_sec_state) &&
1002 !route_irq_to_el3) {
1003 break;
1004 }
1005 }
1006
1007 return;
1008
1009 default:
1010 break;
1011 }
1012
1013 deactivateIRQ(int_id, group);
1014 break;
1015 }
1016
1017 // Deactivate Virtual Interrupt Register
1018 case MISCREG_ICV_DIR_EL1: {
1019 int int_id = val & 0xffffff;
1020
1021 // avoid deactivation for special interrupts
1022 if (int_id >= Gicv3::INTID_SECURE &&
1023 int_id <= Gicv3::INTID_SPURIOUS) {
1024 return;
1025 }
1026
1027 if (!virtualIsEOISplitMode()) {
1028 return;
1029 }
1030
1031 int lr_idx = virtualFindActive(int_id);
1032
1033 if (lr_idx < 0) {
1034 // No matching LR found
1035 virtualIncrementEOICount();
1036 } else {
1037 virtualDeactivateIRQ(lr_idx);
1038 }
1039
1040 virtualUpdate();
1041 break;
1042 }
1043
1044 // Binary Point Register 0
1045 case MISCREG_ICC_BPR0:
1046 case MISCREG_ICC_BPR0_EL1: {
1047 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
1048 return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
1049 }
1050 break;
1051 }
1052 // Binary Point Register 1
1053 case MISCREG_ICC_BPR1:
1054 case MISCREG_ICC_BPR1_EL1: {
1055 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
1056 return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
1057 }
1058
1059 val &= 0x7;
1060
1061 if (isSecureBelowEL3()) {
1062 // group == Gicv3::G1S
1063 ICC_CTLR_EL1 icc_ctlr_el1_s =
1064 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1065
1066 val = val > GIC_MIN_BPR ? val : GIC_MIN_BPR;
1067 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
1068 isa->setMiscRegNoEffect(MISCREG_ICC_BPR0_EL1, val);
1069 } else {
1070 isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S, val);
1071 }
1072 return;
1073 } else {
1074 // group == Gicv3::G1NS
1075 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1076 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1077
1078 val = val > GIC_MIN_BPR_NS ? val : GIC_MIN_BPR_NS;
1079 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
1080 // Non secure writes from EL1 and EL2 are ignored
1081 } else {
1082 isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS, val);
1083 }
1084 return;
1085 }
1086
1087 break;
1088 }
1089
1090 // Virtual Binary Point Register 0
1091 case MISCREG_ICV_BPR0_EL1:
1092 // Virtual Binary Point Register 1
1093 case MISCREG_ICV_BPR1_EL1: {
1094 Gicv3::GroupId group =
1095 misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
1096 ICH_VMCR_EL2 ich_vmcr_el2 =
1097 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1098
1099 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1100 // BPR0 + 1 saturated to 7, WI
1101 return;
1102 }
1103
1104 uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
1105
1106 if (group != Gicv3::G0S) {
1107 min_VPBR++;
1108 }
1109
1110 if (val < min_VPBR) {
1111 val = min_VPBR;
1112 }
1113
1114 if (group == Gicv3::G0S) {
1115 ich_vmcr_el2.VBPR0 = val;
1116 } else {
1117 ich_vmcr_el2.VBPR1 = val;
1118 }
1119
1120 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1121 do_virtual_update = true;
1122 break;
1123 }
1124
1125 // Control Register EL1
1126 case MISCREG_ICC_CTLR:
1127 case MISCREG_ICC_CTLR_EL1: {
1128 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1129 return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
1130 }
1131
1132 /*
1133 * ExtRange is RO.
1134 * RSS is RO.
1135 * A3V is RO.
1136 * SEIS is RO.
1137 * IDbits is RO.
1138 * PRIbits is RO.
1139 */
1140 ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
1141 ICC_CTLR_EL1 icc_ctlr_el1 =
1142 readBankedMiscReg(MISCREG_ICC_CTLR_EL1);
1143
1144 ICC_CTLR_EL3 icc_ctlr_el3 =
1145 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1146
1147 // The following could be refactored but it is following
1148 // spec description section 9.2.6 point by point.
1149
1150 // PMHE
1151 if (haveEL(EL3)) {
1152 // PMHE is alias of ICC_CTLR_EL3.PMHE
1153
1154 if (distributor->DS == 0) {
1155 // PMHE is RO
1156 } else if (distributor->DS == 1) {
1157 // PMHE is RW
1158 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1159 icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
1160 }
1161 } else {
1162 // PMHE is RW (by implementation choice)
1163 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1164 }
1165
1166 // EOImode
1167 icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
1168
1169 if (inSecureState()) {
1170 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
1171 icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
1172 } else {
1173 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
1174 icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
1175 }
1176
1177 // CBPR
1178 if (haveEL(EL3)) {
1179 // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
1180
1181 if (distributor->DS == 0) {
1182 // CBPR is RO
1183 } else {
1184 // CBPR is RW
1185 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1186
1187 if (inSecureState()) {
1188 icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
1189 } else {
1190 icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
1191 }
1192 }
1193 } else {
1194 // CBPR is RW
1195 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1196 }
1197
1198 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
1199
1200 setBankedMiscReg(MISCREG_ICC_CTLR_EL1, icc_ctlr_el1);
1201 return;
1202 }
1203
1204 // Virtual Control Register
1205 case MISCREG_ICV_CTLR_EL1: {
1206 ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
1207 ICV_CTLR_EL1 icv_ctlr_el1 =
1208 isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
1209 icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
1210 icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
1211 val = icv_ctlr_el1;
1212
1213 // Aliases
1214 // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
1215 // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
1216 ICH_VMCR_EL2 ich_vmcr_el2 =
1217 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1218 ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
1219 ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
1220 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1221 break;
1222 }
1223
1224 // Control Register EL3
1225 case MISCREG_ICC_MCTLR:
1226 case MISCREG_ICC_CTLR_EL3: {
1227 /*
1228 * ExtRange is RO.
1229 * RSS is RO.
1230 * nDS is RO.
1231 * A3V is RO.
1232 * SEIS is RO.
1233 * IDbits is RO.
1234 * PRIbits is RO.
1235 * PMHE is RAO/WI, priority-based routing is always used.
1236 */
1237 ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
1238
1239 // Aliases
1240 if (haveEL(EL3))
1241 {
1242 ICC_CTLR_EL1 icc_ctlr_el1_s =
1243 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1244 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1245 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1246
1247 // ICC_CTLR_EL1(NS).EOImode is an alias of
1248 // ICC_CTLR_EL3.EOImode_EL1NS
1249 icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
1250 // ICC_CTLR_EL1(S).EOImode is an alias of
1251 // ICC_CTLR_EL3.EOImode_EL1S
1252 icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
1253 // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
1254 icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
1255 // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
1256 icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
1257
1258 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
1259 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
1260 icc_ctlr_el1_ns);
1261 }
1262
1263 ICC_CTLR_EL3 icc_ctlr_el3 =
1264 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1265
1266 icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
1267 icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
1268 icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
1269 icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
1270 icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
1271 icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
1272
1273 val = icc_ctlr_el3;
1274 break;
1275 }
1276
1277 // Priority Mask Register
1278 case MISCREG_ICC_PMR:
1279 case MISCREG_ICC_PMR_EL1: {
1280 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1281 return setMiscReg(MISCREG_ICV_PMR_EL1, val);
1282 }
1283
1284 val &= 0xff;
1285 SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
1286
1287 if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
1288 // Spec section 4.8.1
1289 // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
1290 RegVal old_icc_pmr_el1 =
1291 isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
1292
1293 if (!(old_icc_pmr_el1 & 0x80)) {
1294 // If the current priority mask value is in the range of
1295 // 0x00-0x7F then WI
1296 return;
1297 }
1298
1299 // If the current priority mask value is in the range of
1300 // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
1301 // based on the Non-secure read of the priority mask value
1302 // written to the register.
1303
1304 val = (val >> 1) | 0x80;
1305 }
1306
1307 val &= ~0U << (8 - PRIORITY_BITS);
1308 break;
1309 }
1310
1311 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
1312 ICH_VMCR_EL2 ich_vmcr_el2 =
1313 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1314 ich_vmcr_el2.VPMR = val & 0xff;
1315
1316 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1317 virtualUpdate();
1318 return;
1319 }
1320
1321 // Interrupt Group 0 Enable Register EL1
1322 case MISCREG_ICC_IGRPEN0:
1323 case MISCREG_ICC_IGRPEN0_EL1: {
1324 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
1325 return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
1326 }
1327
1328 isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1, val);
1329 updateDistributor();
1330 return;
1331 }
1332
1333 // Virtual Interrupt Group 0 Enable register
1334 case MISCREG_ICV_IGRPEN0_EL1: {
1335 bool enable = val & 0x1;
1336 ICH_VMCR_EL2 ich_vmcr_el2 =
1337 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1338 ich_vmcr_el2.VENG0 = enable;
1339 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1340 virtualUpdate();
1341 return;
1342 }
1343
1344 // Interrupt Group 1 Enable register EL1
1345 case MISCREG_ICC_IGRPEN1:
1346 case MISCREG_ICC_IGRPEN1_EL1: {
1347 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
1348 return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
1349 }
1350
1351 setBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1, val);
1352 updateDistributor();
1353 return;
1354 }
1355
1356 // Virtual Interrupt Group 1 Enable register
1357 case MISCREG_ICV_IGRPEN1_EL1: {
1358 bool enable = val & 0x1;
1359 ICH_VMCR_EL2 ich_vmcr_el2 =
1360 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1361 ich_vmcr_el2.VENG1 = enable;
1362 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1363 virtualUpdate();
1364 return;
1365 }
1366
1367 // Interrupt Group 1 Enable register
1368 case MISCREG_ICC_MGRPEN1:
1369 case MISCREG_ICC_IGRPEN1_EL3: {
1370 ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
1371
1372 isa->setMiscRegNoEffect(
1373 MISCREG_ICC_IGRPEN1_EL1_S, icc_igrpen1_el3.EnableGrp1S);
1374 isa->setMiscRegNoEffect(
1375 MISCREG_ICC_IGRPEN1_EL1_NS, icc_igrpen1_el3.EnableGrp1NS);
1376 updateDistributor();
1377 return;
1378 }
1379
1380 // Software Generated Interrupt Group 0 Register
1381 case MISCREG_ICC_SGI0R:
1382 case MISCREG_ICC_SGI0R_EL1:
1383 generateSGI(val, Gicv3::G0S);
1384 break;
1385
1386 // Software Generated Interrupt Group 1 Register
1387 case MISCREG_ICC_SGI1R:
1388 case MISCREG_ICC_SGI1R_EL1: {
1389 Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
1390
1391 generateSGI(val, group);
1392 break;
1393 }
1394
1395 // Alias Software Generated Interrupt Group 1 Register
1396 case MISCREG_ICC_ASGI1R:
1397 case MISCREG_ICC_ASGI1R_EL1: {
1398 Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;
1399
1400 generateSGI(val, group);
1401 break;
1402 }
1403
1404 // System Register Enable Register EL1
1405 case MISCREG_ICC_SRE:
1406 case MISCREG_ICC_SRE_EL1:
1407 // System Register Enable Register EL2
1408 case MISCREG_ICC_HSRE:
1409 case MISCREG_ICC_SRE_EL2:
1410 // System Register Enable Register EL3
1411 case MISCREG_ICC_MSRE:
1412 case MISCREG_ICC_SRE_EL3:
1413 // All bits are RAO/WI
1414 return;
1415
1416 // Hyp Control Register
1417 case MISCREG_ICH_HCR:
1418 case MISCREG_ICH_HCR_EL2: {
1419 ICH_HCR_EL2 requested_ich_hcr_el2 = val;
1420 ICH_HCR_EL2 ich_hcr_el2 =
1421 isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
1422
1423 if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
1424 {
1425 // EOIcount - Permitted behaviors are:
1426 // - Increment EOIcount.
1427 // - Leave EOIcount unchanged.
1428 ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
1429 }
1430
1431 ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
1432 ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
1433 ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
1434 ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
1435 ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
1436 ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
1437 ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
1438 ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
1439 ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
1440 ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
1441 ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
1442 ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
1443 ich_hcr_el2.En = requested_ich_hcr_el2.En;
1444 val = ich_hcr_el2;
1445 do_virtual_update = true;
1446 break;
1447 }
1448
1449 // List Registers
1450 case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
1451 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
1452 ICH_LRC requested_ich_lrc = val;
1453 ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
1454
1455 ich_lrc.State = requested_ich_lrc.State;
1456 ich_lrc.HW = requested_ich_lrc.HW;
1457 ich_lrc.Group = requested_ich_lrc.Group;
1458
1459 // Priority, bits [23:16]
1460 // At least five bits must be implemented.
1461 // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
1462 // We implement 5 bits.
1463 ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
1464 (ich_lrc.Priority & 0x07);
1465
1466 // pINTID, bits [12:0]
1467 // When ICH_LR<n>.HW is 0 this field has the following meaning:
1468 // - Bits[12:10] : RES0.
1469 // - Bit[9] : EOI.
1470 // - Bits[8:0] : RES0.
1471 // When ICH_LR<n>.HW is 1:
1472 // - This field is only required to implement enough bits to hold a
1473 // valid value for the implemented INTID size. Any unused higher
1474 // order bits are RES0.
1475 if (requested_ich_lrc.HW == 0) {
1476 ich_lrc.EOI = requested_ich_lrc.EOI;
1477 } else {
1478 ich_lrc.pINTID = requested_ich_lrc.pINTID;
1479 }
1480
1481 val = ich_lrc;
1482 do_virtual_update = true;
1483 break;
1484 }
1485
1486 // List Registers
1487 case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
1488 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
1489 RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
1490 val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
1491 do_virtual_update = true;
1492 break;
1493 }
1494
1495 // List Registers
1496 case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
1497 ICH_LR_EL2 requested_ich_lr_el2 = val;
1498 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
1499
1500 ich_lr_el2.State = requested_ich_lr_el2.State;
1501 ich_lr_el2.HW = requested_ich_lr_el2.HW;
1502 ich_lr_el2.Group = requested_ich_lr_el2.Group;
1503
1504 // Priority, bits [55:48]
1505 // At least five bits must be implemented.
1506 // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
1507 // We implement 5 bits.
1508 ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
1509 (ich_lr_el2.Priority & 0x07);
1510
1511 // pINTID, bits [44:32]
1512 // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
1513 // - Bits[44:42] : RES0.
1514 // - Bit[41] : EOI.
1515 // - Bits[40:32] : RES0.
1516 // When ICH_LR<n>_EL2.HW is 1:
1517 // - This field is only required to implement enough bits to hold a
1518 // valid value for the implemented INTID size. Any unused higher
1519 // order bits are RES0.
1520 if (requested_ich_lr_el2.HW == 0) {
1521 ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
1522 } else {
1523 ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
1524 }
1525
1526 // vINTID, bits [31:0]
1527 // It is IMPLEMENTATION DEFINED how many bits are implemented,
1528 // though at least 16 bits must be implemented.
1529 // Unimplemented bits are RES0.
1530 ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
1531
1532 val = ich_lr_el2;
1533 do_virtual_update = true;
1534 break;
1535 }
1536
1537 // Virtual Machine Control Register
1538 case MISCREG_ICH_VMCR:
1539 case MISCREG_ICH_VMCR_EL2: {
1540 ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
1541 ICH_VMCR_EL2 ich_vmcr_el2 =
1542 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1543 ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
1544 uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
1545
1546 if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
1547 ich_vmcr_el2.VBPR0 = min_vpr0;
1548 } else {
1549 ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
1550 }
1551
1552 uint8_t min_vpr1 = min_vpr0 + 1;
1553
1554 if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
1555 ich_vmcr_el2.VBPR1 = min_vpr1;
1556 } else {
1557 ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
1558 }
1559
1560 ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
1561 ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
1562 ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
1563 ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
1564 val = ich_vmcr_el2;
1565 break;
1566 }
1567
1568 // Hyp Active Priorities Group 0 Registers
1569 case MISCREG_ICH_AP0R0:
1570 case MISCREG_ICH_AP0R0_EL2:
1571 break;
1572
1573 // only implemented if supporting 6 or more bits of priority
1574 case MISCREG_ICH_AP0R1:
1575 case MISCREG_ICH_AP0R1_EL2:
1576 // only implemented if supporting 7 or more bits of priority
1577 case MISCREG_ICH_AP0R2:
1578 case MISCREG_ICH_AP0R2_EL2:
1579 // only implemented if supporting 7 or more bits of priority
1580 case MISCREG_ICH_AP0R3:
1581 case MISCREG_ICH_AP0R3_EL2:
1582 // Unimplemented registers are RAZ/WI
1583 return;
1584
1585 // Hyp Active Priorities Group 1 Registers
1586 case MISCREG_ICH_AP1R0:
1587 case MISCREG_ICH_AP1R0_EL2:
1588 break;
1589
1590 // only implemented if supporting 6 or more bits of priority
1591 case MISCREG_ICH_AP1R1:
1592 case MISCREG_ICH_AP1R1_EL2:
1593 // only implemented if supporting 7 or more bits of priority
1594 case MISCREG_ICH_AP1R2:
1595 case MISCREG_ICH_AP1R2_EL2:
1596 // only implemented if supporting 7 or more bits of priority
1597 case MISCREG_ICH_AP1R3:
1598 case MISCREG_ICH_AP1R3_EL2:
1599 // Unimplemented registers are RAZ/WI
1600 return;
1601
1602 default:
1603 panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
1604 misc_reg, miscRegName[misc_reg]);
1605 }
1606
1607 isa->setMiscRegNoEffect(misc_reg, val);
1608
1609 if (do_virtual_update) {
1610 virtualUpdate();
1611 }
1612 }
1613
1614 RegVal
1615 Gicv3CPUInterface::readBankedMiscReg(MiscRegIndex misc_reg) const
1616 {
1617 return isa->readMiscRegNoEffect(
1618 isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()));
1619 }
1620
1621 void
1622 Gicv3CPUInterface::setBankedMiscReg(MiscRegIndex misc_reg, RegVal val) const
1623 {
1624 isa->setMiscRegNoEffect(
1625 isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()), val);
1626 }
1627
1628 int
1629 Gicv3CPUInterface::virtualFindActive(uint32_t int_id) const
1630 {
1631 for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
1632 ICH_LR_EL2 ich_lr_el2 =
1633 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
1634
1635 if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
1636 (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
1637 (ich_lr_el2.vINTID == int_id)) {
1638 return lr_idx;
1639 }
1640 }
1641
1642 return -1;
1643 }
1644
1645 uint32_t
1646 Gicv3CPUInterface::getHPPIR0() const
1647 {
1648 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1649 return Gicv3::INTID_SPURIOUS;
1650 }
1651
1652 bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
1653
1654 if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
1655 // interrupt for the other state pending
1656 return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
1657 }
1658
1659 if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
1660 return Gicv3::INTID_SPURIOUS;
1661 }
1662
1663 if (irq_is_secure && !inSecureState()) {
1664 // Secure interrupts not visible in Non-secure
1665 return Gicv3::INTID_SPURIOUS;
1666 }
1667
1668 return hppi.intid;
1669 }
1670
1671 uint32_t
1672 Gicv3CPUInterface::getHPPIR1() const
1673 {
1674 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1675 return Gicv3::INTID_SPURIOUS;
1676 }
1677
1678 ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1679 if ((currEL() == EL3) && icc_ctlr_el3.RM) {
1680 if (hppi.group == Gicv3::G0S) {
1681 return Gicv3::INTID_SECURE;
1682 } else if (hppi.group == Gicv3::G1NS) {
1683 return Gicv3::INTID_NONSECURE;
1684 }
1685 }
1686
1687 if (hppi.group == Gicv3::G0S) {
1688 return Gicv3::INTID_SPURIOUS;
1689 }
1690
1691 bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
1692
1693 if (irq_is_secure) {
1694 if (!inSecureState()) {
1695 // Secure interrupts not visible in Non-secure
1696 return Gicv3::INTID_SPURIOUS;
1697 }
1698 } else if (!isEL3OrMon() && inSecureState()) {
1699 // Group 1 non-secure interrupts not visible in Secure EL1
1700 return Gicv3::INTID_SPURIOUS;
1701 }
1702
1703 return hppi.intid;
1704 }
1705
1706 void
1707 Gicv3CPUInterface::dropPriority(Gicv3::GroupId group)
1708 {
1709 int apr_misc_reg = 0;
1710
1711 switch (group) {
1712 case Gicv3::G0S:
1713 apr_misc_reg = MISCREG_ICC_AP0R0_EL1;
1714 break;
1715 case Gicv3::G1S:
1716 apr_misc_reg = MISCREG_ICC_AP1R0_EL1_S;
1717 break;
1718 case Gicv3::G1NS:
1719 apr_misc_reg = MISCREG_ICC_AP1R0_EL1_NS;
1720 break;
1721 default:
1722 panic("Invalid Gicv3::GroupId");
1723 }
1724
1725 RegVal apr = isa->readMiscRegNoEffect(apr_misc_reg);
1726
1727 if (apr) {
1728 apr &= apr - 1;
1729 isa->setMiscRegNoEffect(apr_misc_reg, apr);
1730 }
1731
1732 update();
1733 }
1734
1735 uint8_t
1736 Gicv3CPUInterface::virtualDropPriority()
1737 {
1738 int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
1739
1740 for (int i = 0; i < apr_max; i++) {
1741 RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
1742 RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
1743
1744 if (!vapr0 && !vapr1) {
1745 continue;
1746 }
1747
1748 int vapr0_count = ctz32(vapr0);
1749 int vapr1_count = ctz32(vapr1);
1750
1751 if (vapr0_count <= vapr1_count) {
1752 vapr0 &= vapr0 - 1;
1753 isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
1754 return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
1755 } else {
1756 vapr1 &= vapr1 - 1;
1757 isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
1758 return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
1759 }
1760 }
1761
1762 return 0xff;
1763 }
1764
1765 void
1766 Gicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
1767 {
1768 uint8_t aff3 = bits(val, 55, 48);
1769 uint8_t aff2 = bits(val, 39, 32);
1770 uint8_t aff1 = bits(val, 23, 16);;
1771 uint16_t target_list = bits(val, 15, 0);
1772 uint32_t int_id = bits(val, 27, 24);
1773 bool irm = bits(val, 40, 40);
1774 uint8_t rs = bits(val, 47, 44);
1775
1776 bool ns = !inSecureState();
1777
1778 for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
1779 Gicv3Redistributor * redistributor_i =
1780 gic->getRedistributor(i);
1781 uint32_t affinity_i = redistributor_i->getAffinity();
1782
1783 if (irm) {
1784 // Interrupts routed to all PEs in the system,
1785 // excluding "self"
1786 if (affinity_i == redistributor->getAffinity()) {
1787 continue;
1788 }
1789 } else {
1790 // Interrupts routed to the PEs specified by
1791 // Aff3.Aff2.Aff1.<target list>
1792 if ((affinity_i >> 8) !=
1793 ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
1794 continue;
1795 }
1796
1797 uint8_t aff0_i = bits(affinity_i, 7, 0);
1798
1799 if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
1800 ((0x1 << (aff0_i - rs * 16)) & target_list))) {
1801 continue;
1802 }
1803 }
1804
1805 redistributor_i->sendSGI(int_id, group, ns);
1806 }
1807 }
1808
1809 void
1810 Gicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
1811 {
1812 // Update active priority registers.
1813 uint32_t prio = hppi.prio & 0xf8;
1814 int apr_bit = prio >> (8 - PRIORITY_BITS);
1815 int reg_bit = apr_bit % 32;
1816
1817 int apr_idx = 0;
1818 switch (group) {
1819 case Gicv3::G0S:
1820 apr_idx = MISCREG_ICC_AP0R0_EL1;
1821 break;
1822 case Gicv3::G1S:
1823 apr_idx = MISCREG_ICC_AP1R0_EL1_S;
1824 break;
1825 case Gicv3::G1NS:
1826 apr_idx = MISCREG_ICC_AP1R0_EL1_NS;
1827 break;
1828 default:
1829 panic("Invalid Gicv3::GroupId");
1830 }
1831
1832 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1833 apr |= (1 << reg_bit);
1834 isa->setMiscRegNoEffect(apr_idx, apr);
1835
1836 // Move interrupt state from pending to active.
1837 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1838 // SGI or PPI, redistributor
1839 redistributor->activateIRQ(int_id);
1840 } else if (int_id < Gicv3::INTID_SECURE) {
1841 // SPI, distributor
1842 distributor->activateIRQ(int_id);
1843 } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
1844 // LPI, Redistributor
1845 redistributor->setClrLPI(int_id, false);
1846 }
1847
1848 // By setting the priority to 0xff we are effectively
1849 // making the int_id not pending anymore at the cpu
1850 // interface.
1851 resetHppi(int_id);
1852 updateDistributor();
1853 }
1854
1855 void
1856 Gicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
1857 {
1858 // Update active priority registers.
1859 ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1860 lr_idx);
1861 Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
1862 uint8_t prio = ich_lr_el.Priority & 0xf8;
1863 int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
1864 int reg_no = apr_bit / 32;
1865 int reg_bit = apr_bit % 32;
1866 int apr_idx = group == Gicv3::G0S ?
1867 MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
1868 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1869 apr |= (1 << reg_bit);
1870 isa->setMiscRegNoEffect(apr_idx, apr);
1871 // Move interrupt state from pending to active.
1872 ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
1873 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
1874 }
1875
1876 void
1877 Gicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
1878 {
1879 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1880 // SGI or PPI, redistributor
1881 redistributor->deactivateIRQ(int_id);
1882 } else if (int_id < Gicv3::INTID_SECURE) {
1883 // SPI, distributor
1884 distributor->deactivateIRQ(int_id);
1885 }
1886
1887 updateDistributor();
1888 }
1889
1890 void
1891 Gicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
1892 {
1893 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1894 lr_idx);
1895
1896 if (ich_lr_el2.HW) {
1897 // Deactivate the associated physical interrupt
1898 if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
1899 Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
1900 distributor->getIntGroup(ich_lr_el2.pINTID) :
1901 redistributor->getIntGroup(ich_lr_el2.pINTID);
1902 deactivateIRQ(ich_lr_el2.pINTID, group);
1903 }
1904 }
1905
1906 // Remove the active bit
1907 ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
1908 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
1909 }
1910
1911 /*
1912 * Returns the priority group field for the current BPR value for the group.
1913 * GroupBits() Pseudocode from spec.
1914 */
1915 uint32_t
1916 Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
1917 {
1918 ICC_CTLR_EL1 icc_ctlr_el1_s =
1919 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1920 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1921 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1922
1923 if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
1924 (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
1925 group = Gicv3::G0S;
1926 }
1927
1928 int bpr;
1929
1930 if (group == Gicv3::G0S) {
1931 bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
1932 } else if (group == Gicv3::G1S) {
1933 bpr = bpr1(Gicv3::G1S) & 0x7;
1934 } else {
1935 bpr = bpr1(Gicv3::G1NS) & 0x7;
1936 }
1937
1938 if (group == Gicv3::G1NS) {
1939 assert(bpr > 0);
1940 bpr--;
1941 }
1942
1943 return ~0U << (bpr + 1);
1944 }
1945
1946 uint32_t
1947 Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
1948 {
1949 ICH_VMCR_EL2 ich_vmcr_el2 =
1950 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1951
1952 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1953 group = Gicv3::G0S;
1954 }
1955
1956 int bpr;
1957
1958 if (group == Gicv3::G0S) {
1959 bpr = ich_vmcr_el2.VBPR0;
1960 } else {
1961 bpr = ich_vmcr_el2.VBPR1;
1962 }
1963
1964 if (group == Gicv3::G1NS) {
1965 assert(bpr > 0);
1966 bpr--;
1967 }
1968
1969 return ~0U << (bpr + 1);
1970 }
1971
1972 bool
1973 Gicv3CPUInterface::isEOISplitMode() const
1974 {
1975 if (isEL3OrMon()) {
1976 ICC_CTLR_EL3 icc_ctlr_el3 =
1977 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1978 return icc_ctlr_el3.EOImode_EL3;
1979 } else {
1980 ICC_CTLR_EL1 icc_ctlr_el1 = 0;
1981 if (inSecureState())
1982 icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1983 else
1984 icc_ctlr_el1 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1985 return icc_ctlr_el1.EOImode;
1986 }
1987 }
1988
1989 bool
1990 Gicv3CPUInterface::virtualIsEOISplitMode() const
1991 {
1992 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1993 return ich_vmcr_el2.VEOIM;
1994 }
1995
1996 int
1997 Gicv3CPUInterface::highestActiveGroup() const
1998 {
1999 int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
2000 int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
2001 int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
2002
2003 if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
2004 return Gicv3::G1NS;
2005 }
2006
2007 if (gq_ctz < g0_ctz) {
2008 return Gicv3::G1S;
2009 }
2010
2011 if (g0_ctz < 32) {
2012 return Gicv3::G0S;
2013 }
2014
2015 return -1;
2016 }
2017
2018 void
2019 Gicv3CPUInterface::updateDistributor()
2020 {
2021 distributor->update();
2022 }
2023
2024 void
2025 Gicv3CPUInterface::update()
2026 {
2027 bool signal_IRQ = false;
2028 bool signal_FIQ = false;
2029
2030 if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
2031 /*
2032 * Secure enabled GIC sending a G1S IRQ to a secure disabled
2033 * CPU -> send G0 IRQ
2034 */
2035 hppi.group = Gicv3::G0S;
2036 }
2037
2038 if (hppiCanPreempt()) {
2039 ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
2040 DPRINTF(GIC, "Gicv3CPUInterface::update(): "
2041 "posting int as %d!\n", int_type);
2042 int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
2043 }
2044
2045 if (signal_IRQ) {
2046 gic->postInt(cpuId, ArmISA::INT_IRQ);
2047 } else {
2048 gic->deassertInt(cpuId, ArmISA::INT_IRQ);
2049 }
2050
2051 if (signal_FIQ) {
2052 gic->postInt(cpuId, ArmISA::INT_FIQ);
2053 } else {
2054 gic->deassertInt(cpuId, ArmISA::INT_FIQ);
2055 }
2056 }
2057
2058 void
2059 Gicv3CPUInterface::virtualUpdate()
2060 {
2061 bool signal_IRQ = false;
2062 bool signal_FIQ = false;
2063 int lr_idx = getHPPVILR();
2064
2065 if (lr_idx >= 0) {
2066 ICH_LR_EL2 ich_lr_el2 =
2067 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2068
2069 if (hppviCanPreempt(lr_idx)) {
2070 if (ich_lr_el2.Group) {
2071 signal_IRQ = true;
2072 } else {
2073 signal_FIQ = true;
2074 }
2075 }
2076 }
2077
2078 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2079
2080 if (ich_hcr_el2.En) {
2081 if (maintenanceInterruptStatus()) {
2082 maintenanceInterrupt->raise();
2083 }
2084 }
2085
2086 if (signal_IRQ) {
2087 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2088 "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
2089 gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
2090 } else {
2091 gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
2092 }
2093
2094 if (signal_FIQ) {
2095 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2096 "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
2097 gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
2098 } else {
2099 gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
2100 }
2101 }
2102
2103 // Returns the index of the LR with the HPPI
2104 int
2105 Gicv3CPUInterface::getHPPVILR() const
2106 {
2107 int idx = -1;
2108 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2109
2110 if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
2111 // VG0 and VG1 disabled...
2112 return idx;
2113 }
2114
2115 uint8_t highest_prio = 0xff;
2116
2117 for (int i = 0; i < 16; i++) {
2118 ICH_LR_EL2 ich_lr_el2 =
2119 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
2120
2121 if (ich_lr_el2.State != Gicv3::INT_PENDING) {
2122 continue;
2123 }
2124
2125 if (ich_lr_el2.Group) {
2126 // VG1
2127 if (!ich_vmcr_el2.VENG1) {
2128 continue;
2129 }
2130 } else {
2131 // VG0
2132 if (!ich_vmcr_el2.VENG0) {
2133 continue;
2134 }
2135 }
2136
2137 uint8_t prio = ich_lr_el2.Priority;
2138
2139 if (prio < highest_prio) {
2140 highest_prio = prio;
2141 idx = i;
2142 }
2143 }
2144
2145 return idx;
2146 }
2147
2148 bool
2149 Gicv3CPUInterface::hppviCanPreempt(int lr_idx) const
2150 {
2151 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2152 if (!ich_hcr_el2.En) {
2153 // virtual interface is disabled
2154 return false;
2155 }
2156
2157 ICH_LR_EL2 ich_lr_el2 =
2158 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2159 uint8_t prio = ich_lr_el2.Priority;
2160 uint8_t vpmr =
2161 bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
2162
2163 if (prio >= vpmr) {
2164 // prioriry masked
2165 return false;
2166 }
2167
2168 uint8_t rprio = virtualHighestActivePriority();
2169
2170 if (rprio == 0xff) {
2171 return true;
2172 }
2173
2174 Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
2175 uint32_t prio_mask = virtualGroupPriorityMask(group);
2176
2177 if ((prio & prio_mask) < (rprio & prio_mask)) {
2178 return true;
2179 }
2180
2181 return false;
2182 }
2183
2184 uint8_t
2185 Gicv3CPUInterface::virtualHighestActivePriority() const
2186 {
2187 uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
2188
2189 for (int i = 0; i < num_aprs; i++) {
2190 RegVal vapr =
2191 isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
2192 isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
2193
2194 if (!vapr) {
2195 continue;
2196 }
2197
2198 return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
2199 }
2200
2201 // no active interrups, return idle priority
2202 return 0xff;
2203 }
2204
2205 void
2206 Gicv3CPUInterface::virtualIncrementEOICount()
2207 {
2208 // Increment the EOICOUNT field in ICH_HCR_EL2
2209 RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2210 uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
2211 EOI_cout++;
2212 ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
2213 isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
2214 }
2215
2216 // spec section 4.6.2
2217 ArmISA::InterruptTypes
2218 Gicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
2219 {
2220 bool is_fiq = false;
2221
2222 switch (group) {
2223 case Gicv3::G0S:
2224 is_fiq = true;
2225 break;
2226
2227 case Gicv3::G1S:
2228 is_fiq = (distributor->DS == 0) &&
2229 (!inSecureState() || ((currEL() == EL3) && isAA64()));
2230 break;
2231
2232 case Gicv3::G1NS:
2233 is_fiq = (distributor->DS == 0) && inSecureState();
2234 break;
2235
2236 default:
2237 panic("Gicv3CPUInterface::intSignalType(): invalid group!");
2238 }
2239
2240 if (is_fiq) {
2241 return ArmISA::INT_FIQ;
2242 } else {
2243 return ArmISA::INT_IRQ;
2244 }
2245 }
2246
2247 bool
2248 Gicv3CPUInterface::hppiCanPreempt()
2249 {
2250 if (hppi.prio == 0xff) {
2251 // there is no pending interrupt
2252 return false;
2253 }
2254
2255 if (!groupEnabled(hppi.group)) {
2256 // group disabled at CPU interface
2257 return false;
2258 }
2259
2260 if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
2261 // priority masked
2262 return false;
2263 }
2264
2265 uint8_t rprio = highestActivePriority();
2266
2267 if (rprio == 0xff) {
2268 return true;
2269 }
2270
2271 uint32_t prio_mask = groupPriorityMask(hppi.group);
2272
2273 if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
2274 return true;
2275 }
2276
2277 return false;
2278 }
2279
2280 uint8_t
2281 Gicv3CPUInterface::highestActivePriority() const
2282 {
2283 uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
2284 isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
2285 isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
2286
2287 if (apr) {
2288 return ctz32(apr) << (GIC_MIN_BPR + 1);
2289 }
2290
2291 // no active interrups, return idle priority
2292 return 0xff;
2293 }
2294
2295 bool
2296 Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
2297 {
2298 switch (group) {
2299 case Gicv3::G0S: {
2300 ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
2301 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
2302 return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
2303 }
2304
2305 case Gicv3::G1S: {
2306 ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
2307 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
2308 return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
2309 }
2310
2311 case Gicv3::G1NS: {
2312 ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
2313 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
2314 return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
2315 }
2316
2317 default:
2318 panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
2319 }
2320 }
2321
2322 bool
2323 Gicv3CPUInterface::inSecureState() const
2324 {
2325 if (!gic->getSystem()->haveSecurity()) {
2326 return false;
2327 }
2328
2329 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2330 SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
2331 return ArmISA::inSecureState(scr, cpsr);
2332 }
2333
2334 int
2335 Gicv3CPUInterface::currEL() const
2336 {
2337 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2338 bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2339
2340 if (is_64) {
2341 return (ExceptionLevel)(uint8_t) cpsr.el;
2342 } else {
2343 switch (cpsr.mode) {
2344 case MODE_USER:
2345 return 0;
2346
2347 case MODE_HYP:
2348 return 2;
2349
2350 case MODE_MON:
2351 return 3;
2352
2353 default:
2354 return 1;
2355 }
2356 }
2357 }
2358
2359 bool
2360 Gicv3CPUInterface::haveEL(ExceptionLevel el) const
2361 {
2362 switch (el) {
2363 case EL0:
2364 case EL1:
2365 return true;
2366
2367 case EL2:
2368 return gic->getSystem()->haveVirtualization();
2369
2370 case EL3:
2371 return gic->getSystem()->haveSecurity();
2372
2373 default:
2374 warn("Unimplemented Exception Level\n");
2375 return false;
2376 }
2377 }
2378
2379 bool
2380 Gicv3CPUInterface::isSecureBelowEL3() const
2381 {
2382 SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
2383 return haveEL(EL3) && scr.ns == 0;
2384 }
2385
2386 bool
2387 Gicv3CPUInterface::isAA64() const
2388 {
2389 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2390 return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2391 }
2392
2393 bool
2394 Gicv3CPUInterface::isEL3OrMon() const
2395 {
2396 if (haveEL(EL3)) {
2397 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2398 bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2399
2400 if (is_64 && (cpsr.el == EL3)) {
2401 return true;
2402 } else if (!is_64 && (cpsr.mode == MODE_MON)) {
2403 return true;
2404 }
2405 }
2406
2407 return false;
2408 }
2409
2410 // Computes ICH_EISR_EL2
2411 uint64_t
2412 Gicv3CPUInterface::eoiMaintenanceInterruptStatus() const
2413 {
2414 // ICH_EISR_EL2
2415 // Bits [63:16] - RES0
2416 // Status<n>, bit [n], for n = 0 to 15
2417 // EOI maintenance interrupt status bit for List register <n>:
2418 // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
2419 // maintenance interrupt.
2420 // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
2421 // interrupt that has not been handled.
2422 //
2423 // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
2424 // of the following are true:
2425 // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
2426 // - ICH_LR<n>_EL2.HW is 0.
2427 // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
2428
2429 uint64_t value = 0;
2430
2431 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2432 ICH_LR_EL2 ich_lr_el2 =
2433 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2434
2435 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
2436 !ich_lr_el2.HW && ich_lr_el2.EOI) {
2437 value |= (1 << lr_idx);
2438 }
2439 }
2440
2441 return value;
2442 }
2443
2444 Gicv3CPUInterface::ICH_MISR_EL2
2445 Gicv3CPUInterface::maintenanceInterruptStatus() const
2446 {
2447 // Comments are copied from SPEC section 9.4.7 (ID012119)
2448 ICH_MISR_EL2 ich_misr_el2 = 0;
2449 ICH_HCR_EL2 ich_hcr_el2 =
2450 isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2451 ICH_VMCR_EL2 ich_vmcr_el2 =
2452 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2453
2454 // End Of Interrupt. [bit 0]
2455 // This maintenance interrupt is asserted when at least one bit in
2456 // ICH_EISR_EL2 is 1.
2457
2458 if (eoiMaintenanceInterruptStatus()) {
2459 ich_misr_el2.EOI = 1;
2460 }
2461
2462 // Underflow. [bit 1]
2463 // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
2464 // zero or one of the List register entries are marked as a valid
2465 // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
2466 // do not equal 0x0.
2467 uint32_t num_valid_interrupts = 0;
2468 uint32_t num_pending_interrupts = 0;
2469
2470 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2471 ICH_LR_EL2 ich_lr_el2 =
2472 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2473
2474 if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
2475 num_valid_interrupts++;
2476 }
2477
2478 if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
2479 num_pending_interrupts++;
2480 }
2481 }
2482
2483 if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
2484 ich_misr_el2.U = 1;
2485 }
2486
2487 // List Register Entry Not Present. [bit 2]
2488 // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
2489 // and ICH_HCR_EL2.EOIcount is non-zero.
2490 if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
2491 ich_misr_el2.LRENP = 1;
2492 }
2493
2494 // No Pending. [bit 3]
2495 // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
2496 // no List register is in pending state.
2497 if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
2498 ich_misr_el2.NP = 1;
2499 }
2500
2501 // vPE Group 0 Enabled. [bit 4]
2502 // This maintenance interrupt is asserted when
2503 // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
2504 if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
2505 ich_misr_el2.VGrp0E = 1;
2506 }
2507
2508 // vPE Group 0 Disabled. [bit 5]
2509 // This maintenance interrupt is asserted when
2510 // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
2511 if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
2512 ich_misr_el2.VGrp0D = 1;
2513 }
2514
2515 // vPE Group 1 Enabled. [bit 6]
2516 // This maintenance interrupt is asserted when
2517 // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
2518 if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
2519 ich_misr_el2.VGrp1E = 1;
2520 }
2521
2522 // vPE Group 1 Disabled. [bit 7]
2523 // This maintenance interrupt is asserted when
2524 // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
2525 if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
2526 ich_misr_el2.VGrp1D = 1;
2527 }
2528
2529 return ich_misr_el2;
2530 }
2531
2532 RegVal
2533 Gicv3CPUInterface::bpr1(Gicv3::GroupId group)
2534 {
2535 bool hcr_imo = getHCREL2IMO();
2536 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
2537 return readMiscReg(MISCREG_ICV_BPR1_EL1);
2538 }
2539
2540 RegVal bpr = 0;
2541
2542 if (group == Gicv3::G1S) {
2543 ICC_CTLR_EL1 icc_ctlr_el1_s =
2544 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
2545
2546 if (!isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
2547 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
2548 } else {
2549 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S);
2550 bpr = bpr > GIC_MIN_BPR ? bpr : GIC_MIN_BPR;
2551 }
2552 } else if (group == Gicv3::G1NS) {
2553 ICC_CTLR_EL1 icc_ctlr_el1_ns =
2554 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
2555
2556 // Check if EL3 is implemented and this is a non secure accesses at
2557 // EL1 and EL2
2558 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
2559 // Reads return BPR0 + 1 saturated to 7, WI
2560 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) + 1;
2561 bpr = bpr < 7 ? bpr : 7;
2562 } else {
2563 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS);
2564 bpr = bpr > GIC_MIN_BPR_NS ? bpr : GIC_MIN_BPR_NS;
2565 }
2566 } else {
2567 panic("Should be used with G1S and G1NS only\n");
2568 }
2569
2570 return bpr;
2571 }
2572
2573 void
2574 Gicv3CPUInterface::serialize(CheckpointOut & cp) const
2575 {
2576 SERIALIZE_SCALAR(hppi.intid);
2577 SERIALIZE_SCALAR(hppi.prio);
2578 SERIALIZE_ENUM(hppi.group);
2579 }
2580
2581 void
2582 Gicv3CPUInterface::unserialize(CheckpointIn & cp)
2583 {
2584 UNSERIALIZE_SCALAR(hppi.intid);
2585 UNSERIALIZE_SCALAR(hppi.prio);
2586 UNSERIALIZE_ENUM(hppi.group);
2587 }