mem: Dynamically determine page bytes in memory components
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 16 Oct 2014 09:49:43 +0000 (05:49 -0400)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 16 Oct 2014 09:49:43 +0000 (05:49 -0400)
This patch takes a step towards an ISA-agnostic memory
system by enabling the components to establish the page size after
instantiation. The swap operation in the memory is now also allowing
any granularity to avoid depending on the IntReg of the ISA.

16 files changed:
src/mem/abstract_mem.cc
src/mem/abstract_mem.hh
src/mem/cache/prefetch/Prefetcher.py
src/mem/cache/prefetch/base.cc
src/mem/cache/prefetch/base.hh
src/mem/cache/tags/base.cc
src/mem/dram_ctrl.cc
src/mem/dramsim2.cc
src/mem/ruby/common/Address.cc
src/mem/ruby/common/Address.hh
src/mem/ruby/structures/Prefetcher.cc
src/mem/ruby/structures/Prefetcher.hh
src/mem/ruby/structures/RubyPrefetcher.py
src/mem/simple_mem.cc
src/sim/system.cc
src/sim/system.hh

index 98f03b9afc4dc01f70018172ead717b0745e6389..c819ce2fc0edc055f21e3d301eb86439ada7f711 100644 (file)
@@ -42,8 +42,8 @@
  *          Andreas Hansson
  */
 
-#include "arch/registers.hh"
-#include "config/the_isa.hh"
+#include <vector>
+
 #include "cpu/base.hh"
 #include "cpu/thread_context.hh"
 #include "debug/LLSC.hh"
@@ -59,7 +59,14 @@ AbstractMemory::AbstractMemory(const Params *p) :
     confTableReported(p->conf_table_reported), inAddrMap(p->in_addr_map),
     _system(NULL)
 {
-    if (size() % TheISA::PageBytes != 0)
+}
+
+void
+AbstractMemory::init()
+{
+    assert(system());
+
+    if (size() % _system->getPageBytes() != 0)
         panic("Memory Size not divisible by page size\n");
 }
 
@@ -327,19 +334,17 @@ AbstractMemory::access(PacketPtr pkt)
     uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start();
 
     if (pkt->cmd == MemCmd::SwapReq) {
-        TheISA::IntReg overwrite_val;
-        bool overwrite_mem;
+        std::vector<uint8_t> overwrite_val(pkt->getSize());
         uint64_t condition_val64;
         uint32_t condition_val32;
 
         if (!pmemAddr)
             panic("Swap only works if there is real memory (i.e. null=False)");
-        assert(sizeof(TheISA::IntReg) >= pkt->getSize());
 
-        overwrite_mem = true;
+        bool overwrite_mem = true;
         // keep a copy of our possible write value, and copy what is at the
         // memory address into the packet
-        std::memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize());
+        std::memcpy(&overwrite_val[0], pkt->getPtr<uint8_t>(), pkt->getSize());
         std::memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
 
         if (pkt->req->isCondSwap()) {
@@ -356,7 +361,7 @@ AbstractMemory::access(PacketPtr pkt)
         }
 
         if (overwrite_mem)
-            std::memcpy(hostAddr, &overwrite_val, pkt->getSize());
+            std::memcpy(hostAddr, &overwrite_val[0], pkt->getSize());
 
         assert(!pkt->req->isInstFetch());
         TRACE_PACKET("Read/Write");
index 57a47e3902c8970d1c6046e63f91ad1adebf1279..4b7ad8139f947b831ff9c925ab2d3175981e7997 100644 (file)
@@ -194,6 +194,11 @@ class AbstractMemory : public MemObject
     AbstractMemory(const Params* p);
     virtual ~AbstractMemory() {}
 
+    /**
+     * Initialise this memory.
+     */
+    void init();
+
     /**
      * See if this is a null memory that should never store data and
      * always return zero.
index 6bb4e52d3706b4546351c86dffb7b60c37616ffe..fed59661ddd1e89e256beabba4d060d62cc69589 100644 (file)
@@ -67,7 +67,7 @@ class BasePrefetcher(ClockedObject):
          "Let lower cache prefetcher train on prefetch requests")
     inst_tagged = Param.Bool(True,
          "Perform a tagged prefetch for instruction fetches always")
-    sys = Param.System(Parent.any, "System this device belongs to")
+    sys = Param.System(Parent.any, "System this prefetcher belongs to")
 
 class StridePrefetcher(BasePrefetcher):
     type = 'StridePrefetcher'
index 971ecf5b0d888395afb3ff0aedc3b6a3d4f923ee..ab740461dd0e95ad084a6ad61c0ce21a365f0faf 100644 (file)
@@ -47,9 +47,7 @@
 
 #include <list>
 
-#include "arch/isa_traits.hh"
 #include "base/trace.hh"
-#include "config/the_isa.hh"
 #include "debug/HWPrefetch.hh"
 #include "mem/cache/prefetch/base.hh"
 #include "mem/cache/base.hh"
@@ -63,7 +61,8 @@ BasePrefetcher::BasePrefetcher(const Params *p)
       serialSquash(p->serial_squash), onlyData(p->data_accesses_only),
       onMissOnly(p->on_miss_only), onReadOnly(p->on_read_only),
       onPrefetch(p->on_prefetch), system(p->sys),
-      masterId(system->getMasterId(name()))
+      masterId(system->getMasterId(name())),
+      pageBytes(system->getPageBytes())
 {
 }
 
@@ -312,9 +311,9 @@ BasePrefetcher::inPrefetch(Addr address, bool is_secure)
 }
 
 bool
-BasePrefetcher::samePage(Addr a, Addr b)
+BasePrefetcher::samePage(Addr a, Addr b) const
 {
-    return roundDown(a, TheISA::PageBytes) == roundDown(b, TheISA::PageBytes);
+    return roundDown(a, pageBytes) == roundDown(b, pageBytes);
 }
 
 
index 22a4c68f68d2c11f2d763f1805ebee93dc74a165..54f91a5096ccb81b82918a3477a31eeb78c484a9 100644 (file)
@@ -118,6 +118,8 @@ class BasePrefetcher : public ClockedObject
     /** Request id for prefetches */
     MasterID masterId;
 
+    const Addr pageBytes;
+
   public:
 
     Stats::Scalar pfIdentified;
@@ -172,7 +174,7 @@ class BasePrefetcher : public ClockedObject
     /**
      * Utility function: are addresses a and b on the same VM page?
      */
-    bool samePage(Addr a, Addr b);
+    bool samePage(Addr a, Addr b) const;
  public:
     const Params*
     params() const
index 2ec1379b00a0e7ec01d8c73ff8c94ad9bc1fff65..47a43fb7ec55dd6534497d2857076e6b09802e9e 100644 (file)
@@ -46,7 +46,6 @@
  * Definitions of BaseTags.
  */
 
-#include "config/the_isa.hh"
 #include "cpu/smt.hh" //maxThreadsPerCPU
 #include "mem/cache/tags/base.hh"
 #include "mem/cache/base.hh"
index eac9ca353a0a0048cfd6768630396dc46a19fd23..ac78a3d1e6ee70f4f7e622eede4898f5b0969a9c 100644 (file)
@@ -225,7 +225,9 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) :
 void
 DRAMCtrl::init()
 {
-    if (!port.isConnected()) {
+    AbstractMemory::init();
+
+   if (!port.isConnected()) {
         fatal("DRAMCtrl %s is unconnected!\n", name());
     } else {
         port.sendRangeChange();
index 3356fd7d2fd5bc8697a683da87f7d29186538b52..218500573c37428b3336ad683eec1181cec6f217 100644 (file)
@@ -77,6 +77,8 @@ DRAMSim2::DRAMSim2(const Params* p) :
 void
 DRAMSim2::init()
 {
+    AbstractMemory::init();
+
     if (!port.isConnected()) {
         fatal("DRAMSim2 %s is unconnected!\n", name());
     } else {
index eb234f46e97b49177c88d83c5ce2348ba9717c2a..5d9fa49e581b03f44c5aa5eef2d98766ea174822 100644 (file)
@@ -26,8 +26,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/System.hh"
 
@@ -136,20 +134,6 @@ Address::operator=(const Address& obj)
     return *this;
 }
 
-void
-Address::makePageAddress()
-{
-    m_address = maskLowOrderBits(TheISA::PageShift);
-}
-
-Address
-page_address(const Address& addr)
-{
-    Address temp = addr;
-    temp.makePageAddress();
-    return temp;
-}
-
 Address
 next_stride_address(const Address& addr, int stride)
 {
index feb8741c94a7d70bbc49cfc16e11f47d299418d4..d47ff9ac5d9e69f503a0a7b1ac9e3a46733c978f 100644 (file)
@@ -69,7 +69,6 @@ class Address
     physical_address_t getLineAddress() const;
     physical_address_t getOffset() const;
     void makeLineAddress();
-    void makePageAddress();
     void makeNextStrideAddress(int stride);
 
     int64 memoryModuleIndex() const;
@@ -201,7 +200,6 @@ Address::shiftLowOrderBits(unsigned int number) const
 }
 
 Address next_stride_address(const Address& addr, int stride);
-Address page_address(const Address& addr);
 
 __hash_namespace_begin
 template <> struct hash<Address>
index 05a1d8e62117e732d53d7b1c98814d5160d83f25..306174c2c3b82bca468421d17e9875daa1bcbe37 100644 (file)
@@ -45,7 +45,8 @@ Prefetcher::Prefetcher(const Params *p)
     m_unit_filter(p->unit_filter, Address(0)),
     m_negative_filter(p->unit_filter, Address(0)),
     m_nonunit_filter(p->nonunit_filter, Address(0)),
-    m_prefetch_cross_pages(p->cross_page)
+    m_prefetch_cross_pages(p->cross_page),
+    m_page_shift(p->sys->getPageShift())
 {
     assert(m_num_streams > 0);
     assert(m_num_startup_pfs <= MAX_PF_INFLIGHT);
@@ -231,12 +232,12 @@ Prefetcher::issueNextPrefetch(const Address &address, PrefetchEntry *stream)
     }
 
     // extend this prefetching stream by 1 (or more)
-    Address page_addr = page_address(stream->m_address);
+    Address page_addr = pageAddress(stream->m_address);
     Address line_addr = next_stride_address(stream->m_address,
                                             stream->m_stride);
 
     // possibly stop prefetching at page boundaries
-    if (page_addr != page_address(line_addr)) {
+    if (page_addr != pageAddress(line_addr)) {
         numPagesCrossed++;
         if (!m_prefetch_cross_pages) {
             // Deallocate the stream since we are not prefetching
@@ -295,7 +296,7 @@ Prefetcher::initializeStream(const Address& address, int stride,
     mystream->m_type = type;
 
     // create a number of initial prefetches for this stream
-    Address page_addr = page_address(mystream->m_address);
+    Address page_addr = pageAddress(mystream->m_address);
     Address line_addr = line_address(mystream->m_address);
     Address prev_addr = line_addr;
 
@@ -303,7 +304,7 @@ Prefetcher::initializeStream(const Address& address, int stride,
     for (int k = 0; k < m_num_startup_pfs; k++) {
         line_addr = next_stride_address(line_addr, stride);
         // possibly stop prefetching at page boundaries
-        if (page_addr != page_address(line_addr)) {
+        if (page_addr != pageAddress(line_addr)) {
             numPagesCrossed++;
             if (!m_prefetch_cross_pages) {
                 // deallocate this stream prefetcher
@@ -382,11 +383,11 @@ Prefetcher::accessNonunitFilter(const Address& address, int *stride,
     alloc = false;
 
     /// look for non-unit strides based on a (user-defined) page size
-    Address page_addr = page_address(address);
+    Address page_addr = pageAddress(address);
     Address line_addr = line_address(address);
 
     for (uint32_t i = 0; i < m_num_nonunit_filters; i++) {
-        if (page_address(m_nonunit_filter[i]) == page_addr) {
+        if (pageAddress(m_nonunit_filter[i]) == page_addr) {
             // hit in the non-unit filter
             // compute the actual stride (for this reference)
             int delta = line_addr.getAddress() - m_nonunit_filter[i].getAddress();
@@ -467,3 +468,11 @@ Prefetcher::print(std::ostream& out) const
             << m_array[i].m_use_time << std::endl;
     }
 }
+
+Address
+Prefetcher::pageAddress(const Address& addr) const
+{
+    Address temp = addr;
+    temp.maskLowOrderBits(m_page_shift);
+    return temp;
+}
index 2bc7d812eed9a291548facb5eb93fe9d6bc65fe6..6ed945b9ec097762e9a8088ce7f4c9d80e0d1483 100644 (file)
@@ -41,6 +41,7 @@
 #include "mem/ruby/system/System.hh"
 #include "params/Prefetcher.hh"
 #include "sim/sim_object.hh"
+#include "sim/system.hh"
 
 #define MAX_PF_INFLIGHT 8
 
@@ -139,6 +140,9 @@ class Prefetcher : public SimObject
         bool accessNonunitFilter(const Address& address, int *stride,
             bool &alloc);
 
+        /// determine the page aligned address
+        Address pageAddress(const Address& addr) const;
+
         //! number of prefetch streams available
         uint32_t m_num_streams;
         //! an array of the active prefetch streams
@@ -187,6 +191,8 @@ class Prefetcher : public SimObject
 
         AbstractController *m_controller;
 
+        const Addr m_page_shift;
+
         //! Count of accesses to the prefetcher
         Stats::Scalar numMissObserved;
         //! Count of prefetch streams allocated
index a02b116962150d93687706ea070e9d0588f0fae8..18bb3dc69472cf6d08ff90277396485033e73a76 100644 (file)
@@ -27,7 +27,9 @@
 # Authors: Nilay Vaish
 
 from m5.SimObject import SimObject
+from System import System
 from m5.params import *
+from m5.proxy import *
 
 class Prefetcher(SimObject):
     type = 'Prefetcher'
@@ -45,3 +47,4 @@ class Prefetcher(SimObject):
     num_startup_pfs = Param.UInt32(1, "")
     cross_page = Param.Bool(False, """True if prefetched address can be on a
             page different from the observed address""")
+    sys = Param.System(Parent.any, "System this prefetcher belongs to")
index 11ed74b3b2127ab030071ecca72f31112094c97c..27d3f11862d9e2199925ce303f41971a95a507c7 100644 (file)
@@ -59,6 +59,8 @@ SimpleMemory::SimpleMemory(const SimpleMemoryParams* p) :
 void
 SimpleMemory::init()
 {
+    AbstractMemory::init();
+
     // allow unconnected memories as this is used in several ruby
     // systems at the moment
     if (port.isConnected()) {
index c0b9486f47dfb31ab7610428b8334201ff8306ad..61c6decf7301e6dc0c82a6f734e04002f9f7b91f 100644 (file)
  *          Rick Strong
  */
 
-#include "arch/isa_traits.hh"
 #include "arch/remote_gdb.hh"
 #include "arch/utility.hh"
 #include "base/loader/object_file.hh"
 #include "base/loader/symtab.hh"
 #include "base/str.hh"
 #include "base/trace.hh"
-#include "config/the_isa.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Loader.hh"
 #include "debug/WorkItems.hh"
index 5b68373a6157353bca9596b15b1b86e0f903aaaa..d8297801870dd3513da6b7640d23dac89d7fe3a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2014 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
 #include <utility>
 #include <vector>
 
+#include "arch/isa_traits.hh"
 #include "base/loader/symtab.hh"
 #include "base/misc.hh"
 #include "base/statistics.hh"
+#include "config/the_isa.hh"
 #include "cpu/pc_event.hh"
 #include "enums/MemoryMode.hh"
 #include "kern/system_events.hh"
@@ -269,6 +271,16 @@ class System : public MemObject
      */
     bool isMemAddr(Addr addr) const;
 
+     /**
+     * Get the page bytes for the ISA.
+     */
+    Addr getPageBytes() const { return TheISA::PageBytes; }
+
+    /**
+     * Get the number of bits worth of in-page adress for the ISA.
+     */
+    Addr getPageShift() const { return TheISA::PageShift; }
+
   protected:
 
     PhysicalMemory physmem;