diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm index d0fc61e90..ebbd09ae0 100644 --- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm @@ -183,6 +183,26 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := L1_TBEs[addr]; + if(is_valid(tbe)) { + return L1Cache_State_to_permission(tbe.TBEState); + } + + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L1Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L1Cache_State_to_permission(state)); + } + } + Event mandatory_request_type_to_event(RubyRequestType type) { if (type == RubyRequestType:LD) { return Event:Load; diff --git a/src/mem/protocol/MESI_CMP_directory-L2cache.sm b/src/mem/protocol/MESI_CMP_directory-L2cache.sm index 771a2dfb2..6044f5233 100644 --- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm +++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm @@ -202,7 +202,6 @@ machine(L2Cache, "MESI Directory L2 Cache CMP") return L2Cache_State_to_string(getState(tbe, cache_entry, addr)); } - // when is this called void setState(TBE tbe, Entry cache_entry, Address addr, State state) { // MUST CHANGE @@ -215,6 +214,26 @@ machine(L2Cache, "MESI Directory L2 Cache CMP") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := L2_TBEs[addr]; + if(is_valid(tbe)) { + return L2Cache_State_to_permission(tbe.TBEState); + } + + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L2Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L2Cache_State_to_permission(state)); + } + } + Event L1Cache_request_type_to_event(CoherenceRequestType type, Address addr, MachineID requestor, Entry cache_entry) { if(type == CoherenceRequestType:GETS) { diff --git a/src/mem/protocol/MESI_CMP_directory-dir.sm b/src/mem/protocol/MESI_CMP_directory-dir.sm index 6ad88f809..6e3e79641 100644 --- a/src/mem/protocol/MESI_CMP_directory-dir.sm +++ b/src/mem/protocol/MESI_CMP_directory-dir.sm @@ -124,7 +124,6 @@ machine(Directory, "MESI_CMP_filter_directory protocol") } } - void setState(TBE tbe, Address addr, State state) { if (is_valid(tbe)) { @@ -145,6 +144,20 @@ machine(Directory, "MESI_CMP_filter_directory protocol") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return Directory_State_to_permission(tbe.TBEState); + } + + return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState); + } + + void setAccessPermission(Address addr, State state) { + if (directory.isPresent(addr)) { + getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state)); + } + } bool isGETRequest(CoherenceRequestType type) { return (type == CoherenceRequestType:GETS) || diff --git a/src/mem/protocol/MESI_CMP_directory-dma.sm b/src/mem/protocol/MESI_CMP_directory-dma.sm index 205d337b1..aee2e467d 100644 --- a/src/mem/protocol/MESI_CMP_directory-dma.sm +++ b/src/mem/protocol/MESI_CMP_directory-dma.sm @@ -35,6 +35,13 @@ machine(DMA, "DMA Controller") cur_state := state; } + AccessPermission getAccessPermission(Address addr) { + return AccessPermission:NotPresent; + } + + void setAccessPermission(Address addr, State state) { + } + 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 cef89afda..afc415b5a 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -120,6 +120,26 @@ machine(L1Cache, "MI Example L1 Cache") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return L1Cache_State_to_permission(tbe.TBEState); + } + + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L1Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L1Cache_State_to_permission(state)); + } + } + 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 bffdd04fd..baffe2412 100644 --- a/src/mem/protocol/MI_example-dir.sm +++ b/src/mem/protocol/MI_example-dir.sm @@ -116,6 +116,21 @@ machine(Directory, "Directory protocol") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return Directory_State_to_permission(tbe.TBEState); + } + + return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState); + } + + void setAccessPermission(Address addr, State state) { + if (directory.isPresent(addr)) { + getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state)); + } + } + // ** 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 bb864e934..8d79976fc 100644 --- a/src/mem/protocol/MI_example-dma.sm +++ b/src/mem/protocol/MI_example-dma.sm @@ -30,6 +30,13 @@ machine(DMA, "DMA Controller") cur_state := state; } + AccessPermission getAccessPermission(Address addr) { + return AccessPermission:NotPresent; + } + + void setAccessPermission(Address addr, State state) { + } + 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 e9622c30b..35832ee9c 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm @@ -194,6 +194,26 @@ machine(L1Cache, "Directory protocol") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return L1Cache_State_to_permission(tbe.TBEState); + } + + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L1Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L1Cache_State_to_permission(state)); + } + } + 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 a9c1e74a0..8202a9c2f 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm @@ -499,6 +499,26 @@ machine(L2Cache, "Token protocol") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return L2Cache_State_to_permission(tbe.TBEState); + } + + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L2Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L2Cache_State_to_permission(state)); + } + } + 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 572101f00..b13b56ffb 100644 --- a/src/mem/protocol/MOESI_CMP_directory-dir.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm @@ -171,6 +171,20 @@ machine(Directory, "Directory protocol") } } + AccessPermission getAccessPermission(Address addr) { + if (directory.isPresent(addr)) { + return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Address addr, State state) { + if (directory.isPresent(addr)) { + getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state)); + } + } + // 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 642c6e22d..0d99e354e 100644 --- a/src/mem/protocol/MOESI_CMP_directory-dma.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dma.sm @@ -61,6 +61,13 @@ machine(DMA, "DMA Controller") cur_state := state; } + AccessPermission getAccessPermission(Address addr) { + return AccessPermission:NotPresent; + } + + void setAccessPermission(Address addr, State state) { + } + 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 a4dbe5fe7..d557132fc 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -341,6 +341,26 @@ machine(L1Cache, "Token protocol") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := L1_TBEs[addr]; + if(is_valid(tbe)) { + return L1Cache_State_to_permission(tbe.TBEState); + } + + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L1Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L1Cache_State_to_permission(state)); + } + } + Event mandatory_request_type_to_event(RubyRequestType type) { if (type == RubyRequestType:LD) { return Event:Load; diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm index 8b87889b1..c9c729263 100644 --- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm @@ -211,6 +211,21 @@ machine(L2Cache, "Token protocol") } } + AccessPermission getAccessPermission(Address addr) { + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L2Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L2Cache_State_to_permission(state)); + } + } + void removeSharer(Address addr, NodeID id) { if (localDirectory.isTagPresent(addr)) { diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm index aabde0af8..9ca0f1fc6 100644 --- a/src/mem/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm @@ -199,7 +199,20 @@ machine(Directory, "Token protocol") // assert(getDirectoryEntry(addr).Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold } } - + + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return Directory_State_to_permission(tbe.TBEState); + } + + return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState); + } + + void setAccessPermission(Address addr, State state) { + getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state)); + } + bool okToIssueStarving(Address addr, MachineID machinID) { return persistentTable.okToIssueStarving(addr, machineID); } diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm index dfd26e64d..40b60490c 100644 --- a/src/mem/protocol/MOESI_CMP_token-dma.sm +++ b/src/mem/protocol/MOESI_CMP_token-dma.sm @@ -63,6 +63,13 @@ machine(DMA, "DMA Controller") cur_state := state; } + AccessPermission getAccessPermission(Address addr) { + return AccessPermission:NotPresent; + } + + void setAccessPermission(Address addr, State state) { + } + 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 24f3ab318..6fe12d561 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -227,6 +227,26 @@ machine(L1Cache, "AMD Hammer-like protocol") } } + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return L1Cache_State_to_permission(tbe.TBEState); + } + + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return L1Cache_State_to_permission(cache_entry.CacheState); + } + + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + if (is_valid(cache_entry)) { + cache_entry.changePermission(L1Cache_State_to_permission(state)); + } + } + Event mandatory_request_type_to_event(RubyRequestType type) { if (type == RubyRequestType:LD) { return Event:Load; diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm index 96af4228f..828c762cb 100644 --- a/src/mem/protocol/MOESI_hammer-dir.sm +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -232,7 +232,20 @@ machine(Directory, "AMD Hammer-like protocol") } getDirectoryEntry(addr).DirectoryState := state; } - + + AccessPermission getAccessPermission(Address addr) { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return Directory_State_to_permission(tbe.TBEState); + } + + return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState); + } + + void setAccessPermission(PfEntry pf_entry, Address addr, State state) { + getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state)); + } + Event cache_request_to_event(CoherenceRequestType type) { if (type == CoherenceRequestType:GETS) { return Event:GETS; diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm index c784fb6b9..f254c1633 100644 --- a/src/mem/protocol/MOESI_hammer-dma.sm +++ b/src/mem/protocol/MOESI_hammer-dma.sm @@ -60,6 +60,13 @@ machine(DMA, "DMA Controller") cur_state := state; } + AccessPermission getAccessPermission(Address addr) { + return AccessPermission:NotPresent; + } + + void setAccessPermission(Address addr, State state) { + } + out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="..."); in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { diff --git a/src/mem/protocol/Network_test-cache.sm b/src/mem/protocol/Network_test-cache.sm index e76c002f5..b97819ca3 100644 --- a/src/mem/protocol/Network_test-cache.sm +++ b/src/mem/protocol/Network_test-cache.sm @@ -120,6 +120,13 @@ machine(L1Cache, "Network_test L1 Cache") } + AccessPermission getAccessPermission(Address addr) { + return AccessPermission:NotPresent; + } + + void setAccessPermission(Entry cache_entry, Address addr, State state) { + } + Entry getCacheEntry(Address address), return_by_pointer="yes" { return OOD; } diff --git a/src/mem/protocol/Network_test-dir.sm b/src/mem/protocol/Network_test-dir.sm index c3e6dfaf0..593a409d0 100644 --- a/src/mem/protocol/Network_test-dir.sm +++ b/src/mem/protocol/Network_test-dir.sm @@ -69,6 +69,13 @@ machine(Directory, "Network_test Directory") } + AccessPermission getAccessPermission(Address addr) { + return AccessPermission:NotPresent; + } + + void setAccessPermission(Address addr, State state) { + } + // ** IN_PORTS ** in_port(requestQueue_in, RequestMsg, requestToDir) { diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index cf0f64500..a2f8abfaa 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -120,7 +120,9 @@ structure(RubyRequest, desc="...", interface="Message", external="yes") { int contextId, desc="this goes away but must be replace with Nilay"; } -external_type(AbstractEntry, primitive="yes"); +structure(AbstractEntry, primitive="yes", external = "yes") { + void changePermission(AccessPermission); +} structure (DirectoryMemory, external = "yes") { AbstractEntry lookup(Address); @@ -128,7 +130,9 @@ structure (DirectoryMemory, external = "yes") { void invalidateBlock(Address); } -external_type(AbstractCacheEntry, primitive="yes"); +structure(AbstractCacheEntry, primitive="yes", external = "yes") { + void changePermission(AccessPermission); +} structure (CacheMemory, external = "yes") { bool cacheAvail(Address); diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index fcfe104b3..eb8399af2 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -32,6 +32,7 @@ #include #include +#include "mem/protocol/AccessPermission.hh" #include "mem/protocol/MachineType.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" @@ -67,6 +68,9 @@ class AbstractController : public SimObject, public Consumer virtual void wakeup() = 0; // virtual void dumpStats(std::ostream & out) = 0; virtual void clearStats() = 0; + + private: + virtual AccessPermission getAccessPermission(Address addr) = 0; }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py index 6a2977533..cfee9b19d 100644 --- a/src/mem/slicc/ast/MethodCallExprAST.py +++ b/src/mem/slicc/ast/MethodCallExprAST.py @@ -160,7 +160,13 @@ class MemberMethodCallExprAST(MethodCallExprAST): if return_type.isInterface: prefix = "static_cast<%s &>" % return_type.c_ident - prefix = "%s((%s)." % (prefix, code) + + if str(obj_type) == "AbstractCacheEntry" or \ + ("interface" in obj_type and + obj_type["interface"] == "AbstractCacheEntry"): + prefix = "%s((*(%s))." % (prefix, code) + else: + prefix = "%s((%s)." % (prefix, code) return obj_type, methodId, prefix diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index 09e17aee9..a3a95002d 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -348,8 +348,6 @@ static int m_num_controllers; // Set and Reset for cache_entry variable void set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry); void unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr); -// Set permissions for the cache_entry -void set_permission(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AccessPermission perm); ''') if self.TBEType != None: @@ -864,15 +862,6 @@ $c_ident::unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr) { m_cache_entry_ptr = 0; } - -void -$c_ident::set_permission(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, - AccessPermission perm) -{ - if (m_cache_entry_ptr != NULL) { - m_cache_entry_ptr->changePermission(perm); - } -} ''') if self.TBEType != None: @@ -1116,14 +1105,16 @@ ${ident}_Controller::doTransition(${ident}_Event event, ''') if self.TBEType != None and self.EntryType != None: code('setState(m_tbe_ptr, m_cache_entry_ptr, addr, next_state);') - code('set_permission(m_cache_entry_ptr, ${ident}_State_to_permission(next_state));') + code('setAccessPermission(m_cache_entry_ptr, addr, next_state);') elif self.TBEType != None: code('setState(m_tbe_ptr, addr, next_state);') + code('setAccessPermission(addr, next_state);') elif self.EntryType != None: code('setState(m_cache_entry_ptr, addr, next_state);') - code('set_permission(m_cache_entry_ptr, ${ident}_State_to_permission(next_state));') + code('setAccessPermission(m_cache_entry_ptr, addr, next_state);') else: code('setState(addr, next_state);') + code('setAccessPermission(addr, next_state);') code(''' } else if (result == TransitionResult_ResourceStall) {