Cleaned up some of the Fault system.
arch/alpha/ev5.cc: Commented out the intr_post function since it's not used. If this really -is- needed, it should be moved into the fault class. arch/alpha/faults.cc: arch/alpha/faults.hh: Moved the fault invocation code into the fault class fully, and got rid of the need for isA. cpu/exec_context.cc: cpu/exec_context.hh: Removed the trap function from the ExecContext. The faults will execute normally in full system mode, but always panic in syscall emulation mode. cpu/ozone/cpu.hh: cpu/simple/cpu.hh: Changed the execution context executing a fault to a fault executing on the execution context. sim/faults.cc: If not in full system mode, trying to invoke a fault causes a panic. sim/faults.hh: Removed the isA function. --HG-- extra : convert_revision : 894dc8f0755c8efc4b7ef5a09fb2cf7373042395
This commit is contained in:
parent
1cfc277424
commit
2eff368dd0
|
@ -166,7 +166,7 @@ AlphaISA::zeroRegisters(CPU *cpu)
|
||||||
void
|
void
|
||||||
AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc)
|
AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc)
|
||||||
{
|
{
|
||||||
bool use_pc = (fault == NoFault);
|
/* bool use_pc = (fault == NoFault);
|
||||||
|
|
||||||
if (fault->isA<ArithmeticFault>())
|
if (fault->isA<ArithmeticFault>())
|
||||||
panic("arithmetic faults NYI...");
|
panic("arithmetic faults NYI...");
|
||||||
|
@ -186,7 +186,7 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc)
|
||||||
(dynamic_cast<AlphaFault *>(fault.get()))->vect();
|
(dynamic_cast<AlphaFault *>(fault.get()))->vect();
|
||||||
else
|
else
|
||||||
regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc;
|
regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc;
|
||||||
|
*/
|
||||||
// that's it! (orders of magnitude less painful than x86)
|
// that's it! (orders of magnitude less painful than x86)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,14 +107,11 @@ void AlphaFault::invoke(ExecContext * xc)
|
||||||
assert(!xc->misspeculating());
|
assert(!xc->misspeculating());
|
||||||
xc->kernelStats->fault(this);
|
xc->kernelStats->fault(this);
|
||||||
|
|
||||||
if (isA<ArithmeticFault>())
|
|
||||||
panic("Arithmetic traps are unimplemented!");
|
|
||||||
|
|
||||||
// exception restart address
|
// exception restart address
|
||||||
if (!isA<InterruptFault>() || !xc->inPalMode())
|
if (setRestartAddress() || !xc->inPalMode())
|
||||||
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc);
|
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc);
|
||||||
|
|
||||||
if (isA<PalFault>() || isA<ArithmeticFault>()) {
|
if (skipFaultingInstruction()) {
|
||||||
// traps... skip faulting instruction.
|
// traps... skip faulting instruction.
|
||||||
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
|
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
|
||||||
xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
|
xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
|
||||||
|
@ -127,6 +124,23 @@ void AlphaFault::invoke(ExecContext * xc)
|
||||||
xc->regs.npc = xc->regs.pc + sizeof(MachInst);
|
xc->regs.npc = xc->regs.pc + sizeof(MachInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArithmeticFault::invoke(ExecContext * xc)
|
||||||
|
{
|
||||||
|
DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc);
|
||||||
|
xc->cpu->recordEvent(csprintf("Fault %s", name()));
|
||||||
|
|
||||||
|
assert(!xc->misspeculating());
|
||||||
|
xc->kernelStats->fault(this);
|
||||||
|
|
||||||
|
panic("Arithmetic traps are unimplemented!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*void ArithmeticFault::invoke(ExecContext * xc)
|
||||||
|
{
|
||||||
|
panic("Arithmetic traps are unimplemented!");
|
||||||
|
}*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -40,6 +40,9 @@ typedef const Addr FaultVect;
|
||||||
|
|
||||||
class AlphaFault : public virtual FaultBase
|
class AlphaFault : public virtual FaultBase
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
virtual bool skipFaultingInstruction() {return false;}
|
||||||
|
virtual bool setRestartAddress() {return true;}
|
||||||
public:
|
public:
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
void invoke(ExecContext * xc);
|
void invoke(ExecContext * xc);
|
||||||
|
@ -95,6 +98,8 @@ class ResetFault : public AlphaFault
|
||||||
|
|
||||||
class ArithmeticFault : public AlphaFault
|
class ArithmeticFault : public AlphaFault
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
bool skipFaultingInstruction() {return true;}
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
|
@ -103,10 +108,13 @@ class ArithmeticFault : public AlphaFault
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & stat() {return _stat;}
|
FaultStat & stat() {return _stat;}
|
||||||
|
void invoke(ExecContext * xc);
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterruptFault : public AlphaFault
|
class InterruptFault : public AlphaFault
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
bool setRestartAddress() {return false;}
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
|
@ -227,6 +235,8 @@ class FloatEnableFault : public AlphaFault
|
||||||
|
|
||||||
class PalFault : public AlphaFault
|
class PalFault : public AlphaFault
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
bool skipFaultingInstruction() {return true;}
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
|
|
|
@ -220,15 +220,3 @@ ExecContext::regStats(const string &name)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ExecContext::trap(Fault fault)
|
|
||||||
{
|
|
||||||
//TheISA::trap(fault); //One possible way to do it...
|
|
||||||
|
|
||||||
/** @todo: Going to hack it for now. Do a true fixup later. */
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
fault->invoke(this);
|
|
||||||
#else
|
|
||||||
fatal("fault (%d) detected @ PC 0x%08p", fault, readPC());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
|
@ -427,18 +427,9 @@ class ExecContext
|
||||||
void setIntrFlag(int val) { regs.intrflag = val; }
|
void setIntrFlag(int val) { regs.intrflag = val; }
|
||||||
Fault hwrei();
|
Fault hwrei();
|
||||||
bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
|
bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
|
||||||
void ev5_temp_trap(Fault fault);
|
|
||||||
bool simPalCheck(int palFunc);
|
bool simPalCheck(int palFunc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Meant to be more generic trap function to be
|
|
||||||
* called when an instruction faults.
|
|
||||||
* @param fault The fault generated by executing the instruction.
|
|
||||||
* @todo How to do this properly so it's dependent upon ISA only?
|
|
||||||
*/
|
|
||||||
|
|
||||||
void trap(Fault fault);
|
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
TheISA::IntReg getSyscallArg(int i)
|
TheISA::IntReg getSyscallArg(int i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -517,7 +517,7 @@ class OoOCPU : public BaseCPU
|
||||||
int readIntrFlag() { return xc->readIntrFlag(); }
|
int readIntrFlag() { return xc->readIntrFlag(); }
|
||||||
void setIntrFlag(int val) { xc->setIntrFlag(val); }
|
void setIntrFlag(int val) { xc->setIntrFlag(val); }
|
||||||
bool inPalMode() { return xc->inPalMode(); }
|
bool inPalMode() { return xc->inPalMode(); }
|
||||||
void ev5_trap(Fault fault) { xc->ev5_trap(fault); }
|
void trap(Fault fault) { fault->invoke(xc); }
|
||||||
bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
|
bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
|
||||||
#else
|
#else
|
||||||
void syscall() { xc->syscall(); }
|
void syscall() { xc->syscall(); }
|
||||||
|
|
|
@ -347,7 +347,7 @@ class SimpleCPU : public BaseCPU
|
||||||
int readIntrFlag() { return xc->readIntrFlag(); }
|
int readIntrFlag() { return xc->readIntrFlag(); }
|
||||||
void setIntrFlag(int val) { xc->setIntrFlag(val); }
|
void setIntrFlag(int val) { xc->setIntrFlag(val); }
|
||||||
bool inPalMode() { return xc->inPalMode(); }
|
bool inPalMode() { return xc->inPalMode(); }
|
||||||
void ev5_trap(Fault fault) { fault->invoke(xc); }
|
void trap(Fault fault) { fault->invoke(xc); }
|
||||||
bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
|
bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
|
||||||
#else
|
#else
|
||||||
void syscall() { xc->syscall(); }
|
void syscall() { xc->syscall(); }
|
||||||
|
|
|
@ -27,7 +27,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sim/faults.hh"
|
#include "sim/faults.hh"
|
||||||
|
#include "cpu/exec_context.hh"
|
||||||
|
|
||||||
FaultName MachineCheckFault::_name = "mchk";
|
FaultName MachineCheckFault::_name = "mchk";
|
||||||
FaultName AlignmentFault::_name = "unalign";
|
FaultName AlignmentFault::_name = "unalign";
|
||||||
|
|
||||||
|
#if !FULL_SYSTEM
|
||||||
|
void FaultBase::invoke(ExecContext * xc)
|
||||||
|
{
|
||||||
|
fatal("fault (%s) detected @ PC 0x%08p", name(), xc->readPC());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -54,9 +54,11 @@ class FaultBase : public RefCounted
|
||||||
virtual FaultStat & stat() = 0;
|
virtual FaultStat & stat() = 0;
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
virtual void invoke(ExecContext * xc) = 0;
|
virtual void invoke(ExecContext * xc) = 0;
|
||||||
|
#else
|
||||||
|
virtual void invoke(ExecContext * xc);
|
||||||
#endif
|
#endif
|
||||||
template<typename T>
|
// template<typename T>
|
||||||
bool isA() {return dynamic_cast<T *>(this);}
|
// bool isA() {return dynamic_cast<T *>(this);}
|
||||||
virtual bool isMachineCheckFault() {return false;}
|
virtual bool isMachineCheckFault() {return false;}
|
||||||
virtual bool isAlignmentFault() {return false;}
|
virtual bool isAlignmentFault() {return false;}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue