X86: Turn on the page table walker in SE mode.
This commit is contained in:
parent
4b2e5ebead
commit
8adc6781bf
5 changed files with 50 additions and 55 deletions
|
@ -57,6 +57,7 @@ if env['TARGET_ISA'] == 'x86':
|
||||||
Source('isa.cc')
|
Source('isa.cc')
|
||||||
Source('nativetrace.cc')
|
Source('nativetrace.cc')
|
||||||
Source('pagetable.cc')
|
Source('pagetable.cc')
|
||||||
|
Source('pagetable_walker.cc')
|
||||||
Source('predecoder.cc')
|
Source('predecoder.cc')
|
||||||
Source('predecoder_tables.cc')
|
Source('predecoder_tables.cc')
|
||||||
Source('remote_gdb.cc')
|
Source('remote_gdb.cc')
|
||||||
|
@ -70,18 +71,17 @@ if env['TARGET_ISA'] == 'x86':
|
||||||
|
|
||||||
DebugFlag('Faults', "Trace all faults/exceptions/traps")
|
DebugFlag('Faults', "Trace all faults/exceptions/traps")
|
||||||
DebugFlag('LocalApic', "Local APIC debugging")
|
DebugFlag('LocalApic', "Local APIC debugging")
|
||||||
|
DebugFlag('PageTableWalker', \
|
||||||
|
"Page table walker state machine debugging")
|
||||||
DebugFlag('Predecoder', "Predecoder debug output")
|
DebugFlag('Predecoder', "Predecoder debug output")
|
||||||
DebugFlag('X86', "Generic X86 ISA debugging")
|
DebugFlag('X86', "Generic X86 ISA debugging")
|
||||||
|
|
||||||
if env['FULL_SYSTEM']:
|
if env['FULL_SYSTEM']:
|
||||||
DebugFlag('PageTableWalker', \
|
|
||||||
"Page table walker state machine debugging")
|
|
||||||
|
|
||||||
SimObject('X86System.py')
|
SimObject('X86System.py')
|
||||||
|
|
||||||
# Full-system sources
|
# Full-system sources
|
||||||
Source('linux/system.cc')
|
Source('linux/system.cc')
|
||||||
Source('pagetable_walker.cc')
|
|
||||||
Source('system.cc')
|
Source('system.cc')
|
||||||
Source('stacktrace.cc')
|
Source('stacktrace.cc')
|
||||||
Source('vtophys.cc')
|
Source('vtophys.cc')
|
||||||
|
|
|
@ -35,24 +35,21 @@
|
||||||
#
|
#
|
||||||
# Authors: Gabe Black
|
# Authors: Gabe Black
|
||||||
|
|
||||||
from m5.defines import buildEnv
|
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
|
|
||||||
from BaseTLB import BaseTLB
|
from BaseTLB import BaseTLB
|
||||||
from MemObject import MemObject
|
from MemObject import MemObject
|
||||||
|
|
||||||
if buildEnv['FULL_SYSTEM']:
|
class X86PagetableWalker(MemObject):
|
||||||
class X86PagetableWalker(MemObject):
|
type = 'X86PagetableWalker'
|
||||||
type = 'X86PagetableWalker'
|
cxx_class = 'X86ISA::Walker'
|
||||||
cxx_class = 'X86ISA::Walker'
|
port = Port("Port for the hardware table walker")
|
||||||
port = Port("Port for the hardware table walker")
|
system = Param.System(Parent.any, "system object")
|
||||||
system = Param.System(Parent.any, "system object")
|
|
||||||
|
|
||||||
class X86TLB(BaseTLB):
|
class X86TLB(BaseTLB):
|
||||||
type = 'X86TLB'
|
type = 'X86TLB'
|
||||||
cxx_class = 'X86ISA::TLB'
|
cxx_class = 'X86ISA::TLB'
|
||||||
size = Param.Int(64, "TLB size")
|
size = Param.Int(64, "TLB size")
|
||||||
if buildEnv['FULL_SYSTEM']:
|
walker = Param.X86PagetableWalker(\
|
||||||
walker = Param.X86PagetableWalker(\
|
X86PagetableWalker(), "page table walker")
|
||||||
X86PagetableWalker(), "page table walker")
|
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "arch/x86/regs/msr.hh"
|
#include "arch/x86/regs/msr.hh"
|
||||||
#include "arch/x86/faults.hh"
|
#include "arch/x86/faults.hh"
|
||||||
#include "arch/x86/pagetable.hh"
|
#include "arch/x86/pagetable.hh"
|
||||||
|
#include "arch/x86/pagetable_walker.hh"
|
||||||
#include "arch/x86/tlb.hh"
|
#include "arch/x86/tlb.hh"
|
||||||
#include "arch/x86/x86_traits.hh"
|
#include "arch/x86/x86_traits.hh"
|
||||||
#include "base/bitfield.hh"
|
#include "base/bitfield.hh"
|
||||||
|
@ -55,13 +56,13 @@
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
#include "mem/request.hh"
|
#include "mem/request.hh"
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
#include "arch/x86/pagetable_walker.hh"
|
|
||||||
#else
|
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "sim/full_system.hh"
|
||||||
|
|
||||||
namespace X86ISA {
|
namespace X86ISA {
|
||||||
|
|
||||||
TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size)
|
TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size)
|
||||||
|
@ -72,10 +73,8 @@ TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size)
|
||||||
for (int x = 0; x < size; x++)
|
for (int x = 0; x < size; x++)
|
||||||
freeList.push_back(&tlb[x]);
|
freeList.push_back(&tlb[x]);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
walker = p->walker;
|
walker = p->walker;
|
||||||
walker->setTLB(this);
|
walker->setTLB(this);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TlbEntry *
|
TlbEntry *
|
||||||
|
@ -293,40 +292,42 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
||||||
// The vaddr already has the segment base applied.
|
// The vaddr already has the segment base applied.
|
||||||
TlbEntry *entry = lookup(vaddr);
|
TlbEntry *entry = lookup(vaddr);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
#if FULL_SYSTEM
|
if (FullSystem) {
|
||||||
Fault fault = walker->start(tc, translation, req, mode);
|
Fault fault = walker->start(tc, translation, req, mode);
|
||||||
if (timing || fault != NoFault) {
|
if (timing || fault != NoFault) {
|
||||||
// This gets ignored in atomic mode.
|
// This gets ignored in atomic mode.
|
||||||
delayedResponse = true;
|
delayedResponse = true;
|
||||||
return fault;
|
return fault;
|
||||||
}
|
|
||||||
entry = lookup(vaddr);
|
|
||||||
assert(entry);
|
|
||||||
#else
|
|
||||||
DPRINTF(TLB, "Handling a TLB miss for "
|
|
||||||
"address %#x at pc %#x.\n",
|
|
||||||
vaddr, tc->instAddr());
|
|
||||||
|
|
||||||
Process *p = tc->getProcessPtr();
|
|
||||||
TlbEntry newEntry;
|
|
||||||
bool success = p->pTable->lookup(vaddr, newEntry);
|
|
||||||
if (!success && mode != Execute) {
|
|
||||||
// Check if we just need to grow the stack.
|
|
||||||
if (p->fixupStackFault(vaddr)) {
|
|
||||||
// If we did, lookup the entry for the new page.
|
|
||||||
success = p->pTable->lookup(vaddr, newEntry);
|
|
||||||
}
|
}
|
||||||
}
|
entry = lookup(vaddr);
|
||||||
if (!success) {
|
assert(entry);
|
||||||
return new PageFault(vaddr, true, mode, true, false);
|
|
||||||
} else {
|
} else {
|
||||||
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
#if !FULL_SYSTEM
|
||||||
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
|
DPRINTF(TLB, "Handling a TLB miss for "
|
||||||
newEntry.pageStart());
|
"address %#x at pc %#x.\n",
|
||||||
entry = insert(alignedVaddr, newEntry);
|
vaddr, tc->instAddr());
|
||||||
}
|
|
||||||
DPRINTF(TLB, "Miss was serviced.\n");
|
Process *p = tc->getProcessPtr();
|
||||||
|
TlbEntry newEntry;
|
||||||
|
bool success = p->pTable->lookup(vaddr, newEntry);
|
||||||
|
if (!success && mode != Execute) {
|
||||||
|
// Check if we just need to grow the stack.
|
||||||
|
if (p->fixupStackFault(vaddr)) {
|
||||||
|
// If we did, lookup the entry for the new page.
|
||||||
|
success = p->pTable->lookup(vaddr, newEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
return new PageFault(vaddr, true, mode, true, false);
|
||||||
|
} else {
|
||||||
|
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
||||||
|
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
|
||||||
|
newEntry.pageStart());
|
||||||
|
entry = insert(alignedVaddr, newEntry);
|
||||||
|
}
|
||||||
|
DPRINTF(TLB, "Miss was serviced.\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Do paging protection checks.
|
// Do paging protection checks.
|
||||||
bool inUser = (m5Reg.cpl == 3 &&
|
bool inUser = (m5Reg.cpl == 3 &&
|
||||||
|
|
|
@ -85,15 +85,11 @@ namespace X86ISA
|
||||||
|
|
||||||
EntryList::iterator lookupIt(Addr va, bool update_lru = true);
|
EntryList::iterator lookupIt(Addr va, bool update_lru = true);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Walker * walker;
|
Walker * walker;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Walker *getWalker();
|
Walker *getWalker();
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
void invalidateAll();
|
void invalidateAll();
|
||||||
|
|
||||||
void invalidateNonGlobal();
|
void invalidateNonGlobal();
|
||||||
|
|
|
@ -140,7 +140,8 @@ class BaseCPU(MemObject):
|
||||||
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
|
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
|
||||||
|
|
||||||
_cached_ports = []
|
_cached_ports = []
|
||||||
if buildEnv['TARGET_ISA'] in ['x86', 'arm'] and buildEnv['FULL_SYSTEM']:
|
if buildEnv['TARGET_ISA'] == 'x86' or \
|
||||||
|
(buildEnv['TARGET_ISA'] == 'arm' and buildEnv['FULL_SYSTEM']):
|
||||||
_cached_ports = ["itb.walker.port", "dtb.walker.port"]
|
_cached_ports = ["itb.walker.port", "dtb.walker.port"]
|
||||||
|
|
||||||
_uncached_ports = []
|
_uncached_ports = []
|
||||||
|
|
Loading…
Reference in a new issue