tlb.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 633 行 · 第 1/2 页
CC
633 行
if (PcPAL(req->getPC())) { // strip off PAL PC marker (lsb is 1) req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); hits++; return NoFault; } if (req->getFlags() & PHYSICAL) { req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address if (!validVirtualAddress(req->getVaddr())) { acv++; return new ItbAcvFault(req->getVaddr()); } // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6#if ALPHA_TLASER if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) && VAddrSpaceEV5(req->getVaddr()) == 2)#else if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)#endif { // only valid in kernel mode if (ICM_CM(tc->readMiscRegNoEffect(IPR_ICM)) != mode_kernel) { acv++; return new ItbAcvFault(req->getVaddr()); } req->setPaddr(req->getVaddr() & PAddrImplMask);#if !ALPHA_TLASER // sign extend the physical address properly if (req->getPaddr() & PAddrUncachedBit40) req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); else req->setPaddr(req->getPaddr() & ULL(0xffffffffff));#endif } else { // not a physical address: need to look up pte int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN)); TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(), asn); if (!entry) { misses++; return new ItbPageFault(req->getVaddr()); } req->setPaddr((entry->ppn << PageShift) + (VAddr(req->getVaddr()).offset() & ~3)); // check permissions for this access if (!(entry->xre & (1 << ICM_CM(tc->readMiscRegNoEffect(IPR_ICM))))) { // instruction access fault acv++; return new ItbAcvFault(req->getVaddr()); } hits++; } } // check that the physical address is ok (catch bad physical addresses) if (req->getPaddr() & ~PAddrImplMask) return genMachineCheckFault(); return checkCacheability(req);}/////////////////////////////////////////////////////////////////////////// Alpha DTB// DTB::DTB(const Params *p) : TLB(p){}voidDTB::regStats(){ read_hits .name(name() + ".read_hits") .desc("DTB read hits") ; read_misses .name(name() + ".read_misses") .desc("DTB read misses") ; read_acv .name(name() + ".read_acv") .desc("DTB read access violations") ; read_accesses .name(name() + ".read_accesses") .desc("DTB read accesses") ; write_hits .name(name() + ".write_hits") .desc("DTB write hits") ; write_misses .name(name() + ".write_misses") .desc("DTB write misses") ; write_acv .name(name() + ".write_acv") .desc("DTB write access violations") ; write_accesses .name(name() + ".write_accesses") .desc("DTB write accesses") ; hits .name(name() + ".hits") .desc("DTB hits") ; misses .name(name() + ".misses") .desc("DTB misses") ; acv .name(name() + ".acv") .desc("DTB access violations") ; accesses .name(name() + ".accesses") .desc("DTB accesses") ; hits = read_hits + write_hits; misses = read_misses + write_misses; acv = read_acv + write_acv; accesses = read_accesses + write_accesses;}FaultDTB::translate(RequestPtr &req, ThreadContext *tc, bool write){ Addr pc = tc->readPC(); mode_type mode = (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)); /** * Check for alignment faults */ if (req->getVaddr() & (req->getSize() - 1)) { DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), req->getSize()); uint64_t flags = write ? MM_STAT_WR_MASK : 0; return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); } if (PcPAL(pc)) { mode = (req->getFlags() & ALTMODE) ? (mode_type)ALT_MODE_AM( tc->readMiscRegNoEffect(IPR_ALT_MODE)) : mode_kernel; } if (req->getFlags() & PHYSICAL) { req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address if (!validVirtualAddress(req->getVaddr())) { if (write) { write_acv++; } else { read_acv++; } uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | MM_STAT_ACV_MASK; return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } // Check for "superpage" mapping#if ALPHA_TLASER if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) && VAddrSpaceEV5(req->getVaddr()) == 2)#else if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)#endif { // only valid in kernel mode if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) != mode_kernel) { if (write) { write_acv++; } else { read_acv++; } uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK); return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); } req->setPaddr(req->getVaddr() & PAddrImplMask);#if !ALPHA_TLASER // sign extend the physical address properly if (req->getPaddr() & PAddrUncachedBit40) req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); else req->setPaddr(req->getPaddr() & ULL(0xffffffffff));#endif } else { if (write) write_accesses++; else read_accesses++; int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN)); // not a physical address: need to look up pte TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(), asn); if (!entry) { // page fault if (write) { write_misses++; } else { read_misses++; } uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK; return (req->getFlags() & VPTE) ? (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(), flags)) : (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(), flags)); } req->setPaddr((entry->ppn << PageShift) + VAddr(req->getVaddr()).offset()); if (write) { if (!(entry->xwe & MODE2MASK(mode))) { // declare the instruction access fault write_acv++; uint64_t flags = MM_STAT_WR_MASK | MM_STAT_ACV_MASK | (entry->fonw ? MM_STAT_FONW_MASK : 0); return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } if (entry->fonw) { write_acv++; uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK; return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } } else { if (!(entry->xre & MODE2MASK(mode))) { read_acv++; uint64_t flags = MM_STAT_ACV_MASK | (entry->fonr ? MM_STAT_FONR_MASK : 0); return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); } if (entry->fonr) { read_acv++; uint64_t flags = MM_STAT_FONR_MASK; return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } } } if (write) write_hits++; else read_hits++; } // check that the physical address is ok (catch bad physical addresses) if (req->getPaddr() & ~PAddrImplMask) return genMachineCheckFault(); return checkCacheability(req);}TlbEntry &TLB::index(bool advance){ TlbEntry *entry = &table[nlu]; if (advance) nextnlu(); return *entry;}/* end namespace AlphaISA */ }AlphaISA::ITB *AlphaITBParams::create(){ return new AlphaISA::ITB(this);}AlphaISA::DTB *AlphaDTBParams::create(){ return new AlphaISA::DTB(this);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?