void
ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
{
+
MiscReg newVal = val;
if (misc_reg == MISCREG_CPSR) {
updateRegMap(val);
+
+
+ CPSR old_cpsr = miscRegs[MISCREG_CPSR];
+ int old_mode = old_cpsr.mode;
CPSR cpsr = val;
+ if (old_mode != cpsr.mode) {
+ tc->getITBPtr()->invalidateMiscReg();
+ tc->getDTBPtr()->invalidateMiscReg();
+ }
+
DPRINTF(Arm, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
miscRegs[misc_reg], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
PCState pc = tc->pcState();
SCTLR new_sctlr = newVal;
new_sctlr.nmfi = (bool)sctlr.nmfi;
miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr;
+ tc->getITBPtr()->invalidateMiscReg();
+ tc->getDTBPtr()->invalidateMiscReg();
return;
}
case MISCREG_TLBTR:
}
return;
}
+ case MISCREG_CONTEXTIDR:
+ case MISCREG_PRRR:
+ case MISCREG_NMRR:
+ case MISCREG_DACR:
+ tc->getITBPtr()->invalidateMiscReg();
+ tc->getDTBPtr()->invalidateMiscReg();
+ break;
+
}
}
setMiscRegNoEffect(misc_reg, newVal);
#if FULL_SYSTEM
, tableWalker(p->walker)
#endif
- , rangeMRU(1)
+ , rangeMRU(1), miscRegValid(false)
{
table = new TlbEntry[size];
memset(table, 0, sizeof(TlbEntry[size]));
bool
TLB::translateFunctional(ThreadContext *tc, Addr va, Addr &pa)
{
- uint32_t context_id = tc->readMiscReg(MISCREG_CONTEXTIDR);
- TlbEntry *e = lookup(va, context_id, true);
+ if (!miscRegValid)
+ updateMiscReg(tc);
+ TlbEntry *e = lookup(va, contextId, true);
if (!e)
return false;
pa = e->pAddr(va);
for(int i = 0; i < size; i++){
table[i].unserialize(cp, csprintf("%s.TlbEntry%d", section, i));
}
+ miscRegValid = false;
}
void
TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
Translation *translation, bool &delay, bool timing)
{
- // XXX Cache misc registers and have miscreg write function inv cache
+ if (!miscRegValid)
+ updateMiscReg(tc);
Addr vaddr = req->getVaddr();
- SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
uint32_t flags = req->getFlags();
bool is_fetch = (mode == Execute);
TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
Translation *translation, bool &delay, bool timing)
{
- // XXX Cache misc registers and have miscreg write function inv cache
+ if (!miscRegValid)
+ updateMiscReg(tc);
+
Addr vaddr = req->getVaddr();
- SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
- CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
uint32_t flags = req->getFlags();
bool is_fetch = (mode == Execute);
bool is_write = (mode == Write);
- bool is_priv = (cpsr.mode != MODE_USER) && !(flags & UserMode);
+ bool is_priv = isPriv && !(flags & UserMode);
- DPRINTF(TLBVerbose, "CPSR is user:%d UserMode:%d\n", cpsr.mode == MODE_USER, flags
- & UserMode);
+ DPRINTF(TLBVerbose, "CPSR is user:%d UserMode:%d\n",
+ isPriv, flags & UserMode);
// If this is a clrex instruction, provide a PA of 0 with no fault
// This will force the monitor to set the tracked address to 0
// a bit of a hack but this effectively clrears this processors monitor
}
}
- uint32_t context_id = tc->readMiscReg(MISCREG_CONTEXTIDR);
Fault fault;
-
if (!sctlr.m) {
req->setPaddr(vaddr);
if (sctlr.tre == 0) {
req->setFlags(Request::UNCACHEABLE);
} else {
- PRRR prrr = tc->readMiscReg(MISCREG_PRRR);
- NMRR nmrr = tc->readMiscReg(MISCREG_NMRR);
-
if (nmrr.ir0 == 0 || nmrr.or0 == 0 || prrr.tr0 != 0x2)
req->setFlags(Request::UNCACHEABLE);
}
return trickBoxCheck(req, mode, 0, false);
}
- DPRINTF(TLBVerbose, "Translating vaddr=%#x context=%d\n", vaddr, context_id);
+ DPRINTF(TLBVerbose, "Translating vaddr=%#x context=%d\n", vaddr, contextId);
// Translation enabled
- TlbEntry *te = lookup(vaddr, context_id);
+ TlbEntry *te = lookup(vaddr, contextId);
if (te == NULL) {
if (req->isPrefetch()){
//if the request is a prefetch don't attempt to fill the TLB
// start translation table walk, pass variables rather than
// re-retreaving in table walker for speed
DPRINTF(TLB, "TLB Miss: Starting hardware table walker for %#x(%d)\n",
- vaddr, context_id);
- fault = tableWalker->walk(req, tc, context_id, mode, translation,
+ vaddr, contextId);
+ fault = tableWalker->walk(req, tc, contextId, mode, translation,
timing);
if (timing) {
delay = true;
if (fault)
return fault;
- te = lookup(vaddr, context_id);
+ te = lookup(vaddr, contextId);
if (!te)
printTlb();
assert(te);
setAttr(te->attributes);
if (te->nonCacheable)
req->setFlags(Request::UNCACHEABLE);
- uint32_t dacr = tc->readMiscReg(MISCREG_DACR);
+
switch ( (dacr >> (te->domain * 2)) & 0x3) {
case 0:
domainFaults++;