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