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