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 + -
显示快捷键?