tlb.cc (5894:8091ac99341a) | tlb.cc (5895:569e3b31a868) |
---|---|
1/* 2 * Copyright (c) 2007-2008 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 58 unchanged lines hidden (view full) --- 67#include "config/full_system.hh" 68#include "cpu/thread_context.hh" 69#include "cpu/base.hh" 70#include "mem/packet_access.hh" 71#include "mem/request.hh" 72 73#if FULL_SYSTEM 74#include "arch/x86/pagetable_walker.hh" | 1/* 2 * Copyright (c) 2007-2008 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 58 unchanged lines hidden (view full) --- 67#include "config/full_system.hh" 68#include "cpu/thread_context.hh" 69#include "cpu/base.hh" 70#include "mem/packet_access.hh" 71#include "mem/request.hh" 72 73#if FULL_SYSTEM 74#include "arch/x86/pagetable_walker.hh" |
75#else 76#include "mem/page_table.hh" 77#include "sim/process.hh" |
|
75#endif 76 77namespace X86ISA { 78 79TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) 80{ 81 tlb = new TlbEntry[size]; 82 std::memset(tlb, 0, sizeof(TlbEntry) * size); 83 84 for (int x = 0; x < size; x++) 85 freeList.push_back(&tlb[x]); 86 87#if FULL_SYSTEM 88 walker = p->walker; 89 walker->setTLB(this); 90#endif 91} 92 | 78#endif 79 80namespace X86ISA { 81 82TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) 83{ 84 tlb = new TlbEntry[size]; 85 std::memset(tlb, 0, sizeof(TlbEntry) * size); 86 87 for (int x = 0; x < size; x++) 88 freeList.push_back(&tlb[x]); 89 90#if FULL_SYSTEM 91 walker = p->walker; 92 walker->setTLB(this); 93#endif 94} 95 |
93void | 96TlbEntry * |
94TLB::insert(Addr vpn, TlbEntry &entry) 95{ 96 //TODO Deal with conflicting entries 97 98 TlbEntry *newEntry = NULL; 99 if (!freeList.empty()) { 100 newEntry = freeList.front(); 101 freeList.pop_front(); 102 } else { 103 newEntry = entryList.back(); 104 entryList.pop_back(); 105 } 106 *newEntry = entry; 107 newEntry->vaddr = vpn; 108 entryList.push_front(newEntry); | 97TLB::insert(Addr vpn, TlbEntry &entry) 98{ 99 //TODO Deal with conflicting entries 100 101 TlbEntry *newEntry = NULL; 102 if (!freeList.empty()) { 103 newEntry = freeList.front(); 104 freeList.pop_front(); 105 } else { 106 newEntry = entryList.back(); 107 entryList.pop_back(); 108 } 109 *newEntry = entry; 110 newEntry->vaddr = vpn; 111 entryList.push_front(newEntry); |
112 return newEntry; |
|
109} 110 111TLB::EntryList::iterator 112TLB::lookupIt(Addr va, bool update_lru) 113{ 114 //TODO make this smarter at some point 115 EntryList::iterator entry; 116 for (entry = entryList.begin(); entry != entryList.end(); entry++) { --- 16 unchanged lines hidden (view full) --- 133{ 134 EntryList::iterator entry = lookupIt(va, update_lru); 135 if (entry == entryList.end()) 136 return NULL; 137 else 138 return *entry; 139} 140 | 113} 114 115TLB::EntryList::iterator 116TLB::lookupIt(Addr va, bool update_lru) 117{ 118 //TODO make this smarter at some point 119 EntryList::iterator entry; 120 for (entry = entryList.begin(); entry != entryList.end(); entry++) { --- 16 unchanged lines hidden (view full) --- 137{ 138 EntryList::iterator entry = lookupIt(va, update_lru); 139 if (entry == entryList.end()) 140 return NULL; 141 else 142 return *entry; 143} 144 |
141#if FULL_SYSTEM | |
142void | 145void |
143TLB::walk(ThreadContext * _tc, Addr vaddr, bool write, bool execute) 144{ 145 walker->start(_tc, vaddr, write, execute); 146} 147#endif 148 149void | |
150TLB::invalidateAll() 151{ 152 DPRINTF(TLB, "Invalidating all entries.\n"); 153 while (!entryList.empty()) { 154 TlbEntry *entry = entryList.front(); 155 entryList.pop_front(); 156 freeList.push_back(entry); 157 } --- 25 unchanged lines hidden (view full) --- 183{ 184 EntryList::iterator entry = lookupIt(va, false); 185 if (entry != entryList.end()) { 186 freeList.push_back(*entry); 187 entryList.erase(entry); 188 } 189} 190 | 146TLB::invalidateAll() 147{ 148 DPRINTF(TLB, "Invalidating all entries.\n"); 149 while (!entryList.empty()) { 150 TlbEntry *entry = entryList.front(); 151 entryList.pop_front(); 152 freeList.push_back(entry); 153 } --- 25 unchanged lines hidden (view full) --- 179{ 180 EntryList::iterator entry = lookupIt(va, false); 181 if (entry != entryList.end()) { 182 freeList.push_back(*entry); 183 entryList.erase(entry); 184 } 185} 186 |
191template<class TlbFault> | |
192Fault | 187Fault |
193TLB::translateAtomic(RequestPtr req, ThreadContext *tc, 194 bool write, bool execute) | 188TLB::translate(RequestPtr req, ThreadContext *tc, 189 Translation *translation, bool write, bool execute, 190 bool &delayedResponse, bool timing) |
195{ | 191{ |
192 delayedResponse = false; |
|
196 Addr vaddr = req->getVaddr(); 197 DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr); 198 uint32_t flags = req->getFlags(); 199 bool storeCheck = flags & StoreCheck; 200 201 int seg = flags & mask(4); 202 203 //XXX Junk code to surpress the warning --- 408 unchanged lines hidden (view full) --- 612 } 613 } 614 // If paging is enabled, do the translation. 615 if (cr0.pg) { 616 DPRINTF(TLB, "Paging enabled.\n"); 617 // The vaddr already has the segment base applied. 618 TlbEntry *entry = lookup(vaddr); 619 if (!entry) { | 193 Addr vaddr = req->getVaddr(); 194 DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr); 195 uint32_t flags = req->getFlags(); 196 bool storeCheck = flags & StoreCheck; 197 198 int seg = flags & mask(4); 199 200 //XXX Junk code to surpress the warning --- 408 unchanged lines hidden (view full) --- 609 } 610 } 611 // If paging is enabled, do the translation. 612 if (cr0.pg) { 613 DPRINTF(TLB, "Paging enabled.\n"); 614 // The vaddr already has the segment base applied. 615 TlbEntry *entry = lookup(vaddr); 616 if (!entry) { |
620 return new TlbFault(vaddr, write, execute); 621 } else { 622 // Do paging protection checks. 623 DPRINTF(TLB, "Entry found with paddr %#x, doing protection checks.\n", entry->paddr); 624 Addr paddr = entry->paddr | (vaddr & (entry->size-1)); 625 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); 626 req->setPaddr(paddr); | 617#if FULL_SYSTEM 618 Fault fault = walker->start(tc, translation, req, 619 write, execute); 620 if (timing || fault != NoFault) { 621 // This gets ignored in atomic mode. 622 delayedResponse = true; 623 return fault; 624 } 625 entry = lookup(vaddr); 626 assert(entry); 627#else 628 DPRINTF(TLB, "Handling a TLB miss for " 629 "address %#x at pc %#x.\n", 630 vaddr, tc->readPC()); 631 632 Process *p = tc->getProcessPtr(); 633 TlbEntry newEntry; 634 bool success = p->pTable->lookup(vaddr, newEntry); 635 if(!success && !execute) { 636 p->checkAndAllocNextPage(vaddr); 637 success = p->pTable->lookup(vaddr, newEntry); 638 } 639 if(!success) { 640 panic("Tried to execute unmapped address %#x.\n", vaddr); 641 } else { 642 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 643 DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, 644 newEntry.pageStart()); 645 entry = insert(alignedVaddr, newEntry); 646 } 647 DPRINTF(TLB, "Miss was serviced.\n"); 648#endif |
627 } | 649 } |
650 // Do paging protection checks. 651 DPRINTF(TLB, "Entry found with paddr %#x, " 652 "doing protection checks.\n", entry->paddr); 653 Addr paddr = entry->paddr | (vaddr & (entry->size-1)); 654 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); 655 req->setPaddr(paddr); |
|
628 } else { 629 //Use the address which already has segmentation applied. 630 DPRINTF(TLB, "Paging disabled.\n"); 631 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr); 632 req->setPaddr(vaddr); 633 } 634 } else { 635 // Real mode --- 24 unchanged lines hidden (view full) --- 660 } 661#endif 662 return NoFault; 663}; 664 665Fault 666DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) 667{ | 656 } else { 657 //Use the address which already has segmentation applied. 658 DPRINTF(TLB, "Paging disabled.\n"); 659 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr); 660 req->setPaddr(vaddr); 661 } 662 } else { 663 // Real mode --- 24 unchanged lines hidden (view full) --- 688 } 689#endif 690 return NoFault; 691}; 692 693Fault 694DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) 695{ |
668 return TLB::translateAtomic<FakeDTLBFault>(req, tc, write, false); | 696 bool delayedResponse; 697 return TLB::translate(req, tc, NULL, write, 698 false, delayedResponse, false); |
669} 670 671void 672DTB::translateTiming(RequestPtr req, ThreadContext *tc, 673 Translation *translation, bool write) 674{ | 699} 700 701void 702DTB::translateTiming(RequestPtr req, ThreadContext *tc, 703 Translation *translation, bool write) 704{ |
705 bool delayedResponse; |
|
675 assert(translation); | 706 assert(translation); |
676 translation->finish(translateAtomic(req, tc, write), req, tc, write); | 707 Fault fault = TLB::translate(req, tc, translation, 708 write, false, delayedResponse, true); 709 if (!delayedResponse) 710 translation->finish(fault, req, tc, write); |
677} 678 679Fault 680ITB::translateAtomic(RequestPtr req, ThreadContext *tc) 681{ | 711} 712 713Fault 714ITB::translateAtomic(RequestPtr req, ThreadContext *tc) 715{ |
682 return TLB::translateAtomic<FakeITLBFault>(req, tc, false, true); | 716 bool delayedResponse; 717 return TLB::translate(req, tc, NULL, false, 718 true, delayedResponse, false); |
683} 684 685void 686ITB::translateTiming(RequestPtr req, ThreadContext *tc, 687 Translation *translation) 688{ | 719} 720 721void 722ITB::translateTiming(RequestPtr req, ThreadContext *tc, 723 Translation *translation) 724{ |
725 bool delayedResponse; |
|
689 assert(translation); | 726 assert(translation); |
690 translation->finish(translateAtomic(req, tc), req, tc, false); | 727 Fault fault = TLB::translate(req, tc, translation, 728 false, true, delayedResponse, true); 729 if (!delayedResponse) 730 translation->finish(fault, req, tc, false); |
691} 692 693#if FULL_SYSTEM 694 695Tick 696DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 697{ 698 return tc->getCpuPtr()->ticks(1); --- 45 unchanged lines hidden --- | 731} 732 733#if FULL_SYSTEM 734 735Tick 736DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 737{ 738 return tc->getCpuPtr()->ticks(1); --- 45 unchanged lines hidden --- |