From: Brad Beckmann Date: Thu, 24 Feb 2011 00:41:59 +0000 (-0800) Subject: ruby: automate permission setting X-Git-Tag: stable_2012_02_02~520 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=12a05c23b7d351afee4b0c531021d8fb8ea5f57d;p=gem5.git ruby: automate permission setting This patch integrates permissions with cache and memory states, and then automates the setting of permissions within the generated code. No longer does one need to manually set the permissions within the setState funciton. This patch will faciliate easier functional access support by always correctly setting permissions for both cache and memory states. --HG-- rename : src/mem/slicc/ast/EnumDeclAST.py => src/mem/slicc/ast/StateDeclAST.py rename : src/mem/slicc/ast/TypeFieldEnumAST.py => src/mem/slicc/ast/TypeFieldStateAST.py --- diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm index 4442cee41..ecd8c9681 100644 --- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm @@ -52,23 +52,23 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") MessageBuffer responseToL1Cache, network="From", virtual_network="1", ordered="false"; // STATES - enumeration(State, desc="Cache states", default="L1Cache_State_I") { + state_declaration(State, desc="Cache states", default="L1Cache_State_I") { // Base states - NP, desc="Not present in either cache"; - I, desc="a L1 cache entry Idle"; - S, desc="a L1 cache entry Shared"; - E, desc="a L1 cache entry Exclusive"; - M, desc="a L1 cache entry Modified", format="!b"; + NP, AccessPermission:Invalid, desc="Not present in either cache"; + I, AccessPermission:Invalid, desc="a L1 cache entry Idle"; + S, AccessPermission:Read_Only, desc="a L1 cache entry Shared"; + E, AccessPermission:Read_Only, desc="a L1 cache entry Exclusive"; + M, AccessPermission:Read_Write, desc="a L1 cache entry Modified", format="!b"; // Transient States - IS, desc="L1 idle, issued GETS, have not seen response yet"; - IM, desc="L1 idle, issued GETX, have not seen response yet"; - SM, desc="L1 idle, issued GETX, have not seen response yet"; - IS_I, desc="L1 idle, issued GETS, saw Inv before data because directory doesn't block on GETS hit"; + IS, AccessPermission:Busy, desc="L1 idle, issued GETS, have not seen response yet"; + IM, AccessPermission:Busy, desc="L1 idle, issued GETX, have not seen response yet"; + SM, AccessPermission:Read_Only, desc="L1 idle, issued GETX, have not seen response yet"; + IS_I, AccessPermission:Busy, desc="L1 idle, issued GETS, saw Inv before data because directory doesn't block on GETS hit"; - M_I, desc="L1 replacing, waiting for ACK"; - E_I, desc="L1 replacing, waiting for ACK"; - SINK_WB_ACK, desc="This is to sink WB_Acks from L2"; + M_I, AccessPermission:Busy, desc="L1 replacing, waiting for ACK"; + E_I, AccessPermission:Busy, desc="L1 replacing, waiting for ACK"; + SINK_WB_ACK, AccessPermission:Busy, desc="This is to sink WB_Acks from L2"; } @@ -180,17 +180,6 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") if (is_valid(cache_entry)) { cache_entry.CacheState := state; - - // Set permission - if (state == State:I) { - cache_entry.changePermission(AccessPermission:Invalid); - } else if (state == State:S || state == State:E) { - cache_entry.changePermission(AccessPermission:Read_Only); - } else if (state == State:M) { - cache_entry.changePermission(AccessPermission:Read_Write); - } else { - cache_entry.changePermission(AccessPermission:Busy); - } } } diff --git a/src/mem/protocol/MESI_CMP_directory-L2cache.sm b/src/mem/protocol/MESI_CMP_directory-L2cache.sm index aeaf3d60d..c30e42e69 100644 --- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm +++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm @@ -51,33 +51,33 @@ machine(L2Cache, "MESI Directory L2 Cache CMP") // MessageBuffer unblockToL2Cache, network="From", virtual_network="4", ordered="false"; // a local L1 || Memory -> this L2 bank // STATES - enumeration(State, desc="L2 Cache states", default="L2Cache_State_NP") { + state_declaration(State, desc="L2 Cache states", default="L2Cache_State_NP") { // Base states - NP, desc="Not present in either cache"; - SS, desc="L2 cache entry Shared, also present in one or more L1s"; - M, desc="L2 cache entry Modified, not present in any L1s", format="!b"; - MT, desc="L2 cache entry Modified in a local L1, assume L2 copy stale", format="!b"; + 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"; // L2 replacement - M_I, desc="L2 cache replacing, have all acks, sent dirty data to memory, waiting for ACK from memory"; - MT_I, desc="L2 cache replacing, getting data from exclusive"; - MCT_I, desc="L2 cache replacing, clean in L2, getting data or ack from exclusive"; - I_I, desc="L2 replacing clean data, need to inv sharers and then drop data"; - S_I, desc="L2 replacing dirty data, collecting acks from L1s"; + M_I, AccessPermission:Busy, desc="L2 cache replacing, have all acks, sent dirty data to memory, waiting for ACK from memory"; + MT_I, AccessPermission:Busy, desc="L2 cache replacing, getting data from exclusive"; + MCT_I, AccessPermission:Busy, desc="L2 cache replacing, clean in L2, getting data or ack from exclusive"; + I_I, AccessPermission:Busy, desc="L2 replacing clean data, need to inv sharers and then drop data"; + S_I, AccessPermission:Busy, desc="L2 replacing dirty data, collecting acks from L1s"; // Transient States for fetching data from memory - ISS, desc="L2 idle, got single L1_GETS, issued memory fetch, have not seen response yet"; - IS, desc="L2 idle, got L1_GET_INSTR or multiple L1_GETS, issued memory fetch, have not seen response yet"; - IM, desc="L2 idle, got L1_GETX, issued memory fetch, have not seen response(s) yet"; + ISS, AccessPermission:Busy, desc="L2 idle, got single L1_GETS, issued memory fetch, have not seen response yet"; + IS, AccessPermission:Busy, desc="L2 idle, got L1_GET_INSTR or multiple L1_GETS, issued memory fetch, have not seen response yet"; + IM, AccessPermission:Busy, desc="L2 idle, got L1_GETX, issued memory fetch, have not seen response(s) yet"; // Blocking states - SS_MB, desc="Blocked for L1_GETX from SS"; - MT_MB, desc="Blocked for L1_GETX from MT"; - M_MB, desc="Blocked for L1_GETX from M"; + SS_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from SS"; + MT_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from MT"; + M_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from M"; - MT_IIB, desc="Blocked for L1_GETS from MT, waiting for unblock and data"; - MT_IB, desc="Blocked for L1_GETS from MT, got unblock, waiting for data"; - MT_SB, desc="Blocked for L1_GETS from MT, got data, waiting for unblock"; + MT_IIB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, waiting for unblock and data"; + MT_IB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, got unblock, waiting for data"; + MT_SB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, got data, waiting for unblock"; } @@ -212,17 +212,6 @@ machine(L2Cache, "MESI Directory L2 Cache CMP") if (is_valid(cache_entry)) { cache_entry.CacheState := state; - - // Set permission - if (state == State:SS ) { - cache_entry.changePermission(AccessPermission:Read_Only); - } else if (state == State:M) { - cache_entry.changePermission(AccessPermission:Read_Write); - } else if (state == State:MT) { - cache_entry.changePermission(AccessPermission:Invalid); - } else { - cache_entry.changePermission(AccessPermission:Busy); - } } } diff --git a/src/mem/protocol/MESI_CMP_directory-dir.sm b/src/mem/protocol/MESI_CMP_directory-dir.sm index 0c3532fbf..46c14bc0f 100644 --- a/src/mem/protocol/MESI_CMP_directory-dir.sm +++ b/src/mem/protocol/MESI_CMP_directory-dir.sm @@ -49,19 +49,19 @@ machine(Directory, "MESI_CMP_filter_directory protocol") MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false"; // STATES - enumeration(State, desc="Directory states", default="Directory_State_I") { + state_declaration(State, desc="Directory states", default="Directory_State_I") { // Base states - I, desc="Owner"; - ID, desc="Intermediate state for DMA_READ when in I"; - ID_W, desc="Intermediate state for DMA_WRITE when in I"; - - M, desc="Modified"; - IM, desc="Intermediate State I>M"; - MI, desc="Intermediate State M>I"; - M_DRD, desc="Intermediate State when there is a dma read"; - M_DRDI, desc="Intermediate State when there is a dma read"; - M_DWR, desc="Intermediate State when there is a dma write"; - M_DWRI, desc="Intermediate State when there is a dma write"; + I, AccessPermission:Read_Write, desc="dir is the owner and memory is up-to-date, all other copies are Invalid"; + 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"; + 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"; + M_DRDI, AccessPermission:Busy, desc="Intermediate State when there is a dma read"; + M_DWR, AccessPermission:Busy, desc="Intermediate State when there is a dma write"; + M_DWRI, AccessPermission:Busy, desc="Intermediate State when there is a dma write"; } // Events diff --git a/src/mem/protocol/MESI_CMP_directory-dma.sm b/src/mem/protocol/MESI_CMP_directory-dma.sm index fe1cd2fb4..3fab439c6 100644 --- a/src/mem/protocol/MESI_CMP_directory-dma.sm +++ b/src/mem/protocol/MESI_CMP_directory-dma.sm @@ -7,10 +7,10 @@ machine(DMA, "DMA Controller") MessageBuffer responseFromDir, network="From", virtual_network="1", ordered="true", no_vector="true"; MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true"; - enumeration(State, desc="DMA states", default="DMA_State_READY") { - READY, desc="Ready to accept a new request"; - BUSY_RD, desc="Busy: currently processing a request"; - BUSY_WR, desc="Busy: currently processing a request"; + state_declaration(State, desc="DMA states", default="DMA_State_READY") { + READY, AccessPermission:Invalid, desc="Ready to accept a new request"; + BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; + BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; } enumeration(Event, desc="DMA events") { diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm index 96b7ab826..26572770c 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -14,15 +14,15 @@ machine(L1Cache, "MI Example L1 Cache") MessageBuffer responseToCache, network="From", virtual_network="4", ordered="true"; // STATES - enumeration(State, desc="Cache states") { - I, desc="Not Present/Invalid"; - II, desc="Not Present/Invalid, issued PUT"; - M, desc="Modified"; - MI, desc="Modified, issued PUT"; - MII, desc="Modified, issued PUTX, received nack"; + state_declaration(State, desc="Cache states") { + I, AccessPermission:Invalid, desc="Not Present/Invalid"; + II, AccessPermission:Busy, desc="Not Present/Invalid, issued PUT"; + M, AccessPermission:Read_Write, desc="Modified"; + MI, AccessPermission:Busy, desc="Modified, issued PUT"; + MII, AccessPermission:Busy, desc="Modified, issued PUTX, received nack"; - IS, desc="Issued request for LOAD/IFETCH"; - IM, desc="Issued request for STORE/ATOMIC"; + IS, AccessPermission:Busy, desc="Issued request for LOAD/IFETCH"; + IM, AccessPermission:Busy, desc="Issued request for STORE/ATOMIC"; } // EVENTS @@ -117,11 +117,6 @@ machine(L1Cache, "MI Example L1 Cache") if (is_valid(cache_entry)) { cache_entry.CacheState := state; - if (state == State:M) { - cache_entry.changePermission(AccessPermission:Read_Write); - } else { - cache_entry.changePermission(AccessPermission:Invalid); - } } } diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm index 30720e433..d4ba3829d 100644 --- a/src/mem/protocol/MI_example-dir.sm +++ b/src/mem/protocol/MI_example-dir.sm @@ -13,21 +13,21 @@ machine(Directory, "Directory protocol") MessageBuffer dmaRequestToDir, network="From", virtual_network="0", ordered="true"; // STATES - enumeration(State, desc="Directory states", default="Directory_State_I") { + state_declaration(State, desc="Directory states", default="Directory_State_I") { // Base states - I, desc="Invalid"; - M, desc="Modified"; + I, AccessPermission:Read_Write, desc="Invalid"; + M, AccessPermission:Invalid, desc="Modified"; - M_DRD, desc="Blocked on an invalidation for a DMA read"; - M_DWR, desc="Blocked on an invalidation for a DMA write"; + M_DRD, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA read"; + M_DWR, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA write"; - M_DWRI, desc="Intermediate state M_DWR-->I"; - M_DRDI, desc="Intermediate state M_DRD-->I"; + M_DWRI, AccessPermission:Busy, desc="Intermediate state M_DWR-->I"; + M_DRDI, AccessPermission:Busy, desc="Intermediate state M_DRD-->I"; - IM, desc="Intermediate state I-->M"; - MI, desc="Intermediate state M-->I"; - ID, desc="Intermediate state for DMA_READ when in I"; - ID_W, desc="Intermediate state for DMA_WRITE when in I"; + IM, AccessPermission:Busy, desc="Intermediate state I-->M"; + MI, AccessPermission:Busy, desc="Intermediate state M-->I"; + 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"; } // Events diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm index 3e52ae5f6..878af538e 100644 --- a/src/mem/protocol/MI_example-dma.sm +++ b/src/mem/protocol/MI_example-dma.sm @@ -7,10 +7,10 @@ machine(DMA, "DMA Controller") MessageBuffer responseFromDir, network="From", virtual_network="1", ordered="true", no_vector="true"; MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true"; - enumeration(State, desc="DMA states", default="DMA_State_READY") { - READY, desc="Ready to accept a new request"; - BUSY_RD, desc="Busy: currently processing a request"; - BUSY_WR, desc="Busy: currently processing a request"; + state_declaration(State, desc="DMA states", default="DMA_State_READY") { + READY, AccessPermission:Invalid, desc="Ready to accept a new request"; + BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; + BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; } enumeration(Event, desc="DMA events") { diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm index e590c952a..50df2e52a 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm @@ -58,25 +58,25 @@ machine(L1Cache, "Directory protocol") // STATES - enumeration(State, desc="Cache states", default="L1Cache_State_I") { + state_declaration(State, desc="Cache states", default="L1Cache_State_I") { // Base states - I, desc="Idle"; - S, desc="Shared"; - O, desc="Owned"; - M, desc="Modified (dirty)"; - M_W, desc="Modified (dirty)"; - MM, desc="Modified (dirty and locally modified)"; - MM_W, desc="Modified (dirty and locally modified)"; + I, AccessPermission:Invalid, desc="Idle"; + S, AccessPermission:Read_Only, desc="Shared"; + O, AccessPermission:Read_Only, desc="Owned"; + M, AccessPermission:Read_Only, desc="Modified (dirty)"; + M_W, AccessPermission:Read_Only, desc="Modified (dirty)"; + MM, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)"; + MM_W, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)"; // Transient States - IM, "IM", desc="Issued GetX"; - SM, "SM", desc="Issued GetX, we still have an old copy of the line"; - OM, "SM", desc="Issued GetX, received data"; - IS, "IS", desc="Issued GetS"; - SI, "OI", desc="Issued PutS, waiting for ack"; - OI, "OI", desc="Issued PutO, waiting for ack"; - MI, "MI", desc="Issued PutX, waiting for ack"; - II, "II", desc="Issued PutX/O, saw Fwd_GETS or Fwd_GETX, waiting for ack"; + IM, AccessPermission:Busy, "IM", desc="Issued GetX"; + SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have an old copy of the line"; + OM, AccessPermission:Read_Only, "SM", desc="Issued GetX, received data"; + IS, AccessPermission:Busy, "IS", desc="Issued GetS"; + SI, AccessPermission:Busy, "OI", desc="Issued PutS, waiting for ack"; + OI, AccessPermission:Busy, "OI", desc="Issued PutO, waiting for ack"; + MI, AccessPermission:Busy, "MI", desc="Issued PutX, waiting for ack"; + II, AccessPermission:Busy, "II", desc="Issued PutX/O, saw Fwd_GETS or Fwd_GETX, waiting for ack"; } // EVENTS @@ -191,20 +191,6 @@ machine(L1Cache, "Directory protocol") else { cache_entry.CacheState := state; } - - // Set permission - if (state == State:MM || state == State:MM_W) { - cache_entry.changePermission(AccessPermission:Read_Write); - } else if ((state == State:S) || - (state == State:O) || - (state == State:M) || - (state == State:M_W) || - (state == State:SM) || - (state == State:OM)) { - cache_entry.changePermission(AccessPermission:Read_Only); - } else { - cache_entry.changePermission(AccessPermission:Invalid); - } } } diff --git a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm index a638b171f..cdc91c292 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm @@ -51,80 +51,80 @@ machine(L2Cache, "Token protocol") // MessageBuffer L1WritebackToL2Cache, network="From", virtual_network="3", ordered="false"; // STATES - enumeration(State, desc="L2 Cache states", default="L2Cache_State_I") { + state_declaration(State, desc="L2 Cache states", default="L2Cache_State_I") { // Stable states - NP, desc="Not Present"; - I, desc="Invalid"; - ILS, desc="Idle/NP, but local sharers exist"; - ILX, desc="Idle/NP, but local exclusive exists"; - ILO, desc="Idle/NP, but local owner exists"; - ILOX, desc="Idle/NP, but local owner exists and chip is exclusive"; - ILOS, desc="Idle/NP, but local owner exists and local sharers as well"; - ILOSX, desc="Idle/NP, but local owner exists, local sharers exist, chip is exclusive "; - S, desc="Shared, no local sharers"; - O, desc="Owned, no local sharers"; - OLS, desc="Owned with local sharers"; - OLSX, desc="Owned with local sharers, chip is exclusive"; - SLS, desc="Shared with local sharers"; - M, desc="Modified"; + 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 "; + 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"; + OLSX, AccessPermission:Read_Only, desc="Owned with local sharers, chip is exclusive"; + SLS, AccessPermission:Read_Only, desc="Shared with local sharers"; + M, AccessPermission:Read_Write, desc="Modified"; // Transient States - IFGX, desc="Blocked, forwarded global GETX to local owner/exclusive. No other on-chip invs needed"; - IFGS, desc="Blocked, forwarded global GETS to local owner"; - ISFGS, desc="Blocked, forwarded global GETS to local owner, local sharers exist"; + IFGX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to local owner/exclusive. No other on-chip invs needed"; + IFGS, AccessPermission:Busy, desc="Blocked, forwarded global GETS to local owner"; + ISFGS, AccessPermission:Busy, desc="Blocked, forwarded global GETS to local owner, local sharers exist"; // UNUSED - IFGXX, desc="Blocked, forwarded global GETX to local owner but may need acks from other sharers"; - OFGX, desc="Blocked, forwarded global GETX to owner and got data but may need acks"; + IFGXX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to local owner but may need acks from other sharers"; + OFGX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to owner and got data but may need acks"; - OLSF, desc="Blocked, got Fwd_GETX with local sharers, waiting for local inv acks"; + OLSF, AccessPermission:Busy, desc="Blocked, got Fwd_GETX with local sharers, waiting for local inv acks"; // writebacks - ILOW, desc="local WB request, was ILO"; - ILOXW, desc="local WB request, was ILOX"; - ILOSW, desc="local WB request, was ILOS"; - ILOSXW, desc="local WB request, was ILOSX"; - SLSW, desc="local WB request, was SLS"; - OLSW, desc="local WB request, was OLS"; - ILSW, desc="local WB request, was ILS"; - IW, desc="local WB request from only sharer, was ILS"; - OW, desc="local WB request from only sharer, was OLS"; - SW, desc="local WB request from only sharer, was SLS"; - OXW, desc="local WB request from only sharer, was OLSX"; - OLSXW, desc="local WB request from sharer, was OLSX"; - ILXW, desc="local WB request, was ILX"; - - IFLS, desc="Blocked, forwarded local GETS to _some_ local sharer"; - IFLO, desc="Blocked, forwarded local GETS to local owner"; - IFLOX, desc="Blocked, forwarded local GETS to local owner but chip is exclusive"; - IFLOXX, desc="Blocked, forwarded local GETX to local owner/exclusive, chip is exclusive"; - IFLOSX, desc="Blocked, forwarded local GETS to local owner w/ other sharers, chip is exclusive"; - IFLXO, desc="Blocked, forwarded local GETX to local owner with other sharers, chip is exclusive"; - - IGS, desc="Semi-blocked, issued local GETS to directory"; - IGM, desc="Blocked, issued local GETX to directory. Need global acks and data"; - IGMLS, desc="Blocked, issued local GETX to directory but may need to INV local sharers"; - IGMO, desc="Blocked, have data for local GETX but need all acks"; - IGMIO, desc="Blocked, issued local GETX, local owner with possible local sharer, may need to INV"; - OGMIO, desc="Blocked, issued local GETX, was owner, may need to INV"; - IGMIOF, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETX"; - IGMIOFS, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETS"; - OGMIOF, desc="Blocked, issued local GETX, was owner, waiting for global acks, got Fwd_GETX"; - - II, desc="Blocked, handling invalidations"; - MM, desc="Blocked, was M satisfying local GETX"; - SS, desc="Blocked, was S satisfying local GETS"; - OO, desc="Blocked, was O satisfying local GETS"; - OLSS, desc="Blocked, satisfying local GETS"; - OLSXS, desc="Blocked, satisfying local GETS"; - SLSS, desc="Blocked, satisfying local GETS"; - - OI, desc="Blocked, doing writeback, was O"; - MI, desc="Blocked, doing writeback, was M"; - MII, desc="Blocked, doing writeback, was M, got Fwd_GETX"; - OLSI, desc="Blocked, doing writeback, was OLS"; - ILSI, desc="Blocked, doing writeback, was OLS got Fwd_GETX"; + ILOW, AccessPermission:Busy, desc="local WB request, was ILO"; + ILOXW, AccessPermission:Busy, desc="local WB request, was ILOX"; + ILOSW, AccessPermission:Busy, desc="local WB request, was ILOS"; + ILOSXW, AccessPermission:Busy, desc="local WB request, was ILOSX"; + SLSW, AccessPermission:Busy, desc="local WB request, was SLS"; + OLSW, AccessPermission:Busy, desc="local WB request, was OLS"; + ILSW, AccessPermission:Busy, desc="local WB request, was ILS"; + IW, AccessPermission:Busy, desc="local WB request from only sharer, was ILS"; + OW, AccessPermission:Busy, desc="local WB request from only sharer, was OLS"; + SW, AccessPermission:Busy, desc="local WB request from only sharer, was SLS"; + OXW, AccessPermission:Busy, desc="local WB request from only sharer, was OLSX"; + OLSXW, AccessPermission:Busy, desc="local WB request from sharer, was OLSX"; + ILXW, AccessPermission:Busy, desc="local WB request, was ILX"; + + IFLS, AccessPermission:Busy, desc="Blocked, forwarded local GETS to _some_ local sharer"; + IFLO, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner"; + IFLOX, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner but chip is exclusive"; + IFLOXX, AccessPermission:Busy, desc="Blocked, forwarded local GETX to local owner/exclusive, chip is exclusive"; + IFLOSX, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner w/ other sharers, chip is exclusive"; + IFLXO, AccessPermission:Busy, desc="Blocked, forwarded local GETX to local owner with other sharers, chip is exclusive"; + + IGS, AccessPermission:Busy, desc="Semi-blocked, issued local GETS to directory"; + IGM, AccessPermission:Busy, desc="Blocked, issued local GETX to directory. Need global acks and data"; + IGMLS, AccessPermission:Busy, desc="Blocked, issued local GETX to directory but may need to INV local sharers"; + IGMO, AccessPermission:Busy, desc="Blocked, have data for local GETX but need all acks"; + IGMIO, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner with possible local sharer, may need to INV"; + OGMIO, AccessPermission:Busy, desc="Blocked, issued local GETX, was owner, may need to INV"; + IGMIOF, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETX"; + IGMIOFS, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETS"; + OGMIOF, AccessPermission:Busy, desc="Blocked, issued local GETX, was owner, waiting for global acks, got Fwd_GETX"; + + II, AccessPermission:Busy, desc="Blocked, handling invalidations"; + MM, AccessPermission:Busy, desc="Blocked, was M satisfying local GETX"; + SS, AccessPermission:Busy, desc="Blocked, was S satisfying local GETS"; + OO, AccessPermission:Busy, desc="Blocked, was O satisfying local GETS"; + OLSS, AccessPermission:Busy, desc="Blocked, satisfying local GETS"; + OLSXS, AccessPermission:Busy, desc="Blocked, satisfying local GETS"; + SLSS, AccessPermission:Busy, desc="Blocked, satisfying local GETS"; + + OI, AccessPermission:Busy, desc="Blocked, doing writeback, was O"; + MI, AccessPermission:Busy, desc="Blocked, doing writeback, was M"; + MII, AccessPermission:Busy, desc="Blocked, doing writeback, was M, got Fwd_GETX"; + OLSI, AccessPermission:Busy, desc="Blocked, doing writeback, was OLS"; + ILSI, AccessPermission:Busy, desc="Blocked, doing writeback, was OLS got Fwd_GETX"; } // EVENTS @@ -486,9 +486,6 @@ machine(L2Cache, "Token protocol") else { cache_entry.CacheState := state; } - - // Set permission - cache_entry.changePermission(AccessPermission:Read_Only); } else if (localDirectory.isTagPresent(addr)) { localDirectory[addr].DirState := state; diff --git a/src/mem/protocol/MOESI_CMP_directory-dir.sm b/src/mem/protocol/MOESI_CMP_directory-dir.sm index 19b69c64c..55afa7161 100644 --- a/src/mem/protocol/MOESI_CMP_directory-dir.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm @@ -48,28 +48,28 @@ machine(Directory, "Directory protocol") // STATES - enumeration(State, desc="Directory states", default="Directory_State_I") { + state_declaration(State, desc="Directory states", default="Directory_State_I") { // Base states - I, desc="Invalid"; - S, desc="Shared"; - O, desc="Owner"; - M, desc="Modified"; - - IS, desc="Blocked, was in idle"; - SS, desc="Blocked, was in shared"; - OO, desc="Blocked, was in owned"; - MO, desc="Blocked, going to owner or maybe modified"; - MM, desc="Blocked, going to modified"; - MM_DMA, desc="Blocked, going to I"; - - MI, desc="Blocked on a writeback"; - MIS, desc="Blocked on a writeback, but don't remove from sharers when received"; - OS, desc="Blocked on a writeback"; - OSS, desc="Blocked on a writeback, but don't remove from sharers when received"; - - XI_M, desc="In a stable state, going to I, waiting for the memory controller"; - XI_U, desc="In a stable state, going to I, waiting for an unblock"; - OI_D, desc="In O, going to I, waiting for data"; + I, AccessPermission:Invalid, desc="Invalid"; + S, AccessPermission:Read_Only, desc="Shared"; + O, AccessPermission:Read_Only, desc="Owner"; + M, AccessPermission:Read_Write, 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"; + MM_DMA, AccessPermission:Busy, desc="Blocked, going to I"; + + MI, AccessPermission:Busy, desc="Blocked on a writeback"; + MIS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received"; + OS, AccessPermission:Busy, desc="Blocked on a writeback"; + OSS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received"; + + XI_M, AccessPermission:Busy, desc="In a stable state, going to I, waiting for the memory controller"; + XI_U, AccessPermission:Busy, desc="In a stable state, going to I, waiting for an unblock"; + OI_D, AccessPermission:Busy, desc="In O, going to I, waiting for data"; } // Events diff --git a/src/mem/protocol/MOESI_CMP_directory-dma.sm b/src/mem/protocol/MOESI_CMP_directory-dma.sm index b129757b8..43503ee25 100644 --- a/src/mem/protocol/MOESI_CMP_directory-dma.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dma.sm @@ -13,10 +13,10 @@ machine(DMA, "DMA Controller") MessageBuffer reqToDir, network="To", virtual_network="1", ordered="false"; MessageBuffer respToDir, network="To", virtual_network="2", ordered="false"; - enumeration(State, desc="DMA states", default="DMA_State_READY") { - READY, desc="Ready to accept a new request"; - BUSY_RD, desc="Busy: currently processing a request"; - BUSY_WR, desc="Busy: currently processing a request"; + state_declaration(State, desc="DMA states", default="DMA_State_READY") { + READY, AccessPermission:Invalid, desc="Ready to accept a new request"; + BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; + BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; } enumeration(Event, desc="DMA events") { diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index 226f21374..160208aac 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -63,29 +63,29 @@ machine(L1Cache, "Token protocol") MessageBuffer requestToL1Cache, network="From", virtual_network="1", ordered="false"; // STATES - enumeration(State, desc="Cache states", default="L1Cache_State_I") { + state_declaration(State, desc="Cache states", default="L1Cache_State_I") { // Base states - NP, "NP", desc="Not Present"; - I, "I", desc="Idle"; - S, "S", desc="Shared"; - O, "O", desc="Owned"; - M, "M", desc="Modified (dirty)"; - MM, "MM", desc="Modified (dirty and locally modified)"; - M_W, "M^W", desc="Modified (dirty), waiting"; - MM_W, "MM^W", desc="Modified (dirty and locally modified), waiting"; + NP, AccessPermission:Invalid, "NP", desc="Not Present"; + I, AccessPermission:Invalid, "I", desc="Idle"; + S, AccessPermission:Read_Only, "S", desc="Shared"; + O, AccessPermission:Read_Only, "O", desc="Owned"; + M, AccessPermission:Read_Only, "M", desc="Modified (dirty)"; + MM, AccessPermission:Read_Write, "MM", desc="Modified (dirty and locally modified)"; + M_W, AccessPermission:Read_Only, "M^W", desc="Modified (dirty), waiting"; + MM_W, AccessPermission:Read_Write, "MM^W", desc="Modified (dirty and locally modified), waiting"; // Transient States - IM, "IM", desc="Issued GetX"; - SM, "SM", desc="Issued GetX, we still have an old copy of the line"; - OM, "OM", desc="Issued GetX, received data"; - IS, "IS", desc="Issued GetS"; + IM, AccessPermission:Busy, "IM", desc="Issued GetX"; + SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have an old copy of the line"; + OM, AccessPermission:Read_Only, "OM", desc="Issued GetX, received data"; + IS, AccessPermission:Busy, "IS", desc="Issued GetS"; // Locked states - I_L, "I^L", desc="Invalid, Locked"; - S_L, "S^L", desc="Shared, Locked"; - IM_L, "IM^L", desc="Invalid, Locked, trying to go to Modified"; - SM_L, "SM^L", desc="Shared, Locked, trying to go to Modified"; - IS_L, "IS^L", desc="Invalid, Locked, trying to go to Shared"; + I_L, AccessPermission:Busy, "I^L", desc="Invalid, Locked"; + S_L, AccessPermission:Busy, "S^L", desc="Shared, Locked"; + IM_L, AccessPermission:Busy, "IM^L", desc="Invalid, Locked, trying to go to Modified"; + SM_L, AccessPermission:Busy, "SM^L", desc="Shared, Locked, trying to go to Modified"; + IS_L, AccessPermission:Busy, "IS^L", desc="Invalid, Locked, trying to go to Shared"; } // EVENTS @@ -336,23 +336,6 @@ machine(L1Cache, "Token protocol") } cache_entry.CacheState := state; - - // Set permission - if (state == State:MM || - state == State:MM_W) { - cache_entry.changePermission(AccessPermission:Read_Write); - } else if ((state == State:S) || - (state == State:O) || - (state == State:M) || - (state == State:M_W) || - (state == State:SM) || - (state == State:S_L) || - (state == State:SM_L) || - (state == State:OM)) { - cache_entry.changePermission(AccessPermission:Read_Only); - } else { - cache_entry.changePermission(AccessPermission:Invalid); - } } } diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm index c23f98f9a..e685984c5 100644 --- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm @@ -62,17 +62,17 @@ machine(L2Cache, "Token protocol") MessageBuffer L1RequestToL2Cache, network="From", virtual_network="1", ordered="false"; // STATES - enumeration(State, desc="L2 Cache states", default="L2Cache_State_I") { + state_declaration(State, desc="L2 Cache states", default="L2Cache_State_I") { // Base states - NP, desc="Not Present"; - I, desc="Idle"; - S, desc="Shared, not present in any local L1s"; - O, desc="Owned, not present in any L1s"; - M, desc="Modified, not present in any L1s"; + NP, AccessPermission:Invalid, desc="Not Present"; + I, AccessPermission:Invalid, desc="Idle"; + S, AccessPermission:Read_Only, desc="Shared, not present in any local L1s"; + O, AccessPermission:Read_Only, desc="Owned, not present in any L1s"; + M, AccessPermission:Read_Write, desc="Modified, not present in any L1s"; // Locked states - I_L, "I^L", desc="Invalid, Locked"; - S_L, "S^L", desc="Shared, Locked"; + I_L, AccessPermission:Busy, "I^L", desc="Invalid, Locked"; + S_L, AccessPermission:Busy, "S^L", desc="Shared, Locked"; } // EVENTS @@ -208,17 +208,6 @@ machine(L2Cache, "Token protocol") } cache_entry.CacheState := state; - - // Set permission - if (state == State:I) { - cache_entry.changePermission(AccessPermission:Invalid); - } else if (state == State:S || state == State:O ) { - cache_entry.changePermission(AccessPermission:Read_Only); - } else if (state == State:M ) { - cache_entry.changePermission(AccessPermission:Read_Write); - } else { - cache_entry.changePermission(AccessPermission:Invalid); - } } } diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm index c77d46bbe..14a2f0fb2 100644 --- a/src/mem/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm @@ -52,30 +52,30 @@ machine(Directory, "Token protocol") MessageBuffer dmaRequestToDir, network="From", virtual_network="0", ordered="true"; // STATES - enumeration(State, desc="Directory states", default="Directory_State_O") { + state_declaration(State, desc="Directory states", default="Directory_State_O") { // Base states - O, desc="Owner"; - NO, desc="Not Owner"; - L, desc="Locked"; + O, AccessPermission:Read_Only, desc="Owner, memory has valid data, but not necessarily all the tokens"; + NO, AccessPermission:Invalid, desc="Not Owner"; + L, AccessPermission:Busy, desc="Locked"; // Memory wait states - can block all messages including persistent requests - O_W, desc="transitioning to Owner, waiting for memory write"; - L_O_W, desc="transitioning to Locked, waiting for memory read, could eventually return to O"; - L_NO_W, desc="transitioning to Locked, waiting for memory read, eventually return to NO"; - DR_L_W, desc="transitioning to Locked underneath a DMA read, waiting for memory data"; - DW_L_W, desc="transitioning to Locked underneath a DMA write, waiting for memory ack"; - NO_W, desc="transitioning to Not Owner, waiting for memory read"; - O_DW_W, desc="transitioning to Owner, waiting for memory before DMA ack"; - O_DR_W, desc="transitioning to Owner, waiting for memory before DMA data"; + O_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory write"; + L_O_W, AccessPermission:Busy, desc="transitioning to Locked, waiting for memory read, could eventually return to O"; + L_NO_W, AccessPermission:Busy, desc="transitioning to Locked, waiting for memory read, eventually return to NO"; + DR_L_W, AccessPermission:Busy, desc="transitioning to Locked underneath a DMA read, waiting for memory data"; + DW_L_W, AccessPermission:Busy, desc="transitioning to Locked underneath a DMA write, waiting for memory ack"; + NO_W, AccessPermission:Busy, desc="transitioning to Not Owner, waiting for memory read"; + O_DW_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory before DMA ack"; + O_DR_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory before DMA data"; // DMA request transient states - must respond to persistent requests - O_DW, desc="issued GETX for DMA write, waiting for all tokens"; - NO_DW, desc="issued GETX for DMA write, waiting for all tokens"; - NO_DR, desc="issued GETS for DMA read, waiting for data"; + O_DW, AccessPermission:Busy, desc="issued GETX for DMA write, waiting for all tokens"; + NO_DW, AccessPermission:Busy, desc="issued GETX for DMA write, waiting for all tokens"; + NO_DR, AccessPermission:Busy, desc="issued GETS for DMA read, waiting for data"; // DMA request in progress - competing with a CPU persistent request - DW_L, desc="issued GETX for DMA write, CPU persistent request must complete first"; - DR_L, desc="issued GETS for DMA read, CPU persistent request must complete first"; + DW_L, AccessPermission:Busy, desc="issued GETX for DMA write, CPU persistent request must complete first"; + DR_L, AccessPermission:Busy, desc="issued GETS for DMA read, CPU persistent request must complete first"; } diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm index 666117a10..e80f91995 100644 --- a/src/mem/protocol/MOESI_CMP_token-dma.sm +++ b/src/mem/protocol/MOESI_CMP_token-dma.sm @@ -35,10 +35,10 @@ machine(DMA, "DMA Controller") MessageBuffer responseFromDir, network="From", virtual_network="5", ordered="true", no_vector="true"; MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true"; - enumeration(State, desc="DMA states", default="DMA_State_READY") { - READY, desc="Ready to accept a new request"; - BUSY_RD, desc="Busy: currently processing a request"; - BUSY_WR, desc="Busy: currently processing a request"; + state_declaration(State, desc="DMA states", default="DMA_State_READY") { + READY, AccessPermission:Invalid, desc="Ready to accept a new request"; + BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; + BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; } enumeration(Event, desc="DMA events") { diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 9592e3881..05d74038b 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -54,31 +54,31 @@ machine(L1Cache, "AMD Hammer-like protocol") // STATES - enumeration(State, desc="Cache states", default="L1Cache_State_I") { + state_declaration(State, desc="Cache states", default="L1Cache_State_I") { // Base states - I, desc="Idle"; - S, desc="Shared"; - O, desc="Owned"; - M, desc="Modified (dirty)"; - MM, desc="Modified (dirty and locally modified)"; + I, AccessPermission:Invalid, desc="Idle"; + S, AccessPermission:Read_Only, desc="Shared"; + O, AccessPermission:Read_Only, desc="Owned"; + M, AccessPermission:Read_Only, desc="Modified (dirty)"; + MM, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)"; // Transient States - IM, "IM", desc="Issued GetX"; - SM, "SM", desc="Issued GetX, we still have an old copy of the line"; - OM, "OM", desc="Issued GetX, received data"; - ISM, "ISM", desc="Issued GetX, received data, waiting for all acks"; - M_W, "M^W", desc="Issued GetS, received exclusive data"; - MM_W, "MM^W", desc="Issued GetX, received exclusive data"; - IS, "IS", desc="Issued GetS"; - SS, "SS", desc="Issued GetS, received data, waiting for all acks"; - OI, "OI", desc="Issued PutO, waiting for ack"; - MI, "MI", desc="Issued PutX, waiting for ack"; - II, "II", desc="Issued PutX/O, saw Other_GETS or Other_GETX, waiting for ack"; - IT, "IT", desc="Invalid block transferring to L1"; - ST, "ST", desc="S block transferring to L1"; - OT, "OT", desc="O block transferring to L1"; - MT, "MT", desc="M block transferring to L1"; - MMT, "MMT", desc="MM block transferring to L1"; + IM, AccessPermission:Busy, "IM", desc="Issued GetX"; + SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have a valid copy of the line"; + OM, AccessPermission:Read_Only, "OM", desc="Issued GetX, received data"; + ISM, AccessPermission:Read_Only, "ISM", desc="Issued GetX, received valid data, waiting for all acks"; + M_W, AccessPermission:Read_Only, "M^W", desc="Issued GetS, received exclusive data"; + MM_W, AccessPermission:Read_Write, "MM^W", desc="Issued GetX, received exclusive data"; + IS, AccessPermission:Busy, "IS", desc="Issued GetS"; + SS, AccessPermission:Read_Only, "SS", desc="Issued GetS, received data, waiting for all acks"; + OI, AccessPermission:Busy, "OI", desc="Issued PutO, waiting for ack"; + MI, AccessPermission:Busy, "MI", desc="Issued PutX, waiting for ack"; + II, AccessPermission:Busy, "II", desc="Issued PutX/O, saw Other_GETS or Other_GETX, waiting for ack"; + IT, AccessPermission:Busy, "IT", desc="Invalid block transferring to L1"; + ST, AccessPermission:Busy, "ST", desc="S block transferring to L1"; + OT, AccessPermission:Busy, "OT", desc="O block transferring to L1"; + MT, AccessPermission:Busy, "MT", desc="M block transferring to L1"; + MMT, AccessPermission:Busy, "MMT", desc="MM block transferring to L1"; } // EVENTS @@ -209,23 +209,6 @@ machine(L1Cache, "AMD Hammer-like protocol") if (is_valid(cache_entry)) { cache_entry.CacheState := state; - - // Set permission - if ((state == State:MM) || - (state == State:MM_W)) { - cache_entry.changePermission(AccessPermission:Read_Write); - } else if (state == State:S || - state == State:O || - state == State:M || - state == State:M_W || - state == State:SM || - state == State:ISM || - state == State:OM || - state == State:SS) { - cache_entry.changePermission(AccessPermission:Read_Only); - } else { - cache_entry.changePermission(AccessPermission:Invalid); - } } } diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm index 67c375fbc..8f6cb14b7 100644 --- a/src/mem/protocol/MOESI_hammer-dir.sm +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -57,37 +57,37 @@ machine(Directory, "AMD Hammer-like protocol") MessageBuffer dmaRequestToDir, network="From", virtual_network="0", ordered="true"; // STATES - enumeration(State, desc="Directory states", default="Directory_State_E") { + state_declaration(State, desc="Directory states", default="Directory_State_E") { // Base states - NX, desc="Not Owner, probe filter entry exists, block in O at Owner"; - NO, desc="Not Owner, probe filter entry exists, block in E/M at Owner"; - S, desc="Data clean, probe filter entry exists pointing to the current owner"; - O, desc="Data clean, probe filter entry exists"; - E, desc="Exclusive Owner, no probe filter entry"; - - O_R, desc="Was data Owner, replacing probe filter entry"; - S_R, desc="Was Not Owner or Sharer, replacing probe filter entry"; - NO_R, desc="Was Not Owner or Sharer, replacing probe filter entry"; - - NO_B, "NO^B", desc="Not Owner, Blocked"; - NO_B_X, "NO^B", desc="Not Owner, Blocked, next queued request GETX"; - NO_B_S, "NO^B", desc="Not Owner, Blocked, next queued request GETS"; - NO_B_S_W, "NO^B", desc="Not Owner, Blocked, forwarded merged GETS, waiting for responses"; - O_B, "O^B", desc="Owner, Blocked"; - NO_B_W, desc="Not Owner, Blocked, waiting for Dram"; - O_B_W, desc="Owner, Blocked, waiting for Dram"; - NO_W, desc="Not Owner, waiting for Dram"; - O_W, desc="Owner, waiting for Dram"; - NO_DW_B_W, desc="Not Owner, Dma Write waiting for Dram and cache responses"; - NO_DR_B_W, desc="Not Owner, Dma Read waiting for Dram and cache responses"; - NO_DR_B_D, desc="Not Owner, Dma Read waiting for cache responses including dirty data"; - NO_DR_B, desc="Not Owner, Dma Read waiting for cache responses"; - NO_DW_W, desc="Not Owner, Dma Write waiting for Dram"; - O_DR_B_W, desc="Owner, Dma Read waiting for Dram and cache responses"; - O_DR_B, desc="Owner, Dma Read waiting for cache responses"; - WB, desc="Blocked on a writeback"; - WB_O_W, desc="Blocked on memory write, will go to O"; - WB_E_W, desc="Blocked on memory write, will go to E"; + 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"; + 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"; } // Events diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm index dbb5ffe68..d80c55c73 100644 --- a/src/mem/protocol/MOESI_hammer-dma.sm +++ b/src/mem/protocol/MOESI_hammer-dma.sm @@ -35,10 +35,12 @@ machine(DMA, "DMA Controller") MessageBuffer responseFromDir, network="From", virtual_network="1", ordered="true", no_vector="true"; MessageBuffer reqToDirectory, network="To", virtual_network="0", ordered="false", no_vector="true"; - enumeration(State, desc="DMA states", default="DMA_State_READY") { - READY, desc="Ready to accept a new request"; - BUSY_RD, desc="Busy: currently processing a request"; - BUSY_WR, desc="Busy: currently processing a request"; + state_declaration(State, + desc="DMA states", + default="DMA_State_READY") { + READY, AccessPermission:Invalid, desc="Ready to accept a new request"; + BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request"; + BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request"; } enumeration(Event, desc="DMA events") { diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index 1d68768e4..f8783230e 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -117,9 +117,7 @@ external_type(DirectoryMemory) { void invalidateBlock(Address); } -external_type(AbstractCacheEntry, primitive="yes") { - void changePermission(AccessPermission); -} +external_type(AbstractCacheEntry, primitive="yes"); external_type(CacheMemory) { bool cacheAvail(Address); diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc index d53697c76..137a6c950 100644 --- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc +++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.cc @@ -30,8 +30,8 @@ AbstractCacheEntry::AbstractCacheEntry() { - m_Address.setAddress(0); m_Permission = AccessPermission_NotPresent; + m_Address.setAddress(0); m_locked = -1; } @@ -39,16 +39,10 @@ AbstractCacheEntry::~AbstractCacheEntry() { } -AccessPermission -AbstractCacheEntry::getPermission() const -{ - return m_Permission; -} - void AbstractCacheEntry::changePermission(AccessPermission new_perm) { - m_Permission = new_perm; + AbstractEntry::changePermission(new_perm); if ((new_perm == AccessPermission_Invalid) || (new_perm == AccessPermission_NotPresent)) { m_locked = -1; diff --git a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh index 87c96a9cb..69333f481 100644 --- a/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh +++ b/src/mem/ruby/slicc_interface/AbstractCacheEntry.hh @@ -48,15 +48,12 @@ class AbstractCacheEntry : public AbstractEntry AbstractCacheEntry(); virtual ~AbstractCacheEntry() = 0; - // Get/Set permission of cache entry - AccessPermission getPermission() const; + // Get/Set permission of the entry void changePermission(AccessPermission new_perm); Address m_Address; // Address of this block, required by CacheMemory Time m_LastRef; // Last time this block was referenced, required // by CacheMemory - AccessPermission m_Permission; // Access permission for this - // block, required by CacheMemory int m_locked; // Holds info whether the address is locked, // required for implementing LL/SC }; diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.cc b/src/mem/ruby/slicc_interface/AbstractEntry.cc index d66258eef..51f16df6a 100644 --- a/src/mem/ruby/slicc_interface/AbstractEntry.cc +++ b/src/mem/ruby/slicc_interface/AbstractEntry.cc @@ -30,8 +30,21 @@ AbstractEntry::AbstractEntry() { + m_Permission = AccessPermission_NotPresent; } AbstractEntry::~AbstractEntry() { } + +AccessPermission +AbstractEntry::getPermission() const +{ + return m_Permission; +} + +void +AbstractEntry::changePermission(AccessPermission new_perm) +{ + m_Permission = new_perm; +} diff --git a/src/mem/ruby/slicc_interface/AbstractEntry.hh b/src/mem/ruby/slicc_interface/AbstractEntry.hh index 19852fbe9..6752bf6c4 100644 --- a/src/mem/ruby/slicc_interface/AbstractEntry.hh +++ b/src/mem/ruby/slicc_interface/AbstractEntry.hh @@ -43,11 +43,18 @@ class AbstractEntry AbstractEntry(); virtual ~AbstractEntry() = 0; + // Get/Set permission of the entry + AccessPermission getPermission() const; + void changePermission(AccessPermission new_perm); + // The methods below are those called by ruby runtime, add when it // is absolutely necessary and should all be virtual function. virtual DataBlock& getDataBlk() = 0; virtual void print(std::ostream& out) const = 0; + + AccessPermission m_Permission; // Access permission for this + // block, required by CacheMemory }; inline std::ostream& diff --git a/src/mem/slicc/ast/StateDeclAST.py b/src/mem/slicc/ast/StateDeclAST.py new file mode 100644 index 000000000..a1bbd74ae --- /dev/null +++ b/src/mem/slicc/ast/StateDeclAST.py @@ -0,0 +1,79 @@ +# Copyright (c) 2011 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Func, Type + +class StateDeclAST(DeclAST): + def __init__(self, slicc, type_ast, pairs, states): + super(StateDeclAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.states = states + + def __repr__(self): + return "[StateDecl: %s]" % (self.type_ast) + + def files(self, parent=None): + if "external" in self: + return set() + + if parent: + ident = "%s_%s" % (parent, self.type_ast.ident) + else: + ident = self.type_ast.ident + s = set(("%s.hh" % ident, "%s.cc" % ident)) + return s + + def generate(self): + ident = str(self.type_ast) + + # Make the new type + t = Type(self.symtab, ident, self.location, self.pairs, + self.state_machine) + self.symtab.newSymbol(t) + + # Add all of the states of the type to it + for state in self.states: + state.generate(t) + + # Add the implicit State_to_string method - FIXME, this is a bit dirty + func_id = "%s_to_string" % t.c_ident + + pairs = { "external" : "yes" } + func = Func(self.symtab, func_id, self.location, + self.symtab.find("std::string", Type), [ t ], [], "", + pairs, None) + self.symtab.newSymbol(func) + + # Add the State_to_permission method + func_id = "%s_to_permission" % t.c_ident + + pairs = { "external" : "yes" } + func = Func(self.symtab, func_id, self.location, + self.symtab.find("AccessPermission", Type), [ t ], [], "", + pairs, None) + self.symtab.newSymbol(func) diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.py b/src/mem/slicc/ast/TypeFieldEnumAST.py index 138fff793..398604550 100644 --- a/src/mem/slicc/ast/TypeFieldEnumAST.py +++ b/src/mem/slicc/ast/TypeFieldEnumAST.py @@ -39,6 +39,9 @@ class TypeFieldEnumAST(TypeFieldAST): return "[TypeFieldEnum: %r]" % self.field_id def generate(self, type): + if str(type) == "State": + self.error("States must in a State Declaration, not a normal enum.") + # Add enumeration if not type.enumAdd(self.field_id, self.pairs_ast.pairs): self.error("Duplicate enumeration: %s:%s" % (type, self.field_id)) @@ -46,12 +49,6 @@ class TypeFieldEnumAST(TypeFieldAST): # Fill machine info machine = self.symtab.state_machine - if str(type) == "State": - if not machine: - self.error("State declaration not part of a machine.") - s = State(self.symtab, self.field_id, self.location, self.pairs) - machine.addState(s) - if str(type) == "Event": if not machine: self.error("Event declaration not part of a machine.") diff --git a/src/mem/slicc/ast/TypeFieldStateAST.py b/src/mem/slicc/ast/TypeFieldStateAST.py new file mode 100644 index 000000000..aafa241dd --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldStateAST.py @@ -0,0 +1,61 @@ +# Copyright (c) 2011 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.TypeFieldAST import TypeFieldAST +from slicc.symbols import Event, State + +class TypeFieldStateAST(TypeFieldAST): + def __init__(self, slicc, field_id, perm_ast, pairs_ast): + super(TypeFieldStateAST, self).__init__(slicc, pairs_ast) + + self.field_id = field_id + self.perm_ast = perm_ast + if not (perm_ast.type_ast.ident == "AccessPermission"): + self.error("AccessPermission enum value must be specified") + self.pairs_ast = pairs_ast + + def __repr__(self): + return "[TypeFieldState: %r]" % self.field_id + + def generate(self, type): + if not str(type) == "State": + self.error("State Declaration must be of type State.") + + # Add enumeration + if not type.enumAdd(self.field_id, self.pairs_ast.pairs): + self.error("Duplicate enumeration: %s:%s" % (type, self.field_id)) + + # Fill machine info + machine = self.symtab.state_machine + + if not machine: + self.error("State declaration not part of a machine.") + s = State(self.symtab, self.field_id, self.location, self.pairs) + machine.addState(s) + + type.statePermPairAdd(s, self.perm_ast.value) + + diff --git a/src/mem/slicc/ast/__init__.py b/src/mem/slicc/ast/__init__.py index 4af6c2036..c0f54a9a3 100644 --- a/src/mem/slicc/ast/__init__.py +++ b/src/mem/slicc/ast/__init__.py @@ -61,6 +61,7 @@ from slicc.ast.PairListAST import * from slicc.ast.PeekStatementAST import * from slicc.ast.ReturnStatementAST import * from slicc.ast.StallAndWaitStatementAST import * +from slicc.ast.StateDeclAST import * from slicc.ast.StatementAST import * from slicc.ast.StatementListAST import * from slicc.ast.StaticCastAST import * @@ -71,6 +72,7 @@ from slicc.ast.TypeFieldAST import * from slicc.ast.TypeFieldEnumAST import * from slicc.ast.TypeFieldMemberAST import * from slicc.ast.TypeFieldMethodAST import * +from slicc.ast.TypeFieldStateAST import * from slicc.ast.VarExprAST import * from slicc.ast.WakeUpAllDependentsStatementAST import * from slicc.ast.WakeUpDependentsStatementAST import * diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py index 823e08819..448954e63 100644 --- a/src/mem/slicc/parser.py +++ b/src/mem/slicc/parser.py @@ -156,6 +156,7 @@ class SLICC(Grammar): 'structure' : 'STRUCT', 'external_type' : 'EXTERN_TYPE', 'enumeration' : 'ENUM', + 'state_declaration' : 'STATE_DECL', 'peek' : 'PEEK', 'stall_and_wait' : 'STALL_AND_WAIT', 'wake_up_dependents' : 'WAKE_UP_DEPENDENTS', @@ -329,6 +330,12 @@ class SLICC(Grammar): p[4]["enumeration"] = "yes" p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7]) + def p_decl__state_decl(self, p): + "decl : STATE_DECL '(' type pairs ')' '{' type_states '}'" + p[4]["enumeration"] = "yes" + p[4]["state_decl"] = "yes" + p[0] = ast.StateDeclAST(self, p[3], p[4], p[7]) + def p_decl__object(self, p): "decl : type ident pairs SEMI" p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3]) @@ -387,6 +394,19 @@ class SLICC(Grammar): "type_enum : ident pairs SEMI" p[0] = ast.TypeFieldEnumAST(self, p[1], p[2]) + # States + def p_type_states__list(self, p): + "type_states : type_state type_states" + p[0] = [ p[1] ] + p[2] + + def p_type_states__empty(self, p): + "type_states : empty" + p[0] = [] + + def p_type_state(self, p): + "type_state : ident ',' enumeration pairs SEMI" + p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4]) + # Type def p_types__multiple(self, p): "types : type ',' types" diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index 1251196c9..3c5f860ea 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -347,6 +347,8 @@ 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: @@ -850,6 +852,15 @@ $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: @@ -1090,10 +1101,12 @@ ${ident}_Controller::doTransition(${ident}_Event event, ''') if self.TBEType != None and self.EntryType != None: code('${ident}_setState(m_tbe_ptr, m_cache_entry_ptr, addr, next_state);') + code('set_permission(m_cache_entry_ptr, ${ident}_State_to_permission(next_state));') elif self.TBEType != None: code('${ident}_setState(m_tbe_ptr, addr, next_state);') elif self.EntryType != None: code('${ident}_setState(m_cache_entry_ptr, addr, next_state);') + code('set_permission(m_cache_entry_ptr, ${ident}_State_to_permission(next_state));') else: code('${ident}_setState(addr, next_state);') diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py index e521d544f..da9ecba3a 100644 --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -100,6 +100,9 @@ class Type(Symbol): self.isMachineType = (ident == "MachineType") + self.isStateDecl = ("state_decl" in self) + self.statePermPairs = [] + self.data_members = orderdict() # Methods @@ -158,6 +161,9 @@ class Type(Symbol): def methodIdAbstract(self, name, param_type_vec): return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ]) + def statePermPairAdd(self, state_name, perm_name): + self.statePermPairs.append([state_name, perm_name]) + def methodAdd(self, name, return_type, param_type_vec): ident = self.methodId(name, param_type_vec) if ident in self.methods: @@ -446,6 +452,11 @@ ${{self.c_ident}}::print(ostream& out) const #include #include "mem/ruby/common/Global.hh" +''') + if self.isStateDecl: + code('#include "mem/protocol/AccessPermission.hh"') + + code(''' // Class definition /** \\enum ${{self.c_ident}} @@ -491,6 +502,14 @@ int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); for enum in self.enums.itervalues(): code('#define MACHINETYPE_${{enum.ident}} 1') + if self.isStateDecl: + code(''' + +// Code to convert the current state to an access permission +AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj); + +''') + # Trailer code(''' std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); @@ -517,6 +536,27 @@ std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); using namespace std; +''') + + if self.isStateDecl: + code(''' +// Code to convert the current state to an access permission +AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) +{ + switch(obj) { +''') + # For each case + code.indent() + for statePerm in self.statePermPairs: + code(' case ${{self.c_ident}}_${{statePerm[0]}}:') + code(' return AccessPermission_${{statePerm[1]}};') + code.dedent() + code (''' + default: + panic("Unknown state access permission converstion for ${{self.c_ident}}"); + } +} + ''') if self.isMachineType: