2008-02-08 15:19:31 +03:00
/ * MN1 0 3 0 0 L o w l e v e l F P U m a n a g e m e n t o p e r a t i o n s
*
* Copyright ( C ) 2 0 0 7 R e d H a t , I n c . A l l R i g h t s R e s e r v e d .
* Written b y D a v i d H o w e l l s ( d h o w e l l s @redhat.com)
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or
* modify i t u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n c e
* as p u b l i s h e d b y t h e F r e e S o f t w a r e F o u n d a t i o n ; either version
* 2 of t h e L i c e n c e , o r ( a t y o u r o p t i o n ) a n y l a t e r v e r s i o n .
* /
2010-10-27 20:28:52 +04:00
# include < l i n u x / l i n k a g e . h >
2008-02-08 15:19:31 +03:00
# include < a s m / c p u - r e g s . h >
2010-10-27 20:28:52 +04:00
# include < a s m / s m p . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / f r a m e . i n c >
2008-02-08 15:19:31 +03:00
2010-10-27 20:28:52 +04:00
.macro FPU_INIT_STATE_ALL
2008-02-08 15:19:31 +03:00
fmov 0 ,f s0
fmov f s0 ,f s1
fmov f s0 ,f s2
fmov f s0 ,f s3
fmov f s0 ,f s4
fmov f s0 ,f s5
fmov f s0 ,f s6
fmov f s0 ,f s7
fmov f s0 ,f s8
fmov f s0 ,f s9
fmov f s0 ,f s10
fmov f s0 ,f s11
fmov f s0 ,f s12
fmov f s0 ,f s13
fmov f s0 ,f s14
fmov f s0 ,f s15
fmov f s0 ,f s16
fmov f s0 ,f s17
fmov f s0 ,f s18
fmov f s0 ,f s19
fmov f s0 ,f s20
fmov f s0 ,f s21
fmov f s0 ,f s22
fmov f s0 ,f s23
fmov f s0 ,f s24
fmov f s0 ,f s25
fmov f s0 ,f s26
fmov f s0 ,f s27
fmov f s0 ,f s28
fmov f s0 ,f s29
fmov f s0 ,f s30
fmov f s0 ,f s31
fmov F P C R _ I N I T ,f p c r
2010-10-27 20:28:52 +04:00
.endm
.macro FPU_SAVE_ALL areg,d r e g
fmov f s0 ,( \ a r e g + )
fmov f s1 ,( \ a r e g + )
fmov f s2 ,( \ a r e g + )
fmov f s3 ,( \ a r e g + )
fmov f s4 ,( \ a r e g + )
fmov f s5 ,( \ a r e g + )
fmov f s6 ,( \ a r e g + )
fmov f s7 ,( \ a r e g + )
fmov f s8 ,( \ a r e g + )
fmov f s9 ,( \ a r e g + )
fmov f s10 ,( \ a r e g + )
fmov f s11 ,( \ a r e g + )
fmov f s12 ,( \ a r e g + )
fmov f s13 ,( \ a r e g + )
fmov f s14 ,( \ a r e g + )
fmov f s15 ,( \ a r e g + )
fmov f s16 ,( \ a r e g + )
fmov f s17 ,( \ a r e g + )
fmov f s18 ,( \ a r e g + )
fmov f s19 ,( \ a r e g + )
fmov f s20 ,( \ a r e g + )
fmov f s21 ,( \ a r e g + )
fmov f s22 ,( \ a r e g + )
fmov f s23 ,( \ a r e g + )
fmov f s24 ,( \ a r e g + )
fmov f s25 ,( \ a r e g + )
fmov f s26 ,( \ a r e g + )
fmov f s27 ,( \ a r e g + )
fmov f s28 ,( \ a r e g + )
fmov f s29 ,( \ a r e g + )
fmov f s30 ,( \ a r e g + )
fmov f s31 ,( \ a r e g + )
fmov f p c r ,\ d r e g
mov \ d r e g ,( \ a r e g )
.endm
.macro FPU_RESTORE_ALL areg,d r e g
fmov ( \ a r e g + ) ,f s0
fmov ( \ a r e g + ) ,f s1
fmov ( \ a r e g + ) ,f s2
fmov ( \ a r e g + ) ,f s3
fmov ( \ a r e g + ) ,f s4
fmov ( \ a r e g + ) ,f s5
fmov ( \ a r e g + ) ,f s6
fmov ( \ a r e g + ) ,f s7
fmov ( \ a r e g + ) ,f s8
fmov ( \ a r e g + ) ,f s9
fmov ( \ a r e g + ) ,f s10
fmov ( \ a r e g + ) ,f s11
fmov ( \ a r e g + ) ,f s12
fmov ( \ a r e g + ) ,f s13
fmov ( \ a r e g + ) ,f s14
fmov ( \ a r e g + ) ,f s15
fmov ( \ a r e g + ) ,f s16
fmov ( \ a r e g + ) ,f s17
fmov ( \ a r e g + ) ,f s18
fmov ( \ a r e g + ) ,f s19
fmov ( \ a r e g + ) ,f s20
fmov ( \ a r e g + ) ,f s21
fmov ( \ a r e g + ) ,f s22
fmov ( \ a r e g + ) ,f s23
fmov ( \ a r e g + ) ,f s24
fmov ( \ a r e g + ) ,f s25
fmov ( \ a r e g + ) ,f s26
fmov ( \ a r e g + ) ,f s27
fmov ( \ a r e g + ) ,f s28
fmov ( \ a r e g + ) ,f s29
fmov ( \ a r e g + ) ,f s30
fmov ( \ a r e g + ) ,f s31
mov ( \ a r e g ) ,\ d r e g
fmov \ d r e g ,f p c r
.endm
2008-02-08 15:19:31 +03:00
2010-10-27 20:28:52 +04:00
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# void f p u _ i n i t _ s t a t e ( v o i d )
# - initialise t h e F P U
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl fpu_init_state
.type fpu_ i n i t _ s t a t e ,@function
fpu_init_state :
mov e p s w ,d0
or E P S W _ F E ,e p s w
# ifdef C O N F I G _ M N 1 0 3 0 0 _ P R O C _ M N 1 0 3 E 0 1 0
nop
nop
nop
# endif
FPU_ I N I T _ S T A T E _ A L L
2008-02-08 15:19:31 +03:00
# ifdef C O N F I G _ M N 1 0 3 0 0 _ P R O C _ M N 1 0 3 E 0 1 0
nop
nop
nop
# endif
mov d0 ,e p s w
ret [ ] ,0
.size fpu_ i n i t _ s t a t e ,. - f p u _ i n i t _ s t a t e
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# void f p u _ s a v e ( s t r u c t f p u _ s t a t e _ s t r u c t * )
# - save t h e f p u s t a t e
# - note t h a t a n F P U O p e r a t i o n a l e x c e p t i o n m i g h t o c c u r d u r i n g t h i s p r o c e s s
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl fpu_save
.type fpu_ s a v e ,@function
fpu_save :
mov e p s w ,d1
or E P S W _ F E ,e p s w / * e n a b l e t h e F P U s o w e c a n a c c e s s i t * /
# ifdef C O N F I G _ M N 1 0 3 0 0 _ P R O C _ M N 1 0 3 E 0 1 0
nop
nop
# endif
mov d0 ,a0
2010-10-27 20:28:52 +04:00
FPU_ S A V E _ A L L a0 ,d0
2008-02-08 15:19:31 +03:00
# ifdef C O N F I G _ M N 1 0 3 0 0 _ P R O C _ M N 1 0 3 E 0 1 0
nop
nop
# endif
mov d1 ,e p s w
ret [ ] ,0
.size fpu_ s a v e ,. - f p u _ s a v e
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
2010-10-27 20:28:52 +04:00
# void f p u _ d i s a b l e d ( v o i d )
# - handle a n e x c e p t i o n d u e t o t h e F P U b e i n g d i s a b l e d
# when C O N F I G _ F P U i s e n a b l e d
2008-02-08 15:19:31 +03:00
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
2010-10-27 20:28:52 +04:00
.type fpu_ d i s a b l e d ,@function
.globl fpu_disabled
fpu_disabled :
or E P S W _ n A R | E P S W _ F E ,e p s w
2008-02-08 15:19:31 +03:00
nop
nop
nop
2010-10-27 20:28:52 +04:00
mov s p ,a1
mov ( a1 ) ,d1 / * g e t e p s w o f u s e r c o n t e x t * /
and ~ ( T H R E A D _ S I Z E - 1 ) ,a1 / * a1 : ( t h r e a d _ i n f o * t i ) * /
mov ( T I _ t a s k ,a1 ) ,a2 / * a2 : ( t a s k _ s t r u c t * t s k ) * /
btst E P S W _ n S L ,d1
beq f p u _ u s e d _ i n _ k e r n e l
or E P S W _ F E ,d1
mov d1 ,( s p )
mov ( T A S K _ T H R E A D + T H R E A D _ F P U _ F L A G S ,a2 ) ,d1
# ifndef C O N F I G _ L A Z Y _ S A V E _ F P U
or _ _ T H R E A D _ H A S _ F P U ,d1
mov d1 ,( T A S K _ T H R E A D + T H R E A D _ F P U _ F L A G S ,a2 )
# else / * ! C O N F I G _ L A Z Y _ S A V E _ F P U * /
mov ( f p u _ s t a t e _ o w n e r ) ,a0
cmp 0 ,a0
beq f p u _ r e g s _ s a v e _ e n d
mov ( T A S K _ T H R E A D + T H R E A D _ U R E G S ,a0 ) ,a1
add T A S K _ T H R E A D + T H R E A D _ F P U _ S T A T E ,a0
FPU_ S A V E _ A L L a0 ,d0
mov ( R E G _ E P S W ,a1 ) ,d0
and ~ E P S W _ F E ,d0
mov d0 ,( R E G _ E P S W ,a1 )
fpu_regs_save_end :
mov a2 ,( f p u _ s t a t e _ o w n e r )
# endif / * ! C O N F I G _ L A Z Y _ S A V E _ F P U * /
btst _ _ T H R E A D _ U S I N G _ F P U ,d1
beq f p u _ r e g s _ i n i t
add T A S K _ T H R E A D + T H R E A D _ F P U _ S T A T E ,a2
FPU_ R E S T O R E _ A L L a2 ,d0
rti
fpu_regs_init :
FPU_ I N I T _ S T A T E _ A L L
add T A S K _ T H R E A D + T H R E A D _ F P U _ F L A G S ,a2
bset _ _ T H R E A D _ U S I N G _ F P U ,( 0 ,a2 )
rti
fpu_used_in_kernel :
and ~ ( E P S W _ n A R | E P S W _ F E ) ,e p s w
2008-02-08 15:19:31 +03:00
nop
nop
2010-10-27 20:28:52 +04:00
add - 4 ,s p
SAVE_ A L L
mov - 1 ,d0
mov d0 ,( R E G _ O R I G _ D 0 ,f p )
and ~ E P S W _ N M I D ,e p s w
mov f p ,d0
call f p u _ d i s a b l e d _ i n _ k e r n e l [ ] ,0
jmp r e t _ f r o m _ e x c e p t i o n
2008-02-08 15:19:31 +03:00
2010-10-27 20:28:52 +04:00
.size fpu_ d i s a b l e d ,. - f p u _ d i s a b l e d