packet.hh (11199:929fd978ab4e) packet.hh (11256:65db40192591)
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,
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 ReleaseReq,
115 ReleaseResp,
116 AcquireReq,
117 AcquireResp,
114 MemFenceReq,
115 MemFenceResp,
118 // Error responses
119 // @TODO these should be classified as responses rather than
120 // requests; coding them as requests initially for backwards
121 // compatibility
122 InvalidDestError, // packet dest field invalid
123 BadAddressError, // memory address invalid
124 FunctionalReadError, // unable to fulfill functional read
125 FunctionalWriteError, // unable to fulfill functional write
126 // Fake simulator-only commands
127 PrintReq, // Print state matching address
128 FlushReq, //request for a cache flush
129 InvalidateReq, // request for address to be invalidated
130 InvalidateResp,
131 NUM_MEM_CMDS
132 };
133
134 private:
135 /**
136 * List of command attributes.
137 */
138 enum Attribute
139 {
140 IsRead, //!< Data flows from responder to requester
141 IsWrite, //!< Data flows from requester to responder
142 IsUpgrade,
143 IsInvalidate,
144 NeedsExclusive, //!< Requires exclusive copy to complete in-cache
145 IsRequest, //!< Issued by requester
146 IsResponse, //!< Issue by responder
147 NeedsResponse, //!< Requester needs response from target
148 IsEviction,
149 IsSWPrefetch,
150 IsHWPrefetch,
151 IsLlsc, //!< Alpha/MIPS LL or SC access
152 HasData, //!< There is an associated payload
153 IsError, //!< Error response
154 IsPrint, //!< Print state matching address (for debugging)
155 IsFlush, //!< Flush the address from caches
156 NUM_COMMAND_ATTRIBUTES
157 };
158
159 /**
160 * Structure that defines attributes and other data associated
161 * with a Command.
162 */
163 struct CommandInfo
164 {
165 /// Set of attribute flags.
166 const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
167 /// Corresponding response for requests; InvalidCmd if no
168 /// response is applicable.
169 const Command response;
170 /// String representation (for printing)
171 const std::string str;
172 };
173
174 /// Array to map Command enum to associated info.
175 static const CommandInfo commandInfo[];
176
177 private:
178
179 Command cmd;
180
181 bool
182 testCmdAttrib(MemCmd::Attribute attrib) const
183 {
184 return commandInfo[cmd].attributes[attrib] != 0;
185 }
186
187 public:
188
189 bool isRead() const { return testCmdAttrib(IsRead); }
190 bool isWrite() const { return testCmdAttrib(IsWrite); }
191 bool isUpgrade() const { return testCmdAttrib(IsUpgrade); }
192 bool isRequest() const { return testCmdAttrib(IsRequest); }
193 bool isResponse() const { return testCmdAttrib(IsResponse); }
194 bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); }
195 bool needsResponse() const { return testCmdAttrib(NeedsResponse); }
196 bool isInvalidate() const { return testCmdAttrib(IsInvalidate); }
197 bool isEviction() const { return testCmdAttrib(IsEviction); }
198
199 /**
200 * A writeback is an eviction that carries data.
201 */
202 bool isWriteback() const { return testCmdAttrib(IsEviction) &&
203 testCmdAttrib(HasData); }
204
205 /**
206 * Check if this particular packet type carries payload data. Note
207 * that this does not reflect if the data pointer of the packet is
208 * valid or not.
209 */
210 bool hasData() const { return testCmdAttrib(HasData); }
211 bool isLLSC() const { return testCmdAttrib(IsLlsc); }
212 bool isSWPrefetch() const { return testCmdAttrib(IsSWPrefetch); }
213 bool isHWPrefetch() const { return testCmdAttrib(IsHWPrefetch); }
214 bool isPrefetch() const { return testCmdAttrib(IsSWPrefetch) ||
215 testCmdAttrib(IsHWPrefetch); }
216 bool isError() const { return testCmdAttrib(IsError); }
217 bool isPrint() const { return testCmdAttrib(IsPrint); }
218 bool isFlush() const { return testCmdAttrib(IsFlush); }
219
220 const Command
221 responseCommand() const
222 {
223 return commandInfo[cmd].response;
224 }
225
226 /// Return the string to a cmd given by idx.
227 const std::string &toString() const { return commandInfo[cmd].str; }
228 int toInt() const { return (int)cmd; }
229
230 MemCmd(Command _cmd) : cmd(_cmd) { }
231 MemCmd(int _cmd) : cmd((Command)_cmd) { }
232 MemCmd() : cmd(InvalidCmd) { }
233
234 bool operator==(MemCmd c2) const { return (cmd == c2.cmd); }
235 bool operator!=(MemCmd c2) const { return (cmd != c2.cmd); }
236};
237
238/**
239 * A Packet is used to encapsulate a transfer between two objects in
240 * the memory system (e.g., the L1 and L2 cache). (In contrast, a
241 * single Request travels all the way from the requester to the
242 * ultimate destination and back, possibly being conveyed by several
243 * different Packets along the way.)
244 */
245class Packet : public Printable
246{
247 public:
248 typedef uint32_t FlagsType;
249 typedef ::Flags<FlagsType> Flags;
250
251 private:
252
253 enum : FlagsType {
254 // Flags to transfer across when copying a packet
255 COPY_FLAGS = 0x0000000F,
256
257 SHARED = 0x00000001,
258 // Special control flags
259 /// Special timing-mode atomic snoop for multi-level coherence.
260 EXPRESS_SNOOP = 0x00000002,
261 /// Does supplier have exclusive copy?
262 /// Useful for multi-level coherence.
263 SUPPLY_EXCLUSIVE = 0x00000004,
264 // Snoop response flags
265 MEM_INHIBIT = 0x00000008,
266
267 /// Are the 'addr' and 'size' fields valid?
268 VALID_ADDR = 0x00000100,
269 VALID_SIZE = 0x00000200,
270
271 /// Is the data pointer set to a value that shouldn't be freed
272 /// when the packet is destroyed?
273 STATIC_DATA = 0x00001000,
274 /// The data pointer points to a value that should be freed when
275 /// the packet is destroyed. The pointer is assumed to be pointing
276 /// to an array, and delete [] is consequently called
277 DYNAMIC_DATA = 0x00002000,
278
279 /// suppress the error if this packet encounters a functional
280 /// access failure.
281 SUPPRESS_FUNC_ERROR = 0x00008000,
282
283 // Signal block present to squash prefetch and cache evict packets
284 // through express snoop flag
285 BLOCK_CACHED = 0x00010000
286 };
287
288 Flags flags;
289
290 public:
291 typedef MemCmd::Command Command;
292
293 /// The command field of the packet.
294 MemCmd cmd;
295
296 /// A pointer to the original request.
297 const RequestPtr req;
298
299 private:
300 /**
301 * A pointer to the data being transfered. It can be differnt
302 * sizes at each level of the heirarchy so it belongs in the
303 * packet, not request. This may or may not be populated when a
304 * responder recieves the packet. If not populated it memory should
305 * be allocated.
306 */
307 PacketDataPtr data;
308
309 /// The address of the request. This address could be virtual or
310 /// physical, depending on the system configuration.
311 Addr addr;
312
313 /// True if the request targets the secure memory space.
314 bool _isSecure;
315
316 /// The size of the request or transfer.
317 unsigned size;
318
319 /**
320 * Track the bytes found that satisfy a functional read.
321 */
322 std::vector<bool> bytesValid;
323
324 public:
325
326 /**
327 * The extra delay from seeing the packet until the header is
328 * transmitted. This delay is used to communicate the crossbar
329 * forwarding latency to the neighbouring object (e.g. a cache)
330 * that actually makes the packet wait. As the delay is relative,
331 * a 32-bit unsigned should be sufficient.
332 */
333 uint32_t headerDelay;
334
335 /**
336 * Keep track of the extra delay incurred by snooping upwards
337 * before sending a request down the memory system. This is used
338 * by the coherent crossbar to account for the additional request
339 * delay.
340 */
341 uint32_t snoopDelay;
342
343 /**
344 * The extra pipelining delay from seeing the packet until the end of
345 * payload is transmitted by the component that provided it (if
346 * any). This includes the header delay. Similar to the header
347 * delay, this is used to make up for the fact that the
348 * crossbar does not make the packet wait. As the delay is
349 * relative, a 32-bit unsigned should be sufficient.
350 */
351 uint32_t payloadDelay;
352
353 /**
354 * A virtual base opaque structure used to hold state associated
355 * with the packet (e.g., an MSHR), specific to a MemObject that
356 * sees the packet. A pointer to this state is returned in the
357 * packet's response so that the MemObject in question can quickly
358 * look up the state needed to process it. A specific subclass
359 * would be derived from this to carry state specific to a
360 * particular sending device.
361 *
362 * As multiple MemObjects may add their SenderState throughout the
363 * memory system, the SenderStates create a stack, where a
364 * MemObject can add a new Senderstate, as long as the
365 * predecessing SenderState is restored when the response comes
366 * back. For this reason, the predecessor should always be
367 * populated with the current SenderState of a packet before
368 * modifying the senderState field in the request packet.
369 */
370 struct SenderState
371 {
372 SenderState* predecessor;
373 SenderState() : predecessor(NULL) {}
374 virtual ~SenderState() {}
375 };
376
377 /**
378 * Object used to maintain state of a PrintReq. The senderState
379 * field of a PrintReq should always be of this type.
380 */
381 class PrintReqState : public SenderState
382 {
383 private:
384 /**
385 * An entry in the label stack.
386 */
387 struct LabelStackEntry
388 {
389 const std::string label;
390 std::string *prefix;
391 bool labelPrinted;
392 LabelStackEntry(const std::string &_label, std::string *_prefix);
393 };
394
395 typedef std::list<LabelStackEntry> LabelStack;
396 LabelStack labelStack;
397
398 std::string *curPrefixPtr;
399
400 public:
401 std::ostream &os;
402 const int verbosity;
403
404 PrintReqState(std::ostream &os, int verbosity = 0);
405 ~PrintReqState();
406
407 /**
408 * Returns the current line prefix.
409 */
410 const std::string &curPrefix() { return *curPrefixPtr; }
411
412 /**
413 * Push a label onto the label stack, and prepend the given
414 * prefix string onto the current prefix. Labels will only be
415 * printed if an object within the label's scope is printed.
416 */
417 void pushLabel(const std::string &lbl,
418 const std::string &prefix = " ");
419
420 /**
421 * Pop a label off the label stack.
422 */
423 void popLabel();
424
425 /**
426 * Print all of the pending unprinted labels on the
427 * stack. Called by printObj(), so normally not called by
428 * users unless bypassing printObj().
429 */
430 void printLabels();
431
432 /**
433 * Print a Printable object to os, because it matched the
434 * address on a PrintReq.
435 */
436 void printObj(Printable *obj);
437 };
438
439 /**
440 * This packet's sender state. Devices should use dynamic_cast<>
441 * to cast to the state appropriate to the sender. The intent of
442 * this variable is to allow a device to attach extra information
443 * to a request. A response packet must return the sender state
444 * that was attached to the original request (even if a new packet
445 * is created).
446 */
447 SenderState *senderState;
448
449 /**
450 * Push a new sender state to the packet and make the current
451 * sender state the predecessor of the new one. This should be
452 * prefered over direct manipulation of the senderState member
453 * variable.
454 *
455 * @param sender_state SenderState to push at the top of the stack
456 */
457 void pushSenderState(SenderState *sender_state);
458
459 /**
460 * Pop the top of the state stack and return a pointer to it. This
461 * assumes the current sender state is not NULL. This should be
462 * preferred over direct manipulation of the senderState member
463 * variable.
464 *
465 * @return The current top of the stack
466 */
467 SenderState *popSenderState();
468
469 /**
470 * Go through the sender state stack and return the first instance
471 * that is of type T (as determined by a dynamic_cast). If there
472 * is no sender state of type T, NULL is returned.
473 *
474 * @return The topmost state of type T
475 */
476 template <typename T>
477 T * findNextSenderState() const
478 {
479 T *t = NULL;
480 SenderState* sender_state = senderState;
481 while (t == NULL && sender_state != NULL) {
482 t = dynamic_cast<T*>(sender_state);
483 sender_state = sender_state->predecessor;
484 }
485 return t;
486 }
487
488 /// Return the string name of the cmd field (for debugging and
489 /// tracing).
490 const std::string &cmdString() const { return cmd.toString(); }
491
492 /// Return the index of this command.
493 inline int cmdToIndex() const { return cmd.toInt(); }
494
495 bool isRead() const { return cmd.isRead(); }
496 bool isWrite() const { return cmd.isWrite(); }
497 bool isUpgrade() const { return cmd.isUpgrade(); }
498 bool isRequest() const { return cmd.isRequest(); }
499 bool isResponse() const { return cmd.isResponse(); }
500 bool needsExclusive() const { return cmd.needsExclusive(); }
501 bool needsResponse() const { return cmd.needsResponse(); }
502 bool isInvalidate() const { return cmd.isInvalidate(); }
503 bool isEviction() const { return cmd.isEviction(); }
504 bool isWriteback() const { return cmd.isWriteback(); }
505 bool hasData() const { return cmd.hasData(); }
506 bool isLLSC() const { return cmd.isLLSC(); }
507 bool isError() const { return cmd.isError(); }
508 bool isPrint() const { return cmd.isPrint(); }
509 bool isFlush() const { return cmd.isFlush(); }
510
511 // Snoop flags
512 void assertMemInhibit()
513 {
514 assert(isRequest());
515 assert(!flags.isSet(MEM_INHIBIT));
516 flags.set(MEM_INHIBIT);
517 }
518 bool memInhibitAsserted() const { return flags.isSet(MEM_INHIBIT); }
519 void assertShared() { flags.set(SHARED); }
520 bool sharedAsserted() const { return flags.isSet(SHARED); }
521
522 // Special control flags
523 void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
524 bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
525 void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
526 bool isSupplyExclusive() const { return flags.isSet(SUPPLY_EXCLUSIVE); }
527 void setSuppressFuncError() { flags.set(SUPPRESS_FUNC_ERROR); }
528 bool suppressFuncError() const { return flags.isSet(SUPPRESS_FUNC_ERROR); }
529 void setBlockCached() { flags.set(BLOCK_CACHED); }
530 bool isBlockCached() const { return flags.isSet(BLOCK_CACHED); }
531 void clearBlockCached() { flags.clear(BLOCK_CACHED); }
532
533 // Network error conditions... encapsulate them as methods since
534 // their encoding keeps changing (from result field to command
535 // field, etc.)
536 void
537 setBadAddress()
538 {
539 assert(isResponse());
540 cmd = MemCmd::BadAddressError;
541 }
542
543 void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
544
545 Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
546 /**
547 * Update the address of this packet mid-transaction. This is used
548 * by the address mapper to change an already set address to a new
549 * one based on the system configuration. It is intended to remap
550 * an existing address, so it asserts that the current address is
551 * valid.
552 */
553 void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
554
555 unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
556
557 Addr getOffset(unsigned int blk_size) const
558 {
559 return getAddr() & Addr(blk_size - 1);
560 }
561
562 Addr getBlockAddr(unsigned int blk_size) const
563 {
564 return getAddr() & ~(Addr(blk_size - 1));
565 }
566
567 bool isSecure() const
568 {
569 assert(flags.isSet(VALID_ADDR));
570 return _isSecure;
571 }
572
573 /**
574 * It has been determined that the SC packet should successfully update
575 * memory. Therefore, convert this SC packet to a normal write.
576 */
577 void
578 convertScToWrite()
579 {
580 assert(isLLSC());
581 assert(isWrite());
582 cmd = MemCmd::WriteReq;
583 }
584
585 /**
586 * When ruby is in use, Ruby will monitor the cache line and the
587 * phys memory should treat LL ops as normal reads.
588 */
589 void
590 convertLlToRead()
591 {
592 assert(isLLSC());
593 assert(isRead());
594 cmd = MemCmd::ReadReq;
595 }
596
597 /**
598 * Constructor. Note that a Request object must be constructed
599 * first, but the Requests's physical address and size fields need
600 * not be valid. The command must be supplied.
601 */
602 Packet(const RequestPtr _req, MemCmd _cmd)
603 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
604 size(0), headerDelay(0), snoopDelay(0), payloadDelay(0),
605 senderState(NULL)
606 {
607 if (req->hasPaddr()) {
608 addr = req->getPaddr();
609 flags.set(VALID_ADDR);
610 _isSecure = req->isSecure();
611 }
612 if (req->hasSize()) {
613 size = req->getSize();
614 flags.set(VALID_SIZE);
615 }
616 }
617
618 /**
619 * Alternate constructor if you are trying to create a packet with
620 * a request that is for a whole block, not the address from the
621 * req. this allows for overriding the size/addr of the req.
622 */
623 Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize)
624 : cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
625 headerDelay(0), snoopDelay(0), payloadDelay(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(const PacketPtr pkt, bool clear_flags, bool alloc_data)
645 : cmd(pkt->cmd), req(pkt->req),
646 data(nullptr),
647 addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
648 bytesValid(pkt->bytesValid),
649 headerDelay(pkt->headerDelay),
650 snoopDelay(0),
651 payloadDelay(pkt->payloadDelay),
652 senderState(pkt->senderState)
653 {
654 if (!clear_flags)
655 flags.set(pkt->flags & COPY_FLAGS);
656
657 flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
658
659 // should we allocate space for data, or not, the express
660 // snoops do not need to carry any data as they only serve to
661 // co-ordinate state changes
662 if (alloc_data) {
663 // even if asked to allocate data, if the original packet
664 // holds static data, then the sender will not be doing
665 // any memcpy on receiving the response, thus we simply
666 // carry the pointer forward
667 if (pkt->flags.isSet(STATIC_DATA)) {
668 data = pkt->data;
669 flags.set(STATIC_DATA);
670 } else {
671 allocate();
672 }
673 }
674 }
675
676 /**
677 * Generate the appropriate read MemCmd based on the Request flags.
678 */
679 static MemCmd
680 makeReadCmd(const RequestPtr req)
681 {
682 if (req->isLLSC())
683 return MemCmd::LoadLockedReq;
684 else if (req->isPrefetch())
685 return MemCmd::SoftPFReq;
686 else
687 return MemCmd::ReadReq;
688 }
689
690 /**
691 * Generate the appropriate write MemCmd based on the Request flags.
692 */
693 static MemCmd
694 makeWriteCmd(const RequestPtr req)
695 {
696 if (req->isLLSC())
697 return MemCmd::StoreCondReq;
698 else if (req->isSwap())
699 return MemCmd::SwapReq;
700 else
701 return MemCmd::WriteReq;
702 }
703
704 /**
705 * Constructor-like methods that return Packets based on Request objects.
706 * Fine-tune the MemCmd type if it's not a vanilla read or write.
707 */
708 static PacketPtr
709 createRead(const RequestPtr req)
710 {
711 return new Packet(req, makeReadCmd(req));
712 }
713
714 static PacketPtr
715 createWrite(const RequestPtr req)
716 {
717 return new Packet(req, makeWriteCmd(req));
718 }
719
720 /**
721 * clean up packet variables
722 */
723 ~Packet()
724 {
725 // Delete the request object if this is a request packet which
726 // does not need a response, because the requester will not get
727 // a chance. If the request packet needs a response then the
728 // request will be deleted on receipt of the response
729 // packet. We also make sure to never delete the request for
730 // express snoops, even for cases when responses are not
731 // needed (CleanEvict and Writeback), since the snoop packet
732 // re-uses the same request.
733 if (req && isRequest() && !needsResponse() &&
734 !isExpressSnoop()) {
735 delete req;
736 }
737 deleteData();
738 }
739
740 /**
741 * Take a request packet and modify it in place to be suitable for
742 * returning as a response to that request.
743 */
744 void
745 makeResponse()
746 {
747 assert(needsResponse());
748 assert(isRequest());
749 cmd = cmd.responseCommand();
750
751 // responses are never express, even if the snoop that
752 // triggered them was
753 flags.clear(EXPRESS_SNOOP);
754 }
755
756 void
757 makeAtomicResponse()
758 {
759 makeResponse();
760 }
761
762 void
763 makeTimingResponse()
764 {
765 makeResponse();
766 }
767
768 void
769 setFunctionalResponseStatus(bool success)
770 {
771 if (!success) {
772 if (isWrite()) {
773 cmd = MemCmd::FunctionalWriteError;
774 } else {
775 cmd = MemCmd::FunctionalReadError;
776 }
777 }
778 }
779
780 void
781 setSize(unsigned size)
782 {
783 assert(!flags.isSet(VALID_SIZE));
784
785 this->size = size;
786 flags.set(VALID_SIZE);
787 }
788
789
790 public:
791 /**
792 * @{
793 * @name Data accessor mehtods
794 */
795
796 /**
797 * Set the data pointer to the following value that should not be
798 * freed. Static data allows us to do a single memcpy even if
799 * multiple packets are required to get from source to destination
800 * and back. In essence the pointer is set calling dataStatic on
801 * the original packet, and whenever this packet is copied and
802 * forwarded the same pointer is passed on. When a packet
803 * eventually reaches the destination holding the data, it is
804 * copied once into the location originally set. On the way back
805 * to the source, no copies are necessary.
806 */
807 template <typename T>
808 void
809 dataStatic(T *p)
810 {
811 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
812 data = (PacketDataPtr)p;
813 flags.set(STATIC_DATA);
814 }
815
816 /**
817 * Set the data pointer to the following value that should not be
818 * freed. This version of the function allows the pointer passed
819 * to us to be const. To avoid issues down the line we cast the
820 * constness away, the alternative would be to keep both a const
821 * and non-const data pointer and cleverly choose between
822 * them. Note that this is only allowed for static data.
823 */
824 template <typename T>
825 void
826 dataStaticConst(const T *p)
827 {
828 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
829 data = const_cast<PacketDataPtr>(p);
830 flags.set(STATIC_DATA);
831 }
832
833 /**
834 * Set the data pointer to a value that should have delete []
835 * called on it. Dynamic data is local to this packet, and as the
836 * packet travels from source to destination, forwarded packets
837 * will allocate their own data. When a packet reaches the final
838 * destination it will populate the dynamic data of that specific
839 * packet, and on the way back towards the source, memcpy will be
840 * invoked in every step where a new packet was created e.g. in
841 * the caches. Ultimately when the response reaches the source a
842 * final memcpy is needed to extract the data from the packet
843 * before it is deallocated.
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 * Get the data in the packet byte swapped from big endian to
875 * host endian.
876 */
877 template <typename T>
878 T getBE() const;
879
880 /**
881 * Get the data in the packet byte swapped from little endian to
882 * host endian.
883 */
884 template <typename T>
885 T getLE() const;
886
887 /**
888 * Get the data in the packet byte swapped from the specified
889 * endianness.
890 */
891 template <typename T>
892 T get(ByteOrder endian) const;
893
894 /**
895 * Get the data in the packet byte swapped from guest to host
896 * endian.
897 */
898 template <typename T>
899 T get() const;
900
901 /** Set the value in the data pointer to v as big endian. */
902 template <typename T>
903 void setBE(T v);
904
905 /** Set the value in the data pointer to v as little endian. */
906 template <typename T>
907 void setLE(T v);
908
909 /**
910 * Set the value in the data pointer to v using the specified
911 * endianness.
912 */
913 template <typename T>
914 void set(T v, ByteOrder endian);
915
916 /** Set the value in the data pointer to v as guest endian. */
917 template <typename T>
918 void set(T v);
919
920 /**
921 * Copy data into the packet from the provided pointer.
922 */
923 void
924 setData(const uint8_t *p)
925 {
926 // we should never be copying data onto itself, which means we
927 // must idenfity packets with static data, as they carry the
928 // same pointer from source to destination and back
929 assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA));
930
931 if (p != getPtr<uint8_t>())
932 // for packet with allocated dynamic data, we copy data from
933 // one to the other, e.g. a forwarded response to a response
934 std::memcpy(getPtr<uint8_t>(), p, getSize());
935 }
936
937 /**
938 * Copy data into the packet from the provided block pointer,
939 * which is aligned to the given block size.
940 */
941 void
942 setDataFromBlock(const uint8_t *blk_data, int blkSize)
943 {
944 setData(blk_data + getOffset(blkSize));
945 }
946
947 /**
948 * Copy data from the packet to the provided block pointer, which
949 * is aligned to the given block size.
950 */
951 void
952 writeData(uint8_t *p) const
953 {
954 std::memcpy(p, getConstPtr<uint8_t>(), getSize());
955 }
956
957 /**
958 * Copy data from the packet to the memory at the provided pointer.
959 */
960 void
961 writeDataToBlock(uint8_t *blk_data, int blkSize) const
962 {
963 writeData(blk_data + getOffset(blkSize));
964 }
965
966 /**
967 * delete the data pointed to in the data pointer. Ok to call to
968 * matter how data was allocted.
969 */
970 void
971 deleteData()
972 {
973 if (flags.isSet(DYNAMIC_DATA))
974 delete [] data;
975
976 flags.clear(STATIC_DATA|DYNAMIC_DATA);
977 data = NULL;
978 }
979
980 /** Allocate memory for the packet. */
981 void
982 allocate()
983 {
984 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
985 flags.set(DYNAMIC_DATA);
986 data = new uint8_t[getSize()];
987 }
988
989 /** @} */
990
991 private: // Private data accessor methods
992 /** Get the data in the packet without byte swapping. */
993 template <typename T>
994 T getRaw() const;
995
996 /** Set the value in the data pointer to v without byte swapping. */
997 template <typename T>
998 void setRaw(T v);
999
1000 public:
1001 /**
1002 * Check a functional request against a memory value stored in
1003 * another packet (i.e. an in-transit request or
1004 * response). Returns true if the current packet is a read, and
1005 * the other packet provides the data, which is then copied to the
1006 * current packet. If the current packet is a write, and the other
1007 * packet intersects this one, then we update the data
1008 * accordingly.
1009 */
1010 bool
1011 checkFunctional(PacketPtr other)
1012 {
1013 // all packets that are carrying a payload should have a valid
1014 // data pointer
1015 return checkFunctional(other, other->getAddr(), other->isSecure(),
1016 other->getSize(),
1017 other->hasData() ?
1018 other->getPtr<uint8_t>() : NULL);
1019 }
1020
1021 /**
1022 * Does the request need to check for cached copies of the same block
1023 * in the memory hierarchy above.
1024 **/
1025 bool
1026 mustCheckAbove() const
1027 {
1028 return cmd == MemCmd::HardPFReq || isEviction();
1029 }
1030
1031 /**
1032 * Is this packet a clean eviction, including both actual clean
1033 * evict packets, but also clean writebacks.
1034 */
1035 bool
1036 isCleanEviction() const
1037 {
1038 return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
1039 }
1040
1041 /**
1042 * Check a functional request against a memory value represented
1043 * by a base/size pair and an associated data array. If the
1044 * current packet is a read, it may be satisfied by the memory
1045 * value. If the current packet is a write, it may update the
1046 * memory value.
1047 */
1048 bool
1049 checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
1050 uint8_t *_data);
1051
1052 /**
1053 * Push label for PrintReq (safe to call unconditionally).
1054 */
1055 void
1056 pushLabel(const std::string &lbl)
1057 {
1058 if (isPrint())
1059 safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
1060 }
1061
1062 /**
1063 * Pop label for PrintReq (safe to call unconditionally).
1064 */
1065 void
1066 popLabel()
1067 {
1068 if (isPrint())
1069 safe_cast<PrintReqState*>(senderState)->popLabel();
1070 }
1071
1072 void print(std::ostream &o, int verbosity = 0,
1073 const std::string &prefix = "") const;
1074
1075 /**
1076 * A no-args wrapper of print(std::ostream...)
1077 * meant to be invoked from DPRINTFs
1078 * avoiding string overheads in fast mode
1079 * @return string with the request's type and start<->end addresses
1080 */
1081 std::string print() const;
1082};
1083
1084#endif //__MEM_PACKET_HH
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
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); }
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,
256 // Special control flags
257 /// Special timing-mode atomic snoop for multi-level coherence.
258 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
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(); }
498 bool needsExclusive() const { return cmd.needsExclusive(); }
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
509 // Snoop flags
510 void assertMemInhibit()
511 {
512 assert(isRequest());
513 assert(!flags.isSet(MEM_INHIBIT));
514 flags.set(MEM_INHIBIT);
515 }
516 bool memInhibitAsserted() const { return flags.isSet(MEM_INHIBIT); }
517 void assertShared() { flags.set(SHARED); }
518 bool sharedAsserted() const { return flags.isSet(SHARED); }
519
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); }
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