summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/isa.hh')
-rw-r--r--src/arch/arm/isa.hh116
1 files changed, 109 insertions, 7 deletions
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 2315afa9e..905eb0183 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -44,6 +44,38 @@ namespace ArmISA
{
protected:
MiscReg miscRegs[NumMiscRegs];
+ const IntRegIndex *intRegMap;
+
+ void
+ updateRegMap(CPSR cpsr)
+ {
+ switch (cpsr.mode) {
+ case MODE_USER:
+ case MODE_SYSTEM:
+ intRegMap = IntRegUsrMap;
+ break;
+ case MODE_FIQ:
+ intRegMap = IntRegFiqMap;
+ break;
+ case MODE_IRQ:
+ intRegMap = IntRegIrqMap;
+ break;
+ case MODE_SVC:
+ intRegMap = IntRegSvcMap;
+ break;
+ case MODE_MON:
+ intRegMap = IntRegMonMap;
+ break;
+ case MODE_ABORT:
+ intRegMap = IntRegAbtMap;
+ break;
+ case MODE_UNDEFINED:
+ intRegMap = IntRegUndMap;
+ break;
+ default:
+ panic("Unrecognized mode setting in CPSR.\n");
+ }
+ }
public:
void clear()
@@ -52,6 +84,15 @@ namespace ArmISA
CPSR cpsr = 0;
cpsr.mode = MODE_USER;
miscRegs[MISCREG_CPSR] = cpsr;
+ updateRegMap(cpsr);
+
+ SCTLR sctlr = 0;
+ sctlr.nmfi = 1;
+ sctlr.rao1 = 1;
+ sctlr.rao2 = 1;
+ sctlr.rao3 = 1;
+ sctlr.rao4 = 1;
+
//XXX We need to initialize the rest of the state.
}
@@ -59,34 +100,94 @@ namespace ArmISA
readMiscRegNoEffect(int misc_reg)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ return miscRegs[MISCREG_SPSR];
+ case MODE_FIQ:
+ return miscRegs[MISCREG_SPSR_FIQ];
+ case MODE_IRQ:
+ return miscRegs[MISCREG_SPSR_IRQ];
+ case MODE_SVC:
+ return miscRegs[MISCREG_SPSR_SVC];
+ case MODE_MON:
+ return miscRegs[MISCREG_SPSR_MON];
+ case MODE_ABORT:
+ return miscRegs[MISCREG_SPSR_ABT];
+ case MODE_UNDEFINED:
+ return miscRegs[MISCREG_SPSR_UND];
+ default:
+ return miscRegs[MISCREG_SPSR];
+ }
+ }
return miscRegs[misc_reg];
}
MiscReg
readMiscReg(int misc_reg, ThreadContext *tc)
{
- assert(misc_reg < NumMiscRegs);
- return miscRegs[misc_reg];
+ return readMiscRegNoEffect(misc_reg);
}
void
setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ case MODE_FIQ:
+ miscRegs[MISCREG_SPSR_FIQ] = val;
+ return;
+ case MODE_IRQ:
+ miscRegs[MISCREG_SPSR_IRQ] = val;
+ return;
+ case MODE_SVC:
+ miscRegs[MISCREG_SPSR_SVC] = val;
+ return;
+ case MODE_MON:
+ miscRegs[MISCREG_SPSR_MON] = val;
+ return;
+ case MODE_ABORT:
+ miscRegs[MISCREG_SPSR_ABT] = val;
+ return;
+ case MODE_UNDEFINED:
+ miscRegs[MISCREG_SPSR_UND] = val;
+ return;
+ default:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ }
+ }
miscRegs[misc_reg] = val;
}
void
setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
{
- assert(misc_reg < NumMiscRegs);
- miscRegs[misc_reg] = val;
+ if (misc_reg == MISCREG_CPSR) {
+ updateRegMap(val);
+ }
+ return setMiscRegNoEffect(misc_reg, val);
}
int
flattenIntIndex(int reg)
{
- return reg;
+ assert(reg >= 0);
+ if (reg < NUM_ARCH_INTREGS) {
+ return intRegMap[reg];
+ } else if (reg < NUM_INTREGS) {
+ return reg;
+ } else {
+ reg -= NUM_INTREGS;
+ assert(reg < NUM_ARCH_INTREGS);
+ return reg;
+ }
}
int
@@ -95,9 +196,10 @@ namespace ArmISA
return reg;
}
- void serialize(std::ostream &os)
+ void serialize(EventManager *em, std::ostream &os)
{}
- void unserialize(Checkpoint *cp, const std::string &section)
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section)
{}
ISA()