summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2010-11-15 14:04:03 -0600
committerAli Saidi <Ali.Saidi@ARM.com>2010-11-15 14:04:03 -0600
commit4c2e5c282b334dcd263373c48d325c7f77847c61 (patch)
tree3139a60a9725b971ff26da6c0588f77a93bd0f0f
parent08c5673d56ddb77b3dd93d96b405c96c18c491d2 (diff)
downloadgem5-4c2e5c282b334dcd263373c48d325c7f77847c61.tar.xz
ARM: Add support for switching CPUs
-rw-r--r--src/arch/arm/table_walker.cc16
-rw-r--r--src/arch/arm/table_walker.hh1
-rw-r--r--src/arch/arm/utility.cc17
-rw-r--r--src/arch/arm/utility.hh6
4 files changed, 33 insertions, 7 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index c7c00924d..98dc1760d 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -43,6 +43,7 @@
#include "dev/io_device.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
+#include "sim/system.hh"
using namespace ArmISA;
@@ -59,9 +60,10 @@ TableWalker::~TableWalker()
}
-unsigned int TableWalker::drain(Event *de)
+unsigned int
+TableWalker::drain(Event *de)
{
- if (stateQueueL1.size() != 0 || stateQueueL2.size() != 0)
+ if (stateQueueL1.size() || stateQueueL2.size() || pendingQueue.size())
{
changeState(Draining);
DPRINTF(Checkpoint, "TableWalker busy, wait to drain\n");
@@ -75,6 +77,16 @@ unsigned int TableWalker::drain(Event *de)
}
}
+void
+TableWalker::resume()
+{
+ MemObject::resume();
+ if ((params()->sys->getMemoryMode() == Enums::timing) && currState) {
+ delete currState;
+ currState = NULL;
+ }
+}
+
Port*
TableWalker::getPort(const std::string &if_name, int idx)
{
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index 0804997c3..2739973e8 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -351,6 +351,7 @@ class TableWalker : public MemObject
}
virtual unsigned int drain(Event *de);
+ virtual void resume();
virtual Port *getPort(const std::string &if_name, int idx = -1);
Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index a114ec5e0..c42a8dddd 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -133,5 +133,22 @@ skipFunction(ThreadContext *tc)
tc->pcState(newPC);
}
+void
+copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ int i;
+ for(i = 0; i < TheISA::NumIntRegs; i++)
+ dest->setIntReg(i, src->readIntReg(i));
+ for(i = 0; i < TheISA::NumFloatRegs; i++)
+ dest->setFloatReg(i, src->readFloatReg(i));
+ for(i = 0; i < TheISA::NumMiscRegs; i++)
+ dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
+ // setMiscReg "with effect" will set the misc register mapping correctly.
+ // e.g. updateRegMap(val)
+ dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));
+
+ // Lastly copy PC/NPC
+ dest->pcState(src->pcState());
+}
}
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index a92ab072c..ca54984cb 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -102,11 +102,7 @@ namespace ArmISA {
tc->activate(0);
}
- static inline void
- copyRegs(ThreadContext *src, ThreadContext *dest)
- {
- panic("Copy Regs Not Implemented Yet\n");
- }
+ void copyRegs(ThreadContext *src, ThreadContext *dest);
static inline void
copyMiscRegs(ThreadContext *src, ThreadContext *dest)