request.hh revision 11055:54071fd5c397
17720Sgblack@eecs.umich.edu/*
27720Sgblack@eecs.umich.edu * Copyright (c) 2012-2013 ARM Limited
37720Sgblack@eecs.umich.edu * All rights reserved
47720Sgblack@eecs.umich.edu *
57720Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
67720Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
77720Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
87720Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
97720Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
107720Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
117720Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
127720Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137720Sgblack@eecs.umich.edu *
147720Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
157720Sgblack@eecs.umich.edu * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
167720Sgblack@eecs.umich.edu * All rights reserved.
177720Sgblack@eecs.umich.edu *
187720Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
197720Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
207720Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
217720Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
227720Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
237720Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
247720Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
257720Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
267720Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
277720Sgblack@eecs.umich.edu * this software without specific prior written permission.
287720Sgblack@eecs.umich.edu *
297720Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
307720Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
317720Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
327720Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
337720Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
347720Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
357720Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
368229Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
377720Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
387720Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
397720Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
407720Sgblack@eecs.umich.edu *
417720Sgblack@eecs.umich.edu * Authors: Ron Dreslinski
427720Sgblack@eecs.umich.edu *          Steve Reinhardt
437720Sgblack@eecs.umich.edu *          Ali Saidi
4410905Sandreas.sandberg@arm.com */
457720Sgblack@eecs.umich.edu
467720Sgblack@eecs.umich.edu/**
477720Sgblack@eecs.umich.edu * @file
487720Sgblack@eecs.umich.edu * Declaration of a request, the overall memory request consisting of
497720Sgblack@eecs.umich.edu the parts of the request that are persistent throughout the transaction.
5010537Sandreas.hansson@arm.com */
5110537Sandreas.hansson@arm.com
527720Sgblack@eecs.umich.edu#ifndef __MEM_REQUEST_HH__
537720Sgblack@eecs.umich.edu#define __MEM_REQUEST_HH__
547720Sgblack@eecs.umich.edu
557720Sgblack@eecs.umich.edu#include <cassert>
567720Sgblack@eecs.umich.edu#include <climits>
577720Sgblack@eecs.umich.edu
587720Sgblack@eecs.umich.edu#include "base/flags.hh"
597720Sgblack@eecs.umich.edu#include "base/misc.hh"
607720Sgblack@eecs.umich.edu#include "base/types.hh"
617720Sgblack@eecs.umich.edu#include "sim/core.hh"
627720Sgblack@eecs.umich.edu
637720Sgblack@eecs.umich.edu/**
647720Sgblack@eecs.umich.edu * Special TaskIds that are used for per-context-switch stats dumps
657720Sgblack@eecs.umich.edu * and Cache Occupancy. Having too many tasks seems to be a problem
667720Sgblack@eecs.umich.edu * with vector stats. 1024 seems to be a reasonable number that
677720Sgblack@eecs.umich.edu * doesn't cause a problem with stats and is large enough to realistic
687720Sgblack@eecs.umich.edu * benchmarks (Linux/Android boot, BBench, etc.)
697720Sgblack@eecs.umich.edu */
707720Sgblack@eecs.umich.edu
717720Sgblack@eecs.umich.edunamespace ContextSwitchTaskId {
727720Sgblack@eecs.umich.edu    enum TaskId {
737720Sgblack@eecs.umich.edu        MaxNormalTaskId = 1021, /* Maximum number of normal tasks */
747720Sgblack@eecs.umich.edu        Prefetcher = 1022, /* For cache lines brought in by prefetcher */
757720Sgblack@eecs.umich.edu        DMA = 1023, /* Mostly Table Walker */
767720Sgblack@eecs.umich.edu        Unknown = 1024,
777720Sgblack@eecs.umich.edu        NumTaskId
787720Sgblack@eecs.umich.edu    };
797720Sgblack@eecs.umich.edu}
807720Sgblack@eecs.umich.edu
817720Sgblack@eecs.umich.educlass Request;
827720Sgblack@eecs.umich.edu
837720Sgblack@eecs.umich.edutypedef Request* RequestPtr;
847720Sgblack@eecs.umich.edutypedef uint16_t MasterID;
857720Sgblack@eecs.umich.edu
867720Sgblack@eecs.umich.educlass Request
877720Sgblack@eecs.umich.edu{
887720Sgblack@eecs.umich.edu  public:
897720Sgblack@eecs.umich.edu    typedef uint32_t FlagsType;
907720Sgblack@eecs.umich.edu    typedef uint8_t ArchFlagsType;
917720Sgblack@eecs.umich.edu    typedef ::Flags<FlagsType> Flags;
927720Sgblack@eecs.umich.edu
937720Sgblack@eecs.umich.edu    enum : FlagsType {
947720Sgblack@eecs.umich.edu        /**
957720Sgblack@eecs.umich.edu         * Architecture specific flags.
967720Sgblack@eecs.umich.edu         *
977720Sgblack@eecs.umich.edu         * These bits int the flag field are reserved for
987720Sgblack@eecs.umich.edu         * architecture-specific code. For example, SPARC uses them to
997720Sgblack@eecs.umich.edu         * represent ASIs.
1007720Sgblack@eecs.umich.edu         */
1018361Sksewell@umich.edu        ARCH_BITS                   = 0x000000FF,
1028361Sksewell@umich.edu        /** The request was an instruction fetch. */
1038361Sksewell@umich.edu        INST_FETCH                  = 0x00000100,
1048361Sksewell@umich.edu        /** The virtual address is also the physical address. */
1058361Sksewell@umich.edu        PHYSICAL                    = 0x00000200,
1068361Sksewell@umich.edu        /**
1077720Sgblack@eecs.umich.edu         * The request is to an uncacheable address.
10810905Sandreas.sandberg@arm.com         *
1097720Sgblack@eecs.umich.edu         * @note Uncacheable accesses may be reordered by CPU models. The
1107720Sgblack@eecs.umich.edu         * STRICT_ORDER flag should be set if such reordering is
1117720Sgblack@eecs.umich.edu         * undesirable.
1127720Sgblack@eecs.umich.edu         */
1137720Sgblack@eecs.umich.edu        UNCACHEABLE                = 0x00000400,
1147720Sgblack@eecs.umich.edu        /**
11510905Sandreas.sandberg@arm.com         * The request is required to be strictly ordered by <i>CPU
1167720Sgblack@eecs.umich.edu         * models</i> and is non-speculative.
1177720Sgblack@eecs.umich.edu         *
1187720Sgblack@eecs.umich.edu         * A strictly ordered request is guaranteed to never be
1197720Sgblack@eecs.umich.edu         * re-ordered or executed speculatively by a CPU model. The
1207720Sgblack@eecs.umich.edu         * memory system may still reorder requests in caches unless
1217720Sgblack@eecs.umich.edu         * the UNCACHEABLE flag is set as well.
1227720Sgblack@eecs.umich.edu         */
1237720Sgblack@eecs.umich.edu        STRICT_ORDER                = 0x00000800,
1247720Sgblack@eecs.umich.edu        /** This request is to a memory mapped register. */
1257720Sgblack@eecs.umich.edu        MMAPPED_IPR                 = 0x00002000,
1267720Sgblack@eecs.umich.edu        /** This request is made in privileged mode. */
1277720Sgblack@eecs.umich.edu        PRIVILEGED                  = 0x00008000,
1287720Sgblack@eecs.umich.edu
1297720Sgblack@eecs.umich.edu        /**
1307720Sgblack@eecs.umich.edu         * This is a write that is targeted and zeroing an entire
1317720Sgblack@eecs.umich.edu         * cache block.  There is no need for a read/modify/write
1327720Sgblack@eecs.umich.edu         */
1337720Sgblack@eecs.umich.edu        CACHE_BLOCK_ZERO            = 0x00010000,
1347720Sgblack@eecs.umich.edu
1357720Sgblack@eecs.umich.edu        /** The request should not cause a memory access. */
1367720Sgblack@eecs.umich.edu        NO_ACCESS                   = 0x00080000,
1377720Sgblack@eecs.umich.edu        /**
1387720Sgblack@eecs.umich.edu         * This request will lock or unlock the accessed memory. When
1397720Sgblack@eecs.umich.edu         * used with a load, the access locks the particular chunk of
1407720Sgblack@eecs.umich.edu         * memory. When used with a store, it unlocks. The rule is
1417720Sgblack@eecs.umich.edu         * that locked accesses have to be made up of a locked load,
1427720Sgblack@eecs.umich.edu         * some operation on the data, and then a locked store.
1437720Sgblack@eecs.umich.edu         */
1447720Sgblack@eecs.umich.edu        LOCKED_RMW                  = 0x00100000,
1457720Sgblack@eecs.umich.edu        /** The request is a Load locked/store conditional. */
1467720Sgblack@eecs.umich.edu        LLSC                        = 0x00200000,
1477720Sgblack@eecs.umich.edu        /** This request is for a memory swap. */
1487720Sgblack@eecs.umich.edu        MEM_SWAP                    = 0x00400000,
1497720Sgblack@eecs.umich.edu        MEM_SWAP_COND               = 0x00800000,
1507720Sgblack@eecs.umich.edu
1517720Sgblack@eecs.umich.edu        /** The request is a prefetch. */
1527720Sgblack@eecs.umich.edu        PREFETCH                    = 0x01000000,
1537720Sgblack@eecs.umich.edu        /** The request should be prefetched into the exclusive state. */
1547720Sgblack@eecs.umich.edu        PF_EXCLUSIVE                = 0x02000000,
1557720Sgblack@eecs.umich.edu        /** The request should be marked as LRU. */
1567720Sgblack@eecs.umich.edu        EVICT_NEXT                  = 0x04000000,
1577720Sgblack@eecs.umich.edu
1587720Sgblack@eecs.umich.edu        /**
1597720Sgblack@eecs.umich.edu         * The request should be handled by the generic IPR code (only
1607720Sgblack@eecs.umich.edu         * valid together with MMAPPED_IPR)
1617720Sgblack@eecs.umich.edu         */
1627720Sgblack@eecs.umich.edu        GENERIC_IPR                 = 0x08000000,
1637720Sgblack@eecs.umich.edu
1647720Sgblack@eecs.umich.edu        /** The request targets the secure memory space. */
1657720Sgblack@eecs.umich.edu        SECURE                      = 0x10000000,
1667720Sgblack@eecs.umich.edu        /** The request is a page table walk */
1677720Sgblack@eecs.umich.edu        PT_WALK                     = 0x20000000,
1687720Sgblack@eecs.umich.edu
1697720Sgblack@eecs.umich.edu        /**
1707720Sgblack@eecs.umich.edu         * These flags are *not* cleared when a Request object is
1717720Sgblack@eecs.umich.edu         * reused (assigned a new address).
1727720Sgblack@eecs.umich.edu         */
1737720Sgblack@eecs.umich.edu        STICKY_FLAGS = INST_FETCH
1747720Sgblack@eecs.umich.edu    };
1757720Sgblack@eecs.umich.edu
1767720Sgblack@eecs.umich.edu    /** Master Ids that are statically allocated
1777720Sgblack@eecs.umich.edu     * @{*/
1787720Sgblack@eecs.umich.edu    enum : MasterID {
1797720Sgblack@eecs.umich.edu        /** This master id is used for writeback requests by the caches */
1807720Sgblack@eecs.umich.edu        wbMasterId = 0,
1817720Sgblack@eecs.umich.edu        /**
1827720Sgblack@eecs.umich.edu         * This master id is used for functional requests that
1837720Sgblack@eecs.umich.edu         * don't come from a particular device
1847720Sgblack@eecs.umich.edu         */
1857720Sgblack@eecs.umich.edu        funcMasterId = 1,
1867720Sgblack@eecs.umich.edu        /** This master id is used for message signaled interrupts */
1877720Sgblack@eecs.umich.edu        intMasterId = 2,
1887720Sgblack@eecs.umich.edu        /**
1897720Sgblack@eecs.umich.edu         * Invalid master id for assertion checking only. It is
1907720Sgblack@eecs.umich.edu         * invalid behavior to ever send this id as part of a request.
1917720Sgblack@eecs.umich.edu         */
1927720Sgblack@eecs.umich.edu        invldMasterId = std::numeric_limits<MasterID>::max()
1937720Sgblack@eecs.umich.edu    };
1947720Sgblack@eecs.umich.edu    /** @} */
1957720Sgblack@eecs.umich.edu
1967720Sgblack@eecs.umich.edu  private:
1977720Sgblack@eecs.umich.edu    typedef uint8_t PrivateFlagsType;
1987720Sgblack@eecs.umich.edu    typedef ::Flags<PrivateFlagsType> PrivateFlags;
1997720Sgblack@eecs.umich.edu
2007720Sgblack@eecs.umich.edu    enum : PrivateFlagsType {
2017720Sgblack@eecs.umich.edu        /** Whether or not the size is valid. */
2027720Sgblack@eecs.umich.edu        VALID_SIZE           = 0x00000001,
2037720Sgblack@eecs.umich.edu        /** Whether or not paddr is valid (has been written yet). */
2047720Sgblack@eecs.umich.edu        VALID_PADDR          = 0x00000002,
2057720Sgblack@eecs.umich.edu        /** Whether or not the vaddr & asid are valid. */
2067720Sgblack@eecs.umich.edu        VALID_VADDR          = 0x00000004,
2077720Sgblack@eecs.umich.edu        /** Whether or not the pc is valid. */
2087720Sgblack@eecs.umich.edu        VALID_PC             = 0x00000010,
20910537Sandreas.hansson@arm.com        /** Whether or not the context ID is valid. */
21010537Sandreas.hansson@arm.com        VALID_CONTEXT_ID     = 0x00000020,
2117720Sgblack@eecs.umich.edu        VALID_THREAD_ID      = 0x00000040,
2127720Sgblack@eecs.umich.edu        /** Whether or not the sc result is valid. */
2137720Sgblack@eecs.umich.edu        VALID_EXTRA_DATA     = 0x00000080,
2147720Sgblack@eecs.umich.edu
2157720Sgblack@eecs.umich.edu        /**
2167720Sgblack@eecs.umich.edu         * These flags are *not* cleared when a Request object is reused
2177720Sgblack@eecs.umich.edu         * (assigned a new address).
2187720Sgblack@eecs.umich.edu         */
2197720Sgblack@eecs.umich.edu        STICKY_PRIVATE_FLAGS = VALID_CONTEXT_ID | VALID_THREAD_ID
2207720Sgblack@eecs.umich.edu    };
2217720Sgblack@eecs.umich.edu
2227720Sgblack@eecs.umich.edu  private:
2237720Sgblack@eecs.umich.edu
2247720Sgblack@eecs.umich.edu    /**
2257720Sgblack@eecs.umich.edu     * Set up a physical (e.g. device) request in a previously
2267720Sgblack@eecs.umich.edu     * allocated Request object.
2277720Sgblack@eecs.umich.edu     */
2287720Sgblack@eecs.umich.edu    void
2297720Sgblack@eecs.umich.edu    setPhys(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
2307720Sgblack@eecs.umich.edu    {
2317720Sgblack@eecs.umich.edu        assert(size >= 0);
2327720Sgblack@eecs.umich.edu        _paddr = paddr;
2337720Sgblack@eecs.umich.edu        _size = size;
2347720Sgblack@eecs.umich.edu        _time = time;
2357720Sgblack@eecs.umich.edu        _masterId = mid;
2367720Sgblack@eecs.umich.edu        _flags.clear(~STICKY_FLAGS);
2377720Sgblack@eecs.umich.edu        _flags.set(flags);
2387720Sgblack@eecs.umich.edu        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
2397720Sgblack@eecs.umich.edu        privateFlags.set(VALID_PADDR|VALID_SIZE);
2407720Sgblack@eecs.umich.edu        depth = 0;
2417720Sgblack@eecs.umich.edu        accessDelta = 0;
2427720Sgblack@eecs.umich.edu        //translateDelta = 0;
2437720Sgblack@eecs.umich.edu    }
2448361Sksewell@umich.edu
2458361Sksewell@umich.edu    /**
2468361Sksewell@umich.edu     * The physical address of the request. Valid only if validPaddr
2478361Sksewell@umich.edu     * is set.
2488361Sksewell@umich.edu     */
2498361Sksewell@umich.edu    Addr _paddr;
2507720Sgblack@eecs.umich.edu
25110905Sandreas.sandberg@arm.com    /**
2527720Sgblack@eecs.umich.edu     * The size of the request. This field must be set when vaddr or
25310905Sandreas.sandberg@arm.com     * paddr is written via setVirt() or setPhys(), so it is always
2547720Sgblack@eecs.umich.edu     * valid as long as one of the address fields is valid.
2557720Sgblack@eecs.umich.edu     */
2567720Sgblack@eecs.umich.edu    unsigned _size;
2577720Sgblack@eecs.umich.edu
2587720Sgblack@eecs.umich.edu    /** The requestor ID which is unique in the system for all ports
25910905Sandreas.sandberg@arm.com     * that are capable of issuing a transaction
2607720Sgblack@eecs.umich.edu     */
26110905Sandreas.sandberg@arm.com    MasterID _masterId;
2627720Sgblack@eecs.umich.edu
2637720Sgblack@eecs.umich.edu    /** Flag structure for the request. */
2647720Sgblack@eecs.umich.edu    Flags _flags;
2657720Sgblack@eecs.umich.edu
2667720Sgblack@eecs.umich.edu    /** Private flags for field validity checking. */
2677720Sgblack@eecs.umich.edu    PrivateFlags privateFlags;
2687720Sgblack@eecs.umich.edu
2697720Sgblack@eecs.umich.edu    /**
2707720Sgblack@eecs.umich.edu     * The time this request was started. Used to calculate
2717720Sgblack@eecs.umich.edu     * latencies. This field is set to curTick() any time paddr or vaddr
2728435Snilay@cs.wisc.edu     * is written.
2737720Sgblack@eecs.umich.edu     */
2747720Sgblack@eecs.umich.edu    Tick _time;
2757720Sgblack@eecs.umich.edu
2767720Sgblack@eecs.umich.edu    /**
2777720Sgblack@eecs.umich.edu     * The task id associated with this request
2787720Sgblack@eecs.umich.edu     */
2797720Sgblack@eecs.umich.edu    uint32_t _taskId;
2807720Sgblack@eecs.umich.edu
2817720Sgblack@eecs.umich.edu    /** The address space ID. */
2827720Sgblack@eecs.umich.edu    int _asid;
2837720Sgblack@eecs.umich.edu
2847720Sgblack@eecs.umich.edu    /** The virtual address of the request. */
2857720Sgblack@eecs.umich.edu    Addr _vaddr;
2867720Sgblack@eecs.umich.edu
2877720Sgblack@eecs.umich.edu    /**
2887720Sgblack@eecs.umich.edu     * Extra data for the request, such as the return value of
2897720Sgblack@eecs.umich.edu     * store conditional or the compare value for a CAS. */
2907720Sgblack@eecs.umich.edu    uint64_t _extraData;
2917720Sgblack@eecs.umich.edu
2927720Sgblack@eecs.umich.edu    /** The context ID (for statistics, typically). */
2937720Sgblack@eecs.umich.edu    ContextID _contextId;
2947720Sgblack@eecs.umich.edu    /** The thread ID (id within this CPU) */
2957720Sgblack@eecs.umich.edu    ThreadID _threadId;
2967720Sgblack@eecs.umich.edu
2977720Sgblack@eecs.umich.edu    /** program counter of initiating access; for tracing/debugging */
2987720Sgblack@eecs.umich.edu    Addr _pc;
2997720Sgblack@eecs.umich.edu
3007720Sgblack@eecs.umich.edu  public:
3017720Sgblack@eecs.umich.edu
3027720Sgblack@eecs.umich.edu    /**
3037720Sgblack@eecs.umich.edu     * Minimal constructor. No fields are initialized. (Note that
3047720Sgblack@eecs.umich.edu     *  _flags and privateFlags are cleared by Flags default
3057720Sgblack@eecs.umich.edu     *  constructor.)
3067720Sgblack@eecs.umich.edu     */
3077720Sgblack@eecs.umich.edu    Request()
3087720Sgblack@eecs.umich.edu        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
3097720Sgblack@eecs.umich.edu          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
3107720Sgblack@eecs.umich.edu          _extraData(0), _contextId(0), _threadId(0), _pc(0),
3117720Sgblack@eecs.umich.edu          translateDelta(0), accessDelta(0), depth(0)
3127720Sgblack@eecs.umich.edu    {}
3137720Sgblack@eecs.umich.edu
3147720Sgblack@eecs.umich.edu    /**
3157720Sgblack@eecs.umich.edu     * Constructor for physical (e.g. device) requests.  Initializes
3167720Sgblack@eecs.umich.edu     * just physical address, size, flags, and timestamp (to curTick()).
3177720Sgblack@eecs.umich.edu     * These fields are adequate to perform a request.
3187720Sgblack@eecs.umich.edu     */
3197720Sgblack@eecs.umich.edu    Request(Addr paddr, unsigned size, Flags flags, MasterID mid)
3207720Sgblack@eecs.umich.edu        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
3217720Sgblack@eecs.umich.edu          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
3227720Sgblack@eecs.umich.edu          _extraData(0), _contextId(0), _threadId(0), _pc(0),
3237720Sgblack@eecs.umich.edu          translateDelta(0), accessDelta(0), depth(0)
3247720Sgblack@eecs.umich.edu    {
3258361Sksewell@umich.edu        setPhys(paddr, size, flags, mid, curTick());
3268361Sksewell@umich.edu    }
3278361Sksewell@umich.edu
3288361Sksewell@umich.edu    Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
3298361Sksewell@umich.edu        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
3308361Sksewell@umich.edu          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
3317720Sgblack@eecs.umich.edu          _extraData(0), _contextId(0), _threadId(0), _pc(0),
33210905Sandreas.sandberg@arm.com          translateDelta(0), accessDelta(0), depth(0)
3337720Sgblack@eecs.umich.edu    {
33410905Sandreas.sandberg@arm.com        setPhys(paddr, size, flags, mid, time);
3357720Sgblack@eecs.umich.edu    }
3367720Sgblack@eecs.umich.edu
3377720Sgblack@eecs.umich.edu    Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time,
3387720Sgblack@eecs.umich.edu            Addr pc)
33910905Sandreas.sandberg@arm.com        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
3407720Sgblack@eecs.umich.edu          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
34110905Sandreas.sandberg@arm.com          _extraData(0), _contextId(0), _threadId(0), _pc(0),
3427720Sgblack@eecs.umich.edu          translateDelta(0), accessDelta(0), depth(0)
3437720Sgblack@eecs.umich.edu    {
3447720Sgblack@eecs.umich.edu        setPhys(paddr, size, flags, mid, time);
3457720Sgblack@eecs.umich.edu        privateFlags.set(VALID_PC);
3467720Sgblack@eecs.umich.edu        _pc = pc;
3477720Sgblack@eecs.umich.edu    }
3487720Sgblack@eecs.umich.edu
3497720Sgblack@eecs.umich.edu    Request(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid,
3507720Sgblack@eecs.umich.edu            Addr pc, ContextID cid, ThreadID tid)
3517720Sgblack@eecs.umich.edu        : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
3527720Sgblack@eecs.umich.edu          _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
3537720Sgblack@eecs.umich.edu          _extraData(0), _contextId(0), _threadId(0), _pc(0),
3547720Sgblack@eecs.umich.edu          translateDelta(0), accessDelta(0), depth(0)
3557720Sgblack@eecs.umich.edu    {
3567720Sgblack@eecs.umich.edu        setVirt(asid, vaddr, size, flags, mid, pc);
3577720Sgblack@eecs.umich.edu        setThreadContext(cid, tid);
3587720Sgblack@eecs.umich.edu    }
3597720Sgblack@eecs.umich.edu
3607720Sgblack@eecs.umich.edu    ~Request() {}
3617720Sgblack@eecs.umich.edu
3627720Sgblack@eecs.umich.edu    /**
3637720Sgblack@eecs.umich.edu     * Set up CPU and thread numbers.
3647720Sgblack@eecs.umich.edu     */
3657720Sgblack@eecs.umich.edu    void
3667720Sgblack@eecs.umich.edu    setThreadContext(ContextID context_id, ThreadID tid)
3677720Sgblack@eecs.umich.edu    {
3687720Sgblack@eecs.umich.edu        _contextId = context_id;
3697720Sgblack@eecs.umich.edu        _threadId = tid;
3707720Sgblack@eecs.umich.edu        privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID);
3717720Sgblack@eecs.umich.edu    }
3727720Sgblack@eecs.umich.edu
3737720Sgblack@eecs.umich.edu    /**
3747720Sgblack@eecs.umich.edu     * Set up a virtual (e.g., CPU) request in a previously
3757720Sgblack@eecs.umich.edu     * allocated Request object.
3767720Sgblack@eecs.umich.edu     */
3777720Sgblack@eecs.umich.edu    void
3787720Sgblack@eecs.umich.edu    setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid,
3797720Sgblack@eecs.umich.edu            Addr pc)
3807720Sgblack@eecs.umich.edu    {
3817720Sgblack@eecs.umich.edu        _asid = asid;
3827720Sgblack@eecs.umich.edu        _vaddr = vaddr;
3837720Sgblack@eecs.umich.edu        _size = size;
3847720Sgblack@eecs.umich.edu        _masterId = mid;
3857720Sgblack@eecs.umich.edu        _pc = pc;
3867720Sgblack@eecs.umich.edu        _time = curTick();
3877720Sgblack@eecs.umich.edu
3887720Sgblack@eecs.umich.edu        _flags.clear(~STICKY_FLAGS);
3897720Sgblack@eecs.umich.edu        _flags.set(flags);
3907720Sgblack@eecs.umich.edu        privateFlags.clear(~STICKY_PRIVATE_FLAGS);
3917720Sgblack@eecs.umich.edu        privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC);
3927720Sgblack@eecs.umich.edu        depth = 0;
3937720Sgblack@eecs.umich.edu        accessDelta = 0;
3947720Sgblack@eecs.umich.edu        translateDelta = 0;
3957720Sgblack@eecs.umich.edu    }
3967720Sgblack@eecs.umich.edu
3977720Sgblack@eecs.umich.edu    /**
3987720Sgblack@eecs.umich.edu     * Set just the physical address.  This usually used to record the
3997720Sgblack@eecs.umich.edu     * result of a translation. However, when using virtualized CPUs
4007720Sgblack@eecs.umich.edu     * setPhys() is sometimes called to finalize a physical address
4017720Sgblack@eecs.umich.edu     * without a virtual address, so we can't check if the virtual
4027720Sgblack@eecs.umich.edu     * address is valid.
4037720Sgblack@eecs.umich.edu     */
4047720Sgblack@eecs.umich.edu    void
4057720Sgblack@eecs.umich.edu    setPaddr(Addr paddr)
4067720Sgblack@eecs.umich.edu    {
4077720Sgblack@eecs.umich.edu        _paddr = paddr;
4087720Sgblack@eecs.umich.edu        privateFlags.set(VALID_PADDR);
4097720Sgblack@eecs.umich.edu    }
4107720Sgblack@eecs.umich.edu
4117720Sgblack@eecs.umich.edu    /**
4127720Sgblack@eecs.umich.edu     * Generate two requests as if this request had been split into two
4137720Sgblack@eecs.umich.edu     * pieces. The original request can't have been translated already.
4147720Sgblack@eecs.umich.edu     */
4157720Sgblack@eecs.umich.edu    void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2)
4167720Sgblack@eecs.umich.edu    {
4177720Sgblack@eecs.umich.edu        assert(privateFlags.isSet(VALID_VADDR));
4187720Sgblack@eecs.umich.edu        assert(privateFlags.noneSet(VALID_PADDR));
4197720Sgblack@eecs.umich.edu        assert(split_addr > _vaddr && split_addr < _vaddr + _size);
4207720Sgblack@eecs.umich.edu        req1 = new Request(*this);
4217720Sgblack@eecs.umich.edu        req2 = new Request(*this);
4228361Sksewell@umich.edu        req1->_size = split_addr - _vaddr;
4238361Sksewell@umich.edu        req2->_vaddr = split_addr;
4248361Sksewell@umich.edu        req2->_size = _size - req1->_size;
4258361Sksewell@umich.edu    }
4268361Sksewell@umich.edu
4278361Sksewell@umich.edu    /**
4287720Sgblack@eecs.umich.edu     * Accessor for paddr.
42910905Sandreas.sandberg@arm.com     */
4307720Sgblack@eecs.umich.edu    bool
43110905Sandreas.sandberg@arm.com    hasPaddr() const
4327720Sgblack@eecs.umich.edu    {
4337720Sgblack@eecs.umich.edu        return privateFlags.isSet(VALID_PADDR);
4347720Sgblack@eecs.umich.edu    }
4357720Sgblack@eecs.umich.edu
4367720Sgblack@eecs.umich.edu    Addr
43710905Sandreas.sandberg@arm.com    getPaddr() const
4387720Sgblack@eecs.umich.edu    {
43910905Sandreas.sandberg@arm.com        assert(privateFlags.isSet(VALID_PADDR));
4407720Sgblack@eecs.umich.edu        return _paddr;
4417720Sgblack@eecs.umich.edu    }
4427720Sgblack@eecs.umich.edu
4437720Sgblack@eecs.umich.edu    /**
4447720Sgblack@eecs.umich.edu     * Time for the TLB/table walker to successfully translate this request.
4457720Sgblack@eecs.umich.edu     */
4467720Sgblack@eecs.umich.edu    Tick translateDelta;
4477720Sgblack@eecs.umich.edu
4487720Sgblack@eecs.umich.edu    /**
4497720Sgblack@eecs.umich.edu     * Access latency to complete this memory transaction not including
4507720Sgblack@eecs.umich.edu     * translation time.
4517720Sgblack@eecs.umich.edu     */
4527720Sgblack@eecs.umich.edu    Tick accessDelta;
4537720Sgblack@eecs.umich.edu
4547720Sgblack@eecs.umich.edu    /**
4557720Sgblack@eecs.umich.edu     * Level of the cache hierachy where this request was responded to
4567720Sgblack@eecs.umich.edu     * (e.g. 0 = L1; 1 = L2).
457     */
458    mutable int depth;
459
460    /**
461     *  Accessor for size.
462     */
463    bool
464    hasSize() const
465    {
466        return privateFlags.isSet(VALID_SIZE);
467    }
468
469    unsigned
470    getSize() const
471    {
472        assert(privateFlags.isSet(VALID_SIZE));
473        return _size;
474    }
475
476    /** Accessor for time. */
477    Tick
478    time() const
479    {
480        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
481        return _time;
482    }
483
484    /** Accessor for flags. */
485    Flags
486    getFlags()
487    {
488        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
489        return _flags;
490    }
491
492    /** Note that unlike other accessors, this function sets *specific
493        flags* (ORs them in); it does not assign its argument to the
494        _flags field.  Thus this method should rightly be called
495        setFlags() and not just flags(). */
496    void
497    setFlags(Flags flags)
498    {
499        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
500        _flags.set(flags);
501    }
502
503    /** Accessor function for vaddr.*/
504    bool
505    hasVaddr() const
506    {
507        return privateFlags.isSet(VALID_VADDR);
508    }
509
510    Addr
511    getVaddr() const
512    {
513        assert(privateFlags.isSet(VALID_VADDR));
514        return _vaddr;
515    }
516
517    /** Accesssor for the requestor id. */
518    MasterID
519    masterId() const
520    {
521        return _masterId;
522    }
523
524    uint32_t
525    taskId() const
526    {
527        return _taskId;
528    }
529
530    void
531    taskId(uint32_t id) {
532        _taskId = id;
533    }
534
535    /** Accessor function for asid.*/
536    int
537    getAsid() const
538    {
539        assert(privateFlags.isSet(VALID_VADDR));
540        return _asid;
541    }
542
543    /** Accessor function for asid.*/
544    void
545    setAsid(int asid)
546    {
547        _asid = asid;
548    }
549
550    /** Accessor function for architecture-specific flags.*/
551    ArchFlagsType
552    getArchFlags() const
553    {
554        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
555        return _flags & ARCH_BITS;
556    }
557
558    /** Accessor function to check if sc result is valid. */
559    bool
560    extraDataValid() const
561    {
562        return privateFlags.isSet(VALID_EXTRA_DATA);
563    }
564
565    /** Accessor function for store conditional return value.*/
566    uint64_t
567    getExtraData() const
568    {
569        assert(privateFlags.isSet(VALID_EXTRA_DATA));
570        return _extraData;
571    }
572
573    /** Accessor function for store conditional return value.*/
574    void
575    setExtraData(uint64_t extraData)
576    {
577        _extraData = extraData;
578        privateFlags.set(VALID_EXTRA_DATA);
579    }
580
581    bool
582    hasContextId() const
583    {
584        return privateFlags.isSet(VALID_CONTEXT_ID);
585    }
586
587    /** Accessor function for context ID.*/
588    ContextID
589    contextId() const
590    {
591        assert(privateFlags.isSet(VALID_CONTEXT_ID));
592        return _contextId;
593    }
594
595    /** Accessor function for thread ID. */
596    ThreadID
597    threadId() const
598    {
599        assert(privateFlags.isSet(VALID_THREAD_ID));
600        return _threadId;
601    }
602
603    void
604    setPC(Addr pc)
605    {
606        privateFlags.set(VALID_PC);
607        _pc = pc;
608    }
609
610    bool
611    hasPC() const
612    {
613        return privateFlags.isSet(VALID_PC);
614    }
615
616    /** Accessor function for pc.*/
617    Addr
618    getPC() const
619    {
620        assert(privateFlags.isSet(VALID_PC));
621        return _pc;
622    }
623
624    /**
625     * Increment/Get the depth at which this request is responded to.
626     * This currently happens when the request misses in any cache level.
627     */
628    void incAccessDepth() const { depth++; }
629    int getAccessDepth() const { return depth; }
630
631    /**
632     * Set/Get the time taken for this request to be successfully translated.
633     */
634    void setTranslateLatency() { translateDelta = curTick() - _time; }
635    Tick getTranslateLatency() const { return translateDelta; }
636
637    /**
638     * Set/Get the time taken to complete this request's access, not including
639     *  the time to successfully translate the request.
640     */
641    void setAccessLatency() { accessDelta = curTick() - _time - translateDelta; }
642    Tick getAccessLatency() const { return accessDelta; }
643
644    /** Accessor functions for flags.  Note that these are for testing
645        only; setting flags should be done via setFlags(). */
646    bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
647    bool isStrictlyOrdered() const { return _flags.isSet(STRICT_ORDER); }
648    bool isInstFetch() const { return _flags.isSet(INST_FETCH); }
649    bool isPrefetch() const { return _flags.isSet(PREFETCH); }
650    bool isLLSC() const { return _flags.isSet(LLSC); }
651    bool isPriv() const { return _flags.isSet(PRIVILEGED); }
652    bool isLockedRMW() const { return _flags.isSet(LOCKED_RMW); }
653    bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
654    bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
655    bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
656    bool isSecure() const { return _flags.isSet(SECURE); }
657    bool isPTWalk() const { return _flags.isSet(PT_WALK); }
658};
659
660#endif // __MEM_REQUEST_HH__
661