2006-06-28 02:03:03 +04:00
/ *
* arch/ a r m / k e r n e l / c r u n c h - b i t s . S
* Cirrus M a v e r i c k C r u n c h c o n t e x t s w i t c h i n g a n d h a n d l i n g
*
* Copyright ( C ) 2 0 0 6 L e n n e r t B u y t e n h e k < b u y t e n h @wantstofly.org>
*
* Shamelessly s t o l e n f r o m t h e i W M M X t c o d e b y N i c o l a s P i t r e , w h i c h i s
* Copyright ( c ) 2 0 0 3 - 2 0 0 4 , M o n t a V i s t a S o f t w a r e , I n c .
*
* 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
* it 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 s e v e r s i o n 2 a s
* published 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 .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / p t r a c e . 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 >
2008-08-05 19:14:15 +04:00
# include < m a c h / e p93 x x - r e g s . h >
2006-06-28 02:03:03 +04:00
/ *
* We c a n ' t u s e h e x c o n s t a n t s h e r e d u e t o a b u g i n g a s .
* /
# define C R U N C H _ M V D X 0 0
# define C R U N C H _ M V D X 1 8
# define C R U N C H _ M V D X 2 1 6
# define C R U N C H _ M V D X 3 2 4
# define C R U N C H _ M V D X 4 3 2
# define C R U N C H _ M V D X 5 4 0
# define C R U N C H _ M V D X 6 4 8
# define C R U N C H _ M V D X 7 5 6
# define C R U N C H _ M V D X 8 6 4
# define C R U N C H _ M V D X 9 7 2
# define C R U N C H _ M V D X 1 0 8 0
# define C R U N C H _ M V D X 1 1 8 8
# define C R U N C H _ M V D X 1 2 9 6
# define C R U N C H _ M V D X 1 3 1 0 4
# define C R U N C H _ M V D X 1 4 1 1 2
# define C R U N C H _ M V D X 1 5 1 2 0
# define C R U N C H _ M V A X 0 L 1 2 8
# define C R U N C H _ M V A X 0 M 1 3 2
# define C R U N C H _ M V A X 0 H 1 3 6
# define C R U N C H _ M V A X 1 L 1 4 0
# define C R U N C H _ M V A X 1 M 1 4 4
# define C R U N C H _ M V A X 1 H 1 4 8
# define C R U N C H _ M V A X 2 L 1 5 2
# define C R U N C H _ M V A X 2 M 1 5 6
# define C R U N C H _ M V A X 2 H 1 6 0
# define C R U N C H _ M V A X 3 L 1 6 4
# define C R U N C H _ M V A X 3 M 1 6 8
# define C R U N C H _ M V A X 3 H 1 7 2
# define C R U N C H _ D S P S C 1 7 6
# define C R U N C H _ S I Z E 1 8 4
.text
/ *
* Lazy s w i t c h i n g o f c r u n c h c o p r o c e s s o r c o n t e x t
*
* r1 0 = s t r u c t t h r e a d _ i n f o p o i n t e r
* r9 = r e t _ f r o m _ e x c e p t i o n
* lr = u n d e f i n e d i n s t r e x i t
*
* called f r o m p r e f e t c h e x c e p t i o n h a n d l e r w i t h i n t e r r u p t s d i s a b l e d
* /
ENTRY( c r u n c h _ t a s k _ e n a b l e )
ldr r8 , = ( E P 9 3 X X _ A P B _ V I R T _ B A S E + 0 x00 1 3 0 0 0 0 ) @ syscon addr
ldr r1 , [ r8 , #0x80 ]
tst r1 , #0x00800000 @ access to crunch enabled?
movne p c , l r @ if so no business here
mov r3 , #0xaa @ unlock syscon swlock
str r3 , [ r8 , #0xc0 ]
orr r1 , r1 , #0x00800000 @ enable access to crunch
str r1 , [ r8 , #0x80 ]
ldr r3 , =crunch_owner
add r0 , r10 , #T I _ C R U N C H _ S T A T E @ g e t t a s k c r u n c h s a v e a r e a
ldr r2 , [ s p , #60 ] @ current task pc value
ldr r1 , [ r3 ] @ get current crunch owner
str r0 , [ r3 ] @ this task now owns crunch
sub r2 , r2 , #4 @ adjust pc back
str r2 , [ s p , #60 ]
ldr r2 , [ r8 , #0x80 ]
mov r2 , r2 @ flush out enable (@@@)
teq r1 , #0 @ test for last ownership
mov l r , r9 @ normal exit from exception
beq c r u n c h _ l o a d @ no owner, skip save
crunch_save :
cfstr6 4 m v d x0 , [ r1 , #C R U N C H _ M V D X 0 ] @ save 64b registers
cfstr6 4 m v d x1 , [ r1 , #C R U N C H _ M V D X 1 ]
cfstr6 4 m v d x2 , [ r1 , #C R U N C H _ M V D X 2 ]
cfstr6 4 m v d x3 , [ r1 , #C R U N C H _ M V D X 3 ]
cfstr6 4 m v d x4 , [ r1 , #C R U N C H _ M V D X 4 ]
cfstr6 4 m v d x5 , [ r1 , #C R U N C H _ M V D X 5 ]
cfstr6 4 m v d x6 , [ r1 , #C R U N C H _ M V D X 6 ]
cfstr6 4 m v d x7 , [ r1 , #C R U N C H _ M V D X 7 ]
cfstr6 4 m v d x8 , [ r1 , #C R U N C H _ M V D X 8 ]
cfstr6 4 m v d x9 , [ r1 , #C R U N C H _ M V D X 9 ]
cfstr6 4 m v d x10 , [ r1 , #C R U N C H _ M V D X 10 ]
cfstr6 4 m v d x11 , [ r1 , #C R U N C H _ M V D X 11 ]
cfstr6 4 m v d x12 , [ r1 , #C R U N C H _ M V D X 12 ]
cfstr6 4 m v d x13 , [ r1 , #C R U N C H _ M V D X 13 ]
cfstr6 4 m v d x14 , [ r1 , #C R U N C H _ M V D X 14 ]
cfstr6 4 m v d x15 , [ r1 , #C R U N C H _ M V D X 15 ]
# ifdef _ _ A R M E B _ _
# error f i x m e f o r A R M E B
# endif
cfmv3 2 a l m v f x0 , m v a x0 @ save 72b accumulators
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 0 L ]
cfmv3 2 a m m v f x0 , m v a x0
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 0 M ]
cfmv3 2 a h m v f x0 , m v a x0
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 0 H ]
cfmv3 2 a l m v f x0 , m v a x1
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 1 L ]
cfmv3 2 a m m v f x0 , m v a x1
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 1 M ]
cfmv3 2 a h m v f x0 , m v a x1
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 1 H ]
cfmv3 2 a l m v f x0 , m v a x2
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 2 L ]
cfmv3 2 a m m v f x0 , m v a x2
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 2 M ]
cfmv3 2 a h m v f x0 , m v a x2
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 2 H ]
cfmv3 2 a l m v f x0 , m v a x3
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 3 L ]
cfmv3 2 a m m v f x0 , m v a x3
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 3 M ]
cfmv3 2 a h m v f x0 , m v a x3
cfstr3 2 m v f x0 , [ r1 , #C R U N C H _ M V A X 3 H ]
cfmv3 2 s c m v d x0 , d s p s c @ save status word
cfstr6 4 m v d x0 , [ r1 , #C R U N C H _ D S P S C ]
teq r0 , #0 @ anything to load?
cfldr6 4 e q m v d x0 , [ r1 , #C R U N C H _ M V D X 0 ] @ mvdx0 was clobbered
moveq p c , l r
crunch_load :
cfldr6 4 m v d x0 , [ r0 , #C R U N C H _ D S P S C ] @ l o a d s t a t u s w o r d
cfmvsc3 2 d s p s c , m v d x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 0 L ] @ load 72b accumulators
cfmval3 2 m v a x0 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 0 M ]
cfmvam3 2 m v a x0 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 0 H ]
cfmvah3 2 m v a x0 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 1 L ]
cfmval3 2 m v a x1 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 1 M ]
cfmvam3 2 m v a x1 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 1 H ]
cfmvah3 2 m v a x1 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 2 L ]
cfmval3 2 m v a x2 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 2 M ]
cfmvam3 2 m v a x2 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 2 H ]
cfmvah3 2 m v a x2 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 3 L ]
cfmval3 2 m v a x3 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 3 M ]
cfmvam3 2 m v a x3 , m v f x0
cfldr3 2 m v f x0 , [ r0 , #C R U N C H _ M V A X 3 H ]
cfmvah3 2 m v a x3 , m v f x0
cfldr6 4 m v d x0 , [ r0 , #C R U N C H _ M V D X 0 ] @ load 64b registers
cfldr6 4 m v d x1 , [ r0 , #C R U N C H _ M V D X 1 ]
cfldr6 4 m v d x2 , [ r0 , #C R U N C H _ M V D X 2 ]
cfldr6 4 m v d x3 , [ r0 , #C R U N C H _ M V D X 3 ]
cfldr6 4 m v d x4 , [ r0 , #C R U N C H _ M V D X 4 ]
cfldr6 4 m v d x5 , [ r0 , #C R U N C H _ M V D X 5 ]
cfldr6 4 m v d x6 , [ r0 , #C R U N C H _ M V D X 6 ]
cfldr6 4 m v d x7 , [ r0 , #C R U N C H _ M V D X 7 ]
cfldr6 4 m v d x8 , [ r0 , #C R U N C H _ M V D X 8 ]
cfldr6 4 m v d x9 , [ r0 , #C R U N C H _ M V D X 9 ]
cfldr6 4 m v d x10 , [ r0 , #C R U N C H _ M V D X 10 ]
cfldr6 4 m v d x11 , [ r0 , #C R U N C H _ M V D X 11 ]
cfldr6 4 m v d x12 , [ r0 , #C R U N C H _ M V D X 12 ]
cfldr6 4 m v d x13 , [ r0 , #C R U N C H _ M V D X 13 ]
cfldr6 4 m v d x14 , [ r0 , #C R U N C H _ M V D X 14 ]
cfldr6 4 m v d x15 , [ r0 , #C R U N C H _ M V D X 15 ]
mov p c , l r
/ *
* Back u p c r u n c h r e g s t o s a v e a r e a a n d d i s a b l e a c c e s s t o t h e m
* ( mainly f o r g d b o r s l e e p m o d e u s a g e )
*
* r0 = s t r u c t t h r e a d _ i n f o p o i n t e r o f t a r g e t t a s k o r N U L L f o r a n y
* /
ENTRY( c r u n c h _ t a s k _ d i s a b l e )
stmfd s p ! , { r4 , r5 , l r }
mrs i p , c p s r
orr r2 , i p , #P S R _ I _ B I T @ d i s a b l e i n t e r r u p t s
msr c p s r _ c , r2
ldr r4 , = ( E P 9 3 X X _ A P B _ V I R T _ B A S E + 0 x00 1 3 0 0 0 0 ) @ syscon addr
ldr r3 , =crunch_owner
add r2 , r0 , #T I _ C R U N C H _ S T A T E @ g e t t a s k c r u n c h s a v e a r e a
ldr r1 , [ r3 ] @ get current crunch owner
teq r1 , #0 @ any current owner?
beq 1 f @ no: quit
teq r0 , #0 @ any owner?
teqne r1 , r2 @ or specified one?
bne 1 f @ no: quit
ldr r5 , [ r4 , #0x80 ] @ enable access to crunch
mov r2 , #0xaa
str r2 , [ r4 , #0xc0 ]
orr r5 , r5 , #0x00800000
str r5 , [ r4 , #0x80 ]
mov r0 , #0 @ nothing to load
str r0 , [ r3 ] @ no more current owner
ldr r2 , [ r4 , #0x80 ] @ flush out enable (@@@)
mov r2 , r2
bl c r u n c h _ s a v e
mov r2 , #0xaa @ disable access to crunch
str r2 , [ r4 , #0xc0 ]
bic r5 , r5 , #0x00800000
str r5 , [ r4 , #0x80 ]
ldr r5 , [ r4 , #0x80 ] @ flush out enable (@@@)
mov r5 , r5
1 : msr c p s r _ c , i p @ restore interrupt mode
ldmfd s p ! , { r4 , r5 , p c }
/ *
* Copy c r u n c h s t a t e t o g i v e n m e m o r y a d d r e s s
*
* r0 = s t r u c t t h r e a d _ i n f o p o i n t e r o f t a r g e t t a s k
* r1 = m e m o r y a d d r e s s w h e r e t o s t o r e c r u n c h s t a t e
*
* this i s c a l l e d m a i n l y i n t h e c r e a t i o n o f s i g n a l s t a c k f r a m e s
* /
ENTRY( c r u n c h _ t a s k _ c o p y )
mrs i p , c p s r
orr r2 , i p , #P S R _ I _ B I T @ d i s a b l e i n t e r r u p t s
msr c p s r _ c , r2
ldr r3 , =crunch_owner
add r2 , r0 , #T I _ C R U N C H _ S T A T E @ g e t t a s k c r u n c h s a v e a r e a
ldr r3 , [ r3 ] @ get current crunch owner
teq r2 , r3 @ does this task own it...
beq 1 f
@ current crunch values are in the task save area
msr c p s r _ c , i p @ restore interrupt mode
mov r0 , r1
mov r1 , r2
mov r2 , #C R U N C H _ S I Z E
b m e m c p y
1 : @ this task owns crunch regs -- grab a copy from there
mov r0 , #0 @ nothing to load
mov r3 , l r @ preserve return address
bl c r u n c h _ s a v e
msr c p s r _ c , i p @ restore interrupt mode
mov p c , r3
/ *
* Restore c r u n c h s t a t e f r o m g i v e n m e m o r y a d d r e s s
*
* r0 = s t r u c t t h r e a d _ i n f o p o i n t e r o f t a r g e t t a s k
* r1 = m e m o r y a d d r e s s w h e r e t o g e t c r u n c h s t a t e f r o m
*
* this i s u s e d t o r e s t o r e c r u n c h s t a t e w h e n u n w i n d i n g a s i g n a l s t a c k f r a m e
* /
ENTRY( c r u n c h _ t a s k _ r e s t o r e )
mrs i p , c p s r
orr r2 , i p , #P S R _ I _ B I T @ d i s a b l e i n t e r r u p t s
msr c p s r _ c , r2
ldr r3 , =crunch_owner
add r2 , r0 , #T I _ C R U N C H _ S T A T E @ g e t t a s k c r u n c h s a v e a r e a
ldr r3 , [ r3 ] @ get current crunch owner
teq r2 , r3 @ does this task own it...
beq 1 f
@ this task doesn't own crunch regs -- use its save area
msr c p s r _ c , i p @ restore interrupt mode
mov r0 , r2
mov r2 , #C R U N C H _ S I Z E
b m e m c p y
1 : @ this task owns crunch regs -- load them directly
mov r0 , r1
mov r1 , #0 @ nothing to save
mov r3 , l r @ preserve return address
bl c r u n c h _ l o a d
msr c p s r _ c , i p @ restore interrupt mode
mov p c , r3