packet.hh revision 11600
1/*
2 * Copyright (c) 2012-2016 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2006 The Regents of The University of Michigan
15 * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Ron Dreslinski
42 *          Steve Reinhardt
43 *          Ali Saidi
44 *          Andreas Hansson
45 */
46
47/**
48 * @file
49 * Declaration of the Packet class.
50 */
51
52#ifndef __MEM_PACKET_HH__
53#define __MEM_PACKET_HH__
54
55#include <bitset>
56#include <cassert>
57#include <list>
58
59#include "base/cast.hh"
60#include "base/compiler.hh"
61#include "base/flags.hh"
62#include "base/misc.hh"
63#include "base/printable.hh"
64#include "base/types.hh"
65#include "mem/request.hh"
66#include "sim/core.hh"
67
68class Packet;
69typedef Packet *PacketPtr;
70typedef uint8_t* PacketDataPtr;
71typedef std::list<PacketPtr> PacketList;
72
73class MemCmd
74{
75    friend class Packet;
76
77  public:
78    /**
79     * List of all commands associated with a packet.
80     */
81    enum Command
82    {
83        InvalidCmd,
84        ReadReq,
85        ReadResp,
86        ReadRespWithInvalidate,
87        WriteReq,
88        WriteResp,
89        WritebackDirty,
90        WritebackClean,
91        CleanEvict,
92        SoftPFReq,
93        HardPFReq,
94        SoftPFResp,
95        HardPFResp,
96        WriteLineReq,
97        UpgradeReq,
98        SCUpgradeReq,           // Special "weak" upgrade for StoreCond
99        UpgradeResp,
100        SCUpgradeFailReq,       // Failed SCUpgradeReq in MSHR (never sent)
101        UpgradeFailResp,        // Valid for SCUpgradeReq only
102        ReadExReq,
103        ReadExResp,
104        ReadCleanReq,
105        ReadSharedReq,
106        LoadLockedReq,
107        StoreCondReq,
108        StoreCondFailReq,       // Failed StoreCondReq in MSHR (never sent)
109        StoreCondResp,
110        SwapReq,
111        SwapResp,
112        MessageReq,
113        MessageResp,
114        MemFenceReq,
115        MemFenceResp,
116        // Error responses
117        // @TODO these should be classified as responses rather than
118        // requests; coding them as requests initially for backwards
119        // compatibility
120        InvalidDestError,  // packet dest field invalid
121        BadAddressError,   // memory address invalid
122        FunctionalReadError, // unable to fulfill functional read
123        FunctionalWriteError, // unable to fulfill functional write
124        // Fake simulator-only commands
125        PrintReq,       // Print state matching address
126        FlushReq,      //request for a cache flush
127        InvalidateReq,   // request for address to be invalidated
128        InvalidateResp,
129        NUM_MEM_CMDS
130    };
131
132  private:
133    /**
134     * List of command attributes.
135     */
136    enum Attribute
137    {
138        IsRead,         //!< Data flows from responder to requester
139        IsWrite,        //!< Data flows from requester to responder
140        IsUpgrade,
141        IsInvalidate,
142        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        flags.set(RESPONDER_HAD_WRITABLE);
616    }
617    bool responderHadWritable() const
618    { return flags.isSet(RESPONDER_HAD_WRITABLE); }
619
620    void setSuppressFuncError()     { flags.set(SUPPRESS_FUNC_ERROR); }
621    bool suppressFuncError() const  { return flags.isSet(SUPPRESS_FUNC_ERROR); }
622    void setBlockCached()          { flags.set(BLOCK_CACHED); }
623    bool isBlockCached() const     { return flags.isSet(BLOCK_CACHED); }
624    void clearBlockCached()        { flags.clear(BLOCK_CACHED); }
625
626    // Network error conditions... encapsulate them as methods since
627    // their encoding keeps changing (from result field to command
628    // field, etc.)
629    void
630    setBadAddress()
631    {
632        assert(isResponse());
633        cmd = MemCmd::BadAddressError;
634    }
635
636    void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
637
638    Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
639    /**
640     * Update the address of this packet mid-transaction. This is used
641     * by the address mapper to change an already set address to a new
642     * one based on the system configuration. It is intended to remap
643     * an existing address, so it asserts that the current address is
644     * valid.
645     */
646    void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
647
648    unsigned getSize() const  { assert(flags.isSet(VALID_SIZE)); return size; }
649
650    Addr getOffset(unsigned int blk_size) const
651    {
652        return getAddr() & Addr(blk_size - 1);
653    }
654
655    Addr getBlockAddr(unsigned int blk_size) const
656    {
657        return getAddr() & ~(Addr(blk_size - 1));
658    }
659
660    bool isSecure() const
661    {
662        assert(flags.isSet(VALID_ADDR));
663        return _isSecure;
664    }
665
666    /**
667     * Accessor function to atomic op.
668     */
669    AtomicOpFunctor *getAtomicOp() const { return req->getAtomicOpFunctor(); }
670    bool isAtomicOp() const { return req->isAtomic(); }
671
672    /**
673     * It has been determined that the SC packet should successfully update
674     * memory. Therefore, convert this SC packet to a normal write.
675     */
676    void
677    convertScToWrite()
678    {
679        assert(isLLSC());
680        assert(isWrite());
681        cmd = MemCmd::WriteReq;
682    }
683
684    /**
685     * When ruby is in use, Ruby will monitor the cache line and the
686     * phys memory should treat LL ops as normal reads.
687     */
688    void
689    convertLlToRead()
690    {
691        assert(isLLSC());
692        assert(isRead());
693        cmd = MemCmd::ReadReq;
694    }
695
696    /**
697     * Constructor. Note that a Request object must be constructed
698     * first, but the Requests's physical address and size fields need
699     * not be valid. The command must be supplied.
700     */
701    Packet(const RequestPtr _req, MemCmd _cmd)
702        :  cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
703           size(0), headerDelay(0), snoopDelay(0), payloadDelay(0),
704           senderState(NULL)
705    {
706        if (req->hasPaddr()) {
707            addr = req->getPaddr();
708            flags.set(VALID_ADDR);
709            _isSecure = req->isSecure();
710        }
711        if (req->hasSize()) {
712            size = req->getSize();
713            flags.set(VALID_SIZE);
714        }
715    }
716
717    /**
718     * Alternate constructor if you are trying to create a packet with
719     * a request that is for a whole block, not the address from the
720     * req.  this allows for overriding the size/addr of the req.
721     */
722    Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize)
723        :  cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
724           headerDelay(0), snoopDelay(0), payloadDelay(0),
725           senderState(NULL)
726    {
727        if (req->hasPaddr()) {
728            addr = req->getPaddr() & ~(_blkSize - 1);
729            flags.set(VALID_ADDR);
730            _isSecure = req->isSecure();
731        }
732        size = _blkSize;
733        flags.set(VALID_SIZE);
734    }
735
736    /**
737     * Alternate constructor for copying a packet.  Copy all fields
738     * *except* if the original packet's data was dynamic, don't copy
739     * that, as we can't guarantee that the new packet's lifetime is
740     * less than that of the original packet.  In this case the new
741     * packet should allocate its own data.
742     */
743    Packet(const PacketPtr pkt, bool clear_flags, bool alloc_data)
744        :  cmd(pkt->cmd), req(pkt->req),
745           data(nullptr),
746           addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
747           bytesValid(pkt->bytesValid),
748           headerDelay(pkt->headerDelay),
749           snoopDelay(0),
750           payloadDelay(pkt->payloadDelay),
751           senderState(pkt->senderState)
752    {
753        if (!clear_flags)
754            flags.set(pkt->flags & COPY_FLAGS);
755
756        flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
757
758        // should we allocate space for data, or not, the express
759        // snoops do not need to carry any data as they only serve to
760        // co-ordinate state changes
761        if (alloc_data) {
762            // even if asked to allocate data, if the original packet
763            // holds static data, then the sender will not be doing
764            // any memcpy on receiving the response, thus we simply
765            // carry the pointer forward
766            if (pkt->flags.isSet(STATIC_DATA)) {
767                data = pkt->data;
768                flags.set(STATIC_DATA);
769            } else {
770                allocate();
771            }
772        }
773    }
774
775    /**
776     * Generate the appropriate read MemCmd based on the Request flags.
777     */
778    static MemCmd
779    makeReadCmd(const RequestPtr req)
780    {
781        if (req->isLLSC())
782            return MemCmd::LoadLockedReq;
783        else if (req->isPrefetch())
784            return MemCmd::SoftPFReq;
785        else
786            return MemCmd::ReadReq;
787    }
788
789    /**
790     * Generate the appropriate write MemCmd based on the Request flags.
791     */
792    static MemCmd
793    makeWriteCmd(const RequestPtr req)
794    {
795        if (req->isLLSC())
796            return MemCmd::StoreCondReq;
797        else if (req->isSwap())
798            return MemCmd::SwapReq;
799        else
800            return MemCmd::WriteReq;
801    }
802
803    /**
804     * Constructor-like methods that return Packets based on Request objects.
805     * Fine-tune the MemCmd type if it's not a vanilla read or write.
806     */
807    static PacketPtr
808    createRead(const RequestPtr req)
809    {
810        return new Packet(req, makeReadCmd(req));
811    }
812
813    static PacketPtr
814    createWrite(const RequestPtr req)
815    {
816        return new Packet(req, makeWriteCmd(req));
817    }
818
819    /**
820     * clean up packet variables
821     */
822    ~Packet()
823    {
824        // Delete the request object if this is a request packet which
825        // does not need a response, because the requester will not get
826        // a chance. If the request packet needs a response then the
827        // request will be deleted on receipt of the response
828        // packet. We also make sure to never delete the request for
829        // express snoops, even for cases when responses are not
830        // needed (CleanEvict and Writeback), since the snoop packet
831        // re-uses the same request.
832        if (req && isRequest() && !needsResponse() &&
833            !isExpressSnoop()) {
834            delete req;
835        }
836        deleteData();
837    }
838
839    /**
840     * Take a request packet and modify it in place to be suitable for
841     * returning as a response to that request.
842     */
843    void
844    makeResponse()
845    {
846        assert(needsResponse());
847        assert(isRequest());
848        cmd = cmd.responseCommand();
849
850        // responses are never express, even if the snoop that
851        // triggered them was
852        flags.clear(EXPRESS_SNOOP);
853    }
854
855    void
856    makeAtomicResponse()
857    {
858        makeResponse();
859    }
860
861    void
862    makeTimingResponse()
863    {
864        makeResponse();
865    }
866
867    void
868    setFunctionalResponseStatus(bool success)
869    {
870        if (!success) {
871            if (isWrite()) {
872                cmd = MemCmd::FunctionalWriteError;
873            } else {
874                cmd = MemCmd::FunctionalReadError;
875            }
876        }
877    }
878
879    void
880    setSize(unsigned size)
881    {
882        assert(!flags.isSet(VALID_SIZE));
883
884        this->size = size;
885        flags.set(VALID_SIZE);
886    }
887
888
889  public:
890    /**
891     * @{
892     * @name Data accessor mehtods
893     */
894
895    /**
896     * Set the data pointer to the following value that should not be
897     * freed. Static data allows us to do a single memcpy even if
898     * multiple packets are required to get from source to destination
899     * and back. In essence the pointer is set calling dataStatic on
900     * the original packet, and whenever this packet is copied and
901     * forwarded the same pointer is passed on. When a packet
902     * eventually reaches the destination holding the data, it is
903     * copied once into the location originally set. On the way back
904     * to the source, no copies are necessary.
905     */
906    template <typename T>
907    void
908    dataStatic(T *p)
909    {
910        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
911        data = (PacketDataPtr)p;
912        flags.set(STATIC_DATA);
913    }
914
915    /**
916     * Set the data pointer to the following value that should not be
917     * freed. This version of the function allows the pointer passed
918     * to us to be const. To avoid issues down the line we cast the
919     * constness away, the alternative would be to keep both a const
920     * and non-const data pointer and cleverly choose between
921     * them. Note that this is only allowed for static data.
922     */
923    template <typename T>
924    void
925    dataStaticConst(const T *p)
926    {
927        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
928        data = const_cast<PacketDataPtr>(p);
929        flags.set(STATIC_DATA);
930    }
931
932    /**
933     * Set the data pointer to a value that should have delete []
934     * called on it. Dynamic data is local to this packet, and as the
935     * packet travels from source to destination, forwarded packets
936     * will allocate their own data. When a packet reaches the final
937     * destination it will populate the dynamic data of that specific
938     * packet, and on the way back towards the source, memcpy will be
939     * invoked in every step where a new packet was created e.g. in
940     * the caches. Ultimately when the response reaches the source a
941     * final memcpy is needed to extract the data from the packet
942     * before it is deallocated.
943     */
944    template <typename T>
945    void
946    dataDynamic(T *p)
947    {
948        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
949        data = (PacketDataPtr)p;
950        flags.set(DYNAMIC_DATA);
951    }
952
953    /**
954     * get a pointer to the data ptr.
955     */
956    template <typename T>
957    T*
958    getPtr()
959    {
960        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
961        return (T*)data;
962    }
963
964    template <typename T>
965    const T*
966    getConstPtr() const
967    {
968        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
969        return (const T*)data;
970    }
971
972    /**
973     * Get the data in the packet byte swapped from big endian to
974     * host endian.
975     */
976    template <typename T>
977    T getBE() const;
978
979    /**
980     * Get the data in the packet byte swapped from little endian to
981     * host endian.
982     */
983    template <typename T>
984    T getLE() const;
985
986    /**
987     * Get the data in the packet byte swapped from the specified
988     * endianness.
989     */
990    template <typename T>
991    T get(ByteOrder endian) const;
992
993    /**
994     * Get the data in the packet byte swapped from guest to host
995     * endian.
996     */
997    template <typename T>
998    T get() const;
999
1000    /** Set the value in the data pointer to v as big endian. */
1001    template <typename T>
1002    void setBE(T v);
1003
1004    /** Set the value in the data pointer to v as little endian. */
1005    template <typename T>
1006    void setLE(T v);
1007
1008    /**
1009     * Set the value in the data pointer to v using the specified
1010     * endianness.
1011     */
1012    template <typename T>
1013    void set(T v, ByteOrder endian);
1014
1015    /** Set the value in the data pointer to v as guest endian. */
1016    template <typename T>
1017    void set(T v);
1018
1019    /**
1020     * Copy data into the packet from the provided pointer.
1021     */
1022    void
1023    setData(const uint8_t *p)
1024    {
1025        // we should never be copying data onto itself, which means we
1026        // must idenfity packets with static data, as they carry the
1027        // same pointer from source to destination and back
1028        assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA));
1029
1030        if (p != getPtr<uint8_t>())
1031            // for packet with allocated dynamic data, we copy data from
1032            // one to the other, e.g. a forwarded response to a response
1033            std::memcpy(getPtr<uint8_t>(), p, getSize());
1034    }
1035
1036    /**
1037     * Copy data into the packet from the provided block pointer,
1038     * which is aligned to the given block size.
1039     */
1040    void
1041    setDataFromBlock(const uint8_t *blk_data, int blkSize)
1042    {
1043        setData(blk_data + getOffset(blkSize));
1044    }
1045
1046    /**
1047     * Copy data from the packet to the provided block pointer, which
1048     * is aligned to the given block size.
1049     */
1050    void
1051    writeData(uint8_t *p) const
1052    {
1053        std::memcpy(p, getConstPtr<uint8_t>(), getSize());
1054    }
1055
1056    /**
1057     * Copy data from the packet to the memory at the provided pointer.
1058     */
1059    void
1060    writeDataToBlock(uint8_t *blk_data, int blkSize) const
1061    {
1062        writeData(blk_data + getOffset(blkSize));
1063    }
1064
1065    /**
1066     * delete the data pointed to in the data pointer. Ok to call to
1067     * matter how data was allocted.
1068     */
1069    void
1070    deleteData()
1071    {
1072        if (flags.isSet(DYNAMIC_DATA))
1073            delete [] data;
1074
1075        flags.clear(STATIC_DATA|DYNAMIC_DATA);
1076        data = NULL;
1077    }
1078
1079    /** Allocate memory for the packet. */
1080    void
1081    allocate()
1082    {
1083        // if either this command or the response command has a data
1084        // payload, actually allocate space
1085        if (hasData() || hasRespData()) {
1086            assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
1087            flags.set(DYNAMIC_DATA);
1088            data = new uint8_t[getSize()];
1089        }
1090    }
1091
1092    /** @} */
1093
1094  private: // Private data accessor methods
1095    /** Get the data in the packet without byte swapping. */
1096    template <typename T>
1097    T getRaw() const;
1098
1099    /** Set the value in the data pointer to v without byte swapping. */
1100    template <typename T>
1101    void setRaw(T v);
1102
1103  public:
1104    /**
1105     * Check a functional request against a memory value stored in
1106     * another packet (i.e. an in-transit request or
1107     * response). Returns true if the current packet is a read, and
1108     * the other packet provides the data, which is then copied to the
1109     * current packet. If the current packet is a write, and the other
1110     * packet intersects this one, then we update the data
1111     * accordingly.
1112     */
1113    bool
1114    checkFunctional(PacketPtr other)
1115    {
1116        // all packets that are carrying a payload should have a valid
1117        // data pointer
1118        return checkFunctional(other, other->getAddr(), other->isSecure(),
1119                               other->getSize(),
1120                               other->hasData() ?
1121                               other->getPtr<uint8_t>() : NULL);
1122    }
1123
1124    /**
1125     * Does the request need to check for cached copies of the same block
1126     * in the memory hierarchy above.
1127     **/
1128    bool
1129    mustCheckAbove() const
1130    {
1131        return cmd == MemCmd::HardPFReq || isEviction();
1132    }
1133
1134    /**
1135     * Is this packet a clean eviction, including both actual clean
1136     * evict packets, but also clean writebacks.
1137     */
1138    bool
1139    isCleanEviction() const
1140    {
1141        return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
1142    }
1143
1144    /**
1145     * Check a functional request against a memory value represented
1146     * by a base/size pair and an associated data array. If the
1147     * current packet is a read, it may be satisfied by the memory
1148     * value. If the current packet is a write, it may update the
1149     * memory value.
1150     */
1151    bool
1152    checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
1153                    uint8_t *_data);
1154
1155    /**
1156     * Push label for PrintReq (safe to call unconditionally).
1157     */
1158    void
1159    pushLabel(const std::string &lbl)
1160    {
1161        if (isPrint())
1162            safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
1163    }
1164
1165    /**
1166     * Pop label for PrintReq (safe to call unconditionally).
1167     */
1168    void
1169    popLabel()
1170    {
1171        if (isPrint())
1172            safe_cast<PrintReqState*>(senderState)->popLabel();
1173    }
1174
1175    void print(std::ostream &o, int verbosity = 0,
1176               const std::string &prefix = "") const;
1177
1178    /**
1179     * A no-args wrapper of print(std::ostream...)
1180     * meant to be invoked from DPRINTFs
1181     * avoiding string overheads in fast mode
1182     * @return string with the request's type and start<->end addresses
1183     */
1184    std::string print() const;
1185};
1186
1187#endif //__MEM_PACKET_HH
1188