changeset 7d97cec15818 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=7d97cec15818
description:
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:
src/mem/packet.hh | 24 +++++++++++++
src/mem/protocol/RubySlicc_Exports.sm | 2 -
src/mem/ruby/system/CacheMemory.cc | 4 +-
src/mem/ruby/system/RubyPort.cc | 49 ++++++++++++++++++--------
src/mem/ruby/system/Sequencer.cc | 63 ++++++++++++++++++++++------------
src/mem/ruby/system/Sequencer.hh | 1 +
6 files changed, 101 insertions(+), 42 deletions(-)
diffs (241 lines):
diff -r 08dbd22d58a0 -r 7d97cec15818 src/mem/packet.hh
--- a/src/mem/packet.hh Fri Aug 20 11:46:12 2010 -0700
+++ b/src/mem/packet.hh Fri Aug 20 11:46:12 2010 -0700
@@ -463,6 +463,30 @@
Addr getOffset(int blkSize) const { return getAddr() & (Addr)(blkSize -
1); }
/**
+ * It has been determined that the SC packet should successfully update
+ * memory. Therefore, convert this SC packet to a normal write.
+ */
+ void
+ convertScToWrite()
+ {
+ assert(isLLSC());
+ assert(isWrite());
+ cmd = MemCmd::WriteReq;
+ }
+
+ /**
+ * When ruby is in use, Ruby will monitor the cache line and thus M5
+ * phys memory should treat LL ops as normal reads.
+ */
+ void
+ convertLlToRead()
+ {
+ assert(isLLSC());
+ assert(isRead());
+ cmd = MemCmd::ReadReq;
+ }
+
+ /**
* Constructor. Note that a Request object must be constructed
* first, but the Requests's physical address and size fields need
* not be valid. The command and destination addresses must be
diff -r 08dbd22d58a0 -r 7d97cec15818 src/mem/protocol/RubySlicc_Exports.sm
--- a/src/mem/protocol/RubySlicc_Exports.sm Fri Aug 20 11:46:12 2010 -0700
+++ b/src/mem/protocol/RubySlicc_Exports.sm Fri Aug 20 11:46:12 2010 -0700
@@ -53,7 +53,6 @@
Read_Write, desc="Read/Write";
Invalid, desc="Invalid";
NotPresent, desc="NotPresent";
- OnHold, desc="Holding a place in dnuca cache";
ReadUpgradingToWrite, desc="Read only, but trying to get Read/Write";
Stale, desc="local L1 has a modified copy, assume L2 copy is stale
data";
}
@@ -345,6 +344,5 @@
Issued, desc="The sequencer successfully issued the request";
BufferFull, desc="Can not issue because the sequencer is full";
Aliased, desc="This request aliased with a currently outstanding request";
- LlscFailed, desc="The write failed in the Load-Link Store-Conditional pair";
NULL, desc="";
}
diff -r 08dbd22d58a0 -r 7d97cec15818 src/mem/ruby/system/CacheMemory.cc
--- a/src/mem/ruby/system/CacheMemory.cc Fri Aug 20 11:46:12 2010 -0700
+++ b/src/mem/ruby/system/CacheMemory.cc Fri Aug 20 11:46:12 2010 -0700
@@ -353,7 +353,9 @@
lookup(address).m_Permission = new_perm;
Index cacheSet = addressToCacheSet(address);
int loc = findTagInSet(cacheSet, address);
- if (new_perm != AccessPermission_Read_Write) {
+ if ((new_perm == AccessPermission_Invalid) ||
+ (new_perm == AccessPermission_NotPresent) ||
+ (new_perm == AccessPermission_Stale)) {
DPRINTF(RubyCache, "Permission clearing lock for addr: %x\n", address);
m_locked[cacheSet][loc] = -1;
}
diff -r 08dbd22d58a0 -r 7d97cec15818 src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc Fri Aug 20 11:46:12 2010 -0700
+++ b/src/mem/ruby/system/RubyPort.cc Fri Aug 20 11:46:12 2010 -0700
@@ -229,23 +229,10 @@
// 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 @@
{
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) {
diff -r 08dbd22d58a0 -r 7d97cec15818 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc Fri Aug 20 11:46:12 2010 -0700
+++ b/src/mem/ruby/system/Sequencer.cc Fri Aug 20 11:46:12 2010 -0700
@@ -41,6 +41,7 @@
#include "mem/ruby/system/CacheMemory.hh"
#include "mem/ruby/system/Sequencer.hh"
#include "mem/ruby/system/System.hh"
+#include "mem/packet.hh"
#include "params/RubySequencer.hh"
using namespace std;
@@ -303,6 +304,38 @@
}
void
+Sequencer::handleLlscWrites(const Address& address, SequencerRequest* request)
+{
+ if (request->ruby_request.type == RubyRequestType_Locked_Write) {
+ if (!m_dataCache_ptr->isLocked(address, m_version)) {
+ //
+ // For failed SC requests, indicate the failure to the cpu by
+ // setting the extra data to zero.
+ //
+ request->ruby_request.pkt->req->setExtraData(0);
+ } else {
+ //
+ // For successful SC requests, indicate the success to the cpu by
+ // setting the extra data to one.
+ //
+ request->ruby_request.pkt->req->setExtraData(1);
+ }
+ m_dataCache_ptr->clearLocked(address);
+ } else if (request->ruby_request.type == RubyRequestType_Locked_Read) {
+ //
+ // Note: To fully follow Alpha LLSC semantics, should the LL clear any
+ // previously locked cache lines?
+ //
+ m_dataCache_ptr->setLocked(address, m_version);
+ } else if (m_dataCache_ptr->isLocked(address, m_version)) {
+ //
+ // Normal writes should clear the locked address
+ //
+ m_dataCache_ptr->clearLocked(address);
+ }
+}
+
+void
Sequencer::writeCallback(const Address& address, DataBlock& data)
{
writeCallback(address, GenericMachineType_NULL, data);
@@ -329,9 +362,13 @@
(request->ruby_request.type == RubyRequestType_Locked_Read) ||
(request->ruby_request.type == RubyRequestType_Locked_Write));
- if (request->ruby_request.type == RubyRequestType_Locked_Read) {
- m_dataCache_ptr->setLocked(address, m_version);
- } else if (request->ruby_request.type == RubyRequestType_RMW_Read) {
+ //
+ // For Alpha, properly handle LL, SC, and write requests with respect to
+ // locked cache blocks.
+ //
+ handleLlscWrites(address, request);
+
+ if (request->ruby_request.type == RubyRequestType_RMW_Read) {
m_controller->blockOnQueue(address, m_mandatory_q_ptr);
} else if (request->ruby_request.type == RubyRequestType_RMW_Write) {
m_controller->unblock(address);
@@ -504,26 +541,6 @@
return RequestStatus_NULL;
}
- if (request.type == RubyRequestType_Locked_Write) {
- // NOTE: it is OK to check the locked flag here as the
- // mandatory queue will be checked first ensuring that nothing
- // comes between checking the flag and servicing the store.
-
- Address line_addr = line_address(Address(request.paddr));
- if (!m_dataCache_ptr->isLocked(line_addr, m_version)) {
- removeRequest(srequest);
- if (Debug::getProtocolTrace()) {
- g_system_ptr->getProfiler()->
- profileTransition("Seq", m_version,
- Address(request.paddr),
- "", "SC Fail", "",
- RubyRequestType_to_string(request.type));
- }
- return RequestStatus_LlscFailed;
- } else {
- m_dataCache_ptr->clearLocked(line_addr);
- }
- }
issueRequest(request);
// TODO: issue hardware prefetches here
diff -r 08dbd22d58a0 -r 7d97cec15818 src/mem/ruby/system/Sequencer.hh
--- a/src/mem/ruby/system/Sequencer.hh Fri Aug 20 11:46:12 2010 -0700
+++ b/src/mem/ruby/system/Sequencer.hh Fri Aug 20 11:46:12 2010 -0700
@@ -109,6 +109,7 @@
bool insertRequest(SequencerRequest* request);
+ void handleLlscWrites(const Address& address, SequencerRequest* request);
// Private copy constructor and assignment operator
Sequencer(const Sequencer& obj);
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev