From 7846f59d0dcb36c13e06a3ba8a4c461e646582b6 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Mon, 3 Jun 2013 13:55:41 +0200 Subject: [PATCH] arch: Create a method to finalize physical addresses in the TLB Some architectures (currently only x86) require some fixing-up of physical addresses after a normal address translation. This is usually to remap devices such as the APIC, but could be used for other memory mapped devices as well. When running the CPU in a using hardware virtualization, we still need to do these address fix-ups before inserting the request into the memory system. This patch moves this patch allows that code to be used by such CPUs without doing full address translations. --- src/arch/alpha/tlb.cc | 6 +++++ src/arch/alpha/tlb.hh | 1 + src/arch/arm/tlb.cc | 6 +++++ src/arch/arm/tlb.hh | 1 + src/arch/mips/tlb.cc | 6 +++++ src/arch/mips/tlb.hh | 1 + src/arch/power/tlb.cc | 6 +++++ src/arch/power/tlb.hh | 1 + src/arch/sparc/tlb.cc | 6 +++++ src/arch/sparc/tlb.hh | 1 + src/arch/x86/tlb.cc | 61 +++++++++++++++++++++++++------------------ src/arch/x86/tlb.hh | 16 ++++++++++++ src/sim/tlb.cc | 6 +++++ src/sim/tlb.hh | 17 ++++++++++++ 14 files changed, 110 insertions(+), 25 deletions(-) diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 1d18c8d39..f39785ebb 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -607,6 +607,12 @@ TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode) return NoFault; } +Fault +TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const +{ + return NoFault; +} + } // namespace AlphaISA AlphaISA::TLB * diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 4e56100c7..3300e5761 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -148,6 +148,7 @@ class TLB : public BaseTLB * translateFunctional stub function for future CheckerCPU support */ Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode); + Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const; }; } // namespace AlphaISA diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 6b864b980..7a79725e1 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -94,6 +94,12 @@ TLB::translateFunctional(ThreadContext *tc, Addr va, Addr &pa) return true; } +Fault +TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const +{ + return NoFault; +} + TlbEntry* TLB::lookup(Addr va, uint8_t cid, bool functional) { diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index c1eba1ba7..a66e28b06 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -207,6 +207,7 @@ class TLB : public BaseTLB Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode); Fault translateTiming(RequestPtr req, ThreadContext *tc, Translation *translation, Mode mode); + Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const; void drainResume(); diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index 49ff2caba..8b106d437 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -346,6 +346,12 @@ TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode) return NoFault; } +Fault +TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const +{ + return NoFault; +} + MipsISA::PTE & TLB::index(bool advance) diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index e949d16d9..fdd590e85 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -118,6 +118,7 @@ class TLB : public BaseTLB * support the Checker model at the moment. */ Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode); + Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const; private: Fault translateInst(RequestPtr req, ThreadContext *tc); diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc index de828a625..9c1745cc8 100644 --- a/src/arch/power/tlb.cc +++ b/src/arch/power/tlb.cc @@ -333,6 +333,12 @@ TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode) return NoFault; } +Fault +TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const +{ + return NoFault; +} + PowerISA::PTE & TLB::index(bool advance) { diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh index 3cf2a3706..753231a89 100644 --- a/src/arch/power/tlb.hh +++ b/src/arch/power/tlb.hh @@ -164,6 +164,7 @@ class TLB : public BaseTLB * supported by Checker at the moment */ Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode); + Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const; // Checkpointing void serialize(std::ostream &os); diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 5d6dfe2c3..66e75a98a 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -848,6 +848,12 @@ TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode) return NoFault; } +Fault +TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const +{ + return NoFault; +} + Cycles TLB::doMmuRegRead(ThreadContext *tc, Packet *pkt) { diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index 7246cd4f6..e084f665c 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -169,6 +169,7 @@ class TLB : public BaseTLB * does not support the Checker model at the moment */ Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode); + Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const; Cycles doMmuRegRead(ThreadContext *tc, Packet *pkt); Cycles doMmuRegWrite(ThreadContext *tc, Packet *pkt); void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 33de0129a..52cc3e0ee 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -225,6 +225,40 @@ TLB::translateInt(RequestPtr req, ThreadContext *tc) } } +Fault +TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const +{ + Addr paddr = req->getPaddr(); + + // Check for an access to the local APIC + if (FullSystem) { + LocalApicBase localApicBase = + tc->readMiscRegNoEffect(MISCREG_APIC_BASE); + AddrRange apicRange(localApicBase.base * PageBytes, + (localApicBase.base + 1) * PageBytes - 1); + + if (apicRange.contains(paddr)) { + // The Intel developer's manuals say the below restrictions apply, + // but the linux kernel, because of a compiler optimization, breaks + // them. + /* + // Check alignment + if (paddr & ((32/8) - 1)) + return new GeneralProtection(0); + // Check access size + if (req->getSize() != (32/8)) + return new GeneralProtection(0); + */ + // Force the access to be uncacheable. + req->setFlags(Request::UNCACHEABLE); + req->setPaddr(x86LocalAPICAddress(tc->contextId(), + paddr - apicRange.start())); + } + } + + return NoFault; +} + Fault TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, Mode mode, bool &delayedResponse, bool timing) @@ -366,31 +400,8 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr); req->setPaddr(vaddr); } - // Check for an access to the local APIC - if (FullSystem) { - LocalApicBase localApicBase = - tc->readMiscRegNoEffect(MISCREG_APIC_BASE); - Addr baseAddr = localApicBase.base * PageBytes; - Addr paddr = req->getPaddr(); - if (baseAddr <= paddr && baseAddr + PageBytes > paddr) { - // The Intel developer's manuals say the below restrictions apply, - // but the linux kernel, because of a compiler optimization, breaks - // them. - /* - // Check alignment - if (paddr & ((32/8) - 1)) - return new GeneralProtection(0); - // Check access size - if (req->getSize() != (32/8)) - return new GeneralProtection(0); - */ - // Force the access to be uncacheable. - req->setFlags(Request::UNCACHEABLE); - req->setPaddr(x86LocalAPICAddress(tc->contextId(), - paddr - baseAddr)); - } - } - return NoFault; + + return finalizePhysical(req, tc, mode); } Fault diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index 39ae240af..4f0d58d5c 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -129,6 +129,22 @@ namespace X86ISA */ Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode); + /** + * Do post-translation physical address finalization. + * + * Some addresses, for example requests going to the APIC, + * need post-translation updates. Such physical addresses are + * remapped into a "magic" part of the physical address space + * by this method. + * + * @param req Request to updated in-place. + * @param tc Thread context that created the request. + * @param mode Request type (read/write/execute). + * @return A fault on failure, NoFault otherwise. + */ + Fault finalizePhysical(RequestPtr req, ThreadContext *tc, + Mode mode) const; + TlbEntry * insert(Addr vpn, TlbEntry &entry); // Checkpointing diff --git a/src/sim/tlb.cc b/src/sim/tlb.cc index 86428f168..00a51dbe3 100644 --- a/src/sim/tlb.cc +++ b/src/sim/tlb.cc @@ -58,6 +58,12 @@ GenericTLB::translateTiming(RequestPtr req, ThreadContext *tc, translation->finish(translateAtomic(req, tc, mode), req, tc, mode); } +Fault +GenericTLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const +{ + return NoFault; +} + void GenericTLB::demapPage(Addr vaddr, uint64_t asn) { diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh index 95a252e16..f46c2d856 100644 --- a/src/sim/tlb.hh +++ b/src/sim/tlb.hh @@ -124,6 +124,23 @@ class GenericTLB : public BaseTLB Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode); void translateTiming(RequestPtr req, ThreadContext *tc, Translation *translation, Mode mode); + + + /** + * Do post-translation physical address finalization. + * + * This method is used by some architectures that need + * post-translation massaging of physical addresses. For example, + * X86 uses this to remap physical addresses in the APIC range to + * a range of physical memory not normally available to real x86 + * implementations. + * + * @param req Request to updated in-place. + * @param tc Thread context that created the request. + * @param mode Request type (read/write/execute). + * @return A fault on failure, NoFault otherwise. + */ + Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const; }; #endif // __ARCH_SPARC_TLB_HH__ -- 2.30.2