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