arch/alpha/alpha_memory.cc:
    SCCS merged

--HG--
extra : convert_revision : 0348e29c833684fd593a6c02913319f45f24e76e
This commit is contained in:
Andrew Schultz 2004-02-16 22:04:55 -05:00
commit 59a6e9d705
3 changed files with 76 additions and 47 deletions

View file

@ -280,17 +280,13 @@ AlphaItb::translate(MemReqPtr &req) const
return No_Fault; return No_Fault;
} }
// verify that this is a good virtual address if (req->flags & PHYSICAL) {
if (!validVirtualAddress(req->vaddr)) { req->paddr = req->vaddr;
fault(req->vaddr, req->xc); } else if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
acv++; VA_SPACE(req->vaddr) == 2) {
return Itb_Acv_Fault;
}
// Check for "superpage" mapping: when SP<1> is set, and // Check for "superpage" mapping: when SP<1> is set, and
// VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. // 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 // only valid in kernel mode
if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) {
fault(req->vaddr, req->xc); fault(req->vaddr, req->xc);
@ -298,14 +294,16 @@ AlphaItb::translate(MemReqPtr &req) const
return Itb_Acv_Fault; return Itb_Acv_Fault;
} }
req->flags |= PHYSICAL;
}
if (req->flags & PHYSICAL) {
req->paddr = req->vaddr & PA_IMPL_MASK; req->paddr = req->vaddr & PA_IMPL_MASK;
} else { } 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), AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
@ -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); checkCacheability(req);
hits++; hits++;
@ -440,11 +442,6 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const
Addr pc = regs->pc; Addr pc = regs->pc;
InternalProcReg *ipr = regs->ipr; InternalProcReg *ipr = regs->ipr;
if (write)
write_accesses++;
else
read_accesses++;
AlphaISA::mode_type mode = AlphaISA::mode_type mode =
(AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); (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; : AlphaISA::mode_kernel;
} }
// verify that this is a good virtual address if (req->flags & PHYSICAL) {
if (!(req->flags & PHYSICAL) && !validVirtualAddress(req->vaddr)) { req->paddr = req->vaddr;
fault(req->vaddr, } else if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | VA_SPACE(req->vaddr) == 2) {
MM_STAT_ACV_MASK),
req->xc);
if (write) { write_acv++; } else { read_acv++; }
return Dtb_Fault_Fault;
}
// Check for "superpage" mapping: when SP<1> is set, and // Check for "superpage" mapping: when SP<1> is set, and
// VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>. // 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 // only valid in kernel mode
if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) { if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) {
fault(req->vaddr, fault(req->vaddr,
@ -477,14 +467,25 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const
return Dtb_Acv_Fault; return Dtb_Acv_Fault;
} }
req->flags |= PHYSICAL;
}
if (req->flags & PHYSICAL) {
req->paddr = req->vaddr & PA_IMPL_MASK; req->paddr = req->vaddr & PA_IMPL_MASK;
} else { } 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), AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
@ -528,14 +529,18 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const
return Dtb_Fault_Fault; return Dtb_Fault_Fault;
} }
} }
}
checkCacheability(req);
if (write) if (write)
write_hits++; write_hits++;
else else
read_hits++; read_hits++;
}
// check that the physical address is ok (catch bad physical addresses)
if (req->paddr & ~PA_IMPL_MASK)
return Machine_Check_Fault;
checkCacheability(req);
return No_Fault; return No_Fault;
} }

View file

@ -53,6 +53,8 @@ MemTest::MemTest(const string &name,
unsigned _percentCopies, unsigned _percentCopies,
unsigned _percentUncacheable, unsigned _percentUncacheable,
unsigned _progressInterval, unsigned _progressInterval,
unsigned _percentSourceUnaligned,
unsigned _percentDestUnaligned,
Addr _traceAddr, Addr _traceAddr,
Counter max_loads_any_thread, Counter max_loads_any_thread,
Counter max_loads_all_threads) Counter max_loads_all_threads)
@ -66,7 +68,9 @@ MemTest::MemTest(const string &name,
percentCopies(_percentCopies), percentCopies(_percentCopies),
percentUncacheable(_percentUncacheable), percentUncacheable(_percentUncacheable),
progressInterval(_progressInterval), progressInterval(_progressInterval),
nextProgressMessage(_progressInterval) nextProgressMessage(_progressInterval),
percentSourceUnaligned(_percentSourceUnaligned),
percentDestUnaligned(percentDestUnaligned)
{ {
vector<string> cmd; vector<string> cmd;
cmd.push_back("/bin/ls"); cmd.push_back("/bin/ls");
@ -219,6 +223,8 @@ MemTest::tick()
uint64_t data = random(); uint64_t data = random();
unsigned access_size = random() % 4; unsigned access_size = random() % 4;
unsigned cacheable = rand() % 100; unsigned cacheable = rand() % 100;
unsigned source_align = rand() % 100;
unsigned dest_align = rand() % 100;
MemReqPtr req = new MemReq(); MemReqPtr req = new MemReq();
@ -281,8 +287,14 @@ MemTest::tick()
} }
} else { } else {
// copy // copy
Addr source = blockAddr(((base) ? baseAddr1 : baseAddr2) + offset1); Addr source = ((base) ? baseAddr1 : baseAddr2) + offset1;
Addr dest = blockAddr(((base) ? baseAddr2 : baseAddr1) + offset2); Addr dest = ((base) ? baseAddr2 : baseAddr1) + offset2;
if (source_align >= percentSourceUnaligned) {
source = blockAddr(source);
}
if (dest_align >= percentDestUnaligned) {
dest = blockAddr(dest);
}
req->cmd = Copy; req->cmd = Copy;
req->flags &= ~UNCACHEABLE; req->flags &= ~UNCACHEABLE;
req->paddr = source; req->paddr = source;
@ -331,6 +343,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
Param<unsigned> percent_copies; Param<unsigned> percent_copies;
Param<unsigned> percent_uncacheable; Param<unsigned> percent_uncacheable;
Param<unsigned> progress_interval; Param<unsigned> progress_interval;
Param<unsigned> percent_source_unaligned;
Param<unsigned> percent_dest_unaligned;
Param<Addr> trace_addr; Param<Addr> trace_addr;
Param<Counter> max_loads_any_thread; Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads; 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(percent_uncacheable, "target uncacheable percentage", 10),
INIT_PARAM_DFLT(progress_interval, INIT_PARAM_DFLT(progress_interval,
"progress report interval (in accesses)", 1000000), "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(trace_addr, "address to trace", 0),
INIT_PARAM_DFLT(max_loads_any_thread, INIT_PARAM_DFLT(max_loads_any_thread,
"terminate when any thread reaches this load count", "terminate when any thread reaches this load count",
@ -365,6 +383,7 @@ CREATE_SIM_OBJECT(MemTest)
return new MemTest(getInstanceName(), cache->getInterface(), main_mem, return new MemTest(getInstanceName(), cache->getInterface(), main_mem,
check_mem, memory_size, percent_reads, percent_copies, check_mem, memory_size, percent_reads, percent_copies,
percent_uncacheable, progress_interval, percent_uncacheable, progress_interval,
percent_source_unaligned, percent_dest_unaligned,
trace_addr, max_loads_any_thread, trace_addr, max_loads_any_thread,
max_loads_all_threads); max_loads_all_threads);
} }

View file

@ -51,6 +51,8 @@ class MemTest : public BaseCPU
unsigned _percentCopies, unsigned _percentCopies,
unsigned _percentUncacheable, unsigned _percentUncacheable,
unsigned _progressInterval, unsigned _progressInterval,
unsigned _percentSourceUnaligned,
unsigned _percentDestUnaligned,
Addr _traceAddr, Addr _traceAddr,
Counter max_loads_any_thread, Counter max_loads_any_thread,
Counter max_loads_all_threads); Counter max_loads_all_threads);
@ -103,6 +105,9 @@ class MemTest : public BaseCPU
unsigned progressInterval; // frequency of progress reports unsigned progressInterval; // frequency of progress reports
Tick nextProgressMessage; // access # for next progress report Tick nextProgressMessage; // access # for next progress report
unsigned percentSourceUnaligned;
unsigned percentDestUnaligned;
Tick noResponseCycles; Tick noResponseCycles;
Statistics::Scalar<> numReads; Statistics::Scalar<> numReads;