X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fpacket.hh;h=cb97dd0366c9ebb8ab9279fed851317cd9dc9a77;hb=06482e6eeda9ba092c2fdc87217e391e64ff36a0;hp=2b97ab0c1de715e32396ee44407e3b1e4832bcc2;hpb=b973fae85d47a8184204d5d38b32ad3d427ce41c;p=gem5.git diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 2b97ab0c1..cb97dd036 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -38,28 +38,29 @@ #ifndef __MEM_PACKET_HH__ #define __MEM_PACKET_HH__ +#include +#include + #include "mem/request.hh" -#include "arch/isa_traits.hh" +#include "sim/host.hh" #include "sim/root.hh" -#include struct Packet; -typedef Packet* PacketPtr; +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 - -//For statistics we need max number of commands, hard code it at -//20 for now. @todo fix later -#define NUM_MEM_CMDS 1 << 9 - +#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 @@ -92,7 +93,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; @@ -103,7 +103,7 @@ class Packet /** Device address (e.g., bus ID) of the source of the * transaction. The source is not responsible for setting this * field; it is set implicitly by the interconnect when the - * packet * is first sent. */ + * packet is first sent. */ short src; /** Device address (e.g., bus ID) of the destination of the @@ -124,6 +124,12 @@ class Packet /** 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; @@ -162,17 +168,21 @@ 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, - IsWrite = 1 << 1, - IsPrefetch = 1 << 2, - IsInvalidate = 1 << 3, - IsRequest = 1 << 4, - IsResponse = 1 << 5, - NeedsResponse = 1 << 6, + IsRead = 1 << 0, + IsWrite = 1 << 1, + IsPrefetch = 1 << 2, + IsInvalidate = 1 << 3, + IsRequest = 1 << 4, + IsResponse = 1 << 5, + NeedsResponse = 1 << 6, IsSWPrefetch = 1 << 7, - IsHWPrefetch = 1 << 8 + IsHWPrefetch = 1 << 8, + IsUpgrade = 1 << 9, + HasData = 1 << 10 }; public: @@ -180,22 +190,27 @@ class Packet enum Command { InvalidCmd = 0, - ReadReq = IsRead | IsRequest | NeedsResponse, - WriteReq = IsWrite | IsRequest | NeedsResponse, - WriteReqNoAck = IsWrite | IsRequest, - ReadResp = IsRead | IsResponse, - WriteResp = IsWrite | IsResponse, - Writeback = IsWrite | IsRequest, + ReadReq = IsRead | IsRequest | NeedsResponse, + 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 | IsRequest | IsSWPrefetch | IsResponse, - HardPFResp = IsRead | IsRequest | IsHWPrefetch | IsResponse, + SoftPFResp = IsRead | IsResponse | IsSWPrefetch + | NeedsResponse | HasData, + HardPFResp = IsRead | IsResponse | IsHWPrefetch + | NeedsResponse | HasData, InvalidateReq = IsInvalidate | IsRequest, - WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest, - UpgradeReq = IsInvalidate | NeedsResponse, - UpgradeResp = IsInvalidate | IsResponse, - ReadExReq = IsRead | IsInvalidate | NeedsResponse, + WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest + | HasData | NeedsResponse, + WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest + | NeedsResponse | IsResponse, + 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 @@ -211,18 +226,19 @@ class Packet /** 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 isRead() const { return (cmd & IsRead) != 0; } + bool isWrite() const { return (cmd & IsWrite) != 0; } + bool isRequest() const { return (cmd & IsRequest) != 0; } + bool isResponse() const { return (cmd & IsResponse) != 0; } + bool needsResponse() const { return (cmd & NeedsResponse) != 0; } + bool isInvalidate() const { return (cmd & IsInvalidate) != 0; } + bool hasData() const { 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 isCacheFill() const { return (flags & CACHE_LINE_FILL) != 0; } + bool isNoAllocate() const { return (flags & NO_ALLOCATE) != 0; } + bool isCompressed() const { return (flags & COMPRESSED) != 0; } - bool nic_pkt() { assert("Unimplemented\n" && 0); } + bool nic_pkt() { assert("Unimplemented\n" && 0); return false; } /** Possible results of a packet's request. */ enum Result @@ -247,7 +263,7 @@ class Packet Addr getAddr() const { assert(addrSizeValid); return addr; } int getSize() const { assert(addrSizeValid); return size; } - Addr getOffset(int blkSize) const { return req->getPaddr() & (Addr)(blkSize - 1); } + Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); } void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; } void cmdOverride(Command newCmd) { cmd = newCmd; } @@ -265,6 +281,7 @@ class Packet result(Unknown) { flags = 0; + time = curTick; } /** Alternate constructor if you are trying to create a packet with @@ -279,6 +296,7 @@ class Packet result(Unknown) { flags = 0; + time = curTick; } /** Destructor. */ @@ -292,8 +310,10 @@ class Packet * multiple transactions. */ void reinitFromRequest() { assert(req->validPaddr); + flags = 0; addr = req->paddr; size = req->size; + time = req->time; addrSizeValid = true; result = Unknown; if (dynamicData) { @@ -307,63 +327,135 @@ 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 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() { + /** + * 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; + if (isRead()) + icmd |= HasData; + if (isWrite()) + icmd &= ~HasData; + 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. */ + /** + * Set the data pointer to the following value that should not be + * freed. + */ template - void dataStatic(T *p); + void + dataStatic(T *p) + { + if(dynamicData) + dynamicData = false; + data = (PacketDataPtr)p; + staticData = true; + } - /** Set the data pointer to a value that should have delete [] called on it. + /** + * Set the data pointer to a value that should have delete [] + * called on it. */ template - void dataDynamicArray(T *p); + void + dataDynamicArray(T *p) + { + assert(!staticData && !dynamicData); + data = (PacketDataPtr)p; + dynamicData = true; + arrayData = true; + } - /** set the data pointer to a value that should have delete called on it. */ + /** + * set the data pointer to a value that should have delete called + * on it. + */ template - void dataDynamic(T *p); + void + dataDynamic(T *p) + { + assert(!staticData && !dynamicData); + data = (PacketDataPtr)p; + dynamicData = true; + arrayData = false; + } - /** return the value of what is pointed to in the packet. */ + /** get a pointer to the data ptr. */ template - T get(); + T* + getPtr() + { + assert(staticData || dynamicData); + return (T*)data; + } - /** get a pointer to the data ptr. */ + /** return the value of what is pointed to in the packet. */ template - T* getPtr(); + T get(); /** set the value in the data pointer to v. */ template void set(T v); - /** delete the data pointed to in the data pointer. Ok to call to matter how - * data was allocted. */ + /** + * delete the data pointed to in the data pointer. Ok to call to + * matter how data was allocted. + */ void deleteData(); /** If there isn't data in the packet, allocate some. */ void allocate(); /** Do the packet modify the same addresses. */ - bool intersect(Packet *p); + bool intersect(PacketPtr p); }; -bool fixPacket(Packet *func, Packet *timing); + +/** This function given a functional packet and a timing packet either satisfies + * the timing packet, or updates the timing packet to reflect the updated state + * in the timing packet. It returns if the functional packet should continue to + * traverse the memory hierarchy or not. + */ +bool fixPacket(PacketPtr func, PacketPtr timing); + +std::ostream & operator<<(std::ostream &o, const Packet &p); + #endif //__MEM_PACKET_HH