45 #include "debug/GIC.hh"
53 using namespace ArmISA;
61 redistributor(nullptr),
88 "Invalid maintenance interrupt number\n");
96 if (hcr.tge && hcr.e2h) {
110 if (hcr.tge && hcr.e2h) {
112 }
else if (hcr.tge) {
184 ICH_VMCR_EL2 ich_vmcr_el2 =
186 value = ich_vmcr_el2.VENG0;
202 ICH_VMCR_EL2 ich_vmcr_el2 =
204 value = ich_vmcr_el2.VENG1;
211 ICC_IGRPEN1_EL3 igrp_el3 = 0;
226 (hcr_imo || hcr_fmo)) {
236 if ((rprio & 0x80) == 0) {
240 }
else if (rprio != 0xff) {
244 rprio = (rprio << 1) & 0xff;
275 ICH_LR_EL2 ich_lr_el2 =
281 value = ich_lr_el2.vINTID;
305 ICH_LR_EL2 ich_lr_el2 =
311 value = ich_lr_el2.vINTID;
338 ICH_VMCR_EL2 ich_vmcr_el2 =
341 value = ich_vmcr_el2.VBPR0;
347 ICH_VMCR_EL2 ich_vmcr_el2 =
350 if (ich_vmcr_el2.VCBPR) {
352 value = ich_vmcr_el2.VBPR0 + 1;
353 value = value < 7 ? value : 7;
355 value = ich_vmcr_el2.VBPR1;
372 if ((value & 0x80) == 0) {
376 }
else if (value != 0xff) {
380 value = (value << 1) & 0xff;
387 ICH_VMCR_EL2 ich_vmcr_el2 =
390 value = ich_vmcr_el2.VPMR;
425 ICH_LR_EL2 ich_lr_el2 =
429 int_id = ich_lr_el2.vINTID;
438 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
481 ICH_LR_EL2 ich_lr_el2 =
485 int_id = ich_lr_el2.vINTID;
494 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
514 ICC_SRE_EL1 icc_sre_el1 = 0;
532 ICC_SRE_EL2 icc_sre_el2 = 0;
536 icc_sre_el2.Enable = 1;
553 ICC_SRE_EL3 icc_sre_el3 = 0;
557 icc_sre_el3.Enable = 1;
578 ICC_CTLR_EL1 icc_ctlr_el1 = value;
579 icc_ctlr_el1.ExtRange = 0;
580 icc_ctlr_el1.RSS = 1;
581 icc_ctlr_el1.A3V = 1;
582 icc_ctlr_el1.SEIS = 0;
583 icc_ctlr_el1.IDbits = 1;
584 icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
585 value = icc_ctlr_el1;
591 ICV_CTLR_EL1 icv_ctlr_el1 = value;
592 icv_ctlr_el1.RSS = 0;
593 icv_ctlr_el1.A3V = 1;
594 icv_ctlr_el1.SEIS = 0;
595 icv_ctlr_el1.IDbits = 1;
596 icv_ctlr_el1.PRIbits = 7;
597 value = icv_ctlr_el1;
613 ICC_CTLR_EL3 icc_ctlr_el3 = value;
614 icc_ctlr_el3.ExtRange = 0;
615 icc_ctlr_el3.RSS = 1;
616 icc_ctlr_el3.nDS = 0;
617 icc_ctlr_el3.A3V = 1;
618 icc_ctlr_el3.SEIS = 0;
619 icc_ctlr_el3.IDbits = 0;
620 icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
621 value = icc_ctlr_el3;
673 ICH_VTR_EL2 ich_vtr_el2 = value;
677 ich_vtr_el2.IDbits = 1;
697 ICH_LR_EL2 ich_lr_el2 =
700 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
701 (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
702 value |= (1 << lr_idx);
717 value = value & 0xffffffff;
730 panic(
"Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
734 DPRINTF(GIC,
"Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
742 bool do_virtual_update =
false;
743 DPRINTF(GIC,
"Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
801 int int_id =
val & 0xffffff;
826 int int_id =
val & 0xffffff;
836 if (drop_prio == 0xff) {
846 ICH_LR_EL2 ich_lr_el2 =
850 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
852 if (lr_group ==
Gicv3::G0S && lr_group_prio == drop_prio) {
871 int int_id =
val & 0xffffff;
905 int int_id =
val & 0xffffff;
915 if (drop_prio == 0xff) {
925 ICH_LR_EL2 ich_lr_el2 =
929 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
931 if (lr_group ==
Gicv3::G1NS && lr_group_prio == drop_prio) {
946 (hcr_imo || hcr_fmo)) {
950 int int_id =
val & 0xffffff;
970 bool irq_is_secure = !single_sec_state && (group !=
Gicv3::G1NS);
972 bool route_fiq_to_el3 = scr_el3.fiq;
973 bool route_irq_to_el3 = scr_el3.irq;
974 bool route_fiq_to_el2 = hcr_fmo;
975 bool route_irq_to_el2 = hcr_imo;
982 if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
986 if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
994 if (single_sec_state && irq_is_grp0 &&
995 !route_fiq_to_el3 && !route_fiq_to_el2) {
999 if (!irq_is_secure && !irq_is_grp0 &&
1000 !route_irq_to_el3 && !route_irq_to_el2) {
1004 if (irq_is_grp0 && !route_fiq_to_el3) {
1009 (!irq_is_secure || !single_sec_state) &&
1010 !route_irq_to_el3) {
1027 int int_id =
val & 0xffffff;
1071 ICC_CTLR_EL1 icc_ctlr_el1_s =
1083 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1104 ICH_VMCR_EL2 ich_vmcr_el2 =
1107 if ((group ==
Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1118 if (
val < min_VPBR) {
1123 ich_vmcr_el2.VBPR0 =
val;
1125 ich_vmcr_el2.VBPR1 =
val;
1129 do_virtual_update =
true;
1148 ICC_CTLR_EL1 requested_icc_ctlr_el1 =
val;
1149 ICC_CTLR_EL1 icc_ctlr_el1 =
1152 ICC_CTLR_EL3 icc_ctlr_el3 =
1166 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1167 icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
1171 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1175 icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
1179 icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
1182 icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
1193 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1196 icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
1198 icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
1203 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1214 ICV_CTLR_EL1 requested_icv_ctlr_el1 =
val;
1215 ICV_CTLR_EL1 icv_ctlr_el1 =
1217 icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
1218 icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
1224 ICH_VMCR_EL2 ich_vmcr_el2 =
1226 ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
1227 ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
1245 ICC_CTLR_EL3 requested_icc_ctlr_el3 =
val;
1250 ICC_CTLR_EL1 icc_ctlr_el1_s =
1252 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1257 icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
1260 icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
1262 icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
1264 icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
1271 ICC_CTLR_EL3 icc_ctlr_el3 =
1274 icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
1275 icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
1276 icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
1277 icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
1278 icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
1279 icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
1301 if (!(old_icc_pmr_el1 & 0x80)) {
1315 val &= ~0
U << (8 - PRIORITY_BITS);
1320 ICH_VMCR_EL2 ich_vmcr_el2 =
1322 ich_vmcr_el2.VPMR =
val & 0xff;
1344 ICH_VMCR_EL2 ich_vmcr_el2 =
1346 ich_vmcr_el2.VENG0 =
enable;
1367 ICH_VMCR_EL2 ich_vmcr_el2 =
1369 ich_vmcr_el2.VENG1 =
enable;
1378 ICC_IGRPEN1_EL3 icc_igrpen1_el3 =
val;
1427 ICH_HCR_EL2 requested_ich_hcr_el2 =
val;
1428 ICH_HCR_EL2 ich_hcr_el2 =
1431 if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
1436 ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
1439 ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
1440 ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
1441 ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
1442 ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
1443 ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
1444 ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
1445 ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
1446 ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
1447 ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
1448 ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
1449 ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
1450 ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
1451 ich_hcr_el2.En = requested_ich_hcr_el2.En;
1453 do_virtual_update =
true;
1460 ICH_LRC requested_ich_lrc =
val;
1463 ich_lrc.State = requested_ich_lrc.State;
1464 ich_lrc.HW = requested_ich_lrc.HW;
1465 ich_lrc.Group = requested_ich_lrc.Group;
1471 ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
1472 (ich_lrc.Priority & 0x07);
1483 if (requested_ich_lrc.HW == 0) {
1484 ich_lrc.EOI = requested_ich_lrc.EOI;
1486 ich_lrc.pINTID = requested_ich_lrc.pINTID;
1490 do_virtual_update =
true;
1498 val = (old_val & 0xffffffff00000000) | (
val & 0xffffffff);
1499 do_virtual_update =
true;
1505 ICH_LR_EL2 requested_ich_lr_el2 =
val;
1508 ich_lr_el2.State = requested_ich_lr_el2.State;
1509 ich_lr_el2.HW = requested_ich_lr_el2.HW;
1510 ich_lr_el2.Group = requested_ich_lr_el2.Group;
1516 ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
1517 (ich_lr_el2.Priority & 0x07);
1528 if (requested_ich_lr_el2.HW == 0) {
1529 ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
1531 ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
1538 ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
1541 do_virtual_update =
true;
1548 ICH_VMCR_EL2 requested_ich_vmcr_el2 =
val;
1549 ICH_VMCR_EL2 ich_vmcr_el2 =
1551 ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
1554 if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
1555 ich_vmcr_el2.VBPR0 = min_vpr0;
1557 ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
1560 uint8_t min_vpr1 = min_vpr0 + 1;
1562 if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
1563 ich_vmcr_el2.VBPR1 = min_vpr1;
1565 ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
1568 ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
1569 ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
1570 ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
1571 ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
1611 panic(
"Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
1617 if (do_virtual_update) {
1640 ICH_LR_EL2 ich_lr_el2 =
1645 (ich_lr_el2.vINTID == int_id)) {
1687 if ((
currEL() ==
EL3) && icc_ctlr_el3.RM) {
1701 if (irq_is_secure) {
1717 int apr_misc_reg = 0;
1730 panic(
"Invalid Gicv3::GroupId");
1748 for (
int i = 0;
i < apr_max;
i++) {
1752 if (!vapr0 && !vapr1) {
1756 int vapr0_count =
ctz32(vapr0);
1757 int vapr1_count =
ctz32(vapr1);
1759 if (vapr0_count <= vapr1_count) {
1779 uint16_t target_list =
bits(
val, 15, 0);
1780 uint32_t int_id =
bits(
val, 27, 24);
1789 uint32_t affinity_i = redistributor_i->
getAffinity();
1800 if ((affinity_i >> 8) !=
1805 uint8_t aff0_i =
bits(affinity_i, 7, 0);
1807 if (!(aff0_i >=
rs * 16 && aff0_i < (
rs + 1) * 16 &&
1808 ((0x1 << (aff0_i -
rs * 16)) & target_list))) {
1813 redistributor_i->
sendSGI(int_id, group,
ns);
1818 Gicv3CPUInterface::activateIRQ(uint32_t int_id,
Gicv3::GroupId group)
1822 int apr_bit = prio >> (8 - PRIORITY_BITS);
1823 int reg_bit = apr_bit % 32;
1837 panic(
"Invalid Gicv3::GroupId");
1841 apr |= (1 << reg_bit);
1870 uint8_t prio = ich_lr_el.Priority & 0xf8;
1872 int reg_no = apr_bit / 32;
1873 int reg_bit = apr_bit % 32;
1877 apr |= (1 << reg_bit);
1904 if (ich_lr_el2.HW) {
1926 ICC_CTLR_EL1 icc_ctlr_el1_s =
1928 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1931 if ((group ==
Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
1951 return ~0
U << (bpr + 1);
1957 ICH_VMCR_EL2 ich_vmcr_el2 =
1960 if ((group ==
Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1967 bpr = ich_vmcr_el2.VBPR0;
1969 bpr = ich_vmcr_el2.VBPR1;
1977 return ~0
U << (bpr + 1);
1984 ICC_CTLR_EL3 icc_ctlr_el3 =
1986 return icc_ctlr_el3.EOImode_EL3;
1988 ICC_CTLR_EL1 icc_ctlr_el1 = 0;
1993 return icc_ctlr_el1.EOImode;
2001 return ich_vmcr_el2.VEOIM;
2011 if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
2015 if (gq_ctz < g0_ctz) {
2038 bool signal_IRQ =
false;
2039 bool signal_FIQ =
false;
2051 DPRINTF(GIC,
"Gicv3CPUInterface::update(): "
2075 bool signal_IRQ =
false;
2076 bool signal_FIQ =
false;
2080 ICH_LR_EL2 ich_lr_el2 =
2084 if (ich_lr_el2.Group) {
2099 }
else if (maint_pending) {
2104 DPRINTF(GIC,
"Gicv3CPUInterface::virtualUpdate(): "
2112 DPRINTF(GIC,
"Gicv3CPUInterface::virtualUpdate(): "
2127 if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
2132 uint8_t highest_prio = 0xff;
2134 for (
int i = 0;
i < 16;
i++) {
2135 ICH_LR_EL2 ich_lr_el2 =
2142 if (ich_lr_el2.Group) {
2144 if (!ich_vmcr_el2.VENG1) {
2149 if (!ich_vmcr_el2.VENG0) {
2154 uint8_t prio = ich_lr_el2.Priority;
2156 if (prio < highest_prio) {
2157 highest_prio = prio;
2169 if (!ich_hcr_el2.En) {
2174 ICH_LR_EL2 ich_lr_el2 =
2176 uint8_t prio = ich_lr_el2.Priority;
2187 if (rprio == 0xff) {
2194 if ((prio & prio_mask) < (rprio & prio_mask)) {
2206 for (
int i = 0;
i < num_aprs;
i++) {
2227 uint32_t EOI_cout =
bits(ich_hcr_el2, 31, 27);
2229 ich_hcr_el2 =
insertBits(ich_hcr_el2, 31, 27, EOI_cout);
2237 bool is_fiq =
false;
2254 panic(
"Gicv3CPUInterface::intSignalType(): invalid group!");
2284 if (rprio == 0xff) {
2290 if ((
hppi.
prio & prio_mask) < (rprio & prio_mask)) {
2317 ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
2323 ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
2329 ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
2335 panic(
"Gicv3CPUInterface::groupEnable(): invalid group!\n");
2366 warn(
"Unimplemented Exception Level\n");
2390 bool is_64 = opModeIs64((
OperatingMode)(uint8_t) cpsr.mode);
2392 if (is_64 && (cpsr.el ==
EL3)) {
2394 }
else if (!is_64 && (cpsr.mode ==
MODE_MON)) {
2424 ICH_LR_EL2 ich_lr_el2 =
2427 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
2428 !ich_lr_el2.HW && ich_lr_el2.EOI) {
2429 value |= (1 << lr_idx);
2436 Gicv3CPUInterface::ICH_MISR_EL2
2440 ICH_MISR_EL2 ich_misr_el2 = 0;
2441 ICH_HCR_EL2 ich_hcr_el2 =
2443 ICH_VMCR_EL2 ich_vmcr_el2 =
2451 ich_misr_el2.EOI = 1;
2459 uint32_t num_valid_interrupts = 0;
2460 uint32_t num_pending_interrupts = 0;
2463 ICH_LR_EL2 ich_lr_el2 =
2466 if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
2467 num_valid_interrupts++;
2471 num_pending_interrupts++;
2475 if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
2482 if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
2483 ich_misr_el2.LRENP = 1;
2489 if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
2490 ich_misr_el2.NP = 1;
2496 if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
2497 ich_misr_el2.VGrp0E = 1;
2503 if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
2504 ich_misr_el2.VGrp0D = 1;
2510 if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
2511 ich_misr_el2.VGrp1E = 1;
2517 if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
2518 ich_misr_el2.VGrp1D = 1;
2521 return ich_misr_el2;
2535 ICC_CTLR_EL1 icc_ctlr_el1_s =
2545 ICC_CTLR_EL1 icc_ctlr_el1_ns =
2553 bpr = bpr < 7 ? bpr : 7;
2559 panic(
"Should be used with G1S and G1NS only\n");
2602 if (PRIORITY_BITS >= 6) {
2606 if (PRIORITY_BITS >= 7) {