diff -r 2cb46eb4ed94 -r e5872950c9a3 src/cpu/base.cc --- a/src/cpu/base.cc Mon Aug 20 15:06:52 2012 +0100 +++ b/src/cpu/base.cc Mon Aug 20 15:34:26 2012 +0100 @@ -413,17 +413,21 @@ MasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort(); // Move over any table walker ports if they exist - if (new_itb_port && !new_itb_port->isConnected()) { + if (new_itb_port) { + assert(!new_itb_port->isConnected()); assert(old_itb_port); + assert(old_itb_port->isConnected()); SlavePort &slavePort = old_itb_port->getSlavePort(); + old_itb_port->unbind(); new_itb_port->bind(slavePort); - old_itb_port->unBind(); } - if (new_dtb_port && !new_dtb_port->isConnected()) { + if (new_dtb_port) { + assert(!new_dtb_port->isConnected()); assert(old_dtb_port); + assert(old_dtb_port->isConnected()); SlavePort &slavePort = old_dtb_port->getSlavePort(); + old_dtb_port->unbind(); new_dtb_port->bind(slavePort); - old_dtb_port->unBind(); } // Checker whether or not we have to transfer CheckerCPU @@ -441,17 +445,21 @@ newChecker->getDTBPtr()->getMasterPort(); // Move over any table walker ports if they exist for checker - if (new_checker_itb_port && !new_checker_itb_port->isConnected()) { + if (new_checker_itb_port) { + assert(!new_checker_itb_port->isConnected()); assert(old_checker_itb_port); - SlavePort &slavePort = old_checker_itb_port->getSlavePort();; + assert(old_checker_itb_port->isConnected()); + SlavePort &slavePort = old_checker_itb_port->getSlavePort(); + old_checker_itb_port->unbind(); new_checker_itb_port->bind(slavePort); - old_checker_itb_port->unBind(); } - if (new_checker_dtb_port && !new_checker_dtb_port->isConnected()) { + if (new_checker_dtb_port) { + assert(!new_checker_dtb_port->isConnected()); assert(old_checker_dtb_port); - SlavePort &slavePort = old_checker_dtb_port->getSlavePort();; + assert(old_checker_dtb_port->isConnected()); + SlavePort &slavePort = old_checker_dtb_port->getSlavePort(); + old_checker_dtb_port->unbind(); new_checker_dtb_port->bind(slavePort); - old_checker_dtb_port->unBind(); } } } @@ -468,18 +476,21 @@ schedule(profileEvent, curTick()); } - // Connect new CPU to old CPU's memory only if new CPU isn't - // connected to anything. Also connect old CPU's memory to new - // CPU. - if (!getInstPort().isConnected()) { - getInstPort().bind(oldCPU->getInstPort().getSlavePort()); - oldCPU->getInstPort().unBind(); - } + // All CPUs have an instruction and a data port, and the new CPU's + // ports are dangling while the old CPU has its ports connected + // already. Unbind the old CPU and then bind the ports of the one + // we are switching to. + assert(!getInstPort().isConnected()); + assert(oldCPU->getInstPort().isConnected()); + SlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort(); + oldCPU->getInstPort().unbind(); + getInstPort().bind(inst_peer_port); - if (!getDataPort().isConnected()) { - getDataPort().bind(oldCPU->getDataPort().getSlavePort()); - oldCPU->getDataPort().unBind(); - } + assert(!getDataPort().isConnected()); + assert(oldCPU->getDataPort().isConnected()); + SlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort(); + oldCPU->getDataPort().unbind(); + getDataPort().bind(data_peer_port); } diff -r 2cb46eb4ed94 -r e5872950c9a3 src/mem/port.hh --- a/src/mem/port.hh Mon Aug 20 15:06:52 2012 +0100 +++ b/src/mem/port.hh Mon Aug 20 15:34:26 2012 +0100 @@ -140,8 +140,17 @@ PortID id = InvalidPortID); virtual ~MasterPort(); - void unBind(); + /** + * Bind this master port to a slave port. This also does the + * mirror action and binds the slave port to the master port. + */ void bind(SlavePort& slave_port); + + /** + * Unbind this master port and the associated slave port. + */ + void unbind(); + SlavePort& getSlavePort() const; bool isConnected() const; @@ -298,8 +307,6 @@ PortID id = InvalidPortID); virtual ~SlavePort(); - void unBind(); - void bind(MasterPort& master_port); MasterPort& getMasterPort() const; bool isConnected() const; @@ -387,6 +394,18 @@ protected: /** + * Called by the master port to unbind. Should never be called + * directly. + */ + void unbind(); + + /** + * Called by the master port to bind. Should never be called + * directly. + */ + void bind(MasterPort& master_port); + + /** * Receive an atomic request packet from the master port. */ virtual Tick recvAtomic(PacketPtr pkt) = 0; diff -r 2cb46eb4ed94 -r e5872950c9a3 src/mem/port.cc --- a/src/mem/port.cc Mon Aug 20 15:06:52 2012 +0100 +++ b/src/mem/port.cc Mon Aug 20 15:34:26 2012 +0100 @@ -82,14 +82,22 @@ } void -MasterPort::unBind() +MasterPort::unbind() { + if (_slavePort == NULL) + panic("Attempting to unbind master port %s that is not connected\n", + name()); + _slavePort->unbind(); _slavePort = NULL; } void MasterPort::bind(SlavePort& slave_port) { + if (_slavePort != NULL) + panic("Attempting to bind master port %s that is already connected\n", + name()); + // master port keeps track of the slave port _slavePort = &slave_port; @@ -173,7 +181,7 @@ } void -SlavePort::unBind() +SlavePort::unbind() { _masterPort = NULL; }