changeset 569e3b31a868 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=569e3b31a868
description:
X86: Make the X86 TLB take advantage of delayed translations, and get
rid of the fake TLB miss faults.
diffstat:
6 files changed, 187 insertions(+), 192 deletions(-)
src/arch/x86/faults.cc | 50 -----------
src/arch/x86/faults.hh | 32 -------
src/arch/x86/pagetable_walker.cc | 170 +++++++++++++++++++++-----------------
src/arch/x86/pagetable_walker.hh | 26 ++++-
src/arch/x86/tlb.cc | 86 ++++++++++++++-----
src/arch/x86/tlb.hh | 15 +--
diffs (truncated from 738 to 300 lines):
diff -r 8091ac99341a -r 569e3b31a868 src/arch/x86/faults.cc
--- a/src/arch/x86/faults.cc Wed Feb 25 10:16:15 2009 -0800
+++ b/src/arch/x86/faults.cc Wed Feb 25 10:16:21 2009 -0800
@@ -163,56 +163,6 @@
}
}
- void FakeITLBFault::invoke(ThreadContext * tc)
- {
- // Start the page table walker.
- tc->getITBPtr()->walk(tc, vaddr, write, execute);
- }
-
- void FakeDTLBFault::invoke(ThreadContext * tc)
- {
- // Start the page table walker.
- tc->getDTBPtr()->walk(tc, vaddr, write, execute);
- }
-
-#else // !FULL_SYSTEM
- void FakeITLBFault::invoke(ThreadContext * tc)
- {
- DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n",
- vaddr, tc->readPC());
- Process *p = tc->getProcessPtr();
- TlbEntry entry;
- bool success = p->pTable->lookup(vaddr, entry);
- if(!success) {
- panic("Tried to execute unmapped address %#x.\n", vaddr);
- } else {
- Addr alignedVaddr = p->pTable->pageAlign(vaddr);
- DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
- entry.pageStart());
- tc->getITBPtr()->insert(alignedVaddr, entry);
- }
- }
-
- void FakeDTLBFault::invoke(ThreadContext * tc)
- {
- DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n",
- vaddr, tc->readPC());
- Process *p = tc->getProcessPtr();
- TlbEntry entry;
- bool success = p->pTable->lookup(vaddr, entry);
- if(!success) {
- p->checkAndAllocNextPage(vaddr);
- success = p->pTable->lookup(vaddr, entry);
- }
- if(!success) {
- panic("Tried to access unmapped address %#x.\n", vaddr);
- } else {
- Addr alignedVaddr = p->pTable->pageAlign(vaddr);
- DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
- entry.pageStart());
- tc->getDTBPtr()->insert(alignedVaddr, entry);
- }
- }
#endif
} // namespace X86ISA
diff -r 8091ac99341a -r 569e3b31a868 src/arch/x86/faults.hh
--- a/src/arch/x86/faults.hh Wed Feb 25 10:16:15 2009 -0800
+++ b/src/arch/x86/faults.hh Wed Feb 25 10:16:21 2009 -0800
@@ -422,38 +422,6 @@
return true;
}
};
-
- // These faults aren't part of the ISA definition. They trigger filling
- // the tlb on a miss and are to take the place of a hardware table walker.
- class FakeITLBFault : public X86Fault
- {
- protected:
- Addr vaddr;
- bool write;
- bool execute;
- public:
- FakeITLBFault(Addr _vaddr, bool _write, bool _execute) :
- X86Fault("fake instruction tlb fault", "itlb", 0),
- vaddr(_vaddr), write(_write), execute(_execute)
- {}
-
- void invoke(ThreadContext * tc);
- };
-
- class FakeDTLBFault : public X86Fault
- {
- protected:
- Addr vaddr;
- bool write;
- bool execute;
- public:
- FakeDTLBFault(Addr _vaddr, bool _write, bool _execute) :
- X86Fault("fake data tlb fault", "dtlb", 0),
- vaddr(_vaddr), write(_write), execute(_execute)
- {}
-
- void invoke(ThreadContext * tc);
- };
};
#endif // __ARCH_X86_FAULTS_HH__
diff -r 8091ac99341a -r 569e3b31a868 src/arch/x86/pagetable_walker.cc
--- a/src/arch/x86/pagetable_walker.cc Wed Feb 25 10:16:15 2009 -0800
+++ b/src/arch/x86/pagetable_walker.cc Wed Feb 25 10:16:21 2009 -0800
@@ -84,7 +84,7 @@
Bitfield<0> p;
EndBitUnion(PageTableEntry)
-void
+Fault
Walker::doNext(PacketPtr &read, PacketPtr &write)
{
assert(state != Ready && state != Waiting);
@@ -106,11 +106,11 @@
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (badNX)
- panic("NX violation!\n");
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
entry.noExec = pte.nx;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
nextState = LongPDP;
break;
case LongPDP:
@@ -119,10 +119,10 @@
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
nextState = LongPD;
break;
case LongPD:
@@ -130,10 +130,10 @@
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
if (!pte.ps) {
// 4 KB page
entry.size = 4 * (1 << 10);
@@ -150,36 +150,32 @@
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
}
case LongPTE:
doWrite = !pte.a;
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
entry.paddr = (uint64_t)pte & (mask(40) << 12);
entry.uncacheable = uncacheable;
entry.global = pte.g;
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
case PAEPDP:
nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (!pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
nextState = PAEPD;
break;
case PAEPD:
@@ -187,10 +183,10 @@
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
if (!pte.ps) {
// 4 KB page
entry.size = 4 * (1 << 10);
@@ -206,39 +202,35 @@
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
}
case PAEPTE:
doWrite = !pte.a;
pte.a = 1;
entry.writable = entry.writable && pte.w;
entry.user = entry.user && pte.u;
- if (badNX)
- panic("NX violation!\n");
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (badNX || !pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
entry.paddr = (uint64_t)pte & (mask(40) << 12);
entry.uncacheable = uncacheable;
entry.global = pte.g;
entry.patBit = bits(pte, 7);
entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
case PSEPD:
doWrite = !pte.a;
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (!pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
if (!pte.ps) {
// 4 KB page
entry.size = 4 * (1 << 10);
@@ -255,44 +247,40 @@
entry.patBit = bits(pte, 12);
entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
tlb->insert(entry.vaddr, entry);
- nextState = Ready;
- delete read->req;
- delete read;
- read = NULL;
- return;
+ stop();
+ return NoFault;
}
case PD:
doWrite = !pte.a;
pte.a = 1;
entry.writable = pte.w;
entry.user = pte.u;
- if (!pte.p)
- panic("Page at %#x not present!\n", entry.vaddr);
+ if (!pte.p) {
+ stop();
+ return pageFault(pte.p);
+ }
// 4 KB page
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev