diff options
Diffstat (limited to 'src/arch/arm')
-rw-r--r-- | src/arch/arm/ArmSystem.py | 4 | ||||
-rw-r--r-- | src/arch/arm/ArmTLB.py | 1 | ||||
-rw-r--r-- | src/arch/arm/system.cc | 3 | ||||
-rw-r--r-- | src/arch/arm/system.hh | 12 | ||||
-rw-r--r-- | src/arch/arm/tlb.cc | 27 | ||||
-rw-r--r-- | src/arch/arm/tlb.hh | 2 |
6 files changed, 45 insertions, 4 deletions
diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index 41f6b9d79..c21b9c6ec 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -76,6 +76,10 @@ class ArmSystem(System): have_large_asid_64 = Param.Bool(False, "True if ASID is 16 bits in AArch64 (ARMv8)") + m5ops_base = Param.Addr(0, + "Base of the 64KiB PA range used for memory-mapped m5ops. Set to 0 " + "to disable.") + class GenericArmSystem(ArmSystem): type = 'GenericArmSystem' cxx_header = "arch/arm/system.hh" diff --git a/src/arch/arm/ArmTLB.py b/src/arch/arm/ArmTLB.py index 4e6c69f72..b3f711d83 100644 --- a/src/arch/arm/ArmTLB.py +++ b/src/arch/arm/ArmTLB.py @@ -63,6 +63,7 @@ class ArmTLB(SimObject): type = 'ArmTLB' cxx_class = 'ArmISA::TLB' cxx_header = "arch/arm/tlb.hh" + sys = Param.System(Parent.any, "system object parameter") size = Param.Int(64, "TLB size") walker = Param.ArmTableWalker(ArmTableWalker(), "HW Table walker") is_stage2 = Param.Bool(False, "Is this a stage 2 TLB?") diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc index 322f686dc..50d0af909 100644 --- a/src/arch/arm/system.cc +++ b/src/arch/arm/system.cc @@ -65,6 +65,9 @@ ArmSystem::ArmSystem(Params *p) _resetAddr64(p->reset_addr_64), _physAddrRange64(p->phys_addr_range_64), _haveLargeAsid64(p->have_large_asid_64), + _m5opRange(p->m5ops_base ? + RangeSize(p->m5ops_base, 0x10000) : + AddrRange(1, 0)), // Create an empty range if disabled multiProc(p->multi_proc) { // Check if the physical address range is valid diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh index ee286d23a..97769337a 100644 --- a/src/arch/arm/system.hh +++ b/src/arch/arm/system.hh @@ -116,6 +116,12 @@ class ArmSystem : public System */ const bool _haveLargeAsid64; + /** + * Range for memory-mapped m5 pseudo ops. The range will be + * invalid/empty if disabled. + */ + const AddrRange _m5opRange; + protected: /** * Get a boot loader that matches the kernel. @@ -216,6 +222,12 @@ class ArmSystem : public System return mask(physAddrRange()); } + /** + * Range used by memory-mapped m5 pseudo-ops if enabled. Returns + * an invalid/empty range if disabled. + */ + const AddrRange &m5opRange() const { return _m5opRange; } + /** Returns true if the system of a specific thread context implements the * Security Extensions */ diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index eeccca0c0..6f7998db2 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -55,6 +55,7 @@ #include "arch/arm/system.hh" #include "arch/arm/table_walker.hh" #include "arch/arm/utility.hh" +#include "arch/generic/mmapped_ipr.hh" #include "base/inifile.hh" #include "base/str.hh" #include "base/trace.hh" @@ -81,12 +82,17 @@ TLB::TLB(const ArmTLBParams *p) isHyp(false), asid(0), vmid(0), dacr(0), miscRegValid(false), miscRegContext(0), curTranType(NormalTran) { + const ArmSystem *sys = dynamic_cast<const ArmSystem *>(p->sys); + tableWalker->setTlb(this); // Cache system-level properties haveLPAE = tableWalker->haveLPAE(); haveVirtualization = tableWalker->haveVirtualization(); haveLargeAsid64 = tableWalker->haveLargeAsid64(); + + if (sys) + m5opRange = sys->m5opRange(); } TLB::~TLB() @@ -129,6 +135,15 @@ TLB::translateFunctional(ThreadContext *tc, Addr va, Addr &pa) Fault TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const { + const Addr paddr = req->getPaddr(); + + if (m5opRange.contains(paddr)) { + req->setFlags(Request::MMAPPED_IPR | Request::GENERIC_IPR); + req->setPaddr(GenericISA::iprAddressPseudoInst( + (paddr >> 8) & 0xFF, + paddr & 0xFF)); + } + return NoFault; } @@ -582,7 +597,7 @@ TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode, return std::make_shared<GenericPageTableFault>(vaddr_tainted); req->setPaddr(paddr); - return NoFault; + return finalizePhysical(req, tc, mode); } Fault @@ -1108,14 +1123,18 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode, fault = testTranslation(req, mode, te->domain); } - // Generate Illegal Inst Set State fault if IL bit is set in CPSR if (fault == NoFault) { + // Generate Illegal Inst Set State fault if IL bit is set in CPSR if (aarch64 && is_fetch && cpsr.il == 1) { return std::make_shared<IllegalInstSetStateFault>(); } - } - return fault; + // Don't try to finalize a physical address unless the + // translation has completed (i.e., there is a table entry). + return te ? finalizePhysical(req, tc, mode) : NoFault; + } else { + return fault; + } } Fault diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index f4530a219..f5849f3e3 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -393,6 +393,8 @@ protected: bool haveVirtualization; bool haveLargeAsid64; + AddrRange m5opRange; + void updateMiscReg(ThreadContext *tc, ArmTranslationType tranType = NormalTran); |