packet.hh revision 2641:6d9d837e2032
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, a packet is a transaction occuring
32 * between a single level of the memory heirarchy (ie L1->L2).
33 */
34
35#ifndef __MEM_PACKET_HH__
36#define __MEM_PACKET_HH__
37
38#include "mem/request.hh"
39#include "arch/isa_traits.hh"
40#include "sim/root.hh"
41
42struct Packet;
43typedef Packet* PacketPtr;
44typedef uint8_t* PacketDataPtr;
45
46/**
47 * A Packet is the structure to handle requests between two levels
48 * of the memory system.  The Request is a global object that trancends
49 * all of the memory heirarchy, but at each levels interface a packet
50 * is created to transfer data/requests.  For example, a request would
51 * be used to initiate a request to go to memory/IOdevices, as the request
52 * passes through the memory system several packets will be created.  One
53 * will be created to go between the L1 and L2 caches and another to go to
54 * the next level and so forth.
55 *
56 * Packets are assumed to be returned in the case of a single response.  If
57 * the transaction has no response, then the consumer will delete the packet.
58 */
59class Packet
60{
61  private:
62   /** A pointer to the data being transfered.  It can be differnt sizes
63        at each level of the heirarchy so it belongs in the packet,
64        not request. This may or may not be populated when a responder recieves
65        the packet. If not populated it memory should be allocated.
66    */
67    PacketDataPtr data;
68
69    /** Is the data pointer set to a value that shouldn't be freed when the
70     * packet is destroyed? */
71    bool staticData;
72    /** The data pointer points to a value that should be freed when the packet
73     * is destroyed. */
74    bool dynamicData;
75    /** the data pointer points to an array (thus delete [] ) needs to be called
76     * on it rather than simply delete.*/
77    bool arrayData;
78
79
80    /** The address of the request, could be virtual or physical (depending on
81        cache configurations). */
82    Addr addr;
83
84     /** Indicates the size of the request. */
85    int size;
86
87    /** A index of the source of the transaction. */
88    short src;
89
90    /** A index to the destination of the transaction. */
91    short dest;
92
93    bool addrValid;
94    bool sizeValid;
95    bool srcValid;
96
97  public:
98
99    static const short Broadcast = -1;
100
101    /** A pointer to the overall request. */
102    RequestPtr req;
103
104    class CoherenceState {
105      public:
106        virtual ~CoherenceState() {}
107    };
108
109    /** A virtual base opaque structure used to hold
110        coherence status messages. */
111    CoherenceState *coherence;  // virtual base opaque,
112                           // assert(dynamic_cast<Foo>) etc.
113
114    class SenderState {
115      public:
116        virtual ~SenderState() {}
117    };
118
119    /** A virtual base opaque structure used to hold the senders state. */
120    SenderState *senderState; // virtual base opaque,
121    // assert(dynamic_cast<Foo>) etc.
122
123  private:
124    /** List of command attributes. */
125    enum CommandAttribute
126    {
127        IsRead		= 1 << 0,
128        IsWrite		= 1 << 1,
129        IsPrefetch	= 1 << 2,
130        IsInvalidate	= 1 << 3,
131        IsRequest	= 1 << 4,
132        IsResponse 	= 1 << 5,
133        NeedsResponse	= 1 << 6,
134    };
135
136  public:
137    /** List of all commands associated with a packet. */
138    enum Command
139    {
140        ReadReq		= IsRead  | IsRequest | NeedsResponse,
141        WriteReq	= IsWrite | IsRequest | NeedsResponse,
142        WriteReqNoAck	= IsWrite | IsRequest,
143        ReadResp	= IsRead  | IsResponse,
144        WriteResp	= IsWrite | IsResponse
145    };
146
147    const std::string &cmdString() const;
148
149    /** The command of the transaction. */
150    Command cmd;
151
152    bool isRead() 	 { return (cmd & IsRead)  != 0; }
153    bool isRequest()	 { return (cmd & IsRequest)  != 0; }
154    bool isResponse()	 { return (cmd & IsResponse) != 0; }
155    bool needsResponse() { return (cmd & NeedsResponse) != 0; }
156
157    void makeTimingResponse() {
158        assert(needsResponse());
159        int icmd = (int)cmd;
160        icmd &= ~(IsRequest | NeedsResponse);
161        icmd |= IsResponse;
162        cmd = (Command)icmd;
163        dest = src;
164        srcValid = false;
165    }
166
167    /** The time this request was responded to. Used to calculate latencies. */
168    Tick time;
169
170    /** The result of a particular packets request. */
171    enum Result
172    {
173        Success,
174        BadAddress,
175        Unknown
176    };
177
178    /** The result of the packet transaction. */
179    Result result;
180
181    /** Accessor function that returns the source index of the packet. */
182    short getSrc() const { assert(srcValid); return src; }
183    void setSrc(short _src) { src = _src; srcValid = true; }
184
185    /** Accessor function that returns the destination index of
186        the packet. */
187    short getDest() const { return dest; }
188    void setDest(short _dest) { dest = _dest; }
189
190    Addr getAddr() const { assert(addrValid); return addr; }
191    void setAddr(Addr _addr) { addr = _addr; addrValid = true; }
192
193    int getSize() const { assert(sizeValid); return size; }
194    void setSize(int _size) { size = _size; sizeValid = true; }
195
196
197    Packet(Request *_req, Command _cmd, short _dest)
198        :  data(NULL), staticData(false), dynamicData(false), arrayData(false),
199           addr(_req->paddr), size(_req->size), dest(_dest),
200           addrValid(_req->validPaddr), sizeValid(_req->validSize),
201           srcValid(false),
202           req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
203           time(curTick), result(Unknown)
204    {
205    }
206
207    ~Packet()
208    { deleteData(); }
209
210
211    /** Minimally reset a packet so something like simple cpu can reuse it. */
212    void reset();
213
214    void reinitFromRequest() {
215        if (req->validPaddr) setAddr(req->paddr);
216        if (req->validSize)  setSize(req->size);
217    }
218
219    /** Set the data pointer to the following value that should not be freed. */
220    template <typename T>
221    void dataStatic(T *p);
222
223    /** Set the data pointer to a value that should have delete [] called on it.
224     */
225    template <typename T>
226    void dataDynamicArray(T *p);
227
228    /** set the data pointer to a value that should have delete called on it. */
229    template <typename T>
230    void dataDynamic(T *p);
231
232    /** return the value of what is pointed to in the packet. */
233    template <typename T>
234    T get();
235
236    /** get a pointer to the data ptr. */
237    template <typename T>
238    T* getPtr();
239
240    /** set the value in the data pointer to v. */
241    template <typename T>
242    void set(T v);
243
244    /** delete the data pointed to in the data pointer. Ok to call to matter how
245     * data was allocted. */
246    void deleteData();
247
248    /** If there isn't data in the packet, allocate some. */
249    void allocate();
250
251    /** Do the packet modify the same addresses. */
252    bool intersect(Packet *p);
253};
254
255bool fixPacket(Packet *func, Packet *timing);
256#endif //__MEM_PACKET_HH
257