ARM: Support switchover with hardware table walkers

This commit is contained in:
Ali Saidi 2010-12-07 16:19:57 -08:00
parent 658849d101
commit 21bfbd422c
5 changed files with 43 additions and 2 deletions

View file

@ -92,8 +92,7 @@ TableWalker::getPort(const std::string &if_name, int idx)
{ {
if (if_name == "port") { if (if_name == "port") {
if (port != NULL) if (port != NULL)
fatal("%s: port already connected to %s", return port;
name(), port->getPeer()->name());
System *sys = params()->sys; System *sys = params()->sys;
Tick minb = params()->min_backoff; Tick minb = params()->min_backoff;
Tick maxb = params()->max_backoff; Tick maxb = params()->max_backoff;

View file

@ -693,6 +693,18 @@ TLB::translateTiming(RequestPtr req, ThreadContext *tc,
return fault; return fault;
} }
Port*
TLB::getPort()
{
#if FULL_SYSTEM
return tableWalker->getPort("port");
#else
return NULL;
#endif
}
ArmISA::TLB * ArmISA::TLB *
ArmTLBParams::create() ArmTLBParams::create()
{ {

View file

@ -209,6 +209,9 @@ class TLB : public BaseTLB
void regStats(); void regStats();
// Get the port from the table walker and return it
virtual Port *getPort();
// Caching misc register values here. // Caching misc register values here.
// Writing to misc registers needs to invalidate them. // Writing to misc registers needs to invalidate them.
// translateFunctional/translateSe/translateFs checks if they are // translateFunctional/translateSe/translateFs checks if they are

View file

@ -33,6 +33,7 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include "arch/tlb.hh"
#include "base/cprintf.hh" #include "base/cprintf.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/misc.hh" #include "base/misc.hh"
@ -359,6 +360,26 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
if (DTRACE(Context)) if (DTRACE(Context))
ThreadContext::compare(oldTC, newTC); 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 #if FULL_SYSTEM

View file

@ -38,6 +38,7 @@
class ThreadContext; class ThreadContext;
class Packet; class Packet;
class Port;
class BaseTLB : public SimObject class BaseTLB : public SimObject
{ {
@ -52,6 +53,11 @@ class BaseTLB : public SimObject
public: public:
virtual void demapPage(Addr vaddr, uint64_t asn) = 0; 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 class Translation
{ {
public: public: