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:
Giacomo Travaglini
2018-06-05 16:17:48 +01:00
parent fc278fffb7
commit b4a10d55e5
5 changed files with 35 additions and 46 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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.

View File

@@ -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);

View File

@@ -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)