diff options
author | Nathan Binkert <nate@binkert.org> | 2009-04-08 22:21:27 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2009-04-08 22:21:27 -0700 |
commit | e0de2c34433be76eac7798e58e1ae02f5bffb732 (patch) | |
tree | 120f809cf3feb35e6b42e83a9896b8ae673c5445 /src/arch/x86 | |
parent | 7b5a96f06b530db35637aca6f9d0f7a2ddfa6e60 (diff) | |
download | gem5-e0de2c34433be76eac7798e58e1ae02f5bffb732.tar.xz |
tlb: More fixing of unified TLB
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/faults.hh | 9 | ||||
-rw-r--r-- | src/arch/x86/pagetable_walker.cc | 18 | ||||
-rw-r--r-- | src/arch/x86/pagetable_walker.hh | 5 | ||||
-rw-r--r-- | src/arch/x86/tlb.cc | 33 | ||||
-rw-r--r-- | src/arch/x86/tlb.hh | 8 |
5 files changed, 34 insertions, 39 deletions
diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index fe5132994..dbfb8d4d0 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -61,6 +61,7 @@ #include "base/bitunion.hh" #include "base/misc.hh" #include "sim/faults.hh" +#include "sim/tlb.hh" #include <string> @@ -331,16 +332,16 @@ namespace X86ISA X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr) {} - PageFault(Addr _addr, bool present, bool write, - bool user, bool reserved, bool fetch) : + PageFault(Addr _addr, bool present, BaseTLB::Mode mode, + bool user, bool reserved) : X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr) { PageFaultErrorCode code = 0; code.present = present; - code.write = write; + code.write = (mode == BaseTLB::Write); code.user = user; code.reserved = reserved; - code.fetch = fetch; + code.fetch = (mode == BaseTLB::Execute); errorCode = code; } diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index 2471c0663..69ded7cbc 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -98,7 +98,7 @@ Walker::doNext(PacketPtr &write) bool uncacheable = pte.pcd; Addr nextRead = 0; bool doWrite = false; - bool badNX = pte.nx && execute && enableNX; + bool badNX = pte.nx && mode == BaseTLB::Write && enableNX; switch(state) { case LongPML4: DPRINTF(PageTableWalker, @@ -329,14 +329,13 @@ Walker::doNext(PacketPtr &write) Fault Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, - RequestPtr _req, bool _write, bool _execute) + RequestPtr _req, BaseTLB::Mode _mode) { assert(state == Ready); tc = _tc; req = _req; Addr vaddr = req->getVaddr(); - execute = _execute; - write = _write; + mode = _mode; translation = _translation; VAddr addr = vaddr; @@ -451,14 +450,14 @@ Walker::recvTiming(PacketPtr pkt) * well. */ bool delayedResponse; - Fault fault = tlb->translate(req, tc, NULL, write, execute, + Fault fault = tlb->translate(req, tc, NULL, mode, delayedResponse, true); assert(!delayedResponse); // Let the CPU continue. - translation->finish(fault, req, tc, write); + translation->finish(fault, req, tc, mode); } else { // There was a fault during the walk. Let the CPU know. - translation->finish(timingFault, req, tc, write); + translation->finish(timingFault, req, tc, mode); } } } else if (pkt->wasNacked()) { @@ -563,8 +562,9 @@ Walker::pageFault(bool present) { DPRINTF(PageTableWalker, "Raising page fault.\n"); HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); - return new PageFault(entry.vaddr, present, write, - m5reg.cpl == 3, false, execute && enableNX); + if (mode == BaseTLB::Execute && !enableNX) + mode = BaseTLB::Read; + return new PageFault(entry.vaddr, present, mode, m5reg.cpl == 3, false); } } diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index f73774a45..0f9d24923 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -97,7 +97,7 @@ namespace X86ISA // Kick off the state machine. Fault start(ThreadContext * _tc, BaseTLB::Translation *translation, - RequestPtr req, bool write, bool execute); + RequestPtr req, BaseTLB::Mode mode); // Clean up after the state machine. void stop() @@ -183,7 +183,8 @@ namespace X86ISA State nextState; int size; bool enableNX; - bool write, execute, user; + BaseTLB::Mode mode; + bool user; TlbEntry entry; Fault pageFault(bool present); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 2feed6f3e..62d694225 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -186,9 +186,8 @@ TLB::demapPage(Addr va, uint64_t asn) } Fault -TLB::translate(RequestPtr req, ThreadContext *tc, - Translation *translation, bool write, bool execute, - bool &delayedResponse, bool timing) +TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, + Mode mode, bool &delayedResponse, bool timing) { delayedResponse = false; Addr vaddr = req->getVaddr(); @@ -577,9 +576,9 @@ TLB::translate(RequestPtr req, ThreadContext *tc, bool expandDown = false; SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) { - if (!attr.writable && write) + if (!attr.writable && mode == Write) return new GeneralProtection(0); - if (!attr.readable && !write && !execute) + if (!attr.readable && mode == Read) return new GeneralProtection(0); expandDown = attr.expandDown; @@ -612,8 +611,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, TlbEntry *entry = lookup(vaddr); if (!entry) { #if FULL_SYSTEM - Fault fault = walker->start(tc, translation, req, - write, execute); + Fault fault = walker->start(tc, translation, req, mode); if (timing || fault != NoFault) { // This gets ignored in atomic mode. delayedResponse = true; @@ -629,7 +627,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Process *p = tc->getProcessPtr(); TlbEntry newEntry; bool success = p->pTable->lookup(vaddr, newEntry); - if(!success && !execute) { + if(!success && mode != Execute) { p->checkAndAllocNextPage(vaddr); success = p->pTable->lookup(vaddr, newEntry); } @@ -648,12 +646,11 @@ TLB::translate(RequestPtr req, ThreadContext *tc, bool inUser = (csAttr.dpl == 3 && !(flags & (CPL0FlagBit << FlagShift))); if ((inUser && !entry->user) || - (write && !entry->writable)) { + (mode == Write && !entry->writable)) { // The page must have been present to get into the TLB in // the first place. We'll assume the reserved bits are // fine even though we're not checking them. - return new PageFault(vaddr, true, write, - inUser, false, execute); + return new PageFault(vaddr, true, mode, inUser, false); } @@ -700,24 +697,22 @@ TLB::translate(RequestPtr req, ThreadContext *tc, }; Fault -TLB::translateAtomic(RequestPtr req, ThreadContext *tc, - bool write, bool execute) +TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) { bool delayedResponse; - return TLB::translate(req, tc, NULL, write, - execute, delayedResponse, false); + return TLB::translate(req, tc, NULL, mode, delayedResponse, false); } void TLB::translateTiming(RequestPtr req, ThreadContext *tc, - Translation *translation, bool write, bool execute) + Translation *translation, Mode mode) { bool delayedResponse; assert(translation); - Fault fault = TLB::translate(req, tc, translation, - write, execute, delayedResponse, true); + Fault fault = + TLB::translate(req, tc, translation, mode, delayedResponse, true); if (!delayedResponse) - translation->finish(fault, req, tc, write, execute); + translation->finish(fault, req, tc, mode); } #if FULL_SYSTEM diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index f67a93d8d..a9d3a4fa6 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -127,16 +127,14 @@ namespace X86ISA EntryList entryList; Fault translate(RequestPtr req, ThreadContext *tc, - Translation *translation, bool write, bool execute, + Translation *translation, Mode mode, bool &delayedResponse, bool timing); public: - Fault translateAtomic(RequestPtr req, ThreadContext *tc, - bool write = false, bool execute = false); + Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode); void translateTiming(RequestPtr req, ThreadContext *tc, - Translation *translation, - bool write = false, bool execute = false); + Translation *translation, Mode mode); #if FULL_SYSTEM Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); |