X86: Make initCPU and startupCPU do something basic.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 8 Oct 2007 01:10:42 +0000 (18:10 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 8 Oct 2007 01:10:42 +0000 (18:10 -0700)
--HG--
extra : convert_revision : 1a04f4402f4f31e4e5cd482c7983d853fe117df5

src/arch/x86/SConscript
src/arch/x86/miscregs.hh
src/arch/x86/utility.cc
src/arch/x86/utility.hh

index 2a14943b04ab9b91262a0bff72b10fc898a60a35..6d79841473c2ebf06f1e8695eb778bed9593a5ad 100644 (file)
@@ -102,6 +102,7 @@ if env['TARGET_ISA'] == 'x86':
     Source('regfile.cc')
     Source('remote_gdb.cc')
     Source('tlb.cc')
+    Source('utility.cc')
 
     SimObject('X86TLB.py')
 
@@ -111,7 +112,6 @@ if env['TARGET_ISA'] == 'x86':
         # Full-system sources
         Source('system.cc')
         Source('stacktrace.cc')
-        Source('utility.cc')
         Source('vtophys.cc')
     else:
         Source('process.cc')
index 8080bd90bfe4654c0a750bdc11c14f47ee050e24..15932f92c6a48c2c56e9fd1b066969b2e6a574e8 100644 (file)
@@ -117,6 +117,9 @@ namespace X86ISA
         // Flags register
         MISCREG_RFLAGS = MISCREG_DR_BASE + NumDRegs,
 
+        // Extended feature enable register
+        MISCREG_EFER,
+
         // Segment selectors
         MISCREG_SEG_SEL_BASE,
         MISCREG_ES = MISCREG_SEG_SEL_BASE,
index b2532a13e984fbf4754cf26362f42f61ef718fa3..862d144607aa0bfff65c252851cadf64d51893d7 100644 (file)
  * Authors: Gabe Black
  */
 
+#include "arch/x86/intregs.hh"
+#include "arch/x86/miscregs.hh"
+#include "arch/x86/segmentregs.hh"
 #include "arch/x86/utility.hh"
+#include "arch/x86/x86_traits.hh"
 
 namespace X86ISA {
 
@@ -67,4 +71,128 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
     M5_DUMMY_RETURN
 #endif
 }
+
+# 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);
+    }
+
+    // These next two loops zero internal microcode and implicit registers.
+    // They aren't specified by the ISA but are used internally by M5's
+    // implementation.
+    for (int index = 0; index < NumMicroIntRegs; index++) {
+        tc->setIntReg(INTREG_MICRO(index), 0);
+    }
+
+    for (int index = 0; index < NumImplicitIntRegs; index++) {
+        tc->setIntReg(INTREG_IMPLICIT(index), 0);
+    }
+
+    // Set integer register EAX to 0 to indicate that the optional BIST
+    // passed. No BIST actually runs, but software may still check this
+    // register for errors.
+    tc->setIntReg(INTREG_RAX, 0);
+
+    //The following values are dictated by the architecture for after a RESET#
+    tc->setMiscReg(MISCREG_CR0, 0x0000000060000010);
+    tc->setMiscReg(MISCREG_CR2, 0);
+    tc->setMiscReg(MISCREG_CR3, 0);
+    tc->setMiscReg(MISCREG_CR4, 0);
+    tc->setMiscReg(MISCREG_CR8, 0);
+
+    tc->setMiscReg(MISCREG_RFLAGS, 0x0000000000000002);
+
+    tc->setMiscReg(MISCREG_EFER, 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_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->setPC(0x000000000000fff0 +
+            tc->readMiscReg(MISCREG_CS_BASE));
+    tc->setNextPC(tc->readPC() + sizeof(MachInst));
+
+    tc->setMiscReg(MISCREG_GDTR_BASE, 0);
+    tc->setMiscReg(MISCREG_GDTR_LIMIT, 0xffff);
+
+    tc->setMiscReg(MISCREG_IDTR_BASE, 0);
+    tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
+
+    tc->setMiscReg(MISCREG_LDTR, 0);
+    tc->setMiscReg(MISCREG_LDTR_BASE, 0);
+    tc->setMiscReg(MISCREG_LDTR_LIMIT, 0xffff);
+    tc->setMiscReg(MISCREG_LDTR_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);
+
+    // TODO initialize x87, 64 bit, and 128 bit media state
+
+    // TODO Set up MTRRs (page 512)
+
+    // TODO Set up machine check registers (page 515)
+
+    tc->setMiscReg(MISCREG_DR0, 0);
+    tc->setMiscReg(MISCREG_DR1, 0);
+    tc->setMiscReg(MISCREG_DR2, 0);
+    tc->setMiscReg(MISCREG_DR3, 0);
+
+    tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0);
+    tc->setMiscReg(MISCREG_DR7, 0x0000000000000400);
+
+    // TODO Set time stamp counter to 0
+
+    // TODO Set up performance monitoring registers (page 517)
+
+    // TODO Set up the rest of the MSRs (page 507)
+
+    // 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
+}
+
+#endif
+
+void startupCPU(ThreadContext *tc, int cpuId)
+{
+    if (cpuId == 0) {
+        // This is the boot strap processor (BSP). Initialize it to look like
+        // the boot loader has just turned control over to the 64 bit OS.
+
+        // Enable paging, turn on long mode, etc.
+
+        tc->activate(0);
+    } else {
+        // This is an application processor (AP). It should be initialized to
+        // look like only the BIOS POST has run on it and put then put it into
+        // a halted state.
+    }
+}
+
 } //namespace X86_ISA
index 9497986e6a51ee2ef7198bbd24fe0eefd4948f74..477a76e0b0febd723510c158b83043e4f947794f 100644 (file)
@@ -61,6 +61,7 @@
 #include "arch/x86/types.hh"
 #include "base/hashmap.hh"
 #include "base/misc.hh"
+#include "config/full_system.hh"
 #include "cpu/thread_context.hh"
 #include "sim/host.hh"
 
@@ -140,15 +141,13 @@ namespace X86ISA
     template <class TC>
     void zeroRegisters(TC *tc);
 
-    inline void initCPU(ThreadContext *tc, int cpuId)
-    {
-        panic("initCPU not implemented!\n");
-    }
+#if FULL_SYSTEM
 
-    inline void startupCPU(ThreadContext *tc, int cpuId)
-    {
-        tc->activate(0);
-    }
+    void initCPU(ThreadContext *tc, int cpuId);
+
+#endif
+
+    void startupCPU(ThreadContext *tc, int cpuId);
 };
 
 #endif // __ARCH_X86_UTILITY_HH__