|
@@ -307,30 +307,39 @@ default_entry:
|
|
|
movl %eax,%cr0
|
|
|
|
|
|
/*
|
|
|
- * New page tables may be in 4Mbyte page mode and may
|
|
|
- * be using the global pages.
|
|
|
+ * We want to start out with EFLAGS unambiguously cleared. Some BIOSes leave
|
|
|
+ * bits like NT set. This would confuse the debugger if this code is traced. So
|
|
|
+ * initialize them properly now before switching to protected mode. That means
|
|
|
+ * DF in particular (even though we have cleared it earlier after copying the
|
|
|
+ * command line) because GCC expects it.
|
|
|
+ */
|
|
|
+ pushl $0
|
|
|
+ popfl
|
|
|
+
|
|
|
+/*
|
|
|
+ * New page tables may be in 4Mbyte page mode and may be using the global pages.
|
|
|
*
|
|
|
- * NOTE! If we are on a 486 we may have no cr4 at all!
|
|
|
- * Specifically, cr4 exists if and only if CPUID exists
|
|
|
- * and has flags other than the FPU flag set.
|
|
|
+ * NOTE! If we are on a 486 we may have no cr4 at all! Specifically, cr4 exists
|
|
|
+ * if and only if CPUID exists and has flags other than the FPU flag set.
|
|
|
*/
|
|
|
+ movl $-1,pa(X86_CPUID) # preset CPUID level
|
|
|
movl $X86_EFLAGS_ID,%ecx
|
|
|
pushl %ecx
|
|
|
- popfl
|
|
|
- pushfl
|
|
|
- popl %eax
|
|
|
- pushl $0
|
|
|
- popfl
|
|
|
+ popfl # set EFLAGS=ID
|
|
|
pushfl
|
|
|
- popl %edx
|
|
|
- xorl %edx,%eax
|
|
|
- testl %ecx,%eax
|
|
|
- jz 6f # No ID flag = no CPUID = no CR4
|
|
|
+ popl %eax # get EFLAGS
|
|
|
+ testl $X86_EFLAGS_ID,%eax # did EFLAGS.ID remained set?
|
|
|
+ jz 6f # hw disallowed setting of ID bit
|
|
|
+ # which means no CPUID and no CR4
|
|
|
+
|
|
|
+ xorl %eax,%eax
|
|
|
+ cpuid
|
|
|
+ movl %eax,pa(X86_CPUID) # save largest std CPUID function
|
|
|
|
|
|
movl $1,%eax
|
|
|
cpuid
|
|
|
- andl $~1,%edx # Ignore CPUID.FPU
|
|
|
- jz 6f # No flags or only CPUID.FPU = no CR4
|
|
|
+ andl $~1,%edx # Ignore CPUID.FPU
|
|
|
+ jz 6f # No flags or only CPUID.FPU = no CR4
|
|
|
|
|
|
movl pa(mmu_cr4_features),%eax
|
|
|
movl %eax,%cr4
|
|
@@ -377,14 +386,6 @@ default_entry:
|
|
|
/* Shift the stack pointer to a virtual address */
|
|
|
addl $__PAGE_OFFSET, %esp
|
|
|
|
|
|
-/*
|
|
|
- * Initialize eflags. Some BIOS's leave bits like NT set. This would
|
|
|
- * confuse the debugger if this code is traced.
|
|
|
- * XXX - best to initialize before switching to protected mode.
|
|
|
- */
|
|
|
- pushl $0
|
|
|
- popfl
|
|
|
-
|
|
|
/*
|
|
|
* start system 32-bit setup. We need to re-do some of the things done
|
|
|
* in 16-bit mode for the "real" operations.
|
|
@@ -461,7 +462,6 @@ is486: movl $0x50022,%ecx # set AM, WP, NE and MP
|
|
|
xorl %eax,%eax # Clear LDT
|
|
|
lldt %ax
|
|
|
|
|
|
- cld # gcc2 wants the direction flag cleared at all times
|
|
|
pushl $0 # fake return address for unwinder
|
|
|
jmp *(initial_code)
|
|
|
|