summaryrefslogtreecommitdiff
path: root/arch/alpha
diff options
context:
space:
mode:
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/isa_desc29
1 files changed, 18 insertions, 11 deletions
diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc
index e3b8cf01b..aef9135d3 100644
--- a/arch/alpha/isa_desc
+++ b/arch/alpha/isa_desc
@@ -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