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).
|
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/**
|
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.
|
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:
|
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.
|
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
|
69 /** Is the data pointer set to a value that shouldn't be freed when the
70 * packet is destroyed? */
|
63 /** Is the data pointer set to a value that shouldn't be freed 64 * when the packet is destroyed? */ |
65 bool staticData;
|
72 /** The data pointer points to a value that should be freed when the packet
73 * is destroyed. */
|
66 /** The data pointer points to a value that should be freed when 67 * the packet is destroyed. */ |
68 bool dynamicData;
|
75 /** the data pointer points to an array (thus delete [] ) needs to be called
76 * on it rather than simply delete.*/
|
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
|
80 /** The address of the request, could be virtual or physical (depending on
81 cache configurations). */
|
74 /** The address of the request. This address could be virtual or 75 * physical, depending on the system configuration. */ |
76 Addr addr; 77
|
84 /** Indicates the size of the request. */
|
78 /** The size of the request or transfer. */ |
79 int size; 80
|
87 /** A index of the source of the transaction. */
|
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
|
90 /** A index to the destination of the transaction. */
|
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 /** Is the 'addr' field valid? */ |
95 bool addrValid;
|
96 /** Is the 'size' field valid? */ |
97 bool sizeValid;
|
98 /** Is the 'src' field valid? */ |
99 bool srcValid; 100 101 public: 102
|
103 /** The special destination address indicating that the packet 104 * should be routed based on its address. */ |
105 static const short Broadcast = -1; 106
|
101 /** A pointer to the overall request. */
|
107 /** A pointer to the original request. */ |
108 RequestPtr req; 109
|
110 /** A virtual base opaque structure used to hold coherence-related 111 * state. A specific subclass would be derived from this to 112 * carry state specific to a particular coherence protocol. */ |
113 class CoherenceState { 114 public: 115 virtual ~CoherenceState() {} 116 }; 117
|
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.
|
118 /** This packet's coherence state. Caches should use 119 * dynamic_cast<> to cast to the state appropriate for the 120 * system's coherence protocol. */ 121 CoherenceState *coherence; |
122
|
123 /** A virtual base opaque structure used to hold state associated 124 * with the packet but specific to the sending device (e.g., an 125 * MSHR). A pointer to this state is returned in the packet's 126 * response so that the sender can quickly look up the state 127 * needed to process it. A specific subclass would be derived 128 * from this to carry state specific to a particular sending 129 * device. */ |
130 class SenderState { 131 public: 132 virtual ~SenderState() {} 133 }; 134
|
119 /** A virtual base opaque structure used to hold the senders state. */
120 SenderState *senderState; // virtual base opaque,
121 // assert(dynamic_cast<Foo>) etc.
|
135 /** This packet's sender state. Devices should use dynamic_cast<> 136 * to cast to the state appropriate to the sender. */ 137 SenderState *senderState; |
138 139 private: 140 /** List of command attributes. */ 141 enum CommandAttribute 142 { 143 IsRead = 1 << 0, 144 IsWrite = 1 << 1, 145 IsPrefetch = 1 << 2, 146 IsInvalidate = 1 << 3, 147 IsRequest = 1 << 4, 148 IsResponse = 1 << 5, 149 NeedsResponse = 1 << 6, 150 }; 151 152 public: 153 /** List of all commands associated with a packet. */ 154 enum Command 155 { 156 ReadReq = IsRead | IsRequest | NeedsResponse, 157 WriteReq = IsWrite | IsRequest | NeedsResponse, 158 WriteReqNoAck = IsWrite | IsRequest, 159 ReadResp = IsRead | IsResponse, 160 WriteResp = IsWrite | IsResponse 161 }; 162
|
163 /** Return the string name of the cmd field (for debugging and 164 * tracing). */ |
165 const std::string &cmdString() const; 166
|
149 /** The command of the transaction. */
|
167 /** The command field of the packet. */ |
168 Command cmd; 169 170 bool isRead() { return (cmd & IsRead) != 0; } 171 bool isRequest() { return (cmd & IsRequest) != 0; } 172 bool isResponse() { return (cmd & IsResponse) != 0; } 173 bool needsResponse() { return (cmd & NeedsResponse) != 0; } 174
|
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. */
|
175 /** Possible results of a packet's request. */ |
176 enum Result 177 { 178 Success, 179 BadAddress, 180 Unknown 181 }; 182
|
178 /** The result of the packet transaction. */
|
183 /** The result of this packet's request. */ |
184 Result result; 185 186 /** Accessor function that returns the source index of the packet. */ 187 short getSrc() const { assert(srcValid); return src; } 188 void setSrc(short _src) { src = _src; srcValid = true; } 189 190 /** Accessor function that returns the destination index of 191 the packet. */ 192 short getDest() const { return dest; } 193 void setDest(short _dest) { dest = _dest; } 194 195 Addr getAddr() const { assert(addrValid); return addr; } 196 void setAddr(Addr _addr) { addr = _addr; addrValid = true; } 197 198 int getSize() const { assert(sizeValid); return size; } 199 void setSize(int _size) { size = _size; sizeValid = true; } 200
|
196
|
201 /** Constructor. Note that a Request object must be constructed 202 * first, but the Requests's physical address and size fields 203 * need not be valid. The command and destination addresses 204 * must be supplied. */ |
205 Packet(Request *_req, Command _cmd, short _dest) 206 : data(NULL), staticData(false), dynamicData(false), arrayData(false), 207 addr(_req->paddr), size(_req->size), dest(_dest), 208 addrValid(_req->validPaddr), sizeValid(_req->validSize), 209 srcValid(false), 210 req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
|
203 time(curTick), result(Unknown)
|
211 result(Unknown) |
212 { 213 } 214
|
215 /** Destructor. */ |
216 ~Packet() 217 { deleteData(); } 218
|
210
211 /** Minimally reset a packet so something like simple cpu can reuse it. */
212 void reset();
213
|
219 /** Reinitialize packet address and size from the associated 220 * Request object, and reset other fields that may have been 221 * modified by a previous transaction. Typically called when a 222 * statically allocated Request/Packet pair is reused for 223 * multiple transactions. */ |
224 void reinitFromRequest() {
|
215 if (req->validPaddr) setAddr(req->paddr);
216 if (req->validSize) setSize(req->size);
|
225 assert(req->validPaddr); 226 setAddr(req->paddr); 227 assert(req->validSize); 228 setSize(req->size); 229 result = Unknown; 230 if (dynamicData) { 231 deleteData(); 232 dynamicData = false; 233 arrayData = false; 234 } |
235 } 236
|
237 /** Take a request packet and modify it in place to be suitable 238 * for returning as a response to that request. Used for timing 239 * accesses only. For atomic and functional accesses, the 240 * request packet is always implicitly passed back *without* 241 * modifying the command or destination fields, so this function 242 * should not be called. */ 243 void makeTimingResponse() { 244 assert(needsResponse()); 245 int icmd = (int)cmd; 246 icmd &= ~(IsRequest | NeedsResponse); 247 icmd |= IsResponse; 248 cmd = (Command)icmd; 249 dest = src; 250 srcValid = false; 251 } 252 |
253 /** Set the data pointer to the following value that should not be freed. */ 254 template <typename T> 255 void dataStatic(T *p); 256 257 /** Set the data pointer to a value that should have delete [] called on it. 258 */ 259 template <typename T> 260 void dataDynamicArray(T *p); 261 262 /** set the data pointer to a value that should have delete called on it. */ 263 template <typename T> 264 void dataDynamic(T *p); 265 266 /** return the value of what is pointed to in the packet. */ 267 template <typename T> 268 T get(); 269 270 /** get a pointer to the data ptr. */ 271 template <typename T> 272 T* getPtr(); 273 274 /** set the value in the data pointer to v. */ 275 template <typename T> 276 void set(T v); 277 278 /** delete the data pointed to in the data pointer. Ok to call to matter how 279 * data was allocted. */ 280 void deleteData(); 281 282 /** If there isn't data in the packet, allocate some. */ 283 void allocate(); 284 285 /** Do the packet modify the same addresses. */ 286 bool intersect(Packet *p); 287}; 288 289bool fixPacket(Packet *func, Packet *timing); 290#endif //__MEM_PACKET_HH
|