summaryrefslogtreecommitdiff
path: root/src/mem/protocol
diff options
context:
space:
mode:
authorBrad Beckmann ext:(%2C%20Nilay%20Vaish%20%3Cnilay%40cs.wisc.edu%3E) <Brad.Beckmann@amd.com>2011-06-30 19:49:26 -0500
committerBrad Beckmann ext:(%2C%20Nilay%20Vaish%20%3Cnilay%40cs.wisc.edu%3E) <Brad.Beckmann@amd.com>2011-06-30 19:49:26 -0500
commitc86f849d5a1da1fc77f2fca43b82cb6760f68bc9 (patch)
treef192cbc73d86ee4e15e752f6ed174e4ce3425c9e /src/mem/protocol
parentf4cfd65d2982f0f97304ef05083b40f3346a496f (diff)
downloadgem5-c86f849d5a1da1fc77f2fca43b82cb6760f68bc9.tar.xz
Ruby: Add support for functional accesses
This patch rpovides functional access support in Ruby. Currently only the M5Port of RubyPort supports functional accesses. The support for functional through the PioPort will be added as a separate patch.
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";