packet.hh (10566:c99c8d2a7c31) packet.hh (10567:926802ed1536)
1/*
2 * Copyright (c) 2012-2014 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 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 Writeback,
90 SoftPFReq,
91 HardPFReq,
92 SoftPFResp,
93 HardPFResp,
94 WriteInvalidateReq,
95 WriteInvalidateResp,
96 UpgradeReq,
97 SCUpgradeReq, // Special "weak" upgrade for StoreCond
98 UpgradeResp,
99 SCUpgradeFailReq, // Failed SCUpgradeReq in MSHR (never sent)
100 UpgradeFailResp, // Valid for SCUpgradeReq only
101 ReadExReq,
102 ReadExResp,
103 LoadLockedReq,
104 StoreCondReq,
105 StoreCondFailReq, // Failed StoreCondReq in MSHR (never sent)
106 StoreCondResp,
107 SwapReq,
108 SwapResp,
109 MessageReq,
110 MessageResp,
111 // Error responses
112 // @TODO these should be classified as responses rather than
113 // requests; coding them as requests initially for backwards
114 // compatibility
115 InvalidDestError, // packet dest field invalid
116 BadAddressError, // memory address invalid
117 FunctionalReadError, // unable to fulfill functional read
118 FunctionalWriteError, // unable to fulfill functional write
119 // Fake simulator-only commands
120 PrintReq, // Print state matching address
121 FlushReq, //request for a cache flush
122 InvalidationReq, // request for address to be invalidated from lsq
123 NUM_MEM_CMDS
124 };
125
126 private:
127 /**
128 * List of command attributes.
129 */
130 enum Attribute
131 {
132 IsRead, //!< Data flows from responder to requester
133 IsWrite, //!< Data flows from requester to responder
134 IsUpgrade,
135 IsInvalidate,
136 NeedsExclusive, //!< Requires exclusive copy to complete in-cache
137 IsRequest, //!< Issued by requester
138 IsResponse, //!< Issue by responder
139 NeedsResponse, //!< Requester needs response from target
140 IsSWPrefetch,
141 IsHWPrefetch,
142 IsLlsc, //!< Alpha/MIPS LL or SC access
143 HasData, //!< There is an associated payload
144 IsError, //!< Error response
145 IsPrint, //!< Print state matching address (for debugging)
146 IsFlush, //!< Flush the address from caches
147 NUM_COMMAND_ATTRIBUTES
148 };
149
150 /**
151 * Structure that defines attributes and other data associated
152 * with a Command.
153 */
154 struct CommandInfo
155 {
156 /// Set of attribute flags.
157 const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
158 /// Corresponding response for requests; InvalidCmd if no
159 /// response is applicable.
160 const Command response;
161 /// String representation (for printing)
162 const std::string str;
163 };
164
165 /// Array to map Command enum to associated info.
166 static const CommandInfo commandInfo[];
167
168 private:
169
170 Command cmd;
171
172 bool
173 testCmdAttrib(MemCmd::Attribute attrib) const
174 {
175 return commandInfo[cmd].attributes[attrib] != 0;
176 }
177
178 public:
179
180 bool isRead() const { return testCmdAttrib(IsRead); }
181 bool isWrite() const { return testCmdAttrib(IsWrite); }
182 bool isUpgrade() const { return testCmdAttrib(IsUpgrade); }
183 bool isRequest() const { return testCmdAttrib(IsRequest); }
184 bool isResponse() const { return testCmdAttrib(IsResponse); }
185 bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); }
186 bool needsResponse() const { return testCmdAttrib(NeedsResponse); }
187 bool isInvalidate() const { return testCmdAttrib(IsInvalidate); }
188 bool hasData() const { return testCmdAttrib(HasData); }
189 bool isLLSC() const { return testCmdAttrib(IsLlsc); }
190 bool isSWPrefetch() const { return testCmdAttrib(IsSWPrefetch); }
191 bool isHWPrefetch() const { return testCmdAttrib(IsHWPrefetch); }
192 bool isPrefetch() const { return testCmdAttrib(IsSWPrefetch) ||
193 testCmdAttrib(IsHWPrefetch); }
194 bool isError() const { return testCmdAttrib(IsError); }
195 bool isPrint() const { return testCmdAttrib(IsPrint); }
196 bool isFlush() const { return testCmdAttrib(IsFlush); }
197
198 const Command
199 responseCommand() const
200 {
201 return commandInfo[cmd].response;
202 }
203
204 /// Return the string to a cmd given by idx.
205 const std::string &toString() const { return commandInfo[cmd].str; }
206 int toInt() const { return (int)cmd; }
207
208 MemCmd(Command _cmd) : cmd(_cmd) { }
209 MemCmd(int _cmd) : cmd((Command)_cmd) { }
210 MemCmd() : cmd(InvalidCmd) { }
211
212 bool operator==(MemCmd c2) const { return (cmd == c2.cmd); }
213 bool operator!=(MemCmd c2) const { return (cmd != c2.cmd); }
214};
215
216/**
217 * A Packet is used to encapsulate a transfer between two objects in
218 * the memory system (e.g., the L1 and L2 cache). (In contrast, a
219 * single Request travels all the way from the requester to the
220 * ultimate destination and back, possibly being conveyed by several
221 * different Packets along the way.)
222 */
223class Packet : public Printable
224{
225 public:
226 typedef uint32_t FlagsType;
227 typedef ::Flags<FlagsType> Flags;
228
229 private:
230 static const FlagsType PUBLIC_FLAGS = 0x00000000;
231 static const FlagsType PRIVATE_FLAGS = 0x00007F0F;
232 static const FlagsType COPY_FLAGS = 0x0000000F;
233
234 static const FlagsType SHARED = 0x00000001;
235 // Special control flags
236 /// Special timing-mode atomic snoop for multi-level coherence.
237 static const FlagsType EXPRESS_SNOOP = 0x00000002;
238 /// Does supplier have exclusive copy?
239 /// Useful for multi-level coherence.
240 static const FlagsType SUPPLY_EXCLUSIVE = 0x00000004;
241 // Snoop response flags
242 static const FlagsType MEM_INHIBIT = 0x00000008;
243 /// Are the 'addr' and 'size' fields valid?
244 static const FlagsType VALID_ADDR = 0x00000100;
245 static const FlagsType VALID_SIZE = 0x00000200;
246 /// Is the data pointer set to a value that shouldn't be freed
247 /// when the packet is destroyed?
248 static const FlagsType STATIC_DATA = 0x00001000;
249 /// The data pointer points to a value that should be freed when
250 /// the packet is destroyed. The pointer is assumed to be pointing
251 /// to an array, and delete [] is consequently called
252 static const FlagsType DYNAMIC_DATA = 0x00002000;
253 /// suppress the error if this packet encounters a functional
254 /// access failure.
255 static const FlagsType SUPPRESS_FUNC_ERROR = 0x00008000;
256 // Signal prefetch squash through express snoop flag
257 static const FlagsType PREFETCH_SNOOP_SQUASH = 0x00010000;
258
259 Flags flags;
260
261 public:
262 typedef MemCmd::Command Command;
263
264 /// The command field of the packet.
265 MemCmd cmd;
266
267 /// A pointer to the original request.
268 RequestPtr req;
269
270 private:
271 /**
272 * A pointer to the data being transfered. It can be differnt
273 * sizes at each level of the heirarchy so it belongs in the
274 * packet, not request. This may or may not be populated when a
275 * responder recieves the packet. If not populated it memory should
276 * be allocated.
277 */
278 PacketDataPtr data;
279
280 /// The address of the request. This address could be virtual or
281 /// physical, depending on the system configuration.
282 Addr addr;
283
284 /// True if the request targets the secure memory space.
285 bool _isSecure;
286
287 /// The size of the request or transfer.
288 unsigned size;
289
290 /**
291 * Source port identifier set on a request packet to enable
292 * appropriate routing of the responses. The source port
293 * identifier is set by any multiplexing component, e.g. a
294 * crossbar, as the timing responses need this information to be
295 * routed back to the appropriate port at a later point in
296 * time. The field can be updated (over-written) as the request
297 * packet passes through additional multiplexing components, and
298 * it is their responsibility to remember the original source port
299 * identifier, for example by using an appropriate sender
300 * state. The latter is done in the cache and bridge.
301 */
302 PortID src;
303
304 /**
305 * Destination port identifier that is present on all response
306 * packets that passed through a multiplexing component as a
307 * request packet. The source port identifier is turned into a
308 * destination port identifier when the packet is turned into a
309 * response, and the destination is used, e.g. by the crossbar, to
310 * select the appropriate path through the interconnect.
311 */
312 PortID dest;
313
314 /**
315 * The original value of the command field. Only valid when the
316 * current command field is an error condition; in that case, the
317 * previous contents of the command field are copied here. This
318 * field is *not* set on non-error responses.
319 */
320 MemCmd origCmd;
321
322 /**
323 * These values specify the range of bytes found that satisfy a
324 * functional read.
325 */
326 uint16_t bytesValidStart;
327 uint16_t bytesValidEnd;
328
329 public:
330
331 /**
332 * The extra delay from seeing the packet until the first word 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 firstWordDelay;
339
340 /**
341 * The extra pipelining delay from seeing the packet until the
342 * last word is transmitted by the component that provided it (if
343 * any). This includes the first word delay. Similar to the first
344 * word delay, this is used to make up for the fact that the
345 * crossbar does not make the packet wait. As the delay is
346 * relative, a 32-bit unsigned should be sufficient.
347 */
348 uint32_t lastWordDelay;
349
350 /**
351 * A virtual base opaque structure used to hold state associated
352 * with the packet (e.g., an MSHR), specific to a MemObject that
353 * sees the packet. A pointer to this state is returned in the
354 * packet's response so that the MemObject in question can quickly
355 * look up the state needed to process it. A specific subclass
356 * would be derived from this to carry state specific to a
357 * particular sending device.
358 *
359 * As multiple MemObjects may add their SenderState throughout the
360 * memory system, the SenderStates create a stack, where a
361 * MemObject can add a new Senderstate, as long as the
362 * predecessing SenderState is restored when the response comes
363 * back. For this reason, the predecessor should always be
364 * populated with the current SenderState of a packet before
365 * modifying the senderState field in the request packet.
366 */
367 struct SenderState
368 {
369 SenderState* predecessor;
370 SenderState() : predecessor(NULL) {}
371 virtual ~SenderState() {}
372 };
373
374 /**
375 * Object used to maintain state of a PrintReq. The senderState
376 * field of a PrintReq should always be of this type.
377 */
378 class PrintReqState : public SenderState
379 {
380 private:
381 /**
382 * An entry in the label stack.
383 */
384 struct LabelStackEntry
385 {
386 const std::string label;
387 std::string *prefix;
388 bool labelPrinted;
389 LabelStackEntry(const std::string &_label, std::string *_prefix);
390 };
391
392 typedef std::list<LabelStackEntry> LabelStack;
393 LabelStack labelStack;
394
395 std::string *curPrefixPtr;
396
397 public:
398 std::ostream &os;
399 const int verbosity;
400
401 PrintReqState(std::ostream &os, int verbosity = 0);
402 ~PrintReqState();
403
404 /**
405 * Returns the current line prefix.
406 */
407 const std::string &curPrefix() { return *curPrefixPtr; }
408
409 /**
410 * Push a label onto the label stack, and prepend the given
411 * prefix string onto the current prefix. Labels will only be
412 * printed if an object within the label's scope is printed.
413 */
414 void pushLabel(const std::string &lbl,
415 const std::string &prefix = " ");
416
417 /**
418 * Pop a label off the label stack.
419 */
420 void popLabel();
421
422 /**
423 * Print all of the pending unprinted labels on the
424 * stack. Called by printObj(), so normally not called by
425 * users unless bypassing printObj().
426 */
427 void printLabels();
428
429 /**
430 * Print a Printable object to os, because it matched the
431 * address on a PrintReq.
432 */
433 void printObj(Printable *obj);
434 };
435
436 /**
437 * This packet's sender state. Devices should use dynamic_cast<>
438 * to cast to the state appropriate to the sender. The intent of
439 * this variable is to allow a device to attach extra information
440 * to a request. A response packet must return the sender state
441 * that was attached to the original request (even if a new packet
442 * is created).
443 */
444 SenderState *senderState;
445
446 /**
447 * Push a new sender state to the packet and make the current
448 * sender state the predecessor of the new one. This should be
449 * prefered over direct manipulation of the senderState member
450 * variable.
451 *
452 * @param sender_state SenderState to push at the top of the stack
453 */
454 void pushSenderState(SenderState *sender_state);
455
456 /**
457 * Pop the top of the state stack and return a pointer to it. This
458 * assumes the current sender state is not NULL. This should be
459 * preferred over direct manipulation of the senderState member
460 * variable.
461 *
462 * @return The current top of the stack
463 */
464 SenderState *popSenderState();
465
466 /**
467 * Go through the sender state stack and return the first instance
468 * that is of type T (as determined by a dynamic_cast). If there
469 * is no sender state of type T, NULL is returned.
470 *
471 * @return The topmost state of type T
472 */
473 template <typename T>
474 T * findNextSenderState() const
475 {
476 T *t = NULL;
477 SenderState* sender_state = senderState;
478 while (t == NULL && sender_state != NULL) {
479 t = dynamic_cast<T*>(sender_state);
480 sender_state = sender_state->predecessor;
481 }
482 return t;
483 }
484
485 /// Return the string name of the cmd field (for debugging and
486 /// tracing).
487 const std::string &cmdString() const { return cmd.toString(); }
488
489 /// Return the index of this command.
490 inline int cmdToIndex() const { return cmd.toInt(); }
491
492 bool isRead() const { return cmd.isRead(); }
493 bool isWrite() const { return cmd.isWrite(); }
494 bool isUpgrade() const { return cmd.isUpgrade(); }
495 bool isRequest() const { return cmd.isRequest(); }
496 bool isResponse() const { return cmd.isResponse(); }
497 bool needsExclusive() const { return cmd.needsExclusive(); }
498 bool needsResponse() const { return cmd.needsResponse(); }
499 bool isInvalidate() const { return cmd.isInvalidate(); }
500 bool hasData() const { return cmd.hasData(); }
501 bool isLLSC() const { return cmd.isLLSC(); }
502 bool isError() const { return cmd.isError(); }
503 bool isPrint() const { return cmd.isPrint(); }
504 bool isFlush() const { return cmd.isFlush(); }
505
506 // Snoop flags
1/*
2 * Copyright (c) 2012-2014 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 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 Writeback,
90 SoftPFReq,
91 HardPFReq,
92 SoftPFResp,
93 HardPFResp,
94 WriteInvalidateReq,
95 WriteInvalidateResp,
96 UpgradeReq,
97 SCUpgradeReq, // Special "weak" upgrade for StoreCond
98 UpgradeResp,
99 SCUpgradeFailReq, // Failed SCUpgradeReq in MSHR (never sent)
100 UpgradeFailResp, // Valid for SCUpgradeReq only
101 ReadExReq,
102 ReadExResp,
103 LoadLockedReq,
104 StoreCondReq,
105 StoreCondFailReq, // Failed StoreCondReq in MSHR (never sent)
106 StoreCondResp,
107 SwapReq,
108 SwapResp,
109 MessageReq,
110 MessageResp,
111 // Error responses
112 // @TODO these should be classified as responses rather than
113 // requests; coding them as requests initially for backwards
114 // compatibility
115 InvalidDestError, // packet dest field invalid
116 BadAddressError, // memory address invalid
117 FunctionalReadError, // unable to fulfill functional read
118 FunctionalWriteError, // unable to fulfill functional write
119 // Fake simulator-only commands
120 PrintReq, // Print state matching address
121 FlushReq, //request for a cache flush
122 InvalidationReq, // request for address to be invalidated from lsq
123 NUM_MEM_CMDS
124 };
125
126 private:
127 /**
128 * List of command attributes.
129 */
130 enum Attribute
131 {
132 IsRead, //!< Data flows from responder to requester
133 IsWrite, //!< Data flows from requester to responder
134 IsUpgrade,
135 IsInvalidate,
136 NeedsExclusive, //!< Requires exclusive copy to complete in-cache
137 IsRequest, //!< Issued by requester
138 IsResponse, //!< Issue by responder
139 NeedsResponse, //!< Requester needs response from target
140 IsSWPrefetch,
141 IsHWPrefetch,
142 IsLlsc, //!< Alpha/MIPS LL or SC access
143 HasData, //!< There is an associated payload
144 IsError, //!< Error response
145 IsPrint, //!< Print state matching address (for debugging)
146 IsFlush, //!< Flush the address from caches
147 NUM_COMMAND_ATTRIBUTES
148 };
149
150 /**
151 * Structure that defines attributes and other data associated
152 * with a Command.
153 */
154 struct CommandInfo
155 {
156 /// Set of attribute flags.
157 const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
158 /// Corresponding response for requests; InvalidCmd if no
159 /// response is applicable.
160 const Command response;
161 /// String representation (for printing)
162 const std::string str;
163 };
164
165 /// Array to map Command enum to associated info.
166 static const CommandInfo commandInfo[];
167
168 private:
169
170 Command cmd;
171
172 bool
173 testCmdAttrib(MemCmd::Attribute attrib) const
174 {
175 return commandInfo[cmd].attributes[attrib] != 0;
176 }
177
178 public:
179
180 bool isRead() const { return testCmdAttrib(IsRead); }
181 bool isWrite() const { return testCmdAttrib(IsWrite); }
182 bool isUpgrade() const { return testCmdAttrib(IsUpgrade); }
183 bool isRequest() const { return testCmdAttrib(IsRequest); }
184 bool isResponse() const { return testCmdAttrib(IsResponse); }
185 bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); }
186 bool needsResponse() const { return testCmdAttrib(NeedsResponse); }
187 bool isInvalidate() const { return testCmdAttrib(IsInvalidate); }
188 bool hasData() const { return testCmdAttrib(HasData); }
189 bool isLLSC() const { return testCmdAttrib(IsLlsc); }
190 bool isSWPrefetch() const { return testCmdAttrib(IsSWPrefetch); }
191 bool isHWPrefetch() const { return testCmdAttrib(IsHWPrefetch); }
192 bool isPrefetch() const { return testCmdAttrib(IsSWPrefetch) ||
193 testCmdAttrib(IsHWPrefetch); }
194 bool isError() const { return testCmdAttrib(IsError); }
195 bool isPrint() const { return testCmdAttrib(IsPrint); }
196 bool isFlush() const { return testCmdAttrib(IsFlush); }
197
198 const Command
199 responseCommand() const
200 {
201 return commandInfo[cmd].response;
202 }
203
204 /// Return the string to a cmd given by idx.
205 const std::string &toString() const { return commandInfo[cmd].str; }
206 int toInt() const { return (int)cmd; }
207
208 MemCmd(Command _cmd) : cmd(_cmd) { }
209 MemCmd(int _cmd) : cmd((Command)_cmd) { }
210 MemCmd() : cmd(InvalidCmd) { }
211
212 bool operator==(MemCmd c2) const { return (cmd == c2.cmd); }
213 bool operator!=(MemCmd c2) const { return (cmd != c2.cmd); }
214};
215
216/**
217 * A Packet is used to encapsulate a transfer between two objects in
218 * the memory system (e.g., the L1 and L2 cache). (In contrast, a
219 * single Request travels all the way from the requester to the
220 * ultimate destination and back, possibly being conveyed by several
221 * different Packets along the way.)
222 */
223class Packet : public Printable
224{
225 public:
226 typedef uint32_t FlagsType;
227 typedef ::Flags<FlagsType> Flags;
228
229 private:
230 static const FlagsType PUBLIC_FLAGS = 0x00000000;
231 static const FlagsType PRIVATE_FLAGS = 0x00007F0F;
232 static const FlagsType COPY_FLAGS = 0x0000000F;
233
234 static const FlagsType SHARED = 0x00000001;
235 // Special control flags
236 /// Special timing-mode atomic snoop for multi-level coherence.
237 static const FlagsType EXPRESS_SNOOP = 0x00000002;
238 /// Does supplier have exclusive copy?
239 /// Useful for multi-level coherence.
240 static const FlagsType SUPPLY_EXCLUSIVE = 0x00000004;
241 // Snoop response flags
242 static const FlagsType MEM_INHIBIT = 0x00000008;
243 /// Are the 'addr' and 'size' fields valid?
244 static const FlagsType VALID_ADDR = 0x00000100;
245 static const FlagsType VALID_SIZE = 0x00000200;
246 /// Is the data pointer set to a value that shouldn't be freed
247 /// when the packet is destroyed?
248 static const FlagsType STATIC_DATA = 0x00001000;
249 /// The data pointer points to a value that should be freed when
250 /// the packet is destroyed. The pointer is assumed to be pointing
251 /// to an array, and delete [] is consequently called
252 static const FlagsType DYNAMIC_DATA = 0x00002000;
253 /// suppress the error if this packet encounters a functional
254 /// access failure.
255 static const FlagsType SUPPRESS_FUNC_ERROR = 0x00008000;
256 // Signal prefetch squash through express snoop flag
257 static const FlagsType PREFETCH_SNOOP_SQUASH = 0x00010000;
258
259 Flags flags;
260
261 public:
262 typedef MemCmd::Command Command;
263
264 /// The command field of the packet.
265 MemCmd cmd;
266
267 /// A pointer to the original request.
268 RequestPtr req;
269
270 private:
271 /**
272 * A pointer to the data being transfered. It can be differnt
273 * sizes at each level of the heirarchy so it belongs in the
274 * packet, not request. This may or may not be populated when a
275 * responder recieves the packet. If not populated it memory should
276 * be allocated.
277 */
278 PacketDataPtr data;
279
280 /// The address of the request. This address could be virtual or
281 /// physical, depending on the system configuration.
282 Addr addr;
283
284 /// True if the request targets the secure memory space.
285 bool _isSecure;
286
287 /// The size of the request or transfer.
288 unsigned size;
289
290 /**
291 * Source port identifier set on a request packet to enable
292 * appropriate routing of the responses. The source port
293 * identifier is set by any multiplexing component, e.g. a
294 * crossbar, as the timing responses need this information to be
295 * routed back to the appropriate port at a later point in
296 * time. The field can be updated (over-written) as the request
297 * packet passes through additional multiplexing components, and
298 * it is their responsibility to remember the original source port
299 * identifier, for example by using an appropriate sender
300 * state. The latter is done in the cache and bridge.
301 */
302 PortID src;
303
304 /**
305 * Destination port identifier that is present on all response
306 * packets that passed through a multiplexing component as a
307 * request packet. The source port identifier is turned into a
308 * destination port identifier when the packet is turned into a
309 * response, and the destination is used, e.g. by the crossbar, to
310 * select the appropriate path through the interconnect.
311 */
312 PortID dest;
313
314 /**
315 * The original value of the command field. Only valid when the
316 * current command field is an error condition; in that case, the
317 * previous contents of the command field are copied here. This
318 * field is *not* set on non-error responses.
319 */
320 MemCmd origCmd;
321
322 /**
323 * These values specify the range of bytes found that satisfy a
324 * functional read.
325 */
326 uint16_t bytesValidStart;
327 uint16_t bytesValidEnd;
328
329 public:
330
331 /**
332 * The extra delay from seeing the packet until the first word 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 firstWordDelay;
339
340 /**
341 * The extra pipelining delay from seeing the packet until the
342 * last word is transmitted by the component that provided it (if
343 * any). This includes the first word delay. Similar to the first
344 * word delay, this is used to make up for the fact that the
345 * crossbar does not make the packet wait. As the delay is
346 * relative, a 32-bit unsigned should be sufficient.
347 */
348 uint32_t lastWordDelay;
349
350 /**
351 * A virtual base opaque structure used to hold state associated
352 * with the packet (e.g., an MSHR), specific to a MemObject that
353 * sees the packet. A pointer to this state is returned in the
354 * packet's response so that the MemObject in question can quickly
355 * look up the state needed to process it. A specific subclass
356 * would be derived from this to carry state specific to a
357 * particular sending device.
358 *
359 * As multiple MemObjects may add their SenderState throughout the
360 * memory system, the SenderStates create a stack, where a
361 * MemObject can add a new Senderstate, as long as the
362 * predecessing SenderState is restored when the response comes
363 * back. For this reason, the predecessor should always be
364 * populated with the current SenderState of a packet before
365 * modifying the senderState field in the request packet.
366 */
367 struct SenderState
368 {
369 SenderState* predecessor;
370 SenderState() : predecessor(NULL) {}
371 virtual ~SenderState() {}
372 };
373
374 /**
375 * Object used to maintain state of a PrintReq. The senderState
376 * field of a PrintReq should always be of this type.
377 */
378 class PrintReqState : public SenderState
379 {
380 private:
381 /**
382 * An entry in the label stack.
383 */
384 struct LabelStackEntry
385 {
386 const std::string label;
387 std::string *prefix;
388 bool labelPrinted;
389 LabelStackEntry(const std::string &_label, std::string *_prefix);
390 };
391
392 typedef std::list<LabelStackEntry> LabelStack;
393 LabelStack labelStack;
394
395 std::string *curPrefixPtr;
396
397 public:
398 std::ostream &os;
399 const int verbosity;
400
401 PrintReqState(std::ostream &os, int verbosity = 0);
402 ~PrintReqState();
403
404 /**
405 * Returns the current line prefix.
406 */
407 const std::string &curPrefix() { return *curPrefixPtr; }
408
409 /**
410 * Push a label onto the label stack, and prepend the given
411 * prefix string onto the current prefix. Labels will only be
412 * printed if an object within the label's scope is printed.
413 */
414 void pushLabel(const std::string &lbl,
415 const std::string &prefix = " ");
416
417 /**
418 * Pop a label off the label stack.
419 */
420 void popLabel();
421
422 /**
423 * Print all of the pending unprinted labels on the
424 * stack. Called by printObj(), so normally not called by
425 * users unless bypassing printObj().
426 */
427 void printLabels();
428
429 /**
430 * Print a Printable object to os, because it matched the
431 * address on a PrintReq.
432 */
433 void printObj(Printable *obj);
434 };
435
436 /**
437 * This packet's sender state. Devices should use dynamic_cast<>
438 * to cast to the state appropriate to the sender. The intent of
439 * this variable is to allow a device to attach extra information
440 * to a request. A response packet must return the sender state
441 * that was attached to the original request (even if a new packet
442 * is created).
443 */
444 SenderState *senderState;
445
446 /**
447 * Push a new sender state to the packet and make the current
448 * sender state the predecessor of the new one. This should be
449 * prefered over direct manipulation of the senderState member
450 * variable.
451 *
452 * @param sender_state SenderState to push at the top of the stack
453 */
454 void pushSenderState(SenderState *sender_state);
455
456 /**
457 * Pop the top of the state stack and return a pointer to it. This
458 * assumes the current sender state is not NULL. This should be
459 * preferred over direct manipulation of the senderState member
460 * variable.
461 *
462 * @return The current top of the stack
463 */
464 SenderState *popSenderState();
465
466 /**
467 * Go through the sender state stack and return the first instance
468 * that is of type T (as determined by a dynamic_cast). If there
469 * is no sender state of type T, NULL is returned.
470 *
471 * @return The topmost state of type T
472 */
473 template <typename T>
474 T * findNextSenderState() const
475 {
476 T *t = NULL;
477 SenderState* sender_state = senderState;
478 while (t == NULL && sender_state != NULL) {
479 t = dynamic_cast<T*>(sender_state);
480 sender_state = sender_state->predecessor;
481 }
482 return t;
483 }
484
485 /// Return the string name of the cmd field (for debugging and
486 /// tracing).
487 const std::string &cmdString() const { return cmd.toString(); }
488
489 /// Return the index of this command.
490 inline int cmdToIndex() const { return cmd.toInt(); }
491
492 bool isRead() const { return cmd.isRead(); }
493 bool isWrite() const { return cmd.isWrite(); }
494 bool isUpgrade() const { return cmd.isUpgrade(); }
495 bool isRequest() const { return cmd.isRequest(); }
496 bool isResponse() const { return cmd.isResponse(); }
497 bool needsExclusive() const { return cmd.needsExclusive(); }
498 bool needsResponse() const { return cmd.needsResponse(); }
499 bool isInvalidate() const { return cmd.isInvalidate(); }
500 bool hasData() const { return cmd.hasData(); }
501 bool isLLSC() const { return cmd.isLLSC(); }
502 bool isError() const { return cmd.isError(); }
503 bool isPrint() const { return cmd.isPrint(); }
504 bool isFlush() const { return cmd.isFlush(); }
505
506 // Snoop flags
507 void assertMemInhibit() { flags.set(MEM_INHIBIT); }
507 void assertMemInhibit()
508 {
509 assert(isRequest());
510 assert(!flags.isSet(MEM_INHIBIT));
511 flags.set(MEM_INHIBIT);
512 }
508 bool memInhibitAsserted() const { return flags.isSet(MEM_INHIBIT); }
509 void assertShared() { flags.set(SHARED); }
510 bool sharedAsserted() const { return flags.isSet(SHARED); }
511
512 // Special control flags
513 void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
514 bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
515 void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
516 void clearSupplyExclusive() { flags.clear(SUPPLY_EXCLUSIVE); }
517 bool isSupplyExclusive() const { return flags.isSet(SUPPLY_EXCLUSIVE); }
518 void setSuppressFuncError() { flags.set(SUPPRESS_FUNC_ERROR); }
519 bool suppressFuncError() const { return flags.isSet(SUPPRESS_FUNC_ERROR); }
520 void setPrefetchSquashed() { flags.set(PREFETCH_SNOOP_SQUASH); }
521 bool prefetchSquashed() const { return flags.isSet(PREFETCH_SNOOP_SQUASH); }
522
523 // Network error conditions... encapsulate them as methods since
524 // their encoding keeps changing (from result field to command
525 // field, etc.)
526 void
527 setBadAddress()
528 {
529 assert(isResponse());
530 cmd = MemCmd::BadAddressError;
531 }
532
533 bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; }
534 void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
535
536 bool isSrcValid() const { return src != InvalidPortID; }
537 /// Accessor function to get the source index of the packet.
538 PortID getSrc() const { assert(isSrcValid()); return src; }
539 /// Accessor function to set the source index of the packet.
540 void setSrc(PortID _src) { src = _src; }
541
542 bool isDestValid() const { return dest != InvalidPortID; }
543 /// Accessor function for the destination index of the packet.
544 PortID getDest() const { assert(isDestValid()); return dest; }
545 /// Accessor function to set the destination index of the packet.
546 void setDest(PortID _dest) { dest = _dest; }
547 /// Reset destination field, e.g. to turn a response into a request again.
548 void clearDest() { dest = InvalidPortID; }
549
550 Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
551 /**
552 * Update the address of this packet mid-transaction. This is used
553 * by the address mapper to change an already set address to a new
554 * one based on the system configuration. It is intended to remap
555 * an existing address, so it asserts that the current address is
556 * valid.
557 */
558 void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
559
560 unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
561 Addr getOffset(int blkSize) const { return getAddr() & (Addr)(blkSize - 1); }
562
563 bool isSecure() const
564 {
565 assert(flags.isSet(VALID_ADDR));
566 return _isSecure;
567 }
568
569 /**
570 * It has been determined that the SC packet should successfully update
571 * memory. Therefore, convert this SC packet to a normal write.
572 */
573 void
574 convertScToWrite()
575 {
576 assert(isLLSC());
577 assert(isWrite());
578 cmd = MemCmd::WriteReq;
579 }
580
581 /**
582 * When ruby is in use, Ruby will monitor the cache line and thus M5
583 * phys memory should treat LL ops as normal reads.
584 */
585 void
586 convertLlToRead()
587 {
588 assert(isLLSC());
589 assert(isRead());
590 cmd = MemCmd::ReadReq;
591 }
592
593 /**
594 * Constructor. Note that a Request object must be constructed
595 * first, but the Requests's physical address and size fields need
596 * not be valid. The command must be supplied.
597 */
598 Packet(Request *_req, MemCmd _cmd)
599 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
600 size(0), src(InvalidPortID), dest(InvalidPortID),
601 bytesValidStart(0), bytesValidEnd(0),
602 firstWordDelay(0), lastWordDelay(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(Request *_req, MemCmd _cmd, int _blkSize)
622 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
623 src(InvalidPortID), dest(InvalidPortID),
624 bytesValidStart(0), bytesValidEnd(0),
625 firstWordDelay(0), lastWordDelay(0),
626 senderState(NULL)
627 {
628 if (req->hasPaddr()) {
629 addr = req->getPaddr() & ~(_blkSize - 1);
630 flags.set(VALID_ADDR);
631 _isSecure = req->isSecure();
632 }
633 size = _blkSize;
634 flags.set(VALID_SIZE);
635 }
636
637 /**
638 * Alternate constructor for copying a packet. Copy all fields
639 * *except* if the original packet's data was dynamic, don't copy
640 * that, as we can't guarantee that the new packet's lifetime is
641 * less than that of the original packet. In this case the new
642 * packet should allocate its own data.
643 */
644 Packet(Packet *pkt, bool clearFlags = false)
645 : cmd(pkt->cmd), req(pkt->req),
646 data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL),
647 addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
648 src(pkt->src), dest(pkt->dest),
649 bytesValidStart(pkt->bytesValidStart),
650 bytesValidEnd(pkt->bytesValidEnd),
651 firstWordDelay(pkt->firstWordDelay),
652 lastWordDelay(pkt->lastWordDelay),
653 senderState(pkt->senderState)
654 {
655 if (!clearFlags)
656 flags.set(pkt->flags & COPY_FLAGS);
657
658 flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
659 flags.set(pkt->flags & STATIC_DATA);
660
661 // if we did not copy the static data pointer, allocate data
662 // dynamically instead
663 if (!data)
664 allocate();
665 }
666
667 /**
668 * Change the packet type based on request type.
669 */
670 void
671 refineCommand()
672 {
673 if (cmd == MemCmd::ReadReq) {
674 if (req->isLLSC()) {
675 cmd = MemCmd::LoadLockedReq;
676 } else if (req->isPrefetch()) {
677 cmd = MemCmd::SoftPFReq;
678 }
679 } else if (cmd == MemCmd::WriteReq) {
680 if (req->isLLSC()) {
681 cmd = MemCmd::StoreCondReq;
682 } else if (req->isSwap()) {
683 cmd = MemCmd::SwapReq;
684 }
685 }
686 }
687
688 /**
689 * Constructor-like methods that return Packets based on Request objects.
690 * Will call refineCommand() to fine-tune the Packet type if it's not a
691 * vanilla read or write.
692 */
693 static PacketPtr
694 createRead(Request *req)
695 {
696 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
697 pkt->refineCommand();
698 return pkt;
699 }
700
701 static PacketPtr
702 createWrite(Request *req)
703 {
704 PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
705 pkt->refineCommand();
706 return pkt;
707 }
708
709 /**
710 * clean up packet variables
711 */
712 ~Packet()
713 {
714 // If this is a request packet for which there's no response,
715 // delete the request object here, since the requester will
716 // never get the chance.
717 if (req && isRequest() && !needsResponse())
718 delete req;
719 deleteData();
720 }
721
722 /**
723 * Reinitialize packet address and size from the associated
724 * Request object, and reset other fields that may have been
725 * modified by a previous transaction. Typically called when a
726 * statically allocated Request/Packet pair is reused for multiple
727 * transactions.
728 */
729 void
730 reinitFromRequest()
731 {
732 assert(req->hasPaddr());
733 flags = 0;
734 addr = req->getPaddr();
735 _isSecure = req->isSecure();
736 size = req->getSize();
737
738 src = InvalidPortID;
739 dest = InvalidPortID;
740 bytesValidStart = 0;
741 bytesValidEnd = 0;
742 firstWordDelay = 0;
743 lastWordDelay = 0;
744
745 flags.set(VALID_ADDR|VALID_SIZE);
746 deleteData();
747 }
748
749 /**
750 * Take a request packet and modify it in place to be suitable for
751 * returning as a response to that request. The source field is
752 * turned into the destination, and subsequently cleared. Note
753 * that the latter is not necessary for atomic requests, but
754 * causes no harm as neither field is valid.
755 */
756 void
757 makeResponse()
758 {
759 assert(needsResponse());
760 assert(isRequest());
761 origCmd = cmd;
762 cmd = cmd.responseCommand();
763
764 // responses are never express, even if the snoop that
765 // triggered them was
766 flags.clear(EXPRESS_SNOOP);
767
768 dest = src;
769 src = InvalidPortID;
770 }
771
772 void
773 makeAtomicResponse()
774 {
775 makeResponse();
776 }
777
778 void
779 makeTimingResponse()
780 {
781 makeResponse();
782 }
783
784 void
785 setFunctionalResponseStatus(bool success)
786 {
787 if (!success) {
788 if (isWrite()) {
789 cmd = MemCmd::FunctionalWriteError;
790 } else {
791 cmd = MemCmd::FunctionalReadError;
792 }
793 }
794 }
795
796 void
797 setSize(unsigned size)
798 {
799 assert(!flags.isSet(VALID_SIZE));
800
801 this->size = size;
802 flags.set(VALID_SIZE);
803 }
804
805
806 /**
807 * Set the data pointer to the following value that should not be
808 * freed.
809 */
810 template <typename T>
811 void
812 dataStatic(T *p)
813 {
814 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
815 data = (PacketDataPtr)p;
816 flags.set(STATIC_DATA);
817 }
818
819 /**
820 * Set the data pointer to the following value that should not be
821 * freed. This version of the function allows the pointer passed
822 * to us to be const. To avoid issues down the line we cast the
823 * constness away, the alternative would be to keep both a const
824 * and non-const data pointer and cleverly choose between
825 * them. Note that this is only allowed for static data.
826 */
827 template <typename T>
828 void
829 dataStaticConst(const T *p)
830 {
831 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
832 data = const_cast<PacketDataPtr>(p);
833 flags.set(STATIC_DATA);
834 }
835
836 /**
837 * Set the data pointer to a value that should have delete []
838 * called on it.
839 */
840 template <typename T>
841 void
842 dataDynamic(T *p)
843 {
844 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
845 data = (PacketDataPtr)p;
846 flags.set(DYNAMIC_DATA);
847 }
848
849 /**
850 * get a pointer to the data ptr.
851 */
852 template <typename T>
853 T*
854 getPtr()
855 {
856 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
857 return (T*)data;
858 }
859
860 template <typename T>
861 const T*
862 getConstPtr() const
863 {
864 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
865 return (const T*)data;
866 }
867
868 /**
869 * return the value of what is pointed to in the packet.
870 */
871 template <typename T>
872 T get() const;
873
874 /**
875 * set the value in the data pointer to v.
876 */
877 template <typename T>
878 void set(T v);
879
880 /**
881 * Copy data into the packet from the provided pointer.
882 */
883 void
884 setData(const uint8_t *p)
885 {
886 if (p != getPtr<uint8_t>())
887 std::memcpy(getPtr<uint8_t>(), p, getSize());
888 }
889
890 /**
891 * Copy data into the packet from the provided block pointer,
892 * which is aligned to the given block size.
893 */
894 void
895 setDataFromBlock(const uint8_t *blk_data, int blkSize)
896 {
897 setData(blk_data + getOffset(blkSize));
898 }
899
900 /**
901 * Copy data from the packet to the provided block pointer, which
902 * is aligned to the given block size.
903 */
904 void
905 writeData(uint8_t *p) const
906 {
907 std::memcpy(p, getConstPtr<uint8_t>(), getSize());
908 }
909
910 /**
911 * Copy data from the packet to the memory at the provided pointer.
912 */
913 void
914 writeDataToBlock(uint8_t *blk_data, int blkSize) const
915 {
916 writeData(blk_data + getOffset(blkSize));
917 }
918
919 /**
920 * delete the data pointed to in the data pointer. Ok to call to
921 * matter how data was allocted.
922 */
923 void
924 deleteData()
925 {
926 if (flags.isSet(DYNAMIC_DATA))
927 delete [] data;
928
929 flags.clear(STATIC_DATA|DYNAMIC_DATA);
930 data = NULL;
931 }
932
933 /** Allocate memory for the packet. */
934 void
935 allocate()
936 {
937 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
938 flags.set(DYNAMIC_DATA);
939 data = new uint8_t[getSize()];
940 }
941
942 /**
943 * Check a functional request against a memory value represented
944 * by a base/size pair and an associated data array. If the
945 * functional request is a read, it may be satisfied by the memory
946 * value. If the functional request is a write, it may update the
947 * memory value.
948 */
949 bool checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
950 uint8_t *data);
951
952 /**
953 * Check a functional request against a memory value stored in
954 * another packet (i.e. an in-transit request or response).
955 */
956 bool
957 checkFunctional(PacketPtr other)
958 {
959 uint8_t *data = other->hasData() ? other->getPtr<uint8_t>() : NULL;
960 return checkFunctional(other, other->getAddr(), other->isSecure(),
961 other->getSize(), data);
962 }
963
964 /**
965 * Push label for PrintReq (safe to call unconditionally).
966 */
967 void
968 pushLabel(const std::string &lbl)
969 {
970 if (isPrint())
971 safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
972 }
973
974 /**
975 * Pop label for PrintReq (safe to call unconditionally).
976 */
977 void
978 popLabel()
979 {
980 if (isPrint())
981 safe_cast<PrintReqState*>(senderState)->popLabel();
982 }
983
984 void print(std::ostream &o, int verbosity = 0,
985 const std::string &prefix = "") const;
986
987 /**
988 * A no-args wrapper of print(std::ostream...)
989 * meant to be invoked from DPRINTFs
990 * avoiding string overheads in fast mode
991 * @return string with the request's type and start<->end addresses
992 */
993 std::string print() const;
994};
995
996#endif //__MEM_PACKET_HH
513 bool memInhibitAsserted() const { return flags.isSet(MEM_INHIBIT); }
514 void assertShared() { flags.set(SHARED); }
515 bool sharedAsserted() const { return flags.isSet(SHARED); }
516
517 // Special control flags
518 void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
519 bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
520 void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
521 void clearSupplyExclusive() { flags.clear(SUPPLY_EXCLUSIVE); }
522 bool isSupplyExclusive() const { return flags.isSet(SUPPLY_EXCLUSIVE); }
523 void setSuppressFuncError() { flags.set(SUPPRESS_FUNC_ERROR); }
524 bool suppressFuncError() const { return flags.isSet(SUPPRESS_FUNC_ERROR); }
525 void setPrefetchSquashed() { flags.set(PREFETCH_SNOOP_SQUASH); }
526 bool prefetchSquashed() const { return flags.isSet(PREFETCH_SNOOP_SQUASH); }
527
528 // Network error conditions... encapsulate them as methods since
529 // their encoding keeps changing (from result field to command
530 // field, etc.)
531 void
532 setBadAddress()
533 {
534 assert(isResponse());
535 cmd = MemCmd::BadAddressError;
536 }
537
538 bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; }
539 void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
540
541 bool isSrcValid() const { return src != InvalidPortID; }
542 /// Accessor function to get the source index of the packet.
543 PortID getSrc() const { assert(isSrcValid()); return src; }
544 /// Accessor function to set the source index of the packet.
545 void setSrc(PortID _src) { src = _src; }
546
547 bool isDestValid() const { return dest != InvalidPortID; }
548 /// Accessor function for the destination index of the packet.
549 PortID getDest() const { assert(isDestValid()); return dest; }
550 /// Accessor function to set the destination index of the packet.
551 void setDest(PortID _dest) { dest = _dest; }
552 /// Reset destination field, e.g. to turn a response into a request again.
553 void clearDest() { dest = InvalidPortID; }
554
555 Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
556 /**
557 * Update the address of this packet mid-transaction. This is used
558 * by the address mapper to change an already set address to a new
559 * one based on the system configuration. It is intended to remap
560 * an existing address, so it asserts that the current address is
561 * valid.
562 */
563 void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
564
565 unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
566 Addr getOffset(int blkSize) const { return getAddr() & (Addr)(blkSize - 1); }
567
568 bool isSecure() const
569 {
570 assert(flags.isSet(VALID_ADDR));
571 return _isSecure;
572 }
573
574 /**
575 * It has been determined that the SC packet should successfully update
576 * memory. Therefore, convert this SC packet to a normal write.
577 */
578 void
579 convertScToWrite()
580 {
581 assert(isLLSC());
582 assert(isWrite());
583 cmd = MemCmd::WriteReq;
584 }
585
586 /**
587 * When ruby is in use, Ruby will monitor the cache line and thus M5
588 * phys memory should treat LL ops as normal reads.
589 */
590 void
591 convertLlToRead()
592 {
593 assert(isLLSC());
594 assert(isRead());
595 cmd = MemCmd::ReadReq;
596 }
597
598 /**
599 * Constructor. Note that a Request object must be constructed
600 * first, but the Requests's physical address and size fields need
601 * not be valid. The command must be supplied.
602 */
603 Packet(Request *_req, MemCmd _cmd)
604 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
605 size(0), src(InvalidPortID), dest(InvalidPortID),
606 bytesValidStart(0), bytesValidEnd(0),
607 firstWordDelay(0), lastWordDelay(0),
608 senderState(NULL)
609 {
610 if (req->hasPaddr()) {
611 addr = req->getPaddr();
612 flags.set(VALID_ADDR);
613 _isSecure = req->isSecure();
614 }
615 if (req->hasSize()) {
616 size = req->getSize();
617 flags.set(VALID_SIZE);
618 }
619 }
620
621 /**
622 * Alternate constructor if you are trying to create a packet with
623 * a request that is for a whole block, not the address from the
624 * req. this allows for overriding the size/addr of the req.
625 */
626 Packet(Request *_req, MemCmd _cmd, int _blkSize)
627 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
628 src(InvalidPortID), dest(InvalidPortID),
629 bytesValidStart(0), bytesValidEnd(0),
630 firstWordDelay(0), lastWordDelay(0),
631 senderState(NULL)
632 {
633 if (req->hasPaddr()) {
634 addr = req->getPaddr() & ~(_blkSize - 1);
635 flags.set(VALID_ADDR);
636 _isSecure = req->isSecure();
637 }
638 size = _blkSize;
639 flags.set(VALID_SIZE);
640 }
641
642 /**
643 * Alternate constructor for copying a packet. Copy all fields
644 * *except* if the original packet's data was dynamic, don't copy
645 * that, as we can't guarantee that the new packet's lifetime is
646 * less than that of the original packet. In this case the new
647 * packet should allocate its own data.
648 */
649 Packet(Packet *pkt, bool clearFlags = false)
650 : cmd(pkt->cmd), req(pkt->req),
651 data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL),
652 addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
653 src(pkt->src), dest(pkt->dest),
654 bytesValidStart(pkt->bytesValidStart),
655 bytesValidEnd(pkt->bytesValidEnd),
656 firstWordDelay(pkt->firstWordDelay),
657 lastWordDelay(pkt->lastWordDelay),
658 senderState(pkt->senderState)
659 {
660 if (!clearFlags)
661 flags.set(pkt->flags & COPY_FLAGS);
662
663 flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
664 flags.set(pkt->flags & STATIC_DATA);
665
666 // if we did not copy the static data pointer, allocate data
667 // dynamically instead
668 if (!data)
669 allocate();
670 }
671
672 /**
673 * Change the packet type based on request type.
674 */
675 void
676 refineCommand()
677 {
678 if (cmd == MemCmd::ReadReq) {
679 if (req->isLLSC()) {
680 cmd = MemCmd::LoadLockedReq;
681 } else if (req->isPrefetch()) {
682 cmd = MemCmd::SoftPFReq;
683 }
684 } else if (cmd == MemCmd::WriteReq) {
685 if (req->isLLSC()) {
686 cmd = MemCmd::StoreCondReq;
687 } else if (req->isSwap()) {
688 cmd = MemCmd::SwapReq;
689 }
690 }
691 }
692
693 /**
694 * Constructor-like methods that return Packets based on Request objects.
695 * Will call refineCommand() to fine-tune the Packet type if it's not a
696 * vanilla read or write.
697 */
698 static PacketPtr
699 createRead(Request *req)
700 {
701 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
702 pkt->refineCommand();
703 return pkt;
704 }
705
706 static PacketPtr
707 createWrite(Request *req)
708 {
709 PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
710 pkt->refineCommand();
711 return pkt;
712 }
713
714 /**
715 * clean up packet variables
716 */
717 ~Packet()
718 {
719 // If this is a request packet for which there's no response,
720 // delete the request object here, since the requester will
721 // never get the chance.
722 if (req && isRequest() && !needsResponse())
723 delete req;
724 deleteData();
725 }
726
727 /**
728 * Reinitialize packet address and size from the associated
729 * Request object, and reset other fields that may have been
730 * modified by a previous transaction. Typically called when a
731 * statically allocated Request/Packet pair is reused for multiple
732 * transactions.
733 */
734 void
735 reinitFromRequest()
736 {
737 assert(req->hasPaddr());
738 flags = 0;
739 addr = req->getPaddr();
740 _isSecure = req->isSecure();
741 size = req->getSize();
742
743 src = InvalidPortID;
744 dest = InvalidPortID;
745 bytesValidStart = 0;
746 bytesValidEnd = 0;
747 firstWordDelay = 0;
748 lastWordDelay = 0;
749
750 flags.set(VALID_ADDR|VALID_SIZE);
751 deleteData();
752 }
753
754 /**
755 * Take a request packet and modify it in place to be suitable for
756 * returning as a response to that request. The source field is
757 * turned into the destination, and subsequently cleared. Note
758 * that the latter is not necessary for atomic requests, but
759 * causes no harm as neither field is valid.
760 */
761 void
762 makeResponse()
763 {
764 assert(needsResponse());
765 assert(isRequest());
766 origCmd = cmd;
767 cmd = cmd.responseCommand();
768
769 // responses are never express, even if the snoop that
770 // triggered them was
771 flags.clear(EXPRESS_SNOOP);
772
773 dest = src;
774 src = InvalidPortID;
775 }
776
777 void
778 makeAtomicResponse()
779 {
780 makeResponse();
781 }
782
783 void
784 makeTimingResponse()
785 {
786 makeResponse();
787 }
788
789 void
790 setFunctionalResponseStatus(bool success)
791 {
792 if (!success) {
793 if (isWrite()) {
794 cmd = MemCmd::FunctionalWriteError;
795 } else {
796 cmd = MemCmd::FunctionalReadError;
797 }
798 }
799 }
800
801 void
802 setSize(unsigned size)
803 {
804 assert(!flags.isSet(VALID_SIZE));
805
806 this->size = size;
807 flags.set(VALID_SIZE);
808 }
809
810
811 /**
812 * Set the data pointer to the following value that should not be
813 * freed.
814 */
815 template <typename T>
816 void
817 dataStatic(T *p)
818 {
819 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
820 data = (PacketDataPtr)p;
821 flags.set(STATIC_DATA);
822 }
823
824 /**
825 * Set the data pointer to the following value that should not be
826 * freed. This version of the function allows the pointer passed
827 * to us to be const. To avoid issues down the line we cast the
828 * constness away, the alternative would be to keep both a const
829 * and non-const data pointer and cleverly choose between
830 * them. Note that this is only allowed for static data.
831 */
832 template <typename T>
833 void
834 dataStaticConst(const T *p)
835 {
836 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
837 data = const_cast<PacketDataPtr>(p);
838 flags.set(STATIC_DATA);
839 }
840
841 /**
842 * Set the data pointer to a value that should have delete []
843 * called on it.
844 */
845 template <typename T>
846 void
847 dataDynamic(T *p)
848 {
849 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
850 data = (PacketDataPtr)p;
851 flags.set(DYNAMIC_DATA);
852 }
853
854 /**
855 * get a pointer to the data ptr.
856 */
857 template <typename T>
858 T*
859 getPtr()
860 {
861 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
862 return (T*)data;
863 }
864
865 template <typename T>
866 const T*
867 getConstPtr() const
868 {
869 assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
870 return (const T*)data;
871 }
872
873 /**
874 * return the value of what is pointed to in the packet.
875 */
876 template <typename T>
877 T get() const;
878
879 /**
880 * set the value in the data pointer to v.
881 */
882 template <typename T>
883 void set(T v);
884
885 /**
886 * Copy data into the packet from the provided pointer.
887 */
888 void
889 setData(const uint8_t *p)
890 {
891 if (p != getPtr<uint8_t>())
892 std::memcpy(getPtr<uint8_t>(), p, getSize());
893 }
894
895 /**
896 * Copy data into the packet from the provided block pointer,
897 * which is aligned to the given block size.
898 */
899 void
900 setDataFromBlock(const uint8_t *blk_data, int blkSize)
901 {
902 setData(blk_data + getOffset(blkSize));
903 }
904
905 /**
906 * Copy data from the packet to the provided block pointer, which
907 * is aligned to the given block size.
908 */
909 void
910 writeData(uint8_t *p) const
911 {
912 std::memcpy(p, getConstPtr<uint8_t>(), getSize());
913 }
914
915 /**
916 * Copy data from the packet to the memory at the provided pointer.
917 */
918 void
919 writeDataToBlock(uint8_t *blk_data, int blkSize) const
920 {
921 writeData(blk_data + getOffset(blkSize));
922 }
923
924 /**
925 * delete the data pointed to in the data pointer. Ok to call to
926 * matter how data was allocted.
927 */
928 void
929 deleteData()
930 {
931 if (flags.isSet(DYNAMIC_DATA))
932 delete [] data;
933
934 flags.clear(STATIC_DATA|DYNAMIC_DATA);
935 data = NULL;
936 }
937
938 /** Allocate memory for the packet. */
939 void
940 allocate()
941 {
942 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
943 flags.set(DYNAMIC_DATA);
944 data = new uint8_t[getSize()];
945 }
946
947 /**
948 * Check a functional request against a memory value represented
949 * by a base/size pair and an associated data array. If the
950 * functional request is a read, it may be satisfied by the memory
951 * value. If the functional request is a write, it may update the
952 * memory value.
953 */
954 bool checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
955 uint8_t *data);
956
957 /**
958 * Check a functional request against a memory value stored in
959 * another packet (i.e. an in-transit request or response).
960 */
961 bool
962 checkFunctional(PacketPtr other)
963 {
964 uint8_t *data = other->hasData() ? other->getPtr<uint8_t>() : NULL;
965 return checkFunctional(other, other->getAddr(), other->isSecure(),
966 other->getSize(), data);
967 }
968
969 /**
970 * Push label for PrintReq (safe to call unconditionally).
971 */
972 void
973 pushLabel(const std::string &lbl)
974 {
975 if (isPrint())
976 safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
977 }
978
979 /**
980 * Pop label for PrintReq (safe to call unconditionally).
981 */
982 void
983 popLabel()
984 {
985 if (isPrint())
986 safe_cast<PrintReqState*>(senderState)->popLabel();
987 }
988
989 void print(std::ostream &o, int verbosity = 0,
990 const std::string &prefix = "") const;
991
992 /**
993 * A no-args wrapper of print(std::ostream...)
994 * meant to be invoked from DPRINTFs
995 * avoiding string overheads in fast mode
996 * @return string with the request's type and start<->end addresses
997 */
998 std::string print() const;
999};
1000
1001#endif //__MEM_PACKET_HH