summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Binkert <binkertn@umich.edu>2004-02-18 12:01:04 -0500
committerNathan Binkert <binkertn@umich.edu>2004-02-18 12:01:04 -0500
commit3bf012fe2f9a9091efdb0495cf1db778571fce65 (patch)
tree6a00b5b3400770b95b2c80bddf7675340825ecb6
parent8c89212fa3d00929d64d76ee8473580c630df8ed (diff)
parent6610699987f54ae1736b70881c2023d93b82370d (diff)
downloadgem5-3bf012fe2f9a9091efdb0495cf1db778571fce65.tar.xz
Merge
--HG-- extra : convert_revision : b29c9bbb50994e2567fd58deedb853123d2d69a0
-rw-r--r--arch/alpha/alpha_memory.cc93
-rw-r--r--cpu/memtest/memtest.cc57
-rw-r--r--cpu/memtest/memtest.hh5
3 files changed, 97 insertions, 58 deletions
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc
index 00e97250f..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 (!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..051d9623a 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");
@@ -127,7 +131,8 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
case Read:
if (memcmp(req->data, data, req->size) != 0) {
cerr << name() << ": on read of 0x" << hex << req->paddr
- << " @ cycle " << dec << curTick
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << "@ cycle " << dec << curTick
<< ", cache returns 0x";
printData(cerr, req->data, req->size);
cerr << ", expected 0x";
@@ -159,11 +164,13 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
}
if (blockAddr(req->paddr) == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": " << name() << ": completed "
+ cerr << name() << ": completed "
<< (req->cmd.isWrite() ? "write" : "read")
<< " access of "
<< dec << req->size << " bytes at address 0x"
- << hex << req->paddr << ", value = 0x";
+ << hex << req->paddr
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << ", value = 0x";
printData(cerr, req->data, req->size);
cerr << " @ cycle " << dec << curTick;
@@ -219,6 +226,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();
@@ -243,11 +252,13 @@ MemTest::tick()
uint8_t *result = new uint8_t[8];
checkMem->access(Read, req->paddr, result, req->size);
if (blockAddr(req->paddr) == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": " << name()
+ cerr << name()
<< ": initiating read "
<< ((probe)?"probe of ":"access of ")
<< dec << req->size << " bytes from addr 0x"
- << hex << req->paddr << " at cycle "
+ << hex << req->paddr
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << " at cycle "
<< dec << curTick << endl;
}
if (probe) {
@@ -263,13 +274,14 @@ MemTest::tick()
memcpy(req->data, &data, req->size);
checkMem->access(Write, req->paddr, req->data, req->size);
if (blockAddr(req->paddr) == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": "
- << name() << ": initiating write "
+ cerr << name() << ": initiating write "
<< ((probe)?"probe of ":"access of ")
<< dec << req->size << " bytes (value = 0x";
printData(cerr, req->data, req->size);
cerr << ") to addr 0x"
- << hex << req->paddr << " at cycle "
+ << hex << req->paddr
+ << " (0x" << hex << blockAddr(req->paddr) << ")"
+ << " at cycle "
<< dec << curTick << endl;
}
if (probe) {
@@ -281,8 +293,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;
@@ -291,11 +309,15 @@ MemTest::tick()
req->data = new uint8_t[blockSize];
req->size = blockSize;
if (source == traceBlockAddr || dest == traceBlockAddr) {
- cerr << hex << traceBlockAddr << ": " << name()
+ cerr << name()
<< ": initiating copy of "
<< dec << req->size << " bytes from addr 0x"
- << hex << source << " to addr 0x"
- << hex << dest << " at cycle "
+ << hex << source
+ << " (0x" << hex << blockAddr(source) << ")"
+ << " to addr 0x"
+ << hex << dest
+ << " (0x" << hex << blockAddr(dest) << ")"
+ << " at cycle "
<< dec << curTick << endl;
}
cacheInterface->access(req);
@@ -331,6 +353,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 +373,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 +393,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;