summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system/RubyPort.cc
diff options
context:
space:
mode:
authorBrad Beckmann <Brad.Beckmann@amd.com>2010-08-20 11:46:12 -0700
committerBrad Beckmann <Brad.Beckmann@amd.com>2010-08-20 11:46:12 -0700
commit8e5c441a54b481085d6311f14af66e41b5766f91 (patch)
tree8d0e6f8395685fb8a7fb2eda83e572301e687d1a /src/mem/ruby/system/RubyPort.cc
parent54d76f0ce5d721ad3b4de168db98054844e634cc (diff)
downloadgem5-8e5c441a54b481085d6311f14af66e41b5766f91.tar.xz
ruby: fix ruby llsc support to sync sc outcomes
Added support so that ruby can determine the outcome of store conditional operations and reflect that outcome to M5 physical memory and cpus.
Diffstat (limited to 'src/mem/ruby/system/RubyPort.cc')
-rw-r--r--src/mem/ruby/system/RubyPort.cc49
1 files changed, 33 insertions, 16 deletions
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 87a98185c..a8edb03b2 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -229,23 +229,10 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt)
// Submit the ruby request
RequestStatus requestStatus = ruby_port->makeRequest(ruby_request);
- // If the request successfully issued or the SC request completed because
- // exclusive permission was lost, then we should return true.
+ // If the request successfully issued then we should return true.
// Otherwise, we need to delete the senderStatus we just created and return
// false.
- if ((requestStatus == RequestStatus_Issued) ||
- (requestStatus == RequestStatus_LlscFailed)) {
-
- // The communicate to M5 whether the SC command succeeded by seting the
- // packet's extra data.
- if (pkt->isLLSC() && pkt->isWrite()) {
- if (requestStatus == RequestStatus_LlscFailed) {
- DPRINTF(MemoryAccess, "SC failed and request completed\n");
- pkt->req->setExtraData(0);
- } else {
- pkt->req->setExtraData(1);
- }
- }
+ if (requestStatus == RequestStatus_Issued) {
return true;
}
@@ -280,9 +267,39 @@ RubyPort::M5Port::hitCallback(PacketPtr pkt)
{
bool needsResponse = pkt->needsResponse();
+ //
+ // All responses except failed SC operations access M5 physical memory
+ //
+ bool accessPhysMem = true;
+
+ if (pkt->isLLSC()) {
+ if (pkt->isWrite()) {
+ if (pkt->req->getExtraData() != 0) {
+ //
+ // Successful SC packets convert to normal writes
+ //
+ pkt->convertScToWrite();
+ } else {
+ //
+ // Failed SC packets don't access physical memory and thus
+ // the RubyPort itself must convert it to a response.
+ //
+ accessPhysMem = false;
+ pkt->makeAtomicResponse();
+ }
+ } else {
+ //
+ // All LL packets convert to normal loads so that M5 PhysMem does
+ // not lock the blocks.
+ //
+ pkt->convertLlToRead();
+ }
+ }
DPRINTF(MemoryAccess, "Hit callback needs response %d\n", needsResponse);
- ruby_port->physMemPort->sendAtomic(pkt);
+ if (accessPhysMem) {
+ ruby_port->physMemPort->sendAtomic(pkt);
+ }
// turn packet around to go back to requester if response expected
if (needsResponse) {