packet.hh revision 2641
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.
272381SN/A */
282381SN/A
292381SN/A/**
302381SN/A * @file
312381SN/A * Declaration of the Packet Class, a packet is a transaction occuring
322381SN/A * between a single level of the memory heirarchy (ie L1->L2).
332381SN/A */
342381SN/A
352381SN/A#ifndef __MEM_PACKET_HH__
362381SN/A#define __MEM_PACKET_HH__
372381SN/A
382392SN/A#include "mem/request.hh"
392423SN/A#include "arch/isa_traits.hh"
402394SN/A#include "sim/root.hh"
412394SN/A
422394SN/Astruct Packet;
432394SN/Atypedef Packet* PacketPtr;
442394SN/Atypedef uint8_t* PacketDataPtr;
452382SN/A
462381SN/A/**
472381SN/A * A Packet is the structure to handle requests between two levels
482381SN/A * of the memory system.  The Request is a global object that trancends
492381SN/A * all of the memory heirarchy, but at each levels interface a packet
502381SN/A * is created to transfer data/requests.  For example, a request would
512381SN/A * be used to initiate a request to go to memory/IOdevices, as the request
522381SN/A * passes through the memory system several packets will be created.  One
532381SN/A * will be created to go between the L1 and L2 caches and another to go to
542381SN/A * the next level and so forth.
552381SN/A *
562381SN/A * Packets are assumed to be returned in the case of a single response.  If
572381SN/A * the transaction has no response, then the consumer will delete the packet.
582381SN/A */
592641Sstever@eecs.umich.educlass Packet
602381SN/A{
612566SN/A  private:
622566SN/A   /** A pointer to the data being transfered.  It can be differnt sizes
632566SN/A        at each level of the heirarchy so it belongs in the packet,
642566SN/A        not request. This may or may not be populated when a responder recieves
652566SN/A        the packet. If not populated it memory should be allocated.
662566SN/A    */
672566SN/A    PacketDataPtr data;
682566SN/A
692566SN/A    /** Is the data pointer set to a value that shouldn't be freed when the
702566SN/A     * packet is destroyed? */
712566SN/A    bool staticData;
722566SN/A    /** The data pointer points to a value that should be freed when the packet
732566SN/A     * is destroyed. */
742566SN/A    bool dynamicData;
752566SN/A    /** the data pointer points to an array (thus delete [] ) needs to be called
762566SN/A     * on it rather than simply delete.*/
772566SN/A    bool arrayData;
782566SN/A
792566SN/A
802381SN/A    /** The address of the request, could be virtual or physical (depending on
812381SN/A        cache configurations). */
822381SN/A    Addr addr;
832381SN/A
842566SN/A     /** Indicates the size of the request. */
852381SN/A    int size;
862381SN/A
872381SN/A    /** A index of the source of the transaction. */
882381SN/A    short src;
892381SN/A
902641Sstever@eecs.umich.edu    /** A index to the destination of the transaction. */
912641Sstever@eecs.umich.edu    short dest;
922641Sstever@eecs.umich.edu
932641Sstever@eecs.umich.edu    bool addrValid;
942641Sstever@eecs.umich.edu    bool sizeValid;
952641Sstever@eecs.umich.edu    bool srcValid;
962641Sstever@eecs.umich.edu
972641Sstever@eecs.umich.edu  public:
982641Sstever@eecs.umich.edu
992623SN/A    static const short Broadcast = -1;
1002623SN/A
1012641Sstever@eecs.umich.edu    /** A pointer to the overall request. */
1022641Sstever@eecs.umich.edu    RequestPtr req;
1032641Sstever@eecs.umich.edu
1042641Sstever@eecs.umich.edu    class CoherenceState {
1052641Sstever@eecs.umich.edu      public:
1062641Sstever@eecs.umich.edu        virtual ~CoherenceState() {}
1072641Sstever@eecs.umich.edu    };
1082641Sstever@eecs.umich.edu
1092641Sstever@eecs.umich.edu    /** A virtual base opaque structure used to hold
1102641Sstever@eecs.umich.edu        coherence status messages. */
1112641Sstever@eecs.umich.edu    CoherenceState *coherence;  // virtual base opaque,
1122641Sstever@eecs.umich.edu                           // assert(dynamic_cast<Foo>) etc.
1132641Sstever@eecs.umich.edu
1142641Sstever@eecs.umich.edu    class SenderState {
1152641Sstever@eecs.umich.edu      public:
1162641Sstever@eecs.umich.edu        virtual ~SenderState() {}
1172641Sstever@eecs.umich.edu    };
1182641Sstever@eecs.umich.edu
1192641Sstever@eecs.umich.edu    /** A virtual base opaque structure used to hold the senders state. */
1202641Sstever@eecs.umich.edu    SenderState *senderState; // virtual base opaque,
1212641Sstever@eecs.umich.edu    // assert(dynamic_cast<Foo>) etc.
1222641Sstever@eecs.umich.edu
1232641Sstever@eecs.umich.edu  private:
1242641Sstever@eecs.umich.edu    /** List of command attributes. */
1252641Sstever@eecs.umich.edu    enum CommandAttribute
1262641Sstever@eecs.umich.edu    {
1272641Sstever@eecs.umich.edu        IsRead		= 1 << 0,
1282641Sstever@eecs.umich.edu        IsWrite		= 1 << 1,
1292641Sstever@eecs.umich.edu        IsPrefetch	= 1 << 2,
1302641Sstever@eecs.umich.edu        IsInvalidate	= 1 << 3,
1312641Sstever@eecs.umich.edu        IsRequest	= 1 << 4,
1322641Sstever@eecs.umich.edu        IsResponse 	= 1 << 5,
1332641Sstever@eecs.umich.edu        NeedsResponse	= 1 << 6,
1342641Sstever@eecs.umich.edu    };
1352641Sstever@eecs.umich.edu
1362641Sstever@eecs.umich.edu  public:
1372641Sstever@eecs.umich.edu    /** List of all commands associated with a packet. */
1382641Sstever@eecs.umich.edu    enum Command
1392641Sstever@eecs.umich.edu    {
1402641Sstever@eecs.umich.edu        ReadReq		= IsRead  | IsRequest | NeedsResponse,
1412641Sstever@eecs.umich.edu        WriteReq	= IsWrite | IsRequest | NeedsResponse,
1422641Sstever@eecs.umich.edu        WriteReqNoAck	= IsWrite | IsRequest,
1432641Sstever@eecs.umich.edu        ReadResp	= IsRead  | IsResponse,
1442641Sstever@eecs.umich.edu        WriteResp	= IsWrite | IsResponse
1452641Sstever@eecs.umich.edu    };
1462641Sstever@eecs.umich.edu
1472641Sstever@eecs.umich.edu    const std::string &cmdString() const;
1482381SN/A
1492381SN/A    /** The command of the transaction. */
1502381SN/A    Command cmd;
1512381SN/A
1522641Sstever@eecs.umich.edu    bool isRead() 	 { return (cmd & IsRead)  != 0; }
1532641Sstever@eecs.umich.edu    bool isRequest()	 { return (cmd & IsRequest)  != 0; }
1542641Sstever@eecs.umich.edu    bool isResponse()	 { return (cmd & IsResponse) != 0; }
1552641Sstever@eecs.umich.edu    bool needsResponse() { return (cmd & NeedsResponse) != 0; }
1562641Sstever@eecs.umich.edu
1572641Sstever@eecs.umich.edu    void makeTimingResponse() {
1582641Sstever@eecs.umich.edu        assert(needsResponse());
1592641Sstever@eecs.umich.edu        int icmd = (int)cmd;
1602641Sstever@eecs.umich.edu        icmd &= ~(IsRequest | NeedsResponse);
1612641Sstever@eecs.umich.edu        icmd |= IsResponse;
1622641Sstever@eecs.umich.edu        cmd = (Command)icmd;
1632641Sstever@eecs.umich.edu        dest = src;
1642641Sstever@eecs.umich.edu        srcValid = false;
1652641Sstever@eecs.umich.edu    }
1662641Sstever@eecs.umich.edu
1672497SN/A    /** The time this request was responded to. Used to calculate latencies. */
1682497SN/A    Tick time;
1692497SN/A
1702641Sstever@eecs.umich.edu    /** The result of a particular packets request. */
1712641Sstever@eecs.umich.edu    enum Result
1722641Sstever@eecs.umich.edu    {
1732641Sstever@eecs.umich.edu        Success,
1742641Sstever@eecs.umich.edu        BadAddress,
1752641Sstever@eecs.umich.edu        Unknown
1762641Sstever@eecs.umich.edu    };
1772641Sstever@eecs.umich.edu
1782381SN/A    /** The result of the packet transaction. */
1792641Sstever@eecs.umich.edu    Result result;
1802381SN/A
1812381SN/A    /** Accessor function that returns the source index of the packet. */
1822641Sstever@eecs.umich.edu    short getSrc() const { assert(srcValid); return src; }
1832641Sstever@eecs.umich.edu    void setSrc(short _src) { src = _src; srcValid = true; }
1842381SN/A
1852381SN/A    /** Accessor function that returns the destination index of
1862381SN/A        the packet. */
1872381SN/A    short getDest() const { return dest; }
1882641Sstever@eecs.umich.edu    void setDest(short _dest) { dest = _dest; }
1892549SN/A
1902641Sstever@eecs.umich.edu    Addr getAddr() const { assert(addrValid); return addr; }
1912641Sstever@eecs.umich.edu    void setAddr(Addr _addr) { addr = _addr; addrValid = true; }
1922641Sstever@eecs.umich.edu
1932641Sstever@eecs.umich.edu    int getSize() const { assert(sizeValid); return size; }
1942641Sstever@eecs.umich.edu    void setSize(int _size) { size = _size; sizeValid = true; }
1952641Sstever@eecs.umich.edu
1962641Sstever@eecs.umich.edu
1972641Sstever@eecs.umich.edu    Packet(Request *_req, Command _cmd, short _dest)
1982566SN/A        :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
1992641Sstever@eecs.umich.edu           addr(_req->paddr), size(_req->size), dest(_dest),
2002641Sstever@eecs.umich.edu           addrValid(_req->validPaddr), sizeValid(_req->validSize),
2012641Sstever@eecs.umich.edu           srcValid(false),
2022641Sstever@eecs.umich.edu           req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
2032568SN/A           time(curTick), result(Unknown)
2042641Sstever@eecs.umich.edu    {
2052641Sstever@eecs.umich.edu    }
2062549SN/A
2072566SN/A    ~Packet()
2082566SN/A    { deleteData(); }
2092566SN/A
2102566SN/A
2112566SN/A    /** Minimally reset a packet so something like simple cpu can reuse it. */
2122592SN/A    void reset();
2132566SN/A
2142641Sstever@eecs.umich.edu    void reinitFromRequest() {
2152641Sstever@eecs.umich.edu        if (req->validPaddr) setAddr(req->paddr);
2162641Sstever@eecs.umich.edu        if (req->validSize)  setSize(req->size);
2172641Sstever@eecs.umich.edu    }
2182641Sstever@eecs.umich.edu
2192566SN/A    /** Set the data pointer to the following value that should not be freed. */
2202566SN/A    template <typename T>
2212592SN/A    void dataStatic(T *p);
2222566SN/A
2232566SN/A    /** Set the data pointer to a value that should have delete [] called on it.
2242566SN/A     */
2252566SN/A    template <typename T>
2262592SN/A    void dataDynamicArray(T *p);
2272566SN/A
2282566SN/A    /** set the data pointer to a value that should have delete called on it. */
2292566SN/A    template <typename T>
2302592SN/A    void dataDynamic(T *p);
2312566SN/A
2322566SN/A    /** return the value of what is pointed to in the packet. */
2332566SN/A    template <typename T>
2342592SN/A    T get();
2352566SN/A
2362566SN/A    /** get a pointer to the data ptr. */
2372566SN/A    template <typename T>
2382592SN/A    T* getPtr();
2392566SN/A
2402566SN/A    /** set the value in the data pointer to v. */
2412566SN/A    template <typename T>
2422592SN/A    void set(T v);
2432566SN/A
2442566SN/A    /** delete the data pointed to in the data pointer. Ok to call to matter how
2452566SN/A     * data was allocted. */
2462592SN/A    void deleteData();
2472566SN/A
2482566SN/A    /** If there isn't data in the packet, allocate some. */
2492592SN/A    void allocate();
2502568SN/A
2512568SN/A    /** Do the packet modify the same addresses. */
2522592SN/A    bool intersect(Packet *p);
2532381SN/A};
2542381SN/A
2552630SN/Abool fixPacket(Packet *func, Packet *timing);
2562381SN/A#endif //__MEM_PACKET_HH
257