diff options
Diffstat (limited to 'arch/x86_64/boot/setup.S')
-rw-r--r-- | arch/x86_64/boot/setup.S | 65 |
1 files changed, 6 insertions, 59 deletions
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index deb3573c7aec..816d04faa2be 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S | |||
@@ -299,64 +299,10 @@ loader_ok: | |||
299 | movw %cs,%ax | 299 | movw %cs,%ax |
300 | movw %ax,%ds | 300 | movw %ax,%ds |
301 | 301 | ||
302 | /* minimum CPUID flags for x86-64 */ | 302 | call verify_cpu |
303 | /* see http://www.x86-64.org/lists/discuss/msg02971.html */ | 303 | testl %eax,%eax |
304 | #define SSE_MASK ((1<<25)|(1<<26)) | 304 | jz sse_ok |
305 | #define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ | 305 | |
306 | (1<<13)|(1<<15)|(1<<24)) | ||
307 | #define REQUIRED_MASK2 (1<<29) | ||
308 | |||
309 | pushfl /* standard way to check for cpuid */ | ||
310 | popl %eax | ||
311 | movl %eax,%ebx | ||
312 | xorl $0x200000,%eax | ||
313 | pushl %eax | ||
314 | popfl | ||
315 | pushfl | ||
316 | popl %eax | ||
317 | cmpl %eax,%ebx | ||
318 | jz no_longmode /* cpu has no cpuid */ | ||
319 | movl $0x0,%eax | ||
320 | cpuid | ||
321 | cmpl $0x1,%eax | ||
322 | jb no_longmode /* no cpuid 1 */ | ||
323 | xor %di,%di | ||
324 | cmpl $0x68747541,%ebx /* AuthenticAMD */ | ||
325 | jnz noamd | ||
326 | cmpl $0x69746e65,%edx | ||
327 | jnz noamd | ||
328 | cmpl $0x444d4163,%ecx | ||
329 | jnz noamd | ||
330 | mov $1,%di /* cpu is from AMD */ | ||
331 | noamd: | ||
332 | movl $0x1,%eax | ||
333 | cpuid | ||
334 | andl $REQUIRED_MASK1,%edx | ||
335 | xorl $REQUIRED_MASK1,%edx | ||
336 | jnz no_longmode | ||
337 | movl $0x80000000,%eax | ||
338 | cpuid | ||
339 | cmpl $0x80000001,%eax | ||
340 | jb no_longmode /* no extended cpuid */ | ||
341 | movl $0x80000001,%eax | ||
342 | cpuid | ||
343 | andl $REQUIRED_MASK2,%edx | ||
344 | xorl $REQUIRED_MASK2,%edx | ||
345 | jnz no_longmode | ||
346 | sse_test: | ||
347 | movl $1,%eax | ||
348 | cpuid | ||
349 | andl $SSE_MASK,%edx | ||
350 | cmpl $SSE_MASK,%edx | ||
351 | je sse_ok | ||
352 | test %di,%di | ||
353 | jz no_longmode /* only try to force SSE on AMD */ | ||
354 | movl $0xc0010015,%ecx /* HWCR */ | ||
355 | rdmsr | ||
356 | btr $15,%eax /* enable SSE */ | ||
357 | wrmsr | ||
358 | xor %di,%di /* don't loop */ | ||
359 | jmp sse_test /* try again */ | ||
360 | no_longmode: | 306 | no_longmode: |
361 | call beep | 307 | call beep |
362 | lea long_mode_panic,%si | 308 | lea long_mode_panic,%si |
@@ -366,7 +312,8 @@ no_longmode_loop: | |||
366 | long_mode_panic: | 312 | long_mode_panic: |
367 | .string "Your CPU does not support long mode. Use a 32bit distribution." | 313 | .string "Your CPU does not support long mode. Use a 32bit distribution." |
368 | .byte 0 | 314 | .byte 0 |
369 | 315 | ||
316 | #include "../kernel/verify_cpu.S" | ||
370 | sse_ok: | 317 | sse_ok: |
371 | popw %ds | 318 | popw %ds |
372 | 319 | ||