mem: use single BadAddr responder per system.
Previously there was one per bus, which caused some coherence problems when more than one decided to respond. Now there is just one on the main memory bus. The default bus responder on all other buses is now the downstream cache's cpu_side port. Caches no longer need to do address range filtering; instead, we just have a simple flag to prevent snoops from propagating to the I/O bus.
This commit is contained in:
parent
05d8c9acb8
commit
6629d9b2bc
17 changed files with 92 additions and 94 deletions
|
@ -50,3 +50,4 @@ class IOCache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
size = '1kB'
|
size = '1kB'
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
|
forward_snoops = False
|
||||||
|
|
|
@ -38,6 +38,11 @@ class CowIdeDisk(IdeDisk):
|
||||||
def childImage(self, ci):
|
def childImage(self, ci):
|
||||||
self.image.child.image_file = ci
|
self.image.child.image_file = ci
|
||||||
|
|
||||||
|
class MemBus(Bus):
|
||||||
|
badaddr_responder = BadAddr()
|
||||||
|
default = Self.badaddr_responder.pio
|
||||||
|
|
||||||
|
|
||||||
def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
class BaseTsunami(Tsunami):
|
class BaseTsunami(Tsunami):
|
||||||
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
|
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
|
||||||
|
@ -50,7 +55,7 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
mdesc = SysConfig()
|
mdesc = SysConfig()
|
||||||
self.readfile = mdesc.script()
|
self.readfile = mdesc.script()
|
||||||
self.iobus = Bus(bus_id=0)
|
self.iobus = Bus(bus_id=0)
|
||||||
self.membus = Bus(bus_id=1)
|
self.membus = MemBus(bus_id=1)
|
||||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||||
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()))
|
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()))
|
||||||
self.bridge.side_a = self.iobus.port
|
self.bridge.side_a = self.iobus.port
|
||||||
|
@ -90,7 +95,7 @@ def makeSparcSystem(mem_mode, mdesc = None):
|
||||||
mdesc = SysConfig()
|
mdesc = SysConfig()
|
||||||
self.readfile = mdesc.script()
|
self.readfile = mdesc.script()
|
||||||
self.iobus = Bus(bus_id=0)
|
self.iobus = Bus(bus_id=0)
|
||||||
self.membus = Bus(bus_id=1)
|
self.membus = MemBus(bus_id=1)
|
||||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||||
self.t1000 = T1000()
|
self.t1000 = T1000()
|
||||||
self.t1000.attachOnChipIO(self.membus)
|
self.t1000.attachOnChipIO(self.membus)
|
||||||
|
@ -130,7 +135,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
||||||
mdesc = SysConfig()
|
mdesc = SysConfig()
|
||||||
self.readfile = mdesc.script()
|
self.readfile = mdesc.script()
|
||||||
self.iobus = Bus(bus_id=0)
|
self.iobus = Bus(bus_id=0)
|
||||||
self.membus = Bus(bus_id=1)
|
self.membus = MemBus(bus_id=1)
|
||||||
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
|
||||||
self.physmem = PhysicalMemory(range = AddrRange('1GB'))
|
self.physmem = PhysicalMemory(range = AddrRange('1GB'))
|
||||||
self.bridge.side_a = self.iobus.port
|
self.bridge.side_a = self.iobus.port
|
||||||
|
@ -170,7 +175,7 @@ def makeX86System(mem_mode, mdesc = None, self = None):
|
||||||
self.readfile = mdesc.script()
|
self.readfile = mdesc.script()
|
||||||
|
|
||||||
# Physical memory
|
# Physical memory
|
||||||
self.membus = Bus(bus_id=1)
|
self.membus = MemBus(bus_id=1)
|
||||||
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()))
|
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()))
|
||||||
self.physmem.port = self.membus.port
|
self.physmem.port = self.membus.port
|
||||||
|
|
||||||
|
|
|
@ -126,8 +126,7 @@ test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)]
|
||||||
if options.caches:
|
if options.caches:
|
||||||
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
|
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
|
||||||
test_sys.bridge.filter_ranges_b=[AddrRange(0, size='8GB')]
|
test_sys.bridge.filter_ranges_b=[AddrRange(0, size='8GB')]
|
||||||
test_sys.iocache = IOCache(mem_side_filter_ranges=[AddrRange(0, Addr.max)],
|
test_sys.iocache = IOCache(addr_range=AddrRange(0, size='8GB'))
|
||||||
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)])
|
|
||||||
test_sys.iocache.cpu_side = test_sys.iobus.port
|
test_sys.iocache.cpu_side = test_sys.iobus.port
|
||||||
test_sys.iocache.mem_side = test_sys.membus.port
|
test_sys.iocache.mem_side = test_sys.membus.port
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ class IsaFake(BasicPioDevice):
|
||||||
warn_access = Param.String("", "String to print when device is accessed")
|
warn_access = Param.String("", "String to print when device is accessed")
|
||||||
|
|
||||||
class BadAddr(IsaFake):
|
class BadAddr(IsaFake):
|
||||||
|
pio_addr = 0
|
||||||
ret_bad_addr = Param.Bool(True, "Return pkt status bad address on access")
|
ret_bad_addr = Param.Bool(True, "Return pkt status bad address on access")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,4 @@ class Bus(MemObject):
|
||||||
width = Param.Int(64, "bus width (bytes)")
|
width = Param.Int(64, "bus width (bytes)")
|
||||||
responder_set = Param.Bool(False, "Did the user specify a default responder.")
|
responder_set = Param.Bool(False, "Did the user specify a default responder.")
|
||||||
block_size = Param.Int(64, "The default block size if one isn't set by a device attached to the bus.")
|
block_size = Param.Int(64, "The default block size if one isn't set by a device attached to the bus.")
|
||||||
if build_env['FULL_SYSTEM']:
|
default = Port("Default port for requests that aren't handled by a device.")
|
||||||
responder = BadAddr(pio_addr=0x0, pio_latency="1ps")
|
|
||||||
default = Port(Self.responder.pio, "Default port for requests that aren't handled by a device.")
|
|
||||||
else:
|
|
||||||
default = Port("Default port for requests that aren't handled by a device.")
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ Bus::recvTiming(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(dest >= 0 && dest < maxId);
|
assert(dest < maxId);
|
||||||
assert(dest != src); // catch infinite loops
|
assert(dest != src); // catch infinite loops
|
||||||
dest_port_id = dest;
|
dest_port_id = dest;
|
||||||
if (dest_port_id == defaultId)
|
if (dest_port_id == defaultId)
|
||||||
|
@ -238,7 +238,6 @@ Bus::recvTiming(PacketPtr pkt)
|
||||||
if (dest_port_id == src) {
|
if (dest_port_id == src) {
|
||||||
// Must be forwarded snoop up from below...
|
// Must be forwarded snoop up from below...
|
||||||
assert(dest == Packet::Broadcast);
|
assert(dest == Packet::Broadcast);
|
||||||
assert(src != defaultId); // catch infinite loops
|
|
||||||
} else {
|
} else {
|
||||||
// send to actual target
|
// send to actual target
|
||||||
if (!dest_port->sendTiming(pkt)) {
|
if (!dest_port->sendTiming(pkt)) {
|
||||||
|
|
8
src/mem/cache/BaseCache.py
vendored
8
src/mem/cache/BaseCache.py
vendored
|
@ -45,6 +45,8 @@ class BaseCache(MemObject):
|
||||||
"always service demand misses first")
|
"always service demand misses first")
|
||||||
repl = Param.Repl(NULL, "replacement policy")
|
repl = Param.Repl(NULL, "replacement policy")
|
||||||
size = Param.MemorySize("capacity in bytes")
|
size = Param.MemorySize("capacity in bytes")
|
||||||
|
forward_snoops = Param.Bool(True,
|
||||||
|
"forward snoops from mem side to cpu side")
|
||||||
subblock_size = Param.Int(0,
|
subblock_size = Param.Int(0,
|
||||||
"Size of subblock in IIC used for compression")
|
"Size of subblock in IIC used for compression")
|
||||||
tgts_per_mshr = Param.Int("max number of accesses per MSHR")
|
tgts_per_mshr = Param.Int("max number of accesses per MSHR")
|
||||||
|
@ -74,8 +76,4 @@ class BaseCache(MemObject):
|
||||||
"Only prefetch on data not on instruction accesses")
|
"Only prefetch on data not on instruction accesses")
|
||||||
cpu_side = Port("Port on side closer to CPU")
|
cpu_side = Port("Port on side closer to CPU")
|
||||||
mem_side = Port("Port on side closer to MEM")
|
mem_side = Port("Port on side closer to MEM")
|
||||||
cpu_side_filter_ranges = VectorParam.AddrRange([],
|
addr_range = Param.AddrRange(AllMemory, "The address range for the CPU-side port")
|
||||||
"What addresses shouldn't be passed through the side of the bridge")
|
|
||||||
mem_side_filter_ranges = VectorParam.AddrRange([],
|
|
||||||
"What addresses shouldn't be passed through the side of the bridge")
|
|
||||||
addr_range = VectorParam.AddrRange(AllMemory, "The address range in bytes")
|
|
||||||
|
|
9
src/mem/cache/base.cc
vendored
9
src/mem/cache/base.cc
vendored
|
@ -41,11 +41,10 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
|
BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
|
||||||
const std::string &_label,
|
const std::string &_label)
|
||||||
std::vector<Range<Addr> > filter_ranges)
|
|
||||||
: SimpleTimingPort(_name, _cache), cache(_cache),
|
: SimpleTimingPort(_name, _cache), cache(_cache),
|
||||||
label(_label), otherPort(NULL),
|
label(_label), otherPort(NULL),
|
||||||
blocked(false), mustSendRetry(false), filterRanges(filter_ranges)
|
blocked(false), mustSendRetry(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,10 +57,12 @@ BaseCache::BaseCache(const Params *p)
|
||||||
blkSize(p->block_size),
|
blkSize(p->block_size),
|
||||||
hitLatency(p->latency),
|
hitLatency(p->latency),
|
||||||
numTarget(p->tgts_per_mshr),
|
numTarget(p->tgts_per_mshr),
|
||||||
|
forwardSnoops(p->forward_snoops),
|
||||||
blocked(0),
|
blocked(0),
|
||||||
noTargetMSHR(NULL),
|
noTargetMSHR(NULL),
|
||||||
missCount(p->max_miss_count),
|
missCount(p->max_miss_count),
|
||||||
drainEvent(NULL)
|
drainEvent(NULL),
|
||||||
|
addrRange(p->addr_range)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/mem/cache/base.hh
vendored
20
src/mem/cache/base.hh
vendored
|
@ -100,8 +100,7 @@ class BaseCache : public MemObject
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CachePort(const std::string &_name, BaseCache *_cache,
|
CachePort(const std::string &_name, BaseCache *_cache,
|
||||||
const std::string &_label,
|
const std::string &_label);
|
||||||
std::vector<Range<Addr> > filter_ranges);
|
|
||||||
|
|
||||||
virtual void recvStatusChange(Status status);
|
virtual void recvStatusChange(Status status);
|
||||||
|
|
||||||
|
@ -129,9 +128,6 @@ class BaseCache : public MemObject
|
||||||
|
|
||||||
bool mustSendRetry;
|
bool mustSendRetry;
|
||||||
|
|
||||||
/** filter ranges */
|
|
||||||
std::vector<Range<Addr> > filterRanges;
|
|
||||||
|
|
||||||
void requestBus(RequestCause cause, Tick time)
|
void requestBus(RequestCause cause, Tick time)
|
||||||
{
|
{
|
||||||
DPRINTF(CachePort, "Asserting bus request for cause %d\n", cause);
|
DPRINTF(CachePort, "Asserting bus request for cause %d\n", cause);
|
||||||
|
@ -194,8 +190,8 @@ class BaseCache : public MemObject
|
||||||
/** The number of targets for each MSHR. */
|
/** The number of targets for each MSHR. */
|
||||||
const int numTarget;
|
const int numTarget;
|
||||||
|
|
||||||
/** Increasing order number assigned to each incoming request. */
|
/** Do we forward snoops from mem side port through to cpu side port? */
|
||||||
uint64_t order;
|
bool forwardSnoops;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bit vector of the blocking reasons for the access path.
|
* Bit vector of the blocking reasons for the access path.
|
||||||
|
@ -203,6 +199,9 @@ class BaseCache : public MemObject
|
||||||
*/
|
*/
|
||||||
uint8_t blocked;
|
uint8_t blocked;
|
||||||
|
|
||||||
|
/** Increasing order number assigned to each incoming request. */
|
||||||
|
uint64_t order;
|
||||||
|
|
||||||
/** Stores time the cache blocked for statistics. */
|
/** Stores time the cache blocked for statistics. */
|
||||||
Tick blockedCycle;
|
Tick blockedCycle;
|
||||||
|
|
||||||
|
@ -215,6 +214,11 @@ class BaseCache : public MemObject
|
||||||
/** The drain event. */
|
/** The drain event. */
|
||||||
Event *drainEvent;
|
Event *drainEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The address range to which the cache responds on the CPU side.
|
||||||
|
* Normally this is all possible memory addresses. */
|
||||||
|
Range<Addr> addrRange;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Statistics
|
// Statistics
|
||||||
/**
|
/**
|
||||||
|
@ -377,6 +381,8 @@ class BaseCache : public MemObject
|
||||||
Addr blockAlign(Addr addr) const { return (addr & ~(blkSize - 1)); }
|
Addr blockAlign(Addr addr) const { return (addr & ~(blkSize - 1)); }
|
||||||
|
|
||||||
|
|
||||||
|
const Range<Addr> &getAddrRange() const { return addrRange; }
|
||||||
|
|
||||||
MSHR *allocateMissBuffer(PacketPtr pkt, Tick time, bool requestBus)
|
MSHR *allocateMissBuffer(PacketPtr pkt, Tick time, bool requestBus)
|
||||||
{
|
{
|
||||||
assert(!pkt->req->isUncacheable());
|
assert(!pkt->req->isUncacheable());
|
||||||
|
|
6
src/mem/cache/cache.hh
vendored
6
src/mem/cache/cache.hh
vendored
|
@ -71,8 +71,7 @@ class Cache : public BaseCache
|
||||||
public:
|
public:
|
||||||
CpuSidePort(const std::string &_name,
|
CpuSidePort(const std::string &_name,
|
||||||
Cache<TagStore> *_cache,
|
Cache<TagStore> *_cache,
|
||||||
const std::string &_label,
|
const std::string &_label);
|
||||||
std::vector<Range<Addr> > filterRanges);
|
|
||||||
|
|
||||||
// BaseCache::CachePort just has a BaseCache *; this function
|
// BaseCache::CachePort just has a BaseCache *; this function
|
||||||
// lets us get back the type info we lost when we stored the
|
// lets us get back the type info we lost when we stored the
|
||||||
|
@ -96,8 +95,7 @@ class Cache : public BaseCache
|
||||||
public:
|
public:
|
||||||
MemSidePort(const std::string &_name,
|
MemSidePort(const std::string &_name,
|
||||||
Cache<TagStore> *_cache,
|
Cache<TagStore> *_cache,
|
||||||
const std::string &_label,
|
const std::string &_label);
|
||||||
std::vector<Range<Addr> > filterRanges);
|
|
||||||
|
|
||||||
// BaseCache::CachePort just has a BaseCache *; this function
|
// BaseCache::CachePort just has a BaseCache *; this function
|
||||||
// lets us get back the type info we lost when we stored the
|
// lets us get back the type info we lost when we stored the
|
||||||
|
|
92
src/mem/cache/cache_impl.hh
vendored
92
src/mem/cache/cache_impl.hh
vendored
|
@ -40,7 +40,7 @@
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "base/fast_alloc.hh"
|
#include "base/fast_alloc.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "base/range_ops.hh"
|
#include "base/range.hh"
|
||||||
|
|
||||||
#include "mem/cache/cache.hh"
|
#include "mem/cache/cache.hh"
|
||||||
#include "mem/cache/blk.hh"
|
#include "mem/cache/blk.hh"
|
||||||
|
@ -62,11 +62,9 @@ Cache<TagStore>::Cache(const Params *p, TagStore *tags, BasePrefetcher *pf)
|
||||||
tempBlock->data = new uint8_t[blkSize];
|
tempBlock->data = new uint8_t[blkSize];
|
||||||
|
|
||||||
cpuSidePort = new CpuSidePort(p->name + "-cpu_side_port", this,
|
cpuSidePort = new CpuSidePort(p->name + "-cpu_side_port", this,
|
||||||
"CpuSidePort",
|
"CpuSidePort");
|
||||||
p->cpu_side_filter_ranges);
|
|
||||||
memSidePort = new MemSidePort(p->name + "-mem_side_port", this,
|
memSidePort = new MemSidePort(p->name + "-mem_side_port", this,
|
||||||
"MemSidePort",
|
"MemSidePort");
|
||||||
p->mem_side_filter_ranges);
|
|
||||||
cpuSidePort->setOtherPort(memSidePort);
|
cpuSidePort->setOtherPort(memSidePort);
|
||||||
memSidePort->setOtherPort(cpuSidePort);
|
memSidePort->setOtherPort(cpuSidePort);
|
||||||
|
|
||||||
|
@ -96,8 +94,7 @@ Cache<TagStore>::getPort(const std::string &if_name, int idx)
|
||||||
} else if (if_name == "functional") {
|
} else if (if_name == "functional") {
|
||||||
CpuSidePort *funcPort =
|
CpuSidePort *funcPort =
|
||||||
new CpuSidePort(name() + "-cpu_side_funcport", this,
|
new CpuSidePort(name() + "-cpu_side_funcport", this,
|
||||||
"CpuSideFuncPort",
|
"CpuSideFuncPort");
|
||||||
std::vector<Range<Addr> >());
|
|
||||||
funcPort->setOtherPort(memSidePort);
|
funcPort->setOtherPort(memSidePort);
|
||||||
return funcPort;
|
return funcPort;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1063,35 +1060,37 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
|
||||||
assert(!(pending_inval && !is_deferred));
|
assert(!(pending_inval && !is_deferred));
|
||||||
assert(pkt->isRequest());
|
assert(pkt->isRequest());
|
||||||
|
|
||||||
// first propagate snoop upward to see if anyone above us wants to
|
if (forwardSnoops) {
|
||||||
// handle it. save & restore packet src since it will get
|
// first propagate snoop upward to see if anyone above us wants to
|
||||||
// rewritten to be relative to cpu-side bus (if any)
|
// handle it. save & restore packet src since it will get
|
||||||
bool alreadyResponded = pkt->memInhibitAsserted();
|
// rewritten to be relative to cpu-side bus (if any)
|
||||||
if (is_timing) {
|
bool alreadyResponded = pkt->memInhibitAsserted();
|
||||||
Packet *snoopPkt = new Packet(pkt, true); // clear flags
|
if (is_timing) {
|
||||||
snoopPkt->setExpressSnoop();
|
Packet *snoopPkt = new Packet(pkt, true); // clear flags
|
||||||
snoopPkt->senderState = new ForwardResponseRecord(pkt, this);
|
snoopPkt->setExpressSnoop();
|
||||||
cpuSidePort->sendTiming(snoopPkt);
|
snoopPkt->senderState = new ForwardResponseRecord(pkt, this);
|
||||||
if (snoopPkt->memInhibitAsserted()) {
|
cpuSidePort->sendTiming(snoopPkt);
|
||||||
// cache-to-cache response from some upper cache
|
if (snoopPkt->memInhibitAsserted()) {
|
||||||
assert(!alreadyResponded);
|
// cache-to-cache response from some upper cache
|
||||||
pkt->assertMemInhibit();
|
assert(!alreadyResponded);
|
||||||
|
pkt->assertMemInhibit();
|
||||||
|
} else {
|
||||||
|
delete snoopPkt->senderState;
|
||||||
|
}
|
||||||
|
if (snoopPkt->sharedAsserted()) {
|
||||||
|
pkt->assertShared();
|
||||||
|
}
|
||||||
|
delete snoopPkt;
|
||||||
} else {
|
} else {
|
||||||
delete snoopPkt->senderState;
|
int origSrc = pkt->getSrc();
|
||||||
|
cpuSidePort->sendAtomic(pkt);
|
||||||
|
if (!alreadyResponded && pkt->memInhibitAsserted()) {
|
||||||
|
// cache-to-cache response from some upper cache:
|
||||||
|
// forward response to original requester
|
||||||
|
assert(pkt->isResponse());
|
||||||
|
}
|
||||||
|
pkt->setSrc(origSrc);
|
||||||
}
|
}
|
||||||
if (snoopPkt->sharedAsserted()) {
|
|
||||||
pkt->assertShared();
|
|
||||||
}
|
|
||||||
delete snoopPkt;
|
|
||||||
} else {
|
|
||||||
int origSrc = pkt->getSrc();
|
|
||||||
cpuSidePort->sendAtomic(pkt);
|
|
||||||
if (!alreadyResponded && pkt->memInhibitAsserted()) {
|
|
||||||
// cache-to-cache response from some upper cache:
|
|
||||||
// forward response to original requester
|
|
||||||
assert(pkt->isResponse());
|
|
||||||
}
|
|
||||||
pkt->setSrc(origSrc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!blk || !blk->isValid()) {
|
if (!blk || !blk->isValid()) {
|
||||||
|
@ -1385,11 +1384,10 @@ void
|
||||||
Cache<TagStore>::CpuSidePort::
|
Cache<TagStore>::CpuSidePort::
|
||||||
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
|
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
|
||||||
{
|
{
|
||||||
// CPU side port doesn't snoop; it's a target only.
|
// CPU side port doesn't snoop; it's a target only. It can
|
||||||
bool dummy;
|
// potentially respond to any address.
|
||||||
otherPort->getPeerAddressRanges(resp, dummy);
|
|
||||||
FilterRangeList(filterRanges, resp);
|
|
||||||
snoop = false;
|
snoop = false;
|
||||||
|
resp.push_back(myCache()->getAddrRange());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1428,9 +1426,8 @@ Cache<TagStore>::CpuSidePort::recvFunctional(PacketPtr pkt)
|
||||||
template<class TagStore>
|
template<class TagStore>
|
||||||
Cache<TagStore>::
|
Cache<TagStore>::
|
||||||
CpuSidePort::CpuSidePort(const std::string &_name, Cache<TagStore> *_cache,
|
CpuSidePort::CpuSidePort(const std::string &_name, Cache<TagStore> *_cache,
|
||||||
const std::string &_label,
|
const std::string &_label)
|
||||||
std::vector<Range<Addr> > filterRanges)
|
: BaseCache::CachePort(_name, _cache, _label)
|
||||||
: BaseCache::CachePort(_name, _cache, _label, filterRanges)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,11 +1442,9 @@ void
|
||||||
Cache<TagStore>::MemSidePort::
|
Cache<TagStore>::MemSidePort::
|
||||||
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
|
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
|
||||||
{
|
{
|
||||||
otherPort->getPeerAddressRanges(resp, snoop);
|
// Memory-side port always snoops, but never passes requests
|
||||||
FilterRangeList(filterRanges, resp);
|
// through to targets on the cpu side (so we don't add anything to
|
||||||
|
// the address range list).
|
||||||
// Memory-side port always snoops, so unconditionally set flag for
|
|
||||||
// caller.
|
|
||||||
snoop = true;
|
snoop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1581,9 +1576,8 @@ Cache<TagStore>::MemSidePort::processSendEvent()
|
||||||
template<class TagStore>
|
template<class TagStore>
|
||||||
Cache<TagStore>::
|
Cache<TagStore>::
|
||||||
MemSidePort::MemSidePort(const std::string &_name, Cache<TagStore> *_cache,
|
MemSidePort::MemSidePort(const std::string &_name, Cache<TagStore> *_cache,
|
||||||
const std::string &_label,
|
const std::string &_label)
|
||||||
std::vector<Range<Addr> > filterRanges)
|
: BaseCache::CachePort(_name, _cache, _label)
|
||||||
: BaseCache::CachePort(_name, _cache, _label, filterRanges)
|
|
||||||
{
|
{
|
||||||
// override default send event from SimpleTimingPort
|
// override default send event from SimpleTimingPort
|
||||||
delete sendEvent;
|
delete sendEvent;
|
||||||
|
|
|
@ -63,8 +63,8 @@ class IOCache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
size = '1kB'
|
size = '1kB'
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
mem_side_filter_ranges=[AddrRange(0, Addr.max)]
|
addr_range=AddrRange(0, size='8GB')
|
||||||
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)]
|
forward_snoops = False
|
||||||
|
|
||||||
#cpu
|
#cpu
|
||||||
cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(2) ]
|
cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(2) ]
|
||||||
|
|
|
@ -63,8 +63,8 @@ class IOCache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
size = '1kB'
|
size = '1kB'
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
mem_side_filter_ranges=[AddrRange(0, Addr.max)]
|
addr_range=AddrRange(0, size='8GB')
|
||||||
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)]
|
forward_snoops = False
|
||||||
|
|
||||||
#cpu
|
#cpu
|
||||||
cpu = DerivO3CPU(cpu_id=0)
|
cpu = DerivO3CPU(cpu_id=0)
|
||||||
|
|
|
@ -62,8 +62,8 @@ class IOCache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
size = '1kB'
|
size = '1kB'
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
mem_side_filter_ranges=[AddrRange(0, Addr.max)]
|
addr_range=AddrRange(0, size='8GB')
|
||||||
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)]
|
forward_snoops = False
|
||||||
|
|
||||||
#cpu
|
#cpu
|
||||||
cpus = [ AtomicSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
cpus = [ AtomicSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
||||||
|
|
|
@ -62,8 +62,8 @@ class IOCache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
size = '1kB'
|
size = '1kB'
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
mem_side_filter_ranges=[AddrRange(0, Addr.max)]
|
addr_range=AddrRange(0, size='8GB')
|
||||||
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)]
|
forward_snoops = False
|
||||||
|
|
||||||
#cpu
|
#cpu
|
||||||
cpu = AtomicSimpleCPU(cpu_id=0)
|
cpu = AtomicSimpleCPU(cpu_id=0)
|
||||||
|
|
|
@ -62,8 +62,8 @@ class IOCache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
size = '1kB'
|
size = '1kB'
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
mem_side_filter_ranges=[AddrRange(0, Addr.max)]
|
addr_range=AddrRange(0, size='8GB')
|
||||||
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)]
|
forward_snoops = False
|
||||||
|
|
||||||
#cpu
|
#cpu
|
||||||
cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
||||||
|
|
|
@ -63,8 +63,8 @@ class IOCache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
size = '1kB'
|
size = '1kB'
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
mem_side_filter_ranges=[AddrRange(0, Addr.max)]
|
addr_range=AddrRange(0, size='8GB')
|
||||||
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)]
|
forward_snoops = False
|
||||||
|
|
||||||
#cpu
|
#cpu
|
||||||
cpu = TimingSimpleCPU(cpu_id=0)
|
cpu = TimingSimpleCPU(cpu_id=0)
|
||||||
|
|
Loading…
Reference in a new issue