packet.hh revision 4916:000ab733f1eb
110923SN/A/* 210923SN/A * Copyright (c) 2006 The Regents of The University of Michigan 310923SN/A * All rights reserved. 410923SN/A * 510923SN/A * Redistribution and use in source and binary forms, with or without 610923SN/A * modification, are permitted provided that the following conditions are 710923SN/A * met: redistributions of source code must retain the above copyright 810923SN/A * notice, this list of conditions and the following disclaimer; 910923SN/A * redistributions in binary form must reproduce the above copyright 1010923SN/A * notice, this list of conditions and the following disclaimer in the 1110923SN/A * documentation and/or other materials provided with the distribution; 1210923SN/A * neither the name of the copyright holders nor the names of its 1310923SN/A * contributors may be used to endorse or promote products derived from 1410923SN/A * this software without specific prior written permission. 1510923SN/A * 1610923SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710923SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810923SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910923SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010923SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110923SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210923SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310923SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410923SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510923SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610923SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710923SN/A * 2810923SN/A * Authors: Ron Dreslinski 2910923SN/A * Steve Reinhardt 3010923SN/A * Ali Saidi 3110923SN/A */ 3210923SN/A 3310923SN/A/** 3410923SN/A * @file 3510923SN/A * Declaration of the Packet class. 3610923SN/A */ 3710923SN/A 3810923SN/A#ifndef __MEM_PACKET_HH__ 3910923SN/A#define __MEM_PACKET_HH__ 4010923SN/A 4111290Sgabor.dozsa@arm.com#include <cassert> 4210923SN/A#include <list> 4310923SN/A#include <bitset> 4411290Sgabor.dozsa@arm.com 4510923SN/A#include "base/compiler.hh" 4610923SN/A#include "base/fast_alloc.hh" 4710923SN/A#include "base/misc.hh" 4810923SN/A#include "mem/request.hh" 4910923SN/A#include "sim/host.hh" 5010923SN/A#include "sim/core.hh" 5110923SN/A 5210923SN/A 5310923SN/Astruct Packet; 5410923SN/Atypedef Packet *PacketPtr; 5510923SN/Atypedef uint8_t* PacketDataPtr; 5610923SN/Atypedef std::list<PacketPtr> PacketList; 5711290Sgabor.dozsa@arm.com 5811290Sgabor.dozsa@arm.comclass MemCmd 5910923SN/A{ 6011290Sgabor.dozsa@arm.com public: 6111263SN/A 6211263SN/A /** List of all commands associated with a packet. */ 6311263SN/A enum Command 6411263SN/A { 6511263SN/A InvalidCmd, 6611263SN/A ReadReq, 6710923SN/A ReadResp, 6810923SN/A WriteReq, 6910923SN/A WriteResp, 7010923SN/A Writeback, 7110923SN/A SoftPFReq, 7210923SN/A HardPFReq, 7310923SN/A SoftPFResp, 7411290Sgabor.dozsa@arm.com HardPFResp, 7511290Sgabor.dozsa@arm.com WriteInvalidateReq, 7610923SN/A WriteInvalidateResp, 7711290Sgabor.dozsa@arm.com UpgradeReq, 7811290Sgabor.dozsa@arm.com UpgradeResp, 7910923SN/A ReadExReq, 8010923SN/A ReadExResp, 8110923SN/A LoadLockedReq, 8210923SN/A LoadLockedResp, 8310923SN/A StoreCondReq, 8411290Sgabor.dozsa@arm.com StoreCondResp, 8511290Sgabor.dozsa@arm.com SwapReq, 8611290Sgabor.dozsa@arm.com SwapResp, 8711290Sgabor.dozsa@arm.com // Error responses 8811290Sgabor.dozsa@arm.com // @TODO these should be classified as responses rather than 8911290Sgabor.dozsa@arm.com // requests; coding them as requests initially for backwards 9011290Sgabor.dozsa@arm.com // compatibility 9111290Sgabor.dozsa@arm.com NetworkNackError, // nacked at network layer (not by protocol) 9211290Sgabor.dozsa@arm.com InvalidDestError, // packet dest field invalid 9310923SN/A BadAddressError, // memory address invalid 9411290Sgabor.dozsa@arm.com NUM_MEM_CMDS 9511290Sgabor.dozsa@arm.com }; 9611290Sgabor.dozsa@arm.com 9711290Sgabor.dozsa@arm.com private: 9811290Sgabor.dozsa@arm.com /** List of command attributes. */ 9911290Sgabor.dozsa@arm.com enum Attribute 10011290Sgabor.dozsa@arm.com { 10110923SN/A IsRead, //!< Data flows from responder to requester 10210923SN/A IsWrite, //!< Data flows from requester to responder 10311290Sgabor.dozsa@arm.com IsPrefetch, //!< Not a demand access 10410923SN/A IsInvalidate, 10510923SN/A NeedsExclusive, //!< Requires exclusive copy to complete in-cache 10610923SN/A IsRequest, //!< Issued by requester 10710923SN/A IsResponse, //!< Issue by responder 10811290Sgabor.dozsa@arm.com NeedsResponse, //!< Requester needs response from target 10910923SN/A IsSWPrefetch, 11010923SN/A IsHWPrefetch, 11110923SN/A IsLocked, //!< Alpha/MIPS LL or SC access 11211290Sgabor.dozsa@arm.com HasData, //!< There is an associated payload 11310923SN/A IsError, //!< Error response 11410923SN/A NUM_COMMAND_ATTRIBUTES 11510923SN/A }; 11610923SN/A 11710923SN/A /** Structure that defines attributes and other data associated 11810923SN/A * with a Command. */ 11910923SN/A struct CommandInfo { 12010923SN/A /** Set of attribute flags. */ 12110923SN/A const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes; 12211290Sgabor.dozsa@arm.com /** Corresponding response for requests; InvalidCmd if no 12311290Sgabor.dozsa@arm.com * response is applicable. */ 12410923SN/A const Command response; 12511290Sgabor.dozsa@arm.com /** String representation (for printing) */ 12611290Sgabor.dozsa@arm.com const std::string str; 12711290Sgabor.dozsa@arm.com }; 12810923SN/A 12910923SN/A /** Array to map Command enum to associated info. */ 13010923SN/A static const CommandInfo commandInfo[]; 13111290Sgabor.dozsa@arm.com 13210923SN/A private: 13311290Sgabor.dozsa@arm.com 13411290Sgabor.dozsa@arm.com Command cmd; 13511290Sgabor.dozsa@arm.com 13610923SN/A bool testCmdAttrib(MemCmd::Attribute attrib) const { 13710923SN/A return commandInfo[cmd].attributes[attrib] != 0; 13810923SN/A } 13911290Sgabor.dozsa@arm.com 14010923SN/A public: 14111290Sgabor.dozsa@arm.com 14211290Sgabor.dozsa@arm.com bool isRead() const { return testCmdAttrib(IsRead); } 14310923SN/A bool isWrite() const { return testCmdAttrib(IsWrite); } 14410923SN/A bool isRequest() const { return testCmdAttrib(IsRequest); } 14510923SN/A bool isResponse() const { return testCmdAttrib(IsResponse); } 14611290Sgabor.dozsa@arm.com bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); } 14710923SN/A bool needsResponse() const { return testCmdAttrib(NeedsResponse); } 14811290Sgabor.dozsa@arm.com bool isInvalidate() const { return testCmdAttrib(IsInvalidate); } 14911290Sgabor.dozsa@arm.com bool hasData() const { return testCmdAttrib(HasData); } 15010923SN/A bool isReadWrite() const { return isRead() && isWrite(); } 15110923SN/A bool isLocked() const { return testCmdAttrib(IsLocked); } 15210923SN/A bool isError() const { return testCmdAttrib(IsError); } 15311290Sgabor.dozsa@arm.com 15410923SN/A const Command responseCommand() const { 15511290Sgabor.dozsa@arm.com return commandInfo[cmd].response; 15611290Sgabor.dozsa@arm.com } 15710923SN/A 15810923SN/A /** Return the string to a cmd given by idx. */ 15910923SN/A const std::string &toString() const { 16011290Sgabor.dozsa@arm.com return commandInfo[cmd].str; 16110923SN/A } 16210923SN/A 16310923SN/A int toInt() const { return (int)cmd; } 16410923SN/A 16511290Sgabor.dozsa@arm.com MemCmd(Command _cmd) 16610923SN/A : cmd(_cmd) 16710923SN/A { } 16810923SN/A 16910923SN/A MemCmd(int _cmd) 17011290Sgabor.dozsa@arm.com : cmd((Command)_cmd) 17110923SN/A { } 17210923SN/A 17310923SN/A MemCmd() 17410923SN/A : cmd(InvalidCmd) 17510923SN/A { } 17610923SN/A 17710923SN/A bool operator==(MemCmd c2) { return (cmd == c2.cmd); } 17810923SN/A bool operator!=(MemCmd c2) { return (cmd != c2.cmd); } 17910923SN/A 18011290Sgabor.dozsa@arm.com friend class Packet; 18110923SN/A}; 18210923SN/A 18310923SN/A/** 18410923SN/A * A Packet is used to encapsulate a transfer between two objects in 18510923SN/A * the memory system (e.g., the L1 and L2 cache). (In contrast, a 18610923SN/A * single Request travels all the way from the requester to the 18710923SN/A * ultimate destination and back, possibly being conveyed by several 18810923SN/A * different Packets along the way.) 18910923SN/A */ 19010923SN/Aclass Packet : public FastAlloc 19110923SN/A{ 19211290Sgabor.dozsa@arm.com public: 19310923SN/A 19410923SN/A typedef MemCmd::Command Command; 19511290Sgabor.dozsa@arm.com 19610923SN/A /** The command field of the packet. */ 19710923SN/A MemCmd cmd; 19810923SN/A 19910923SN/A /** A pointer to the original request. */ 20010923SN/A RequestPtr req; 20110923SN/A 20210923SN/A private: 20310923SN/A /** A pointer to the data being transfered. It can be differnt 20410923SN/A * sizes at each level of the heirarchy so it belongs in the 20511290Sgabor.dozsa@arm.com * packet, not request. This may or may not be populated when a 20611290Sgabor.dozsa@arm.com * responder recieves the packet. If not populated it memory 20710923SN/A * should be allocated. 20810923SN/A */ 20910923SN/A PacketDataPtr data; 21010923SN/A 21110923SN/A /** Is the data pointer set to a value that shouldn't be freed 21210923SN/A * when the packet is destroyed? */ 21310923SN/A bool staticData; 21410923SN/A /** The data pointer points to a value that should be freed when 21511290Sgabor.dozsa@arm.com * the packet is destroyed. */ 21610923SN/A bool dynamicData; 21710923SN/A /** the data pointer points to an array (thus delete [] ) needs to 21811290Sgabor.dozsa@arm.com * be called on it rather than simply delete.*/ 21910923SN/A bool arrayData; 22011290Sgabor.dozsa@arm.com 22110923SN/A /** The address of the request. This address could be virtual or 22210923SN/A * physical, depending on the system configuration. */ 22311290Sgabor.dozsa@arm.com Addr addr; 22410923SN/A 22510923SN/A /** The size of the request or transfer. */ 22611290Sgabor.dozsa@arm.com int size; 22710923SN/A 22810923SN/A /** Device address (e.g., bus ID) of the source of the 22910923SN/A * transaction. The source is not responsible for setting this 23010923SN/A * field; it is set implicitly by the interconnect when the 23111290Sgabor.dozsa@arm.com * packet is first sent. */ 23210923SN/A short src; 23310923SN/A 23411290Sgabor.dozsa@arm.com /** Device address (e.g., bus ID) of the destination of the 23510923SN/A * transaction. The special value Broadcast indicates that the 23610923SN/A * packet should be routed based on its address. This field is 23711290Sgabor.dozsa@arm.com * initialized in the constructor and is thus always valid 23810923SN/A * (unlike * addr, size, and src). */ 23910923SN/A short dest; 24010923SN/A 24111290Sgabor.dozsa@arm.com /** The original value of the command field. Only valid when the 24210923SN/A * current command field is an error condition; in that case, the 24310923SN/A * previous contents of the command field are copied here. This 24411290Sgabor.dozsa@arm.com * field is *not* set on non-error responses. 24510923SN/A */ 24610923SN/A MemCmd origCmd; 24710923SN/A 24810923SN/A /** Are the 'addr' and 'size' fields valid? */ 24911290Sgabor.dozsa@arm.com bool addrSizeValid; 25010923SN/A /** Is the 'src' field valid? */ 25110923SN/A bool srcValid; 25211290Sgabor.dozsa@arm.com bool destValid; 25310923SN/A 25410923SN/A enum Flag { 25510923SN/A // Snoop response flags 25610923SN/A MemInhibit, 25711290Sgabor.dozsa@arm.com Shared, 25811290Sgabor.dozsa@arm.com // Special control flags 25910923SN/A /// Special timing-mode atomic snoop for multi-level coherence. 26010923SN/A ExpressSnoop, 26111290Sgabor.dozsa@arm.com /// Does supplier have exclusive copy? 26211290Sgabor.dozsa@arm.com /// Useful for multi-level coherence. 26310923SN/A SupplyExclusive, 26411290Sgabor.dozsa@arm.com NUM_PACKET_FLAGS 26510923SN/A }; 26610923SN/A 26710923SN/A /** Status flags */ 268 std::bitset<NUM_PACKET_FLAGS> flags; 269 270 public: 271 272 /** Used to calculate latencies for each packet.*/ 273 Tick time; 274 275 /** The time at which the packet will be fully transmitted */ 276 Tick finishTime; 277 278 /** The time at which the first chunk of the packet will be transmitted */ 279 Tick firstWordTime; 280 281 /** The special destination address indicating that the packet 282 * should be routed based on its address. */ 283 static const short Broadcast = -1; 284 285 /** A virtual base opaque structure used to hold state associated 286 * with the packet but specific to the sending device (e.g., an 287 * MSHR). A pointer to this state is returned in the packet's 288 * response so that the sender can quickly look up the state 289 * needed to process it. A specific subclass would be derived 290 * from this to carry state specific to a particular sending 291 * device. */ 292 class SenderState : public FastAlloc { 293 public: 294 virtual ~SenderState() {} 295 }; 296 297 /** This packet's sender state. Devices should use dynamic_cast<> 298 * to cast to the state appropriate to the sender. */ 299 SenderState *senderState; 300 301 /** Return the string name of the cmd field (for debugging and 302 * tracing). */ 303 const std::string &cmdString() const { return cmd.toString(); } 304 305 /** Return the index of this command. */ 306 inline int cmdToIndex() const { return cmd.toInt(); } 307 308 bool isRead() const { return cmd.isRead(); } 309 bool isWrite() const { return cmd.isWrite(); } 310 bool isRequest() const { return cmd.isRequest(); } 311 bool isResponse() const { return cmd.isResponse(); } 312 bool needsExclusive() const { return cmd.needsExclusive(); } 313 bool needsResponse() const { return cmd.needsResponse(); } 314 bool isInvalidate() const { return cmd.isInvalidate(); } 315 bool hasData() const { return cmd.hasData(); } 316 bool isReadWrite() const { return cmd.isReadWrite(); } 317 bool isLocked() const { return cmd.isLocked(); } 318 bool isError() const { return cmd.isError(); } 319 320 // Snoop flags 321 void assertMemInhibit() { flags[MemInhibit] = true; } 322 bool memInhibitAsserted() { return flags[MemInhibit]; } 323 void assertShared() { flags[Shared] = true; } 324 bool sharedAsserted() { return flags[Shared]; } 325 326 // Special control flags 327 void setExpressSnoop() { flags[ExpressSnoop] = true; } 328 bool isExpressSnoop() { return flags[ExpressSnoop]; } 329 void setSupplyExclusive() { flags[SupplyExclusive] = true; } 330 bool isSupplyExclusive() { return flags[SupplyExclusive]; } 331 332 // Network error conditions... encapsulate them as methods since 333 // their encoding keeps changing (from result field to command 334 // field, etc.) 335 void setNacked() { origCmd = cmd; cmd = MemCmd::NetworkNackError; } 336 void setBadAddress() { origCmd = cmd; cmd = MemCmd::BadAddressError; } 337 bool wasNacked() { return cmd == MemCmd::NetworkNackError; } 338 bool hadBadAddress() { return cmd == MemCmd::BadAddressError; } 339 340 bool nic_pkt() { panic("Unimplemented"); M5_DUMMY_RETURN } 341 342 /** Accessor function that returns the source index of the packet. */ 343 short getSrc() const { assert(srcValid); return src; } 344 void setSrc(short _src) { src = _src; srcValid = true; } 345 /** Reset source field, e.g. to retransmit packet on different bus. */ 346 void clearSrc() { srcValid = false; } 347 348 /** Accessor function that returns the destination index of 349 the packet. */ 350 short getDest() const { assert(destValid); return dest; } 351 void setDest(short _dest) { dest = _dest; destValid = true; } 352 353 Addr getAddr() const { assert(addrSizeValid); return addr; } 354 int getSize() const { assert(addrSizeValid); return size; } 355 Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); } 356 357 /** Constructor. Note that a Request object must be constructed 358 * first, but the Requests's physical address and size fields 359 * need not be valid. The command and destination addresses 360 * must be supplied. */ 361 Packet(Request *_req, MemCmd _cmd, short _dest) 362 : cmd(_cmd), req(_req), 363 data(NULL), staticData(false), dynamicData(false), arrayData(false), 364 addr(_req->paddr), size(_req->size), dest(_dest), 365 addrSizeValid(_req->validPaddr), srcValid(false), destValid(true), 366 flags(0), time(curTick), senderState(NULL) 367 { 368 } 369 370 /** Alternate constructor if you are trying to create a packet with 371 * a request that is for a whole block, not the address from the req. 372 * this allows for overriding the size/addr of the req.*/ 373 Packet(Request *_req, MemCmd _cmd, short _dest, int _blkSize) 374 : cmd(_cmd), req(_req), 375 data(NULL), staticData(false), dynamicData(false), arrayData(false), 376 addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize), dest(_dest), 377 addrSizeValid(_req->validPaddr), srcValid(false), destValid(true), 378 flags(0), time(curTick), senderState(NULL) 379 { 380 } 381 382 /** Alternate constructor for copying a packet. Copy all fields 383 * *except* if the original packet's data was dynamic, don't copy 384 * that, as we can't guarantee that the new packet's lifetime is 385 * less than that of the original packet. In this case the new 386 * packet should allocate its own data. */ 387 Packet(Packet *origPkt, bool clearFlags = false) 388 : cmd(origPkt->cmd), req(origPkt->req), 389 data(origPkt->staticData ? origPkt->data : NULL), 390 staticData(origPkt->staticData), 391 dynamicData(false), arrayData(false), 392 addr(origPkt->addr), size(origPkt->size), 393 src(origPkt->src), dest(origPkt->dest), 394 addrSizeValid(origPkt->addrSizeValid), 395 srcValid(origPkt->srcValid), destValid(origPkt->destValid), 396 flags(clearFlags ? 0 : origPkt->flags), 397 time(curTick), senderState(origPkt->senderState) 398 { 399 } 400 401 /** Destructor. */ 402 ~Packet() 403 { if (staticData || dynamicData) deleteData(); } 404 405 /** Reinitialize packet address and size from the associated 406 * Request object, and reset other fields that may have been 407 * modified by a previous transaction. Typically called when a 408 * statically allocated Request/Packet pair is reused for 409 * multiple transactions. */ 410 void reinitFromRequest() { 411 assert(req->validPaddr); 412 flags = 0; 413 addr = req->paddr; 414 size = req->size; 415 time = req->time; 416 addrSizeValid = true; 417 if (dynamicData) { 418 deleteData(); 419 dynamicData = false; 420 arrayData = false; 421 } 422 } 423 424 /** 425 * Take a request packet and modify it in place to be suitable for 426 * returning as a response to that request. The source and 427 * destination fields are *not* modified, as is appropriate for 428 * atomic accesses. 429 */ 430 void makeResponse() 431 { 432 assert(needsResponse()); 433 assert(isRequest()); 434 cmd = cmd.responseCommand(); 435 dest = src; 436 destValid = srcValid; 437 srcValid = false; 438 } 439 440 void makeAtomicResponse() 441 { 442 makeResponse(); 443 } 444 445 void makeTimingResponse() 446 { 447 makeResponse(); 448 } 449 450 /** 451 * Take a request packet that has been returned as NACKED and 452 * modify it so that it can be sent out again. Only packets that 453 * need a response can be NACKED, so verify that that is true. 454 */ 455 void 456 reinitNacked() 457 { 458 assert(wasNacked()); 459 cmd = origCmd; 460 assert(needsResponse()); 461 setDest(Broadcast); 462 } 463 464 465 /** 466 * Set the data pointer to the following value that should not be 467 * freed. 468 */ 469 template <typename T> 470 void 471 dataStatic(T *p) 472 { 473 if(dynamicData) 474 dynamicData = false; 475 data = (PacketDataPtr)p; 476 staticData = true; 477 } 478 479 /** 480 * Set the data pointer to a value that should have delete [] 481 * called on it. 482 */ 483 template <typename T> 484 void 485 dataDynamicArray(T *p) 486 { 487 assert(!staticData && !dynamicData); 488 data = (PacketDataPtr)p; 489 dynamicData = true; 490 arrayData = true; 491 } 492 493 /** 494 * set the data pointer to a value that should have delete called 495 * on it. 496 */ 497 template <typename T> 498 void 499 dataDynamic(T *p) 500 { 501 assert(!staticData && !dynamicData); 502 data = (PacketDataPtr)p; 503 dynamicData = true; 504 arrayData = false; 505 } 506 507 /** get a pointer to the data ptr. */ 508 template <typename T> 509 T* 510 getPtr() 511 { 512 assert(staticData || dynamicData); 513 return (T*)data; 514 } 515 516 /** return the value of what is pointed to in the packet. */ 517 template <typename T> 518 T get(); 519 520 /** set the value in the data pointer to v. */ 521 template <typename T> 522 void set(T v); 523 524 /** 525 * Copy data into the packet from the provided pointer. 526 */ 527 void setData(uint8_t *p) 528 { 529 std::memcpy(getPtr<uint8_t>(), p, getSize()); 530 } 531 532 /** 533 * Copy data into the packet from the provided block pointer, 534 * which is aligned to the given block size. 535 */ 536 void setDataFromBlock(uint8_t *blk_data, int blkSize) 537 { 538 setData(blk_data + getOffset(blkSize)); 539 } 540 541 /** 542 * Copy data from the packet to the provided block pointer, which 543 * is aligned to the given block size. 544 */ 545 void writeData(uint8_t *p) 546 { 547 std::memcpy(p, getPtr<uint8_t>(), getSize()); 548 } 549 550 /** 551 * Copy data from the packet to the memory at the provided pointer. 552 */ 553 void writeDataToBlock(uint8_t *blk_data, int blkSize) 554 { 555 writeData(blk_data + getOffset(blkSize)); 556 } 557 558 /** 559 * delete the data pointed to in the data pointer. Ok to call to 560 * matter how data was allocted. 561 */ 562 void deleteData(); 563 564 /** If there isn't data in the packet, allocate some. */ 565 void allocate(); 566 567 /** Do the packet modify the same addresses. */ 568 bool intersect(PacketPtr p); 569 570 /** 571 * Check a functional request against a memory value represented 572 * by a base/size pair and an associated data array. If the 573 * functional request is a read, it may be satisfied by the memory 574 * value. If the functional request is a write, it may update the 575 * memory value. 576 */ 577 bool checkFunctional(Addr base, int size, uint8_t *data); 578 579 /** 580 * Check a functional request against a memory value stored in 581 * another packet (i.e. an in-transit request or response). 582 */ 583 bool checkFunctional(PacketPtr otherPkt) { 584 return (otherPkt->hasData() && 585 checkFunctional(otherPkt->getAddr(), otherPkt->getSize(), 586 otherPkt->getPtr<uint8_t>())); 587 } 588}; 589 590std::ostream & operator<<(std::ostream &o, const Packet &p); 591 592#endif //__MEM_PACKET_HH 593