⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alpha_memory.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 2 页
字号:
                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 + -