2009-01-07 18:14:39 +03:00
/ *
2009-09-24 18:11:24 +04:00
* Copyright 2 0 0 7 - 2 0 0 8 A n a l o g D e v i c e s I n c .
* Philippe G e r u m < r p m @xenomai.org>
2009-01-07 18:14:39 +03:00
*
2009-09-24 18:11:24 +04:00
* Licensed u n d e r t h e G P L - 2 o r l a t e r .
2009-01-07 18:14:39 +03:00
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / b l a c k f i n . h >
# include < a s m / c a c h e . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / r w l o c k . h >
# include < a s m / c p l b . h >
.text
.macro coreslot_loadaddr reg : req
\ reg\ ( ) . l = _ c o r e l o c k ;
\ reg\ ( ) . h = _ c o r e l o c k ;
.endm
2009-11-03 06:14:38 +03:00
.macro safe_testset addr : req, s c r a t c h : r e q
# if A N O M A L Y _ 0 5 0 0 0 4 7 7
cli \ s c r a t c h ;
testset ( \ a d d r ) ;
sti \ s c r a t c h ;
# else
testset ( \ a d d r ) ;
# endif
.endm
2009-01-07 18:14:39 +03:00
/ *
* r0 = a d d r e s s o f a t o m i c d a t a t o f l u s h a n d i n v a l i d a t e ( 3 2 b i t ) .
*
* Clear i n t e r r u p t s a n d r e t u r n t h e o l d m a s k .
* We a s s u m e t h a t n o a t o m i c d a t a c a n s p a n c a c h e l i n e s .
*
* Clobbers : r2 : 0 , p0
* /
ENTRY( _ g e t _ c o r e _ l o c k )
r1 = - L 1 _ C A C H E _ B Y T E S ;
r1 = r0 & r1 ;
cli r0 ;
coreslot_ l o a d a d d r p0 ;
.Lretry_corelock :
2009-11-03 06:14:38 +03:00
safe_ t e s t s e t p0 , r2 ;
2009-01-07 18:14:39 +03:00
if c c j u m p . L d o n e _ c o r e l o c k ;
SSYNC( r2 ) ;
jump . L r e t r y _ c o r e l o c k
.Ldone_corelock :
p0 = r1 ;
2010-11-12 08:54:32 +03:00
/* flush core internal write buffer before invalidate dcache */
2009-01-07 18:14:39 +03:00
CSYNC( r2 ) ;
flushinv[ p0 ] ;
SSYNC( r2 ) ;
rts;
ENDPROC( _ g e t _ c o r e _ l o c k )
/ *
* r0 = a d d r e s s o f a t o m i c d a t a i n u n c a c h e a b l e m e m o r y r e g i o n ( 3 2 b i t ) .
*
* Clear i n t e r r u p t s a n d r e t u r n t h e o l d m a s k .
*
* Clobbers : r0 , p0
* /
ENTRY( _ g e t _ c o r e _ l o c k _ n o f l u s h )
cli r0 ;
coreslot_ l o a d a d d r p0 ;
.Lretry_corelock_noflush :
2009-11-03 06:14:38 +03:00
safe_ t e s t s e t p0 , r2 ;
2009-01-07 18:14:39 +03:00
if c c j u m p . L d o n e _ c o r e l o c k _ n o f l u s h ;
SSYNC( r2 ) ;
jump . L r e t r y _ c o r e l o c k _ n o f l u s h
.Ldone_corelock_noflush :
2012-01-17 14:06:34 +04:00
/ *
* SMP k g d b r u n s i n t o d e a d l o o p w i t h o u t N O P h e r e , w h e n o n e c o r e
* single s t e p s o v e r g e t _ c o r e _ l o c k _ n o f l u s h a n d t h e o t h e r e x e c u t e s
* get_ c o r e _ l o c k a s a s l a v e n o d e .
* /
nop;
CSYNC( r2 ) ;
2009-01-07 18:14:39 +03:00
rts;
ENDPROC( _ g e t _ c o r e _ l o c k _ n o f l u s h )
/ *
* r0 = i n t e r r u p t m a s k t o r e s t o r e .
* r1 = a d d r e s s o f a t o m i c d a t a t o f l u s h a n d i n v a l i d a t e ( 3 2 b i t ) .
*
* Interrupts a r e m a s k e d o n e n t r y ( s e e _ g e t _ c o r e _ l o c k ) .
* Clobbers : r2 : 0 , p0
* /
ENTRY( _ p u t _ c o r e _ l o c k )
/* Write-through cache assumed, so no flush needed here. */
coreslot_ l o a d a d d r p0 ;
r1 = 0 ;
[ p0 ] = r1 ;
SSYNC( r2 ) ;
sti r0 ;
rts;
ENDPROC( _ p u t _ c o r e _ l o c k )
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
ENTRY( _ _ _ r a w _ s m p _ m a r k _ b a r r i e r _ a s m )
[ - - sp] = r e t s ;
[ - - sp] = ( r7 : 5 ) ;
[ - - sp] = r0 ;
[ - - sp] = p1 ;
[ - - sp] = p0 ;
call _ g e t _ c o r e _ l o c k _ n o f l u s h ;
/ *
* Calculate c u r r e n t c o r e m a s k
* /
GET_ C P U I D ( p1 , r7 ) ;
r6 = 1 ;
r6 < < = r7 ;
/ *
* Set b i t o f o t h e r c o r e s i n b a r r i e r m a s k . D o n ' t c h a n g e c u r r e n t c o r e b i t .
* /
p1 . l = _ b a r r i e r _ m a s k ;
p1 . h = _ b a r r i e r _ m a s k ;
r7 = [ p1 ] ;
r5 = r7 & r6 ;
r7 = ~ r6 ;
cc = r5 = = 0 ;
if c c j u m p 1 f ;
r7 = r7 | r6 ;
1 :
[ p1 ] = r7 ;
SSYNC( r2 ) ;
call _ p u t _ c o r e _ l o c k ;
p0 = [ s p + + ] ;
p1 = [ s p + + ] ;
r0 = [ s p + + ] ;
( r7 : 5 ) = [ sp+ + ] ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ s m p _ m a r k _ b a r r i e r _ a s m )
ENTRY( _ _ _ r a w _ s m p _ c h e c k _ b a r r i e r _ a s m )
[ - - sp] = r e t s ;
[ - - sp] = ( r7 : 5 ) ;
[ - - sp] = r0 ;
[ - - sp] = p1 ;
[ - - sp] = p0 ;
call _ g e t _ c o r e _ l o c k _ n o f l u s h ;
/ *
* Calculate c u r r e n t c o r e m a s k
* /
GET_ C P U I D ( p1 , r7 ) ;
r6 = 1 ;
r6 < < = r7 ;
/ *
* Clear c u r r e n t c o r e b i t i n b a r r i e r m a s k i f i t i s s e t .
* /
p1 . l = _ b a r r i e r _ m a s k ;
p1 . h = _ b a r r i e r _ m a s k ;
r7 = [ p1 ] ;
r5 = r7 & r6 ;
cc = r5 = = 0 ;
if c c j u m p 1 f ;
r6 = ~ r6 ;
r7 = r7 & r6 ;
[ p1 ] = r7 ;
SSYNC( r2 ) ;
call _ p u t _ c o r e _ l o c k ;
/ *
* Invalidate t h e e n t i r e D - c a c h e o f c u r r e n t c o r e .
* /
sp + = - 1 2 ;
call _ r e s y n c _ c o r e _ d c a c h e
sp + = 1 2 ;
jump 2 f ;
1 :
call _ p u t _ c o r e _ l o c k ;
2 :
p0 = [ s p + + ] ;
p1 = [ s p + + ] ;
r0 = [ s p + + ] ;
( r7 : 5 ) = [ sp+ + ] ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ s m p _ c h e c k _ b a r r i e r _ a s m )
/ *
* r0 = i r q f l a g s
* r1 = a d d r e s s o f a t o m i c d a t a
*
* Clobbers : r2 : 0 , p1 : 0
* /
_start_lock_coherent :
[ - - sp] = r e t s ;
[ - - sp] = ( r7 : 6 ) ;
r7 = r0 ;
p1 = r1 ;
/ *
* Determine w h e t h e r t h e a t o m i c d a t a w a s p r e v i o u s l y
* owned b y a n o t h e r C P U ( =r6 ) .
* /
GET_ C P U I D ( p0 , r2 ) ;
r1 = 1 ;
r1 < < = r2 ;
r2 = ~ r1 ;
r1 = [ p1 ] ;
r1 > > = 2 8 ; /* CPU fingerprints are stored in the high nibble. */
r6 = r1 & r2 ;
r1 = [ p1 ] ;
r1 < < = 4 ;
r1 > > = 4 ;
[ p1 ] = r1 ;
/ *
* Release t h e c o r e l o c k n o w , b u t k e e p I R Q s d i s a b l e d w h i l e w e a r e
* performing t h e r e m a i n i n g h o u s e k e e p i n g c h o r e s f o r t h e c u r r e n t C P U .
* /
coreslot_ l o a d a d d r p0 ;
r1 = 0 ;
[ p0 ] = r1 ;
/ *
* If a n o t h e r C P U h a s o w n e d t h e s a m e a t o m i c s e c t i o n b e f o r e u s ,
* then o u r D - c a c h e d c o p y o f t h e s h a r e d d a t a p r o t e c t e d b y t h e
* current s p i n / w r i t e _ l o c k m a y b e o b s o l e t e .
* /
cc = r6 = = 0 ;
if c c j u m p . L c a c h e _ s y n c e d
/ *
* Invalidate t h e e n t i r e D - c a c h e o f t h e c u r r e n t c o r e .
* /
sp + = - 1 2 ;
call _ r e s y n c _ c o r e _ d c a c h e
sp + = 1 2 ;
.Lcache_synced :
SSYNC( r2 ) ;
sti r7 ;
( r7 : 6 ) = [ sp+ + ] ;
rets = [ s p + + ] ;
rts
/ *
* r0 = i r q f l a g s
* r1 = a d d r e s s o f a t o m i c d a t a
*
* Clobbers : r2 : 0 , p1 : 0
* /
_end_lock_coherent :
p1 = r1 ;
GET_ C P U I D ( p0 , r2 ) ;
r2 + = 2 8 ;
r1 = 1 ;
r1 < < = r2 ;
r2 = [ p1 ] ;
r2 = r1 | r2 ;
[ p1 ] = r2 ;
r1 = p1 ;
jump _ p u t _ c o r e _ l o c k ;
# endif / * _ _ A R C H _ S Y N C _ C O R E _ D C A C H E * /
/ *
* r0 = & s p i n l o c k - > l o c k
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ s p i n _ i s _ l o c k e d _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r3 = [ p1 ] ;
cc = b i t t s t ( r3 , 0 ) ;
r3 = c c ;
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
rets = [ s p + + ] ;
r0 = r3 ;
rts;
ENDPROC( _ _ _ r a w _ s p i n _ i s _ l o c k e d _ a s m )
/ *
* r0 = & s p i n l o c k - > l o c k
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ s p i n _ l o c k _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
.Lretry_spinlock :
call _ g e t _ c o r e _ l o c k ;
r1 = p1 ;
r2 = [ p1 ] ;
cc = b i t t s t ( r2 , 0 ) ;
if c c j u m p . L b u s y _ s p i n l o c k
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
r3 = p1 ;
bitset ( r2 , 0 ) ; /* Raise the lock bit. */
[ p1 ] = r2 ;
call _ s t a r t _ l o c k _ c o h e r e n t
# else
r2 = 1 ;
[ p1 ] = r2 ;
call _ p u t _ c o r e _ l o c k ;
# endif
rets = [ s p + + ] ;
rts;
.Lbusy_spinlock :
/ * We d o n ' t t o u c h t h e a t o m i c a r e a i f b u s y , s o t h a t f l u s h
will b e h a v e l i k e n o p i n _ p u t _ c o r e _ l o c k . * /
call _ p u t _ c o r e _ l o c k ;
SSYNC( r2 ) ;
r0 = p1 ;
jump . L r e t r y _ s p i n l o c k
ENDPROC( _ _ _ r a w _ s p i n _ l o c k _ a s m )
/ *
* r0 = & s p i n l o c k - > l o c k
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ s p i n _ t r y l o c k _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r1 = p1 ;
r3 = [ p1 ] ;
cc = b i t t s t ( r3 , 0 ) ;
if c c j u m p . L f a i l e d _ t r y l o c k
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
bitset ( r3 , 0 ) ; /* Raise the lock bit. */
[ p1 ] = r3 ;
call _ s t a r t _ l o c k _ c o h e r e n t
# else
r2 = 1 ;
[ p1 ] = r2 ;
call _ p u t _ c o r e _ l o c k ;
# endif
r0 = 1 ;
rets = [ s p + + ] ;
rts;
.Lfailed_trylock :
call _ p u t _ c o r e _ l o c k ;
r0 = 0 ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ s p i n _ t r y l o c k _ a s m )
/ *
* r0 = & s p i n l o c k - > l o c k
*
* Clobbers : r2 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ s p i n _ u n l o c k _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r2 = [ p1 ] ;
bitclr ( r2 , 0 ) ;
[ p1 ] = r2 ;
r1 = p1 ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
call _ e n d _ l o c k _ c o h e r e n t
# else
call _ p u t _ c o r e _ l o c k ;
# endif
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ s p i n _ u n l o c k _ a s m )
/ *
* r0 = & r w l o c k - > l o c k
*
* Clobbers : r2 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ r e a d _ l o c k _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
.Lrdlock_try :
r1 = [ p1 ] ;
r1 + = - 1 ;
[ p1 ] = r1 ;
cc = r1 < 0 ;
if c c j u m p . L r d l o c k _ f a i l e d
r1 = p1 ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
call _ s t a r t _ l o c k _ c o h e r e n t
# else
call _ p u t _ c o r e _ l o c k ;
# endif
rets = [ s p + + ] ;
rts;
.Lrdlock_failed :
r1 + = 1 ;
[ p1 ] = r1 ;
.Lrdlock_wait :
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
SSYNC( r2 ) ;
r0 = p1 ;
call _ g e t _ c o r e _ l o c k ;
r1 = [ p1 ] ;
cc = r1 < 2 ;
if c c j u m p . L r d l o c k _ w a i t ;
jump . L r d l o c k _ t r y
ENDPROC( _ _ _ r a w _ r e a d _ l o c k _ a s m )
/ *
* r0 = & r w l o c k - > l o c k
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ r e a d _ t r y l o c k _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r1 = [ p1 ] ;
cc = r1 < = 0 ;
if c c j u m p . L f a i l e d _ t r y r d l o c k ;
r1 + = - 1 ;
[ p1 ] = r1 ;
r1 = p1 ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
call _ s t a r t _ l o c k _ c o h e r e n t
# else
call _ p u t _ c o r e _ l o c k ;
# endif
rets = [ s p + + ] ;
r0 = 1 ;
rts;
.Lfailed_tryrdlock :
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
rets = [ s p + + ] ;
r0 = 0 ;
rts;
ENDPROC( _ _ _ r a w _ r e a d _ t r y l o c k _ a s m )
/ *
* r0 = & r w l o c k - > l o c k
*
* Note : Processing c o n t r o l l e d b y a r e a d e r l o c k s h o u l d n o t h a v e
* any s i d e - e f f e c t o n c a c h e i s s u e s w i t h t h e o t h e r c o r e , s o w e
* just r e l e a s e t h e c o r e l o c k a n d e x i t ( n o _ e n d _ l o c k _ c o h e r e n t ) .
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ r e a d _ u n l o c k _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r1 = [ p1 ] ;
r1 + = 1 ;
[ p1 ] = r1 ;
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ r e a d _ u n l o c k _ a s m )
/ *
* r0 = & r w l o c k - > l o c k
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ w r i t e _ l o c k _ a s m )
p1 = r0 ;
r3 . l = l o ( R W _ L O C K _ B I A S ) ;
r3 . h = h i ( R W _ L O C K _ B I A S ) ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
.Lwrlock_try :
r1 = [ p1 ] ;
r1 = r1 - r3 ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
r2 = r1 ;
r2 < < = 4 ;
r2 > > = 4 ;
cc = r2 = = 0 ;
# else
cc = r1 = = 0 ;
# endif
if ! c c j u m p . L w r l o c k _ w a i t
[ p1 ] = r1 ;
r1 = p1 ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
call _ s t a r t _ l o c k _ c o h e r e n t
# else
call _ p u t _ c o r e _ l o c k ;
# endif
rets = [ s p + + ] ;
rts;
.Lwrlock_wait :
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
SSYNC( r2 ) ;
r0 = p1 ;
call _ g e t _ c o r e _ l o c k ;
r1 = [ p1 ] ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
r1 < < = 4 ;
r1 > > = 4 ;
# endif
cc = r1 = = r3 ;
if ! c c j u m p . L w r l o c k _ w a i t ;
jump . L w r l o c k _ t r y
ENDPROC( _ _ _ r a w _ w r i t e _ l o c k _ a s m )
/ *
* r0 = & r w l o c k - > l o c k
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ w r i t e _ t r y l o c k _ a s m )
p1 = r0 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r1 = [ p1 ] ;
r2 . l = l o ( R W _ L O C K _ B I A S ) ;
r2 . h = h i ( R W _ L O C K _ B I A S ) ;
cc = r1 = = r2 ;
if ! c c j u m p . L f a i l e d _ t r y w r l o c k ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
r1 > > = 2 8 ;
r1 < < = 2 8 ;
# else
r1 = 0 ;
# endif
[ p1 ] = r1 ;
r1 = p1 ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
call _ s t a r t _ l o c k _ c o h e r e n t
# else
call _ p u t _ c o r e _ l o c k ;
# endif
rets = [ s p + + ] ;
r0 = 1 ;
rts;
.Lfailed_trywrlock :
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
rets = [ s p + + ] ;
r0 = 0 ;
rts;
ENDPROC( _ _ _ r a w _ w r i t e _ t r y l o c k _ a s m )
/ *
* r0 = & r w l o c k - > l o c k
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ w r i t e _ u n l o c k _ a s m )
p1 = r0 ;
r3 . l = l o ( R W _ L O C K _ B I A S ) ;
r3 . h = h i ( R W _ L O C K _ B I A S ) ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r1 = [ p1 ] ;
r1 = r1 + r3 ;
[ p1 ] = r1 ;
r1 = p1 ;
# ifdef _ _ A R C H _ S Y N C _ C O R E _ D C A C H E
call _ e n d _ l o c k _ c o h e r e n t
# else
call _ p u t _ c o r e _ l o c k ;
# endif
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ w r i t e _ u n l o c k _ a s m )
/ *
* r0 = p t r
* r1 = v a l u e
*
* Add a s i g n e d v a l u e t o a 3 2 b i t w o r d a n d r e t u r n t h e n e w v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ a t o m i c _ u p d a t e _ a s m )
p1 = r0 ;
r3 = r1 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r2 = [ p1 ] ;
r3 = r3 + r2 ;
[ p1 ] = r3 ;
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
r0 = r3 ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ a t o m i c _ u p d a t e _ a s m )
/ *
* r0 = p t r
* r1 = m a s k
*
* Clear t h e m a s k b i t s f r o m a 3 2 b i t w o r d a n d r e t u r n t h e o l d 3 2 b i t v a l u e
* atomically.
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ a t o m i c _ c l e a r _ a s m )
p1 = r0 ;
r3 = ~ r1 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r2 = [ p1 ] ;
r3 = r2 & r3 ;
[ p1 ] = r3 ;
r3 = r2 ;
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
r0 = r3 ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ a t o m i c _ c l e a r _ a s m )
/ *
* r0 = p t r
* r1 = m a s k
*
* Set t h e m a s k b i t s i n t o a 3 2 b i t w o r d a n d r e t u r n t h e o l d 3 2 b i t v a l u e
* atomically.
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ a t o m i c _ s e t _ a s m )
p1 = r0 ;
r3 = r1 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r2 = [ p1 ] ;
r3 = r2 | r3 ;
[ p1 ] = r3 ;
r3 = r2 ;
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
r0 = r3 ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ a t o m i c _ s e t _ a s m )
/ *
* r0 = p t r
* r1 = m a s k
*
* XOR t h e m a s k b i t s w i t h a 3 2 b i t w o r d a n d r e t u r n t h e o l d 3 2 b i t v a l u e
* atomically.
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ a t o m i c _ x o r _ a s m )
p1 = r0 ;
r3 = r1 ;
[ - - sp] = r e t s ;
call _ g e t _ c o r e _ l o c k ;
r2 = [ p1 ] ;
r3 = r2 ^ r3 ;
[ p1 ] = r3 ;
r3 = r2 ;
r1 = p1 ;
call _ p u t _ c o r e _ l o c k ;
r0 = r3 ;
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ a t o m i c _ x o r _ a s m )
/ *
* r0 = p t r
* r1 = m a s k
*
* Perform a l o g i c a l A N D b e t w e e n t h e m a s k b i t s a n d a 3 2 b i t w o r d , a n d
* return t h e m a s k e d v a l u e . W e n e e d t h i s o n t h i s a r c h i t e c t u r e i n
* order t o i n v a l i d a t e t h e l o c a l c a c h e b e f o r e t e s t i n g .
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ a t o m i c _ t e s t _ a s m )
p1 = r0 ;
r3 = r1 ;
r1 = - L 1 _ C A C H E _ B Y T E S ;
r1 = r0 & r1 ;
p0 = r1 ;
2010-11-12 08:54:32 +03:00
/* flush core internal write buffer before invalidate dcache */
CSYNC( r2 ) ;
2009-01-07 18:14:39 +03:00
flushinv[ p0 ] ;
SSYNC( r2 ) ;
r0 = [ p1 ] ;
r0 = r0 & r3 ;
rts;
ENDPROC( _ _ _ r a w _ a t o m i c _ t e s t _ a s m )
/ *
* r0 = p t r
* r1 = v a l u e
*
* Swap * p t r w i t h v a l u e a n d r e t u r n t h e o l d 3 2 b i t v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
# define _ _ d o _ x c h g ( s r c , d s t ) \
p1 = r0 ; \
r3 = r1 ; \
[ - - sp] = r e t s ; \
call _ g e t _ c o r e _ l o c k ; \
r2 = s r c ; \
dst = r3 ; \
r3 = r2 ; \
r1 = p1 ; \
call _ p u t _ c o r e _ l o c k ; \
r0 = r3 ; \
rets = [ s p + + ] ; \
rts;
ENTRY( _ _ _ r a w _ x c h g _ 1 _ a s m )
_ _ do_ x c h g ( b [ p1 ] ( z ) , b [ p1 ] )
ENDPROC( _ _ _ r a w _ x c h g _ 1 _ a s m )
ENTRY( _ _ _ r a w _ x c h g _ 2 _ a s m )
_ _ do_ x c h g ( w [ p1 ] ( z ) , w [ p1 ] )
ENDPROC( _ _ _ r a w _ x c h g _ 2 _ a s m )
ENTRY( _ _ _ r a w _ x c h g _ 4 _ a s m )
_ _ do_ x c h g ( [ p1 ] , [ p1 ] )
ENDPROC( _ _ _ r a w _ x c h g _ 4 _ a s m )
/ *
* r0 = p t r
* r1 = n e w
* r2 = o l d
*
* Swap * p t r w i t h n e w i f * p t r = = o l d a n d r e t u r n t h e p r e v i o u s * p t r
* value a t o m i c a l l y .
*
* Clobbers : r3 : 0 , p1 : 0
* /
# define _ _ d o _ c m p x c h g ( s r c , d s t ) \
[ - - sp] = r e t s ; \
[ - - sp] = r4 ; \
p1 = r0 ; \
r3 = r1 ; \
r4 = r2 ; \
call _ g e t _ c o r e _ l o c k ; \
r2 = s r c ; \
cc = r2 = = r4 ; \
if ! c c j u m p 1 f ; \
dst = r3 ; \
1 : r3 = r2 ; \
r1 = p1 ; \
call _ p u t _ c o r e _ l o c k ; \
r0 = r3 ; \
r4 = [ s p + + ] ; \
rets = [ s p + + ] ; \
rts;
ENTRY( _ _ _ r a w _ c m p x c h g _ 1 _ a s m )
_ _ do_ c m p x c h g ( b [ p1 ] ( z ) , b [ p1 ] )
ENDPROC( _ _ _ r a w _ c m p x c h g _ 1 _ a s m )
ENTRY( _ _ _ r a w _ c m p x c h g _ 2 _ a s m )
_ _ do_ c m p x c h g ( w [ p1 ] ( z ) , w [ p1 ] )
ENDPROC( _ _ _ r a w _ c m p x c h g _ 2 _ a s m )
ENTRY( _ _ _ r a w _ c m p x c h g _ 4 _ a s m )
_ _ do_ c m p x c h g ( [ p1 ] , [ p1 ] )
ENDPROC( _ _ _ r a w _ c m p x c h g _ 4 _ a s m )
/ *
* r0 = p t r
* r1 = b i t n r
*
* Set a b i t i n a 3 2 b i t w o r d a n d r e t u r n t h e o l d 3 2 b i t v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ b i t _ s e t _ a s m )
r2 = r1 ;
r1 = 1 ;
r1 < < = r2 ;
jump _ _ _ r a w _ a t o m i c _ s e t _ a s m
ENDPROC( _ _ _ r a w _ b i t _ s e t _ a s m )
/ *
* r0 = p t r
* r1 = b i t n r
*
* Clear a b i t i n a 3 2 b i t w o r d a n d r e t u r n t h e o l d 3 2 b i t v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ b i t _ c l e a r _ a s m )
r2 = r1 ;
r1 = 1 ;
r1 < < = r2 ;
jump _ _ _ r a w _ a t o m i c _ c l e a r _ a s m
ENDPROC( _ _ _ r a w _ b i t _ c l e a r _ a s m )
/ *
* r0 = p t r
* r1 = b i t n r
*
* Toggle a b i t i n a 3 2 b i t w o r d a n d r e t u r n t h e o l d 3 2 b i t v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ b i t _ t o g g l e _ a s m )
r2 = r1 ;
r1 = 1 ;
r1 < < = r2 ;
jump _ _ _ r a w _ a t o m i c _ x o r _ a s m
ENDPROC( _ _ _ r a w _ b i t _ t o g g l e _ a s m )
/ *
* r0 = p t r
* r1 = b i t n r
*
* Test- a n d - s e t a b i t i n a 3 2 b i t w o r d a n d r e t u r n t h e o l d b i t v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ b i t _ t e s t _ s e t _ a s m )
[ - - sp] = r e t s ;
[ - - sp] = r1 ;
call _ _ _ r a w _ b i t _ s e t _ a s m
r1 = [ s p + + ] ;
r2 = 1 ;
r2 < < = r1 ;
r0 = r0 & r2 ;
cc = r0 = = 0 ;
if c c j u m p 1 f
r0 = 1 ;
1 :
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ b i t _ t e s t _ s e t _ a s m )
/ *
* r0 = p t r
* r1 = b i t n r
*
* Test- a n d - c l e a r a b i t i n a 3 2 b i t w o r d a n d r e t u r n t h e o l d b i t v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ b i t _ t e s t _ c l e a r _ a s m )
[ - - sp] = r e t s ;
[ - - sp] = r1 ;
call _ _ _ r a w _ b i t _ c l e a r _ a s m
r1 = [ s p + + ] ;
r2 = 1 ;
r2 < < = r1 ;
r0 = r0 & r2 ;
cc = r0 = = 0 ;
if c c j u m p 1 f
r0 = 1 ;
1 :
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ b i t _ t e s t _ c l e a r _ a s m )
/ *
* r0 = p t r
* r1 = b i t n r
*
* Test- a n d - t o g g l e a b i t i n a 3 2 b i t w o r d ,
* and r e t u r n t h e o l d b i t v a l u e a t o m i c a l l y .
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ b i t _ t e s t _ t o g g l e _ a s m )
[ - - sp] = r e t s ;
[ - - sp] = r1 ;
call _ _ _ r a w _ b i t _ t o g g l e _ a s m
r1 = [ s p + + ] ;
r2 = 1 ;
r2 < < = r1 ;
r0 = r0 & r2 ;
cc = r0 = = 0 ;
if c c j u m p 1 f
r0 = 1 ;
1 :
rets = [ s p + + ] ;
rts;
ENDPROC( _ _ _ r a w _ b i t _ t e s t _ t o g g l e _ a s m )
/ *
* r0 = p t r
* r1 = b i t n r
*
* Test a b i t i n a 3 2 b i t w o r d a n d r e t u r n i t s v a l u e .
* We n e e d t h i s o n t h i s a r c h i t e c t u r e i n o r d e r t o i n v a l i d a t e
* the l o c a l c a c h e b e f o r e t e s t i n g .
*
* Clobbers : r3 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ b i t _ t e s t _ a s m )
r2 = r1 ;
r1 = 1 ;
r1 < < = r2 ;
jump _ _ _ r a w _ a t o m i c _ t e s t _ a s m
ENDPROC( _ _ _ r a w _ b i t _ t e s t _ a s m )
/ *
* r0 = p t r
*
* Fetch a n d r e t u r n a n u n c a c h e d 3 2 b i t v a l u e .
*
* Clobbers : r2 : 0 , p1 : 0
* /
ENTRY( _ _ _ r a w _ u n c a c h e d _ f e t c h _ a s m )
p1 = r0 ;
r1 = - L 1 _ C A C H E _ B Y T E S ;
r1 = r0 & r1 ;
p0 = r1 ;
2010-11-12 08:54:32 +03:00
/* flush core internal write buffer before invalidate dcache */
CSYNC( r2 ) ;
2009-01-07 18:14:39 +03:00
flushinv[ p0 ] ;
SSYNC( r2 ) ;
r0 = [ p1 ] ;
rts;
ENDPROC( _ _ _ r a w _ u n c a c h e d _ f e t c h _ a s m )