ruby: reset and dump stats along with reset of the system
[gem5.git] / src / mem / request.hh
index 546774d136aa832eca44d1ee7a7711e6a9d6548f..11f1c74b3e404f48a4babfb62631f245c022a9fb 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
 #define __MEM_REQUEST_HH__
 
 #include <cassert>
+#include <climits>
 
-#include "base/fast_alloc.hh"
 #include "base/flags.hh"
 #include "base/misc.hh"
-#include "sim/host.hh"
+#include "base/types.hh"
 #include "sim/core.hh"
 
+/**
+ * Special TaskIds that are used for per-context-switch stats dumps
+ * and Cache Occupancy. Having too many tasks seems to be a problem
+ * with vector stats. 1024 seems to be a reasonable number that
+ * doesn't cause a problem with stats and is large enough to realistic
+ * benchmarks (Linux/Android boot, BBench, etc.)
+ */
+
+namespace ContextSwitchTaskId {
+    enum TaskId {
+        MaxNormalTaskId = 1021, /* Maximum number of normal tasks */
+        Prefetcher = 1022, /* For cache lines brought in by prefetcher */
+        DMA = 1023, /* Mostly Table Walker */
+        Unknown = 1024,
+        NumTaskId
+    };
+}
+
 class Request;
 
 typedef Request* RequestPtr;
+typedef uint16_t MasterID;
 
-class Request : public FastAlloc
+class Request
 {
   public:
     typedef uint32_t FlagsType;
@@ -70,14 +101,10 @@ class Request : public FastAlloc
     /** The request is to an uncacheable address. */
     static const FlagsType UNCACHEABLE                 = 0x00001000;
     /** This request is to a memory mapped register. */
-    static const FlagsType MMAPED_IPR                  = 0x00002000;
-
-    /** The request should not cause a page fault. */
-    static const FlagsType NO_FAULT                    = 0x00010000;
-    /** The request should ignore unaligned access faults */
-    static const FlagsType NO_ALIGN_FAULT              = 0x00020000;
-    /** The request should ignore unaligned access faults */
-    static const FlagsType NO_HALF_WORD_ALIGN_FAULT    = 0x00040000;
+    static const FlagsType MMAPPED_IPR                  = 0x00002000;
+    /** This request is a clear exclusive. */
+    static const FlagsType CLEAR_LL                    = 0x00004000;
+
     /** The request should not cause a memory access. */
     static const FlagsType NO_ACCESS                   = 0x00080000;
     /** This request will lock or unlock the accessed memory. When used with
@@ -104,6 +131,26 @@ class Request : public FastAlloc
        (assigned a new address). */
     static const FlagsType STICKY_FLAGS = INST_FETCH;
 
+    /** Request Ids that are statically allocated
+     * @{*/
+    /** This request id is used for writeback requests by the caches */
+    static const MasterID wbMasterId = 0;
+    /** This request id is used for functional requests that don't come from a
+     * particular device
+     */
+    static const MasterID funcMasterId = 1;
+    /** This request id is used for message signaled interrupts */
+    static const MasterID intMasterId = 2;
+    /** Invalid request id for assertion checking only. It is invalid behavior
+     * to ever send this id as part of a request.
+     * @todo C++1x replace with numeric_limits when constexpr is added  */
+    static const MasterID invldMasterId = USHRT_MAX;
+    /** @} */
+
+    /** Invalid or unknown Pid. Possible when operating system is not present
+     *  or has not assigned a pid yet */
+    static const uint32_t invldPid = UINT_MAX;
+
   private:
     typedef uint8_t PrivateFlagsType;
     typedef ::Flags<PrivateFlagsType> PrivateFlags;
@@ -132,38 +179,43 @@ class Request : public FastAlloc
      * The physical address of the request. Valid only if validPaddr
      * is set.
      */
-    Addr paddr;
+    Addr _paddr;
 
     /**
      * 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;
+    int _size;
+
+    /** The requestor ID which is unique in the system for all ports
+     * that are capable of issuing a transaction
+     */
+    MasterID _masterId;
 
     /** Flag structure for the request. */
-    Flags flags;
+    Flags _flags;
 
     /** Private flags for field validity checking. */
     PrivateFlags privateFlags;
 
     /**
      * The time this request was started. Used to calculate
-     * latencies. This field is set to curTick any time paddr or vaddr
+     * latencies. This field is set to curTick() any time paddr or vaddr
      * is written.
      */
-    Tick time;
+    Tick _time;
 
     /** The address space ID. */
-    int asid;
+    int _asid;
 
     /** The virtual address of the request. */
-    Addr vaddr;
+    Addr _vaddr;
 
     /**
      * Extra data for the request, such as the return value of
      * store conditional or the compare value for a CAS. */
-    uint64_t extraData;
+    uint64_t _extraData;
 
     /** The context ID (for statistics, typically). */
     int _contextId;
@@ -171,40 +223,55 @@ class Request : public FastAlloc
     int _threadId;
 
     /** program counter of initiating access; for tracing/debugging */
-    Addr pc;
+    Addr _pc;
 
   public:
-    /** Minimal constructor.  No fields are initialized. */
+    /** Minimal constructor.  No fields are initialized. 
+     *  (Note that _flags and privateFlags are cleared by Flags
+     *  default constructor.)
+     */
     Request()
     {}
 
     /**
      * Constructor for physical (e.g. device) requests.  Initializes
-     * just physical address, size, flags, and timestamp (to curTick).
+     * just physical address, size, flags, and timestamp (to curTick()).
      * These fields are adequate to perform a request. 
      */
-    Request(Addr paddr, int size, Flags flags)
+    Request(Addr paddr, int size, Flags flags, MasterID mid)
     {
-        setPhys(paddr, size, flags);
+        setPhys(paddr, size, flags, mid);
     }
 
-    Request(int asid, Addr vaddr, int size, Flags flags, Addr pc,
-            int cid, int tid)
+    Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
     {
-        setVirt(asid, vaddr, size, flags, pc);
+        setPhys(paddr, size, flags, mid, time);
+    }
+
+    Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time, Addr pc)
+    {
+        setPhys(paddr, size, flags, mid, time);
+        privateFlags.set(VALID_PC);
+        _pc = pc;
+    }
+
+    Request(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc,
+            int cid, ThreadID tid)
+    {
+        setVirt(asid, vaddr, size, flags, mid, pc);
         setThreadContext(cid, tid);
     }
 
-    ~Request() {}  // for FastAlloc
+    ~Request() {}
 
     /**
      * Set up CPU and thread numbers.
      */
     void
-    setThreadContext(int context_id, int thread_id)
+    setThreadContext(int context_id, ThreadID tid)
     {
         _contextId = context_id;
-        _threadId = thread_id;
+        _threadId = tid;
         privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID);
     }
 
@@ -213,36 +280,42 @@ class Request : public FastAlloc
      * allocated Request object.
      */
     void
-    setPhys(Addr _paddr, int _size, Flags _flags)
+    setPhys(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
     {
-        assert(_size >= 0);
-        paddr = _paddr;
-        size = _size;
-        time = curTick;
-
-        flags.clear(~STICKY_FLAGS);
-        flags.set(_flags);
+        assert(size >= 0);
+        _paddr = paddr;
+        _size = size;
+        _time = time;
+        _masterId = mid;
+        _flags.clear(~STICKY_FLAGS);
+        _flags.set(flags);
         privateFlags.clear(~STICKY_PRIVATE_FLAGS);
         privateFlags.set(VALID_PADDR|VALID_SIZE);
     }
 
+    void
+    setPhys(Addr paddr, int size, Flags flags, MasterID mid)
+    {
+        setPhys(paddr, size, flags, mid, curTick());
+    }
+
     /**
      * Set up a virtual (e.g., CPU) request in a previously
      * allocated Request object.
      */
     void
-    setVirt(int _asid, Addr _vaddr, int _size, Flags _flags, Addr _pc)
+    setVirt(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc)
     {
-        assert(_size >= 0);
-        asid = _asid;
-        vaddr = _vaddr;
-        size = _size;
-        flags = _flags;
-        pc = _pc;
-        time = curTick;
-
-        flags.clear(~STICKY_FLAGS);
-        flags.set(_flags);
+        assert(size >= 0);
+        _asid = asid;
+        _vaddr = vaddr;
+        _size = size;
+        _masterId = mid;
+        _pc = pc;
+        _time = curTick();
+
+        _flags.clear(~STICKY_FLAGS);
+        _flags.set(flags);
         privateFlags.clear(~STICKY_PRIVATE_FLAGS);
         privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC);
     }
@@ -254,10 +327,10 @@ class Request : public FastAlloc
      * to guarantee that the size and flags are also set.
      */
     void
-    setPaddr(Addr _paddr)
+    setPaddr(Addr paddr)
     {
         assert(privateFlags.isSet(VALID_VADDR));
-        paddr = _paddr;
+        _paddr = paddr;
         privateFlags.set(VALID_PADDR);
     }
 
@@ -269,14 +342,14 @@ class Request : public FastAlloc
     {
         assert(privateFlags.isSet(VALID_VADDR));
         assert(privateFlags.noneSet(VALID_PADDR));
-        assert(split_addr > vaddr && split_addr < vaddr + size);
+        assert(split_addr > _vaddr && split_addr < _vaddr + _size);
         req1 = new Request;
         *req1 = *this;
         req2 = new Request;
         *req2 = *this;
-        req1->size = split_addr - vaddr;
-        req2->vaddr = split_addr;
-        req2->size = size - req1->size;
+        req1->_size = split_addr - _vaddr;
+        req2->_vaddr = split_addr;
+        req2->_size = _size - req1->_size;
     }
 
     /**
@@ -292,7 +365,7 @@ class Request : public FastAlloc
     getPaddr()
     {
         assert(privateFlags.isSet(VALID_PADDR));
-        return paddr;
+        return _paddr;
     }
 
     /**
@@ -308,15 +381,22 @@ class Request : public FastAlloc
     getSize()
     {
         assert(privateFlags.isSet(VALID_SIZE));
-        return size;
+        return _size;
     }
 
     /** Accessor for time. */
     Tick
-    getTime()
+    time() const
     {
         assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
-        return time;
+        return _time;
+    }
+
+    void
+    time(Tick time)
+    {
+        assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
+        _time = time;
     }
 
     /** Accessor for flags. */
@@ -324,14 +404,18 @@ class Request : public FastAlloc
     getFlags()
     {
         assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
-        return flags;
+        return _flags;
     }
 
+    /** Note that unlike other accessors, this function sets *specific
+       flags* (ORs them in); it does not assign its argument to the
+       _flags field.  Thus this method should rightly be called
+       setFlags() and not just flags(). */
     void
-    setFlags(Flags _flags)
+    setFlags(Flags flags)
     {
         assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
-        flags.set(_flags);
+        _flags.set(flags);
     }
 
     /** Accessor function for vaddr.*/
@@ -339,7 +423,14 @@ class Request : public FastAlloc
     getVaddr()
     {
         assert(privateFlags.isSet(VALID_VADDR));
-        return vaddr;
+        return _vaddr;
+    }
+
+    /** Accesssor for the requestor id. */
+    MasterID
+    masterId()
+    {
+        return _masterId;
     }
 
     /** Accessor function for asid.*/
@@ -347,7 +438,14 @@ class Request : public FastAlloc
     getAsid()
     {
         assert(privateFlags.isSet(VALID_VADDR));
-        return asid;
+        return _asid;
+    }
+
+    /** Accessor function for asid.*/
+    void
+    setAsid(int asid)
+    {
+        _asid = asid;
     }
 
     /** Accessor function for asi.*/
@@ -355,22 +453,7 @@ class Request : public FastAlloc
     getAsi()
     {
         assert(privateFlags.isSet(VALID_VADDR));
-        return flags & ASI_BITS;
-    }
-
-    /** Accessor function for MMAPED_IPR flag. */
-    bool
-    isMmapedIpr()
-    {
-        assert(privateFlags.isSet(VALID_PADDR));
-        return flags.isSet(MMAPED_IPR);
-    }
-
-    void
-    setMmapedIpr(bool r)
-    {
-        assert(VALID_VADDR);
-        flags.set(MMAPED_IPR);
+        return _flags & ASI_BITS;
     }
 
     /** Accessor function to check if sc result is valid. */
@@ -385,14 +468,14 @@ class Request : public FastAlloc
     getExtraData() const
     {
         assert(privateFlags.isSet(VALID_EXTRA_DATA));
-        return extraData;
+        return _extraData;
     }
 
     /** Accessor function for store conditional return value.*/
     void
-    setExtraData(uint64_t _extraData)
+    setExtraData(uint64_t extraData)
     {
-        extraData = _extraData;
+        _extraData = extraData;
         privateFlags.set(VALID_EXTRA_DATA);
     }
 
@@ -429,35 +512,20 @@ class Request : public FastAlloc
     getPC() const
     {
         assert(privateFlags.isSet(VALID_PC));
-        return pc;
+        return _pc;
     }
 
-    /** Accessor Function to Check Cacheability. */
-    bool isUncacheable() const { return flags.isSet(UNCACHEABLE); }
-    bool isInstFetch() const { return flags.isSet(INST_FETCH); }
-    bool isPrefetch() const { return flags.isSet(PREFETCH); }
-    bool isLLSC() const { return flags.isSet(LLSC); }
-    bool isLocked() const { return flags.isSet(LOCKED); }
-    bool isSwap() const { return flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
-    bool isCondSwap() const { return flags.isSet(MEM_SWAP_COND); }
-
-    bool
-    isMisaligned() const
-    {
-        if (flags.isSet(NO_ALIGN_FAULT))
-            return false;
-
-        if ((vaddr & 0x1))
-            return true;
-
-        if (flags.isSet(NO_HALF_WORD_ALIGN_FAULT))
-            return false;
-
-        if ((vaddr & 0x2))
-            return true;
-
-        return false;
-    }
+    /** Accessor functions for flags.  Note that these are for testing
+       only; setting flags should be done via setFlags(). */
+    bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
+    bool isInstFetch() const { return _flags.isSet(INST_FETCH); }
+    bool isPrefetch() const { return _flags.isSet(PREFETCH); }
+    bool isLLSC() const { return _flags.isSet(LLSC); }
+    bool isLocked() const { return _flags.isSet(LOCKED); }
+    bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
+    bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
+    bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
+    bool isClearLL() const { return _flags.isSet(CLEAR_LL); }
 };
 
 #endif // __MEM_REQUEST_HH__