summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/base.cc55
-rw-r--r--src/mem/port.cc12
-rw-r--r--src/mem/port.hh25
3 files changed, 65 insertions, 27 deletions
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index c1b1e6d36..ff832f562 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -389,17 +389,21 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
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
@@ -417,17 +421,21 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
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();
}
}
}
@@ -444,18 +452,21 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
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();
- }
-
- if (!getDataPort().isConnected()) {
- getDataPort().bind(oldCPU->getDataPort().getSlavePort());
- oldCPU->getDataPort().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);
+
+ assert(!getDataPort().isConnected());
+ assert(oldCPU->getDataPort().isConnected());
+ SlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort();
+ oldCPU->getDataPort().unbind();
+ getDataPort().bind(data_peer_port);
}
diff --git a/src/mem/port.cc b/src/mem/port.cc
index 3827994fb..9b65da756 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -82,14 +82,22 @@ MasterPort::getSlavePort() const
}
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 @@ SlavePort::~SlavePort()
}
void
-SlavePort::unBind()
+SlavePort::unbind()
{
_masterPort = NULL;
}
diff --git a/src/mem/port.hh b/src/mem/port.hh
index eac92791e..631725ce1 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -140,8 +140,17 @@ class MasterPort : public Port
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 @@ class SlavePort : public Port
PortID id = InvalidPortID);
virtual ~SlavePort();
- void unBind();
- void bind(MasterPort& master_port);
MasterPort& getMasterPort() const;
bool isConnected() const;
@@ -387,6 +394,18 @@ class SlavePort : public Port
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;