summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/ArmSystem.py9
-rw-r--r--src/arch/arm/faults.cc29
-rw-r--r--src/arch/arm/faults.hh5
-rw-r--r--src/arch/arm/isa.cc6
-rw-r--r--src/arch/arm/system.cc10
-rw-r--r--src/arch/arm/system.hh15
6 files changed, 48 insertions, 26 deletions
diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py
index cd08d7449..bee38a41c 100644
--- a/src/arch/arm/ArmSystem.py
+++ b/src/arch/arm/ArmSystem.py
@@ -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,
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index bd06ea288..665b2989c 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -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);
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index 90b550198..dcda03b5f 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -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;
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index a849d04da..5c1139d8f 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -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
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc
index 21b02e968..063066151 100644
--- a/src/arch/arm/system.cc
+++ b/src/arch/arm/system.cc
@@ -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
diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh
index 2e236f722..c6974609e 100644
--- a/src/arch/arm/system.hh
+++ b/src/arch/arm/system.hh
@@ -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