📄 alpha_memory.cc
字号:
acv++; return ITB_Acv_Fault; } req->paddr = req->vaddr & PAddrImplMask;#if !ALPHA_TLASER // sign extend the physical address properly if (req->paddr & PAddrUncachedBit40) req->paddr |= ULL(0xf0000000000); else req->paddr &= ULL(0xffffffffff);#endif } else { // not a physical address: need to look up pte AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); if (!pte) { fault(req->vaddr, req->xc); misses++; return ITB_Fault_Fault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + (AlphaISA::VAddr(req->vaddr).offset() & ~3); // check permissions for this access if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { // instruction access fault fault(req->vaddr, req->xc); acv++; return ITB_Acv_Fault; } hits++; } } // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) return Machine_Check_Fault; checkCacheability(req); return No_Fault;}/////////////////////////////////////////////////////////////////////////// Alpha DTB//AlphaDTB::AlphaDTB(const std::string &name, int size) : AlphaTLB(name, size){}voidAlphaDTB::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;}voidAlphaDTB::fault(MemReqPtr &req, uint64_t flags) const{ ExecContext *xc = req->xc; AlphaISA::VAddr vaddr = req->vaddr; uint64_t *ipr = xc->regs.ipr; // Set fault address and flags. Even though we're modeling an // EV5, we use the EV6 technique of not latching fault registers // on VPTE loads (instead of locking the registers until IPR_VA is // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. if (!xc->misspeculating() && !(req->flags & VPTE) && !(req->flags & NO_FAULT)) { // set VA register with faulting address ipr[AlphaISA::IPR_VA] = req->vaddr; // set MM_STAT register flags ipr[AlphaISA::IPR_MM_STAT] = (((Opcode(xc->getInst()) & 0x3f) << 11) | ((Ra(xc->getInst()) & 0x1f) << 6) | (flags & 0x3f)); // set VA_FORM register with faulting formatted address ipr[AlphaISA::IPR_VA_FORM] = ipr[AlphaISA::IPR_MVPTBR] | (vaddr.vpn() << 3); }}FaultAlphaDTB::translate(MemReqPtr &req, bool write) const{ RegFile *regs = &req->xc->regs; Addr pc = regs->pc; InternalProcReg *ipr = regs->ipr; AlphaISA::mode_type mode = (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); /** * Check for alignment faults */ if (req->vaddr & (req->size - 1)) { fault(req, write ? MM_STAT_WR_MASK : 0); DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, req->size); return Alignment_Fault; } if (pc & 0x1) { mode = (req->flags & ALTMODE) ? (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) : AlphaISA::mode_kernel; } if (req->flags & PHYSICAL) { req->paddr = req->vaddr; } else { // verify that this is a good virtual address if (!validVirtualAddress(req->vaddr)) { fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } return DTB_Fault_Fault; } // Check for "superpage" mapping#if ALPHA_TLASER if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && VAddrSpaceEV5(req->vaddr) == 2) {#else if (VAddrSpaceEV6(req->vaddr) == 0x7e) {#endif // only valid in kernel mode if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) { fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); if (write) { write_acv++; } else { read_acv++; } return DTB_Acv_Fault; } req->paddr = req->vaddr & PAddrImplMask;#if !ALPHA_TLASER // sign extend the physical address properly if (req->paddr & PAddrUncachedBit40) req->paddr |= ULL(0xf0000000000); else req->paddr &= ULL(0xffffffffff);#endif } else { if (write) write_accesses++; else read_accesses++; // not a physical address: need to look up pte AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); if (!pte) { // page fault fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK); if (write) { write_misses++; } else { read_misses++; } return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + AlphaISA::VAddr(req->vaddr).offset(); if (write) { if (!(pte->xwe & MODE2MASK(mode))) { // declare the instruction access fault fault(req, MM_STAT_WR_MASK | MM_STAT_ACV_MASK | (pte->fonw ? MM_STAT_FONW_MASK : 0)); write_acv++; return DTB_Fault_Fault; } if (pte->fonw) { fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK); write_acv++; return DTB_Fault_Fault; } } else { if (!(pte->xre & MODE2MASK(mode))) { fault(req, MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0)); read_acv++; return DTB_Acv_Fault; } if (pte->fonr) { fault(req, MM_STAT_FONR_MASK); read_acv++; return DTB_Fault_Fault; } } } if (write) write_hits++; else read_hits++; } // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) return Machine_Check_Fault; checkCacheability(req); return No_Fault;}AlphaISA::PTE &AlphaTLB::index(bool advance){ AlphaISA::PTE *pte = &table[nlu]; if (advance) nextnlu(); return *pte;}DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB)BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) Param<int> size;END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB) INIT_PARAM_DFLT(size, "TLB size", 48)END_INIT_SIM_OBJECT_PARAMS(AlphaITB)CREATE_SIM_OBJECT(AlphaITB){ return new AlphaITB(getInstanceName(), size);}REGISTER_SIM_OBJECT("AlphaITB", AlphaITB)BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) Param<int> size;END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB) INIT_PARAM_DFLT(size, "TLB size", 64)END_INIT_SIM_OBJECT_PARAMS(AlphaDTB)CREATE_SIM_OBJECT(AlphaDTB){ return new AlphaDTB(getInstanceName(), size);}REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -