/* * 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"; // [InvisiSpec] New request types SPEC_LD, desc="Speculative load"; EXPOSE, desc="Expose"; VALIDATE, desc="Validate"; SPEC_FLUSH, desc="Flush SpecBuffer"; } 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"; SPECLD_Control, desc="SPECLD control message"; SPECLD_Request_Control, desc="SPECLD forward message"; SPECLD_Data, desc="SPECLD data response"; EXPOSE_Control, desc="EXPOSE control message"; EXPOSE_Request_Control, desc="EXPOSE forward request"; EXPOSE_Data, desc="EXPOSE data response"; } // 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"; Merged, desc="This request merged with a currently outstanding request"; NULL, desc=""; } // LinkDirection enumeration(LinkDirection, desc="...") { In, desc="Inward link direction"; Out, desc="Outward link direction"; }