summaryrefslogtreecommitdiff
path: root/src/arch/arm/faults.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/faults.cc')
-rw-r--r--src/arch/arm/faults.cc34
1 files changed, 18 insertions, 16 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 6e138119c..54cf5cfe5 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -104,6 +104,7 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
tc->readIntReg(INTREG_CONDCODES);
+ Addr curPc M5_VAR_USED = tc->pcState().pc();
cpsr.mode = nextMode();
@@ -116,7 +117,7 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
cpsr.i = 1;
cpsr.e = sctlr.ee;
tc->setMiscReg(MISCREG_CPSR, cpsr);
- tc->setIntReg(INTREG_LR, tc->readPC() +
+ tc->setIntReg(INTREG_LR, curPc +
(saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
switch (nextMode()) {
@@ -139,14 +140,15 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
panic("unknown Mode\n");
}
- Addr pc M5_VAR_USED = tc->readPC();
- Addr newPc = getVector(tc) | (sctlr.te ? PcTBit : 0);
+ Addr newPc = getVector(tc);
DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n",
- name(), cpsr, pc, tc->readIntReg(INTREG_LR), newPc);
- tc->setPC(newPc);
- tc->setNextPC(newPc + cpsr.t ? 2 : 4 );
- tc->setMicroPC(0);
- tc->setNextMicroPC(1);
+ name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc);
+ PCState pc(newPc);
+ pc.thumb(cpsr.t);
+ pc.nextThumb(pc.thumb());
+ pc.jazelle(cpsr.j);
+ pc.nextJazelle(pc.jazelle());
+ tc->pcState(pc);
}
void
@@ -193,10 +195,10 @@ SupervisorCall::invoke(ThreadContext *tc, StaticInstPtr inst)
tc->syscall(callNum);
// Advance the PC since that won't happen automatically.
- tc->setPC(tc->readNextPC());
- tc->setNextPC(tc->readNextNPC());
- tc->setMicroPC(0);
- tc->setNextMicroPC(1);
+ PCState pc = tc->pcState();
+ assert(inst);
+ inst->advancePC(pc);
+ tc->pcState(pc);
}
#endif // FULL_SYSTEM
@@ -223,10 +225,10 @@ FlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) {
// Set the PC to the next instruction of the faulting instruction.
// Net effect is simply squashing all instructions behind and
// start refetching from the next instruction.
- tc->setPC(tc->readNextPC());
- tc->setNextPC(tc->readNextNPC());
- tc->setMicroPC(0);
- tc->setNextMicroPC(1);
+ PCState pc = tc->pcState();
+ assert(inst);
+ inst->advancePC(pc);
+ tc->pcState(pc);
}
template void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc,