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