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