55#include "debug/Faults.hh"
109 "Invalid size of ArmFault::shortDescFaultSources[]");
154 "Invalid size of ArmFault::longDescFaultSources[]");
200 "Invalid size of ArmFault::aarch64FaultSources[]");
208 "Reset", 0x000, 0x000, 0x000, 0x000, 0x000,
MODE_SVC,
212 "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600,
MODE_UNDEFINED,
216 "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
220 "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_MON,
224 "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600,
MODE_HYP,
228 "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
232 "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
236 "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600,
MODE_ABORT,
241 "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600,
MODE_HYP,
245 "Secure Monitor Trap", 0x004, 0x000, 0x200, 0x400, 0x600,
MODE_MON,
249 "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680,
MODE_IRQ,
253 "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680,
MODE_IRQ,
257 "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700,
MODE_FIQ,
261 "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700,
MODE_FIQ,
265 "Illegal Inst Set State Fault", 0x004, 0x000, 0x200, 0x400, 0x600,
MODE_UNDEFINED,
270 "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
275 "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
280 "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
285 "SError", 0x000, 0x180, 0x380, 0x580, 0x780,
MODE_SVC,
290 "Software Breakpoint", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
294 "Hardware Breakpoint", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
298 "Watchpoint", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
302 "SoftwareStep", 0x000, 0x000, 0x200, 0x400, 0x600,
MODE_SVC,
307 "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000,
MODE_SVC,
360 panic(
"Invalid target exception level");
377 panic(
"Invalid exception level");
386 uint32_t exc_class = (uint32_t)
ec(tc);
387 uint32_t iss_val =
iss();
395 if (!
from64 && ((
bits(exc_class, 5, 4) == 0) &&
396 (
bits(exc_class, 3, 0) != 0))) {
405 esr.cond_iss.iss =
bits(iss_val, 19, 0);
441 if (
HaveExt(tc, ArmExtension::FEAT_PAN)) {
448 if (
toEL ==
EL2 && hcr.e2h && hcr.tge) {
508 saved_cpsr.it2 = it.top6;
509 saved_cpsr.it1 = it.bottom2;
517 if (have_security && saved_cpsr.mode ==
MODE_MON) {
533 if (!scr.ea) {cpsr.a = 1;}
534 if (!scr.fiq) {cpsr.f = 1;}
535 if (!scr.irq) {cpsr.i = 1;}
552 cpsr.it1 = cpsr.it2 = 0;
553 cpsr.pan =
span ? 1 : saved_cpsr.pan;
581 assert(have_security);
598 panic(
"unknown Mode\n");
602 DPRINTF(Faults,
"Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x "
608 pc.nextThumb(
pc.thumb());
609 pc.aarch64(!cpsr.width);
610 pc.nextAArch64(!cpsr.width);
611 pc.illegalExec(
false);
636 panic(
"Invalid target exception level");
658 spsr.it1 = it.bottom2;
665 Addr ret_addr = curr_pc;
675 OperatingMode64
mode = 0;
683 cpsr.pan =
span ? 1 : spsr.pan;
694 DPRINTF(Faults,
"Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x "
695 "elr:%#x newVec: %#x %s\n",
name(), cpsr, curr_pc, ret_addr,
699 pc.aarch64(!cpsr.width);
700 pc.nextAArch64(!cpsr.width);
701 pc.illegalExec(
false);
763 pc.nextAArch64(
true);
780 panic(
"Attempted to execute disabled instruction "
783 panic(
"Attempted to execute unknown instruction (inst 0x%08x)",
786 panic(
"Attempted to execute unimplemented instruction "
811 uint32_t new_iss = 0;
812 uint32_t op0, op1, op2, CRn, CRm, Rt, dir;
822 new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 |
823 Rt << 5 | CRm << 1 | dir;
924 bool isHypTrap =
false;
930 if (vals.hypTrappable) {
937 return isHypTrap ? 0x14 : vals.offset;
944 if (toEL == fromEL) {
946 return vals.currELTOffset;
947 return vals.currELHOffset;
949 bool lower_32 =
false;
962 return vals.lowerEL32Offset;
963 return vals.lowerEL64Offset;
1040 bool override_LPAE =
false;
1042 [[maybe_unused]] TTBCR ttbcr_ns =
1045 override_LPAE =
true;
1049 DPRINTF(Faults,
"Warning: Incomplete translation method "
1050 "override detected.\n");
1068 FSR fsr = getFsr(tc);
1071 }
else if (stage2) {
1093 DPRINTF(Faults,
"Abort Fault source=%#x fsr=%#x faultAddr=%#x "\
1094 "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod);
1102 tc, OVAddr, this->toEL);
1105 DPRINTF(Faults,
"Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
1109 tc, faultAddr, this->toEL);
1118 srcEncoded = getFaultStatusCode(tc);
1120 panic(
"Invalid fault source\n");
1131 "Trying to use un-updated ArmFault internal variables\n");
1157 auto fsc = getFaultStatusCode(tc);
1165 fsr.fsLow =
bits(fsc, 3, 0);
1166 fsr.fsHigh =
bits(fsc, 4);
1167 fsr.domain =
static_cast<uint8_t
>(
domain);
1170 fsr.wnr = (write ? 1 : 0);
1182 return (!scr.ns || scr.aw);
1227 va = (stage2 ? OVAddr : faultAddr);
1260 auto&
iss = esr.instruction_abort_iss;
1296 panic(
"Asynchronous External Abort should be handled with "
1297 "SystemErrors (SErrors)!");
1342 amo = (!
HaveExt(tc, ArmExtension::FEAT_VHE) || hcr.e2h == 0);
1360 auto&
iss = esr.data_abort_iss;
1452 return (!scr.ns || scr.aw);
1481 return (!scr.ns || scr.aw);
1493 return (!scr.ns || scr.fw);
1621 panic(
"Invalid target exception level");
1630 bool _write,
bool _cm)
1632 write(_write),
cm(_cm)
1639 auto&
iss = esr.watchpoint_iss;
1640 iss.dfsc = 0b100010;
1721 auto&
iss = esr.software_step_iss;
1722 iss.ifsc = 0b100010;
1731 DPRINTF(Faults,
"Invoking ArmSev Fault\n");
1784 auto arm_fault =
dynamic_cast<ArmFault *
>(fault.get());
void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) override
uint8_t getFaultStatusCode(ThreadContext *tc) const
void annotate(ArmFault::AnnotationIDs id, uint64_t val) override
bool abortDisable(ThreadContext *tc) override
bool getFaultVAddr(Addr &va) const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
FSR getFsr(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
FaultOffset offset64(ThreadContext *tc) override
FaultOffset offset(ThreadContext *tc) override
virtual bool routeToMonitor(ThreadContext *tc) const =0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
@ AsynchronousExternalAbort
@ SynchronousExternalAbort
virtual uint32_t iss() const =0
static uint8_t shortDescFaultSources[NumFaultSources]
Encodings of the fault sources when the short-desc.
virtual bool routeToHyp(ThreadContext *tc) const
void invoke32(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
virtual uint8_t thumbPcOffset(bool is_hyp)=0
MiscRegIndex getSyndromeReg64() const
virtual void annotate(AnnotationIDs id, uint64_t val)
virtual Addr getVector(ThreadContext *tc)
virtual bool il(ThreadContext *tc) const =0
ArmStaticInst * instrAnnotate(const StaticInstPtr &inst)
virtual FaultOffset offset64(ThreadContext *tc)=0
virtual bool abortDisable(ThreadContext *tc)=0
void update(ThreadContext *tc)
static uint8_t longDescFaultSources[NumFaultSources]
Encodings of the fault sources when the long-desc.
void invoke64(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
virtual uint8_t armPcOffset(bool is_hyp)=0
virtual uint8_t thumbPcElrOffset()=0
virtual bool fiqDisable(ThreadContext *tc)=0
virtual bool getFaultVAddr(Addr &va) const
static uint8_t aarch64FaultSources[NumFaultSources]
Encodings of the fault sources in AArch64 state.
virtual uint8_t armPcElrOffset()=0
virtual OperatingMode nextMode()=0
Addr getVector64(ThreadContext *tc)
virtual void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
virtual void annotateFault(ArmFault *fault)
MachInst encoding() const
Returns the real encoding of the instruction: the machInst field is in fact always 64 bit wide and co...
bool routeToHyp(ThreadContext *tc) const override
uint32_t iss() const override
void annotate(AnnotationIDs id, uint64_t val) override
bool il(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
bool routeToMonitor(ThreadContext *tc) const override
bool fiqDisable(ThreadContext *tc) override
bool abortDisable(ThreadContext *tc) override
bool routeToMonitor(ThreadContext *tc) const override
bool routeToHyp(ThreadContext *tc) const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
HardwareBreakpoint(Addr _vaddr, uint32_t _iss)
bool routeToMonitor(ThreadContext *tc) const override
HypervisorCall(ExtMachInst mach_inst, uint32_t _imm)
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
ExceptionClass overrideEc
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
IllegalInstSetStateFault()
bool routeToHyp(ThreadContext *tc) const override
bool abortDisable(ThreadContext *tc) override
bool routeToHyp(ThreadContext *tc) const override
bool routeToMonitor(ThreadContext *tc) const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
bool routeToHyp(ThreadContext *tc) const override
Addr faultPC
The unaligned value of the PC.
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
uint32_t iss() const override
bool routeToHyp(ThreadContext *tc) const override
bool routeToMonitor(ThreadContext *tc) const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Addr getVector(ThreadContext *tc) override
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
uint32_t iss() const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
ExceptionClass overrideEc
Software Breakpoint (AArch64 only)
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
SoftwareBreakpoint(ExtMachInst mach_inst, uint32_t _iss)
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
uint32_t iss() const override
SoftwareStepFault(ExtMachInst mach_inst, bool is_ldx, bool stepped)
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
ExceptionClass overrideEc
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
uint32_t iss() const override
bool routeToHyp(ThreadContext *tc) const override
ExceptionClass overrideEc
uint32_t iss() const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
bool routeToMonitor(ThreadContext *tc) const override
bool routeToHyp(ThreadContext *tc) const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
ExceptionClass overrideEc
bool routeToHyp(ThreadContext *tc) const override
uint32_t iss() const override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
Watchpoint(ExtMachInst mach_inst, Addr vaddr, bool _write, bool _cm)
bool routeToHyp(ThreadContext *tc) const override
void annotate(AnnotationIDs id, uint64_t val) override
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
uint32_t iss() const override
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
Addr resetAddr() const
Returns the reset address if the highest implemented exception level is 64 bits (ARMv8)
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
void clearInterrupts(ThreadID tid)
void clearInterrupt(ThreadID tid, int int_num, int index)
virtual FaultName name() const =0
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Addr getFaultVAddr() const
Addr getFaultVAddr() const
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
T * get() const
Directly access the pointer itself without taking a reference.
virtual void advancePC(PCStateBase &pc_state) const =0
Workload * workload
OS kernel.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual RegVal getReg(const RegId ®) const
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
virtual System * getSystemPtr()=0
virtual void clearArchRegs()=0
virtual BaseCPU * getCpuPtr()=0
virtual void setReg(const RegId ®, RegVal val)
virtual const PCStateBase & pcState() const =0
virtual int threadId() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual void syscall(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.
#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...
void writeRegister(ThreadContext *tc, RegVal val, ExceptionLevel el)
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
static bool opModeIsT(OperatingMode mode)
bool getFaultVAddr(Fault fault, Addr &va)
Returns true if the fault passed as a first argument was triggered by a memory access,...
void syncVecRegsToElems(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 ...
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
bool isSecure(ThreadContext *tc)
bool longDescFormatInUse(ThreadContext *tc)
@ PREFETCH_ABORT_LOWER_EL
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
bool EL2Enabled(ThreadContext *tc)
Bitfield< 55, 48 > itstate
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returning the value of MPIDR_EL1.
void syncVecElemsToRegs(ThreadContext *tc)
static ExceptionLevel opModeToEL(OperatingMode mode)
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.
GenericISA::DelaySlotPCState< 4 > PCState
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.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
std::string csprintf(const char *format, const Args &...args)
Overload hash function for BasicBlockRange type.