Generate a fault when a privileged PAL call is
authorSteve Reinhardt <stever@eecs.umich.edu>
Tue, 9 Dec 2003 22:19:35 +0000 (14:19 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Tue, 9 Dec 2003 22:19:35 +0000 (14:19 -0800)
executed in non-privileged (non-PAL) mode.

--HG--
extra : convert_revision : c8823a1eec27d801a1ed6110ade07354c4dd2a32

arch/alpha/isa_desc

index e3b8cf01b465cd194c4ca156ad47b320cdc8997e..aef9135d3e78d43419796abb73d1241636b6b437 100644 (file)
@@ -1399,6 +1399,7 @@ declare {{
       protected:
        int palFunc;    ///< Function code part of instruction
        int palOffset;  ///< Target PC, offset from IPR_PAL_BASE
+       bool palPriv;   ///< is this call privileged?
 
        /// Constructor.
        CallPalBase(const char *mnem, MachInst _machInst,
@@ -1406,7 +1407,7 @@ declare {{
            : AlphaStaticInst(mnem, _machInst, __opClass),
              palFunc(PALFUNC)
        {
-           int palPriv = ((machInst & 0x80) != 0);
+           palPriv = ((machInst & 0x80) != 0);
            int shortPalFunc = (machInst & 0x3f);
            palOffset = 0x2001 + (palPriv << 12) + (shortPalFunc << 6);
        }
@@ -2352,20 +2353,26 @@ decode OPCODE default Unknown::unknown() {
 
 #ifdef FULL_SYSTEM
     0x00: CallPal::call_pal({{
-       // check to see if simulator wants to do something special
-       // on this PAL call (including maybe suppress it)
-       bool dopal = xc->simPalCheck(palFunc);
-
-       if (!xc->misspeculating()) {
-           Annotate::Callpal(xc, palFunc);
+       if (palPriv && !PC_PAL(xc->regs.pc)) {
+           // attempt to do privileged PAL call in non-PAL mode
+           fault = Unimplemented_Opcode_Fault;
        }
+       else {
+           // check to see if simulator wants to do something special
+           // on this PAL call (including maybe suppress it)
+           bool dopal = xc->simPalCheck(palFunc);
 
-       if (dopal) {
            if (!xc->misspeculating()) {
-               AlphaISA::swap_palshadow(&xc->regs, true);
+               Annotate::Callpal(xc, palFunc);
+           }
+
+           if (dopal) {
+               if (!xc->misspeculating()) {
+                   AlphaISA::swap_palshadow(&xc->regs, true);
+               }
+               xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC);
+               NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset;
            }
-           xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC);
-           NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset;
        }
     }});
 #else