systemc: sync the response error between gem5 packet and tlm payload
For now we don't return the correct error status to the upstream of the protocol conversion bridge. This prevents from the requestor to distinguish if the response is good or not. This change fixes the issue. Change-Id: Iec2a388b50fb1bd4fd97ece19e9061138b0b0a1f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64591 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Earl Ou <shunhsingou@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -194,6 +194,24 @@ packet2payload(PacketPtr packet)
|
||||
return trans;
|
||||
}
|
||||
|
||||
void
|
||||
setPacketResponse(PacketPtr pkt, tlm::tlm_generic_payload &trans)
|
||||
{
|
||||
pkt->makeResponse();
|
||||
|
||||
auto resp = trans.get_response_status();
|
||||
switch (resp) {
|
||||
case tlm::TLM_OK_RESPONSE:
|
||||
break;
|
||||
case tlm::TLM_COMMAND_ERROR_RESPONSE:
|
||||
pkt->setBadCommand();
|
||||
break;
|
||||
default:
|
||||
pkt->setBadAddress();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned int BITWIDTH>
|
||||
void
|
||||
Gem5ToTlmBridge<BITWIDTH>::pec(
|
||||
@@ -225,7 +243,7 @@ Gem5ToTlmBridge<BITWIDTH>::pec(
|
||||
// we make a response packet before sending it back to the initiator
|
||||
// side gem5 module.
|
||||
if (packet->needsResponse()) {
|
||||
packet->makeResponse();
|
||||
setPacketResponse(packet, trans);
|
||||
}
|
||||
if (packet->isResponse()) {
|
||||
need_retry = !bridgeResponsePort.sendTimingResp(packet);
|
||||
@@ -296,7 +314,7 @@ Gem5ToTlmBridge<BITWIDTH>::recvAtomic(PacketPtr packet)
|
||||
}
|
||||
|
||||
if (packet->needsResponse())
|
||||
packet->makeResponse();
|
||||
setPacketResponse(packet, *trans);
|
||||
|
||||
trans->release();
|
||||
|
||||
@@ -328,6 +346,7 @@ Gem5ToTlmBridge<BITWIDTH>::recvAtomicBackdoor(
|
||||
backdoor = getBackdoor(*trans);
|
||||
}
|
||||
|
||||
// Always set success response in Backdoor case.
|
||||
if (packet->needsResponse())
|
||||
packet->makeResponse();
|
||||
|
||||
|
||||
@@ -178,6 +178,18 @@ payload2packet(RequestorID _id, tlm::tlm_generic_payload &trans)
|
||||
return std::make_pair(pkt, true);
|
||||
}
|
||||
|
||||
void
|
||||
setPayloadResponse(tlm::tlm_generic_payload &trans, PacketPtr pkt)
|
||||
{
|
||||
if (!pkt->isError()) {
|
||||
trans.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
} else if (pkt->isRead() || pkt->isWrite()) {
|
||||
trans.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
|
||||
} else {
|
||||
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned int BITWIDTH>
|
||||
void
|
||||
TlmToGem5Bridge<BITWIDTH>::sendEndReq(tlm::tlm_generic_payload &trans)
|
||||
@@ -195,9 +207,15 @@ void
|
||||
TlmToGem5Bridge<BITWIDTH>::sendBeginResp(tlm::tlm_generic_payload &trans,
|
||||
sc_core::sc_time &delay)
|
||||
{
|
||||
tlm::tlm_phase phase = tlm::BEGIN_RESP;
|
||||
Gem5SystemC::Gem5Extension *extension = nullptr;
|
||||
trans.get_extension(extension);
|
||||
panic_if(extension == nullptr,
|
||||
"Missing gem5 extension when sending BEGIN_RESP");
|
||||
auto pkt = extension->getPacket();
|
||||
|
||||
trans.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
setPayloadResponse(trans, pkt);
|
||||
|
||||
tlm::tlm_phase phase = tlm::BEGIN_RESP;
|
||||
|
||||
auto status = socket->nb_transport_bw(trans, phase, delay);
|
||||
|
||||
@@ -252,8 +270,6 @@ TlmToGem5Bridge<BITWIDTH>::handleEndResp(tlm::tlm_generic_payload &trans)
|
||||
|
||||
responseInProgress = false;
|
||||
|
||||
checkTransaction(trans);
|
||||
|
||||
if (needToSendRetry) {
|
||||
bmp.sendRetryResp();
|
||||
needToSendRetry = false;
|
||||
@@ -267,18 +283,6 @@ TlmToGem5Bridge<BITWIDTH>::destroyPacket(PacketPtr pkt)
|
||||
delete pkt;
|
||||
}
|
||||
|
||||
template <unsigned int BITWIDTH>
|
||||
void
|
||||
TlmToGem5Bridge<BITWIDTH>::checkTransaction(tlm::tlm_generic_payload &trans)
|
||||
{
|
||||
if (trans.is_response_error()) {
|
||||
std::stringstream ss;
|
||||
ss << "Transaction returned with error, response status = "
|
||||
<< trans.get_response_string();
|
||||
SC_REPORT_ERROR("TLM-2", ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned int BITWIDTH>
|
||||
void
|
||||
TlmToGem5Bridge<BITWIDTH>::invalidateDmi(const gem5::MemBackdoor &backdoor)
|
||||
@@ -362,10 +366,10 @@ TlmToGem5Bridge<BITWIDTH>::b_transport(tlm::tlm_generic_payload &trans,
|
||||
// clean up
|
||||
delete senderState;
|
||||
|
||||
setPayloadResponse(trans, pkt);
|
||||
|
||||
if (pkt_created)
|
||||
destroyPacket(pkt);
|
||||
|
||||
trans.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
}
|
||||
|
||||
template <unsigned int BITWIDTH>
|
||||
@@ -437,11 +441,11 @@ TlmToGem5Bridge<BITWIDTH>::get_direct_mem_ptr(tlm::tlm_generic_payload &trans,
|
||||
// clean up
|
||||
delete senderState;
|
||||
|
||||
setPayloadResponse(trans, pkt);
|
||||
|
||||
if (pkt_created)
|
||||
destroyPacket(pkt);
|
||||
|
||||
trans.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
|
||||
return backdoor != nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,8 +141,6 @@ class TlmToGem5Bridge : public TlmToGem5BridgeBase
|
||||
|
||||
void destroyPacket(gem5::PacketPtr pkt);
|
||||
|
||||
void checkTransaction(tlm::tlm_generic_payload &trans);
|
||||
|
||||
void invalidateDmi(const gem5::MemBackdoor &backdoor);
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user