DMA: Add IOCache and fix bus bridge to optionally only send requests one
way so a cache can handle partial block requests for i/o devices. --HG-- extra : convert_revision : a68b5ae826731bc87ed93eb7ef326a2393053964
This commit is contained in:
parent
5c38668ed6
commit
06a9f58c68
16 changed files with 134 additions and 49 deletions
|
@ -43,3 +43,10 @@ class L2Cache(BaseCache):
|
||||||
mshrs = 20
|
mshrs = 20
|
||||||
tgts_per_mshr = 12
|
tgts_per_mshr = 12
|
||||||
|
|
||||||
|
class IOCache(BaseCache):
|
||||||
|
assoc = 8
|
||||||
|
block_size = 64
|
||||||
|
latency = '10ns'
|
||||||
|
mshrs = 20
|
||||||
|
size = '1kB'
|
||||||
|
tgts_per_mshr = 12
|
||||||
|
|
|
@ -53,7 +53,7 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
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 = Bus(bus_id=1)
|
||||||
self.bridge = Bridge(fix_partial_write_b=True, 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
|
||||||
self.bridge.side_b = self.membus.port
|
self.bridge.side_b = self.membus.port
|
||||||
|
|
|
@ -121,7 +121,12 @@ for i in xrange(np):
|
||||||
if options.caches:
|
if options.caches:
|
||||||
test_sys.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
|
test_sys.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'),
|
||||||
L1Cache(size = '64kB'))
|
L1Cache(size = '64kB'))
|
||||||
|
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
|
||||||
|
test_sys.bridge.filter_ranges_b=[AddrRange(0, size='8GB')]
|
||||||
|
test_sys.iocache = IOCache(mem_side_filter_ranges=[AddrRange(0, Addr.max)],
|
||||||
|
cpu_side_filter_ranges=[AddrRange(0x8000000000, Addr.max)])
|
||||||
|
test_sys.iocache.cpu_side = test_sys.iobus.port
|
||||||
|
test_sys.iocache.mem_side = test_sys.membus.port
|
||||||
if options.l2cache:
|
if options.l2cache:
|
||||||
test_sys.cpu[i].connectMemPorts(test_sys.tol2bus)
|
test_sys.cpu[i].connectMemPorts(test_sys.tol2bus)
|
||||||
else:
|
else:
|
||||||
|
|
55
src/base/range_ops.hh
Normal file
55
src/base/range_ops.hh
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 The Regents of The University of Michigan
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Ali Saidi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BASE_RANGE_OPS_HH__
|
||||||
|
#define __BASE_RANGE_OPS_HH__
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/range.hh"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline void
|
||||||
|
FilterRangeList(std::vector<Range<T> > filter_list, std::list<Range<T> >
|
||||||
|
&range_list) {
|
||||||
|
typename std::list<Range<T> >::iterator i;
|
||||||
|
for (int x = 0; x < filter_list.size(); x++) {
|
||||||
|
for (i = range_list.begin(); i != range_list.end(); ) {
|
||||||
|
// Is the range within one of our filter ranges?
|
||||||
|
if (filter_list[x] == i->start || filter_list[x] == i->end)
|
||||||
|
range_list.erase(i++);
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__BASE_RANGE_OPS_HH__
|
||||||
|
|
|
@ -266,8 +266,7 @@ class DmaDevice : public PioDevice
|
||||||
|
|
||||||
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
|
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
|
||||||
{
|
{
|
||||||
dmaPort->dmaAction(MemCmd::WriteInvalidateReq,
|
dmaPort->dmaAction(MemCmd::WriteReq, addr, size, event, data);
|
||||||
addr, size, event, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmaRead(Addr addr, int size, Event *event, uint8_t *data)
|
void dmaRead(Addr addr, int size, Event *event, uint8_t *data)
|
||||||
|
|
|
@ -40,5 +40,7 @@ class Bridge(MemObject):
|
||||||
delay = Param.Latency('0ns', "The latency of this bridge")
|
delay = Param.Latency('0ns', "The latency of this bridge")
|
||||||
nack_delay = Param.Latency('0ns', "The latency of this bridge")
|
nack_delay = Param.Latency('0ns', "The latency of this bridge")
|
||||||
write_ack = Param.Bool(False, "Should this bridge ack writes")
|
write_ack = Param.Bool(False, "Should this bridge ack writes")
|
||||||
fix_partial_write_a = Param.Bool(False, "Should this bridge fixup partial block writes")
|
filter_ranges_a = VectorParam.AddrRange([],
|
||||||
fix_partial_write_b = Param.Bool(False, "Should this bridge fixup partial block writes")
|
"What addresses shouldn't be passed through the side of the bridge")
|
||||||
|
filter_ranges_b = VectorParam.AddrRange([],
|
||||||
|
"What addresses shouldn't be passed through the side of the bridge")
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "base/range_ops.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "mem/bridge.hh"
|
#include "mem/bridge.hh"
|
||||||
#include "params/Bridge.hh"
|
#include "params/Bridge.hh"
|
||||||
|
@ -44,9 +45,10 @@
|
||||||
Bridge::BridgePort::BridgePort(const std::string &_name,
|
Bridge::BridgePort::BridgePort(const std::string &_name,
|
||||||
Bridge *_bridge, BridgePort *_otherPort,
|
Bridge *_bridge, BridgePort *_otherPort,
|
||||||
int _delay, int _nack_delay, int _req_limit,
|
int _delay, int _nack_delay, int _req_limit,
|
||||||
int _resp_limit, bool fix_partial_write)
|
int _resp_limit,
|
||||||
|
std::vector<Range<Addr> > filter_ranges)
|
||||||
: Port(_name), bridge(_bridge), otherPort(_otherPort),
|
: Port(_name), bridge(_bridge), otherPort(_otherPort),
|
||||||
delay(_delay), nackDelay(_nack_delay), fixPartialWrite(fix_partial_write),
|
delay(_delay), nackDelay(_nack_delay), filterRanges(filter_ranges),
|
||||||
outstandingResponses(0), queuedRequests(0), inRetry(false),
|
outstandingResponses(0), queuedRequests(0), inRetry(false),
|
||||||
reqQueueLimit(_req_limit), respQueueLimit(_resp_limit), sendEvent(this)
|
reqQueueLimit(_req_limit), respQueueLimit(_resp_limit), sendEvent(this)
|
||||||
{
|
{
|
||||||
|
@ -55,9 +57,9 @@ Bridge::BridgePort::BridgePort(const std::string &_name,
|
||||||
Bridge::Bridge(Params *p)
|
Bridge::Bridge(Params *p)
|
||||||
: MemObject(p->name),
|
: MemObject(p->name),
|
||||||
portA(p->name + "-portA", this, &portB, p->delay, p->nack_delay,
|
portA(p->name + "-portA", this, &portB, p->delay, p->nack_delay,
|
||||||
p->req_size_a, p->resp_size_a, p->fix_partial_write_a),
|
p->req_size_a, p->resp_size_a, p->filter_ranges_a),
|
||||||
portB(p->name + "-portB", this, &portA, p->delay, p->nack_delay,
|
portB(p->name + "-portB", this, &portA, p->delay, p->nack_delay,
|
||||||
p->req_size_b, p->resp_size_b, p->fix_partial_write_b),
|
p->req_size_b, p->resp_size_b, p->filter_ranges_b),
|
||||||
ackWrites(p->write_ack), _params(p)
|
ackWrites(p->write_ack), _params(p)
|
||||||
{
|
{
|
||||||
if (ackWrites)
|
if (ackWrites)
|
||||||
|
@ -243,17 +245,6 @@ Bridge::BridgePort::trySend()
|
||||||
|
|
||||||
PacketPtr pkt = buf->pkt;
|
PacketPtr pkt = buf->pkt;
|
||||||
|
|
||||||
// Ugly! @todo When multilevel coherence works this will be removed
|
|
||||||
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite &&
|
|
||||||
!pkt->wasNacked()) {
|
|
||||||
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
|
|
||||||
Packet::Broadcast);
|
|
||||||
funcPkt->dataStatic(pkt->getPtr<uint8_t>());
|
|
||||||
sendFunctional(funcPkt);
|
|
||||||
pkt->cmd = MemCmd::WriteReq;
|
|
||||||
delete funcPkt;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
|
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
|
||||||
buf->origSrc, pkt->getDest(), pkt->getAddr());
|
buf->origSrc, pkt->getDest(), pkt->getAddr());
|
||||||
|
|
||||||
|
@ -313,17 +304,6 @@ Bridge::BridgePort::recvRetry()
|
||||||
Tick
|
Tick
|
||||||
Bridge::BridgePort::recvAtomic(PacketPtr pkt)
|
Bridge::BridgePort::recvAtomic(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
// fix partial atomic writes... similar to the timing code that does the
|
|
||||||
// same... will be removed once our code gets this right
|
|
||||||
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite) {
|
|
||||||
|
|
||||||
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::WriteReq,
|
|
||||||
Packet::Broadcast);
|
|
||||||
funcPkt->dataStatic(pkt->getPtr<uint8_t>());
|
|
||||||
otherPort->sendFunctional(funcPkt);
|
|
||||||
delete funcPkt;
|
|
||||||
pkt->cmd = MemCmd::WriteReq;
|
|
||||||
}
|
|
||||||
return delay + otherPort->sendAtomic(pkt);
|
return delay + otherPort->sendAtomic(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,6 +335,7 @@ Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp,
|
||||||
bool &snoop)
|
bool &snoop)
|
||||||
{
|
{
|
||||||
otherPort->getPeerAddressRanges(resp, snoop);
|
otherPort->getPeerAddressRanges(resp, snoop);
|
||||||
|
FilterRangeList(filterRanges, resp);
|
||||||
// we don't allow snooping across bridges
|
// we don't allow snooping across bridges
|
||||||
snoop = false;
|
snoop = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,8 @@ class Bridge : public MemObject
|
||||||
/** Min delay to respond to a nack. */
|
/** Min delay to respond to a nack. */
|
||||||
Tick nackDelay;
|
Tick nackDelay;
|
||||||
|
|
||||||
bool fixPartialWrite;
|
/** Pass ranges from one side of the bridge to the other? */
|
||||||
|
std::vector<Range<Addr> > filterRanges;
|
||||||
|
|
||||||
class PacketBuffer : public Packet::SenderState {
|
class PacketBuffer : public Packet::SenderState {
|
||||||
|
|
||||||
|
@ -156,7 +157,8 @@ class Bridge : public MemObject
|
||||||
/** Constructor for the BusPort.*/
|
/** Constructor for the BusPort.*/
|
||||||
BridgePort(const std::string &_name, Bridge *_bridge,
|
BridgePort(const std::string &_name, Bridge *_bridge,
|
||||||
BridgePort *_otherPort, int _delay, int _nack_delay,
|
BridgePort *_otherPort, int _delay, int _nack_delay,
|
||||||
int _req_limit, int _resp_limit, bool fix_partial_write);
|
int _req_limit, int _resp_limit,
|
||||||
|
std::vector<Range<Addr> > filter_ranges);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -457,6 +457,10 @@ Bus::recvStatusChange(Port::Status status, int id)
|
||||||
bool snoops;
|
bool snoops;
|
||||||
AddrRangeIter iter;
|
AddrRangeIter iter;
|
||||||
|
|
||||||
|
if (inRecvStatusChange.count(id))
|
||||||
|
return;
|
||||||
|
inRecvStatusChange.insert(id);
|
||||||
|
|
||||||
assert(status == Port::RangeChange &&
|
assert(status == Port::RangeChange &&
|
||||||
"The other statuses need to be implemented.");
|
"The other statuses need to be implemented.");
|
||||||
|
|
||||||
|
@ -524,6 +528,7 @@ Bus::recvStatusChange(Port::Status status, int id)
|
||||||
|
|
||||||
if (id != defaultId && defaultPort)
|
if (id != defaultId && defaultPort)
|
||||||
defaultPort->sendStatusChange(Port::RangeChange);
|
defaultPort->sendStatusChange(Port::RangeChange);
|
||||||
|
inRecvStatusChange.erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#define __MEM_BUS_HH__
|
#define __MEM_BUS_HH__
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <set>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
@ -253,6 +254,7 @@ class Bus : public MemObject
|
||||||
BusFreeEvent busIdle;
|
BusFreeEvent busIdle;
|
||||||
|
|
||||||
bool inRetry;
|
bool inRetry;
|
||||||
|
std::set<int> inRecvStatusChange;
|
||||||
|
|
||||||
/** max number of bus ids we've handed out so far */
|
/** max number of bus ids we've handed out so far */
|
||||||
short maxId;
|
short maxId;
|
||||||
|
|
4
src/mem/cache/BaseCache.py
vendored
4
src/mem/cache/BaseCache.py
vendored
|
@ -81,4 +81,8 @@ 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([],
|
||||||
|
"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")
|
addr_range = VectorParam.AddrRange(AllMemory, "The address range in bytes")
|
||||||
|
|
5
src/mem/cache/base_cache.cc
vendored
5
src/mem/cache/base_cache.cc
vendored
|
@ -40,9 +40,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,
|
||||||
|
std::vector<Range<Addr> > filter_ranges)
|
||||||
: SimpleTimingPort(_name, _cache), cache(_cache), otherPort(NULL),
|
: SimpleTimingPort(_name, _cache), cache(_cache), otherPort(NULL),
|
||||||
blocked(false), mustSendRetry(false)
|
blocked(false), mustSendRetry(false), filterRanges(filter_ranges)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/mem/cache/base_cache.hh
vendored
16
src/mem/cache/base_cache.hh
vendored
|
@ -98,7 +98,8 @@ class BaseCache : public MemObject
|
||||||
BaseCache *cache;
|
BaseCache *cache;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CachePort(const std::string &_name, BaseCache *_cache);
|
CachePort(const std::string &_name, BaseCache *_cache,
|
||||||
|
std::vector<Range<Addr> > filter_ranges);
|
||||||
|
|
||||||
virtual void recvStatusChange(Status status);
|
virtual void recvStatusChange(Status status);
|
||||||
|
|
||||||
|
@ -124,6 +125,9 @@ 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);
|
||||||
|
@ -367,15 +371,21 @@ class BaseCache : public MemObject
|
||||||
*/
|
*/
|
||||||
Counter maxMisses;
|
Counter maxMisses;
|
||||||
|
|
||||||
|
std::vector<Range<Addr> > cpuSideFilterRanges;
|
||||||
|
std::vector<Range<Addr> > memSideFilterRanges;
|
||||||
/**
|
/**
|
||||||
* Construct an instance of this parameter class.
|
* Construct an instance of this parameter class.
|
||||||
*/
|
*/
|
||||||
Params(int _hitLatency, int _blkSize,
|
Params(int _hitLatency, int _blkSize,
|
||||||
int _numMSHRs, int _numTargets, int _numWriteBuffers,
|
int _numMSHRs, int _numTargets, int _numWriteBuffers,
|
||||||
Counter _maxMisses)
|
Counter _maxMisses,
|
||||||
|
std::vector<Range<Addr> > cpu_side_filter_ranges,
|
||||||
|
std::vector<Range<Addr> > mem_side_filter_ranges)
|
||||||
: hitLatency(_hitLatency), blkSize(_blkSize),
|
: hitLatency(_hitLatency), blkSize(_blkSize),
|
||||||
numMSHRs(_numMSHRs), numTargets(_numTargets),
|
numMSHRs(_numMSHRs), numTargets(_numTargets),
|
||||||
numWriteBuffers(_numWriteBuffers), maxMisses(_maxMisses)
|
numWriteBuffers(_numWriteBuffers), maxMisses(_maxMisses),
|
||||||
|
cpuSideFilterRanges(cpu_side_filter_ranges),
|
||||||
|
memSideFilterRanges(mem_side_filter_ranges)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
6
src/mem/cache/cache.hh
vendored
6
src/mem/cache/cache.hh
vendored
|
@ -72,7 +72,8 @@ class Cache : public BaseCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CpuSidePort(const std::string &_name,
|
CpuSidePort(const std::string &_name,
|
||||||
Cache<TagStore> *_cache);
|
Cache<TagStore> *_cache,
|
||||||
|
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
|
||||||
|
@ -95,7 +96,8 @@ class Cache : public BaseCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemSidePort(const std::string &_name,
|
MemSidePort(const std::string &_name,
|
||||||
Cache<TagStore> *_cache);
|
Cache<TagStore> *_cache,
|
||||||
|
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
|
||||||
|
|
3
src/mem/cache/cache_builder.cc
vendored
3
src/mem/cache/cache_builder.cc
vendored
|
@ -241,7 +241,8 @@ BaseCacheParams::create()
|
||||||
// Build BaseCache param object
|
// Build BaseCache param object
|
||||||
BaseCache::Params base_params(latency, block_size,
|
BaseCache::Params base_params(latency, block_size,
|
||||||
mshrs, tgts_per_mshr, write_buffers,
|
mshrs, tgts_per_mshr, write_buffers,
|
||||||
max_miss_count);
|
max_miss_count, cpu_side_filter_ranges,
|
||||||
|
mem_side_filter_ranges);
|
||||||
|
|
||||||
//Warnings about prefetcher policy
|
//Warnings about prefetcher policy
|
||||||
if (prefetch_policy == Enums::none) {
|
if (prefetch_policy == Enums::none) {
|
||||||
|
|
23
src/mem/cache/cache_impl.hh
vendored
23
src/mem/cache/cache_impl.hh
vendored
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
#include "base/range_ops.hh"
|
||||||
|
|
||||||
#include "mem/cache/cache.hh"
|
#include "mem/cache/cache.hh"
|
||||||
#include "mem/cache/cache_blk.hh"
|
#include "mem/cache/cache_blk.hh"
|
||||||
|
@ -61,8 +62,10 @@ Cache<TagStore>::Cache(const std::string &_name,
|
||||||
tempBlock = new BlkType();
|
tempBlock = new BlkType();
|
||||||
tempBlock->data = new uint8_t[blkSize];
|
tempBlock->data = new uint8_t[blkSize];
|
||||||
|
|
||||||
cpuSidePort = new CpuSidePort(_name + "-cpu_side_port", this);
|
cpuSidePort = new CpuSidePort(_name + "-cpu_side_port", this,
|
||||||
memSidePort = new MemSidePort(_name + "-mem_side_port", this);
|
params.baseParams.cpuSideFilterRanges);
|
||||||
|
memSidePort = new MemSidePort(_name + "-mem_side_port", this,
|
||||||
|
params.baseParams.memSideFilterRanges);
|
||||||
cpuSidePort->setOtherPort(memSidePort);
|
cpuSidePort->setOtherPort(memSidePort);
|
||||||
memSidePort->setOtherPort(cpuSidePort);
|
memSidePort->setOtherPort(cpuSidePort);
|
||||||
|
|
||||||
|
@ -88,7 +91,8 @@ Cache<TagStore>::getPort(const std::string &if_name, int idx)
|
||||||
} else if (if_name == "mem_side") {
|
} else if (if_name == "mem_side") {
|
||||||
return memSidePort;
|
return memSidePort;
|
||||||
} else if (if_name == "functional") {
|
} else if (if_name == "functional") {
|
||||||
return new CpuSidePort(name() + "-cpu_side_funcport", this);
|
return new CpuSidePort(name() + "-cpu_side_funcport", this,
|
||||||
|
std::vector<Range<Addr> >());
|
||||||
} else {
|
} else {
|
||||||
panic("Port name %s unrecognized\n", if_name);
|
panic("Port name %s unrecognized\n", if_name);
|
||||||
}
|
}
|
||||||
|
@ -1221,6 +1225,7 @@ 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.
|
||||||
bool dummy;
|
bool dummy;
|
||||||
otherPort->getPeerAddressRanges(resp, dummy);
|
otherPort->getPeerAddressRanges(resp, dummy);
|
||||||
|
FilterRangeList(filterRanges, resp);
|
||||||
snoop = false;
|
snoop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1262,8 +1267,9 @@ Cache<TagStore>::CpuSidePort::recvFunctional(PacketPtr pkt)
|
||||||
template<class TagStore>
|
template<class TagStore>
|
||||||
Cache<TagStore>::
|
Cache<TagStore>::
|
||||||
CpuSidePort::CpuSidePort(const std::string &_name,
|
CpuSidePort::CpuSidePort(const std::string &_name,
|
||||||
Cache<TagStore> *_cache)
|
Cache<TagStore> *_cache, std::vector<Range<Addr> >
|
||||||
: BaseCache::CachePort(_name, _cache)
|
filterRanges)
|
||||||
|
: BaseCache::CachePort(_name, _cache, filterRanges)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1279,6 +1285,8 @@ Cache<TagStore>::MemSidePort::
|
||||||
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
|
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
|
||||||
{
|
{
|
||||||
otherPort->getPeerAddressRanges(resp, snoop);
|
otherPort->getPeerAddressRanges(resp, snoop);
|
||||||
|
FilterRangeList(filterRanges, resp);
|
||||||
|
|
||||||
// Memory-side port always snoops, so unconditionally set flag for
|
// Memory-side port always snoops, so unconditionally set flag for
|
||||||
// caller.
|
// caller.
|
||||||
snoop = true;
|
snoop = true;
|
||||||
|
@ -1416,8 +1424,9 @@ 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,
|
||||||
: BaseCache::CachePort(_name, _cache)
|
std::vector<Range<Addr> > filterRanges)
|
||||||
|
: BaseCache::CachePort(_name, _cache, filterRanges)
|
||||||
{
|
{
|
||||||
// override default send event from SimpleTimingPort
|
// override default send event from SimpleTimingPort
|
||||||
delete sendEvent;
|
delete sendEvent;
|
||||||
|
|
Loading…
Reference in a new issue