You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
1.7 KiB
94 lines
1.7 KiB
/* Check if CPU has some minimum CPUID bits
|
|
This runs in 16bit mode so that the caller can still use the BIOS
|
|
to output errors on the screen */
|
|
#include <asm/cpufeature.h>
|
|
#include <asm/msr.h>
|
|
|
|
verify_cpu:
|
|
pushfl # Save caller passed flags
|
|
pushl $0 # Kill any dangerous flags
|
|
popfl
|
|
|
|
#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
|
|
pushfl
|
|
pop %eax
|
|
orl $(1<<18),%eax # try setting AC
|
|
push %eax
|
|
popfl
|
|
pushfl
|
|
popl %eax
|
|
testl $(1<<18),%eax
|
|
jz bad
|
|
#endif
|
|
#if REQUIRED_MASK1 != 0
|
|
pushfl # standard way to check for cpuid
|
|
popl %eax
|
|
movl %eax,%ebx
|
|
xorl $0x200000,%eax
|
|
pushl %eax
|
|
popfl
|
|
pushfl
|
|
popl %eax
|
|
cmpl %eax,%ebx
|
|
pushfl # standard way to check for cpuid
|
|
popl %eax
|
|
movl %eax,%ebx
|
|
xorl $0x200000,%eax
|
|
pushl %eax
|
|
popfl
|
|
pushfl
|
|
popl %eax
|
|
cmpl %eax,%ebx
|
|
jz bad # REQUIRED_MASK1 != 0 requires CPUID
|
|
|
|
movl $0x0,%eax # See if cpuid 1 is implemented
|
|
cpuid
|
|
cmpl $0x1,%eax
|
|
jb bad # no cpuid 1
|
|
|
|
#if REQUIRED_MASK1 & NEED_CMPXCHG64
|
|
/* Some VIA C3s need magic MSRs to enable CX64. Do this here */
|
|
cmpl $0x746e6543,%ebx # Cent
|
|
jne 1f
|
|
cmpl $0x48727561,%edx # aurH
|
|
jne 1f
|
|
cmpl $0x736c7561,%ecx # auls
|
|
jne 1f
|
|
movl $1,%eax # check model
|
|
cpuid
|
|
movl %eax,%ebx
|
|
shr $8,%ebx
|
|
andl $0xf,%ebx
|
|
cmp $6,%ebx # check family == 6
|
|
jne 1f
|
|
shr $4,%eax
|
|
andl $0xf,%eax
|
|
cmpl $6,%eax # check model >= 6
|
|
jb 1f
|
|
# assume models >= 6 all support this MSR
|
|
movl $MSR_VIA_FCR,%ecx
|
|
rdmsr
|
|
orl $((1<<1)|(1<<7)),%eax # enable CMPXCHG64 and PGE
|
|
wrmsr
|
|
1:
|
|
#endif
|
|
movl $0x1,%eax # Does the cpu have what it takes
|
|
cpuid
|
|
|
|
#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
|
|
#error add proper model checking here
|
|
#endif
|
|
|
|
andl $REQUIRED_MASK1,%edx
|
|
xorl $REQUIRED_MASK1,%edx
|
|
jnz bad
|
|
#endif /* REQUIRED_MASK1 */
|
|
|
|
popfl
|
|
xor %eax,%eax
|
|
ret
|
|
|
|
bad:
|
|
popfl
|
|
movl $1,%eax
|
|
ret
|
|
|