summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/isa.cc9
-rw-r--r--src/arch/arm/miscregs.hh2
-rw-r--r--src/arch/arm/utility.cc13
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh33
4 files changed, 27 insertions, 30 deletions
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 216ae04e7..9988d431a 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -447,6 +447,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
default:
panic("Security Extensions not implemented!");
}
+ warn("Translating via MISCREG in atomic mode! Fix Me!\n");
req->setVirt(0, val, 1, flags, tc->pcState().pc());
fault = tc->getDTBPtr()->translateAtomic(req, tc, mode);
if (fault == NoFault) {
@@ -475,7 +476,13 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
tc->getITBPtr()->invalidateMiscReg();
tc->getDTBPtr()->invalidateMiscReg();
break;
-
+ case MISCREG_CPSR_MODE:
+ // This miscreg is used by copy*Regs to set the CPSR mode
+ // without updating other CPSR variables. It's used to
+ // make sure the register map is in such a state that we can
+ // see all of the registers for the copy.
+ updateRegMap(val);
+ return;
}
}
setMiscRegNoEffect(misc_reg, newVal);
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index fc18fa114..2ccd9b4c2 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -170,6 +170,7 @@ namespace ArmISA
MISCREG_ID_ISAR3,
MISCREG_ID_ISAR4,
MISCREG_ID_ISAR5,
+ MISCREG_CPSR_MODE,
MISCREG_CP15_UNIMP_START,
MISCREG_TCMTR = MISCREG_CP15_UNIMP_START,
MISCREG_ID_PFR1,
@@ -233,6 +234,7 @@ namespace ArmISA
"pmceid1", "pmc_other", "pmxevcntr",
"pmuserenr", "pmintenset", "pmintenclr",
"id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
+ "cpsr_mode",
// Unimplemented below
"tcmtr",
"id_pfr1", "id_dfr0", "id_afr0",
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 0d91c9f90..6bca63291 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -124,8 +124,21 @@ void
copyRegs(ThreadContext *src, ThreadContext *dest)
{
int i;
+
+ int saved_mode = ((CPSR)src->readMiscReg(MISCREG_CPSR)).mode;
+
+ // Make sure we're in user mode, so we can easily see all the registers
+ // in the copy loop
+ src->setMiscReg(MISCREG_CPSR_MODE, MODE_USER);
+ dest->setMiscReg(MISCREG_CPSR_MODE, MODE_USER);
+
for(i = 0; i < TheISA::NumIntRegs; i++)
dest->setIntReg(i, src->readIntReg(i));
+
+ // Restore us back to the old mode
+ src->setMiscReg(MISCREG_CPSR_MODE, saved_mode);
+ dest->setMiscReg(MISCREG_CPSR_MODE, saved_mode);
+
for(i = 0; i < TheISA::NumFloatRegs; i++)
dest->setFloatReg(i, src->readFloatReg(i));
for(i = 0; i < TheISA::NumMiscRegs; i++)
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index e7b0540d1..b179ad50e 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -231,36 +231,11 @@ template <class Impl>
void
O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc)
{
- // This function will mess things up unless the ROB is empty and
- // there are no instructions in the pipeline.
- ThreadID tid = thread->threadId();
- PhysRegIndex renamed_reg;
-
- // First loop through the integer registers.
- for (int i = 0; i < TheISA::NumIntRegs; ++i) {
- renamed_reg = cpu->renameMap[tid].lookup(i);
-
- DPRINTF(O3CPU, "Copying over register %i, had data %lli, "
- "now has data %lli.\n",
- renamed_reg, cpu->readIntReg(renamed_reg),
- tc->readIntReg(i));
-
- cpu->setIntReg(renamed_reg, tc->readIntReg(i));
- }
-
- // Then loop through the floating point registers.
- for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
- renamed_reg = cpu->renameMap[tid].lookup(i + TheISA::FP_Base_DepTag);
- cpu->setFloatRegBits(renamed_reg,
- tc->readFloatRegBits(i));
- }
-
- // Copy the misc regs.
- TheISA::copyMiscRegs(tc, this);
+ // Prevent squashing
+ thread->inSyscall = true;
+ TheISA::copyRegs(tc, this);
+ thread->inSyscall = false;
- // Then finally set the PC, the next PC, the nextNPC, the micropc, and the
- // next micropc.
- cpu->pcState(tc->pcState(), tid);
#if !FULL_SYSTEM
this->thread->funcExeInst = tc->readFuncExeInst();
#endif