request.hh revision 10824
12381SN/A/*
210020Smatt.horsnell@ARM.com * Copyright (c) 2012-2013 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
152381SN/A * All rights reserved.
162381SN/A *
172381SN/A * Redistribution and use in source and binary forms, with or without
182381SN/A * modification, are permitted provided that the following conditions are
192381SN/A * met: redistributions of source code must retain the above copyright
202381SN/A * notice, this list of conditions and the following disclaimer;
212381SN/A * redistributions in binary form must reproduce the above copyright
222381SN/A * notice, this list of conditions and the following disclaimer in the
232381SN/A * documentation and/or other materials provided with the distribution;
242381SN/A * neither the name of the copyright holders nor the names of its
252381SN/A * contributors may be used to endorse or promote products derived from
262381SN/A * this software without specific prior written permission.
272381SN/A *
282381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
412665Ssaidi@eecs.umich.edu *          Steve Reinhardt
422665Ssaidi@eecs.umich.edu *          Ali Saidi
432381SN/A */
442381SN/A
452381SN/A/**
462982Sstever@eecs.umich.edu * @file
472982Sstever@eecs.umich.edu * Declaration of a request, the overall memory request consisting of
482381SN/A the parts of the request that are persistent throughout the transaction.
492381SN/A */
502381SN/A
512381SN/A#ifndef __MEM_REQUEST_HH__
522381SN/A#define __MEM_REQUEST_HH__
532381SN/A
545735Snate@binkert.org#include <cassert>
558833Sdam.sunwoo@arm.com#include <climits>
565735Snate@binkert.org
575735Snate@binkert.org#include "base/flags.hh"
585744Sgblack@eecs.umich.edu#include "base/misc.hh"
596214Snate@binkert.org#include "base/types.hh"
604167Sbinkertn@umich.edu#include "sim/core.hh"
612394SN/A
629332Sdam.sunwoo@arm.com/**
639332Sdam.sunwoo@arm.com * Special TaskIds that are used for per-context-switch stats dumps
649332Sdam.sunwoo@arm.com * and Cache Occupancy. Having too many tasks seems to be a problem
659332Sdam.sunwoo@arm.com * with vector stats. 1024 seems to be a reasonable number that
669332Sdam.sunwoo@arm.com * doesn't cause a problem with stats and is large enough to realistic
679332Sdam.sunwoo@arm.com * benchmarks (Linux/Android boot, BBench, etc.)
689332Sdam.sunwoo@arm.com */
699332Sdam.sunwoo@arm.com
709332Sdam.sunwoo@arm.comnamespace ContextSwitchTaskId {
719332Sdam.sunwoo@arm.com    enum TaskId {
729332Sdam.sunwoo@arm.com        MaxNormalTaskId = 1021, /* Maximum number of normal tasks */
739332Sdam.sunwoo@arm.com        Prefetcher = 1022, /* For cache lines brought in by prefetcher */
749332Sdam.sunwoo@arm.com        DMA = 1023, /* Mostly Table Walker */
759332Sdam.sunwoo@arm.com        Unknown = 1024,
769332Sdam.sunwoo@arm.com        NumTaskId
779332Sdam.sunwoo@arm.com    };
789332Sdam.sunwoo@arm.com}
799332Sdam.sunwoo@arm.com
802394SN/Aclass Request;
812394SN/A
822394SN/Atypedef Request* RequestPtr;
838832SAli.Saidi@ARM.comtypedef uint16_t MasterID;
842394SN/A
859044SAli.Saidi@ARM.comclass Request
862381SN/A{
875735Snate@binkert.org  public:
885735Snate@binkert.org    typedef uint32_t FlagsType;
899912Sandreas@sandberg.pp.se    typedef uint8_t ArchFlagsType;
905735Snate@binkert.org    typedef ::Flags<FlagsType> Flags;
915735Snate@binkert.org
929912Sandreas@sandberg.pp.se    /**
939912Sandreas@sandberg.pp.se     * Architecture specific flags.
949912Sandreas@sandberg.pp.se     *
959912Sandreas@sandberg.pp.se     * These bits int the flag field are reserved for
969912Sandreas@sandberg.pp.se     * architecture-specific code. For example, SPARC uses them to
979912Sandreas@sandberg.pp.se     * represent ASIs.
989912Sandreas@sandberg.pp.se     */
999912Sandreas@sandberg.pp.se    static const FlagsType ARCH_BITS                   = 0x000000FF;
1006133Ssteve.reinhardt@amd.com    /** The request was an instruction fetch. */
1016133Ssteve.reinhardt@amd.com    static const FlagsType INST_FETCH                  = 0x00000100;
1025735Snate@binkert.org    /** The virtual address is also the physical address. */
1035735Snate@binkert.org    static const FlagsType PHYSICAL                    = 0x00000200;
10410824SAndreas.Sandberg@ARM.com    /**
10510824SAndreas.Sandberg@ARM.com     * The request is to an uncacheable address.
10610824SAndreas.Sandberg@ARM.com     *
10710824SAndreas.Sandberg@ARM.com     * @note Uncacheable accesses may be reordered by CPU models. The
10810824SAndreas.Sandberg@ARM.com     * STRICT_ORDER flag should be set if such reordering is
10910824SAndreas.Sandberg@ARM.com     * undesirable.
11010824SAndreas.Sandberg@ARM.com     */
11110824SAndreas.Sandberg@ARM.com    static const FlagsType UNCACHEABLE                = 0x00000400;
11210824SAndreas.Sandberg@ARM.com    /**
11310824SAndreas.Sandberg@ARM.com     * The request is required to be strictly ordered by <i>CPU
11410824SAndreas.Sandberg@ARM.com     * models</i> and is non-speculative.
11510824SAndreas.Sandberg@ARM.com     *
11610824SAndreas.Sandberg@ARM.com     * A strictly ordered request is guaranteed to never be re-ordered
11710824SAndreas.Sandberg@ARM.com     * or executed speculatively by a CPU model. The memory system may
11810824SAndreas.Sandberg@ARM.com     * still reorder requests in caches unless the UNCACHEABLE flag is
11910824SAndreas.Sandberg@ARM.com     * set as well.
12010824SAndreas.Sandberg@ARM.com     */
12110824SAndreas.Sandberg@ARM.com    static const FlagsType STRICT_ORDER                = 0x00000800;
1226133Ssteve.reinhardt@amd.com    /** This request is to a memory mapped register. */
12310755Sandreas.hansson@arm.com    static const FlagsType MMAPPED_IPR                 = 0x00002000;
1247612SGene.Wu@arm.com    /** This request is a clear exclusive. */
1257705Sgblack@eecs.umich.edu    static const FlagsType CLEAR_LL                    = 0x00004000;
1269950Sprakash.ramrakhyani@arm.com    /** This request is made in privileged mode. */
12710755Sandreas.hansson@arm.com    static const FlagsType PRIVILEGED                  = 0x00008000;
1286133Ssteve.reinhardt@amd.com
12910031SAli.Saidi@ARM.com    /** This is a write that is targeted and zeroing an entire cache block.
13010031SAli.Saidi@ARM.com     * There is no need for a read/modify/write
13110031SAli.Saidi@ARM.com     */
13210031SAli.Saidi@ARM.com    static const FlagsType CACHE_BLOCK_ZERO            = 0x00010000;
13310031SAli.Saidi@ARM.com
1345890Sgblack@eecs.umich.edu    /** The request should not cause a memory access. */
1356133Ssteve.reinhardt@amd.com    static const FlagsType NO_ACCESS                   = 0x00080000;
1366103Sgblack@eecs.umich.edu    /** This request will lock or unlock the accessed memory. When used with
1376103Sgblack@eecs.umich.edu     * a load, the access locks the particular chunk of memory. When used
1386103Sgblack@eecs.umich.edu     * with a store, it unlocks. The rule is that locked accesses have to be
1396103Sgblack@eecs.umich.edu     * made up of a locked load, some operation on the data, and then a locked
1406103Sgblack@eecs.umich.edu     * store.
1416103Sgblack@eecs.umich.edu     */
14210760Ssteve.reinhardt@amd.com    static const FlagsType LOCKED_RMW                  = 0x00100000;
1436133Ssteve.reinhardt@amd.com    /** The request is a Load locked/store conditional. */
1446133Ssteve.reinhardt@amd.com    static const FlagsType LLSC                        = 0x00200000;
1455735Snate@binkert.org    /** This request is for a memory swap. */
1466133Ssteve.reinhardt@amd.com    static const FlagsType MEM_SWAP                    = 0x00400000;
1476133Ssteve.reinhardt@amd.com    static const FlagsType MEM_SWAP_COND               = 0x00800000;
1486133Ssteve.reinhardt@amd.com
1496106Ssteve.reinhardt@amd.com    /** The request is a prefetch. */
1506106Ssteve.reinhardt@amd.com    static const FlagsType PREFETCH                    = 0x01000000;
1516133Ssteve.reinhardt@amd.com    /** The request should be prefetched into the exclusive state. */
1526133Ssteve.reinhardt@amd.com    static const FlagsType PF_EXCLUSIVE                = 0x02000000;
1536133Ssteve.reinhardt@amd.com    /** The request should be marked as LRU. */
1546133Ssteve.reinhardt@amd.com    static const FlagsType EVICT_NEXT                  = 0x04000000;
1555735Snate@binkert.org
1569911Sandreas@sandberg.pp.se    /** The request should be handled by the generic IPR code (only
1579911Sandreas@sandberg.pp.se     * valid together with MMAPPED_IPR) */
1589911Sandreas@sandberg.pp.se    static const FlagsType GENERIC_IPR                 = 0x08000000;
1599911Sandreas@sandberg.pp.se
16010028SGiacomo.Gabrielli@arm.com    /** The request targets the secure memory space. */
16110028SGiacomo.Gabrielli@arm.com    static const FlagsType SECURE                      = 0x10000000;
16210029SGiacomo.Gabrielli@arm.com    /** The request is a page table walk */
16310029SGiacomo.Gabrielli@arm.com    static const FlagsType PT_WALK                     = 0x20000000;
16410028SGiacomo.Gabrielli@arm.com
1656104Ssteve.reinhardt@amd.com    /** These flags are *not* cleared when a Request object is reused
1666104Ssteve.reinhardt@amd.com       (assigned a new address). */
1676105Ssteve.reinhardt@amd.com    static const FlagsType STICKY_FLAGS = INST_FETCH;
1686104Ssteve.reinhardt@amd.com
1698832SAli.Saidi@ARM.com    /** Request Ids that are statically allocated
1708832SAli.Saidi@ARM.com     * @{*/
1718832SAli.Saidi@ARM.com    /** This request id is used for writeback requests by the caches */
1728832SAli.Saidi@ARM.com    static const MasterID wbMasterId = 0;
1738832SAli.Saidi@ARM.com    /** This request id is used for functional requests that don't come from a
1748832SAli.Saidi@ARM.com     * particular device
1758832SAli.Saidi@ARM.com     */
1768832SAli.Saidi@ARM.com    static const MasterID funcMasterId = 1;
1778832SAli.Saidi@ARM.com    /** This request id is used for message signaled interrupts */
1788832SAli.Saidi@ARM.com    static const MasterID intMasterId = 2;
1798833Sdam.sunwoo@arm.com    /** Invalid request id for assertion checking only. It is invalid behavior
1808833Sdam.sunwoo@arm.com     * to ever send this id as part of a request.
1818833Sdam.sunwoo@arm.com     * @todo C++1x replace with numeric_limits when constexpr is added  */
18210755Sandreas.hansson@arm.com    static const MasterID invldMasterId = std::numeric_limits<MasterID>::max();
1838832SAli.Saidi@ARM.com    /** @} */
1848832SAli.Saidi@ARM.com
1859332Sdam.sunwoo@arm.com    /** Invalid or unknown Pid. Possible when operating system is not present
1869332Sdam.sunwoo@arm.com     *  or has not assigned a pid yet */
18710755Sandreas.hansson@arm.com    static const uint32_t invldPid = std::numeric_limits<uint32_t>::max();
1889332Sdam.sunwoo@arm.com
1895735Snate@binkert.org  private:
1906104Ssteve.reinhardt@amd.com    typedef uint8_t PrivateFlagsType;
1916104Ssteve.reinhardt@amd.com    typedef ::Flags<PrivateFlagsType> PrivateFlags;
1925735Snate@binkert.org
1935735Snate@binkert.org    /** Whether or not the size is valid. */
1946104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_SIZE           = 0x00000001;
1955735Snate@binkert.org    /** Whether or not paddr is valid (has been written yet). */
1966104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_PADDR          = 0x00000002;
1975735Snate@binkert.org    /** Whether or not the vaddr & asid are valid. */
1986104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_VADDR          = 0x00000004;
1995735Snate@binkert.org    /** Whether or not the pc is valid. */
2006104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_PC             = 0x00000010;
2015735Snate@binkert.org    /** Whether or not the context ID is valid. */
2026104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_CONTEXT_ID     = 0x00000020;
2036104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_THREAD_ID      = 0x00000040;
2045735Snate@binkert.org    /** Whether or not the sc result is valid. */
2056104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_EXTRA_DATA     = 0x00000080;
2066104Ssteve.reinhardt@amd.com
2076104Ssteve.reinhardt@amd.com    /** These flags are *not* cleared when a Request object is reused
2086104Ssteve.reinhardt@amd.com       (assigned a new address). */
2096104Ssteve.reinhardt@amd.com    static const PrivateFlagsType STICKY_PRIVATE_FLAGS =
2106104Ssteve.reinhardt@amd.com        VALID_CONTEXT_ID | VALID_THREAD_ID;
2115735Snate@binkert.org
2122663Sstever@eecs.umich.edu  private:
21310653Sandreas.hansson@arm.com
21410653Sandreas.hansson@arm.com    /**
21510653Sandreas.hansson@arm.com     * Set up a physical (e.g. device) request in a previously
21610653Sandreas.hansson@arm.com     * allocated Request object.
21710653Sandreas.hansson@arm.com     */
21810653Sandreas.hansson@arm.com    void
21910653Sandreas.hansson@arm.com    setPhys(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
22010653Sandreas.hansson@arm.com    {
22110653Sandreas.hansson@arm.com        assert(size >= 0);
22210653Sandreas.hansson@arm.com        _paddr = paddr;
22310653Sandreas.hansson@arm.com        _size = size;
22410653Sandreas.hansson@arm.com        _time = time;
22510653Sandreas.hansson@arm.com        _masterId = mid;
22610653Sandreas.hansson@arm.com        _flags.clear(~STICKY_FLAGS);
22710653Sandreas.hansson@arm.com        _flags.set(flags);
22810653Sandreas.hansson@arm.com        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
22910653Sandreas.hansson@arm.com        privateFlags.set(VALID_PADDR|VALID_SIZE);
23010653Sandreas.hansson@arm.com        depth = 0;
23110653Sandreas.hansson@arm.com        accessDelta = 0;
23210653Sandreas.hansson@arm.com        //translateDelta = 0;
23310653Sandreas.hansson@arm.com    }
23410653Sandreas.hansson@arm.com
2352663Sstever@eecs.umich.edu    /**
2362663Sstever@eecs.umich.edu     * The physical address of the request. Valid only if validPaddr
2375735Snate@binkert.org     * is set.
2385735Snate@binkert.org     */
2396427Ssteve.reinhardt@amd.com    Addr _paddr;
2402532SN/A
2412663Sstever@eecs.umich.edu    /**
2422663Sstever@eecs.umich.edu     * The size of the request. This field must be set when vaddr or
2432663Sstever@eecs.umich.edu     * paddr is written via setVirt() or setPhys(), so it is always
2445735Snate@binkert.org     * valid as long as one of the address fields is valid.
2455735Snate@binkert.org     */
24610653Sandreas.hansson@arm.com    unsigned _size;
2472395SN/A
2488832SAli.Saidi@ARM.com    /** The requestor ID which is unique in the system for all ports
2498832SAli.Saidi@ARM.com     * that are capable of issuing a transaction
2508832SAli.Saidi@ARM.com     */
2518832SAli.Saidi@ARM.com    MasterID _masterId;
2528832SAli.Saidi@ARM.com
2532532SN/A    /** Flag structure for the request. */
2546427Ssteve.reinhardt@amd.com    Flags _flags;
2552384SN/A
2566104Ssteve.reinhardt@amd.com    /** Private flags for field validity checking. */
2576104Ssteve.reinhardt@amd.com    PrivateFlags privateFlags;
2586104Ssteve.reinhardt@amd.com
2592663Sstever@eecs.umich.edu    /**
2602663Sstever@eecs.umich.edu     * The time this request was started. Used to calculate
2617823Ssteve.reinhardt@amd.com     * latencies. This field is set to curTick() any time paddr or vaddr
2625735Snate@binkert.org     * is written.
2635735Snate@binkert.org     */
2646223Snate@binkert.org    Tick _time;
2652384SN/A
26610024Sdam.sunwoo@arm.com    /**
26710024Sdam.sunwoo@arm.com     * The task id associated with this request
26810024Sdam.sunwoo@arm.com     */
26910024Sdam.sunwoo@arm.com    uint32_t _taskId;
27010024Sdam.sunwoo@arm.com
2712384SN/A    /** The address space ID. */
2726427Ssteve.reinhardt@amd.com    int _asid;
2733806Ssaidi@eecs.umich.edu
2742663Sstever@eecs.umich.edu    /** The virtual address of the request. */
2756427Ssteve.reinhardt@amd.com    Addr _vaddr;
2762384SN/A
2775735Snate@binkert.org    /**
2785735Snate@binkert.org     * Extra data for the request, such as the return value of
2794040Ssaidi@eecs.umich.edu     * store conditional or the compare value for a CAS. */
2806427Ssteve.reinhardt@amd.com    uint64_t _extraData;
2812384SN/A
2825714Shsul@eecs.umich.edu    /** The context ID (for statistics, typically). */
2835714Shsul@eecs.umich.edu    int _contextId;
2845714Shsul@eecs.umich.edu    /** The thread ID (id within this CPU) */
28510755Sandreas.hansson@arm.com    ThreadID _threadId;
2862384SN/A
2872381SN/A    /** program counter of initiating access; for tracing/debugging */
2886427Ssteve.reinhardt@amd.com    Addr _pc;
2892663Sstever@eecs.umich.edu
2902532SN/A  public:
29110653Sandreas.hansson@arm.com
29210653Sandreas.hansson@arm.com    /**
29310653Sandreas.hansson@arm.com     * Minimal constructor. No fields are initialized. (Note that
29410653Sandreas.hansson@arm.com     *  _flags and privateFlags are cleared by Flags default
29510653Sandreas.hansson@arm.com     *  constructor.)
2966427Ssteve.reinhardt@amd.com     */
2972663Sstever@eecs.umich.edu    Request()
29810360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
29910360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
30010360Sandreas.hansson@arm.com          _extraData(0), _contextId(0), _threadId(0), _pc(0),
30110360Sandreas.hansson@arm.com          translateDelta(0), accessDelta(0), depth(0)
3022663Sstever@eecs.umich.edu    {}
3032532SN/A
3042663Sstever@eecs.umich.edu    /**
3052663Sstever@eecs.umich.edu     * Constructor for physical (e.g. device) requests.  Initializes
3067823Ssteve.reinhardt@amd.com     * just physical address, size, flags, and timestamp (to curTick()).
30710653Sandreas.hansson@arm.com     * These fields are adequate to perform a request.
3085735Snate@binkert.org     */
30910653Sandreas.hansson@arm.com    Request(Addr paddr, unsigned size, Flags flags, MasterID mid)
31010360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
31110360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
31210360Sandreas.hansson@arm.com          _extraData(0), _contextId(0), _threadId(0), _pc(0),
31310360Sandreas.hansson@arm.com          translateDelta(0), accessDelta(0), depth(0)
3145735Snate@binkert.org    {
31510653Sandreas.hansson@arm.com        setPhys(paddr, size, flags, mid, curTick());
3165735Snate@binkert.org    }
3172532SN/A
31810653Sandreas.hansson@arm.com    Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
31910360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
32010360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
32110360Sandreas.hansson@arm.com          _extraData(0), _contextId(0), _threadId(0), _pc(0),
32210360Sandreas.hansson@arm.com          translateDelta(0), accessDelta(0), depth(0)
3236223Snate@binkert.org    {
3248832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid, time);
3256223Snate@binkert.org    }
3266223Snate@binkert.org
32710653Sandreas.hansson@arm.com    Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time,
32810653Sandreas.hansson@arm.com            Addr pc)
32910360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
33010360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
33110360Sandreas.hansson@arm.com          _extraData(0), _contextId(0), _threadId(0), _pc(0),
33210360Sandreas.hansson@arm.com          translateDelta(0), accessDelta(0), depth(0)
3336899SBrad.Beckmann@amd.com    {
3348832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid, time);
3356899SBrad.Beckmann@amd.com        privateFlags.set(VALID_PC);
3366899SBrad.Beckmann@amd.com        _pc = pc;
3376899SBrad.Beckmann@amd.com    }
3386899SBrad.Beckmann@amd.com
33910653Sandreas.hansson@arm.com    Request(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid,
34010755Sandreas.hansson@arm.com            Addr pc, int cid, ThreadID tid)
34110360Sandreas.hansson@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
34210360Sandreas.hansson@arm.com          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
34310360Sandreas.hansson@arm.com          _extraData(0), _contextId(0), _threadId(0), _pc(0),
34410360Sandreas.hansson@arm.com          translateDelta(0), accessDelta(0), depth(0)
3452669Sktlim@umich.edu    {
3468832SAli.Saidi@ARM.com        setVirt(asid, vaddr, size, flags, mid, pc);
3475735Snate@binkert.org        setThreadContext(cid, tid);
3482669Sktlim@umich.edu    }
3492669Sktlim@umich.edu
3509044SAli.Saidi@ARM.com    ~Request() {}
3514610Ssaidi@eecs.umich.edu
3522663Sstever@eecs.umich.edu    /**
3535735Snate@binkert.org     * Set up CPU and thread numbers.
3545735Snate@binkert.org     */
3555735Snate@binkert.org    void
3566221Snate@binkert.org    setThreadContext(int context_id, ThreadID tid)
3572663Sstever@eecs.umich.edu    {
3585735Snate@binkert.org        _contextId = context_id;
3596221Snate@binkert.org        _threadId = tid;
3606104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID);
3612663Sstever@eecs.umich.edu    }
3622532SN/A
3632663Sstever@eecs.umich.edu    /**
3642663Sstever@eecs.umich.edu     * Set up a virtual (e.g., CPU) request in a previously
3655735Snate@binkert.org     * allocated Request object.
3665735Snate@binkert.org     */
3675735Snate@binkert.org    void
36810653Sandreas.hansson@arm.com    setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid,
36910653Sandreas.hansson@arm.com            Addr pc)
3702663Sstever@eecs.umich.edu    {
3716427Ssteve.reinhardt@amd.com        _asid = asid;
3726427Ssteve.reinhardt@amd.com        _vaddr = vaddr;
3736427Ssteve.reinhardt@amd.com        _size = size;
3748832SAli.Saidi@ARM.com        _masterId = mid;
3756427Ssteve.reinhardt@amd.com        _pc = pc;
3767823Ssteve.reinhardt@amd.com        _time = curTick();
3775735Snate@binkert.org
3786427Ssteve.reinhardt@amd.com        _flags.clear(~STICKY_FLAGS);
3796427Ssteve.reinhardt@amd.com        _flags.set(flags);
3806104Ssteve.reinhardt@amd.com        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
3816104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC);
38210020Smatt.horsnell@ARM.com        depth = 0;
38310020Smatt.horsnell@ARM.com        accessDelta = 0;
38410020Smatt.horsnell@ARM.com        translateDelta = 0;
3852663Sstever@eecs.umich.edu    }
3862532SN/A
3875735Snate@binkert.org    /**
3889760Sandreas@sandberg.pp.se     * Set just the physical address.  This usually used to record the
3899760Sandreas@sandberg.pp.se     * result of a translation. However, when using virtualized CPUs
3909760Sandreas@sandberg.pp.se     * setPhys() is sometimes called to finalize a physical address
3919760Sandreas@sandberg.pp.se     * without a virtual address, so we can't check if the virtual
3929760Sandreas@sandberg.pp.se     * address is valid.
3932663Sstever@eecs.umich.edu     */
3945735Snate@binkert.org    void
3956427Ssteve.reinhardt@amd.com    setPaddr(Addr paddr)
3962663Sstever@eecs.umich.edu    {
3976427Ssteve.reinhardt@amd.com        _paddr = paddr;
3986104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_PADDR);
3992663Sstever@eecs.umich.edu    }
4002532SN/A
4015735Snate@binkert.org    /**
4025744Sgblack@eecs.umich.edu     * Generate two requests as if this request had been split into two
4035744Sgblack@eecs.umich.edu     * pieces. The original request can't have been translated already.
4045744Sgblack@eecs.umich.edu     */
4055744Sgblack@eecs.umich.edu    void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2)
4065744Sgblack@eecs.umich.edu    {
4076104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
4086104Ssteve.reinhardt@amd.com        assert(privateFlags.noneSet(VALID_PADDR));
4096427Ssteve.reinhardt@amd.com        assert(split_addr > _vaddr && split_addr < _vaddr + _size);
41010653Sandreas.hansson@arm.com        req1 = new Request(*this);
41110653Sandreas.hansson@arm.com        req2 = new Request(*this);
4126427Ssteve.reinhardt@amd.com        req1->_size = split_addr - _vaddr;
4136427Ssteve.reinhardt@amd.com        req2->_vaddr = split_addr;
4146427Ssteve.reinhardt@amd.com        req2->_size = _size - req1->_size;
4155744Sgblack@eecs.umich.edu    }
4165744Sgblack@eecs.umich.edu
4175744Sgblack@eecs.umich.edu    /**
4185735Snate@binkert.org     * Accessor for paddr.
4195735Snate@binkert.org     */
4206104Ssteve.reinhardt@amd.com    bool
42110568Sandreas.hansson@arm.com    hasPaddr() const
4226104Ssteve.reinhardt@amd.com    {
4236104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_PADDR);
4246104Ssteve.reinhardt@amd.com    }
4256104Ssteve.reinhardt@amd.com
4265735Snate@binkert.org    Addr
42710568Sandreas.hansson@arm.com    getPaddr() const
4285735Snate@binkert.org    {
4296104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR));
4306427Ssteve.reinhardt@amd.com        return _paddr;
4315735Snate@binkert.org    }
4322663Sstever@eecs.umich.edu
4335735Snate@binkert.org    /**
43410020Smatt.horsnell@ARM.com     * Time for the TLB/table walker to successfully translate this request.
43510020Smatt.horsnell@ARM.com     */
43610020Smatt.horsnell@ARM.com    Tick translateDelta;
43710020Smatt.horsnell@ARM.com
43810020Smatt.horsnell@ARM.com    /**
43910020Smatt.horsnell@ARM.com     * Access latency to complete this memory transaction not including
44010020Smatt.horsnell@ARM.com     * translation time.
44110020Smatt.horsnell@ARM.com     */
44210020Smatt.horsnell@ARM.com    Tick accessDelta;
44310020Smatt.horsnell@ARM.com
44410020Smatt.horsnell@ARM.com    /**
44510020Smatt.horsnell@ARM.com     * Level of the cache hierachy where this request was responded to
44610020Smatt.horsnell@ARM.com     * (e.g. 0 = L1; 1 = L2).
44710020Smatt.horsnell@ARM.com     */
44810568Sandreas.hansson@arm.com    mutable int depth;
44910020Smatt.horsnell@ARM.com
45010020Smatt.horsnell@ARM.com    /**
4515735Snate@binkert.org     *  Accessor for size.
4525735Snate@binkert.org     */
4536104Ssteve.reinhardt@amd.com    bool
45410568Sandreas.hansson@arm.com    hasSize() const
4556104Ssteve.reinhardt@amd.com    {
4566104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_SIZE);
4576104Ssteve.reinhardt@amd.com    }
4586104Ssteve.reinhardt@amd.com
45910755Sandreas.hansson@arm.com    unsigned
46010568Sandreas.hansson@arm.com    getSize() const
4615735Snate@binkert.org    {
4626104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_SIZE));
4636427Ssteve.reinhardt@amd.com        return _size;
4645735Snate@binkert.org    }
4655735Snate@binkert.org
4662663Sstever@eecs.umich.edu    /** Accessor for time. */
4675735Snate@binkert.org    Tick
4686223Snate@binkert.org    time() const
4695735Snate@binkert.org    {
4706104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4716223Snate@binkert.org        return _time;
4726223Snate@binkert.org    }
4736223Snate@binkert.org
4742663Sstever@eecs.umich.edu    /** Accessor for flags. */
4755735Snate@binkert.org    Flags
4765735Snate@binkert.org    getFlags()
4775735Snate@binkert.org    {
4786104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4796427Ssteve.reinhardt@amd.com        return _flags;
4805735Snate@binkert.org    }
4815735Snate@binkert.org
4826428Ssteve.reinhardt@amd.com    /** Note that unlike other accessors, this function sets *specific
4836428Ssteve.reinhardt@amd.com       flags* (ORs them in); it does not assign its argument to the
4846428Ssteve.reinhardt@amd.com       _flags field.  Thus this method should rightly be called
4856428Ssteve.reinhardt@amd.com       setFlags() and not just flags(). */
4865735Snate@binkert.org    void
4876427Ssteve.reinhardt@amd.com    setFlags(Flags flags)
4885735Snate@binkert.org    {
4896104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4906427Ssteve.reinhardt@amd.com        _flags.set(flags);
4915735Snate@binkert.org    }
4925735Snate@binkert.org
4932663Sstever@eecs.umich.edu    /** Accessor function for vaddr.*/
49410362Smitch.hayenga@arm.com    bool
49510362Smitch.hayenga@arm.com    hasVaddr() const
49610362Smitch.hayenga@arm.com    {
49710362Smitch.hayenga@arm.com        return privateFlags.isSet(VALID_VADDR);
49810362Smitch.hayenga@arm.com    }
49910362Smitch.hayenga@arm.com
5005735Snate@binkert.org    Addr
50110362Smitch.hayenga@arm.com    getVaddr() const
5025735Snate@binkert.org    {
5036104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
5046427Ssteve.reinhardt@amd.com        return _vaddr;
5055735Snate@binkert.org    }
5062663Sstever@eecs.umich.edu
5078832SAli.Saidi@ARM.com    /** Accesssor for the requestor id. */
5088832SAli.Saidi@ARM.com    MasterID
50910568Sandreas.hansson@arm.com    masterId() const
5108832SAli.Saidi@ARM.com    {
5118832SAli.Saidi@ARM.com        return _masterId;
5128832SAli.Saidi@ARM.com    }
5138832SAli.Saidi@ARM.com
51410024Sdam.sunwoo@arm.com    uint32_t
51510024Sdam.sunwoo@arm.com    taskId() const
51610024Sdam.sunwoo@arm.com    {
51710024Sdam.sunwoo@arm.com        return _taskId;
51810024Sdam.sunwoo@arm.com    }
51910024Sdam.sunwoo@arm.com
52010024Sdam.sunwoo@arm.com    void
52110024Sdam.sunwoo@arm.com    taskId(uint32_t id) {
52210024Sdam.sunwoo@arm.com        _taskId = id;
52310024Sdam.sunwoo@arm.com    }
52410024Sdam.sunwoo@arm.com
5252663Sstever@eecs.umich.edu    /** Accessor function for asid.*/
5265735Snate@binkert.org    int
52710568Sandreas.hansson@arm.com    getAsid() const
5285735Snate@binkert.org    {
5296104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
5306427Ssteve.reinhardt@amd.com        return _asid;
5315735Snate@binkert.org    }
5322663Sstever@eecs.umich.edu
5338551Sdaniel.johnson@arm.com    /** Accessor function for asid.*/
5348551Sdaniel.johnson@arm.com    void
5358551Sdaniel.johnson@arm.com    setAsid(int asid)
5368551Sdaniel.johnson@arm.com    {
5378551Sdaniel.johnson@arm.com        _asid = asid;
5388551Sdaniel.johnson@arm.com    }
5398551Sdaniel.johnson@arm.com
5409912Sandreas@sandberg.pp.se    /** Accessor function for architecture-specific flags.*/
5419912Sandreas@sandberg.pp.se    ArchFlagsType
54210568Sandreas.hansson@arm.com    getArchFlags() const
5435735Snate@binkert.org    {
5449912Sandreas@sandberg.pp.se        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
5459912Sandreas@sandberg.pp.se        return _flags & ARCH_BITS;
5465735Snate@binkert.org    }
5473804Ssaidi@eecs.umich.edu
5482679Sktlim@umich.edu    /** Accessor function to check if sc result is valid. */
5495735Snate@binkert.org    bool
55010568Sandreas.hansson@arm.com    extraDataValid() const
5515735Snate@binkert.org    {
5526104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_EXTRA_DATA);
5535735Snate@binkert.org    }
5545735Snate@binkert.org
5552663Sstever@eecs.umich.edu    /** Accessor function for store conditional return value.*/
5565735Snate@binkert.org    uint64_t
5575735Snate@binkert.org    getExtraData() const
5585735Snate@binkert.org    {
5596104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_EXTRA_DATA));
5606427Ssteve.reinhardt@amd.com        return _extraData;
5615735Snate@binkert.org    }
5625735Snate@binkert.org
5632663Sstever@eecs.umich.edu    /** Accessor function for store conditional return value.*/
5645735Snate@binkert.org    void
5656427Ssteve.reinhardt@amd.com    setExtraData(uint64_t extraData)
5665735Snate@binkert.org    {
5676427Ssteve.reinhardt@amd.com        _extraData = extraData;
5686104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_EXTRA_DATA);
5695735Snate@binkert.org    }
5702663Sstever@eecs.umich.edu
5716010Ssteve.reinhardt@amd.com    bool
5726010Ssteve.reinhardt@amd.com    hasContextId() const
5736010Ssteve.reinhardt@amd.com    {
5746104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_CONTEXT_ID);
5756010Ssteve.reinhardt@amd.com    }
5766010Ssteve.reinhardt@amd.com
5775714Shsul@eecs.umich.edu    /** Accessor function for context ID.*/
5785735Snate@binkert.org    int
5795735Snate@binkert.org    contextId() const
5805735Snate@binkert.org    {
5816104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_CONTEXT_ID));
5825735Snate@binkert.org        return _contextId;
5835735Snate@binkert.org    }
5845735Snate@binkert.org
5855714Shsul@eecs.umich.edu    /** Accessor function for thread ID. */
58610755Sandreas.hansson@arm.com    ThreadID
5875735Snate@binkert.org    threadId() const
5885735Snate@binkert.org    {
5896104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_THREAD_ID));
5905735Snate@binkert.org        return _threadId;
5915735Snate@binkert.org    }
5922663Sstever@eecs.umich.edu
59310052Smitch.hayenga+gem5@gmail.com    void
59410052Smitch.hayenga+gem5@gmail.com    setPC(Addr pc)
59510052Smitch.hayenga+gem5@gmail.com    {
59610052Smitch.hayenga+gem5@gmail.com        privateFlags.set(VALID_PC);
59710052Smitch.hayenga+gem5@gmail.com        _pc = pc;
59810052Smitch.hayenga+gem5@gmail.com    }
59910052Smitch.hayenga+gem5@gmail.com
6005875Ssteve.reinhardt@amd.com    bool
6015875Ssteve.reinhardt@amd.com    hasPC() const
6025875Ssteve.reinhardt@amd.com    {
6036104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_PC);
6045875Ssteve.reinhardt@amd.com    }
6055875Ssteve.reinhardt@amd.com
6066010Ssteve.reinhardt@amd.com    /** Accessor function for pc.*/
6075735Snate@binkert.org    Addr
6085735Snate@binkert.org    getPC() const
6095735Snate@binkert.org    {
6106104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PC));
6116427Ssteve.reinhardt@amd.com        return _pc;
6125735Snate@binkert.org    }
6132532SN/A
61410020Smatt.horsnell@ARM.com    /**
61510020Smatt.horsnell@ARM.com     * Increment/Get the depth at which this request is responded to.
61610020Smatt.horsnell@ARM.com     * This currently happens when the request misses in any cache level.
61710020Smatt.horsnell@ARM.com     */
61810568Sandreas.hansson@arm.com    void incAccessDepth() const { depth++; }
61910020Smatt.horsnell@ARM.com    int getAccessDepth() const { return depth; }
62010020Smatt.horsnell@ARM.com
62110020Smatt.horsnell@ARM.com    /**
62210020Smatt.horsnell@ARM.com     * Set/Get the time taken for this request to be successfully translated.
62310020Smatt.horsnell@ARM.com     */
62410020Smatt.horsnell@ARM.com    void setTranslateLatency() { translateDelta = curTick() - _time; }
62510020Smatt.horsnell@ARM.com    Tick getTranslateLatency() const { return translateDelta; }
62610020Smatt.horsnell@ARM.com
62710020Smatt.horsnell@ARM.com    /**
62810020Smatt.horsnell@ARM.com     * Set/Get the time taken to complete this request's access, not including
62910020Smatt.horsnell@ARM.com     *  the time to successfully translate the request.
63010020Smatt.horsnell@ARM.com     */
63110020Smatt.horsnell@ARM.com    void setAccessLatency() { accessDelta = curTick() - _time - translateDelta; }
63210020Smatt.horsnell@ARM.com    Tick getAccessLatency() const { return accessDelta; }
63310020Smatt.horsnell@ARM.com
6346428Ssteve.reinhardt@amd.com    /** Accessor functions for flags.  Note that these are for testing
6356428Ssteve.reinhardt@amd.com       only; setting flags should be done via setFlags(). */
6366427Ssteve.reinhardt@amd.com    bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
63710824SAndreas.Sandberg@ARM.com    bool isStrictlyOrdered() const { return _flags.isSet(STRICT_ORDER); }
6386427Ssteve.reinhardt@amd.com    bool isInstFetch() const { return _flags.isSet(INST_FETCH); }
6396427Ssteve.reinhardt@amd.com    bool isPrefetch() const { return _flags.isSet(PREFETCH); }
6406427Ssteve.reinhardt@amd.com    bool isLLSC() const { return _flags.isSet(LLSC); }
6419950Sprakash.ramrakhyani@arm.com    bool isPriv() const { return _flags.isSet(PRIVILEGED); }
64210760Ssteve.reinhardt@amd.com    bool isLockedRMW() const { return _flags.isSet(LOCKED_RMW); }
6436427Ssteve.reinhardt@amd.com    bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
6446427Ssteve.reinhardt@amd.com    bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
6458105Sgblack@eecs.umich.edu    bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
6467705Sgblack@eecs.umich.edu    bool isClearLL() const { return _flags.isSet(CLEAR_LL); }
64710028SGiacomo.Gabrielli@arm.com    bool isSecure() const { return _flags.isSet(SECURE); }
64810029SGiacomo.Gabrielli@arm.com    bool isPTWalk() const { return _flags.isSet(PT_WALK); }
6492384SN/A};
6502381SN/A
6512381SN/A#endif // __MEM_REQUEST_HH__
652