packet.hh revision 12334
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/logging.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        assert(!responderHadWritable());
616        flags.set(RESPONDER_HAD_WRITABLE);
617    }
618    bool responderHadWritable() const
619    { return flags.isSet(RESPONDER_HAD_WRITABLE); }
620
621    void setSuppressFuncError()     { flags.set(SUPPRESS_FUNC_ERROR); }
622    bool suppressFuncError() const  { return flags.isSet(SUPPRESS_FUNC_ERROR); }
623    void setBlockCached()          { flags.set(BLOCK_CACHED); }
624    bool isBlockCached() const     { return flags.isSet(BLOCK_CACHED); }
625    void clearBlockCached()        { flags.clear(BLOCK_CACHED); }
626
627    // Network error conditions... encapsulate them as methods since
628    // their encoding keeps changing (from result field to command
629    // field, etc.)
630    void
631    setBadAddress()
632    {
633        assert(isResponse());
634        cmd = MemCmd::BadAddressError;
635    }
636
637    void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
638
639    Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
640    /**
641     * Update the address of this packet mid-transaction. This is used
642     * by the address mapper to change an already set address to a new
643     * one based on the system configuration. It is intended to remap
644     * an existing address, so it asserts that the current address is
645     * valid.
646     */
647    void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
648
649    unsigned getSize() const  { assert(flags.isSet(VALID_SIZE)); return size; }
650
651    Addr getOffset(unsigned int blk_size) const
652    {
653        return getAddr() & Addr(blk_size - 1);
654    }
655
656    Addr getBlockAddr(unsigned int blk_size) const
657    {
658        return getAddr() & ~(Addr(blk_size - 1));
659    }
660
661    bool isSecure() const
662    {
663        assert(flags.isSet(VALID_ADDR));
664        return _isSecure;
665    }
666
667    /**
668     * Accessor function to atomic op.
669     */
670    AtomicOpFunctor *getAtomicOp() const { return req->getAtomicOpFunctor(); }
671    bool isAtomicOp() const { return req->isAtomic(); }
672
673    /**
674     * It has been determined that the SC packet should successfully update
675     * memory. Therefore, convert this SC packet to a normal write.
676     */
677    void
678    convertScToWrite()
679    {
680        assert(isLLSC());
681        assert(isWrite());
682        cmd = MemCmd::WriteReq;
683    }
684
685    /**
686     * When ruby is in use, Ruby will monitor the cache line and the
687     * phys memory should treat LL ops as normal reads.
688     */
689    void
690    convertLlToRead()
691    {
692        assert(isLLSC());
693        assert(isRead());
694        cmd = MemCmd::ReadReq;
695    }
696
697    /**
698     * Constructor. Note that a Request object must be constructed
699     * first, but the Requests's physical address and size fields need
700     * not be valid. The command must be supplied.
701     */
702    Packet(const RequestPtr _req, MemCmd _cmd)
703        :  cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
704           size(0), headerDelay(0), snoopDelay(0), payloadDelay(0),
705           senderState(NULL)
706    {
707        if (req->hasPaddr()) {
708            addr = req->getPaddr();
709            flags.set(VALID_ADDR);
710            _isSecure = req->isSecure();
711        }
712        if (req->hasSize()) {
713            size = req->getSize();
714            flags.set(VALID_SIZE);
715        }
716    }
717
718    /**
719     * Alternate constructor if you are trying to create a packet with
720     * a request that is for a whole block, not the address from the
721     * req.  this allows for overriding the size/addr of the req.
722     */
723    Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize)
724        :  cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
725           headerDelay(0), snoopDelay(0), payloadDelay(0),
726           senderState(NULL)
727    {
728        if (req->hasPaddr()) {
729            addr = req->getPaddr() & ~(_blkSize - 1);
730            flags.set(VALID_ADDR);
731            _isSecure = req->isSecure();
732        }
733        size = _blkSize;
734        flags.set(VALID_SIZE);
735    }
736
737    /**
738     * Alternate constructor for copying a packet.  Copy all fields
739     * *except* if the original packet's data was dynamic, don't copy
740     * that, as we can't guarantee that the new packet's lifetime is
741     * less than that of the original packet.  In this case the new
742     * packet should allocate its own data.
743     */
744    Packet(const PacketPtr pkt, bool clear_flags, bool alloc_data)
745        :  cmd(pkt->cmd), req(pkt->req),
746           data(nullptr),
747           addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
748           bytesValid(pkt->bytesValid),
749           headerDelay(pkt->headerDelay),
750           snoopDelay(0),
751           payloadDelay(pkt->payloadDelay),
752           senderState(pkt->senderState)
753    {
754        if (!clear_flags)
755            flags.set(pkt->flags & COPY_FLAGS);
756
757        flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
758
759        // should we allocate space for data, or not, the express
760        // snoops do not need to carry any data as they only serve to
761        // co-ordinate state changes
762        if (alloc_data) {
763            // even if asked to allocate data, if the original packet
764            // holds static data, then the sender will not be doing
765            // any memcpy on receiving the response, thus we simply
766            // carry the pointer forward
767            if (pkt->flags.isSet(STATIC_DATA)) {
768                data = pkt->data;
769                flags.set(STATIC_DATA);
770            } else {
771                allocate();
772            }
773        }
774    }
775
776    /**
777     * Generate the appropriate read MemCmd based on the Request flags.
778     */
779    static MemCmd
780    makeReadCmd(const RequestPtr req)
781    {
782        if (req->isLLSC())
783            return MemCmd::LoadLockedReq;
784        else if (req->isPrefetch())
785            return MemCmd::SoftPFReq;
786        else
787            return MemCmd::ReadReq;
788    }
789
790    /**
791     * Generate the appropriate write MemCmd based on the Request flags.
792     */
793    static MemCmd
794    makeWriteCmd(const RequestPtr req)
795    {
796        if (req->isLLSC())
797            return MemCmd::StoreCondReq;
798        else if (req->isSwap())
799            return MemCmd::SwapReq;
800        else
801            return MemCmd::WriteReq;
802    }
803
804    /**
805     * Constructor-like methods that return Packets based on Request objects.
806     * Fine-tune the MemCmd type if it's not a vanilla read or write.
807     */
808    static PacketPtr
809    createRead(const RequestPtr req)
810    {
811        return new Packet(req, makeReadCmd(req));
812    }
813
814    static PacketPtr
815    createWrite(const RequestPtr req)
816    {
817        return new Packet(req, makeWriteCmd(req));
818    }
819
820    /**
821     * clean up packet variables
822     */
823    ~Packet()
824    {
825        // Delete the request object if this is a request packet which
826        // does not need a response, because the requester will not get
827        // a chance. If the request packet needs a response then the
828        // request will be deleted on receipt of the response
829        // packet. We also make sure to never delete the request for
830        // express snoops, even for cases when responses are not
831        // needed (CleanEvict and Writeback), since the snoop packet
832        // re-uses the same request.
833        if (req && isRequest() && !needsResponse() &&
834            !isExpressSnoop()) {
835            delete req;
836        }
837        deleteData();
838    }
839
840    /**
841     * Take a request packet and modify it in place to be suitable for
842     * returning as a response to that request.
843     */
844    void
845    makeResponse()
846    {
847        assert(needsResponse());
848        assert(isRequest());
849        cmd = cmd.responseCommand();
850
851        // responses are never express, even if the snoop that
852        // triggered them was
853        flags.clear(EXPRESS_SNOOP);
854    }
855
856    void
857    makeAtomicResponse()
858    {
859        makeResponse();
860    }
861
862    void
863    makeTimingResponse()
864    {
865        makeResponse();
866    }
867
868    void
869    setFunctionalResponseStatus(bool success)
870    {
871        if (!success) {
872            if (isWrite()) {
873                cmd = MemCmd::FunctionalWriteError;
874            } else {
875                cmd = MemCmd::FunctionalReadError;
876            }
877        }
878    }
879
880    void
881    setSize(unsigned size)
882    {
883        assert(!flags.isSet(VALID_SIZE));
884
885        this->size = size;
886        flags.set(VALID_SIZE);
887    }
888
889
890  public:
891    /**
892     * @{
893     * @name Data accessor mehtods
894     */
895
896    /**
897     * Set the data pointer to the following value that should not be
898     * freed. Static data allows us to do a single memcpy even if
899     * multiple packets are required to get from source to destination
900     * and back. In essence the pointer is set calling dataStatic on
901     * the original packet, and whenever this packet is copied and
902     * forwarded the same pointer is passed on. When a packet
903     * eventually reaches the destination holding the data, it is
904     * copied once into the location originally set. On the way back
905     * to the source, no copies are necessary.
906     */
907    template <typename T>
908    void
909    dataStatic(T *p)
910    {
911        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
912        data = (PacketDataPtr)p;
913        flags.set(STATIC_DATA);
914    }
915
916    /**
917     * Set the data pointer to the following value that should not be
918     * freed. This version of the function allows the pointer passed
919     * to us to be const. To avoid issues down the line we cast the
920     * constness away, the alternative would be to keep both a const
921     * and non-const data pointer and cleverly choose between
922     * them. Note that this is only allowed for static data.
923     */
924    template <typename T>
925    void
926    dataStaticConst(const T *p)
927    {
928        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
929        data = const_cast<PacketDataPtr>(p);
930        flags.set(STATIC_DATA);
931    }
932
933    /**
934     * Set the data pointer to a value that should have delete []
935     * called on it. Dynamic data is local to this packet, and as the
936     * packet travels from source to destination, forwarded packets
937     * will allocate their own data. When a packet reaches the final
938     * destination it will populate the dynamic data of that specific
939     * packet, and on the way back towards the source, memcpy will be
940     * invoked in every step where a new packet was created e.g. in
941     * the caches. Ultimately when the response reaches the source a
942     * final memcpy is needed to extract the data from the packet
943     * before it is deallocated.
944     */
945    template <typename T>
946    void
947    dataDynamic(T *p)
948    {
949        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
950        data = (PacketDataPtr)p;
951        flags.set(DYNAMIC_DATA);
952    }
953
954    /**
955     * get a pointer to the data ptr.
956     */
957    template <typename T>
958    T*
959    getPtr()
960    {
961        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
962        return (T*)data;
963    }
964
965    template <typename T>
966    const T*
967    getConstPtr() const
968    {
969        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
970        return (const T*)data;
971    }
972
973    /**
974     * Get the data in the packet byte swapped from big endian to
975     * host endian.
976     */
977    template <typename T>
978    T getBE() const;
979
980    /**
981     * Get the data in the packet byte swapped from little endian to
982     * host endian.
983     */
984    template <typename T>
985    T getLE() const;
986
987    /**
988     * Get the data in the packet byte swapped from the specified
989     * endianness.
990     */
991    template <typename T>
992    T get(ByteOrder endian) const;
993
994    /**
995     * Get the data in the packet byte swapped from guest to host
996     * endian.
997     */
998    template <typename T>
999    T get() const;
1000
1001    /** Set the value in the data pointer to v as big endian. */
1002    template <typename T>
1003    void setBE(T v);
1004
1005    /** Set the value in the data pointer to v as little endian. */
1006    template <typename T>
1007    void setLE(T v);
1008
1009    /**
1010     * Set the value in the data pointer to v using the specified
1011     * endianness.
1012     */
1013    template <typename T>
1014    void set(T v, ByteOrder endian);
1015
1016    /** Set the value in the data pointer to v as guest endian. */
1017    template <typename T>
1018    void set(T v);
1019
1020    /**
1021     * Copy data into the packet from the provided pointer.
1022     */
1023    void
1024    setData(const uint8_t *p)
1025    {
1026        // we should never be copying data onto itself, which means we
1027        // must idenfity packets with static data, as they carry the
1028        // same pointer from source to destination and back
1029        assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA));
1030
1031        if (p != getPtr<uint8_t>())
1032            // for packet with allocated dynamic data, we copy data from
1033            // one to the other, e.g. a forwarded response to a response
1034            std::memcpy(getPtr<uint8_t>(), p, getSize());
1035    }
1036
1037    /**
1038     * Copy data into the packet from the provided block pointer,
1039     * which is aligned to the given block size.
1040     */
1041    void
1042    setDataFromBlock(const uint8_t *blk_data, int blkSize)
1043    {
1044        setData(blk_data + getOffset(blkSize));
1045    }
1046
1047    /**
1048     * Copy data from the packet to the provided block pointer, which
1049     * is aligned to the given block size.
1050     */
1051    void
1052    writeData(uint8_t *p) const
1053    {
1054        std::memcpy(p, getConstPtr<uint8_t>(), getSize());
1055    }
1056
1057    /**
1058     * Copy data from the packet to the memory at the provided pointer.
1059     */
1060    void
1061    writeDataToBlock(uint8_t *blk_data, int blkSize) const
1062    {
1063        writeData(blk_data + getOffset(blkSize));
1064    }
1065
1066    /**
1067     * delete the data pointed to in the data pointer. Ok to call to
1068     * matter how data was allocted.
1069     */
1070    void
1071    deleteData()
1072    {
1073        if (flags.isSet(DYNAMIC_DATA))
1074            delete [] data;
1075
1076        flags.clear(STATIC_DATA|DYNAMIC_DATA);
1077        data = NULL;
1078    }
1079
1080    /** Allocate memory for the packet. */
1081    void
1082    allocate()
1083    {
1084        // if either this command or the response command has a data
1085        // payload, actually allocate space
1086        if (hasData() || hasRespData()) {
1087            assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
1088            flags.set(DYNAMIC_DATA);
1089            data = new uint8_t[getSize()];
1090        }
1091    }
1092
1093    /** @} */
1094
1095  private: // Private data accessor methods
1096    /** Get the data in the packet without byte swapping. */
1097    template <typename T>
1098    T getRaw() const;
1099
1100    /** Set the value in the data pointer to v without byte swapping. */
1101    template <typename T>
1102    void setRaw(T v);
1103
1104  public:
1105    /**
1106     * Check a functional request against a memory value stored in
1107     * another packet (i.e. an in-transit request or
1108     * response). Returns true if the current packet is a read, and
1109     * the other packet provides the data, which is then copied to the
1110     * current packet. If the current packet is a write, and the other
1111     * packet intersects this one, then we update the data
1112     * accordingly.
1113     */
1114    bool
1115    checkFunctional(PacketPtr other)
1116    {
1117        // all packets that are carrying a payload should have a valid
1118        // data pointer
1119        return checkFunctional(other, other->getAddr(), other->isSecure(),
1120                               other->getSize(),
1121                               other->hasData() ?
1122                               other->getPtr<uint8_t>() : NULL);
1123    }
1124
1125    /**
1126     * Does the request need to check for cached copies of the same block
1127     * in the memory hierarchy above.
1128     **/
1129    bool
1130    mustCheckAbove() const
1131    {
1132        return cmd == MemCmd::HardPFReq || isEviction();
1133    }
1134
1135    /**
1136     * Is this packet a clean eviction, including both actual clean
1137     * evict packets, but also clean writebacks.
1138     */
1139    bool
1140    isCleanEviction() const
1141    {
1142        return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
1143    }
1144
1145    /**
1146     * Check a functional request against a memory value represented
1147     * by a base/size pair and an associated data array. If the
1148     * current packet is a read, it may be satisfied by the memory
1149     * value. If the current packet is a write, it may update the
1150     * memory value.
1151     */
1152    bool
1153    checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
1154                    uint8_t *_data);
1155
1156    /**
1157     * Push label for PrintReq (safe to call unconditionally).
1158     */
1159    void
1160    pushLabel(const std::string &lbl)
1161    {
1162        if (isPrint())
1163            safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
1164    }
1165
1166    /**
1167     * Pop label for PrintReq (safe to call unconditionally).
1168     */
1169    void
1170    popLabel()
1171    {
1172        if (isPrint())
1173            safe_cast<PrintReqState*>(senderState)->popLabel();
1174    }
1175
1176    void print(std::ostream &o, int verbosity = 0,
1177               const std::string &prefix = "") const;
1178
1179    /**
1180     * A no-args wrapper of print(std::ostream...)
1181     * meant to be invoked from DPRINTFs
1182     * avoiding string overheads in fast mode
1183     * @return string with the request's type and start<->end addresses
1184     */
1185    std::string print() const;
1186};
1187
1188#endif //__MEM_PACKET_HH
1189