/*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
*/
#include "arch/arm/isa.hh"
+#include "config/use_checker.hh"
#include "debug/Arm.hh"
#include "debug/MiscRegs.hh"
#include "sim/faults.hh"
#include "sim/stat_control.hh"
#include "sim/system.hh"
+#if USE_CHECKER
+#include "cpu/checker/cpu.hh"
+#endif
+
namespace ArmISA
{
// See section B4.1.84 of ARM ARM
// All values are latest for ARMv7-A profile
- miscRegs[MISCREG_ID_ISAR0] = 0x01101111;
+ miscRegs[MISCREG_ID_ISAR0] = 0x02101111;
miscRegs[MISCREG_ID_ISAR1] = 0x02112111;
miscRegs[MISCREG_ID_ISAR2] = 0x21232141;
miscRegs[MISCREG_ID_ISAR3] = 0x01112131;
switch (misc_reg) {
case MISCREG_MPIDR:
- return tc->cpuId();
+
+ return 0x80000000 | // multiprocessor extensions available
+ tc->cpuId();
break;
case MISCREG_ID_MMFR0:
return 0x03; // VMSAv7 support
"config registers and jumping to ThumbEE vectors\n");
return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM
case MISCREG_ID_PFR1:
- warn("reading unimplmented register ID_PFR1");
- return 0;
+ return 0x00001; // !Timer | !Virti | !M Profile | !TrustZone | ARMv4
case MISCREG_CTR:
return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact
case MISCREG_ACTLR:
return readMiscRegNoEffect(MISCREG_FPSCR) & ~FpscrQcMask;
case MISCREG_FPSCR_EXC:
return readMiscRegNoEffect(MISCREG_FPSCR) & ~FpscrExcMask;
+ case MISCREG_L2CTLR:
+ {
+ // mostly unimplemented, just set NumCPUs field from sim and return
+ L2CTLR l2ctlr = 0;
+ // b00:1CPU to b11:4CPUs
+ l2ctlr.numCPUs = tc->getSystemPtr()->numContexts() - 1;
+ return l2ctlr;
+ }
+ case MISCREG_DBGDIDR:
+ /* For now just implement the version number.
+ * Return 0 as we don't support debug architecture yet.
+ */
+ return 0;
+ case MISCREG_DBGDSCR_INT:
+ return 0;
}
return readMiscRegNoEffect(misc_reg);
}
PCState pc = tc->pcState();
pc.nextThumb(cpsr.t);
pc.nextJazelle(cpsr.j);
+#if USE_CHECKER
+ tc->pcStateNoRecord(pc);
+#else
tc->pcState(pc);
+#endif //USE_CHECKER
} else if (misc_reg >= MISCREG_CP15_UNIMP_START &&
misc_reg < MISCREG_CP15_END) {
panic("Unimplemented CP15 register %s wrote with %#x.\n",
miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr;
tc->getITBPtr()->invalidateMiscReg();
tc->getDTBPtr()->invalidateMiscReg();
+
+ // Check if all CPUs are booted with caches enabled
+ // so we can stop enforcing coherency of some kernel
+ // structures manually.
+ sys = tc->getSystemPtr();
+ for (x = 0; x < sys->numContexts(); x++) {
+ oc = sys->getThreadContext(x);
+ SCTLR other_sctlr = oc->readMiscRegNoEffect(MISCREG_SCTLR);
+ if (!other_sctlr.c && oc->status() != ThreadContext::Halted)
+ return;
+ }
+
+ for (x = 0; x < sys->numContexts(); x++) {
+ oc = sys->getThreadContext(x);
+ oc->getDTBPtr()->allCpusCaching();
+ oc->getITBPtr()->allCpusCaching();
+#if USE_CHECKER
+ CheckerCPU *checker =
+ dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+ if (checker) {
+ checker->getDTBPtr()->allCpusCaching();
+ checker->getITBPtr()->allCpusCaching();
+ }
+#endif
+ }
return;
}
case MISCREG_TLBTR:
assert(oc->getITBPtr() && oc->getDTBPtr());
oc->getITBPtr()->flushAll();
oc->getDTBPtr()->flushAll();
+#if USE_CHECKER
+ CheckerCPU *checker =
+ dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+ if (checker) {
+ checker->getITBPtr()->flushAll();
+ checker->getDTBPtr()->flushAll();
+ }
+#endif
}
return;
case MISCREG_ITLBIALL:
bits(newVal, 7,0));
oc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
bits(newVal, 7,0));
+#if USE_CHECKER
+ CheckerCPU *checker =
+ dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+ if (checker) {
+ checker->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+ bits(newVal, 7,0));
+ checker->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+ bits(newVal, 7,0));
+ }
+#endif
}
return;
case MISCREG_TLBIASIDIS:
assert(oc->getITBPtr() && oc->getDTBPtr());
oc->getITBPtr()->flushAsid(bits(newVal, 7,0));
oc->getDTBPtr()->flushAsid(bits(newVal, 7,0));
+#if USE_CHECKER
+ CheckerCPU *checker =
+ dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+ if (checker) {
+ checker->getITBPtr()->flushAsid(bits(newVal, 7,0));
+ checker->getDTBPtr()->flushAsid(bits(newVal, 7,0));
+ }
+#endif
}
return;
case MISCREG_TLBIMVAAIS:
assert(oc->getITBPtr() && oc->getDTBPtr());
oc->getITBPtr()->flushMva(mbits(newVal, 31,12));
oc->getDTBPtr()->flushMva(mbits(newVal, 31,12));
+#if USE_CHECKER
+ CheckerCPU *checker =
+ dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+ if (checker) {
+ checker->getITBPtr()->flushMva(mbits(newVal, 31,12));
+ checker->getDTBPtr()->flushMva(mbits(newVal, 31,12));
+ }
+#endif
}
return;
case MISCREG_ITLBIMVA:
panic("Security Extensions not implemented!");
}
warn("Translating via MISCREG in atomic mode! Fix Me!\n");
- req->setVirt(0, val, 1, flags, tc->pcState().pc());
+ req->setVirt(0, val, 1, flags, tc->pcState().pc(),
+ Request::funcMasterId);
fault = tc->getDTBPtr()->translateAtomic(req, tc, mode);
if (fault == NoFault) {
miscRegs[MISCREG_PAR] =
// see all of the registers for the copy.
updateRegMap(val);
return;
+ case MISCREG_L2CTLR:
+ warn("miscreg L2CTLR (%s) written with %#x. ignored...\n",
+ miscRegName[misc_reg], uint32_t(val));
}
}
setMiscRegNoEffect(misc_reg, newVal);