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