diff options
-rw-r--r-- | arch/i386/Kconfig.cpu | 22 | ||||
-rw-r--r-- | arch/i386/boot/setup.S | 17 | ||||
-rw-r--r-- | arch/i386/kernel/verify_cpu.S | 65 | ||||
-rw-r--r-- | include/asm-i386/cpufeature.h | 3 | ||||
-rw-r--r-- | include/asm-i386/required-features.h | 34 |
5 files changed, 139 insertions, 2 deletions
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index b1af9f50a143..dce6124cb842 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu | |||
@@ -240,14 +240,19 @@ config X86_L1_CACHE_SHIFT | |||
240 | default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX | 240 | default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX |
241 | default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 | 241 | default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 |
242 | 242 | ||
243 | config X86_XADD | ||
244 | bool | ||
245 | depends on !M386 | ||
246 | default y | ||
247 | |||
243 | config RWSEM_GENERIC_SPINLOCK | 248 | config RWSEM_GENERIC_SPINLOCK |
244 | bool | 249 | bool |
245 | depends on M386 | 250 | depends on !X86_XADD |
246 | default y | 251 | default y |
247 | 252 | ||
248 | config RWSEM_XCHGADD_ALGORITHM | 253 | config RWSEM_XCHGADD_ALGORITHM |
249 | bool | 254 | bool |
250 | depends on !M386 | 255 | depends on X86_XADD |
251 | default y | 256 | default y |
252 | 257 | ||
253 | config ARCH_HAS_ILOG2_U32 | 258 | config ARCH_HAS_ILOG2_U32 |
@@ -331,3 +336,16 @@ config X86_TSC | |||
331 | bool | 336 | bool |
332 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ | 337 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ |
333 | default y | 338 | default y |
339 | |||
340 | # this should be set for all -march=.. options where the compiler | ||
341 | # generates cmov. | ||
342 | config X86_CMOV | ||
343 | bool | ||
344 | depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7) | ||
345 | default y | ||
346 | |||
347 | config X86_MINIMUM_CPU_MODEL | ||
348 | int | ||
349 | default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP | ||
350 | default "0" | ||
351 | |||
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index b74b7f40b79c..f8b3b9cda2b1 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S | |||
@@ -302,7 +302,24 @@ good_sig: | |||
302 | 302 | ||
303 | loader_panic_mess: .string "Wrong loader, giving up..." | 303 | loader_panic_mess: .string "Wrong loader, giving up..." |
304 | 304 | ||
305 | # check minimum cpuid | ||
306 | # we do this here because it is the last place we can actually | ||
307 | # show a user visible error message. Later the video modus | ||
308 | # might be already messed up. | ||
305 | loader_ok: | 309 | loader_ok: |
310 | call verify_cpu | ||
311 | testl %eax,%eax | ||
312 | jz cpu_ok | ||
313 | lea cpu_panic_mess,%si | ||
314 | call prtstr | ||
315 | 1: jmp 1b | ||
316 | |||
317 | cpu_panic_mess: | ||
318 | .asciz "PANIC: CPU too old for this kernel." | ||
319 | |||
320 | #include "../kernel/verify_cpu.S" | ||
321 | |||
322 | cpu_ok: | ||
306 | # Get memory size (extended mem, kB) | 323 | # Get memory size (extended mem, kB) |
307 | 324 | ||
308 | xorl %eax, %eax | 325 | xorl %eax, %eax |
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S new file mode 100644 index 000000000000..e51a8695d54e --- /dev/null +++ b/arch/i386/kernel/verify_cpu.S | |||
@@ -0,0 +1,65 @@ | |||
1 | /* Check if CPU has some minimum CPUID bits | ||
2 | This runs in 16bit mode so that the caller can still use the BIOS | ||
3 | to output errors on the screen */ | ||
4 | #include <asm/cpufeature.h> | ||
5 | |||
6 | verify_cpu: | ||
7 | pushfl # Save caller passed flags | ||
8 | pushl $0 # Kill any dangerous flags | ||
9 | popfl | ||
10 | |||
11 | #if CONFIG_X86_MINIMUM_CPU_MODEL >= 4 | ||
12 | pushfl | ||
13 | orl $(1<<18),(%esp) # try setting AC | ||
14 | popfl | ||
15 | pushfl | ||
16 | popl %eax | ||
17 | testl $(1<<18),%eax | ||
18 | jz bad | ||
19 | #endif | ||
20 | #if REQUIRED_MASK1 != 0 | ||
21 | pushfl # standard way to check for cpuid | ||
22 | popl %eax | ||
23 | movl %eax,%ebx | ||
24 | xorl $0x200000,%eax | ||
25 | pushl %eax | ||
26 | popfl | ||
27 | pushfl | ||
28 | popl %eax | ||
29 | cmpl %eax,%ebx | ||
30 | pushfl # standard way to check for cpuid | ||
31 | popl %eax | ||
32 | movl %eax,%ebx | ||
33 | xorl $0x200000,%eax | ||
34 | pushl %eax | ||
35 | popfl | ||
36 | pushfl | ||
37 | popl %eax | ||
38 | cmpl %eax,%ebx | ||
39 | jz bad # REQUIRED_MASK1 != 0 requires CPUID | ||
40 | |||
41 | movl $0x0,%eax # See if cpuid 1 is implemented | ||
42 | cpuid | ||
43 | cmpl $0x1,%eax | ||
44 | jb bad # no cpuid 1 | ||
45 | |||
46 | movl $0x1,%eax # Does the cpu have what it takes | ||
47 | cpuid | ||
48 | |||
49 | #if CONFIG_X86_MINIMUM_CPU_MODEL > 4 | ||
50 | #error add proper model checking here | ||
51 | #endif | ||
52 | |||
53 | andl $REQUIRED_MASK1,%edx | ||
54 | xorl $REQUIRED_MASK1,%edx | ||
55 | jnz bad | ||
56 | #endif /* REQUIRED_MASK1 */ | ||
57 | |||
58 | popfl | ||
59 | xor %eax,%eax | ||
60 | ret | ||
61 | |||
62 | bad: | ||
63 | popfl | ||
64 | movl $1,%eax | ||
65 | ret | ||
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index d1b8e4ab6c1a..e66d004aa651 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h | |||
@@ -7,7 +7,10 @@ | |||
7 | #ifndef __ASM_I386_CPUFEATURE_H | 7 | #ifndef __ASM_I386_CPUFEATURE_H |
8 | #define __ASM_I386_CPUFEATURE_H | 8 | #define __ASM_I386_CPUFEATURE_H |
9 | 9 | ||
10 | #ifndef __ASSEMBLY__ | ||
10 | #include <linux/bitops.h> | 11 | #include <linux/bitops.h> |
12 | #endif | ||
13 | #include <asm/required-features.h> | ||
11 | 14 | ||
12 | #define NCAPINTS 7 /* N 32-bit words worth of info */ | 15 | #define NCAPINTS 7 /* N 32-bit words worth of info */ |
13 | 16 | ||
diff --git a/include/asm-i386/required-features.h b/include/asm-i386/required-features.h new file mode 100644 index 000000000000..9db866c1e64c --- /dev/null +++ b/include/asm-i386/required-features.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef _ASM_REQUIRED_FEATURES_H | ||
2 | #define _ASM_REQUIRED_FEATURES_H 1 | ||
3 | |||
4 | /* Define minimum CPUID feature set for kernel These bits are checked | ||
5 | really early to actually display a visible error message before the | ||
6 | kernel dies. Only add word 0 bits here | ||
7 | |||
8 | Some requirements that are not in CPUID yet are also in the | ||
9 | CONFIG_X86_MINIMUM_CPU mode which is checked too. | ||
10 | |||
11 | The real information is in arch/i386/Kconfig.cpu, this just converts | ||
12 | the CONFIGs into a bitmask */ | ||
13 | |||
14 | #ifdef CONFIG_X86_PAE | ||
15 | #define NEED_PAE (1<<X86_FEATURE_PAE) | ||
16 | #else | ||
17 | #define NEED_PAE 0 | ||
18 | #endif | ||
19 | |||
20 | #ifdef CONFIG_X86_CMOV | ||
21 | #define NEED_CMOV (1<<X86_FEATURE_CMOV) | ||
22 | #else | ||
23 | #define NEED_CMOV 0 | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_X86_CMPXCHG64 | ||
27 | #define NEED_CMPXCHG64 (1<<X86_FEATURE_CX8) | ||
28 | #else | ||
29 | #define NEED_CMPXCHG64 0 | ||
30 | #endif | ||
31 | |||
32 | #define REQUIRED_MASK1 (NEED_PAE|NEED_CMOV|NEED_CMPXCHG64) | ||
33 | |||
34 | #endif | ||