* 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"
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");
}
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()) {
}
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");
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.
"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'
#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"
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())
{
}
}
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);
}
/** Request id for prefetches */
MasterID masterId;
+ const Addr pageBytes;
+
public:
Stats::Scalar pfIdentified;
/**
* 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
* Definitions of BaseTags.
*/
-#include "config/the_isa.hh"
#include "cpu/smt.hh" //maxThreadsPerCPU
#include "mem/cache/tags/base.hh"
#include "mem/cache/base.hh"
void
DRAMCtrl::init()
{
- if (!port.isConnected()) {
+ AbstractMemory::init();
+
+ if (!port.isConnected()) {
fatal("DRAMCtrl %s is unconnected!\n", name());
} else {
port.sendRangeChange();
void
DRAMSim2::init()
{
+ AbstractMemory::init();
+
if (!port.isConnected()) {
fatal("DRAMSim2 %s is unconnected!\n", name());
} else {
* 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"
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)
{
physical_address_t getLineAddress() const;
physical_address_t getOffset() const;
void makeLineAddress();
- void makePageAddress();
void makeNextStrideAddress(int stride);
int64 memoryModuleIndex() const;
}
Address next_stride_address(const Address& addr, int stride);
-Address page_address(const Address& addr);
__hash_namespace_begin
template <> struct hash<Address>
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);
}
// 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
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;
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
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();
<< 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;
+}
#include "mem/ruby/system/System.hh"
#include "params/Prefetcher.hh"
#include "sim/sim_object.hh"
+#include "sim/system.hh"
#define MAX_PF_INFLIGHT 8
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
AbstractController *m_controller;
+ const Addr m_page_shift;
+
//! Count of accesses to the prefetcher
Stats::Scalar numMissObserved;
//! Count of prefetch streams allocated
# 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'
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")
void
SimpleMemory::init()
{
+ AbstractMemory::init();
+
// allow unconnected memories as this is used in several ruby
// systems at the moment
if (port.isConnected()) {
* 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"
/*
- * 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"
*/
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;