1/* 2 * Copyright 2007 MIPS Technologies, Inc. All Rights Reserved 3 * 4 * This software is part of the M5 simulator. 5 * 6 * THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING 7 * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING 8 * TO THESE TERMS AND CONDITIONS. 9 * 10 * Permission is granted to use, copy, create derivative works and 11 * distribute this software and such derivative works for any purpose, 12 * so long as (1) the copyright notice above, this grant of permission, 13 * and the disclaimer below appear in all copies and derivative works 14 * made, (2) the copyright notice above is augmented as appropriate to 15 * reflect the addition of any new copyrightable work in a derivative 16 * work (e.g., Copyright N) <Publication Year> Copyright Owner), and (3) 17 * the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any 18 * advertising or publicity pertaining to the use or distribution of 19 * this software without specific, written prior authorization. 20 * 21 * THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B MIPS MAKES NO WARRANTIES AND 22 * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR 23 * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 25 * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. 26 * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, 27 * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF 28 * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, 29 * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY 30 * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR 31 * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE 32 * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. 33 * 34 * Authors: Jaidev P. Patwardhan 35 * 36 */ 37 38#include <string> 39#include <vector> 40 41#include "arch/mips/pra_constants.hh" 42#include "arch/mips/pagetable.hh" 43#include "arch/mips/tlb.hh" 44#include "arch/mips/faults.hh" 45#include "arch/mips/utility.hh" 46#include "base/inifile.hh" 47#include "base/str.hh" 48#include "base/trace.hh" 49#include "cpu/thread_context.hh"
| 1/* 2 * Copyright 2007 MIPS Technologies, Inc. All Rights Reserved 3 * 4 * This software is part of the M5 simulator. 5 * 6 * THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING 7 * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING 8 * TO THESE TERMS AND CONDITIONS. 9 * 10 * Permission is granted to use, copy, create derivative works and 11 * distribute this software and such derivative works for any purpose, 12 * so long as (1) the copyright notice above, this grant of permission, 13 * and the disclaimer below appear in all copies and derivative works 14 * made, (2) the copyright notice above is augmented as appropriate to 15 * reflect the addition of any new copyrightable work in a derivative 16 * work (e.g., Copyright N) <Publication Year> Copyright Owner), and (3) 17 * the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any 18 * advertising or publicity pertaining to the use or distribution of 19 * this software without specific, written prior authorization. 20 * 21 * THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B MIPS MAKES NO WARRANTIES AND 22 * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR 23 * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 25 * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. 26 * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, 27 * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF 28 * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, 29 * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY 30 * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR 31 * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE 32 * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. 33 * 34 * Authors: Jaidev P. Patwardhan 35 * 36 */ 37 38#include <string> 39#include <vector> 40 41#include "arch/mips/pra_constants.hh" 42#include "arch/mips/pagetable.hh" 43#include "arch/mips/tlb.hh" 44#include "arch/mips/faults.hh" 45#include "arch/mips/utility.hh" 46#include "base/inifile.hh" 47#include "base/str.hh" 48#include "base/trace.hh" 49#include "cpu/thread_context.hh"
|
| 50#include "sim/process.hh" 51#include "mem/page_table.hh"
|
50#include "params/MipsDTB.hh" 51#include "params/MipsITB.hh" 52#include "params/MipsTLB.hh" 53#include "params/MipsUTB.hh" 54 55 56using namespace std; 57using namespace MipsISA; 58 59/////////////////////////////////////////////////////////////////////// 60// 61// MIPS TLB 62// 63 64#define MODE2MASK(X) (1 << (X)) 65 66TLB::TLB(const Params *p) 67 : SimObject(p), size(p->size), nlu(0) 68{ 69 table = new MipsISA::PTE[size]; 70 memset(table, 0, sizeof(MipsISA::PTE[size])); 71 smallPages=0; 72} 73 74TLB::~TLB() 75{ 76 if (table) 77 delete [] table; 78} 79 80// look up an entry in the TLB 81MipsISA::PTE * 82TLB::lookup(Addr vpn, uint8_t asn) const 83{ 84 // assume not found... 85 MipsISA::PTE *retval = NULL; 86 PageTable::const_iterator i = lookupTable.find(vpn); 87 if (i != lookupTable.end()) { 88 while (i->first == vpn) { 89 int index = i->second; 90 MipsISA::PTE *pte = &table[index]; 91 92 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 93 Addr Mask = pte->Mask; 94 Addr InvMask = ~Mask; 95 Addr VPN = pte->VPN; 96 // warn("Valid: %d - %d\n",pte->V0,pte->V1); 97 if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) 98 { // We have a VPN + ASID Match 99 retval = pte; 100 break; 101 } 102 ++i; 103 } 104 } 105 106 DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 107 retval ? "hit" : "miss", retval ? retval->PFN1 : 0); 108 return retval; 109} 110 111MipsISA::PTE* TLB::getEntry(unsigned Index) const 112{ 113 // Make sure that Index is valid 114 assert(Index<size); 115 return &table[Index]; 116} 117 118int TLB::probeEntry(Addr vpn,uint8_t asn) const 119{ 120 // assume not found... 121 MipsISA::PTE *retval = NULL; 122 int Ind=-1; 123 PageTable::const_iterator i = lookupTable.find(vpn); 124 if (i != lookupTable.end()) { 125 while (i->first == vpn) { 126 int index = i->second; 127 MipsISA::PTE *pte = &table[index]; 128 129 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 130 Addr Mask = pte->Mask; 131 Addr InvMask = ~Mask; 132 Addr VPN = pte->VPN; 133 if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) 134 { // We have a VPN + ASID Match 135 retval = pte; 136 Ind = index; 137 break; 138 } 139 140 ++i; 141 } 142 } 143 DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 144 return Ind; 145} 146Fault inline 147TLB::checkCacheability(RequestPtr &req) 148{ 149 Addr VAddrUncacheable = 0xA0000000; 150 // In MIPS, cacheability is controlled by certain bits of the virtual address 151 // or by the TLB entry 152 if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { 153 // mark request as uncacheable 154 req->setFlags(req->getFlags() | UNCACHEABLE); 155 } 156 return NoFault; 157} 158void TLB::insertAt(MipsISA::PTE &pte, unsigned Index, int _smallPages) 159{ 160 smallPages=_smallPages; 161 if(Index > size){ 162 warn("Attempted to write at index (%d) beyond TLB size (%d)",Index,size); 163 } else { 164 // Update TLB 165 DPRINTF(TLB,"TLB[%d]: %x %x %x %x\n",Index,pte.Mask<<11,((pte.VPN << 11) | pte.asid),((pte.PFN0 <<6) | (pte.C0 << 3) | (pte.D0 << 2) | (pte.V0 <<1) | pte.G), 166 ((pte.PFN1 <<6) | (pte.C1 << 3) | (pte.D1 << 2) | (pte.V1 <<1) | pte.G)); 167 if(table[Index].V0 == true || table[Index].V1 == true){ // Previous entry is valid 168 PageTable::iterator i = lookupTable.find(table[Index].VPN); 169 lookupTable.erase(i); 170 } 171 table[Index]=pte; 172 // Update fast lookup table 173 lookupTable.insert(make_pair(table[Index].VPN, Index)); 174 // int TestIndex=probeEntry(pte.VPN,pte.asid); 175 // warn("Inserted at: %d, Found at: %d (%x)\n",Index,TestIndex,pte.Mask); 176 } 177 178} 179 180// insert a new TLB entry 181void 182TLB::insert(Addr addr, MipsISA::PTE &pte) 183{ 184 fatal("TLB Insert not yet implemented\n"); 185 186 187 /* MipsISA::VAddr vaddr = addr; 188 if (table[nlu].valid) { 189 Addr oldvpn = table[nlu].tag; 190 PageTable::iterator i = lookupTable.find(oldvpn); 191 192 if (i == lookupTable.end()) 193 panic("TLB entry not found in lookupTable"); 194 195 int index; 196 while ((index = i->second) != nlu) { 197 if (table[index].tag != oldvpn) 198 panic("TLB entry not found in lookupTable"); 199 200 ++i; 201 } 202 203 DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 204 205 lookupTable.erase(i); 206 } 207 208 DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); 209 210 table[nlu] = pte; 211 table[nlu].tag = vaddr.vpn(); 212 table[nlu].valid = true; 213 214 lookupTable.insert(make_pair(vaddr.vpn(), nlu)); 215 nextnlu(); 216 */ 217} 218 219void 220TLB::flushAll() 221{ 222 DPRINTF(TLB, "flushAll\n"); 223 memset(table, 0, sizeof(MipsISA::PTE[size])); 224 lookupTable.clear(); 225 nlu = 0; 226} 227 228void 229TLB::serialize(ostream &os) 230{ 231 SERIALIZE_SCALAR(size); 232 SERIALIZE_SCALAR(nlu); 233 234 for (int i = 0; i < size; i++) { 235 nameOut(os, csprintf("%s.PTE%d", name(), i)); 236 table[i].serialize(os); 237 } 238} 239 240void 241TLB::unserialize(Checkpoint *cp, const string §ion) 242{ 243 UNSERIALIZE_SCALAR(size); 244 UNSERIALIZE_SCALAR(nlu); 245 246 for (int i = 0; i < size; i++) { 247 table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 248 if (table[i].V0 || table[i].V1) { 249 lookupTable.insert(make_pair(table[i].VPN, i)); 250 } 251 } 252} 253 254void 255TLB::regStats() 256{ 257 read_hits 258 .name(name() + ".read_hits") 259 .desc("DTB read hits") 260 ; 261 262 read_misses 263 .name(name() + ".read_misses") 264 .desc("DTB read misses") 265 ; 266 267 268 read_accesses 269 .name(name() + ".read_accesses") 270 .desc("DTB read accesses") 271 ; 272 273 write_hits 274 .name(name() + ".write_hits") 275 .desc("DTB write hits") 276 ; 277 278 write_misses 279 .name(name() + ".write_misses") 280 .desc("DTB write misses") 281 ; 282 283 284 write_accesses 285 .name(name() + ".write_accesses") 286 .desc("DTB write accesses") 287 ; 288 289 hits 290 .name(name() + ".hits") 291 .desc("DTB hits") 292 ; 293 294 misses 295 .name(name() + ".misses") 296 .desc("DTB misses") 297 ; 298 299 invalids 300 .name(name() + ".invalids") 301 .desc("DTB access violations") 302 ; 303 304 accesses 305 .name(name() + ".accesses") 306 .desc("DTB accesses") 307 ; 308 309 hits = read_hits + write_hits; 310 misses = read_misses + write_misses; 311 accesses = read_accesses + write_accesses; 312} 313 314Fault 315ITB::translate(RequestPtr &req, ThreadContext *tc) 316{
| 52#include "params/MipsDTB.hh" 53#include "params/MipsITB.hh" 54#include "params/MipsTLB.hh" 55#include "params/MipsUTB.hh" 56 57 58using namespace std; 59using namespace MipsISA; 60 61/////////////////////////////////////////////////////////////////////// 62// 63// MIPS TLB 64// 65 66#define MODE2MASK(X) (1 << (X)) 67 68TLB::TLB(const Params *p) 69 : SimObject(p), size(p->size), nlu(0) 70{ 71 table = new MipsISA::PTE[size]; 72 memset(table, 0, sizeof(MipsISA::PTE[size])); 73 smallPages=0; 74} 75 76TLB::~TLB() 77{ 78 if (table) 79 delete [] table; 80} 81 82// look up an entry in the TLB 83MipsISA::PTE * 84TLB::lookup(Addr vpn, uint8_t asn) const 85{ 86 // assume not found... 87 MipsISA::PTE *retval = NULL; 88 PageTable::const_iterator i = lookupTable.find(vpn); 89 if (i != lookupTable.end()) { 90 while (i->first == vpn) { 91 int index = i->second; 92 MipsISA::PTE *pte = &table[index]; 93 94 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 95 Addr Mask = pte->Mask; 96 Addr InvMask = ~Mask; 97 Addr VPN = pte->VPN; 98 // warn("Valid: %d - %d\n",pte->V0,pte->V1); 99 if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) 100 { // We have a VPN + ASID Match 101 retval = pte; 102 break; 103 } 104 ++i; 105 } 106 } 107 108 DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 109 retval ? "hit" : "miss", retval ? retval->PFN1 : 0); 110 return retval; 111} 112 113MipsISA::PTE* TLB::getEntry(unsigned Index) const 114{ 115 // Make sure that Index is valid 116 assert(Index<size); 117 return &table[Index]; 118} 119 120int TLB::probeEntry(Addr vpn,uint8_t asn) const 121{ 122 // assume not found... 123 MipsISA::PTE *retval = NULL; 124 int Ind=-1; 125 PageTable::const_iterator i = lookupTable.find(vpn); 126 if (i != lookupTable.end()) { 127 while (i->first == vpn) { 128 int index = i->second; 129 MipsISA::PTE *pte = &table[index]; 130 131 /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 132 Addr Mask = pte->Mask; 133 Addr InvMask = ~Mask; 134 Addr VPN = pte->VPN; 135 if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) 136 { // We have a VPN + ASID Match 137 retval = pte; 138 Ind = index; 139 break; 140 } 141 142 ++i; 143 } 144 } 145 DPRINTF(MipsPRA,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 146 return Ind; 147} 148Fault inline 149TLB::checkCacheability(RequestPtr &req) 150{ 151 Addr VAddrUncacheable = 0xA0000000; 152 // In MIPS, cacheability is controlled by certain bits of the virtual address 153 // or by the TLB entry 154 if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { 155 // mark request as uncacheable 156 req->setFlags(req->getFlags() | UNCACHEABLE); 157 } 158 return NoFault; 159} 160void TLB::insertAt(MipsISA::PTE &pte, unsigned Index, int _smallPages) 161{ 162 smallPages=_smallPages; 163 if(Index > size){ 164 warn("Attempted to write at index (%d) beyond TLB size (%d)",Index,size); 165 } else { 166 // Update TLB 167 DPRINTF(TLB,"TLB[%d]: %x %x %x %x\n",Index,pte.Mask<<11,((pte.VPN << 11) | pte.asid),((pte.PFN0 <<6) | (pte.C0 << 3) | (pte.D0 << 2) | (pte.V0 <<1) | pte.G), 168 ((pte.PFN1 <<6) | (pte.C1 << 3) | (pte.D1 << 2) | (pte.V1 <<1) | pte.G)); 169 if(table[Index].V0 == true || table[Index].V1 == true){ // Previous entry is valid 170 PageTable::iterator i = lookupTable.find(table[Index].VPN); 171 lookupTable.erase(i); 172 } 173 table[Index]=pte; 174 // Update fast lookup table 175 lookupTable.insert(make_pair(table[Index].VPN, Index)); 176 // int TestIndex=probeEntry(pte.VPN,pte.asid); 177 // warn("Inserted at: %d, Found at: %d (%x)\n",Index,TestIndex,pte.Mask); 178 } 179 180} 181 182// insert a new TLB entry 183void 184TLB::insert(Addr addr, MipsISA::PTE &pte) 185{ 186 fatal("TLB Insert not yet implemented\n"); 187 188 189 /* MipsISA::VAddr vaddr = addr; 190 if (table[nlu].valid) { 191 Addr oldvpn = table[nlu].tag; 192 PageTable::iterator i = lookupTable.find(oldvpn); 193 194 if (i == lookupTable.end()) 195 panic("TLB entry not found in lookupTable"); 196 197 int index; 198 while ((index = i->second) != nlu) { 199 if (table[index].tag != oldvpn) 200 panic("TLB entry not found in lookupTable"); 201 202 ++i; 203 } 204 205 DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); 206 207 lookupTable.erase(i); 208 } 209 210 DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); 211 212 table[nlu] = pte; 213 table[nlu].tag = vaddr.vpn(); 214 table[nlu].valid = true; 215 216 lookupTable.insert(make_pair(vaddr.vpn(), nlu)); 217 nextnlu(); 218 */ 219} 220 221void 222TLB::flushAll() 223{ 224 DPRINTF(TLB, "flushAll\n"); 225 memset(table, 0, sizeof(MipsISA::PTE[size])); 226 lookupTable.clear(); 227 nlu = 0; 228} 229 230void 231TLB::serialize(ostream &os) 232{ 233 SERIALIZE_SCALAR(size); 234 SERIALIZE_SCALAR(nlu); 235 236 for (int i = 0; i < size; i++) { 237 nameOut(os, csprintf("%s.PTE%d", name(), i)); 238 table[i].serialize(os); 239 } 240} 241 242void 243TLB::unserialize(Checkpoint *cp, const string §ion) 244{ 245 UNSERIALIZE_SCALAR(size); 246 UNSERIALIZE_SCALAR(nlu); 247 248 for (int i = 0; i < size; i++) { 249 table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); 250 if (table[i].V0 || table[i].V1) { 251 lookupTable.insert(make_pair(table[i].VPN, i)); 252 } 253 } 254} 255 256void 257TLB::regStats() 258{ 259 read_hits 260 .name(name() + ".read_hits") 261 .desc("DTB read hits") 262 ; 263 264 read_misses 265 .name(name() + ".read_misses") 266 .desc("DTB read misses") 267 ; 268 269 270 read_accesses 271 .name(name() + ".read_accesses") 272 .desc("DTB read accesses") 273 ; 274 275 write_hits 276 .name(name() + ".write_hits") 277 .desc("DTB write hits") 278 ; 279 280 write_misses 281 .name(name() + ".write_misses") 282 .desc("DTB write misses") 283 ; 284 285 286 write_accesses 287 .name(name() + ".write_accesses") 288 .desc("DTB write accesses") 289 ; 290 291 hits 292 .name(name() + ".hits") 293 .desc("DTB hits") 294 ; 295 296 misses 297 .name(name() + ".misses") 298 .desc("DTB misses") 299 ; 300 301 invalids 302 .name(name() + ".invalids") 303 .desc("DTB access violations") 304 ; 305 306 accesses 307 .name(name() + ".accesses") 308 .desc("DTB accesses") 309 ; 310 311 hits = read_hits + write_hits; 312 misses = read_misses + write_misses; 313 accesses = read_accesses + write_accesses; 314} 315 316Fault 317ITB::translate(RequestPtr &req, ThreadContext *tc) 318{
|
| 319#if !FULL_SYSTEM 320 Process * p = tc->getProcessPtr(); 321 322 Fault fault = p->pTable->translate(req); 323 if(fault != NoFault) 324 return fault; 325 326 return NoFault; 327#else
|
317 if(MipsISA::IsKSeg0(req->getVaddr())) 318 { 319 // Address will not be translated through TLB, set response, and go! 320 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 321 if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) 322 { 323 AddressErrorFault *Flt = new AddressErrorFault(); 324 /* BadVAddr must be set */ 325 Flt->BadVAddr = req->getVaddr(); 326 return Flt; 327 } 328 } 329 else if(MipsISA::IsKSeg1(req->getVaddr())) 330 { 331 // Address will not be translated through TLB, set response, and go! 332 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 333 } 334 else 335 { 336 /* This is an optimization - smallPages is updated every time a TLB operation is performed 337 That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we 338 do a TLB lookup */ 339 Addr VPN; 340 if(smallPages==1){ 341 VPN=((req->getVaddr() >> 11)); 342 } else { 343 VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); 344 } 345 uint8_t Asid = req->getAsid(); 346 if(req->isMisaligned()){ // Unaligned address! 347 AddressErrorFault *Flt = new AddressErrorFault(); 348 /* BadVAddr must be set */ 349 Flt->BadVAddr = req->getVaddr(); 350 return Flt; 351 } 352 MipsISA::PTE *pte = lookup(VPN,Asid); 353 if(pte != NULL) 354 {// Ok, found something 355 /* Check for valid bits */ 356 int EvenOdd; 357 bool Valid; 358 if((((req->getVaddr()) >> pte->AddrShiftAmount) & 1) ==0){ 359 // Check even bits 360 Valid = pte->V0; 361 EvenOdd = 0; 362 } else { 363 // Check odd bits 364 Valid = pte->V1; 365 EvenOdd = 1; 366 } 367 368 if(Valid == false) 369 {//Invalid entry 370 ItbInvalidFault *Flt = new ItbInvalidFault(); 371 /* EntryHi VPN, ASID fields must be set */ 372 Flt->EntryHi_Asid = Asid; 373 Flt->EntryHi_VPN2 = (VPN>>2); 374 Flt->EntryHi_VPN2X = (VPN & 0x3); 375 376 /* BadVAddr must be set */ 377 Flt->BadVAddr = req->getVaddr(); 378 379 /* Context must be set */ 380 Flt->Context_BadVPN2 = (VPN >> 2); 381 return Flt; 382 } 383 else 384 {// Ok, this is really a match, set paddr 385 // hits++; 386 Addr PAddr; 387 if(EvenOdd == 0){ 388 PAddr = pte->PFN0; 389 }else{ 390 PAddr = pte->PFN1; 391 } 392 PAddr >>= (pte->AddrShiftAmount-12); 393 PAddr <<= pte->AddrShiftAmount; 394 PAddr |= ((req->getVaddr()) & pte->OffsetMask); 395 req->setPaddr(PAddr); 396 397 398 } 399 } 400 else 401 { // Didn't find any match, return a TLB Refill Exception 402 // misses++; 403 ItbRefillFault *Flt=new ItbRefillFault(); 404 /* EntryHi VPN, ASID fields must be set */ 405 Flt->EntryHi_Asid = Asid; 406 Flt->EntryHi_VPN2 = (VPN>>2); 407 Flt->EntryHi_VPN2X = (VPN & 0x3); 408 409 410 /* BadVAddr must be set */ 411 Flt->BadVAddr = req->getVaddr(); 412 413 /* Context must be set */ 414 Flt->Context_BadVPN2 = (VPN >> 2); 415 return Flt; 416 } 417 } 418 return checkCacheability(req);
| 328 if(MipsISA::IsKSeg0(req->getVaddr())) 329 { 330 // Address will not be translated through TLB, set response, and go! 331 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 332 if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) 333 { 334 AddressErrorFault *Flt = new AddressErrorFault(); 335 /* BadVAddr must be set */ 336 Flt->BadVAddr = req->getVaddr(); 337 return Flt; 338 } 339 } 340 else if(MipsISA::IsKSeg1(req->getVaddr())) 341 { 342 // Address will not be translated through TLB, set response, and go! 343 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 344 } 345 else 346 { 347 /* This is an optimization - smallPages is updated every time a TLB operation is performed 348 That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we 349 do a TLB lookup */ 350 Addr VPN; 351 if(smallPages==1){ 352 VPN=((req->getVaddr() >> 11)); 353 } else { 354 VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); 355 } 356 uint8_t Asid = req->getAsid(); 357 if(req->isMisaligned()){ // Unaligned address! 358 AddressErrorFault *Flt = new AddressErrorFault(); 359 /* BadVAddr must be set */ 360 Flt->BadVAddr = req->getVaddr(); 361 return Flt; 362 } 363 MipsISA::PTE *pte = lookup(VPN,Asid); 364 if(pte != NULL) 365 {// Ok, found something 366 /* Check for valid bits */ 367 int EvenOdd; 368 bool Valid; 369 if((((req->getVaddr()) >> pte->AddrShiftAmount) & 1) ==0){ 370 // Check even bits 371 Valid = pte->V0; 372 EvenOdd = 0; 373 } else { 374 // Check odd bits 375 Valid = pte->V1; 376 EvenOdd = 1; 377 } 378 379 if(Valid == false) 380 {//Invalid entry 381 ItbInvalidFault *Flt = new ItbInvalidFault(); 382 /* EntryHi VPN, ASID fields must be set */ 383 Flt->EntryHi_Asid = Asid; 384 Flt->EntryHi_VPN2 = (VPN>>2); 385 Flt->EntryHi_VPN2X = (VPN & 0x3); 386 387 /* BadVAddr must be set */ 388 Flt->BadVAddr = req->getVaddr(); 389 390 /* Context must be set */ 391 Flt->Context_BadVPN2 = (VPN >> 2); 392 return Flt; 393 } 394 else 395 {// Ok, this is really a match, set paddr 396 // hits++; 397 Addr PAddr; 398 if(EvenOdd == 0){ 399 PAddr = pte->PFN0; 400 }else{ 401 PAddr = pte->PFN1; 402 } 403 PAddr >>= (pte->AddrShiftAmount-12); 404 PAddr <<= pte->AddrShiftAmount; 405 PAddr |= ((req->getVaddr()) & pte->OffsetMask); 406 req->setPaddr(PAddr); 407 408 409 } 410 } 411 else 412 { // Didn't find any match, return a TLB Refill Exception 413 // misses++; 414 ItbRefillFault *Flt=new ItbRefillFault(); 415 /* EntryHi VPN, ASID fields must be set */ 416 Flt->EntryHi_Asid = Asid; 417 Flt->EntryHi_VPN2 = (VPN>>2); 418 Flt->EntryHi_VPN2X = (VPN & 0x3); 419 420 421 /* BadVAddr must be set */ 422 Flt->BadVAddr = req->getVaddr(); 423 424 /* Context must be set */ 425 Flt->Context_BadVPN2 = (VPN >> 2); 426 return Flt; 427 } 428 } 429 return checkCacheability(req);
|
| 430#endif
|
419} 420 421Fault 422DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 423{
| 431} 432 433Fault 434DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) 435{
|
| 436#if !FULL_SYSTEM 437 Process * p = tc->getProcessPtr(); 438 439 Fault fault = p->pTable->translate(req); 440 if(fault != NoFault) 441 return fault; 442 443 return NoFault; 444#else
|
424 if(MipsISA::IsKSeg0(req->getVaddr())) 425 { 426 // Address will not be translated through TLB, set response, and go! 427 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 428 if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) 429 { 430 StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 431 /* BadVAddr must be set */ 432 Flt->BadVAddr = req->getVaddr(); 433 434 return Flt; 435 } 436 } 437 else if(MipsISA::IsKSeg1(req->getVaddr())) 438 { 439 // Address will not be translated through TLB, set response, and go! 440 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 441 } 442 else 443 { 444 /* This is an optimization - smallPages is updated every time a TLB operation is performed 445 That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we 446 do a TLB lookup */ 447 Addr VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); 448 if(smallPages==1){ 449 VPN=((req->getVaddr() >> 11)); 450 } 451 uint8_t Asid = req->getAsid(); 452 MipsISA::PTE *pte = lookup(VPN,Asid); 453 if(req->isMisaligned()){ // Unaligned address! 454 StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 455 /* BadVAddr must be set */ 456 Flt->BadVAddr = req->getVaddr(); 457 return Flt; 458 } 459 if(pte != NULL) 460 {// Ok, found something 461 /* Check for valid bits */ 462 int EvenOdd; 463 bool Valid; 464 bool Dirty; 465 if(((((req->getVaddr()) >> pte->AddrShiftAmount) & 1)) ==0){ 466 // Check even bits 467 Valid = pte->V0; 468 Dirty = pte->D0; 469 EvenOdd = 0; 470 471 } else { 472 // Check odd bits 473 Valid = pte->V1; 474 Dirty = pte->D1; 475 EvenOdd = 1; 476 } 477 478 if(Valid == false) 479 {//Invalid entry 480 // invalids++; 481 DtbInvalidFault *Flt = new DtbInvalidFault(); 482 /* EntryHi VPN, ASID fields must be set */ 483 Flt->EntryHi_Asid = Asid; 484 Flt->EntryHi_VPN2 = (VPN>>2); 485 Flt->EntryHi_VPN2X = (VPN & 0x3); 486 487 488 /* BadVAddr must be set */ 489 Flt->BadVAddr = req->getVaddr(); 490 491 /* Context must be set */ 492 Flt->Context_BadVPN2 = (VPN >> 2); 493 494 return Flt; 495 } 496 else 497 {// Ok, this is really a match, set paddr 498 // hits++; 499 if(!Dirty) 500 { 501 TLBModifiedFault *Flt = new TLBModifiedFault(); 502 /* EntryHi VPN, ASID fields must be set */ 503 Flt->EntryHi_Asid = Asid; 504 Flt->EntryHi_VPN2 = (VPN>>2); 505 Flt->EntryHi_VPN2X = (VPN & 0x3); 506 507 508 /* BadVAddr must be set */ 509 Flt->BadVAddr = req->getVaddr(); 510 511 /* Context must be set */ 512 Flt->Context_BadVPN2 = (VPN >> 2); 513 return Flt; 514 515 } 516 Addr PAddr; 517 if(EvenOdd == 0){ 518 PAddr = pte->PFN0; 519 }else{ 520 PAddr = pte->PFN1; 521 } 522 PAddr >>= (pte->AddrShiftAmount-12); 523 PAddr <<= pte->AddrShiftAmount; 524 PAddr |= ((req->getVaddr()) & pte->OffsetMask); 525 req->setPaddr(PAddr); 526 } 527 } 528 else 529 { // Didn't find any match, return a TLB Refill Exception 530 // misses++; 531 DtbRefillFault *Flt=new DtbRefillFault(); 532 /* EntryHi VPN, ASID fields must be set */ 533 Flt->EntryHi_Asid = Asid; 534 Flt->EntryHi_VPN2 = (VPN>>2); 535 Flt->EntryHi_VPN2X = (VPN & 0x3); 536 537 538 /* BadVAddr must be set */ 539 Flt->BadVAddr = req->getVaddr(); 540 541 /* Context must be set */ 542 Flt->Context_BadVPN2 = (VPN >> 2); 543 return Flt; 544 } 545 } 546 return checkCacheability(req);
| 445 if(MipsISA::IsKSeg0(req->getVaddr())) 446 { 447 // Address will not be translated through TLB, set response, and go! 448 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 449 if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) 450 { 451 StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 452 /* BadVAddr must be set */ 453 Flt->BadVAddr = req->getVaddr(); 454 455 return Flt; 456 } 457 } 458 else if(MipsISA::IsKSeg1(req->getVaddr())) 459 { 460 // Address will not be translated through TLB, set response, and go! 461 req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); 462 } 463 else 464 { 465 /* This is an optimization - smallPages is updated every time a TLB operation is performed 466 That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we 467 do a TLB lookup */ 468 Addr VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); 469 if(smallPages==1){ 470 VPN=((req->getVaddr() >> 11)); 471 } 472 uint8_t Asid = req->getAsid(); 473 MipsISA::PTE *pte = lookup(VPN,Asid); 474 if(req->isMisaligned()){ // Unaligned address! 475 StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); 476 /* BadVAddr must be set */ 477 Flt->BadVAddr = req->getVaddr(); 478 return Flt; 479 } 480 if(pte != NULL) 481 {// Ok, found something 482 /* Check for valid bits */ 483 int EvenOdd; 484 bool Valid; 485 bool Dirty; 486 if(((((req->getVaddr()) >> pte->AddrShiftAmount) & 1)) ==0){ 487 // Check even bits 488 Valid = pte->V0; 489 Dirty = pte->D0; 490 EvenOdd = 0; 491 492 } else { 493 // Check odd bits 494 Valid = pte->V1; 495 Dirty = pte->D1; 496 EvenOdd = 1; 497 } 498 499 if(Valid == false) 500 {//Invalid entry 501 // invalids++; 502 DtbInvalidFault *Flt = new DtbInvalidFault(); 503 /* EntryHi VPN, ASID fields must be set */ 504 Flt->EntryHi_Asid = Asid; 505 Flt->EntryHi_VPN2 = (VPN>>2); 506 Flt->EntryHi_VPN2X = (VPN & 0x3); 507 508 509 /* BadVAddr must be set */ 510 Flt->BadVAddr = req->getVaddr(); 511 512 /* Context must be set */ 513 Flt->Context_BadVPN2 = (VPN >> 2); 514 515 return Flt; 516 } 517 else 518 {// Ok, this is really a match, set paddr 519 // hits++; 520 if(!Dirty) 521 { 522 TLBModifiedFault *Flt = new TLBModifiedFault(); 523 /* EntryHi VPN, ASID fields must be set */ 524 Flt->EntryHi_Asid = Asid; 525 Flt->EntryHi_VPN2 = (VPN>>2); 526 Flt->EntryHi_VPN2X = (VPN & 0x3); 527 528 529 /* BadVAddr must be set */ 530 Flt->BadVAddr = req->getVaddr(); 531 532 /* Context must be set */ 533 Flt->Context_BadVPN2 = (VPN >> 2); 534 return Flt; 535 536 } 537 Addr PAddr; 538 if(EvenOdd == 0){ 539 PAddr = pte->PFN0; 540 }else{ 541 PAddr = pte->PFN1; 542 } 543 PAddr >>= (pte->AddrShiftAmount-12); 544 PAddr <<= pte->AddrShiftAmount; 545 PAddr |= ((req->getVaddr()) & pte->OffsetMask); 546 req->setPaddr(PAddr); 547 } 548 } 549 else 550 { // Didn't find any match, return a TLB Refill Exception 551 // misses++; 552 DtbRefillFault *Flt=new DtbRefillFault(); 553 /* EntryHi VPN, ASID fields must be set */ 554 Flt->EntryHi_Asid = Asid; 555 Flt->EntryHi_VPN2 = (VPN>>2); 556 Flt->EntryHi_VPN2X = (VPN & 0x3); 557 558 559 /* BadVAddr must be set */ 560 Flt->BadVAddr = req->getVaddr(); 561 562 /* Context must be set */ 563 Flt->Context_BadVPN2 = (VPN >> 2); 564 return Flt; 565 } 566 } 567 return checkCacheability(req);
|
| 568#endif
|
547} 548 549/////////////////////////////////////////////////////////////////////// 550// 551// Mips ITB 552// 553ITB::ITB(const Params *p) 554 : TLB(p) 555{} 556 557 558// void 559// ITB::regStats() 560// { 561// /* hits - causes failure for some reason 562// .name(name() + ".hits") 563// .desc("ITB hits"); 564// misses 565// .name(name() + ".misses") 566// .desc("ITB misses"); 567// acv 568// .name(name() + ".acv") 569// .desc("ITB acv"); 570// accesses 571// .name(name() + ".accesses") 572// .desc("ITB accesses"); 573 574// accesses = hits + misses + invalids; */ 575// } 576 577 578 579/////////////////////////////////////////////////////////////////////// 580// 581// Mips DTB 582// 583DTB::DTB(const Params *p) 584 : TLB(p) 585{} 586 587/////////////////////////////////////////////////////////////////////// 588// 589// Mips UTB 590// 591UTB::UTB(const Params *p) 592 : ITB(p), DTB(p) 593{} 594 595 596 597MipsISA::PTE & 598TLB::index(bool advance) 599{ 600 MipsISA::PTE *pte = &table[nlu]; 601 602 if (advance) 603 nextnlu(); 604 605 return *pte; 606} 607 608MipsISA::ITB * 609MipsITBParams::create() 610{ 611 return new MipsISA::ITB(this); 612} 613 614MipsISA::DTB * 615MipsDTBParams::create() 616{ 617 return new MipsISA::DTB(this); 618} 619 620MipsISA::UTB * 621MipsUTBParams::create() 622{ 623 return new MipsISA::UTB(this); 624}
| 569} 570 571/////////////////////////////////////////////////////////////////////// 572// 573// Mips ITB 574// 575ITB::ITB(const Params *p) 576 : TLB(p) 577{} 578 579 580// void 581// ITB::regStats() 582// { 583// /* hits - causes failure for some reason 584// .name(name() + ".hits") 585// .desc("ITB hits"); 586// misses 587// .name(name() + ".misses") 588// .desc("ITB misses"); 589// acv 590// .name(name() + ".acv") 591// .desc("ITB acv"); 592// accesses 593// .name(name() + ".accesses") 594// .desc("ITB accesses"); 595 596// accesses = hits + misses + invalids; */ 597// } 598 599 600 601/////////////////////////////////////////////////////////////////////// 602// 603// Mips DTB 604// 605DTB::DTB(const Params *p) 606 : TLB(p) 607{} 608 609/////////////////////////////////////////////////////////////////////// 610// 611// Mips UTB 612// 613UTB::UTB(const Params *p) 614 : ITB(p), DTB(p) 615{} 616 617 618 619MipsISA::PTE & 620TLB::index(bool advance) 621{ 622 MipsISA::PTE *pte = &table[nlu]; 623 624 if (advance) 625 nextnlu(); 626 627 return *pte; 628} 629 630MipsISA::ITB * 631MipsITBParams::create() 632{ 633 return new MipsISA::ITB(this); 634} 635 636MipsISA::DTB * 637MipsDTBParams::create() 638{ 639 return new MipsISA::DTB(this); 640} 641 642MipsISA::UTB * 643MipsUTBParams::create() 644{ 645 return new MipsISA::UTB(this); 646}
|