Fixes for full-system call_pal instruction.
arch/alpha/alpha_memory.cc:
Rename md_mode_type to mode_type.
arch/alpha/ev5.cc:
simPalCheck() only gets called on correct path now, so
there's no need to test misspeculating().
arch/alpha/isa_desc:
Get privileged call_pall detection right this time (I hope).
ExecContext::simPalCheck() and Annotate::Callpal() are now
called only on non-speculative executions... this should fix
the bogus pal-call stats we've been seeing (since these are
incremented in simPalCheck()).
Also check for invalid call_pall function codes.
--HG--
extra : convert_revision : 465d6724884007d3fa066d14cd5e6db0cd3954e1
This commit is contained in:
@@ -436,12 +436,12 @@ AlphaDtb::translate(MemReqPtr req, bool write) const
|
||||
else
|
||||
read_accesses++;
|
||||
|
||||
AlphaISA::md_mode_type mode =
|
||||
(AlphaISA::md_mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]);
|
||||
AlphaISA::mode_type mode =
|
||||
(AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]);
|
||||
|
||||
if (PC_PAL(pc)) {
|
||||
mode = (req->flags & ALTMODE) ? (AlphaISA::md_mode_type)
|
||||
(ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]))
|
||||
mode = (req->flags & ALTMODE) ?
|
||||
(AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE])
|
||||
: AlphaISA::mode_kernel;
|
||||
}
|
||||
|
||||
|
||||
@@ -551,16 +551,14 @@ ExecContext::simPalCheck(int palFunc)
|
||||
|
||||
switch (palFunc) {
|
||||
case PAL::halt:
|
||||
if (!misspeculating()) {
|
||||
halt();
|
||||
if (--System::numSystemsRunning == 0)
|
||||
new SimExitEvent("all cpus halted");
|
||||
}
|
||||
halt();
|
||||
if (--System::numSystemsRunning == 0)
|
||||
new SimExitEvent("all cpus halted");
|
||||
break;
|
||||
|
||||
case PAL::bpt:
|
||||
case PAL::bugchk:
|
||||
if (!misspeculating() && system->breakpoint())
|
||||
if (system->breakpoint())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1399,6 +1399,7 @@ declare {{
|
||||
protected:
|
||||
int palFunc; ///< Function code part of instruction
|
||||
int palOffset; ///< Target PC, offset from IPR_PAL_BASE
|
||||
bool palValid; ///< is the function code valid?
|
||||
bool palPriv; ///< is this call privileged?
|
||||
|
||||
/// Constructor.
|
||||
@@ -1407,9 +1408,22 @@ declare {{
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
||||
palFunc(PALFUNC)
|
||||
{
|
||||
palPriv = ((machInst & 0x80) != 0);
|
||||
int shortPalFunc = (machInst & 0x3f);
|
||||
palOffset = 0x2001 + (palPriv << 12) + (shortPalFunc << 6);
|
||||
// From the 21164 HRM (paraphrased):
|
||||
// Bit 7 of the function code (mask 0x80) indicates
|
||||
// whether the call is privileged (bit 7 == 0) or
|
||||
// unprivileged (bit 7 == 1). The privileged call table
|
||||
// starts at 0x2000, the unprivielged call table starts at
|
||||
// 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the
|
||||
// offset.
|
||||
const int palPrivMask = 0x80;
|
||||
const int palOffsetMask = 0x3f;
|
||||
|
||||
// Pal call is invalid unless all other bits are 0
|
||||
palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0);
|
||||
palPriv = ((machInst & palPrivMask) == 0);
|
||||
int shortPalFunc = (machInst & palOffsetMask);
|
||||
// Add 1 to base to set pal-mode bit
|
||||
palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6);
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab)
|
||||
@@ -2353,25 +2367,33 @@ decode OPCODE default Unknown::unknown() {
|
||||
|
||||
#ifdef FULL_SYSTEM
|
||||
0x00: CallPal::call_pal({{
|
||||
if (palPriv && !PC_PAL(xc->regs.pc)) {
|
||||
// attempt to do privileged PAL call in non-PAL mode
|
||||
using namespace AlphaISA;
|
||||
|
||||
if (!palValid ||
|
||||
(palPriv && xc->readIpr(IPR_ICM, fault) != mode_kernel)) {
|
||||
// invalid pal function code, or attempt to do privileged
|
||||
// PAL call in non-kernel 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 (!xc->misspeculating()) {
|
||||
// check to see if simulator wants to do something special
|
||||
// on this PAL call (including maybe suppress it)
|
||||
bool dopal = xc->simPalCheck(palFunc);
|
||||
|
||||
Annotate::Callpal(xc, palFunc);
|
||||
|
||||
if (dopal) {
|
||||
swap_palshadow(&xc->regs, true);
|
||||
xc->setIpr(IPR_EXC_ADDR, NPC);
|
||||
}
|
||||
}
|
||||
|
||||
// if we're misspeculating, it's still safe (if
|
||||
// unrealistic) to set NPC, as the control-flow change
|
||||
// won't get committed.
|
||||
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;
|
||||
NPC = xc->readIpr(IPR_PAL_BASE, fault) + palOffset;
|
||||
}
|
||||
}
|
||||
}});
|
||||
|
||||
Reference in New Issue
Block a user