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