2012-03-05 15:49:28 +04:00
/ *
* Cache m a i n t e n a n c e
*
* Copyright ( C ) 2 0 0 1 D e e p B l u e S o l u t i o n s L t d .
* Copyright ( C ) 2 0 1 2 A R M L t d .
*
* 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 .
*
* This p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
*
* You s h o u l d h a v e r e c e i v e d a c o p y 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
* along w i t h t h i s p r o g r a m . I f n o t , s e e < h t t p : / / w w w . g n u . o r g / l i c e n s e s / > .
* /
# include < l i n u x / l i n k a g e . h >
# include < l i n u x / i n i t . h >
# include < a s m / a s s e m b l e r . h >
# include " p r o c - m a c r o s . S "
/ *
* _ _ flush_ d c a c h e _ a l l ( )
*
* Flush t h e w h o l e D - c a c h e .
*
* Corrupted r e g i s t e r s : x0 - x7 , x9 - x11
* /
2013-08-14 12:54:54 +04:00
__flush_dcache_all :
2012-03-05 15:49:28 +04:00
dsb s y / / e n s u r e o r d e r i n g w i t h p r e v i o u s m e m o r y a c c e s s e s
mrs x0 , c l i d r _ e l 1 / / r e a d c l i d r
and x3 , x0 , #0x7000000 / / e x t r a c t l o c f r o m c l i d r
lsr x3 , x3 , #23 / / l e f t a l i g n l o c b i t f i e l d
cbz x3 , f i n i s h e d / / i f l o c i s 0 , t h e n n o n e e d t o c l e a n
mov x10 , #0 / / s t a r t c l e a n a t c a c h e l e v e l 0
loop1 :
add x2 , x10 , x10 , l s r #1 / / w o r k o u t 3 x c u r r e n t c a c h e l e v e l
lsr x1 , x0 , x2 / / e x t r a c t c a c h e t y p e b i t s f r o m c l i d r
and x1 , x1 , #7 / / m a s k o f t h e b i t s f o r c u r r e n t c a c h e o n l y
cmp x1 , #2 / / s e e w h a t c a c h e w e h a v e a t t h i s l e v e l
b. l t s k i p / / s k i p i f n o c a c h e , o r j u s t i - c a c h e
save_ a n d _ d i s a b l e _ i r q s x9 / / m a k e C S S E L R a n d C C S I D R a c c e s s a t o m i c
msr c s s e l r _ e l 1 , x10 / / s e l e c t c u r r e n t c a c h e l e v e l i n c s s e l r
isb / / i s b t o s y c h t h e n e w c s s r & c s i d r
mrs x1 , c c s i d r _ e l 1 / / r e a d t h e n e w c c s i d r
restore_ i r q s x9
and x2 , x1 , #7 / / e x t r a c t t h e l e n g t h o f t h e c a c h e l i n e s
add x2 , x2 , #4 / / a d d 4 ( l i n e l e n g t h o f f s e t )
mov x4 , #0x3ff
and x4 , x4 , x1 , l s r #3 / / f i n d m a x i m u m n u m b e r o n t h e w a y s i z e
2013-05-14 13:26:54 +04:00
clz w5 , w4 / / f i n d b i t p o s i t i o n o f w a y s i z e i n c r e m e n t
2012-03-05 15:49:28 +04:00
mov x7 , #0x7fff
and x7 , x7 , x1 , l s r #13 / / e x t r a c t m a x n u m b e r o f t h e i n d e x s i z e
loop2 :
mov x9 , x4 / / c r e a t e w o r k i n g c o p y o f m a x w a y s i z e
loop3 :
lsl x6 , x9 , x5
orr x11 , x10 , x6 / / f a c t o r w a y a n d c a c h e n u m b e r i n t o x11
lsl x6 , x7 , x2
orr x11 , x11 , x6 / / f a c t o r i n d e x n u m b e r i n t o x11
dc c i s w , x11 / / c l e a n & i n v a l i d a t e b y s e t / w a y
subs x9 , x9 , #1 / / d e c r e m e n t t h e w a y
b. g e l o o p3
subs x7 , x7 , #1 / / d e c r e m e n t t h e i n d e x
b. g e l o o p2
skip :
add x10 , x10 , #2 / / i n c r e m e n t c a c h e n u m b e r
cmp x3 , x10
b. g t l o o p1
finished :
mov x10 , #0 / / s w i t h b a c k t o c a c h e l e v e l 0
msr c s s e l r _ e l 1 , x10 / / s e l e c t c u r r e n t c a c h e l e v e l i n c s s e l r
dsb s y
isb
ret
ENDPROC( _ _ f l u s h _ d c a c h e _ a l l )
/ *
* flush_ c a c h e _ a l l ( )
*
* Flush t h e e n t i r e c a c h e s y s t e m . T h e d a t a c a c h e f l u s h i s n o w a c h i e v e d
* using a t o m i c c l e a n / i n v a l i d a t e s w o r k i n g o u t w a r d s f r o m L 1 c a c h e . T h i s
* is d o n e u s i n g S e t / W a y b a s e d c a c h e m a i n t a i n a n c e i n s t r u c t i o n s . T h e
* instruction c a c h e c a n s t i l l b e i n v a l i d a t e d b a c k t o t h e p o i n t o f
* unification i n a s i n g l e i n s t r u c t i o n .
* /
ENTRY( f l u s h _ c a c h e _ a l l )
mov x12 , l r
bl _ _ f l u s h _ d c a c h e _ a l l
mov x0 , #0
ic i a l l u i s / / I + B T B c a c h e i n v a l i d a t e
ret x12
ENDPROC( f l u s h _ c a c h e _ a l l )
/ *
* flush_ i c a c h e _ r a n g e ( s t a r t ,e n d )
*
* Ensure t h a t t h e I a n d D c a c h e s a r e c o h e r e n t w i t h i n s p e c i f i e d r e g i o n .
* This i s t y p i c a l l y u s e d w h e n c o d e h a s b e e n w r i t t e n t o a m e m o r y r e g i o n ,
* and w i l l b e e x e c u t e d .
*
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
ENTRY( f l u s h _ i c a c h e _ r a n g e )
/* FALLTHROUGH */
/ *
* _ _ flush_ c a c h e _ u s e r _ r a n g e ( s t a r t ,e n d )
*
* Ensure t h a t t h e I a n d D c a c h e s a r e c o h e r e n t w i t h i n s p e c i f i e d r e g i o n .
* This i s t y p i c a l l y u s e d w h e n c o d e h a s b e e n w r i t t e n t o a m e m o r y r e g i o n ,
* and w i l l b e e x e c u t e d .
*
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
ENTRY( _ _ f l u s h _ c a c h e _ u s e r _ r a n g e )
dcache_ l i n e _ s i z e x2 , x3
sub x3 , x2 , #1
bic x4 , x0 , x3
1 :
USER( 9 f , d c c v a u , x4 ) / / c l e a n D l i n e t o P o U
add x4 , x4 , x2
cmp x4 , x1
b. l o 1 b
dsb s y
icache_ l i n e _ s i z e x2 , x3
sub x3 , x2 , #1
bic x4 , x0 , x3
1 :
USER( 9 f , i c i v a u , x4 ) / / i n v a l i d a t e I l i n e P o U
add x4 , x4 , x2
cmp x4 , x1
b. l o 1 b
9 : / / ignore a n y f a u l t i n g c a c h e o p e r a t i o n
dsb s y
isb
ret
ENDPROC( f l u s h _ i c a c h e _ r a n g e )
ENDPROC( _ _ f l u s h _ c a c h e _ u s e r _ r a n g e )
/ *
2014-01-21 05:17:47 +04:00
* _ _ flush_ d c a c h e _ a r e a ( k a d d r , s i z e )
2012-03-05 15:49:28 +04:00
*
* Ensure t h a t t h e d a t a h e l d i n t h e p a g e k a d d r i s w r i t t e n b a c k t o t h e
* page i n q u e s t i o n .
*
* - kaddr - k e r n e l a d d r e s s
* - size - s i z e i n q u e s t i o n
* /
ENTRY( _ _ f l u s h _ d c a c h e _ a r e a )
dcache_ l i n e _ s i z e x2 , x3
add x1 , x0 , x1
sub x3 , x2 , #1
bic x0 , x0 , x3
1 : dc c i v a c , x0 / / c l e a n & i n v a l i d a t e D l i n e / u n i f i e d l i n e
add x0 , x0 , x2
cmp x0 , x1
b. l o 1 b
dsb s y
ret
ENDPROC( _ _ f l u s h _ d c a c h e _ a r e a )
2013-05-21 20:35:19 +04:00
2014-03-26 22:25:55 +04:00
/ *
* _ _ inval_ c a c h e _ r a n g e ( s t a r t , e n d )
* - start - s t a r t a d d r e s s o f r e g i o n
* - end - e n d a d d r e s s o f r e g i o n
* /
ENTRY( _ _ i n v a l _ c a c h e _ r a n g e )
/* FALLTHROUGH */
2013-05-21 20:35:19 +04:00
/ *
* _ _ dma_ i n v _ r a n g e ( s t a r t , e n d )
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
__dma_inv_range :
dcache_ l i n e _ s i z e x2 , x3
sub x3 , x2 , #1
bic x0 , x0 , x3
bic x1 , x1 , x3
1 : dc i v a c , x0 / / i n v a l i d a t e D / U l i n e
add x0 , x0 , x2
cmp x0 , x1
b. l o 1 b
dsb s y
ret
2014-03-26 22:25:55 +04:00
ENDPROC( _ _ i n v a l _ c a c h e _ r a n g e )
2013-05-21 20:35:19 +04:00
ENDPROC( _ _ d m a _ i n v _ r a n g e )
/ *
* _ _ dma_ c l e a n _ r a n g e ( s t a r t , e n d )
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
__dma_clean_range :
dcache_ l i n e _ s i z e x2 , x3
sub x3 , x2 , #1
bic x0 , x0 , x3
1 : dc c v a c , x0 / / c l e a n D / U l i n e
add x0 , x0 , x2
cmp x0 , x1
b. l o 1 b
dsb s y
ret
ENDPROC( _ _ d m a _ c l e a n _ r a n g e )
/ *
* _ _ dma_ f l u s h _ r a n g e ( s t a r t , e n d )
* - start - v i r t u a l s t a r t a d d r e s s o f r e g i o n
* - end - v i r t u a l e n d a d d r e s s o f r e g i o n
* /
ENTRY( _ _ d m a _ f l u s h _ r a n g e )
dcache_ l i n e _ s i z e x2 , x3
sub x3 , x2 , #1
bic x0 , x0 , x3
1 : dc c i v a c , x0 / / c l e a n & i n v a l i d a t e D / U l i n e
add x0 , x0 , x2
cmp x0 , x1
b. l o 1 b
dsb s y
ret
ENDPROC( _ _ d m a _ f l u s h _ r a n g e )
/ *
* _ _ dma_ m a p _ a r e a ( s t a r t , s i z e , d i r )
* - start - k e r n e l v i r t u a l s t a r t a d d r e s s
* - size - s i z e o f r e g i o n
* - dir - D M A d i r e c t i o n
* /
ENTRY( _ _ d m a _ m a p _ a r e a )
add x1 , x1 , x0
cmp w2 , #D M A _ F R O M _ D E V I C E
b. e q _ _ d m a _ i n v _ r a n g e
b _ _ d m a _ c l e a n _ r a n g e
ENDPROC( _ _ d m a _ m a p _ a r e a )
/ *
* _ _ dma_ u n m a p _ a r e a ( s t a r t , s i z e , d i r )
* - start - k e r n e l v i r t u a l s t a r t a d d r e s s
* - size - s i z e o f r e g i o n
* - dir - D M A d i r e c t i o n
* /
ENTRY( _ _ d m a _ u n m a p _ a r e a )
add x1 , x1 , x0
cmp w2 , #D M A _ T O _ D E V I C E
b. n e _ _ d m a _ i n v _ r a n g e
ret
ENDPROC( _ _ d m a _ u n m a p _ a r e a )