Update copies to work around alignment faults.
authorErik Hallnor <ehallnor@umich.edu>
Tue, 21 Sep 2004 02:00:35 +0000 (22:00 -0400)
committerErik Hallnor <ehallnor@umich.edu>
Tue, 21 Sep 2004 02:00:35 +0000 (22:00 -0400)
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

arch/alpha/isa_desc
cpu/simple_cpu/simple_cpu.cc

index d6b99a8ae191ea5f8f6345318927a13bf81c9698..9d65a02f0e8a68876e76324ebc149e9a063212a4 100644 (file)
@@ -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);
     }
 
index 449b20feecccac2e1c8f5e60c7b8d31f67df73f8..18e6604835f6b31cbb0bbbaeea35225e1971910f 100644 (file)
@@ -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);