changeset 426665ec11a9 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=426665ec11a9
description:
        mem: Page Table map api modification

        This patch adds uncacheable/cacheable and read-only/read-write 
attributes to
        the map method of PageTableBase. It also modifies the constructor of 
TlbEntry
        structs for all architectures to consider the new attributes.

diffstat:

 src/arch/alpha/pagetable.hh            |   6 ++++-
 src/arch/arm/pagetable.hh              |  11 ++++++---
 src/arch/mips/pagetable.hh             |   9 +++++++-
 src/arch/power/tlb.hh                  |   6 ++++-
 src/arch/sparc/pagetable.hh            |  12 +++++++---
 src/arch/x86/pagetable.cc              |   8 ++++--
 src/arch/x86/pagetable.hh              |  36 ++++++++++++++++++++-------------
 src/mem/multi_level_page_table.hh      |   3 +-
 src/mem/multi_level_page_table_impl.hh |  24 +++++++++++++++++----
 src/mem/page_table.cc                  |   7 ++++-
 src/mem/page_table.hh                  |  27 +++++++++++++++++++++++-
 src/sim/Process.py                     |   2 +-
 src/sim/process.cc                     |   7 +++--
 src/sim/process.hh                     |  10 ++++----
 14 files changed, 121 insertions(+), 47 deletions(-)

diffs (truncated from 417 to 300 lines):

diff -r 3a17e8c018b4 -r 426665ec11a9 src/arch/alpha/pagetable.hh
--- a/src/arch/alpha/pagetable.hh       Sun Nov 23 18:01:09 2014 -0800
+++ b/src/arch/alpha/pagetable.hh       Sun Nov 23 18:01:09 2014 -0800
@@ -104,7 +104,8 @@
 
 
     //Construct an entry that maps to physical address addr.
-    TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
+    TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr,
+             bool uncacheable, bool read_only)
     {
         VAddr vaddr(_vaddr);
         VAddr paddr(_paddr);
@@ -117,6 +118,9 @@
         fonr = false;
         fonw = false;
         valid = true;
+        if (uncacheable || read_only)
+            warn("Alpha TlbEntry does not support uncacheable"
+                 " or read-only mappings\n");
     }
 
     TlbEntry()
diff -r 3a17e8c018b4 -r 426665ec11a9 src/arch/arm/pagetable.hh
--- a/src/arch/arm/pagetable.hh Sun Nov 23 18:01:09 2014 -0800
+++ b/src/arch/arm/pagetable.hh Sun Nov 23 18:01:09 2014 -0800
@@ -147,18 +147,21 @@
     bool pxn;               // Privileged Execute Never (LPAE only)
 
     //Construct an entry that maps to physical address addr for SE mode
-    TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr) :
+    TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr,
+             bool uncacheable, bool read_only) :
          pfn(_paddr >> PageShift), size(PageBytes - 1), vpn(_vaddr >> 
PageShift),
          attributes(0), lookupLevel(L1), asid(_asn), vmid(0), N(0),
-         innerAttrs(0), outerAttrs(0), ap(0), hap(0x3),
+         innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3),
          domain(DomainType::Client),  mtype(MemoryType::StronglyOrdered),
          longDescFormat(false), isHyp(false), global(false), valid(true),
-         ns(true), nstid(true), el(0), nonCacheable(false), shareable(false),
-         outerShareable(false), xn(0), pxn(0)
+         ns(true), nstid(true), el(0), nonCacheable(uncacheable),
+         shareable(false), outerShareable(false), xn(0), pxn(0)
     {
         // no restrictions by default, hap = 0x3
 
         // @todo Check the memory type
+        if (read_only)
+            warn("ARM TlbEntry does not support read-only mappings\n");
     }
 
     TlbEntry() :
diff -r 3a17e8c018b4 -r 426665ec11a9 src/arch/mips/pagetable.hh
--- a/src/arch/mips/pagetable.hh        Sun Nov 23 18:01:09 2014 -0800
+++ b/src/arch/mips/pagetable.hh        Sun Nov 23 18:01:09 2014 -0800
@@ -83,7 +83,14 @@
 {
     Addr _pageStart;
     TlbEntry() {}
-    TlbEntry(Addr asn, Addr vaddr, Addr paddr) : _pageStart(paddr) {}
+    TlbEntry(Addr asn, Addr vaddr, Addr paddr,
+             bool uncacheable, bool read_only)
+        : _pageStart(paddr)
+    {
+        if (uncacheable || read_only)
+            warn("MIPS TlbEntry does not support uncacheable"
+                 " or read-only mappings\n");
+    }
 
     Addr pageStart()
     {
diff -r 3a17e8c018b4 -r 426665ec11a9 src/arch/power/tlb.hh
--- a/src/arch/power/tlb.hh     Sun Nov 23 18:01:09 2014 -0800
+++ b/src/arch/power/tlb.hh     Sun Nov 23 18:01:09 2014 -0800
@@ -62,9 +62,13 @@
     {
     }
 
-    TlbEntry(Addr asn, Addr vaddr, Addr paddr)
+    TlbEntry(Addr asn, Addr vaddr, Addr paddr,
+             bool uncacheable, bool read_only)
         : _pageStart(paddr)
     {
+        if (uncacheable || read_only)
+            warn("Power TlbEntry does not support uncacheable"
+                 " or read-only mappings\n");
     }
 
     void
diff -r 3a17e8c018b4 -r 426665ec11a9 src/arch/sparc/pagetable.hh
--- a/src/arch/sparc/pagetable.hh       Sun Nov 23 18:01:09 2014 -0800
+++ b/src/arch/sparc/pagetable.hh       Sun Nov 23 18:01:09 2014 -0800
@@ -230,14 +230,18 @@
     TlbEntry()
     {}
 
-    TlbEntry(Addr asn, Addr vaddr, Addr paddr)
+    TlbEntry(Addr asn, Addr vaddr, Addr paddr,
+             bool uncacheable, bool read_only)
     {
         uint64_t entry = 0;
-        entry |= 1ULL << 1; // Writable
+        if (!read_only)
+            entry |= 1ULL << 1; // Writable
         entry |= 0ULL << 2; // Available in nonpriveleged mode
         entry |= 0ULL << 3; // No side effects
-        entry |= 1ULL << 4; // Virtually cachable
-        entry |= 1ULL << 5; // Physically cachable
+        if (!uncacheable) {
+            entry |= 1ULL << 4; // Virtually cachable
+            entry |= 1ULL << 5; // Physically cachable
+        }
         entry |= 0ULL << 6; // Not locked
         entry |= mbits(paddr, 39, 13); // Physical address
         entry |= 0ULL << 48; // size = 8k
diff -r 3a17e8c018b4 -r 426665ec11a9 src/arch/x86/pagetable.cc
--- a/src/arch/x86/pagetable.cc Sun Nov 23 18:01:09 2014 -0800
+++ b/src/arch/x86/pagetable.cc Sun Nov 23 18:01:09 2014 -0800
@@ -45,9 +45,11 @@
 namespace X86ISA
 {
 
-TlbEntry::TlbEntry(Addr asn, Addr _vaddr, Addr _paddr) :
-    paddr(_paddr), vaddr(_vaddr), logBytes(PageShift), writable(true),
-    user(true), uncacheable(false), global(false), patBit(0), noExec(false)
+TlbEntry::TlbEntry(Addr asn, Addr _vaddr, Addr _paddr,
+                   bool uncacheable, bool read_only) :
+    paddr(_paddr), vaddr(_vaddr), logBytes(PageShift), writable(!read_only),
+    user(true), uncacheable(uncacheable), global(false), patBit(0),
+    noExec(false)
 {}
 
 void
diff -r 3a17e8c018b4 -r 426665ec11a9 src/arch/x86/pagetable.hh
--- a/src/arch/x86/pagetable.hh Sun Nov 23 18:01:09 2014 -0800
+++ b/src/arch/x86/pagetable.hh Sun Nov 23 18:01:09 2014 -0800
@@ -128,7 +128,8 @@
 
         TlbEntryTrie::Handle trieHandle;
 
-        TlbEntry(Addr asn, Addr _vaddr, Addr _paddr);
+        TlbEntry(Addr asn, Addr _vaddr, Addr _paddr,
+                 bool uncacheable, bool read_only);
         TlbEntry() {}
 
         void
@@ -157,13 +158,12 @@
      */
     const std::vector<uint8_t> PageTableLayout = {9, 9, 9, 9};
 
+    /* x86 specific PTE flags */
     enum PTEField{
-        PTE_NotPresent = 0,
-        PTE_Present,
-        PTE_ReadOnly = 0,
-        PTE_ReadWrite,
-        PTE_Supervisor = 0,
-        PTE_UserSupervisor,
+        PTE_NotPresent  = 1,
+        PTE_Supervisor  = 2,
+        PTE_ReadOnly    = 4,
+        PTE_Uncacheable = 8,
     };
 
     /** Page table operations specific to x86 ISA.
@@ -172,14 +172,12 @@
     class PageTableOps
     {
       public:
-        void setPTEFields(PageTableEntry& PTE,
-                          uint64_t present = PTE_Present,
-                          uint64_t read_write = PTE_ReadWrite,
-                          uint64_t user_supervisor = PTE_UserSupervisor)
+        void setPTEFields(PageTableEntry& PTE, uint64_t flags = 0)
         {
-            PTE.p = present;
-            PTE.w = read_write;
-            PTE.u = user_supervisor;// both user and supervisor access allowed
+            PTE.p   = flags & PTE_NotPresent  ? 0 : 1;
+            PTE.pcd = flags & PTE_Uncacheable ? 1 : 0;
+            PTE.w   = flags & PTE_ReadOnly    ? 0 : 1;
+            PTE.u   = flags & PTE_Supervisor  ? 0 : 1;
         }
 
         /** returns the physical memory address of the page table */
@@ -196,6 +194,16 @@
             return PTE.base;
         }
 
+        bool isUncacheable(const PageTableEntry PTE)
+        {
+            return PTE.pcd;
+        }
+
+        bool isReadOnly(PageTableEntry PTE)
+        {
+            return !PTE.w;
+        }
+
         /** sets the page number in a page table entry */
         void setPnum(PageTableEntry& PTE, Addr paddr)
         {
diff -r 3a17e8c018b4 -r 426665ec11a9 src/mem/multi_level_page_table.hh
--- a/src/mem/multi_level_page_table.hh Sun Nov 23 18:01:09 2014 -0800
+++ b/src/mem/multi_level_page_table.hh Sun Nov 23 18:01:09 2014 -0800
@@ -147,7 +147,8 @@
 
     void initState(ThreadContext* tc);
 
-    void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false);
+    void map(Addr vaddr, Addr paddr, int64_t size,
+             uint64_t flags = 0);
     void remap(Addr vaddr, int64_t size, Addr new_vaddr);
     void unmap(Addr vaddr, int64_t size);
     bool isUnmapped(Addr vaddr, int64_t size);
diff -r 3a17e8c018b4 -r 426665ec11a9 src/mem/multi_level_page_table_impl.hh
--- a/src/mem/multi_level_page_table_impl.hh    Sun Nov 23 18:01:09 2014 -0800
+++ b/src/mem/multi_level_page_table_impl.hh    Sun Nov 23 18:01:09 2014 -0800
@@ -137,8 +137,9 @@
 template <class ISAOps>
 void
 MultiLevelPageTable<ISAOps>::map(Addr vaddr, Addr paddr,
-                                 int64_t size, bool clobber)
+                                 int64_t size, uint64_t flags)
 {
+    bool clobber = flags & Clobber;
     // starting address must be page aligned
     assert(pageOffset(vaddr) == 0);
 
@@ -155,12 +156,21 @@
                 fatal("addr 0x%x already mapped to %x", vaddr, entry_paddr);
             }
             pTableISAOps.setPnum(PTE, paddr >> PageShift);
-            pTableISAOps.setPTEFields(PTE);
+            uint64_t PTE_flags = 0;
+            if (flags & NotPresent)
+                PTE_flags |= TheISA::PTE_NotPresent;
+            if (flags & Uncacheable)
+                PTE_flags |= TheISA::PTE_Uncacheable;
+            if (flags & ReadOnly)
+                PTE_flags |= TheISA::PTE_ReadOnly;
+            pTableISAOps.setPTEFields(PTE, PTE_flags);
             p.write<PageTableEntry>(PTE_addr, PTE);
             DPRINTF(MMU, "New mapping: %#x-%#x\n", vaddr, paddr);
 
             eraseCacheEntry(vaddr);
-            updateCache(vaddr, TlbEntry(pid, vaddr, paddr));
+            updateCache(vaddr, TlbEntry(pid, vaddr, paddr,
+                                        flags & Uncacheable,
+                                        flags & ReadOnly));
         }
 
     }
@@ -205,7 +215,9 @@
             }
 
             eraseCacheEntry(vaddr);
-            updateCache(new_vaddr, TlbEntry(pid, new_vaddr, paddr));
+            updateCache(new_vaddr, TlbEntry(pid, new_vaddr, paddr,
+                                            pTableISAOps.isUncacheable(PTE),
+                                            pTableISAOps.isReadOnly(PTE)));
         } else {
             fatal("Page fault while remapping");
         }
@@ -290,7 +302,9 @@
         if (pnum == 0)
             return false;
 
-        entry = TlbEntry(pid, vaddr, pnum << PageShift);
+        entry = TlbEntry(pid, vaddr, pnum << PageShift,
+                         pTableISAOps.isUncacheable(PTE),
+                         pTableISAOps.isReadOnly(PTE));
         updateCache(page_addr, entry);
     } else {
         return false;
diff -r 3a17e8c018b4 -r 426665ec11a9 src/mem/page_table.cc
--- a/src/mem/page_table.cc     Sun Nov 23 18:01:09 2014 -0800
+++ b/src/mem/page_table.cc     Sun Nov 23 18:01:09 2014 -0800
@@ -62,8 +62,9 @@
 }
 
 void
-FuncPageTable::map(Addr vaddr, Addr paddr, int64_t size, bool clobber)
+FuncPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
 {
+    bool clobber = flags & Clobber;
     // starting address must be page aligned
     assert(pageOffset(vaddr) == 0);
 
@@ -75,7 +76,9 @@
             fatal("FuncPageTable::allocate: addr 0x%x already mapped", vaddr);
         }
 
-        pTable[vaddr] = TheISA::TlbEntry(pid, vaddr, paddr);
+        pTable[vaddr] = TheISA::TlbEntry(pid, vaddr, paddr,
+                                         flags & Uncacheable,
+                                         flags & ReadOnly);
         eraseCacheEntry(vaddr);
         updateCache(vaddr, pTable[vaddr]);
     }
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to