summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Hallnor <ehallnor@umich.edu>2004-09-20 22:00:35 -0400
committerErik Hallnor <ehallnor@umich.edu>2004-09-20 22:00:35 -0400
commit15d08a3422d5038b7fe8aa1e3206e27e889d69e3 (patch)
tree8a2bb7d7a553b2d7dc4afa8d5278341af0fb3e5c
parentbb59e2e7a3ec7e599dac92cfc780c7fdde2ad286 (diff)
downloadgem5-15d08a3422d5038b7fe8aa1e3206e27e889d69e3.tar.xz
Update copies to work around alignment faults.
arch/alpha/isa_desc: whitespace fix. cpu/simple_cpu/simple_cpu.cc: Add support to make sure we don't get alignment faults in copies. Warn if we go over an 8k page boundary. --HG-- extra : convert_revision : 98b38da86a66215d80ea9eb6e6f1f68ee573cb57
-rw-r--r--arch/alpha/isa_desc4
-rw-r--r--cpu/simple_cpu/simple_cpu.cc41
2 files changed, 36 insertions, 9 deletions
diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc
index d6b99a8ae..9d65a02f0 100644
--- a/arch/alpha/isa_desc
+++ b/arch/alpha/isa_desc
@@ -1842,7 +1842,7 @@ decode OPCODE default Unknown::unknown() {
0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED);
0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED);
0x20: copy_load({{EA = Ra;}},
- {{ fault = xc->copySrcTranslate(EA);}},
+ {{fault = xc->copySrcTranslate(EA);}},
IsMemRef, IsLoad, IsCopy);
}
@@ -1864,7 +1864,7 @@ decode OPCODE default Unknown::unknown() {
0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }});
0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }});
0x24: copy_store({{EA = Rb;}},
- {{ fault = xc->copy(EA);}},
+ {{fault = xc->copy(EA);}},
IsMemRef, IsStore, IsCopy);
}
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 449b20fee..18e660483 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -338,16 +338,29 @@ change_thread_state(int thread_number, int activate, int priority)
Fault
SimpleCPU::copySrcTranslate(Addr src)
{
- memReq->reset(src, (dcacheInterface) ?
- dcacheInterface->getBlockSize()
- : 64);
+ static bool no_warn = true;
+ int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
+ // Only support block sizes of 64 atm.
+ assert(blk_size == 64);
+ int offset = src & (blk_size - 1);
+
+ // Make sure block doesn't span page
+ if (no_warn && (src & (~8191)) == ((src + blk_size) & (~8191))) {
+ warn("Copied block source spans pages.");
+ no_warn = false;
+ }
+
+
+ memReq->reset(src & ~(blk_size - 1), blk_size);
// translate to physical address
Fault fault = xc->translateDataReadReq(memReq);
+ assert(fault != Alignment_Fault);
+
if (fault == No_Fault) {
xc->copySrcAddr = src;
- xc->copySrcPhysAddr = memReq->paddr;
+ xc->copySrcPhysAddr = memReq->paddr + offset;
} else {
xc->copySrcAddr = 0;
xc->copySrcPhysAddr = 0;
@@ -358,14 +371,28 @@ SimpleCPU::copySrcTranslate(Addr src)
Fault
SimpleCPU::copy(Addr dest)
{
+ static bool no_warn = true;
int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
+ // Only support block sizes of 64 atm.
+ assert(blk_size == 64);
uint8_t data[blk_size];
- assert(xc->copySrcAddr);
- memReq->reset(dest, blk_size);
+ //assert(xc->copySrcAddr);
+ int offset = dest & (blk_size - 1);
+
+ // Make sure block doesn't span page
+ if (no_warn && (dest & (~8191)) == ((dest + blk_size) & (~8191))) {
+ no_warn = false;
+ warn("Copied block destination spans pages. ");
+ }
+
+ memReq->reset(dest & ~(blk_size -1), blk_size);
// translate to physical address
Fault fault = xc->translateDataWriteReq(memReq);
+
+ assert(fault != Alignment_Fault);
+
if (fault == No_Fault) {
- Addr dest_addr = memReq->paddr;
+ Addr dest_addr = memReq->paddr + offset;
// Need to read straight from memory since we have more than 8 bytes.
memReq->paddr = xc->copySrcPhysAddr;
xc->mem->read(memReq, data);