tlb.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 678 行 · 第 1/2 页
CC
678 行
; hits = read_hits + write_hits; misses = read_misses + write_misses; accesses = read_accesses + write_accesses;}FaultITB::translate(RequestPtr &req, ThreadContext *tc){#if !FULL_SYSTEM Process * p = tc->getProcessPtr(); Fault fault = p->pTable->translate(req); if(fault != NoFault) return fault; return NoFault;#else if(MipsISA::IsKSeg0(req->getVaddr())) { // Address will not be translated through TLB, set response, and go! req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) { AddressErrorFault *Flt = new AddressErrorFault(); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); return Flt; } } else if(MipsISA::IsKSeg1(req->getVaddr())) { // Address will not be translated through TLB, set response, and go! req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); } else { /* This is an optimization - smallPages is updated every time a TLB operation is performed That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup */ Addr VPN; if(smallPages==1){ VPN=((req->getVaddr() >> 11)); } else { VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); } uint8_t Asid = req->getAsid(); if(req->isMisaligned()){ // Unaligned address! AddressErrorFault *Flt = new AddressErrorFault(); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); return Flt; } MipsISA::PTE *pte = lookup(VPN,Asid); if(pte != NULL) {// Ok, found something /* Check for valid bits */ int EvenOdd; bool Valid; if((((req->getVaddr()) >> pte->AddrShiftAmount) & 1) ==0){ // Check even bits Valid = pte->V0; EvenOdd = 0; } else { // Check odd bits Valid = pte->V1; EvenOdd = 1; } if(Valid == false) {//Invalid entry ItbInvalidFault *Flt = new ItbInvalidFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; Flt->EntryHi_VPN2 = (VPN>>2); Flt->EntryHi_VPN2X = (VPN & 0x3); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); /* Context must be set */ Flt->Context_BadVPN2 = (VPN >> 2); return Flt; } else {// Ok, this is really a match, set paddr // hits++; Addr PAddr; if(EvenOdd == 0){ PAddr = pte->PFN0; }else{ PAddr = pte->PFN1; } PAddr >>= (pte->AddrShiftAmount-12); PAddr <<= pte->AddrShiftAmount; PAddr |= ((req->getVaddr()) & pte->OffsetMask); req->setPaddr(PAddr); } } else { // Didn't find any match, return a TLB Refill Exception // misses++; ItbRefillFault *Flt=new ItbRefillFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; Flt->EntryHi_VPN2 = (VPN>>2); Flt->EntryHi_VPN2X = (VPN & 0x3); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); /* Context must be set */ Flt->Context_BadVPN2 = (VPN >> 2); return Flt; } } return checkCacheability(req);#endif}FaultDTB::translate(RequestPtr &req, ThreadContext *tc, bool write){#if !FULL_SYSTEM Process * p = tc->getProcessPtr(); Fault fault = p->pTable->translate(req); if(fault != NoFault) return fault; return NoFault;#else if(MipsISA::IsKSeg0(req->getVaddr())) { // Address will not be translated through TLB, set response, and go! req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); if(MipsISA::getOperatingMode(tc->readMiscReg(MipsISA::Status)) != mode_kernel || req->isMisaligned()) { StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); return Flt; } } else if(MipsISA::IsKSeg1(req->getVaddr())) { // Address will not be translated through TLB, set response, and go! req->setPaddr(MipsISA::KSeg02Phys(req->getVaddr())); } else { /* This is an optimization - smallPages is updated every time a TLB operation is performed That way, we don't need to look at Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup */ Addr VPN=((req->getVaddr() >> 11) & 0xFFFFFFFC); if(smallPages==1){ VPN=((req->getVaddr() >> 11)); } uint8_t Asid = req->getAsid(); MipsISA::PTE *pte = lookup(VPN,Asid); if(req->isMisaligned()){ // Unaligned address! StoreAddressErrorFault *Flt = new StoreAddressErrorFault(); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); return Flt; } if(pte != NULL) {// Ok, found something /* Check for valid bits */ int EvenOdd; bool Valid; bool Dirty; if(((((req->getVaddr()) >> pte->AddrShiftAmount) & 1)) ==0){ // Check even bits Valid = pte->V0; Dirty = pte->D0; EvenOdd = 0; } else { // Check odd bits Valid = pte->V1; Dirty = pte->D1; EvenOdd = 1; } if(Valid == false) {//Invalid entry // invalids++; DtbInvalidFault *Flt = new DtbInvalidFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; Flt->EntryHi_VPN2 = (VPN>>2); Flt->EntryHi_VPN2X = (VPN & 0x3); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); /* Context must be set */ Flt->Context_BadVPN2 = (VPN >> 2); return Flt; } else {// Ok, this is really a match, set paddr // hits++; if(!Dirty) { TLBModifiedFault *Flt = new TLBModifiedFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; Flt->EntryHi_VPN2 = (VPN>>2); Flt->EntryHi_VPN2X = (VPN & 0x3); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); /* Context must be set */ Flt->Context_BadVPN2 = (VPN >> 2); return Flt; } Addr PAddr; if(EvenOdd == 0){ PAddr = pte->PFN0; }else{ PAddr = pte->PFN1; } PAddr >>= (pte->AddrShiftAmount-12); PAddr <<= pte->AddrShiftAmount; PAddr |= ((req->getVaddr()) & pte->OffsetMask); req->setPaddr(PAddr); } } else { // Didn't find any match, return a TLB Refill Exception // misses++; DtbRefillFault *Flt=new DtbRefillFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; Flt->EntryHi_VPN2 = (VPN>>2); Flt->EntryHi_VPN2X = (VPN & 0x3); /* BadVAddr must be set */ Flt->BadVAddr = req->getVaddr(); /* Context must be set */ Flt->Context_BadVPN2 = (VPN >> 2); return Flt; } } return checkCacheability(req);#endif}/////////////////////////////////////////////////////////////////////////// Mips ITB//ITB::ITB(const Params *p) : TLB(p){}// void// ITB::regStats()// {// /* hits - causes failure for some reason// .name(name() + ".hits")// .desc("ITB hits");// misses// .name(name() + ".misses")// .desc("ITB misses");// acv// .name(name() + ".acv")// .desc("ITB acv");// accesses// .name(name() + ".accesses")// .desc("ITB accesses");// accesses = hits + misses + invalids; */// }/////////////////////////////////////////////////////////////////////////// Mips DTB//DTB::DTB(const Params *p) : TLB(p){}/////////////////////////////////////////////////////////////////////////// Mips UTB//UTB::UTB(const Params *p) : ITB(p), DTB(p){}MipsISA::PTE &TLB::index(bool advance){ MipsISA::PTE *pte = &table[nlu]; if (advance) nextnlu(); return *pte;}MipsISA::ITB *MipsITBParams::create(){ return new MipsISA::ITB(this);}MipsISA::DTB *MipsDTBParams::create(){ return new MipsISA::DTB(this);}MipsISA::UTB *MipsUTBParams::create(){ return new MipsISA::UTB(this);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?