diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 8c8288341..d3f9fdfc3 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -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__ diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh index 34ce1dd02..1b77f9e4a 100644 --- a/src/arch/arm/process.hh +++ b/src/arch/arm/process.hh @@ -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__ diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index a126344ca..33c02d08b 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -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__ diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh index 977b75ae8..b96c77c70 100644 --- a/src/arch/power/process.hh +++ b/src/arch/power/process.hh @@ -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__ diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index 119f608ba..2eda40aac 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -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__ diff --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh index 2a7ade853..86e488bdc 100644 --- a/src/arch/x86/pagetable.hh +++ b/src/arch/x86/pagetable.hh @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014 Advanced Micro Devices, Inc. * Copyright (c) 2007 The Hewlett-Packard Development Company * All rights reserved. * @@ -42,11 +43,15 @@ #include #include +#include #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 §ion); }; + + /** The size of each level of the page table expressed in base 2 + * logarithmic values + */ + const std::vector 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 getOffsets(Addr vaddr) + { + X86ISA::VAddr addr(vaddr); + return {addr.longl1, addr.longl2, addr.longl3, addr.longl4}; + } + }; + } #endif diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index e75f2edc4..3d8cc9292 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -63,23 +63,6 @@ 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) diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index 6a221e792..2fb051953 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -44,6 +44,7 @@ #include #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 ArchPageTable; + } #endif // __ARCH_X86_PROCESS_HH__ diff --git a/src/arch/x86/system.hh b/src/arch/x86/system.hh index 998a69cd7..e8dd2f8b3 100644 --- a/src/arch/x86/system.hh +++ b/src/arch/x86/system.hh @@ -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 diff --git a/src/mem/SConscript b/src/mem/SConscript index 50b00e8db..dd96879e6 100644 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@ -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') diff --git a/src/sim/Process.py b/src/sim/Process.py index 55ccc50d0..6f2322805 100644 --- a/src/sim/Process.py +++ b/src/sim/Process.py @@ -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 diff --git a/src/sim/process.cc b/src/sim/process.cc index d9f9a0fe6..a738908e1 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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(new ArchPageTable(name(), M5_pid, system)) : + static_cast(new FuncPageTable(name(), M5_pid)) ), initVirtMem(system->getSystemPort(), this, SETranslatingPortProxy::Always) { diff --git a/src/sim/process.hh b/src/sim/process.hh index 361e07bca..03380acf7 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -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