request.hh revision 5607:eb9b92bf37ec
1955SN/A/* 2955SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 31762SN/A * All rights reserved. 4955SN/A * 5955SN/A * Redistribution and use in source and binary forms, with or without 6955SN/A * modification, are permitted provided that the following conditions are 7955SN/A * met: redistributions of source code must retain the above copyright 8955SN/A * notice, this list of conditions and the following disclaimer; 9955SN/A * redistributions in binary form must reproduce the above copyright 10955SN/A * notice, this list of conditions and the following disclaimer in the 11955SN/A * documentation and/or other materials provided with the distribution; 12955SN/A * neither the name of the copyright holders nor the names of its 13955SN/A * contributors may be used to endorse or promote products derived from 14955SN/A * this software without specific prior written permission. 15955SN/A * 16955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A * 282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski 294762Snate@binkert.org * Steve Reinhardt 30955SN/A * Ali Saidi 315522Snate@binkert.org */ 324762Snate@binkert.org 335522Snate@binkert.org/** 34955SN/A * @file 355522Snate@binkert.org * Declaration of a request, the overall memory request consisting of 36955SN/A the parts of the request that are persistent throughout the transaction. 375522Snate@binkert.org */ 384202Sbinkertn@umich.edu 395742Snate@binkert.org#ifndef __MEM_REQUEST_HH__ 40955SN/A#define __MEM_REQUEST_HH__ 414381Sbinkertn@umich.edu 424381Sbinkertn@umich.edu#include "base/fast_alloc.hh" 43955SN/A#include "sim/host.hh" 44955SN/A#include "sim/core.hh" 45955SN/A 464202Sbinkertn@umich.edu#include <cassert> 47955SN/A 484382Sbinkertn@umich.educlass Request; 494382Sbinkertn@umich.edu 504382Sbinkertn@umich.edutypedef Request* RequestPtr; 515517Snate@binkert.org 525517Snate@binkert.org 534762Snate@binkert.org/** ASI information for this request if it exsits. */ 544762Snate@binkert.orgconst uint32_t ASI_BITS = 0x000FF; 554762Snate@binkert.org/** The request is a Load locked/store conditional. */ 564762Snate@binkert.orgconst uint32_t LOCKED = 0x00100; 574762Snate@binkert.org/** The virtual address is also the physical address. */ 584762Snate@binkert.orgconst uint32_t PHYSICAL = 0x00200; 594762Snate@binkert.org/** The request is an ALPHA VPTE pal access (hw_ld). */ 604762Snate@binkert.orgconst uint32_t VPTE = 0x00400; 614762Snate@binkert.org/** Use the alternate mode bits in ALPHA. */ 624762Snate@binkert.orgconst uint32_t ALTMODE = 0x00800; 635522Snate@binkert.org/** The request is to an uncacheable address. */ 645604Snate@binkert.orgconst uint32_t UNCACHEABLE = 0x01000; 655604Snate@binkert.org/** The request should not cause a page fault. */ 665604Snate@binkert.orgconst uint32_t NO_FAULT = 0x02000; 674762Snate@binkert.org/** The request should be prefetched into the exclusive state. */ 684762Snate@binkert.orgconst uint32_t PF_EXCLUSIVE = 0x10000; 694762Snate@binkert.org/** The request should be marked as LRU. */ 705522Snate@binkert.orgconst uint32_t EVICT_NEXT = 0x20000; 715522Snate@binkert.org/** The request should ignore unaligned access faults */ 725522Snate@binkert.orgconst uint32_t NO_ALIGN_FAULT = 0x40000; 735522Snate@binkert.org/** The request was an instruction read. */ 745604Snate@binkert.orgconst uint32_t INST_READ = 0x80000; 755604Snate@binkert.org/** This request is for a memory swap. */ 764762Snate@binkert.orgconst uint32_t MEM_SWAP = 0x100000; 774762Snate@binkert.orgconst uint32_t MEM_SWAP_COND = 0x200000; 784762Snate@binkert.org/** The request should ignore unaligned access faults */ 794762Snate@binkert.orgconst uint32_t NO_HALF_WORD_ALIGN_FAULT = 0x400000; 805522Snate@binkert.org 814762Snate@binkert.org 824762Snate@binkert.orgclass Request : public FastAlloc 835604Snate@binkert.org{ 845604Snate@binkert.org private: 855604Snate@binkert.org /** 865604Snate@binkert.org * The physical address of the request. Valid only if validPaddr 875604Snate@binkert.org * is set. */ 885604Snate@binkert.org Addr paddr; 894762Snate@binkert.org 904762Snate@binkert.org /** 914762Snate@binkert.org * The size of the request. This field must be set when vaddr or 924762Snate@binkert.org * paddr is written via setVirt() or setPhys(), so it is always 935604Snate@binkert.org * valid as long as one of the address fields is valid. */ 944762Snate@binkert.org int size; 955522Snate@binkert.org 965522Snate@binkert.org /** Flag structure for the request. */ 975522Snate@binkert.org uint32_t flags; 984762Snate@binkert.org 994382Sbinkertn@umich.edu /** 1004762Snate@binkert.org * The time this request was started. Used to calculate 1014382Sbinkertn@umich.edu * latencies. This field is set to curTick any time paddr or vaddr 1025522Snate@binkert.org * is written. */ 1034381Sbinkertn@umich.edu Tick time; 1045522Snate@binkert.org 1054762Snate@binkert.org /** The address space ID. */ 1064762Snate@binkert.org int asid; 1074762Snate@binkert.org 1085522Snate@binkert.org /** This request is to a memory mapped register. */ 1095522Snate@binkert.org bool mmapedIpr; 1105522Snate@binkert.org 1115522Snate@binkert.org /** The virtual address of the request. */ 1125522Snate@binkert.org Addr vaddr; 1135522Snate@binkert.org 1145522Snate@binkert.org /** Extra data for the request, such as the return value of 1155522Snate@binkert.org * store conditional or the compare value for a CAS. */ 1165522Snate@binkert.org uint64_t extraData; 1174762Snate@binkert.org 1184762Snate@binkert.org /** The cpu number (for statistics, typically). */ 1194762Snate@binkert.org int cpuNum; 1204762Snate@binkert.org /** The requesting thread id (for statistics, typically). */ 1214762Snate@binkert.org int threadNum; 1224762Snate@binkert.org 1234762Snate@binkert.org /** program counter of initiating access; for tracing/debugging */ 1244762Snate@binkert.org Addr pc; 1254762Snate@binkert.org 1264762Snate@binkert.org /** Whether or not paddr is valid (has been written yet). */ 1274762Snate@binkert.org bool validPaddr; 1284762Snate@binkert.org /** Whether or not the asid & vaddr are valid. */ 1294762Snate@binkert.org bool validAsidVaddr; 1304762Snate@binkert.org /** Whether or not the sc result is valid. */ 1314762Snate@binkert.org bool validExData; 1324762Snate@binkert.org /** Whether or not the cpu number & thread ID are valid. */ 1334762Snate@binkert.org bool validCpuAndThreadNums; 1344762Snate@binkert.org /** Whether or not the pc is valid. */ 1354762Snate@binkert.org bool validPC; 1364762Snate@binkert.org 1374762Snate@binkert.org public: 1384762Snate@binkert.org /** Minimal constructor. No fields are initialized. */ 1394762Snate@binkert.org Request() 1404762Snate@binkert.org : validPaddr(false), validAsidVaddr(false), 1414762Snate@binkert.org validExData(false), validCpuAndThreadNums(false), validPC(false) 1424762Snate@binkert.org {} 1434762Snate@binkert.org 1444762Snate@binkert.org /** 1454762Snate@binkert.org * Constructor for physical (e.g. device) requests. Initializes 1464762Snate@binkert.org * just physical address, size, flags, and timestamp (to curTick). 1474762Snate@binkert.org * These fields are adequate to perform a request. */ 1484762Snate@binkert.org Request(Addr _paddr, int _size, int _flags) 1494762Snate@binkert.org : validCpuAndThreadNums(false) 1504762Snate@binkert.org { setPhys(_paddr, _size, _flags); } 1514762Snate@binkert.org 152955SN/A Request(int _asid, Addr _vaddr, int _size, int _flags, Addr _pc, 1535584Snate@binkert.org int _cpuNum, int _threadNum) 1545584Snate@binkert.org { 1555584Snate@binkert.org setThreadContext(_cpuNum, _threadNum); 1565584Snate@binkert.org setVirt(_asid, _vaddr, _size, _flags, _pc); 1575584Snate@binkert.org } 1585584Snate@binkert.org 1595584Snate@binkert.org ~Request() {} // for FastAlloc 1605584Snate@binkert.org 1615584Snate@binkert.org /** 1625584Snate@binkert.org * Set up CPU and thread numbers. */ 1635584Snate@binkert.org void setThreadContext(int _cpuNum, int _threadNum) 1645584Snate@binkert.org { 1655584Snate@binkert.org cpuNum = _cpuNum; 1664382Sbinkertn@umich.edu threadNum = _threadNum; 1674202Sbinkertn@umich.edu validCpuAndThreadNums = true; 1685522Snate@binkert.org } 1694382Sbinkertn@umich.edu 1704382Sbinkertn@umich.edu /** 1714382Sbinkertn@umich.edu * Set up a physical (e.g. device) request in a previously 1725584Snate@binkert.org * allocated Request object. */ 1734382Sbinkertn@umich.edu void setPhys(Addr _paddr, int _size, int _flags) 1744382Sbinkertn@umich.edu { 1754382Sbinkertn@umich.edu paddr = _paddr; 1765192Ssaidi@eecs.umich.edu size = _size; 1775192Ssaidi@eecs.umich.edu flags = _flags; 1785192Ssaidi@eecs.umich.edu time = curTick; 1795192Ssaidi@eecs.umich.edu validPaddr = true; 1805192Ssaidi@eecs.umich.edu validAsidVaddr = false; 1815192Ssaidi@eecs.umich.edu validPC = false; 1825192Ssaidi@eecs.umich.edu validExData = false; 1835192Ssaidi@eecs.umich.edu mmapedIpr = false; 1845192Ssaidi@eecs.umich.edu } 1855192Ssaidi@eecs.umich.edu 1865192Ssaidi@eecs.umich.edu /** 1875192Ssaidi@eecs.umich.edu * Set up a virtual (e.g., CPU) request in a previously 1885192Ssaidi@eecs.umich.edu * allocated Request object. */ 1895192Ssaidi@eecs.umich.edu void setVirt(int _asid, Addr _vaddr, int _size, int _flags, Addr _pc) 1905192Ssaidi@eecs.umich.edu { 1915192Ssaidi@eecs.umich.edu asid = _asid; 1925192Ssaidi@eecs.umich.edu vaddr = _vaddr; 1935192Ssaidi@eecs.umich.edu size = _size; 1945192Ssaidi@eecs.umich.edu flags = _flags; 1955192Ssaidi@eecs.umich.edu pc = _pc; 1965192Ssaidi@eecs.umich.edu time = curTick; 1975192Ssaidi@eecs.umich.edu validPaddr = false; 1985192Ssaidi@eecs.umich.edu validAsidVaddr = true; 1995192Ssaidi@eecs.umich.edu validPC = true; 2005192Ssaidi@eecs.umich.edu validExData = false; 2015192Ssaidi@eecs.umich.edu mmapedIpr = false; 2025192Ssaidi@eecs.umich.edu } 2035192Ssaidi@eecs.umich.edu 2045192Ssaidi@eecs.umich.edu /** Set just the physical address. This should only be used to 2055192Ssaidi@eecs.umich.edu * record the result of a translation, and thus the vaddr must be 2065192Ssaidi@eecs.umich.edu * valid before this method is called. Otherwise, use setPhys() 2075192Ssaidi@eecs.umich.edu * to guarantee that the size and flags are also set. 2084382Sbinkertn@umich.edu */ 2094382Sbinkertn@umich.edu void setPaddr(Addr _paddr) 2104382Sbinkertn@umich.edu { 2112667Sstever@eecs.umich.edu assert(validAsidVaddr); 2122667Sstever@eecs.umich.edu paddr = _paddr; 2132667Sstever@eecs.umich.edu validPaddr = true; 2142667Sstever@eecs.umich.edu } 2152667Sstever@eecs.umich.edu 2162667Sstever@eecs.umich.edu /** Accessor for paddr. */ 2175742Snate@binkert.org Addr getPaddr() { assert(validPaddr); return paddr; } 2185742Snate@binkert.org 2195742Snate@binkert.org /** Accessor for size. */ 2202037SN/A int getSize() { assert(validPaddr || validAsidVaddr); return size; } 2212037SN/A /** Accessor for time. */ 2222037SN/A Tick getTime() { assert(validPaddr || validAsidVaddr); return time; } 2235793Snate@binkert.org void resetTime() { assert(validPaddr || validAsidVaddr); time = curTick; } 2245793Snate@binkert.org void 2255793Snate@binkert.org setTime(Tick when) 2265793Snate@binkert.org { 2275793Snate@binkert.org assert(validPaddr || validAsidVaddr); 2284382Sbinkertn@umich.edu time = when; 2294762Snate@binkert.org } 2305344Sstever@gmail.com 2314382Sbinkertn@umich.edu /** Accessor for flags. */ 2325341Sstever@gmail.com uint32_t getFlags() { assert(validPaddr || validAsidVaddr); return flags; } 2335742Snate@binkert.org /** Accessor for paddr. */ 2345742Snate@binkert.org void setFlags(uint32_t _flags) 2355742Snate@binkert.org { assert(validPaddr || validAsidVaddr); flags = _flags; } 2365742Snate@binkert.org 2375742Snate@binkert.org /** Accessor function for vaddr.*/ 2384762Snate@binkert.org Addr getVaddr() { assert(validAsidVaddr); return vaddr; } 2395742Snate@binkert.org 2405742Snate@binkert.org /** Accessor function for asid.*/ 2415742Snate@binkert.org int getAsid() { assert(validAsidVaddr); return asid; } 2425742Snate@binkert.org 2435742Snate@binkert.org /** Accessor function for asi.*/ 2445742Snate@binkert.org uint8_t getAsi() { assert(validAsidVaddr); return flags & ASI_BITS; } 2455742Snate@binkert.org 2465341Sstever@gmail.com /** Accessor function for asi.*/ 2475742Snate@binkert.org void setAsi(uint8_t a) 2485341Sstever@gmail.com { assert(validAsidVaddr); flags = (flags & ~ASI_BITS) | a; } 2494773Snate@binkert.org 2501858SN/A /** Accessor function for asi.*/ 2511858SN/A bool isMmapedIpr() { assert(validPaddr); return mmapedIpr; } 2521085SN/A 2534382Sbinkertn@umich.edu /** Accessor function for asi.*/ 2544382Sbinkertn@umich.edu void setMmapedIpr(bool r) { assert(validAsidVaddr); mmapedIpr = r; } 2554762Snate@binkert.org 2564762Snate@binkert.org /** Accessor function to check if sc result is valid. */ 2574762Snate@binkert.org bool extraDataValid() { return validExData; } 2585517Snate@binkert.org /** Accessor function for store conditional return value.*/ 2595517Snate@binkert.org uint64_t getExtraData() { assert(validExData); return extraData; } 2605517Snate@binkert.org /** Accessor function for store conditional return value.*/ 2615517Snate@binkert.org void setExtraData(uint64_t _extraData) 2625517Snate@binkert.org { extraData = _extraData; validExData = true; } 2635517Snate@binkert.org 2645517Snate@binkert.org /** Accessor function for cpu number.*/ 2655517Snate@binkert.org int getCpuNum() { assert(validCpuAndThreadNums); return cpuNum; } 2665517Snate@binkert.org /** Accessor function for thread number.*/ 2675517Snate@binkert.org int getThreadNum() { assert(validCpuAndThreadNums); return threadNum; } 2685517Snate@binkert.org 2695517Snate@binkert.org /** Accessor function for pc.*/ 2705517Snate@binkert.org Addr getPC() { assert(validPC); return pc; } 2715517Snate@binkert.org 2725517Snate@binkert.org /** Accessor Function to Check Cacheability. */ 2735517Snate@binkert.org bool isUncacheable() { return (getFlags() & UNCACHEABLE) != 0; } 2745517Snate@binkert.org 2755798Snate@binkert.org bool isInstRead() { return (getFlags() & INST_READ) != 0; } 2765517Snate@binkert.org 2775517Snate@binkert.org bool isLocked() { return (getFlags() & LOCKED) != 0; } 2785517Snate@binkert.org 2795517Snate@binkert.org bool isSwap() { return (getFlags() & MEM_SWAP || 2805517Snate@binkert.org getFlags() & MEM_SWAP_COND); } 2815517Snate@binkert.org 2825517Snate@binkert.org bool isCondSwap() { return (getFlags() & MEM_SWAP_COND) != 0; } 2835517Snate@binkert.org 2845517Snate@binkert.org bool inline isMisaligned() {return (!(getFlags() & NO_ALIGN_FAULT) && 2855517Snate@binkert.org ((vaddr & 1) || 2865517Snate@binkert.org (!(getFlags() & NO_HALF_WORD_ALIGN_FAULT) 2875517Snate@binkert.org && (vaddr & 0x2))));} 2885517Snate@binkert.org 2895517Snate@binkert.org friend class Packet; 2905517Snate@binkert.org}; 2915517Snate@binkert.org 2925517Snate@binkert.org#endif // __MEM_REQUEST_HH__ 2935517Snate@binkert.org