MEM: Separate queries for snooping and address ranges
authorAndreas Hansson <andreas.hansson@arm.com>
Tue, 17 Jan 2012 18:55:09 +0000 (12:55 -0600)
committerAndreas Hansson <andreas.hansson@arm.com>
Tue, 17 Jan 2012 18:55:09 +0000 (12:55 -0600)
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.

54 files changed:
src/arch/x86/interrupts.cc
src/arch/x86/interrupts.hh
src/arch/x86/pagetable_walker.cc
src/arch/x86/pagetable_walker.hh
src/cpu/base.cc
src/cpu/base.hh
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/cache_unit.hh
src/cpu/o3/cpu.hh
src/cpu/ozone/front_end.hh
src/cpu/ozone/front_end_impl.hh
src/cpu/ozone/lw_lsq.hh
src/cpu/ozone/lw_lsq_impl.hh
src/cpu/simple/atomic.cc
src/cpu/testers/memtest/memtest.cc
src/cpu/testers/memtest/memtest.hh
src/cpu/testers/networktest/networktest.cc
src/cpu/testers/networktest/networktest.hh
src/dev/arm/gic.cc
src/dev/arm/gic.hh
src/dev/arm/pl111.cc
src/dev/arm/pl111.hh
src/dev/copy_engine.hh
src/dev/io_device.cc
src/dev/io_device.hh
src/dev/pciconfigall.cc
src/dev/pciconfigall.hh
src/dev/pcidev.cc
src/dev/pcidev.hh
src/dev/sinic.cc
src/dev/sparc/iob.cc
src/dev/sparc/iob.hh
src/dev/uart8250.cc
src/dev/uart8250.hh
src/dev/x86/i8042.cc
src/dev/x86/i8042.hh
src/dev/x86/i82094aa.hh
src/dev/x86/intdev.cc
src/dev/x86/intdev.hh
src/kern/tru64/tru64_events.cc
src/mem/bridge.cc
src/mem/bridge.hh
src/mem/bus.cc
src/mem/bus.hh
src/mem/cache/base.cc
src/mem/cache/base.hh
src/mem/cache/cache.hh
src/mem/cache/cache_impl.hh
src/mem/physical.cc
src/mem/physical.hh
src/mem/port.hh
src/mem/ruby/system/RubyPort.cc
src/mem/tport.hh
src/sim/system.hh

index 7d6f6e35e3b00affc5b4362a956d6c7040e42382..9944f4afde2acd54b854fd0170777b2f92478f48 100644 (file)
@@ -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;
 }
 
 
index f5d86219b7360041578ab6f453176c509b3434d3..6cf50e2fea2a05cc9aa321b510ff02f87ffb90a9 100644 (file)
@@ -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)
     {
index c80fe10fcf789bed7598b46f999ef9665d3135bc..5b1730f0c626b49ac5248f00ddb49d84838fb232 100644 (file)
@@ -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
index b0edc434f7d92020449bfe658f246095a1c66c06..73e185148774ad62b6b574b11b6a502881ce36cd 100644 (file)
@@ -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;
index 2fe41cd4de5ce5625ca3d5524651f0dfd3e55e7b..370be7ee1e7cef126c75c56674fe5f514095f46e 100644 (file)
@@ -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;
 }
index 5622031f857ccf74e9553ca28492cf75d51f79d1..d4de55453dbd7e794294fc63b69c9ea199a9fe01 100644 (file)
@@ -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();
 
     };
 
index 7fcab6893a3ee01b2ca6d7a5eaae89f8a9758088..856675e055aea0c6ef3965487ed8fc4f6335f402 100644 (file)
@@ -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
index 78eff999117cf8a7461a2cdbb04ee5fd43fd0897..6ca3001635562ea6b72d7a0379797bf58461b9f4 100644 (file)
@@ -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);
index 1dd49a4f3ab2e46d757456cfb138a72fc95ca178..121253475603600dbed65d6961183e13e80b6470 100644 (file)
@@ -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
index 1d200ef7da9451267e4149b145c3c15d17631001..41b86aab8cfa379c160687f7e80ebef290048c4a 100644 (file)
@@ -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. */
index 5d8919d4e9563a2b351e357e08fdbc61f607cbcd..a11cf74bde4f228beea3783e641b1f29897f47a1 100644 (file)
@@ -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>
index 4817622f5497bc2efb80952f81de5b9685f901ca..1add138940e35128b87769894d0bfb415921a9de 100644 (file)
@@ -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);
 
index 3bee831760c0c2d12c727e47cd6663322f6d5b45..811d6656730ca44b3c5360b842805255baa45b59 100644 (file)
@@ -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>
index 84f42da08cfe68cdb63673cfe2235c036b66595e..425c8b1f1cd20233f4f5ff896c84dde75b1591fd 100644 (file)
@@ -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
index ef23825cd37a8b47996bebfa2996de5b71a0a43c..d70dc96e6c568dea4f2796c4979f39e30aa81f07 100644 (file)
@@ -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.
index 292e7d83de8f26fb82434bee36d98b861df7822c..1a59914fde4cc48ec8836d84d991eb8c09a06335 100644 (file)
@@ -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:
index d78f976beb0d3ff74a932a88e59098df175c4b4f..56fcc46c45f4f3aab27ab5236ad5c222d22b5287 100644 (file)
@@ -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);
index 6d9d1edad2f1e194a196ece54d18d5e4711ffca5..c277cfbab74d86e23b13f2128698364680cf07c3 100644 (file)
@@ -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:
index 2dac18c0887f398e502088cfb972106e956e2383..4c45760b853fc645764162cf593f2322ef0f8d11 100644 (file)
@@ -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;
 }
 
 
index 4c43db66008d393b668f5f51f7d6e3245585f43c..6e3f12cdb212abcc34b823865715772ca62d735a 100644 (file)
@@ -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()
index 958f07aa777a460bcb3340c3b83fae9915c7cf03..263a3b62052831a14f066d8f196adb2e766f655d 100644 (file)
@@ -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 *
index f36dc681030e02392a4cb8276b163f35aff2dbf9..b2dc1f6409a38cbe936ee41a193c5b065c246f1f 100644 (file)
@@ -325,10 +325,12 @@ class Pl111: public AmbaDmaDevice
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
-    /** 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
index dfe469588708f8f306a6e87c5ce01e7209e59a13..581d3c80bbdef552a470a3ccbbcbf7ee83f2287e 100644 (file)
@@ -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)
index 9b7b6ec500632f2d130bf96788e568ab062e7f78..6cb7bbed78e72dd28790b33a3debdf90b52977a3 100644 (file)
@@ -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
index 36787c13efd84f4be44694af2c155d465ba6b81b..45fd385b9759af96a7444e36a9dfba68074f88d7 100644 (file)
@@ -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();
 
 };
 
index 55b43985721bf73724898a0067fe02099e877f80..e7130e11db0188699c53753a8900dfcdce0b6401 100644 (file)
@@ -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;
 }
 
 
index b3f6d14725dac40b299a7d41c6629bd4c8a1e48a..e594838faebdf4e53de7f656fa0ff7f5e03cf93a 100644 (file)
@@ -80,7 +80,7 @@ class PciConfigAll : public PioDevice
 
     virtual Tick write(PacketPtr pkt);
 
-    void addressRanges(AddrRangeList &range_list);
+    AddrRangeList getAddrRanges();
 
   private:
     Addr pioAddr;
index 2c7d50e83519acd67df828463b2fa3720f094f3c..c36ac11bacd1644e9e3bb3fa9d11180a49972476 100644 (file)
@@ -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 &section)
     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();
 
 }
 
index 5da8b2dfcdbfa4c51a4692401ef87cbf76476e32..4c3ecc59472f0f3183ac910624d1359ea1eae63f 100644 (file)
@@ -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
index b87dfa7047fe1a4a9bf12f6f6acfd19e79229e60..741442918f0272f8297eb822d8ce2579564abddf 100644 (file)
@@ -1714,7 +1714,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
     if (transmitTick)
         schedule(txEvent, curTick() + transmitTick);
 
-    pioPort->sendStatusChange(Port::RangeChange);
+    pioPort->sendRangeChange();
 
 }
 
index 748a08c81a8011ae7846bc9632c9b0446f0575bc..e7947dcdf5e76e9517f4aac09b7767b790d1439b 100644 (file)
@@ -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;
 }
 
 
index 7391b1ccd93e6ca86a2e6300f82ba2247981fd51..d6a47ce19e6160f4d516eaf3107742e845b8ab4a 100644 (file)
@@ -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 &section);
index 877e9fb47e7d5f85f7a59c203fe87c6be8174f8b..671d5505f8a956e1c465a575ff598fb9f0551a3f 100644 (file)
@@ -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)
 {
index 79c31d5cf52d24b37042dc6c35b27ccf82af462a..f31def2eaf7e6a259998862da9cdb6a145244d1e 100644 (file)
@@ -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.
index a0786c95ce0f0638a8e20ab74d46b3a74e1e8247..746a087782ba9ffe63cdde22ab1b578ff5cd634b 100644 (file)
@@ -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
index be12c4e96a55a7c4d32a071189fc68b19cf44e6f..61220b45d703852a17062a80bba56a5b4bd7fe96 100644 (file)
@@ -255,7 +255,7 @@ class I8042 : public BasicPioDevice
         commandByte.keyboardFullInt = 1;
     }
 
-    void addressRanges(AddrRangeList &range_list);
+    AddrRangeList getAddrRanges();
 
     Tick read(PacketPtr pkt);
 
index ae0322d940a560cd56f071f32562e2d656c1aa52..0bcf8973db7043737e0a51fec90c3e2014b368b5 100644 (file)
@@ -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);
index 0c0fa73cf074894c1f61683d819a5b75e1dace37..a991005bc95a31e45899919487e4a388aa025b31 100644 (file)
@@ -54,7 +54,7 @@ X86ISA::IntDev::init()
     if (!intPort) {
         panic("Int port not connected to anything!");
     }
-    intPort->sendStatusChange(Port::RangeChange);
+    intPort->sendRangeChange();
 }
 
 X86ISA::IntSourcePin *
index 1b3efdbb51f8912c8e9cd6b64006ea7f7b244832..9713d042bd5e8a2d6f2fb9350b23fa83b7107f26 100644 (file)
@@ -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");
     }
index 2fed3179c1971359ca77afb1ea1527d556366a80..5638a2350d9ce283dabae523cb4f496c7bb39156 100644 (file)
@@ -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;
index 6001870ff67f4f442710fa972555c728294bd478..71cbcb76c40d8710e3a66a4243e26cd9d4df6c68 100644 (file)
@@ -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 *
index 732717dd4ec84d05d09162a89230262f4630abad..a3fa1f8f6068611b73a31029bb0e873942de3e14 100644 (file)
@@ -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;
index ce834515b83f6ffb7d02844f08289f8c21b81840..00caa82894a796a50565a347950133ebf63b3ddc 100644 (file)
@@ -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
index df80063f80295882fb0e99e486dd48af16f4f697..6c1b4c19611d5dcda4bc6e08c74ed1def15ecd3c 100644 (file)
@@ -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;
index 023b743231e8ce933047b35227e9f962ae0e35e6..278329152a9f7053d27fbe2bce4fb1f816b410e0 100644 (file)
@@ -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();
 }
 
 
index 297692b32837f2e0d5578c71b0e02890890d38f3..e6a5c284ff015ed02e31a8fc8f2836f3e9c958d2 100644 (file)
@@ -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;
 
index 7b1c877f9278514a49d26ddf4c643e8ad89cf82b..b5c95b301f89c907430c45e5b2f5c126cb0529cb 100644 (file)
@@ -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);
 
index 1e5b59e174f476dc2c7a9e6fead4d340932af4ed..46692a8d3fb0b789633c16277aa8c7b857ca2121 100644 (file)
@@ -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;
 }
 
 
index 91b9052a140dfbb396d919d7beeba15afb32304e..bab6e868c31e60c7c9dd2d2b8ba2ddf127cb4214 100644 (file)
@@ -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
index cd6d809e240dd9a6c265b4cc3ee38dec1cb4e7dc..1e00d8f5b588644c2a8e3eed7b871ed19b09bf96 100644 (file)
@@ -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);
index 0399a2a0e6aad58851b28012f2885b8e5bab0feb..98b3ad5f1b561e544290640dba505bd214888aa0 100644 (file)
@@ -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
index 0b013f78e707465ad3f0f39ccd46f754141faa12..59c9bb19d679743be1576cdd6fb6dc1f5a9b300a 100644 (file)
@@ -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++) {
index 9143562fcae5c6c6f14adecd20ad7196909461d0..eaf5acd5d6afeefb0a181eac9cb77b90b92ba417 100644 (file)
@@ -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:
index eedd11e85cc9f7de71ed004f20292c2cbbdfb06a..53f1762c7915151208c59550aeb5e304627fe9b9 100644 (file)
@@ -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() { }
 
     };