packet.hh revision 2855
12SN/A/* 21762SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski 292665Ssaidi@eecs.umich.edu * Steve Reinhardt 302665Ssaidi@eecs.umich.edu * Ali Saidi 312SN/A */ 322SN/A 332623SN/A/** 342623SN/A * @file 352SN/A * Declaration of the Packet class. 364182Sgblack@eecs.umich.edu */ 371354SN/A 381858SN/A#ifndef __MEM_PACKET_HH__ 391717SN/A#define __MEM_PACKET_HH__ 402683Sktlim@umich.edu 411354SN/A#include "mem/request.hh" 421354SN/A#include "arch/isa_traits.hh" 432387SN/A#include "sim/root.hh" 442387SN/A#include <list> 452387SN/A 4656SN/Astruct Packet; 472SN/Atypedef Packet* PacketPtr; 482SN/Atypedef uint8_t* PacketDataPtr; 491858SN/Atypedef std::list<PacketPtr> PacketList; 502SN/A 513453Sgblack@eecs.umich.edu//Coherence Flags 523453Sgblack@eecs.umich.edu#define NACKED_LINE 1 << 0 533453Sgblack@eecs.umich.edu#define SATISFIED 1 << 1 543453Sgblack@eecs.umich.edu#define SHARED_LINE 1 << 2 553453Sgblack@eecs.umich.edu#define CACHE_LINE_FILL 1 << 3 562462SN/A#define COMPRESSED 1 << 4 572SN/A#define NO_ALLOCATE 1 << 5 58715SN/A 59715SN/A//For statistics we need max number of commands, hard code it at 60715SN/A//20 for now. @todo fix later 61715SN/A#define NUM_MEM_CMDS 1 << 9 622SN/A 632SN/A/** 643960Sgblack@eecs.umich.edu * A Packet is used to encapsulate a transfer between two objects in 653960Sgblack@eecs.umich.edu * the memory system (e.g., the L1 and L2 cache). (In contrast, a 663960Sgblack@eecs.umich.edu * single Request travels all the way from the requester to the 674182Sgblack@eecs.umich.edu * ultimate destination and back, possibly being conveyed by several 684182Sgblack@eecs.umich.edu * different Packets along the way.) 694182Sgblack@eecs.umich.edu */ 704182Sgblack@eecs.umich.educlass Packet 712680Sktlim@umich.edu{ 72237SN/A public: 732SN/A /** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */ 742SN/A uint64_t flags; 752SN/A 762SN/A private: 772SN/A /** A pointer to the data being transfered. It can be differnt 782420SN/A * sizes at each level of the heirarchy so it belongs in the 792623SN/A * packet, not request. This may or may not be populated when a 802SN/A * responder recieves the packet. If not populated it memory 812107SN/A * should be allocated. 822159SN/A */ 832455SN/A PacketDataPtr data; 842455SN/A 852386SN/A /** Is the data pointer set to a value that shouldn't be freed 862623SN/A * when the packet is destroyed? */ 872SN/A bool staticData; 881371SN/A /** The data pointer points to a value that should be freed when 892SN/A * the packet is destroyed. */ 902SN/A bool dynamicData; 912SN/A /** the data pointer points to an array (thus delete [] ) needs to 922SN/A * be called on it rather than simply delete.*/ 932SN/A bool arrayData; 942SN/A 952SN/A 962SN/A /** The address of the request. This address could be virtual or 972SN/A * physical, depending on the system configuration. */ 982SN/A Addr addr; 992SN/A 1001400SN/A /** The size of the request or transfer. */ 1011400SN/A int size; 1021400SN/A 1033453Sgblack@eecs.umich.edu /** Device address (e.g., bus ID) of the source of the 1043453Sgblack@eecs.umich.edu * transaction. The source is not responsible for setting this 1054997Sgblack@eecs.umich.edu * field; it is set implicitly by the interconnect when the 1061400SN/A * packet * is first sent. */ 1072SN/A short src; 1081400SN/A 1092623SN/A /** Device address (e.g., bus ID) of the destination of the 1102623SN/A * transaction. The special value Broadcast indicates that the 1112SN/A * packet should be routed based on its address. This field is 1121400SN/A * initialized in the constructor and is thus always valid 1132683Sktlim@umich.edu * (unlike * addr, size, and src). */ 1142683Sktlim@umich.edu short dest; 1152190SN/A 1162683Sktlim@umich.edu /** Are the 'addr' and 'size' fields valid? */ 1172683Sktlim@umich.edu bool addrSizeValid; 1182683Sktlim@umich.edu /** Is the 'src' field valid? */ 1192680Sktlim@umich.edu bool srcValid; 1205169Ssaidi@eecs.umich.edu 1215169Ssaidi@eecs.umich.edu 1225169Ssaidi@eecs.umich.edu public: 1235169Ssaidi@eecs.umich.edu 1242SN/A /** Used to calculate latencies for each packet.*/ 1251858SN/A Tick time; 1262SN/A 1272SN/A /** The special destination address indicating that the packet 1282SN/A * should be routed based on its address. */ 1292SN/A static const short Broadcast = -1; 1302SN/A 1312SN/A /** A pointer to the original request. */ 1324181Sgblack@eecs.umich.edu RequestPtr req; 1334181Sgblack@eecs.umich.edu 1344182Sgblack@eecs.umich.edu /** A virtual base opaque structure used to hold coherence-related 1354182Sgblack@eecs.umich.edu * state. A specific subclass would be derived from this to 1362SN/A * carry state specific to a particular coherence protocol. */ 1372107SN/A class CoherenceState { 1383276Sgblack@eecs.umich.edu public: 1391469SN/A virtual ~CoherenceState() {} 1404377Sgblack@eecs.umich.edu }; 1414377Sgblack@eecs.umich.edu 1424377Sgblack@eecs.umich.edu /** This packet's coherence state. Caches should use 1434377Sgblack@eecs.umich.edu * dynamic_cast<> to cast to the state appropriate for the 1444377Sgblack@eecs.umich.edu * system's coherence protocol. */ 1454377Sgblack@eecs.umich.edu CoherenceState *coherence; 1462623SN/A 1472662Sstever@eecs.umich.edu /** A virtual base opaque structure used to hold state associated 1482623SN/A * with the packet but specific to the sending device (e.g., an 1492623SN/A * MSHR). A pointer to this state is returned in the packet's 1502623SN/A * response so that the sender can quickly look up the state 151180SN/A * needed to process it. A specific subclass would be derived 152393SN/A * from this to carry state specific to a particular sending 153393SN/A * device. */ 1542SN/A class SenderState { 1552SN/A public: 156334SN/A virtual ~SenderState() {} 157334SN/A }; 1582SN/A 1592SN/A /** This packet's sender state. Devices should use dynamic_cast<> 1602SN/A * to cast to the state appropriate to the sender. */ 161334SN/A SenderState *senderState; 162729SN/A 163707SN/A private: 1644998Sgblack@eecs.umich.edu /** List of command attributes. */ 1654998Sgblack@eecs.umich.edu enum CommandAttribute 1664998Sgblack@eecs.umich.edu { 1674998Sgblack@eecs.umich.edu IsRead = 1 << 0, 1684998Sgblack@eecs.umich.edu IsWrite = 1 << 1, 1694998Sgblack@eecs.umich.edu IsPrefetch = 1 << 2, 1704998Sgblack@eecs.umich.edu IsInvalidate = 1 << 3, 1714998Sgblack@eecs.umich.edu IsRequest = 1 << 4, 172707SN/A IsResponse = 1 << 5, 173707SN/A NeedsResponse = 1 << 6, 174707SN/A IsSWPrefetch = 1 << 7, 175707SN/A IsHWPrefetch = 1 << 8 1762SN/A }; 1774564Sgblack@eecs.umich.edu 1784564Sgblack@eecs.umich.edu public: 1794564Sgblack@eecs.umich.edu /** List of all commands associated with a packet. */ 1802SN/A enum Command 181729SN/A { 1822SN/A InvalidCmd = 0, 183124SN/A ReadReq = IsRead | IsRequest | NeedsResponse, 184124SN/A WriteReq = IsWrite | IsRequest | NeedsResponse, 185334SN/A WriteReqNoAck = IsWrite | IsRequest, 186124SN/A ReadResp = IsRead | IsResponse | NeedsResponse, 1872SN/A WriteResp = IsWrite | IsResponse | NeedsResponse, 188729SN/A Writeback = IsWrite | IsRequest, 189729SN/A SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse, 1902SN/A HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse, 1912390SN/A SoftPFResp = IsRead | IsResponse | IsSWPrefetch | NeedsResponse, 192729SN/A HardPFResp = IsRead | IsResponse | IsHWPrefetch | NeedsResponse, 1932SN/A InvalidateReq = IsInvalidate | IsRequest, 1942SN/A WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest, 1952390SN/A UpgradeReq = IsInvalidate | IsRequest | NeedsResponse, 1962390SN/A UpgradeResp = IsInvalidate | IsResponse | NeedsResponse, 1972390SN/A ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse, 1982390SN/A ReadExResp = IsRead | IsInvalidate | IsResponse | NeedsResponse 1992390SN/A }; 200729SN/A 2012SN/A /** Return the string name of the cmd field (for debugging and 2022SN/A * tracing). */ 2032390SN/A const std::string &cmdString() const; 2042390SN/A 2052390SN/A /** Reutrn the string to a cmd given by idx. */ 2062390SN/A const std::string &cmdIdxToString(Command idx); 207217SN/A 208237SN/A /** Return the index of this command. */ 2092SN/A inline int cmdToIndex() const { return (int) cmd; } 2101371SN/A 2111371SN/A /** The command field of the packet. */ 2122623SN/A Command cmd; 2133918Ssaidi@eecs.umich.edu 2143918Ssaidi@eecs.umich.edu bool isRead() { return (cmd & IsRead) != 0; } 2151371SN/A bool isWrite() { return (cmd & IsWrite) != 0; } 216581SN/A bool isRequest() { return (cmd & IsRequest) != 0; } 2172SN/A bool isResponse() { return (cmd & IsResponse) != 0; } 2182SN/A bool needsResponse() { return (cmd & NeedsResponse) != 0; } 2192SN/A bool isInvalidate() { return (cmd * IsInvalidate) != 0; } 2202SN/A 221753SN/A bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; } 2222SN/A bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; } 2232SN/A bool isCompressed() { return (flags & COMPRESSED) != 0; } 2242SN/A 225594SN/A bool nic_pkt() { assert("Unimplemented\n" && 0); } 2264661Sksewell@umich.edu 227595SN/A /** Possible results of a packet's request. */ 228594SN/A enum Result 229595SN/A { 230705SN/A Success, 231726SN/A BadAddress, 232726SN/A Nacked, 233726SN/A Unknown 234726SN/A }; 235726SN/A 236726SN/A /** The result of this packet's request. */ 237726SN/A Result result; 238726SN/A 239726SN/A /** Accessor function that returns the source index of the packet. */ 240726SN/A short getSrc() const { assert(srcValid); return src; } 241705SN/A void setSrc(short _src) { src = _src; srcValid = true; } 2423735Sstever@eecs.umich.edu 243726SN/A /** Accessor function that returns the destination index of 2442683Sktlim@umich.edu the packet. */ 245726SN/A short getDest() const { return dest; } 246705SN/A void setDest(short _dest) { dest = _dest; } 2473735Sstever@eecs.umich.edu 248726SN/A Addr getAddr() const { assert(addrSizeValid); return addr; } 249726SN/A int getSize() const { assert(addrSizeValid); return size; } 2502683Sktlim@umich.edu Addr getOffset(int blkSize) const { return req->getPaddr() & (Addr)(blkSize - 1); } 251726SN/A 252705SN/A void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; } 2533735Sstever@eecs.umich.edu void cmdOverride(Command newCmd) { cmd = newCmd; } 254726SN/A 255726SN/A /** Constructor. Note that a Request object must be constructed 2562683Sktlim@umich.edu * first, but the Requests's physical address and size fields 257726SN/A * need not be valid. The command and destination addresses 258705SN/A * must be supplied. */ 2593735Sstever@eecs.umich.edu Packet(Request *_req, Command _cmd, short _dest) 2603735Sstever@eecs.umich.edu : data(NULL), staticData(false), dynamicData(false), arrayData(false), 261726SN/A addr(_req->paddr), size(_req->size), dest(_dest), 262726SN/A addrSizeValid(_req->validPaddr), 2632683Sktlim@umich.edu srcValid(false), 2642455SN/A req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), 2652455SN/A result(Unknown) 2663735Sstever@eecs.umich.edu { 2672455SN/A flags = 0; 2682455SN/A } 2692683Sktlim@umich.edu 270726SN/A /** Alternate constructor if you are trying to create a packet with 271705SN/A * a request that is for a whole block, not the address from the req. 2723735Sstever@eecs.umich.edu * this allows for overriding the size/addr of the req.*/ 273726SN/A Packet(Request *_req, Command _cmd, short _dest, int _blkSize) 2742683Sktlim@umich.edu : data(NULL), staticData(false), dynamicData(false), arrayData(false), 275726SN/A addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize), 276705SN/A dest(_dest), 2773735Sstever@eecs.umich.edu addrSizeValid(_req->validPaddr), srcValid(false), 2783735Sstever@eecs.umich.edu req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), 279726SN/A result(Unknown) 280726SN/A { 2812683Sktlim@umich.edu flags = 0; 282726SN/A } 283705SN/A 2843735Sstever@eecs.umich.edu /** Destructor. */ 285726SN/A ~Packet() 286726SN/A { deleteData(); } 2872683Sktlim@umich.edu 288726SN/A /** Reinitialize packet address and size from the associated 289726SN/A * Request object, and reset other fields that may have been 2903735Sstever@eecs.umich.edu * modified by a previous transaction. Typically called when a 2913735Sstever@eecs.umich.edu * statically allocated Request/Packet pair is reused for 292726SN/A * multiple transactions. */ 293726SN/A void reinitFromRequest() { 2942683Sktlim@umich.edu assert(req->validPaddr); 2952455SN/A addr = req->paddr; 2962455SN/A size = req->size; 2973735Sstever@eecs.umich.edu addrSizeValid = true; 2983735Sstever@eecs.umich.edu result = Unknown; 2992455SN/A if (dynamicData) { 3002455SN/A deleteData(); 3012683Sktlim@umich.edu dynamicData = false; 302726SN/A arrayData = false; 303705SN/A } 3042683Sktlim@umich.edu } 3054950Sgblack@eecs.umich.edu 3062683Sktlim@umich.edu /** Take a request packet and modify it in place to be suitable 3074950Sgblack@eecs.umich.edu * for returning as a response to that request. Used for timing 3082683Sktlim@umich.edu * accesses only. For atomic and functional accesses, the 3092447SN/A * request packet is always implicitly passed back *without* 3102683Sktlim@umich.edu * modifying the command or destination fields, so this function 3114950Sgblack@eecs.umich.edu * should not be called. */ 3122683Sktlim@umich.edu void makeTimingResponse() { 3134950Sgblack@eecs.umich.edu assert(needsResponse()); 3142683Sktlim@umich.edu assert(isRequest()); 315705SN/A int icmd = (int)cmd; 3164172Ssaidi@eecs.umich.edu icmd &= ~(IsRequest); 3174172Ssaidi@eecs.umich.edu icmd |= IsResponse; 3184172Ssaidi@eecs.umich.edu cmd = (Command)icmd; 3194172Ssaidi@eecs.umich.edu dest = src; 3204172Ssaidi@eecs.umich.edu srcValid = false; 3212159SN/A } 3222159SN/A 3232683Sktlim@umich.edu /** Take a request packet that has been returned as NACKED and modify it so 3242159SN/A * that it can be sent out again. Only packets that need a response can be 325705SN/A * NACKED, so verify that that is true. */ 3264172Ssaidi@eecs.umich.edu void reinitNacked() { 3272159SN/A assert(needsResponse() && result == Nacked); 3284172Ssaidi@eecs.umich.edu dest = Broadcast; 3292159SN/A result = Unknown; 3302159SN/A } 3313468Sgblack@eecs.umich.edu 3322159SN/A 3332683Sktlim@umich.edu /** Set the data pointer to the following value that should not be freed. */ 3342159SN/A template <typename T> 3352159SN/A void dataStatic(T *p); 3364185Ssaidi@eecs.umich.edu 3372159SN/A /** Set the data pointer to a value that should have delete [] called on it. 3384172Ssaidi@eecs.umich.edu */ 3394172Ssaidi@eecs.umich.edu template <typename T> 3402159SN/A void dataDynamicArray(T *p); 341705SN/A 3424185Ssaidi@eecs.umich.edu /** set the data pointer to a value that should have delete called on it. */ 3433792Sgblack@eecs.umich.edu template <typename T> 3443792Sgblack@eecs.umich.edu void dataDynamic(T *p); 3453792Sgblack@eecs.umich.edu 3463792Sgblack@eecs.umich.edu /** return the value of what is pointed to in the packet. */ 3473792Sgblack@eecs.umich.edu template <typename T> 3484185Ssaidi@eecs.umich.edu T get(); 3493792Sgblack@eecs.umich.edu 3503792Sgblack@eecs.umich.edu /** get a pointer to the data ptr. */ 3514172Ssaidi@eecs.umich.edu template <typename T> 3523792Sgblack@eecs.umich.edu T* getPtr(); 3533792Sgblack@eecs.umich.edu 3544185Ssaidi@eecs.umich.edu /** set the value in the data pointer to v. */ 3553792Sgblack@eecs.umich.edu template <typename T> 3563792Sgblack@eecs.umich.edu void set(T v); 3573792Sgblack@eecs.umich.edu 3584172Ssaidi@eecs.umich.edu /** delete the data pointed to in the data pointer. Ok to call to matter how 3593792Sgblack@eecs.umich.edu * data was allocted. */ 3603792Sgblack@eecs.umich.edu void deleteData(); 3614027Sstever@eecs.umich.edu 3624027Sstever@eecs.umich.edu /** If there isn't data in the packet, allocate some. */ 3634027Sstever@eecs.umich.edu void allocate(); 3644027Sstever@eecs.umich.edu 3654027Sstever@eecs.umich.edu /** Do the packet modify the same addresses. */ 3664027Sstever@eecs.umich.edu bool intersect(Packet *p); 3674027Sstever@eecs.umich.edu}; 3684027Sstever@eecs.umich.edu 3694661Sksewell@umich.edubool fixPacket(Packet *func, Packet *timing); 3704661Sksewell@umich.edu#endif //__MEM_PACKET_HH 3714661Sksewell@umich.edu