cpu-simple: Convert invalid access assertions to panic()

Currently, an access to an invalid address will cause GEM5 to exit with
a `!pkt.isError()` assertion failure. I was seeing this assertion while
running a baremetal RISC-V binary that faulted before the trap vector
had been configured and therefore tried to jump to address zero. With
this change we now print the invalid address and the type of access
(ifetch/load/store/amo) which makes debugging such a problem much easier.
For example, my faulting program now prints the following:
`panic: Instruction fetch ([0:0x4]) failed: BadAddressError [0:3] IF`
I also saw this assertion with a program that was dereferencing a NULL
pointer, which now prints a more helpful message:
`panic: Data fetch ([0x10:0x11]) failed: BadAddressError [10:10]`

Change-Id: Id983b74bf4688711f47308c6c7c15f49662ac495
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/55203
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Alex Richardson
2021-12-30 18:23:34 +00:00
parent a8c85b1c40
commit f4e84cd25e
2 changed files with 12 additions and 7 deletions

View File

@@ -406,7 +406,8 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t *data, unsigned size,
}
dcache_access = true;
assert(!pkt.isError());
panic_if(pkt.isError(), "Data fetch (%s) failed: %s",
pkt.getAddrRange().to_string(), pkt.print());
if (req->isLLSC()) {
thread->getIsaPtr()->handleLockedRead(req);
@@ -508,8 +509,8 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size, Addr addr,
threadSnoop(&pkt, curThread);
}
dcache_access = true;
assert(!pkt.isError());
panic_if(pkt.isError(), "Data write (%s) failed: %s",
pkt.getAddrRange().to_string(), pkt.print());
if (req->isSwap()) {
assert(res && curr_frag_id == 0);
memcpy(res, pkt.getConstPtr<uint8_t>(), size);
@@ -597,7 +598,8 @@ AtomicSimpleCPU::amoMem(Addr addr, uint8_t* data, unsigned size,
dcache_access = true;
assert(!pkt.isError());
panic_if(pkt.isError(), "Atomic access (%s) failed: %s",
pkt.getAddrRange().to_string(), pkt.print());
assert(!req->isLLSC());
}
@@ -752,7 +754,8 @@ AtomicSimpleCPU::fetchInstMem()
pkt.dataStatic(decoder->moreBytesPtr());
Tick latency = sendPacket(icachePort, &pkt);
assert(!pkt.isError());
panic_if(pkt.isError(), "Instruction fetch (%s) failed: %s",
pkt.getAddrRange().to_string(), pkt.print());
return latency;
}

View File

@@ -826,7 +826,8 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
// received a response from the icache: execute the received
// instruction
assert(!pkt || !pkt->isError());
panic_if(pkt && pkt->isError(), "Instruction fetch (%s) failed: %s",
pkt->getAddrRange().to_string(), pkt->print());
assert(_status == IcacheWaitResponse);
_status = BaseSimpleCPU::Running;
@@ -950,7 +951,8 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
// received a response from the dcache: complete the load or store
// instruction
assert(!pkt->isError());
panic_if(pkt->isError(), "Data access (%s) failed: %s",
pkt->getAddrRange().to_string(), pkt->print());
assert(_status == DcacheWaitResponse || _status == DTBWaitResponse ||
pkt->req->getFlags().isSet(Request::NO_ACCESS));