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