2006-09-26 12:38:18 +04:00
/ *
* linux/ a r c h / a r m / m m / a r m 9 4 0 . S : u t i l i t y f u n c t i o n s f o r A R M 9 4 0 T
*
* Copyright ( C ) 2 0 0 4 - 2 0 0 6 H y o k S . C h o i ( h y o k . c h o i @samsung.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
* 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 >
# include < a s m / a s s e m b l e r . h >
2008-09-07 22:15:31 +04:00
# include < a s m / h w c a p . h >
2006-09-26 12:38:18 +04:00
# include < a s m / p g t a b l e - h w d e f . h >
# include < a s m / p g t a b l e . h >
# include < a s m / p t r a c e . h >
2008-08-12 17:02:23 +04:00
# include " p r o c - m a c r o s . S "
2006-09-26 12:38:18 +04:00
/* ARM940T has a 4KB DCache comprising 256 lines of 4 words */
# define C A C H E _ D L I N E S I Z E 1 6
# define C A C H E _ D S E G M E N T S 4
# define C A C H E _ D E N T R I E S 6 4
.text
/ *
* cpu_ a r m 9 4 0 _ p r o c _ i n i t ( )
* cpu_ a r m 9 4 0 _ s w i t c h _ m m ( )
*
* These a r e n o t r e q u i r e d .
* /
ENTRY( c p u _ a r m 9 4 0 _ p r o c _ i n i t )
ENTRY( c p u _ a r m 9 4 0 _ s w i t c h _ m m )
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
/ *
* cpu_ a r m 9 4 0 _ p r o c _ f i n ( )
* /
ENTRY( c p u _ a r m 9 4 0 _ p r o c _ f i n )
mrc p15 , 0 , r0 , c1 , c0 , 0 @ ctrl register
bic r0 , r0 , #0x00001000 @ i-cache
bic r0 , r0 , #0x00000004 @ d-cache
mcr p15 , 0 , r0 , c1 , c0 , 0 @ disable caches
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
/ *
* cpu_ a r m 9 4 0 _ r e s e t ( l o c )
* Params : r0 = a d d r e s s t o j u m p t o
* Notes : T h i s s e t s u p e v e r y t h i n g f o r a r e s e t
* /
2011-11-15 17:25:04 +04:00
.pushsection .idmap .text , " ax"
2006-09-26 12:38:18 +04:00
ENTRY( c p u _ a r m 9 4 0 _ r e s e t )
mov i p , #0
mcr p15 , 0 , i p , c7 , c5 , 0 @ flush I cache
mcr p15 , 0 , i p , c7 , c6 , 0 @ flush D cache
mcr p15 , 0 , i p , c7 , c10 , 4 @ drain WB
mrc p15 , 0 , i p , c1 , c0 , 0 @ ctrl register
bic i p , i p , #0x00000005 @ .............c.p
bic i p , i p , #0x00001000 @ i-cache
mcr p15 , 0 , i p , c1 , c0 , 0 @ ctrl register
2014-06-30 19:29:12 +04:00
ret r0
2011-11-15 17:25:04 +04:00
ENDPROC( c p u _ a r m 9 4 0 _ r e s e t )
.popsection
2006-09-26 12:38:18 +04:00
/ *
* cpu_ a r m 9 4 0 _ d o _ i d l e ( )
* /
.align 5
ENTRY( c p u _ a r m 9 4 0 _ d o _ i d l e )
mcr p15 , 0 , r0 , c7 , c0 , 4 @ Wait for interrupt
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
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( a r m 9 4 0 _ 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
2014-06-30 19:29:12 +04:00
ret l r
2010-10-28 14:27:40 +04:00
ENDPROC( a r m 9 4 0 _ f l u s h _ i c a c h e _ a l l )
2006-09-26 12:38:18 +04:00
/ *
* flush_ u s e r _ c a c h e _ a l l ( )
* /
ENTRY( a r m 9 4 0 _ 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( a r m 9 4 0 _ f l u s h _ k e r n _ c a c h e _ a l l )
mov r2 , #V M _ E X E C
/* FALLTHROUGH */
/ *
* 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 )
*
* There i s n o e f f i c i e n t w a y t o f l u s h a r a n g e o f c a c h e e n t r i e s
* in t h e s p e c i f i e d a d d r e s s r a n g e . T h u s , f l u s h e s a l l .
*
* - start - s t a r t a d d r e s s ( i n c l u s i v e )
* - end - e n d a d d r e s s ( e x c l u s i v e )
* - flags - v m _ 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( a r m 9 4 0 _ f l u s h _ u s e r _ c a c h e _ r a n g e )
mov i p , #0
# ifdef C O N F I G _ C P U _ D C A C H E _ W R I T E T H R O U G H
mcr p15 , 0 , i p , c7 , c6 , 0 @ flush D cache
# else
mov r1 , #( C A C H E _ D S E G M E N T S - 1 ) < < 4 @ 4 segments
1 : orr r3 , r1 , #( C A C H E _ D E N T R I E S - 1 ) < < 2 6 @ 64 entries
2 : mcr p15 , 0 , r3 , c7 , c14 , 2 @ clean/flush D index
subs r3 , r3 , #1 < < 2 6
bcs 2 b @ entries 63 to 0
subs r1 , r1 , #1 < < 4
bcs 1 b @ segments 3 to 0
# endif
tst r2 , #V M _ E X E C
mcrne p15 , 0 , i p , c7 , c5 , 0 @ invalidate I cache
mcrne p15 , 0 , i p , c7 , c10 , 4 @ drain WB
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
/ *
* 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 , e n d . 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( a r m 9 4 0 _ c o h e r e n t _ k e r n _ r a n g e )
/* FALLTHROUGH */
/ *
* 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 , e n d . 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( a r m 9 4 0 _ c o h e r e n t _ u s e r _ r a n g e )
/* FALLTHROUGH */
/ *
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 )
2006-09-26 12:38:18 +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
2006-09-26 12:38:18 +04:00
* /
2009-11-26 15:56:21 +03:00
ENTRY( a r m 9 4 0 _ f l u s h _ k e r n _ d c a c h e _ a r e a )
2012-04-27 16:08:53 +04:00
mov r0 , #0
2006-09-26 12:38:18 +04:00
mov r1 , #( C A C H E _ D S E G M E N T S - 1 ) < < 4 @ 4 segments
1 : orr r3 , r1 , #( C A C H E _ D E N T R I E S - 1 ) < < 2 6 @ 64 entries
2 : mcr p15 , 0 , r3 , c7 , c14 , 2 @ clean/flush D index
subs r3 , r3 , #1 < < 2 6
bcs 2 b @ entries 63 to 0
subs r1 , r1 , #1 < < 4
bcs 1 b @ segments 7 to 0
2012-04-27 16:08:53 +04:00
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate I cache
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain WB
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
/ *
* dma_ i n v _ r a n g e ( s t a r t , e n d )
*
* There i s n o e f f i c i e n t w a y t o i n v a l i d a t e a s p e c i f i d v i r t u a l
* address r a n g e . T h u s , i n v a l i d a t e s a l l .
*
* - 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
arm940_dma_inv_range :
2006-09-26 12:38:18 +04:00
mov i p , #0
mov r1 , #( C A C H E _ D S E G M E N T S - 1 ) < < 4 @ 4 segments
1 : orr r3 , r1 , #( C A C H E _ D E N T R I E S - 1 ) < < 2 6 @ 64 entries
2 : mcr p15 , 0 , r3 , c7 , c6 , 2 @ flush D entry
subs r3 , r3 , #1 < < 2 6
bcs 2 b @ entries 63 to 0
subs r1 , r1 , #1 < < 4
bcs 1 b @ segments 7 to 0
mcr p15 , 0 , i p , c7 , c10 , 4 @ drain WB
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
/ *
* dma_ c l e a n _ r a n g e ( s t a r t , e n d )
*
* There i s n o e f f i c i e n t w a y t o c l e a n a s p e c i f i d v i r t u a l
* address r a n g e . T h u s , c l e a n s a l l .
*
* - 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
arm940_dma_clean_range :
2006-09-26 12:38:18 +04:00
ENTRY( c p u _ a r m 9 4 0 _ d c a c h e _ c l e a n _ a r e a )
mov i p , #0
# ifndef C O N F I G _ C P U _ D C A C H E _ W R I T E T H R O U G H
mov r1 , #( C A C H E _ D S E G M E N T S - 1 ) < < 4 @ 4 segments
1 : orr r3 , r1 , #( C A C H E _ D E N T R I E S - 1 ) < < 2 6 @ 64 entries
2 : mcr p15 , 0 , r3 , c7 , c10 , 2 @ clean D entry
subs r3 , r3 , #1 < < 2 6
bcs 2 b @ entries 63 to 0
subs r1 , r1 , #1 < < 4
bcs 1 b @ segments 7 to 0
# endif
mcr p15 , 0 , i p , c7 , c10 , 4 @ drain WB
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
/ *
* dma_ f l u s h _ r a n g e ( s t a r t , e n d )
*
* There i s n o e f f i c i e n t w a y t o c l e a n a n d i n v a l i d a t e a s p e c i f i d
* virtual 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
* /
ENTRY( a r m 9 4 0 _ d m a _ f l u s h _ r a n g e )
mov i p , #0
mov r1 , #( C A C H E _ D S E G M E N T S - 1 ) < < 4 @ 4 segments
1 : orr r3 , r1 , #( C A C H E _ D E N T R I E S - 1 ) < < 2 6 @ 64 entries
2 :
# ifndef C O N F I G _ C P U _ D C A C H E _ W R I T E T H R O U G H
mcr p15 , 0 , r3 , c7 , c14 , 2 @ clean/flush D entry
# else
2008-05-11 00:05:31 +04:00
mcr p15 , 0 , r3 , c7 , c6 , 2 @ invalidate D entry
2006-09-26 12:38:18 +04:00
# endif
subs r3 , r3 , #1 < < 2 6
bcs 2 b @ entries 63 to 0
subs r1 , r1 , #1 < < 4
bcs 1 b @ segments 7 to 0
mcr p15 , 0 , i p , c7 , c10 , 4 @ drain WB
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
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( a r m 9 4 0 _ 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 a r m 9 4 0 _ d m a _ c l e a n _ r a n g e
bcs a r m 9 4 0 _ d m a _ i n v _ r a n g e
b a r m 9 4 0 _ d m a _ f l u s h _ r a n g e
ENDPROC( a r m 9 4 0 _ 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( a r m 9 4 0 _ d m a _ u n m a p _ a r e a )
2014-06-30 19:29:12 +04:00
ret l r
2009-11-26 19:19:58 +03:00
ENDPROC( a r m 9 4 0 _ d m a _ u n m a p _ a r e a )
2012-09-06 17:05:13 +04:00
.globl arm940_flush_kern_cache_louis
.equ arm9 4 0 _ f l u s h _ k e r n _ c a c h e _ l o u i s , a r m 9 4 0 _ f l u s h _ k e r n _ c a c h e _ a l l
2011-06-23 20:21:02 +04:00
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_ c a c h e _ f u n c t i o n s a r m 9 4 0
2006-09-26 12:38:18 +04:00
.type _ _ arm9 4 0 _ s e t u p , #f u n c t i o n
__arm940_setup :
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate I cache
mcr p15 , 0 , r0 , c7 , c6 , 0 @ invalidate D cache
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain WB
mcr p15 , 0 , r0 , c6 , c3 , 0 @ disable data area 3~7
mcr p15 , 0 , r0 , c6 , c4 , 0
mcr p15 , 0 , r0 , c6 , c5 , 0
mcr p15 , 0 , r0 , c6 , c6 , 0
mcr p15 , 0 , r0 , c6 , c7 , 0
mcr p15 , 0 , r0 , c6 , c3 , 1 @ disable instruction area 3~7
mcr p15 , 0 , r0 , c6 , c4 , 1
mcr p15 , 0 , r0 , c6 , c5 , 1
mcr p15 , 0 , r0 , c6 , c6 , 1
mcr p15 , 0 , r0 , c6 , c7 , 1
mov r0 , #0x0000003F @ base = 0, size = 4GB
mcr p15 , 0 , r0 , c6 , c0 , 0 @ set area 0, default
mcr p15 , 0 , r0 , c6 , c0 , 1
ldr r0 , = ( C O N F I G _ D R A M _ B A S E & 0 x F F F F F 0 0 0 ) @ base[31:12] of RAM
2015-04-05 01:22:07 +03:00
ldr r7 , =CONFIG_DRAM_SIZE > > 1 2 @ size of RAM (must be >= 4KB)
pr_ v a l r3 , r0 , r7 , #1
mcr p15 , 0 , r3 , c6 , c1 , 0 @ set area 1, RAM
mcr p15 , 0 , r3 , c6 , c1 , 1
2006-09-26 12:38:18 +04:00
ldr r0 , = ( C O N F I G _ F L A S H _ M E M _ B A S E & 0 x F F F F F 0 0 0 ) @ base[31:12] of FLASH
2015-04-05 01:22:07 +03:00
ldr r7 , =CONFIG_FLASH_SIZE @ size of FLASH (must be >= 4KB)
pr_ v a l r3 , r0 , r6 , #1
mcr p15 , 0 , r3 , c6 , c2 , 0 @ set area 2, ROM/FLASH
mcr p15 , 0 , r3 , c6 , c2 , 1
2006-09-26 12:38:18 +04:00
mov r0 , #0x06
mcr p15 , 0 , r0 , c2 , c0 , 0 @ Region 1&2 cacheable
mcr p15 , 0 , r0 , c2 , c0 , 1
# ifdef C O N F I G _ C P U _ D C A C H E _ W R I T E T H R O U G H
mov r0 , #0x00 @ disable whole write buffer
# else
mov r0 , #0x02 @ Region 1 write bufferred
# endif
mcr p15 , 0 , r0 , c3 , c0 , 0
mov r0 , #0x10000
sub r0 , r0 , #1 @ r0 = 0xffff
mcr p15 , 0 , r0 , c5 , c0 , 0 @ all read/write access
mcr p15 , 0 , r0 , c5 , c0 , 1
mrc p15 , 0 , r0 , c1 , c0 @ get control register
orr r0 , r0 , #0x00001000 @ I-cache
orr r0 , r0 , #0x00000005 @ MPU/D-cache
2014-06-30 19:29:12 +04:00
ret l r
2006-09-26 12:38:18 +04:00
.size _ _ arm9 4 0 _ s e t u p , . - _ _ a r m 9 4 0 _ s e t u p
_ _ INITDATA
2011-06-23 20:21:02 +04:00
@ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
define_ p r o c e s s o r _ f u n c t i o n s a r m 9 4 0 , d a b o r t =nommu_early_abort , p a b o r t =legacy_pabort , n o m m u =1
2006-09-26 12:38:18 +04:00
.section " .rodata "
2011-06-23 20:21:02 +04:00
string c p u _ a r c h _ n a m e , " a r m v4 t "
string c p u _ e l f _ n a m e , " v4 "
string c p u _ a r m 9 4 0 _ n a m e , " A R M 9 4 0 T "
2006-09-26 12:38:18 +04:00
.align
2015-03-18 09:29:32 +03:00
.section " .proc .info .init " , # alloc
2006-09-26 12:38:18 +04:00
.type _ _ arm9 4 0 _ p r o c _ i n f o ,#o b j e c t
__arm940_proc_info :
.long 0x41009400
.long 0xff00fff0
.long 0
2015-03-18 09:29:32 +03:00
initfn _ _ a r m 9 4 0 _ s e t u p , _ _ a r m 9 4 0 _ p r o c _ i n f o
2006-09-26 12:38:18 +04:00
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_ H A L F | H W C A P _ T H U M B
.long cpu_arm940_name
.long arm940_processor_functions
.long 0
.long 0
.long arm940_cache_fns
.size _ _ arm9 4 0 _ p r o c _ i n f o , . - _ _ a r m 9 4 0 _ p r o c _ i n f o