56 #include "debug/Faults.hh"
105 "Invalid size of ArmFault::shortDescFaultSources[]");
150 "Invalid size of ArmFault::longDescFaultSources[]");
196 "Invalid size of ArmFault::aarch64FaultSources[]");
204 "Reset", 0x000, 0x000, 0x000, 0x000, 0x000,
MODE_SVC,
208 "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600,
MODE_UNDEFINED,
212 "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
216 "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_MON,
220 "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_HYP,
224 "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
228 "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
232 "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
237 "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600,
MODE_HYP,
241 "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680,
MODE_IRQ,
245 "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680,
MODE_IRQ,
249 "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700,
MODE_FIQ,
253 "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700,
MODE_FIQ,
258 "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
263 "Secure Monitor Trap", 0x014, 0x000, 0x200, 0x400, 0x600,
MODE_MON,
268 "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
273 "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
278 "SError", 0x000, 0x180, 0x380, 0x580, 0x780,
MODE_SVC,
283 "Pipe Flush", 0x000, 0x000, 0x000, 0x000, 0x000,
MODE_SVC,
288 "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000,
MODE_SVC,
293 "Illegal Inst Set State Fault", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
311 assert(haveSecurity || cpsr.mode !=
MODE_MON);
350 panic(
"Invalid target exception level");
367 panic(
"Invalid exception level");
383 panic(
"Invalid exception level");
392 uint32_t exc_class = (uint32_t)
ec(tc);
393 uint32_t issVal =
iss();
396 value = exc_class << 26;
404 }
else if ((
bits(exc_class, 5, 3) != 4) ||
405 (
bits(exc_class, 2) &&
bits(issVal, 24))) {
410 if (!
from64 && ((
bits(exc_class, 5, 4) == 0) &&
411 (
bits(exc_class, 3, 0) != 0))) {
421 value |=
bits(issVal, 19, 0);
477 ITSTATE it = tc->
pcState().itstate();
478 saved_cpsr.it2 = it.top6;
479 saved_cpsr.it1 = it.bottom2;
491 else if (have_virtualization &&
routeToHyp(tc))
497 if (have_security && saved_cpsr.mode ==
MODE_MON) {
510 if (!scr.ea) {cpsr.a = 1;}
511 if (!scr.fiq) {cpsr.f = 1;}
512 if (!scr.irq) {cpsr.i = 1;}
529 cpsr.it1 = cpsr.it2 = 0;
558 assert(have_security);
570 assert(have_virtualization);
575 panic(
"unknown Mode\n");
579 DPRINTF(Faults,
"Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n",
583 pc.nextThumb(pc.thumb());
585 pc.nextJazelle(pc.jazelle());
586 pc.aarch64(!cpsr.width);
587 pc.nextAArch64(!cpsr.width);
612 panic(
"Invalid target exception level");
633 ITSTATE it = tc->
pcState().itstate();
635 spsr.it1 = it.bottom2;
644 Addr ret_addr = curr_pc;
652 OperatingMode64
mode = 0;
664 DPRINTF(Faults,
"Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x "
665 "elr:%#x newVec: %#x\n",
name(), cpsr, curr_pc, ret_addr, new_pc);
667 pc.aarch64(!cpsr.width);
668 pc.nextAArch64(!cpsr.width);
704 pc.nextAArch64(
true);
720 panic(
"Attempted to execute disabled instruction "
723 panic(
"Attempted to execute unknown instruction (inst 0x%08x)",
726 panic(
"Attempted to execute unimplemented instruction "
741 toHyp = scr.ns && (cpsr.mode ==
MODE_HYP);
753 uint32_t new_iss = 0;
754 uint32_t op0, op1, op2, CRn, CRm, Rt, dir;
764 new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 |
765 Rt << 5 | CRm << 1 | dir;
783 if (opModeIs64(mode))
807 toHyp = scr.ns && (cpsr.mode ==
MODE_HYP);
863 bool isHypTrap =
false;
869 if (vals.hypTrappable) {
876 return isHypTrap ? 0x14 : vals.offset;
932 bool override_LPAE =
false;
936 override_LPAE =
true;
940 DPRINTF(Faults,
"Warning: Incomplete translation method "
941 "override detected.\n");
953 FSR fsr = getFsr(tc);
969 DPRINTF(Faults,
"Abort Fault source=%#x fsr=%#x faultAddr=%#x "\
970 "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod);
980 DPRINTF(Faults,
"Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
999 fsr.status = srcEncoded;
1003 fsr.fsLow =
bits(srcEncoded, 3, 0);
1004 fsr.fsHigh =
bits(srcEncoded, 4);
1005 fsr.domain =
static_cast<uint8_t
>(
domain);
1007 fsr.wnr = (write ? 1 : 0);
1014 panic(
"Invalid fault source\n");
1025 return (!scr.ns || scr.aw);
1055 val = srcEncoded & 0x3F;
1126 toHyp = scr.ns && (cpsr.mode ==
MODE_HYP);
1141 panic(
"Asynchronous External Abort should be handled with "
1142 "SystemErrors (SErrors)!");
1187 toHyp = scr.ns && (cpsr.mode ==
MODE_HYP);
1193 ( (cpsr.mode ==
MODE_USER) && hcr.tge &&
1297 return (!scr.ns || scr.aw);
1336 return (!scr.ns || scr.aw);
1348 return (!scr.ns || scr.fw);
1403 DPRINTF(Faults,
"Invoking FlushPipe Fault\n");
1416 DPRINTF(Faults,
"Invoking ArmSev Fault\n");
ExceptionClass overrideEc
bool abortDisable(ThreadContext *tc)
bool abortDisable(ThreadContext *tc)
static uint8_t aarch64FaultSources[NumFaultSources]
Encodings of the fault sources in AArch64 state.
virtual uint8_t armPcElrOffset()=0
bool routeToHyp(ThreadContext *tc) const
virtual void syscall(int64_t callnum, Fault *fault)=0
virtual System * getSystemPtr()=0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
bool routeToMonitor(ThreadContext *tc) const
ExceptionClass overrideEc
ExceptionClass ec(ThreadContext *tc) const
virtual CCReg readCCReg(int reg_idx)=0
virtual FaultOffset offset(ThreadContext *tc)=0
ExceptionLevel highestEL() const
Returns the highest implemented exception level.
virtual MiscReg readMiscRegNoEffect(int misc_reg) const =0
T * get() const
Directly access the pointer itself without taking a reference.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
virtual void setMiscReg(int misc_reg, const MiscReg &val)=0
virtual void annotateFault(ArmFault *fault)
virtual void setIntReg(int reg_idx, uint64_t val)=0
virtual BaseCPU * getCpuPtr()=0
MiscRegIndex getFaultAddrReg64() const
virtual TheISA::PCState pcState()=0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
ExceptionClass ec(ThreadContext *tc) const
bool abortDisable(ThreadContext *tc)
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void invoke(ThreadContext *tc, const StaticInstPtr &inst)
virtual bool fiqDisable(ThreadContext *tc)=0
virtual FaultName name() const =0
bool routeToHyp(ThreadContext *tc) const
Bitfield< 31, 28 > condCode
virtual bool routeToHyp(ThreadContext *tc) const
static uint8_t shortDescFaultSources[NumFaultSources]
Encodings of the fault sources when the short-desc.
virtual FaultOffset offset64()=0
ExceptionClass overrideEc
ExceptionClass ec(ThreadContext *tc) const
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
ExceptionClass ec(ThreadContext *tc) const
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
bool routeToMonitor(ThreadContext *tc) const
virtual uint64_t readIntReg(int reg_idx)=0
static uint8_t longDescFaultSources[NumFaultSources]
Encodings of the fault sources when the long-desc.
bool routeToHyp(ThreadContext *tc) const
void annotate(AnnotationIDs id, uint64_t val)
ExceptionClass overrideEc
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
bool routeToHyp(ThreadContext *tc) const
virtual bool abortDisable(ThreadContext *tc)=0
static ExceptionLevel opModeToEL(OperatingMode mode)
bool routeToMonitor(ThreadContext *tc) const
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
FSR getFsr(ThreadContext *tc)
ExceptionClass ec(ThreadContext *tc) const
MiscRegIndex getSyndromeReg64() const
bool routeToHyp(ThreadContext *tc) const
HypervisorCall(ExtMachInst _machInst, uint32_t _imm)
ExceptionClass ec(ThreadContext *tc) const
virtual FaultStat & countStat()=0
virtual bool routeToMonitor(ThreadContext *tc) const =0
virtual uint8_t thumbPcOffset(bool isHyp)=0
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Addr getVector64(ThreadContext *tc)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void invoke64(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
virtual MiscReg readMiscReg(int misc_reg)=0
virtual OperatingMode nextMode()=0
static const int NumArgumentRegs M5_VAR_USED
virtual uint8_t thumbPcElrOffset()=0
bool routeToHyp(ThreadContext *tc) const
virtual uint32_t iss() const =0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
Addr getVector(ThreadContext *tc)
bool longDescFormatInUse(ThreadContext *tc)
bool routeToHyp(ThreadContext *tc) const
ExceptionClass ec(ThreadContext *tc) const
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
virtual void advancePC(TheISA::PCState &pcState) const =0
virtual ExceptionClass ec(ThreadContext *tc) const
GenericISA::SimplePCState< MachInst > PCState
virtual int threadId() const =0
ExceptionClass ec(ThreadContext *tc) const
void annotate(ArmFault::AnnotationIDs id, uint64_t val)
bool routeToMonitor(ThreadContext *tc) const
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
virtual void clearArchRegs()=0
virtual uint8_t armPcOffset(bool isHyp)=0
ExceptionClass ec(ThreadContext *tc) const
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
FaultOffset offset(ThreadContext *tc)
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TTBCR tcr)
Removes the tag from tagged addresses if that mode is enabled.
IllegalInstSetStateFault()
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
bool routeToMonitor(ThreadContext *tc) const
uint32_t getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
virtual void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
bool inSecureState(ThreadContext *tc)
virtual ExceptionClass ec(ThreadContext *tc) const =0
bool fiqDisable(ThreadContext *tc)
Addr faultPC
The unaligned value of the PC.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
virtual void setMiscRegNoEffect(int misc_reg, const MiscReg &val)=0
std::shared_ptr< FaultBase > Fault
ExceptionClass overrideEc
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
Addr resetAddr64() const
Returns the reset address if the highest implemented exception level is 64 bits (ARMv8) ...