58 std::unordered_map<MiscRegNum32, MiscRegIndex> miscRegNum32ToIdx{
522 auto it = miscRegNum32ToIdx.find(cop_reg);
523 if (it != miscRegNum32ToIdx.end()) {
526 warn(
"CP14 unimplemented crn[%d], opc1[%d], crm[%d], opc2[%d]",
527 crn, opc1, crm,
opc2);
536 auto it = miscRegNum32ToIdx.find(cop_reg);
537 if (it != miscRegNum32ToIdx.end()) {
541 (crn == 9 && (crm <= 2 || crm >= 5)) ||
542 (crn == 10 && opc1 == 0 && crm <= 1) ||
543 (crn == 11 && opc1 <= 7 && (crm <= 8 || crm ==15))) {
555 auto it = miscRegNum32ToIdx.find(cop_reg);
556 if (it != miscRegNum32ToIdx.end()) {
563 std::tuple<bool, bool>
566 bool secure = !scr.ns;
567 bool can_read =
false;
568 bool undefined =
false;
607 return std::make_tuple(can_read, undefined);
610 std::tuple<bool, bool>
613 bool secure = !scr.ns;
614 bool can_write =
false;
615 bool undefined =
false;
654 return std::make_tuple(can_write, undefined);
663 if (trap_cond && (!
EL2Enabled(tc) || !hcr.tge))
679 int reg_as_int =
static_cast<int>(
reg);
692 return isa->snsBankedIndex64(
reg, scr.ns);
740 std::unordered_map<MiscRegIndex, MiscRegNum64> idxToMiscRegNum;
744 std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
1221 faultSpEL0(
const MiscRegLUTEntry &entry, ThreadContext *tc,
1222 const MiscRegOp64 &inst)
1225 return inst.undefined();
1231 faultDaif(
const MiscRegLUTEntry &entry, ThreadContext *tc,
1232 const MiscRegOp64 &inst)
1237 if ((el2_enabled && hcr.e2h && hcr.tge) || sctlr.uma == 0) {
1238 if (el2_enabled && hcr.tge) {
1239 return inst.generateTrap(
EL2);
1241 return inst.generateTrap(
EL1);
1249 faultDczvaEL0(
const MiscRegLUTEntry &entry, ThreadContext *tc,
1250 const MiscRegOp64 &inst)
1260 const bool in_host = hcr.e2h && hcr.tge;
1261 if (!(el2_enabled && in_host) && !sctlr.dze) {
1262 if (el2_enabled && hcr.tge) {
1263 return inst.generateTrap(
EL2);
1265 return inst.generateTrap(
EL1);
1267 }
else if (el2_enabled && !in_host && hcr.tdz) {
1268 return inst.generateTrap(
EL2);
1269 }
else if (el2_enabled && in_host && !sctlr2.dze) {
1270 return inst.generateTrap(
EL2);
1277 faultCvacEL0(
const MiscRegLUTEntry &entry, ThreadContext *tc,
1278 const MiscRegOp64 &inst)
1285 const bool in_host = hcr.e2h && hcr.tge;
1286 if (!(el2_enabled && in_host) && !sctlr.uci) {
1287 if (el2_enabled && hcr.tge) {
1288 return inst.generateTrap(
EL2);
1290 return inst.generateTrap(
EL1);
1292 }
else if (el2_enabled && !in_host && hcr.tpc) {
1293 return inst.generateTrap(
EL2);
1294 }
else if (el2_enabled && in_host && !sctlr2.uci) {
1295 return inst.generateTrap(
EL2);
1302 faultFpcrEL0(
const MiscRegLUTEntry &entry, ThreadContext *tc,
1303 const MiscRegOp64 &inst)
1311 const bool in_host = hcr.e2h && hcr.tge;
1312 if (!(el2_enabled && in_host) && cpacr.fpen != 0b11) {
1313 if (el2_enabled && hcr.tge) {
1316 return inst.generateTrap(
EL1,
1319 }
else if (el2_enabled && in_host && cptr_el2.fpen != 0b11) {
1320 return inst.generateTrap(
EL2,
1322 }
else if (el2_enabled && hcr.e2h && ((cptr_el2.fpen & 0b1) == 0b0)) {
1323 return inst.generateTrap(
EL2,
1325 }
else if (el2_enabled && !hcr.e2h && cptr_el2.tfp) {
1326 return inst.generateTrap(
EL2,
1329 return inst.generateTrap(
EL3,
1337 faultFpcrEL1(
const MiscRegLUTEntry &entry, ThreadContext *tc,
1338 const MiscRegOp64 &inst)
1346 if ((cpacr.fpen & 0b1) == 0b0) {
1347 return inst.generateTrap(
EL1,
1349 }
else if (el2_enabled && !hcr.e2h && cptr_el2.tfp) {
1350 return inst.generateTrap(
EL2,
1352 }
else if (el2_enabled && hcr.e2h && ((cptr_el2.fpen & 0b1) == 0b0)) {
1353 return inst.generateTrap(
EL2,
1356 return inst.generateTrap(
EL3,
1364 faultFpcrEL2(
const MiscRegLUTEntry &entry, ThreadContext *tc,
1365 const MiscRegOp64 &inst)
1371 if (!hcr.e2h && cptr_el2.tfp) {
1372 return inst.generateTrap(
EL2,
1374 }
else if (hcr.e2h && ((cptr_el2.fpen & 0b1) == 0b0)) {
1375 return inst.generateTrap(
EL2,
1378 return inst.generateTrap(
EL3,
1386 faultFpcrEL3(
const MiscRegLUTEntry &entry,
1387 ThreadContext *tc,
const MiscRegOp64 &inst)
1391 return inst.generateTrap(
EL3,
1399 faultPouEL0(
const MiscRegLUTEntry &entry,
1400 ThreadContext *tc,
const MiscRegOp64 &inst)
1407 const bool in_host = hcr.e2h && hcr.tge;
1408 if (!(el2_enabled && in_host) && !sctlr.uci) {
1409 if (el2_enabled && hcr.tge) {
1410 return inst.generateTrap(
EL2);
1412 return inst.generateTrap(
EL1);
1414 }
else if (el2_enabled && !in_host && hcr.tpu) {
1415 return inst.generateTrap(
EL2);
1416 }
else if (el2_enabled && !in_host && hcr.tocu) {
1417 return inst.generateTrap(
EL2);
1418 }
else if (el2_enabled && in_host && !sctlr2.uci) {
1419 return inst.generateTrap(
EL2);
1426 faultPouEL1(
const MiscRegLUTEntry &entry,
1427 ThreadContext *tc,
const MiscRegOp64 &inst)
1431 if (el2_enabled && hcr.tpu) {
1432 return inst.generateTrap(
EL2);
1433 }
else if (el2_enabled && hcr.tocu) {
1434 return inst.generateTrap(
EL2);
1441 faultPouIsEL1(
const MiscRegLUTEntry &entry,
1442 ThreadContext *tc,
const MiscRegOp64 &inst)
1446 if (el2_enabled && hcr.tpu) {
1447 return inst.generateTrap(
EL2);
1448 }
else if (el2_enabled && hcr.ticab) {
1449 return inst.generateTrap(
EL2);
1456 faultCtrEL0(
const MiscRegLUTEntry &entry,
1457 ThreadContext *tc,
const MiscRegOp64 &inst)
1464 const bool in_host = hcr.e2h && hcr.tge;
1465 if (!(el2_enabled && in_host) && !sctlr.uct) {
1466 if (el2_enabled && hcr.tge) {
1467 return inst.generateTrap(
EL2);
1469 return inst.generateTrap(
EL1);
1471 }
else if (el2_enabled && !in_host && hcr.tid2) {
1472 return inst.generateTrap(
EL2);
1473 }
else if (el2_enabled && in_host && !sctlr2.uct) {
1474 return inst.generateTrap(
EL2);
1481 faultMdccsrEL0(
const MiscRegLUTEntry &entry,
1482 ThreadContext *tc,
const MiscRegOp64 &inst)
1491 if (el2_enabled && hcr.tge) {
1492 return inst.generateTrap(
EL2);
1494 return inst.generateTrap(
EL1);
1496 }
else if (el2_enabled && mdcr_el2.tdcc) {
1497 return inst.generateTrap(
EL2);
1498 }
else if (el2_enabled && (hcr.tge || (mdcr_el2.tde || mdcr_el2.tda))) {
1499 return inst.generateTrap(
EL2);
1501 return inst.generateTrap(
EL3);
1508 faultMdccsrEL1(
const MiscRegLUTEntry &entry,
1509 ThreadContext *tc,
const MiscRegOp64 &inst)
1515 if (el2_enabled && mdcr_el2.tdcc) {
1516 return inst.generateTrap(
EL2);
1517 }
else if (el2_enabled && (mdcr_el2.tde || mdcr_el2.tda)) {
1518 return inst.generateTrap(
EL2);
1520 return inst.generateTrap(
EL3);
1527 faultMdccsrEL2(
const MiscRegLUTEntry &entry,
1528 ThreadContext *tc,
const MiscRegOp64 &inst)
1532 return inst.generateTrap(
EL3);
1539 faultDebugEL1(
const MiscRegLUTEntry &entry,
1540 ThreadContext *tc,
const MiscRegOp64 &inst)
1546 if (el2_enabled && (mdcr_el2.tde || mdcr_el2.tda)) {
1547 return inst.generateTrap(
EL2);
1549 return inst.generateTrap(
EL3);
1556 faultDebugEL2(
const MiscRegLUTEntry &entry,
1557 ThreadContext *tc,
const MiscRegOp64 &inst)
1561 return inst.generateTrap(
EL3);
1568 faultZcrEL1(
const MiscRegLUTEntry &entry,
1569 ThreadContext *tc,
const MiscRegOp64 &inst)
1577 if (!(cpacr_el1.zen & 0x1)) {
1579 }
else if (el2_enabled && !hcr.e2h && cptr_el2.tz) {
1581 }
else if (el2_enabled && hcr.e2h && !(cptr_el2.zen & 0x1)) {
1591 faultZcrEL2(
const MiscRegLUTEntry &entry,
1592 ThreadContext *tc,
const MiscRegOp64 &inst)
1598 if (!hcr.e2h && cptr_el2.tz) {
1600 }
else if (hcr.e2h && !(cptr_el2.zen & 0x1)) {
1610 faultZcrEL3(
const MiscRegLUTEntry &entry,
1611 ThreadContext *tc,
const MiscRegOp64 &inst)
1622 faultGicv3(
const MiscRegLUTEntry &entry,
1623 ThreadContext *tc,
const MiscRegOp64 &inst)
1625 auto gic =
static_cast<ArmSystem*
>(tc->getSystemPtr())->getGIC();
1627 return inst.undefined();
1634 faultIccSgiEL1(
const MiscRegLUTEntry &entry,
1635 ThreadContext *tc,
const MiscRegOp64 &inst)
1637 if (
auto fault = faultGicv3(entry, tc, inst); fault !=
NoFault) {
1641 const Gicv3CPUInterface::ICH_HCR_EL2 ich_hcr =
1645 if (
EL2Enabled(tc) && (hcr.fmo || hcr.imo || ich_hcr.TC)) {
1646 return inst.generateTrap(
EL2);
1648 return inst.generateTrap(
EL3);
1655 faultIccSgiEL2(
const MiscRegLUTEntry &entry,
1656 ThreadContext *tc,
const MiscRegOp64 &inst)
1658 if (
auto fault = faultGicv3(entry, tc, inst); fault !=
NoFault) {
1664 return inst.generateTrap(
EL3);
1671 faultCpacrEL1(
const MiscRegLUTEntry &entry,
1672 ThreadContext *tc,
const MiscRegOp64 &inst)
1677 return inst.generateTrap(
EL2);
1679 return inst.generateTrap(
EL3);
1686 faultCpacrEL2(
const MiscRegLUTEntry &entry,
1687 ThreadContext *tc,
const MiscRegOp64 &inst)
1691 return inst.generateTrap(
EL3);
1698 faultCpacrVheEL2(
const MiscRegLUTEntry &entry,
1699 ThreadContext *tc,
const MiscRegOp64 &inst)
1703 return faultCpacrEL2(entry, tc, inst);
1705 return inst.undefined();
1709 #define HCR_TRAP(bitfield) [] (const MiscRegLUTEntry &entry, \
1710 ThreadContext *tc, const MiscRegOp64 &inst) -> Fault \
1712 const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); \
1713 if (EL2Enabled(tc) && hcr.bitfield) { \
1714 return inst.generateTrap(EL2); \
1721 faultPauthEL1(
const MiscRegLUTEntry &entry,
1722 ThreadContext *tc,
const MiscRegOp64 &inst)
1727 return inst.generateTrap(
EL2);
1729 return inst.generateTrap(
EL3);
1736 faultPauthEL2(
const MiscRegLUTEntry &entry,
1737 ThreadContext *tc,
const MiscRegOp64 &inst)
1741 return inst.generateTrap(
EL3);
1748 faultGenericTimerEL0(
const MiscRegLUTEntry &entry,
1749 ThreadContext *tc,
const MiscRegOp64 &inst)
1753 const bool in_host = el2_enabled && hcr.e2h && hcr.tge;
1756 if (!(in_host) && !cntkctl_el1.el0pcten && !cntkctl_el1.el0vcten) {
1757 if (el2_enabled && hcr.tge)
1758 return inst.generateTrap(
EL2);
1760 return inst.generateTrap(
EL1);
1761 }
else if (in_host && !cnthctl_el2.el0pcten && !cnthctl_el2.el0vcten) {
1762 return inst.generateTrap(
EL2);
1769 faultCntpctEL0(
const MiscRegLUTEntry &entry,
1770 ThreadContext *tc,
const MiscRegOp64 &inst)
1774 const bool in_host = el2_enabled && hcr.e2h && hcr.tge;
1777 if (!(in_host) && !cntkctl_el1.el0pcten) {
1778 if (el2_enabled && hcr.tge)
1779 return inst.generateTrap(
EL2);
1781 return inst.generateTrap(
EL1);
1782 }
else if (el2_enabled && !hcr.e2h &&
1783 !
static_cast<CNTHCTL
>(cnthctl_el2).el1pcten) {
1784 return inst.generateTrap(
EL2);
1785 }
else if (el2_enabled && hcr.e2h && !hcr.tge &&
1786 !
static_cast<CNTHCTL_E2H
>(cnthctl_el2).el1pcten) {
1787 return inst.generateTrap(
EL2);
1788 }
else if (in_host &&
1789 !
static_cast<CNTHCTL_E2H
>(cnthctl_el2).
el0pcten) {
1790 return inst.generateTrap(
EL2);
1797 faultCntpctEL1(
const MiscRegLUTEntry &entry,
1798 ThreadContext *tc,
const MiscRegOp64 &inst)
1803 if (el2_enabled && hcr.e2h &&
1804 !
static_cast<CNTHCTL_E2H
>(cnthctl_el2).el1pcten) {
1805 return inst.generateTrap(
EL2);
1806 }
else if (el2_enabled && !hcr.e2h &&
1807 !
static_cast<CNTHCTL
>(cnthctl_el2).el1pcten) {
1808 return inst.generateTrap(
EL2);
1815 faultCntvctEL0(
const MiscRegLUTEntry &entry,
1816 ThreadContext *tc,
const MiscRegOp64 &inst)
1820 const bool in_host = el2_enabled && hcr.e2h && hcr.tge;
1823 if (!(in_host) && !cntkctl_el1.el0vcten) {
1824 if (el2_enabled && hcr.tge)
1825 return inst.generateTrap(
EL2);
1827 return inst.generateTrap(
EL1);
1828 }
else if (in_host && !cnthctl_el2.el0vcten) {
1829 return inst.generateTrap(
EL2);
1830 }
else if (el2_enabled && !(hcr.e2h && hcr.tge) && cnthctl_el2.el1tvct) {
1831 return inst.generateTrap(
EL2);
1838 faultCntvctEL1(
const MiscRegLUTEntry &entry,
1839 ThreadContext *tc,
const MiscRegOp64 &inst)
1843 return inst.generateTrap(
EL2);
1851 faultCntpCtlEL0(
const MiscRegLUTEntry &entry,
1852 ThreadContext *tc,
const MiscRegOp64 &inst)
1856 const bool in_host = el2_enabled && hcr.e2h && hcr.tge;
1859 if (!(in_host) && !cntkctl_el1.el0pten) {
1860 if (el2_enabled && hcr.tge)
1861 return inst.generateTrap(
EL2);
1863 return inst.generateTrap(
EL1);
1864 }
else if (el2_enabled && !hcr.e2h &&
1865 !
static_cast<CNTHCTL
>(cnthctl_el2).el1pcen) {
1866 return inst.generateTrap(
EL2);
1867 }
else if (el2_enabled && hcr.e2h && !hcr.tge &&
1868 !
static_cast<CNTHCTL_E2H
>(cnthctl_el2).el1pten) {
1869 return inst.generateTrap(
EL2);
1870 }
else if (in_host &&
1871 !
static_cast<CNTHCTL_E2H
>(cnthctl_el2).
el0pten) {
1872 return inst.generateTrap(
EL2);
1879 faultCntpCtlEL1(
const MiscRegLUTEntry &entry,
1880 ThreadContext *tc,
const MiscRegOp64 &inst)
1885 if (el2_enabled && !hcr.e2h &&
1886 !
static_cast<CNTHCTL
>(cnthctl_el2).el1pcen) {
1887 return inst.generateTrap(
EL2);
1888 }
else if (el2_enabled && hcr.e2h &&
1889 !
static_cast<CNTHCTL_E2H
>(cnthctl_el2).el1pten) {
1890 return inst.generateTrap(
EL2);
1898 faultCntvCtlEL0(
const MiscRegLUTEntry &entry,
1899 ThreadContext *tc,
const MiscRegOp64 &inst)
1903 const bool in_host = el2_enabled && hcr.e2h && hcr.tge;
1906 if (!(in_host) && !cntkctl_el1.el0vten) {
1907 if (el2_enabled && hcr.tge)
1908 return inst.generateTrap(
EL2);
1910 return inst.generateTrap(
EL1);
1911 }
else if (in_host && !cnthctl_el2.el0vten) {
1912 return inst.generateTrap(
EL2);
1913 }
else if (el2_enabled && !(hcr.e2h && hcr.tge) && cnthctl_el2.el1tvt) {
1914 return inst.generateTrap(
EL2);
1921 faultCntvCtlEL1(
const MiscRegLUTEntry &entry,
1922 ThreadContext *tc,
const MiscRegOp64 &inst)
1926 return inst.generateTrap(
EL2);
1933 faultCntpsCtlEL1(
const MiscRegLUTEntry &entry,
1934 ThreadContext *tc,
const MiscRegOp64 &inst)
1939 return inst.undefined();
1941 return inst.generateTrap(
EL3);
1945 return inst.undefined();
1950 faultUnimplemented(
const MiscRegLUTEntry &entry,
1951 ThreadContext *tc,
const MiscRegOp64 &inst)
1956 return inst.undefined();
1961 faultImpdefUnimplEL1(
const MiscRegLUTEntry &entry,
1962 ThreadContext *tc,
const MiscRegOp64 &inst)
1966 return inst.generateTrap(
EL2);
1968 return faultUnimplemented(entry, tc, inst);
1976 unsigned crn,
unsigned crm,
1986 auto it = miscRegNumToIdx.find(sys_reg);
1987 if (it != miscRegNumToIdx.end()) {
1991 if ((sys_reg.
op0 == 1 || sys_reg.
op0 == 3) &&
1992 (sys_reg.
crn == 11 || sys_reg.
crn == 15)) {
2003 if (
auto it = idxToMiscRegNum.find(misc_reg);
2004 it != idxToMiscRegNum.end()) {
2007 panic(
"Invalid MiscRegIndex: %d\n", misc_reg);
2019 template <MiscRegInfo Sec, MiscRegInfo NonSec>
2048 const bool el2_host =
EL2Enabled(tc) && hcr.e2h;
2074 static bool completed =
false;
2092 bool LSMAOE =
false;
2095 bool nTLSMD =
false;
2103 const bool vhe_implemented =
release->
has(ArmExtension::FEAT_VHE);
2104 const bool sel2_implemented =
release->
has(ArmExtension::FEAT_SEL2);
2502 .
res1(0x00400800 | (SPAN ? 0 : 0x800000)
2503 | (LSMAOE ? 0 : 0x10)
2504 | (nTLSMD ? 0 : 0x8));
2535 .
res0(0x0512c7c0 | (EnDB ? 0 : 0x2000)
2536 | (IESB ? 0 : 0x200000)
2537 | (EnDA ? 0 : 0x8000000)
2538 | (EnIB ? 0 : 0x40000000)
2539 | (EnIA ? 0 : 0x80000000))
3682 .
res0( 0x20440 | (EnDB ? 0 : 0x2000)
3683 | (IESB ? 0 : 0x200000)
3684 | (EnDA ? 0 : 0x8000000)
3685 | (EnIB ? 0 : 0x40000000)
3686 | (EnIA ? 0 : 0x80000000))
3687 .
res1(0x500800 | (SPAN ? 0 : 0x800000)
3688 | (nTLSMD ? 0 : 0x8000000)
3689 | (LSMAOE ? 0 : 0x10000000))
3694 .
res0( 0x20440 | (EnDB ? 0 : 0x2000)
3695 | (IESB ? 0 : 0x200000)
3696 | (EnDA ? 0 : 0x8000000)
3697 | (EnIB ? 0 : 0x40000000)
3698 | (EnIA ? 0 : 0x80000000))
3699 .
res1(0x500800 | (SPAN ? 0 : 0x800000)
3700 | (nTLSMD ? 0 : 0x8000000)
3701 | (LSMAOE ? 0 : 0x10000000))
3718 .
res0(0x0512c7c0 | (EnDB ? 0 : 0x2000)
3719 | (IESB ? 0 : 0x200000)
3720 | (EnDA ? 0 : 0x8000000)
3721 | (EnIB ? 0 : 0x40000000)
3722 | (EnIA ? 0 : 0x80000000))
3747 .
res0(0x0512c7c0 | (EnDB ? 0 : 0x2000)
3748 | (IESB ? 0 : 0x200000)
3749 | (EnDA ? 0 : 0x8000000)
3750 | (EnIB ? 0 : 0x40000000)
3751 | (EnIA ? 0 : 0x80000000))