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