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.
This commit is contained in:
parent
37908d62a4
commit
df973abef3
16 changed files with 72 additions and 46 deletions
|
@ -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");
|
||||
|
|
|
@ -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.
|
||||
|
|
2
src/mem/cache/prefetch/Prefetcher.py
vendored
2
src/mem/cache/prefetch/Prefetcher.py
vendored
|
@ -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'
|
||||
|
|
9
src/mem/cache/prefetch/base.cc
vendored
9
src/mem/cache/prefetch/base.cc
vendored
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
4
src/mem/cache/prefetch/base.hh
vendored
4
src/mem/cache/prefetch/base.hh
vendored
|
@ -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
|
||||
|
|
1
src/mem/cache/tags/base.cc
vendored
1
src/mem/cache/tags/base.cc
vendored
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 <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;
|
||||
|
|
Loading…
Reference in a new issue