2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / a r m / m m / c a c h e - v4 w b . S
*
* Copyright ( C ) 1 9 9 7 - 2 0 0 2 R u s s e l l k i n g
*
* 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 < l i n u x / i n i t . h >
2006-04-07 16:17:15 +04:00
# include < a s m / m e m o r y . h >
2005-04-17 02:20:36 +04:00
# include < a s m / p a g e . h >
# include " p r o c - m a c r o s . S "
/ *
* The s i z e o f o n e d a t a c a c h e l i n e .
* /
# define C A C H E _ D L I N E S I Z E 3 2
/ *
* The t o t a l s i z e o f t h e d a t a c a c h e .
* /
# if d e f i n e d ( C O N F I G _ C P U _ S A 1 1 0 )
# define C A C H E _ D S I Z E 1 6 3 8 4
# elif d e f i n e d ( C O N F I G _ C P U _ S A 1 1 0 0 )
# define C A C H E _ D S I Z E 8 1 9 2
# else
# error U n k n o w n c a c h e s i z e
# endif
/ *
* This i s t h e s i z e a t w h i c h i t b e c o m e s m o r e e f f i c i e n t t o
* clean t h e w h o l e c a c h e , r a t h e r t h a n u s i n g t h e i n d i v i d u a l
* cache l i n e m a i n t a i n e n c e i n s t r u c t i o n s .
*
* Size C l e a n ( t i c k s ) D i r t y ( t i c k s )
* 4 0 9 6 2 1 2 0 2 1 5 3 5 5 5 4
* 8 1 9 2 4 0 4 1 4 0 1 0 6 1 0 0 1 0 2
* 1 6 3 8 4 7 7 7 7 7 6 1 4 0 1 4 0 1 3 8
* 3 2 7 6 8 1 5 0 1 4 9 1 5 0 2 1 4 2 1 6 2 1 2 < - - -
* 6 5 5 3 6 2 9 6 2 9 7 2 9 6 3 5 1 3 5 8 3 6 1
* 1 3 1 0 7 2 5 9 1 5 9 1 5 9 1 6 5 6 6 5 7 6 5 1
* Whole 1 3 2 1 3 6 1 3 2 2 2 1 2 1 7 2 0 7 < - - -
* /
# define C A C H E _ D L I M I T ( C A C H E _ D S I Z E * 4 )
2006-04-07 16:17:15 +04:00
.data
flush_base :
.long FLUSH_BASE
.text
2010-10-28 14:27:40 +04:00
/ *
* flush_ i c a c h e _ a l l ( )
*
* Unconditionally c l e a n a n d i n v a l i d a t e t h e e n t i r e i c a c h e .
* /
ENTRY( v4 w b _ f l u s h _ i c a c h e _ a l l )
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate I cache
mov p c , l r
ENDPROC( v4 w b _ f l u s h _ i c a c h e _ a l l )
2005-04-17 02:20:36 +04:00
/ *
* flush_ u s e r _ c a c h e _ a l l ( )
*
* Clean a n d i n v a l i d a t e a l l c a c h e e n t r i e s i n a p a r t i c u l a r a d d r e s s
* space.
* /
ENTRY( v4 w b _ f l u s h _ u s e r _ c a c h e _ a l l )
/* FALLTHROUGH */
/ *
* flush_ k e r n _ c a c h e _ a l l ( )
*
* Clean a n d i n v a l i d a t e t h e e n t i r e c a c h e .
* /
ENTRY( v4 w b _ f l u s h _ k e r n _ c a c h e _ a l l )
mov i p , #0
mcr p15 , 0 , i p , c7 , c5 , 0 @ invalidate I cache
__flush_whole_cache :
2006-04-07 16:17:15 +04:00
ldr r3 , =flush_base
ldr r1 , [ r3 , #0 ]
eor r1 , r1 , #C A C H E _ D S I Z E
str r1 , [ r3 , #0 ]
add r2 , r1 , #C A C H E _ D S I Z E
1 : ldr r3 , [ r1 ] , #32
cmp r1 , r2
blo 1 b
# ifdef F L U S H _ B A S E _ M I N I C A C H E
add r2 , r2 , #F L U S H _ B A S E _ M I N I C A C H E - F L U S H _ B A S E
sub r1 , r2 , #512 @ only 512 bytes
1 : ldr r3 , [ r1 ] , #32
cmp r1 , r2
2005-04-17 02:20:36 +04:00
blo 1 b
2006-04-07 16:17:15 +04:00
# endif
2005-04-17 02:20:36 +04:00
mcr p15 , 0 , i p , c7 , c10 , 4 @ drain write buffer
mov p c , l r
/ *
* flush_ u s e r _ c a c h e _ r a n g e ( s t a r t , e n d , f l a g s )
*
* Invalidate a r a n g e o f c a c h e e n t r i e s i n t h e s p e c i f i e d
* address s p a c e .
*
* - start - s t a r t a d d r e s s ( i n c l u s i v e , p a g e a l i g n e d )
* - end - e n d a d d r e s s ( e x c l u s i v e , p a g e a l i g n e d )
* - flags - v m a _ a r e a _ s t r u c t f l a g s d e s c r i b i n g a d d r e s s s p a c e
* /
ENTRY( v4 w b _ f l u s h _ u s e r _ c a c h e _ r a n g e )
2006-04-07 16:17:15 +04:00
mov i p , #0
2005-04-17 02:20:36 +04:00
sub r3 , r1 , r0 @ calculate total size
tst r2 , #V M _ E X E C @ e x e c u t a b l e r e g i o n ?
mcrne p15 , 0 , i p , c7 , c5 , 0 @ invalidate I cache
cmp r3 , #C A C H E _ D L I M I T @ t o t a l s i z e > = l i m i t ?
bhs _ _ f l u s h _ w h o l e _ c a c h e @ flush whole D cache
1 : mcr p15 , 0 , r0 , c7 , c10 , 1 @ clean D entry
mcr p15 , 0 , r0 , c7 , c6 , 1 @ invalidate D entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
cmp r0 , r1
blo 1 b
tst r2 , #V M _ E X E C
mcrne p15 , 0 , i p , c7 , c10 , 4 @ drain write buffer
mov p c , l r
/ *
2009-11-26 15:56:21 +03:00
* flush_ k e r n _ d c a c h e _ a r e a ( v o i d * a d d r , s i z e _ t s i z e )
2005-04-17 02:20:36 +04:00
*
* Ensure n o D c a c h e a l i a s i n g o c c u r s , e i t h e r w i t h i t s e l f o r
* the I c a c h e
*
2009-11-26 15:56:21 +03:00
* - addr - k e r n e l a d d r e s s
* - size - r e g i o n s i z e
2005-04-17 02:20:36 +04:00
* /
2009-11-26 15:56:21 +03:00
ENTRY( v4 w b _ f l u s h _ k e r n _ d c a c h e _ a r e a )
add r1 , r0 , r1
2005-04-17 02:20:36 +04:00
/* fall through */
/ *
* coherent_ k e r n _ r a n g e ( s t a r t , e n d )
*
* Ensure c o h e r e n c y b e t w e e n t h e I c a c h e a n d t h e D c a c h e i n t h e
* region d e s c r i b e d b y s t a r t . I f y o u h a v e n o n - s n o o p i n g
* Harvard c a c h e s , y o u n e e d t o i m p l e m e n t t h i s f u n c t i o n .
*
* - start - v i r t u a l s t a r t a d d r e s s
* - end - v i r t u a l e n d a d d r e s s
* /
ENTRY( v4 w b _ c o h e r e n t _ k e r n _ r a n g e )
/* fall through */
/ *
* coherent_ u s e r _ r a n g e ( s t a r t , e n d )
*
* Ensure c o h e r e n c y b e t w e e n t h e I c a c h e a n d t h e D c a c h e i n t h e
* region d e s c r i b e d b y s t a r t . I f y o u h a v e n o n - s n o o p i n g
* Harvard c a c h e s , y o u n e e d t o i m p l e m e n t t h i s f u n c t i o n .
*
* - start - v i r t u a l s t a r t a d d r e s s
* - end - v i r t u a l e n d a d d r e s s
* /
ENTRY( v4 w b _ c o h e r e n t _ u s e r _ r a n g e )
bic r0 , r0 , #C A C H E _ D L I N E S I Z E - 1
1 : mcr p15 , 0 , r0 , c7 , c10 , 1 @ clean D entry
mcr p15 , 0 , r0 , c7 , c6 , 1 @ invalidate D entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
cmp r0 , r1
blo 1 b
mov i p , #0
mcr p15 , 0 , i p , c7 , c5 , 0 @ invalidate I cache
mcr p15 , 0 , i p , c7 , c10 , 4 @ drain WB
mov p c , l r
/ *
* dma_ i n v _ r a n g e ( s t a r t , e n d )
*
* Invalidate ( d i s c a r d ) t h e s p e c i f i e d v i r t u a l a d d r e s s r a n g e .
* May n o t w r i t e b a c k a n y e n t r i e s . I f ' s t a r t ' o r ' e n d '
* are n o t c a c h e l i n e a l i g n e d , t h o s e l i n e s m u s t b e w r i t t e n
* back.
*
* - start - v i r t u a l s t a r t a d d r e s s
* - end - v i r t u a l e n d a d d r e s s
* /
2009-11-26 19:24:19 +03:00
v4wb_dma_inv_range :
2005-04-17 02:20:36 +04:00
tst r0 , #C A C H E _ D L I N E S I Z E - 1
bic r0 , r0 , #C A C H E _ D L I N E S I Z E - 1
mcrne p15 , 0 , r0 , c7 , c10 , 1 @ clean D entry
tst r1 , #C A C H E _ D L I N E S I Z E - 1
mcrne p15 , 0 , r1 , c7 , c10 , 1 @ clean D entry
1 : mcr p15 , 0 , r0 , c7 , c6 , 1 @ invalidate D entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
cmp r0 , r1
blo 1 b
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
mov p c , l r
/ *
* dma_ c l e a n _ r a n g e ( s t a r t , e n d )
*
* Clean ( w r i t e b a c k ) t h e s p e c i f i e d v i r t u a l a d d r e s s r a n g e .
*
* - start - v i r t u a l s t a r t a d d r e s s
* - end - v i r t u a l e n d a d d r e s s
* /
2009-11-26 19:24:19 +03:00
v4wb_dma_clean_range :
2005-04-17 02:20:36 +04:00
bic r0 , r0 , #C A C H E _ D L I N E S I Z E - 1
1 : mcr p15 , 0 , r0 , c7 , c10 , 1 @ clean D entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
cmp r0 , r1
blo 1 b
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
mov p c , l r
/ *
* dma_ f l u s h _ r a n g e ( s t a r t , e n d )
*
* Clean a n d i n v a l i d a t e t h e s p e c i f i e d v i r t u a l a d d r e s s r a n g e .
*
* - start - v i r t u a l s t a r t a d d r e s s
* - end - v i r t u a l e n d a d d r e s s
*
* This i s a c t u a l l y t h e s a m e a s v4 w b _ c o h e r e n t _ k e r n _ r a n g e ( )
* /
.globl v4wb_dma_flush_range
.set v4 w b _ d m a _ f l u s h _ r a n g e , v4 w b _ c o h e r e n t _ k e r n _ r a n g e
2009-11-26 19:19:58 +03:00
/ *
* 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( v4 w b _ d m a _ m a p _ a r e a )
add r1 , r1 , r0
cmp r2 , #D M A _ T O _ D E V I C E
beq v4 w b _ d m a _ c l e a n _ r a n g e
bcs v4 w b _ d m a _ i n v _ r a n g e
b v4 w b _ d m a _ f l u s h _ r a n g e
ENDPROC( v4 w b _ 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( v4 w b _ d m a _ u n m a p _ a r e a )
mov p c , l r
ENDPROC( v4 w b _ d m a _ u n m a p _ a r e a )
2005-04-17 02:20:36 +04:00
_ _ INITDATA
.type v4 w b _ c a c h e _ f n s , #o b j e c t
ENTRY( v4 w b _ c a c h e _ f n s )
2010-10-28 14:27:40 +04:00
.long v4wb_flush_icache_all
2005-04-17 02:20:36 +04:00
.long v4wb_flush_kern_cache_all
.long v4wb_flush_user_cache_all
.long v4wb_flush_user_cache_range
.long v4wb_coherent_kern_range
.long v4wb_coherent_user_range
2009-11-26 15:56:21 +03:00
.long v4wb_flush_kern_dcache_area
2009-11-26 19:19:58 +03:00
.long v4wb_dma_map_area
.long v4wb_dma_unmap_area
2005-04-17 02:20:36 +04:00
.long v4wb_dma_flush_range
.size v4 w b _ c a c h e _ f n s , . - v4 w b _ c a c h e _ f n s