summaryrefslogtreecommitdiff
path: root/src/mem/ruby/protocol/RubySlicc_Exports.sm
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/protocol/RubySlicc_Exports.sm')
-rw-r--r--src/mem/ruby/protocol/RubySlicc_Exports.sm355
1 files changed, 355 insertions, 0 deletions
diff --git a/src/mem/ruby/protocol/RubySlicc_Exports.sm b/src/mem/ruby/protocol/RubySlicc_Exports.sm
new file mode 100644
index 000000000..8e17f9849
--- /dev/null
+++ b/src/mem/ruby/protocol/RubySlicc_Exports.sm
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+// Declarations of external types that are common to all protocols
+external_type(int, primitive="yes", default="0");
+external_type(bool, primitive="yes", default="false");
+external_type(std::string, primitive="yes");
+external_type(uint32_t, primitive="yes");
+external_type(uint64_t, primitive="yes");
+external_type(PacketPtr, primitive="yes");
+external_type(Packet, primitive="yes");
+external_type(Addr, primitive="yes");
+external_type(Cycles, primitive="yes", default="Cycles(0)");
+external_type(Tick, primitive="yes", default="0");
+
+structure(WriteMask, external="yes", desc="...") {
+ void clear();
+ bool cmpMask(WriteMask);
+ bool isEmpty();
+ bool isFull();
+ bool isOverlap(WriteMask);
+ void orMask(WriteMask);
+ void fillMask();
+}
+
+structure(DataBlock, external = "yes", desc="..."){
+ void clear();
+ void copyPartial(DataBlock, int, int);
+ void copyPartial(DataBlock, WriteMask);
+ void atomicPartial(DataBlock, WriteMask);
+}
+
+bool testAndRead(Addr addr, DataBlock datablk, Packet *pkt);
+bool testAndReadMask(Addr addr, DataBlock datablk, WriteMask mask, Packet *pkt);
+bool testAndWrite(Addr addr, DataBlock datablk, Packet *pkt);
+
+// AccessPermission
+// The following five states define the access permission of all memory blocks.
+// These permissions have multiple uses. They coordinate locking and
+// synchronization primitives, as well as enable functional accesses.
+// One should not need to add any additional permission values and it is very
+// risky to do so.
+enumeration(AccessPermission, desc="...", default="AccessPermission_NotPresent") {
+ // Valid data
+ 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";
+ // In Broadcast/Snoop protocols, memory has no idea if it is exclusive owner
+ // or not of a block, making it hard to make the logic of having only one
+ // read_write block in the system impossible. This is to allow the memory to
+ // say, "I have the block" and for the RubyPort logic to know that this is a
+ // last-resort block if there are no writable copies in the caching hierarchy.
+ // This is not supposed to be used in directory or token protocols where
+ // memory/NB has an idea of what is going on in the whole system.
+ Backing_Store, desc="for memory in Broadcast/Snoop protocols";
+
+ // Invalid data
+ Invalid, desc="block is in an Invalid base state";
+ NotPresent, desc="block is NotPresent";
+ Busy, desc="block is in a transient state, currently invalid";
+}
+//HSA scopes
+enumeration(HSAScope, desc="...", default="HSAScope_UNSPECIFIED") {
+ UNSPECIFIED, desc="Unspecified scope";
+ NOSCOPE, desc="Explictly unscoped";
+ WAVEFRONT, desc="Wavefront scope";
+ WORKGROUP, desc="Workgroup scope";
+ DEVICE, desc="Device scope";
+ SYSTEM, desc="System scope";
+}
+
+// HSA segment types
+enumeration(HSASegment, desc="...", default="HSASegment_GLOBAL") {
+ GLOBAL, desc="Global segment";
+ GROUP, desc="Group segment";
+ PRIVATE, desc="Private segment";
+ KERNARG, desc="Kernarg segment";
+ READONLY, desc="Readonly segment";
+ SPILL, desc="Spill segment";
+ ARG, desc="Arg segment";
+}
+
+// TesterStatus
+enumeration(TesterStatus, desc="...") {
+ Idle, desc="Idle";
+ Action_Pending, desc="Action Pending";
+ Ready, desc="Ready";
+ Check_Pending, desc="Check Pending";
+}
+
+// InvalidateGeneratorStatus
+enumeration(InvalidateGeneratorStatus, desc="...") {
+ Load_Waiting, desc="Load waiting to be issued";
+ Load_Pending, desc="Load issued";
+ Inv_Waiting, desc="Store (invalidate) waiting to be issued";
+ Inv_Pending, desc="Store (invalidate) issued";
+}
+
+// SeriesRequestGeneratorStatus
+enumeration(SeriesRequestGeneratorStatus, desc="...") {
+ Thinking, desc="Doing work before next action";
+ Request_Pending, desc="Request pending";
+}
+
+// LockStatus
+enumeration(LockStatus, desc="...") {
+ Unlocked, desc="Lock is not held";
+ Locked, desc="Lock is held";
+}
+
+// SequencerStatus
+enumeration(SequencerStatus, desc="...") {
+ Idle, desc="Idle";
+ Pending, desc="Pending";
+}
+
+enumeration(TransitionResult, desc="...") {
+ Valid, desc="Valid transition";
+ ResourceStall, desc="Stalled due to insufficient resources";
+ ProtocolStall, desc="Protocol specified stall";
+ Reject, desc="Rejected because of a type mismatch";
+}
+
+// RubyRequestType
+enumeration(RubyRequestType, desc="...", default="RubyRequestType_NULL") {
+ LD, desc="Load";
+ ST, desc="Store";
+ ATOMIC, desc="Atomic Load/Store -- depricated. use ATOMIC_RETURN or ATOMIC_NO_RETURN";
+ ATOMIC_RETURN, desc="Atomic Load/Store, return data";
+ ATOMIC_NO_RETURN, desc="Atomic Load/Store, do not return data";
+ IFETCH, desc="Instruction fetch";
+ IO, desc="I/O";
+ REPLACEMENT, desc="Replacement";
+ Load_Linked, desc="";
+ Store_Conditional, desc="";
+ RMW_Read, desc="";
+ RMW_Write, desc="";
+ Locked_RMW_Read, desc="";
+ Locked_RMW_Write, desc="";
+ COMMIT, desc="Commit version";
+ NULL, desc="Invalid request type";
+ FLUSH, desc="Flush request type";
+ Release, desc="Release operation";
+ Acquire, desc="Acquire opertion";
+ AcquireRelease, desc="Acquire and Release opertion";
+}
+
+enumeration(SequencerRequestType, desc="...", default="SequencerRequestType_NULL") {
+ Default, desc="Replace this with access_types passed to the DMA Ruby object";
+ LD, desc="Load";
+ ST, desc="Store";
+ ATOMIC, desc="Atomic Load/Store";
+ REPLACEMENT, desc="Replacement";
+ FLUSH, desc="Flush request type";
+ NULL, desc="Invalid request type";
+}
+
+enumeration(CacheRequestType, desc="...", default="CacheRequestType_NULL") {
+ DataArrayRead, desc="Read access to the cache's data array";
+ DataArrayWrite, desc="Write access to the cache's data array";
+ TagArrayRead, desc="Read access to the cache's tag array";
+ TagArrayWrite, desc="Write access to the cache's tag array";
+}
+
+enumeration(CacheResourceType, desc="...", default="CacheResourceType_NULL") {
+ DataArray, desc="Access to the cache's data array";
+ TagArray, desc="Access to the cache's tag array";
+}
+
+enumeration(DirectoryRequestType, desc="...", default="DirectoryRequestType_NULL") {
+ Default, desc="Replace this with access_types passed to the Directory Ruby object";
+}
+
+enumeration(DMASequencerRequestType, desc="...", default="DMASequencerRequestType_NULL") {
+ Default, desc="Replace this with access_types passed to the DMA Ruby object";
+}
+
+enumeration(MemoryControlRequestType, desc="...", default="MemoryControlRequestType_NULL") {
+ Default, desc="Replace this with access_types passed to the DMA Ruby object";
+}
+
+
+// These are statically defined types of states machines that we can have.
+// If you want to add a new machine type, edit this enum. It is not necessary
+// for a protocol to have state machines defined for the all types here. But
+// you cannot use anything other than the ones defined here. Also, a protocol
+// can have only one state machine for a given type.
+enumeration(MachineType, desc="...", default="MachineType_NULL") {
+ L0Cache, desc="L0 Cache Mach";
+ L1Cache, desc="L1 Cache Mach";
+ L2Cache, desc="L2 Cache Mach";
+ L3Cache, desc="L3 Cache Mach";
+ Directory, desc="Directory Mach";
+ DMA, desc="DMA Mach";
+ Collector, desc="Collector Mach";
+ L1Cache_wCC, desc="L1 Cache Mach to track cache-to-cache transfer (used for miss latency profile)";
+ L2Cache_wCC, desc="L2 Cache Mach to track cache-to-cache transfer (used for miss latency profile)";
+ CorePair, desc="Cache Mach (2 cores, Private L1Ds, Shared L1I & L2)";
+ TCP, desc="GPU L1 Data Cache (Texture Cache per Pipe)";
+ TCC, desc="GPU L2 Shared Cache (Texture Cache per Channel)";
+ TCCdir, desc="Directory at the GPU L2 Cache (TCC)";
+ SQC, desc="GPU L1 Instr Cache (Sequencer Cache)";
+ RegionDir, desc="Region-granular directory";
+ RegionBuffer,desc="Region buffer for CPU and GPU";
+ NULL, desc="null mach type";
+}
+
+// MessageSizeType
+enumeration(MessageSizeType, desc="...") {
+ Control, desc="Control Message";
+ Data, desc="Data Message";
+ Request_Control, desc="Request";
+ Reissue_Control, desc="Reissued request";
+ Response_Data, desc="data response";
+ ResponseL2hit_Data, desc="data response";
+ ResponseLocal_Data, desc="data response";
+ Response_Control, desc="non-data response";
+ Writeback_Data, desc="Writeback data";
+ Writeback_Control, desc="Writeback control";
+ Broadcast_Control, desc="Broadcast control";
+ Multicast_Control, desc="Multicast control";
+ Forwarded_Control, desc="Forwarded control";
+ Invalidate_Control, desc="Invalidate control";
+ Unblock_Control, desc="Unblock control";
+ Persistent_Control, desc="Persistent request activation messages";
+ Completion_Control, desc="Completion messages";
+}
+
+// AccessType
+enumeration(AccessType, desc="...") {
+ Read, desc="Reading from cache";
+ Write, desc="Writing to cache";
+}
+
+// RubyAccessMode
+enumeration(RubyAccessMode, default="RubyAccessMode_User", desc="...") {
+ Supervisor, desc="Supervisor mode";
+ User, desc="User mode";
+ Device, desc="Device mode";
+}
+
+enumeration(PrefetchBit, default="PrefetchBit_No", desc="...") {
+ No, desc="No, not a prefetch";
+ Yes, desc="Yes, a prefetch";
+ L1_HW, desc="This is a L1 hardware prefetch";
+ L2_HW, desc="This is a L2 hardware prefetch";
+}
+
+// CacheMsg
+structure(SequencerMsg, desc="...", interface="Message") {
+ Addr LineAddress, desc="Line address for this request";
+ Addr PhysicalAddress, desc="Physical address for this request";
+ SequencerRequestType Type, desc="Type of request (LD, ST, etc)";
+ Addr ProgramCounter, desc="Program counter of the instruction that caused the miss";
+ RubyAccessMode AccessMode, desc="user/supervisor access type";
+ DataBlock DataBlk, desc="Data";
+ int Len, desc="size in bytes of access";
+ PrefetchBit Prefetch, desc="Is this a prefetch request";
+ MessageSizeType MessageSize, default="MessageSizeType_Request_Control";
+
+ bool functionalRead(Packet *pkt) {
+ return testAndRead(PhysicalAddress, DataBlk, pkt);
+ }
+
+ bool functionalWrite(Packet *pkt) {
+ return testAndWrite(PhysicalAddress, DataBlk, pkt);
+ }
+}
+
+// MaskPredictorType
+enumeration(MaskPredictorType, "MaskPredictorType_Undefined", desc="...") {
+ Undefined, desc="Undefined";
+ AlwaysUnicast, desc="AlwaysUnicast";
+ TokenD, desc="TokenD";
+ AlwaysBroadcast, desc="AlwaysBroadcast";
+ TokenB, desc="TokenB";
+ TokenNull, desc="TokenNull";
+ Random, desc="Random";
+ Pairwise, desc="Pairwise";
+ Owner, desc="Owner";
+ BroadcastIfShared, desc="Broadcast-If-Shared";
+ BroadcastCounter, desc="Broadcast Counter";
+ Group, desc="Group";
+ Counter, desc="Counter";
+ StickySpatial, desc="StickySpatial";
+ OwnerBroadcast, desc="Owner/Broadcast Hybrid";
+ OwnerGroup, desc="Owner/Group Hybrid";
+ OwnerBroadcastMod, desc="Owner/Broadcast Hybrid-Mod";
+ OwnerGroupMod, desc="Owner/Group Hybrid-Mod";
+ LastNMasks, desc="Last N Masks";
+ BandwidthAdaptive, desc="Bandwidth Adaptive";
+}
+
+// MaskPredictorIndex
+enumeration(MaskPredictorIndex, "MaskPredictorIndex_Undefined", desc="...") {
+ Undefined, desc="Undefined";
+ DataBlock, desc="Data Block";
+ PC, desc="Program Counter";
+}
+
+// MaskPredictorTraining
+enumeration(MaskPredictorTraining, "MaskPredictorTraining_Undefined", desc="...") {
+ Undefined, desc="Undefined";
+ None, desc="None";
+ Implicit, desc="Implicit";
+ Explicit, desc="Explicit";
+ Both, desc="Both";
+}
+
+// Request Status
+enumeration(RequestStatus, desc="...", default="RequestStatus_NULL") {
+ Ready, desc="The sequencer is ready and the request does not alias";
+ Issued, desc="The sequencer successfully issued the request";
+ BufferFull, desc="Can not issue because the sequencer is full";
+ Aliased, desc="This request aliased with a currently outstanding request";
+ NULL, desc="";
+}
+
+// LinkDirection
+enumeration(LinkDirection, desc="...") {
+ In, desc="Inward link direction";
+ Out, desc="Outward link direction";
+}