From 8858b0b667a7982604070b3f4a73fcdc76513b76 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 7 Oct 2007 18:20:51 -0700 Subject: [PATCH] X86: Make x86 initialize more state. --HG-- extra : convert_revision : a55866efd339ae795da4072c070918bf419b07fa --- src/arch/x86/utility.cc | 98 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 12 deletions(-) diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index 862d14460..96228b6c4 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -75,10 +75,6 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { # if FULL_SYSTEM void initCPU(ThreadContext *tc, int cpuId) { - // TODO Figure out what the attribute registers should be set to. How this - // information is stored isn't specified, but it's values are in table - // 14.2. - // The otherwise unmodified integer registers should be set to 0. for (int index = 0; index < NUM_INTREGS; index++) { tc->setIntReg(index, 0); @@ -111,18 +107,32 @@ void initCPU(ThreadContext *tc, int cpuId) tc->setMiscReg(MISCREG_EFER, 0); + SegAttr dataAttr = 0; + dataAttr.writable = 1; + dataAttr.readable = 1; + dataAttr.expandDown = 0; + dataAttr.dpl = 0; + dataAttr.defaultSize = 0; + for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) { tc->setMiscReg(MISCREG_SEG_SEL(seg), 0); tc->setMiscReg(MISCREG_SEG_BASE(seg), 0); tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff); - tc->setMiscReg(MISCREG_SEG_ATTR(seg), 0); + tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr); } + SegAttr codeAttr = 0; + codeAttr.writable = 0; + codeAttr.readable = 1; + codeAttr.expandDown = 0; + codeAttr.dpl = 0; + codeAttr.defaultSize = 0; + tc->setMiscReg(MISCREG_CS, 0xf000); tc->setMiscReg(MISCREG_CS_BASE, 0x00000000ffff0000); // This has the base value pre-added. tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff); - tc->setMiscReg(MISCREG_CS_ATTR, 0); + tc->setMiscReg(MISCREG_CS_ATTR, codeAttr); tc->setPC(0x000000000000fff0 + tc->readMiscReg(MISCREG_CS_BASE)); @@ -151,9 +161,35 @@ void initCPU(ThreadContext *tc, int cpuId) // TODO initialize x87, 64 bit, and 128 bit media state - // TODO Set up MTRRs (page 512) + tc->setMiscReg(MISCREG_MTRRCAP, 0x0508); + for (int i = 0; i < 8; i++) { + tc->setMiscReg(MISCREG_MTRR_PHYS_BASE(i), 0); + tc->setMiscReg(MISCREG_MTRR_PHYS_MASK(i), 0); + } + tc->setMiscReg(MISCREG_MTRR_FIX_64K_00000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_16K_80000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_16K_A0000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4K_C0000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4k_C8000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4K_D0000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4K_D8000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4K_E0000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4K_E8000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4K_F0000, 0); + tc->setMiscReg(MISCREG_MTRR_FIX_4K_F8000, 0); - // TODO Set up machine check registers (page 515) + tc->setMiscReg(MISCREG_DEF_TYPE, 0); + + tc->setMiscReg(MISCREG_MCG_CAP, 0x104); + tc->setMiscReg(MISCREG_MCG_STATUS, 0); + tc->setMiscReg(MISCREG_MCG_CTL, 0); + + for (int i = 0; i < 5; i++) { + tc->setMiscReg(MISCREG_MC_CTL(i), 0); + tc->setMiscReg(MISCREG_MC_STATUS(i), 0); + tc->setMiscReg(MISCREG_MC_ADDR(i), 0); + tc->setMiscReg(MISCREG_MC_MISC(i), 0); + } tc->setMiscReg(MISCREG_DR0, 0); tc->setMiscReg(MISCREG_DR1, 0); @@ -163,18 +199,56 @@ void initCPU(ThreadContext *tc, int cpuId) tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0); tc->setMiscReg(MISCREG_DR7, 0x0000000000000400); - // TODO Set time stamp counter to 0 + tc->setMiscReg(MISCREG_TSC, 0); + tc->setMiscReg(MISCREG_TSC_AUX, 0); - // TODO Set up performance monitoring registers (page 517) + for (int i = 0; i < 4; i++) { + tc->setMiscReg(MISCREG_PERF_EVT_SEL(i), 0); + tc->setMiscReg(MISCREG_PERF_EVT_CTR(i), 0); + } - // TODO Set up the rest of the MSRs (page 507) + tc->setMiscReg(MISCREG_STAR, 0); + tc->setMiscReg(MISCREG_LSTAR, 0); + tc->setMiscReg(MISCREG_CSTAR, 0); + + tc->setMiscReg(MISCREG_SF_MASK, 0); + + tc->setMiscReg(MISCREG_KERNEL_GS_BASE, 0); + + tc->setMiscReg(MISCREG_SYSENTER_CS, 0); + tc->setMiscReg(MISCREG_SYSENTER_ESP, 0); + tc->setMiscReg(MISCREG_SYSENTER_EIP, 0); + + tc->setMiscReg(MISCREG_PAT, 0x0007040600070406); + + tc->setMiscReg(MISCREG_SYSCFG, 0x20601); + + tc->setMiscReg(MISCREG_IORR_BASE0, 0); + tc->setMiscReg(MISCREG_IORR_BASE1, 0); + + tc->setMiscReg(MISCREG_IORR_MASK0, 0); + tc->setMiscReg(MISCREG_IORR_MASK1, 0); + + tc->setMiscReg(MISCREG_TOP_MEM, 0x4000000); + tc->setMiscReg(MISCREG_TOP_MEM2, 0x0); + + tc->setMiscReg(MISCREG_DEBUG_CTL_MSR, 0); + tc->setMiscReg(MISCREG_LAST_BRANCH_FROM_IP, 0); + tc->setMiscReg(MISCREG_LAST_BRANCH_TO_IP, 0); + tc->setMiscReg(MISCREG_LAST_EXCEPTION_FROM_IP, 0); + tc->setMiscReg(MISCREG_LAST_EXCEPTION_TO_IP, 0); // Invalidate the caches (this should already be done for us) // TODO Turn on the APIC. This should be handled elsewhere but it isn't // currently being handled at all. - // Set the SMRAM base address (SMBASE) to 0x00030000 + // TODO Set the SMRAM base address (SMBASE) to 0x00030000 + + tc->setMiscReg(MISCREG_VM_CR, 0); + tc->setMiscReg(MISCREG_IGNNE, 0); + tc->setMiscReg(MISCREG_SMM_CTL, 0); + tc->setMiscReg(MISCREG_VM_HSAVE_PA, 0); } #endif