12381SN/A/*
212917Sstacze01@arm.com * Copyright (c) 2012-2013,2017-2018 ARM Limited
39332Sdam.sunwoo@arm.com * All rights reserved
49332Sdam.sunwoo@arm.com *
59332Sdam.sunwoo@arm.com * The license below extends only to copyright in the software and shall
69332Sdam.sunwoo@arm.com * not be construed as granting a license to any other intellectual
79332Sdam.sunwoo@arm.com * property including but not limited to intellectual property relating
89332Sdam.sunwoo@arm.com * to a hardware implementation of the functionality of the software
99332Sdam.sunwoo@arm.com * licensed hereunder.  You may use the software subject to the license
109332Sdam.sunwoo@arm.com * terms below provided that you ensure that this notice is replicated
119332Sdam.sunwoo@arm.com * unmodified and in its entirety in all distributions of the software,
129332Sdam.sunwoo@arm.com * modified or unmodified, in source code or in binary form.
139332Sdam.sunwoo@arm.com *
142381SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
1510975Sdavid.hashe@amd.com * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
162381SN/A * All rights reserved.
172381SN/A *
182381SN/A * Redistribution and use in source and binary forms, with or without
192381SN/A * modification, are permitted provided that the following conditions are
202381SN/A * met: redistributions of source code must retain the above copyright
212381SN/A * notice, this list of conditions and the following disclaimer;
222381SN/A * redistributions in binary form must reproduce the above copyright
232381SN/A * notice, this list of conditions and the following disclaimer in the
242381SN/A * documentation and/or other materials provided with the distribution;
252381SN/A * neither the name of the copyright holders nor the names of its
262381SN/A * contributors may be used to endorse or promote products derived from
272381SN/A * this software without specific prior written permission.
282381SN/A *
292381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402665Ssaidi@eecs.umich.edu *
412665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
422665Ssaidi@eecs.umich.edu *          Steve Reinhardt
432665Ssaidi@eecs.umich.edu *          Ali Saidi
442381SN/A */
452381SN/A
462381SN/A/**
472982Sstever@eecs.umich.edu * @file
482982Sstever@eecs.umich.edu * Declaration of a request, the overall memory request consisting of
492381SN/A the parts of the request that are persistent throughout the transaction.
502381SN/A */
512381SN/A
522381SN/A#ifndef __MEM_REQUEST_HH__
532381SN/A#define __MEM_REQUEST_HH__
542381SN/A
555735Snate@binkert.org#include <cassert>
568833Sdam.sunwoo@arm.com#include <climits>
575735Snate@binkert.org
585735Snate@binkert.org#include "base/flags.hh"
5912334Sgabeblack@google.com#include "base/logging.hh"
606214Snate@binkert.org#include "base/types.hh"
6111248Sradhika.jagtap@ARM.com#include "cpu/inst_seq.hh"
624167Sbinkertn@umich.edu#include "sim/core.hh"
632394SN/A
649332Sdam.sunwoo@arm.com/**
659332Sdam.sunwoo@arm.com * Special TaskIds that are used for per-context-switch stats dumps
669332Sdam.sunwoo@arm.com * and Cache Occupancy. Having too many tasks seems to be a problem
679332Sdam.sunwoo@arm.com * with vector stats. 1024 seems to be a reasonable number that
689332Sdam.sunwoo@arm.com * doesn't cause a problem with stats and is large enough to realistic
699332Sdam.sunwoo@arm.com * benchmarks (Linux/Android boot, BBench, etc.)
709332Sdam.sunwoo@arm.com */
719332Sdam.sunwoo@arm.com
729332Sdam.sunwoo@arm.comnamespace ContextSwitchTaskId {
739332Sdam.sunwoo@arm.com    enum TaskId {
749332Sdam.sunwoo@arm.com        MaxNormalTaskId = 1021, /* Maximum number of normal tasks */
759332Sdam.sunwoo@arm.com        Prefetcher = 1022, /* For cache lines brought in by prefetcher */
769332Sdam.sunwoo@arm.com        DMA = 1023, /* Mostly Table Walker */
779332Sdam.sunwoo@arm.com        Unknown = 1024,
789332Sdam.sunwoo@arm.com        NumTaskId
799332Sdam.sunwoo@arm.com    };
809332Sdam.sunwoo@arm.com}
819332Sdam.sunwoo@arm.com
822394SN/Aclass Request;
832394SN/A
8412749Sgiacomo.travaglini@arm.comtypedef std::shared_ptr<Request> RequestPtr;
858832SAli.Saidi@ARM.comtypedef uint16_t MasterID;
862394SN/A
879044SAli.Saidi@ARM.comclass Request
882381SN/A{
895735Snate@binkert.org  public:
9012346Snikos.nikoleris@arm.com    typedef uint64_t FlagsType;
919912Sandreas@sandberg.pp.se    typedef uint8_t ArchFlagsType;
925735Snate@binkert.org    typedef ::Flags<FlagsType> Flags;
935735Snate@binkert.org
9410882Sandreas.hansson@arm.com    enum : FlagsType {
9510882Sandreas.hansson@arm.com        /**
9610882Sandreas.hansson@arm.com         * Architecture specific flags.
9710882Sandreas.hansson@arm.com         *
9810882Sandreas.hansson@arm.com         * These bits int the flag field are reserved for
9910882Sandreas.hansson@arm.com         * architecture-specific code. For example, SPARC uses them to
10010882Sandreas.hansson@arm.com         * represent ASIs.
10110882Sandreas.hansson@arm.com         */
10211003Sandreas.hansson@arm.com        ARCH_BITS                   = 0x000000FF,
10310882Sandreas.hansson@arm.com        /** The request was an instruction fetch. */
10411003Sandreas.hansson@arm.com        INST_FETCH                  = 0x00000100,
10510882Sandreas.hansson@arm.com        /** The virtual address is also the physical address. */
10611003Sandreas.hansson@arm.com        PHYSICAL                    = 0x00000200,
10710882Sandreas.hansson@arm.com        /**
10810882Sandreas.hansson@arm.com         * The request is to an uncacheable address.
10910882Sandreas.hansson@arm.com         *
11010882Sandreas.hansson@arm.com         * @note Uncacheable accesses may be reordered by CPU models. The
11110882Sandreas.hansson@arm.com         * STRICT_ORDER flag should be set if such reordering is
11210882Sandreas.hansson@arm.com         * undesirable.
11310882Sandreas.hansson@arm.com         */
11411003Sandreas.hansson@arm.com        UNCACHEABLE                = 0x00000400,
11510882Sandreas.hansson@arm.com        /**
11610882Sandreas.hansson@arm.com         * The request is required to be strictly ordered by <i>CPU
11710882Sandreas.hansson@arm.com         * models</i> and is non-speculative.
11810882Sandreas.hansson@arm.com         *
11910882Sandreas.hansson@arm.com         * A strictly ordered request is guaranteed to never be
12010882Sandreas.hansson@arm.com         * re-ordered or executed speculatively by a CPU model. The
12110882Sandreas.hansson@arm.com         * memory system may still reorder requests in caches unless
12210882Sandreas.hansson@arm.com         * the UNCACHEABLE flag is set as well.
12310882Sandreas.hansson@arm.com         */
12411003Sandreas.hansson@arm.com        STRICT_ORDER                = 0x00000800,
12510882Sandreas.hansson@arm.com        /** This request is to a memory mapped register. */
12611003Sandreas.hansson@arm.com        MMAPPED_IPR                 = 0x00002000,
12710882Sandreas.hansson@arm.com        /** This request is made in privileged mode. */
12811003Sandreas.hansson@arm.com        PRIVILEGED                  = 0x00008000,
1296133Ssteve.reinhardt@amd.com
13010882Sandreas.hansson@arm.com        /**
13110882Sandreas.hansson@arm.com         * This is a write that is targeted and zeroing an entire
13210882Sandreas.hansson@arm.com         * cache block.  There is no need for a read/modify/write
13310882Sandreas.hansson@arm.com         */
13411003Sandreas.hansson@arm.com        CACHE_BLOCK_ZERO            = 0x00010000,
13510031SAli.Saidi@ARM.com
13610882Sandreas.hansson@arm.com        /** The request should not cause a memory access. */
13711003Sandreas.hansson@arm.com        NO_ACCESS                   = 0x00080000,
13810882Sandreas.hansson@arm.com        /**
13910882Sandreas.hansson@arm.com         * This request will lock or unlock the accessed memory. When
14010882Sandreas.hansson@arm.com         * used with a load, the access locks the particular chunk of
14110882Sandreas.hansson@arm.com         * memory. When used with a store, it unlocks. The rule is
14210882Sandreas.hansson@arm.com         * that locked accesses have to be made up of a locked load,
14310882Sandreas.hansson@arm.com         * some operation on the data, and then a locked store.
14410882Sandreas.hansson@arm.com         */
14511003Sandreas.hansson@arm.com        LOCKED_RMW                  = 0x00100000,
14610882Sandreas.hansson@arm.com        /** The request is a Load locked/store conditional. */
14711003Sandreas.hansson@arm.com        LLSC                        = 0x00200000,
14810882Sandreas.hansson@arm.com        /** This request is for a memory swap. */
14911003Sandreas.hansson@arm.com        MEM_SWAP                    = 0x00400000,
15011003Sandreas.hansson@arm.com        MEM_SWAP_COND               = 0x00800000,
1516133Ssteve.reinhardt@amd.com
15210882Sandreas.hansson@arm.com        /** The request is a prefetch. */
15311003Sandreas.hansson@arm.com        PREFETCH                    = 0x01000000,
15410882Sandreas.hansson@arm.com        /** The request should be prefetched into the exclusive state. */
15511003Sandreas.hansson@arm.com        PF_EXCLUSIVE                = 0x02000000,
15610882Sandreas.hansson@arm.com        /** The request should be marked as LRU. */
15711003Sandreas.hansson@arm.com        EVICT_NEXT                  = 0x04000000,
15811269Sdavid.hashe@amd.com        /** The request should be marked with ACQUIRE. */
15911269Sdavid.hashe@amd.com        ACQUIRE                     = 0x00020000,
16011269Sdavid.hashe@amd.com        /** The request should be marked with RELEASE. */
16111269Sdavid.hashe@amd.com        RELEASE                     = 0x00040000,
1625735Snate@binkert.org
16311306Santhony.gutierrez@amd.com        /** The request is an atomic that returns data. */
16411306Santhony.gutierrez@amd.com        ATOMIC_RETURN_OP            = 0x40000000,
16511306Santhony.gutierrez@amd.com        /** The request is an atomic that does not return data. */
16611306Santhony.gutierrez@amd.com        ATOMIC_NO_RETURN_OP         = 0x80000000,
16711306Santhony.gutierrez@amd.com
16811305Sblake.hechtman@amd.com        /** The request should be marked with KERNEL.
16911305Sblake.hechtman@amd.com          * Used to indicate the synchronization associated with a GPU kernel
17011305Sblake.hechtman@amd.com          * launch or completion.
17111305Sblake.hechtman@amd.com          */
17211305Sblake.hechtman@amd.com        KERNEL                      = 0x00001000,
17311305Sblake.hechtman@amd.com
17410882Sandreas.hansson@arm.com        /**
17510882Sandreas.hansson@arm.com         * The request should be handled by the generic IPR code (only
17610882Sandreas.hansson@arm.com         * valid together with MMAPPED_IPR)
17710882Sandreas.hansson@arm.com         */
17811003Sandreas.hansson@arm.com        GENERIC_IPR                 = 0x08000000,
1799911Sandreas@sandberg.pp.se
18010882Sandreas.hansson@arm.com        /** The request targets the secure memory space. */
18111003Sandreas.hansson@arm.com        SECURE                      = 0x10000000,
18210882Sandreas.hansson@arm.com        /** The request is a page table walk */
18311003Sandreas.hansson@arm.com        PT_WALK                     = 0x20000000,
18410028SGiacomo.Gabrielli@arm.com
18512347Snikos.nikoleris@arm.com        /** The request invalidates a memory location */
18612347Snikos.nikoleris@arm.com        INVALIDATE                  = 0x0000000100000000,
18712347Snikos.nikoleris@arm.com        /** The request cleans a memory location */
18812347Snikos.nikoleris@arm.com        CLEAN                       = 0x0000000200000000,
18912347Snikos.nikoleris@arm.com
19012346Snikos.nikoleris@arm.com        /** The request targets the point of unification */
19112346Snikos.nikoleris@arm.com        DST_POU                     = 0x0000001000000000,
19212346Snikos.nikoleris@arm.com
19312346Snikos.nikoleris@arm.com        /** The request targets the point of coherence */
19412346Snikos.nikoleris@arm.com        DST_POC                     = 0x0000002000000000,
19512346Snikos.nikoleris@arm.com
19612346Snikos.nikoleris@arm.com        /** Bits to define the destination of a request */
19712346Snikos.nikoleris@arm.com        DST_BITS                    = 0x0000003000000000,
19812346Snikos.nikoleris@arm.com
19910882Sandreas.hansson@arm.com        /**
20010882Sandreas.hansson@arm.com         * These flags are *not* cleared when a Request object is
20110882Sandreas.hansson@arm.com         * reused (assigned a new address).
20210882Sandreas.hansson@arm.com         */
20310882Sandreas.hansson@arm.com        STICKY_FLAGS = INST_FETCH
20410882Sandreas.hansson@arm.com    };
20512355Snikos.nikoleris@arm.com    static const FlagsType STORE_NO_DATA = CACHE_BLOCK_ZERO |
20612355Snikos.nikoleris@arm.com        CLEAN | INVALIDATE;
2076104Ssteve.reinhardt@amd.com
20810882Sandreas.hansson@arm.com    /** Master Ids that are statically allocated
2098832SAli.Saidi@ARM.com     * @{*/
21010882Sandreas.hansson@arm.com    enum : MasterID {
21110882Sandreas.hansson@arm.com        /** This master id is used for writeback requests by the caches */
21210882Sandreas.hansson@arm.com        wbMasterId = 0,
21310882Sandreas.hansson@arm.com        /**
21410882Sandreas.hansson@arm.com         * This master id is used for functional requests that
21510882Sandreas.hansson@arm.com         * don't come from a particular device
21610882Sandreas.hansson@arm.com         */
21710882Sandreas.hansson@arm.com        funcMasterId = 1,
21810882Sandreas.hansson@arm.com        /** This master id is used for message signaled interrupts */
21910882Sandreas.hansson@arm.com        intMasterId = 2,
22010882Sandreas.hansson@arm.com        /**
22110882Sandreas.hansson@arm.com         * Invalid master id for assertion checking only. It is
22210882Sandreas.hansson@arm.com         * invalid behavior to ever send this id as part of a request.
22310882Sandreas.hansson@arm.com         */
22410882Sandreas.hansson@arm.com        invldMasterId = std::numeric_limits<MasterID>::max()
22510882Sandreas.hansson@arm.com    };
2268832SAli.Saidi@ARM.com    /** @} */
2278832SAli.Saidi@ARM.com
22811305Sblake.hechtman@amd.com    typedef uint32_t MemSpaceConfigFlagsType;
22911305Sblake.hechtman@amd.com    typedef ::Flags<MemSpaceConfigFlagsType> MemSpaceConfigFlags;
23011305Sblake.hechtman@amd.com
23111305Sblake.hechtman@amd.com    enum : MemSpaceConfigFlagsType {
23211305Sblake.hechtman@amd.com        /** Has a synchronization scope been set? */
23311305Sblake.hechtman@amd.com        SCOPE_VALID            = 0x00000001,
23411305Sblake.hechtman@amd.com        /** Access has Wavefront scope visibility */
23511305Sblake.hechtman@amd.com        WAVEFRONT_SCOPE        = 0x00000002,
23611305Sblake.hechtman@amd.com        /** Access has Workgroup scope visibility */
23711305Sblake.hechtman@amd.com        WORKGROUP_SCOPE        = 0x00000004,
23811305Sblake.hechtman@amd.com        /** Access has Device (e.g., GPU) scope visibility */
23911305Sblake.hechtman@amd.com        DEVICE_SCOPE           = 0x00000008,
24011305Sblake.hechtman@amd.com        /** Access has System (e.g., CPU + GPU) scope visibility */
24111305Sblake.hechtman@amd.com        SYSTEM_SCOPE           = 0x00000010,
24211305Sblake.hechtman@amd.com
24311305Sblake.hechtman@amd.com        /** Global Segment */
24411305Sblake.hechtman@amd.com        GLOBAL_SEGMENT         = 0x00000020,
24511305Sblake.hechtman@amd.com        /** Group Segment */
24611305Sblake.hechtman@amd.com        GROUP_SEGMENT          = 0x00000040,
24711305Sblake.hechtman@amd.com        /** Private Segment */
24811305Sblake.hechtman@amd.com        PRIVATE_SEGMENT        = 0x00000080,
24911305Sblake.hechtman@amd.com        /** Kergarg Segment */
25011305Sblake.hechtman@amd.com        KERNARG_SEGMENT        = 0x00000100,
25111305Sblake.hechtman@amd.com        /** Readonly Segment */
25211305Sblake.hechtman@amd.com        READONLY_SEGMENT       = 0x00000200,
25311305Sblake.hechtman@amd.com        /** Spill Segment */
25411305Sblake.hechtman@amd.com        SPILL_SEGMENT          = 0x00000400,
25511305Sblake.hechtman@amd.com        /** Arg Segment */
25611305Sblake.hechtman@amd.com        ARG_SEGMENT            = 0x00000800,
25711305Sblake.hechtman@amd.com    };
25811305Sblake.hechtman@amd.com
2595735Snate@binkert.org  private:
26012917Sstacze01@arm.com    typedef uint16_t PrivateFlagsType;
2616104Ssteve.reinhardt@amd.com    typedef ::Flags<PrivateFlagsType> PrivateFlags;
2625735Snate@binkert.org
26310882Sandreas.hansson@arm.com    enum : PrivateFlagsType {
26410882Sandreas.hansson@arm.com        /** Whether or not the size is valid. */
26510882Sandreas.hansson@arm.com        VALID_SIZE           = 0x00000001,
26610882Sandreas.hansson@arm.com        /** Whether or not paddr is valid (has been written yet). */
26710882Sandreas.hansson@arm.com        VALID_PADDR          = 0x00000002,
26810882Sandreas.hansson@arm.com        /** Whether or not the vaddr & asid are valid. */
26910882Sandreas.hansson@arm.com        VALID_VADDR          = 0x00000004,
27011248Sradhika.jagtap@ARM.com        /** Whether or not the instruction sequence number is valid. */
27111248Sradhika.jagtap@ARM.com        VALID_INST_SEQ_NUM   = 0x00000008,
27210882Sandreas.hansson@arm.com        /** Whether or not the pc is valid. */
27310882Sandreas.hansson@arm.com        VALID_PC             = 0x00000010,
27410882Sandreas.hansson@arm.com        /** Whether or not the context ID is valid. */
27510882Sandreas.hansson@arm.com        VALID_CONTEXT_ID     = 0x00000020,
27610882Sandreas.hansson@arm.com        /** Whether or not the sc result is valid. */
27710882Sandreas.hansson@arm.com        VALID_EXTRA_DATA     = 0x00000080,
27812917Sstacze01@arm.com        /** Whether or not the stream ID and substream ID is valid. */
27912917Sstacze01@arm.com        VALID_STREAM_ID      = 0x00000100,
28012917Sstacze01@arm.com        VALID_SUBSTREAM_ID   = 0x00000200,
28110882Sandreas.hansson@arm.com        /**
28210882Sandreas.hansson@arm.com         * These flags are *not* cleared when a Request object is reused
28310882Sandreas.hansson@arm.com         * (assigned a new address).
28410882Sandreas.hansson@arm.com         */
28511435Smitch.hayenga@arm.com        STICKY_PRIVATE_FLAGS = VALID_CONTEXT_ID
28610882Sandreas.hansson@arm.com    };
2875735Snate@binkert.org
2882663Sstever@eecs.umich.edu  private:
28910653Sandreas.hansson@arm.com
29010653Sandreas.hansson@arm.com    /**
29110653Sandreas.hansson@arm.com     * Set up a physical (e.g. device) request in a previously
29210653Sandreas.hansson@arm.com     * allocated Request object.
29310653Sandreas.hansson@arm.com     */
29410653Sandreas.hansson@arm.com    void
29510653Sandreas.hansson@arm.com    setPhys(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
29610653Sandreas.hansson@arm.com    {
29710653Sandreas.hansson@arm.com        _paddr = paddr;
29810653Sandreas.hansson@arm.com        _size = size;
29910653Sandreas.hansson@arm.com        _time = time;
30010653Sandreas.hansson@arm.com        _masterId = mid;
30110653Sandreas.hansson@arm.com        _flags.clear(~STICKY_FLAGS);
30210653Sandreas.hansson@arm.com        _flags.set(flags);
30310653Sandreas.hansson@arm.com        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
30410653Sandreas.hansson@arm.com        privateFlags.set(VALID_PADDR|VALID_SIZE);
30510653Sandreas.hansson@arm.com        depth = 0;
30610653Sandreas.hansson@arm.com        accessDelta = 0;
30710653Sandreas.hansson@arm.com        //translateDelta = 0;
30810653Sandreas.hansson@arm.com    }
30910653Sandreas.hansson@arm.com
3102663Sstever@eecs.umich.edu    /**
3112663Sstever@eecs.umich.edu     * The physical address of the request. Valid only if validPaddr
3125735Snate@binkert.org     * is set.
3135735Snate@binkert.org     */
3146427Ssteve.reinhardt@amd.com    Addr _paddr;
3152532SN/A
3162663Sstever@eecs.umich.edu    /**
3172663Sstever@eecs.umich.edu     * The size of the request. This field must be set when vaddr or
3182663Sstever@eecs.umich.edu     * paddr is written via setVirt() or setPhys(), so it is always
3195735Snate@binkert.org     * valid as long as one of the address fields is valid.
3205735Snate@binkert.org     */
32110653Sandreas.hansson@arm.com    unsigned _size;
3222395SN/A
32313954Sgiacomo.gabrielli@arm.com    /** Byte-enable mask for writes. */
32413954Sgiacomo.gabrielli@arm.com    std::vector<bool> _byteEnable;
32513954Sgiacomo.gabrielli@arm.com
3268832SAli.Saidi@ARM.com    /** The requestor ID which is unique in the system for all ports
3278832SAli.Saidi@ARM.com     * that are capable of issuing a transaction
3288832SAli.Saidi@ARM.com     */
3298832SAli.Saidi@ARM.com    MasterID _masterId;
3308832SAli.Saidi@ARM.com
3312532SN/A    /** Flag structure for the request. */
3326427Ssteve.reinhardt@amd.com    Flags _flags;
3332384SN/A
33411305Sblake.hechtman@amd.com    /** Memory space configuraiton flag structure for the request. */
33511305Sblake.hechtman@amd.com    MemSpaceConfigFlags _memSpaceConfigFlags;
33611305Sblake.hechtman@amd.com
3376104Ssteve.reinhardt@amd.com    /** Private flags for field validity checking. */
3386104Ssteve.reinhardt@amd.com    PrivateFlags privateFlags;
3396104Ssteve.reinhardt@amd.com
3402663Sstever@eecs.umich.edu    /**
3412663Sstever@eecs.umich.edu     * The time this request was started. Used to calculate
3427823Ssteve.reinhardt@amd.com     * latencies. This field is set to curTick() any time paddr or vaddr
3435735Snate@binkert.org     * is written.
3445735Snate@binkert.org     */
3456223Snate@binkert.org    Tick _time;
3462384SN/A
34710024Sdam.sunwoo@arm.com    /**
34810024Sdam.sunwoo@arm.com     * The task id associated with this request
34910024Sdam.sunwoo@arm.com     */
35010024Sdam.sunwoo@arm.com    uint32_t _taskId;
35110024Sdam.sunwoo@arm.com
35212917Sstacze01@arm.com    union {
35312917Sstacze01@arm.com        struct {
35412917Sstacze01@arm.com            /**
35512917Sstacze01@arm.com             * The stream ID uniquely identifies a device behind the
35612917Sstacze01@arm.com             * SMMU/IOMMU Each transaction arriving at the SMMU/IOMMU is
35712917Sstacze01@arm.com             * associated with exactly one stream ID.
35812917Sstacze01@arm.com             */
35912917Sstacze01@arm.com            uint32_t  _streamId;
36012917Sstacze01@arm.com
36112917Sstacze01@arm.com            /**
36212917Sstacze01@arm.com             * The substream ID identifies an "execution context" within a
36312917Sstacze01@arm.com             * device behind an SMMU/IOMMU. It's intended to map 1-to-1 to
36412917Sstacze01@arm.com             * PCIe PASID (Process Address Space ID). The presence of a
36512917Sstacze01@arm.com             * substream ID is optional.
36612917Sstacze01@arm.com             */
36712917Sstacze01@arm.com            uint32_t _substreamId;
36812917Sstacze01@arm.com        };
36912917Sstacze01@arm.com
37012917Sstacze01@arm.com        /** The address space ID. */
37112917Sstacze01@arm.com        uint64_t _asid;
37212917Sstacze01@arm.com    };
3733806Ssaidi@eecs.umich.edu
3742663Sstever@eecs.umich.edu    /** The virtual address of the request. */
3756427Ssteve.reinhardt@amd.com    Addr _vaddr;
3762384SN/A
3775735Snate@binkert.org    /**
3785735Snate@binkert.org     * Extra data for the request, such as the return value of
3794040Ssaidi@eecs.umich.edu     * store conditional or the compare value for a CAS. */
3806427Ssteve.reinhardt@amd.com    uint64_t _extraData;
3812384SN/A
38211435Smitch.hayenga@arm.com    /** The context ID (for statistics, locks, and wakeups). */
38311005Sandreas.sandberg@arm.com    ContextID _contextId;
3842384SN/A
3852381SN/A    /** program counter of initiating access; for tracing/debugging */
3866427Ssteve.reinhardt@amd.com    Addr _pc;
3872663Sstever@eecs.umich.edu
38811248Sradhika.jagtap@ARM.com    /** Sequence number of the instruction that creates the request */
38911253Sradhika.jagtap@ARM.com    InstSeqNum _reqInstSeqNum;
39011248Sradhika.jagtap@ARM.com
39111306Santhony.gutierrez@amd.com    /** A pointer to an atomic operation */
39214297Sjordi.vaquero@metempsy.com    AtomicOpFunctorPtr atomicOpFunctor;
39311306Santhony.gutierrez@amd.com
3942532SN/A  public:
39510653Sandreas.hansson@arm.com
39610653Sandreas.hansson@arm.com    /**
39710653Sandreas.hansson@arm.com     * Minimal constructor. No fields are initialized. (Note that
39810653Sandreas.hansson@arm.com     *  _flags and privateFlags are cleared by Flags default
39910653Sandreas.hansson@arm.com     *  constructor.)
4006427Ssteve.reinhardt@amd.com     */
4012663Sstever@eecs.umich.edu    Request()
40210360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
40310360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
40411435Smitch.hayenga@arm.com          _extraData(0), _contextId(0), _pc(0),
40511306Santhony.gutierrez@amd.com          _reqInstSeqNum(0), atomicOpFunctor(nullptr), translateDelta(0),
40611306Santhony.gutierrez@amd.com          accessDelta(0), depth(0)
4072663Sstever@eecs.umich.edu    {}
4082532SN/A
40911248Sradhika.jagtap@ARM.com    Request(Addr paddr, unsigned size, Flags flags, MasterID mid,
41011435Smitch.hayenga@arm.com            InstSeqNum seq_num, ContextID cid)
41111248Sradhika.jagtap@ARM.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
41211248Sradhika.jagtap@ARM.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
41311435Smitch.hayenga@arm.com          _extraData(0), _contextId(0), _pc(0),
41411306Santhony.gutierrez@amd.com          _reqInstSeqNum(seq_num), atomicOpFunctor(nullptr), translateDelta(0),
41511306Santhony.gutierrez@amd.com          accessDelta(0), depth(0)
41611248Sradhika.jagtap@ARM.com    {
41711248Sradhika.jagtap@ARM.com        setPhys(paddr, size, flags, mid, curTick());
41811435Smitch.hayenga@arm.com        setContext(cid);
41911248Sradhika.jagtap@ARM.com        privateFlags.set(VALID_INST_SEQ_NUM);
42011248Sradhika.jagtap@ARM.com    }
42111248Sradhika.jagtap@ARM.com
4222663Sstever@eecs.umich.edu    /**
4232663Sstever@eecs.umich.edu     * Constructor for physical (e.g. device) requests.  Initializes
4247823Ssteve.reinhardt@amd.com     * just physical address, size, flags, and timestamp (to curTick()).
42510653Sandreas.hansson@arm.com     * These fields are adequate to perform a request.
4265735Snate@binkert.org     */
42710653Sandreas.hansson@arm.com    Request(Addr paddr, unsigned size, Flags flags, MasterID mid)
42810360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
42910360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
43011435Smitch.hayenga@arm.com          _extraData(0), _contextId(0), _pc(0),
43111306Santhony.gutierrez@amd.com          _reqInstSeqNum(0), atomicOpFunctor(nullptr), translateDelta(0),
43211306Santhony.gutierrez@amd.com          accessDelta(0), depth(0)
4335735Snate@binkert.org    {
43410653Sandreas.hansson@arm.com        setPhys(paddr, size, flags, mid, curTick());
4355735Snate@binkert.org    }
4362532SN/A
43710653Sandreas.hansson@arm.com    Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
43810360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
43910360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
44011435Smitch.hayenga@arm.com          _extraData(0), _contextId(0), _pc(0),
44111306Santhony.gutierrez@amd.com          _reqInstSeqNum(0), atomicOpFunctor(nullptr), translateDelta(0),
44211306Santhony.gutierrez@amd.com          accessDelta(0), depth(0)
4436223Snate@binkert.org    {
4448832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid, time);
4456223Snate@binkert.org    }
4466223Snate@binkert.org
44710653Sandreas.hansson@arm.com    Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time,
44810653Sandreas.hansson@arm.com            Addr pc)
44910360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
45010360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
45111435Smitch.hayenga@arm.com          _extraData(0), _contextId(0), _pc(pc),
45211306Santhony.gutierrez@amd.com          _reqInstSeqNum(0), atomicOpFunctor(nullptr), translateDelta(0),
45311306Santhony.gutierrez@amd.com          accessDelta(0), depth(0)
4546899SBrad.Beckmann@amd.com    {
4558832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid, time);
4566899SBrad.Beckmann@amd.com        privateFlags.set(VALID_PC);
4576899SBrad.Beckmann@amd.com    }
4586899SBrad.Beckmann@amd.com
45912917Sstacze01@arm.com    Request(uint64_t asid, Addr vaddr, unsigned size, Flags flags,
46012917Sstacze01@arm.com            MasterID mid, Addr pc, ContextID cid)
46110360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
46210360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
46311435Smitch.hayenga@arm.com          _extraData(0), _contextId(0), _pc(0),
46411306Santhony.gutierrez@amd.com          _reqInstSeqNum(0), atomicOpFunctor(nullptr), translateDelta(0),
46511306Santhony.gutierrez@amd.com          accessDelta(0), depth(0)
4662669Sktlim@umich.edu    {
4678832SAli.Saidi@ARM.com        setVirt(asid, vaddr, size, flags, mid, pc);
46811435Smitch.hayenga@arm.com        setContext(cid);
4692669Sktlim@umich.edu    }
4702669Sktlim@umich.edu
47112917Sstacze01@arm.com    Request(uint64_t asid, Addr vaddr, unsigned size, Flags flags,
47212917Sstacze01@arm.com            MasterID mid, Addr pc, ContextID cid,
47314297Sjordi.vaquero@metempsy.com            AtomicOpFunctorPtr atomic_op)
47411306Santhony.gutierrez@amd.com    {
47514297Sjordi.vaquero@metempsy.com        setVirt(asid, vaddr, size, flags, mid, pc, std::move(atomic_op));
47611435Smitch.hayenga@arm.com        setContext(cid);
47711306Santhony.gutierrez@amd.com    }
47811306Santhony.gutierrez@amd.com
47912766Sqtt2@cornell.edu    Request(const Request& other)
48012766Sqtt2@cornell.edu        : _paddr(other._paddr), _size(other._size),
48112766Sqtt2@cornell.edu          _masterId(other._masterId),
48212766Sqtt2@cornell.edu          _flags(other._flags),
48312766Sqtt2@cornell.edu          _memSpaceConfigFlags(other._memSpaceConfigFlags),
48412766Sqtt2@cornell.edu          privateFlags(other.privateFlags),
48512766Sqtt2@cornell.edu          _time(other._time),
48612766Sqtt2@cornell.edu          _taskId(other._taskId), _asid(other._asid), _vaddr(other._vaddr),
48712766Sqtt2@cornell.edu          _extraData(other._extraData), _contextId(other._contextId),
48812766Sqtt2@cornell.edu          _pc(other._pc), _reqInstSeqNum(other._reqInstSeqNum),
48912766Sqtt2@cornell.edu          translateDelta(other.translateDelta),
49012766Sqtt2@cornell.edu          accessDelta(other.accessDelta), depth(other.depth)
49112766Sqtt2@cornell.edu    {
49214297Sjordi.vaquero@metempsy.com
49314297Sjordi.vaquero@metempsy.com        atomicOpFunctor.reset(other.atomicOpFunctor ?
49414297Sjordi.vaquero@metempsy.com                                other.atomicOpFunctor->clone() : nullptr);
49512766Sqtt2@cornell.edu    }
49612766Sqtt2@cornell.edu
49714297Sjordi.vaquero@metempsy.com    ~Request() {}
4984610Ssaidi@eecs.umich.edu
4992663Sstever@eecs.umich.edu    /**
50011435Smitch.hayenga@arm.com     * Set up Context numbers.
5015735Snate@binkert.org     */
5025735Snate@binkert.org    void
50311435Smitch.hayenga@arm.com    setContext(ContextID context_id)
5042663Sstever@eecs.umich.edu    {
5055735Snate@binkert.org        _contextId = context_id;
50611435Smitch.hayenga@arm.com        privateFlags.set(VALID_CONTEXT_ID);
5072663Sstever@eecs.umich.edu    }
5082532SN/A
50912917Sstacze01@arm.com    void
51012917Sstacze01@arm.com    setStreamId(uint32_t sid)
51112917Sstacze01@arm.com    {
51212917Sstacze01@arm.com        _streamId = sid;
51312917Sstacze01@arm.com        privateFlags.set(VALID_STREAM_ID);
51412917Sstacze01@arm.com    }
51512917Sstacze01@arm.com
51612917Sstacze01@arm.com    void
51712917Sstacze01@arm.com    setSubStreamId(uint32_t ssid)
51812917Sstacze01@arm.com    {
51912917Sstacze01@arm.com        assert(privateFlags.isSet(VALID_STREAM_ID));
52012917Sstacze01@arm.com        _substreamId = ssid;
52112917Sstacze01@arm.com        privateFlags.set(VALID_SUBSTREAM_ID);
52212917Sstacze01@arm.com    }
52312917Sstacze01@arm.com
5242663Sstever@eecs.umich.edu    /**
5252663Sstever@eecs.umich.edu     * Set up a virtual (e.g., CPU) request in a previously
5265735Snate@binkert.org     * allocated Request object.
5275735Snate@binkert.org     */
5285735Snate@binkert.org    void
52912917Sstacze01@arm.com    setVirt(uint64_t asid, Addr vaddr, unsigned size, Flags flags,
53014297Sjordi.vaquero@metempsy.com            MasterID mid, Addr pc, AtomicOpFunctorPtr amo_op = nullptr)
5312663Sstever@eecs.umich.edu    {
5326427Ssteve.reinhardt@amd.com        _asid = asid;
5336427Ssteve.reinhardt@amd.com        _vaddr = vaddr;
5346427Ssteve.reinhardt@amd.com        _size = size;
5358832SAli.Saidi@ARM.com        _masterId = mid;
5366427Ssteve.reinhardt@amd.com        _pc = pc;
5377823Ssteve.reinhardt@amd.com        _time = curTick();
5385735Snate@binkert.org
5396427Ssteve.reinhardt@amd.com        _flags.clear(~STICKY_FLAGS);
5406427Ssteve.reinhardt@amd.com        _flags.set(flags);
5416104Ssteve.reinhardt@amd.com        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
5426104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC);
54310020Smatt.horsnell@ARM.com        depth = 0;
54410020Smatt.horsnell@ARM.com        accessDelta = 0;
54510020Smatt.horsnell@ARM.com        translateDelta = 0;
54614297Sjordi.vaquero@metempsy.com        atomicOpFunctor = std::move(amo_op);
5472663Sstever@eecs.umich.edu    }
5482532SN/A
5495735Snate@binkert.org    /**
5509760Sandreas@sandberg.pp.se     * Set just the physical address.  This usually used to record the
5519760Sandreas@sandberg.pp.se     * result of a translation. However, when using virtualized CPUs
5529760Sandreas@sandberg.pp.se     * setPhys() is sometimes called to finalize a physical address
5539760Sandreas@sandberg.pp.se     * without a virtual address, so we can't check if the virtual
5549760Sandreas@sandberg.pp.se     * address is valid.
5552663Sstever@eecs.umich.edu     */
5565735Snate@binkert.org    void
5576427Ssteve.reinhardt@amd.com    setPaddr(Addr paddr)
5582663Sstever@eecs.umich.edu    {
5596427Ssteve.reinhardt@amd.com        _paddr = paddr;
5606104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_PADDR);
5612663Sstever@eecs.umich.edu    }
5622532SN/A
5635735Snate@binkert.org    /**
5645744Sgblack@eecs.umich.edu     * Generate two requests as if this request had been split into two
5655744Sgblack@eecs.umich.edu     * pieces. The original request can't have been translated already.
5665744Sgblack@eecs.umich.edu     */
56713954Sgiacomo.gabrielli@arm.com    // TODO: this function is still required by TimingSimpleCPU - should be
56813954Sgiacomo.gabrielli@arm.com    // removed once TimingSimpleCPU will support arbitrarily long multi-line
56913954Sgiacomo.gabrielli@arm.com    // mem. accesses
5705744Sgblack@eecs.umich.edu    void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2)
5715744Sgblack@eecs.umich.edu    {
5726104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
5736104Ssteve.reinhardt@amd.com        assert(privateFlags.noneSet(VALID_PADDR));
5746427Ssteve.reinhardt@amd.com        assert(split_addr > _vaddr && split_addr < _vaddr + _size);
57512749Sgiacomo.travaglini@arm.com        req1 = std::make_shared<Request>(*this);
57612749Sgiacomo.travaglini@arm.com        req2 = std::make_shared<Request>(*this);
5776427Ssteve.reinhardt@amd.com        req1->_size = split_addr - _vaddr;
5786427Ssteve.reinhardt@amd.com        req2->_vaddr = split_addr;
5796427Ssteve.reinhardt@amd.com        req2->_size = _size - req1->_size;
58013954Sgiacomo.gabrielli@arm.com        if (!_byteEnable.empty()) {
58113954Sgiacomo.gabrielli@arm.com            req1->_byteEnable = std::vector<bool>(
58213954Sgiacomo.gabrielli@arm.com                _byteEnable.begin(),
58313954Sgiacomo.gabrielli@arm.com                _byteEnable.begin() + req1->_size);
58413954Sgiacomo.gabrielli@arm.com            req2->_byteEnable = std::vector<bool>(
58513954Sgiacomo.gabrielli@arm.com                _byteEnable.begin() + req1->_size,
58613954Sgiacomo.gabrielli@arm.com                _byteEnable.end());
58713954Sgiacomo.gabrielli@arm.com        }
5885744Sgblack@eecs.umich.edu    }
5895744Sgblack@eecs.umich.edu
5905744Sgblack@eecs.umich.edu    /**
5915735Snate@binkert.org     * Accessor for paddr.
5925735Snate@binkert.org     */
5936104Ssteve.reinhardt@amd.com    bool
59410568Sandreas.hansson@arm.com    hasPaddr() const
5956104Ssteve.reinhardt@amd.com    {
5966104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_PADDR);
5976104Ssteve.reinhardt@amd.com    }
5986104Ssteve.reinhardt@amd.com
5995735Snate@binkert.org    Addr
60010568Sandreas.hansson@arm.com    getPaddr() const
6015735Snate@binkert.org    {
6026104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR));
6036427Ssteve.reinhardt@amd.com        return _paddr;
6045735Snate@binkert.org    }
6052663Sstever@eecs.umich.edu
6065735Snate@binkert.org    /**
60710020Smatt.horsnell@ARM.com     * Time for the TLB/table walker to successfully translate this request.
60810020Smatt.horsnell@ARM.com     */
60910020Smatt.horsnell@ARM.com    Tick translateDelta;
61010020Smatt.horsnell@ARM.com
61110020Smatt.horsnell@ARM.com    /**
61210020Smatt.horsnell@ARM.com     * Access latency to complete this memory transaction not including
61310020Smatt.horsnell@ARM.com     * translation time.
61410020Smatt.horsnell@ARM.com     */
61510020Smatt.horsnell@ARM.com    Tick accessDelta;
61610020Smatt.horsnell@ARM.com
61710020Smatt.horsnell@ARM.com    /**
61810020Smatt.horsnell@ARM.com     * Level of the cache hierachy where this request was responded to
61910020Smatt.horsnell@ARM.com     * (e.g. 0 = L1; 1 = L2).
62010020Smatt.horsnell@ARM.com     */
62110568Sandreas.hansson@arm.com    mutable int depth;
62210020Smatt.horsnell@ARM.com
62310020Smatt.horsnell@ARM.com    /**
6245735Snate@binkert.org     *  Accessor for size.
6255735Snate@binkert.org     */
6266104Ssteve.reinhardt@amd.com    bool
62710568Sandreas.hansson@arm.com    hasSize() const
6286104Ssteve.reinhardt@amd.com    {
6296104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_SIZE);
6306104Ssteve.reinhardt@amd.com    }
6316104Ssteve.reinhardt@amd.com
63210755Sandreas.hansson@arm.com    unsigned
63310568Sandreas.hansson@arm.com    getSize() const
6345735Snate@binkert.org    {
6356104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_SIZE));
6366427Ssteve.reinhardt@amd.com        return _size;
6375735Snate@binkert.org    }
6385735Snate@binkert.org
63913954Sgiacomo.gabrielli@arm.com    const std::vector<bool>&
64013954Sgiacomo.gabrielli@arm.com    getByteEnable() const
64113954Sgiacomo.gabrielli@arm.com    {
64213954Sgiacomo.gabrielli@arm.com        return _byteEnable;
64313954Sgiacomo.gabrielli@arm.com    }
64413954Sgiacomo.gabrielli@arm.com
64513954Sgiacomo.gabrielli@arm.com    void
64613954Sgiacomo.gabrielli@arm.com    setByteEnable(const std::vector<bool>& be)
64713954Sgiacomo.gabrielli@arm.com    {
64813954Sgiacomo.gabrielli@arm.com        assert(be.empty() || be.size() == _size);
64913954Sgiacomo.gabrielli@arm.com        _byteEnable = be;
65013954Sgiacomo.gabrielli@arm.com    }
65113954Sgiacomo.gabrielli@arm.com
6522663Sstever@eecs.umich.edu    /** Accessor for time. */
6535735Snate@binkert.org    Tick
6546223Snate@binkert.org    time() const
6555735Snate@binkert.org    {
6566104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
6576223Snate@binkert.org        return _time;
6586223Snate@binkert.org    }
6596223Snate@binkert.org
66011306Santhony.gutierrez@amd.com    /**
66111306Santhony.gutierrez@amd.com     * Accessor for atomic-op functor.
66211306Santhony.gutierrez@amd.com     */
66311306Santhony.gutierrez@amd.com    bool
66411306Santhony.gutierrez@amd.com    hasAtomicOpFunctor()
66511306Santhony.gutierrez@amd.com    {
66614297Sjordi.vaquero@metempsy.com        return (bool)atomicOpFunctor;
66711306Santhony.gutierrez@amd.com    }
66811306Santhony.gutierrez@amd.com
66911306Santhony.gutierrez@amd.com    AtomicOpFunctor *
67011306Santhony.gutierrez@amd.com    getAtomicOpFunctor()
67111306Santhony.gutierrez@amd.com    {
67214297Sjordi.vaquero@metempsy.com        assert(atomicOpFunctor);
67314297Sjordi.vaquero@metempsy.com        return atomicOpFunctor.get();
67411306Santhony.gutierrez@amd.com    }
67511306Santhony.gutierrez@amd.com
6762663Sstever@eecs.umich.edu    /** Accessor for flags. */
6775735Snate@binkert.org    Flags
6785735Snate@binkert.org    getFlags()
6795735Snate@binkert.org    {
6806104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
6816427Ssteve.reinhardt@amd.com        return _flags;
6825735Snate@binkert.org    }
6835735Snate@binkert.org
6846428Ssteve.reinhardt@amd.com    /** Note that unlike other accessors, this function sets *specific
68510882Sandreas.hansson@arm.com        flags* (ORs them in); it does not assign its argument to the
68610882Sandreas.hansson@arm.com        _flags field.  Thus this method should rightly be called
68710882Sandreas.hansson@arm.com        setFlags() and not just flags(). */
6885735Snate@binkert.org    void
6896427Ssteve.reinhardt@amd.com    setFlags(Flags flags)
6905735Snate@binkert.org    {
6916104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
6926427Ssteve.reinhardt@amd.com        _flags.set(flags);
6935735Snate@binkert.org    }
6945735Snate@binkert.org
69511305Sblake.hechtman@amd.com    void
69611305Sblake.hechtman@amd.com    setMemSpaceConfigFlags(MemSpaceConfigFlags extraFlags)
69711305Sblake.hechtman@amd.com    {
69811305Sblake.hechtman@amd.com        assert(privateFlags.isSet(VALID_PADDR | VALID_VADDR));
69911305Sblake.hechtman@amd.com        _memSpaceConfigFlags.set(extraFlags);
70011305Sblake.hechtman@amd.com    }
70111305Sblake.hechtman@amd.com
7022663Sstever@eecs.umich.edu    /** Accessor function for vaddr.*/
70310362Smitch.hayenga@arm.com    bool
70410362Smitch.hayenga@arm.com    hasVaddr() const
70510362Smitch.hayenga@arm.com    {
70610362Smitch.hayenga@arm.com        return privateFlags.isSet(VALID_VADDR);
70710362Smitch.hayenga@arm.com    }
70810362Smitch.hayenga@arm.com
7095735Snate@binkert.org    Addr
71010362Smitch.hayenga@arm.com    getVaddr() const
7115735Snate@binkert.org    {
7126104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
7136427Ssteve.reinhardt@amd.com        return _vaddr;
7145735Snate@binkert.org    }
7152663Sstever@eecs.umich.edu
7168832SAli.Saidi@ARM.com    /** Accesssor for the requestor id. */
7178832SAli.Saidi@ARM.com    MasterID
71810568Sandreas.hansson@arm.com    masterId() const
7198832SAli.Saidi@ARM.com    {
7208832SAli.Saidi@ARM.com        return _masterId;
7218832SAli.Saidi@ARM.com    }
7228832SAli.Saidi@ARM.com
72310024Sdam.sunwoo@arm.com    uint32_t
72410024Sdam.sunwoo@arm.com    taskId() const
72510024Sdam.sunwoo@arm.com    {
72610024Sdam.sunwoo@arm.com        return _taskId;
72710024Sdam.sunwoo@arm.com    }
72810024Sdam.sunwoo@arm.com
72910024Sdam.sunwoo@arm.com    void
73010024Sdam.sunwoo@arm.com    taskId(uint32_t id) {
73110024Sdam.sunwoo@arm.com        _taskId = id;
73210024Sdam.sunwoo@arm.com    }
73310024Sdam.sunwoo@arm.com
7342663Sstever@eecs.umich.edu    /** Accessor function for asid.*/
73512917Sstacze01@arm.com    uint64_t
73610568Sandreas.hansson@arm.com    getAsid() const
7375735Snate@binkert.org    {
7386104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
7396427Ssteve.reinhardt@amd.com        return _asid;
7405735Snate@binkert.org    }
7412663Sstever@eecs.umich.edu
7428551Sdaniel.johnson@arm.com    /** Accessor function for asid.*/
7438551Sdaniel.johnson@arm.com    void
74412917Sstacze01@arm.com    setAsid(uint64_t asid)
7458551Sdaniel.johnson@arm.com    {
7468551Sdaniel.johnson@arm.com        _asid = asid;
7478551Sdaniel.johnson@arm.com    }
7488551Sdaniel.johnson@arm.com
7499912Sandreas@sandberg.pp.se    /** Accessor function for architecture-specific flags.*/
7509912Sandreas@sandberg.pp.se    ArchFlagsType
75110568Sandreas.hansson@arm.com    getArchFlags() const
7525735Snate@binkert.org    {
7539912Sandreas@sandberg.pp.se        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
7549912Sandreas@sandberg.pp.se        return _flags & ARCH_BITS;
7555735Snate@binkert.org    }
7563804Ssaidi@eecs.umich.edu
7572679Sktlim@umich.edu    /** Accessor function to check if sc result is valid. */
7585735Snate@binkert.org    bool
75910568Sandreas.hansson@arm.com    extraDataValid() const
7605735Snate@binkert.org    {
7616104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_EXTRA_DATA);
7625735Snate@binkert.org    }
7635735Snate@binkert.org
7642663Sstever@eecs.umich.edu    /** Accessor function for store conditional return value.*/
7655735Snate@binkert.org    uint64_t
7665735Snate@binkert.org    getExtraData() const
7675735Snate@binkert.org    {
7686104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_EXTRA_DATA));
7696427Ssteve.reinhardt@amd.com        return _extraData;
7705735Snate@binkert.org    }
7715735Snate@binkert.org
7722663Sstever@eecs.umich.edu    /** Accessor function for store conditional return value.*/
7735735Snate@binkert.org    void
7746427Ssteve.reinhardt@amd.com    setExtraData(uint64_t extraData)
7755735Snate@binkert.org    {
7766427Ssteve.reinhardt@amd.com        _extraData = extraData;
7776104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_EXTRA_DATA);
7785735Snate@binkert.org    }
7792663Sstever@eecs.umich.edu
7806010Ssteve.reinhardt@amd.com    bool
7816010Ssteve.reinhardt@amd.com    hasContextId() const
7826010Ssteve.reinhardt@amd.com    {
7836104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_CONTEXT_ID);
7846010Ssteve.reinhardt@amd.com    }
7856010Ssteve.reinhardt@amd.com
7865714Shsul@eecs.umich.edu    /** Accessor function for context ID.*/
78711005Sandreas.sandberg@arm.com    ContextID
7885735Snate@binkert.org    contextId() const
7895735Snate@binkert.org    {
7906104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_CONTEXT_ID));
7915735Snate@binkert.org        return _contextId;
7925735Snate@binkert.org    }
7935735Snate@binkert.org
79412917Sstacze01@arm.com    uint32_t
79512917Sstacze01@arm.com    streamId() const
79612917Sstacze01@arm.com    {
79712917Sstacze01@arm.com        assert(privateFlags.isSet(VALID_STREAM_ID));
79812917Sstacze01@arm.com        return _streamId;
79912917Sstacze01@arm.com    }
80012917Sstacze01@arm.com
80112917Sstacze01@arm.com    bool
80212917Sstacze01@arm.com    hasSubstreamId() const
80312917Sstacze01@arm.com    {
80412917Sstacze01@arm.com        return privateFlags.isSet(VALID_SUBSTREAM_ID);
80512917Sstacze01@arm.com    }
80612917Sstacze01@arm.com
80712917Sstacze01@arm.com    uint32_t
80812917Sstacze01@arm.com    substreamId() const
80912917Sstacze01@arm.com    {
81012917Sstacze01@arm.com        assert(privateFlags.isSet(VALID_SUBSTREAM_ID));
81112917Sstacze01@arm.com        return _substreamId;
81212917Sstacze01@arm.com    }
81312917Sstacze01@arm.com
81410052Smitch.hayenga+gem5@gmail.com    void
81510052Smitch.hayenga+gem5@gmail.com    setPC(Addr pc)
81610052Smitch.hayenga+gem5@gmail.com    {
81710052Smitch.hayenga+gem5@gmail.com        privateFlags.set(VALID_PC);
81810052Smitch.hayenga+gem5@gmail.com        _pc = pc;
81910052Smitch.hayenga+gem5@gmail.com    }
82010052Smitch.hayenga+gem5@gmail.com
8215875Ssteve.reinhardt@amd.com    bool
8225875Ssteve.reinhardt@amd.com    hasPC() const
8235875Ssteve.reinhardt@amd.com    {
8246104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_PC);
8255875Ssteve.reinhardt@amd.com    }
8265875Ssteve.reinhardt@amd.com
8276010Ssteve.reinhardt@amd.com    /** Accessor function for pc.*/
8285735Snate@binkert.org    Addr
8295735Snate@binkert.org    getPC() const
8305735Snate@binkert.org    {
8316104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PC));
8326427Ssteve.reinhardt@amd.com        return _pc;
8335735Snate@binkert.org    }
8342532SN/A
83510020Smatt.horsnell@ARM.com    /**
83610020Smatt.horsnell@ARM.com     * Increment/Get the depth at which this request is responded to.
83710020Smatt.horsnell@ARM.com     * This currently happens when the request misses in any cache level.
83810020Smatt.horsnell@ARM.com     */
83910568Sandreas.hansson@arm.com    void incAccessDepth() const { depth++; }
84010020Smatt.horsnell@ARM.com    int getAccessDepth() const { return depth; }
84110020Smatt.horsnell@ARM.com
84210020Smatt.horsnell@ARM.com    /**
84310020Smatt.horsnell@ARM.com     * Set/Get the time taken for this request to be successfully translated.
84410020Smatt.horsnell@ARM.com     */
84510020Smatt.horsnell@ARM.com    void setTranslateLatency() { translateDelta = curTick() - _time; }
84610020Smatt.horsnell@ARM.com    Tick getTranslateLatency() const { return translateDelta; }
84710020Smatt.horsnell@ARM.com
84810020Smatt.horsnell@ARM.com    /**
84910020Smatt.horsnell@ARM.com     * Set/Get the time taken to complete this request's access, not including
85010020Smatt.horsnell@ARM.com     *  the time to successfully translate the request.
85110020Smatt.horsnell@ARM.com     */
85210020Smatt.horsnell@ARM.com    void setAccessLatency() { accessDelta = curTick() - _time - translateDelta; }
85310020Smatt.horsnell@ARM.com    Tick getAccessLatency() const { return accessDelta; }
85410020Smatt.horsnell@ARM.com
85511248Sradhika.jagtap@ARM.com    /**
85611248Sradhika.jagtap@ARM.com     * Accessor for the sequence number of instruction that creates the
85711248Sradhika.jagtap@ARM.com     * request.
85811248Sradhika.jagtap@ARM.com     */
85911248Sradhika.jagtap@ARM.com    bool
86011248Sradhika.jagtap@ARM.com    hasInstSeqNum() const
86111248Sradhika.jagtap@ARM.com    {
86211248Sradhika.jagtap@ARM.com        return privateFlags.isSet(VALID_INST_SEQ_NUM);
86311248Sradhika.jagtap@ARM.com    }
86411248Sradhika.jagtap@ARM.com
86511248Sradhika.jagtap@ARM.com    InstSeqNum
86611248Sradhika.jagtap@ARM.com    getReqInstSeqNum() const
86711248Sradhika.jagtap@ARM.com    {
86811248Sradhika.jagtap@ARM.com        assert(privateFlags.isSet(VALID_INST_SEQ_NUM));
86911248Sradhika.jagtap@ARM.com        return _reqInstSeqNum;
87011248Sradhika.jagtap@ARM.com    }
87111248Sradhika.jagtap@ARM.com
87211253Sradhika.jagtap@ARM.com    void
87311253Sradhika.jagtap@ARM.com    setReqInstSeqNum(const InstSeqNum seq_num)
87411253Sradhika.jagtap@ARM.com    {
87511253Sradhika.jagtap@ARM.com        privateFlags.set(VALID_INST_SEQ_NUM);
87611253Sradhika.jagtap@ARM.com        _reqInstSeqNum = seq_num;
87711253Sradhika.jagtap@ARM.com    }
87811253Sradhika.jagtap@ARM.com
87911305Sblake.hechtman@amd.com    /** Accessor functions for flags. Note that these are for testing
88010882Sandreas.hansson@arm.com        only; setting flags should be done via setFlags(). */
8816427Ssteve.reinhardt@amd.com    bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
88210824SAndreas.Sandberg@ARM.com    bool isStrictlyOrdered() const { return _flags.isSet(STRICT_ORDER); }
8836427Ssteve.reinhardt@amd.com    bool isInstFetch() const { return _flags.isSet(INST_FETCH); }
88413367Syuetsu.kodama@riken.jp    bool isPrefetch() const { return (_flags.isSet(PREFETCH) ||
88513367Syuetsu.kodama@riken.jp                                      _flags.isSet(PF_EXCLUSIVE)); }
88613367Syuetsu.kodama@riken.jp    bool isPrefetchEx() const { return _flags.isSet(PF_EXCLUSIVE); }
8876427Ssteve.reinhardt@amd.com    bool isLLSC() const { return _flags.isSet(LLSC); }
8889950Sprakash.ramrakhyani@arm.com    bool isPriv() const { return _flags.isSet(PRIVILEGED); }
88910760Ssteve.reinhardt@amd.com    bool isLockedRMW() const { return _flags.isSet(LOCKED_RMW); }
8906427Ssteve.reinhardt@amd.com    bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
8916427Ssteve.reinhardt@amd.com    bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
8928105Sgblack@eecs.umich.edu    bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
89310028SGiacomo.Gabrielli@arm.com    bool isSecure() const { return _flags.isSet(SECURE); }
89410029SGiacomo.Gabrielli@arm.com    bool isPTWalk() const { return _flags.isSet(PT_WALK); }
89511269Sdavid.hashe@amd.com    bool isAcquire() const { return _flags.isSet(ACQUIRE); }
89611269Sdavid.hashe@amd.com    bool isRelease() const { return _flags.isSet(RELEASE); }
89711305Sblake.hechtman@amd.com    bool isKernel() const { return _flags.isSet(KERNEL); }
89811306Santhony.gutierrez@amd.com    bool isAtomicReturn() const { return _flags.isSet(ATOMIC_RETURN_OP); }
89911306Santhony.gutierrez@amd.com    bool isAtomicNoReturn() const { return _flags.isSet(ATOMIC_NO_RETURN_OP); }
90011306Santhony.gutierrez@amd.com
90111306Santhony.gutierrez@amd.com    bool
90211306Santhony.gutierrez@amd.com    isAtomic() const
90311306Santhony.gutierrez@amd.com    {
90411306Santhony.gutierrez@amd.com        return _flags.isSet(ATOMIC_RETURN_OP) ||
90511306Santhony.gutierrez@amd.com               _flags.isSet(ATOMIC_NO_RETURN_OP);
90611306Santhony.gutierrez@amd.com    }
90711305Sblake.hechtman@amd.com
90811305Sblake.hechtman@amd.com    /**
90912346Snikos.nikoleris@arm.com     * Accessor functions for the destination of a memory request. The
91012346Snikos.nikoleris@arm.com     * destination flag can specify a point of reference for the
91112346Snikos.nikoleris@arm.com     * operation (e.g. a cache block clean to the the point of
91212346Snikos.nikoleris@arm.com     * unification). At the moment the destination is only used by the
91312346Snikos.nikoleris@arm.com     * cache maintenance operations.
91412346Snikos.nikoleris@arm.com     */
91512346Snikos.nikoleris@arm.com    bool isToPOU() const { return _flags.isSet(DST_POU); }
91612346Snikos.nikoleris@arm.com    bool isToPOC() const { return _flags.isSet(DST_POC); }
91712346Snikos.nikoleris@arm.com    Flags getDest() const { return _flags & DST_BITS; }
91812346Snikos.nikoleris@arm.com
91912346Snikos.nikoleris@arm.com    /**
92011305Sblake.hechtman@amd.com     * Accessor functions for the memory space configuration flags and used by
92111305Sblake.hechtman@amd.com     * GPU ISAs such as the Heterogeneous System Architecture (HSA). Note that
92211305Sblake.hechtman@amd.com     * these are for testing only; setting extraFlags should be done via
92311305Sblake.hechtman@amd.com     * setMemSpaceConfigFlags().
92411305Sblake.hechtman@amd.com     */
92511305Sblake.hechtman@amd.com    bool isScoped() const { return _memSpaceConfigFlags.isSet(SCOPE_VALID); }
92611305Sblake.hechtman@amd.com
92711305Sblake.hechtman@amd.com    bool
92811305Sblake.hechtman@amd.com    isWavefrontScope() const
92911305Sblake.hechtman@amd.com    {
93011305Sblake.hechtman@amd.com        assert(isScoped());
93111305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(WAVEFRONT_SCOPE);
93211305Sblake.hechtman@amd.com    }
93311305Sblake.hechtman@amd.com
93411305Sblake.hechtman@amd.com    bool
93511305Sblake.hechtman@amd.com    isWorkgroupScope() const
93611305Sblake.hechtman@amd.com    {
93711305Sblake.hechtman@amd.com        assert(isScoped());
93811305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(WORKGROUP_SCOPE);
93911305Sblake.hechtman@amd.com    }
94011305Sblake.hechtman@amd.com
94111305Sblake.hechtman@amd.com    bool
94211305Sblake.hechtman@amd.com    isDeviceScope() const
94311305Sblake.hechtman@amd.com    {
94411305Sblake.hechtman@amd.com        assert(isScoped());
94511305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(DEVICE_SCOPE);
94611305Sblake.hechtman@amd.com    }
94711305Sblake.hechtman@amd.com
94811305Sblake.hechtman@amd.com    bool
94911305Sblake.hechtman@amd.com    isSystemScope() const
95011305Sblake.hechtman@amd.com    {
95111305Sblake.hechtman@amd.com        assert(isScoped());
95211305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(SYSTEM_SCOPE);
95311305Sblake.hechtman@amd.com    }
95411305Sblake.hechtman@amd.com
95511305Sblake.hechtman@amd.com    bool
95611305Sblake.hechtman@amd.com    isGlobalSegment() const
95711305Sblake.hechtman@amd.com    {
95811305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(GLOBAL_SEGMENT) ||
95911305Sblake.hechtman@amd.com               (!isGroupSegment() && !isPrivateSegment() &&
96011305Sblake.hechtman@amd.com                !isKernargSegment() && !isReadonlySegment() &&
96111305Sblake.hechtman@amd.com                !isSpillSegment() && !isArgSegment());
96211305Sblake.hechtman@amd.com    }
96311305Sblake.hechtman@amd.com
96411305Sblake.hechtman@amd.com    bool
96511305Sblake.hechtman@amd.com    isGroupSegment() const
96611305Sblake.hechtman@amd.com    {
96711305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(GROUP_SEGMENT);
96811305Sblake.hechtman@amd.com    }
96911305Sblake.hechtman@amd.com
97011305Sblake.hechtman@amd.com    bool
97111305Sblake.hechtman@amd.com    isPrivateSegment() const
97211305Sblake.hechtman@amd.com    {
97311305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(PRIVATE_SEGMENT);
97411305Sblake.hechtman@amd.com    }
97511305Sblake.hechtman@amd.com
97611305Sblake.hechtman@amd.com    bool
97711305Sblake.hechtman@amd.com    isKernargSegment() const
97811305Sblake.hechtman@amd.com    {
97911305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(KERNARG_SEGMENT);
98011305Sblake.hechtman@amd.com    }
98111305Sblake.hechtman@amd.com
98211305Sblake.hechtman@amd.com    bool
98311305Sblake.hechtman@amd.com    isReadonlySegment() const
98411305Sblake.hechtman@amd.com    {
98511305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(READONLY_SEGMENT);
98611305Sblake.hechtman@amd.com    }
98711305Sblake.hechtman@amd.com
98811305Sblake.hechtman@amd.com    bool
98911305Sblake.hechtman@amd.com    isSpillSegment() const
99011305Sblake.hechtman@amd.com    {
99111305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(SPILL_SEGMENT);
99211305Sblake.hechtman@amd.com    }
99311305Sblake.hechtman@amd.com
99411305Sblake.hechtman@amd.com    bool
99511305Sblake.hechtman@amd.com    isArgSegment() const
99611305Sblake.hechtman@amd.com    {
99711305Sblake.hechtman@amd.com        return _memSpaceConfigFlags.isSet(ARG_SEGMENT);
99811305Sblake.hechtman@amd.com    }
99912347Snikos.nikoleris@arm.com
100012347Snikos.nikoleris@arm.com    /**
100112347Snikos.nikoleris@arm.com     * Accessor functions to determine whether this request is part of
100212347Snikos.nikoleris@arm.com     * a cache maintenance operation. At the moment three operations
100312347Snikos.nikoleris@arm.com     * are supported:
100412347Snikos.nikoleris@arm.com
100512347Snikos.nikoleris@arm.com     * 1) A cache clean operation updates all copies of a memory
100612347Snikos.nikoleris@arm.com     * location to the point of reference,
100712347Snikos.nikoleris@arm.com     * 2) A cache invalidate operation invalidates all copies of the
100812347Snikos.nikoleris@arm.com     * specified block in the memory above the point of reference,
100912347Snikos.nikoleris@arm.com     * 3) A clean and invalidate operation is a combination of the two
101012347Snikos.nikoleris@arm.com     * operations.
101112347Snikos.nikoleris@arm.com     * @{ */
101212347Snikos.nikoleris@arm.com    bool isCacheClean() const { return _flags.isSet(CLEAN); }
101312347Snikos.nikoleris@arm.com    bool isCacheInvalidate() const { return _flags.isSet(INVALIDATE); }
101412347Snikos.nikoleris@arm.com    bool isCacheMaintenance() const { return _flags.isSet(CLEAN|INVALIDATE); }
101512347Snikos.nikoleris@arm.com    /** @} */
10162384SN/A};
10172381SN/A
10182381SN/A#endif // __MEM_REQUEST_HH__
1019