summaryrefslogtreecommitdiff
path: root/src/mem/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/protocol')
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L1cache.sm5
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L2cache.sm5
-rw-r--r--src/mem/protocol/MESI_CMP_directory-dir.sm7
-rw-r--r--src/mem/protocol/MESI_CMP_directory-msg.sm53
-rw-r--r--src/mem/protocol/MI_example-cache.sm5
-rw-r--r--src/mem/protocol/MI_example-dir.sm13
-rw-r--r--src/mem/protocol/MI_example-msg.sm44
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L1cache.sm12
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L2cache.sm14
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-dir.sm3
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-msg.sm40
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L1cache.sm2
-rw-r--r--src/mem/protocol/MOESI_CMP_token-dir.sm1
-rw-r--r--src/mem/protocol/MOESI_CMP_token-msg.sm47
-rw-r--r--src/mem/protocol/MOESI_hammer-cache.sm13
-rw-r--r--src/mem/protocol/MOESI_hammer-dir.sm27
-rw-r--r--src/mem/protocol/MOESI_hammer-msg.sm57
-rw-r--r--src/mem/protocol/Network_test-msg.sm4
-rw-r--r--src/mem/protocol/RubySlicc_Exports.sm21
-rw-r--r--src/mem/protocol/RubySlicc_MemControl.sm8
20 files changed, 335 insertions, 46 deletions
diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
index d54f7e71c..eb8e62d30 100644
--- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
@@ -201,6 +201,11 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ TBE tbe := L1_TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
return getCacheEntry(addr).DataBlk;
}
diff --git a/src/mem/protocol/MESI_CMP_directory-L2cache.sm b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
index 88053aeb8..fbdc10ac2 100644
--- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
@@ -232,6 +232,11 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ TBE tbe := L2_TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
return getCacheEntry(addr).DataBlk;
}
diff --git a/src/mem/protocol/MESI_CMP_directory-dir.sm b/src/mem/protocol/MESI_CMP_directory-dir.sm
index 7e1280337..d98326b34 100644
--- a/src/mem/protocol/MESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MESI_CMP_directory-dir.sm
@@ -110,7 +110,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
void set_tbe(TBE tbe);
void unset_tbe();
void wakeUpBuffers(Address a);
-
+
Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
@@ -170,6 +170,11 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ TBE tbe := TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
return getDirectoryEntry(addr).DataBlk;
}
diff --git a/src/mem/protocol/MESI_CMP_directory-msg.sm b/src/mem/protocol/MESI_CMP_directory-msg.sm
index 67619f075..473012c61 100644
--- a/src/mem/protocol/MESI_CMP_directory-msg.sm
+++ b/src/mem/protocol/MESI_CMP_directory-msg.sm
@@ -35,11 +35,9 @@ enumeration(CoherenceRequestType, desc="...") {
GETS, desc="Get Shared";
GET_INSTR, desc="Get Instruction";
INV, desc="INValidate";
- PUTX, desc="replacement message";
+ PUTX, desc="Replacement message";
WB_ACK, desc="Writeback ack";
- WB_NACK, desc="Writeback neg. ack";
- FWD, desc="Generic FWD";
DMA_READ, desc="DMA Read";
DMA_WRITE, desc="DMA Write";
@@ -47,14 +45,14 @@ enumeration(CoherenceRequestType, desc="...") {
// CoherenceResponseType
enumeration(CoherenceResponseType, desc="...") {
- MEMORY_ACK, desc="Ack from memory controller";
- DATA, desc="Data";
- DATA_EXCLUSIVE, desc="Data";
- MEMORY_DATA, desc="Data";
- ACK, desc="Generic invalidate ack";
- WB_ACK, desc="writeback ack";
- UNBLOCK, desc="unblock";
- EXCLUSIVE_UNBLOCK, desc="exclusive unblock";
+ MEMORY_ACK, desc="Ack from memory controller";
+ DATA, desc="Data block for L1 cache in S state";
+ DATA_EXCLUSIVE, desc="Data block for L1 cache in M/E state";
+ MEMORY_DATA, desc="Data block from / to main memory";
+ ACK, desc="Generic invalidate ack";
+ WB_ACK, desc="writeback ack";
+ UNBLOCK, desc="unblock";
+ EXCLUSIVE_UNBLOCK, desc="exclusive unblock";
INV, desc="Invalidate from directory";
}
@@ -70,6 +68,21 @@ structure(RequestMsg, desc="...", interface="NetworkMessage") {
int Len;
bool Dirty, default="false", desc="Dirty bit";
PrefetchBit Prefetch, desc="Is this a prefetch request";
+
+ bool functionalRead(Packet *pkt) {
+ // Only PUTX messages contains the data block
+ if (Type == CoherenceRequestType:PUTX) {
+ return testAndRead(Address, DataBlk, pkt);
+ }
+
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No check on message type required since the protocol should
+ // read data from those messages that contain the block
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
// ResponseMsg
@@ -82,4 +95,22 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") {
bool Dirty, default="false", desc="Dirty bit";
int AckCount, default="0", desc="number of acks in this message";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ // Valid data block is only present in message with following types
+ if (Type == CoherenceResponseType:DATA ||
+ Type == CoherenceResponseType:DATA_EXCLUSIVE ||
+ Type == CoherenceResponseType:MEMORY_DATA) {
+
+ return testAndRead(Address, DataBlk, pkt);
+ }
+
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No check on message type required since the protocol should
+ // read data from those messages that contain the block
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm
index cf5cf9505..5040eb85d 100644
--- a/src/mem/protocol/MI_example-cache.sm
+++ b/src/mem/protocol/MI_example-cache.sm
@@ -168,6 +168,11 @@ machine(L1Cache, "MI Example L1 Cache")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ TBE tbe := TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
return getCacheEntry(addr).DataBlk;
}
diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm
index 241ad3b30..f15ccb14e 100644
--- a/src/mem/protocol/MI_example-dir.sm
+++ b/src/mem/protocol/MI_example-dir.sm
@@ -172,6 +172,11 @@ machine(Directory, "Directory protocol")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ TBE tbe := TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
return getDirectoryEntry(addr).DataBlk;
}
@@ -506,7 +511,6 @@ machine(Directory, "Directory protocol")
out_msg.OriginalRequestorMachId := in_msg.Requestor;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.MessageSize := in_msg.MessageSize;
- //out_msg.Prefetch := in_msg.Prefetch;
DPRINTF(RubySlicc,"%s\n", out_msg);
}
@@ -518,12 +522,8 @@ machine(Directory, "Directory protocol")
}
action(w_writeDataToMemoryFromTBE, "\w", desc="Write date to directory memory from TBE") {
- //getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk;
assert(is_valid(tbe));
- getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk,
- addressOffset(tbe.PhysicalAddress),
- tbe.Len);
-
+ getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk;
}
// TRANSITIONS
@@ -633,7 +633,6 @@ machine(Directory, "Directory protocol")
}
transition(M, PUTX, MI) {
- l_writeDataToMemory;
c_clearOwner;
v_allocateTBEFromRequestNet;
l_queueMemoryWBRequest;
diff --git a/src/mem/protocol/MI_example-msg.sm b/src/mem/protocol/MI_example-msg.sm
index 2fb1c48ba..0645371f6 100644
--- a/src/mem/protocol/MI_example-msg.sm
+++ b/src/mem/protocol/MI_example-msg.sm
@@ -31,11 +31,9 @@ enumeration(CoherenceRequestType, desc="...") {
GETX, desc="Get eXclusive";
GETS, desc="Get Shared";
PUTX, desc="Put eXclusive";
- PUTO, desc="Put Owned";
WB_ACK, desc="Writeback ack";
WB_NACK, desc="Writeback neg. ack";
INV, desc="Invalidation";
- FWD, desc="Generic FWD";
}
// CoherenceResponseType
@@ -59,6 +57,20 @@ structure(RequestMsg, desc="...", interface="NetworkMessage") {
NetDest Destination, desc="Multicast destination mask";
DataBlock DataBlk, desc="data for the cache line";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ // Valid data block is only present in PUTX messages
+ if (Type == CoherenceRequestType:PUTX) {
+ return testAndRead(Address, DataBlk, pkt);
+ }
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No check on message type required since the protocol should read
+ // data block from only those messages that contain valid data
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
// ResponseMsg (and also unblock requests)
@@ -70,6 +82,18 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") {
DataBlock DataBlk, desc="data for the cache line";
bool Dirty, desc="Is the data dirty (different than memory)?";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ // A check on message type should appear here so that only those
+ // messages that contain data
+ return testAndRead(Address, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No check on message type required since the protocol should read
+ // data block from only those messages that contain valid data
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") {
@@ -93,6 +117,14 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
DataBlock DataBlk, desc="DataBlk attached to this request";
int Len, desc="The length of the request";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ return testAndRead(LineAddress, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(LineAddress, DataBlk, pkt);
+ }
}
structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
@@ -102,4 +134,12 @@ structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
NetDest Destination, desc="Destination";
DataBlock DataBlk, desc="DataBlk attached to this request";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ return testAndRead(LineAddress, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(LineAddress, DataBlk, pkt);
+ }
}
diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
index 43c2def2e..6295f90fd 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
@@ -219,7 +219,17 @@ machine(L1Cache, "Directory protocol")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
- return getCacheEntry(addr).DataBlk;
+ Entry cache_entry := getCacheEntry(addr);
+ if(is_valid(cache_entry)) {
+ return cache_entry.DataBlk;
+ }
+
+ TBE tbe := TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
+ error("Data block missing!");
}
Event mandatory_request_type_to_event(RubyRequestType type) {
diff --git a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
index 6238953ad..2e4e66a7b 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
@@ -193,7 +193,7 @@ machine(L2Cache, "Token protocol")
// TBE fields
structure(TBE, desc="...") {
- Address Address, desc="Physical address for this TBE";
+ Address address, desc="Physical address for this TBE";
State TBEState, desc="Transient state";
Address PC, desc="Program counter of request";
DataBlock DataBlk, desc="Buffer for the data block";
@@ -512,11 +512,6 @@ machine(L2Cache, "Token protocol")
return L2Cache_State_to_permission(cache_entry.CacheState);
}
- else if (localDirectory.isTagPresent(addr)) {
- DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(localDirectory[addr].DirState));
- return L2Cache_State_to_permission(localDirectory[addr].DirState);
- }
-
DPRINTF(RubySlicc, "AccessPermission_NotPresent\n");
return AccessPermission:NotPresent;
}
@@ -528,6 +523,11 @@ machine(L2Cache, "Token protocol")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ TBE tbe := TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
return getCacheEntry(addr).DataBlk;
}
@@ -1451,6 +1451,8 @@ machine(L2Cache, "Token protocol")
peek(responseNetwork_in, ResponseMsg) {
assert(is_valid(cache_entry));
cache_entry.DataBlk := in_msg.DataBlk;
+ DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
+ address, cache_entry.DataBlk);
if ((cache_entry.Dirty == false) && in_msg.Dirty) {
cache_entry.Dirty := in_msg.Dirty;
}
diff --git a/src/mem/protocol/MOESI_CMP_directory-dir.sm b/src/mem/protocol/MOESI_CMP_directory-dir.sm
index 1635267f6..0dd4239a9 100644
--- a/src/mem/protocol/MOESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm
@@ -473,6 +473,9 @@ machine(Directory, "Directory protocol")
// implementation. We include the data in the "dataless"
// message so we can assert the clean data matches the datablock
// in memory
+ DPRINTF(RubySlicc, "Address: %s, MsgDataBlock: %s MemoryDataBlock: %s\n",
+ in_msg.Address, in_msg.DataBlk,
+ getDirectoryEntry(in_msg.Address).DataBlk);
assert(getDirectoryEntry(in_msg.Address).DataBlk == in_msg.DataBlk);
}
}
diff --git a/src/mem/protocol/MOESI_CMP_directory-msg.sm b/src/mem/protocol/MOESI_CMP_directory-msg.sm
index 7b203537f..e428be7f7 100644
--- a/src/mem/protocol/MOESI_CMP_directory-msg.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-msg.sm
@@ -71,6 +71,16 @@ enumeration(TriggerType, desc="...") {
structure(TriggerMsg, desc="...", interface="Message") {
Address Address, desc="Physical address for this request";
TriggerType Type, desc="Type of trigger";
+
+ bool functionalRead(Packet *pkt) {
+ // Trigger message does not hold data
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // Trigger message does not hold data
+ return false;
+ }
}
// RequestMsg (and also forwarded requests)
@@ -86,6 +96,20 @@ structure(RequestMsg, desc="...", interface="NetworkMessage") {
MessageSizeType MessageSize, desc="size category of the message";
RubyAccessMode AccessMode, desc="user/supervisor access type";
PrefetchBit Prefetch, desc="Is this a prefetch request";
+
+ bool functionalRead(Packet *pkt) {
+ // Read only those messages that contain the data
+ if (Type == CoherenceRequestType:DMA_READ ||
+ Type == CoherenceRequestType:DMA_WRITE) {
+ return testAndRead(Address, DataBlk, pkt);
+ }
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No check required since all messages are written
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
// ResponseMsg (and also unblock requests)
@@ -99,4 +123,20 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") {
bool Dirty, desc="Is the data dirty (different than memory)?";
int Acks, desc="How many acks to expect";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ // Read only those messages that contain the data
+ if (Type == CoherenceResponseType:DATA ||
+ Type == CoherenceResponseType:DATA_EXCLUSIVE ||
+ Type == CoherenceResponseType:WRITEBACK_CLEAN_DATA ||
+ Type == CoherenceResponseType:WRITEBACK_DIRTY_DATA) {
+ return testAndRead(Address, DataBlk, pkt);
+ }
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No check required since all messages are written
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
index b6de5a714..8cf40974e 100644
--- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
@@ -139,7 +139,7 @@ machine(L1Cache, "Token protocol")
// TBE fields
structure(TBE, desc="...") {
- Address Address, desc="Physical address for this TBE";
+ Address address, desc="Physical address for this TBE";
State TBEState, desc="Transient state";
int IssueCount, default="0", desc="The number of times we've issued a request for this line.";
Address PC, desc="Program counter of request";
diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm
index 8d78be40c..fd51e2924 100644
--- a/src/mem/protocol/MOESI_CMP_token-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_token-dir.sm
@@ -677,6 +677,7 @@ machine(Directory, "Token protocol")
enqueue(memQueue_out, MemoryMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
+ out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
DPRINTF(RubySlicc, "%s\n", out_msg);
}
}
diff --git a/src/mem/protocol/MOESI_CMP_token-msg.sm b/src/mem/protocol/MOESI_CMP_token-msg.sm
index b1c3f4580..6a8d6c6bc 100644
--- a/src/mem/protocol/MOESI_CMP_token-msg.sm
+++ b/src/mem/protocol/MOESI_CMP_token-msg.sm
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
* All rights reserved.
@@ -66,6 +65,16 @@ structure(PersistentMsg, desc="...", interface="NetworkMessage") {
MessageSizeType MessageSize, desc="size category of the message";
RubyAccessMode AccessMode, desc="user/supervisor access type";
PrefetchBit Prefetch, desc="Is this a prefetch request";
+
+ bool functionalRead(Packet *pkt) {
+ // No data in persistent messages
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No data in persistent messages
+ return false;
+ }
}
// RequestMsg
@@ -79,6 +88,16 @@ structure(RequestMsg, desc="...", interface="NetworkMessage") {
MessageSizeType MessageSize, desc="size category of the message";
RubyAccessMode AccessMode, desc="user/supervisor access type";
PrefetchBit Prefetch, desc="Is this a prefetch request";
+
+ bool functionalRead(Packet *pkt) {
+ // No data in request messages
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No data in request messages
+ return false;
+ }
}
// ResponseMsg
@@ -91,6 +110,16 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") {
DataBlock DataBlk, desc="data for the cache line";
bool Dirty, desc="Is the data dirty (different than memory)?";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ // No check being carried out on the message type. Would be added later.
+ return testAndRead(Address, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // No check required since all messages are written.
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") {
@@ -114,6 +143,14 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
DataBlock DataBlk, desc="DataBlk attached to this request";
int Len, desc="The length of the request";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(LineAddress, DataBlk, pkt);
+ }
}
structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
@@ -123,4 +160,12 @@ structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
NetDest Destination, desc="Destination";
DataBlock DataBlk, desc="DataBlk attached to this request";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(LineAddress, DataBlk, pkt);
+ }
}
diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm
index 6eb0974b0..a3fa1219f 100644
--- a/src/mem/protocol/MOESI_hammer-cache.sm
+++ b/src/mem/protocol/MOESI_hammer-cache.sm
@@ -198,7 +198,17 @@ machine(L1Cache, "AMD Hammer-like protocol")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
- return getCacheEntry(addr).DataBlk;
+ Entry cache_entry := getCacheEntry(addr);
+ if(is_valid(cache_entry)) {
+ return cache_entry.DataBlk;
+ }
+
+ TBE tbe := TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
+ error("Missing data block");
}
Entry getL2CacheEntry(Address address), return_by_pointer="yes" {
@@ -879,6 +889,7 @@ machine(L1Cache, "AMD Hammer-like protocol")
tbe.ForwardRequestTime,
tbe.FirstResponseTime);
}
+ DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
cache_entry.Dirty := true;
}
diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm
index ed1fb7669..22ca568a8 100644
--- a/src/mem/protocol/MOESI_hammer-dir.sm
+++ b/src/mem/protocol/MOESI_hammer-dir.sm
@@ -87,7 +87,7 @@ machine(Directory, "AMD Hammer-like protocol")
O_DR_B, AccessPermission:Busy, desc="Owner, Dma Read waiting for cache responses";
WB, AccessPermission:Busy, desc="Blocked on a writeback";
WB_O_W, AccessPermission:Busy, desc="Blocked on memory write, will go to O";
- WB_E_W, AccessPermission:Read_Write, desc="Blocked on memory write, will go to E";
+ WB_E_W, AccessPermission:Busy, desc="Blocked on memory write, will go to E";
NO_F, AccessPermission:Busy, desc="Blocked on a flush";
NO_F_W, AccessPermission:Busy, desc="Not Owner, Blocked, waiting for Dram";
@@ -199,7 +199,17 @@ machine(Directory, "AMD Hammer-like protocol")
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {
- return getDirectoryEntry(addr).DataBlk;
+ Entry dir_entry := getDirectoryEntry(addr);
+ if(is_valid(dir_entry)) {
+ return dir_entry.DataBlk;
+ }
+
+ TBE tbe := TBEs[addr];
+ if(is_valid(tbe)) {
+ return tbe.DataBlk;
+ }
+
+ error("Data block missing!");
}
PfEntry getProbeFilterEntry(Address addr), return_by_pointer="yes" {
@@ -222,7 +232,7 @@ machine(Directory, "AMD Hammer-like protocol")
return getDirectoryEntry(addr).DirectoryState;
}
}
-
+
void setState(TBE tbe, PfEntry pf_entry, Address addr, State state) {
if (is_valid(tbe)) {
tbe.TBEState := state;
@@ -1168,9 +1178,7 @@ machine(Directory, "AMD Hammer-like protocol")
}
action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") {
- peek(unblockNetwork_in, ResponseMsg) {
- assert(in_msg.Dirty);
- assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
+ peek(memQueue_in, MemoryMsg) {
getDirectoryEntry(address).DataBlk := in_msg.DataBlk;
DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
in_msg.Address, in_msg.DataBlk);
@@ -1236,8 +1244,11 @@ machine(Directory, "AMD Hammer-like protocol")
action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
peek(unblockNetwork_in, ResponseMsg) {
enqueue(memQueue_out, MemoryMsg, latency="1") {
+ assert(in_msg.Dirty);
+ assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
out_msg.Address := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
+ out_msg.DataBlk := in_msg.DataBlk;
DPRINTF(RubySlicc, "%s\n", out_msg);
}
}
@@ -1854,26 +1865,26 @@ machine(Directory, "AMD Hammer-like protocol")
// WB State Transistions
transition(WB, Writeback_Dirty, WB_O_W) {
- l_writeDataToMemory;
rs_removeSharer;
l_queueMemoryWBRequest;
j_popIncomingUnblockQueue;
}
transition(WB, Writeback_Exclusive_Dirty, WB_E_W) {
- l_writeDataToMemory;
rs_removeSharer;
l_queueMemoryWBRequest;
j_popIncomingUnblockQueue;
}
transition(WB_E_W, Memory_Ack, E) {
+ l_writeDataToMemory;
pfd_probeFilterDeallocate;
k_wakeUpDependents;
l_popMemQueue;
}
transition(WB_O_W, Memory_Ack, O) {
+ l_writeDataToMemory;
k_wakeUpDependents;
l_popMemQueue;
}
diff --git a/src/mem/protocol/MOESI_hammer-msg.sm b/src/mem/protocol/MOESI_hammer-msg.sm
index 6ead7200a..41d176a9c 100644
--- a/src/mem/protocol/MOESI_hammer-msg.sm
+++ b/src/mem/protocol/MOESI_hammer-msg.sm
@@ -73,6 +73,16 @@ enumeration(TriggerType, desc="...") {
structure(TriggerMsg, desc="...", interface="Message") {
Address Address, desc="Physical address for this request";
TriggerType Type, desc="Type of trigger";
+
+ bool functionalRead(Packet *pkt) {
+ // Trigger messages do not hold any data!
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // Trigger messages do not hold any data!
+ return false;
+ }
}
// RequestMsg (and also forwarded requests)
@@ -87,6 +97,16 @@ structure(RequestMsg, desc="...", interface="NetworkMessage") {
Time InitialRequestTime, default="0", desc="time the initial requests was sent from the L1Cache";
Time ForwardRequestTime, default="0", desc="time the dir forwarded the request";
int SilentAcks, default="0", desc="silent acks from the full-bit directory";
+
+ bool functionalRead(Packet *pkt) {
+ // Request messages do not hold any data
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // Request messages do not hold any data
+ return false;
+ }
}
// ResponseMsg (and also unblock requests)
@@ -103,6 +123,27 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") {
Time InitialRequestTime, default="0", desc="time the initial requests was sent from the L1Cache";
Time ForwardRequestTime, default="0", desc="time the dir forwarded the request";
int SilentAcks, default="0", desc="silent acks from the full-bit directory";
+
+ bool functionalRead(Packet *pkt) {
+ // The check below ensures that data is read only from messages that
+ // actually hold data.
+ if (Type == CoherenceResponseType:DATA ||
+ Type == CoherenceResponseType:DATA_SHARED ||
+ Type == CoherenceResponseType:DATA_EXCLUSIVE ||
+ Type == CoherenceResponseType:WB_DIRTY ||
+ Type == CoherenceResponseType:WB_EXCLUSIVE_DIRTY) {
+ return testAndRead(Address, DataBlk, pkt);
+ }
+
+ return false;
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ // Message type does not matter since all messages are written.
+ // If a protocol reads data from a packet that is not supposed
+ // to hold the data, then the fault lies with the protocol.
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}
enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") {
@@ -126,6 +167,14 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
DataBlock DataBlk, desc="DataBlk attached to this request";
int Len, desc="The length of the request";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ return testAndRead(LineAddress, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(LineAddress, DataBlk, pkt);
+ }
}
structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
@@ -135,4 +184,12 @@ structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
NetDest Destination, desc="Destination";
DataBlock DataBlk, desc="DataBlk attached to this request";
MessageSizeType MessageSize, desc="size category of the message";
+
+ bool functionalRead(Packet *pkt) {
+ return testAndRead(LineAddress, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(LineAddress, DataBlk, pkt);
+ }
}
diff --git a/src/mem/protocol/Network_test-msg.sm b/src/mem/protocol/Network_test-msg.sm
index 6492024d8..9e21d39bb 100644
--- a/src/mem/protocol/Network_test-msg.sm
+++ b/src/mem/protocol/Network_test-msg.sm
@@ -40,4 +40,8 @@ structure(RequestMsg, desc="...", interface="NetworkMessage") {
NetDest Destination, desc="Multicast destination mask";
DataBlock DataBlk, desc="data for the cache line";
MessageSizeType MessageSize, desc="size category of the message";
+
+ void functionalWrite(Packet *pkt) {
+ error("Network test does not support functional accesses!");
+ }
}
diff --git a/src/mem/protocol/RubySlicc_Exports.sm b/src/mem/protocol/RubySlicc_Exports.sm
index b42f9c3a9..2a4281757 100644
--- a/src/mem/protocol/RubySlicc_Exports.sm
+++ b/src/mem/protocol/RubySlicc_Exports.sm
@@ -27,24 +27,23 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Id$
- *
- */
-
-// defines
+// Declarations of external types that are common to all protocols
external_type(int, primitive="yes", default="0");
external_type(bool, primitive="yes", default="false");
external_type(std::string, primitive="yes");
external_type(uint64, primitive="yes");
external_type(Time, primitive="yes", default="0");
+external_type(PacketPtr, primitive="yes");
+external_type(Packet, primitive="yes");
external_type(Address);
+
structure(DataBlock, external = "yes", desc="..."){
void clear();
void copyPartial(DataBlock, int, int);
}
-// Declarations of external types that are common to all protocols
+bool testAndRead(Address addr, DataBlock datablk, Packet *pkt);
+bool testAndWrite(Address addr, DataBlock datablk, Packet *pkt);
// AccessPermission
// The following five states define the access permission of all memory blocks.
@@ -265,6 +264,14 @@ structure(SequencerMsg, desc="...", interface="Message") {
DataBlock DataBlk, desc="Data";
int Len, desc="size in bytes of access";
PrefetchBit Prefetch, desc="Is this a prefetch request";
+
+ bool functionalRead(Packet *pkt) {
+ return testAndRead(PhysicalAddress, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(PhysicalAddress, DataBlk, pkt);
+ }
}
// MaskPredictorType
diff --git a/src/mem/protocol/RubySlicc_MemControl.sm b/src/mem/protocol/RubySlicc_MemControl.sm
index 66bb37bca..08bff6e36 100644
--- a/src/mem/protocol/RubySlicc_MemControl.sm
+++ b/src/mem/protocol/RubySlicc_MemControl.sm
@@ -61,4 +61,12 @@ structure(MemoryMsg, desc="...", interface="Message") {
PrefetchBit Prefetch, desc="Is this a prefetch request";
bool ReadX, desc="Exclusive";
int Acks, desc="How many acks to expect";
+
+ bool functionalRead(Packet *pkt) {
+ return testAndRead(Address, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(Address, DataBlk, pkt);
+ }
}