diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arm/ArmSystem.py | 9 | ||||
-rw-r--r-- | src/arch/arm/faults.cc | 29 | ||||
-rw-r--r-- | src/arch/arm/faults.hh | 5 | ||||
-rw-r--r-- | src/arch/arm/isa.cc | 6 | ||||
-rw-r--r-- | src/arch/arm/system.cc | 10 | ||||
-rw-r--r-- | src/arch/arm/system.hh | 15 |
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 |