Go to the documentation of this file.
96 (!secure ||
HaveExt(tc, ArmExtension::FEAT_SEL2))) {
100 route_to_el2 = (hdcr.tde == 1 || hcr.tge == 1);
104 route_to_el2 = (mdcr.tde == 1 || hcr.tge == 1);
107 route_to_el2 =
false;
149 switch (current_el) {
155 warn_once(
"Trying to read MPIDR at EL0\n");
166 panic(
"Invalid EL for reading MPIDR register\n");
184 assert((0 <= tc->
cpuId()) && (tc->
cpuId() < 256));
187 RegVal mpidr = 0x80000000;
222 aff.aff0 =
getAff0(arm_sys, tc);
223 aff.aff1 =
getAff1(arm_sys, tc);
224 aff.aff2 =
getAff2(arm_sys, tc);
255 return !
ELIs32(tc,
EL3) &&
static_cast<SCR
>(
282 panic_if(!known,
"EL state is UNKNOWN");
292 HaveExt(tc, ArmExtension::FEAT_VHE) &&
325 panic_if(
el ==
EL2 && !have_el2,
"Asking for EL2 when it doesn't exist");
326 panic_if(
el ==
EL3 && !have_el3,
"Asking for EL3 when it doesn't exist");
329 known = aarch32 =
false;
333 known =
true; aarch32 =
false;
334 }
else if (secure &&
el ==
EL2) {
335 known =
true; aarch32 =
false;
338 known =
true; aarch32 =
true;
340 known =
true; aarch32 =
false;
343 bool aarch32_below_el3 = have_el3 && scr.rw == 0 &&
344 (!secure || !
HaveExt(tc, ArmExtension::FEAT_SEL2) || !scr.eel2);
347 bool sec_el2 =
HaveExt(tc, ArmExtension::FEAT_SEL2) && scr.eel2;
348 bool aarch32_at_el1 = (aarch32_below_el3 ||
349 (have_el2 && (sec_el2 || !secure) &&
351 !(hcr.e2h && hcr.tge &&
352 HaveExt(tc, ArmExtension::FEAT_VHE))));
355 if (
el ==
EL0 && !aarch32_at_el1) {
359 aarch32 = (cpsr.width == 1);
362 aarch32 = (aarch32_below_el3 &&
el !=
EL3) ||
363 (aarch32_at_el1 && (
el ==
EL0 ||
el ==
EL1) );
367 return std::make_pair(known, aarch32);
374 panic_if(!known,
"EL state is UNKNOWN");
391 panic(
"Invalid exception level");
422 tbi = selbit? tcr.tbi1 : tcr.tbi0;
423 tbid = selbit? tcr.tbid1 : tcr.tbid0;
430 tbi = selbit? tcr.tbi1 : tcr.tbi0;
431 tbid = selbit? tcr.tbid1 : tcr.tbid0;
450 int res = (
tbi && (!
tbid || !is_instr))? 55: 63;
461 uint64_t
mask = ((uint64_t)0x1 << topbit) -1;
471 TCR tcr,
bool is_instr)
506 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
520 bool trap_to_hyp =
false;
529 trap_to_hyp = ((uint32_t) hstr) & (1 << crn);
530 trap_to_hyp |= hdcr.tpm && (crn == 9) && (crm >= 12);
531 trap_to_hyp |= hcr.tidcp && (
532 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
533 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) ||
534 ((crn == 11) && ((crm <= 8) || (crm == 15))));
539 trap_to_hyp = hcptr.tcpac;
545 trap_to_hyp = hcr.tid1;
551 trap_to_hyp = hcr.tid2;
569 trap_to_hyp = hcr.tid3;
574 trap_to_hyp = hcr.tsw;
579 trap_to_hyp = hcr.tpc;
585 trap_to_hyp = hcr.tpu;
605 trap_to_hyp = hcr.ttlb;
608 trap_to_hyp = hcr.tac;
626 trap_to_hyp = hcr.tvm & !is_read;
629 trap_to_hyp = hdcr.tpmcr;
635 if (isa->haveGICv3CpuIfc())
636 trap_to_hyp = hcr.fmo;
643 if (isa->haveGICv3CpuIfc())
644 trap_to_hyp = hcr.imo;
680 bool trap_to_hyp =
false;
684 inform(
"trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
685 crm, crn, opc1,
opc2, hdcr, hcptr, hstr);
686 trap_to_hyp = hdcr.tda && (opc1 == 0);
687 trap_to_hyp |= hcptr.tta && (opc1 == 1);
694 trap_to_hyp = hdcr.tdosa;
698 trap_to_hyp = hdcr.tdra;
701 trap_to_hyp = hcr.tid0;
705 trap_to_hyp = hstr.tjdbx;
709 trap_to_hyp = hstr.ttee;
726 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
740 bool trap_to_hyp =
false;
750 trap_to_hyp = ((uint32_t)hstr) & (1 << crm);
770 trap_to_hyp = hcr.tvm & !is_read;
797 return std::make_shared<SupervisorTrap>(mach_inst,
imm,
ec);
800 return std::make_shared<HypervisorTrap>(mach_inst,
imm,
ec);
850 if (
ELIs32(tc,
EL1) && trap_cond && hcr.tge) {
873 return !cnthctl.el1pcten;
875 return !cnthctl.el1pcen;
892 return !(
EL2Enabled(tc) && hcr.e2h && hcr.tge) && trap_cond &&
909 return !cntkctl.el0pcten && !cntkctl.el0vcten;
912 return !cntkctl.el0pcten;
915 return !cntkctl.el0vcten;
918 return !cntkctl.el0pten;
921 return !cntkctl.el0vten;
984 return (!
ELIs32(tc,
EL1) && !hcr.e2h && trap_cond_el1 && hcr.tge) ||
985 (
ELIs32(tc,
EL1) && trap_cond_el1 && hcr.tge) ||
986 (hcr.e2h && hcr.tge && trap_cond_el2);
1002 return !hcr.e2h && trap_cond_1;
1005 return (!hcr.e2h && trap_cond_0) ||
1006 (hcr.e2h && !hcr.tge && trap_cond_1);
1030 return (!hcr.e2h && trap_cond_0) ||
1031 (hcr.e2h && trap_cond_1);
1045 return !
ELIs32(tc,
EL1) && !(hcr.e2h && hcr.tge) && trap_cond;
1056 return !cnthctl.el0pcten && !cnthctl.el0vcten;
1059 return !cnthctl.el0pcten;
1062 return !cnthctl.el0vcten;
1065 return !cnthctl.el0pten;
1068 return !cnthctl.el0vten;
1082 const CNTHCTL cnthctl = cnthctl_val;
1083 const CNTHCTL_E2H cnthctl_e2h = cnthctl_val;
1087 return hcr.e2h ? !cnthctl_e2h.el1pcten : !cnthctl.el1pcten;
1093 return hcr.e2h ? cnthctl_e2h.el1tvct : cnthctl.el1tvct;
1096 return hcr.e2h ? !cnthctl_e2h.el1pten :
false;
1102 return hcr.e2h ? cnthctl_e2h.el1tvt : cnthctl.el1tvt;
1114 return !cnthctl.el1pcen;
1125 return currEL(tc) ==
EL1 && !scr.ns && !scr.st;
1135 CPSR cpsr, SCR scr, NSACR nsacr,
bool checkSecurity)
1179 int sysM4To3 =
bits(sysM, 4, 3);
1181 if (sysM4To3 == 0) {
1183 regIdx = int_reg::regInMode(
mode,
bits(sysM, 2, 0) + 8);
1184 }
else if (sysM4To3 == 1) {
1186 regIdx = int_reg::regInMode(
mode,
bits(sysM, 2, 0) + 8);
1187 }
else if (sysM4To3 == 3) {
1188 if (
bits(sysM, 1) == 0) {
1190 regIdx = int_reg::regInMode(
mode, 14 -
bits(sysM, 0));
1193 if (
bits(sysM, 0) == 1) {
1194 regIdx = int_reg::regInMode(
mode, 13);
1201 int sysM2 =
bits(sysM, 2);
1202 int sysM1 =
bits(sysM, 1);
1206 ((sysM2 && !sysM1) << 2) |
1207 ((sysM2 && sysM1) << 3) |
1209 regIdx = int_reg::regInMode(
mode, 14 -
bits(sysM, 0));
1212 ok &=
mode != cpsr.mode;
1217 if (ok && checkSecurity &&
mode != cpsr.mode) {
1218 switch (cpsr.mode) {
1243 panic(
"unknown Mode 0x%x\n", cpsr.mode);
1257 bool have_nv_ext =
false;
1260 have_nv_ext && hcr.nv == 1 && hcr.nv1 == 1);
1262 HaveExt(tc, ArmExtension::FEAT_VHE) &&
1263 currEL(tc) ==
EL2 && hcr.e2h == 1 && hcr.tge == 1;
1265 return (unpriv_el1 || unpriv_el2) && !cpsr.uao;
1287 panic(
"Invalid exception level");
1311 panic(
"Invalid phys. address range encoding");
1334 panic(
"Invalid phys. address range");
constexpr unsigned NumVecElemPerVecReg
static void mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, RegIndex &rt, uint32_t &crn, uint32_t &opc1, uint32_t &opc2)
Addr maskTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, int topbit)
virtual RegVal readMiscReg(RegIndex misc_reg)=0
constexpr decltype(nullptr) NoFault
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Affinity getAffinity(ArmSystem *arm_sys, ThreadContext *tc)
Retrieves MPIDR_EL1.
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
@ VecElemClass
Vector Register Native Elem lane.
bool isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
virtual RegVal getReg(const RegId ®) const
bool isGenericTimerHypTrap(const MiscRegIndex misc_reg, ThreadContext *tc, ExceptionClass *ec)
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
@ EC_TRAPPED_CP15_MCR_MRC
bool isGenericTimerSystemAccessTrapEL1(const MiscRegIndex misc_reg, ThreadContext *tc)
bool isGenericTimerCommonEL0HypTrap(const MiscRegIndex misc_reg, ThreadContext *tc, ExceptionClass *ec)
uint8_t encodePhysAddrRange64(int pa_size)
Returns the encoding corresponding to the specified n.
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.
bool isSecureBelowEL3(ThreadContext *tc)
bool isGenericTimerSystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool mcrrMrrc15TrapToHyp(const MiscRegIndex misc_reg, ThreadContext *tc, uint32_t iss, ExceptionClass *ec)
@ MISCREG_ID_AA64MMFR0_EL1
static ExceptionLevel opModeToEL(OperatingMode mode)
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 isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool inAArch64(ThreadContext *tc)
bool badMode(ThreadContext *tc, OperatingMode mode)
badMode is checking if the execution mode provided as an argument is valid and implemented.
virtual int cpuId() const =0
Fault AArch64AArch32SystemAccessTrap(const MiscRegIndex misc_reg, ExtMachInst mach_inst, ThreadContext *tc, uint32_t imm, ExceptionClass ec)
Addr truncPage(Addr addr)
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 condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool condGenericTimerSystemAccessTrapEL1(const MiscRegIndex misc_reg, ThreadContext *tc)
bool mcrMrc14TrapToHyp(const MiscRegIndex misc_reg, ThreadContext *tc, uint32_t iss)
Fault mcrMrc15Trap(const MiscRegIndex misc_reg, ExtMachInst mach_inst, ThreadContext *tc, uint32_t imm)
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool is_instr)
Removes the tag from tagged addresses if that mode is enabled.
static bool unknownMode32(OperatingMode mode)
bool isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
bool has(ArmExtension ext) const
static RegVal getAff1(ArmSystem *arm_sys, ThreadContext *tc)
bool multiProc
true if this a multiprocessor system
static RegVal getAff2(ArmSystem *arm_sys, ThreadContext *tc)
ArmISA::ExceptionLevel highestEL() const
Returns the highest implemented exception level.
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
virtual uint32_t socketId() const =0
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Fault mcrrMrrc15Trap(const MiscRegIndex misc_reg, ExtMachInst mach_inst, ThreadContext *tc, uint32_t imm)
bool condGenericTimerPhysHypTrap(const MiscRegIndex misc_reg, ThreadContext *tc)
std::shared_ptr< FaultBase > Fault
Addr roundPage(Addr addr)
static bool unknownMode(OperatingMode mode)
@ EC_TRAPPED_CP15_MCRR_MRRC
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
void syncVecElemsToRegs(ThreadContext *tc)
bool EL2Enabled(ThreadContext *tc)
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
bool SPAlignmentCheckEnabled(ThreadContext *tc)
bool mcrMrc15TrapToHyp(const MiscRegIndex misc_reg, ThreadContext *tc, uint32_t iss, ExceptionClass *ec)
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool isSecure(ThreadContext *tc)
std::pair< bool, bool > ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure)
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
bool has(ArmExtension ext) const
bool IsSecureEL2Enabled(ThreadContext *tc)
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
void syncVecRegsToElems(ThreadContext *tc)
bool decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
bool isUnpriviledgeAccess(ThreadContext *tc)
static RegVal getAff0(ArmSystem *arm_sys, ThreadContext *tc)
bool isGenericTimerSystemAccessTrapEL3(const MiscRegIndex misc_reg, ThreadContext *tc)
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
bool ELStateUsingAArch32(ThreadContext *tc, ExceptionLevel el, bool secure)
bool longDescFormatInUse(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 haveAArch32EL(ThreadContext *tc, ExceptionLevel el)
bool isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
virtual BaseCPU * getCpuPtr()=0
virtual int threadId() const =0
bool condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
@ VecRegClass
Vector Register.
virtual BaseISA * getIsaPtr() const =0
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
bool condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
int computeAddrTop(ThreadContext *tc, bool selbit, bool is_instr, TCR tcr, ExceptionLevel el)
bool isGenericTimerPhysHypTrap(const MiscRegIndex misc_reg, ThreadContext *tc, ExceptionClass *ec)
bool isBigEndian64(const ThreadContext *tc)
bool isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex misc_reg, ThreadContext *tc)
const ArmRelease * getRelease() const
bool HaveExt(ThreadContext *tc, ArmExtension ext)
Returns true if the provided ThreadContext supports the ArmExtension passed as a second argument.
bool isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex misc_reg, ThreadContext *tc)
RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is either returing the value of MPIDR_EL1 (by calling getMPIDR),...
int unflattenMiscReg(int reg)
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returning the value of MPIDR_EL1.
Register ID: describe an architectural register with its class and index.
#define panic(...)
This implements a cprintf based panic() function.
virtual void setReg(const RegId ®, RegVal val)
Generated on Wed Jul 13 2022 10:39:12 for gem5 by doxygen 1.8.17