44a45
> #include "base/cast.hh"
46a48
> #include "base/flags.hh"
61c63
< public:
---
> friend class Packet;
63c65,68
< /** List of all commands associated with a packet. */
---
> public:
> /**
> * List of all commands associated with a packet.
> */
103c108,110
< /** List of command attributes. */
---
> /**
> * List of command attributes.
> */
123,126c130,136
< /** Structure that defines attributes and other data associated
< * with a Command. */
< struct CommandInfo {
< /** Set of attribute flags. */
---
> /**
> * Structure that defines attributes and other data associated
> * with a Command.
> */
> struct CommandInfo
> {
> /// Set of attribute flags.
128,129c138,139
< /** Corresponding response for requests; InvalidCmd if no
< * response is applicable. */
---
> /// Corresponding response for requests; InvalidCmd if no
> /// response is applicable.
131c141
< /** String representation (for printing) */
---
> /// String representation (for printing)
135c145
< /** Array to map Command enum to associated info. */
---
> /// Array to map Command enum to associated info.
142c152,154
< bool testCmdAttrib(MemCmd::Attribute attrib) const {
---
> bool
> testCmdAttrib(MemCmd::Attribute attrib) const
> {
161c173,175
< const Command responseCommand() const {
---
> const Command
> responseCommand() const
> {
165,169c179,180
< /** Return the string to a cmd given by idx. */
< const std::string &toString() const {
< return commandInfo[cmd].str;
< }
<
---
> /// Return the string to a cmd given by idx.
> const std::string &toString() const { return commandInfo[cmd].str; }
172,174c183,185
< MemCmd(Command _cmd)
< : cmd(_cmd)
< { }
---
> MemCmd(Command _cmd) : cmd(_cmd) { }
> MemCmd(int _cmd) : cmd((Command)_cmd) { }
> MemCmd() : cmd(InvalidCmd) { }
176,187c187,188
< MemCmd(int _cmd)
< : cmd((Command)_cmd)
< { }
<
< MemCmd()
< : cmd(InvalidCmd)
< { }
<
< bool operator==(MemCmd c2) { return (cmd == c2.cmd); }
< bool operator!=(MemCmd c2) { return (cmd != c2.cmd); }
<
< friend class Packet;
---
> bool operator==(MemCmd c2) const { return (cmd == c2.cmd); }
> bool operator!=(MemCmd c2) const { return (cmd != c2.cmd); }
199a201,203
> typedef uint32_t FlagsType;
> typedef ::Flags<FlagsType> Flags;
> typedef short NodeID;
200a205,237
> private:
> static const FlagsType PUBLIC_FLAGS = 0x00000000;
> static const FlagsType PRIVATE_FLAGS = 0x00007F0F;
> static const FlagsType COPY_FLAGS = 0x0000000F;
>
> static const FlagsType SHARED = 0x00000001;
> // Special control flags
> /// Special timing-mode atomic snoop for multi-level coherence.
> static const FlagsType EXPRESS_SNOOP = 0x00000002;
> /// Does supplier have exclusive copy?
> /// Useful for multi-level coherence.
> static const FlagsType SUPPLY_EXCLUSIVE = 0x00000004;
> // Snoop response flags
> static const FlagsType MEM_INHIBIT = 0x00000008;
> /// Are the 'addr' and 'size' fields valid?
> static const FlagsType VALID_ADDR = 0x00000100;
> static const FlagsType VALID_SIZE = 0x00000200;
> /// Is the 'src' field valid?
> static const FlagsType VALID_SRC = 0x00000400;
> static const FlagsType VALID_DST = 0x00000800;
> /// Is the data pointer set to a value that shouldn't be freed
> /// when the packet is destroyed?
> static const FlagsType STATIC_DATA = 0x00001000;
> /// The data pointer points to a value that should be freed when
> /// the packet is destroyed.
> static const FlagsType DYNAMIC_DATA = 0x00002000;
> /// the data pointer points to an array (thus delete []) needs to
> /// be called on it rather than simply delete.
> static const FlagsType ARRAY_DATA = 0x00004000;
>
> Flags flags;
>
> public:
203c240
< /** The command field of the packet. */
---
> /// The command field of the packet.
206c243
< /** A pointer to the original request. */
---
> /// A pointer to the original request.
210,214c247,252
< /** A pointer to the data being transfered. It can be differnt
< * sizes at each level of the heirarchy so it belongs in the
< * packet, not request. This may or may not be populated when a
< * responder recieves the packet. If not populated it memory
< * should be allocated.
---
> /**
> * A pointer to the data being transfered. It can be differnt
> * sizes at each level of the heirarchy so it belongs in the
> * packet, not request. This may or may not be populated when a
> * responder recieves the packet. If not populated it memory should
> * be allocated.
218,229c256,257
< /** Is the data pointer set to a value that shouldn't be freed
< * when the packet is destroyed? */
< bool staticData;
< /** The data pointer points to a value that should be freed when
< * the packet is destroyed. */
< bool dynamicData;
< /** the data pointer points to an array (thus delete [] ) needs to
< * be called on it rather than simply delete.*/
< bool arrayData;
<
< /** The address of the request. This address could be virtual or
< * physical, depending on the system configuration. */
---
> /// The address of the request. This address could be virtual or
> /// physical, depending on the system configuration.
232c260
< /** The size of the request or transfer. */
---
> /// The size of the request or transfer.
235,239c263,269
< /** Device address (e.g., bus ID) of the source of the
< * transaction. The source is not responsible for setting this
< * field; it is set implicitly by the interconnect when the
< * packet is first sent. */
< short src;
---
> /**
> * Device address (e.g., bus ID) of the source of the
> * transaction. The source is not responsible for setting this
> * field; it is set implicitly by the interconnect when the packet
> * is first sent.
> */
> NodeID src;
241,246c271,278
< /** Device address (e.g., bus ID) of the destination of the
< * transaction. The special value Broadcast indicates that the
< * packet should be routed based on its address. This field is
< * initialized in the constructor and is thus always valid
< * (unlike * addr, size, and src). */
< short dest;
---
> /**
> * Device address (e.g., bus ID) of the destination of the
> * transaction. The special value Broadcast indicates that the
> * packet should be routed based on its address. This field is
> * initialized in the constructor and is thus always valid (unlike
> * addr, size, and src).
> */
> NodeID dest;
248c280,281
< /** The original value of the command field. Only valid when the
---
> /**
> * The original value of the command field. Only valid when the
255,276d287
< /** Are the 'addr' and 'size' fields valid? */
< bool addrSizeValid;
< /** Is the 'src' field valid? */
< bool srcValid;
< bool destValid;
<
< enum Flag {
< // Snoop response flags
< MemInhibit,
< Shared,
< // Special control flags
< /// Special timing-mode atomic snoop for multi-level coherence.
< ExpressSnoop,
< /// Does supplier have exclusive copy?
< /// Useful for multi-level coherence.
< SupplyExclusive,
< NUM_PACKET_FLAGS
< };
<
< /** Status flags */
< std::bitset<NUM_PACKET_FLAGS> flags;
<
278,279c289
<
< /** Used to calculate latencies for each packet.*/
---
> /// Used to calculate latencies for each packet.
282c292
< /** The time at which the packet will be fully transmitted */
---
> /// The time at which the packet will be fully transmitted
285c295
< /** The time at which the first chunk of the packet will be transmitted */
---
> /// The time at which the first chunk of the packet will be transmitted
288,290c298,300
< /** The special destination address indicating that the packet
< * should be routed based on its address. */
< static const short Broadcast = -1;
---
> /// The special destination address indicating that the packet
> /// should be routed based on its address.
> static const NodeID Broadcast = -1;
292,300c302,312
< /** A virtual base opaque structure used to hold state associated
< * with the packet but specific to the sending device (e.g., an
< * MSHR). A pointer to this state is returned in the packet's
< * response so that the sender can quickly look up the state
< * needed to process it. A specific subclass would be derived
< * from this to carry state specific to a particular sending
< * device. */
< class SenderState {
< public:
---
> /**
> * A virtual base opaque structure used to hold state associated
> * with the packet but specific to the sending device (e.g., an
> * MSHR). A pointer to this state is returned in the packet's
> * response so that the sender can quickly look up the state
> * needed to process it. A specific subclass would be derived
> * from this to carry state specific to a particular sending
> * device.
> */
> struct SenderState
> {
308,311c320,327
< class PrintReqState : public SenderState, public FastAlloc {
< /** An entry in the label stack. */
< class LabelStackEntry {
< public:
---
> class PrintReqState : public SenderState, public FastAlloc
> {
> private:
> /**
> * An entry in the label stack.
> */
> struct LabelStackEntry
> {
315,316c331
< LabelStackEntry(const std::string &_label,
< std::string *_prefix);
---
> LabelStackEntry(const std::string &_label, std::string *_prefix);
331c346,348
< /** Returns the current line prefix. */
---
> /**
> * Returns the current line prefix.
> */
334c351,352
< /** Push a label onto the label stack, and prepend the given
---
> /**
> * Push a label onto the label stack, and prepend the given
336,337c354,355
< * printed if an object within the label's scope is
< * printed. */
---
> * printed if an object within the label's scope is printed.
> */
340c358,361
< /** Pop a label off the label stack. */
---
>
> /**
> * Pop a label off the label stack.
> */
342c363,365
< /** Print all of the pending unprinted labels on the
---
>
> /**
> * Print all of the pending unprinted labels on the
344c367,368
< * users unless bypassing printObj(). */
---
> * users unless bypassing printObj().
> */
346,347c370,374
< /** Print a Printable object to os, because it matched the
< * address on a PrintReq. */
---
>
> /**
> * Print a Printable object to os, because it matched the
> * address on a PrintReq.
> */
351,352c378,385
< /** This packet's sender state. Devices should use dynamic_cast<>
< * to cast to the state appropriate to the sender. */
---
> /**
> * This packet's sender state. Devices should use dynamic_cast<>
> * to cast to the state appropriate to the sender. The intent of
> * this variable is to allow a device to attach extra information
> * to a request. A response packet must return the sender state
> * that was attached to the original request (even if a new packet
> * is created).
> */
355,356c388,389
< /** Return the string name of the cmd field (for debugging and
< * tracing). */
---
> /// Return the string name of the cmd field (for debugging and
> /// tracing).
359c392
< /** Return the index of this command. */
---
> /// Return the index of this command.
376,379c409,412
< void assertMemInhibit() { flags[MemInhibit] = true; }
< bool memInhibitAsserted() { return flags[MemInhibit]; }
< void assertShared() { flags[Shared] = true; }
< bool sharedAsserted() { return flags[Shared]; }
---
> void assertMemInhibit() { flags.set(MEM_INHIBIT); }
> bool memInhibitAsserted() { return flags.any(MEM_INHIBIT); }
> void assertShared() { flags.set(SHARED); }
> bool sharedAsserted() { return flags.any(SHARED); }
382,385c415,418
< void setExpressSnoop() { flags[ExpressSnoop] = true; }
< bool isExpressSnoop() { return flags[ExpressSnoop]; }
< void setSupplyExclusive() { flags[SupplyExclusive] = true; }
< bool isSupplyExclusive() { return flags[SupplyExclusive]; }
---
> void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
> bool isExpressSnoop() { return flags.any(EXPRESS_SNOOP); }
> void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
> bool isSupplyExclusive() { return flags.any(SUPPLY_EXCLUSIVE); }
390,394c423,428
< void setNacked() { assert(isResponse()); cmd = MemCmd::NetworkNackError; }
< void setBadAddress() { assert(isResponse()); cmd = MemCmd::BadAddressError; }
< bool wasNacked() { return cmd == MemCmd::NetworkNackError; }
< bool hadBadAddress() { return cmd == MemCmd::BadAddressError; }
< void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
---
> void
> setNacked()
> {
> assert(isResponse());
> cmd = MemCmd::NetworkNackError;
> }
396c430,435
< bool nic_pkt() { panic("Unimplemented"); M5_DUMMY_RETURN }
---
> void
> setBadAddress()
> {
> assert(isResponse());
> cmd = MemCmd::BadAddressError;
> }
398,402c437,439
< /** Accessor function that returns the source index of the packet. */
< short getSrc() const { assert(srcValid); return src; }
< void setSrc(short _src) { src = _src; srcValid = true; }
< /** Reset source field, e.g. to retransmit packet on different bus. */
< void clearSrc() { srcValid = false; }
---
> bool wasNacked() const { return cmd == MemCmd::NetworkNackError; }
> bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; }
> void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
404,407c441,446
< /** Accessor function that returns the destination index of
< the packet. */
< short getDest() const { assert(destValid); return dest; }
< void setDest(short _dest) { dest = _dest; destValid = true; }
---
> /// Accessor function to get the source index of the packet.
> NodeID getSrc() const { assert(flags.any(VALID_SRC)); return src; }
> /// Accessor function to set the source index of the packet.
> void setSrc(NodeID _src) { src = _src; flags.set(VALID_SRC); }
> /// Reset source field, e.g. to retransmit packet on different bus.
> void clearSrc() { flags.clear(VALID_SRC); }
409,411c448,451
< Addr getAddr() const { assert(addrSizeValid); return addr; }
< int getSize() const { assert(addrSizeValid); return size; }
< Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); }
---
> /// Accessor function for the destination index of the packet.
> NodeID getDest() const { assert(flags.any(VALID_DST)); return dest; }
> /// Accessor function to set the destination index of the packet.
> void setDest(NodeID _dest) { dest = _dest; flags.set(VALID_DST); }
413,422c453,465
< /** Constructor. Note that a Request object must be constructed
< * first, but the Requests's physical address and size fields
< * need not be valid. The command and destination addresses
< * must be supplied. */
< Packet(Request *_req, MemCmd _cmd, short _dest)
< : cmd(_cmd), req(_req),
< data(NULL), staticData(false), dynamicData(false), arrayData(false),
< addr(_req->paddr), size(_req->size), dest(_dest),
< addrSizeValid(_req->validPaddr), srcValid(false), destValid(true),
< flags(0), time(curTick), senderState(NULL)
---
> Addr getAddr() const { assert(flags.all(VALID_ADDR)); return addr; }
> int getSize() const { assert(flags.all(VALID_SIZE)); return size; }
> Addr getOffset(int blkSize) const { return getAddr() & (Addr)(blkSize - 1); }
>
> /**
> * Constructor. Note that a Request object must be constructed
> * first, but the Requests's physical address and size fields need
> * not be valid. The command and destination addresses must be
> * supplied.
> */
> Packet(Request *_req, MemCmd _cmd, NodeID _dest)
> : cmd(_cmd), req(_req), data(NULL), addr(_req->paddr),
> size(_req->size), dest(_dest), time(curTick), senderState(NULL)
426,431c469,475
< /** Alternate constructor if you are trying to create a packet with
< * a request that is for a whole block, not the address from the req.
< * this allows for overriding the size/addr of the req.*/
< Packet(Request *_req, MemCmd _cmd, short _dest, int _blkSize)
< : cmd(_cmd), req(_req),
< data(NULL), staticData(false), dynamicData(false), arrayData(false),
---
> /**
> * Alternate constructor if you are trying to create a packet with
> * a request that is for a whole block, not the address from the
> * req. this allows for overriding the size/addr of the req.
> */
> Packet(Request *_req, MemCmd _cmd, NodeID _dest, int _blkSize)
> : cmd(_cmd), req(_req), data(NULL),
433,434c477
< addrSizeValid(_req->validPaddr), srcValid(false), destValid(true),
< flags(0), time(curTick), senderState(NULL)
---
> time(curTick), senderState(NULL)
438c481,482
< /** Alternate constructor for copying a packet. Copy all fields
---
> /**
> * Alternate constructor for copying a packet. Copy all fields
442,453c486,492
< * packet should allocate its own data. */
< Packet(Packet *origPkt, bool clearFlags = false)
< : cmd(origPkt->cmd), req(origPkt->req),
< data(origPkt->staticData ? origPkt->data : NULL),
< staticData(origPkt->staticData),
< dynamicData(false), arrayData(false),
< addr(origPkt->addr), size(origPkt->size),
< src(origPkt->src), dest(origPkt->dest),
< addrSizeValid(origPkt->addrSizeValid),
< srcValid(origPkt->srcValid), destValid(origPkt->destValid),
< flags(clearFlags ? 0 : origPkt->flags),
< time(curTick), senderState(origPkt->senderState)
---
> * packet should allocate its own data.
> */
> Packet(Packet *pkt, bool clearFlags = false)
> : cmd(pkt->cmd), req(pkt->req),
> data(pkt->flags.any(STATIC_DATA) ? pkt->data : NULL),
> addr(pkt->addr), size(pkt->size), src(pkt->src), dest(pkt->dest),
> time(curTick), senderState(pkt->senderState)
454a494,498
> if (!clearFlags)
> flags.set(pkt->flags & COPY_FLAGS);
>
> flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE|VALID_SRC|VALID_DST));
> flags.set(pkt->flags & STATIC_DATA);
457c501,503
< /** Destructor. */
---
> /**
> * clean up packet variables
> */
465,466c511
< if (staticData || dynamicData)
< deleteData();
---
> deleteData();
469,475c514,524
< /** Reinitialize packet address and size from the associated
< * Request object, and reset other fields that may have been
< * modified by a previous transaction. Typically called when a
< * statically allocated Request/Packet pair is reused for
< * multiple transactions. */
< void reinitFromRequest() {
< assert(req->validPaddr);
---
> /**
> * Reinitialize packet address and size from the associated
> * Request object, and reset other fields that may have been
> * modified by a previous transaction. Typically called when a
> * statically allocated Request/Packet pair is reused for multiple
> * transactions.
> */
> void
> reinitFromRequest()
> {
> assert(req->flags.any(Request::VALID_PADDR));
480,485c529,531
< addrSizeValid = true;
< if (dynamicData) {
< deleteData();
< dynamicData = false;
< arrayData = false;
< }
---
>
> flags.set(VALID_ADDR|VALID_SIZE);
> deleteData();
494c540,541
< void makeResponse()
---
> void
> makeResponse()
500,502c547,553
< dest = src;
< destValid = srcValid;
< srcValid = false;
---
> if (flags.any(VALID_SRC)) {
> dest = src;
> flags.set(VALID_DST);
> flags.clear(VALID_SRC);
> } else {
> flags.clear(VALID_DST);
> }
505c556,557
< void makeAtomicResponse()
---
> void
> makeAtomicResponse()
510c562,563
< void makeTimingResponse()
---
> void
> makeTimingResponse()
538,539c591
< if(dynamicData)
< dynamicData = false;
---
> assert(flags.none(STATIC_DATA|DYNAMIC_DATA|ARRAY_DATA));
541c593
< staticData = true;
---
> flags.set(STATIC_DATA);
552c604
< assert(!staticData && !dynamicData);
---
> assert(flags.none(STATIC_DATA|DYNAMIC_DATA|ARRAY_DATA));
554,555c606
< dynamicData = true;
< arrayData = true;
---
> flags.set(DYNAMIC_DATA|ARRAY_DATA);
566c617
< assert(!staticData && !dynamicData);
---
> assert(flags.none(STATIC_DATA|DYNAMIC_DATA|ARRAY_DATA));
568,569c619
< dynamicData = true;
< arrayData = false;
---
> flags.set(DYNAMIC_DATA);
572c622,624
< /** get a pointer to the data ptr. */
---
> /**
> * get a pointer to the data ptr.
> */
577c629
< assert(staticData || dynamicData);
---
> assert(flags.any(STATIC_DATA|DYNAMIC_DATA));
581c633,635
< /** return the value of what is pointed to in the packet. */
---
> /**
> * return the value of what is pointed to in the packet.
> */
585c639,641
< /** set the value in the data pointer to v. */
---
> /**
> * set the value in the data pointer to v.
> */
592c648,649
< void setData(uint8_t *p)
---
> void
> setData(uint8_t *p)
601c658,659
< void setDataFromBlock(uint8_t *blk_data, int blkSize)
---
> void
> setDataFromBlock(uint8_t *blk_data, int blkSize)
610c668,669
< void writeData(uint8_t *p)
---
> void
> writeData(uint8_t *p)
618c677,678
< void writeDataToBlock(uint8_t *blk_data, int blkSize)
---
> void
> writeDataToBlock(uint8_t *blk_data, int blkSize)
627c687,692
< void deleteData();
---
> void
> deleteData()
> {
> if (flags.any(ARRAY_DATA))
> delete [] data;
> else if (flags.any(DYNAMIC_DATA))
628a694,699
> delete data;
>
> flags.clear(STATIC_DATA|DYNAMIC_DATA|ARRAY_DATA);
> data = NULL;
> }
>
630c701,710
< void allocate();
---
> void
> allocate()
> {
> if (data) {
> assert(flags.none(STATIC_DATA|DYNAMIC_DATA));
> } else {
> flags.set(DYNAMIC_DATA|ARRAY_DATA);
> data = new uint8_t[getSize()];
> }
> }
631a712
>
645,649c726,731
< bool checkFunctional(PacketPtr otherPkt) {
< return checkFunctional(otherPkt,
< otherPkt->getAddr(), otherPkt->getSize(),
< otherPkt->hasData() ?
< otherPkt->getPtr<uint8_t>() : NULL);
---
> bool
> checkFunctional(PacketPtr other)
> {
> uint8_t *data = other->hasData() ? other->getPtr<uint8_t>() : NULL;
> return checkFunctional(other, other->getAddr(), other->getSize(),
> data);
655,658c737,741
< void pushLabel(const std::string &lbl) {
< if (isPrint()) {
< dynamic_cast<PrintReqState*>(senderState)->pushLabel(lbl);
< }
---
> void
> pushLabel(const std::string &lbl)
> {
> if (isPrint())
> safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
664,667c747,751
< void popLabel() {
< if (isPrint()) {
< dynamic_cast<PrintReqState*>(senderState)->popLabel();
< }
---
> void
> popLabel()
> {
> if (isPrint())
> safe_cast<PrintReqState*>(senderState)->popLabel();