diff options
-rw-r--r-- | arch/x86/kernel/head_32.S | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index a9c5cc851285..e3725a0f4327 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -307,30 +307,39 @@ default_entry: | |||
307 | movl %eax,%cr0 | 307 | movl %eax,%cr0 |
308 | 308 | ||
309 | /* | 309 | /* |
310 | * New page tables may be in 4Mbyte page mode and may | 310 | * We want to start out with EFLAGS unambiguously cleared. Some BIOSes leave |
311 | * be using the global pages. | 311 | * bits like NT set. This would confuse the debugger if this code is traced. So |
312 | * initialize them properly now before switching to protected mode. That means | ||
313 | * DF in particular (even though we have cleared it earlier after copying the | ||
314 | * command line) because GCC expects it. | ||
315 | */ | ||
316 | pushl $0 | ||
317 | popfl | ||
318 | |||
319 | /* | ||
320 | * New page tables may be in 4Mbyte page mode and may be using the global pages. | ||
312 | * | 321 | * |
313 | * NOTE! If we are on a 486 we may have no cr4 at all! | 322 | * NOTE! If we are on a 486 we may have no cr4 at all! Specifically, cr4 exists |
314 | * Specifically, cr4 exists if and only if CPUID exists | 323 | * if and only if CPUID exists and has flags other than the FPU flag set. |
315 | * and has flags other than the FPU flag set. | ||
316 | */ | 324 | */ |
325 | movl $-1,pa(X86_CPUID) # preset CPUID level | ||
317 | movl $X86_EFLAGS_ID,%ecx | 326 | movl $X86_EFLAGS_ID,%ecx |
318 | pushl %ecx | 327 | pushl %ecx |
319 | popfl | 328 | popfl # set EFLAGS=ID |
320 | pushfl | ||
321 | popl %eax | ||
322 | pushl $0 | ||
323 | popfl | ||
324 | pushfl | 329 | pushfl |
325 | popl %edx | 330 | popl %eax # get EFLAGS |
326 | xorl %edx,%eax | 331 | testl $X86_EFLAGS_ID,%eax # did EFLAGS.ID remained set? |
327 | testl %ecx,%eax | 332 | jz 6f # hw disallowed setting of ID bit |
328 | jz 6f # No ID flag = no CPUID = no CR4 | 333 | # which means no CPUID and no CR4 |
334 | |||
335 | xorl %eax,%eax | ||
336 | cpuid | ||
337 | movl %eax,pa(X86_CPUID) # save largest std CPUID function | ||
329 | 338 | ||
330 | movl $1,%eax | 339 | movl $1,%eax |
331 | cpuid | 340 | cpuid |
332 | andl $~1,%edx # Ignore CPUID.FPU | 341 | andl $~1,%edx # Ignore CPUID.FPU |
333 | jz 6f # No flags or only CPUID.FPU = no CR4 | 342 | jz 6f # No flags or only CPUID.FPU = no CR4 |
334 | 343 | ||
335 | movl pa(mmu_cr4_features),%eax | 344 | movl pa(mmu_cr4_features),%eax |
336 | movl %eax,%cr4 | 345 | movl %eax,%cr4 |
@@ -378,14 +387,6 @@ default_entry: | |||
378 | addl $__PAGE_OFFSET, %esp | 387 | addl $__PAGE_OFFSET, %esp |
379 | 388 | ||
380 | /* | 389 | /* |
381 | * Initialize eflags. Some BIOS's leave bits like NT set. This would | ||
382 | * confuse the debugger if this code is traced. | ||
383 | * XXX - best to initialize before switching to protected mode. | ||
384 | */ | ||
385 | pushl $0 | ||
386 | popfl | ||
387 | |||
388 | /* | ||
389 | * start system 32-bit setup. We need to re-do some of the things done | 390 | * start system 32-bit setup. We need to re-do some of the things done |
390 | * in 16-bit mode for the "real" operations. | 391 | * in 16-bit mode for the "real" operations. |
391 | */ | 392 | */ |
@@ -461,7 +462,6 @@ is486: movl $0x50022,%ecx # set AM, WP, NE and MP | |||
461 | xorl %eax,%eax # Clear LDT | 462 | xorl %eax,%eax # Clear LDT |
462 | lldt %ax | 463 | lldt %ax |
463 | 464 | ||
464 | cld # gcc2 wants the direction flag cleared at all times | ||
465 | pushl $0 # fake return address for unwinder | 465 | pushl $0 # fake return address for unwinder |
466 | jmp *(initial_code) | 466 | jmp *(initial_code) |
467 | 467 | ||