106 (!secure ||
HaveExt(tc, ArmExtension::FEAT_SEL2))) {
109 route_to_el2 = (mdcr.tde == 1 || hcr.tge == 1);
111 route_to_el2 =
false;
151 switch (current_el) {
157 warn_once(
"Trying to read MPIDR at EL0\n");
168 panic(
"Invalid EL for reading MPIDR register\n");
186 assert((0 <= tc->
cpuId()) && (tc->
cpuId() < 256));
189 RegVal mpidr = 0x80000000;
224 aff.aff0 =
getAff0(arm_sys, tc);
225 aff.aff1 =
getAff1(arm_sys, tc);
226 aff.aff2 =
getAff2(arm_sys, tc);
258 return !
ELIs32(tc,
EL3) &&
static_cast<SCR
>(
285 panic_if(!known,
"EL state is UNKNOWN");
295 HaveExt(tc, ArmExtension::FEAT_VHE) &&
328 panic_if(
el ==
EL2 && !have_el2,
"Asking for EL2 when it doesn't exist");
329 panic_if(
el ==
EL3 && !have_el3,
"Asking for EL3 when it doesn't exist");
332 known = aarch32 =
false;
336 known =
true; aarch32 =
false;
337 }
else if (secure &&
el ==
EL2) {
338 known =
true; aarch32 =
false;
341 known =
true; aarch32 =
true;
343 known =
true; aarch32 =
false;
346 bool aarch32_below_el3 = have_el3 && scr.rw == 0 &&
347 (!secure || !
HaveExt(tc, ArmExtension::FEAT_SEL2) || !scr.eel2);
350 bool sec_el2 =
HaveExt(tc, ArmExtension::FEAT_SEL2) && scr.eel2;
351 bool aarch32_at_el1 = (aarch32_below_el3 ||
352 (have_el2 && (sec_el2 || !secure) &&
354 !(hcr.e2h && hcr.tge &&
355 HaveExt(tc, ArmExtension::FEAT_VHE))));
358 if (
el ==
EL0 && !aarch32_at_el1) {
362 aarch32 = (cpsr.width == 1);
365 aarch32 = (aarch32_below_el3 &&
el !=
EL3) ||
366 (aarch32_at_el1 && (
el ==
EL0 ||
el ==
EL1) );
370 return std::make_pair(known, aarch32);
377 panic_if(!known,
"EL state is UNKNOWN");
394 panic(
"Invalid exception level");
425 tbi = selbit? tcr.tbi1 : tcr.tbi0;
426 tbid = selbit? tcr.tbid1 : tcr.tbid0;
433 tbi = selbit? tcr.tbi1 : tcr.tbi0;
434 tbid = selbit? tcr.tbid1 : tcr.tbid0;
453 int res = (
tbi && (!
tbid || !is_instr))? 55: 63;
464 uint64_t
mask = ((uint64_t)0x1 << topbit) -1;
474 TCR tcr,
bool is_instr)
509 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
523 bool trap_to_hyp =
false;
532 trap_to_hyp = ((uint32_t) hstr) & (1 << crn);
533 trap_to_hyp |= hdcr.tpm && (crn == 9) && (crm >= 12);
534 trap_to_hyp |= hcr.tidcp && (
535 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
536 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) ||
537 ((crn == 11) && ((crm <= 8) || (crm == 15))));
542 trap_to_hyp = hcptr.tcpac;
548 trap_to_hyp = hcr.tid1;
554 trap_to_hyp = hcr.tid2;
572 trap_to_hyp = hcr.tid3;
577 trap_to_hyp = hcr.tsw;
582 trap_to_hyp = hcr.tpc;
588 trap_to_hyp = hcr.tpu;
608 trap_to_hyp = hcr.ttlb;
611 trap_to_hyp = hcr.tac;
629 trap_to_hyp = hcr.tvm & !is_read;
632 trap_to_hyp = hdcr.tpmcr;
636 trap_to_hyp = hcr.fmo;
640 trap_to_hyp = hcr.imo;
675 bool trap_to_hyp =
false;
679 inform(
"trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
680 crm, crn, opc1,
opc2, hdcr, hcptr, hstr);
681 trap_to_hyp = hdcr.tda && (opc1 == 0);
682 trap_to_hyp |= hcptr.tta && (opc1 == 1);
689 trap_to_hyp = hdcr.tdosa;
693 trap_to_hyp = hdcr.tdra;
696 trap_to_hyp = hcr.tid0;
700 trap_to_hyp = hstr.tjdbx;
704 trap_to_hyp = hstr.ttee;
721 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
735 bool trap_to_hyp =
false;
745 trap_to_hyp = ((uint32_t)hstr) & (1 << crm);
765 trap_to_hyp = hcr.tvm & !is_read;
792 return std::make_shared<SupervisorTrap>(mach_inst,
imm,
ec);
795 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
845 if (
ELIs32(tc,
EL1) && trap_cond && hcr.tge) {
868 return !cnthctl.el1pcten;
870 return !cnthctl.el1pcen;
887 return !(
EL2Enabled(tc) && hcr.e2h && hcr.tge) && trap_cond &&
904 return !cntkctl.el0pcten && !cntkctl.el0vcten;
907 return !cntkctl.el0pcten;
910 return !cntkctl.el0vcten;
913 return !cntkctl.el0pten;
916 return !cntkctl.el0vten;
979 return (!
ELIs32(tc,
EL1) && !hcr.e2h && trap_cond_el1 && hcr.tge) ||
980 (
ELIs32(tc,
EL1) && trap_cond_el1 && hcr.tge) ||
981 (hcr.e2h && hcr.tge && trap_cond_el2);
997 return !hcr.e2h && trap_cond_1;
1000 return (!hcr.e2h && trap_cond_0) ||
1001 (hcr.e2h && !hcr.tge && trap_cond_1);
1025 return (!hcr.e2h && trap_cond_0) ||
1026 (hcr.e2h && trap_cond_1);
1040 return !
ELIs32(tc,
EL1) && !(hcr.e2h && hcr.tge) && trap_cond;
1051 return !cnthctl.el0pcten && !cnthctl.el0vcten;
1054 return !cnthctl.el0pcten;
1057 return !cnthctl.el0vcten;
1060 return !cnthctl.el0pten;
1063 return !cnthctl.el0vten;
1077 const CNTHCTL cnthctl = cnthctl_val;
1078 const CNTHCTL_E2H cnthctl_e2h = cnthctl_val;
1082 return hcr.e2h ? !cnthctl_e2h.el1pcten : !cnthctl.el1pcten;
1088 return hcr.e2h ? cnthctl_e2h.el1tvct : cnthctl.el1tvct;
1091 return hcr.e2h ? !cnthctl_e2h.el1pten :
false;
1097 return hcr.e2h ? cnthctl_e2h.el1tvt : cnthctl.el1tvt;
1109 return !cnthctl.el1pcen;
1120 return currEL(tc) ==
EL1 && !scr.ns && !scr.st;
1130 CPSR cpsr, SCR scr, NSACR nsacr,
bool checkSecurity)
1174 int sysM4To3 =
bits(sysM, 4, 3);
1176 if (sysM4To3 == 0) {
1179 }
else if (sysM4To3 == 1) {
1182 }
else if (sysM4To3 == 3) {
1183 if (
bits(sysM, 1) == 0) {
1188 if (
bits(sysM, 0) == 1) {
1196 int sysM2 =
bits(sysM, 2);
1197 int sysM1 =
bits(sysM, 1);
1201 ((sysM2 && !sysM1) << 2) |
1202 ((sysM2 && sysM1) << 3) |
1207 ok &=
mode != cpsr.mode;
1212 if (ok && checkSecurity &&
mode != cpsr.mode) {
1213 switch (cpsr.mode) {
1238 panic(
"unknown Mode 0x%x\n", cpsr.mode);
1252 bool have_nv_ext =
false;
1255 have_nv_ext && hcr.nv == 1 && hcr.nv1 == 1);
1257 HaveExt(tc, ArmExtension::FEAT_VHE) &&
1258 currEL(tc) ==
EL2 && hcr.e2h == 1 && hcr.tge == 1;
1260 return (unpriv_el1 || unpriv_el2) && !cpsr.uao;
1282 panic(
"Invalid exception level");
1306 panic(
"Invalid phys. address range encoding");
1329 panic(
"Invalid phys. address range");
1393 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)
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.
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)
bool isSecureAtEL(ThreadContext *tc, ExceptionLevel el)
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 - Pranith Kumar Copyright (c) 2020 Inria 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.