aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/boot
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2007-05-02 13:27:08 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:08 -0400
commita4831e08b7f3ed51623c9eb25e8c945b76b3eda3 (patch)
treecc38c9df02560fba778dfbff5f389e4ac3b720b9 /arch/x86_64/boot
parent8035d3ea78c2a61a9738c7857742370e0aa74d5c (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.S19
-rw-r--r--arch/x86_64/boot/setup.S65
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:
541: popl %ebp 541: 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
171no_longmode:
172 /* This isn't an x86-64 CPU so hang */
1731:
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
169ENTRY(startup_64) 186ENTRY(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 */
331noamd:
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
346sse_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 */
360no_longmode: 306no_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:
366long_mode_panic: 312long_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"
370sse_ok: 317sse_ok:
371 popw %ds 318 popw %ds
372 319