packet.hh revision 12346:9b1144d046ca
1/*
2 * Copyright (c) 2012-2017 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        WriteClean,            // writes dirty data below without evicting
92        CleanEvict,
93        SoftPFReq,
94        HardPFReq,
95        SoftPFResp,
96        HardPFResp,
97        WriteLineReq,
98        UpgradeReq,
99        SCUpgradeReq,           // Special "weak" upgrade for StoreCond
100        UpgradeResp,
101        SCUpgradeFailReq,       // Failed SCUpgradeReq in MSHR (never sent)
102        UpgradeFailResp,        // Valid for SCUpgradeReq only
103        ReadExReq,
104        ReadExResp,
105        ReadCleanReq,
106        ReadSharedReq,
107        LoadLockedReq,
108        StoreCondReq,
109        StoreCondFailReq,       // Failed StoreCondReq in MSHR (never sent)
110        StoreCondResp,
111        SwapReq,
112        SwapResp,
113        MessageReq,
114        MessageResp,
115        MemFenceReq,
116        MemFenceResp,
117        // Error responses
118        // @TODO these should be classified as responses rather than
119        // requests; coding them as requests initially for backwards
120        // compatibility
121        InvalidDestError,  // packet dest field invalid
122        BadAddressError,   // memory address invalid
123        FunctionalReadError, // unable to fulfill functional read
124        FunctionalWriteError, // unable to fulfill functional write
125        // Fake simulator-only commands
126        PrintReq,       // Print state matching address
127        FlushReq,      //request for a cache flush
128        InvalidateReq,   // request for address to be invalidated
129        InvalidateResp,
130        NUM_MEM_CMDS
131    };
132
133  private:
134    /**
135     * List of command attributes.
136     */
137    enum Attribute
138    {
139        IsRead,         //!< Data flows from responder to requester
140        IsWrite,        //!< Data flows from requester to responder
141        IsUpgrade,
142        IsInvalidate,
143        NeedsWritable,  //!< Requires writable copy to complete in-cache
144        IsRequest,      //!< Issued by requester
145        IsResponse,     //!< Issue by responder
146        NeedsResponse,  //!< Requester needs response from target
147        IsEviction,
148        IsSWPrefetch,
149        IsHWPrefetch,
150        IsLlsc,         //!< Alpha/MIPS LL or SC access
151        HasData,        //!< There is an associated payload
152        IsError,        //!< Error response
153        IsPrint,        //!< Print state matching address (for debugging)
154        IsFlush,        //!< Flush the address from caches
155        FromCache,      //!< Request originated from a caching agent
156        NUM_COMMAND_ATTRIBUTES
157    };
158
159    /**
160     * Structure that defines attributes and other data associated
161     * with a Command.
162     */
163    struct CommandInfo
164    {
165        /// Set of attribute flags.
166        const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
167        /// Corresponding response for requests; InvalidCmd if no
168        /// response is applicable.
169        const Command response;
170        /// String representation (for printing)
171        const std::string str;
172    };
173
174    /// Array to map Command enum to associated info.
175    static const CommandInfo commandInfo[];
176
177  private:
178
179    Command cmd;
180
181    bool
182    testCmdAttrib(MemCmd::Attribute attrib) const
183    {
184        return commandInfo[cmd].attributes[attrib] != 0;
185    }
186
187  public:
188
189    bool isRead() const            { return testCmdAttrib(IsRead); }
190    bool isWrite() const           { return testCmdAttrib(IsWrite); }
191    bool isUpgrade() const         { return testCmdAttrib(IsUpgrade); }
192    bool isRequest() const         { return testCmdAttrib(IsRequest); }
193    bool isResponse() const        { return testCmdAttrib(IsResponse); }
194    bool needsWritable() const     { return testCmdAttrib(NeedsWritable); }
195    bool needsResponse() const     { return testCmdAttrib(NeedsResponse); }
196    bool isInvalidate() const      { return testCmdAttrib(IsInvalidate); }
197    bool isEviction() const        { return testCmdAttrib(IsEviction); }
198    bool fromCache() const         { return testCmdAttrib(FromCache); }
199
200    /**
201     * A writeback is an eviction that carries data.
202     */
203    bool isWriteback() const       { return testCmdAttrib(IsEviction) &&
204                                            testCmdAttrib(HasData); }
205
206    /**
207     * Check if this particular packet type carries payload data. Note
208     * that this does not reflect if the data pointer of the packet is
209     * valid or not.
210     */
211    bool hasData() const        { return testCmdAttrib(HasData); }
212    bool isLLSC() const         { return testCmdAttrib(IsLlsc); }
213    bool isSWPrefetch() const   { return testCmdAttrib(IsSWPrefetch); }
214    bool isHWPrefetch() const   { return testCmdAttrib(IsHWPrefetch); }
215    bool isPrefetch() const     { return testCmdAttrib(IsSWPrefetch) ||
216                                         testCmdAttrib(IsHWPrefetch); }
217    bool isError() const        { return testCmdAttrib(IsError); }
218    bool isPrint() const        { return testCmdAttrib(IsPrint); }
219    bool isFlush() const        { return testCmdAttrib(IsFlush); }
220
221    Command
222    responseCommand() const
223    {
224        return commandInfo[cmd].response;
225    }
226
227    /// Return the string to a cmd given by idx.
228    const std::string &toString() const { return commandInfo[cmd].str; }
229    int toInt() const { return (int)cmd; }
230
231    MemCmd(Command _cmd) : cmd(_cmd) { }
232    MemCmd(int _cmd) : cmd((Command)_cmd) { }
233    MemCmd() : cmd(InvalidCmd) { }
234
235    bool operator==(MemCmd c2) const { return (cmd == c2.cmd); }
236    bool operator!=(MemCmd c2) const { return (cmd != c2.cmd); }
237};
238
239/**
240 * A Packet is used to encapsulate a transfer between two objects in
241 * the memory system (e.g., the L1 and L2 cache).  (In contrast, a
242 * single Request travels all the way from the requester to the
243 * ultimate destination and back, possibly being conveyed by several
244 * different Packets along the way.)
245 */
246class Packet : public Printable
247{
248  public:
249    typedef uint32_t FlagsType;
250    typedef ::Flags<FlagsType> Flags;
251
252  private:
253
254    enum : FlagsType {
255        // Flags to transfer across when copying a packet
256        COPY_FLAGS             = 0x0000001F,
257
258        // Does this packet have sharers (which means it should not be
259        // considered writable) or not. See setHasSharers below.
260        HAS_SHARERS            = 0x00000001,
261
262        // Special control flags
263        /// Special timing-mode atomic snoop for multi-level coherence.
264        EXPRESS_SNOOP          = 0x00000002,
265
266        /// Allow a responding cache to inform the cache hierarchy
267        /// that it had a writable copy before responding. See
268        /// setResponderHadWritable below.
269        RESPONDER_HAD_WRITABLE = 0x00000004,
270
271        // Snoop co-ordination flag to indicate that a cache is
272        // responding to a snoop. See setCacheResponding below.
273        CACHE_RESPONDING       = 0x00000008,
274
275        // The writeback/writeclean should be propagated further
276        // downstream by the receiver
277        WRITE_THROUGH          = 0x00000010,
278
279        /// Are the 'addr' and 'size' fields valid?
280        VALID_ADDR             = 0x00000100,
281        VALID_SIZE             = 0x00000200,
282
283        /// Is the data pointer set to a value that shouldn't be freed
284        /// when the packet is destroyed?
285        STATIC_DATA            = 0x00001000,
286        /// The data pointer points to a value that should be freed when
287        /// the packet is destroyed. The pointer is assumed to be pointing
288        /// to an array, and delete [] is consequently called
289        DYNAMIC_DATA           = 0x00002000,
290
291        /// suppress the error if this packet encounters a functional
292        /// access failure.
293        SUPPRESS_FUNC_ERROR    = 0x00008000,
294
295        // Signal block present to squash prefetch and cache evict packets
296        // through express snoop flag
297        BLOCK_CACHED          = 0x00010000
298    };
299
300    Flags flags;
301
302  public:
303    typedef MemCmd::Command Command;
304
305    /// The command field of the packet.
306    MemCmd cmd;
307
308    /// A pointer to the original request.
309    const RequestPtr req;
310
311  private:
312   /**
313    * A pointer to the data being transfered.  It can be differnt
314    * sizes at each level of the heirarchy so it belongs in the
315    * packet, not request. This may or may not be populated when a
316    * responder recieves the packet. If not populated it memory should
317    * be allocated.
318    */
319    PacketDataPtr data;
320
321    /// The address of the request.  This address could be virtual or
322    /// physical, depending on the system configuration.
323    Addr addr;
324
325    /// True if the request targets the secure memory space.
326    bool _isSecure;
327
328    /// The size of the request or transfer.
329    unsigned size;
330
331    /**
332     * Track the bytes found that satisfy a functional read.
333     */
334    std::vector<bool> bytesValid;
335
336  public:
337
338    /**
339     * The extra delay from seeing the packet until the header is
340     * transmitted. This delay is used to communicate the crossbar
341     * forwarding latency to the neighbouring object (e.g. a cache)
342     * that actually makes the packet wait. As the delay is relative,
343     * a 32-bit unsigned should be sufficient.
344     */
345    uint32_t headerDelay;
346
347    /**
348     * Keep track of the extra delay incurred by snooping upwards
349     * before sending a request down the memory system. This is used
350     * by the coherent crossbar to account for the additional request
351     * delay.
352     */
353    uint32_t snoopDelay;
354
355    /**
356     * The extra pipelining delay from seeing the packet until the end of
357     * payload is transmitted by the component that provided it (if
358     * any). This includes the header delay. Similar to the header
359     * delay, this is used to make up for the fact that the
360     * crossbar does not make the packet wait. As the delay is
361     * relative, a 32-bit unsigned should be sufficient.
362     */
363    uint32_t payloadDelay;
364
365    /**
366     * A virtual base opaque structure used to hold state associated
367     * with the packet (e.g., an MSHR), specific to a MemObject that
368     * sees the packet. A pointer to this state is returned in the
369     * packet's response so that the MemObject in question can quickly
370     * look up the state needed to process it. A specific subclass
371     * would be derived from this to carry state specific to a
372     * particular sending device.
373     *
374     * As multiple MemObjects may add their SenderState throughout the
375     * memory system, the SenderStates create a stack, where a
376     * MemObject can add a new Senderstate, as long as the
377     * predecessing SenderState is restored when the response comes
378     * back. For this reason, the predecessor should always be
379     * populated with the current SenderState of a packet before
380     * modifying the senderState field in the request packet.
381     */
382    struct SenderState
383    {
384        SenderState* predecessor;
385        SenderState() : predecessor(NULL) {}
386        virtual ~SenderState() {}
387    };
388
389    /**
390     * Object used to maintain state of a PrintReq.  The senderState
391     * field of a PrintReq should always be of this type.
392     */
393    class PrintReqState : public SenderState
394    {
395      private:
396        /**
397         * An entry in the label stack.
398         */
399        struct LabelStackEntry
400        {
401            const std::string label;
402            std::string *prefix;
403            bool labelPrinted;
404            LabelStackEntry(const std::string &_label, std::string *_prefix);
405        };
406
407        typedef std::list<LabelStackEntry> LabelStack;
408        LabelStack labelStack;
409
410        std::string *curPrefixPtr;
411
412      public:
413        std::ostream &os;
414        const int verbosity;
415
416        PrintReqState(std::ostream &os, int verbosity = 0);
417        ~PrintReqState();
418
419        /**
420         * Returns the current line prefix.
421         */
422        const std::string &curPrefix() { return *curPrefixPtr; }
423
424        /**
425         * Push a label onto the label stack, and prepend the given
426         * prefix string onto the current prefix.  Labels will only be
427         * printed if an object within the label's scope is printed.
428         */
429        void pushLabel(const std::string &lbl,
430                       const std::string &prefix = "  ");
431
432        /**
433         * Pop a label off the label stack.
434         */
435        void popLabel();
436
437        /**
438         * Print all of the pending unprinted labels on the
439         * stack. Called by printObj(), so normally not called by
440         * users unless bypassing printObj().
441         */
442        void printLabels();
443
444        /**
445         * Print a Printable object to os, because it matched the
446         * address on a PrintReq.
447         */
448        void printObj(Printable *obj);
449    };
450
451    /**
452     * This packet's sender state.  Devices should use dynamic_cast<>
453     * to cast to the state appropriate to the sender.  The intent of
454     * this variable is to allow a device to attach extra information
455     * to a request. A response packet must return the sender state
456     * that was attached to the original request (even if a new packet
457     * is created).
458     */
459    SenderState *senderState;
460
461    /**
462     * Push a new sender state to the packet and make the current
463     * sender state the predecessor of the new one. This should be
464     * prefered over direct manipulation of the senderState member
465     * variable.
466     *
467     * @param sender_state SenderState to push at the top of the stack
468     */
469    void pushSenderState(SenderState *sender_state);
470
471    /**
472     * Pop the top of the state stack and return a pointer to it. This
473     * assumes the current sender state is not NULL. This should be
474     * preferred over direct manipulation of the senderState member
475     * variable.
476     *
477     * @return The current top of the stack
478     */
479    SenderState *popSenderState();
480
481    /**
482     * Go through the sender state stack and return the first instance
483     * that is of type T (as determined by a dynamic_cast). If there
484     * is no sender state of type T, NULL is returned.
485     *
486     * @return The topmost state of type T
487     */
488    template <typename T>
489    T * findNextSenderState() const
490    {
491        T *t = NULL;
492        SenderState* sender_state = senderState;
493        while (t == NULL && sender_state != NULL) {
494            t = dynamic_cast<T*>(sender_state);
495            sender_state = sender_state->predecessor;
496        }
497        return t;
498    }
499
500    /// Return the string name of the cmd field (for debugging and
501    /// tracing).
502    const std::string &cmdString() const { return cmd.toString(); }
503
504    /// Return the index of this command.
505    inline int cmdToIndex() const { return cmd.toInt(); }
506
507    bool isRead() const              { return cmd.isRead(); }
508    bool isWrite() const             { return cmd.isWrite(); }
509    bool isUpgrade()  const          { return cmd.isUpgrade(); }
510    bool isRequest() const           { return cmd.isRequest(); }
511    bool isResponse() const          { return cmd.isResponse(); }
512    bool needsWritable() const
513    {
514        // we should never check if a response needsWritable, the
515        // request has this flag, and for a response we should rather
516        // look at the hasSharers flag (if not set, the response is to
517        // be considered writable)
518        assert(isRequest());
519        return cmd.needsWritable();
520    }
521    bool needsResponse() const       { return cmd.needsResponse(); }
522    bool isInvalidate() const        { return cmd.isInvalidate(); }
523    bool isEviction() const          { return cmd.isEviction(); }
524    bool fromCache() const           { return cmd.fromCache(); }
525    bool isWriteback() const         { return cmd.isWriteback(); }
526    bool hasData() const             { return cmd.hasData(); }
527    bool hasRespData() const
528    {
529        MemCmd resp_cmd = cmd.responseCommand();
530        return resp_cmd.hasData();
531    }
532    bool isLLSC() const              { return cmd.isLLSC(); }
533    bool isError() const             { return cmd.isError(); }
534    bool isPrint() const             { return cmd.isPrint(); }
535    bool isFlush() const             { return cmd.isFlush(); }
536
537    //@{
538    /// Snoop flags
539    /**
540     * Set the cacheResponding flag. This is used by the caches to
541     * signal another cache that they are responding to a request. A
542     * cache will only respond to snoops if it has the line in either
543     * Modified or Owned state. Note that on snoop hits we always pass
544     * the line as Modified and never Owned. In the case of an Owned
545     * line we proceed to invalidate all other copies.
546     *
547     * On a cache fill (see Cache::handleFill), we check hasSharers
548     * first, ignoring the cacheResponding flag if hasSharers is set.
549     * A line is consequently allocated as:
550     *
551     * hasSharers cacheResponding state
552     * true       false           Shared
553     * true       true            Shared
554     * false      false           Exclusive
555     * false      true            Modified
556     */
557    void setCacheResponding()
558    {
559        assert(isRequest());
560        assert(!flags.isSet(CACHE_RESPONDING));
561        flags.set(CACHE_RESPONDING);
562    }
563    bool cacheResponding() const { return flags.isSet(CACHE_RESPONDING); }
564    /**
565     * On fills, the hasSharers flag is used by the caches in
566     * combination with the cacheResponding flag, as clarified
567     * above. If the hasSharers flag is not set, the packet is passing
568     * writable. Thus, a response from a memory passes the line as
569     * writable by default.
570     *
571     * The hasSharers flag is also used by upstream caches to inform a
572     * downstream cache that they have the block (by calling
573     * setHasSharers on snoop request packets that hit in upstream
574     * cachs tags or MSHRs). If the snoop packet has sharers, a
575     * downstream cache is prevented from passing a dirty line upwards
576     * if it was not explicitly asked for a writable copy. See
577     * Cache::satisfyCpuSideRequest.
578     *
579     * The hasSharers flag is also used on writebacks, in
580     * combination with the WritbackClean or WritebackDirty commands,
581     * to allocate the block downstream either as:
582     *
583     * command        hasSharers state
584     * WritebackDirty false      Modified
585     * WritebackDirty true       Owned
586     * WritebackClean false      Exclusive
587     * WritebackClean true       Shared
588     */
589    void setHasSharers()    { flags.set(HAS_SHARERS); }
590    bool hasSharers() const { return flags.isSet(HAS_SHARERS); }
591    //@}
592
593    /**
594     * The express snoop flag is used for two purposes. Firstly, it is
595     * used to bypass flow control for normal (non-snoop) requests
596     * going downstream in the memory system. In cases where a cache
597     * is responding to a snoop from another cache (it had a dirty
598     * line), but the line is not writable (and there are possibly
599     * other copies), the express snoop flag is set by the downstream
600     * cache to invalidate all other copies in zero time. Secondly,
601     * the express snoop flag is also set to be able to distinguish
602     * snoop packets that came from a downstream cache, rather than
603     * snoop packets from neighbouring caches.
604     */
605    void setExpressSnoop()      { flags.set(EXPRESS_SNOOP); }
606    bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
607
608    /**
609     * On responding to a snoop request (which only happens for
610     * Modified or Owned lines), make sure that we can transform an
611     * Owned response to a Modified one. If this flag is not set, the
612     * responding cache had the line in the Owned state, and there are
613     * possibly other Shared copies in the memory system. A downstream
614     * cache helps in orchestrating the invalidation of these copies
615     * by sending out the appropriate express snoops.
616     */
617    void setResponderHadWritable()
618    {
619        assert(cacheResponding());
620        assert(!responderHadWritable());
621        flags.set(RESPONDER_HAD_WRITABLE);
622    }
623    bool responderHadWritable() const
624    { return flags.isSet(RESPONDER_HAD_WRITABLE); }
625
626    /**
627     * A writeback/writeclean cmd gets propagated further downstream
628     * by the receiver when the flag is set.
629     */
630    void setWriteThrough()
631    {
632        assert(cmd.isWrite() &&
633               (cmd.isEviction() || cmd == MemCmd::WriteClean));
634        flags.set(WRITE_THROUGH);
635    }
636    void clearWriteThrough() { flags.clear(WRITE_THROUGH); }
637    bool writeThrough() const { return flags.isSet(WRITE_THROUGH); }
638
639    void setSuppressFuncError()     { flags.set(SUPPRESS_FUNC_ERROR); }
640    bool suppressFuncError() const  { return flags.isSet(SUPPRESS_FUNC_ERROR); }
641    void setBlockCached()          { flags.set(BLOCK_CACHED); }
642    bool isBlockCached() const     { return flags.isSet(BLOCK_CACHED); }
643    void clearBlockCached()        { flags.clear(BLOCK_CACHED); }
644
645    // Network error conditions... encapsulate them as methods since
646    // their encoding keeps changing (from result field to command
647    // field, etc.)
648    void
649    setBadAddress()
650    {
651        assert(isResponse());
652        cmd = MemCmd::BadAddressError;
653    }
654
655    void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
656
657    Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
658    /**
659     * Update the address of this packet mid-transaction. This is used
660     * by the address mapper to change an already set address to a new
661     * one based on the system configuration. It is intended to remap
662     * an existing address, so it asserts that the current address is
663     * valid.
664     */
665    void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
666
667    unsigned getSize() const  { assert(flags.isSet(VALID_SIZE)); return size; }
668
669    Addr getOffset(unsigned int blk_size) const
670    {
671        return getAddr() & Addr(blk_size - 1);
672    }
673
674    Addr getBlockAddr(unsigned int blk_size) const
675    {
676        return getAddr() & ~(Addr(blk_size - 1));
677    }
678
679    bool isSecure() const
680    {
681        assert(flags.isSet(VALID_ADDR));
682        return _isSecure;
683    }
684
685    /**
686     * Accessor function to atomic op.
687     */
688    AtomicOpFunctor *getAtomicOp() const { return req->getAtomicOpFunctor(); }
689    bool isAtomicOp() const { return req->isAtomic(); }
690
691    /**
692     * It has been determined that the SC packet should successfully update
693     * memory. Therefore, convert this SC packet to a normal write.
694     */
695    void
696    convertScToWrite()
697    {
698        assert(isLLSC());
699        assert(isWrite());
700        cmd = MemCmd::WriteReq;
701    }
702
703    /**
704     * When ruby is in use, Ruby will monitor the cache line and the
705     * phys memory should treat LL ops as normal reads.
706     */
707    void
708    convertLlToRead()
709    {
710        assert(isLLSC());
711        assert(isRead());
712        cmd = MemCmd::ReadReq;
713    }
714
715    /**
716     * Constructor. Note that a Request object must be constructed
717     * first, but the Requests's physical address and size fields need
718     * not be valid. The command must be supplied.
719     */
720    Packet(const RequestPtr _req, MemCmd _cmd)
721        :  cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
722           size(0), headerDelay(0), snoopDelay(0), payloadDelay(0),
723           senderState(NULL)
724    {
725        if (req->hasPaddr()) {
726            addr = req->getPaddr();
727            flags.set(VALID_ADDR);
728            _isSecure = req->isSecure();
729        }
730        if (req->hasSize()) {
731            size = req->getSize();
732            flags.set(VALID_SIZE);
733        }
734    }
735
736    /**
737     * Alternate constructor if you are trying to create a packet with
738     * a request that is for a whole block, not the address from the
739     * req.  this allows for overriding the size/addr of the req.
740     */
741    Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize)
742        :  cmd(_cmd), req(_req), data(nullptr), addr(0), _isSecure(false),
743           headerDelay(0), snoopDelay(0), payloadDelay(0),
744           senderState(NULL)
745    {
746        if (req->hasPaddr()) {
747            addr = req->getPaddr() & ~(_blkSize - 1);
748            flags.set(VALID_ADDR);
749            _isSecure = req->isSecure();
750        }
751        size = _blkSize;
752        flags.set(VALID_SIZE);
753    }
754
755    /**
756     * Alternate constructor for copying a packet.  Copy all fields
757     * *except* if the original packet's data was dynamic, don't copy
758     * that, as we can't guarantee that the new packet's lifetime is
759     * less than that of the original packet.  In this case the new
760     * packet should allocate its own data.
761     */
762    Packet(const PacketPtr pkt, bool clear_flags, bool alloc_data)
763        :  cmd(pkt->cmd), req(pkt->req),
764           data(nullptr),
765           addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
766           bytesValid(pkt->bytesValid),
767           headerDelay(pkt->headerDelay),
768           snoopDelay(0),
769           payloadDelay(pkt->payloadDelay),
770           senderState(pkt->senderState)
771    {
772        if (!clear_flags)
773            flags.set(pkt->flags & COPY_FLAGS);
774
775        flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
776
777        // should we allocate space for data, or not, the express
778        // snoops do not need to carry any data as they only serve to
779        // co-ordinate state changes
780        if (alloc_data) {
781            // even if asked to allocate data, if the original packet
782            // holds static data, then the sender will not be doing
783            // any memcpy on receiving the response, thus we simply
784            // carry the pointer forward
785            if (pkt->flags.isSet(STATIC_DATA)) {
786                data = pkt->data;
787                flags.set(STATIC_DATA);
788            } else {
789                allocate();
790            }
791        }
792    }
793
794    /**
795     * Generate the appropriate read MemCmd based on the Request flags.
796     */
797    static MemCmd
798    makeReadCmd(const RequestPtr req)
799    {
800        if (req->isLLSC())
801            return MemCmd::LoadLockedReq;
802        else if (req->isPrefetch())
803            return MemCmd::SoftPFReq;
804        else
805            return MemCmd::ReadReq;
806    }
807
808    /**
809     * Generate the appropriate write MemCmd based on the Request flags.
810     */
811    static MemCmd
812    makeWriteCmd(const RequestPtr req)
813    {
814        if (req->isLLSC())
815            return MemCmd::StoreCondReq;
816        else if (req->isSwap())
817            return MemCmd::SwapReq;
818        else
819            return MemCmd::WriteReq;
820    }
821
822    /**
823     * Constructor-like methods that return Packets based on Request objects.
824     * Fine-tune the MemCmd type if it's not a vanilla read or write.
825     */
826    static PacketPtr
827    createRead(const RequestPtr req)
828    {
829        return new Packet(req, makeReadCmd(req));
830    }
831
832    static PacketPtr
833    createWrite(const RequestPtr req)
834    {
835        return new Packet(req, makeWriteCmd(req));
836    }
837
838    /**
839     * clean up packet variables
840     */
841    ~Packet()
842    {
843        // Delete the request object if this is a request packet which
844        // does not need a response, because the requester will not get
845        // a chance. If the request packet needs a response then the
846        // request will be deleted on receipt of the response
847        // packet. We also make sure to never delete the request for
848        // express snoops, even for cases when responses are not
849        // needed (CleanEvict and Writeback), since the snoop packet
850        // re-uses the same request.
851        if (req && isRequest() && !needsResponse() &&
852            !isExpressSnoop()) {
853            delete req;
854        }
855        deleteData();
856    }
857
858    /**
859     * Take a request packet and modify it in place to be suitable for
860     * returning as a response to that request.
861     */
862    void
863    makeResponse()
864    {
865        assert(needsResponse());
866        assert(isRequest());
867        cmd = cmd.responseCommand();
868
869        // responses are never express, even if the snoop that
870        // triggered them was
871        flags.clear(EXPRESS_SNOOP);
872    }
873
874    void
875    makeAtomicResponse()
876    {
877        makeResponse();
878    }
879
880    void
881    makeTimingResponse()
882    {
883        makeResponse();
884    }
885
886    void
887    setFunctionalResponseStatus(bool success)
888    {
889        if (!success) {
890            if (isWrite()) {
891                cmd = MemCmd::FunctionalWriteError;
892            } else {
893                cmd = MemCmd::FunctionalReadError;
894            }
895        }
896    }
897
898    void
899    setSize(unsigned size)
900    {
901        assert(!flags.isSet(VALID_SIZE));
902
903        this->size = size;
904        flags.set(VALID_SIZE);
905    }
906
907
908  public:
909    /**
910     * @{
911     * @name Data accessor mehtods
912     */
913
914    /**
915     * Set the data pointer to the following value that should not be
916     * freed. Static data allows us to do a single memcpy even if
917     * multiple packets are required to get from source to destination
918     * and back. In essence the pointer is set calling dataStatic on
919     * the original packet, and whenever this packet is copied and
920     * forwarded the same pointer is passed on. When a packet
921     * eventually reaches the destination holding the data, it is
922     * copied once into the location originally set. On the way back
923     * to the source, no copies are necessary.
924     */
925    template <typename T>
926    void
927    dataStatic(T *p)
928    {
929        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
930        data = (PacketDataPtr)p;
931        flags.set(STATIC_DATA);
932    }
933
934    /**
935     * Set the data pointer to the following value that should not be
936     * freed. This version of the function allows the pointer passed
937     * to us to be const. To avoid issues down the line we cast the
938     * constness away, the alternative would be to keep both a const
939     * and non-const data pointer and cleverly choose between
940     * them. Note that this is only allowed for static data.
941     */
942    template <typename T>
943    void
944    dataStaticConst(const T *p)
945    {
946        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
947        data = const_cast<PacketDataPtr>(p);
948        flags.set(STATIC_DATA);
949    }
950
951    /**
952     * Set the data pointer to a value that should have delete []
953     * called on it. Dynamic data is local to this packet, and as the
954     * packet travels from source to destination, forwarded packets
955     * will allocate their own data. When a packet reaches the final
956     * destination it will populate the dynamic data of that specific
957     * packet, and on the way back towards the source, memcpy will be
958     * invoked in every step where a new packet was created e.g. in
959     * the caches. Ultimately when the response reaches the source a
960     * final memcpy is needed to extract the data from the packet
961     * before it is deallocated.
962     */
963    template <typename T>
964    void
965    dataDynamic(T *p)
966    {
967        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
968        data = (PacketDataPtr)p;
969        flags.set(DYNAMIC_DATA);
970    }
971
972    /**
973     * get a pointer to the data ptr.
974     */
975    template <typename T>
976    T*
977    getPtr()
978    {
979        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
980        return (T*)data;
981    }
982
983    template <typename T>
984    const T*
985    getConstPtr() const
986    {
987        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
988        return (const T*)data;
989    }
990
991    /**
992     * Get the data in the packet byte swapped from big endian to
993     * host endian.
994     */
995    template <typename T>
996    T getBE() const;
997
998    /**
999     * Get the data in the packet byte swapped from little endian to
1000     * host endian.
1001     */
1002    template <typename T>
1003    T getLE() const;
1004
1005    /**
1006     * Get the data in the packet byte swapped from the specified
1007     * endianness.
1008     */
1009    template <typename T>
1010    T get(ByteOrder endian) const;
1011
1012    /**
1013     * Get the data in the packet byte swapped from guest to host
1014     * endian.
1015     */
1016    template <typename T>
1017    T get() const;
1018
1019    /** Set the value in the data pointer to v as big endian. */
1020    template <typename T>
1021    void setBE(T v);
1022
1023    /** Set the value in the data pointer to v as little endian. */
1024    template <typename T>
1025    void setLE(T v);
1026
1027    /**
1028     * Set the value in the data pointer to v using the specified
1029     * endianness.
1030     */
1031    template <typename T>
1032    void set(T v, ByteOrder endian);
1033
1034    /** Set the value in the data pointer to v as guest endian. */
1035    template <typename T>
1036    void set(T v);
1037
1038    /**
1039     * Copy data into the packet from the provided pointer.
1040     */
1041    void
1042    setData(const uint8_t *p)
1043    {
1044        // we should never be copying data onto itself, which means we
1045        // must idenfity packets with static data, as they carry the
1046        // same pointer from source to destination and back
1047        assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA));
1048
1049        if (p != getPtr<uint8_t>())
1050            // for packet with allocated dynamic data, we copy data from
1051            // one to the other, e.g. a forwarded response to a response
1052            std::memcpy(getPtr<uint8_t>(), p, getSize());
1053    }
1054
1055    /**
1056     * Copy data into the packet from the provided block pointer,
1057     * which is aligned to the given block size.
1058     */
1059    void
1060    setDataFromBlock(const uint8_t *blk_data, int blkSize)
1061    {
1062        setData(blk_data + getOffset(blkSize));
1063    }
1064
1065    /**
1066     * Copy data from the packet to the provided block pointer, which
1067     * is aligned to the given block size.
1068     */
1069    void
1070    writeData(uint8_t *p) const
1071    {
1072        std::memcpy(p, getConstPtr<uint8_t>(), getSize());
1073    }
1074
1075    /**
1076     * Copy data from the packet to the memory at the provided pointer.
1077     */
1078    void
1079    writeDataToBlock(uint8_t *blk_data, int blkSize) const
1080    {
1081        writeData(blk_data + getOffset(blkSize));
1082    }
1083
1084    /**
1085     * delete the data pointed to in the data pointer. Ok to call to
1086     * matter how data was allocted.
1087     */
1088    void
1089    deleteData()
1090    {
1091        if (flags.isSet(DYNAMIC_DATA))
1092            delete [] data;
1093
1094        flags.clear(STATIC_DATA|DYNAMIC_DATA);
1095        data = NULL;
1096    }
1097
1098    /** Allocate memory for the packet. */
1099    void
1100    allocate()
1101    {
1102        // if either this command or the response command has a data
1103        // payload, actually allocate space
1104        if (hasData() || hasRespData()) {
1105            assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
1106            flags.set(DYNAMIC_DATA);
1107            data = new uint8_t[getSize()];
1108        }
1109    }
1110
1111    /** @} */
1112
1113  private: // Private data accessor methods
1114    /** Get the data in the packet without byte swapping. */
1115    template <typename T>
1116    T getRaw() const;
1117
1118    /** Set the value in the data pointer to v without byte swapping. */
1119    template <typename T>
1120    void setRaw(T v);
1121
1122  public:
1123    /**
1124     * Check a functional request against a memory value stored in
1125     * another packet (i.e. an in-transit request or
1126     * response). Returns true if the current packet is a read, and
1127     * the other packet provides the data, which is then copied to the
1128     * current packet. If the current packet is a write, and the other
1129     * packet intersects this one, then we update the data
1130     * accordingly.
1131     */
1132    bool
1133    checkFunctional(PacketPtr other)
1134    {
1135        // all packets that are carrying a payload should have a valid
1136        // data pointer
1137        return checkFunctional(other, other->getAddr(), other->isSecure(),
1138                               other->getSize(),
1139                               other->hasData() ?
1140                               other->getPtr<uint8_t>() : NULL);
1141    }
1142
1143    /**
1144     * Does the request need to check for cached copies of the same block
1145     * in the memory hierarchy above.
1146     **/
1147    bool
1148    mustCheckAbove() const
1149    {
1150        return cmd == MemCmd::HardPFReq || isEviction();
1151    }
1152
1153    /**
1154     * Is this packet a clean eviction, including both actual clean
1155     * evict packets, but also clean writebacks.
1156     */
1157    bool
1158    isCleanEviction() const
1159    {
1160        return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
1161    }
1162
1163    /**
1164     * Check a functional request against a memory value represented
1165     * by a base/size pair and an associated data array. If the
1166     * current packet is a read, it may be satisfied by the memory
1167     * value. If the current packet is a write, it may update the
1168     * memory value.
1169     */
1170    bool
1171    checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
1172                    uint8_t *_data);
1173
1174    /**
1175     * Push label for PrintReq (safe to call unconditionally).
1176     */
1177    void
1178    pushLabel(const std::string &lbl)
1179    {
1180        if (isPrint())
1181            safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
1182    }
1183
1184    /**
1185     * Pop label for PrintReq (safe to call unconditionally).
1186     */
1187    void
1188    popLabel()
1189    {
1190        if (isPrint())
1191            safe_cast<PrintReqState*>(senderState)->popLabel();
1192    }
1193
1194    void print(std::ostream &o, int verbosity = 0,
1195               const std::string &prefix = "") const;
1196
1197    /**
1198     * A no-args wrapper of print(std::ostream...)
1199     * meant to be invoked from DPRINTFs
1200     * avoiding string overheads in fast mode
1201     * @return string with the request's type and start<->end addresses
1202     */
1203    std::string print() const;
1204};
1205
1206#endif //__MEM_PACKET_HH
1207