diff options
author | Vivek Goyal <vgoyal@in.ibm.com> | 2007-05-02 13:27:08 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 13:27:08 -0400 |
commit | a4831e08b7f3ed51623c9eb25e8c945b76b3eda3 (patch) | |
tree | cc38c9df02560fba778dfbff5f389e4ac3b720b9 /arch/x86_64/boot | |
parent | 8035d3ea78c2a61a9738c7857742370e0aa74d5c (diff) |
[PATCH] x86-64: Move cpu verification code to common file
o This patch moves the code to verify long mode and SSE to a common file.
This code is now shared by trampoline.S, wakeup.S, boot/setup.S and
boot/compressed/head.S
o So far we used to do very limited check in trampoline.S, wakeup.S and
in 32bit entry point. Now all the entry paths are forced to do the
exhaustive check, including SSE because verify_cpu is shared.
o I am keeping this patch as last in the x86 relocatable series because
previous patches have got quite some amount of testing done and don't want
to distrub that. So that if there is problem introduced by this patch, at
least it can be easily isolated.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/boot')
-rw-r--r-- | arch/x86_64/boot/compressed/head.S | 19 | ||||
-rw-r--r-- | arch/x86_64/boot/setup.S | 65 |
2 files changed, 24 insertions, 60 deletions
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index c353a9266ea4..f9d5692a0106 100644 --- a/arch/x86_64/boot/compressed/head.S +++ b/arch/x86_64/boot/compressed/head.S | |||
@@ -54,6 +54,15 @@ startup_32: | |||
54 | 1: popl %ebp | 54 | 1: popl %ebp |
55 | subl $1b, %ebp | 55 | subl $1b, %ebp |
56 | 56 | ||
57 | /* setup a stack and make sure cpu supports long mode. */ | ||
58 | movl $user_stack_end, %eax | ||
59 | addl %ebp, %eax | ||
60 | movl %eax, %esp | ||
61 | |||
62 | call verify_cpu | ||
63 | testl %eax, %eax | ||
64 | jnz no_longmode | ||
65 | |||
57 | /* Compute the delta between where we were compiled to run at | 66 | /* Compute the delta between where we were compiled to run at |
58 | * and where the code will actually run at. | 67 | * and where the code will actually run at. |
59 | */ | 68 | */ |
@@ -159,13 +168,21 @@ startup_32: | |||
159 | /* Jump from 32bit compatibility mode into 64bit mode. */ | 168 | /* Jump from 32bit compatibility mode into 64bit mode. */ |
160 | lret | 169 | lret |
161 | 170 | ||
171 | no_longmode: | ||
172 | /* This isn't an x86-64 CPU so hang */ | ||
173 | 1: | ||
174 | hlt | ||
175 | jmp 1b | ||
176 | |||
177 | #include "../../kernel/verify_cpu.S" | ||
178 | |||
162 | /* Be careful here startup_64 needs to be at a predictable | 179 | /* Be careful here startup_64 needs to be at a predictable |
163 | * address so I can export it in an ELF header. Bootloaders | 180 | * address so I can export it in an ELF header. Bootloaders |
164 | * should look at the ELF header to find this address, as | 181 | * should look at the ELF header to find this address, as |
165 | * it may change in the future. | 182 | * it may change in the future. |
166 | */ | 183 | */ |
167 | .code64 | 184 | .code64 |
168 | .org 0x100 | 185 | .org 0x200 |
169 | ENTRY(startup_64) | 186 | ENTRY(startup_64) |
170 | /* We come here either from startup_32 or directly from a | 187 | /* We come here either from startup_32 or directly from a |
171 | * 64bit bootloader. If we come here from a bootloader we depend on | 188 | * 64bit bootloader. If we come here from a bootloader we depend on |
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 | ||