}
 
 
-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;
 }
 
 
 
         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)
     {
 
 }
 
 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
 
         {
           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;
 
 }
 
 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;
 }
 
          * @param _name structural owner of this port
          */
         CpuPort(const std::string& _name, MemObject* _owner) :
-            Port(_name, _owner), snoopRangeSent(false)
+            Port(_name, _owner)
         { }
 
       protected:
 
         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();
 
     };
 
 
 }
 
 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
 
         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);
         /** 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);
 
          * 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
 
         /** 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. */
 
 
 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>
 
 
         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);
 
 
 
 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>
 
     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
 
 }
 
 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
       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.
 
             : Port(_name, _memtest), memtest(_memtest)
         { }
 
-        bool snoopRangeSent;
-
       protected:
 
         virtual bool recvTiming(PacketPtr pkt);
 
         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:
 
 }
 
 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
       injRate(p->inj_rate),
       precision(p->precision)
 {
-    cachePort.snoopRangeSent = false;
-
     // set up counters
     noResponseCycles = 0;
     schedule(tickEvent, 0);
 
             : Port(_name, _networktest), networktest(_networktest)
         { }
 
-        bool snoopRangeSent;
-
       protected:
 
         virtual bool recvTiming(PacketPtr pkt);
 
         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:
 
         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;
 }
 
 
 
     /** 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()
 
     }
 }
 
-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 *
 
     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
 
         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)
 
     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();
 }
 
 
 {
     if (!pioPort)
         panic("Pio port of %s not connected to anything!", name());
-    pioPort->sendStatusChange(Port::RangeChange);
+    pioPort->sendRangeChange();
 }
 
 Port *
       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;
 }
 
 
       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
 
  * 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
 
     virtual Tick recvAtomic(PacketPtr pkt);
 
-    virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                        bool &snoop);
+    virtual AddrRangeList getAddrRanges();
 
   public:
 
     /** 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)
     {
         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();
 /**
  * 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.
  */
      * 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.
         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();
 
 };
 
 
 }
 
 
-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;
 }
 
 
 
 
     virtual Tick write(PacketPtr pkt);
 
-    void addressRanges(AddrRangeList &range_list);
+    AddrRangeList getAddrRanges();
 
   private:
     Addr pioAddr;
 
     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;
 }
 
 
 {
     if (!configPort)
         panic("pci config port not connected to anything!");
-   configPort->sendStatusChange(Port::RangeChange);
+   configPort->sendRangeChange();
    PioDevice::init();
 }
 
 
 }
 
-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
                             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) |
     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();
 
 }
 
 
 
         virtual Tick recvAtomic(PacketPtr pkt);
 
-        virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                            bool &snoop);
+        virtual AddrRangeList getAddrRanges();
 
         Platform *platform;
 
     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
 
     if (transmitTick)
         schedule(txEvent, curTick() + transmitTick);
 
-    pioPort->sendStatusChange(Port::RangeChange);
+    pioPort->sendRangeChange();
 
 }
 
 
     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;
 }
 
 
 
     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);
 
 
 }
 
-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)
 {
 
 
     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.
 
 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
 
         commandByte.keyboardFullInt = 1;
     }
 
-    void addressRanges(AddrRangeList &range_list);
+    AddrRangeList getAddrRanges();
 
     Tick read(PacketPtr pkt);
 
 
     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);
 
     if (!intPort) {
         panic("Int port not connected to anything!");
     }
-    intPort->sendStatusChange(Port::RangeChange);
+    intPort->sendRangeChange();
 }
 
 X86ISA::IntSourcePin *
 
         {
         }
 
-        void getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+        AddrRangeList getAddrRanges()
         {
-            snoop = false;
-            device->getIntAddrRange(resp);
+            return device->getIntAddrRange();
         }
 
         Tick recvMessage(PacketPtr pkt)
         return 0;
     }
 
-    virtual void
-    getIntAddrRange(AddrRangeList &range_list)
+    virtual AddrRangeList
+    getIntAddrRange()
     {
         panic("intAddrRange not implemented.\n");
     }
 
 
     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;
 
     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 *
 
             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;
 
 /*
+ * 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.
  *
     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)
     }
 }
 
-/** 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);
 
         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",
                 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",
 
     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);
     }
             }
         }
         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) {
             break;
         }
     }
+    return snoop;
 }
 
 unsigned
 
 /*
+ * 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.
  *
 
         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),
         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. */
         // 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
      * 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.
         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.
     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;
 
 }
 
 void
-BaseCache::CachePort::recvStatusChange(Port::Status status)
+BaseCache::CachePort::recvRangeChange() const
 {
-    if (status == Port::RangeChange) {
-        otherPort->sendStatusChange(Port::RangeChange);
-    }
+    otherPort->sendRangeChange();
 }
 
 
 {
     if (!cpuSidePort || !memSidePort)
         panic("Cache not hooked up on both sides\n");
-    cpuSidePort->sendStatusChange(Port::RangeChange);
+    cpuSidePort->sendRangeChange();
 }
 
 
 
         CachePort(const std::string &_name, BaseCache *_cache,
                   const std::string &_label);
 
-        virtual void recvStatusChange(Status status);
+        virtual void recvRangeChange() const;
 
         virtual unsigned deviceBlockSize() const;
 
 
             return static_cast<Cache<TagStore> *>(cache);
         }
 
-        virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                            bool &snoop);
+        virtual AddrRangeList getAddrRanges();
 
         virtual bool recvTiming(PacketPtr pkt);
 
 
         void processSendEvent();
 
-        virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                            bool &snoop);
+        virtual bool isSnooping();
 
         virtual bool recvTiming(PacketPtr pkt);
 
 
 ///////////////
 
 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;
 }
 
 
 ///////////////
 
 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;
 }
 
 
 
 
     for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
         if (*pi)
-            (*pi)->sendStatusChange(Port::RangeChange);
+            (*pi)->sendRangeChange();
     }
 }
 
     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
 
 
         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;
     };
 
   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);
     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);
 
 /*
+ * 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.
  *
 #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.
 
     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; }
 
     /** 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).
     */
     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.
     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.
     */
     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
 
 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++) {
 
     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:
 
         { 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() { }
 
     };