arch-arm: Add support for the brk instruction
authorAndreas Sandberg <andreas.sandberg@arm.com>
Fri, 23 Jun 2017 13:49:56 +0000 (14:49 +0100)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Wed, 22 Nov 2017 16:12:38 +0000 (16:12 +0000)
Add support for software breakpoints as signalled by the aarch64 brk
instruction. This introduces a new SoftwareBreakpoint fault.

Change-Id: I93646c3298e09d7f7b0983108ba8937c7331297a
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5721
Reviewed-by: Giacomo Gabrielli <Giacomo.Gabrielli@arm.com>
src/arch/arm/faults.cc
src/arch/arm/faults.hh
src/arch/arm/isa/insts/misc64.isa
src/arch/arm/types.hh

index ef9d05a135c51d4bbf4781787e78f69894e5479e..0293ee10073acb4ff719bfcf7491e513d32845dc 100644 (file)
@@ -278,6 +278,11 @@ template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals = {
     "SError",                0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC,
     0, 0, 0, 0, false, true,  true,  EC_SERROR, FaultStat()
 };
+template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals = {
+    // Some dummy values (SoftwareBreakpoint is AArch64-only)
+    "Software Breakpoint",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+    0, 0, 0, 0, true, false, false,  EC_SOFTWARE_BREAKPOINT, FaultStat()
+};
 template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals = {
     // Some dummy values
     "ArmSev Flush",          0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
@@ -1393,6 +1398,25 @@ SystemError::routeToHyp(ThreadContext *tc) const
     return toHyp;
 }
 
+
+SoftwareBreakpoint::SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss)
+    : ArmFaultVals<SoftwareBreakpoint>(_mach_inst, _iss)
+{}
+
+bool
+SoftwareBreakpoint::routeToHyp(ThreadContext *tc) const
+{
+    assert(from64);
+
+    const bool have_el2 = ArmSystem::haveVirtualization(tc);
+
+    const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
+    const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+
+    return have_el2 && !inSecureState(tc) && fromEL <= EL1 &&
+        (hcr.tge || mdcr.tde);
+}
+
 void
 ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) {
     DPRINTF(Faults, "Invoking ArmSev Fault\n");
@@ -1425,6 +1449,7 @@ template class ArmFaultVals<SecureMonitorTrap>;
 template class ArmFaultVals<PCAlignmentFault>;
 template class ArmFaultVals<SPAlignmentFault>;
 template class ArmFaultVals<SystemError>;
+template class ArmFaultVals<SoftwareBreakpoint>;
 template class ArmFaultVals<ArmSev>;
 template class AbortFault<PrefetchAbort>;
 template class AbortFault<DataAbort>;
index de5061bed6403b74a64d460ec38f79c7c4dc17b7..8f860970d427b95144969e409e21e3085241294d 100644 (file)
@@ -545,6 +545,15 @@ class SystemError : public ArmFaultVals<SystemError>
     bool routeToHyp(ThreadContext *tc) const override;
 };
 
+/// System error (AArch64 only)
+class SoftwareBreakpoint : public ArmFaultVals<SoftwareBreakpoint>
+{
+  public:
+    SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss);
+
+    bool routeToHyp(ThreadContext *tc) const override;
+};
+
 // A fault that flushes the pipe, excluding the faulting instructions
 class ArmSev : public ArmFaultVals<ArmSev>
 {
@@ -583,6 +592,7 @@ template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals;
+template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals;
 
 
index 00724c095d9c79d3b3f28c45cde6d44c93050c63..dd6711e6274892b217b7212e5d88567e17548ae9 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2011-2013, 2016 ARM Limited
+// Copyright (c) 2011-2013, 2016-2017 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -162,4 +162,16 @@ let {{
     header_output += BasicDeclare.subst(clrexIop)
     decoder_output += BasicConstructor64.subst(clrexIop)
     exec_output += BasicExecute.subst(clrexIop)
+
+
+    brkCode = '''
+    fault = std::make_shared<SoftwareBreakpoint>(machInst,
+                                                 bits(machInst, 20, 5));
+    '''
+
+    brkIop = InstObjParams("brk", "Brk64", "ArmStaticInst",
+                           brkCode, ["IsSerializeAfter"])
+    header_output += BasicDeclare.subst(brkIop)
+    decoder_output += BasicConstructor64.subst(brkIop)
+    exec_output += BasicExecute.subst(brkIop)
 }};
index 9fd945abe3ca2291eb709e4637c18871ef2d1bfb..30725811abbbdf4504fe13ac764434c2762fa50a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -621,7 +621,8 @@ namespace ArmISA
         EC_STACK_PTR_ALIGNMENT     = 0x26,
         EC_FP_EXCEPTION            = 0x28,
         EC_FP_EXCEPTION_64         = 0x2C,
-        EC_SERROR                  = 0x2F
+        EC_SERROR                  = 0x2F,
+        EC_SOFTWARE_BREAKPOINT     = 0x38,
     };
 
     /**