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 | ||
