packet.hh revision 3349
12381SN/A/* 22592SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32381SN/A * All rights reserved. 42381SN/A * 52381SN/A * Redistribution and use in source and binary forms, with or without 62381SN/A * modification, are permitted provided that the following conditions are 72381SN/A * met: redistributions of source code must retain the above copyright 82381SN/A * notice, this list of conditions and the following disclaimer; 92381SN/A * redistributions in binary form must reproduce the above copyright 102381SN/A * notice, this list of conditions and the following disclaimer in the 112381SN/A * documentation and/or other materials provided with the distribution; 122381SN/A * neither the name of the copyright holders nor the names of its 132381SN/A * contributors may be used to endorse or promote products derived from 142381SN/A * this software without specific prior written permission. 152381SN/A * 162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262381SN/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 312381SN/A */ 322381SN/A 332381SN/A/** 342381SN/A * @file 352662Sstever@eecs.umich.edu * Declaration of the Packet class. 362381SN/A */ 372381SN/A 382381SN/A#ifndef __MEM_PACKET_HH__ 392381SN/A#define __MEM_PACKET_HH__ 402381SN/A 412392SN/A#include <cassert> 422980Sgblack@eecs.umich.edu#include <list> 432394SN/A 442812Srdreslin@umich.edu#include "mem/request.hh" 452989Ssaidi@eecs.umich.edu#include "sim/host.hh" 462394SN/A#include "sim/root.hh" 472394SN/A 482394SN/Astruct Packet; 492394SN/Atypedef Packet *PacketPtr; 502812Srdreslin@umich.edutypedef uint8_t* PacketDataPtr; 512812Srdreslin@umich.edutypedef std::list<PacketPtr> PacketList; 522812Srdreslin@umich.edu 532812Srdreslin@umich.edu//Coherence Flags 542812Srdreslin@umich.edu#define NACKED_LINE 1 << 0 552812Srdreslin@umich.edu#define SATISFIED 1 << 1 562813Srdreslin@umich.edu#define SHARED_LINE 1 << 2 572813Srdreslin@umich.edu#define CACHE_LINE_FILL 1 << 3 582813Srdreslin@umich.edu#define COMPRESSED 1 << 4 593074Srdreslin@umich.edu#define NO_ALLOCATE 1 << 5 602382SN/A#define SNOOP_COMMIT 1 << 6 612381SN/A 622662Sstever@eecs.umich.edu//for now. @todo fix later 632662Sstever@eecs.umich.edu#define NUM_MEM_CMDS 1 << 11 642662Sstever@eecs.umich.edu/** 652662Sstever@eecs.umich.edu * A Packet is used to encapsulate a transfer between two objects in 662662Sstever@eecs.umich.edu * the memory system (e.g., the L1 and L2 cache). (In contrast, a 672381SN/A * single Request travels all the way from the requester to the 682641Sstever@eecs.umich.edu * ultimate destination and back, possibly being conveyed by several 692381SN/A * different Packets along the way.) 702813Srdreslin@umich.edu */ 712813Srdreslin@umich.educlass Packet 722813Srdreslin@umich.edu{ 732813Srdreslin@umich.edu public: 742566SN/A /** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */ 752662Sstever@eecs.umich.edu uint64_t flags; 762662Sstever@eecs.umich.edu 772662Sstever@eecs.umich.edu private: 782662Sstever@eecs.umich.edu /** A pointer to the data being transfered. It can be differnt 792662Sstever@eecs.umich.edu * sizes at each level of the heirarchy so it belongs in the 802566SN/A * packet, not request. This may or may not be populated when a 812566SN/A * responder recieves the packet. If not populated it memory 822566SN/A * should be allocated. 832662Sstever@eecs.umich.edu */ 842662Sstever@eecs.umich.edu PacketDataPtr data; 852566SN/A 862662Sstever@eecs.umich.edu /** Is the data pointer set to a value that shouldn't be freed 872662Sstever@eecs.umich.edu * when the packet is destroyed? */ 882566SN/A bool staticData; 892662Sstever@eecs.umich.edu /** The data pointer points to a value that should be freed when 902662Sstever@eecs.umich.edu * the packet is destroyed. */ 912566SN/A bool dynamicData; 922566SN/A /** the data pointer points to an array (thus delete [] ) needs to 932662Sstever@eecs.umich.edu * be called on it rather than simply delete.*/ 942662Sstever@eecs.umich.edu bool arrayData; 952381SN/A 962381SN/A /** The address of the request. This address could be virtual or 972662Sstever@eecs.umich.edu * physical, depending on the system configuration. */ 982381SN/A Addr addr; 992381SN/A 1002662Sstever@eecs.umich.edu /** The size of the request or transfer. */ 1012662Sstever@eecs.umich.edu int size; 1022662Sstever@eecs.umich.edu 1032662Sstever@eecs.umich.edu /** Device address (e.g., bus ID) of the source of the 1042381SN/A * transaction. The source is not responsible for setting this 1052381SN/A * field; it is set implicitly by the interconnect when the 1062662Sstever@eecs.umich.edu * packet is first sent. */ 1072662Sstever@eecs.umich.edu short src; 1082662Sstever@eecs.umich.edu 1092662Sstever@eecs.umich.edu /** Device address (e.g., bus ID) of the destination of the 1102662Sstever@eecs.umich.edu * transaction. The special value Broadcast indicates that the 1112641Sstever@eecs.umich.edu * packet should be routed based on its address. This field is 1122641Sstever@eecs.umich.edu * initialized in the constructor and is thus always valid 1132663Sstever@eecs.umich.edu * (unlike * addr, size, and src). */ 1142663Sstever@eecs.umich.edu short dest; 1152662Sstever@eecs.umich.edu 1162641Sstever@eecs.umich.edu /** Are the 'addr' and 'size' fields valid? */ 1172813Srdreslin@umich.edu bool addrSizeValid; 1182641Sstever@eecs.umich.edu /** Is the 'src' field valid? */ 1192641Sstever@eecs.umich.edu bool srcValid; 1202641Sstever@eecs.umich.edu 1212811Srdreslin@umich.edu 1222811Srdreslin@umich.edu public: 1232811Srdreslin@umich.edu 1243218Sgblack@eecs.umich.edu /** Used to calculate latencies for each packet.*/ 1253218Sgblack@eecs.umich.edu Tick time; 1263218Sgblack@eecs.umich.edu 1273218Sgblack@eecs.umich.edu /** The time at which the packet will be fully transmitted */ 1283218Sgblack@eecs.umich.edu Tick finishTime; 1293218Sgblack@eecs.umich.edu 1302662Sstever@eecs.umich.edu /** The time at which the first chunk of the packet will be transmitted */ 1312662Sstever@eecs.umich.edu Tick firstWordTime; 1322623SN/A 1332623SN/A /** The special destination address indicating that the packet 1342662Sstever@eecs.umich.edu * should be routed based on its address. */ 1352641Sstever@eecs.umich.edu static const short Broadcast = -1; 1362641Sstever@eecs.umich.edu 1372662Sstever@eecs.umich.edu /** A pointer to the original request. */ 1382662Sstever@eecs.umich.edu RequestPtr req; 1392662Sstever@eecs.umich.edu 1402641Sstever@eecs.umich.edu /** A virtual base opaque structure used to hold coherence-related 1412641Sstever@eecs.umich.edu * state. A specific subclass would be derived from this to 1422641Sstever@eecs.umich.edu * carry state specific to a particular coherence protocol. */ 1432641Sstever@eecs.umich.edu class CoherenceState { 1442641Sstever@eecs.umich.edu public: 1452662Sstever@eecs.umich.edu virtual ~CoherenceState() {} 1462662Sstever@eecs.umich.edu }; 1472662Sstever@eecs.umich.edu 1482662Sstever@eecs.umich.edu /** This packet's coherence state. Caches should use 1492641Sstever@eecs.umich.edu * dynamic_cast<> to cast to the state appropriate for the 1502662Sstever@eecs.umich.edu * system's coherence protocol. */ 1512662Sstever@eecs.umich.edu CoherenceState *coherence; 1522662Sstever@eecs.umich.edu 1532662Sstever@eecs.umich.edu /** A virtual base opaque structure used to hold state associated 1542662Sstever@eecs.umich.edu * with the packet but specific to the sending device (e.g., an 1552662Sstever@eecs.umich.edu * MSHR). A pointer to this state is returned in the packet's 1562662Sstever@eecs.umich.edu * response so that the sender can quickly look up the state 1572641Sstever@eecs.umich.edu * needed to process it. A specific subclass would be derived 1582641Sstever@eecs.umich.edu * from this to carry state specific to a particular sending 1592641Sstever@eecs.umich.edu * device. */ 1602641Sstever@eecs.umich.edu class SenderState { 1612641Sstever@eecs.umich.edu public: 1622662Sstever@eecs.umich.edu virtual ~SenderState() {} 1632662Sstever@eecs.umich.edu }; 1642662Sstever@eecs.umich.edu 1652641Sstever@eecs.umich.edu /** This packet's sender state. Devices should use dynamic_cast<> 1662641Sstever@eecs.umich.edu * to cast to the state appropriate to the sender. */ 1672641Sstever@eecs.umich.edu SenderState *senderState; 1683158Sgblack@eecs.umich.edu 1693158Sgblack@eecs.umich.edu private: 1702641Sstever@eecs.umich.edu /** List of command attributes. */ 1712641Sstever@eecs.umich.edu // If you add a new CommandAttribute, make sure to increase NUM_MEM_CMDS 1722641Sstever@eecs.umich.edu // as well. 1732641Sstever@eecs.umich.edu enum CommandAttribute 1742641Sstever@eecs.umich.edu { 1752641Sstever@eecs.umich.edu IsRead = 1 << 0, 1762641Sstever@eecs.umich.edu IsWrite = 1 << 1, 1772641Sstever@eecs.umich.edu IsPrefetch = 1 << 2, 1782641Sstever@eecs.umich.edu IsInvalidate = 1 << 3, 1792811Srdreslin@umich.edu IsRequest = 1 << 4, 1803156Sgblack@eecs.umich.edu IsResponse = 1 << 5, 1813156Sgblack@eecs.umich.edu NeedsResponse = 1 << 6, 1822641Sstever@eecs.umich.edu IsSWPrefetch = 1 << 7, 1832641Sstever@eecs.umich.edu IsHWPrefetch = 1 << 8, 1843158Sgblack@eecs.umich.edu IsUpgrade = 1 << 9, 1853158Sgblack@eecs.umich.edu HasData = 1 << 10 1863158Sgblack@eecs.umich.edu }; 1873158Sgblack@eecs.umich.edu 1882641Sstever@eecs.umich.edu public: 1892641Sstever@eecs.umich.edu /** List of all commands associated with a packet. */ 1902641Sstever@eecs.umich.edu enum Command 1912641Sstever@eecs.umich.edu { 1922813Srdreslin@umich.edu InvalidCmd = 0, 1932641Sstever@eecs.umich.edu ReadReq = IsRead | IsRequest | NeedsResponse, 1943158Sgblack@eecs.umich.edu WriteReq = IsWrite | IsRequest | NeedsResponse | HasData, 1953158Sgblack@eecs.umich.edu WriteReqNoAck = IsWrite | IsRequest | HasData, 1963158Sgblack@eecs.umich.edu ReadResp = IsRead | IsResponse | NeedsResponse | HasData, 1972855Srdreslin@umich.edu WriteResp = IsWrite | IsResponse | NeedsResponse, 1983158Sgblack@eecs.umich.edu Writeback = IsWrite | IsRequest | HasData, 1992811Srdreslin@umich.edu SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse, 2002811Srdreslin@umich.edu HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse, 2013156Sgblack@eecs.umich.edu SoftPFResp = IsRead | IsResponse | IsSWPrefetch 2023158Sgblack@eecs.umich.edu | NeedsResponse | HasData, 2033156Sgblack@eecs.umich.edu HardPFResp = IsRead | IsResponse | IsHWPrefetch 2043158Sgblack@eecs.umich.edu | NeedsResponse | HasData, 2052812Srdreslin@umich.edu InvalidateReq = IsInvalidate | IsRequest, 2063158Sgblack@eecs.umich.edu WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest 2073206Srdreslin@umich.edu | HasData | NeedsResponse, 2082855Srdreslin@umich.edu WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest | NeedsResponse 2093156Sgblack@eecs.umich.edu | IsResponse, 2103158Sgblack@eecs.umich.edu UpgradeReq = IsInvalidate | IsRequest | IsUpgrade, 2112641Sstever@eecs.umich.edu ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse, 2122641Sstever@eecs.umich.edu ReadExResp = IsRead | IsInvalidate | IsResponse 2132662Sstever@eecs.umich.edu | NeedsResponse | HasData 2142662Sstever@eecs.umich.edu }; 2152641Sstever@eecs.umich.edu 2162381SN/A /** Return the string name of the cmd field (for debugging and 2172811Srdreslin@umich.edu * tracing). */ 2182811Srdreslin@umich.edu const std::string &cmdString() const; 2192811Srdreslin@umich.edu 2202811Srdreslin@umich.edu /** Reutrn the string to a cmd given by idx. */ 2212811Srdreslin@umich.edu const std::string &cmdIdxToString(Command idx); 2222811Srdreslin@umich.edu 2232662Sstever@eecs.umich.edu /** Return the index of this command. */ 2242381SN/A inline int cmdToIndex() const { return (int) cmd; } 2252381SN/A 2262641Sstever@eecs.umich.edu /** The command field of the packet. */ 2272812Srdreslin@umich.edu Command cmd; 2282641Sstever@eecs.umich.edu 2292641Sstever@eecs.umich.edu bool isRead() const { return (cmd & IsRead) != 0; } 2302641Sstever@eecs.umich.edu bool isWrite() const { return (cmd & IsWrite) != 0; } 2313013Srdreslin@umich.edu bool isRequest() const { return (cmd & IsRequest) != 0; } 2323156Sgblack@eecs.umich.edu bool isResponse() const { return (cmd & IsResponse) != 0; } 2332812Srdreslin@umich.edu bool needsResponse() const { return (cmd & NeedsResponse) != 0; } 2342813Srdreslin@umich.edu bool isInvalidate() const { return (cmd & IsInvalidate) != 0; } 2352813Srdreslin@umich.edu bool hasData() const { return (cmd & HasData) != 0; } 2362814Srdreslin@umich.edu 2372814Srdreslin@umich.edu bool isCacheFill() const { return (flags & CACHE_LINE_FILL) != 0; } 2383039Sstever@eecs.umich.edu bool isNoAllocate() const { return (flags & NO_ALLOCATE) != 0; } 2392641Sstever@eecs.umich.edu bool isCompressed() const { return (flags & COMPRESSED) != 0; } 2402662Sstever@eecs.umich.edu 2412641Sstever@eecs.umich.edu bool nic_pkt() { assert("Unimplemented\n" && 0); return false; } 2422641Sstever@eecs.umich.edu 2432641Sstever@eecs.umich.edu /** Possible results of a packet's request. */ 2442641Sstever@eecs.umich.edu enum Result 2452685Ssaidi@eecs.umich.edu { 2462641Sstever@eecs.umich.edu Success, 2472641Sstever@eecs.umich.edu BadAddress, 2482641Sstever@eecs.umich.edu Nacked, 2492662Sstever@eecs.umich.edu Unknown 2502641Sstever@eecs.umich.edu }; 2512381SN/A 2522381SN/A /** The result of this packet's request. */ 2532641Sstever@eecs.umich.edu Result result; 2542641Sstever@eecs.umich.edu 2552381SN/A /** Accessor function that returns the source index of the packet. */ 2562381SN/A short getSrc() const { assert(srcValid); return src; } 2572381SN/A void setSrc(short _src) { src = _src; srcValid = true; } 2582381SN/A 2592641Sstever@eecs.umich.edu /** Accessor function that returns the destination index of 2602549SN/A the packet. */ 2612663Sstever@eecs.umich.edu short getDest() const { return dest; } 2622663Sstever@eecs.umich.edu void setDest(short _dest) { dest = _dest; } 2632883Srdreslin@umich.edu 2642813Srdreslin@umich.edu Addr getAddr() const { assert(addrSizeValid); return addr; } 2652813Srdreslin@umich.edu int getSize() const { assert(addrSizeValid); return size; } 2662813Srdreslin@umich.edu Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); } 2672641Sstever@eecs.umich.edu 2682662Sstever@eecs.umich.edu void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; } 2692662Sstever@eecs.umich.edu void cmdOverride(Command newCmd) { cmd = newCmd; } 2702662Sstever@eecs.umich.edu 2712662Sstever@eecs.umich.edu /** Constructor. Note that a Request object must be constructed 2722641Sstever@eecs.umich.edu * first, but the Requests's physical address and size fields 2732566SN/A * need not be valid. The command and destination addresses 2742641Sstever@eecs.umich.edu * must be supplied. */ 2752663Sstever@eecs.umich.edu Packet(Request *_req, Command _cmd, short _dest) 2762814Srdreslin@umich.edu : data(NULL), staticData(false), dynamicData(false), arrayData(false), 2772641Sstever@eecs.umich.edu addr(_req->paddr), size(_req->size), dest(_dest), 2782662Sstever@eecs.umich.edu addrSizeValid(_req->validPaddr), 2792641Sstever@eecs.umich.edu srcValid(false), 2802813Srdreslin@umich.edu req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), 2813018Srdreslin@umich.edu result(Unknown) 2822813Srdreslin@umich.edu { 2832813Srdreslin@umich.edu flags = 0; 2842813Srdreslin@umich.edu time = curTick; 2852813Srdreslin@umich.edu } 2862813Srdreslin@umich.edu 2872813Srdreslin@umich.edu /** Alternate constructor if you are trying to create a packet with 2882813Srdreslin@umich.edu * a request that is for a whole block, not the address from the req. 2892813Srdreslin@umich.edu * this allows for overriding the size/addr of the req.*/ 2902814Srdreslin@umich.edu Packet(Request *_req, Command _cmd, short _dest, int _blkSize) 2912814Srdreslin@umich.edu : data(NULL), staticData(false), dynamicData(false), arrayData(false), 2922813Srdreslin@umich.edu addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize), 2932813Srdreslin@umich.edu dest(_dest), 2942813Srdreslin@umich.edu addrSizeValid(_req->validPaddr), srcValid(false), 2952813Srdreslin@umich.edu req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), 2963018Srdreslin@umich.edu result(Unknown) 2972641Sstever@eecs.umich.edu { 2982549SN/A flags = 0; 2992662Sstever@eecs.umich.edu time = curTick; 3002566SN/A } 3012566SN/A 3022566SN/A /** Destructor. */ 3032662Sstever@eecs.umich.edu ~Packet() 3042662Sstever@eecs.umich.edu { deleteData(); } 3052662Sstever@eecs.umich.edu 3062662Sstever@eecs.umich.edu /** Reinitialize packet address and size from the associated 3072662Sstever@eecs.umich.edu * Request object, and reset other fields that may have been 3082662Sstever@eecs.umich.edu * modified by a previous transaction. Typically called when a 3092662Sstever@eecs.umich.edu * statically allocated Request/Packet pair is reused for 3102663Sstever@eecs.umich.edu * multiple transactions. */ 3112663Sstever@eecs.umich.edu void reinitFromRequest() { 3123018Srdreslin@umich.edu assert(req->validPaddr); 3132663Sstever@eecs.umich.edu addr = req->paddr; 3142662Sstever@eecs.umich.edu size = req->size; 3152662Sstever@eecs.umich.edu time = req->time; 3162662Sstever@eecs.umich.edu addrSizeValid = true; 3172662Sstever@eecs.umich.edu result = Unknown; 3182662Sstever@eecs.umich.edu if (dynamicData) { 3192662Sstever@eecs.umich.edu deleteData(); 3202662Sstever@eecs.umich.edu dynamicData = false; 3212566SN/A arrayData = false; 3222662Sstever@eecs.umich.edu } 3232662Sstever@eecs.umich.edu } 3242662Sstever@eecs.umich.edu 3252662Sstever@eecs.umich.edu /** Take a request packet and modify it in place to be suitable 3263135Srdreslin@umich.edu * for returning as a response to that request. Used for timing 3272662Sstever@eecs.umich.edu * accesses only. For atomic and functional accesses, the 3282662Sstever@eecs.umich.edu * request packet is always implicitly passed back *without* 3292662Sstever@eecs.umich.edu * modifying the destination fields, so this function 3302855Srdreslin@umich.edu * should not be called. */ 3312662Sstever@eecs.umich.edu void makeTimingResponse() { 3322855Srdreslin@umich.edu assert(needsResponse()); 3332662Sstever@eecs.umich.edu assert(isRequest()); 3342662Sstever@eecs.umich.edu int icmd = (int)cmd; 3352662Sstever@eecs.umich.edu icmd &= ~(IsRequest); 3362662Sstever@eecs.umich.edu icmd |= IsResponse; 3372641Sstever@eecs.umich.edu if (isRead()) 3382641Sstever@eecs.umich.edu icmd |= HasData; 3393135Srdreslin@umich.edu if (isWrite()) 3403135Srdreslin@umich.edu icmd &= ~HasData; 3413135Srdreslin@umich.edu cmd = (Command)icmd; 3423135Srdreslin@umich.edu dest = src; 3433135Srdreslin@umich.edu srcValid = false; 3443135Srdreslin@umich.edu } 3453135Srdreslin@umich.edu 3463135Srdreslin@umich.edu /** 3473135Srdreslin@umich.edu * Take a request packet and modify it in place to be suitable for 3483135Srdreslin@umich.edu * returning as a response to that request. 3493135Srdreslin@umich.edu */ 3503135Srdreslin@umich.edu void makeAtomicResponse() 3512685Ssaidi@eecs.umich.edu { 3522685Ssaidi@eecs.umich.edu assert(needsResponse()); 3532685Ssaidi@eecs.umich.edu assert(isRequest()); 3542685Ssaidi@eecs.umich.edu int icmd = (int)cmd; 3552685Ssaidi@eecs.umich.edu icmd &= ~(IsRequest); 3562685Ssaidi@eecs.umich.edu icmd |= IsResponse; 3572685Ssaidi@eecs.umich.edu if (isRead()) 3582685Ssaidi@eecs.umich.edu icmd |= HasData; 3592685Ssaidi@eecs.umich.edu if (isWrite()) 3602685Ssaidi@eecs.umich.edu icmd &= ~HasData; 3612566SN/A cmd = (Command)icmd; 3622566SN/A } 3632592SN/A 3642566SN/A /** 3652566SN/A * Take a request packet that has been returned as NACKED and 3662566SN/A * modify it so that it can be sent out again. Only packets that 3672566SN/A * need a response can be NACKED, so verify that that is true. 3682592SN/A */ 3692566SN/A void 3702566SN/A reinitNacked() 3712566SN/A { 3722592SN/A assert(needsResponse() && result == Nacked); 3732566SN/A dest = Broadcast; 3742566SN/A result = Unknown; 3752566SN/A } 3762592SN/A 3772566SN/A 3782566SN/A /** 3792566SN/A * Set the data pointer to the following value that should not be 3802592SN/A * freed. 3812566SN/A */ 3822566SN/A template <typename T> 3832566SN/A void 3842592SN/A dataStatic(T *p) 3852566SN/A { 3862566SN/A if(dynamicData) 3872566SN/A dynamicData = false; 3882592SN/A data = (PacketDataPtr)p; 3892566SN/A staticData = true; 3902566SN/A } 3912592SN/A 3922568SN/A /** 3932568SN/A * Set the data pointer to a value that should have delete [] 3942592SN/A * called on it. 3952381SN/A */ 3962381SN/A template <typename T> 3972630SN/A void 3982381SN/A dataDynamicArray(T *p) 399 { 400 assert(!staticData && !dynamicData); 401 data = (PacketDataPtr)p; 402 dynamicData = true; 403 arrayData = true; 404 } 405 406 /** 407 * set the data pointer to a value that should have delete called 408 * on it. 409 */ 410 template <typename T> 411 void 412 dataDynamic(T *p) 413 { 414 assert(!staticData && !dynamicData); 415 data = (PacketDataPtr)p; 416 dynamicData = true; 417 arrayData = false; 418 } 419 420 /** get a pointer to the data ptr. */ 421 template <typename T> 422 T* 423 getPtr() 424 { 425 assert(staticData || dynamicData); 426 return (T*)data; 427 } 428 429 /** return the value of what is pointed to in the packet. */ 430 template <typename T> 431 T get(); 432 433 /** set the value in the data pointer to v. */ 434 template <typename T> 435 void set(T v); 436 437 /** 438 * delete the data pointed to in the data pointer. Ok to call to 439 * matter how data was allocted. 440 */ 441 void deleteData(); 442 443 /** If there isn't data in the packet, allocate some. */ 444 void allocate(); 445 446 /** Do the packet modify the same addresses. */ 447 bool intersect(PacketPtr p); 448}; 449 450 451/** This function given a functional packet and a timing packet either satisfies 452 * the timing packet, or updates the timing packet to reflect the updated state 453 * in the timing packet. It returns if the functional packet should continue to 454 * traverse the memory hierarchy or not. 455 */ 456bool fixPacket(PacketPtr func, PacketPtr timing); 457 458std::ostream & operator<<(std::ostream &o, const Packet &p); 459 460#endif //__MEM_PACKET_HH 461