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.sm7
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L2cache.sm9
-rw-r--r--src/mem/protocol/MESI_CMP_directory-dir.sm15
-rw-r--r--src/mem/protocol/MESI_CMP_directory-dma.sm4
-rw-r--r--src/mem/protocol/MI_example-cache.sm4
-rw-r--r--src/mem/protocol/MI_example-dir.sm10
-rw-r--r--src/mem/protocol/MI_example-dma.sm4
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L1cache.sm7
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L2cache.sm24
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-dir.sm18
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-dma.sm4
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L1cache.sm4
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L2cache.sm4
-rw-r--r--src/mem/protocol/MOESI_CMP_token-dir.sm14
-rw-r--r--src/mem/protocol/MOESI_CMP_token-dma.sm4
-rw-r--r--src/mem/protocol/MOESI_hammer-cache.sm4
-rw-r--r--src/mem/protocol/MOESI_hammer-dir.sm62
-rw-r--r--src/mem/protocol/MOESI_hammer-dma.sm4
-rw-r--r--src/mem/protocol/RubySlicc_Exports.sm7
19 files changed, 164 insertions, 45 deletions
diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
index ebbd09ae0..287bda004 100644
--- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
@@ -186,17 +186,24 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
AccessPermission getAccessPermission(Address addr) {
TBE tbe := L1_TBEs[addr];
if(is_valid(tbe)) {
+ DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(tbe.TBEState));
return L1Cache_State_to_permission(tbe.TBEState);
}
Entry cache_entry := getCacheEntry(addr);
if(is_valid(cache_entry)) {
+ DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(cache_entry.CacheState));
return L1Cache_State_to_permission(cache_entry.CacheState);
}
+ DPRINTF(RubySlicc, "%s\n", AccessPermission:NotPresent);
return AccessPermission:NotPresent;
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
void setAccessPermission(Entry cache_entry, Address addr, State state) {
if (is_valid(cache_entry)) {
cache_entry.changePermission(L1Cache_State_to_permission(state));
diff --git a/src/mem/protocol/MESI_CMP_directory-L2cache.sm b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
index 6044f5233..a8fcb07d1 100644
--- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm
@@ -56,7 +56,7 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
NP, AccessPermission:Invalid, desc="Not present in either cache";
SS, AccessPermission:Read_Only, desc="L2 cache entry Shared, also present in one or more L1s";
M, AccessPermission:Read_Write, desc="L2 cache entry Modified, not present in any L1s", format="!b";
- MT, AccessPermission:Invalid, desc="L2 cache entry Modified in a local L1, assume L2 copy stale", format="!b";
+ MT, AccessPermission:Maybe_Stale, desc="L2 cache entry Modified in a local L1, assume L2 copy stale", format="!b";
// L2 replacement
M_I, AccessPermission:Busy, desc="L2 cache replacing, have all acks, sent dirty data to memory, waiting for ACK from memory";
@@ -217,17 +217,24 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
AccessPermission getAccessPermission(Address addr) {
TBE tbe := L2_TBEs[addr];
if(is_valid(tbe)) {
+ DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(tbe.TBEState));
return L2Cache_State_to_permission(tbe.TBEState);
}
Entry cache_entry := getCacheEntry(addr);
if(is_valid(cache_entry)) {
+ DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(cache_entry.CacheState));
return L2Cache_State_to_permission(cache_entry.CacheState);
}
+ DPRINTF(RubySlicc, "%s\n", AccessPermission:NotPresent);
return AccessPermission:NotPresent;
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
void setAccessPermission(Entry cache_entry, Address addr, State state) {
if (is_valid(cache_entry)) {
cache_entry.changePermission(L2Cache_State_to_permission(state));
diff --git a/src/mem/protocol/MESI_CMP_directory-dir.sm b/src/mem/protocol/MESI_CMP_directory-dir.sm
index 6e3e79641..423272905 100644
--- a/src/mem/protocol/MESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MESI_CMP_directory-dir.sm
@@ -55,7 +55,7 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
ID, AccessPermission:Busy, desc="Intermediate state for DMA_READ when in I";
ID_W, AccessPermission:Busy, desc="Intermediate state for DMA_WRITE when in I";
- M, AccessPermission:Invalid, desc="memory copy may be stale, i.e. other modified copies may exist";
+ M, AccessPermission:Maybe_Stale, desc="memory copy may be stale, i.e. other modified copies may exist";
IM, AccessPermission:Busy, desc="Intermediate State I>M";
MI, AccessPermission:Busy, desc="Intermediate State M>I";
M_DRD, AccessPermission:Busy, desc="Intermediate State when there is a dma read";
@@ -147,10 +147,21 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
AccessPermission getAccessPermission(Address addr) {
TBE tbe := TBEs[addr];
if(is_valid(tbe)) {
+ DPRINTF(RubySlicc, "%s\n", Directory_State_to_permission(tbe.TBEState));
return Directory_State_to_permission(tbe.TBEState);
}
- return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ if(directory.isPresent(addr)) {
+ DPRINTF(RubySlicc, "%s\n", Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState));
+ return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ }
+
+ DPRINTF(RubySlicc, "%s\n", AccessPermission:NotPresent);
+ return AccessPermission:NotPresent;
+ }
+
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getDirectoryEntry(addr).DataBlk;
}
void setAccessPermission(Address addr, State state) {
diff --git a/src/mem/protocol/MESI_CMP_directory-dma.sm b/src/mem/protocol/MESI_CMP_directory-dma.sm
index aee2e467d..f32c73218 100644
--- a/src/mem/protocol/MESI_CMP_directory-dma.sm
+++ b/src/mem/protocol/MESI_CMP_directory-dma.sm
@@ -42,6 +42,10 @@ machine(DMA, "DMA Controller")
void setAccessPermission(Address addr, State state) {
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ error("DMA does not support get data block.");
+ }
+
out_port(reqToDirectory_out, RequestMsg, reqToDirectory, desc="...");
in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm
index afc415b5a..b11fddd95 100644
--- a/src/mem/protocol/MI_example-cache.sm
+++ b/src/mem/protocol/MI_example-cache.sm
@@ -140,6 +140,10 @@ machine(L1Cache, "MI Example L1 Cache")
}
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
GenericMachineType getNondirectHitMachType(MachineID sender) {
if (machineIDToMachineType(sender) == MachineType:L1Cache) {
//
diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm
index baffe2412..2bd3afa44 100644
--- a/src/mem/protocol/MI_example-dir.sm
+++ b/src/mem/protocol/MI_example-dir.sm
@@ -122,7 +122,11 @@ machine(Directory, "Directory protocol")
return Directory_State_to_permission(tbe.TBEState);
}
- return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ if(directory.isPresent(addr)) {
+ return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ }
+
+ return AccessPermission:NotPresent;
}
void setAccessPermission(Address addr, State state) {
@@ -131,6 +135,10 @@ machine(Directory, "Directory protocol")
}
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getDirectoryEntry(addr).DataBlk;
+ }
+
// ** OUT_PORTS **
out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm
index 8d79976fc..e13d247c7 100644
--- a/src/mem/protocol/MI_example-dma.sm
+++ b/src/mem/protocol/MI_example-dma.sm
@@ -37,6 +37,10 @@ machine(DMA, "DMA Controller")
void setAccessPermission(Address addr, State state) {
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ error("DMA Controller does not support getDataBlock function.\n");
+ }
+
out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
index 35832ee9c..2845d1ad1 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
@@ -197,14 +197,17 @@ machine(L1Cache, "Directory protocol")
AccessPermission getAccessPermission(Address addr) {
TBE tbe := TBEs[addr];
if(is_valid(tbe)) {
+ DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(tbe.TBEState));
return L1Cache_State_to_permission(tbe.TBEState);
}
Entry cache_entry := getCacheEntry(addr);
if(is_valid(cache_entry)) {
+ DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(cache_entry.CacheState));
return L1Cache_State_to_permission(cache_entry.CacheState);
}
+ DPRINTF(RubySlicc, "AccessPermission_NotPresent\n");
return AccessPermission:NotPresent;
}
@@ -214,6 +217,10 @@ machine(L1Cache, "Directory protocol")
}
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
Event mandatory_request_type_to_event(RubyRequestType type) {
if (type == RubyRequestType:LD) {
return Event:Load;
diff --git a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
index 8202a9c2f..eb9693ed9 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
@@ -56,12 +56,12 @@ machine(L2Cache, "Token protocol")
// Stable states
NP, AccessPermission:Invalid, desc="Not Present";
I, AccessPermission:Invalid, desc="Invalid";
- ILS, AccessPermission:Busy, desc="Idle/NP, but local sharers exist";
- ILX, AccessPermission:Busy, desc="Idle/NP, but local exclusive exists";
- ILO, AccessPermission:Busy, desc="Idle/NP, but local owner exists";
- ILOX, AccessPermission:Busy, desc="Idle/NP, but local owner exists and chip is exclusive";
- ILOS, AccessPermission:Busy, desc="Idle/NP, but local owner exists and local sharers as well";
- ILOSX, AccessPermission:Busy, desc="Idle/NP, but local owner exists, local sharers exist, chip is exclusive ";
+ ILS, AccessPermission:Invalid, desc="Idle/NP, but local sharers exist";
+ ILX, AccessPermission:Invalid, desc="Idle/NP, but local exclusive exists";
+ ILO, AccessPermission:Invalid, desc="Idle/NP, but local owner exists";
+ ILOX, AccessPermission:Invalid, desc="Idle/NP, but local owner exists and chip is exclusive";
+ ILOS, AccessPermission:Invalid, desc="Idle/NP, but local owner exists and local sharers as well";
+ ILOSX, AccessPermission:Invalid, desc="Idle/NP, but local owner exists, local sharers exist, chip is exclusive ";
S, AccessPermission:Read_Only, desc="Shared, no local sharers";
O, AccessPermission:Read_Only, desc="Owned, no local sharers";
OLS, AccessPermission:Read_Only, desc="Owned with local sharers";
@@ -502,14 +502,22 @@ machine(L2Cache, "Token protocol")
AccessPermission getAccessPermission(Address addr) {
TBE tbe := TBEs[addr];
if(is_valid(tbe)) {
+ DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(tbe.TBEState));
return L2Cache_State_to_permission(tbe.TBEState);
}
Entry cache_entry := getCacheEntry(addr);
if(is_valid(cache_entry)) {
+ DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(cache_entry.CacheState));
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;
}
@@ -519,6 +527,10 @@ machine(L2Cache, "Token protocol")
}
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
MessageBuffer triggerQueue, ordered="true";
out_port(globalRequestNetwork_out, RequestMsg, GlobalRequestFromL2Cache);
diff --git a/src/mem/protocol/MOESI_CMP_directory-dir.sm b/src/mem/protocol/MOESI_CMP_directory-dir.sm
index b13b56ffb..b71518b3f 100644
--- a/src/mem/protocol/MOESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm
@@ -50,16 +50,16 @@ machine(Directory, "Directory protocol")
// STATES
state_declaration(State, desc="Directory states", default="Directory_State_I") {
// Base states
- I, AccessPermission:Invalid, desc="Invalid";
+ I, AccessPermission:Read_Write, desc="Invalid";
S, AccessPermission:Read_Only, desc="Shared";
- O, AccessPermission:Read_Only, desc="Owner";
- M, AccessPermission:Read_Write, desc="Modified";
+ O, AccessPermission:Maybe_Stale, desc="Owner";
+ M, AccessPermission:Maybe_Stale, desc="Modified";
IS, AccessPermission:Busy, desc="Blocked, was in idle";
SS, AccessPermission:Read_Only, desc="Blocked, was in shared";
- OO, AccessPermission:Read_Only, desc="Blocked, was in owned";
- MO, AccessPermission:Read_Only, desc="Blocked, going to owner or maybe modified";
- MM, AccessPermission:Read_Only, desc="Blocked, going to modified";
+ OO, AccessPermission:Busy, desc="Blocked, was in owned";
+ MO, AccessPermission:Busy, desc="Blocked, going to owner or maybe modified";
+ MM, AccessPermission:Busy, desc="Blocked, going to modified";
MM_DMA, AccessPermission:Busy, desc="Blocked, going to I";
MI, AccessPermission:Busy, desc="Blocked on a writeback";
@@ -173,9 +173,11 @@ machine(Directory, "Directory protocol")
AccessPermission getAccessPermission(Address addr) {
if (directory.isPresent(addr)) {
+ DPRINTF(RubySlicc, "%s\n", Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState));
return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
}
+ DPRINTF(RubySlicc, "AccessPermission_NotPresent\n");
return AccessPermission:NotPresent;
}
@@ -185,6 +187,10 @@ machine(Directory, "Directory protocol")
}
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getDirectoryEntry(addr).DataBlk;
+ }
+
// if no sharers, then directory can be considered both a sharer and exclusive w.r.t. coherence checking
bool isBlockShared(Address addr) {
if (directory.isPresent(addr)) {
diff --git a/src/mem/protocol/MOESI_CMP_directory-dma.sm b/src/mem/protocol/MOESI_CMP_directory-dma.sm
index 0d99e354e..e3aefbe51 100644
--- a/src/mem/protocol/MOESI_CMP_directory-dma.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-dma.sm
@@ -68,6 +68,10 @@ machine(DMA, "DMA Controller")
void setAccessPermission(Address addr, State state) {
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ error("DMA Controller does not support getDataBlock().\n");
+ }
+
out_port(reqToDirectory_out, RequestMsg, reqToDir, desc="...");
out_port(respToDirectory_out, ResponseMsg, respToDir, desc="...");
out_port(foo1_out, ResponseMsg, foo1, desc="...");
diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
index d557132fc..66789b594 100644
--- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
@@ -227,6 +227,10 @@ machine(L1Cache, "Token protocol")
return L1Icache_entry;
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
Entry getL1DCacheEntry(Address addr), return_by_pointer="yes" {
Entry L1Dcache_entry := static_cast(Entry, "pointer", L1DcacheMemory.lookup(addr));
return L1Dcache_entry;
diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm
index c9c729263..078b5c7a6 100644
--- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm
@@ -156,6 +156,10 @@ machine(L2Cache, "Token protocol")
return cache_entry;
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
int getTokens(Entry cache_entry) {
if (is_valid(cache_entry)) {
return cache_entry.Tokens;
diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm
index 9ca0f1fc6..9e6c6c99b 100644
--- a/src/mem/protocol/MOESI_CMP_token-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_token-dir.sm
@@ -55,7 +55,7 @@ machine(Directory, "Token protocol")
state_declaration(State, desc="Directory states", default="Directory_State_O") {
// Base states
O, AccessPermission:Read_Only, desc="Owner, memory has valid data, but not necessarily all the tokens";
- NO, AccessPermission:Invalid, desc="Not Owner";
+ NO, AccessPermission:Maybe_Stale, desc="Not Owner";
L, AccessPermission:Busy, desc="Locked";
// Memory wait states - can block all messages including persistent requests
@@ -169,6 +169,10 @@ machine(Directory, "Token protocol")
return static_cast(Entry, directory[addr]);
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getDirectoryEntry(addr).DataBlk;
+ }
+
State getState(TBE tbe, Address addr) {
if (is_valid(tbe)) {
return tbe.TBEState;
@@ -206,7 +210,13 @@ machine(Directory, "Token protocol")
return Directory_State_to_permission(tbe.TBEState);
}
- return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ if (directory.isPresent(addr)) {
+ DPRINTF(RubySlicc, "%s\n", Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState));
+ return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ }
+
+ DPRINTF(RubySlicc, "AccessPermission_NotPresent\n");
+ return AccessPermission:NotPresent;
}
void setAccessPermission(Address addr, State state) {
diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm
index 40b60490c..98666998a 100644
--- a/src/mem/protocol/MOESI_CMP_token-dma.sm
+++ b/src/mem/protocol/MOESI_CMP_token-dma.sm
@@ -70,6 +70,10 @@ machine(DMA, "DMA Controller")
void setAccessPermission(Address addr, State state) {
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ error("DMA Controller does not support getDataBlock function.\n");
+ }
+
out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm
index 6fe12d561..edb1587e3 100644
--- a/src/mem/protocol/MOESI_hammer-cache.sm
+++ b/src/mem/protocol/MOESI_hammer-cache.sm
@@ -189,6 +189,10 @@ machine(L1Cache, "AMD Hammer-like protocol")
return L1Icache_entry;
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getCacheEntry(addr).DataBlk;
+ }
+
Entry getL2CacheEntry(Address address), return_by_pointer="yes" {
Entry L2cache_entry := static_cast(Entry, "pointer", L2cacheMemory.lookup(address));
return L2cache_entry;
diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm
index 828c762cb..bb0a97ac4 100644
--- a/src/mem/protocol/MOESI_hammer-dir.sm
+++ b/src/mem/protocol/MOESI_hammer-dir.sm
@@ -59,38 +59,38 @@ machine(Directory, "AMD Hammer-like protocol")
// STATES
state_declaration(State, desc="Directory states", default="Directory_State_E") {
// Base states
- NX, AccessPermission:Invalid, desc="Not Owner, probe filter entry exists, block in O at Owner";
- NO, AccessPermission:Invalid, desc="Not Owner, probe filter entry exists, block in E/M at Owner";
+ NX, AccessPermission:Maybe_Stale, desc="Not Owner, probe filter entry exists, block in O at Owner";
+ NO, AccessPermission:Maybe_Stale, desc="Not Owner, probe filter entry exists, block in E/M at Owner";
S, AccessPermission:Read_Only, desc="Data clean, probe filter entry exists pointing to the current owner";
O, AccessPermission:Read_Only, desc="Data clean, probe filter entry exists";
E, AccessPermission:Read_Write, desc="Exclusive Owner, no probe filter entry";
O_R, AccessPermission:Read_Only, desc="Was data Owner, replacing probe filter entry";
S_R, AccessPermission:Read_Only, desc="Was Not Owner or Sharer, replacing probe filter entry";
- NO_R, AccessPermission:Invalid, desc="Was Not Owner or Sharer, replacing probe filter entry";
-
- NO_B, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked";
- NO_B_X, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, next queued request GETX";
- NO_B_S, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, next queued request GETS";
- NO_B_S_W, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, forwarded merged GETS, waiting for responses";
- O_B, AccessPermission:Invalid, "O^B", desc="Owner, Blocked";
- NO_B_W, AccessPermission:Invalid, desc="Not Owner, Blocked, waiting for Dram";
- O_B_W, AccessPermission:Invalid, desc="Owner, Blocked, waiting for Dram";
- NO_W, AccessPermission:Invalid, desc="Not Owner, waiting for Dram";
- O_W, AccessPermission:Invalid, desc="Owner, waiting for Dram";
- NO_DW_B_W, AccessPermission:Invalid, desc="Not Owner, Dma Write waiting for Dram and cache responses";
- NO_DR_B_W, AccessPermission:Invalid, desc="Not Owner, Dma Read waiting for Dram and cache responses";
- NO_DR_B_D, AccessPermission:Invalid, desc="Not Owner, Dma Read waiting for cache responses including dirty data";
- NO_DR_B, AccessPermission:Invalid, desc="Not Owner, Dma Read waiting for cache responses";
- NO_DW_W, AccessPermission:Invalid, desc="Not Owner, Dma Write waiting for Dram";
- O_DR_B_W, AccessPermission:Invalid, desc="Owner, Dma Read waiting for Dram and cache responses";
- O_DR_B, AccessPermission:Invalid, desc="Owner, Dma Read waiting for cache responses";
- WB, AccessPermission:Invalid, desc="Blocked on a writeback";
- WB_O_W, AccessPermission:Invalid, desc="Blocked on memory write, will go to O";
- WB_E_W, AccessPermission:Invalid, desc="Blocked on memory write, will go to E";
-
- NO_F, AccessPermission:Invalid, desc="Blocked on a flush";
- NO_F_W, AccessPermission:Invalid, desc="Not Owner, Blocked, waiting for Dram";
+ NO_R, AccessPermission:Busy, desc="Was Not Owner or Sharer, replacing probe filter entry";
+
+ NO_B, AccessPermission:Busy, "NO^B", desc="Not Owner, Blocked";
+ NO_B_X, AccessPermission:Busy, "NO^B", desc="Not Owner, Blocked, next queued request GETX";
+ NO_B_S, AccessPermission:Busy, "NO^B", desc="Not Owner, Blocked, next queued request GETS";
+ NO_B_S_W, AccessPermission:Busy, "NO^B", desc="Not Owner, Blocked, forwarded merged GETS, waiting for responses";
+ O_B, AccessPermission:Busy, "O^B", desc="Owner, Blocked";
+ NO_B_W, AccessPermission:Busy, desc="Not Owner, Blocked, waiting for Dram";
+ O_B_W, AccessPermission:Busy, desc="Owner, Blocked, waiting for Dram";
+ NO_W, AccessPermission:Busy, desc="Not Owner, waiting for Dram";
+ O_W, AccessPermission:Busy, desc="Owner, waiting for Dram";
+ NO_DW_B_W, AccessPermission:Busy, desc="Not Owner, Dma Write waiting for Dram and cache responses";
+ NO_DR_B_W, AccessPermission:Busy, desc="Not Owner, Dma Read waiting for Dram and cache responses";
+ NO_DR_B_D, AccessPermission:Busy, desc="Not Owner, Dma Read waiting for cache responses including dirty data";
+ NO_DR_B, AccessPermission:Busy, desc="Not Owner, Dma Read waiting for cache responses";
+ NO_DW_W, AccessPermission:Busy, desc="Not Owner, Dma Write waiting for Dram";
+ O_DR_B_W, AccessPermission:Busy, desc="Owner, Dma Read waiting for Dram and cache responses";
+ 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: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";
}
// Events
@@ -190,6 +190,10 @@ machine(Directory, "AMD Hammer-like protocol")
return static_cast(Entry, directory[addr]);
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ return getDirectoryEntry(addr).DataBlk;
+ }
+
PfEntry getProbeFilterEntry(Address addr), return_by_pointer="yes" {
if (probe_filter_enabled || full_bit_dir_enabled) {
PfEntry pfEntry := static_cast(PfEntry, "pointer", probeFilter.lookup(addr));
@@ -239,7 +243,11 @@ machine(Directory, "AMD Hammer-like protocol")
return Directory_State_to_permission(tbe.TBEState);
}
- return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ if(directory.isPresent(addr)) {
+ return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
+ }
+
+ return AccessPermission:NotPresent;
}
void setAccessPermission(PfEntry pf_entry, Address addr, State state) {
diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm
index f254c1633..bfb3cb98d 100644
--- a/src/mem/protocol/MOESI_hammer-dma.sm
+++ b/src/mem/protocol/MOESI_hammer-dma.sm
@@ -67,6 +67,10 @@ machine(DMA, "DMA Controller")
void setAccessPermission(Address addr, State state) {
}
+ DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+ error("DMA Controller does not support getDataBlock function.\n");
+ }
+
out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
diff --git a/src/mem/protocol/RubySlicc_Exports.sm b/src/mem/protocol/RubySlicc_Exports.sm
index ccd3aeb7f..2e4a16784 100644
--- a/src/mem/protocol/RubySlicc_Exports.sm
+++ b/src/mem/protocol/RubySlicc_Exports.sm
@@ -57,6 +57,13 @@ enumeration(AccessPermission, desc="...", default="AccessPermission_NotPresent")
Read_Only, desc="block is Read Only (modulo functional writes)";
Read_Write, desc="block is Read/Write";
+ // Possibly Invalid data
+ // The maybe stale permission indicates that accordingly to the protocol,
+ // there is no guarantee the block contains valid data. However, functional
+ // writes should update the block because a dataless PUT request may
+ // revalidate the block's data.
+ Maybe_Stale, desc="block can be stale or revalidated by a dataless PUT";
+
// Invalid data
Invalid, desc="block is in an Invalid base state";
NotPresent, desc="block is NotPresent";