diff options
-rw-r--r-- | arch/alpha/alpha_memory.cc | 93 | ||||
-rw-r--r-- | cpu/memtest/memtest.cc | 25 | ||||
-rw-r--r-- | cpu/memtest/memtest.hh | 5 |
3 files changed, 76 insertions, 47 deletions
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 401dc21ec..7bdbea6c1 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -280,17 +280,13 @@ AlphaItb::translate(MemReqPtr &req) const return No_Fault; } - // verify that this is a good virtual address - if (!validVirtualAddress(req->vaddr)) { - fault(req->vaddr, req->xc); - acv++; - return Itb_Acv_Fault; - } + if (req->flags & PHYSICAL) { + req->paddr = req->vaddr; + } else if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && + VA_SPACE(req->vaddr) == 2) { + // Check for "superpage" mapping: when SP<1> is set, and + // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. - // Check for "superpage" mapping: when SP<1> is set, and - // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. - if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && - VA_SPACE(req->vaddr) == 2) { // only valid in kernel mode if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); @@ -298,16 +294,18 @@ AlphaItb::translate(MemReqPtr &req) const return Itb_Acv_Fault; } - req->flags |= PHYSICAL; - } - - if (req->flags & PHYSICAL) { req->paddr = req->vaddr & PA_IMPL_MASK; } else { - // not a physical address: need to look up pte + // verify that this is a good virtual address + if (!validVirtualAddress(req->vaddr)) { + fault(req->vaddr, req->xc); + acv++; + return Itb_Acv_Fault; + } + // not a physical address: need to look up pte AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); if (!pte) { fault(req->vaddr, req->xc); @@ -326,6 +324,10 @@ AlphaItb::translate(MemReqPtr &req) const } } + // check that the physical address is ok (catch bad physical addresses) + if (req->paddr & ~PA_IMPL_MASK) + return Machine_Check_Fault; + checkCacheability(req); hits++; @@ -440,11 +442,6 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const Addr pc = regs->pc; InternalProcReg *ipr = regs->ipr; - if (write) - write_accesses++; - else - read_accesses++; - AlphaISA::mode_type mode = (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); @@ -454,20 +451,13 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const : AlphaISA::mode_kernel; } - // verify that this is a good virtual address - if (!(req->flags & PHYSICAL) && !validVirtualAddress(req->vaddr)) { - fault(req->vaddr, - ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | - MM_STAT_ACV_MASK), - req->xc); - - if (write) { write_acv++; } else { read_acv++; } - return Dtb_Fault_Fault; - } + if (req->flags & PHYSICAL) { + req->paddr = req->vaddr; + } else if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && + VA_SPACE(req->vaddr) == 2) { + // Check for "superpage" mapping: when SP<1> is set, and + // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. - // Check for "superpage" mapping: when SP<1> is set, and - // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. - if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && VA_SPACE(req->vaddr) == 2) { // only valid in kernel mode if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) { fault(req->vaddr, @@ -477,14 +467,25 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const return Dtb_Acv_Fault; } - req->flags |= PHYSICAL; - } - - if (req->flags & PHYSICAL) { req->paddr = req->vaddr & PA_IMPL_MASK; } else { - // not a physical address: need to look up pte + if (write) + write_accesses++; + else + read_accesses++; + + // verify that this is a good virtual address + if (!validVirtualAddress(req->vaddr)) { + fault(req->vaddr, + ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | + MM_STAT_ACV_MASK), + req->xc); + + if (write) { write_acv++; } else { read_acv++; } + return Dtb_Fault_Fault; + } + // not a physical address: need to look up pte AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); @@ -528,14 +529,18 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const return Dtb_Fault_Fault; } } + + if (write) + write_hits++; + else + read_hits++; } - checkCacheability(req); + // check that the physical address is ok (catch bad physical addresses) + if (req->paddr & ~PA_IMPL_MASK) + return Machine_Check_Fault; - if (write) - write_hits++; - else - read_hits++; + checkCacheability(req); return No_Fault; } diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 05de370fd..82bec8ac9 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -53,6 +53,8 @@ MemTest::MemTest(const string &name, unsigned _percentCopies, unsigned _percentUncacheable, unsigned _progressInterval, + unsigned _percentSourceUnaligned, + unsigned _percentDestUnaligned, Addr _traceAddr, Counter max_loads_any_thread, Counter max_loads_all_threads) @@ -66,7 +68,9 @@ MemTest::MemTest(const string &name, percentCopies(_percentCopies), percentUncacheable(_percentUncacheable), progressInterval(_progressInterval), - nextProgressMessage(_progressInterval) + nextProgressMessage(_progressInterval), + percentSourceUnaligned(_percentSourceUnaligned), + percentDestUnaligned(percentDestUnaligned) { vector<string> cmd; cmd.push_back("/bin/ls"); @@ -219,6 +223,8 @@ MemTest::tick() uint64_t data = random(); unsigned access_size = random() % 4; unsigned cacheable = rand() % 100; + unsigned source_align = rand() % 100; + unsigned dest_align = rand() % 100; MemReqPtr req = new MemReq(); @@ -281,8 +287,14 @@ MemTest::tick() } } else { // copy - Addr source = blockAddr(((base) ? baseAddr1 : baseAddr2) + offset1); - Addr dest = blockAddr(((base) ? baseAddr2 : baseAddr1) + offset2); + Addr source = ((base) ? baseAddr1 : baseAddr2) + offset1; + Addr dest = ((base) ? baseAddr2 : baseAddr1) + offset2; + if (source_align >= percentSourceUnaligned) { + source = blockAddr(source); + } + if (dest_align >= percentDestUnaligned) { + dest = blockAddr(dest); + } req->cmd = Copy; req->flags &= ~UNCACHEABLE; req->paddr = source; @@ -331,6 +343,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest) Param<unsigned> percent_copies; Param<unsigned> percent_uncacheable; Param<unsigned> progress_interval; + Param<unsigned> percent_source_unaligned; + Param<unsigned> percent_dest_unaligned; Param<Addr> trace_addr; Param<Counter> max_loads_any_thread; Param<Counter> max_loads_all_threads; @@ -349,6 +363,10 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest) INIT_PARAM_DFLT(percent_uncacheable, "target uncacheable percentage", 10), INIT_PARAM_DFLT(progress_interval, "progress report interval (in accesses)", 1000000), + INIT_PARAM_DFLT(percent_source_unaligned, "percent of copy source address " + "that are unaligned", 50), + INIT_PARAM_DFLT(percent_dest_unaligned, "percent of copy dest address " + "that are unaligned", 50), INIT_PARAM_DFLT(trace_addr, "address to trace", 0), INIT_PARAM_DFLT(max_loads_any_thread, "terminate when any thread reaches this load count", @@ -365,6 +383,7 @@ CREATE_SIM_OBJECT(MemTest) return new MemTest(getInstanceName(), cache->getInterface(), main_mem, check_mem, memory_size, percent_reads, percent_copies, percent_uncacheable, progress_interval, + percent_source_unaligned, percent_dest_unaligned, trace_addr, max_loads_any_thread, max_loads_all_threads); } diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index d3ac020fd..da6e180a0 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -51,6 +51,8 @@ class MemTest : public BaseCPU unsigned _percentCopies, unsigned _percentUncacheable, unsigned _progressInterval, + unsigned _percentSourceUnaligned, + unsigned _percentDestUnaligned, Addr _traceAddr, Counter max_loads_any_thread, Counter max_loads_all_threads); @@ -103,6 +105,9 @@ class MemTest : public BaseCPU unsigned progressInterval; // frequency of progress reports Tick nextProgressMessage; // access # for next progress report + unsigned percentSourceUnaligned; + unsigned percentDestUnaligned; + Tick noResponseCycles; Statistics::Scalar<> numReads; |