2007-05-02 19:27:08 +02:00
/ *
*
* verify_ c p u . S - C o d e f o r c p u l o n g m o d e a n d S S E v e r i f i c a t i o n . T h i s
* code h a s b e e n b o r r o w e d f r o m b o o t / s e t u p . S a n d w a s i n t r o d u c e d b y
* Andi K l e e n .
*
* Copyright ( c ) 2 0 0 7 A n d i K l e e n ( a k @suse.de)
* Copyright ( c ) 2 0 0 7 E r i c B i e d e r m a n ( e b i e d e r m @xmission.com)
* Copyright ( c ) 2 0 0 7 V i v e k G o y a l ( v g o y a l @in.ibm.com)
*
* This s o u r c e c o d e i s l i c e n s e d u n d e r t h e G N U G e n e r a l P u b l i c L i c e n s e ,
* Version 2 . S e e t h e f i l e C O P Y I N G f o r m o r e d e t a i l s .
*
* This i s a c o m m o n c o d e f o r v e r i f i c a t i o n w h e t h e r C P U s u p p o r t s
* long m o d e a n d S S E o r n o t . I t i s n o t c a l l e d d i r e c t l y i n s t e a d t h i s
* file i s i n c l u d e d a t v a r i o u s p l a c e s a n d c o m p i l e d i n t h a t c o n t e x t .
* Following a r e t h e c u r r e n t u s a g e .
*
* This f i l e i s i n c l u d e d b y b o t h 1 6 b i t a n d 3 2 b i t c o d e .
*
* arch/ x86 _ 6 4 / b o o t / s e t u p . S : B o o t c p u v e r i f i c a t i o n ( 1 6 b i t )
* arch/ x86 _ 6 4 / b o o t / c o m p r e s s e d / h e a d . S : B o o t c p u v e r i f i c a t i o n ( 3 2 b i t )
* arch/ x86 _ 6 4 / k e r n e l / t r a m p o l i n e . S : s e c o n d a r y p r o c e s s o r v e r f i c a t i o n ( 1 6 b i t )
* arch/ x86 _ 6 4 / k e r n e l / a c p i / w a k e u p . S : V e r f i c a t i o n a t r e s u m e ( 1 6 b i t )
*
* verify_ c p u , r e t u r n s t h e s t a t u s o f c p u c h e c k i n r e g i s t e r % e a x .
* 0 : Success 1 : F a i l u r e
*
* The c a l l e r n e e d s t o c h e c k f o r t h e e r r o r c o d e a n d t a k e t h e a c t i o n
* appropriately. E i t h e r d i s p l a y a m e s s a g e o r h a l t .
* /
2007-05-02 19:27:20 +02:00
# include < a s m / c p u f e a t u r e . h >
2007-05-02 19:27:08 +02:00
2007-05-02 19:27:20 +02:00
verify_cpu :
2007-05-02 19:27:08 +02:00
pushfl # S a v e c a l l e r p a s s e d f l a g s
pushl $ 0 # K i l l a n y d a n g e r o u s f l a g s
popfl
pushfl # s t a n d a r d w a y t o c h e c k f o r c p u i d
popl % e a x
movl % e a x ,% e b x
xorl $ 0 x20 0 0 0 0 ,% e a x
pushl % e a x
popfl
pushfl
popl % e a x
cmpl % e a x ,% e b x
jz v e r i f y _ c p u _ n o _ l o n g m o d e # c p u h a s n o c p u i d
movl $ 0 x0 ,% e a x # S e e i f c p u i d 1 i s i m p l e m e n t e d
cpuid
cmpl $ 0 x1 ,% e a x
jb v e r i f y _ c p u _ n o _ l o n g m o d e # n o c p u i d 1
xor % d i ,% d i
cmpl $ 0 x68 7 4 7 5 4 1 ,% e b x # A u t h e n t i c A M D
jnz v e r i f y _ c p u _ n o a m d
cmpl $ 0 x69 7 4 6 e 6 5 ,% e d x
jnz v e r i f y _ c p u _ n o a m d
cmpl $ 0 x44 4 d41 6 3 ,% e c x
jnz v e r i f y _ c p u _ n o a m d
mov $ 1 ,% d i # c p u i s f r o m A M D
verify_cpu_noamd :
movl $ 0 x1 ,% e a x # D o e s t h e c p u h a v e w h a t i t t a k e s
cpuid
2007-07-11 12:18:29 -07:00
andl $ R E Q U I R E D _ M A S K 0 ,% e d x
xorl $ R E Q U I R E D _ M A S K 0 ,% e d x
2007-05-02 19:27:08 +02:00
jnz v e r i f y _ c p u _ n o _ l o n g m o d e
movl $ 0 x80 0 0 0 0 0 0 ,% e a x # S e e i f e x t e n d e d c p u i d i s i m p l e m e n t e d
cpuid
cmpl $ 0 x80 0 0 0 0 0 1 ,% e a x
jb v e r i f y _ c p u _ n o _ l o n g m o d e # n o e x t e n d e d c p u i d
movl $ 0 x80 0 0 0 0 0 1 ,% e a x # D o e s t h e c p u h a v e w h a t i t t a k e s
cpuid
2007-07-11 12:18:29 -07:00
andl $ R E Q U I R E D _ M A S K 1 ,% e d x
xorl $ R E Q U I R E D _ M A S K 1 ,% e d x
2007-05-02 19:27:08 +02:00
jnz v e r i f y _ c p u _ n o _ l o n g m o d e
verify_cpu_sse_test :
movl $ 1 ,% e a x
cpuid
andl $ S S E _ M A S K ,% e d x
cmpl $ S S E _ M A S K ,% e d x
je v e r i f y _ c p u _ s s e _ o k
test % d i ,% d i
jz v e r i f y _ c p u _ n o _ l o n g m o d e # o n l y t r y t o f o r c e S S E o n A M D
movl $ 0 x c00 1 0 0 1 5 ,% e c x # H W C R
rdmsr
btr $ 1 5 ,% e a x # e n a b l e S S E
wrmsr
xor % d i ,% d i # d o n ' t l o o p
jmp v e r i f y _ c p u _ s s e _ t e s t # t r y a g a i n
verify_cpu_no_longmode :
popfl # R e s t o r e c a l l e r p a s s e d f l a g s
movl $ 1 ,% e a x
ret
verify_cpu_sse_ok :
popfl # R e s t o r e c a l l e r p a s s e d f l a g s
xorl % e a x , % e a x
ret