packet.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 666 行 · 第 1/2 页

HH
666
字号
         * prefix string onto the current prefix.  Labels will only be         * printed if an object within the label's scope is         * printed. */        void pushLabel(const std::string &lbl,                       const std::string &prefix = "  ");        /** Pop a label off the label stack. */        void popLabel();        /** Print all of the pending unprinted labels on the         * stack. Called by printObj(), so normally not called by         * users unless bypassing printObj(). */        void printLabels();        /** Print a Printable object to os, because it matched the         * address on a PrintReq. */        void printObj(Printable *obj);    };    /** This packet's sender state.  Devices should use dynamic_cast<>     *   to cast to the state appropriate to the sender. */    SenderState *senderState;    /** Return the string name of the cmd field (for debugging and     *   tracing). */    const std::string &cmdString() const { return cmd.toString(); }    /** Return the index of this command. */    inline int cmdToIndex() const { return cmd.toInt(); }    bool isRead() const         { return cmd.isRead(); }    bool isWrite()  const       { return cmd.isWrite(); }    bool isRequest() const      { return cmd.isRequest(); }    bool isResponse() const     { return cmd.isResponse(); }    bool needsExclusive() const { return cmd.needsExclusive(); }    bool needsResponse() const  { return cmd.needsResponse(); }    bool isInvalidate() const   { return cmd.isInvalidate(); }    bool hasData() const        { return cmd.hasData(); }    bool isReadWrite() const    { return cmd.isReadWrite(); }    bool isLocked() const       { return cmd.isLocked(); }    bool isError() const        { return cmd.isError(); }    bool isPrint() const        { return cmd.isPrint(); }    // Snoop flags    void assertMemInhibit()     { flags[MemInhibit] = true; }    bool memInhibitAsserted()   { return flags[MemInhibit]; }    void assertShared()         { flags[Shared] = true; }    bool sharedAsserted()       { return flags[Shared]; }    // Special control flags    void setExpressSnoop()      { flags[ExpressSnoop] = true; }    bool isExpressSnoop()       { return flags[ExpressSnoop]; }    void setSupplyExclusive()   { flags[SupplyExclusive] = true; }    bool isSupplyExclusive()    { return flags[SupplyExclusive]; }    // Network error conditions... encapsulate them as methods since    // their encoding keeps changing (from result field to command    // field, etc.)    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; }    bool nic_pkt() { panic("Unimplemented"); M5_DUMMY_RETURN }    /** 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; }    /** 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; }    Addr getAddr() const { assert(addrSizeValid); return addr; }    int getSize() const  { assert(addrSizeValid); return size; }    Addr getOffset(int blkSize) const { return addr & (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, 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)    {    }    /** 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),           addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize), dest(_dest),           addrSizeValid(_req->validPaddr), srcValid(false), destValid(true),           flags(0), time(curTick), senderState(NULL)    {    }    /** Alternate constructor for copying a packet.  Copy all fields     * *except* if the original packet's data was dynamic, don't copy     * that, as we can't guarantee that the new packet's lifetime is     * less than that of the original packet.  In this case the new     * 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)    {    }    /** Destructor. */    ~Packet()    { if (staticData || dynamicData) deleteData(); }    /** 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);        flags = 0;        addr = req->paddr;        size = req->size;        time = req->time;        addrSizeValid = true;        if (dynamicData) {            deleteData();            dynamicData = false;            arrayData = false;        }    }    /**     * Take a request packet and modify it in place to be suitable for     * returning as a response to that request.  The source and     * destination fields are *not* modified, as is appropriate for     * atomic accesses.     */    void makeResponse()    {        assert(needsResponse());        assert(isRequest());        origCmd = cmd;        cmd = cmd.responseCommand();        dest = src;        destValid = srcValid;        srcValid = false;    }    void makeAtomicResponse()    {        makeResponse();    }    void makeTimingResponse()    {        makeResponse();    }    /**     * Take a request packet that has been returned as NACKED and     * modify it so that it can be sent out again. Only packets that     * need a response can be NACKED, so verify that that is true.     */    void    reinitNacked()    {        assert(wasNacked());        cmd = origCmd;        assert(needsResponse());        setDest(Broadcast);    }    /**     * Set the data pointer to the following value that should not be     * freed.     */    template <typename T>    void    dataStatic(T *p)    {        if(dynamicData)            dynamicData = false;        data = (PacketDataPtr)p;        staticData = true;    }    /**     * Set the data pointer to a value that should have delete []     * called on it.     */    template <typename T>    void    dataDynamicArray(T *p)    {        assert(!staticData && !dynamicData);        data = (PacketDataPtr)p;        dynamicData = true;        arrayData = true;    }    /**     * set the data pointer to a value that should have delete called     * on it.     */    template <typename T>    void    dataDynamic(T *p)    {        assert(!staticData && !dynamicData);        data = (PacketDataPtr)p;        dynamicData = true;        arrayData = false;    }    /** get a pointer to the data ptr. */    template <typename T>    T*    getPtr()    {        assert(staticData || dynamicData);        return (T*)data;    }    /** return the value of what is pointed to in the packet. */    template <typename T>    T get();    /** set the value in the data pointer to v. */    template <typename T>    void set(T v);    /**     * Copy data into the packet from the provided pointer.     */    void setData(uint8_t *p)    {        std::memcpy(getPtr<uint8_t>(), p, getSize());    }    /**     * Copy data into the packet from the provided block pointer,     * which is aligned to the given block size.     */    void setDataFromBlock(uint8_t *blk_data, int blkSize)    {        setData(blk_data + getOffset(blkSize));    }    /**     * Copy data from the packet to the provided block pointer, which     * is aligned to the given block size.     */    void writeData(uint8_t *p)    {        std::memcpy(p, getPtr<uint8_t>(), getSize());    }    /**     * Copy data from the packet to the memory at the provided pointer.     */    void writeDataToBlock(uint8_t *blk_data, int blkSize)    {        writeData(blk_data + getOffset(blkSize));    }    /**     * delete the data pointed to in the data pointer. Ok to call to     * matter how data was allocted.     */    void deleteData();    /** If there isn't data in the packet, allocate some. */    void allocate();    /**     * Check a functional request against a memory value represented     * by a base/size pair and an associated data array.  If the     * functional request is a read, it may be satisfied by the memory     * value.  If the functional request is a write, it may update the     * memory value.     */    bool checkFunctional(Printable *obj, Addr base, int size, uint8_t *data);    /**     * Check a functional request against a memory value stored in     * another packet (i.e. an in-transit request or response).     */    bool checkFunctional(PacketPtr otherPkt) {        return checkFunctional(otherPkt,                               otherPkt->getAddr(), otherPkt->getSize(),                               otherPkt->hasData() ?                                   otherPkt->getPtr<uint8_t>() : NULL);    }    /**     * Push label for PrintReq (safe to call unconditionally).     */    void pushLabel(const std::string &lbl) {        if (isPrint()) {            dynamic_cast<PrintReqState*>(senderState)->pushLabel(lbl);        }    }    /**     * Pop label for PrintReq (safe to call unconditionally).     */    void popLabel() {        if (isPrint()) {            dynamic_cast<PrintReqState*>(senderState)->popLabel();        }    }    void print(std::ostream &o, int verbosity = 0,               const std::string &prefix = "") const;};#endif //__MEM_PACKET_HH

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?