107 (!secure ||
HaveExt(tc, ArmExtension::FEAT_SEL2))) {
110 route_to_el2 = (mdcr.tde == 1 || hcr.tge == 1);
112 route_to_el2 =
false;
152 switch (current_el) {
158 warn_once(
"Trying to read MPIDR at EL0\n");
169 panic(
"Invalid EL for reading MPIDR register\n");
187 assert((0 <= tc->
cpuId()) && (tc->
cpuId() < 256));
190 RegVal mpidr = 0x80000000;
225 aff.aff0 =
getAff0(arm_sys, tc);
226 aff.aff1 =
getAff1(arm_sys, tc);
227 aff.aff2 =
getAff2(arm_sys, tc);
259 return !
ELIs32(tc,
EL3) &&
static_cast<SCR
>(
286 panic_if(!known,
"EL state is UNKNOWN");
296 HaveExt(tc, ArmExtension::FEAT_VHE) &&
329 panic_if(
el ==
EL2 && !have_el2,
"Asking for EL2 when it doesn't exist");
330 panic_if(
el ==
EL3 && !have_el3,
"Asking for EL3 when it doesn't exist");
333 known = aarch32 =
false;
337 known =
true; aarch32 =
false;
338 }
else if (secure &&
el ==
EL2) {
339 known =
true; aarch32 =
false;
342 known =
true; aarch32 =
true;
344 known =
true; aarch32 =
false;
347 bool aarch32_below_el3 = have_el3 && scr.rw == 0 &&
348 (!secure || !
HaveExt(tc, ArmExtension::FEAT_SEL2) || !scr.eel2);
351 bool sec_el2 =
HaveExt(tc, ArmExtension::FEAT_SEL2) && scr.eel2;
352 bool aarch32_at_el1 = (aarch32_below_el3 ||
353 (have_el2 && (sec_el2 || !secure) &&
355 !(hcr.e2h && hcr.tge &&
356 HaveExt(tc, ArmExtension::FEAT_VHE))));
359 if (
el ==
EL0 && !aarch32_at_el1) {
363 aarch32 = (cpsr.width == 1);
366 aarch32 = (aarch32_below_el3 &&
el !=
EL3) ||
367 (aarch32_at_el1 && (
el ==
EL0 ||
el ==
EL1) );
371 return std::make_pair(known, aarch32);
378 panic_if(!known,
"EL state is UNKNOWN");
395 panic(
"Invalid exception level");
426 tbi = selbit? tcr.tbi1 : tcr.tbi0;
427 tbid = selbit? tcr.tbid1 : tcr.tbid0;
434 tbi = selbit? tcr.tbi1 : tcr.tbi0;
435 tbid = selbit? tcr.tbid1 : tcr.tbid0;
454 int res = (
tbi && (!
tbid || !is_instr))? 55: 63;
465 uint64_t
mask = ((uint64_t)0x1 << topbit) -1;
475 TCR tcr,
bool is_instr)
510 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
524 bool trap_to_hyp =
false;
533 trap_to_hyp = ((uint32_t) hstr) & (1 << crn);
534 trap_to_hyp |= hdcr.tpm && (crn == 9) && (crm >= 12);
535 trap_to_hyp |= hcr.tidcp && (
536 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
537 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) ||
538 ((crn == 11) && ((crm <= 8) || (crm == 15))));
543 trap_to_hyp = hcptr.tcpac;
549 trap_to_hyp = hcr.tid1;
555 trap_to_hyp = hcr.tid2;
573 trap_to_hyp = hcr.tid3;
578 trap_to_hyp = hcr.tsw;
583 trap_to_hyp = hcr.tpc;
589 trap_to_hyp = hcr.tpu;
609 trap_to_hyp = hcr.ttlb;
612 trap_to_hyp = hcr.tac;
630 trap_to_hyp = hcr.tvm & !is_read;
633 trap_to_hyp = hdcr.tpmcr;
637 trap_to_hyp = hcr.fmo;
641 trap_to_hyp = hcr.imo;
676 bool trap_to_hyp =
false;
680 inform(
"trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
681 crm, crn, opc1,
opc2, hdcr, hcptr, hstr);
682 trap_to_hyp = hdcr.tda && (opc1 == 0);
683 trap_to_hyp |= hcptr.tta && (opc1 == 1);
690 trap_to_hyp = hdcr.tdosa;
694 trap_to_hyp = hdcr.tdra;
697 trap_to_hyp = hcr.tid0;
701 trap_to_hyp = hstr.tjdbx;
705 trap_to_hyp = hstr.ttee;
722 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
736 bool trap_to_hyp =
false;
746 trap_to_hyp = ((uint32_t)hstr) & (1 << crm);
766 trap_to_hyp = hcr.tvm & !is_read;
793 return std::make_shared<SupervisorTrap>(mach_inst,
imm,
ec);
796 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
846 if (
ELIs32(tc,
EL1) && trap_cond && hcr.tge) {
869 return !cnthctl.el1pcten;
871 return !cnthctl.el1pcen;
888 return !(
EL2Enabled(tc) && hcr.e2h && hcr.tge) && trap_cond &&
905 return !cntkctl.el0pcten && !cntkctl.el0vcten;
908 return !cntkctl.el0pcten;
911 return !cntkctl.el0vcten;
914 return !cntkctl.el0pten;
917 return !cntkctl.el0vten;
980 return (!
ELIs32(tc,
EL1) && !hcr.e2h && trap_cond_el1 && hcr.tge) ||
981 (
ELIs32(tc,
EL1) && trap_cond_el1 && hcr.tge) ||
982 (hcr.e2h && hcr.tge && trap_cond_el2);
998 return !hcr.e2h && trap_cond_1;
1001 return (!hcr.e2h && trap_cond_0) ||
1002 (hcr.e2h && !hcr.tge && trap_cond_1);
1026 return (!hcr.e2h && trap_cond_0) ||
1027 (hcr.e2h && trap_cond_1);
1041 return !
ELIs32(tc,
EL1) && !(hcr.e2h && hcr.tge) && trap_cond;
1052 return !cnthctl.el0pcten && !cnthctl.el0vcten;
1055 return !cnthctl.el0pcten;
1058 return !cnthctl.el0vcten;
1061 return !cnthctl.el0pten;
1064 return !cnthctl.el0vten;
1078 const CNTHCTL cnthctl = cnthctl_val;
1079 const CNTHCTL_E2H cnthctl_e2h = cnthctl_val;
1083 return hcr.e2h ? !cnthctl_e2h.el1pcten : !cnthctl.el1pcten;
1089 return hcr.e2h ? cnthctl_e2h.el1tvct : cnthctl.el1tvct;
1092 return hcr.e2h ? !cnthctl_e2h.el1pten :
false;
1098 return hcr.e2h ? cnthctl_e2h.el1tvt : cnthctl.el1tvt;
1110 return !cnthctl.el1pcen;
1121 return currEL(tc) ==
EL1 && !scr.ns && !scr.st;
1131 CPSR cpsr, SCR scr, NSACR nsacr,
bool checkSecurity)
1175 int sysM4To3 =
bits(sysM, 4, 3);
1177 if (sysM4To3 == 0) {
1180 }
else if (sysM4To3 == 1) {
1183 }
else if (sysM4To3 == 3) {
1184 if (
bits(sysM, 1) == 0) {
1189 if (
bits(sysM, 0) == 1) {
1197 int sysM2 =
bits(sysM, 2);
1198 int sysM1 =
bits(sysM, 1);
1202 ((sysM2 && !sysM1) << 2) |
1203 ((sysM2 && sysM1) << 3) |
1208 ok &=
mode != cpsr.mode;
1213 if (ok && checkSecurity &&
mode != cpsr.mode) {
1214 switch (cpsr.mode) {
1239 panic(
"unknown Mode 0x%x\n", cpsr.mode);
1253 bool have_nv_ext =
false;
1256 have_nv_ext && hcr.nv == 1 && hcr.nv1 == 1);
1258 HaveExt(tc, ArmExtension::FEAT_VHE) &&
1259 currEL(tc) ==
EL2 && hcr.e2h == 1 && hcr.tge == 1;
1261 return (unpriv_el1 || unpriv_el2) && !cpsr.uao;
1283 panic(
"Invalid exception level");
1307 panic(
"Invalid phys. address range encoding");
1330 panic(
"Invalid phys. address range");
1394 panic(
"Invalid ExceptionLevel\n");
const ArmRelease * getRelease() const
bool has(ArmExtension ext) const
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
ArmISA::ExceptionLevel highestEL() const
Returns the highest implemented exception level.
bool has(ArmExtension ext) const
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
bool multiProc
true if this a multiprocessor system
void postInterrupt(ThreadID tid, int int_num, int index)
Register ID: describe an architectural register with its class and index.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual RegVal getReg(const RegId ®) const
virtual uint32_t socketId() const =0
virtual BaseISA * getIsaPtr() const =0
virtual BaseCPU * getCpuPtr()=0
virtual void setReg(const RegId ®, RegVal val)
virtual int threadId() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual int cpuId() const =0
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
constexpr void replaceBits(T &val, unsigned first, unsigned last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
static int regInMode(OperatingMode mode, int reg)
bool badMode(ThreadContext *tc, OperatingMode mode)
badMode is checking if the execution mode provided as an argument is valid and implemented.
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
static void mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, RegIndex &rt, uint32_t &crn, uint32_t &opc1, uint32_t &opc2)
bool isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
uint8_t encodePhysAddrRange64(int pa_size)
Returns the encoding corresponding to the specified n.
Fault mcrrMrrc15Trap(const MiscRegIndex misc_reg, ExtMachInst mach_inst, ThreadContext *tc, uint32_t imm)
void syncVecRegsToElems(ThreadContext *tc)
Fault AArch64AArch32SystemAccessTrap(const MiscRegIndex misc_reg, ExtMachInst mach_inst, ThreadContext *tc, uint32_t imm, ExceptionClass ec)
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el)
Returns true if the current exception level el is executing a Host OS or an application of a Host OS ...
bool isGenericTimerSystemAccessTrapEL3(const MiscRegIndex misc_reg, ThreadContext *tc)
ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure)
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
bool SPAlignmentCheckEnabled(ThreadContext *tc)
bool isSecure(ThreadContext *tc)
bool haveAArch32EL(ThreadContext *tc, ExceptionLevel el)
Affinity getAffinity(ArmSystem *arm_sys, ThreadContext *tc)
Retrieves MPIDR_EL1.
Fault mcrMrc15Trap(const MiscRegIndex misc_reg, ExtMachInst mach_inst, ThreadContext *tc, uint32_t imm)
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Addr maskTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, int topbit)
bool longDescFormatInUse(ThreadContext *tc)
Addr roundPage(Addr addr)
static bool unknownMode32(OperatingMode mode)
bool isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex misc_reg, ThreadContext *tc)
static bool unknownMode(OperatingMode mode)
bool isBigEndian64(const ThreadContext *tc)
bool isGenericTimerSystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool ELStateUsingAArch32(ThreadContext *tc, ExceptionLevel el, bool secure)
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
bool isGenericTimerCommonEL0HypTrap(const MiscRegIndex misc_reg, ThreadContext *tc, ExceptionClass *ec)
constexpr unsigned NumVecElemPerVecReg
bool isGenericTimerPhysHypTrap(const MiscRegIndex misc_reg, ThreadContext *tc, ExceptionClass *ec)
constexpr RegClass vecElemClass
bool isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
static RegVal getAff1(ArmSystem *arm_sys, ThreadContext *tc)
bool isGenericTimerSystemAccessTrapEL1(const MiscRegIndex misc_reg, ThreadContext *tc)
bool condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool isGenericTimerHypTrap(const MiscRegIndex misc_reg, ThreadContext *tc, ExceptionClass *ec)
SecurityState securityStateAtEL(ThreadContext *tc, ExceptionLevel el)
bool mcrMrc15TrapToHyp(const MiscRegIndex misc_reg, ThreadContext *tc, uint32_t iss, ExceptionClass *ec)
static RegVal getAff2(ArmSystem *arm_sys, ThreadContext *tc)
bool isSecureBelowEL3(ThreadContext *tc)
TranslationRegime translationRegime(ThreadContext *tc, ExceptionLevel el)
bool fgtEnabled(ThreadContext *tc)
bool isUnpriviledgeAccess(ThreadContext *tc)
bool EL2Enabled(ThreadContext *tc)
ExceptionLevel translationEl(TranslationRegime regime)
std::pair< bool, bool > ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
This function checks whether selected EL provided as an argument is using the AArch32 ISA.
SecurityState
Security State.
bool IsSecureEL2Enabled(ThreadContext *tc)
int computeAddrTop(ThreadContext *tc, bool selbit, bool is_instr, TCR tcr, ExceptionLevel el)
bool mcrMrc14TrapToHyp(const MiscRegIndex misc_reg, ThreadContext *tc, uint32_t iss)
bool isHcrxEL2Enabled(ThreadContext *tc)
bool badMode32(ThreadContext *tc, OperatingMode mode)
badMode is checking if the execution mode provided as an argument is valid and implemented for AArch3...
bool decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
@ MISCREG_ID_AA64MMFR0_EL1
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returning the value of MPIDR_EL1.
void syncVecElemsToRegs(ThreadContext *tc)
bool isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
std::pair< bool, bool > ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure)
bool condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool condGenericTimerSystemAccessTrapEL1(const MiscRegIndex misc_reg, ThreadContext *tc)
int unflattenMiscReg(int reg)
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
static ExceptionLevel opModeToEL(OperatingMode mode)
RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is either returing the value of MPIDR_EL1 (by calling getMPIDR),...
bool inAArch64(ThreadContext *tc)
bool HaveExt(ThreadContext *tc, ArmExtension ext)
Returns true if the provided ThreadContext supports the ArmExtension passed as a second argument.
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool is_instr)
Removes the tag from tagged addresses if that mode is enabled.
bool condGenericTimerPhysHypTrap(const MiscRegIndex misc_reg, ThreadContext *tc)
static RegVal getAff0(ArmSystem *arm_sys, ThreadContext *tc)
Addr truncPage(Addr addr)
bool condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
constexpr RegClass vecRegClass
bool mcrrMrrc15TrapToHyp(const MiscRegIndex misc_reg, ThreadContext *tc, uint32_t iss, ExceptionClass *ec)
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
constexpr decltype(nullptr) NoFault
PortProxy Object Declaration.