diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2012-01-17 12:55:09 -0600 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2012-01-17 12:55:09 -0600 |
commit | 07cf9d914b292008ead7021182ec2ef8fc4671f1 (patch) | |
tree | f99ab26383bcdde2f8761af1e75a431d7a84c634 /src | |
parent | 142380a373e28cd61b79d348361ec1ed4ed330e5 (diff) | |
download | gem5-07cf9d914b292008ead7021182ec2ef8fc4671f1.tar.xz |
MEM: Separate queries for snooping and address ranges
This patch simplifies the address-range determination mechanism and
also unifies the naming across ports and devices. It further splits
the queries for determining if a port is snooping and what address
ranges it responds to (aiming towards a separation of
cache-maintenance ports and pure memory-mapped ports). Default
behaviours are such that most ports do not have to define isSnooping,
and master ports need not implement getAddrRanges.
Diffstat (limited to 'src')
54 files changed, 345 insertions, 416 deletions
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 7d6f6e35e..9944f4afd 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -353,25 +353,27 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt) } -void -X86ISA::Interrupts::addressRanges(AddrRangeList &range_list) +AddrRangeList +X86ISA::Interrupts::getAddrRanges() { - range_list.clear(); + AddrRangeList ranges; Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0), x86LocalAPICAddress(initialApicId, 0) + PageBytes); - range_list.push_back(range); + ranges.push_back(range); pioAddr = range.start; + return ranges; } -void -X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list) +AddrRangeList +X86ISA::Interrupts::getIntAddrRange() { - range_list.clear(); - range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0), - x86InterruptAddress(initialApicId, 0) + - PhysAddrAPICRangeSize)); + AddrRangeList ranges; + ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0), + x86InterruptAddress(initialApicId, 0) + + PhysAddrAPICRangeSize)); + return ranges; } diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index f5d86219b..6cf50e2fe 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -217,8 +217,8 @@ class Interrupts : public BasicPioDevice, IntDev return entry.periodic; } - void addressRanges(AddrRangeList &range_list); - void getIntAddrRange(AddrRangeList &range_list); + AddrRangeList getAddrRanges(); + AddrRangeList getIntAddrRange(); Port *getPort(const std::string &if_name, int idx = -1) { diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index c80fe10fc..5b1730f0c 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -154,17 +154,8 @@ Walker::WalkerPort::recvFunctional(PacketPtr pkt) } void -Walker::WalkerPort::recvStatusChange(Status status) +Walker::WalkerPort::recvRangeChange() { - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("Unexpected recvStatusChange.\n"); } void diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index b0edc434f..73e185148 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -63,26 +63,18 @@ namespace X86ISA { public: WalkerPort(const std::string &_name, Walker * _walker) : - Port(_name, _walker), walker(_walker), - snoopRangeSent(false) + Port(_name, _walker), walker(_walker) {} protected: Walker * walker; - bool snoopRangeSent; - bool recvTiming(PacketPtr pkt); Tick recvAtomic(PacketPtr pkt); void recvFunctional(PacketPtr pkt); - void recvStatusChange(Status status); + void recvRangeChange(); void recvRetry(); - void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { - resp.clear(); - snoop = true; - } + bool isSnooping() { return true; } }; friend class WalkerPort; diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 2fe41cd4d..370be7ee1 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -527,23 +527,6 @@ BaseCPU::CpuPort::recvFunctional(PacketPtr pkt) } void -BaseCPU::CpuPort::recvStatusChange(Status status) +BaseCPU::CpuPort::recvRangeChange() { - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("BaseCPU doesn't expect recvStatusChange callback!"); -} - -void -BaseCPU::CpuPort::getDeviceAddressRanges(AddrRangeList& resp, - bool& snoop) -{ - resp.clear(); - snoop = false; } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 5622031f8..d4de55453 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -126,7 +126,7 @@ class BaseCPU : public MemObject * @param _name structural owner of this port */ CpuPort(const std::string& _name, MemObject* _owner) : - Port(_name, _owner), snoopRangeSent(false) + Port(_name, _owner) { } protected: @@ -139,22 +139,7 @@ class BaseCPU : public MemObject void recvFunctional(PacketPtr pkt); - void recvStatusChange(Status status); - - /** - * Add CPU ports are master ports and do not respond to any - * address ranges. Note that the LSQ snoops for specific ISAs - * and thus has to override this method. - * - * @param resp list of ranges this port responds to - * @param snoop indicating if the port snoops or not - */ - virtual void getDeviceAddressRanges(AddrRangeList& resp, - bool& snoop); - - private: - - bool snoopRangeSent; + void recvRangeChange(); }; diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 7fcab6893..856675e05 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -82,17 +82,8 @@ CacheUnit::CachePort::recvFunctional(PacketPtr pkt) } void -CacheUnit::CachePort::recvStatusChange(Status status) +CacheUnit::CachePort::recvRangeChange() { - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("CacheUnit::CachePort doesn't expect recvStatusChange callback!"); } bool diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh index 78eff9991..6ca300163 100644 --- a/src/cpu/inorder/resources/cache_unit.hh +++ b/src/cpu/inorder/resources/cache_unit.hh @@ -90,11 +90,9 @@ class CacheUnit : public Resource CachePort(CacheUnit *_cachePortUnit) : Port(_cachePortUnit->name() + "-cache-port", (MemObject*)_cachePortUnit->cpu), - cachePortUnit(_cachePortUnit), snoopRangeSent(false) + cachePortUnit(_cachePortUnit) { } - bool snoopRangeSent; - protected: /** Atomic version of receive. Panics. */ Tick recvAtomic(PacketPtr pkt); @@ -102,13 +100,8 @@ class CacheUnit : public Resource /** Functional version of receive.*/ void recvFunctional(PacketPtr pkt); - /** Receives status change. Other than range changing, panics. */ - void recvStatusChange(Status status); - - /** Returns the address ranges of this device. */ - void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = true; } + /** Receives range changes. */ + void recvRangeChange(); /** Timing version of receive */ bool recvTiming(PacketPtr pkt); diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 1dd49a4f3..121253475 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -186,12 +186,10 @@ class FullO3CPU : public BaseO3CPU * As this CPU requires snooping to maintain the load store queue * change the behaviour from the base CPU port. * - * @param resp list of ranges this port responds to - * @param snoop indicating if the port snoops or not + * @return true since we have to snoop */ - virtual void getDeviceAddressRanges(AddrRangeList& resp, - bool& snoop) - { resp.clear(); snoop = true; } + virtual bool isSnooping() + { return true; } }; class TickEvent : public Event diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh index 1d200ef7d..41b86aab8 100644 --- a/src/cpu/ozone/front_end.hh +++ b/src/cpu/ozone/front_end.hh @@ -87,13 +87,8 @@ class FrontEnd /** Functional version of receive. Panics. */ virtual void recvFunctional(PacketPtr pkt); - /** Receives status change. Other than range changing, panics. */ - virtual void recvStatusChange(Status status); - - /** Returns the address ranges of this device. */ - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = true; } + /** Receives range change. */ + virtual void recvRangeChange(); /** Timing version of receive. Handles setting fetch to the * proper status to start fetching. */ diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 5d8919d4e..a11cf74bd 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -64,12 +64,8 @@ FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt) template<class Impl> void -FrontEnd<Impl>::IcachePort::recvStatusChange(Status status) +FrontEnd<Impl>::IcachePort::recvRangeChange() { - if (status == RangeChange) - return; - - panic("FrontEnd doesn't expect recvStatusChange callback!"); } template<class Impl> diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index 4817622f5..1add13894 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -256,11 +256,13 @@ class OzoneLWLSQ { virtual void recvFunctional(PacketPtr pkt); - virtual void recvStatusChange(Status status); + virtual void recvRangeChange(); - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = true; } + /** + * Is a snooper due to LSQ maintenance + */ + virtual bool isSnooping() + { return true; } virtual bool recvTiming(PacketPtr pkt); diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh index 3bee83176..811d66567 100644 --- a/src/cpu/ozone/lw_lsq_impl.hh +++ b/src/cpu/ozone/lw_lsq_impl.hh @@ -77,12 +77,8 @@ OzoneLWLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt) template <class Impl> void -OzoneLWLSQ<Impl>::DcachePort::recvStatusChange(Status status) +OzoneLWLSQ<Impl>::DcachePort::recvRangeChange() { - if (status == RangeChange) - return; - - panic("O3CPU doesn't expect recvStatusChange callback!"); } template <class Impl> diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 84f42da08..425c8b1f1 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -96,9 +96,7 @@ AtomicSimpleCPU::init() tcBase()->initMemProxies(tcBase()); #endif if (hasPhysMemPort) { - bool snoop = false; - AddrRangeList pmAddrList; - physmemPort.getPeerAddressRanges(pmAddrList, snoop); + AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges(); physMemAddr = *pmAddrList.begin(); } // Atomic doesn't do MT right now, so contextId == threadId diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc index ef23825cd..d70dc96e6 100644 --- a/src/cpu/testers/memtest/memtest.cc +++ b/src/cpu/testers/memtest/memtest.cc @@ -84,17 +84,8 @@ MemTest::CpuPort::recvFunctional(PacketPtr pkt) } void -MemTest::CpuPort::recvStatusChange(Status status) +MemTest::CpuPort::recvRangeChange() { - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("MemTest doesn't expect recvStatusChange callback!"); } void @@ -149,9 +140,6 @@ MemTest::MemTest(const Params *p) atomic(p->atomic), suppress_func_warnings(p->suppress_func_warnings) { - cachePort.snoopRangeSent = false; - funcPort.snoopRangeSent = true; - id = TESTER_ALLOCATOR++; // Needs to be masked off once we know the block size. diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh index 292e7d83d..1a59914fd 100644 --- a/src/cpu/testers/memtest/memtest.hh +++ b/src/cpu/testers/memtest/memtest.hh @@ -93,8 +93,6 @@ class MemTest : public MemObject : Port(_name, _memtest), memtest(_memtest) { } - bool snoopRangeSent; - protected: virtual bool recvTiming(PacketPtr pkt); @@ -103,20 +101,14 @@ class MemTest : public MemObject virtual void recvFunctional(PacketPtr pkt); - virtual void recvStatusChange(Status status); + virtual void recvRangeChange(); virtual void recvRetry(); - - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = false; } }; CpuPort cachePort; CpuPort funcPort; - bool snoopRangeSent; - class MemTestSenderState : public Packet::SenderState, public FastAlloc { public: diff --git a/src/cpu/testers/networktest/networktest.cc b/src/cpu/testers/networktest/networktest.cc index d78f976be..56fcc46c4 100644 --- a/src/cpu/testers/networktest/networktest.cc +++ b/src/cpu/testers/networktest/networktest.cc @@ -81,17 +81,8 @@ NetworkTest::CpuPort::recvFunctional(PacketPtr pkt) } void -NetworkTest::CpuPort::recvStatusChange(Status status) +NetworkTest::CpuPort::recvRangeChange() { - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("NetworkTest doesn't expect recvStatusChange callback!"); } void @@ -124,8 +115,6 @@ NetworkTest::NetworkTest(const Params *p) injRate(p->inj_rate), precision(p->precision) { - cachePort.snoopRangeSent = false; - // set up counters noResponseCycles = 0; schedule(tickEvent, 0); diff --git a/src/cpu/testers/networktest/networktest.hh b/src/cpu/testers/networktest/networktest.hh index 6d9d1edad..c277cfbab 100644 --- a/src/cpu/testers/networktest/networktest.hh +++ b/src/cpu/testers/networktest/networktest.hh @@ -89,8 +89,6 @@ class NetworkTest : public MemObject : Port(_name, _networktest), networktest(_networktest) { } - bool snoopRangeSent; - protected: virtual bool recvTiming(PacketPtr pkt); @@ -99,19 +97,13 @@ class NetworkTest : public MemObject virtual void recvFunctional(PacketPtr pkt); - virtual void recvStatusChange(Status status); + virtual void recvRangeChange(); virtual void recvRetry(); - - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = false; } }; CpuPort cachePort; - bool snoopRangeSent; - class NetworkTestSenderState : public Packet::SenderState, public FastAlloc { public: diff --git a/src/dev/arm/gic.cc b/src/dev/arm/gic.cc index 2dac18c08..4c45760b8 100644 --- a/src/dev/arm/gic.cc +++ b/src/dev/arm/gic.cc @@ -703,12 +703,13 @@ Gic::postInt(uint32_t cpu, Tick when) eventq->schedule(postIntEvent[cpu], when); } -void -Gic::addressRanges(AddrRangeList &range_list) +AddrRangeList +Gic::getAddrRanges() { - range_list.clear(); - range_list.push_back(RangeSize(distAddr, DIST_SIZE)); - range_list.push_back(RangeSize(cpuAddr, CPU_SIZE)); + AddrRangeList ranges; + ranges.push_back(RangeSize(distAddr, DIST_SIZE)); + ranges.push_back(RangeSize(cpuAddr, CPU_SIZE)); + return ranges; } diff --git a/src/dev/arm/gic.hh b/src/dev/arm/gic.hh index 4c43db660..6e3f12cdb 100644 --- a/src/dev/arm/gic.hh +++ b/src/dev/arm/gic.hh @@ -259,7 +259,7 @@ class Gic : public PioDevice /** Return the address ranges used by the Gic * This is the distributor address + all cpu addresses */ - virtual void addressRanges(AddrRangeList &range_list); + virtual AddrRangeList getAddrRanges(); /** A PIO read to the device, immediately split up into * readDistributor() or readCpu() diff --git a/src/dev/arm/pl111.cc b/src/dev/arm/pl111.cc index 958f07aa7..263a3b620 100644 --- a/src/dev/arm/pl111.cc +++ b/src/dev/arm/pl111.cc @@ -735,11 +735,12 @@ Pl111::generateInterrupt() } } -void -Pl111::addressRanges(AddrRangeList& range_list) +AddrRangeList +Pl111::getAddrRanges() { - range_list.clear(); - range_list.push_back(RangeSize(pioAddr, pioSize)); + AddrRangeList ranges; + ranges.push_back(RangeSize(pioAddr, pioSize)); + return ranges; } Pl111 * diff --git a/src/dev/arm/pl111.hh b/src/dev/arm/pl111.hh index f36dc6810..b2dc1f640 100644 --- a/src/dev/arm/pl111.hh +++ b/src/dev/arm/pl111.hh @@ -325,10 +325,12 @@ class Pl111: public AmbaDmaDevice virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); - /** return the address ranges that this device responds to. - * @param range_list range list to populate with ranges + /** + * Determine the address ranges that this device responds to. + * + * @return a list of non-overlapping address ranges */ - void addressRanges(AddrRangeList &range_list); + AddrRangeList getAddrRanges(); }; #endif diff --git a/src/dev/copy_engine.hh b/src/dev/copy_engine.hh index dfe469588..581d3c80b 100644 --- a/src/dev/copy_engine.hh +++ b/src/dev/copy_engine.hh @@ -85,7 +85,6 @@ class CopyEngine : public PciDev void init(); std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); } - virtual void addressRanges(AddrRangeList &range_list) { range_list.clear(); } virtual Tick read(PacketPtr pkt) { panic("CopyEngineChannel has no I/O access\n");} virtual Tick write(PacketPtr pkt) diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 9b7b6ec50..6cb7bbed7 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -47,13 +47,10 @@ PioPort::recvAtomic(PacketPtr pkt) return pkt->isRead() ? device->read(pkt) : device->write(pkt); } -void -PioPort::getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) +AddrRangeList +PioPort::getAddrRanges() { - snoop = false; - device->addressRanges(resp); - for (AddrRangeIter i = resp.begin(); i != resp.end(); i++) - DPRINTF(BusAddrRanges, "Adding Range %#x-%#x\n", i->start, i->end); + return device->getAddrRanges(); } @@ -72,7 +69,7 @@ PioDevice::init() { if (!pioPort) panic("Pio port of %s not connected to anything!", name()); - pioPort->sendStatusChange(Port::RangeChange); + pioPort->sendRangeChange(); } Port * @@ -105,13 +102,14 @@ BasicPioDevice::BasicPioDevice(const Params *p) pioDelay(p->pio_latency) {} -void -BasicPioDevice::addressRanges(AddrRangeList &range_list) +AddrRangeList +BasicPioDevice::getAddrRanges() { assert(pioSize != 0); - range_list.clear(); + AddrRangeList ranges; DPRINTF(BusAddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize); - range_list.push_back(RangeSize(pioAddr, pioSize)); + ranges.push_back(RangeSize(pioAddr, pioSize)); + return ranges; } @@ -121,7 +119,7 @@ DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff, pendingCount(0), actionInProgress(0), drainEvent(NULL), backoffTime(0), minBackoffDelay(min_backoff), maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops), - snoopRangeSent(false), backoffEvent(this) + backoffEvent(this) { } bool diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index 36787c13e..45fd385b9 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -51,7 +51,7 @@ class System; * The PioPort class is a programmed i/o port that all devices that are * sensitive to an address range use. The port takes all the memory * access types and roles them into one read() and write() call that the device - * must respond to. The device must also provide the addressRanges() function + * must respond to. The device must also provide getAddrRanges() function * with which it returns the address ranges it is interested in. */ class PioPort : public SimpleTimingPort @@ -62,8 +62,7 @@ class PioPort : public SimpleTimingPort virtual Tick recvAtomic(PacketPtr pkt); - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual AddrRangeList getAddrRanges(); public: @@ -133,9 +132,6 @@ class DmaPort : public Port /** Port accesses a cache which requires snooping */ bool recvSnoops; - /** Records snoop response so we only reply once to a status change */ - bool snoopRangeSent; - virtual bool recvTiming(PacketPtr pkt); virtual Tick recvAtomic(PacketPtr pkt) { @@ -150,25 +146,16 @@ class DmaPort : public Port panic("dma port shouldn't be used for pio access."); } - virtual void recvStatusChange(Status status) + virtual void recvRangeChange() { - if (recvSnoops) { - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - panic("Unexpected recvStatusChange\n"); - } + // DMA port is a master with a single slave so there is no choice and + // thus no need to worry about any address changes } virtual void recvRetry() ; - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = recvSnoops; } + virtual bool isSnooping() + { return recvSnoops; } void queueDma(PacketPtr pkt, bool front = false); void sendDma(); @@ -192,7 +179,7 @@ class DmaPort : public Port /** * This device is the base class which all devices senstive to an address range * inherit from. There are three pure virtual functions which all devices must - * implement addressRanges(), read(), and write(). The magic do choose which + * implement getAddrRanges(), read(), and write(). The magic do choose which * mode we are in, etc is handled by the PioPort so the device doesn't have to * bother. */ @@ -210,7 +197,13 @@ class PioDevice : public MemObject * that it sees. */ PioPort *pioPort; - virtual void addressRanges(AddrRangeList &range_list) = 0; + /** + * Every PIO device is obliged to provide an implementation that + * returns the address ranges the device responds to. + * + * @return a list of non-overlapping address ranges + */ + virtual AddrRangeList getAddrRanges() = 0; /** Pure virtual function that the device must implement. Called * when a read command is recieved by the port. @@ -269,10 +262,12 @@ class BasicPioDevice : public PioDevice return dynamic_cast<const Params *>(_params); } - /** return the address ranges that this device responds to. - * @param range_list range list to populate with ranges + /** + * Determine the address ranges that this device responds to. + * + * @return a list of non-overlapping address ranges */ - void addressRanges(AddrRangeList &range_list); + virtual AddrRangeList getAddrRanges(); }; diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc index 55b439857..e7130e11d 100644 --- a/src/dev/pciconfigall.cc +++ b/src/dev/pciconfigall.cc @@ -86,11 +86,12 @@ PciConfigAll::write(PacketPtr pkt) } -void -PciConfigAll::addressRanges(AddrRangeList &range_list) +AddrRangeList +PciConfigAll::getAddrRanges() { - range_list.clear(); - range_list.push_back(RangeSize(pioAddr, params()->size)); + AddrRangeList ranges; + ranges.push_back(RangeSize(pioAddr, params()->size)); + return ranges; } diff --git a/src/dev/pciconfigall.hh b/src/dev/pciconfigall.hh index b3f6d1472..e594838fa 100644 --- a/src/dev/pciconfigall.hh +++ b/src/dev/pciconfigall.hh @@ -80,7 +80,7 @@ class PciConfigAll : public PioDevice virtual Tick write(PacketPtr pkt); - void addressRanges(AddrRangeList &range_list); + AddrRangeList getAddrRanges(); private: Addr pioAddr; diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index 2c7d50e83..c36ac11ba 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -72,13 +72,13 @@ PciDev::PciConfigPort::recvAtomic(PacketPtr pkt) return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt); } -void -PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) +AddrRangeList +PciDev::PciConfigPort::getAddrRanges() { - snoop = false;; + AddrRangeList ranges; if (configAddr != ULL(-1)) - resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1)); + ranges.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1)); + return ranges; } @@ -152,7 +152,7 @@ PciDev::init() { if (!configPort) panic("pci config port not connected to anything!"); - configPort->sendStatusChange(Port::RangeChange); + configPort->sendRangeChange(); PioDevice::init(); } @@ -207,14 +207,15 @@ PciDev::readConfig(PacketPtr pkt) } -void -PciDev::addressRanges(AddrRangeList &range_list) +AddrRangeList +PciDev::getAddrRanges() { + AddrRangeList ranges; int x = 0; - range_list.clear(); for (x = 0; x < 6; x++) if (BARAddrs[x] != 0) - range_list.push_back(RangeSize(BARAddrs[x],BARSize[x])); + ranges.push_back(RangeSize(BARAddrs[x],BARSize[x])); + return ranges; } Tick @@ -301,7 +302,7 @@ PciDev::writeConfig(PacketPtr pkt) BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ? platform->calcPciIOAddr(he_new_bar) : platform->calcPciMemAddr(he_new_bar); - pioPort->sendStatusChange(Port::RangeChange); + pioPort->sendRangeChange(); } } config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) | @@ -354,7 +355,7 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0])); UNSERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0])); - pioPort->sendStatusChange(Port::RangeChange); + pioPort->sendRangeChange(); } diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh index 5da8b2dfc..4c3ecc594 100644 --- a/src/dev/pcidev.hh +++ b/src/dev/pcidev.hh @@ -65,8 +65,7 @@ class PciDev : public DmaDevice virtual Tick recvAtomic(PacketPtr pkt); - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual AddrRangeList getAddrRanges(); Platform *platform; @@ -187,10 +186,12 @@ class PciDev : public DmaDevice interruptLine() { return letoh(config.interruptLine); } - /** return the address ranges that this device responds to. - * @params range_list range list to populate with ranges + /** + * Determine the address ranges that this device responds to. + * + * @return a list of non-overlapping address ranges */ - void addressRanges(AddrRangeList &range_list); + AddrRangeList getAddrRanges(); /** * Constructor for PCI Dev. This function copies data from the diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index b87dfa704..741442918 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -1714,7 +1714,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) if (transmitTick) schedule(txEvent, curTick() + transmitTick); - pioPort->sendStatusChange(Port::RangeChange); + pioPort->sendRangeChange(); } diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc index 748a08c81..e7947dcdf 100644 --- a/src/dev/sparc/iob.cc +++ b/src/dev/sparc/iob.cc @@ -325,12 +325,13 @@ Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1) return true; } -void -Iob::addressRanges(AddrRangeList &range_list) +AddrRangeList +Iob::getAddrRanges() { - range_list.clear(); - range_list.push_back(RangeSize(iobManAddr, iobManSize)); - range_list.push_back(RangeSize(iobJBusAddr, iobJBusSize)); + AddrRangeList ranges; + ranges.push_back(RangeSize(iobManAddr, iobManSize)); + ranges.push_back(RangeSize(iobJBusAddr, iobJBusSize)); + return ranges; } diff --git a/src/dev/sparc/iob.hh b/src/dev/sparc/iob.hh index 7391b1ccd..d6a47ce19 100644 --- a/src/dev/sparc/iob.hh +++ b/src/dev/sparc/iob.hh @@ -141,7 +141,7 @@ class Iob : public PioDevice bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1); - void addressRanges(AddrRangeList &range_list); + AddrRangeList getAddrRanges(); virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index 877e9fb47..671d5505f 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -286,16 +286,14 @@ Uart8250::dataAvailable() } -void -Uart8250::addressRanges(AddrRangeList &range_list) +AddrRangeList +Uart8250::getAddrRanges() { - assert(pioSize != 0); - range_list.clear(); - range_list.push_back(RangeSize(pioAddr, pioSize)); + AddrRangeList ranges; + ranges.push_back(RangeSize(pioAddr, pioSize)); + return ranges; } - - void Uart8250::serialize(ostream &os) { diff --git a/src/dev/uart8250.hh b/src/dev/uart8250.hh index 79c31d5cf..f31def2ea 100644 --- a/src/dev/uart8250.hh +++ b/src/dev/uart8250.hh @@ -100,7 +100,7 @@ class Uart8250 : public Uart virtual Tick read(PacketPtr pkt); virtual Tick write(PacketPtr pkt); - virtual void addressRanges(AddrRangeList &range_list); + virtual AddrRangeList getAddrRanges(); /** * Inform the uart that there is data available. diff --git a/src/dev/x86/i8042.cc b/src/dev/x86/i8042.cc index a0786c95c..746a08778 100644 --- a/src/dev/x86/i8042.cc +++ b/src/dev/x86/i8042.cc @@ -43,12 +43,13 @@ const uint8_t CommandAck = 0xfa; const uint8_t CommandNack = 0xfe; const uint8_t BatSuccessful = 0xaa; -void -X86ISA::I8042::addressRanges(AddrRangeList &range_list) +AddrRangeList +X86ISA::I8042::getAddrRanges() { - range_list.clear(); - range_list.push_back(RangeSize(dataPort, 1)); - range_list.push_back(RangeSize(commandPort, 1)); + AddrRangeList ranges; + ranges.push_back(RangeSize(dataPort, 1)); + ranges.push_back(RangeSize(commandPort, 1)); + return ranges; } void diff --git a/src/dev/x86/i8042.hh b/src/dev/x86/i8042.hh index be12c4e96..61220b45d 100644 --- a/src/dev/x86/i8042.hh +++ b/src/dev/x86/i8042.hh @@ -255,7 +255,7 @@ class I8042 : public BasicPioDevice commandByte.keyboardFullInt = 1; } - void addressRanges(AddrRangeList &range_list); + AddrRangeList getAddrRanges(); Tick read(PacketPtr pkt); diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh index ae0322d94..0bcf8973d 100644 --- a/src/dev/x86/i82094aa.hh +++ b/src/dev/x86/i82094aa.hh @@ -103,19 +103,21 @@ class I82094AA : public PioDevice, public IntDev Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); - void addressRanges(AddrRangeList &range_list) + AddrRangeList getAddrRanges() { - range_list.clear(); - range_list.push_back(RangeEx(pioAddr, pioAddr + 4)); - range_list.push_back(RangeEx(pioAddr + 16, pioAddr + 20)); + AddrRangeList ranges; + ranges.push_back(RangeEx(pioAddr, pioAddr + 4)); + ranges.push_back(RangeEx(pioAddr + 16, pioAddr + 20)); + return ranges; } - void getIntAddrRange(AddrRangeList &range_list) + AddrRangeList getIntAddrRange() { - range_list.clear(); - range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0), - x86InterruptAddress(initialApicId, 0) + - PhysAddrAPICRangeSize)); + AddrRangeList ranges; + ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0), + x86InterruptAddress(initialApicId, 0) + + PhysAddrAPICRangeSize)); + return ranges; } void writeReg(uint8_t offset, uint32_t value); diff --git a/src/dev/x86/intdev.cc b/src/dev/x86/intdev.cc index 0c0fa73cf..a991005bc 100644 --- a/src/dev/x86/intdev.cc +++ b/src/dev/x86/intdev.cc @@ -54,7 +54,7 @@ X86ISA::IntDev::init() if (!intPort) { panic("Int port not connected to anything!"); } - intPort->sendStatusChange(Port::RangeChange); + intPort->sendRangeChange(); } X86ISA::IntSourcePin * diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh index 1b3efdbb5..9713d042b 100644 --- a/src/dev/x86/intdev.hh +++ b/src/dev/x86/intdev.hh @@ -63,10 +63,9 @@ class IntDev { } - void getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) + AddrRangeList getAddrRanges() { - snoop = false; - device->getIntAddrRange(resp); + return device->getIntAddrRange(); } Tick recvMessage(PacketPtr pkt) @@ -134,8 +133,8 @@ class IntDev return 0; } - virtual void - getIntAddrRange(AddrRangeList &range_list) + virtual AddrRangeList + getIntAddrRange() { panic("intAddrRange not implemented.\n"); } diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc index 2fed3179c..5638a2350 100644 --- a/src/kern/tru64/tru64_events.cc +++ b/src/kern/tru64/tru64_events.cc @@ -57,14 +57,12 @@ BadAddrEvent::process(ThreadContext *tc) uint64_t a0 = tc->readIntReg(16); - AddrRangeList resp; - bool snoop; AddrRangeIter iter; bool found = false; Port* dataPort = tc->getCpuPtr()->getPort("dcache_port"); - dataPort->getPeerAddressRanges(resp, snoop); + AddrRangeList resp = dataPort->getPeer()->getAddrRanges(); for (iter = resp.begin(); iter != resp.end(); iter++) { if (*iter == (K0Seg2Phys(a0) & PAddrImplMask)) found = true; diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 6001870ff..71cbcb76c 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -338,21 +338,19 @@ Bridge::BridgePort::recvFunctional(PacketPtr pkt) otherPort->sendFunctional(pkt); } -/** Function called by the port when the bus is receiving a status change.*/ +/** Function called by the port when the bridge is receiving a range change.*/ void -Bridge::BridgePort::recvStatusChange(Port::Status status) +Bridge::BridgePort::recvRangeChange() { - otherPort->sendStatusChange(status); + otherPort->sendRangeChange(); } -void -Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) +AddrRangeList +Bridge::BridgePort::getAddrRanges() { - otherPort->getPeerAddressRanges(resp, snoop); - FilterRangeList(filterRanges, resp); - // we don't allow snooping across bridges - snoop = false; + AddrRangeList ranges = otherPort->getPeer()->getAddrRanges(); + FilterRangeList(filterRanges, ranges); + return ranges; } Bridge * diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index 732717dd4..a3fa1f8f6 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -178,14 +178,14 @@ class Bridge : public MemObject pass it to the bridge. */ virtual void recvFunctional(PacketPtr pkt); - /** When receiving a status changefrom the peer port, - pass it to the bridge. */ - virtual void recvStatusChange(Status status); + /** + * When receiving a range change, pass it through the bridge. + */ + virtual void recvRangeChange(); /** When receiving a address range request the peer port, pass it to the bridge. */ - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual AddrRangeList getAddrRanges(); }; BridgePort portA, portB; diff --git a/src/mem/bus.cc b/src/mem/bus.cc index ce834515b..00caa8289 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * @@ -94,14 +106,21 @@ Bus::getPort(const std::string &if_name, int idx) return bp; } -/** Get the ranges of anyone other buses that we are connected to. */ void Bus::init() { m5::hash_map<short,BusPort*>::iterator intIter; - for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) - intIter->second->sendStatusChange(Port::RangeChange); + // iterate over our interfaces and determine which of our neighbours + // are snooping and add them as snoopers + for (intIter = interfaces.begin(); intIter != interfaces.end(); + intIter++) { + if (intIter->second->getPeer()->isSnooping()) { + DPRINTF(BusAddrRanges, "Adding snooping neighbour %s\n", + intIter->second->getPeer()->name()); + snoopPorts.push_back(intIter->second); + } + } } Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) @@ -468,20 +487,16 @@ Bus::recvFunctional(PacketPtr pkt) } } -/** Function called by the port when the bus is receiving a status change.*/ +/** Function called by the port when the bus is receiving a range change.*/ void -Bus::recvStatusChange(Port::Status status, int id) +Bus::recvRangeChange(int id) { AddrRangeList ranges; - bool snoops; AddrRangeIter iter; - if (inRecvStatusChange.count(id)) + if (inRecvRangeChange.count(id)) return; - inRecvStatusChange.insert(id); - - assert(status == Port::RangeChange && - "The other statuses need to be implemented."); + inRecvRangeChange.insert(id); DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id); @@ -490,8 +505,7 @@ Bus::recvStatusChange(Port::Status status, int id) defaultRange.clear(); // Only try to update these ranges if the user set a default responder. if (useDefaultRange) { - defaultPort->getPeerAddressRanges(ranges, snoops); - assert(snoops == false); + AddrRangeList ranges = defaultPort->getPeer()->getAddrRanges(); for(iter = ranges.begin(); iter != ranges.end(); iter++) { defaultRange.push_back(*iter); DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n", @@ -512,20 +526,7 @@ Bus::recvStatusChange(Port::Status status, int id) portIter++; } - for (SnoopIter s_iter = snoopPorts.begin(); - s_iter != snoopPorts.end(); ) { - if ((*s_iter)->getId() == id) - s_iter = snoopPorts.erase(s_iter); - else - s_iter++; - } - - port->getPeerAddressRanges(ranges, snoops); - - if (snoops) { - DPRINTF(BusAddrRanges, "Adding id %d to snoop list\n", id); - snoopPorts.push_back(port); - } + ranges = port->getPeer()->getAddrRanges(); for (iter = ranges.begin(); iter != ranges.end(); iter++) { DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n", @@ -546,24 +547,23 @@ Bus::recvStatusChange(Port::Status status, int id) for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) if (intIter->first != id && intIter->first != funcPortId) - intIter->second->sendStatusChange(Port::RangeChange); + intIter->second->sendRangeChange(); if (id != defaultId && defaultPort) - defaultPort->sendStatusChange(Port::RangeChange); - inRecvStatusChange.erase(id); + defaultPort->sendRangeChange(); + inRecvRangeChange.erase(id); } -void -Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id) +AddrRangeList +Bus::getAddrRanges(int id) { - resp.clear(); - snoop = false; + AddrRangeList ranges; DPRINTF(BusAddrRanges, "received address range request, returning:\n"); for (AddrRangeIter dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end(); dflt_iter++) { - resp.push_back(*dflt_iter); + ranges.push_back(*dflt_iter); DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start, dflt_iter->end); } @@ -586,12 +586,21 @@ Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id) } } if (portIter->second != id && !subset) { - resp.push_back(portIter->first); + ranges.push_back(portIter->first); DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n", portIter->first.start, portIter->first.end); } } + return ranges; +} + +bool +Bus::isSnooping(int id) +{ + // in essence, answer the question if there are other snooping + // ports rather than the port that is asking + bool snoop = false; for (SnoopIter s_iter = snoopPorts.begin(); s_iter != snoopPorts.end(); s_iter++) { if ((*s_iter)->getId() != id) { @@ -599,6 +608,7 @@ Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id) break; } } + return snoop; } unsigned diff --git a/src/mem/bus.hh b/src/mem/bus.hh index df80063f8..6c1b4c196 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * @@ -81,6 +93,15 @@ class Bus : public MemObject int getId() { return id; } + /** + * Determine if this port should be considered a snooper. This + * is determined by the bus. + * + * @return a boolean that is true if this port is snooping + */ + virtual bool isSnooping() + { return bus->isSnooping(id); } + protected: /** When reciving a timing request from the peer port (at id), @@ -98,10 +119,10 @@ class Bus : public MemObject virtual void recvFunctional(PacketPtr pkt) { pkt->setSrc(id); bus->recvFunctional(pkt); } - /** When reciving a status changefrom the peer port (at id), + /** When reciving a range change from the peer port (at id), pass it to the bus. */ - virtual void recvStatusChange(Status status) - { bus->recvStatusChange(status, id); } + virtual void recvRangeChange() + { bus->recvRangeChange(id); } /** When reciving a retry from the peer port (at id), pass it to the bus. */ @@ -112,9 +133,8 @@ class Bus : public MemObject // downstream from this bus, yes? That is, the union of all // the 'owned' address ranges of all the other interfaces on // this bus... - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { bus->addressRanges(resp, snoop, id); } + virtual AddrRangeList getAddrRanges() + { return bus->getAddrRanges(id); } // Ask the bus to ask everyone on the bus what their block size is and // take the max of it. This might need to be changed a bit if we ever @@ -174,8 +194,8 @@ class Bus : public MemObject * requests. */ void recvRetry(int id); - /** Function called by the port when the bus is recieving a status change.*/ - void recvStatusChange(Port::Status status, int id); + /** Function called by the port when the bus is recieving a range change.*/ + void recvRangeChange(int id); /** Find which port connected to this bus (if any) should be given a packet * with this address. @@ -238,12 +258,23 @@ class Bus : public MemObject portCache[0].valid = false; } - /** Process address range request. - * @param resp addresses that we can respond to - * @param snoop addresses that we would like to snoop - * @param id ide of the busport that made the request. + /** + * Return the address ranges this port is responsible for. + * + * @param id id of the bus port that made the request + * + * @return a list of non-overlapping address ranges + */ + AddrRangeList getAddrRanges(int id); + + /** + * Determine if the bus port is snooping or not. + * + * @param id id of the bus port that made the request + * + * @return a boolean indicating if this port is snooping or not */ - void addressRanges(AddrRangeList &resp, bool &snoop, int id); + bool isSnooping(int id); /** Calculate the timing parameters for the packet. Updates the * firstWordTime and finishTime fields of the packet object. @@ -264,7 +295,7 @@ class Bus : public MemObject BusFreeEvent busIdle; bool inRetry; - std::set<int> inRecvStatusChange; + std::set<int> inRecvRangeChange; /** max number of bus ids we've handed out so far */ short maxId; diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 023b74323..278329152 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -70,11 +70,9 @@ BaseCache::BaseCache(const Params *p) } void -BaseCache::CachePort::recvStatusChange(Port::Status status) +BaseCache::CachePort::recvRangeChange() const { - if (status == Port::RangeChange) { - otherPort->sendStatusChange(Port::RangeChange); - } + otherPort->sendRangeChange(); } @@ -136,7 +134,7 @@ BaseCache::init() { if (!cpuSidePort || !memSidePort) panic("Cache not hooked up on both sides\n"); - cpuSidePort->sendStatusChange(Port::RangeChange); + cpuSidePort->sendRangeChange(); } diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index 297692b32..e6a5c284f 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -105,7 +105,7 @@ class BaseCache : public MemObject CachePort(const std::string &_name, BaseCache *_cache, const std::string &_label); - virtual void recvStatusChange(Status status); + virtual void recvRangeChange() const; virtual unsigned deviceBlockSize() const; diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 7b1c877f9..b5c95b301 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -90,8 +90,7 @@ class Cache : public BaseCache return static_cast<Cache<TagStore> *>(cache); } - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual AddrRangeList getAddrRanges(); virtual bool recvTiming(PacketPtr pkt); @@ -118,8 +117,7 @@ class Cache : public BaseCache void processSendEvent(); - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual bool isSnooping(); virtual bool recvTiming(PacketPtr pkt); diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 1e5b59e17..46692a8d3 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1554,14 +1554,15 @@ Cache<TagStore>::nextMSHRReadyTime() /////////////// template<class TagStore> -void +AddrRangeList Cache<TagStore>::CpuSidePort:: -getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) +getAddrRanges() { // CPU side port doesn't snoop; it's a target only. It can // potentially respond to any address. - snoop = false; - resp.push_back(myCache()->getAddrRange()); + AddrRangeList ranges; + ranges.push_back(myCache()->getAddrRange()); + return ranges; } @@ -1612,14 +1613,13 @@ CpuSidePort::CpuSidePort(const std::string &_name, Cache<TagStore> *_cache, /////////////// template<class TagStore> -void -Cache<TagStore>::MemSidePort:: -getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) +bool +Cache<TagStore>::MemSidePort::isSnooping() { // Memory-side port always snoops, but never passes requests // through to targets on the cpu side (so we don't add anything to // the address range list). - snoop = true; + return true; } diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 91b9052a1..bab6e868c 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -116,7 +116,7 @@ PhysicalMemory::init() for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) { if (*pi) - (*pi)->sendStatusChange(Port::RangeChange); + (*pi)->sendRangeChange(); } } @@ -398,36 +398,30 @@ PhysicalMemory::getPort(const std::string &if_name, int idx) return port; } - -void -PhysicalMemory::recvStatusChange(Port::Status status) -{ -} - PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name, PhysicalMemory *_memory) : SimpleTimingPort(_name, _memory), memory(_memory) { } void -PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status) +PhysicalMemory::MemoryPort::recvRangeChange() { - memory->recvStatusChange(status); + // memory is a slave and thus should never have to worry about its + // neighbours address ranges } -void -PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) +AddrRangeList +PhysicalMemory::MemoryPort::getAddrRanges() { - memory->getAddressRanges(resp, snoop); + return memory->getAddrRanges(); } -void -PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop) +AddrRangeList +PhysicalMemory::getAddrRanges() { - snoop = false; - resp.clear(); - resp.push_back(RangeSize(start(), size())); + AddrRangeList ranges; + ranges.push_back(RangeSize(start(), size())); + return ranges; } unsigned diff --git a/src/mem/physical.hh b/src/mem/physical.hh index cd6d809e2..1e00d8f5b 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -65,10 +65,9 @@ class PhysicalMemory : public MemObject virtual void recvFunctional(PacketPtr pkt); - virtual void recvStatusChange(Status status); + virtual void recvRangeChange(); - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop); + virtual AddrRangeList getAddrRanges(); virtual unsigned deviceBlockSize() const; }; @@ -172,7 +171,7 @@ class PhysicalMemory : public MemObject public: unsigned deviceBlockSize() const; - void getAddressRanges(AddrRangeList &resp, bool &snoop); + AddrRangeList getAddrRanges(); virtual Port *getPort(const std::string &if_name, int idx = -1); void virtual init(); unsigned int drain(Event *de); @@ -181,7 +180,6 @@ class PhysicalMemory : public MemObject Tick doAtomicAccess(PacketPtr pkt); void doFunctionalAccess(PacketPtr pkt); virtual Tick calculateLatency(PacketPtr pkt); - void recvStatusChange(Port::Status status); public: virtual void serialize(std::ostream &os); diff --git a/src/mem/port.hh b/src/mem/port.hh index 0399a2a0e..98b3ad5f1 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * @@ -48,8 +60,7 @@ #include "mem/packet.hh" #include "mem/request.hh" -/** This typedef is used to clean up the parameter list of - * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared +/** This typedef is used to clean up getAddrRanges(). It's declared * outside the Port object since it's also used by some mem objects. * Eventually we should move this typedef to wherever Addr is * defined. @@ -101,13 +112,6 @@ class Port virtual ~Port(); - // mey be better to use subclasses & RTTI? - /** Holds the ports status. Currently just that a range recomputation needs - * to be done. */ - enum Status { - RangeChange - }; - void setName(const std::string &name) { portName = name; } @@ -139,8 +143,8 @@ class Port /** Called to recive a functional call from the peer port. */ virtual void recvFunctional(PacketPtr pkt) = 0; - /** Called to recieve a status change from the peer port. */ - virtual void recvStatusChange(Status status) = 0; + /** Called to recieve an address range change from the peer port. */ + virtual void recvRangeChange() = 0; /** Called by a peer port if the send was unsuccesful, and had to wait. This shouldn't be valid for response paths (IO Devices). @@ -155,17 +159,31 @@ class Port */ virtual unsigned deviceBlockSize() const { return 0; } - /** The peer port is requesting us to reply with a list of the ranges we - are responsible for. - @param resp is a list of ranges responded to - @param snoop is a list of ranges snooped - */ - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { panic("??"); } - public: + /** + * Get a list of the non-overlapping address ranges we are + * responsible for. The default implementation returns an empty + * list and thus no address ranges. Any slave port must override + * this function and return a populated list with at least one + * item. + * + * @return a list of ranges responded to + */ + virtual AddrRangeList getAddrRanges() + { AddrRangeList ranges; return ranges; } + + /** + * Determine if this port is snooping or not. The default + * implementation returns false and thus tells the neighbour we + * are not snooping. Any port that is to snoop (e.g. a cache + * connected to a bus) has to override this function. + * + * @return true if the port should be considered a snooper + */ + virtual bool isSnooping() + { return false; } + /** Function called by associated memory device (cache, memory, iodevice) in order to send a timing request to the port. Simply calls the peer port receive function. @@ -193,10 +211,11 @@ class Port void sendFunctional(PacketPtr pkt) { return peer->recvFunctional(pkt); } - /** Called by the associated device to send a status change to the device - connected to the peer interface. - */ - void sendStatusChange(Status status) {peer->recvStatusChange(status); } + /** + * Called by the associated device to send a status range to the + * peer interface. + */ + void sendRangeChange() const { peer->recvRangeChange(); } /** When a timing access doesn't return a success, some time later the Retry will be sent. @@ -208,12 +227,6 @@ class Port */ unsigned peerBlockSize() const { return peer->deviceBlockSize(); } - /** Called by the associated device if it wishes to find out the address - ranges connected to the peer ports devices. - */ - void getPeerAddressRanges(AddrRangeList &resp, bool &snoop) - { peer->getDeviceAddressRanges(resp, snoop); } - /** This function is a wrapper around sendFunctional() that breaks a larger, arbitrarily aligned access into appropriate chunks. The default implementation can use diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index 0b013f78e..59c9bb19d 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -671,9 +671,8 @@ RubyPort::PioPort::sendTiming(PacketPtr pkt) bool RubyPort::M5Port::isPhysMemAddress(Addr addr) { - AddrRangeList physMemAddrList; - bool snoop = false; - ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop); + AddrRangeList physMemAddrList = + ruby_port->physMemPort->getPeer()->getAddrRanges(); for (AddrRangeIter iter = physMemAddrList.begin(); iter != physMemAddrList.end(); iter++) { diff --git a/src/mem/tport.hh b/src/mem/tport.hh index 9143562fc..eaf5acd5d 100644 --- a/src/mem/tport.hh +++ b/src/mem/tport.hh @@ -139,10 +139,13 @@ class SimpleTimingPort : public Port bool recvTiming(PacketPtr pkt); /** - * Simple ports generally don't care about any status - * changes... can always override this in cases where that's not - * true. */ - virtual void recvStatusChange(Status status) { } + * Simple ports are generally used as slave ports (i.e. the + * respond to requests) and thus do not expect to receive any + * range changes (as the neighbouring port has a master role and + * do not have any address ranges. A subclass can override the + * default behaviuor if needed. + */ + virtual void recvRangeChange() { } public: diff --git a/src/sim/system.hh b/src/sim/system.hh index eedd11e85..53f1762c7 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -102,7 +102,13 @@ class System : public MemObject { panic("SystemPort does not receive atomic!\n"); return 0; } void recvFunctional(PacketPtr pkt) { panic("SystemPort does not receive functional!\n"); } - void recvStatusChange(Status status) { } + + /** + * The system port is a master port connected to a single + * slave and thus do not care about what ranges the slave + * covers (as there is nothing to choose from). + */ + void recvRangeChange() { } }; |