From 07cf9d914b292008ead7021182ec2ef8fc4671f1 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: [PATCH] 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. --- src/arch/x86/interrupts.cc | 22 +++--- src/arch/x86/interrupts.hh | 4 +- src/arch/x86/pagetable_walker.cc | 11 +-- src/arch/x86/pagetable_walker.hh | 14 +--- src/cpu/base.cc | 19 +---- src/cpu/base.hh | 19 +---- src/cpu/inorder/resources/cache_unit.cc | 11 +-- src/cpu/inorder/resources/cache_unit.hh | 13 +--- src/cpu/o3/cpu.hh | 8 +-- src/cpu/ozone/front_end.hh | 9 +-- src/cpu/ozone/front_end_impl.hh | 6 +- src/cpu/ozone/lw_lsq.hh | 10 +-- src/cpu/ozone/lw_lsq_impl.hh | 6 +- src/cpu/simple/atomic.cc | 4 +- src/cpu/testers/memtest/memtest.cc | 14 +--- src/cpu/testers/memtest/memtest.hh | 10 +-- src/cpu/testers/networktest/networktest.cc | 13 +--- src/cpu/testers/networktest/networktest.hh | 10 +-- src/dev/arm/gic.cc | 11 +-- src/dev/arm/gic.hh | 2 +- src/dev/arm/pl111.cc | 9 +-- src/dev/arm/pl111.hh | 8 ++- src/dev/copy_engine.hh | 1 - src/dev/io_device.cc | 22 +++--- src/dev/io_device.hh | 45 ++++++------ src/dev/pciconfigall.cc | 9 +-- src/dev/pciconfigall.hh | 2 +- src/dev/pcidev.cc | 25 +++---- src/dev/pcidev.hh | 11 +-- src/dev/sinic.cc | 2 +- src/dev/sparc/iob.cc | 11 +-- src/dev/sparc/iob.hh | 2 +- src/dev/uart8250.cc | 12 ++-- src/dev/uart8250.hh | 2 +- src/dev/x86/i8042.cc | 11 +-- src/dev/x86/i8042.hh | 2 +- src/dev/x86/i82094aa.hh | 20 +++--- src/dev/x86/intdev.cc | 2 +- src/dev/x86/intdev.hh | 9 ++- src/kern/tru64/tru64_events.cc | 4 +- src/mem/bridge.cc | 18 +++-- src/mem/bridge.hh | 10 +-- src/mem/bus.cc | 82 ++++++++++++---------- src/mem/bus.hh | 59 ++++++++++++---- src/mem/cache/base.cc | 8 +-- src/mem/cache/base.hh | 2 +- src/mem/cache/cache.hh | 6 +- src/mem/cache/cache_impl.hh | 16 ++--- src/mem/physical.cc | 30 ++++---- src/mem/physical.hh | 8 +-- src/mem/port.hh | 73 +++++++++++-------- src/mem/ruby/system/RubyPort.cc | 5 +- src/mem/tport.hh | 11 +-- src/sim/system.hh | 8 ++- 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 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::IcachePort::recvFunctional(PacketPtr pkt) template void -FrontEnd::IcachePort::recvStatusChange(Status status) +FrontEnd::IcachePort::recvRangeChange() { - if (status == RangeChange) - return; - - panic("FrontEnd doesn't expect recvStatusChange callback!"); } template 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::DcachePort::recvFunctional(PacketPtr pkt) template void -OzoneLWLSQ::DcachePort::recvStatusChange(Status status) +OzoneLWLSQ::DcachePort::recvRangeChange() { - if (status == RangeChange) - return; - - panic("O3CPU doesn't expect recvStatusChange callback!"); } template 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(_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::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 */ - void addressRanges(AddrRangeList &resp, bool &snoop, int id); + 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 + */ + 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 inRecvStatusChange; + std::set 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); } - 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::nextMSHRReadyTime() /////////////// template -void +AddrRangeList Cache::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 *_cache, /////////////// template -void -Cache::MemSidePort:: -getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) +bool +Cache::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() { } };