• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/x86/kernel/
1/*
2 *
3 *	verify_cpu.S - Code for cpu long mode and SSE verification. This
4 *	code has been borrowed from boot/setup.S and was introduced by
5 * 	Andi Kleen.
6 *
7 *	Copyright (c) 2007  Andi Kleen (ak@suse.de)
8 *	Copyright (c) 2007  Eric Biederman (ebiederm@xmission.com)
9 *	Copyright (c) 2007  Vivek Goyal (vgoyal@in.ibm.com)
10 *
11 * 	This source code is licensed under the GNU General Public License,
12 * 	Version 2.  See the file COPYING for more details.
13 *
14 *	This is a common code for verification whether CPU supports
15 * 	long mode and SSE or not. It is not called directly instead this
16 *	file is included at various places and compiled in that context.
17 * 	Following are the current usage.
18 *
19 * 	This file is included by both 16bit and 32bit code.
20 *
21 *	arch/x86_64/boot/setup.S : Boot cpu verification (16bit)
22 *	arch/x86_64/boot/compressed/head.S: Boot cpu verification (32bit)
23 *	arch/x86_64/kernel/trampoline.S: secondary processor verfication (16bit)
24 *	arch/x86_64/kernel/acpi/wakeup.S:Verfication at resume (16bit)
25 *
26 *	verify_cpu, returns the status of cpu check in register %eax.
27 *		0: Success    1: Failure
28 *
29 * 	The caller needs to check for the error code and take the action
30 * 	appropriately. Either display a message or halt.
31 */
32
33#include <asm/cpufeature.h>
34#include <asm/msr-index.h>
35
36verify_cpu:
37	pushfl				# Save caller passed flags
38	pushl	$0			# Kill any dangerous flags
39	popfl
40
41	pushfl				# standard way to check for cpuid
42	popl	%eax
43	movl	%eax,%ebx
44	xorl	$0x200000,%eax
45	pushl	%eax
46	popfl
47	pushfl
48	popl	%eax
49	cmpl	%eax,%ebx
50	jz	verify_cpu_no_longmode	# cpu has no cpuid
51
52	movl	$0x0,%eax		# See if cpuid 1 is implemented
53	cpuid
54	cmpl	$0x1,%eax
55	jb	verify_cpu_no_longmode	# no cpuid 1
56
57	xor	%di,%di
58	cmpl	$0x68747541,%ebx	# AuthenticAMD
59	jnz	verify_cpu_noamd
60	cmpl	$0x69746e65,%edx
61	jnz	verify_cpu_noamd
62	cmpl	$0x444d4163,%ecx
63	jnz	verify_cpu_noamd
64	mov	$1,%di			# cpu is from AMD
65
66verify_cpu_noamd:
67	movl    $0x1,%eax		# Does the cpu have what it takes
68	cpuid
69	andl	$REQUIRED_MASK0,%edx
70	xorl	$REQUIRED_MASK0,%edx
71	jnz	verify_cpu_no_longmode
72
73	movl    $0x80000000,%eax	# See if extended cpuid is implemented
74	cpuid
75	cmpl    $0x80000001,%eax
76	jb      verify_cpu_no_longmode	# no extended cpuid
77
78	movl    $0x80000001,%eax	# Does the cpu have what it takes
79	cpuid
80	andl    $REQUIRED_MASK1,%edx
81	xorl    $REQUIRED_MASK1,%edx
82	jnz     verify_cpu_no_longmode
83
84verify_cpu_sse_test:
85	movl	$1,%eax
86	cpuid
87	andl	$SSE_MASK,%edx
88	cmpl	$SSE_MASK,%edx
89	je	verify_cpu_sse_ok
90	test	%di,%di
91	jz	verify_cpu_no_longmode	# only try to force SSE on AMD
92	movl	$MSR_K7_HWCR,%ecx
93	rdmsr
94	btr	$15,%eax		# enable SSE
95	wrmsr
96	xor	%di,%di			# don't loop
97	jmp	verify_cpu_sse_test	# try again
98
99verify_cpu_no_longmode:
100	popfl				# Restore caller passed flags
101	movl $1,%eax
102	ret
103verify_cpu_sse_ok:
104	popfl				# Restore caller passed flags
105	xorl %eax, %eax
106	ret
107