diff options
-rw-r--r-- | src/arch/sparc/faults.cc | 10 | ||||
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 13 | ||||
-rw-r--r-- | src/arch/sparc/tlb.cc | 27 | ||||
-rw-r--r-- | src/cpu/exetrace.cc | 3 |
4 files changed, 43 insertions, 10 deletions
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index d94c05a0f..a6f4343ae 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -314,6 +314,11 @@ void doREDFault(ThreadContext *tc, TrapType tt) TL++; + if (bits(PSTATE, 3,3)) { + PC &= mask(32); + NPC &= mask(32); + } + //set TSTATE.gl to gl replaceBits(TSTATE, 42, 40, GL); //set TSTATE.ccr to ccr @@ -394,6 +399,11 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); + if (bits(PSTATE, 3,3)) { + PC &= mask(32); + NPC &= mask(32); + } + //Increment the trap level TL++; tc->setMiscReg(MISCREG_TL, TL); diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index e59ce9d11..138485a17 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -169,7 +169,10 @@ decode OP default Unknown::unknown() 0x6: Trap::fbfcc({{fault = new FpDisabled;}}); } 0x1: BranchN::call(30, {{ - R15 = xc->readPC(); + if (Pstate<3:>) + R15 = (xc->readPC())<31:0>; + else + R15 = xc->readPC(); NNPC = R15 + disp; }}); 0x2: decode OP3 { @@ -581,6 +584,9 @@ decode OP default Unknown::unknown() Cansave = Cansave - 1; else Otherwin = Otherwin - 1; + + if(Cleanwin < NWindows - 1) + Cleanwin = Cleanwin + 1; }}); } 0x32: decode RD { @@ -878,7 +884,10 @@ decode OP default Unknown::unknown() fault = new MemAddressNotAligned; else { - Rd = xc->readPC(); + if (Pstate<3:>) + (Rd = xc->readPC())<31:0>; + else + Rd = xc->readPC(); NNPC = target; } }}); diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 1a2ec6eac..0e59f3e15 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -549,6 +549,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) // were not priviledged accesing priv page if (!priv && e->pte.priv()) { + writeTagAccess(tc, vaddr, context); writeSfsr(tc, false, ct, false, PrivViolation, asi); return new InstructionAccessException; } @@ -592,13 +593,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) // Be fast if we can! if (cacheValid && cacheState == tlbdata) { if (cacheEntry[0] && cacheAsi[0] == asi && cacheEntry[0]->range.va < vaddr + size && - cacheEntry[0]->range.va + cacheEntry[0]->range.size > vaddr) { + cacheEntry[0]->range.va + cacheEntry[0]->range.size > vaddr && + (!write || cacheEntry[0]->pte.writable())) { req->setPaddr(cacheEntry[0]->pte.paddr() & ~(cacheEntry[0]->pte.size()-1) | vaddr & cacheEntry[0]->pte.size()-1 ); return NoFault; } if (cacheEntry[1] && cacheAsi[1] == asi && cacheEntry[1]->range.va < vaddr + size && - cacheEntry[1]->range.va + cacheEntry[1]->range.size > vaddr) { + cacheEntry[1]->range.va + cacheEntry[1]->range.size > vaddr && + (!write || cacheEntry[1]->pte.writable())) { req->setPaddr(cacheEntry[1]->pte.paddr() & ~(cacheEntry[1]->pte.size()-1) | vaddr & cacheEntry[1]->pte.size()-1 ); return NoFault; @@ -726,26 +729,34 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) } + if (!priv && e->pte.priv()) { + writeTagAccess(tc, vaddr, context); + writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi); + return new DataAccessException; + } if (write && !e->pte.writable()) { + writeTagAccess(tc, vaddr, context); writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), OtherFault, asi); return new FastDataAccessProtection; } if (e->pte.nofault() && !AsiIsNoFault(asi)) { + writeTagAccess(tc, vaddr, context); writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi); return new DataAccessException; } - if (e->pte.sideffect()) - req->setFlags(req->getFlags() | UNCACHEABLE); - - - if (!priv && e->pte.priv()) { - writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi); + if (e->pte.sideffect() && AsiIsNoFault(asi)) { + writeTagAccess(tc, vaddr, context); + writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), SideEffect, asi); return new DataAccessException; } + + if (e->pte.sideffect()) + req->setFlags(req->getFlags() | UNCACHEABLE); + // cache translation date for next translation cacheState = tlbdata; if (!cacheValid) { diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 7ebbf455a..23291825d 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -342,6 +342,9 @@ Trace::InstRecord::dump(ostream &outs) while (!compared) { if (shared_data->flags == OWN_M5) { m5Pc = PC & TheISA::PAddrImplMask; + if (bits(shared_data->pstate,3,3)) { + m5Pc &= mask(32); + } lgnPc = shared_data->pc & TheISA::PAddrImplMask; if (lgnPc != m5Pc) diffPC = true; |