mem: adding architectural page table support for SE mode
authorAlexandru <alexandru.dutu@amd.com>
Thu, 28 Aug 2014 15:11:44 +0000 (10:11 -0500)
committerAlexandru <alexandru.dutu@amd.com>
Thu, 28 Aug 2014 15:11:44 +0000 (10:11 -0500)
This patch enables the use of page tables that are stored in system memory
and respect x86 specification, in SE mode. It defines an architectural
page table for x86 as a MultiLevelPageTable class and puts a placeholder
class for other ISAs page tables, giving the possibility for future
implementation.

13 files changed:
src/arch/alpha/process.hh
src/arch/arm/process.hh
src/arch/mips/process.hh
src/arch/power/process.hh
src/arch/sparc/process.hh
src/arch/x86/pagetable.hh
src/arch/x86/pagetable_walker.cc
src/arch/x86/process.hh
src/arch/x86/system.hh
src/mem/SConscript
src/sim/Process.py
src/sim/process.cc
src/sim/process.hh

index 8c8288341b743b00b91b9f1a47ccf6e778693c9e..d3f9fdfc39ee2197c6683ab179bd082e2bb4ca2d 100644 (file)
@@ -55,4 +55,7 @@ class AlphaLiveProcess : public LiveProcess
     void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
 };
 
+/* No architectural page table defined for this ISA */
+typedef NoArchPageTable ArchPageTable;
+
 #endif // __ARCH_ALPHA_PROCESS_HH__
index 34ce1dd02cb546ea77f3034c40b7889fb8062e9c..1b77f9e4a06c14815244ff21c7be8c96a539d437 100644 (file)
@@ -98,5 +98,8 @@ class ArmLiveProcess64 : public ArmLiveProcess
     void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
 };
 
+/* No architectural page table defined for this ISA */
+typedef NoArchPageTable ArchPageTable;
+
 #endif // __ARM_PROCESS_HH__
 
index a126344caea5947201b157cfded93557060010a4..33c02d08b514870904d28aff649fc149bd49d21a 100644 (file)
@@ -59,5 +59,8 @@ class MipsLiveProcess : public LiveProcess
     void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
 };
 
+/* No architectural page table defined for this ISA */
+typedef NoArchPageTable ArchPageTable;
+
 
 #endif // __MIPS_PROCESS_HH__
index 977b75ae81aea8c0478451e9614b2df95b45a764..b96c77c70747d01a14661eb8722e36f889361509 100644 (file)
@@ -58,5 +58,8 @@ class PowerLiveProcess : public LiveProcess
     void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
 };
 
+/* No architectural page table defined for this ISA */
+typedef NoArchPageTable ArchPageTable;
+
 #endif // __POWER_PROCESS_HH__
 
index 119f608ba41e3531808f566963253326aed73701..2eda40aacef053a12706ede253d254eef4d569d6 100644 (file)
@@ -131,4 +131,7 @@ class Sparc64LiveProcess : public SparcLiveProcess
     void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
 };
 
+/* No architectural page table defined for this ISA */
+typedef NoArchPageTable ArchPageTable;
+
 #endif // __SPARC_PROCESS_HH__
index 2a7ade85375921ce858f65c9cf8ae2138f849e98..86e488bdc0ad7a92d6a658ab590db5a8c33e1178 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
  * Copyright (c) 2007 The Hewlett-Packard Development Company
  * All rights reserved.
  *
 
 #include <iostream>
 #include <string>
+#include <vector>
 
 #include "base/bitunion.hh"
 #include "base/misc.hh"
 #include "base/types.hh"
 #include "base/trie.hh"
+#include "cpu/thread_context.hh"
+#include "arch/x86/system.hh"
+#include "debug/MMU.hh"
 
 class Checkpoint;
 
@@ -73,6 +78,25 @@ namespace X86ISA
         Bitfield<31, 22> norml2;
     EndBitUnion(VAddr)
 
+    // Unfortunately, the placement of the base field in a page table entry is
+    // very erratic and would make a mess here. It might be moved here at some
+    // point in the future.
+    BitUnion64(PageTableEntry)
+        Bitfield<63> nx;
+        Bitfield<51, 12> base;
+        Bitfield<11, 9> avl;
+        Bitfield<8> g;
+        Bitfield<7> ps;
+        Bitfield<6> d;
+        Bitfield<5> a;
+        Bitfield<4> pcd;
+        Bitfield<3> pwt;
+        Bitfield<2> u;
+        Bitfield<1> w;
+        Bitfield<0> p;
+    EndBitUnion(PageTableEntry)
+
+
     struct TlbEntry
     {
         // The base of the physical page.
@@ -127,6 +151,67 @@ namespace X86ISA
         void serialize(std::ostream &os);
         void unserialize(Checkpoint *cp, const std::string &section);
     };
+
+    /** The size of each level of the page table expressed in base 2
+     * logarithmic values
+     */
+    const std::vector<uint8_t> PageTableLayout = {9, 9, 9, 9};
+
+    enum PTEField{
+        PTE_NotPresent = 0,
+        PTE_Present,
+        PTE_ReadOnly = 0,
+        PTE_ReadWrite,
+        PTE_Supervisor = 0,
+        PTE_UserSupervisor,
+    };
+
+    /** Page table operations specific to x86 ISA.
+     * Indended to be used as parameter of MultiLevelPageTable.
+     */
+    class PageTableOps
+    {
+      public:
+        void setPTEFields(PageTableEntry& PTE,
+                          uint64_t present = PTE_Present,
+                          uint64_t read_write = PTE_ReadWrite,
+                          uint64_t user_supervisor = PTE_UserSupervisor)
+        {
+            PTE.p = present;
+            PTE.w = read_write;
+            PTE.u = user_supervisor;// both user and supervisor access allowed
+        }
+
+        /** returns the physical memory address of the page table */
+        Addr getBasePtr(ThreadContext* tc)
+        {
+            CR3 cr3 = pageTablePhysAddr;
+            DPRINTF(MMU, "CR3: %d\n", cr3);
+            return cr3.longPdtb;
+        }
+
+        /** returns the page number out of a page table entry */
+        Addr getPnum(PageTableEntry PTE)
+        {
+            return PTE.base;
+        }
+
+        /** sets the page number in a page table entry */
+        void setPnum(PageTableEntry& PTE, Addr paddr)
+        {
+            PTE.base = paddr;
+        }
+
+        /** returns the offsets to index in every level of a page
+         * table, contained in a virtual address
+         */
+        std::vector<uint64_t> getOffsets(Addr vaddr)
+        {
+            X86ISA::VAddr addr(vaddr);
+            return {addr.longl1, addr.longl2, addr.longl3, addr.longl4};
+        }
+    };
+
 }
 
 #endif
index e75f2edc4ef38fbb9e33b2c3b611d3e894476146..3d8cc92927c2ec7a155a81c6d6fc9516d9636e38 100644 (file)
 
 namespace X86ISA {
 
-// Unfortunately, the placement of the base field in a page table entry is
-// very erratic and would make a mess here. It might be moved here at some
-// point in the future.
-BitUnion64(PageTableEntry)
-    Bitfield<63> nx;
-    Bitfield<11, 9> avl;
-    Bitfield<8> g;
-    Bitfield<7> ps;
-    Bitfield<6> d;
-    Bitfield<5> a;
-    Bitfield<4> pcd;
-    Bitfield<3> pwt;
-    Bitfield<2> u;
-    Bitfield<1> w;
-    Bitfield<0> p;
-EndBitUnion(PageTableEntry)
-
 Fault
 Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
               RequestPtr _req, BaseTLB::Mode _mode)
index 6a221e792b1b64861d57147219b83f5ba216a4b9..2fb05195359d7927c015486baf5a97d1925ca81b 100644 (file)
@@ -44,6 +44,7 @@
 #include <vector>
 
 #include "sim/process.hh"
+#include "mem/multi_level_page_table.hh"
 
 class SyscallDesc;
 
@@ -133,6 +134,14 @@ namespace X86ISA
         X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
         void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
     };
+
+    /**
+     * Declaration of architectural page table for x86.
+     *
+     * These page tables are stored in system memory and respect x86 specification.
+     */
+    typedef MultiLevelPageTable<PageTableOps> ArchPageTable;
+
 }
 
 #endif // __ARCH_X86_PROCESS_HH__
index 998a69cd74041891c19df5164d59cd96e0c39741..e8dd2f8b3cf5b1a25184437253c86d131793d01e 100644 (file)
@@ -61,6 +61,20 @@ namespace X86ISA
         class FloatingPointer;
         class ConfigTable;
     }
+
+    /* memory mappings for KVMCpu in SE mode */
+    const uint64_t syscallCodeVirtAddr = 0xffff800000000000;
+    const uint64_t syscallCodePhysAddr = 0x60000;
+    const uint64_t GDTVirtAddr = 0xffff800000001000;
+    const uint64_t GDTPhysAddr = 0x61000;
+    const uint64_t IDTVirtAddr = 0xffff800000002000;
+    const uint64_t IDTPhysAddr = 0x62000;
+    const uint64_t TSSVirtAddr = 0xffff800000003000;
+    const uint64_t TSSPhysAddr = 0x63000;
+    const uint64_t ISTVirtAddr = 0xffff800000004000;
+    const uint64_t ISTPhysAddr = 0x64000;
+
+    const uint64_t pageTablePhysAddr = 0x70000;
 }
 
 class X86System : public System
index 50b00e8dbb0217a9be6481c06b2c73f321edcf83..dd96879e6b70b5435e790e19272085481cd8dd0e 100644 (file)
@@ -65,6 +65,8 @@ if env['TARGET_ISA'] != 'null':
     Source('fs_translating_port_proxy.cc')
     Source('se_translating_port_proxy.cc')
     Source('page_table.cc')
+if env['TARGET_ISA'] == 'x86':
+    Source('multi_level_page_table.cc')
 
 if env['HAVE_DRAMSIM']:
     SimObject('DRAMSim2.py')
index 55ccc50d02aabd5c80cce131e4c0c8b5b4379421..6f2322805c32ac6afeaf94a4ee41a01a5095f9e5 100644 (file)
@@ -38,6 +38,8 @@ class Process(SimObject):
     output = Param.String('cout', 'filename for stdout')
     errout = Param.String('cerr', 'filename for stderr')
     system = Param.System(Parent.any, "system process will run on")
+    useArchPT = Param.Bool('false', 'maintain an in-memory version of the page\
+                            table in an architecture-specific format')
     max_stack_size = Param.MemorySize('64MB', 'maximum size of the stack')
 
     @classmethod
index d9f9a0fe6cf86118052da0b63286296e7aa7f0e5..a738908e17c74e125406df6a99aaee8509de30d0 100644 (file)
@@ -106,7 +106,10 @@ Process::Process(ProcessParams * params)
     : SimObject(params), system(params->system),
       max_stack_size(params->max_stack_size),
       M5_pid(system->allocatePID()),
-      pTable(new FuncPageTable(name(), M5_pid)),
+      useArchPT(params->useArchPT),
+      pTable(useArchPT ?
+        static_cast<PageTableBase *>(new ArchPageTable(name(), M5_pid, system)) :
+        static_cast<PageTableBase *>(new FuncPageTable(name(), M5_pid)) ),
       initVirtMem(system->getSystemPort(), this,
                   SETranslatingPortProxy::Always)
 {
index 361e07bca39bcaf897fe860e0edfda2a3cf8d113..03380acf74f02ffb0e6b0f6ffec24c00f1ea12e9 100644 (file)
@@ -125,6 +125,8 @@ class Process : public SimObject
     //separated.
     uint64_t M5_pid;
 
+    // flag for using architecture specific page table
+    bool useArchPT;
     PageTableBase* pTable;
 
     class FdMap