45 #include "debug/GIC.hh"
58 redistributor(nullptr),
85 "Invalid maintenance interrupt number\n");
93 if (hcr.tge && hcr.e2h) {
107 if (hcr.tge && hcr.e2h) {
109 }
else if (hcr.tge) {
181 ICH_VMCR_EL2 ich_vmcr_el2 =
183 value = ich_vmcr_el2.VENG0;
199 ICH_VMCR_EL2 ich_vmcr_el2 =
201 value = ich_vmcr_el2.VENG1;
208 ICC_IGRPEN1_EL3 igrp_el3 = 0;
223 (hcr_imo || hcr_fmo)) {
233 if ((rprio & 0x80) == 0) {
237 }
else if (rprio != 0xff) {
241 rprio = (rprio << 1) & 0xff;
272 ICH_LR_EL2 ich_lr_el2 =
278 value = ich_lr_el2.vINTID;
302 ICH_LR_EL2 ich_lr_el2 =
308 value = ich_lr_el2.vINTID;
335 ICH_VMCR_EL2 ich_vmcr_el2 =
338 value = ich_vmcr_el2.VBPR0;
344 ICH_VMCR_EL2 ich_vmcr_el2 =
347 if (ich_vmcr_el2.VCBPR) {
349 value = ich_vmcr_el2.VBPR0 + 1;
350 value = value < 7 ? value : 7;
352 value = ich_vmcr_el2.VBPR1;
369 if ((value & 0x80) == 0) {
373 }
else if (value != 0xff) {
377 value = (value << 1) & 0xff;
384 ICH_VMCR_EL2 ich_vmcr_el2 =
387 value = ich_vmcr_el2.VPMR;
422 ICH_LR_EL2 ich_lr_el2 =
426 int_id = ich_lr_el2.vINTID;
435 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
478 ICH_LR_EL2 ich_lr_el2 =
482 int_id = ich_lr_el2.vINTID;
491 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
511 ICC_SRE_EL1 icc_sre_el1 = 0;
529 ICC_SRE_EL2 icc_sre_el2 = 0;
533 icc_sre_el2.Enable = 1;
550 ICC_SRE_EL3 icc_sre_el3 = 0;
554 icc_sre_el3.Enable = 1;
575 ICC_CTLR_EL1 icc_ctlr_el1 = value;
576 icc_ctlr_el1.ExtRange = 0;
577 icc_ctlr_el1.RSS = 1;
578 icc_ctlr_el1.A3V = 1;
579 icc_ctlr_el1.SEIS = 0;
580 icc_ctlr_el1.IDbits = 1;
581 icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
582 value = icc_ctlr_el1;
588 ICV_CTLR_EL1 icv_ctlr_el1 = value;
589 icv_ctlr_el1.RSS = 0;
590 icv_ctlr_el1.A3V = 1;
591 icv_ctlr_el1.SEIS = 0;
592 icv_ctlr_el1.IDbits = 1;
593 icv_ctlr_el1.PRIbits = 7;
594 value = icv_ctlr_el1;
610 ICC_CTLR_EL3 icc_ctlr_el3 = value;
611 icc_ctlr_el3.ExtRange = 0;
612 icc_ctlr_el3.RSS = 1;
613 icc_ctlr_el3.nDS = 0;
614 icc_ctlr_el3.A3V = 1;
615 icc_ctlr_el3.SEIS = 0;
616 icc_ctlr_el3.IDbits = 0;
617 icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
618 value = icc_ctlr_el3;
670 ICH_VTR_EL2 ich_vtr_el2 = value;
674 ich_vtr_el2.IDbits = 1;
694 ICH_LR_EL2 ich_lr_el2 =
697 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
698 (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
699 value |= (1 << lr_idx);
714 value = value & 0xffffffff;
727 panic(
"Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
731 DPRINTF(GIC,
"Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
739 bool do_virtual_update =
false;
740 DPRINTF(GIC,
"Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
798 int int_id =
val & 0xffffff;
823 int int_id =
val & 0xffffff;
833 if (drop_prio == 0xff) {
843 ICH_LR_EL2 ich_lr_el2 =
847 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
849 if (lr_group ==
Gicv3::G0S && lr_group_prio == drop_prio) {
868 int int_id =
val & 0xffffff;
902 int int_id =
val & 0xffffff;
912 if (drop_prio == 0xff) {
922 ICH_LR_EL2 ich_lr_el2 =
926 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
928 if (lr_group ==
Gicv3::G1NS && lr_group_prio == drop_prio) {
943 (hcr_imo || hcr_fmo)) {
947 int int_id =
val & 0xffffff;
967 bool irq_is_secure = !single_sec_state && (group !=
Gicv3::G1NS);
969 bool route_fiq_to_el3 = scr_el3.fiq;
970 bool route_irq_to_el3 = scr_el3.irq;
971 bool route_fiq_to_el2 = hcr_fmo;
972 bool route_irq_to_el2 = hcr_imo;
979 if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
983 if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
991 if (single_sec_state && irq_is_grp0 &&
992 !route_fiq_to_el3 && !route_fiq_to_el2) {
996 if (!irq_is_secure && !irq_is_grp0 &&
997 !route_irq_to_el3 && !route_irq_to_el2) {
1001 if (irq_is_grp0 && !route_fiq_to_el3) {
1006 (!irq_is_secure || !single_sec_state) &&
1007 !route_irq_to_el3) {
1024 int int_id =
val & 0xffffff;
1068 ICC_CTLR_EL1 icc_ctlr_el1_s =
1080 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1101 ICH_VMCR_EL2 ich_vmcr_el2 =
1104 if ((group ==
Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1115 if (
val < min_VPBR) {
1120 ich_vmcr_el2.VBPR0 =
val;
1122 ich_vmcr_el2.VBPR1 =
val;
1126 do_virtual_update =
true;
1145 ICC_CTLR_EL1 requested_icc_ctlr_el1 =
val;
1146 ICC_CTLR_EL1 icc_ctlr_el1 =
1149 ICC_CTLR_EL3 icc_ctlr_el3 =
1163 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1164 icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
1168 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1172 icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
1176 icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
1179 icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
1190 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1193 icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
1195 icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
1200 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1211 ICV_CTLR_EL1 requested_icv_ctlr_el1 =
val;
1212 ICV_CTLR_EL1 icv_ctlr_el1 =
1214 icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
1215 icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
1221 ICH_VMCR_EL2 ich_vmcr_el2 =
1223 ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
1224 ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
1242 ICC_CTLR_EL3 requested_icc_ctlr_el3 =
val;
1247 ICC_CTLR_EL1 icc_ctlr_el1_s =
1249 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1254 icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
1257 icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
1259 icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
1261 icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
1268 ICC_CTLR_EL3 icc_ctlr_el3 =
1271 icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
1272 icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
1273 icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
1274 icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
1275 icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
1276 icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
1298 if (!(old_icc_pmr_el1 & 0x80)) {
1312 val &= ~0
U << (8 - PRIORITY_BITS);
1317 ICH_VMCR_EL2 ich_vmcr_el2 =
1319 ich_vmcr_el2.VPMR =
val & 0xff;
1341 ICH_VMCR_EL2 ich_vmcr_el2 =
1343 ich_vmcr_el2.VENG0 =
enable;
1364 ICH_VMCR_EL2 ich_vmcr_el2 =
1366 ich_vmcr_el2.VENG1 =
enable;
1375 ICC_IGRPEN1_EL3 icc_igrpen1_el3 =
val;
1424 ICH_HCR_EL2 requested_ich_hcr_el2 =
val;
1425 ICH_HCR_EL2 ich_hcr_el2 =
1428 if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
1433 ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
1436 ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
1437 ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
1438 ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
1439 ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
1440 ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
1441 ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
1442 ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
1443 ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
1444 ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
1445 ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
1446 ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
1447 ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
1448 ich_hcr_el2.En = requested_ich_hcr_el2.En;
1450 do_virtual_update =
true;
1457 ICH_LRC requested_ich_lrc =
val;
1460 ich_lrc.State = requested_ich_lrc.State;
1461 ich_lrc.HW = requested_ich_lrc.HW;
1462 ich_lrc.Group = requested_ich_lrc.Group;
1468 ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
1469 (ich_lrc.Priority & 0x07);
1480 if (requested_ich_lrc.HW == 0) {
1481 ich_lrc.EOI = requested_ich_lrc.EOI;
1483 ich_lrc.pINTID = requested_ich_lrc.pINTID;
1487 do_virtual_update =
true;
1495 val = (old_val & 0xffffffff00000000) | (
val & 0xffffffff);
1496 do_virtual_update =
true;
1502 ICH_LR_EL2 requested_ich_lr_el2 =
val;
1505 ich_lr_el2.State = requested_ich_lr_el2.State;
1506 ich_lr_el2.HW = requested_ich_lr_el2.HW;
1507 ich_lr_el2.Group = requested_ich_lr_el2.Group;
1513 ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
1514 (ich_lr_el2.Priority & 0x07);
1525 if (requested_ich_lr_el2.HW == 0) {
1526 ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
1528 ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
1535 ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
1538 do_virtual_update =
true;
1545 ICH_VMCR_EL2 requested_ich_vmcr_el2 =
val;
1546 ICH_VMCR_EL2 ich_vmcr_el2 =
1548 ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
1551 if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
1552 ich_vmcr_el2.VBPR0 = min_vpr0;
1554 ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
1557 uint8_t min_vpr1 = min_vpr0 + 1;
1559 if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
1560 ich_vmcr_el2.VBPR1 = min_vpr1;
1562 ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
1565 ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
1566 ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
1567 ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
1568 ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
1608 panic(
"Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
1614 if (do_virtual_update) {
1637 ICH_LR_EL2 ich_lr_el2 =
1642 (ich_lr_el2.vINTID == int_id)) {
1684 if ((
currEL() ==
EL3) && icc_ctlr_el3.RM) {
1698 if (irq_is_secure) {
1714 int apr_misc_reg = 0;
1727 panic(
"Invalid Gicv3::GroupId");
1745 for (
int i = 0;
i < apr_max;
i++) {
1749 if (!vapr0 && !vapr1) {
1753 int vapr0_count =
ctz32(vapr0);
1754 int vapr1_count =
ctz32(vapr1);
1756 if (vapr0_count <= vapr1_count) {
1773 uint8_t aff3 =
bits(
val, 55, 48);
1774 uint8_t aff2 =
bits(
val, 39, 32);
1775 uint8_t aff1 =
bits(
val, 23, 16);;
1776 uint16_t target_list =
bits(
val, 15, 0);
1777 uint32_t int_id =
bits(
val, 27, 24);
1786 uint32_t affinity_i = redistributor_i->
getAffinity();
1797 if ((affinity_i >> 8) !=
1798 ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
1802 uint8_t aff0_i =
bits(affinity_i, 7, 0);
1804 if (!(aff0_i >=
rs * 16 && aff0_i < (
rs + 1) * 16 &&
1805 ((0x1 << (aff0_i -
rs * 16)) & target_list))) {
1810 redistributor_i->
sendSGI(int_id, group,
ns);
1815 Gicv3CPUInterface::activateIRQ(uint32_t int_id,
Gicv3::GroupId group)
1819 int apr_bit = prio >> (8 - PRIORITY_BITS);
1820 int reg_bit = apr_bit % 32;
1834 panic(
"Invalid Gicv3::GroupId");
1838 apr |= (1 << reg_bit);
1867 uint8_t prio = ich_lr_el.Priority & 0xf8;
1869 int reg_no = apr_bit / 32;
1870 int reg_bit = apr_bit % 32;
1874 apr |= (1 << reg_bit);
1901 if (ich_lr_el2.HW) {
1923 ICC_CTLR_EL1 icc_ctlr_el1_s =
1925 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1928 if ((group ==
Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
1948 return ~0
U << (bpr + 1);
1954 ICH_VMCR_EL2 ich_vmcr_el2 =
1957 if ((group ==
Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1964 bpr = ich_vmcr_el2.VBPR0;
1966 bpr = ich_vmcr_el2.VBPR1;
1974 return ~0
U << (bpr + 1);
1981 ICC_CTLR_EL3 icc_ctlr_el3 =
1983 return icc_ctlr_el3.EOImode_EL3;
1985 ICC_CTLR_EL1 icc_ctlr_el1 = 0;
1990 return icc_ctlr_el1.EOImode;
1998 return ich_vmcr_el2.VEOIM;
2008 if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
2012 if (gq_ctz < g0_ctz) {
2032 bool signal_IRQ =
false;
2033 bool signal_FIQ =
false;
2045 DPRINTF(GIC,
"Gicv3CPUInterface::update(): "
2066 bool signal_IRQ =
false;
2067 bool signal_FIQ =
false;
2071 ICH_LR_EL2 ich_lr_el2 =
2075 if (ich_lr_el2.Group) {
2090 }
else if (maint_pending) {
2095 DPRINTF(GIC,
"Gicv3CPUInterface::virtualUpdate(): "
2103 DPRINTF(GIC,
"Gicv3CPUInterface::virtualUpdate(): "
2118 if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
2123 uint8_t highest_prio = 0xff;
2125 for (
int i = 0;
i < 16;
i++) {
2126 ICH_LR_EL2 ich_lr_el2 =
2133 if (ich_lr_el2.Group) {
2135 if (!ich_vmcr_el2.VENG1) {
2140 if (!ich_vmcr_el2.VENG0) {
2145 uint8_t prio = ich_lr_el2.Priority;
2147 if (prio < highest_prio) {
2148 highest_prio = prio;
2160 if (!ich_hcr_el2.En) {
2165 ICH_LR_EL2 ich_lr_el2 =
2167 uint8_t prio = ich_lr_el2.Priority;
2178 if (rprio == 0xff) {
2185 if ((prio & prio_mask) < (rprio & prio_mask)) {
2197 for (
int i = 0;
i < num_aprs;
i++) {
2218 uint32_t EOI_cout =
bits(ich_hcr_el2, 31, 27);
2220 ich_hcr_el2 =
insertBits(ich_hcr_el2, 31, 27, EOI_cout);
2228 bool is_fiq =
false;
2245 panic(
"Gicv3CPUInterface::intSignalType(): invalid group!");
2275 if (rprio == 0xff) {
2281 if ((
hppi.
prio & prio_mask) < (rprio & prio_mask)) {
2308 ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
2314 ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
2320 ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
2326 panic(
"Gicv3CPUInterface::groupEnable(): invalid group!\n");
2346 bool is_64 = opModeIs64((
OperatingMode)(uint8_t) cpsr.mode);
2351 switch (cpsr.mode) {
2382 warn(
"Unimplemented Exception Level\n");
2406 bool is_64 = opModeIs64((
OperatingMode)(uint8_t) cpsr.mode);
2408 if (is_64 && (cpsr.el ==
EL3)) {
2410 }
else if (!is_64 && (cpsr.mode ==
MODE_MON)) {
2440 ICH_LR_EL2 ich_lr_el2 =
2443 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
2444 !ich_lr_el2.HW && ich_lr_el2.EOI) {
2445 value |= (1 << lr_idx);
2452 Gicv3CPUInterface::ICH_MISR_EL2
2456 ICH_MISR_EL2 ich_misr_el2 = 0;
2457 ICH_HCR_EL2 ich_hcr_el2 =
2459 ICH_VMCR_EL2 ich_vmcr_el2 =
2467 ich_misr_el2.EOI = 1;
2475 uint32_t num_valid_interrupts = 0;
2476 uint32_t num_pending_interrupts = 0;
2479 ICH_LR_EL2 ich_lr_el2 =
2482 if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
2483 num_valid_interrupts++;
2487 num_pending_interrupts++;
2491 if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
2498 if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
2499 ich_misr_el2.LRENP = 1;
2505 if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
2506 ich_misr_el2.NP = 1;
2512 if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
2513 ich_misr_el2.VGrp0E = 1;
2519 if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
2520 ich_misr_el2.VGrp0D = 1;
2526 if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
2527 ich_misr_el2.VGrp1E = 1;
2533 if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
2534 ich_misr_el2.VGrp1D = 1;
2537 return ich_misr_el2;
2551 ICC_CTLR_EL1 icc_ctlr_el1_s =
2561 ICC_CTLR_EL1 icc_ctlr_el1_ns =
2569 bpr = bpr < 7 ? bpr : 7;
2575 panic(
"Should be used with G1S and G1NS only\n");