summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/pagetable.hh147
-rw-r--r--src/arch/x86/process.cc34
-rw-r--r--src/arch/x86/process.hh2
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;