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:
Andreas Hansson 2014-10-16 05:49:43 -04:00
parent 37908d62a4
commit df973abef3
16 changed files with 72 additions and 46 deletions

View 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");

View 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.

View 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'

View 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);
}

View 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

View 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"

View file

@ -225,6 +225,8 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) :
void
DRAMCtrl::init()
{
AbstractMemory::init();
if (!port.isConnected()) {
fatal("DRAMCtrl %s is unconnected!\n", name());
} else {

View 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 {

View 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)
{

View 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>

View 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;
}

View 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

View 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")

View 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()) {

View file

@ -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"

View 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
@ -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;