packet.hh (11256:65db40192591) packet.hh (11284:b3926db25371)
1/*
2 * Copyright (c) 2012-2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2006 The Regents of The University of Michigan
15 * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Ron Dreslinski
42 * Steve Reinhardt
43 * Ali Saidi
44 * Andreas Hansson
45 */
46
47/**
48 * @file
49 * Declaration of the Packet class.
50 */
51
52#ifndef __MEM_PACKET_HH__
53#define __MEM_PACKET_HH__
54
55#include <bitset>
56#include <cassert>
57#include <list>
58
59#include "base/cast.hh"
60#include "base/compiler.hh"
61#include "base/flags.hh"
62#include "base/misc.hh"
63#include "base/printable.hh"
64#include "base/types.hh"
65#include "mem/request.hh"
66#include "sim/core.hh"
67
68class Packet;
69typedef Packet *PacketPtr;
70typedef uint8_t* PacketDataPtr;
71typedef std::list<PacketPtr> PacketList;
72
73class MemCmd
74{
75 friend class Packet;
76
77 public:
78 /**
79 * List of all commands associated with a packet.
80 */
81 enum Command
82 {
83 InvalidCmd,
84 ReadReq,
85 ReadResp,
86 ReadRespWithInvalidate,
87 WriteReq,
88 WriteResp,
89 WritebackDirty,
90 WritebackClean,
91 CleanEvict,
92 SoftPFReq,
93 HardPFReq,
94 SoftPFResp,
95 HardPFResp,
96 WriteLineReq,
97 UpgradeReq,
98 SCUpgradeReq, // Special "weak" upgrade for StoreCond
99 UpgradeResp,
100 SCUpgradeFailReq, // Failed SCUpgradeReq in MSHR (never sent)
101 UpgradeFailResp, // Valid for SCUpgradeReq only
102 ReadExReq,
103 ReadExResp,
104 ReadCleanReq,
105 ReadSharedReq,
106 LoadLockedReq,
107 StoreCondReq,
108 StoreCondFailReq, // Failed StoreCondReq in MSHR (never sent)
109 StoreCondResp,
110 SwapReq,
111 SwapResp,
112 MessageReq,
113 MessageResp,
114 MemFenceReq,
115 MemFenceResp,
116 // Error responses
117 // @TODO these should be classified as responses rather than
118 // requests; coding them as requests initially for backwards
119 // compatibility
120 InvalidDestError, // packet dest field invalid
121 BadAddressError, // memory address invalid
122 FunctionalReadError, // unable to fulfill functional read
123 FunctionalWriteError, // unable to fulfill functional write
124 // Fake simulator-only commands
125 PrintReq, // Print state matching address
126 FlushReq, //request for a cache flush
127 InvalidateReq, // request for address to be invalidated
128 InvalidateResp,
129 NUM_MEM_CMDS
130 };
131
132 private:
133 /**
134 * List of command attributes.
135 */
136 enum Attribute
137 {
138 IsRead, //!< Data flows from responder to requester
139 IsWrite, //!< Data flows from requester to responder
140 IsUpgrade,
141 IsInvalidate,
1/*
2 * Copyright (c) 2012-2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2006 The Regents of The University of Michigan
15 * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Ron Dreslinski
42 * Steve Reinhardt
43 * Ali Saidi
44 * Andreas Hansson
45 */
46
47/**
48 * @file
49 * Declaration of the Packet class.
50 */
51
52#ifndef __MEM_PACKET_HH__
53#define __MEM_PACKET_HH__
54
55#include <bitset>
56#include <cassert>
57#include <list>
58
59#include "base/cast.hh"
60#include "base/compiler.hh"
61#include "base/flags.hh"
62#include "base/misc.hh"
63#include "base/printable.hh"
64#include "base/types.hh"
65#include "mem/request.hh"
66#include "sim/core.hh"
67
68class Packet;
69typedef Packet *PacketPtr;
70typedef uint8_t* PacketDataPtr;
71typedef std::list<PacketPtr> PacketList;
72
73class MemCmd
74{
75 friend class Packet;
76
77 public:
78 /**
79 * List of all commands associated with a packet.
80 */
81 enum Command
82 {
83 InvalidCmd,
84 ReadReq,
85 ReadResp,
86 ReadRespWithInvalidate,
87 WriteReq,
88 WriteResp,
89 WritebackDirty,
90 WritebackClean,
91 CleanEvict,
92 SoftPFReq,
93 HardPFReq,
94 SoftPFResp,
95 HardPFResp,
96 WriteLineReq,
97 UpgradeReq,
98 SCUpgradeReq, // Special "weak" upgrade for StoreCond
99 UpgradeResp,
100 SCUpgradeFailReq, // Failed SCUpgradeReq in MSHR (never sent)
101 UpgradeFailResp, // Valid for SCUpgradeReq only
102 ReadExReq,
103 ReadExResp,
104 ReadCleanReq,
105 ReadSharedReq,
106 LoadLockedReq,
107 StoreCondReq,
108 StoreCondFailReq, // Failed StoreCondReq in MSHR (never sent)
109 StoreCondResp,
110 SwapReq,
111 SwapResp,
112 MessageReq,
113 MessageResp,
114 MemFenceReq,
115 MemFenceResp,
116 // Error responses
117 // @TODO these should be classified as responses rather than
118 // requests; coding them as requests initially for backwards
119 // compatibility
120 InvalidDestError, // packet dest field invalid
121 BadAddressError, // memory address invalid
122 FunctionalReadError, // unable to fulfill functional read
123 FunctionalWriteError, // unable to fulfill functional write
124 // Fake simulator-only commands
125 PrintReq, // Print state matching address
126 FlushReq, //request for a cache flush
127 InvalidateReq, // request for address to be invalidated
128 InvalidateResp,
129 NUM_MEM_CMDS
130 };
131
132 private:
133 /**
134 * List of command attributes.
135 */
136 enum Attribute
137 {
138 IsRead, //!< Data flows from responder to requester
139 IsWrite, //!< Data flows from requester to responder
140 IsUpgrade,
141 IsInvalidate,
142 NeedsExclusive, //!< Requires exclusive copy to complete in-cache
142 NeedsWritable, //!< Requires writable copy to complete in-cache
143 IsRequest, //!< Issued by requester
144 IsResponse, //!< Issue by responder
145 NeedsResponse, //!< Requester needs response from target
146 IsEviction,
147 IsSWPrefetch,
148 IsHWPrefetch,
149 IsLlsc, //!< Alpha/MIPS LL or SC access
150 HasData, //!< There is an associated payload
151 IsError, //!< Error response
152 IsPrint, //!< Print state matching address (for debugging)
153 IsFlush, //!< Flush the address from caches
154 NUM_COMMAND_ATTRIBUTES
155 };
156
157 /**
158 * Structure that defines attributes and other data associated
159 * with a Command.
160 */
161 struct CommandInfo
162 {
163 /// Set of attribute flags.
164 const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
165 /// Corresponding response for requests; InvalidCmd if no
166 /// response is applicable.
167 const Command response;
168 /// String representation (for printing)
169 const std::string str;
170 };
171
172 /// Array to map Command enum to associated info.
173 static const CommandInfo commandInfo[];
174
175 private:
176
177 Command cmd;
178
179 bool
180 testCmdAttrib(MemCmd::Attribute attrib) const
181 {
182 return commandInfo[cmd].attributes[attrib] != 0;
183 }
184
185 public:
186
187 bool isRead() const { return testCmdAttrib(IsRead); }
188 bool isWrite() const { return testCmdAttrib(IsWrite); }
189 bool isUpgrade() const { return testCmdAttrib(IsUpgrade); }
190 bool isRequest() const { return testCmdAttrib(IsRequest); }
191 bool isResponse() const { return testCmdAttrib(IsResponse); }
143 IsRequest, //!< Issued by requester
144 IsResponse, //!< Issue by responder
145 NeedsResponse, //!< Requester needs response from target
146 IsEviction,
147 IsSWPrefetch,
148 IsHWPrefetch,
149 IsLlsc, //!< Alpha/MIPS LL or SC access
150 HasData, //!< There is an associated payload
151 IsError, //!< Error response
152 IsPrint, //!< Print state matching address (for debugging)
153 IsFlush, //!< Flush the address from caches
154 NUM_COMMAND_ATTRIBUTES
155 };
156
157 /**
158 * Structure that defines attributes and other data associated
159 * with a Command.
160 */
161 struct CommandInfo
162 {
163 /// Set of attribute flags.
164 const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
165 /// Corresponding response for requests; InvalidCmd if no
166 /// response is applicable.
167 const Command response;
168 /// String representation (for printing)
169 const std::string str;
170 };
171
172 /// Array to map Command enum to associated info.
173 static const CommandInfo commandInfo[];
174
175 private:
176
177 Command cmd;
178
179 bool
180 testCmdAttrib(MemCmd::Attribute attrib) const
181 {
182 return commandInfo[cmd].attributes[attrib] != 0;
183 }
184
185 public:
186
187 bool isRead() const { return testCmdAttrib(IsRead); }
188 bool isWrite() const { return testCmdAttrib(IsWrite); }
189 bool isUpgrade() const { return testCmdAttrib(IsUpgrade); }
190 bool isRequest() const { return testCmdAttrib(IsRequest); }
191 bool isResponse() const { return testCmdAttrib(IsResponse); }
192 bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); }
192 bool needsWritable() const { return testCmdAttrib(NeedsWritable); }
193 bool needsResponse() const { return testCmdAttrib(NeedsResponse); }
194 bool isInvalidate() const { return testCmdAttrib(IsInvalidate); }
195 bool isEviction() const { return testCmdAttrib(IsEviction); }
196
197 /**
198 * A writeback is an eviction that carries data.
199 */
200 bool isWriteback() const { return testCmdAttrib(IsEviction) &&
201 testCmdAttrib(HasData); }
202
203 /**
204 * Check if this particular packet type carries payload data. Note
205 * that this does not reflect if the data pointer of the packet is
206 * valid or not.
207 */
208 bool hasData() const { return testCmdAttrib(HasData); }
209 bool isLLSC() const { return testCmdAttrib(IsLlsc); }
210 bool isSWPrefetch() const { return testCmdAttrib(IsSWPrefetch); }
211 bool isHWPrefetch() const { return testCmdAttrib(IsHWPrefetch); }
212 bool isPrefetch() const { return testCmdAttrib(IsSWPrefetch) ||
213 testCmdAttrib(IsHWPrefetch); }
214 bool isError() const { return testCmdAttrib(IsError); }
215 bool isPrint() const { return testCmdAttrib(IsPrint); }
216 bool isFlush() const { return testCmdAttrib(IsFlush); }
217
218 const Command
219 responseCommand() const
220 {
221 return commandInfo[cmd].response;
222 }
223
224 /// Return the string to a cmd given by idx.
225 const std::string &toString() const { return commandInfo[cmd].str; }
226 int toInt() const { return (int)cmd; }
227
228 MemCmd(Command _cmd) : cmd(_cmd) { }
229 MemCmd(int _cmd) : cmd((Command)_cmd) { }
230 MemCmd() : cmd(InvalidCmd) { }
231
232 bool operator==(MemCmd c2) const { return (cmd == c2.cmd); }
233 bool operator!=(MemCmd c2) const { return (cmd != c2.cmd); }
234};
235
236/**
237 * A Packet is used to encapsulate a transfer between two objects in
238 * the memory system (e.g., the L1 and L2 cache). (In contrast, a
239 * single Request travels all the way from the requester to the
240 * ultimate destination and back, possibly being conveyed by several
241 * different Packets along the way.)
242 */
243class Packet : public Printable
244{
245 public:
246 typedef uint32_t FlagsType;
247 typedef ::Flags<FlagsType> Flags;
248
249 private:
250
251 enum : FlagsType {
252 // Flags to transfer across when copying a packet
253 COPY_FLAGS = 0x0000000F,
254
193 bool needsResponse() const { return testCmdAttrib(NeedsResponse); }
194 bool isInvalidate() const { return testCmdAttrib(IsInvalidate); }
195 bool isEviction() const { return testCmdAttrib(IsEviction); }
196
197 /**
198 * A writeback is an eviction that carries data.
199 */
200 bool isWriteback() const { return testCmdAttrib(IsEviction) &&
201 testCmdAttrib(HasData); }
202
203 /**
204 * Check if this particular packet type carries payload data. Note
205 * that this does not reflect if the data pointer of the packet is
206 * valid or not.
207 */
208 bool hasData() const { return testCmdAttrib(HasData); }
209 bool isLLSC() const { return testCmdAttrib(IsLlsc); }
210 bool isSWPrefetch() const { return testCmdAttrib(IsSWPrefetch); }
211 bool isHWPrefetch() const { return testCmdAttrib(IsHWPrefetch); }
212 bool isPrefetch() const { return testCmdAttrib(IsSWPrefetch) ||
213 testCmdAttrib(IsHWPrefetch); }
214 bool isError() const { return testCmdAttrib(IsError); }
215 bool isPrint() const { return testCmdAttrib(IsPrint); }
216 bool isFlush() const { return testCmdAttrib(IsFlush); }
217
218 const Command
219 responseCommand() const
220 {
221 return commandInfo[cmd].response;
222 }
223
224 /// Return the string to a cmd given by idx.
225 const std::string &toString() const { return commandInfo[cmd].str; }
226 int toInt() const { return (int)cmd; }
227
228 MemCmd(Command _cmd) : cmd(_cmd) { }
229 MemCmd(int _cmd) : cmd((Command)_cmd) { }
230 MemCmd() : cmd(InvalidCmd) { }
231
232 bool operator==(MemCmd c2) const { return (cmd == c2.cmd); }
233 bool operator!=(MemCmd c2) const { return (cmd != c2.cmd); }
234};
235
236/**
237 * A Packet is used to encapsulate a transfer between two objects in
238 * the memory system (e.g., the L1 and L2 cache). (In contrast, a
239 * single Request travels all the way from the requester to the
240 * ultimate destination and back, possibly being conveyed by several
241 * different Packets along the way.)
242 */
243class Packet : public Printable
244{
245 public:
246 typedef uint32_t FlagsType;
247 typedef ::Flags<FlagsType> Flags;
248
249 private:
250
251 enum : FlagsType {
252 // Flags to transfer across when copying a packet
253 COPY_FLAGS = 0x0000000F,
254
255 SHARED = 0x00000001,
255 // Does this packet have sharers (which means it should not be
256 // considered writable) or not. See setHasSharers below.
257 HAS_SHARERS = 0x00000001,
258
256 // Special control flags
257 /// Special timing-mode atomic snoop for multi-level coherence.
258 EXPRESS_SNOOP = 0x00000002,
259 // Special control flags
260 /// Special timing-mode atomic snoop for multi-level coherence.
261 EXPRESS_SNOOP = 0x00000002,
259 /// Does supplier have exclusive copy?
260 /// Useful for multi-level coherence.
261 SUPPLY_EXCLUSIVE = 0x00000004,
262 // Snoop response flags
263 MEM_INHIBIT = 0x00000008,
264
262
263 /// Allow a responding cache to inform the cache hierarchy
264 /// that it had a writable copy before responding. See
265 /// setResponderHadWritable below.
266 RESPONDER_HAD_WRITABLE = 0x00000004,
267
268 // Snoop co-ordination flag to indicate that a cache is
269 // responding to a snoop. See setCacheResponding below.
270 CACHE_RESPONDING = 0x00000008,
271
265 /// Are the 'addr' and 'size' fields valid?
266 VALID_ADDR = 0x00000100,
267 VALID_SIZE = 0x00000200,
268
269 /// Is the data pointer set to a value that shouldn't be freed
270 /// when the packet is destroyed?
271 STATIC_DATA = 0x00001000,
272 /// The data pointer points to a value that should be freed when
273 /// the packet is destroyed. The pointer is assumed to be pointing
274 /// to an array, and delete [] is consequently called
275 DYNAMIC_DATA = 0x00002000,
276
277 /// suppress the error if this packet encounters a functional
278 /// access failure.
279 SUPPRESS_FUNC_ERROR = 0x00008000,
280
281 // Signal block present to squash prefetch and cache evict packets
282 // through express snoop flag
283 BLOCK_CACHED = 0x00010000
284 };
285
286 Flags flags;
287
288 public:
289 typedef MemCmd::Command Command;
290
291 /// The command field of the packet.
292 MemCmd cmd;
293
294 /// A pointer to the original request.
295 const RequestPtr req;
296
297 private:
298 /**
299 * A pointer to the data being transfered. It can be differnt
300 * sizes at each level of the heirarchy so it belongs in the
301 * packet, not request. This may or may not be populated when a
302 * responder recieves the packet. If not populated it memory should
303 * be allocated.
304 */
305 PacketDataPtr data;
306
307 /// The address of the request. This address could be virtual or
308 /// physical, depending on the system configuration.
309 Addr addr;
310
311 /// True if the request targets the secure memory space.
312 bool _isSecure;
313
314 /// The size of the request or transfer.
315 unsigned size;
316
317 /**
318 * Track the bytes found that satisfy a functional read.
319 */
320 std::vector<bool> bytesValid;
321
322 public:
323
324 /**
325 * The extra delay from seeing the packet until the header is
326 * transmitted. This delay is used to communicate the crossbar
327 * forwarding latency to the neighbouring object (e.g. a cache)
328 * that actually makes the packet wait. As the delay is relative,
329 * a 32-bit unsigned should be sufficient.
330 */
331 uint32_t headerDelay;
332
333 /**
334 * Keep track of the extra delay incurred by snooping upwards
335 * before sending a request down the memory system. This is used
336 * by the coherent crossbar to account for the additional request
337 * delay.
338 */
339 uint32_t snoopDelay;
340
341 /**
342 * The extra pipelining delay from seeing the packet until the end of
343 * payload is transmitted by the component that provided it (if
344 * any). This includes the header delay. Similar to the header
345 * delay, this is used to make up for the fact that the
346 * crossbar does not make the packet wait. As the delay is
347 * relative, a 32-bit unsigned should be sufficient.
348 */
349 uint32_t payloadDelay;
350
351 /**
352 * A virtual base opaque structure used to hold state associated
353 * with the packet (e.g., an MSHR), specific to a MemObject that
354 * sees the packet. A pointer to this state is returned in the
355 * packet's response so that the MemObject in question can quickly
356 * look up the state needed to process it. A specific subclass
357 * would be derived from this to carry state specific to a
358 * particular sending device.
359 *
360 * As multiple MemObjects may add their SenderState throughout the
361 * memory system, the SenderStates create a stack, where a
362 * MemObject can add a new Senderstate, as long as the
363 * predecessing SenderState is restored when the response comes
364 * back. For this reason, the predecessor should always be
365 * populated with the current SenderState of a packet before
366 * modifying the senderState field in the request packet.
367 */
368 struct SenderState
369 {
370 SenderState* predecessor;
371 SenderState() : predecessor(NULL) {}
372 virtual ~SenderState() {}
373 };
374
375 /**
376 * Object used to maintain state of a PrintReq. The senderState
377 * field of a PrintReq should always be of this type.
378 */
379 class PrintReqState : public SenderState
380 {
381 private:
382 /**
383 * An entry in the label stack.
384 */
385 struct LabelStackEntry
386 {
387 const std::string label;
388 std::string *prefix;
389 bool labelPrinted;
390 LabelStackEntry(const std::string &_label, std::string *_prefix);
391 };
392
393 typedef std::list<LabelStackEntry> LabelStack;
394 LabelStack labelStack;
395
396 std::string *curPrefixPtr;
397
398 public:
399 std::ostream &os;
400 const int verbosity;
401
402 PrintReqState(std::ostream &os, int verbosity = 0);
403 ~PrintReqState();
404
405 /**
406 * Returns the current line prefix.
407 */
408 const std::string &curPrefix() { return *curPrefixPtr; }
409
410 /**
411 * Push a label onto the label stack, and prepend the given
412 * prefix string onto the current prefix. Labels will only be
413 * printed if an object within the label's scope is printed.
414 */
415 void pushLabel(const std::string &lbl,
416 const std::string &prefix = " ");
417
418 /**
419 * Pop a label off the label stack.
420 */
421 void popLabel();
422
423 /**
424 * Print all of the pending unprinted labels on the
425 * stack. Called by printObj(), so normally not called by
426 * users unless bypassing printObj().
427 */
428 void printLabels();
429
430 /**
431 * Print a Printable object to os, because it matched the
432 * address on a PrintReq.
433 */
434 void printObj(Printable *obj);
435 };
436
437 /**
438 * This packet's sender state. Devices should use dynamic_cast<>
439 * to cast to the state appropriate to the sender. The intent of
440 * this variable is to allow a device to attach extra information
441 * to a request. A response packet must return the sender state
442 * that was attached to the original request (even if a new packet
443 * is created).
444 */
445 SenderState *senderState;
446
447 /**
448 * Push a new sender state to the packet and make the current
449 * sender state the predecessor of the new one. This should be
450 * prefered over direct manipulation of the senderState member
451 * variable.
452 *
453 * @param sender_state SenderState to push at the top of the stack
454 */
455 void pushSenderState(SenderState *sender_state);
456
457 /**
458 * Pop the top of the state stack and return a pointer to it. This
459 * assumes the current sender state is not NULL. This should be
460 * preferred over direct manipulation of the senderState member
461 * variable.
462 *
463 * @return The current top of the stack
464 */
465 SenderState *popSenderState();
466
467 /**
468 * Go through the sender state stack and return the first instance
469 * that is of type T (as determined by a dynamic_cast). If there
470 * is no sender state of type T, NULL is returned.
471 *
472 * @return The topmost state of type T
473 */
474 template <typename T>
475 T * findNextSenderState() const
476 {
477 T *t = NULL;
478 SenderState* sender_state = senderState;
479 while (t == NULL && sender_state != NULL) {
480 t = dynamic_cast<T*>(sender_state);
481 sender_state = sender_state->predecessor;
482 }
483 return t;
484 }
485
486 /// Return the string name of the cmd field (for debugging and
487 /// tracing).
488 const std::string &cmdString() const { return cmd.toString(); }
489
490 /// Return the index of this command.
491 inline int cmdToIndex() const { return cmd.toInt(); }
492
493 bool isRead() const { return cmd.isRead(); }
494 bool isWrite() const { return cmd.isWrite(); }
495 bool isUpgrade() const { return cmd.isUpgrade(); }
496 bool isRequest() const { return cmd.isRequest(); }
497 bool isResponse() const { return cmd.isResponse(); }
272 /// Are the 'addr' and 'size' fields valid?
273 VALID_ADDR = 0x00000100,
274 VALID_SIZE = 0x00000200,
275
276 /// Is the data pointer set to a value that shouldn't be freed
277 /// when the packet is destroyed?
278 STATIC_DATA = 0x00001000,
279 /// The data pointer points to a value that should be freed when
280 /// the packet is destroyed. The pointer is assumed to be pointing
281 /// to an array, and delete [] is consequently called
282 DYNAMIC_DATA = 0x00002000,
283
284 /// suppress the error if this packet encounters a functional
285 /// access failure.
286 SUPPRESS_FUNC_ERROR = 0x00008000,
287
288 // Signal block present to squash prefetch and cache evict packets
289 // through express snoop flag
290 BLOCK_CACHED = 0x00010000
291 };
292
293 Flags flags;
294
295 public:
296 typedef MemCmd::Command Command;
297
298 /// The command field of the packet.
299 MemCmd cmd;
300
301 /// A pointer to the original request.
302 const RequestPtr req;
303
304 private:
305 /**
306 * A pointer to the data being transfered. It can be differnt
307 * sizes at each level of the heirarchy so it belongs in the
308 * packet, not request. This may or may not be populated when a
309 * responder recieves the packet. If not populated it memory should
310 * be allocated.
311 */
312 PacketDataPtr data;
313
314 /// The address of the request. This address could be virtual or
315 /// physical, depending on the system configuration.
316 Addr addr;
317
318 /// True if the request targets the secure memory space.
319 bool _isSecure;
320
321 /// The size of the request or transfer.
322 unsigned size;
323
324 /**
325 * Track the bytes found that satisfy a functional read.
326 */
327 std::vector<bool> bytesValid;
328
329 public:
330
331 /**
332 * The extra delay from seeing the packet until the header is
333 * transmitted. This delay is used to communicate the crossbar
334 * forwarding latency to the neighbouring object (e.g. a cache)
335 * that actually makes the packet wait. As the delay is relative,
336 * a 32-bit unsigned should be sufficient.
337 */
338 uint32_t headerDelay;
339
340 /**
341 * Keep track of the extra delay incurred by snooping upwards
342 * before sending a request down the memory system. This is used
343 * by the coherent crossbar to account for the additional request
344 * delay.
345 */
346 uint32_t snoopDelay;
347
348 /**
349 * The extra pipelining delay from seeing the packet until the end of
350 * payload is transmitted by the component that provided it (if
351 * any). This includes the header delay. Similar to the header
352 * delay, this is used to make up for the fact that the
353 * crossbar does not make the packet wait. As the delay is
354 * relative, a 32-bit unsigned should be sufficient.
355 */
356 uint32_t payloadDelay;
357
358 /**
359 * A virtual base opaque structure used to hold state associated
360 * with the packet (e.g., an MSHR), specific to a MemObject that
361 * sees the packet. A pointer to this state is returned in the
362 * packet's response so that the MemObject in question can quickly
363 * look up the state needed to process it. A specific subclass
364 * would be derived from this to carry state specific to a
365 * particular sending device.
366 *
367 * As multiple MemObjects may add their SenderState throughout the
368 * memory system, the SenderStates create a stack, where a
369 * MemObject can add a new Senderstate, as long as the
370 * predecessing SenderState is restored when the response comes
371 * back. For this reason, the predecessor should always be
372 * populated with the current SenderState of a packet before
373 * modifying the senderState field in the request packet.
374 */
375 struct SenderState
376 {
377 SenderState* predecessor;
378 SenderState() : predecessor(NULL) {}
379 virtual ~SenderState() {}
380 };
381
382 /**
383 * Object used to maintain state of a PrintReq. The senderState
384 * field of a PrintReq should always be of this type.
385 */
386 class PrintReqState : public SenderState
387 {
388 private:
389 /**
390 * An entry in the label stack.
391 */
392 struct LabelStackEntry
393 {
394 const std::string label;
395 std::string *prefix;
396 bool labelPrinted;
397 LabelStackEntry(const std::string &_label, std::string *_prefix);
398 };
399
400 typedef std::list<LabelStackEntry> LabelStack;
401 LabelStack labelStack;
402
403 std::string *curPrefixPtr;
404
405 public:
406 std::ostream &os;
407 const int verbosity;
408
409 PrintReqState(std::ostream &os, int verbosity = 0);
410 ~PrintReqState();
411
412 /**
413 * Returns the current line prefix.
414 */
415 const std::string &curPrefix() { return *curPrefixPtr; }
416
417 /**
418 * Push a label onto the label stack, and prepend the given
419 * prefix string onto the current prefix. Labels will only be
420 * printed if an object within the label's scope is printed.
421 */
422 void pushLabel(const std::string &lbl,
423 const std::string &prefix = " ");
424
425 /**
426 * Pop a label off the label stack.
427 */
428 void popLabel();
429
430 /**
431 * Print all of the pending unprinted labels on the
432 * stack. Called by printObj(), so normally not called by
433 * users unless bypassing printObj().
434 */
435 void printLabels();
436
437 /**
438 * Print a Printable object to os, because it matched the
439 * address on a PrintReq.
440 */
441 void printObj(Printable *obj);
442 };
443
444 /**
445 * This packet's sender state. Devices should use dynamic_cast<>
446 * to cast to the state appropriate to the sender. The intent of
447 * this variable is to allow a device to attach extra information
448 * to a request. A response packet must return the sender state
449 * that was attached to the original request (even if a new packet
450 * is created).
451 */
452 SenderState *senderState;
453
454 /**
455 * Push a new sender state to the packet and make the current
456 * sender state the predecessor of the new one. This should be
457 * prefered over direct manipulation of the senderState member
458 * variable.
459 *
460 * @param sender_state SenderState to push at the top of the stack
461 */
462 void pushSenderState(SenderState *sender_state);
463
464 /**
465 * Pop the top of the state stack and return a pointer to it. This
466 * assumes the current sender state is not NULL. This should be
467 * preferred over direct manipulation of the senderState member
468 * variable.
469 *
470 * @return The current top of the stack
471 */
472 SenderState *popSenderState();
473
474 /**
475 * Go through the sender state stack and return the first instance
476 * that is of type T (as determined by a dynamic_cast). If there
477 * is no sender state of type T, NULL is returned.
478 *
479 * @return The topmost state of type T
480 */
481 template <typename T>
482 T * findNextSenderState() const
483 {
484 T *t = NULL;
485 SenderState* sender_state = senderState;
486 while (t == NULL && sender_state != NULL) {
487 t = dynamic_cast<T*>(sender_state);
488 sender_state = sender_state->predecessor;
489 }
490 return t;
491 }
492
493 /// Return the string name of the cmd field (for debugging and
494 /// tracing).
495 const std::string &cmdString() const { return cmd.toString(); }
496
497 /// Return the index of this command.
498 inline int cmdToIndex() const { return cmd.toInt(); }
499
500 bool isRead() const { return cmd.isRead(); }
501 bool isWrite() const { return cmd.isWrite(); }
502 bool isUpgrade() const { return cmd.isUpgrade(); }
503 bool isRequest() const { return cmd.isRequest(); }
504 bool isResponse() const { return cmd.isResponse(); }
498 bool needsExclusive() const { return cmd.needsExclusive(); }
505 bool needsWritable() const { return cmd.needsWritable(); }
499 bool needsResponse() const { return cmd.needsResponse(); }
500 bool isInvalidate() const { return cmd.isInvalidate(); }
501 bool isEviction() const { return cmd.isEviction(); }
502 bool isWriteback() const { return cmd.isWriteback(); }
503 bool hasData() const { return cmd.hasData(); }
504 bool isLLSC() const { return cmd.isLLSC(); }
505 bool isError() const { return cmd.isError(); }
506 bool isPrint() const { return cmd.isPrint(); }
507 bool isFlush() const { return cmd.isFlush(); }
508
506 bool needsResponse() const { return cmd.needsResponse(); }
507 bool isInvalidate() const { return cmd.isInvalidate(); }
508 bool isEviction() const { return cmd.isEviction(); }
509 bool isWriteback() const { return cmd.isWriteback(); }
510 bool hasData() const { return cmd.hasData(); }
511 bool isLLSC() const { return cmd.isLLSC(); }
512 bool isError() const { return cmd.isError(); }
513 bool isPrint() const { return cmd.isPrint(); }
514 bool isFlush() const { return cmd.isFlush(); }
515
509 // Snoop flags
510 void assertMemInhibit()
516 //@{
517 /// Snoop flags
518 /**
519 * Set the cacheResponding flag. This is used by the caches to
520 * signal another cache that they are responding to a request. A
521 * cache will only respond to snoops if it has the line in either
522 * Modified or Owned state. Note that on snoop hits we always pass
523 * the line as Modified and never Owned. In the case of an Owned
524 * line we proceed to invalidate all other copies.
525 *
526 * On a cache fill (see Cache::handleFill), we check hasSharers
527 * first, ignoring the cacheResponding flag if hasSharers is set.
528 * A line is consequently allocated as:
529 *
530 * hasSharers cacheResponding state
531 * true false Shared
532 * true true Shared
533 * false false Exclusive
534 * false true Modified
535 */
536 void setCacheResponding()
511 {
512 assert(isRequest());
537 {
538 assert(isRequest());
513 assert(!flags.isSet(MEM_INHIBIT));
514 flags.set(MEM_INHIBIT);
539 assert(!flags.isSet(CACHE_RESPONDING));
540 flags.set(CACHE_RESPONDING);
515 }
541 }
516 bool memInhibitAsserted() const { return flags.isSet(MEM_INHIBIT); }
517 void assertShared() { flags.set(SHARED); }
518 bool sharedAsserted() const { return flags.isSet(SHARED); }
542 bool cacheResponding() const { return flags.isSet(CACHE_RESPONDING); }
543 /**
544 * On fills, the hasSharers flag is used by the caches in
545 * combination with the cacheResponding flag, as clarified
546 * above. If the hasSharers flag is not set, the packet is passing
547 * writable. Thus, a response from a memory passes the line as
548 * writable by default.
549 *
550 * The hasSharers flag is also used by upstream caches to inform a
551 * downstream cache that they have the block (by calling
552 * setHasSharers on snoop request packets that hit in upstream
553 * cachs tags or MSHRs). If the snoop packet has sharers, a
554 * downstream cache is prevented from passing a dirty line upwards
555 * if it was not explicitly asked for a writable copy. See
556 * Cache::satisfyCpuSideRequest.
557 *
558 * The hasSharers flag is also used on writebacks, in
559 * combination with the WritbackClean or WritebackDirty commands,
560 * to allocate the block downstream either as:
561 *
562 * command hasSharers state
563 * WritebackDirty false Modified
564 * WritebackDirty true Owned
565 * WritebackClean false Exclusive
566 * WritebackClean true Shared
567 */
568 void setHasSharers() { flags.set(HAS_SHARERS); }
569 bool hasSharers() const { return flags.isSet(HAS_SHARERS); }
570 //@}
519
571
520 // Special control flags
521 void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
522 bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
523 void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
524 bool isSupplyExclusive() const { return flags.isSet(SUPPLY_EXCLUSIVE); }
572 /**
573 * The express snoop flag is used for two purposes. Firstly, it is
574 * used to bypass flow control for normal (non-snoop) requests
575 * going downstream in the memory system. In cases where a cache
576 * is responding to a snoop from another cache (it had a dirty
577 * line), but the line is not writable (and there are possibly
578 * other copies), the express snoop flag is set by the downstream
579 * cache to invalidate all other copies in zero time. Secondly,
580 * the express snoop flag is also set to be able to distinguish
581 * snoop packets that came from a downstream cache, rather than
582 * snoop packets from neighbouring caches.
583 */
584 void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
585 bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
586
587 /**
588 * On responding to a snoop request (which only happens for
589 * Modified or Owned lines), make sure that we can transform an
590 * Owned response to a Modified one. If this flag is not set, the
591 * responding cache had the line in the Owned state, and there are
592 * possibly other Shared copies in the memory system. A downstream
593 * cache helps in orchestrating the invalidation of these copies
594 * by sending out the appropriate express snoops.
595 */
596 void setResponderHadWritable()
597 {
598 assert(cacheResponding());
599 flags.set(RESPONDER_HAD_WRITABLE);
600 }
601 bool responderHadWritable() const
602 { return flags.isSet(RESPONDER_HAD_WRITABLE); }
603
525 void setSuppressFuncError() { flags.set(SUPPRESS_FUNC_ERROR); }
526 bool suppressFuncError() const { return flags.isSet(SUPPRESS_FUNC_ERROR); }
527 void setBlockCached() { flags.set(BLOCK_CACHED); }
528 bool isBlockCached() const { return flags.isSet(BLOCK_CACHED); }
529 void clearBlockCached() { flags.clear(BLOCK_CACHED); }
530
531 // Network error conditions... encapsulate them as methods since
532 // their encoding keeps changing (from result field to command
533 // field, etc.)
534 void
535 setBadAddress()
536 {
537 assert(isResponse());
538 cmd = MemCmd::BadAddressError;
539 }
540
541 void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
542
543 Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
544 /**
545 * Update the address of this packet mid-transaction. This is used
546 * by the address mapper to change an already set address to a new
547 * one based on the system configuration. It is intended to remap
548 * an existing address, so it asserts that the current address is
549 * valid.
550 */
551 void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
552
553 unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
554
555 Addr getOffset(unsigned int blk_size) const
556 {
557 return getAddr() & Addr(blk_size - 1);
558 }
559
560 Addr getBlockAddr(unsigned int blk_size) const
561 {
562 return getAddr() & ~(Addr(blk_size - 1));
563 }
564
565 bool isSecure() const
566 {
567 assert(flags.isSet(VALID_ADDR));
568 return _isSecure;
569 }
570
571 /**
572 * It has been determined that the SC packet should successfully update
573 * memory. Therefore, convert this SC packet to a normal write.
574 */
575 void
576 convertScToWrite()
577 {
578 assert(isLLSC());
579 assert(isWrite());
580 cmd = MemCmd::WriteReq;
581 }
582
583 /**
584 * When ruby is in use, Ruby will monitor the cache line and the
585 * phys memory should treat LL ops as normal reads.
586 */
587 void
588 convertLlToRead()
589 {
590 assert(isLLSC());
591 assert(isRead());
592 cmd = MemCmd::ReadReq;
593 }
594
595 /**
596 * Constructor. Note that a Request object must be constructed
597 * first, but the Requests's physical address and size fields need
598 * not be valid. The command must be supplied.
599 */
600 Packet(const RequestPtr _req, MemCmd _cmd)
601 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
602 size(0), headerDelay(0), snoopDelay(0), payloadDelay(0),
603 senderState(NULL)
604 {
605 if (req->hasPaddr()) {
606 addr = req->getPaddr();
607 flags.set(VALID_ADDR);
608 _isSecure = req->isSecure();
609 }
610 if (req->hasSize()) {
611 size = req->getSize();
612 flags.set(VALID_SIZE);
613 }
614 }
615
616 /**
617 * Alternate constructor if you are trying to create a packet with
618 * a request that is for a whole block, not the address from the
619 * req. this allows for overriding the size/addr of the req.
620 */
621 Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize)
622 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
623 headerDelay(0), snoopDelay(0), payloadDelay(0),
624 senderState(NULL)
625 {
626 if (req->hasPaddr()) {
627 addr = req->getPaddr() & ~(_blkSize - 1);
628 flags.set(VALID_ADDR);
629 _isSecure = req->isSecure();
630 }
631 size = _blkSize;
632 flags.set(VALID_SIZE);
633 }
634
635 /**
636 * Alternate constructor for copying a packet. Copy all fields
637 * *except* if the original packet's data was dynamic, don't copy
638 * that, as we can't guarantee that the new packet's lifetime is
639 * less than that of the original packet. In this case the new
640 * packet should allocate its own data.
641 */
642 Packet(const PacketPtr pkt, bool clear_flags, bool alloc_data)
643 : cmd(pkt->cmd), req(pkt->req),
644 data(nullptr),
645 addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
646 bytesValid(pkt->bytesValid),
647 headerDelay(pkt->headerDelay),
648 snoopDelay(0),
649 payloadDelay(pkt->payloadDelay),
650 senderState(pkt->senderState)
651 {
652 if (!clear_flags)
653 flags.set(pkt->flags & COPY_FLAGS);
654
655 flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
656
657 // should we allocate space for data, or not, the express
658 // snoops do not need to carry any data as they only serve to
659 // co-ordinate state changes
660 if (alloc_data) {
661 // even if asked to allocate data, if the original packet
662 // holds static data, then the sender will not be doing
663 // any memcpy on receiving the response, thus we simply
664 // carry the pointer forward
665 if (pkt->flags.isSet(STATIC_DATA)) {
666 data = pkt->data;
667 flags.set(STATIC_DATA);
668 } else {
669 allocate();
670 }
671 }
672 }
673
674 /**
675 * Generate the appropriate read MemCmd based on the Request flags.
676 */
677 static MemCmd
678 makeReadCmd(const RequestPtr req)
679 {
680 if (req->isLLSC())
681 return MemCmd::LoadLockedReq;
682 else if (req->isPrefetch())
683 return MemCmd::SoftPFReq;
684 else
685 return MemCmd::ReadReq;
686 }
687
688 /**
689 * Generate the appropriate write MemCmd based on the Request flags.
690 */
691 static MemCmd
692 makeWriteCmd(const RequestPtr req)
693 {
694 if (req->isLLSC())
695 return MemCmd::StoreCondReq;
696 else if (req->isSwap())
697 return MemCmd::SwapReq;
698 else
699 return MemCmd::WriteReq;
700 }
701
702 /**
703 * Constructor-like methods that return Packets based on Request objects.
704 * Fine-tune the MemCmd type if it's not a vanilla read or write.
705 */
706 static PacketPtr
707 createRead(const RequestPtr req)
708 {
709 return new Packet(req, makeReadCmd(req));
710 }
711
712 static PacketPtr
713 createWrite(const RequestPtr req)
714 {
715 return new Packet(req, makeWriteCmd(req));
716 }
717
718 /**
719 * clean up packet variables
720 */
721 ~Packet()
722 {
723 // Delete the request object if this is a request packet which
724 // does not need a response, because the requester will not get
725 // a chance. If the request packet needs a response then the
726 // request will be deleted on receipt of the response
727 // packet. We also make sure to never delete the request for
728 // express snoops, even for cases when responses are not
729 // needed (CleanEvict and Writeback), since the snoop packet
730 // re-uses the same request.
731 if (req && isRequest() && !needsResponse() &&
732 !isExpressSnoop()) {
733 delete req;
734 }
735 deleteData();
736 }
737
738 /**
739 * Take a request packet and modify it in place to be suitable for
740 * returning as a response to that request.
741 */
742 void
743 makeResponse()
744 {
745 assert(needsResponse());
746 assert(isRequest());
747 cmd = cmd.responseCommand();
748
749 // responses are never express, even if the snoop that
750 // triggered them was
751 flags.clear(EXPRESS_SNOOP);
752 }
753
754 void
755 makeAtomicResponse()
756 {
757 makeResponse();
758 }
759
760 void
761 makeTimingResponse()
762 {
763 makeResponse();
764 }
765
766 void
767 setFunctionalResponseStatus(bool success)
768 {
769 if (!success) {
770 if (isWrite()) {
771 cmd = MemCmd::FunctionalWriteError;
772 } else {
773 cmd = MemCmd::FunctionalReadError;
774 }
775 }
776 }
777
778 void
779 setSize(unsigned size)
780 {
781 assert(!flags.isSet(VALID_SIZE));
782
783 this->size = size;
784 flags.set(VALID_SIZE);
785 }
786
787
788 public:
789 /**
790 * @{
791 * @name Data accessor mehtods
792 */
793
794 /**
795 * Set the data pointer to the following value that should not be
796 * freed. Static data allows us to do a single memcpy even if
797 * multiple packets are required to get from source to destination
798 * and back. In essence the pointer is set calling dataStatic on
799 * the original packet, and whenever this packet is copied and
800 * forwarded the same pointer is passed on. When a packet
801 * eventually reaches the destination holding the data, it is
802 * copied once into the location originally set. On the way back
803 * to the source, no copies are necessary.
804 */
805 template <typename T>
806 void
807 dataStatic(T *p)
808 {
809 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
810 data = (PacketDataPtr)p;
811 flags.set(STATIC_DATA);
812 }
813
814 /**
815 * Set the data pointer to the following value that should not be
816 * freed. This version of the function allows the pointer passed
817 * to us to be const. To avoid issues down the line we cast the
818 * constness away, the alternative would be to keep both a const
819 * and non-const data pointer and cleverly choose between
820 * them. Note that this is only allowed for static data.
821 */
822 template <typename T>
823 void
824 dataStaticConst(const T *p)
825 {
826 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
827 data = const_cast<PacketDataPtr>(p);
828 flags.set(STATIC_DATA);
829 }
830
831 /**
832 * Set the data pointer to a value that should have delete []
833 * called on it. Dynamic data is local to this packet, and as the
834 * packet travels from source to destination, forwarded packets
835 * will allocate their own data. When a packet reaches the final
836 * destination it will populate the dynamic data of that specific
837 * packet, and on the way back towards the source, memcpy will be
838 * invoked in every step where a new packet was created e.g. in
839 * the caches. Ultimately when the response reaches the source a
840 * final memcpy is needed to extract the data from the packet
841 * before it is deallocated.
842 */
843 template <typename T>
844 void
845 dataDynamic(T *p)
846 {
847 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
848 data = (PacketDataPtr)p;
849 flags.set(DYNAMIC_DATA);
850 }
851
852 /**
853 * get a pointer to the data ptr.
854 */
855 template <typename T>
856 T*
857 getPtr()
858 {
859 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
860 return (T*)data;
861 }
862
863 template <typename T>
864 const T*
865 getConstPtr() const
866 {
867 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
868 return (const T*)data;
869 }
870
871 /**
872 * Get the data in the packet byte swapped from big endian to
873 * host endian.
874 */
875 template <typename T>
876 T getBE() const;
877
878 /**
879 * Get the data in the packet byte swapped from little endian to
880 * host endian.
881 */
882 template <typename T>
883 T getLE() const;
884
885 /**
886 * Get the data in the packet byte swapped from the specified
887 * endianness.
888 */
889 template <typename T>
890 T get(ByteOrder endian) const;
891
892 /**
893 * Get the data in the packet byte swapped from guest to host
894 * endian.
895 */
896 template <typename T>
897 T get() const;
898
899 /** Set the value in the data pointer to v as big endian. */
900 template <typename T>
901 void setBE(T v);
902
903 /** Set the value in the data pointer to v as little endian. */
904 template <typename T>
905 void setLE(T v);
906
907 /**
908 * Set the value in the data pointer to v using the specified
909 * endianness.
910 */
911 template <typename T>
912 void set(T v, ByteOrder endian);
913
914 /** Set the value in the data pointer to v as guest endian. */
915 template <typename T>
916 void set(T v);
917
918 /**
919 * Copy data into the packet from the provided pointer.
920 */
921 void
922 setData(const uint8_t *p)
923 {
924 // we should never be copying data onto itself, which means we
925 // must idenfity packets with static data, as they carry the
926 // same pointer from source to destination and back
927 assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA));
928
929 if (p != getPtr<uint8_t>())
930 // for packet with allocated dynamic data, we copy data from
931 // one to the other, e.g. a forwarded response to a response
932 std::memcpy(getPtr<uint8_t>(), p, getSize());
933 }
934
935 /**
936 * Copy data into the packet from the provided block pointer,
937 * which is aligned to the given block size.
938 */
939 void
940 setDataFromBlock(const uint8_t *blk_data, int blkSize)
941 {
942 setData(blk_data + getOffset(blkSize));
943 }
944
945 /**
946 * Copy data from the packet to the provided block pointer, which
947 * is aligned to the given block size.
948 */
949 void
950 writeData(uint8_t *p) const
951 {
952 std::memcpy(p, getConstPtr<uint8_t>(), getSize());
953 }
954
955 /**
956 * Copy data from the packet to the memory at the provided pointer.
957 */
958 void
959 writeDataToBlock(uint8_t *blk_data, int blkSize) const
960 {
961 writeData(blk_data + getOffset(blkSize));
962 }
963
964 /**
965 * delete the data pointed to in the data pointer. Ok to call to
966 * matter how data was allocted.
967 */
968 void
969 deleteData()
970 {
971 if (flags.isSet(DYNAMIC_DATA))
972 delete [] data;
973
974 flags.clear(STATIC_DATA|DYNAMIC_DATA);
975 data = NULL;
976 }
977
978 /** Allocate memory for the packet. */
979 void
980 allocate()
981 {
982 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
983 flags.set(DYNAMIC_DATA);
984 data = new uint8_t[getSize()];
985 }
986
987 /** @} */
988
989 private: // Private data accessor methods
990 /** Get the data in the packet without byte swapping. */
991 template <typename T>
992 T getRaw() const;
993
994 /** Set the value in the data pointer to v without byte swapping. */
995 template <typename T>
996 void setRaw(T v);
997
998 public:
999 /**
1000 * Check a functional request against a memory value stored in
1001 * another packet (i.e. an in-transit request or
1002 * response). Returns true if the current packet is a read, and
1003 * the other packet provides the data, which is then copied to the
1004 * current packet. If the current packet is a write, and the other
1005 * packet intersects this one, then we update the data
1006 * accordingly.
1007 */
1008 bool
1009 checkFunctional(PacketPtr other)
1010 {
1011 // all packets that are carrying a payload should have a valid
1012 // data pointer
1013 return checkFunctional(other, other->getAddr(), other->isSecure(),
1014 other->getSize(),
1015 other->hasData() ?
1016 other->getPtr<uint8_t>() : NULL);
1017 }
1018
1019 /**
1020 * Does the request need to check for cached copies of the same block
1021 * in the memory hierarchy above.
1022 **/
1023 bool
1024 mustCheckAbove() const
1025 {
1026 return cmd == MemCmd::HardPFReq || isEviction();
1027 }
1028
1029 /**
1030 * Is this packet a clean eviction, including both actual clean
1031 * evict packets, but also clean writebacks.
1032 */
1033 bool
1034 isCleanEviction() const
1035 {
1036 return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
1037 }
1038
1039 /**
1040 * Check a functional request against a memory value represented
1041 * by a base/size pair and an associated data array. If the
1042 * current packet is a read, it may be satisfied by the memory
1043 * value. If the current packet is a write, it may update the
1044 * memory value.
1045 */
1046 bool
1047 checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
1048 uint8_t *_data);
1049
1050 /**
1051 * Push label for PrintReq (safe to call unconditionally).
1052 */
1053 void
1054 pushLabel(const std::string &lbl)
1055 {
1056 if (isPrint())
1057 safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
1058 }
1059
1060 /**
1061 * Pop label for PrintReq (safe to call unconditionally).
1062 */
1063 void
1064 popLabel()
1065 {
1066 if (isPrint())
1067 safe_cast<PrintReqState*>(senderState)->popLabel();
1068 }
1069
1070 void print(std::ostream &o, int verbosity = 0,
1071 const std::string &prefix = "") const;
1072
1073 /**
1074 * A no-args wrapper of print(std::ostream...)
1075 * meant to be invoked from DPRINTFs
1076 * avoiding string overheads in fast mode
1077 * @return string with the request's type and start<->end addresses
1078 */
1079 std::string print() const;
1080};
1081
1082#endif //__MEM_PACKET_HH
604 void setSuppressFuncError() { flags.set(SUPPRESS_FUNC_ERROR); }
605 bool suppressFuncError() const { return flags.isSet(SUPPRESS_FUNC_ERROR); }
606 void setBlockCached() { flags.set(BLOCK_CACHED); }
607 bool isBlockCached() const { return flags.isSet(BLOCK_CACHED); }
608 void clearBlockCached() { flags.clear(BLOCK_CACHED); }
609
610 // Network error conditions... encapsulate them as methods since
611 // their encoding keeps changing (from result field to command
612 // field, etc.)
613 void
614 setBadAddress()
615 {
616 assert(isResponse());
617 cmd = MemCmd::BadAddressError;
618 }
619
620 void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
621
622 Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
623 /**
624 * Update the address of this packet mid-transaction. This is used
625 * by the address mapper to change an already set address to a new
626 * one based on the system configuration. It is intended to remap
627 * an existing address, so it asserts that the current address is
628 * valid.
629 */
630 void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
631
632 unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
633
634 Addr getOffset(unsigned int blk_size) const
635 {
636 return getAddr() & Addr(blk_size - 1);
637 }
638
639 Addr getBlockAddr(unsigned int blk_size) const
640 {
641 return getAddr() & ~(Addr(blk_size - 1));
642 }
643
644 bool isSecure() const
645 {
646 assert(flags.isSet(VALID_ADDR));
647 return _isSecure;
648 }
649
650 /**
651 * It has been determined that the SC packet should successfully update
652 * memory. Therefore, convert this SC packet to a normal write.
653 */
654 void
655 convertScToWrite()
656 {
657 assert(isLLSC());
658 assert(isWrite());
659 cmd = MemCmd::WriteReq;
660 }
661
662 /**
663 * When ruby is in use, Ruby will monitor the cache line and the
664 * phys memory should treat LL ops as normal reads.
665 */
666 void
667 convertLlToRead()
668 {
669 assert(isLLSC());
670 assert(isRead());
671 cmd = MemCmd::ReadReq;
672 }
673
674 /**
675 * Constructor. Note that a Request object must be constructed
676 * first, but the Requests's physical address and size fields need
677 * not be valid. The command must be supplied.
678 */
679 Packet(const RequestPtr _req, MemCmd _cmd)
680 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
681 size(0), headerDelay(0), snoopDelay(0), payloadDelay(0),
682 senderState(NULL)
683 {
684 if (req->hasPaddr()) {
685 addr = req->getPaddr();
686 flags.set(VALID_ADDR);
687 _isSecure = req->isSecure();
688 }
689 if (req->hasSize()) {
690 size = req->getSize();
691 flags.set(VALID_SIZE);
692 }
693 }
694
695 /**
696 * Alternate constructor if you are trying to create a packet with
697 * a request that is for a whole block, not the address from the
698 * req. this allows for overriding the size/addr of the req.
699 */
700 Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize)
701 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
702 headerDelay(0), snoopDelay(0), payloadDelay(0),
703 senderState(NULL)
704 {
705 if (req->hasPaddr()) {
706 addr = req->getPaddr() & ~(_blkSize - 1);
707 flags.set(VALID_ADDR);
708 _isSecure = req->isSecure();
709 }
710 size = _blkSize;
711 flags.set(VALID_SIZE);
712 }
713
714 /**
715 * Alternate constructor for copying a packet. Copy all fields
716 * *except* if the original packet's data was dynamic, don't copy
717 * that, as we can't guarantee that the new packet's lifetime is
718 * less than that of the original packet. In this case the new
719 * packet should allocate its own data.
720 */
721 Packet(const PacketPtr pkt, bool clear_flags, bool alloc_data)
722 : cmd(pkt->cmd), req(pkt->req),
723 data(nullptr),
724 addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
725 bytesValid(pkt->bytesValid),
726 headerDelay(pkt->headerDelay),
727 snoopDelay(0),
728 payloadDelay(pkt->payloadDelay),
729 senderState(pkt->senderState)
730 {
731 if (!clear_flags)
732 flags.set(pkt->flags & COPY_FLAGS);
733
734 flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
735
736 // should we allocate space for data, or not, the express
737 // snoops do not need to carry any data as they only serve to
738 // co-ordinate state changes
739 if (alloc_data) {
740 // even if asked to allocate data, if the original packet
741 // holds static data, then the sender will not be doing
742 // any memcpy on receiving the response, thus we simply
743 // carry the pointer forward
744 if (pkt->flags.isSet(STATIC_DATA)) {
745 data = pkt->data;
746 flags.set(STATIC_DATA);
747 } else {
748 allocate();
749 }
750 }
751 }
752
753 /**
754 * Generate the appropriate read MemCmd based on the Request flags.
755 */
756 static MemCmd
757 makeReadCmd(const RequestPtr req)
758 {
759 if (req->isLLSC())
760 return MemCmd::LoadLockedReq;
761 else if (req->isPrefetch())
762 return MemCmd::SoftPFReq;
763 else
764 return MemCmd::ReadReq;
765 }
766
767 /**
768 * Generate the appropriate write MemCmd based on the Request flags.
769 */
770 static MemCmd
771 makeWriteCmd(const RequestPtr req)
772 {
773 if (req->isLLSC())
774 return MemCmd::StoreCondReq;
775 else if (req->isSwap())
776 return MemCmd::SwapReq;
777 else
778 return MemCmd::WriteReq;
779 }
780
781 /**
782 * Constructor-like methods that return Packets based on Request objects.
783 * Fine-tune the MemCmd type if it's not a vanilla read or write.
784 */
785 static PacketPtr
786 createRead(const RequestPtr req)
787 {
788 return new Packet(req, makeReadCmd(req));
789 }
790
791 static PacketPtr
792 createWrite(const RequestPtr req)
793 {
794 return new Packet(req, makeWriteCmd(req));
795 }
796
797 /**
798 * clean up packet variables
799 */
800 ~Packet()
801 {
802 // Delete the request object if this is a request packet which
803 // does not need a response, because the requester will not get
804 // a chance. If the request packet needs a response then the
805 // request will be deleted on receipt of the response
806 // packet. We also make sure to never delete the request for
807 // express snoops, even for cases when responses are not
808 // needed (CleanEvict and Writeback), since the snoop packet
809 // re-uses the same request.
810 if (req && isRequest() && !needsResponse() &&
811 !isExpressSnoop()) {
812 delete req;
813 }
814 deleteData();
815 }
816
817 /**
818 * Take a request packet and modify it in place to be suitable for
819 * returning as a response to that request.
820 */
821 void
822 makeResponse()
823 {
824 assert(needsResponse());
825 assert(isRequest());
826 cmd = cmd.responseCommand();
827
828 // responses are never express, even if the snoop that
829 // triggered them was
830 flags.clear(EXPRESS_SNOOP);
831 }
832
833 void
834 makeAtomicResponse()
835 {
836 makeResponse();
837 }
838
839 void
840 makeTimingResponse()
841 {
842 makeResponse();
843 }
844
845 void
846 setFunctionalResponseStatus(bool success)
847 {
848 if (!success) {
849 if (isWrite()) {
850 cmd = MemCmd::FunctionalWriteError;
851 } else {
852 cmd = MemCmd::FunctionalReadError;
853 }
854 }
855 }
856
857 void
858 setSize(unsigned size)
859 {
860 assert(!flags.isSet(VALID_SIZE));
861
862 this->size = size;
863 flags.set(VALID_SIZE);
864 }
865
866
867 public:
868 /**
869 * @{
870 * @name Data accessor mehtods
871 */
872
873 /**
874 * Set the data pointer to the following value that should not be
875 * freed. Static data allows us to do a single memcpy even if
876 * multiple packets are required to get from source to destination
877 * and back. In essence the pointer is set calling dataStatic on
878 * the original packet, and whenever this packet is copied and
879 * forwarded the same pointer is passed on. When a packet
880 * eventually reaches the destination holding the data, it is
881 * copied once into the location originally set. On the way back
882 * to the source, no copies are necessary.
883 */
884 template <typename T>
885 void
886 dataStatic(T *p)
887 {
888 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
889 data = (PacketDataPtr)p;
890 flags.set(STATIC_DATA);
891 }
892
893 /**
894 * Set the data pointer to the following value that should not be
895 * freed. This version of the function allows the pointer passed
896 * to us to be const. To avoid issues down the line we cast the
897 * constness away, the alternative would be to keep both a const
898 * and non-const data pointer and cleverly choose between
899 * them. Note that this is only allowed for static data.
900 */
901 template <typename T>
902 void
903 dataStaticConst(const T *p)
904 {
905 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
906 data = const_cast<PacketDataPtr>(p);
907 flags.set(STATIC_DATA);
908 }
909
910 /**
911 * Set the data pointer to a value that should have delete []
912 * called on it. Dynamic data is local to this packet, and as the
913 * packet travels from source to destination, forwarded packets
914 * will allocate their own data. When a packet reaches the final
915 * destination it will populate the dynamic data of that specific
916 * packet, and on the way back towards the source, memcpy will be
917 * invoked in every step where a new packet was created e.g. in
918 * the caches. Ultimately when the response reaches the source a
919 * final memcpy is needed to extract the data from the packet
920 * before it is deallocated.
921 */
922 template <typename T>
923 void
924 dataDynamic(T *p)
925 {
926 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
927 data = (PacketDataPtr)p;
928 flags.set(DYNAMIC_DATA);
929 }
930
931 /**
932 * get a pointer to the data ptr.
933 */
934 template <typename T>
935 T*
936 getPtr()
937 {
938 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
939 return (T*)data;
940 }
941
942 template <typename T>
943 const T*
944 getConstPtr() const
945 {
946 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
947 return (const T*)data;
948 }
949
950 /**
951 * Get the data in the packet byte swapped from big endian to
952 * host endian.
953 */
954 template <typename T>
955 T getBE() const;
956
957 /**
958 * Get the data in the packet byte swapped from little endian to
959 * host endian.
960 */
961 template <typename T>
962 T getLE() const;
963
964 /**
965 * Get the data in the packet byte swapped from the specified
966 * endianness.
967 */
968 template <typename T>
969 T get(ByteOrder endian) const;
970
971 /**
972 * Get the data in the packet byte swapped from guest to host
973 * endian.
974 */
975 template <typename T>
976 T get() const;
977
978 /** Set the value in the data pointer to v as big endian. */
979 template <typename T>
980 void setBE(T v);
981
982 /** Set the value in the data pointer to v as little endian. */
983 template <typename T>
984 void setLE(T v);
985
986 /**
987 * Set the value in the data pointer to v using the specified
988 * endianness.
989 */
990 template <typename T>
991 void set(T v, ByteOrder endian);
992
993 /** Set the value in the data pointer to v as guest endian. */
994 template <typename T>
995 void set(T v);
996
997 /**
998 * Copy data into the packet from the provided pointer.
999 */
1000 void
1001 setData(const uint8_t *p)
1002 {
1003 // we should never be copying data onto itself, which means we
1004 // must idenfity packets with static data, as they carry the
1005 // same pointer from source to destination and back
1006 assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA));
1007
1008 if (p != getPtr<uint8_t>())
1009 // for packet with allocated dynamic data, we copy data from
1010 // one to the other, e.g. a forwarded response to a response
1011 std::memcpy(getPtr<uint8_t>(), p, getSize());
1012 }
1013
1014 /**
1015 * Copy data into the packet from the provided block pointer,
1016 * which is aligned to the given block size.
1017 */
1018 void
1019 setDataFromBlock(const uint8_t *blk_data, int blkSize)
1020 {
1021 setData(blk_data + getOffset(blkSize));
1022 }
1023
1024 /**
1025 * Copy data from the packet to the provided block pointer, which
1026 * is aligned to the given block size.
1027 */
1028 void
1029 writeData(uint8_t *p) const
1030 {
1031 std::memcpy(p, getConstPtr<uint8_t>(), getSize());
1032 }
1033
1034 /**
1035 * Copy data from the packet to the memory at the provided pointer.
1036 */
1037 void
1038 writeDataToBlock(uint8_t *blk_data, int blkSize) const
1039 {
1040 writeData(blk_data + getOffset(blkSize));
1041 }
1042
1043 /**
1044 * delete the data pointed to in the data pointer. Ok to call to
1045 * matter how data was allocted.
1046 */
1047 void
1048 deleteData()
1049 {
1050 if (flags.isSet(DYNAMIC_DATA))
1051 delete [] data;
1052
1053 flags.clear(STATIC_DATA|DYNAMIC_DATA);
1054 data = NULL;
1055 }
1056
1057 /** Allocate memory for the packet. */
1058 void
1059 allocate()
1060 {
1061 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
1062 flags.set(DYNAMIC_DATA);
1063 data = new uint8_t[getSize()];
1064 }
1065
1066 /** @} */
1067
1068 private: // Private data accessor methods
1069 /** Get the data in the packet without byte swapping. */
1070 template <typename T>
1071 T getRaw() const;
1072
1073 /** Set the value in the data pointer to v without byte swapping. */
1074 template <typename T>
1075 void setRaw(T v);
1076
1077 public:
1078 /**
1079 * Check a functional request against a memory value stored in
1080 * another packet (i.e. an in-transit request or
1081 * response). Returns true if the current packet is a read, and
1082 * the other packet provides the data, which is then copied to the
1083 * current packet. If the current packet is a write, and the other
1084 * packet intersects this one, then we update the data
1085 * accordingly.
1086 */
1087 bool
1088 checkFunctional(PacketPtr other)
1089 {
1090 // all packets that are carrying a payload should have a valid
1091 // data pointer
1092 return checkFunctional(other, other->getAddr(), other->isSecure(),
1093 other->getSize(),
1094 other->hasData() ?
1095 other->getPtr<uint8_t>() : NULL);
1096 }
1097
1098 /**
1099 * Does the request need to check for cached copies of the same block
1100 * in the memory hierarchy above.
1101 **/
1102 bool
1103 mustCheckAbove() const
1104 {
1105 return cmd == MemCmd::HardPFReq || isEviction();
1106 }
1107
1108 /**
1109 * Is this packet a clean eviction, including both actual clean
1110 * evict packets, but also clean writebacks.
1111 */
1112 bool
1113 isCleanEviction() const
1114 {
1115 return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
1116 }
1117
1118 /**
1119 * Check a functional request against a memory value represented
1120 * by a base/size pair and an associated data array. If the
1121 * current packet is a read, it may be satisfied by the memory
1122 * value. If the current packet is a write, it may update the
1123 * memory value.
1124 */
1125 bool
1126 checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
1127 uint8_t *_data);
1128
1129 /**
1130 * Push label for PrintReq (safe to call unconditionally).
1131 */
1132 void
1133 pushLabel(const std::string &lbl)
1134 {
1135 if (isPrint())
1136 safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
1137 }
1138
1139 /**
1140 * Pop label for PrintReq (safe to call unconditionally).
1141 */
1142 void
1143 popLabel()
1144 {
1145 if (isPrint())
1146 safe_cast<PrintReqState*>(senderState)->popLabel();
1147 }
1148
1149 void print(std::ostream &o, int verbosity = 0,
1150 const std::string &prefix = "") const;
1151
1152 /**
1153 * A no-args wrapper of print(std::ostream...)
1154 * meant to be invoked from DPRINTFs
1155 * avoiding string overheads in fast mode
1156 * @return string with the request's type and start<->end addresses
1157 */
1158 std::string print() const;
1159};
1160
1161#endif //__MEM_PACKET_HH