Many more fixes for SPARC_FS. Gets us to the point where SOFTINT starts
[gem5.git] / src / mem / request.hh
index 10550e859b4052fdfd3fe97589893a886cbabfa8..de0512e1c7d72a690cccf5c3e3df624d1db4fb45 100644 (file)
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ron Dreslinski
+ *          Steve Reinhardt
+ *          Ali Saidi
  */
 
 /**
- * @file Decleration of a request, the overall memory request consisting of
+ * @file
+ * Declaration of a request, the overall memory request consisting of
  the parts of the request that are persistent throughout the transaction.
  */
 
 #ifndef __MEM_REQUEST_HH__
 #define __MEM_REQUEST_HH__
 
-#include "arch/isa_traits.hh"
+#include "sim/host.hh"
+#include "sim/root.hh"
+
+#include <cassert>
 
 class Request;
 
 typedef Request* RequestPtr;
 
+
+/** ASI information for this request if it exsits. */
+const uint32_t ASI_BITS         = 0x000FF;
 /** The request is a Load locked/store conditional. */
-const unsigned LOCKED          = 0x001;
+const uint32_t LOCKED          = 0x00100;
 /** The virtual address is also the physical address. */
-const unsigned PHYSICAL                = 0x002;
+const uint32_t PHYSICAL                = 0x00200;
 /** The request is an ALPHA VPTE pal access (hw_ld). */
-const unsigned VPTE            = 0x004;
+const uint32_t VPTE            = 0x00400;
 /** Use the alternate mode bits in ALPHA. */
-const unsigned ALTMODE         = 0x008;
+const uint32_t ALTMODE         = 0x00800;
 /** The request is to an uncacheable address. */
-const unsigned UNCACHEABLE     = 0x010;
+const uint32_t UNCACHEABLE     = 0x01000;
 /** The request should not cause a page fault. */
-const unsigned NO_FAULT         = 0x020;
+const uint32_t NO_FAULT         = 0x02000;
 /** The request should be prefetched into the exclusive state. */
-const unsigned PF_EXCLUSIVE    = 0x100;
+const uint32_t PF_EXCLUSIVE    = 0x10000;
 /** The request should be marked as LRU. */
-const unsigned EVICT_NEXT      = 0x200;
+const uint32_t EVICT_NEXT      = 0x20000;
 /** The request should ignore unaligned access faults */
-const unsigned NO_ALIGN_FAULT   = 0x400;
+const uint32_t NO_ALIGN_FAULT   = 0x40000;
+/** The request was an instruction read. */
+const uint32_t INST_READ        = 0x80000;
 
 class Request
 {
-    //@todo Make Accesor functions, make these private.
-  public:
-    /** Constructor, needs a bool to signify if it is/isn't Cpu Request. */
-    Request(bool isCpu);
-
-    /** reset the request to it's initial state so it can be reused.*/
-    void resetAll(bool isCpu);
-
-    /** reset the request's addrs times, etc, so but not everything to same
-     * time. */
-    void resetMin();
-
-//First non-cpu request fields
   private:
-    /** The physical address of the request. */
+    /**
+     * The physical address of the request. Valid only if validPaddr
+     * is set. */
     Addr paddr;
-    /** Wether or not paddr is valid (has been written yet). */
-    bool validPaddr;
 
-    /** The size of the request. */
+    /**
+     * The size of the request. This field must be set when vaddr or
+     * paddr is written via setVirt() or setPhys(), so it is always
+     * valid as long as one of the address fields is valid.  */
     int size;
-    /** Wether or not size is valid (has been written yet). */
-    bool validSize;
-
-    /** The time this request was started. Used to calculate latencies. */
-    Tick time;
-    /** Wether or not time is valid (has been written yet). */
-    bool validTime;
-
-    /** Destination address if this is a block copy. */
-    Addr copyDest;
-    /** Wether or not copyDest is valid (has been written yet). */
-    bool validCopyDest;
 
     /** Flag structure for the request. */
     uint32_t flags;
 
-//Accsesors for non-cpu request fields
-  public:
-    /** Accesor for paddr. */
-    Addr getPaddr();
-    /** Accesor for paddr. */
-    void setPaddr(Addr _paddr);
-
-    /** Accesor for size. */
-    int getSize();
-    /** Accesor for size. */
-    void setSize(int _size);
-
-    /** Accesor for time. */
-    Tick getTime();
-    /** Accesor for time. */
-    void setTime(Tick _time);
-
-    /** Accesor for copy dest. */
-    Addr getCopyDest();
-    /** Accesor for copy dest. */
-    void setCopyDest(Addr _copyDest);
-
-    /** Accesor for flags. */
-    uint32_t getFlags();
-    /** Accesor for paddr. */
-    void setFlags(uint32_t _flags);
-
-//Now cpu-request fields
-  private:
-    /** Bool to signify if this is a cpuRequest. */
-    bool cpuReq;
-
-    /** The virtual address of the request. */
-    Addr vaddr;
-    /** Wether or not the vaddr is valid. */
-    bool validVaddr;
+    /**
+     * The time this request was started. Used to calculate
+     * latencies. This field is set to curTick any time paddr or vaddr
+     * is written.  */
+    Tick time;
 
     /** The address space ID. */
     int asid;
-    /** Wether or not the asid is valid. */
-    bool validAsid;
+
+    /** This request is to a memory mapped register. */
+    bool mmapedIpr;
+
+    /** The virtual address of the request. */
+    Addr vaddr;
 
     /** The return value of store conditional. */
     uint64_t scResult;
-    /** Wether or not the sc result is valid. */
-    bool validScResult;
 
-    /** The cpu number for statistics. */
+    /** The cpu number (for statistics, typically). */
     int cpuNum;
-    /** Wether or not the cpu number is valid. */
-    bool validCpuNum;
-
-    /** The requesting  thread id. */
+    /** The requesting thread id (for statistics, typically). */
     int  threadNum;
-    /** Wether or not the thread id is valid. */
-    bool validThreadNum;
 
     /** program counter of initiating access; for tracing/debugging */
     Addr pc;
-    /** Wether or not the pc is valid. */
+
+    /** Whether or not paddr is valid (has been written yet). */
+    bool validPaddr;
+    /** Whether or not the asid & vaddr are valid. */
+    bool validAsidVaddr;
+    /** Whether or not the sc result is valid. */
+    bool validScResult;
+    /** Whether or not the cpu number & thread ID are valid. */
+    bool validCpuAndThreadNums;
+    /** Whether or not the pc is valid. */
     bool validPC;
 
-//Accessor Functions for cpu request fields
   public:
-    /** Accesor function to determine if this is a cpu request or not.*/
-    bool isCpuRequest();
-
-    /** Accesor function for vaddr.*/
-    Addr getVaddr();
-    /** Accesor function for vaddr.*/
-    void setVaddr(Addr _vaddr);
-
-    /** Accesor function for asid.*/
-    int getAsid();
-    /** Accesor function for asid.*/
-    void setAsid(int _asid);
-
-    /** Accesor function for store conditional return value.*/
-    uint64_t getScResult();
-    /** Accesor function for store conditional return value.*/
-    void setScResult(uint64_t _scResult);
-
-    /** Accesor function for cpu number.*/
-    int getCpuNum();
-    /** Accesor function for cpu number.*/
-    void setCpuNum(int _cpuNum);
-
-    /** Accesor function for thread number.*/
-    int getThreadNum();
-    /** Accesor function for thread number.*/
-    void setThreadNum(int _threadNum);
-
-    /** Accesor function for pc.*/
-    Addr getPC();
-    /** Accesor function for pc.*/
-    void setPC(Addr _pc);
+    /** Minimal constructor.  No fields are initialized. */
+    Request()
+        : validPaddr(false), validAsidVaddr(false),
+          validScResult(false), validCpuAndThreadNums(false), validPC(false)
+    {}
+
+    /**
+     * Constructor for physical (e.g. device) requests.  Initializes
+     * just physical address, size, flags, and timestamp (to curTick).
+     * These fields are adequate to perform a request.  */
+    Request(Addr _paddr, int _size, int _flags)
+        : validCpuAndThreadNums(false)
+    { setPhys(_paddr, _size, _flags); }
+
+    Request(int _asid, Addr _vaddr, int _size, int _flags, Addr _pc,
+            int _cpuNum, int _threadNum)
+    {
+        setThreadContext(_cpuNum, _threadNum);
+        setVirt(_asid, _vaddr, _size, _flags, _pc);
+    }
+
+    /**
+     * Set up CPU and thread numbers. */
+    void setThreadContext(int _cpuNum, int _threadNum)
+    {
+        cpuNum = _cpuNum;
+        threadNum = _threadNum;
+        validCpuAndThreadNums = true;
+    }
+
+    /**
+     * Set up a physical (e.g. device) request in a previously
+     * allocated Request object. */
+    void setPhys(Addr _paddr, int _size, int _flags)
+    {
+        paddr = _paddr;
+        size = _size;
+        flags = _flags;
+        time = curTick;
+        validPaddr = true;
+        validAsidVaddr = false;
+        validPC = false;
+        validScResult = false;
+        mmapedIpr = false;
+    }
+
+    /**
+     * Set up a virtual (e.g., CPU) request in a previously
+     * allocated Request object. */
+    void setVirt(int _asid, Addr _vaddr, int _size, int _flags, Addr _pc)
+    {
+        asid = _asid;
+        vaddr = _vaddr;
+        size = _size;
+        flags = _flags;
+        pc = _pc;
+        time = curTick;
+        validPaddr = false;
+        validAsidVaddr = true;
+        validPC = true;
+        validScResult = false;
+        mmapedIpr = false;
+    }
+
+    /** Set just the physical address.  This should only be used to
+     * record the result of a translation, and thus the vaddr must be
+     * valid before this method is called.  Otherwise, use setPhys()
+     * to guarantee that the size and flags are also set.
+     */
+    void setPaddr(Addr _paddr)
+    {
+        assert(validAsidVaddr);
+        paddr = _paddr;
+        validPaddr = true;
+    }
+
+    /** Accessor for paddr. */
+    Addr getPaddr() { assert(validPaddr); return paddr; }
+
+    /** Accessor for size. */
+    int getSize() { assert(validPaddr || validAsidVaddr); return size; }
+    /** Accessor for time. */
+    Tick getTime() { assert(validPaddr || validAsidVaddr); return time; }
+
+    /** Accessor for flags. */
+    uint32_t getFlags() { assert(validPaddr || validAsidVaddr); return flags; }
+    /** Accessor for paddr. */
+    void setFlags(uint32_t _flags)
+    { assert(validPaddr || validAsidVaddr); flags = _flags; }
+
+    /** Accessor function for vaddr.*/
+    Addr getVaddr() { assert(validAsidVaddr); return vaddr; }
+
+    /** Accessor function for asid.*/
+    int getAsid() { assert(validAsidVaddr); return asid; }
+
+    /** Accessor function for asi.*/
+    uint8_t getAsi() { assert(validAsidVaddr); return flags & ASI_BITS; }
+
+    /** Accessor function for asi.*/
+    void setAsi(uint8_t a)
+    { assert(validAsidVaddr); flags = (flags & ~ASI_BITS) | a; }
+
+    /** Accessor function for asi.*/
+    bool isMmapedIpr() { assert(validPaddr); return mmapedIpr; }
+
+    /** Accessor function for asi.*/
+    void setMmapedIpr(bool r) { assert(validAsidVaddr); mmapedIpr = r; }
+
+    /** Accessor function to check if sc result is valid. */
+    bool scResultValid() { return validScResult; }
+    /** Accessor function for store conditional return value.*/
+    uint64_t getScResult() { assert(validScResult); return scResult; }
+    /** Accessor function for store conditional return value.*/
+    void setScResult(uint64_t _scResult)
+    { scResult = _scResult; validScResult = true; }
+
+    /** Accessor function for cpu number.*/
+    int getCpuNum() { assert(validCpuAndThreadNums); return cpuNum; }
+    /** Accessor function for thread number.*/
+    int getThreadNum()  { assert(validCpuAndThreadNums); return threadNum; }
+
+    /** Accessor function for pc.*/
+    Addr getPC() { assert(validPC); return pc; }
+
+    /** Accessor Function to Check Cacheability. */
+    bool isUncacheable() { return (getFlags() & UNCACHEABLE) != 0; }
+
+    bool isInstRead() { return (getFlags() & INST_READ) != 0; }
+
+    bool isLocked() { return (getFlags() & LOCKED) != 0; }
 
     friend class Packet;
 };