59 panic(
"getArgument() only implemented for full system mode.\n");
64 panic(
"getArgument(): Floating point arguments not implemented\n");
67 if (size == (uint16_t)(-1))
68 size =
sizeof(uint64_t);
73 panic(
"getArgument(): No support reading stack args for AArch64\n");
76 if (size == (uint16_t)(-1))
83 if (size ==
sizeof(uint64_t)) {
84 if ((number % 2) != 0)
99 if (size ==
sizeof(uint64_t)) {
101 if ((number % 2) != 0)
103 arg = vp.
read<uint64_t>(sp +
108 arg = vp.
read<uint32_t>(sp +
114 panic(
"getArgument() should always return\n");
124 if (src_mode == Enums::Full) {
160 dynamic_cast<TLB *
>(dest->
getITBPtr())->invalidateMiscReg();
161 dynamic_cast<TLB *
>(dest->
getDTBPtr())->invalidateMiscReg();
210 switch (current_el) {
216 warn_once(
"Trying to read MPIDR at EL0\n");
227 panic(
"Invalid EL for reading MPIDR register\n");
245 assert((0 <= tc->
cpuId()) && (tc->
cpuId() < 256));
248 RegVal mpidr = 0x80000000;
289 return id_aa64mmfr1.vh;
311 return id_aa64pfr0.sel2;
346 panic_if(!known,
"EL state is UNKNOWN");
356 (el ==
EL2 || (el ==
EL0 && hcr.tge == 1)));
366 panic_if(el ==
EL2 && !have_el2,
"Asking for EL2 when it doesn't exist");
367 panic_if(el ==
EL3 && !have_el3,
"Asking for EL3 when it doesn't exist");
370 known = aarch32 =
false;
374 known =
true; aarch32 =
false;
377 known =
true; aarch32 =
true;
380 bool aarch32_below_el3 = (have_el3 && scr.rw == 0);
383 bool aarch32_at_el1 = (aarch32_below_el3
388 if (el ==
EL0 && !aarch32_at_el1) {
393 aarch32 = (cpsr.width == 1);
396 aarch32 = (aarch32_below_el3 && el !=
EL3)
397 || (aarch32_at_el1 && (el ==
EL0 || el ==
EL1) );
401 return std::make_pair(known, aarch32);
417 panic(
"Invalid exception level");
448 tbi = selbit? tcr.tbi1 : tcr.tbi0;
449 tbid = selbit? tcr.tbid1 : tcr.tbid0;
456 tbi = selbit? tcr.tbi1 : tcr.tbi0;
457 tbid = selbit? tcr.tbid1 : tcr.tbid0;
476 int res = (tbi && (!tbid || !isInstr))? 55: 63;
481 TCR tcr,
bool isInstr)
483 bool selbit =
bits(addr, 55);
490 uint64_t
mask = ((uint64_t)0x1 << topbit) -1;
493 addr =
bits(addr, topbit, 0);
525 return std::make_shared<HypervisorTrap>(machInst,
imm,
ec);
539 bool trapToHype =
false;
550 trapToHype = ((uint32_t) hstr) & (1 << crn);
551 trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12);
552 trapToHype |= hcr.tidcp && (
553 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
554 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) ||
555 ((crn == 11) && ((crm <= 8) || (crm == 15))) );
560 trapToHype = hcptr.tcpac;
566 trapToHype = hcr.tid1;
572 trapToHype = hcr.tid2;
588 trapToHype = hcr.tid3;
593 trapToHype = hcr.tsw;
598 trapToHype = hcr.tpc;
604 trapToHype = hcr.tpu;
624 trapToHype = hcr.ttlb;
627 trapToHype = hcr.tac;
645 trapToHype = hcr.tvm & !isRead;
648 trapToHype = hdcr.tpmcr;
654 if (isa->haveGICv3CpuIfc())
655 trapToHype = hcr.fmo;
662 if (isa->haveGICv3CpuIfc())
663 trapToHype = hcr.imo;
686 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
694 bool trapToHype =
false;
698 inform(
"trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
699 crm, crn, opc1, opc2, hdcr, hcptr, hstr);
700 trapToHype = hdcr.tda && (opc1 == 0);
701 trapToHype |= hcptr.tta && (opc1 == 1);
708 trapToHype = hdcr.tdosa;
712 trapToHype = hdcr.tdra;
715 trapToHype = hcr.tid0;
719 trapToHype = hstr.tjdbx;
723 trapToHype = hstr.ttee;
740 return std::make_shared<HypervisorTrap>(machInst,
imm,
ec);
754 bool trapToHype =
false;
766 trapToHype = ((uint32_t) hstr) & (1 << crm);
786 trapToHype = hcr.tvm & !isRead;
812 return std::make_shared<SupervisorTrap>(machInst,
imm,
ec);
815 return std::make_shared<HypervisorTrap>(machInst, imm, ec);
865 if (
ELIs32(tc,
EL1) && trap_cond && hcr.tge) {
888 return !cnthctl.el1pcten;
890 return !cnthctl.el1pcen;
907 return !(
EL2Enabled(tc) && hcr.e2h && hcr.tge) && trap_cond &&
924 return !cntkctl.el0pcten && !cntkctl.el0vcten;
927 return !cntkctl.el0pcten;
930 return !cntkctl.el0vcten;
933 return !cntkctl.el0pten;
936 return !cntkctl.el0vten;
999 return (!
ELIs32(tc,
EL1) && !hcr.e2h && trap_cond_el1 && hcr.tge) ||
1000 (
ELIs32(tc,
EL1) && trap_cond_el1 && hcr.tge) ||
1001 (hcr.e2h && hcr.tge && trap_cond_el2);
1015 return !hcr.e2h && trap_cond_1;
1018 return (!hcr.e2h && trap_cond_0) ||
1019 (hcr.e2h && !hcr.tge && trap_cond_1);
1041 return (!hcr.e2h && trap_cond_0) ||
1042 (hcr.e2h && trap_cond_1);
1055 return !
ELIs32(tc,
EL1) && !(hcr.e2h && hcr.tge) && trap_cond;
1066 return !cnthctl.el0pcten && !cnthctl.el0vcten;
1069 return !cnthctl.el0pcten;
1072 return !cnthctl.el0vcten;
1075 return !cnthctl.el0pten;
1078 return !cnthctl.el0vten;
1092 const CNTHCTL cnthctl = cnthctl_val;
1093 const CNTHCTL_E2H cnthctl_e2h = cnthctl_val;
1097 return hcr.e2h ? !cnthctl_e2h.el1pcten : !cnthctl.el1pcten;
1103 return hcr.e2h ? cnthctl_e2h.el1tvct : cnthctl.el1tvct;
1106 return hcr.e2h ? !cnthctl_e2h.el1pten :
false;
1112 return hcr.e2h ? cnthctl_e2h.el1tvt : cnthctl.el1tvt;
1124 return !cnthctl.el1pcen;
1135 return currEL(tc) ==
EL1 && !scr.ns && !scr.st;
1145 CPSR cpsr, SCR scr, NSACR nsacr,
bool checkSecurity)
1190 int sysM4To3 =
bits(sysM, 4, 3);
1192 if (sysM4To3 == 0) {
1195 }
else if (sysM4To3 == 1) {
1198 }
else if (sysM4To3 == 3) {
1199 if (
bits(sysM, 1) == 0) {
1204 if (
bits(sysM, 0) == 1) {
1212 int sysM2 =
bits(sysM, 2);
1213 int sysM1 =
bits(sysM, 1);
1217 ((sysM2 && !sysM1) << 2) |
1218 ((sysM2 && sysM1) << 3) |
1223 ok &= mode != cpsr.mode;
1228 if (ok && checkSecurity && mode != cpsr.mode) {
1236 ok &= (mode !=
MODE_MON) || !scr.ns;
1240 ok &= (mode !=
MODE_FIQ) || !nsacr.rfr;
1248 ok &= (mode !=
MODE_MON) || !scr.ns;
1249 ok &= (mode !=
MODE_FIQ) || !nsacr.rfr;
1255 panic(
"unknown Mode 0x%x\n", cpsr.mode);
1275 panic(
"Invalid exception level");
1299 panic(
"Invalid phys. address range encoding");
1320 panic(
"Invalid phys. address range");
bool mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss, ExceptionClass *ec)
#define panic(...)
This implements a cprintf based panic() function.
static RegVal getAff0(ArmSystem *arm_sys, ThreadContext *tc)
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
bool condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
static bool unknownMode(OperatingMode mode)
decltype(nullptr) constexpr NoFault
RegVal getAffinity(ArmSystem *arm_sys, ThreadContext *tc)
Retrieves MPIDR_EL1.
bool isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
bool IsSecureEL2Enabled(ThreadContext *tc)
bool HaveVirtHostExt(ThreadContext *tc)
bool isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex miscReg, ThreadContext *tc)
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
virtual BaseTLB * getDTBPtr()=0
virtual TheISA::PCState pcState() const =0
virtual RegVal readIntReg(RegIndex reg_idx) const =0
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
bool isGenericTimerHypTrap(const MiscRegIndex miscReg, ThreadContext *tc, ExceptionClass *ec)
virtual PortProxy & getVirtProxy()=0
T read(Addr address) const
Read sizeof(T) bytes from address and return as object T.
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
bool mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss, ExceptionClass *ec)
constexpr unsigned NumVecElemPerVecReg
virtual BaseCPU * getCpuPtr()=0
static Enums::VecRegRenameMode mode(const TheISA::PCState &)
static RegVal getAff1(ArmSystem *arm_sys, ThreadContext *tc)
bool mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
virtual RegVal readCCReg(RegIndex reg_idx) const =0
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool isInstr)
Removes the tag from tagged addresses if that mode is enabled.
RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is either returing the value of MPIDR_EL1 (by calling getMPIDR), or it is issuing a read to VMPIDR_EL2 (as it happens in virtualized systems)
static RegVal getAff2(ArmSystem *arm_sys, ThreadContext *tc)
ThreadContext is the external interface to all thread state for anything outside of the CPU...
static ExceptionLevel currEL(const ThreadContext *tc)
Fault AArch64AArch32SystemAccessTrap(const MiscRegIndex miscReg, ExtMachInst machInst, ThreadContext *tc, uint32_t imm, ExceptionClass ec)
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returning the value of MPIDR_EL1.
bool isGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg, ThreadContext *tc)
static bool haveEL(ThreadContext *tc, ExceptionLevel el)
Return true if the system implements a specific exception level.
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
bool HaveSecureEL2Ext(ThreadContext *tc)
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
bool isSecureBelowEL3(ThreadContext *tc)
uint8_t encodePhysAddrRange64(int pa_size)
Returns the encoding corresponding to the specified n.
PortProxy Object Declaration.
bool isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr, TCR tcr, ExceptionLevel el)
int unflattenMiscReg(int reg)
bool isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
bool isGenericTimerCommonEL0HypTrap(const MiscRegIndex miscReg, ThreadContext *tc, ExceptionClass *ec)
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
virtual int cpuId() const =0
bool multiProc
true if this a multiprocessor system
uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
const int StackPointerReg
virtual const VecElem & readVecElemFlat(RegIndex idx, const ElemIndex &elemIdx) const =0
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
bool SPAlignmentCheckEnabled(ThreadContext *tc)
static ExceptionLevel opModeToEL(OperatingMode mode)
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
virtual BaseTLB * getITBPtr()=0
virtual const VecRegContainer & readVecRegFlat(RegIndex idx) const =0
virtual void setFloatRegFlat(RegIndex idx, RegVal val)=0
static void copyVecRegs(ThreadContext *src, ThreadContext *dest)
bool condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
const int NumArgumentRegs
virtual void setVecElemFlat(RegIndex idx, const ElemIndex &elemIdx, const VecElem &val)=0
std::pair< bool, bool > ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
This function checks whether selected EL provided as an argument is using the AArch32 ISA...
virtual void setCCReg(RegIndex reg_idx, RegVal val)=0
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
virtual BaseISA * getIsaPtr()=0
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Addr roundPage(Addr addr)
bool isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
Fault mcrMrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst, ThreadContext *tc, uint32_t imm)
Addr truncPage(Addr addr)
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
bool decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
bool isGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc, ExceptionClass *ec)
This object is a proxy for a port or other object which implements the functional response protocol...
Fault mcrrMrrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst, ThreadContext *tc, uint32_t imm)
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
static bool unknownMode32(OperatingMode mode)
bool longDescFormatInUse(ThreadContext *tc)
ExceptionLevel highestEL() const
Returns the highest implemented exception level.
static void mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, IntRegIndex &rt, uint32_t &crn, uint32_t &opc1, uint32_t &opc2)
virtual int threadId() const =0
bool isBigEndian64(const ThreadContext *tc)
virtual RegVal readIntRegFlat(RegIndex idx) const =0
Flat register interfaces.
virtual uint32_t socketId() const =0
virtual void setVecRegFlat(RegIndex idx, const VecRegContainer &val)=0
bool inAArch64(ThreadContext *tc)
virtual RegVal readFloatRegFlat(RegIndex idx) const =0
virtual void setIntRegFlat(RegIndex idx, RegVal val)=0
bool inSecureState(ThreadContext *tc)
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 ...
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
bool EL2Enabled(ThreadContext *tc)
void copyRegs(ThreadContext *src, ThreadContext *dest)
bool condGenericTimerPhysHypTrap(const MiscRegIndex miscReg, 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...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual RegVal readMiscReg(RegIndex misc_reg)=0
bool badMode(ThreadContext *tc, OperatingMode mode)
badMode is checking if the execution mode provided as an argument is valid and implemented.
bool condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
std::shared_ptr< FaultBase > Fault
void postInterrupt(ThreadID tid, int int_num, int index)
bool condGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg, ThreadContext *tc)
static int intRegInMode(OperatingMode mode, int reg)
bool isGenericTimerSystemAccessTrapEL3(const MiscRegIndex miscReg, ThreadContext *tc)
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
bool isGenericTimerSystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)
bool isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg, ThreadContext *tc)