summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-04-19 02:56:03 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-04-19 02:56:03 -0700
commit08f021aad0aa2ce7510060e1d29523dada226236 (patch)
tree17783c781e82564723d28f9de46963a7d4f2f427 /src/arch/x86
parentd277feb925bae400fb264656c4b851f1f2db7707 (diff)
downloadgem5-08f021aad0aa2ce7510060e1d29523dada226236.tar.xz
X86: Implement the STARTUP IPI.
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/faults.cc20
-rw-r--r--src/arch/x86/faults.hh10
2 files changed, 30 insertions, 0 deletions
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc
index e2a4d8ca2..bef7e4414 100644
--- a/src/arch/x86/faults.cc
+++ b/src/arch/x86/faults.cc
@@ -282,6 +282,26 @@ namespace X86ISA
tc->setNextMicroPC(romMicroPC(entry) + 1);
}
+ void
+ StartupInterrupt::invoke(ThreadContext *tc)
+ {
+ DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
+ HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
+ if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
+ panic("Startup IPI recived outside of real mode. "
+ "Don't know what to do.");
+ }
+
+ tc->setMiscReg(MISCREG_CS, vector << 8);
+ tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
+ tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
+ // This has the base value pre-added.
+ tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);
+
+ tc->setPC(tc->readMiscReg(MISCREG_CS_BASE));
+ tc->setNextPC(tc->readPC() + sizeof(MachInst));
+ }
+
#endif
} // namespace X86ISA
diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh
index 54b92bd47..0e573f051 100644
--- a/src/arch/x86/faults.hh
+++ b/src/arch/x86/faults.hh
@@ -418,6 +418,16 @@ namespace X86ISA
void invoke(ThreadContext * tc);
};
+ class StartupInterrupt : public X86Interrupt
+ {
+ public:
+ StartupInterrupt(uint8_t _vector) :
+ X86Interrupt("Startup Interrupt", "#SIPI", _vector)
+ {}
+
+ void invoke(ThreadContext * tc);
+ };
+
class SoftwareInterrupt : public X86Interrupt
{
public: