packet.hh revision 2663:c82193ae8467
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @file
31 * Declaration of the Packet class.
32 */
33
34#ifndef __MEM_PACKET_HH__
35#define __MEM_PACKET_HH__
36
37#include "mem/request.hh"
38#include "arch/isa_traits.hh"
39#include "sim/root.hh"
40
41struct Packet;
42typedef Packet* PacketPtr;
43typedef uint8_t* PacketDataPtr;
44
45/**
46 * A Packet is used to encapsulate a transfer between two objects in
47 * the memory system (e.g., the L1 and L2 cache).  (In contrast, a
48 * single Request travels all the way from the requester to the
49 * ultimate destination and back, possibly being conveyed by several
50 * different Packets along the way.)
51 */
52class Packet
53{
54  private:
55   /** A pointer to the data being transfered.  It can be differnt
56    *    sizes at each level of the heirarchy so it belongs in the
57    *    packet, not request. This may or may not be populated when a
58    *    responder recieves the packet. If not populated it memory
59    *    should be allocated.
60    */
61    PacketDataPtr data;
62
63    /** Is the data pointer set to a value that shouldn't be freed
64     *   when the packet is destroyed? */
65    bool staticData;
66    /** The data pointer points to a value that should be freed when
67     *   the packet is destroyed. */
68    bool dynamicData;
69    /** the data pointer points to an array (thus delete [] ) needs to
70     *   be called on it rather than simply delete.*/
71    bool arrayData;
72
73
74    /** The address of the request.  This address could be virtual or
75     *   physical, depending on the system configuration. */
76    Addr addr;
77
78     /** The size of the request or transfer. */
79    int size;
80
81    /** Device address (e.g., bus ID) of the source of the
82     *   transaction. The source is not responsible for setting this
83     *   field; it is set implicitly by the interconnect when the
84     *   packet * is first sent.  */
85    short src;
86
87    /** Device address (e.g., bus ID) of the destination of the
88     *   transaction. The special value Broadcast indicates that the
89     *   packet should be routed based on its address. This field is
90     *   initialized in the constructor and is thus always valid
91     *   (unlike * addr, size, and src). */
92    short dest;
93
94    /** Are the 'addr' and 'size' fields valid? */
95    bool addrSizeValid;
96    /** Is the 'src' field valid? */
97    bool srcValid;
98
99  public:
100
101    /** The special destination address indicating that the packet
102     *   should be routed based on its address. */
103    static const short Broadcast = -1;
104
105    /** A pointer to the original request. */
106    RequestPtr req;
107
108    /** A virtual base opaque structure used to hold coherence-related
109     *    state.  A specific subclass would be derived from this to
110     *    carry state specific to a particular coherence protocol.  */
111    class CoherenceState {
112      public:
113        virtual ~CoherenceState() {}
114    };
115
116    /** This packet's coherence state.  Caches should use
117     *   dynamic_cast<> to cast to the state appropriate for the
118     *   system's coherence protocol.  */
119    CoherenceState *coherence;
120
121    /** A virtual base opaque structure used to hold state associated
122     *    with the packet but specific to the sending device (e.g., an
123     *    MSHR).  A pointer to this state is returned in the packet's
124     *    response so that the sender can quickly look up the state
125     *    needed to process it.  A specific subclass would be derived
126     *    from this to carry state specific to a particular sending
127     *    device.  */
128    class SenderState {
129      public:
130        virtual ~SenderState() {}
131    };
132
133    /** This packet's sender state.  Devices should use dynamic_cast<>
134     *   to cast to the state appropriate to the sender. */
135    SenderState *senderState;
136
137  private:
138    /** List of command attributes. */
139    enum CommandAttribute
140    {
141        IsRead		= 1 << 0,
142        IsWrite		= 1 << 1,
143        IsPrefetch	= 1 << 2,
144        IsInvalidate	= 1 << 3,
145        IsRequest	= 1 << 4,
146        IsResponse 	= 1 << 5,
147        NeedsResponse	= 1 << 6,
148    };
149
150  public:
151    /** List of all commands associated with a packet. */
152    enum Command
153    {
154        ReadReq		= IsRead  | IsRequest | NeedsResponse,
155        WriteReq	= IsWrite | IsRequest | NeedsResponse,
156        WriteReqNoAck	= IsWrite | IsRequest,
157        ReadResp	= IsRead  | IsResponse,
158        WriteResp	= IsWrite | IsResponse
159    };
160
161    /** Return the string name of the cmd field (for debugging and
162     *   tracing). */
163    const std::string &cmdString() const;
164
165    /** The command field of the packet. */
166    Command cmd;
167
168    bool isRead() 	 { return (cmd & IsRead)  != 0; }
169    bool isRequest()	 { return (cmd & IsRequest)  != 0; }
170    bool isResponse()	 { return (cmd & IsResponse) != 0; }
171    bool needsResponse() { return (cmd & NeedsResponse) != 0; }
172
173    /** Possible results of a packet's request. */
174    enum Result
175    {
176        Success,
177        BadAddress,
178        Unknown
179    };
180
181    /** The result of this packet's request. */
182    Result result;
183
184    /** Accessor function that returns the source index of the packet. */
185    short getSrc() const { assert(srcValid); return src; }
186    void setSrc(short _src) { src = _src; srcValid = true; }
187
188    /** Accessor function that returns the destination index of
189        the packet. */
190    short getDest() const { return dest; }
191    void setDest(short _dest) { dest = _dest; }
192
193    Addr getAddr() const { assert(addrSizeValid); return addr; }
194    int getSize() const { assert(addrSizeValid); return size; }
195
196    /** Constructor.  Note that a Request object must be constructed
197     *   first, but the Requests's physical address and size fields
198     *   need not be valid. The command and destination addresses
199     *   must be supplied.  */
200    Packet(Request *_req, Command _cmd, short _dest)
201        :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
202           addr(_req->paddr), size(_req->size), dest(_dest),
203           addrSizeValid(_req->validPaddr),
204           srcValid(false),
205           req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
206           result(Unknown)
207    {
208    }
209
210    /** Destructor. */
211    ~Packet()
212    { deleteData(); }
213
214    /** Reinitialize packet address and size from the associated
215     *   Request object, and reset other fields that may have been
216     *   modified by a previous transaction.  Typically called when a
217     *   statically allocated Request/Packet pair is reused for
218     *   multiple transactions. */
219    void reinitFromRequest() {
220        assert(req->validPaddr);
221        addr = req->paddr;
222        size = req->size;
223        addrSizeValid = true;
224        result = Unknown;
225        if (dynamicData) {
226            deleteData();
227            dynamicData = false;
228            arrayData = false;
229        }
230    }
231
232    /** Take a request packet and modify it in place to be suitable
233     *   for returning as a response to that request.  Used for timing
234     *   accesses only.  For atomic and functional accesses, the
235     *   request packet is always implicitly passed back *without*
236     *   modifying the command or destination fields, so this function
237     *   should not be called. */
238    void makeTimingResponse() {
239        assert(needsResponse());
240        int icmd = (int)cmd;
241        icmd &= ~(IsRequest | NeedsResponse);
242        icmd |= IsResponse;
243        cmd = (Command)icmd;
244        dest = src;
245        srcValid = false;
246    }
247
248    /** Set the data pointer to the following value that should not be freed. */
249    template <typename T>
250    void dataStatic(T *p);
251
252    /** Set the data pointer to a value that should have delete [] called on it.
253     */
254    template <typename T>
255    void dataDynamicArray(T *p);
256
257    /** set the data pointer to a value that should have delete called on it. */
258    template <typename T>
259    void dataDynamic(T *p);
260
261    /** return the value of what is pointed to in the packet. */
262    template <typename T>
263    T get();
264
265    /** get a pointer to the data ptr. */
266    template <typename T>
267    T* getPtr();
268
269    /** set the value in the data pointer to v. */
270    template <typename T>
271    void set(T v);
272
273    /** delete the data pointed to in the data pointer. Ok to call to matter how
274     * data was allocted. */
275    void deleteData();
276
277    /** If there isn't data in the packet, allocate some. */
278    void allocate();
279
280    /** Do the packet modify the same addresses. */
281    bool intersect(Packet *p);
282};
283
284bool fixPacket(Packet *func, Packet *timing);
285#endif //__MEM_PACKET_HH
286