X86: Remove FULL_SYSTEM from the x86 faults.
This commit is contained in:
parent
51f7a66660
commit
91dd72a99a
3 changed files with 78 additions and 89 deletions
|
@ -64,8 +64,9 @@ if env['TARGET_ISA'] == 'x86':
|
||||||
Source('utility.cc')
|
Source('utility.cc')
|
||||||
|
|
||||||
SimObject('X86NativeTrace.py')
|
SimObject('X86NativeTrace.py')
|
||||||
|
|
||||||
SimObject('X86TLB.py')
|
SimObject('X86TLB.py')
|
||||||
|
|
||||||
|
DebugFlag('Faults', "Trace all faults/exceptions/traps")
|
||||||
DebugFlag('Predecoder', "Predecoder debug output")
|
DebugFlag('Predecoder', "Predecoder debug output")
|
||||||
DebugFlag('X86', "Generic X86 ISA debugging")
|
DebugFlag('X86', "Generic X86 ISA debugging")
|
||||||
|
|
||||||
|
@ -73,7 +74,6 @@ if env['TARGET_ISA'] == 'x86':
|
||||||
DebugFlag('LocalApic', "Local APIC debugging")
|
DebugFlag('LocalApic', "Local APIC debugging")
|
||||||
DebugFlag('PageTableWalker', \
|
DebugFlag('PageTableWalker', \
|
||||||
"Page table walker state machine debugging")
|
"Page table walker state machine debugging")
|
||||||
DebugFlag('Faults', "Trace all faults/exceptions/traps")
|
|
||||||
|
|
||||||
SimObject('X86LocalApic.py')
|
SimObject('X86LocalApic.py')
|
||||||
SimObject('X86System.py')
|
SimObject('X86System.py')
|
||||||
|
|
|
@ -42,56 +42,53 @@
|
||||||
|
|
||||||
#include "arch/x86/decoder.hh"
|
#include "arch/x86/decoder.hh"
|
||||||
#include "arch/x86/faults.hh"
|
#include "arch/x86/faults.hh"
|
||||||
#include "base/trace.hh"
|
|
||||||
#include "config/full_system.hh"
|
|
||||||
#include "cpu/thread_context.hh"
|
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
#include "arch/x86/isa_traits.hh"
|
#include "arch/x86/isa_traits.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "base/trace.hh"
|
||||||
#include "sim/process.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#else
|
|
||||||
#include "arch/x86/tlb.hh"
|
|
||||||
#include "debug/Faults.hh"
|
#include "debug/Faults.hh"
|
||||||
#endif
|
#include "sim/full_system.hh"
|
||||||
|
|
||||||
namespace X86ISA
|
namespace X86ISA
|
||||||
{
|
{
|
||||||
#if FULL_SYSTEM
|
|
||||||
void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
PCState pcState = tc->pcState();
|
if (FullSystem) {
|
||||||
Addr pc = pcState.pc();
|
PCState pcState = tc->pcState();
|
||||||
DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe());
|
Addr pc = pcState.pc();
|
||||||
using namespace X86ISAInst::RomLabels;
|
DPRINTF(Faults, "RIP %#x: vector %d: %s\n",
|
||||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
pc, vector, describe());
|
||||||
MicroPC entry;
|
using namespace X86ISAInst::RomLabels;
|
||||||
if (m5reg.mode == LongMode) {
|
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||||
if (isSoft()) {
|
MicroPC entry;
|
||||||
entry = extern_label_longModeSoftInterrupt;
|
|
||||||
} else {
|
|
||||||
entry = extern_label_longModeInterrupt;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
entry = extern_label_legacyModeInterrupt;
|
|
||||||
}
|
|
||||||
tc->setIntReg(INTREG_MICRO(1), vector);
|
|
||||||
tc->setIntReg(INTREG_MICRO(7), pc);
|
|
||||||
if (errorCode != (uint64_t)(-1)) {
|
|
||||||
if (m5reg.mode == LongMode) {
|
if (m5reg.mode == LongMode) {
|
||||||
entry = extern_label_longModeInterruptWithError;
|
if (isSoft()) {
|
||||||
|
entry = extern_label_longModeSoftInterrupt;
|
||||||
|
} else {
|
||||||
|
entry = extern_label_longModeInterrupt;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic("Legacy mode interrupts with error codes "
|
entry = extern_label_legacyModeInterrupt;
|
||||||
"aren't implementde.\n");
|
|
||||||
}
|
}
|
||||||
// Software interrupts shouldn't have error codes. If one does,
|
tc->setIntReg(INTREG_MICRO(1), vector);
|
||||||
// there would need to be microcode to set it up.
|
tc->setIntReg(INTREG_MICRO(7), pc);
|
||||||
assert(!isSoft());
|
if (errorCode != (uint64_t)(-1)) {
|
||||||
tc->setIntReg(INTREG_MICRO(15), errorCode);
|
if (m5reg.mode == LongMode) {
|
||||||
|
entry = extern_label_longModeInterruptWithError;
|
||||||
|
} else {
|
||||||
|
panic("Legacy mode interrupts with error codes "
|
||||||
|
"aren't implementde.\n");
|
||||||
|
}
|
||||||
|
// Software interrupts shouldn't have error codes. If one
|
||||||
|
// does, there would need to be microcode to set it up.
|
||||||
|
assert(!isSoft());
|
||||||
|
tc->setIntReg(INTREG_MICRO(15), errorCode);
|
||||||
|
}
|
||||||
|
pcState.upc(romMicroPC(entry));
|
||||||
|
pcState.nupc(romMicroPC(entry) + 1);
|
||||||
|
tc->pcState(pcState);
|
||||||
|
} else {
|
||||||
|
FaultBase::invoke(tc, inst);
|
||||||
}
|
}
|
||||||
pcState.upc(romMicroPC(entry));
|
|
||||||
pcState.nupc(romMicroPC(entry) + 1);
|
|
||||||
tc->pcState(pcState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
@ -109,9 +106,12 @@ namespace X86ISA
|
||||||
void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
|
void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
X86FaultBase::invoke(tc);
|
X86FaultBase::invoke(tc);
|
||||||
// This is the same as a fault, but it happens -after- the instruction.
|
if (FullSystem) {
|
||||||
PCState pc = tc->pcState();
|
// This is the same as a fault, but it happens -after- the
|
||||||
pc.uEnd();
|
// instruction.
|
||||||
|
PCState pc = tc->pcState();
|
||||||
|
pc.uEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
|
void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
|
@ -119,19 +119,43 @@ namespace X86ISA
|
||||||
panic("Abort exception!");
|
panic("Abort exception!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InvalidOpcode::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
|
{
|
||||||
|
if (FullSystem) {
|
||||||
|
X86Fault::invoke(tc, inst);
|
||||||
|
} else {
|
||||||
|
panic("Unrecognized/invalid instruction executed:\n %s",
|
||||||
|
inst->machInst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
|
void PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
if (FullSystem) {
|
||||||
X86FaultBase::invoke(tc);
|
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||||
/*
|
X86FaultBase::invoke(tc);
|
||||||
* If something bad happens while trying to enter the page fault
|
/*
|
||||||
* handler, I'm pretty sure that's a double fault and then all bets are
|
* If something bad happens while trying to enter the page fault
|
||||||
* off. That means it should be safe to update this state now.
|
* handler, I'm pretty sure that's a double fault and then all
|
||||||
*/
|
* bets are off. That means it should be safe to update this
|
||||||
if (m5reg.mode == LongMode) {
|
* state now.
|
||||||
tc->setMiscReg(MISCREG_CR2, addr);
|
*/
|
||||||
|
if (m5reg.mode == LongMode) {
|
||||||
|
tc->setMiscReg(MISCREG_CR2, addr);
|
||||||
|
} else {
|
||||||
|
tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
|
PageFaultErrorCode code = errorCode;
|
||||||
|
const char *modeStr = "";
|
||||||
|
if (code.fetch)
|
||||||
|
modeStr = "execute";
|
||||||
|
else if (code.write)
|
||||||
|
modeStr = "write";
|
||||||
|
else
|
||||||
|
modeStr = "read";
|
||||||
|
panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,30 +292,5 @@ namespace X86ISA
|
||||||
|
|
||||||
tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
|
tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void
|
|
||||||
InvalidOpcode::invoke(ThreadContext * tc, StaticInstPtr inst)
|
|
||||||
{
|
|
||||||
panic("Unrecognized/invalid instruction executed:\n %s",
|
|
||||||
inst->machInst);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
|
|
||||||
{
|
|
||||||
PageFaultErrorCode code = errorCode;
|
|
||||||
const char *modeStr = "";
|
|
||||||
if (code.fetch)
|
|
||||||
modeStr = "execute";
|
|
||||||
else if (code.write)
|
|
||||||
modeStr = "write";
|
|
||||||
else
|
|
||||||
modeStr = "read";
|
|
||||||
panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
||||||
|
|
|
@ -85,12 +85,10 @@ namespace X86ISA
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
|
|
||||||
virtual std::string describe() const;
|
virtual std::string describe() const;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for x86 faults which behave as if the underlying instruction
|
// Base class for x86 faults which behave as if the underlying instruction
|
||||||
|
@ -114,10 +112,8 @@ namespace X86ISA
|
||||||
: X86FaultBase(name, mnem, vector, _errorCode)
|
: X86FaultBase(name, mnem, vector, _errorCode)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for x86 aborts which seem to be catastrophic failures.
|
// Base class for x86 aborts which seem to be catastrophic failures.
|
||||||
|
@ -129,10 +125,8 @@ namespace X86ISA
|
||||||
: X86FaultBase(name, mnem, vector, _errorCode)
|
: X86FaultBase(name, mnem, vector, _errorCode)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for x86 interrupts.
|
// Base class for x86 interrupts.
|
||||||
|
@ -246,10 +240,8 @@ namespace X86ISA
|
||||||
X86Fault("Invalid-Opcode", "#UD", 6)
|
X86Fault("Invalid-Opcode", "#UD", 6)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeviceNotAvailable : public X86Fault
|
class DeviceNotAvailable : public X86Fault
|
||||||
|
@ -334,9 +326,7 @@ namespace X86ISA
|
||||||
void invoke(ThreadContext * tc,
|
void invoke(ThreadContext * tc,
|
||||||
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
virtual std::string describe() const;
|
virtual std::string describe() const;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class X87FpExceptionPending : public X86Fault
|
class X87FpExceptionPending : public X86Fault
|
||||||
|
|
Loading…
Reference in a new issue