diff -r 6286bb50127e -r 439df91bb20f src/arch/arm/table_walker.cc --- a/src/arch/arm/table_walker.cc Fri Nov 19 18:01:01 2010 -0600 +++ b/src/arch/arm/table_walker.cc Fri Nov 19 18:05:47 2010 -0600 @@ -92,8 +92,7 @@ { if (if_name == "port") { if (port != NULL) - fatal("%s: port already connected to %s", - name(), port->getPeer()->name()); + return port; System *sys = params()->sys; Tick minb = params()->min_backoff; Tick maxb = params()->max_backoff; diff -r 6286bb50127e -r 439df91bb20f src/arch/arm/tlb.hh --- a/src/arch/arm/tlb.hh Fri Nov 19 18:01:01 2010 -0600 +++ b/src/arch/arm/tlb.hh Fri Nov 19 18:05:47 2010 -0600 @@ -209,6 +209,9 @@ void regStats(); + // Get the port from the table walker and return it + virtual Port *getPort(); + // Caching misc register values here. // Writing to misc registers needs to invalidate them. // translateFunctional/translateSe/translateFs checks if they are diff -r 6286bb50127e -r 439df91bb20f src/arch/arm/tlb.cc --- a/src/arch/arm/tlb.cc Fri Nov 19 18:01:01 2010 -0600 +++ b/src/arch/arm/tlb.cc Fri Nov 19 18:05:47 2010 -0600 @@ -693,6 +693,14 @@ return fault; } +Port* +TLB::getPort() +{ + return tableWalker->getPort("port"); +} + + + ArmISA::TLB * ArmTLBParams::create() { diff -r 6286bb50127e -r 439df91bb20f src/cpu/base.cc --- a/src/cpu/base.cc Fri Nov 19 18:01:01 2010 -0600 +++ b/src/cpu/base.cc Fri Nov 19 18:05:47 2010 -0600 @@ -33,6 +33,7 @@ #include #include +#include "arch/tlb.hh" #include "base/cprintf.hh" #include "base/loader/symtab.hh" #include "base/misc.hh" @@ -359,6 +360,26 @@ if (DTRACE(Context)) ThreadContext::compare(oldTC, newTC); */ + + Port *old_itb_port, *old_dtb_port, *new_itb_port, *new_dtb_port; + old_itb_port = oldTC->getITBPtr()->getPort(); + old_dtb_port = oldTC->getDTBPtr()->getPort(); + new_itb_port = newTC->getITBPtr()->getPort(); + new_dtb_port = newTC->getDTBPtr()->getPort(); + + // Move over any table walker ports if they exist + if (new_itb_port && !new_itb_port->isConnected()) { + assert(old_itb_port); + Port *peer = old_itb_port->getPeer();; + new_itb_port->setPeer(peer); + peer->setPeer(new_itb_port); + } + if (new_dtb_port && !new_dtb_port->isConnected()) { + assert(old_dtb_port); + Port *peer = old_dtb_port->getPeer();; + new_dtb_port->setPeer(peer); + peer->setPeer(new_dtb_port); + } } #if FULL_SYSTEM diff -r 6286bb50127e -r 439df91bb20f src/sim/tlb.hh --- a/src/sim/tlb.hh Fri Nov 19 18:01:01 2010 -0600 +++ b/src/sim/tlb.hh Fri Nov 19 18:05:47 2010 -0600 @@ -38,6 +38,7 @@ class ThreadContext; class Packet; +class Port; class BaseTLB : public SimObject { @@ -52,6 +53,11 @@ public: virtual void demapPage(Addr vaddr, uint64_t asn) = 0; + /** Get any port that the TLB or hardware table walker needs. + * This is used for migrating port connections during a takeOverFrom() + * call. */ + virtual Port* getPort() { return NULL; } + class Translation { public: