From df973abef3a70074971375cfe52c46f53528c00e Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Thu, 16 Oct 2014 05:49:43 -0400 Subject: mem: Dynamically determine page bytes in memory components 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. --- src/mem/abstract_mem.cc | 23 ++++++++++++++--------- src/mem/abstract_mem.hh | 5 +++++ src/mem/cache/prefetch/Prefetcher.py | 2 +- src/mem/cache/prefetch/base.cc | 9 ++++----- src/mem/cache/prefetch/base.hh | 4 +++- src/mem/cache/tags/base.cc | 1 - src/mem/dram_ctrl.cc | 4 +++- src/mem/dramsim2.cc | 2 ++ src/mem/ruby/common/Address.cc | 16 ---------------- src/mem/ruby/common/Address.hh | 2 -- src/mem/ruby/structures/Prefetcher.cc | 23 ++++++++++++++++------- src/mem/ruby/structures/Prefetcher.hh | 6 ++++++ src/mem/ruby/structures/RubyPrefetcher.py | 3 +++ src/mem/simple_mem.cc | 2 ++ src/sim/system.cc | 2 -- src/sim/system.hh | 14 +++++++++++++- 16 files changed, 72 insertions(+), 46 deletions(-) diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index 98f03b9af..c819ce2fc 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -42,8 +42,8 @@ * Andreas Hansson */ -#include "arch/registers.hh" -#include "config/the_isa.hh" +#include + #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 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(), pkt->getSize()); + std::memcpy(&overwrite_val[0], pkt->getPtr(), pkt->getSize()); std::memcpy(pkt->getPtr(), 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"); diff --git a/src/mem/abstract_mem.hh b/src/mem/abstract_mem.hh index 57a47e390..4b7ad8139 100644 --- a/src/mem/abstract_mem.hh +++ b/src/mem/abstract_mem.hh @@ -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. diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py index 6bb4e52d3..fed59661d 100644 --- a/src/mem/cache/prefetch/Prefetcher.py +++ b/src/mem/cache/prefetch/Prefetcher.py @@ -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' diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index 971ecf5b0..ab740461d 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -47,9 +47,7 @@ #include -#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); } diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh index 22a4c68f6..54f91a509 100644 --- a/src/mem/cache/prefetch/base.hh +++ b/src/mem/cache/prefetch/base.hh @@ -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 diff --git a/src/mem/cache/tags/base.cc b/src/mem/cache/tags/base.cc index 2ec1379b0..47a43fb7e 100644 --- a/src/mem/cache/tags/base.cc +++ b/src/mem/cache/tags/base.cc @@ -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" diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc index eac9ca353..ac78a3d1e 100644 --- a/src/mem/dram_ctrl.cc +++ b/src/mem/dram_ctrl.cc @@ -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(); diff --git a/src/mem/dramsim2.cc b/src/mem/dramsim2.cc index 3356fd7d2..218500573 100644 --- a/src/mem/dramsim2.cc +++ b/src/mem/dramsim2.cc @@ -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 { diff --git a/src/mem/ruby/common/Address.cc b/src/mem/ruby/common/Address.cc index eb234f46e..5d9fa49e5 100644 --- a/src/mem/ruby/common/Address.cc +++ b/src/mem/ruby/common/Address.cc @@ -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) { diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh index feb8741c9..d47ff9ac5 100644 --- a/src/mem/ruby/common/Address.hh +++ b/src/mem/ruby/common/Address.hh @@ -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
diff --git a/src/mem/ruby/structures/Prefetcher.cc b/src/mem/ruby/structures/Prefetcher.cc index 05a1d8e62..306174c2c 100644 --- a/src/mem/ruby/structures/Prefetcher.cc +++ b/src/mem/ruby/structures/Prefetcher.cc @@ -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; +} diff --git a/src/mem/ruby/structures/Prefetcher.hh b/src/mem/ruby/structures/Prefetcher.hh index 2bc7d812e..6ed945b9e 100644 --- a/src/mem/ruby/structures/Prefetcher.hh +++ b/src/mem/ruby/structures/Prefetcher.hh @@ -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 diff --git a/src/mem/ruby/structures/RubyPrefetcher.py b/src/mem/ruby/structures/RubyPrefetcher.py index a02b11696..18bb3dc69 100644 --- a/src/mem/ruby/structures/RubyPrefetcher.py +++ b/src/mem/ruby/structures/RubyPrefetcher.py @@ -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") diff --git a/src/mem/simple_mem.cc b/src/mem/simple_mem.cc index 11ed74b3b..27d3f1186 100644 --- a/src/mem/simple_mem.cc +++ b/src/mem/simple_mem.cc @@ -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()) { diff --git a/src/sim/system.cc b/src/sim/system.cc index c0b9486f4..61c6decf7 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -45,14 +45,12 @@ * 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" diff --git a/src/sim/system.hh b/src/sim/system.hh index 5b68373a6..d82978018 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -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 @@ -51,9 +51,11 @@ #include #include +#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; -- cgit v1.2.3