arch: Create a method to finalize physical addresses
authorAndreas Sandberg <andreas@sandberg.pp.se>
Mon, 3 Jun 2013 11:55:41 +0000 (13:55 +0200)
committerAndreas Sandberg <andreas@sandberg.pp.se>
Mon, 3 Jun 2013 11:55:41 +0000 (13:55 +0200)
 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.

14 files changed:
src/arch/alpha/tlb.cc
src/arch/alpha/tlb.hh
src/arch/arm/tlb.cc
src/arch/arm/tlb.hh
src/arch/mips/tlb.cc
src/arch/mips/tlb.hh
src/arch/power/tlb.cc
src/arch/power/tlb.hh
src/arch/sparc/tlb.cc
src/arch/sparc/tlb.hh
src/arch/x86/tlb.cc
src/arch/x86/tlb.hh
src/sim/tlb.cc
src/sim/tlb.hh

index 1d18c8d391438b5e3216f5b60996f6dd68fce281..f39785ebb5e956f168117c1ed2d4c8fa33e0559e 100644 (file)
@@ -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 *
index 4e56100c790e6ca78c290a11f32fe101caef8441..3300e57610b247f8083191f089ffb8eff83edb26 100644 (file)
@@ -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
index 6b864b980a00f8559e3853361f719d9330c793f6..7a79725e17b0f5b3371c13e7ec96158c17ac6b47 100644 (file)
@@ -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)
 {
index c1eba1ba780ba7acddb624f0dd49218b2e621383..a66e28b0612074fab1669eb70beb9b72d91a2133 100644 (file)
@@ -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();
 
index 49ff2caba645c7c4ed865d83bee4de8b9a143c78..8b106d4377c179d21d8b18aabcea617fbae7ed3a 100644 (file)
@@ -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)
index e949d16d9a55363c7a5a889a132edb4ed7eac5c0..fdd590e85064cf76852336c377604f8b3c40f8c9 100644 (file)
@@ -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);
index de828a625dc0623634b5b01b30b7dfd2efac0dd4..9c1745cc87aab4e18be7f3bfb173c9d9cd2210d2 100644 (file)
@@ -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)
 {
index 3cf2a3706af788aa7e8b92c0c68d3bbaecb9fa96..753231a89dbed4b25b599bee4f897b25b7e39a3f 100644 (file)
@@ -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);
index 5d6dfe2c3886d8f3279450b5a603ec9e19d28e29..66e75a98a8823e1dbfc843ac025b2ca0be00ba07 100644 (file)
@@ -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)
 {
index 7246cd4f6f19b936f7b5a891b5519c5308d66a3d..e084f665cabd6794703f9c780282c0879a1ea288 100644 (file)
@@ -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);
index 33de0129ae4339d670909ee14adc7b0d700a052d..52cc3e0eef895d2a054ee73eaa2203a33999dbb8 100644 (file)
@@ -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
index 39ae240af62e0435ab590ba687e281367d39764d..4f0d58d5c19cae41cb2b131e9defedfe5191f74c 100644 (file)
@@ -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
index 86428f1687b8a7e6ada0df02e3221b2c774a79b4..00a51dbe321d7a779ef4ebe268aa3be062dad6bf 100644 (file)
@@ -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)
 {
index 95a252e16fb2355cb728e210e3a06899a180e010..f46c2d856ee911fd92f648030084580775803d11 100644 (file)
@@ -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__