From 1f539f13c32ad5a9187d56a098d4c857639b0e05 Mon Sep 17 00:00:00 2001 From: Alexandru Dutu Date: Sun, 23 Nov 2014 18:01:09 -0800 Subject: 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. --- 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 ++++++++++++++++++++++-------------- 7 files changed, 60 insertions(+), 28 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index b9091d5b6..ca44de7fa 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -104,7 +104,8 @@ struct TlbEntry //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 @@ struct TlbEntry fonr = false; fonw = false; valid = true; + if (uncacheable || read_only) + warn("Alpha TlbEntry does not support uncacheable" + " or read-only mappings\n"); } TlbEntry() diff --git a/src/arch/arm/pagetable.hh b/src/arch/arm/pagetable.hh index 591ec9807..c1956cf09 100644 --- a/src/arch/arm/pagetable.hh +++ b/src/arch/arm/pagetable.hh @@ -147,18 +147,21 @@ struct TlbEntry 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 --git a/src/arch/mips/pagetable.hh b/src/arch/mips/pagetable.hh index 8678eb7e4..992d6649b 100755 --- a/src/arch/mips/pagetable.hh +++ b/src/arch/mips/pagetable.hh @@ -83,7 +83,14 @@ struct TlbEntry { 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 --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh index 9ea1fca8b..0abafc777 100644 --- a/src/arch/power/tlb.hh +++ b/src/arch/power/tlb.hh @@ -62,9 +62,13 @@ struct TlbEntry { } - 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 --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh index aba17e505..727727f95 100644 --- a/src/arch/sparc/pagetable.hh +++ b/src/arch/sparc/pagetable.hh @@ -230,14 +230,18 @@ struct TlbEntry 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 --git a/src/arch/x86/pagetable.cc b/src/arch/x86/pagetable.cc index a9ef18129..cd4df42e7 100644 --- a/src/arch/x86/pagetable.cc +++ b/src/arch/x86/pagetable.cc @@ -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 --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh index 86e488bdc..639815893 100644 --- a/src/arch/x86/pagetable.hh +++ b/src/arch/x86/pagetable.hh @@ -128,7 +128,8 @@ namespace X86ISA 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 @@ namespace X86ISA */ const std::vector 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 @@ namespace X86ISA 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 @@ namespace X86ISA 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) { -- cgit v1.2.3