51 #include "debug/Faults.hh" 98 static_assert(
sizeof(ArmFault::shortDescFaultSources) ==
100 "Invalid size of ArmFault::shortDescFaultSources[]");
143 static_assert(
sizeof(ArmFault::longDescFaultSources) ==
145 "Invalid size of ArmFault::longDescFaultSources[]");
189 static_assert(
sizeof(ArmFault::aarch64FaultSources) ==
191 "Invalid size of ArmFault::aarch64FaultSources[]");
199 "Reset", 0x000, 0x000, 0x000, 0x000, 0x000,
MODE_SVC,
203 "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600,
MODE_UNDEFINED,
207 "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
211 "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_MON,
215 "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_HYP,
216 4, 4, 4, 4,
true,
false,
false,
EC_HVC 219 "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
223 "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
227 "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
232 "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600,
MODE_HYP,
236 "Secure Monitor Trap", 0x004, 0x000, 0x200, 0x400, 0x600,
MODE_MON,
240 "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680,
MODE_IRQ,
244 "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680,
MODE_IRQ,
248 "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700,
MODE_FIQ,
252 "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700,
MODE_FIQ,
256 "Illegal Inst Set State Fault", 0x004, 0x000, 0x200, 0x400, 0x600,
MODE_UNDEFINED,
261 "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
266 "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
271 "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
276 "SError", 0x000, 0x180, 0x380, 0x580, 0x780,
MODE_SVC,
281 "Software Breakpoint", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
286 "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000,
MODE_SVC,
339 panic(
"Invalid target exception level");
356 panic(
"Invalid exception level");
372 panic(
"Invalid exception level");
381 uint32_t exc_class = (uint32_t)
ec(tc);
382 uint32_t issVal =
iss();
386 value = exc_class << 26;
394 }
else if ((
bits(exc_class, 5, 3) != 4) ||
395 (
bits(exc_class, 2) &&
bits(issVal, 24))) {
400 if (!
from64 && ((
bits(exc_class, 5, 4) == 0) &&
401 (
bits(exc_class, 3, 0) != 0))) {
411 value |=
bits(issVal, 19, 0);
455 if (
toEL ==
EL2 && hcr.e2h && hcr.tge) {
502 ITSTATE it = tc->
pcState().itstate();
503 saved_cpsr.it2 = it.top6;
504 saved_cpsr.it1 = it.bottom2;
512 if (have_security && saved_cpsr.mode ==
MODE_MON) {
528 if (!scr.ea) {cpsr.a = 1;}
529 if (!scr.fiq) {cpsr.f = 1;}
530 if (!scr.irq) {cpsr.i = 1;}
547 cpsr.it1 = cpsr.it2 = 0;
549 cpsr.pan =
span ? 1 : saved_cpsr.pan;
577 assert(have_security);
594 panic(
"unknown Mode\n");
598 DPRINTF(Faults,
"Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x " 600 newPc, arm_inst ?
csprintf(
"inst: %#x", arm_inst->encoding()) :
604 pc.nextThumb(pc.thumb());
606 pc.nextJazelle(pc.jazelle());
607 pc.aarch64(!cpsr.width);
608 pc.nextAArch64(!cpsr.width);
609 pc.illegalExec(
false);
634 panic(
"Invalid target exception level");
654 ITSTATE it = tc->
pcState().itstate();
656 spsr.it1 = it.bottom2;
664 Addr ret_addr = curr_pc;
674 OperatingMode64
mode = 0;
682 cpsr.pan =
span ? 1 : spsr.pan;
692 DPRINTF(Faults,
"Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x " 693 "elr:%#x newVec: %#x %s\n",
name(), cpsr, curr_pc, ret_addr,
694 new_pc, arm_inst ?
csprintf(
"inst: %#x", arm_inst->encoding()) :
697 pc.aarch64(!cpsr.width);
698 pc.nextAArch64(!cpsr.width);
699 pc.illegalExec(
false);
760 pc.nextAArch64(
true);
774 assert(unknown || mnemonic != NULL);
777 panic(
"Attempted to execute disabled instruction " 778 "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding());
779 }
else if (unknown) {
780 panic(
"Attempted to execute unknown instruction (inst 0x%08x)",
781 arm_inst->encoding());
783 panic(
"Attempted to execute unimplemented instruction " 784 "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding());
816 uint32_t new_iss = 0;
817 uint32_t op0, op1, op2, CRn, CRm, Rt, dir;
827 new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 |
828 Rt << 5 | CRm << 1 | dir;
863 toHyp = scr.ns && (cpsr.mode ==
MODE_HYP);
872 return (overrideEc !=
EC_INVALID) ? overrideEc :
900 return (overrideEc !=
EC_INVALID) ? overrideEc : vals.ec;
924 bool isHypTrap =
false;
949 bool lower_32 =
false;
956 lower_32 =
ELIs32(tc, static_cast<ExceptionLevel>(
toEL - 1));
1031 return (overrideEc !=
EC_INVALID) ? overrideEc :
1045 bool override_LPAE =
false;
1049 override_LPAE =
true;
1053 DPRINTF(Faults,
"Warning: Incomplete translation method " 1054 "override detected.\n");
1075 }
else if (stage2) {
1082 DPRINTF(Faults,
"Abort Fault source=%#x fsr=%#x faultAddr=%#x "\
1083 "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod);
1093 DPRINTF(Faults,
"Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
1105 srcEncoded = getFaultStatusCode(tc);
1107 panic(
"Invalid fault source\n");
1118 "Trying to use un-updated ArmFault internal variables\n");
1126 fsc = ArmFault::longDescFaultSources[source];
1128 fsc = ArmFault::shortDescFaultSources[source];
1132 fsc = ArmFault::aarch64FaultSources[source];
1144 auto fsc = getFaultStatusCode(tc);
1152 fsr.fsLow =
bits(fsc, 3, 0);
1153 fsr.fsHigh =
bits(fsc, 4);
1154 fsr.domain =
static_cast<uint8_t
>(
domain);
1157 fsr.wnr = (write ? 1 : 0);
1169 return (!scr.ns || scr.aw);
1199 val = srcEncoded & 0x3F;
1226 va = (stage2 ? OVAddr : faultAddr);
1264 return scr.ea && !isMMUFault();
1292 panic(
"Asynchronous External Abort should be handled with " 1293 "SystemErrors (SErrors)!");
1324 return scr.ea && !isMMUFault();
1454 return (!scr.ns || scr.aw);
1493 return (!scr.ns || scr.aw);
1505 return (!scr.ns || scr.fw);
1594 (hcr.tge || mdcr.tde);
1605 DPRINTF(Faults,
"Invoking ArmSev Fault\n");
1648 auto arm_fault =
dynamic_cast<ArmFault *
>(fault.get());
bool routeToHyp(ThreadContext *tc) const override
#define panic(...)
This implements a cprintf based panic() function.
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
static uint8_t aarch64FaultSources[NumFaultSources]
Encodings of the fault sources in AArch64 state.
virtual uint8_t armPcElrOffset()=0
uint32_t iss() const override
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
bool routeToHyp(ThreadContext *tc) const override
virtual System * getSystemPtr()=0
virtual void syscall(Fault *fault)=0
ExceptionClass ec(ThreadContext *tc) const override
MiscRegIndex getFaultAddrReg64() const
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
const uint16_t currELTOffset
System error (AArch64 only)
virtual TheISA::PCState pcState() const =0
virtual FaultOffset offset(ThreadContext *tc)=0
virtual RegVal readIntReg(RegIndex reg_idx) const =0
void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) override
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
void annotate(AnnotationIDs id, uint64_t val) override
static bool opModeIsT(OperatingMode mode)
ExceptionClass ec(ThreadContext *tc) const override
void clearInterrupt(ThreadID tid, int int_num, int index)
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
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.
virtual void annotateFault(ArmFault *fault)
ExceptionClass ec(ThreadContext *tc) const override
virtual BaseCPU * getCpuPtr()=0
void clearInterrupts(ThreadID tid)
virtual FSR getFsr(ThreadContext *tc) const
ExceptionClass ec(ThreadContext *tc) const override
const uint16_t currELHOffset
virtual RegVal readCCReg(RegIndex reg_idx) const =0
bool fiqDisable(ThreadContext *tc) override
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool isInstr)
Removes the tag from tagged addresses if that mode is enabled.
ThreadContext is the external interface to all thread state for anything outside of the CPU...
static ExceptionLevel currEL(const ThreadContext *tc)
virtual bool fiqDisable(ThreadContext *tc)=0
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returning the value of MPIDR_EL1.
virtual FaultName name() const =0
virtual bool routeToHyp(ThreadContext *tc) const
static bool haveEL(ThreadContext *tc, ExceptionLevel el)
Return true if the system implements a specific exception level.
ExceptionClass ec(ThreadContext *tc) const override
virtual FaultOffset offset64(ThreadContext *tc)=0
Bitfield< 31, 28 > condCode
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
static uint8_t shortDescFaultSources[NumFaultSources]
Encodings of the fault sources when the short-desc.
virtual bool getFaultVAddr(Addr &va) const
bool routeToHyp(ThreadContext *tc) const override
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
uint32_t iss() const override
static uint8_t longDescFaultSources[NumFaultSources]
Encodings of the fault sources when the long-desc.
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
std::string csprintf(const char *format, const Args &...args)
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
uint32_t iss() const override
bool routeToHyp(ThreadContext *tc) const override
const uint16_t lowerEL32Offset
ArmStaticInst * instrAnnotate(const StaticInstPtr &inst)
bool abortDisable(ThreadContext *tc) override
virtual bool routeToMonitor(ThreadContext *tc) const override
virtual bool abortDisable(ThreadContext *tc)=0
static ExceptionLevel opModeToEL(OperatingMode mode)
const uint16_t lowerEL64Offset
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
bool routeToHyp(ThreadContext *tc) const override
HypervisorCall(ExtMachInst _machInst, uint32_t _imm)
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
virtual FaultStat & countStat()=0
virtual bool routeToMonitor(ThreadContext *tc) const =0
SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss)
virtual uint8_t thumbPcOffset(bool isHyp)=0
Addr getVector64(ThreadContext *tc)
virtual void setIntReg(RegIndex reg_idx, RegVal val)=0
Addr getFaultVAddr() const
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
MiscRegIndex getSyndromeReg64() const
void invoke64(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
bool routeToMonitor(ThreadContext *tc) const override
uint32_t iss() const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
ExceptionClass ec(ThreadContext *tc) const override
bool getFaultVAddr(Addr &va) const override
virtual OperatingMode nextMode()=0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
virtual uint8_t thumbPcElrOffset()=0
bool abortDisable(ThreadContext *tc) override
virtual uint32_t iss() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual Addr getVector(ThreadContext *tc)
bool longDescFormatInUse(ThreadContext *tc)
bool routeToHyp(ThreadContext *tc) const override
Addr getVector(ThreadContext *tc) override
virtual void advancePC(TheISA::PCState &pcState) const =0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
bool routeToMonitor(ThreadContext *tc) const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
virtual int threadId() const =0
bool routeToHyp(ThreadContext *tc) const override
bool routeToHyp(ThreadContext *tc) const override
FSR getFsr(ThreadContext *tc) const override
bool routeToHyp(ThreadContext *tc) const override
uint32_t iss() const override
bool abortDisable(ThreadContext *tc) override
virtual void clearArchRegs()=0
virtual uint8_t armPcOffset(bool isHyp)=0
IllegalInstSetStateFault()
void update(ThreadContext *tc)
void annotate(ArmFault::AnnotationIDs id, uint64_t val) override
bool routeToMonitor(ThreadContext *tc) const override
virtual void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
bool routeToHyp(ThreadContext *tc) const override
bool inSecureState(ThreadContext *tc)
virtual ExceptionClass ec(ThreadContext *tc) const =0
ExceptionClass ec(ThreadContext *tc) const override
FaultOffset offset64(ThreadContext *tc) override
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)
ExceptionClass ec(ThreadContext *tc) const override
GenericISA::DelaySlotPCState< MachInst > PCState
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Addr resetAddr() const
Returns the reset address if the highest implemented exception level is 64 bits (ARMv8) ...
T * get() const
Directly access the pointer itself without taking a reference.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
ExceptionClass ec(ThreadContext *tc) const override
std::shared_ptr< FaultBase > Fault
FaultOffset offset(ThreadContext *tc) override
bool routeToMonitor(ThreadContext *tc) const override
bool routeToMonitor(ThreadContext *tc) const override
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
Addr getFaultVAddr() const
ExceptionClass ec(ThreadContext *tc) const override
uint32_t iss() const override
uint8_t getFaultStatusCode(ThreadContext *tc) const