+
+ SegAttr codeAttr = 0;
+ codeAttr.dpl = 0;
+ codeAttr.unusable = 0;
+ codeAttr.defaultSize = 0;
+ codeAttr.longMode = 0;
+ codeAttr.avl = 0;
+ codeAttr.granularity = 0;
+ codeAttr.present = 1;
+ codeAttr.type = 10;
+ codeAttr.writable = 0;
+ codeAttr.readable = 1;
+ codeAttr.expandDown = 0;
+ codeAttr.system = 1;
+
+ tc->setMiscReg(MISCREG_CS, 0xf000);
+ tc->setMiscReg(MISCREG_CS_BASE,
+ 0x00000000ffff0000ULL);
+ tc->setMiscReg(MISCREG_CS_EFF_BASE,
+ 0x00000000ffff0000ULL);
+ // This has the base value pre-added.
+ tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
+ tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);
+
+ PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE));
+ tc->pcState(pc);
+
+ tc->setMiscReg(MISCREG_TSG_BASE, 0);
+ tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);
+
+ tc->setMiscReg(MISCREG_IDTR_BASE, 0);
+ tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
+
+ tc->setMiscReg(MISCREG_TSL, 0);
+ tc->setMiscReg(MISCREG_TSL_BASE, 0);
+ tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
+ tc->setMiscReg(MISCREG_TSL_ATTR, 0);
+
+ tc->setMiscReg(MISCREG_TR, 0);
+ tc->setMiscReg(MISCREG_TR_BASE, 0);
+ tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff);
+ tc->setMiscReg(MISCREG_TR_ATTR, 0);
+
+ // This value should be the family/model/stepping of the processor.
+ // (page 418). It should be consistent with the value from CPUID, but
+ // the actual value probably doesn't matter much.
+ tc->setIntReg(INTREG_RDX, 0);
+
+ tc->setMiscReg(MISCREG_DR0, 0);
+ tc->setMiscReg(MISCREG_DR1, 0);
+ tc->setMiscReg(MISCREG_DR2, 0);
+ tc->setMiscReg(MISCREG_DR3, 0);
+
+ tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
+ tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);
+
+ tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
+
+ // Flag all elements on the x87 stack as empty.
+ tc->setMiscReg(MISCREG_FTW, 0xFFFF);
+
+ // Update the handy M5 Reg.
+ tc->setMiscReg(MISCREG_M5_REG, 0);
+ MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
+ pc.upc(romMicroPC(entry));
+ pc.nupc(romMicroPC(entry) + 1);
+ tc->pcState(pc);
+ }
+
+ void
+ StartupInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
+ {
+ 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. %d, %d", m5Reg.mode, m5Reg.submode);
+ }
+
+ 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->pcState(tc->readMiscReg(MISCREG_CS_BASE));