diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86/pagetable.hh | 147 | ||||
-rw-r--r-- | src/arch/x86/process.cc | 34 | ||||
-rw-r--r-- | src/arch/x86/process.hh | 2 |
3 files changed, 89 insertions, 94 deletions
diff --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh index 490a2591b..f5e1a05f0 100644 --- a/src/arch/x86/pagetable.hh +++ b/src/arch/x86/pagetable.hh @@ -63,39 +63,6 @@ typedef Trie<Addr, X86ISA::TlbEntry> TlbEntryTrie; namespace X86ISA { - BitUnion64(VAddr) - Bitfield<20, 12> longl1; - Bitfield<29, 21> longl2; - Bitfield<38, 30> longl3; - Bitfield<47, 39> longl4; - - Bitfield<20, 12> pael1; - Bitfield<29, 21> pael2; - Bitfield<31, 30> pael3; - - Bitfield<21, 12> norml1; - 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 : public Serializable { // The base of the physical page. @@ -152,65 +119,87 @@ namespace X86ISA void unserialize(CheckpointIn &cp) override; }; - /** 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}; - - /* x86 specific PTE flags */ - enum PTEField{ - PTE_NotPresent = 1, - PTE_Supervisor = 2, - PTE_ReadOnly = 4, - PTE_Uncacheable = 8, - }; - /** Page table operations specific to x86 ISA. - * Indended to be used as parameter of MultiLevelPageTable. - */ - class PageTableOps + BitUnion64(VAddr) + Bitfield<20, 12> longl1; + Bitfield<29, 21> longl2; + Bitfield<38, 30> longl3; + Bitfield<47, 39> longl4; + + Bitfield<20, 12> pael1; + Bitfield<29, 21> pael2; + Bitfield<31, 30> pael3; + + Bitfield<21, 12> norml1; + 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) + + template <int first, int last> + class LongModePTE { public: - void setPTEFields(PageTableEntry& PTE, uint64_t flags = 0) - { - 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; - } + Addr paddr() { return pte.base << PageShift; } + void paddr(Addr addr) { pte.base = addr >> PageShift; } - /** returns the page number out of a page table entry */ - Addr getPnum(PageTableEntry PTE) - { - return PTE.base; - } + bool present() { return pte.p; } + void present(bool p) { pte.p = p ? 1 : 0; } - bool isUncacheable(const PageTableEntry PTE) - { - return PTE.pcd; - } + bool uncacheable() { return pte.pcd; } + void uncacheable(bool u) { pte.pcd = u ? 1 : 0; } - bool isReadOnly(PageTableEntry PTE) - { - return !PTE.w; - } + bool readonly() { return !pte.w; } + void readonly(bool r) { pte.w = r ? 0 : 1; } - /** sets the page number in a page table entry */ - void setPnum(PageTableEntry& PTE, Addr paddr) + void + read(PortProxy &p, Addr table, Addr vaddr) { - PTE.base = paddr; + entryAddr = table; + entryAddr += bits(vaddr, first, last) * sizeof(PageTableEntry); + pte = p.read<PageTableEntry>(entryAddr); } - /** returns the offsets to index in every level of a page - * table, contained in a virtual address - */ - std::vector<uint64_t> getOffsets(Addr vaddr) + void + reset(Addr _paddr, bool _present=true, + bool _uncacheable=false, bool _readonly=false) + { + pte = 0; + pte.u = 1; + paddr(_paddr); + present(_present); + uncacheable(_uncacheable); + readonly(_readonly); + }; + + void write(PortProxy &p) { p.write(entryAddr, pte); } + + static int + tableSize() { - X86ISA::VAddr addr(vaddr); - return {addr.longl1, addr.longl2, addr.longl3, addr.longl4}; + return 1 << ((first - last) + 4 - PageShift); } - }; + protected: + PageTableEntry pte; + Addr entryAddr; + }; } #endif diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 43a5273d7..cfec21f39 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -96,14 +96,21 @@ static const int ArgumentReg32[] = { static const int NumArgumentRegs32 M5_VAR_USED = sizeof(ArgumentReg) / sizeof(const int); +template class MultiLevelPageTable<LongModePTE<47, 39>, + LongModePTE<38, 30>, + LongModePTE<29, 21>, + LongModePTE<20, 12> >; +typedef MultiLevelPageTable<LongModePTE<47, 39>, + LongModePTE<38, 30>, + LongModePTE<29, 21>, + LongModePTE<20, 12> > ArchPageTable; + X86Process::X86Process(ProcessParams *params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs) : Process(params, params->useArchPT ? static_cast<EmulationPageTable *>( - new ArchPageTable( - params->name, params->pid, - params->system, PageBytes, - PageTableLayout)) : + new ArchPageTable(params->name, params->pid, + params->system, PageBytes)) : new EmulationPageTable(params->name, params->pid, PageBytes), objFile), @@ -543,23 +550,22 @@ X86_64Process::initState() physProxy.writeBlob(pfHandlerPhysAddr, faultBlob, sizeof(faultBlob)); - MultiLevelPageTable<PageTableOps> *pt = - dynamic_cast<MultiLevelPageTable<PageTableOps> *>(pTable); - /* Syscall handler */ - pt->map(syscallCodeVirtAddr, syscallCodePhysAddr, PageBytes, false); + pTable->map(syscallCodeVirtAddr, syscallCodePhysAddr, + PageBytes, false); /* GDT */ - pt->map(GDTVirtAddr, gdtPhysAddr, PageBytes, false); + pTable->map(GDTVirtAddr, gdtPhysAddr, PageBytes, false); /* IDT */ - pt->map(IDTVirtAddr, idtPhysAddr, PageBytes, false); + pTable->map(IDTVirtAddr, idtPhysAddr, PageBytes, false); /* TSS */ - pt->map(TSSVirtAddr, tssPhysAddr, PageBytes, false); + pTable->map(TSSVirtAddr, tssPhysAddr, PageBytes, false); /* IST */ - pt->map(ISTVirtAddr, istPhysAddr, PageBytes, false); + pTable->map(ISTVirtAddr, istPhysAddr, PageBytes, false); /* PF handler */ - pt->map(PFHandlerVirtAddr, pfHandlerPhysAddr, PageBytes, false); + pTable->map(PFHandlerVirtAddr, pfHandlerPhysAddr, PageBytes, false); /* MMIO region for m5ops */ - pt->map(MMIORegionVirtAddr, MMIORegionPhysAddr, 16*PageBytes, false); + pTable->map(MMIORegionVirtAddr, MMIORegionPhysAddr, + 16 * PageBytes, false); } else { for (int i = 0; i < contextIds.size(); i++) { ThreadContext * tc = system->getThreadContext(contextIds[i]); diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index e5e18570d..31706cfdd 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -43,6 +43,7 @@ #include <string> #include <vector> +#include "arch/x86/pagetable.hh" #include "mem/multi_level_page_table.hh" #include "sim/aux_vector.hh" #include "sim/process.hh" @@ -65,7 +66,6 @@ namespace X86ISA * These page tables are stored in system memory and respect x86 * specification. */ - typedef MultiLevelPageTable<PageTableOps> ArchPageTable; Addr _gdtStart; Addr _gdtSize; |