use pstate.am to mask off PC/NPC where it needs to +be
authorAli Saidi <saidi@eecs.umich.edu>
Tue, 23 Jan 2007 20:50:03 +0000 (15:50 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Tue, 23 Jan 2007 20:50:03 +0000 (15:50 -0500)
check writability of tlb cache entry before using
update tagaccess in places I forgot to
move the tlb privileged test up since it is higher priority

src/arch/sparc/faults.cc:
    save only 32 bits of PC/NPC if Pstate.am is set
src/arch/sparc/isa/decoder.isa:
    return only 32 bits of PC/NPC if Pstate.am is set
    increment cleanwin correctly
src/arch/sparc/tlb.cc:
    check writability of cache entry
    update tagaccess in a few more places
    move the privileged test up since it is higher priority
src/cpu/exetrace.cc:
    mask off upper bits of pc if pstate.am is set before comparing to legion

--HG--
extra : convert_revision : 02a51c141ee3f9a2600c28eac018ea7216f3655c

src/arch/sparc/faults.cc
src/arch/sparc/isa/decoder.isa
src/arch/sparc/tlb.cc
src/cpu/exetrace.cc

index b465e52d2e3ac48c22d62cae9dd89d4949fdc181..825ff40f6708b4f14ec9afbd7ce840bbe1073d12 100644 (file)
@@ -312,6 +312,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
@@ -390,6 +395,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);
index 175866eba50099e826d734fc2be122c0aa45b05c..5489539823666cf230b2b0d0278277b5b2c20b45 100644 (file)
@@ -163,7 +163,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 {
@@ -578,6 +581,9 @@ decode OP default Unknown::unknown()
                         Cansave = Cansave - 1;
                     else
                         Otherwin = Otherwin - 1;
+
+                    if(Cleanwin < NWindows - 1)
+                        Cleanwin = Cleanwin + 1;
                 }});
             }
             0x32: decode RD {
@@ -875,7 +881,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;
                 }
             }});
index 1a2ec6eac8ea50aab6a97f35749341ec8df05dbd..0e59f3e15856bfcf3b34caf9bc1e3b4759c9ed39 100644 (file)
@@ -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) {
index 87075c1ecd1d15d679ba4c299faf745419d4c09f..26e8b6b44c460bc1a33873cacf7406fccbea4298 100644 (file)
@@ -340,6 +340,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;