mem: Set the cache line size on a system level

This patch removes the notion of a peer block size and instead sets
the cache line size on the system level.

Previously the size was set per cache, and communicated through the
interconnect. There were plenty checks to ensure that everyone had the
same size specified, and these checks are now removed. Another benefit
that is not yet harnessed is that the cache line size is now known at
construction time, rather than after the port binding. Hence, the
block size can be locally stored and does not have to be queried every
time it is used.

A follow-on patch updates the configuration scripts accordingly.
This commit is contained in:
Andreas Hansson
2013-07-18 08:31:16 -04:00
parent 4e8ecd7c6f
commit d4273cc9a6
44 changed files with 94 additions and 278 deletions

View File

@@ -119,7 +119,7 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
_instMasterId(p->system->getMasterId(name() + ".inst")),
_dataMasterId(p->system->getMasterId(name() + ".data")),
_taskId(ContextSwitchTaskId::Unknown), _pid(Request::invldPid),
_switchedOut(p->switched_out),
_switchedOut(p->switched_out), _cacheLineSize(p->system->cacheLineSize()),
interrupts(p->interrupts), profileEvent(NULL),
numThreads(p->numThreads), system(p->system)
{

View File

@@ -57,12 +57,12 @@
#include "sim/eventq.hh"
#include "sim/full_system.hh"
#include "sim/insttracer.hh"
#include "sim/system.hh"
struct BaseCPUParams;
class BranchPred;
class CheckerCPU;
class ThreadContext;
class System;
class CPUProgressEvent : public Event
{
@@ -117,6 +117,9 @@ class BaseCPU : public MemObject
/** Is the CPU switched out or active? */
bool _switchedOut;
/** Cache the cache line size that we get from the system */
const unsigned int _cacheLineSize;
public:
/**
@@ -342,6 +345,11 @@ class BaseCPU : public MemObject
System *system;
/**
* Get the cache line size of the system.
*/
inline unsigned int cacheLineSize() const { return _cacheLineSize; }
/**
* Serialize this object to the given output stream.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 ARM Limited
* Copyright (c) 2011,2013 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -976,7 +976,7 @@ BaseDynInst<Impl>::splitRequest(RequestPtr req, RequestPtr &sreqLow,
RequestPtr &sreqHigh)
{
// Check to see if the request crosses the next level block boundary.
unsigned block_size = cpu->getDataPort().peerBlockSize();
unsigned block_size = cpu->cacheLineSize();
Addr addr = req->getVaddr();
Addr split_addr = roundDown(addr + req->getSize() - 1, block_size);
assert(split_addr <= addr || split_addr - addr < block_size);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 ARM Limited
* Copyright (c) 2011,2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -142,9 +142,8 @@ Fault
CheckerCPU::readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags)
{
Fault fault = NoFault;
unsigned blockSize = dcachePort->peerBlockSize();
int fullSize = size;
Addr secondAddr = roundDown(addr + size - 1, blockSize);
Addr secondAddr = roundDown(addr + size - 1, cacheLineSize());
bool checked_flags = false;
bool flags_match = true;
Addr pAddr = 0x0;
@@ -236,10 +235,9 @@ CheckerCPU::writeMem(uint8_t *data, unsigned size,
bool flags_match = true;
Addr pAddr = 0x0;
unsigned blockSize = dcachePort->peerBlockSize();
int fullSize = size;
Addr secondAddr = roundDown(addr + size - 1, blockSize);
Addr secondAddr = roundDown(addr + size - 1, cacheLineSize());
if (secondAddr > addr)
size = secondAddr - addr;

View File

@@ -112,7 +112,7 @@ CacheUnit::init()
reqs[i] = new CacheRequest(this);
}
cacheBlkSize = cachePort->peerBlockSize();
cacheBlkSize = cpu->cacheLineSize();
cacheBlkMask = cacheBlkSize - 1;
initSlots();

View File

@@ -216,9 +216,6 @@ class DefaultFetch
/** Initialize stage. */
void startupStage();
/** Tells the fetch stage that the Icache is set. */
void setIcache();
/** Handles retrying the fetch access. */
void recvRetry();
@@ -464,7 +461,7 @@ class DefaultFetch
ThreadID retryTid;
/** Cache block size. */
int cacheBlkSize;
unsigned int cacheBlkSize;
/** Mask to get a cache block's address. */
Addr cacheBlkMask;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2012 ARM Limited
* Copyright (c) 2010-2013 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -81,6 +81,8 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
fetchWidth(params->fetchWidth),
retryPkt(NULL),
retryTid(InvalidThreadID),
cacheBlkSize(cpu->cacheLineSize()),
cacheBlkMask(cacheBlkSize - 1),
numThreads(params->numThreads),
numFetchingThreads(params->smtNumFetchingThreads),
finishTranslationEvent(this)
@@ -126,11 +128,17 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
instSize = sizeof(TheISA::MachInst);
for (int i = 0; i < Impl::MaxThreads; i++) {
cacheData[i] = NULL;
decoder[i] = new TheISA::Decoder;
}
branchPred = params->branchPred;
for (ThreadID tid = 0; tid < numThreads; tid++) {
// Create space to store a cache line.
cacheData[tid] = new uint8_t[cacheBlkSize];
cacheDataPC[tid] = 0;
cacheDataValid[tid] = false;
}
}
template <class Impl>
@@ -336,34 +344,6 @@ DefaultFetch<Impl>::resetStage()
wroteToTimeBuffer = false;
_status = Inactive;
// this CPU could still be unconnected if we are restoring from a
// checkpoint and this CPU is to be switched in, thus we can only
// do this here if the instruction port is actually connected, if
// not we have to do it as part of takeOverFrom.
if (cpu->getInstPort().isConnected())
setIcache();
}
template<class Impl>
void
DefaultFetch<Impl>::setIcache()
{
assert(cpu->getInstPort().isConnected());
// Size of cache block.
cacheBlkSize = cpu->getInstPort().peerBlockSize();
// Create mask to get rid of offset bits.
cacheBlkMask = (cacheBlkSize - 1);
for (ThreadID tid = 0; tid < numThreads; tid++) {
// Create space to store a cache line.
if (!cacheData[tid])
cacheData[tid] = new uint8_t[cacheBlkSize];
cacheDataPC[tid] = 0;
cacheDataValid[tid] = false;
}
}
template<class Impl>

View File

@@ -1,3 +1,4 @@
/*
* Copyright (c) 2010-2012 ARM Limited
* All rights reserved
@@ -190,7 +191,7 @@ LSQUnit<Impl>::resetState()
isLoadBlocked = false;
loadBlockedHandled = false;
cacheBlockMask = 0;
cacheBlockMask = ~(cpu->cacheLineSize() - 1);
}
template<class Impl>
@@ -419,16 +420,6 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
{
int load_idx = loadHead;
if (!cacheBlockMask) {
assert(dcachePort);
Addr bs = dcachePort->peerBlockSize();
// Make sure we actually got a size
assert(bs != 0);
cacheBlockMask = ~(bs - 1);
}
// Unlock the cpu-local monitor when the CPU sees a snoop to a locked
// address. The CPU can speculatively execute a LL operation after a pending
// SC operation in the pipeline and that can make the cache monitor the CPU

View File

@@ -287,14 +287,12 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
traceData->setAddr(addr);
}
//The block size of our peer.
unsigned blockSize = dcachePort.peerBlockSize();
//The size of the data we're trying to read.
int fullSize = size;
//The address of the second part of this access if it needs to be split
//across a cache line boundary.
Addr secondAddr = roundDown(addr + size - 1, blockSize);
Addr secondAddr = roundDown(addr + size - 1, cacheLineSize());
if (secondAddr > addr)
size = secondAddr - addr;
@@ -375,14 +373,12 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
traceData->setAddr(addr);
}
//The block size of our peer.
unsigned blockSize = dcachePort.peerBlockSize();
//The size of the data we're trying to read.
int fullSize = size;
//The address of the second part of this access if it needs to be split
//across a cache line boundary.
Addr secondAddr = roundDown(addr + size - 1, blockSize);
Addr secondAddr = roundDown(addr + size - 1, cacheLineSize());
if(secondAddr > addr)
size = secondAddr - addr;

View File

@@ -404,7 +404,7 @@ TimingSimpleCPU::readMem(Addr addr, uint8_t *data,
const int asid = 0;
const ThreadID tid = 0;
const Addr pc = thread->instAddr();
unsigned block_size = dcachePort.peerBlockSize();
unsigned block_size = cacheLineSize();
BaseTLB::Mode mode = BaseTLB::Read;
if (traceData) {
@@ -473,7 +473,7 @@ TimingSimpleCPU::writeMem(uint8_t *data, unsigned size,
const int asid = 0;
const ThreadID tid = 0;
const Addr pc = thread->instAddr();
unsigned block_size = dcachePort.peerBlockSize();
unsigned block_size = cacheLineSize();
BaseTLB::Mode mode = BaseTLB::Write;
if (traceData) {

View File

@@ -95,7 +95,7 @@ MemTest::MemTest(const Params *p)
tickEvent(this),
cachePort("test", this),
funcPort("functional", this),
funcProxy(funcPort),
funcProxy(funcPort, p->sys->cacheLineSize()),
retryPkt(NULL),
// mainMem(main_mem),
// checkMem(check_mem),
@@ -105,6 +105,7 @@ MemTest::MemTest(const Params *p)
percentUncacheable(p->percent_uncacheable),
issueDmas(p->issue_dmas),
masterId(p->sys->getMasterId(name())),
blockSize(p->sys->cacheLineSize()),
progressInterval(p->progress_interval),
nextProgressMessage(p->progress_interval),
percentSourceUnaligned(p->percent_source_unaligned),
@@ -121,6 +122,9 @@ MemTest::MemTest(const Params *p)
baseAddr2 = 0x400000;
uncacheAddr = 0x800000;
blockAddrMask = blockSize - 1;
traceBlockAddr = blockAddr(traceBlockAddr);
// set up counters
noResponseCycles = 0;
numReads = 0;
@@ -145,11 +149,6 @@ MemTest::getMasterPort(const std::string &if_name, PortID idx)
void
MemTest::init()
{
// By the time init() is called, the ports should be hooked up.
blockSize = cachePort.peerBlockSize();
blockAddrMask = blockSize - 1;
traceBlockAddr = blockAddr(traceBlockAddr);
// initial memory contents for both physical memory and functional
// memory should be 0; no need to initialize them.
}

View File

@@ -268,11 +268,10 @@ TrafficGen::parseConfig()
max_period, read_percent);
if (port.deviceBlockSize() &&
blocksize > port.deviceBlockSize())
if (blocksize > system->cacheLineSize())
fatal("TrafficGen %s block size (%d) is larger than "
"port block size (%d)\n", name(),
blocksize, port.deviceBlockSize());
"system block size (%d)\n", name(),
blocksize, system->cacheLineSize());
if (read_percent > 100)
fatal("%s cannot have more than 100% reads", name());

View File

@@ -110,7 +110,8 @@ ThreadState::initMemProxies(ThreadContext *tc)
// This cannot be done in the constructor as the thread state
// itself is created in the base cpu constructor and the
// getDataPort is a virtual function
physProxy = new PortProxy(baseCpu->getDataPort());
physProxy = new PortProxy(baseCpu->getDataPort(),
baseCpu->cacheLineSize());
assert(virtProxy == NULL);
virtProxy = new FSTranslatingPortProxy(tc);