arch-arm: ArmSystem::resetAddr64 renamed to be used in AArch32
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 31 Oct 2018 17:12:30 +0000 (17:12 +0000)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 7 Nov 2018 15:22:43 +0000 (15:22 +0000)
ARMv8 differs from ARMv7 with the presence of RVBAR register, which
contains the implementation defined reset address when EL3 is not
implemented.
The entry 0x0 in the AArch32 vector table, once used for the Reset
Vector, is now marked as "Not used", stating that it is now IMPLEMENTATION
DEFINED. An implementation might still use this vector table entry to
hold the Reset vector, but having a Reset address != than the general
vector table (for any other exception) is allowed.

At the moment any Reset exception is still using 0 as a vector table
base address. This patch is extending the ArmSystem::resetAddr64 to
ArmSystem::resetAddr so that it can be used for initializing
MVBAR/RVBAR. In order to do so, we are providing a specialized behavior
for the Reset exception when evaluating the vector base address.

Change-Id: I051a730dc089e194db3b107bbed19251c661f87e
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/14000
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

src/arch/arm/ArmSystem.py
src/arch/arm/faults.cc
src/arch/arm/faults.hh
src/arch/arm/isa.cc
src/arch/arm/system.cc
src/arch/arm/system.hh

index cd08d744939b2536b24a3bf747816ef5702bb570..bee38a41c0880b76196fcdb0253b7a18babfc8a9 100644 (file)
@@ -68,14 +68,13 @@ class ArmSystem(System):
     have_crypto = Param.Bool(False,
         "True if Crypto Extensions is implemented")
     have_lpae = Param.Bool(True, "True if LPAE is implemented")
+    reset_addr = Param.Addr(0x0,
+        "Reset address (ARMv8)")
+    auto_reset_addr = Param.Bool(False,
+        "Determine reset address from kernel entry point if no boot loader")
     highest_el_is_64 = Param.Bool(False,
         "True if the register width of the highest implemented exception level "
         "is 64 bits (ARMv8)")
-    reset_addr_64 = Param.Addr(0x0,
-        "Reset address if the highest implemented exception level is 64 bits "
-        "(ARMv8)")
-    auto_reset_addr_64 = Param.Bool(False,
-        "Determine reset address from kernel entry point if no boot loader")
     phys_addr_range_64 = Param.UInt8(40,
         "Supported physical address range in bits when using AArch64 (ARMv8)")
     have_large_asid_64 = Param.Bool(False,
index bd06ea288173d5a03f3e16efa8db4a548b1368fe..665b2989c831bf5212ca03cb14c46dc1b15fc382 100644 (file)
@@ -297,12 +297,9 @@ ArmFault::getVector(ThreadContext *tc)
 {
     Addr base;
 
-    // ARM ARM issue C B1.8.1
-    bool haveSecurity = ArmSystem::haveSecurity(tc);
-
     // Check for invalid modes
     CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
-    assert(haveSecurity                      || cpsr.mode != MODE_MON);
+    assert(ArmSystem::haveSecurity(tc) || cpsr.mode != MODE_MON);
     assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP);
 
     switch (cpsr.mode)
@@ -318,10 +315,12 @@ ArmFault::getVector(ThreadContext *tc)
         if (sctlr.v) {
             base = HighVecs;
         } else {
-            base = haveSecurity ? tc->readMiscReg(MISCREG_VBAR) : 0;
+            base = ArmSystem::haveSecurity(tc) ?
+                tc->readMiscReg(MISCREG_VBAR) : 0;
         }
         break;
     }
+
     return base + offset(tc);
 }
 
@@ -694,6 +693,24 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
         setSyndrome(tc, getSyndromeReg64());
 }
 
+Addr
+Reset::getVector(ThreadContext *tc)
+{
+    Addr base;
+
+    // Check for invalid modes
+    CPSR M5_VAR_USED cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
+    assert(ArmSystem::haveSecurity(tc) || cpsr.mode != MODE_MON);
+    assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP);
+
+    // RVBAR is aliased (implemented as) MVBAR in gem5, since the two
+    // are mutually exclusive; there is no need to check here for
+    // which register to use since they hold the same value
+    base = tc->readMiscReg(MISCREG_MVBAR);
+
+    return base + offset(tc);
+}
+
 void
 Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
 {
@@ -715,7 +732,7 @@ Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
         }
     } else {
         // Advance the PC to the IMPLEMENTATION DEFINED reset value
-        PCState pc = ArmSystem::resetAddr64(tc);
+        PCState pc = ArmSystem::resetAddr(tc);
         pc.aarch64(true);
         pc.nextAArch64(true);
         tc->pcState(pc);
index 90b5501984d44223cb53eee5007f2acd6cebd3be..dcda03b5fe98d4a447748212d2387c78204b4f3b 100644 (file)
@@ -81,7 +81,7 @@ class ArmFault : public FaultBase
 
     bool hypRouted; // True if the fault has been routed to Hypervisor
 
-    Addr getVector(ThreadContext *tc);
+    virtual Addr getVector(ThreadContext *tc);
     Addr getVector64(ThreadContext *tc);
 
   public:
@@ -269,6 +269,9 @@ class ArmFaultVals : public ArmFault
 
 class Reset : public ArmFaultVals<Reset>
 {
+  protected:
+    Addr getVector(ThreadContext *tc) override;
+
   public:
     void invoke(ThreadContext *tc, const StaticInstPtr &inst =
                 StaticInst::nullStaticInstPtr) override;
index a849d04da64e03ad94027df8e20ecbb1c60a3289..5c1139d8fde9e203594eb0115967bb24148b924c 100644 (file)
@@ -201,6 +201,10 @@ ISA::clear32(const ArmISAParams *p, const SCTLR &sctlr_rst)
     CPSR cpsr = 0;
     cpsr.mode = MODE_USER;
 
+    if (FullSystem) {
+        miscRegs[MISCREG_MVBAR] = system->resetAddr();
+    }
+
     miscRegs[MISCREG_CPSR] = cpsr;
     updateRegMap(cpsr);
 
@@ -247,7 +251,7 @@ void
 ISA::clear64(const ArmISAParams *p)
 {
     CPSR cpsr = 0;
-    Addr rvbar = system->resetAddr64();
+    Addr rvbar = system->resetAddr();
     switch (system->highestEL()) {
         // Set initial EL to highest implemented EL using associated stack
         // pointer (SP_ELx); set RVBAR_ELx to implementation defined reset
index 21b02e9680408023a273cf539203bf536de2a64c..063066151369d6874dbcb014182b05d262557204 100644 (file)
@@ -63,10 +63,10 @@ ArmSystem::ArmSystem(Params *p)
       _haveVirtualization(p->have_virtualization),
       _haveCrypto(p->have_crypto),
       _genericTimer(nullptr),
+      _resetAddr(p->auto_reset_addr ?
+                 (kernelEntry & loadAddrMask) + loadAddrOffset :
+                 p->reset_addr),
       _highestELIs64(p->highest_el_is_64),
-      _resetAddr64(p->auto_reset_addr_64 ?
-                   (kernelEntry & loadAddrMask) + loadAddrOffset :
-                   p->reset_addr_64),
       _physAddrRange64(p->phys_addr_range_64),
       _haveLargeAsid64(p->have_large_asid_64),
       _m5opRange(p->m5ops_base ?
@@ -248,9 +248,9 @@ ArmSystem::haveEL(ThreadContext *tc, ExceptionLevel el)
 }
 
 Addr
-ArmSystem::resetAddr64(ThreadContext *tc)
+ArmSystem::resetAddr(ThreadContext *tc)
 {
-    return getArmSystem(tc)->resetAddr64();
+    return getArmSystem(tc)->resetAddr();
 }
 
 uint8_t
index 2e236f722e932f37e5f767297975c27bfc702c73..c6974609e3e2e32f99f390b4e00320101a633383 100644 (file)
@@ -99,16 +99,15 @@ class ArmSystem : public System
     GenericTimer *_genericTimer;
 
     /**
-     * True if the register width of the highest implemented exception level is
-     * 64 bits (ARMv8)
+     * Reset address (ARMv8)
      */
-    bool _highestELIs64;
+    const Addr _resetAddr;
 
     /**
-     * Reset address if the highest implemented exception level is 64 bits
-     * (ARMv8)
+     * True if the register width of the highest implemented exception level is
+     * 64 bits (ARMv8)
      */
-    const Addr _resetAddr64;
+    bool _highestELIs64;
 
     /**
      * Supported physical address range in bits if the highest implemented
@@ -212,7 +211,7 @@ class ArmSystem : public System
 
     /** Returns the reset address if the highest implemented exception level is
      * 64 bits (ARMv8) */
-    Addr resetAddr64() const { return _resetAddr64; }
+    Addr resetAddr() const { return _resetAddr; }
 
     /** Returns true if ASID is 16 bits in AArch64 (ARMv8) */
     bool haveLargeAsid64() const { return _haveLargeAsid64; }
@@ -283,7 +282,7 @@ class ArmSystem : public System
     /** Returns the reset address if the highest implemented exception level
      * for the system of a specific thread context is 64 bits (ARMv8)
      */
-    static Addr resetAddr64(ThreadContext *tc);
+    static Addr resetAddr(ThreadContext *tc);
 
     /** Returns the supported physical address range in bits for the system of a
      * specific thread context