48e43c9ad1
DMA sequencers and protocols can currently only issue one DMA access at a time. This patch implements the necessary functionality to support multiple outstanding DMA requests in Ruby.
252 lines
8.5 KiB
Plaintext
252 lines
8.5 KiB
Plaintext
/*
|
|
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
|
|
* Copyright (c) 2013 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.
|
|
*/
|
|
|
|
// External Types
|
|
|
|
//
|
|
// **PLEASE NOTE!** When adding objects to this file you must also add a line
|
|
// in the src/mem/ruby/SConscript file. Otherwise the external object's .hh
|
|
// file will not be copied to the protocol directory and you will encounter a
|
|
// undefined declaration error.
|
|
//
|
|
|
|
external_type(MessageBuffer, buffer="yes", inport="yes", outport="yes");
|
|
external_type(OutPort, primitive="yes");
|
|
external_type(Scalar, primitive="yes");
|
|
|
|
structure(InPort, external = "yes", primitive="yes") {
|
|
bool isReady(Tick current_time);
|
|
Tick dequeue(Tick current_time);
|
|
void recycle(Tick current_time, Tick recycle_latency);
|
|
bool isEmpty();
|
|
bool isStallMapEmpty();
|
|
int getStallMapSize();
|
|
}
|
|
|
|
external_type(NodeID, default="0", primitive="yes");
|
|
external_type(MachineID);
|
|
|
|
structure (Set, external = "yes", non_obj="yes") {
|
|
void setSize(int);
|
|
void add(NodeID);
|
|
void addSet(Set);
|
|
void remove(NodeID);
|
|
void removeSet(Set);
|
|
void broadcast();
|
|
void addRandom();
|
|
void clear();
|
|
int count();
|
|
bool isElement(NodeID);
|
|
bool isEqual(Set);
|
|
bool isSuperset(Set);
|
|
bool intersectionIsEmpty(Set);
|
|
NodeID smallestElement();
|
|
}
|
|
|
|
structure (NetDest, external = "yes", non_obj="yes") {
|
|
void setSize(int);
|
|
void setSize(int, int);
|
|
void add(NodeID);
|
|
void add(MachineID);
|
|
void addSet(Set);
|
|
void addNetDest(NetDest);
|
|
void setNetDest(MachineType, Set);
|
|
void remove(NodeID);
|
|
void remove(MachineID);
|
|
void removeSet(Set);
|
|
void removeNetDest(NetDest);
|
|
void broadcast();
|
|
void broadcast(MachineType);
|
|
void addRandom();
|
|
void clear();
|
|
Set toSet();
|
|
int count();
|
|
bool isElement(NodeID);
|
|
bool isElement(MachineID);
|
|
bool isSuperset(Set);
|
|
bool isSuperset(NetDest);
|
|
bool isEmpty();
|
|
bool intersectionIsEmpty(Set);
|
|
bool intersectionIsEmpty(NetDest);
|
|
MachineID smallestElement(MachineType);
|
|
NetDest OR(NetDest);
|
|
NetDest AND(NetDest);
|
|
}
|
|
|
|
structure (Sequencer, external = "yes") {
|
|
void readCallback(Addr, DataBlock);
|
|
void readCallback(Addr, DataBlock, bool);
|
|
void readCallback(Addr, DataBlock, bool, MachineType);
|
|
void readCallback(Addr, DataBlock, bool, MachineType,
|
|
Cycles, Cycles, Cycles);
|
|
|
|
void writeCallback(Addr, DataBlock);
|
|
void writeCallback(Addr, DataBlock, bool);
|
|
void writeCallback(Addr, DataBlock, bool, MachineType);
|
|
void writeCallback(Addr, DataBlock, bool, MachineType,
|
|
Cycles, Cycles, Cycles);
|
|
|
|
void checkCoherence(Addr);
|
|
void evictionCallback(Addr);
|
|
void recordRequestType(SequencerRequestType);
|
|
bool checkResourceAvailable(CacheResourceType, Addr);
|
|
void invalidateSC(Addr);
|
|
}
|
|
|
|
structure (GPUCoalescer, external = "yes") {
|
|
void readCallback(Addr, DataBlock);
|
|
void readCallback(Addr, MachineType, DataBlock);
|
|
void readCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles);
|
|
void readCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles, bool);
|
|
void writeCallback(Addr, DataBlock);
|
|
void writeCallback(Addr, MachineType, DataBlock);
|
|
void writeCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles);
|
|
void writeCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles, bool);
|
|
void checkCoherence(Addr);
|
|
void evictionCallback(Addr);
|
|
void recordCPReadCallBack(MachineID, MachineID);
|
|
void recordCPWriteCallBack(MachineID, MachineID);
|
|
}
|
|
|
|
structure (VIPERCoalescer, external = "yes") {
|
|
void readCallback(Addr, DataBlock);
|
|
void readCallback(Addr, MachineType, DataBlock);
|
|
void readCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles);
|
|
void readCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles, bool);
|
|
void writeCallback(Addr, DataBlock);
|
|
void writeCallback(Addr, MachineType, DataBlock);
|
|
void writeCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles);
|
|
void writeCallback(Addr, MachineType, DataBlock,
|
|
Cycles, Cycles, Cycles, bool);
|
|
void invCallback(Addr);
|
|
void wbCallback(Addr);
|
|
void checkCoherence(Addr);
|
|
void evictionCallback(Addr);
|
|
}
|
|
|
|
structure(RubyRequest, desc="...", interface="Message", external="yes") {
|
|
Addr LineAddress, desc="Line address for this request";
|
|
Addr PhysicalAddress, desc="Physical address for this request";
|
|
RubyRequestType 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";
|
|
int Size, desc="size in bytes of access";
|
|
PrefetchBit Prefetch, desc="Is this a prefetch request";
|
|
int contextId, desc="this goes away but must be replace with Nilay";
|
|
WriteMask writeMask, desc="Writethrough mask";
|
|
DataBlock WTData, desc="Writethrough data block";
|
|
int wfid, desc="Writethrough wavefront";
|
|
HSAScope scope, desc="HSA scope";
|
|
HSASegment segment, desc="HSA segment";
|
|
PacketPtr pkt, desc="Packet associated with this request";
|
|
}
|
|
|
|
structure(AbstractEntry, primitive="yes", external = "yes") {
|
|
void changePermission(AccessPermission);
|
|
}
|
|
|
|
structure (DirectoryMemory, external = "yes") {
|
|
AbstractEntry allocate(Addr, AbstractEntry);
|
|
AbstractEntry lookup(Addr);
|
|
bool isPresent(Addr);
|
|
void invalidateBlock(Addr);
|
|
void recordRequestType(DirectoryRequestType);
|
|
}
|
|
|
|
structure(AbstractCacheEntry, primitive="yes", external = "yes") {
|
|
void changePermission(AccessPermission);
|
|
}
|
|
|
|
structure (CacheMemory, external = "yes") {
|
|
bool cacheAvail(Addr);
|
|
Addr cacheProbe(Addr);
|
|
AbstractCacheEntry allocate(Addr, AbstractCacheEntry);
|
|
AbstractCacheEntry allocate(Addr, AbstractCacheEntry, bool);
|
|
void allocateVoid(Addr, AbstractCacheEntry);
|
|
void deallocate(Addr);
|
|
AbstractCacheEntry lookup(Addr);
|
|
bool isTagPresent(Addr);
|
|
Cycles getTagLatency();
|
|
Cycles getDataLatency();
|
|
void setMRU(Addr);
|
|
void setMRU(Addr, int);
|
|
void setMRU(AbstractCacheEntry);
|
|
void recordRequestType(CacheRequestType, Addr);
|
|
bool checkResourceAvailable(CacheResourceType, Addr);
|
|
|
|
int getCacheSize();
|
|
int getNumBlocks();
|
|
Addr getAddressAtIdx(int);
|
|
|
|
Scalar demand_misses;
|
|
Scalar demand_hits;
|
|
}
|
|
|
|
structure (WireBuffer, inport="yes", outport="yes", external = "yes") {
|
|
|
|
}
|
|
|
|
structure (DMASequencer, external = "yes") {
|
|
void ackCallback(Addr);
|
|
void dataCallback(DataBlock,Addr);
|
|
void recordRequestType(CacheRequestType);
|
|
}
|
|
|
|
structure (TimerTable, inport="yes", external = "yes") {
|
|
bool isReady(Tick);
|
|
Addr nextAddress();
|
|
void set(Addr, Tick);
|
|
void unset(Addr);
|
|
bool isSet(Addr);
|
|
}
|
|
|
|
structure (AbstractBloomFilter, external = "yes") {
|
|
void clear(int);
|
|
void increment(Addr, int);
|
|
void decrement(Addr, int);
|
|
void set(Addr, int);
|
|
void unset(Addr, int);
|
|
|
|
bool isSet(Addr, int);
|
|
int getCount(Addr, int);
|
|
}
|
|
|
|
structure (Prefetcher, external = "yes") {
|
|
void observeMiss(Addr, RubyRequestType);
|
|
void observePfHit(Addr);
|
|
void observePfMiss(Addr);
|
|
}
|