packet.hh revision 13347
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    //@{
557    /// Snoop flags
558    /**
559     * Set the cacheResponding flag. This is used by the caches to
560     * signal another cache that they are responding to a request. A
561     * cache will only respond to snoops if it has the line in either
562     * Modified or Owned state. Note that on snoop hits we always pass
563     * the line as Modified and never Owned. In the case of an Owned
564     * line we proceed to invalidate all other copies.
565     *
566     * On a cache fill (see Cache::handleFill), we check hasSharers
567     * first, ignoring the cacheResponding flag if hasSharers is set.
568     * A line is consequently allocated as:
569     *
570     * hasSharers cacheResponding state
571     * true       false           Shared
572     * true       true            Shared
573     * false      false           Exclusive
574     * false      true            Modified
575     */
576    void setCacheResponding()
577    {
578        assert(isRequest());
579        assert(!flags.isSet(CACHE_RESPONDING));
580        flags.set(CACHE_RESPONDING);
581    }
582    bool cacheResponding() const { return flags.isSet(CACHE_RESPONDING); }
583    /**
584     * On fills, the hasSharers flag is used by the caches in
585     * combination with the cacheResponding flag, as clarified
586     * above. If the hasSharers flag is not set, the packet is passing
587     * writable. Thus, a response from a memory passes the line as
588     * writable by default.
589     *
590     * The hasSharers flag is also used by upstream caches to inform a
591     * downstream cache that they have the block (by calling
592     * setHasSharers on snoop request packets that hit in upstream
593     * cachs tags or MSHRs). If the snoop packet has sharers, a
594     * downstream cache is prevented from passing a dirty line upwards
595     * if it was not explicitly asked for a writable copy. See
596     * Cache::satisfyCpuSideRequest.
597     *
598     * The hasSharers flag is also used on writebacks, in
599     * combination with the WritbackClean or WritebackDirty commands,
600     * to allocate the block downstream either as:
601     *
602     * command        hasSharers state
603     * WritebackDirty false      Modified
604     * WritebackDirty true       Owned
605     * WritebackClean false      Exclusive
606     * WritebackClean true       Shared
607     */
608    void setHasSharers()    { flags.set(HAS_SHARERS); }
609    bool hasSharers() const { return flags.isSet(HAS_SHARERS); }
610    //@}
611
612    /**
613     * The express snoop flag is used for two purposes. Firstly, it is
614     * used to bypass flow control for normal (non-snoop) requests
615     * going downstream in the memory system. In cases where a cache
616     * is responding to a snoop from another cache (it had a dirty
617     * line), but the line is not writable (and there are possibly
618     * other copies), the express snoop flag is set by the downstream
619     * cache to invalidate all other copies in zero time. Secondly,
620     * the express snoop flag is also set to be able to distinguish
621     * snoop packets that came from a downstream cache, rather than
622     * snoop packets from neighbouring caches.
623     */
624    void setExpressSnoop()      { flags.set(EXPRESS_SNOOP); }
625    bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
626
627    /**
628     * On responding to a snoop request (which only happens for
629     * Modified or Owned lines), make sure that we can transform an
630     * Owned response to a Modified one. If this flag is not set, the
631     * responding cache had the line in the Owned state, and there are
632     * possibly other Shared copies in the memory system. A downstream
633     * cache helps in orchestrating the invalidation of these copies
634     * by sending out the appropriate express snoops.
635     */
636    void setResponderHadWritable()
637    {
638        assert(cacheResponding());
639        assert(!responderHadWritable());
640        flags.set(RESPONDER_HAD_WRITABLE);
641    }
642    bool responderHadWritable() const
643    { return flags.isSet(RESPONDER_HAD_WRITABLE); }
644
645    /**
646     * A writeback/writeclean cmd gets propagated further downstream
647     * by the receiver when the flag is set.
648     */
649    void setWriteThrough()
650    {
651        assert(cmd.isWrite() &&
652               (cmd.isEviction() || cmd == MemCmd::WriteClean));
653        flags.set(WRITE_THROUGH);
654    }
655    void clearWriteThrough() { flags.clear(WRITE_THROUGH); }
656    bool writeThrough() const { return flags.isSet(WRITE_THROUGH); }
657
658    /**
659     * Set when a request hits in a cache and the cache is not going
660     * to respond. This is used by the crossbar to coordinate
661     * responses for cache maintenance operations.
662     */
663    void setSatisfied()
664    {
665        assert(cmd.isClean());
666        assert(!flags.isSet(SATISFIED));
667        flags.set(SATISFIED);
668    }
669    bool satisfied() const { return flags.isSet(SATISFIED); }
670
671    void setSuppressFuncError()     { flags.set(SUPPRESS_FUNC_ERROR); }
672    bool suppressFuncError() const  { return flags.isSet(SUPPRESS_FUNC_ERROR); }
673    void setBlockCached()          { flags.set(BLOCK_CACHED); }
674    bool isBlockCached() const     { return flags.isSet(BLOCK_CACHED); }
675    void clearBlockCached()        { flags.clear(BLOCK_CACHED); }
676
677    /**
678     * QoS Value getter
679     * Returns 0 if QoS value was never set (constructor default).
680     *
681     * @return QoS priority value of the packet
682     */
683    inline uint8_t qosValue() const { return _qosValue; }
684
685    /**
686     * QoS Value setter
687     * Interface for setting QoS priority value of the packet.
688     *
689     * @param qos_value QoS priority value
690     */
691    inline void qosValue(const uint8_t qos_value)
692    { _qosValue = qos_value; }
693
694    inline MasterID masterId() const { return req->masterId(); }
695
696    // Network error conditions... encapsulate them as methods since
697    // their encoding keeps changing (from result field to command
698    // field, etc.)
699    void
700    setBadAddress()
701    {
702        assert(isResponse());
703        cmd = MemCmd::BadAddressError;
704    }
705
706    void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
707
708    Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
709    /**
710     * Update the address of this packet mid-transaction. This is used
711     * by the address mapper to change an already set address to a new
712     * one based on the system configuration. It is intended to remap
713     * an existing address, so it asserts that the current address is
714     * valid.
715     */
716    void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
717
718    unsigned getSize() const  { assert(flags.isSet(VALID_SIZE)); return size; }
719
720    Addr getOffset(unsigned int blk_size) const
721    {
722        return getAddr() & Addr(blk_size - 1);
723    }
724
725    Addr getBlockAddr(unsigned int blk_size) const
726    {
727        return getAddr() & ~(Addr(blk_size - 1));
728    }
729
730    bool isSecure() const
731    {
732        assert(flags.isSet(VALID_ADDR));
733        return _isSecure;
734    }
735
736    /**
737     * Accessor function to atomic op.
738     */
739    AtomicOpFunctor *getAtomicOp() const { return req->getAtomicOpFunctor(); }
740    bool isAtomicOp() const { return req->isAtomic(); }
741
742    /**
743     * It has been determined that the SC packet should successfully update
744     * memory. Therefore, convert this SC packet to a normal write.
745     */
746    void
747    convertScToWrite()
748    {
749        assert(isLLSC());
750        assert(isWrite());
751        cmd = MemCmd::WriteReq;
752    }
753
754    /**
755     * When ruby is in use, Ruby will monitor the cache line and the
756     * phys memory should treat LL ops as normal reads.
757     */
758    void
759    convertLlToRead()
760    {
761        assert(isLLSC());
762        assert(isRead());
763        cmd = MemCmd::ReadReq;
764    }
765
766    /**
767     * Constructor. Note that a Request object must be constructed
768     * first, but the Requests's physical address and size fields need
769     * not be valid. The command must be supplied.
770     */
771    Packet(const RequestPtr &_req, MemCmd _cmd)
772        :  cmd(_cmd), id((PacketId)_req.get()), req(_req),
773           data(nullptr), addr(0), _isSecure(false), size(0),
774           _qosValue(0), headerDelay(0), snoopDelay(0),
775           payloadDelay(0), senderState(NULL)
776    {
777        if (req->hasPaddr()) {
778            addr = req->getPaddr();
779            flags.set(VALID_ADDR);
780            _isSecure = req->isSecure();
781        }
782        if (req->hasSize()) {
783            size = req->getSize();
784            flags.set(VALID_SIZE);
785        }
786    }
787
788    /**
789     * Alternate constructor if you are trying to create a packet with
790     * a request that is for a whole block, not the address from the
791     * req.  this allows for overriding the size/addr of the req.
792     */
793    Packet(const RequestPtr &_req, MemCmd _cmd, int _blkSize, PacketId _id = 0)
794        :  cmd(_cmd), id(_id ? _id : (PacketId)_req.get()), req(_req),
795           data(nullptr), addr(0), _isSecure(false),
796           _qosValue(0), headerDelay(0),
797           snoopDelay(0), payloadDelay(0), senderState(NULL)
798    {
799        if (req->hasPaddr()) {
800            addr = req->getPaddr() & ~(_blkSize - 1);
801            flags.set(VALID_ADDR);
802            _isSecure = req->isSecure();
803        }
804        size = _blkSize;
805        flags.set(VALID_SIZE);
806    }
807
808    /**
809     * Alternate constructor for copying a packet.  Copy all fields
810     * *except* if the original packet's data was dynamic, don't copy
811     * that, as we can't guarantee that the new packet's lifetime is
812     * less than that of the original packet.  In this case the new
813     * packet should allocate its own data.
814     */
815    Packet(const PacketPtr pkt, bool clear_flags, bool alloc_data)
816        :  cmd(pkt->cmd), id(pkt->id), req(pkt->req),
817           data(nullptr),
818           addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
819           bytesValid(pkt->bytesValid),
820           _qosValue(pkt->qosValue()),
821           headerDelay(pkt->headerDelay),
822           snoopDelay(0),
823           payloadDelay(pkt->payloadDelay),
824           senderState(pkt->senderState)
825    {
826        if (!clear_flags)
827            flags.set(pkt->flags & COPY_FLAGS);
828
829        flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
830
831        // should we allocate space for data, or not, the express
832        // snoops do not need to carry any data as they only serve to
833        // co-ordinate state changes
834        if (alloc_data) {
835            // even if asked to allocate data, if the original packet
836            // holds static data, then the sender will not be doing
837            // any memcpy on receiving the response, thus we simply
838            // carry the pointer forward
839            if (pkt->flags.isSet(STATIC_DATA)) {
840                data = pkt->data;
841                flags.set(STATIC_DATA);
842            } else {
843                allocate();
844            }
845        }
846    }
847
848    /**
849     * Generate the appropriate read MemCmd based on the Request flags.
850     */
851    static MemCmd
852    makeReadCmd(const RequestPtr &req)
853    {
854        if (req->isLLSC())
855            return MemCmd::LoadLockedReq;
856        else if (req->isPrefetch())
857            return MemCmd::SoftPFReq;
858        else
859            return MemCmd::ReadReq;
860    }
861
862    /**
863     * Generate the appropriate write MemCmd based on the Request flags.
864     */
865    static MemCmd
866    makeWriteCmd(const RequestPtr &req)
867    {
868        if (req->isLLSC())
869            return MemCmd::StoreCondReq;
870        else if (req->isSwap() || req->isAtomic())
871            return MemCmd::SwapReq;
872        else if (req->isCacheInvalidate()) {
873          return req->isCacheClean() ? MemCmd::CleanInvalidReq :
874              MemCmd::InvalidateReq;
875        } else if (req->isCacheClean()) {
876            return MemCmd::CleanSharedReq;
877        } else
878            return MemCmd::WriteReq;
879    }
880
881    /**
882     * Constructor-like methods that return Packets based on Request objects.
883     * Fine-tune the MemCmd type if it's not a vanilla read or write.
884     */
885    static PacketPtr
886    createRead(const RequestPtr &req)
887    {
888        return new Packet(req, makeReadCmd(req));
889    }
890
891    static PacketPtr
892    createWrite(const RequestPtr &req)
893    {
894        return new Packet(req, makeWriteCmd(req));
895    }
896
897    /**
898     * clean up packet variables
899     */
900    ~Packet()
901    {
902        deleteData();
903    }
904
905    /**
906     * Take a request packet and modify it in place to be suitable for
907     * returning as a response to that request.
908     */
909    void
910    makeResponse()
911    {
912        assert(needsResponse());
913        assert(isRequest());
914        cmd = cmd.responseCommand();
915
916        // responses are never express, even if the snoop that
917        // triggered them was
918        flags.clear(EXPRESS_SNOOP);
919    }
920
921    void
922    makeAtomicResponse()
923    {
924        makeResponse();
925    }
926
927    void
928    makeTimingResponse()
929    {
930        makeResponse();
931    }
932
933    void
934    setFunctionalResponseStatus(bool success)
935    {
936        if (!success) {
937            if (isWrite()) {
938                cmd = MemCmd::FunctionalWriteError;
939            } else {
940                cmd = MemCmd::FunctionalReadError;
941            }
942        }
943    }
944
945    void
946    setSize(unsigned size)
947    {
948        assert(!flags.isSet(VALID_SIZE));
949
950        this->size = size;
951        flags.set(VALID_SIZE);
952    }
953
954
955  public:
956    /**
957     * @{
958     * @name Data accessor mehtods
959     */
960
961    /**
962     * Set the data pointer to the following value that should not be
963     * freed. Static data allows us to do a single memcpy even if
964     * multiple packets are required to get from source to destination
965     * and back. In essence the pointer is set calling dataStatic on
966     * the original packet, and whenever this packet is copied and
967     * forwarded the same pointer is passed on. When a packet
968     * eventually reaches the destination holding the data, it is
969     * copied once into the location originally set. On the way back
970     * to the source, no copies are necessary.
971     */
972    template <typename T>
973    void
974    dataStatic(T *p)
975    {
976        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
977        data = (PacketDataPtr)p;
978        flags.set(STATIC_DATA);
979    }
980
981    /**
982     * Set the data pointer to the following value that should not be
983     * freed. This version of the function allows the pointer passed
984     * to us to be const. To avoid issues down the line we cast the
985     * constness away, the alternative would be to keep both a const
986     * and non-const data pointer and cleverly choose between
987     * them. Note that this is only allowed for static data.
988     */
989    template <typename T>
990    void
991    dataStaticConst(const T *p)
992    {
993        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
994        data = const_cast<PacketDataPtr>(p);
995        flags.set(STATIC_DATA);
996    }
997
998    /**
999     * Set the data pointer to a value that should have delete []
1000     * called on it. Dynamic data is local to this packet, and as the
1001     * packet travels from source to destination, forwarded packets
1002     * will allocate their own data. When a packet reaches the final
1003     * destination it will populate the dynamic data of that specific
1004     * packet, and on the way back towards the source, memcpy will be
1005     * invoked in every step where a new packet was created e.g. in
1006     * the caches. Ultimately when the response reaches the source a
1007     * final memcpy is needed to extract the data from the packet
1008     * before it is deallocated.
1009     */
1010    template <typename T>
1011    void
1012    dataDynamic(T *p)
1013    {
1014        assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
1015        data = (PacketDataPtr)p;
1016        flags.set(DYNAMIC_DATA);
1017    }
1018
1019    /**
1020     * get a pointer to the data ptr.
1021     */
1022    template <typename T>
1023    T*
1024    getPtr()
1025    {
1026        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
1027        return (T*)data;
1028    }
1029
1030    template <typename T>
1031    const T*
1032    getConstPtr() const
1033    {
1034        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
1035        return (const T*)data;
1036    }
1037
1038    /**
1039     * Get the data in the packet byte swapped from big endian to
1040     * host endian.
1041     */
1042    template <typename T>
1043    T getBE() const;
1044
1045    /**
1046     * Get the data in the packet byte swapped from little endian to
1047     * host endian.
1048     */
1049    template <typename T>
1050    T getLE() const;
1051
1052    /**
1053     * Get the data in the packet byte swapped from the specified
1054     * endianness.
1055     */
1056    template <typename T>
1057    T get(ByteOrder endian) const;
1058
1059#if THE_ISA != NULL_ISA
1060    /**
1061     * Get the data in the packet byte swapped from guest to host
1062     * endian.
1063     */
1064    template <typename T>
1065    T get() const;
1066#endif
1067
1068    /** Set the value in the data pointer to v as big endian. */
1069    template <typename T>
1070    void setBE(T v);
1071
1072    /** Set the value in the data pointer to v as little endian. */
1073    template <typename T>
1074    void setLE(T v);
1075
1076    /**
1077     * Set the value in the data pointer to v using the specified
1078     * endianness.
1079     */
1080    template <typename T>
1081    void set(T v, ByteOrder endian);
1082
1083#if THE_ISA != NULL_ISA
1084    /** Set the value in the data pointer to v as guest endian. */
1085    template <typename T>
1086    void set(T v);
1087#endif
1088
1089
1090    /**
1091     * Get the data in the packet byte swapped from the specified
1092     * endianness and zero-extended to 64 bits.
1093     */
1094    uint64_t getUintX(ByteOrder endian) const;
1095
1096    /**
1097     * Set the value in the word w after truncating it to the length
1098     * of the packet and then byteswapping it to the desired
1099     * endianness.
1100     */
1101    void setUintX(uint64_t w, ByteOrder endian);
1102
1103    /**
1104     * Copy data into the packet from the provided pointer.
1105     */
1106    void
1107    setData(const uint8_t *p)
1108    {
1109        // we should never be copying data onto itself, which means we
1110        // must idenfity packets with static data, as they carry the
1111        // same pointer from source to destination and back
1112        assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA));
1113
1114        if (p != getPtr<uint8_t>())
1115            // for packet with allocated dynamic data, we copy data from
1116            // one to the other, e.g. a forwarded response to a response
1117            std::memcpy(getPtr<uint8_t>(), p, getSize());
1118    }
1119
1120    /**
1121     * Copy data into the packet from the provided block pointer,
1122     * which is aligned to the given block size.
1123     */
1124    void
1125    setDataFromBlock(const uint8_t *blk_data, int blkSize)
1126    {
1127        setData(blk_data + getOffset(blkSize));
1128    }
1129
1130    /**
1131     * Copy data from the packet to the memory at the provided pointer.
1132     * @param p Pointer to which data will be copied.
1133     */
1134    void
1135    writeData(uint8_t *p) const
1136    {
1137        std::memcpy(p, getConstPtr<uint8_t>(), getSize());
1138    }
1139
1140    /**
1141     * Copy data from the packet to the provided block pointer, which
1142     * is aligned to the given block size.
1143     * @param blk_data Pointer to block to which data will be copied.
1144     * @param blkSize Block size in bytes.
1145     */
1146    void
1147    writeDataToBlock(uint8_t *blk_data, int blkSize) const
1148    {
1149        writeData(blk_data + getOffset(blkSize));
1150    }
1151
1152    /**
1153     * delete the data pointed to in the data pointer. Ok to call to
1154     * matter how data was allocted.
1155     */
1156    void
1157    deleteData()
1158    {
1159        if (flags.isSet(DYNAMIC_DATA))
1160            delete [] data;
1161
1162        flags.clear(STATIC_DATA|DYNAMIC_DATA);
1163        data = NULL;
1164    }
1165
1166    /** Allocate memory for the packet. */
1167    void
1168    allocate()
1169    {
1170        // if either this command or the response command has a data
1171        // payload, actually allocate space
1172        if (hasData() || hasRespData()) {
1173            assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA));
1174            flags.set(DYNAMIC_DATA);
1175            data = new uint8_t[getSize()];
1176        }
1177    }
1178
1179    /** @} */
1180
1181    /** Get the data in the packet without byte swapping. */
1182    template <typename T>
1183    T getRaw() const;
1184
1185    /** Set the value in the data pointer to v without byte swapping. */
1186    template <typename T>
1187    void setRaw(T v);
1188
1189  public:
1190    /**
1191     * Check a functional request against a memory value stored in
1192     * another packet (i.e. an in-transit request or
1193     * response). Returns true if the current packet is a read, and
1194     * the other packet provides the data, which is then copied to the
1195     * current packet. If the current packet is a write, and the other
1196     * packet intersects this one, then we update the data
1197     * accordingly.
1198     */
1199    bool
1200    trySatisfyFunctional(PacketPtr other)
1201    {
1202        // all packets that are carrying a payload should have a valid
1203        // data pointer
1204        return trySatisfyFunctional(other, other->getAddr(), other->isSecure(),
1205                                    other->getSize(),
1206                                    other->hasData() ?
1207                                    other->getPtr<uint8_t>() : NULL);
1208    }
1209
1210    /**
1211     * Does the request need to check for cached copies of the same block
1212     * in the memory hierarchy above.
1213     **/
1214    bool
1215    mustCheckAbove() const
1216    {
1217        return cmd == MemCmd::HardPFReq || isEviction();
1218    }
1219
1220    /**
1221     * Is this packet a clean eviction, including both actual clean
1222     * evict packets, but also clean writebacks.
1223     */
1224    bool
1225    isCleanEviction() const
1226    {
1227        return cmd == MemCmd::CleanEvict || cmd == MemCmd::WritebackClean;
1228    }
1229
1230    /**
1231     * Check a functional request against a memory value represented
1232     * by a base/size pair and an associated data array. If the
1233     * current packet is a read, it may be satisfied by the memory
1234     * value. If the current packet is a write, it may update the
1235     * memory value.
1236     */
1237    bool
1238    trySatisfyFunctional(Printable *obj, Addr base, bool is_secure, int size,
1239                         uint8_t *_data);
1240
1241    /**
1242     * Push label for PrintReq (safe to call unconditionally).
1243     */
1244    void
1245    pushLabel(const std::string &lbl)
1246    {
1247        if (isPrint())
1248            safe_cast<PrintReqState*>(senderState)->pushLabel(lbl);
1249    }
1250
1251    /**
1252     * Pop label for PrintReq (safe to call unconditionally).
1253     */
1254    void
1255    popLabel()
1256    {
1257        if (isPrint())
1258            safe_cast<PrintReqState*>(senderState)->popLabel();
1259    }
1260
1261    void print(std::ostream &o, int verbosity = 0,
1262               const std::string &prefix = "") const;
1263
1264    /**
1265     * A no-args wrapper of print(std::ostream...)
1266     * meant to be invoked from DPRINTFs
1267     * avoiding string overheads in fast mode
1268     * @return string with the request's type and start<->end addresses
1269     */
1270    std::string print() const;
1271};
1272
1273#endif //__MEM_PACKET_HH
1274