Deleted Added
sdiff udiff text old ( 11199:929fd978ab4e ) new ( 11256:65db40192591 )
full compact
1/*
2 * Copyright (c) 2012-2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2006 The Regents of The University of Michigan
15 * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Ron Dreslinski
42 * Steve Reinhardt
43 * Ali Saidi
44 * Andreas Hansson
45 */
46
47/**
48 * @file
49 * Declaration of the Packet class.
50 */
51
52#ifndef __MEM_PACKET_HH__
53#define __MEM_PACKET_HH__
54
55#include <bitset>
56#include <cassert>
57#include <list>
58
59#include "base/cast.hh"
60#include "base/compiler.hh"
61#include "base/flags.hh"
62#include "base/misc.hh"
63#include "base/printable.hh"
64#include "base/types.hh"
65#include "mem/request.hh"
66#include "sim/core.hh"
67
68class Packet;
69typedef Packet *PacketPtr;
70typedef uint8_t* PacketDataPtr;
71typedef std::list<PacketPtr> PacketList;
72
73class MemCmd
74{
75 friend class Packet;
76
77 public:
78 /**
79 * List of all commands associated with a packet.
80 */
81 enum Command
82 {
83 InvalidCmd,
84 ReadReq,
85 ReadResp,
86 ReadRespWithInvalidate,
87 WriteReq,
88 WriteResp,
89 WritebackDirty,
90 WritebackClean,
91 CleanEvict,
92 SoftPFReq,
93 HardPFReq,
94 SoftPFResp,
95 HardPFResp,
96 WriteLineReq,
97 UpgradeReq,
98 SCUpgradeReq, // Special "weak" upgrade for StoreCond
99 UpgradeResp,
100 SCUpgradeFailReq, // Failed SCUpgradeReq in MSHR (never sent)
101 UpgradeFailResp, // Valid for SCUpgradeReq only
102 ReadExReq,
103 ReadExResp,
104 ReadCleanReq,
105 ReadSharedReq,
106 LoadLockedReq,
107 StoreCondReq,
108 StoreCondFailReq, // Failed StoreCondReq in MSHR (never sent)
109 StoreCondResp,
110 SwapReq,
111 SwapResp,
112 MessageReq,
113 MessageResp,
114 MemFenceReq,
115 MemFenceResp,
116 // Error responses
117 // @TODO these should be classified as responses rather than
118 // requests; coding them as requests initially for backwards
119 // compatibility
120 InvalidDestError, // packet dest field invalid
121 BadAddressError, // memory address invalid
122 FunctionalReadError, // unable to fulfill functional read
123 FunctionalWriteError, // unable to fulfill functional write
124 // Fake simulator-only commands
125 PrintReq, // Print state matching address
126 FlushReq, //request for a cache flush
127 InvalidateReq, // request for address to be invalidated
128 InvalidateResp,
129 NUM_MEM_CMDS
130 };
131
132 private:
133 /**
134 * List of command attributes.
135 */
136 enum Attribute
137 {
138 IsRead, //!< Data flows from responder to requester
139 IsWrite, //!< Data flows from requester to responder
140 IsUpgrade,
141 IsInvalidate,
142 NeedsExclusive, //!< Requires exclusive copy to complete in-cache
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