request.hh revision 10823:64cd1dcd61a5
1955SN/A/* 2955SN/A * Copyright (c) 2012-2013 ARM Limited 37816Ssteve.reinhardt@amd.com * All rights reserved 45871Snate@binkert.org * 51762SN/A * The license below extends only to copyright in the software and shall 6955SN/A * not be construed as granting a license to any other intellectual 7955SN/A * property including but not limited to intellectual property relating 8955SN/A * to a hardware implementation of the functionality of the software 9955SN/A * licensed hereunder. You may use the software subject to the license 10955SN/A * terms below provided that you ensure that this notice is replicated 11955SN/A * unmodified and in its entirety in all distributions of the software, 12955SN/A * modified or unmodified, in source code or in binary form. 13955SN/A * 14955SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 15955SN/A * All rights reserved. 16955SN/A * 17955SN/A * Redistribution and use in source and binary forms, with or without 18955SN/A * modification, are permitted provided that the following conditions are 19955SN/A * met: redistributions of source code must retain the above copyright 20955SN/A * notice, this list of conditions and the following disclaimer; 21955SN/A * redistributions in binary form must reproduce the above copyright 22955SN/A * notice, this list of conditions and the following disclaimer in the 23955SN/A * documentation and/or other materials provided with the distribution; 24955SN/A * neither the name of the copyright holders nor the names of its 25955SN/A * contributors may be used to endorse or promote products derived from 26955SN/A * this software without specific prior written permission. 27955SN/A * 28955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 325863Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382632Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392632Sstever@eecs.umich.edu * 402632Sstever@eecs.umich.edu * Authors: Ron Dreslinski 412632Sstever@eecs.umich.edu * Steve Reinhardt 42955SN/A * Ali Saidi 432632Sstever@eecs.umich.edu */ 442632Sstever@eecs.umich.edu 452761Sstever@eecs.umich.edu/** 462632Sstever@eecs.umich.edu * @file 472632Sstever@eecs.umich.edu * Declaration of a request, the overall memory request consisting of 482632Sstever@eecs.umich.edu the parts of the request that are persistent throughout the transaction. 492761Sstever@eecs.umich.edu */ 502761Sstever@eecs.umich.edu 512761Sstever@eecs.umich.edu#ifndef __MEM_REQUEST_HH__ 522632Sstever@eecs.umich.edu#define __MEM_REQUEST_HH__ 532632Sstever@eecs.umich.edu 542761Sstever@eecs.umich.edu#include <cassert> 552761Sstever@eecs.umich.edu#include <climits> 562761Sstever@eecs.umich.edu 572761Sstever@eecs.umich.edu#include "base/flags.hh" 582761Sstever@eecs.umich.edu#include "base/misc.hh" 592632Sstever@eecs.umich.edu#include "base/types.hh" 602632Sstever@eecs.umich.edu#include "sim/core.hh" 612632Sstever@eecs.umich.edu 622632Sstever@eecs.umich.edu/** 632632Sstever@eecs.umich.edu * Special TaskIds that are used for per-context-switch stats dumps 642632Sstever@eecs.umich.edu * and Cache Occupancy. Having too many tasks seems to be a problem 652632Sstever@eecs.umich.edu * with vector stats. 1024 seems to be a reasonable number that 66955SN/A * doesn't cause a problem with stats and is large enough to realistic 67955SN/A * benchmarks (Linux/Android boot, BBench, etc.) 68955SN/A */ 695863Snate@binkert.org 705863Snate@binkert.orgnamespace ContextSwitchTaskId { 715863Snate@binkert.org enum TaskId { 725863Snate@binkert.org MaxNormalTaskId = 1021, /* Maximum number of normal tasks */ 735863Snate@binkert.org Prefetcher = 1022, /* For cache lines brought in by prefetcher */ 745863Snate@binkert.org DMA = 1023, /* Mostly Table Walker */ 755863Snate@binkert.org Unknown = 1024, 765863Snate@binkert.org NumTaskId 775863Snate@binkert.org }; 785863Snate@binkert.org} 795863Snate@binkert.org 805863Snate@binkert.orgclass Request; 815863Snate@binkert.org 825863Snate@binkert.orgtypedef Request* RequestPtr; 835863Snate@binkert.orgtypedef uint16_t MasterID; 845863Snate@binkert.org 855863Snate@binkert.orgclass Request 865863Snate@binkert.org{ 875863Snate@binkert.org public: 885863Snate@binkert.org typedef uint32_t FlagsType; 895863Snate@binkert.org typedef uint8_t ArchFlagsType; 905863Snate@binkert.org typedef ::Flags<FlagsType> Flags; 915863Snate@binkert.org 925863Snate@binkert.org /** 935863Snate@binkert.org * Architecture specific flags. 945863Snate@binkert.org * 955863Snate@binkert.org * These bits int the flag field are reserved for 965863Snate@binkert.org * architecture-specific code. For example, SPARC uses them to 975863Snate@binkert.org * represent ASIs. 985863Snate@binkert.org */ 995863Snate@binkert.org static const FlagsType ARCH_BITS = 0x000000FF; 1006654Snate@binkert.org /** The request was an instruction fetch. */ 101955SN/A static const FlagsType INST_FETCH = 0x00000100; 1025396Ssaidi@eecs.umich.edu /** The virtual address is also the physical address. */ 1035863Snate@binkert.org static const FlagsType PHYSICAL = 0x00000200; 1045863Snate@binkert.org /** The request is to an uncacheable address. */ 1054202Sbinkertn@umich.edu static const FlagsType UNCACHEABLE = 0x00001000; 1065863Snate@binkert.org /** This request is to a memory mapped register. */ 1075863Snate@binkert.org static const FlagsType MMAPPED_IPR = 0x00002000; 1085863Snate@binkert.org /** This request is a clear exclusive. */ 1095863Snate@binkert.org static const FlagsType CLEAR_LL = 0x00004000; 110955SN/A /** This request is made in privileged mode. */ 1116654Snate@binkert.org static const FlagsType PRIVILEGED = 0x00008000; 1125273Sstever@gmail.com 1135871Snate@binkert.org /** This is a write that is targeted and zeroing an entire cache block. 1145273Sstever@gmail.com * There is no need for a read/modify/write 1156655Snate@binkert.org */ 1166655Snate@binkert.org static const FlagsType CACHE_BLOCK_ZERO = 0x00010000; 1176655Snate@binkert.org 1186655Snate@binkert.org /** The request should not cause a memory access. */ 1196655Snate@binkert.org static const FlagsType NO_ACCESS = 0x00080000; 1206655Snate@binkert.org /** This request will lock or unlock the accessed memory. When used with 1215871Snate@binkert.org * a load, the access locks the particular chunk of memory. When used 1226654Snate@binkert.org * with a store, it unlocks. The rule is that locked accesses have to be 1235396Ssaidi@eecs.umich.edu * made up of a locked load, some operation on the data, and then a locked 1248120Sgblack@eecs.umich.edu * store. 1258120Sgblack@eecs.umich.edu */ 1268120Sgblack@eecs.umich.edu static const FlagsType LOCKED_RMW = 0x00100000; 1278120Sgblack@eecs.umich.edu /** The request is a Load locked/store conditional. */ 1288120Sgblack@eecs.umich.edu static const FlagsType LLSC = 0x00200000; 1298120Sgblack@eecs.umich.edu /** This request is for a memory swap. */ 1308120Sgblack@eecs.umich.edu static const FlagsType MEM_SWAP = 0x00400000; 1318120Sgblack@eecs.umich.edu static const FlagsType MEM_SWAP_COND = 0x00800000; 1328120Sgblack@eecs.umich.edu 1338120Sgblack@eecs.umich.edu /** The request is a prefetch. */ 1348120Sgblack@eecs.umich.edu static const FlagsType PREFETCH = 0x01000000; 1358120Sgblack@eecs.umich.edu /** The request should be prefetched into the exclusive state. */ 1368120Sgblack@eecs.umich.edu static const FlagsType PF_EXCLUSIVE = 0x02000000; 1378120Sgblack@eecs.umich.edu /** The request should be marked as LRU. */ 1388120Sgblack@eecs.umich.edu static const FlagsType EVICT_NEXT = 0x04000000; 1398120Sgblack@eecs.umich.edu 1408120Sgblack@eecs.umich.edu /** The request should be handled by the generic IPR code (only 1418120Sgblack@eecs.umich.edu * valid together with MMAPPED_IPR) */ 1428120Sgblack@eecs.umich.edu static const FlagsType GENERIC_IPR = 0x08000000; 1438120Sgblack@eecs.umich.edu 1448120Sgblack@eecs.umich.edu /** The request targets the secure memory space. */ 1458120Sgblack@eecs.umich.edu static const FlagsType SECURE = 0x10000000; 1468120Sgblack@eecs.umich.edu /** The request is a page table walk */ 1478120Sgblack@eecs.umich.edu static const FlagsType PT_WALK = 0x20000000; 1488120Sgblack@eecs.umich.edu 1498120Sgblack@eecs.umich.edu /** These flags are *not* cleared when a Request object is reused 1508120Sgblack@eecs.umich.edu (assigned a new address). */ 1518120Sgblack@eecs.umich.edu static const FlagsType STICKY_FLAGS = INST_FETCH; 1528120Sgblack@eecs.umich.edu 1538120Sgblack@eecs.umich.edu /** Request Ids that are statically allocated 1548120Sgblack@eecs.umich.edu * @{*/ 1558120Sgblack@eecs.umich.edu /** This request id is used for writeback requests by the caches */ 1568120Sgblack@eecs.umich.edu static const MasterID wbMasterId = 0; 1578120Sgblack@eecs.umich.edu /** This request id is used for functional requests that don't come from a 1588120Sgblack@eecs.umich.edu * particular device 1598120Sgblack@eecs.umich.edu */ 1607816Ssteve.reinhardt@amd.com static const MasterID funcMasterId = 1; 1617816Ssteve.reinhardt@amd.com /** This request id is used for message signaled interrupts */ 1627816Ssteve.reinhardt@amd.com static const MasterID intMasterId = 2; 1637816Ssteve.reinhardt@amd.com /** Invalid request id for assertion checking only. It is invalid behavior 1647816Ssteve.reinhardt@amd.com * to ever send this id as part of a request. 1657816Ssteve.reinhardt@amd.com * @todo C++1x replace with numeric_limits when constexpr is added */ 1667816Ssteve.reinhardt@amd.com static const MasterID invldMasterId = std::numeric_limits<MasterID>::max(); 1677816Ssteve.reinhardt@amd.com /** @} */ 1687816Ssteve.reinhardt@amd.com 1695871Snate@binkert.org /** Invalid or unknown Pid. Possible when operating system is not present 1705871Snate@binkert.org * or has not assigned a pid yet */ 1716121Snate@binkert.org static const uint32_t invldPid = std::numeric_limits<uint32_t>::max(); 1725871Snate@binkert.org 1735871Snate@binkert.org private: 1746003Snate@binkert.org typedef uint8_t PrivateFlagsType; 1756655Snate@binkert.org typedef ::Flags<PrivateFlagsType> PrivateFlags; 176955SN/A 1775871Snate@binkert.org /** Whether or not the size is valid. */ 1785871Snate@binkert.org static const PrivateFlagsType VALID_SIZE = 0x00000001; 1795871Snate@binkert.org /** Whether or not paddr is valid (has been written yet). */ 1805871Snate@binkert.org static const PrivateFlagsType VALID_PADDR = 0x00000002; 181955SN/A /** Whether or not the vaddr & asid are valid. */ 1826121Snate@binkert.org static const PrivateFlagsType VALID_VADDR = 0x00000004; 1836121Snate@binkert.org /** Whether or not the pc is valid. */ 1846121Snate@binkert.org static const PrivateFlagsType VALID_PC = 0x00000010; 1851533SN/A /** Whether or not the context ID is valid. */ 1866655Snate@binkert.org static const PrivateFlagsType VALID_CONTEXT_ID = 0x00000020; 1876655Snate@binkert.org static const PrivateFlagsType VALID_THREAD_ID = 0x00000040; 1886655Snate@binkert.org /** Whether or not the sc result is valid. */ 1896655Snate@binkert.org static const PrivateFlagsType VALID_EXTRA_DATA = 0x00000080; 1905871Snate@binkert.org 1915871Snate@binkert.org /** These flags are *not* cleared when a Request object is reused 1925863Snate@binkert.org (assigned a new address). */ 1935871Snate@binkert.org static const PrivateFlagsType STICKY_PRIVATE_FLAGS = 1945871Snate@binkert.org VALID_CONTEXT_ID | VALID_THREAD_ID; 1955871Snate@binkert.org 1965871Snate@binkert.org private: 1975871Snate@binkert.org 1985863Snate@binkert.org /** 1996121Snate@binkert.org * Set up a physical (e.g. device) request in a previously 2005863Snate@binkert.org * allocated Request object. 2015871Snate@binkert.org */ 2024678Snate@binkert.org void 2034678Snate@binkert.org setPhys(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time) 2044678Snate@binkert.org { 2054678Snate@binkert.org assert(size >= 0); 2064678Snate@binkert.org _paddr = paddr; 2074678Snate@binkert.org _size = size; 2084678Snate@binkert.org _time = time; 2094678Snate@binkert.org _masterId = mid; 2104678Snate@binkert.org _flags.clear(~STICKY_FLAGS); 2114678Snate@binkert.org _flags.set(flags); 2124678Snate@binkert.org privateFlags.clear(~STICKY_PRIVATE_FLAGS); 2137827Snate@binkert.org privateFlags.set(VALID_PADDR|VALID_SIZE); 2147827Snate@binkert.org depth = 0; 2156121Snate@binkert.org accessDelta = 0; 2164678Snate@binkert.org //translateDelta = 0; 2175871Snate@binkert.org } 2185871Snate@binkert.org 2195871Snate@binkert.org /** 2205871Snate@binkert.org * The physical address of the request. Valid only if validPaddr 2215871Snate@binkert.org * is set. 2225871Snate@binkert.org */ 2235871Snate@binkert.org Addr _paddr; 2245871Snate@binkert.org 2255871Snate@binkert.org /** 2265871Snate@binkert.org * The size of the request. This field must be set when vaddr or 2275871Snate@binkert.org * paddr is written via setVirt() or setPhys(), so it is always 2285871Snate@binkert.org * valid as long as one of the address fields is valid. 2295871Snate@binkert.org */ 2305871Snate@binkert.org unsigned _size; 2318126Sgblack@eecs.umich.edu 2325871Snate@binkert.org /** The requestor ID which is unique in the system for all ports 2335871Snate@binkert.org * that are capable of issuing a transaction 2348122Sgblack@eecs.umich.edu */ 2355871Snate@binkert.org MasterID _masterId; 2365871Snate@binkert.org 2374678Snate@binkert.org /** Flag structure for the request. */ 2385871Snate@binkert.org Flags _flags; 2394678Snate@binkert.org 2405871Snate@binkert.org /** Private flags for field validity checking. */ 2415871Snate@binkert.org PrivateFlags privateFlags; 2425871Snate@binkert.org 2435871Snate@binkert.org /** 2445871Snate@binkert.org * The time this request was started. Used to calculate 2455871Snate@binkert.org * latencies. This field is set to curTick() any time paddr or vaddr 2465871Snate@binkert.org * is written. 2475871Snate@binkert.org */ 2485871Snate@binkert.org Tick _time; 2496121Snate@binkert.org 250955SN/A /** 251955SN/A * The task id associated with this request 2522632Sstever@eecs.umich.edu */ 2532632Sstever@eecs.umich.edu uint32_t _taskId; 254955SN/A 255955SN/A /** The address space ID. */ 256955SN/A int _asid; 257955SN/A 2585863Snate@binkert.org /** The virtual address of the request. */ 259955SN/A Addr _vaddr; 2602632Sstever@eecs.umich.edu 2612632Sstever@eecs.umich.edu /** 2622632Sstever@eecs.umich.edu * Extra data for the request, such as the return value of 2632632Sstever@eecs.umich.edu * store conditional or the compare value for a CAS. */ 2642632Sstever@eecs.umich.edu uint64_t _extraData; 2652632Sstever@eecs.umich.edu 2662632Sstever@eecs.umich.edu /** The context ID (for statistics, typically). */ 2678268Ssteve.reinhardt@amd.com int _contextId; 2688268Ssteve.reinhardt@amd.com /** The thread ID (id within this CPU) */ 2698268Ssteve.reinhardt@amd.com ThreadID _threadId; 2708268Ssteve.reinhardt@amd.com 2718268Ssteve.reinhardt@amd.com /** program counter of initiating access; for tracing/debugging */ 2728268Ssteve.reinhardt@amd.com Addr _pc; 2738268Ssteve.reinhardt@amd.com 2742632Sstever@eecs.umich.edu public: 2752632Sstever@eecs.umich.edu 2762632Sstever@eecs.umich.edu /** 2772632Sstever@eecs.umich.edu * Minimal constructor. No fields are initialized. (Note that 2788268Ssteve.reinhardt@amd.com * _flags and privateFlags are cleared by Flags default 2792632Sstever@eecs.umich.edu * constructor.) 2808268Ssteve.reinhardt@amd.com */ 2818268Ssteve.reinhardt@amd.com Request() 2828268Ssteve.reinhardt@amd.com : _paddr(0), _size(0), _masterId(invldMasterId), _time(0), 2838268Ssteve.reinhardt@amd.com _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0), 2843718Sstever@eecs.umich.edu _extraData(0), _contextId(0), _threadId(0), _pc(0), 2852634Sstever@eecs.umich.edu translateDelta(0), accessDelta(0), depth(0) 2862634Sstever@eecs.umich.edu {} 2875863Snate@binkert.org 2882638Sstever@eecs.umich.edu /** 2898268Ssteve.reinhardt@amd.com * Constructor for physical (e.g. device) requests. Initializes 2902632Sstever@eecs.umich.edu * just physical address, size, flags, and timestamp (to curTick()). 2912632Sstever@eecs.umich.edu * These fields are adequate to perform a request. 2922632Sstever@eecs.umich.edu */ 2932632Sstever@eecs.umich.edu Request(Addr paddr, unsigned size, Flags flags, MasterID mid) 2942632Sstever@eecs.umich.edu : _paddr(0), _size(0), _masterId(invldMasterId), _time(0), 2951858SN/A _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0), 2963716Sstever@eecs.umich.edu _extraData(0), _contextId(0), _threadId(0), _pc(0), 2972638Sstever@eecs.umich.edu translateDelta(0), accessDelta(0), depth(0) 2982638Sstever@eecs.umich.edu { 2992638Sstever@eecs.umich.edu setPhys(paddr, size, flags, mid, curTick()); 3002638Sstever@eecs.umich.edu } 3012638Sstever@eecs.umich.edu 3022638Sstever@eecs.umich.edu Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time) 3032638Sstever@eecs.umich.edu : _paddr(0), _size(0), _masterId(invldMasterId), _time(0), 3045863Snate@binkert.org _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0), 3055863Snate@binkert.org _extraData(0), _contextId(0), _threadId(0), _pc(0), 3065863Snate@binkert.org translateDelta(0), accessDelta(0), depth(0) 307955SN/A { 3085341Sstever@gmail.com setPhys(paddr, size, flags, mid, time); 3095341Sstever@gmail.com } 3105863Snate@binkert.org 3117756SAli.Saidi@ARM.com Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time, 3125341Sstever@gmail.com Addr pc) 3136121Snate@binkert.org : _paddr(0), _size(0), _masterId(invldMasterId), _time(0), 3144494Ssaidi@eecs.umich.edu _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0), 3156121Snate@binkert.org _extraData(0), _contextId(0), _threadId(0), _pc(0), 3161105SN/A translateDelta(0), accessDelta(0), depth(0) 3172667Sstever@eecs.umich.edu { 3182667Sstever@eecs.umich.edu setPhys(paddr, size, flags, mid, time); 3192667Sstever@eecs.umich.edu privateFlags.set(VALID_PC); 3202667Sstever@eecs.umich.edu _pc = pc; 3216121Snate@binkert.org } 3222667Sstever@eecs.umich.edu 3235341Sstever@gmail.com Request(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, 3245863Snate@binkert.org Addr pc, int cid, ThreadID tid) 3255341Sstever@gmail.com : _paddr(0), _size(0), _masterId(invldMasterId), _time(0), 3265341Sstever@gmail.com _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0), 3275341Sstever@gmail.com _extraData(0), _contextId(0), _threadId(0), _pc(0), 3288120Sgblack@eecs.umich.edu translateDelta(0), accessDelta(0), depth(0) 3295341Sstever@gmail.com { 3308120Sgblack@eecs.umich.edu setVirt(asid, vaddr, size, flags, mid, pc); 3315341Sstever@gmail.com setThreadContext(cid, tid); 3328120Sgblack@eecs.umich.edu } 3336121Snate@binkert.org 3346121Snate@binkert.org ~Request() {} 3355397Ssaidi@eecs.umich.edu 3365397Ssaidi@eecs.umich.edu /** 3377727SAli.Saidi@ARM.com * Set up CPU and thread numbers. 3388268Ssteve.reinhardt@amd.com */ 3396168Snate@binkert.org void 3405341Sstever@gmail.com setThreadContext(int context_id, ThreadID tid) 3418120Sgblack@eecs.umich.edu { 3428120Sgblack@eecs.umich.edu _contextId = context_id; 3438120Sgblack@eecs.umich.edu _threadId = tid; 3446814Sgblack@eecs.umich.edu privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID); 3455863Snate@binkert.org } 3468120Sgblack@eecs.umich.edu 3475341Sstever@gmail.com /** 3485863Snate@binkert.org * Set up a virtual (e.g., CPU) request in a previously 3498268Ssteve.reinhardt@amd.com * allocated Request object. 3506121Snate@binkert.org */ 3516121Snate@binkert.org void 3528268Ssteve.reinhardt@amd.com setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, 3535742Snate@binkert.org Addr pc) 3545742Snate@binkert.org { 3555341Sstever@gmail.com _asid = asid; 3565742Snate@binkert.org _vaddr = vaddr; 3575742Snate@binkert.org _size = size; 3585341Sstever@gmail.com _masterId = mid; 3596017Snate@binkert.org _pc = pc; 3606121Snate@binkert.org _time = curTick(); 3616017Snate@binkert.org 3627816Ssteve.reinhardt@amd.com _flags.clear(~STICKY_FLAGS); 3637756SAli.Saidi@ARM.com _flags.set(flags); 3647756SAli.Saidi@ARM.com privateFlags.clear(~STICKY_PRIVATE_FLAGS); 3657756SAli.Saidi@ARM.com privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC); 3667756SAli.Saidi@ARM.com depth = 0; 3677756SAli.Saidi@ARM.com accessDelta = 0; 3687756SAli.Saidi@ARM.com translateDelta = 0; 3697756SAli.Saidi@ARM.com } 3707756SAli.Saidi@ARM.com 3717816Ssteve.reinhardt@amd.com /** 3727816Ssteve.reinhardt@amd.com * Set just the physical address. This usually used to record the 3737816Ssteve.reinhardt@amd.com * result of a translation. However, when using virtualized CPUs 3747816Ssteve.reinhardt@amd.com * setPhys() is sometimes called to finalize a physical address 3757816Ssteve.reinhardt@amd.com * without a virtual address, so we can't check if the virtual 3767816Ssteve.reinhardt@amd.com * address is valid. 3777816Ssteve.reinhardt@amd.com */ 3787816Ssteve.reinhardt@amd.com void 3797816Ssteve.reinhardt@amd.com setPaddr(Addr paddr) 3807816Ssteve.reinhardt@amd.com { 3817756SAli.Saidi@ARM.com _paddr = paddr; 3827816Ssteve.reinhardt@amd.com privateFlags.set(VALID_PADDR); 3837816Ssteve.reinhardt@amd.com } 3847816Ssteve.reinhardt@amd.com 3857816Ssteve.reinhardt@amd.com /** 3867816Ssteve.reinhardt@amd.com * Generate two requests as if this request had been split into two 3877816Ssteve.reinhardt@amd.com * pieces. The original request can't have been translated already. 3887816Ssteve.reinhardt@amd.com */ 3897816Ssteve.reinhardt@amd.com void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2) 3907816Ssteve.reinhardt@amd.com { 3917816Ssteve.reinhardt@amd.com assert(privateFlags.isSet(VALID_VADDR)); 3927816Ssteve.reinhardt@amd.com assert(privateFlags.noneSet(VALID_PADDR)); 3937816Ssteve.reinhardt@amd.com assert(split_addr > _vaddr && split_addr < _vaddr + _size); 3947816Ssteve.reinhardt@amd.com req1 = new Request(*this); 3957816Ssteve.reinhardt@amd.com req2 = new Request(*this); 3967816Ssteve.reinhardt@amd.com req1->_size = split_addr - _vaddr; 3977816Ssteve.reinhardt@amd.com req2->_vaddr = split_addr; 3987816Ssteve.reinhardt@amd.com req2->_size = _size - req1->_size; 3997816Ssteve.reinhardt@amd.com } 4007816Ssteve.reinhardt@amd.com 4017816Ssteve.reinhardt@amd.com /** 4027816Ssteve.reinhardt@amd.com * Accessor for paddr. 4037816Ssteve.reinhardt@amd.com */ 4047816Ssteve.reinhardt@amd.com bool 4057816Ssteve.reinhardt@amd.com hasPaddr() const 4067816Ssteve.reinhardt@amd.com { 4077816Ssteve.reinhardt@amd.com return privateFlags.isSet(VALID_PADDR); 4087816Ssteve.reinhardt@amd.com } 4097816Ssteve.reinhardt@amd.com 4107816Ssteve.reinhardt@amd.com Addr 4117816Ssteve.reinhardt@amd.com getPaddr() const 4127816Ssteve.reinhardt@amd.com { 4137816Ssteve.reinhardt@amd.com assert(privateFlags.isSet(VALID_PADDR)); 4147816Ssteve.reinhardt@amd.com return _paddr; 4157816Ssteve.reinhardt@amd.com } 4167816Ssteve.reinhardt@amd.com 4177816Ssteve.reinhardt@amd.com /** 4187816Ssteve.reinhardt@amd.com * Time for the TLB/table walker to successfully translate this request. 4197816Ssteve.reinhardt@amd.com */ 4207816Ssteve.reinhardt@amd.com Tick translateDelta; 4217816Ssteve.reinhardt@amd.com 4227816Ssteve.reinhardt@amd.com /** 4237816Ssteve.reinhardt@amd.com * Access latency to complete this memory transaction not including 4247816Ssteve.reinhardt@amd.com * translation time. 4257816Ssteve.reinhardt@amd.com */ 4267816Ssteve.reinhardt@amd.com Tick accessDelta; 4277816Ssteve.reinhardt@amd.com 4287816Ssteve.reinhardt@amd.com /** 4297816Ssteve.reinhardt@amd.com * Level of the cache hierachy where this request was responded to 4307816Ssteve.reinhardt@amd.com * (e.g. 0 = L1; 1 = L2). 4317816Ssteve.reinhardt@amd.com */ 4327816Ssteve.reinhardt@amd.com mutable int depth; 4337816Ssteve.reinhardt@amd.com 4347816Ssteve.reinhardt@amd.com /** 4357816Ssteve.reinhardt@amd.com * Accessor for size. 4367816Ssteve.reinhardt@amd.com */ 4377816Ssteve.reinhardt@amd.com bool 4387816Ssteve.reinhardt@amd.com hasSize() const 4397816Ssteve.reinhardt@amd.com { 4407816Ssteve.reinhardt@amd.com return privateFlags.isSet(VALID_SIZE); 4417816Ssteve.reinhardt@amd.com } 4427816Ssteve.reinhardt@amd.com 4437756SAli.Saidi@ARM.com unsigned 4448120Sgblack@eecs.umich.edu getSize() const 4457756SAli.Saidi@ARM.com { 4467756SAli.Saidi@ARM.com assert(privateFlags.isSet(VALID_SIZE)); 4477756SAli.Saidi@ARM.com return _size; 4487756SAli.Saidi@ARM.com } 4497816Ssteve.reinhardt@amd.com 4507816Ssteve.reinhardt@amd.com /** Accessor for time. */ 4517816Ssteve.reinhardt@amd.com Tick 4527816Ssteve.reinhardt@amd.com time() const 4537816Ssteve.reinhardt@amd.com { 4547816Ssteve.reinhardt@amd.com assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); 4557816Ssteve.reinhardt@amd.com return _time; 4567816Ssteve.reinhardt@amd.com } 4577816Ssteve.reinhardt@amd.com 4587816Ssteve.reinhardt@amd.com /** Accessor for flags. */ 4597756SAli.Saidi@ARM.com Flags 4607756SAli.Saidi@ARM.com getFlags() 4616654Snate@binkert.org { 4626654Snate@binkert.org assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); 4635871Snate@binkert.org return _flags; 4646121Snate@binkert.org } 4656121Snate@binkert.org 4666121Snate@binkert.org /** Note that unlike other accessors, this function sets *specific 4676121Snate@binkert.org flags* (ORs them in); it does not assign its argument to the 4683940Ssaidi@eecs.umich.edu _flags field. Thus this method should rightly be called 4693918Ssaidi@eecs.umich.edu setFlags() and not just flags(). */ 4703918Ssaidi@eecs.umich.edu void 4711858SN/A setFlags(Flags flags) 4726121Snate@binkert.org { 4737739Sgblack@eecs.umich.edu assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); 4747739Sgblack@eecs.umich.edu _flags.set(flags); 4756143Snate@binkert.org } 4767739Sgblack@eecs.umich.edu 4777618SAli.Saidi@arm.com /** Accessor function for vaddr.*/ 4787618SAli.Saidi@arm.com bool 4797618SAli.Saidi@arm.com hasVaddr() const 4807618SAli.Saidi@arm.com { 4817618SAli.Saidi@arm.com return privateFlags.isSet(VALID_VADDR); 4827618SAli.Saidi@arm.com } 4837618SAli.Saidi@arm.com 4847739Sgblack@eecs.umich.edu Addr 4856121Snate@binkert.org getVaddr() const 4863940Ssaidi@eecs.umich.edu { 4876121Snate@binkert.org assert(privateFlags.isSet(VALID_VADDR)); 4887739Sgblack@eecs.umich.edu return _vaddr; 4897739Sgblack@eecs.umich.edu } 4907739Sgblack@eecs.umich.edu 4917739Sgblack@eecs.umich.edu /** Accesssor for the requestor id. */ 4927739Sgblack@eecs.umich.edu MasterID 4937739Sgblack@eecs.umich.edu masterId() const 4943918Ssaidi@eecs.umich.edu { 4953918Ssaidi@eecs.umich.edu return _masterId; 4963940Ssaidi@eecs.umich.edu } 4973918Ssaidi@eecs.umich.edu 4983918Ssaidi@eecs.umich.edu uint32_t 4996157Snate@binkert.org taskId() const 5006157Snate@binkert.org { 5016157Snate@binkert.org return _taskId; 5026157Snate@binkert.org } 5035397Ssaidi@eecs.umich.edu 5045397Ssaidi@eecs.umich.edu void 5056121Snate@binkert.org taskId(uint32_t id) { 5066121Snate@binkert.org _taskId = id; 5076121Snate@binkert.org } 5086121Snate@binkert.org 5096121Snate@binkert.org /** Accessor function for asid.*/ 5106121Snate@binkert.org int 5115397Ssaidi@eecs.umich.edu getAsid() const 5121851SN/A { 5131851SN/A assert(privateFlags.isSet(VALID_VADDR)); 5147739Sgblack@eecs.umich.edu return _asid; 515955SN/A } 5163053Sstever@eecs.umich.edu 5176121Snate@binkert.org /** Accessor function for asid.*/ 5183053Sstever@eecs.umich.edu void 5193053Sstever@eecs.umich.edu setAsid(int asid) 5203053Sstever@eecs.umich.edu { 5213053Sstever@eecs.umich.edu _asid = asid; 5223053Sstever@eecs.umich.edu } 5236654Snate@binkert.org 5243053Sstever@eecs.umich.edu /** Accessor function for architecture-specific flags.*/ 5254742Sstever@eecs.umich.edu ArchFlagsType 5264742Sstever@eecs.umich.edu getArchFlags() const 5273053Sstever@eecs.umich.edu { 5283053Sstever@eecs.umich.edu assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); 5293053Sstever@eecs.umich.edu return _flags & ARCH_BITS; 5303053Sstever@eecs.umich.edu } 5316654Snate@binkert.org 5323053Sstever@eecs.umich.edu /** Accessor function to check if sc result is valid. */ 5333053Sstever@eecs.umich.edu bool 5343053Sstever@eecs.umich.edu extraDataValid() const 5353053Sstever@eecs.umich.edu { 5362667Sstever@eecs.umich.edu return privateFlags.isSet(VALID_EXTRA_DATA); 5374554Sbinkertn@umich.edu } 5386121Snate@binkert.org 5392667Sstever@eecs.umich.edu /** Accessor function for store conditional return value.*/ 5404554Sbinkertn@umich.edu uint64_t 5414554Sbinkertn@umich.edu getExtraData() const 5424554Sbinkertn@umich.edu { 5436121Snate@binkert.org assert(privateFlags.isSet(VALID_EXTRA_DATA)); 5444554Sbinkertn@umich.edu return _extraData; 5454554Sbinkertn@umich.edu } 5464554Sbinkertn@umich.edu 5474781Snate@binkert.org /** Accessor function for store conditional return value.*/ 5484554Sbinkertn@umich.edu void 5494554Sbinkertn@umich.edu setExtraData(uint64_t extraData) 5502667Sstever@eecs.umich.edu { 5514554Sbinkertn@umich.edu _extraData = extraData; 5524554Sbinkertn@umich.edu privateFlags.set(VALID_EXTRA_DATA); 5534554Sbinkertn@umich.edu } 5544554Sbinkertn@umich.edu 5552667Sstever@eecs.umich.edu bool 5564554Sbinkertn@umich.edu hasContextId() const 5572667Sstever@eecs.umich.edu { 5584554Sbinkertn@umich.edu return privateFlags.isSet(VALID_CONTEXT_ID); 5596121Snate@binkert.org } 5602667Sstever@eecs.umich.edu 5615522Snate@binkert.org /** Accessor function for context ID.*/ 5625522Snate@binkert.org int 5635522Snate@binkert.org contextId() const 5645522Snate@binkert.org { 5655522Snate@binkert.org assert(privateFlags.isSet(VALID_CONTEXT_ID)); 5665522Snate@binkert.org return _contextId; 5675522Snate@binkert.org } 5685522Snate@binkert.org 5695522Snate@binkert.org /** Accessor function for thread ID. */ 5705522Snate@binkert.org ThreadID 5715522Snate@binkert.org threadId() const 5725522Snate@binkert.org { 5735522Snate@binkert.org assert(privateFlags.isSet(VALID_THREAD_ID)); 5745522Snate@binkert.org return _threadId; 5755522Snate@binkert.org } 5765522Snate@binkert.org 5775522Snate@binkert.org void 5785522Snate@binkert.org setPC(Addr pc) 5795522Snate@binkert.org { 5805522Snate@binkert.org privateFlags.set(VALID_PC); 5815522Snate@binkert.org _pc = pc; 5825522Snate@binkert.org } 5835522Snate@binkert.org 5845522Snate@binkert.org bool 5855522Snate@binkert.org hasPC() const 5865522Snate@binkert.org { 5872638Sstever@eecs.umich.edu return privateFlags.isSet(VALID_PC); 5882638Sstever@eecs.umich.edu } 5896121Snate@binkert.org 5903716Sstever@eecs.umich.edu /** Accessor function for pc.*/ 5915522Snate@binkert.org Addr 5925522Snate@binkert.org getPC() const 5935522Snate@binkert.org { 5945522Snate@binkert.org assert(privateFlags.isSet(VALID_PC)); 5955522Snate@binkert.org return _pc; 5965522Snate@binkert.org } 5971858SN/A 5985227Ssaidi@eecs.umich.edu /** 5995227Ssaidi@eecs.umich.edu * Increment/Get the depth at which this request is responded to. 6005227Ssaidi@eecs.umich.edu * This currently happens when the request misses in any cache level. 6015227Ssaidi@eecs.umich.edu */ 6026654Snate@binkert.org void incAccessDepth() const { depth++; } 6036654Snate@binkert.org int getAccessDepth() const { return depth; } 6047769SAli.Saidi@ARM.com 6057769SAli.Saidi@ARM.com /** 6067769SAli.Saidi@ARM.com * Set/Get the time taken for this request to be successfully translated. 6077769SAli.Saidi@ARM.com */ 6085227Ssaidi@eecs.umich.edu void setTranslateLatency() { translateDelta = curTick() - _time; } 6095227Ssaidi@eecs.umich.edu Tick getTranslateLatency() const { return translateDelta; } 6105227Ssaidi@eecs.umich.edu 6115204Sstever@gmail.com /** 6125204Sstever@gmail.com * Set/Get the time taken to complete this request's access, not including 6135204Sstever@gmail.com * the time to successfully translate the request. 6145204Sstever@gmail.com */ 6155204Sstever@gmail.com void setAccessLatency() { accessDelta = curTick() - _time - translateDelta; } 6165204Sstever@gmail.com Tick getAccessLatency() const { return accessDelta; } 6175204Sstever@gmail.com 6185204Sstever@gmail.com /** Accessor functions for flags. Note that these are for testing 6195204Sstever@gmail.com only; setting flags should be done via setFlags(). */ 6205204Sstever@gmail.com bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); } 6215204Sstever@gmail.com bool isInstFetch() const { return _flags.isSet(INST_FETCH); } 6225204Sstever@gmail.com bool isPrefetch() const { return _flags.isSet(PREFETCH); } 6235204Sstever@gmail.com bool isLLSC() const { return _flags.isSet(LLSC); } 6245204Sstever@gmail.com bool isPriv() const { return _flags.isSet(PRIVILEGED); } 6255204Sstever@gmail.com bool isLockedRMW() const { return _flags.isSet(LOCKED_RMW); } 6265204Sstever@gmail.com bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); } 6275204Sstever@gmail.com bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); } 6286121Snate@binkert.org bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); } 6295204Sstever@gmail.com bool isClearLL() const { return _flags.isSet(CLEAR_LL); } 6303118Sstever@eecs.umich.edu bool isSecure() const { return _flags.isSet(SECURE); } 6313118Sstever@eecs.umich.edu bool isPTWalk() const { return _flags.isSet(PT_WALK); } 6323118Sstever@eecs.umich.edu}; 6333118Sstever@eecs.umich.edu 6343118Sstever@eecs.umich.edu#endif // __MEM_REQUEST_HH__ 6355863Snate@binkert.org