1/*
2 * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
3 * Copyright (c) 2011 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30// Declarations of external types that are common to all protocols
31external_type(int, primitive="yes", default="0");
32external_type(bool, primitive="yes", default="false");
33external_type(std::string, primitive="yes");
34external_type(uint32_t, primitive="yes");
35external_type(uint64_t, primitive="yes");
36external_type(PacketPtr, primitive="yes");
37external_type(Packet, primitive="yes");
38external_type(Addr, primitive="yes");
39external_type(Cycles, primitive="yes", default="Cycles(0)");
40external_type(Tick, primitive="yes", default="0");
41
42structure(WriteMask, external="yes", desc="...") {
43  void clear();
44  bool cmpMask(WriteMask);
45  bool isEmpty();
46  bool isFull();
47  bool isOverlap(WriteMask);
48  void orMask(WriteMask);
49  void fillMask();
50}
51
52structure(DataBlock, external = "yes", desc="..."){
53  void clear();
54  void copyPartial(DataBlock, int, int);
55  void copyPartial(DataBlock, WriteMask);
56  void atomicPartial(DataBlock, WriteMask);
57}
58
59bool testAndRead(Addr addr, DataBlock datablk, Packet *pkt);
60bool testAndReadMask(Addr addr, DataBlock datablk, WriteMask mask, Packet *pkt);
61bool testAndWrite(Addr addr, DataBlock datablk, Packet *pkt);
62
63// AccessPermission
64// The following five states define the access permission of all memory blocks.
65// These permissions have multiple uses.  They coordinate locking and
66// synchronization primitives, as well as enable functional accesses.
67// One should not need to add any additional permission values and it is very
68// risky to do so.
69enumeration(AccessPermission, desc="...", default="AccessPermission_NotPresent") {
70  // Valid data
71  Read_Only,  desc="block is Read Only (modulo functional writes)";
72  Read_Write, desc="block is Read/Write";
73
74  // Possibly Invalid data
75  // The maybe stale permission indicates that accordingly to the protocol,
76  // there is no guarantee the block contains valid data.  However, functional
77  // writes should update the block because a dataless PUT request may
78  // revalidate the block's data.
79  Maybe_Stale, desc="block can be stale or revalidated by a dataless PUT";
80  // In Broadcast/Snoop protocols, memory has no idea if it is exclusive owner
81  // or not of a block, making it hard to make the logic of having only one
82  // read_write block in the system impossible. This is to allow the memory to
83  // say, "I have the block" and for the RubyPort logic to know that this is a
84  // last-resort block if there are no writable copies in the caching hierarchy.
85  // This is not supposed to be used in directory or token protocols where
86  // memory/NB has an idea of what is going on in the whole system.
87  Backing_Store, desc="for memory in Broadcast/Snoop protocols";
88
89  // Invalid data
90  Invalid,    desc="block is in an Invalid base state";
91  NotPresent, desc="block is NotPresent";
92  Busy,       desc="block is in a transient state, currently invalid";
93}
94//HSA scopes
95enumeration(HSAScope, desc="...", default="HSAScope_UNSPECIFIED") {
96  UNSPECIFIED, desc="Unspecified scope";
97  NOSCOPE,     desc="Explictly unscoped";
98  WAVEFRONT,   desc="Wavefront scope";
99  WORKGROUP,   desc="Workgroup scope";
100  DEVICE,      desc="Device scope";
101  SYSTEM,      desc="System scope";
102}
103
104// HSA segment types
105enumeration(HSASegment, desc="...", default="HSASegment_GLOBAL") {
106  GLOBAL,   desc="Global segment";
107  GROUP,    desc="Group segment";
108  PRIVATE,  desc="Private segment";
109  KERNARG,  desc="Kernarg segment";
110  READONLY, desc="Readonly segment";
111  SPILL,    desc="Spill segment";
112  ARG,      desc="Arg segment";
113}
114
115// TesterStatus
116enumeration(TesterStatus, desc="...") {
117  Idle,            desc="Idle";
118  Action_Pending,  desc="Action Pending";
119  Ready,           desc="Ready";
120  Check_Pending,   desc="Check Pending";
121}
122
123// InvalidateGeneratorStatus
124enumeration(InvalidateGeneratorStatus, desc="...") {
125  Load_Waiting,    desc="Load waiting to be issued";
126  Load_Pending,    desc="Load issued";
127  Inv_Waiting,     desc="Store (invalidate) waiting to be issued";
128  Inv_Pending,     desc="Store (invalidate) issued";
129}
130
131// SeriesRequestGeneratorStatus
132enumeration(SeriesRequestGeneratorStatus, desc="...") {
133  Thinking,        desc="Doing work before next action";
134  Request_Pending, desc="Request pending";
135}
136
137// LockStatus
138enumeration(LockStatus, desc="...") {
139  Unlocked,        desc="Lock is not held";
140  Locked,          desc="Lock is held";
141}
142
143// SequencerStatus
144enumeration(SequencerStatus, desc="...") {
145  Idle,            desc="Idle";
146  Pending,         desc="Pending";
147}
148
149enumeration(TransitionResult, desc="...") {
150  Valid,         desc="Valid transition";
151  ResourceStall, desc="Stalled due to insufficient resources";
152  ProtocolStall, desc="Protocol specified stall";
153  Reject,        desc="Rejected because of a type mismatch";
154}
155
156// RubyRequestType
157enumeration(RubyRequestType, desc="...", default="RubyRequestType_NULL") {
158  LD,                desc="Load";
159  ST,                desc="Store";
160  ATOMIC,            desc="Atomic Load/Store -- depricated. use ATOMIC_RETURN or ATOMIC_NO_RETURN";
161  ATOMIC_RETURN,     desc="Atomic Load/Store, return data";
162  ATOMIC_NO_RETURN,  desc="Atomic Load/Store, do not return data";
163  IFETCH,            desc="Instruction fetch";
164  IO,                desc="I/O";
165  REPLACEMENT,       desc="Replacement";
166  Load_Linked,       desc="";
167  Store_Conditional, desc="";
168  RMW_Read,          desc="";
169  RMW_Write,         desc="";
170  Locked_RMW_Read,   desc="";
171  Locked_RMW_Write,  desc="";
172  COMMIT,            desc="Commit version";
173  NULL,              desc="Invalid request type";
174  FLUSH,             desc="Flush request type";
175  Release,           desc="Release operation";
176  Acquire,           desc="Acquire opertion";
177  AcquireRelease,    desc="Acquire and Release opertion";
178}
179
180enumeration(SequencerRequestType, desc="...", default="SequencerRequestType_NULL") {
181  Default,     desc="Replace this with access_types passed to the DMA Ruby object";
182  LD,          desc="Load";
183  ST,          desc="Store";
184  ATOMIC,      desc="Atomic Load/Store";
185  REPLACEMENT, desc="Replacement";
186  FLUSH,       desc="Flush request type";
187  NULL,        desc="Invalid request type";
188}
189
190enumeration(CacheRequestType, desc="...", default="CacheRequestType_NULL") {
191  DataArrayRead,    desc="Read access to the cache's data array";
192  DataArrayWrite,   desc="Write access to the cache's data array";
193  TagArrayRead,     desc="Read access to the cache's tag array";
194  TagArrayWrite,    desc="Write access to the cache's tag array";
195}
196
197enumeration(CacheResourceType, desc="...", default="CacheResourceType_NULL") {
198  DataArray,    desc="Access to the cache's data array";
199  TagArray,     desc="Access to the cache's tag array";
200}
201
202enumeration(DirectoryRequestType, desc="...", default="DirectoryRequestType_NULL") {
203  Default,    desc="Replace this with access_types passed to the Directory Ruby object";
204}
205
206enumeration(DMASequencerRequestType, desc="...", default="DMASequencerRequestType_NULL") {
207  Default,    desc="Replace this with access_types passed to the DMA Ruby object";
208}
209
210enumeration(MemoryControlRequestType, desc="...", default="MemoryControlRequestType_NULL") {
211  Default,    desc="Replace this with access_types passed to the DMA Ruby object";
212}
213
214
215// These are statically defined types of states machines that we can have.
216// If you want to add a new machine type, edit this enum.  It is not necessary
217// for a protocol to have state machines defined for the all types here.  But
218// you cannot use anything other than the ones defined here.  Also, a protocol
219// can have only one state machine for a given type.
220enumeration(MachineType, desc="...", default="MachineType_NULL") {
221    L0Cache,     desc="L0 Cache Mach";
222    L1Cache,     desc="L1 Cache Mach";
223    L2Cache,     desc="L2 Cache Mach";
224    L3Cache,     desc="L3 Cache Mach";
225    Directory,   desc="Directory Mach";
226    DMA,         desc="DMA Mach";
227    Collector,   desc="Collector Mach";
228    L1Cache_wCC, desc="L1 Cache Mach to track cache-to-cache transfer (used for miss latency profile)";
229    L2Cache_wCC, desc="L2 Cache Mach to track cache-to-cache transfer (used for miss latency profile)";
230    CorePair,    desc="Cache Mach (2 cores, Private L1Ds, Shared L1I & L2)";
231    TCP,         desc="GPU L1 Data Cache (Texture Cache per Pipe)";
232    TCC,         desc="GPU L2 Shared Cache (Texture Cache per Channel)";
233    TCCdir,      desc="Directory at the GPU L2 Cache (TCC)";
234    SQC,         desc="GPU L1 Instr Cache (Sequencer Cache)";
235    RegionDir,   desc="Region-granular directory";
236    RegionBuffer,desc="Region buffer for CPU and GPU";
237    NULL,        desc="null mach type";
238}
239
240// MessageSizeType
241enumeration(MessageSizeType, desc="...") {
242  Control,    desc="Control Message";
243  Data,       desc="Data Message";
244  Request_Control, desc="Request";
245  Reissue_Control, desc="Reissued request";
246  Response_Data, desc="data response";
247  ResponseL2hit_Data, desc="data response";
248  ResponseLocal_Data, desc="data response";
249  Response_Control, desc="non-data response";
250  Writeback_Data, desc="Writeback data";
251  Writeback_Control, desc="Writeback control";
252  Broadcast_Control, desc="Broadcast control";
253  Multicast_Control, desc="Multicast control";
254  Forwarded_Control, desc="Forwarded control";
255  Invalidate_Control, desc="Invalidate control";
256  Unblock_Control, desc="Unblock control";
257  Persistent_Control, desc="Persistent request activation messages";
258  Completion_Control, desc="Completion messages";
259}
260
261// AccessType
262enumeration(AccessType, desc="...") {
263  Read, desc="Reading from cache";
264  Write, desc="Writing to cache";
265}
266
267// RubyAccessMode
268enumeration(RubyAccessMode, default="RubyAccessMode_User", desc="...") {
269  Supervisor, desc="Supervisor mode";
270  User,       desc="User mode";
271  Device, desc="Device mode";
272}
273
274enumeration(PrefetchBit, default="PrefetchBit_No", desc="...") {
275  No,    desc="No, not a prefetch";
276  Yes,   desc="Yes, a prefetch";
277  L1_HW, desc="This is a L1 hardware prefetch";
278  L2_HW, desc="This is a L2 hardware prefetch";
279}
280
281// CacheMsg
282structure(SequencerMsg, desc="...", interface="Message") {
283  Addr LineAddress,       desc="Line address for this request";
284  Addr PhysicalAddress,   desc="Physical address for this request";
285  SequencerRequestType Type,     desc="Type of request (LD, ST, etc)";
286  Addr ProgramCounter,    desc="Program counter of the instruction that caused the miss";
287  RubyAccessMode AccessMode, desc="user/supervisor access type";
288  DataBlock DataBlk,         desc="Data";
289  int Len,                   desc="size in bytes of access";
290  PrefetchBit Prefetch,      desc="Is this a prefetch request";
291  MessageSizeType MessageSize, default="MessageSizeType_Request_Control";
292
293  bool functionalRead(Packet *pkt) {
294    return testAndRead(PhysicalAddress, DataBlk, pkt);
295  }
296
297  bool functionalWrite(Packet *pkt) {
298    return testAndWrite(PhysicalAddress, DataBlk, pkt);
299  }
300}
301
302// MaskPredictorType
303enumeration(MaskPredictorType, "MaskPredictorType_Undefined", desc="...") {
304  Undefined, desc="Undefined";
305  AlwaysUnicast, desc="AlwaysUnicast";
306  TokenD, desc="TokenD";
307  AlwaysBroadcast, desc="AlwaysBroadcast";
308  TokenB, desc="TokenB";
309  TokenNull, desc="TokenNull";
310  Random, desc="Random";
311  Pairwise, desc="Pairwise";
312  Owner, desc="Owner";
313  BroadcastIfShared, desc="Broadcast-If-Shared";
314  BroadcastCounter, desc="Broadcast Counter";
315  Group, desc="Group";
316  Counter, desc="Counter";
317  StickySpatial, desc="StickySpatial";
318  OwnerBroadcast, desc="Owner/Broadcast Hybrid";
319  OwnerGroup, desc="Owner/Group Hybrid";
320  OwnerBroadcastMod, desc="Owner/Broadcast Hybrid-Mod";
321  OwnerGroupMod, desc="Owner/Group Hybrid-Mod";
322  LastNMasks, desc="Last N Masks";
323  BandwidthAdaptive, desc="Bandwidth Adaptive";
324}
325
326// MaskPredictorIndex
327enumeration(MaskPredictorIndex, "MaskPredictorIndex_Undefined", desc="...") {
328  Undefined, desc="Undefined";
329  DataBlock, desc="Data Block";
330  PC, desc="Program Counter";
331}
332
333// MaskPredictorTraining
334enumeration(MaskPredictorTraining, "MaskPredictorTraining_Undefined", desc="...") {
335  Undefined, desc="Undefined";
336  None, desc="None";
337  Implicit, desc="Implicit";
338  Explicit, desc="Explicit";
339  Both, desc="Both";
340}
341
342// Request Status
343enumeration(RequestStatus, desc="...", default="RequestStatus_NULL")  {
344  Ready, desc="The sequencer is ready and the request does not alias";
345  Issued, desc="The sequencer successfully issued the request";
346  BufferFull, desc="Can not issue because the sequencer is full";
347  Aliased, desc="This request aliased with a currently outstanding request";
348  NULL, desc="";
349}
350
351// LinkDirection
352enumeration(LinkDirection, desc="...") {
353  In, desc="Inward link direction";
354  Out, desc="Outward link direction";
355}
356