diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 3300e57610..91394e9728 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -87,6 +87,8 @@ class TLB : public BaseTLB TLB(const Params *p); virtual ~TLB(); + void takeOverFrom(BaseTLB *otlb) {} + virtual void regStats(); int getsize() const { return size; } diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 037f7490e6..37cf9b1494 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -353,6 +353,30 @@ TLB::drainResume() miscRegValid = false; } +void +TLB::takeOverFrom(BaseTLB *_otlb) +{ + TLB *otlb = dynamic_cast(_otlb); + /* Make sure we actually have a valid type */ + if (otlb) { + _attr = otlb->_attr; + haveLPAE = otlb->haveLPAE; + directToStage2 = otlb->directToStage2; + stage2Req = otlb->stage2Req; + bootUncacheability = otlb->bootUncacheability; + + /* Sync the stage2 MMU if they exist in both + * the old CPU and the new + */ + if (!isStage2 && + stage2Tlb && otlb->stage2Tlb) { + stage2Tlb->takeOverFrom(otlb->stage2Tlb); + } + } else { + panic("Incompatible TLB type!"); + } +} + void TLB::serialize(ostream &os) { diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index ac8c672bff..b9025fa5f4 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -155,6 +155,8 @@ class TLB : public BaseTLB virtual ~TLB(); + void takeOverFrom(BaseTLB *otlb); + /// setup all the back pointers virtual void init(); diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index fdd590e850..706a96ff0e 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -87,6 +87,9 @@ class TLB : public BaseTLB int probeEntry(Addr vpn,uint8_t) const; MipsISA::PTE *getEntry(unsigned) const; virtual ~TLB(); + + void takeOverFrom(BaseTLB *otlb) {} + int smallPages; int getsize() const { return size; } diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh index 753231a89d..b18956b076 100644 --- a/src/arch/power/tlb.hh +++ b/src/arch/power/tlb.hh @@ -130,6 +130,8 @@ class TLB : public BaseTLB TLB(const Params *p); virtual ~TLB(); + void takeOverFrom(BaseTLB *otlb) {} + int probeEntry(Addr vpn,uint8_t) const; PowerISA::PTE *getEntry(unsigned) const; diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index e084f665ca..e29c5171a4 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -154,6 +154,8 @@ class TLB : public BaseTLB typedef SparcTLBParams Params; TLB(const Params *p); + void takeOverFrom(BaseTLB *otlb) {} + void demapPage(Addr vaddr, uint64_t asn) { diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index ea2d50ec2b..6b65b6f37b 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -75,6 +75,8 @@ namespace X86ISA typedef X86TLBParams Params; TLB(const Params *p); + void takeOverFrom(BaseTLB *otlb) {} + TlbEntry *lookup(Addr va, bool update_lru = true); void setConfigAddress(uint32_t addr); diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 9057856316..c8c8ac5717 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -432,6 +432,8 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) old_dtb_port->unbind(); new_dtb_port->bind(slavePort); } + newTC->getITBPtr()->takeOverFrom(oldTC->getITBPtr()); + newTC->getDTBPtr()->takeOverFrom(oldTC->getDTBPtr()); // Checker whether or not we have to transfer CheckerCPU // objects over in the switch @@ -447,6 +449,9 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) BaseMasterPort *new_checker_dtb_port = newChecker->getDTBPtr()->getMasterPort(); + newChecker->getITBPtr()->takeOverFrom(oldChecker->getITBPtr()); + newChecker->getDTBPtr()->takeOverFrom(oldChecker->getDTBPtr()); + // Move over any table walker ports if they exist for checker if (new_checker_itb_port) { assert(!new_checker_itb_port->isConnected()); diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh index f46c2d856e..397d6e0f2d 100644 --- a/src/sim/tlb.hh +++ b/src/sim/tlb.hh @@ -69,6 +69,11 @@ class BaseTLB : public SimObject */ virtual void flushAll() = 0; + /** + * Take over from an old tlb context + */ + virtual void takeOverFrom(BaseTLB *otlb) = 0; + /** * Get the table walker master port if present. This is used for * migrating port connections during a CPU takeOverFrom()