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
This commit is contained in:
parent
bb59e2e7a3
commit
15d08a3422
2 changed files with 36 additions and 9 deletions
|
@ -1842,7 +1842,7 @@ decode OPCODE default Unknown::unknown() {
|
||||||
0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED);
|
0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED);
|
||||||
0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED);
|
0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED);
|
||||||
0x20: copy_load({{EA = Ra;}},
|
0x20: copy_load({{EA = Ra;}},
|
||||||
{{ fault = xc->copySrcTranslate(EA);}},
|
{{fault = xc->copySrcTranslate(EA);}},
|
||||||
IsMemRef, IsLoad, IsCopy);
|
IsMemRef, IsLoad, IsCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1864,7 +1864,7 @@ decode OPCODE default Unknown::unknown() {
|
||||||
0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }});
|
0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }});
|
||||||
0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }});
|
0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }});
|
||||||
0x24: copy_store({{EA = Rb;}},
|
0x24: copy_store({{EA = Rb;}},
|
||||||
{{ fault = xc->copy(EA);}},
|
{{fault = xc->copy(EA);}},
|
||||||
IsMemRef, IsStore, IsCopy);
|
IsMemRef, IsStore, IsCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,16 +338,29 @@ change_thread_state(int thread_number, int activate, int priority)
|
||||||
Fault
|
Fault
|
||||||
SimpleCPU::copySrcTranslate(Addr src)
|
SimpleCPU::copySrcTranslate(Addr src)
|
||||||
{
|
{
|
||||||
memReq->reset(src, (dcacheInterface) ?
|
static bool no_warn = true;
|
||||||
dcacheInterface->getBlockSize()
|
int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
|
||||||
: 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
|
// translate to physical address
|
||||||
Fault fault = xc->translateDataReadReq(memReq);
|
Fault fault = xc->translateDataReadReq(memReq);
|
||||||
|
|
||||||
|
assert(fault != Alignment_Fault);
|
||||||
|
|
||||||
if (fault == No_Fault) {
|
if (fault == No_Fault) {
|
||||||
xc->copySrcAddr = src;
|
xc->copySrcAddr = src;
|
||||||
xc->copySrcPhysAddr = memReq->paddr;
|
xc->copySrcPhysAddr = memReq->paddr + offset;
|
||||||
} else {
|
} else {
|
||||||
xc->copySrcAddr = 0;
|
xc->copySrcAddr = 0;
|
||||||
xc->copySrcPhysAddr = 0;
|
xc->copySrcPhysAddr = 0;
|
||||||
|
@ -358,14 +371,28 @@ SimpleCPU::copySrcTranslate(Addr src)
|
||||||
Fault
|
Fault
|
||||||
SimpleCPU::copy(Addr dest)
|
SimpleCPU::copy(Addr dest)
|
||||||
{
|
{
|
||||||
|
static bool no_warn = true;
|
||||||
int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
|
int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
|
||||||
|
// Only support block sizes of 64 atm.
|
||||||
|
assert(blk_size == 64);
|
||||||
uint8_t data[blk_size];
|
uint8_t data[blk_size];
|
||||||
assert(xc->copySrcAddr);
|
//assert(xc->copySrcAddr);
|
||||||
memReq->reset(dest, blk_size);
|
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
|
// translate to physical address
|
||||||
Fault fault = xc->translateDataWriteReq(memReq);
|
Fault fault = xc->translateDataWriteReq(memReq);
|
||||||
|
|
||||||
|
assert(fault != Alignment_Fault);
|
||||||
|
|
||||||
if (fault == No_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.
|
// Need to read straight from memory since we have more than 8 bytes.
|
||||||
memReq->paddr = xc->copySrcPhysAddr;
|
memReq->paddr = xc->copySrcPhysAddr;
|
||||||
xc->mem->read(memReq, data);
|
xc->mem->read(memReq, data);
|
||||||
|
|
Loading…
Reference in a new issue