X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fpacket.hh;h=3a7286a697caed5cb95bb54b47b6ac3d650d08e4;hb=012556ecf92da1b5527fece58417725970c3e64a;hp=d5a10d29aacf2b22043719688fd05ce168c3d8ba;hpb=d2d581cf01d07f6a22f02f471d23e3d31919c695;p=gem5.git diff --git a/src/mem/packet.hh b/src/mem/packet.hh index d5a10d29a..3a7286a69 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -39,13 +39,27 @@ #define __MEM_PACKET_HH__ #include "mem/request.hh" -#include "arch/isa_traits.hh" +#include "sim/host.hh" #include "sim/root.hh" +#include +#include struct Packet; typedef Packet* PacketPtr; typedef uint8_t* PacketDataPtr; - +typedef std::list PacketList; + +//Coherence Flags +#define NACKED_LINE 1 << 0 +#define SATISFIED 1 << 1 +#define SHARED_LINE 1 << 2 +#define CACHE_LINE_FILL 1 << 3 +#define COMPRESSED 1 << 4 +#define NO_ALLOCATE 1 << 5 +#define SNOOP_COMMIT 1 << 6 + +//for now. @todo fix later +#define NUM_MEM_CMDS 1 << 11 /** * A Packet is used to encapsulate a transfer between two objects in * the memory system (e.g., the L1 and L2 cache). (In contrast, a @@ -55,6 +69,10 @@ typedef uint8_t* PacketDataPtr; */ class Packet { + public: + /** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */ + uint64_t flags; + private: /** A pointer to the data being transfered. It can be differnt * sizes at each level of the heirarchy so it belongs in the @@ -74,7 +92,6 @@ class Packet * be called on it rather than simply delete.*/ bool arrayData; - /** The address of the request. This address could be virtual or * physical, depending on the system configuration. */ Addr addr; @@ -100,8 +117,18 @@ class Packet /** Is the 'src' field valid? */ bool srcValid; + public: + /** Used to calculate latencies for each packet.*/ + Tick time; + + /** The time at which the packet will be fully transmitted */ + Tick finishTime; + + /** The time at which the first chunk of the packet will be transmitted */ + Tick firstWordTime; + /** The special destination address indicating that the packet * should be routed based on its address. */ static const short Broadcast = -1; @@ -140,6 +167,8 @@ class Packet private: /** List of command attributes. */ + // If you add a new CommandAttribute, make sure to increase NUM_MEM_CMDS + // as well. enum CommandAttribute { IsRead = 1 << 0, @@ -149,36 +178,70 @@ class Packet IsRequest = 1 << 4, IsResponse = 1 << 5, NeedsResponse = 1 << 6, + IsSWPrefetch = 1 << 7, + IsHWPrefetch = 1 << 8, + IsUpgrade = 1 << 9, + HasData = 1 << 10 }; public: /** List of all commands associated with a packet. */ enum Command { + InvalidCmd = 0, ReadReq = IsRead | IsRequest | NeedsResponse, - WriteReq = IsWrite | IsRequest | NeedsResponse, - WriteReqNoAck = IsWrite | IsRequest, - ReadResp = IsRead | IsResponse, - WriteResp = IsWrite | IsResponse + WriteReq = IsWrite | IsRequest | NeedsResponse | HasData, + WriteReqNoAck = IsWrite | IsRequest | HasData, + ReadResp = IsRead | IsResponse | NeedsResponse | HasData, + WriteResp = IsWrite | IsResponse | NeedsResponse, + Writeback = IsWrite | IsRequest | HasData, + SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse, + HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse, + SoftPFResp = IsRead | IsResponse | IsSWPrefetch + | NeedsResponse | HasData, + HardPFResp = IsRead | IsResponse | IsHWPrefetch + | NeedsResponse | HasData, + InvalidateReq = IsInvalidate | IsRequest, + WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData, + UpgradeReq = IsInvalidate | IsRequest | IsUpgrade, + ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse, + ReadExResp = IsRead | IsInvalidate | IsResponse + | NeedsResponse | HasData }; /** Return the string name of the cmd field (for debugging and * tracing). */ const std::string &cmdString() const; + /** Reutrn the string to a cmd given by idx. */ + const std::string &cmdIdxToString(Command idx); + + /** Return the index of this command. */ + inline int cmdToIndex() const { return (int) cmd; } + /** The command field of the packet. */ Command cmd; bool isRead() { return (cmd & IsRead) != 0; } + bool isWrite() { return (cmd & IsWrite) != 0; } bool isRequest() { return (cmd & IsRequest) != 0; } bool isResponse() { return (cmd & IsResponse) != 0; } bool needsResponse() { return (cmd & NeedsResponse) != 0; } + bool isInvalidate() { return (cmd & IsInvalidate) != 0; } + bool hasData() { return (cmd & HasData) != 0; } + + bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; } + bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; } + bool isCompressed() { return (flags & COMPRESSED) != 0; } + + bool nic_pkt() { assert("Unimplemented\n" && 0); return false; } /** Possible results of a packet's request. */ enum Result { Success, BadAddress, + Nacked, Unknown }; @@ -196,6 +259,10 @@ class Packet Addr getAddr() const { assert(addrSizeValid); return addr; } int getSize() const { assert(addrSizeValid); return size; } + Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); } + + void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; } + void cmdOverride(Command newCmd) { cmd = newCmd; } /** Constructor. Note that a Request object must be constructed * first, but the Requests's physical address and size fields @@ -209,6 +276,23 @@ class Packet req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), result(Unknown) { + flags = 0; + time = curTick; + } + + /** Alternate constructor if you are trying to create a packet with + * a request that is for a whole block, not the address from the req. + * this allows for overriding the size/addr of the req.*/ + Packet(Request *_req, Command _cmd, short _dest, int _blkSize) + : data(NULL), staticData(false), dynamicData(false), arrayData(false), + addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize), + dest(_dest), + addrSizeValid(_req->validPaddr), srcValid(false), + req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), + result(Unknown) + { + flags = 0; + time = curTick; } /** Destructor. */ @@ -224,6 +308,7 @@ class Packet assert(req->validPaddr); addr = req->paddr; size = req->size; + time = req->time; addrSizeValid = true; result = Unknown; if (dynamicData) { @@ -237,18 +322,45 @@ class Packet * for returning as a response to that request. Used for timing * accesses only. For atomic and functional accesses, the * request packet is always implicitly passed back *without* - * modifying the command or destination fields, so this function + * modifying the destination fields, so this function * should not be called. */ void makeTimingResponse() { assert(needsResponse()); + assert(isRequest()); int icmd = (int)cmd; - icmd &= ~(IsRequest | NeedsResponse); + icmd &= ~(IsRequest); icmd |= IsResponse; + if (isRead()) + icmd |= HasData; + if (isWrite()) + icmd &= ~HasData; cmd = (Command)icmd; dest = src; srcValid = false; } + /** Take a request packet and modify it in place to be suitable + * for returning as a response to that request. + */ + void makeAtomicResponse() { + assert(needsResponse()); + assert(isRequest()); + int icmd = (int)cmd; + icmd &= ~(IsRequest); + icmd |= IsResponse; + cmd = (Command)icmd; + } + + /** Take a request packet that has been returned as NACKED and modify it so + * that it can be sent out again. Only packets that need a response can be + * NACKED, so verify that that is true. */ + void reinitNacked() { + assert(needsResponse() && result == Nacked); + dest = Broadcast; + result = Unknown; + } + + /** Set the data pointer to the following value that should not be freed. */ template void dataStatic(T *p);