arch-arm: AArch32 execution triggering AArch64 SW Break
AArch32 Software Breakpoint (BKPT) can trigger an AArch64 fault when interprocessing if the trapping conditions are met. Change-Id: I485852ed19429f9cd928a6447a95eb6f471f189c Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/11197 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -1533,8 +1533,6 @@ SoftwareBreakpoint::SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss)
|
||||
bool
|
||||
SoftwareBreakpoint::routeToHyp(ThreadContext *tc) const
|
||||
{
|
||||
assert(from64);
|
||||
|
||||
const bool have_el2 = ArmSystem::haveVirtualization(tc);
|
||||
|
||||
const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
|
||||
|
||||
@@ -605,6 +605,23 @@ ArmStaticInst::generateDisassembly(Addr pc,
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
Fault
|
||||
ArmStaticInst::softwareBreakpoint32(ExecContext *xc, uint16_t imm) const
|
||||
{
|
||||
const auto tc = xc->tcBase();
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
|
||||
if ((ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) &&
|
||||
!ELIs32(tc, EL2) && (hcr.tge == 1 || mdcr.tde == 1)) ||
|
||||
!ELIs32(tc, EL1)) {
|
||||
// Route to AArch64 Software Breakpoint
|
||||
return std::make_shared<SoftwareBreakpoint>(machInst, imm);
|
||||
} else {
|
||||
// Execute AArch32 Software Breakpoint
|
||||
return std::make_shared<PrefetchAbort>(readPC(xc),
|
||||
ArmFault::DebugEvent);
|
||||
}
|
||||
}
|
||||
|
||||
Fault
|
||||
ArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const
|
||||
|
||||
@@ -370,6 +370,14 @@ class ArmStaticInst : public StaticInst
|
||||
bool isWFxTrapping(ThreadContext *tc,
|
||||
ExceptionLevel targetEL, bool isWfe) const;
|
||||
|
||||
/**
|
||||
* Trigger a Software Breakpoint.
|
||||
*
|
||||
* See aarch32/exceptions/debug/AArch32.SoftwareBreakpoint in the
|
||||
* ARM ARM psueodcode library.
|
||||
*/
|
||||
Fault softwareBreakpoint32(ExecContext *xc, uint16_t imm) const;
|
||||
|
||||
/**
|
||||
* Trap an access to Advanced SIMD or FP registers due to access
|
||||
* control bits.
|
||||
|
||||
@@ -45,53 +45,11 @@
|
||||
// Breakpoint instructions
|
||||
//
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Static instruction class for Breakpoint (illegal) instructions.
|
||||
* These cause simulator termination if they are executed in a
|
||||
* non-speculative mode. This is a leaf class.
|
||||
*/
|
||||
class Breakpoint : public ArmStaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
Breakpoint(ExtMachInst _machInst)
|
||||
: ArmStaticInst("Breakpoint", _machInst, No_OpClass)
|
||||
{
|
||||
// don't call execute() (which panics) if we're on a
|
||||
// speculative path
|
||||
flags[IsNonSpeculative] = true;
|
||||
}
|
||||
|
||||
Fault execute(ExecContext *, Trace::InstRecord *) const override;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string
|
||||
Breakpoint::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (inst 0x%x)", "Breakpoint", machInst);
|
||||
}
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
Fault
|
||||
Breakpoint::execute(ExecContext *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
return std::make_shared<PrefetchAbort>(xc->pcState().pc(),
|
||||
ArmFault::DebugEvent);
|
||||
}
|
||||
}};
|
||||
|
||||
def format ArmBkptHlt() {{
|
||||
decode_block = '''
|
||||
{
|
||||
if (bits(machInst, 21)) {
|
||||
return new Breakpoint(machInst);
|
||||
return new BkptInst(machInst);
|
||||
} else {
|
||||
uint32_t imm16 = (bits(machInst, 19, 8) << 4) |
|
||||
(bits(machInst, 3, 0) << 0);
|
||||
|
||||
@@ -688,7 +688,15 @@ let {{
|
||||
decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop)
|
||||
exec_output += PredOpExecute.subst(usada8Iop)
|
||||
|
||||
bkptCode = 'return std::make_shared<PrefetchAbort>(PC, ArmFault::DebugEvent);\n'
|
||||
bkptCode = '''
|
||||
uint16_t imm16;
|
||||
if (!machInst.thumb)
|
||||
imm16 = ((bits(machInst, 19, 8) << 4) | bits(machInst, 3, 0));
|
||||
else
|
||||
imm16 = bits(machInst, 7, 0);
|
||||
|
||||
return softwareBreakpoint32(xc, imm16);
|
||||
'''
|
||||
bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode)
|
||||
header_output += BasicDeclare.subst(bkptIop)
|
||||
decoder_output += BasicConstructor.subst(bkptIop)
|
||||
|
||||
Reference in New Issue
Block a user