request.hh revision 10052
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;
1045735Snate@binkert.org    /** The request is an ALPHA VPTE pal access (hw_ld). */
1055735Snate@binkert.org    static const FlagsType VPTE                        = 0x00000400;
1065735Snate@binkert.org    /** Use the alternate mode bits in ALPHA. */
1075735Snate@binkert.org    static const FlagsType ALTMODE                     = 0x00000800;
1085735Snate@binkert.org    /** The request is to an uncacheable address. */
1095735Snate@binkert.org    static const FlagsType UNCACHEABLE                 = 0x00001000;
1106133Ssteve.reinhardt@amd.com    /** This request is to a memory mapped register. */
1118105Sgblack@eecs.umich.edu    static const FlagsType MMAPPED_IPR                  = 0x00002000;
1127612SGene.Wu@arm.com    /** This request is a clear exclusive. */
1137705Sgblack@eecs.umich.edu    static const FlagsType CLEAR_LL                    = 0x00004000;
1149950Sprakash.ramrakhyani@arm.com    /** This request is made in privileged mode. */
1159950Sprakash.ramrakhyani@arm.com    static const FlagsType PRIVILEGED                   = 0x00008000;
1166133Ssteve.reinhardt@amd.com
11710031SAli.Saidi@ARM.com    /** This is a write that is targeted and zeroing an entire cache block.
11810031SAli.Saidi@ARM.com     * There is no need for a read/modify/write
11910031SAli.Saidi@ARM.com     */
12010031SAli.Saidi@ARM.com    static const FlagsType CACHE_BLOCK_ZERO            = 0x00010000;
12110031SAli.Saidi@ARM.com
1225890Sgblack@eecs.umich.edu    /** The request should not cause a memory access. */
1236133Ssteve.reinhardt@amd.com    static const FlagsType NO_ACCESS                   = 0x00080000;
1246103Sgblack@eecs.umich.edu    /** This request will lock or unlock the accessed memory. When used with
1256103Sgblack@eecs.umich.edu     * a load, the access locks the particular chunk of memory. When used
1266103Sgblack@eecs.umich.edu     * with a store, it unlocks. The rule is that locked accesses have to be
1276103Sgblack@eecs.umich.edu     * made up of a locked load, some operation on the data, and then a locked
1286103Sgblack@eecs.umich.edu     * store.
1296103Sgblack@eecs.umich.edu     */
1306133Ssteve.reinhardt@amd.com    static const FlagsType LOCKED                      = 0x00100000;
1316133Ssteve.reinhardt@amd.com    /** The request is a Load locked/store conditional. */
1326133Ssteve.reinhardt@amd.com    static const FlagsType LLSC                        = 0x00200000;
1335735Snate@binkert.org    /** This request is for a memory swap. */
1346133Ssteve.reinhardt@amd.com    static const FlagsType MEM_SWAP                    = 0x00400000;
1356133Ssteve.reinhardt@amd.com    static const FlagsType MEM_SWAP_COND               = 0x00800000;
1366133Ssteve.reinhardt@amd.com
1376106Ssteve.reinhardt@amd.com    /** The request is a prefetch. */
1386106Ssteve.reinhardt@amd.com    static const FlagsType PREFETCH                    = 0x01000000;
1396133Ssteve.reinhardt@amd.com    /** The request should be prefetched into the exclusive state. */
1406133Ssteve.reinhardt@amd.com    static const FlagsType PF_EXCLUSIVE                = 0x02000000;
1416133Ssteve.reinhardt@amd.com    /** The request should be marked as LRU. */
1426133Ssteve.reinhardt@amd.com    static const FlagsType EVICT_NEXT                  = 0x04000000;
1435735Snate@binkert.org
1449911Sandreas@sandberg.pp.se    /** The request should be handled by the generic IPR code (only
1459911Sandreas@sandberg.pp.se     * valid together with MMAPPED_IPR) */
1469911Sandreas@sandberg.pp.se    static const FlagsType GENERIC_IPR                 = 0x08000000;
1479911Sandreas@sandberg.pp.se
14810028SGiacomo.Gabrielli@arm.com    /** The request targets the secure memory space. */
14910028SGiacomo.Gabrielli@arm.com    static const FlagsType SECURE                      = 0x10000000;
15010029SGiacomo.Gabrielli@arm.com    /** The request is a page table walk */
15110029SGiacomo.Gabrielli@arm.com    static const FlagsType PT_WALK                     = 0x20000000;
15210028SGiacomo.Gabrielli@arm.com
1536104Ssteve.reinhardt@amd.com    /** These flags are *not* cleared when a Request object is reused
1546104Ssteve.reinhardt@amd.com       (assigned a new address). */
1556105Ssteve.reinhardt@amd.com    static const FlagsType STICKY_FLAGS = INST_FETCH;
1566104Ssteve.reinhardt@amd.com
1578832SAli.Saidi@ARM.com    /** Request Ids that are statically allocated
1588832SAli.Saidi@ARM.com     * @{*/
1598832SAli.Saidi@ARM.com    /** This request id is used for writeback requests by the caches */
1608832SAli.Saidi@ARM.com    static const MasterID wbMasterId = 0;
1618832SAli.Saidi@ARM.com    /** This request id is used for functional requests that don't come from a
1628832SAli.Saidi@ARM.com     * particular device
1638832SAli.Saidi@ARM.com     */
1648832SAli.Saidi@ARM.com    static const MasterID funcMasterId = 1;
1658832SAli.Saidi@ARM.com    /** This request id is used for message signaled interrupts */
1668832SAli.Saidi@ARM.com    static const MasterID intMasterId = 2;
1678833Sdam.sunwoo@arm.com    /** Invalid request id for assertion checking only. It is invalid behavior
1688833Sdam.sunwoo@arm.com     * to ever send this id as part of a request.
1698833Sdam.sunwoo@arm.com     * @todo C++1x replace with numeric_limits when constexpr is added  */
1708833Sdam.sunwoo@arm.com    static const MasterID invldMasterId = USHRT_MAX;
1718832SAli.Saidi@ARM.com    /** @} */
1728832SAli.Saidi@ARM.com
1739332Sdam.sunwoo@arm.com    /** Invalid or unknown Pid. Possible when operating system is not present
1749332Sdam.sunwoo@arm.com     *  or has not assigned a pid yet */
1759332Sdam.sunwoo@arm.com    static const uint32_t invldPid = UINT_MAX;
1769332Sdam.sunwoo@arm.com
1775735Snate@binkert.org  private:
1786104Ssteve.reinhardt@amd.com    typedef uint8_t PrivateFlagsType;
1796104Ssteve.reinhardt@amd.com    typedef ::Flags<PrivateFlagsType> PrivateFlags;
1805735Snate@binkert.org
1815735Snate@binkert.org    /** Whether or not the size is valid. */
1826104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_SIZE           = 0x00000001;
1835735Snate@binkert.org    /** Whether or not paddr is valid (has been written yet). */
1846104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_PADDR          = 0x00000002;
1855735Snate@binkert.org    /** Whether or not the vaddr & asid are valid. */
1866104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_VADDR          = 0x00000004;
1875735Snate@binkert.org    /** Whether or not the pc is valid. */
1886104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_PC             = 0x00000010;
1895735Snate@binkert.org    /** Whether or not the context ID is valid. */
1906104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_CONTEXT_ID     = 0x00000020;
1916104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_THREAD_ID      = 0x00000040;
1925735Snate@binkert.org    /** Whether or not the sc result is valid. */
1936104Ssteve.reinhardt@amd.com    static const PrivateFlagsType VALID_EXTRA_DATA     = 0x00000080;
1946104Ssteve.reinhardt@amd.com
1956104Ssteve.reinhardt@amd.com    /** These flags are *not* cleared when a Request object is reused
1966104Ssteve.reinhardt@amd.com       (assigned a new address). */
1976104Ssteve.reinhardt@amd.com    static const PrivateFlagsType STICKY_PRIVATE_FLAGS =
1986104Ssteve.reinhardt@amd.com        VALID_CONTEXT_ID | VALID_THREAD_ID;
1995735Snate@binkert.org
2002663Sstever@eecs.umich.edu  private:
2012663Sstever@eecs.umich.edu    /**
2022663Sstever@eecs.umich.edu     * The physical address of the request. Valid only if validPaddr
2035735Snate@binkert.org     * is set.
2045735Snate@binkert.org     */
2056427Ssteve.reinhardt@amd.com    Addr _paddr;
2062532SN/A
2072663Sstever@eecs.umich.edu    /**
2082663Sstever@eecs.umich.edu     * The size of the request. This field must be set when vaddr or
2092663Sstever@eecs.umich.edu     * paddr is written via setVirt() or setPhys(), so it is always
2105735Snate@binkert.org     * valid as long as one of the address fields is valid.
2115735Snate@binkert.org     */
2126427Ssteve.reinhardt@amd.com    int _size;
2132395SN/A
2148832SAli.Saidi@ARM.com    /** The requestor ID which is unique in the system for all ports
2158832SAli.Saidi@ARM.com     * that are capable of issuing a transaction
2168832SAli.Saidi@ARM.com     */
2178832SAli.Saidi@ARM.com    MasterID _masterId;
2188832SAli.Saidi@ARM.com
2192532SN/A    /** Flag structure for the request. */
2206427Ssteve.reinhardt@amd.com    Flags _flags;
2212384SN/A
2226104Ssteve.reinhardt@amd.com    /** Private flags for field validity checking. */
2236104Ssteve.reinhardt@amd.com    PrivateFlags privateFlags;
2246104Ssteve.reinhardt@amd.com
2252663Sstever@eecs.umich.edu    /**
2262663Sstever@eecs.umich.edu     * The time this request was started. Used to calculate
2277823Ssteve.reinhardt@amd.com     * latencies. This field is set to curTick() any time paddr or vaddr
2285735Snate@binkert.org     * is written.
2295735Snate@binkert.org     */
2306223Snate@binkert.org    Tick _time;
2312384SN/A
23210024Sdam.sunwoo@arm.com    /**
23310024Sdam.sunwoo@arm.com     * The task id associated with this request
23410024Sdam.sunwoo@arm.com     */
23510024Sdam.sunwoo@arm.com    uint32_t _taskId;
23610024Sdam.sunwoo@arm.com
2372384SN/A    /** The address space ID. */
2386427Ssteve.reinhardt@amd.com    int _asid;
2393806Ssaidi@eecs.umich.edu
2402663Sstever@eecs.umich.edu    /** The virtual address of the request. */
2416427Ssteve.reinhardt@amd.com    Addr _vaddr;
2422384SN/A
2435735Snate@binkert.org    /**
2445735Snate@binkert.org     * Extra data for the request, such as the return value of
2454040Ssaidi@eecs.umich.edu     * store conditional or the compare value for a CAS. */
2466427Ssteve.reinhardt@amd.com    uint64_t _extraData;
2472384SN/A
2485714Shsul@eecs.umich.edu    /** The context ID (for statistics, typically). */
2495714Shsul@eecs.umich.edu    int _contextId;
2505714Shsul@eecs.umich.edu    /** The thread ID (id within this CPU) */
2515714Shsul@eecs.umich.edu    int _threadId;
2522384SN/A
2532381SN/A    /** program counter of initiating access; for tracing/debugging */
2546427Ssteve.reinhardt@amd.com    Addr _pc;
2552663Sstever@eecs.umich.edu
2562532SN/A  public:
2576427Ssteve.reinhardt@amd.com    /** Minimal constructor.  No fields are initialized.
2586427Ssteve.reinhardt@amd.com     *  (Note that _flags and privateFlags are cleared by Flags
2596427Ssteve.reinhardt@amd.com     *  default constructor.)
2606427Ssteve.reinhardt@amd.com     */
2612663Sstever@eecs.umich.edu    Request()
26210024Sdam.sunwoo@arm.com        : _taskId(ContextSwitchTaskId::Unknown),
26310024Sdam.sunwoo@arm.com        translateDelta(0), accessDelta(0), depth(0)
2642663Sstever@eecs.umich.edu    {}
2652532SN/A
2662663Sstever@eecs.umich.edu    /**
2672663Sstever@eecs.umich.edu     * Constructor for physical (e.g. device) requests.  Initializes
2687823Ssteve.reinhardt@amd.com     * just physical address, size, flags, and timestamp (to curTick()).
2695735Snate@binkert.org     * These fields are adequate to perform a request.
2705735Snate@binkert.org     */
2718832SAli.Saidi@ARM.com    Request(Addr paddr, int size, Flags flags, MasterID mid)
27210024Sdam.sunwoo@arm.com        : _taskId(ContextSwitchTaskId::Unknown)
2735735Snate@binkert.org    {
2748832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid);
2755735Snate@binkert.org    }
2762532SN/A
2778832SAli.Saidi@ARM.com    Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
27810024Sdam.sunwoo@arm.com        : _taskId(ContextSwitchTaskId::Unknown)
2796223Snate@binkert.org    {
2808832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid, time);
2816223Snate@binkert.org    }
2826223Snate@binkert.org
2838832SAli.Saidi@ARM.com    Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time, Addr pc)
28410024Sdam.sunwoo@arm.com        : _taskId(ContextSwitchTaskId::Unknown)
2856899SBrad.Beckmann@amd.com    {
2868832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid, time);
2876899SBrad.Beckmann@amd.com        privateFlags.set(VALID_PC);
2886899SBrad.Beckmann@amd.com        _pc = pc;
2896899SBrad.Beckmann@amd.com    }
2906899SBrad.Beckmann@amd.com
2918832SAli.Saidi@ARM.com    Request(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc,
2926221Snate@binkert.org            int cid, ThreadID tid)
29310024Sdam.sunwoo@arm.com        : _taskId(ContextSwitchTaskId::Unknown)
2942669Sktlim@umich.edu    {
2958832SAli.Saidi@ARM.com        setVirt(asid, vaddr, size, flags, mid, pc);
2965735Snate@binkert.org        setThreadContext(cid, tid);
2972669Sktlim@umich.edu    }
2982669Sktlim@umich.edu
2999044SAli.Saidi@ARM.com    ~Request() {}
3004610Ssaidi@eecs.umich.edu
3012663Sstever@eecs.umich.edu    /**
3025735Snate@binkert.org     * Set up CPU and thread numbers.
3035735Snate@binkert.org     */
3045735Snate@binkert.org    void
3056221Snate@binkert.org    setThreadContext(int context_id, ThreadID tid)
3062663Sstever@eecs.umich.edu    {
3075735Snate@binkert.org        _contextId = context_id;
3086221Snate@binkert.org        _threadId = tid;
3096104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID);
3102663Sstever@eecs.umich.edu    }
3112532SN/A
3122663Sstever@eecs.umich.edu    /**
3132663Sstever@eecs.umich.edu     * Set up a physical (e.g. device) request in a previously
3145735Snate@binkert.org     * allocated Request object.
3155735Snate@binkert.org     */
3165735Snate@binkert.org    void
3178832SAli.Saidi@ARM.com    setPhys(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
3182663Sstever@eecs.umich.edu    {
3196427Ssteve.reinhardt@amd.com        assert(size >= 0);
3206427Ssteve.reinhardt@amd.com        _paddr = paddr;
3216427Ssteve.reinhardt@amd.com        _size = size;
3226223Snate@binkert.org        _time = time;
3238832SAli.Saidi@ARM.com        _masterId = mid;
3246427Ssteve.reinhardt@amd.com        _flags.clear(~STICKY_FLAGS);
3256427Ssteve.reinhardt@amd.com        _flags.set(flags);
3266104Ssteve.reinhardt@amd.com        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
3276104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_PADDR|VALID_SIZE);
32810020Smatt.horsnell@ARM.com        depth = 0;
32910020Smatt.horsnell@ARM.com        accessDelta = 0;
33010020Smatt.horsnell@ARM.com        //translateDelta = 0;
3312663Sstever@eecs.umich.edu    }
3322532SN/A
3336223Snate@binkert.org    void
3348832SAli.Saidi@ARM.com    setPhys(Addr paddr, int size, Flags flags, MasterID mid)
3356223Snate@binkert.org    {
3368832SAli.Saidi@ARM.com        setPhys(paddr, size, flags, mid, curTick());
3376223Snate@binkert.org    }
3386223Snate@binkert.org
3392663Sstever@eecs.umich.edu    /**
3402663Sstever@eecs.umich.edu     * Set up a virtual (e.g., CPU) request in a previously
3415735Snate@binkert.org     * allocated Request object.
3425735Snate@binkert.org     */
3435735Snate@binkert.org    void
3448832SAli.Saidi@ARM.com    setVirt(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc)
3452663Sstever@eecs.umich.edu    {
3466427Ssteve.reinhardt@amd.com        assert(size >= 0);
3476427Ssteve.reinhardt@amd.com        _asid = asid;
3486427Ssteve.reinhardt@amd.com        _vaddr = vaddr;
3496427Ssteve.reinhardt@amd.com        _size = size;
3508832SAli.Saidi@ARM.com        _masterId = mid;
3516427Ssteve.reinhardt@amd.com        _pc = pc;
3527823Ssteve.reinhardt@amd.com        _time = curTick();
3535735Snate@binkert.org
3546427Ssteve.reinhardt@amd.com        _flags.clear(~STICKY_FLAGS);
3556427Ssteve.reinhardt@amd.com        _flags.set(flags);
3566104Ssteve.reinhardt@amd.com        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
3576104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC);
35810020Smatt.horsnell@ARM.com        depth = 0;
35910020Smatt.horsnell@ARM.com        accessDelta = 0;
36010020Smatt.horsnell@ARM.com        translateDelta = 0;
3612663Sstever@eecs.umich.edu    }
3622532SN/A
3635735Snate@binkert.org    /**
3649760Sandreas@sandberg.pp.se     * Set just the physical address.  This usually used to record the
3659760Sandreas@sandberg.pp.se     * result of a translation. However, when using virtualized CPUs
3669760Sandreas@sandberg.pp.se     * setPhys() is sometimes called to finalize a physical address
3679760Sandreas@sandberg.pp.se     * without a virtual address, so we can't check if the virtual
3689760Sandreas@sandberg.pp.se     * address is valid.
3692663Sstever@eecs.umich.edu     */
3705735Snate@binkert.org    void
3716427Ssteve.reinhardt@amd.com    setPaddr(Addr paddr)
3722663Sstever@eecs.umich.edu    {
3736427Ssteve.reinhardt@amd.com        _paddr = paddr;
3746104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_PADDR);
3752663Sstever@eecs.umich.edu    }
3762532SN/A
3775735Snate@binkert.org    /**
3785744Sgblack@eecs.umich.edu     * Generate two requests as if this request had been split into two
3795744Sgblack@eecs.umich.edu     * pieces. The original request can't have been translated already.
3805744Sgblack@eecs.umich.edu     */
3815744Sgblack@eecs.umich.edu    void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2)
3825744Sgblack@eecs.umich.edu    {
3836104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
3846104Ssteve.reinhardt@amd.com        assert(privateFlags.noneSet(VALID_PADDR));
3856427Ssteve.reinhardt@amd.com        assert(split_addr > _vaddr && split_addr < _vaddr + _size);
3865744Sgblack@eecs.umich.edu        req1 = new Request;
3875744Sgblack@eecs.umich.edu        *req1 = *this;
3885744Sgblack@eecs.umich.edu        req2 = new Request;
3895744Sgblack@eecs.umich.edu        *req2 = *this;
3906427Ssteve.reinhardt@amd.com        req1->_size = split_addr - _vaddr;
3916427Ssteve.reinhardt@amd.com        req2->_vaddr = split_addr;
3926427Ssteve.reinhardt@amd.com        req2->_size = _size - req1->_size;
3935744Sgblack@eecs.umich.edu    }
3945744Sgblack@eecs.umich.edu
3955744Sgblack@eecs.umich.edu    /**
3965735Snate@binkert.org     * Accessor for paddr.
3975735Snate@binkert.org     */
3986104Ssteve.reinhardt@amd.com    bool
3996104Ssteve.reinhardt@amd.com    hasPaddr()
4006104Ssteve.reinhardt@amd.com    {
4016104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_PADDR);
4026104Ssteve.reinhardt@amd.com    }
4036104Ssteve.reinhardt@amd.com
4045735Snate@binkert.org    Addr
4055735Snate@binkert.org    getPaddr()
4065735Snate@binkert.org    {
4076104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR));
4086427Ssteve.reinhardt@amd.com        return _paddr;
4095735Snate@binkert.org    }
4102663Sstever@eecs.umich.edu
4115735Snate@binkert.org    /**
41210020Smatt.horsnell@ARM.com     * Time for the TLB/table walker to successfully translate this request.
41310020Smatt.horsnell@ARM.com     */
41410020Smatt.horsnell@ARM.com    Tick translateDelta;
41510020Smatt.horsnell@ARM.com
41610020Smatt.horsnell@ARM.com    /**
41710020Smatt.horsnell@ARM.com     * Access latency to complete this memory transaction not including
41810020Smatt.horsnell@ARM.com     * translation time.
41910020Smatt.horsnell@ARM.com     */
42010020Smatt.horsnell@ARM.com    Tick accessDelta;
42110020Smatt.horsnell@ARM.com
42210020Smatt.horsnell@ARM.com    /**
42310020Smatt.horsnell@ARM.com     * Level of the cache hierachy where this request was responded to
42410020Smatt.horsnell@ARM.com     * (e.g. 0 = L1; 1 = L2).
42510020Smatt.horsnell@ARM.com     */
42610020Smatt.horsnell@ARM.com    int depth;
42710020Smatt.horsnell@ARM.com
42810020Smatt.horsnell@ARM.com    /**
4295735Snate@binkert.org     *  Accessor for size.
4305735Snate@binkert.org     */
4316104Ssteve.reinhardt@amd.com    bool
4326104Ssteve.reinhardt@amd.com    hasSize()
4336104Ssteve.reinhardt@amd.com    {
4346104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_SIZE);
4356104Ssteve.reinhardt@amd.com    }
4366104Ssteve.reinhardt@amd.com
4375735Snate@binkert.org    int
4385735Snate@binkert.org    getSize()
4395735Snate@binkert.org    {
4406104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_SIZE));
4416427Ssteve.reinhardt@amd.com        return _size;
4425735Snate@binkert.org    }
4435735Snate@binkert.org
4442663Sstever@eecs.umich.edu    /** Accessor for time. */
4455735Snate@binkert.org    Tick
4466223Snate@binkert.org    time() const
4475735Snate@binkert.org    {
4486104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4496223Snate@binkert.org        return _time;
4506223Snate@binkert.org    }
4516223Snate@binkert.org
4526223Snate@binkert.org    void
4536223Snate@binkert.org    time(Tick time)
4546223Snate@binkert.org    {
4556223Snate@binkert.org        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4566223Snate@binkert.org        _time = time;
4575735Snate@binkert.org    }
4585735Snate@binkert.org
4592663Sstever@eecs.umich.edu    /** Accessor for flags. */
4605735Snate@binkert.org    Flags
4615735Snate@binkert.org    getFlags()
4625735Snate@binkert.org    {
4636104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4646427Ssteve.reinhardt@amd.com        return _flags;
4655735Snate@binkert.org    }
4665735Snate@binkert.org
4676428Ssteve.reinhardt@amd.com    /** Note that unlike other accessors, this function sets *specific
4686428Ssteve.reinhardt@amd.com       flags* (ORs them in); it does not assign its argument to the
4696428Ssteve.reinhardt@amd.com       _flags field.  Thus this method should rightly be called
4706428Ssteve.reinhardt@amd.com       setFlags() and not just flags(). */
4715735Snate@binkert.org    void
4726427Ssteve.reinhardt@amd.com    setFlags(Flags flags)
4735735Snate@binkert.org    {
4746104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4756427Ssteve.reinhardt@amd.com        _flags.set(flags);
4765735Snate@binkert.org    }
4775735Snate@binkert.org
4789912Sandreas@sandberg.pp.se    void
4799912Sandreas@sandberg.pp.se    setArchFlags(Flags flags)
4809912Sandreas@sandberg.pp.se    {
4819912Sandreas@sandberg.pp.se        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
4829912Sandreas@sandberg.pp.se        _flags.set(flags & ARCH_BITS);
4839912Sandreas@sandberg.pp.se    }
4849912Sandreas@sandberg.pp.se
4852663Sstever@eecs.umich.edu    /** Accessor function for vaddr.*/
4865735Snate@binkert.org    Addr
4875735Snate@binkert.org    getVaddr()
4885735Snate@binkert.org    {
4896104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
4906427Ssteve.reinhardt@amd.com        return _vaddr;
4915735Snate@binkert.org    }
4922663Sstever@eecs.umich.edu
4938832SAli.Saidi@ARM.com    /** Accesssor for the requestor id. */
4948832SAli.Saidi@ARM.com    MasterID
4958832SAli.Saidi@ARM.com    masterId()
4968832SAli.Saidi@ARM.com    {
4978832SAli.Saidi@ARM.com        return _masterId;
4988832SAli.Saidi@ARM.com    }
4998832SAli.Saidi@ARM.com
50010024Sdam.sunwoo@arm.com    uint32_t
50110024Sdam.sunwoo@arm.com    taskId() const
50210024Sdam.sunwoo@arm.com    {
50310024Sdam.sunwoo@arm.com        return _taskId;
50410024Sdam.sunwoo@arm.com    }
50510024Sdam.sunwoo@arm.com
50610024Sdam.sunwoo@arm.com    void
50710024Sdam.sunwoo@arm.com    taskId(uint32_t id) {
50810024Sdam.sunwoo@arm.com        _taskId = id;
50910024Sdam.sunwoo@arm.com    }
51010024Sdam.sunwoo@arm.com
5112663Sstever@eecs.umich.edu    /** Accessor function for asid.*/
5125735Snate@binkert.org    int
5135735Snate@binkert.org    getAsid()
5145735Snate@binkert.org    {
5156104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_VADDR));
5166427Ssteve.reinhardt@amd.com        return _asid;
5175735Snate@binkert.org    }
5182663Sstever@eecs.umich.edu
5198551Sdaniel.johnson@arm.com    /** Accessor function for asid.*/
5208551Sdaniel.johnson@arm.com    void
5218551Sdaniel.johnson@arm.com    setAsid(int asid)
5228551Sdaniel.johnson@arm.com    {
5238551Sdaniel.johnson@arm.com        _asid = asid;
5248551Sdaniel.johnson@arm.com    }
5258551Sdaniel.johnson@arm.com
5269912Sandreas@sandberg.pp.se    /** Accessor function for architecture-specific flags.*/
5279912Sandreas@sandberg.pp.se    ArchFlagsType
5289912Sandreas@sandberg.pp.se    getArchFlags()
5295735Snate@binkert.org    {
5309912Sandreas@sandberg.pp.se        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
5319912Sandreas@sandberg.pp.se        return _flags & ARCH_BITS;
5325735Snate@binkert.org    }
5333804Ssaidi@eecs.umich.edu
5342679Sktlim@umich.edu    /** Accessor function to check if sc result is valid. */
5355735Snate@binkert.org    bool
5365735Snate@binkert.org    extraDataValid()
5375735Snate@binkert.org    {
5386104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_EXTRA_DATA);
5395735Snate@binkert.org    }
5405735Snate@binkert.org
5412663Sstever@eecs.umich.edu    /** Accessor function for store conditional return value.*/
5425735Snate@binkert.org    uint64_t
5435735Snate@binkert.org    getExtraData() const
5445735Snate@binkert.org    {
5456104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_EXTRA_DATA));
5466427Ssteve.reinhardt@amd.com        return _extraData;
5475735Snate@binkert.org    }
5485735Snate@binkert.org
5492663Sstever@eecs.umich.edu    /** Accessor function for store conditional return value.*/
5505735Snate@binkert.org    void
5516427Ssteve.reinhardt@amd.com    setExtraData(uint64_t extraData)
5525735Snate@binkert.org    {
5536427Ssteve.reinhardt@amd.com        _extraData = extraData;
5546104Ssteve.reinhardt@amd.com        privateFlags.set(VALID_EXTRA_DATA);
5555735Snate@binkert.org    }
5562663Sstever@eecs.umich.edu
5576010Ssteve.reinhardt@amd.com    bool
5586010Ssteve.reinhardt@amd.com    hasContextId() const
5596010Ssteve.reinhardt@amd.com    {
5606104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_CONTEXT_ID);
5616010Ssteve.reinhardt@amd.com    }
5626010Ssteve.reinhardt@amd.com
5635714Shsul@eecs.umich.edu    /** Accessor function for context ID.*/
5645735Snate@binkert.org    int
5655735Snate@binkert.org    contextId() const
5665735Snate@binkert.org    {
5676104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_CONTEXT_ID));
5685735Snate@binkert.org        return _contextId;
5695735Snate@binkert.org    }
5705735Snate@binkert.org
5715714Shsul@eecs.umich.edu    /** Accessor function for thread ID. */
5725735Snate@binkert.org    int
5735735Snate@binkert.org    threadId() const
5745735Snate@binkert.org    {
5756104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_THREAD_ID));
5765735Snate@binkert.org        return _threadId;
5775735Snate@binkert.org    }
5782663Sstever@eecs.umich.edu
57910052Smitch.hayenga+gem5@gmail.com    void
58010052Smitch.hayenga+gem5@gmail.com    setPC(Addr pc)
58110052Smitch.hayenga+gem5@gmail.com    {
58210052Smitch.hayenga+gem5@gmail.com        privateFlags.set(VALID_PC);
58310052Smitch.hayenga+gem5@gmail.com        _pc = pc;
58410052Smitch.hayenga+gem5@gmail.com    }
58510052Smitch.hayenga+gem5@gmail.com
5865875Ssteve.reinhardt@amd.com    bool
5875875Ssteve.reinhardt@amd.com    hasPC() const
5885875Ssteve.reinhardt@amd.com    {
5896104Ssteve.reinhardt@amd.com        return privateFlags.isSet(VALID_PC);
5905875Ssteve.reinhardt@amd.com    }
5915875Ssteve.reinhardt@amd.com
5926010Ssteve.reinhardt@amd.com    /** Accessor function for pc.*/
5935735Snate@binkert.org    Addr
5945735Snate@binkert.org    getPC() const
5955735Snate@binkert.org    {
5966104Ssteve.reinhardt@amd.com        assert(privateFlags.isSet(VALID_PC));
5976427Ssteve.reinhardt@amd.com        return _pc;
5985735Snate@binkert.org    }
5992532SN/A
60010020Smatt.horsnell@ARM.com    /**
60110020Smatt.horsnell@ARM.com     * Increment/Get the depth at which this request is responded to.
60210020Smatt.horsnell@ARM.com     * This currently happens when the request misses in any cache level.
60310020Smatt.horsnell@ARM.com     */
60410020Smatt.horsnell@ARM.com    void incAccessDepth() { depth++; }
60510020Smatt.horsnell@ARM.com    int getAccessDepth() const { return depth; }
60610020Smatt.horsnell@ARM.com
60710020Smatt.horsnell@ARM.com    /**
60810020Smatt.horsnell@ARM.com     * Set/Get the time taken for this request to be successfully translated.
60910020Smatt.horsnell@ARM.com     */
61010020Smatt.horsnell@ARM.com    void setTranslateLatency() { translateDelta = curTick() - _time; }
61110020Smatt.horsnell@ARM.com    Tick getTranslateLatency() const { return translateDelta; }
61210020Smatt.horsnell@ARM.com
61310020Smatt.horsnell@ARM.com    /**
61410020Smatt.horsnell@ARM.com     * Set/Get the time taken to complete this request's access, not including
61510020Smatt.horsnell@ARM.com     *  the time to successfully translate the request.
61610020Smatt.horsnell@ARM.com     */
61710020Smatt.horsnell@ARM.com    void setAccessLatency() { accessDelta = curTick() - _time - translateDelta; }
61810020Smatt.horsnell@ARM.com    Tick getAccessLatency() const { return accessDelta; }
61910020Smatt.horsnell@ARM.com
6206428Ssteve.reinhardt@amd.com    /** Accessor functions for flags.  Note that these are for testing
6216428Ssteve.reinhardt@amd.com       only; setting flags should be done via setFlags(). */
6226427Ssteve.reinhardt@amd.com    bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
6236427Ssteve.reinhardt@amd.com    bool isInstFetch() const { return _flags.isSet(INST_FETCH); }
6246427Ssteve.reinhardt@amd.com    bool isPrefetch() const { return _flags.isSet(PREFETCH); }
6256427Ssteve.reinhardt@amd.com    bool isLLSC() const { return _flags.isSet(LLSC); }
6269950Sprakash.ramrakhyani@arm.com    bool isPriv() const { return _flags.isSet(PRIVILEGED); }
6276427Ssteve.reinhardt@amd.com    bool isLocked() const { return _flags.isSet(LOCKED); }
6286427Ssteve.reinhardt@amd.com    bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
6296427Ssteve.reinhardt@amd.com    bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
6308105Sgblack@eecs.umich.edu    bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
6317705Sgblack@eecs.umich.edu    bool isClearLL() const { return _flags.isSet(CLEAR_LL); }
63210028SGiacomo.Gabrielli@arm.com    bool isSecure() const { return _flags.isSet(SECURE); }
63310029SGiacomo.Gabrielli@arm.com    bool isPTWalk() const { return _flags.isSet(PT_WALK); }
6342384SN/A};
6352381SN/A
6362381SN/A#endif // __MEM_REQUEST_HH__
637