2006-09-26 17:38:32 +09:00
/ *
* linux/ a r c h / a r m / m m / a r m 9 4 6 . 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 6 E - S
*
* 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)
*
* ( Many o f c a c h e c o d e s a r e f r o m p r o c - a r m 9 2 6 . S )
*
* 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 >
2006-11-09 14:20:47 +00:00
# include < a s m / e l f . h >
2006-09-26 17:38:32 +09: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 >
/ *
* ARM9 4 6 E - S i s s y n t h e s i z a b l e t o h a v e 0 K B t o 1 M B s i z e d D - C a c h e ,
* comprising 2 5 6 l i n e s o f 3 2 b y t e s ( 8 w o r d s ) .
* /
# define C A C H E _ D S I Z E ( C O N F I G _ C P U _ D C A C H E _ S I Z E ) / * t y p i c a l l y 8 K B . * /
# define C A C H E _ D L I N E S I Z E 3 2 / * f i x e d * /
# define C A C H E _ D S E G M E N T S 4 / * f i x e d * /
# define C A C H E _ D E N T R I E S ( C A C H E _ D S I Z E / C A C H E _ D S E G M E N T S / C A C H E _ D L I N E S I Z E )
# define C A C H E _ D L I M I T ( C A C H E _ D S I Z E * 4 ) / * b e n c h m a r k n e e d e d * /
.text
/ *
* cpu_ a r m 9 4 6 _ p r o c _ i n i t ( )
* cpu_ a r m 9 4 6 _ 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 6 _ p r o c _ i n i t )
ENTRY( c p u _ a r m 9 4 6 _ s w i t c h _ m m )
mov p c , l r
/ *
* cpu_ a r m 9 4 6 _ p r o c _ f i n ( )
* /
ENTRY( c p u _ a r m 9 4 6 _ p r o c _ f i n )
stmfd s p ! , { l r }
mov i p , #P S R _ F _ B I T | P S R _ I _ B I T | S V C _ M O D E
msr c p s r _ c , i p
bl a r m 9 4 6 _ f l u s h _ k e r n _ c a c h e _ a l l
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
ldmfd s p ! , { p c }
/ *
* cpu_ a r m 9 4 6 _ 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
* /
ENTRY( c p u _ a r m 9 4 6 _ 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
mov p c , r0
/ *
* cpu_ a r m 9 4 6 _ d o _ i d l e ( )
* /
.align 5
ENTRY( c p u _ a r m 9 4 6 _ d o _ i d l e )
mcr p15 , 0 , r0 , c7 , c0 , 4 @ Wait for interrupt
mov p c , l r
/ *
* flush_ u s e r _ c a c h e _ a l l ( )
* /
ENTRY( a r m 9 4 6 _ 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 6 _ 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
mov i p , #0
__flush_whole_cache :
# 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 ) < < 2 9 @ 4 segments
1 : orr r3 , r1 , #( C A C H E _ D E N T R I E S - 1 ) < < 4 @ n entries
2 : mcr p15 , 0 , r3 , c7 , c14 , 2 @ clean/flush D index
subs r3 , r3 , #1 < < 4
bcs 2 b @ entries n to 0
subs r1 , r1 , #1 < < 2 9
bcs 1 b @ segments 3 to 0
# endif
tst r2 , #V M _ E X E C
mcrne p15 , 0 , i p , c7 , c5 , 0 @ flush I cache
mcrne p15 , 0 , i p , c7 , c10 , 4 @ drain WB
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 )
*
* Clean a n d i n v a l i d a t e 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
* specified a d d r e s s r a n g e .
*
* - 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
* ( same a s a r m 9 2 6 )
* /
ENTRY( a r m 9 4 6 _ f l u s h _ u s e r _ c a c h e _ r a n g e )
mov i p , #0
sub r3 , r1 , r0 @ calculate total size
cmp r3 , #C A C H E _ D L I M I T
bhs _ _ f l u s h _ w h o l e _ c a c h e
1 : tst r2 , #V M _ E X E C
# 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 , r0 , c7 , c6 , 1 @ invalidate D entry
mcrne p15 , 0 , r0 , c7 , c5 , 1 @ invalidate I entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
mcr p15 , 0 , r0 , c7 , c6 , 1 @ invalidate D entry
mcrne p15 , 0 , r0 , c7 , c5 , 1 @ invalidate I entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
# else
mcr p15 , 0 , r0 , c7 , c14 , 1 @ clean and invalidate D entry
mcrne p15 , 0 , r0 , c7 , c5 , 1 @ invalidate I entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
mcr p15 , 0 , r0 , c7 , c14 , 1 @ clean and invalidate D entry
mcrne p15 , 0 , r0 , c7 , c5 , 1 @ invalidate I entry
add r0 , r0 , #C A C H E _ D L I N E S I Z E
# endif
cmp r0 , r1
blo 1 b
tst r2 , #V M _ E X E C
mcrne p15 , 0 , i p , c7 , c10 , 4 @ drain WB
mov p c , l r
/ *
* 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 6 _ 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
* ( same a s a r m 9 2 6 )
* /
ENTRY( a r m 9 4 6 _ 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 , c5 , 1 @ invalidate I 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 WB
mov p c , l r
/ *
* flush_ k e r n _ d c a c h e _ p a g e ( v o i d * p a g e )
*
* 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
*
* - addr - p a g e a l i g n e d a d d r e s s
* ( same a s a r m 9 2 6 )
* /
ENTRY( a r m 9 4 6 _ f l u s h _ k e r n _ d c a c h e _ p a g e )
add r1 , r0 , #P A G E _ S Z
1 : mcr p15 , 0 , r0 , c7 , c14 , 1 @ clean+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 r0 , #0
mcr p15 , 0 , r0 , c7 , c5 , 0 @ invalidate I cache
mcr p15 , 0 , r0 , 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
* ( same a s a r m 9 2 6 )
* /
ENTRY( a r m 9 4 6 _ d m a _ i n v _ r a n g e )
# 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
tst 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
# endif
bic r0 , r0 , #C A C H E _ D L I N E S I Z E - 1
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 WB
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 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
*
* ( same a s a r m 9 2 6 )
* /
ENTRY( a r m 9 4 6 _ d m a _ c l e a n _ r a n g e )
# 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
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
# endif
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain WB
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
*
* ( same a s a r m 9 2 6 )
* /
ENTRY( a r m 9 4 6 _ d m a _ f l u s h _ r a n g e )
bic r0 , r0 , #C A C H E _ D L I N E S I Z E - 1
1 :
# 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 , r0 , c7 , c14 , 1 @ clean+invalidate D entry
# else
mcr p15 , 0 , r0 , c7 , c10 , 1 @ clean D entry
# endif
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 WB
mov p c , l r
ENTRY( a r m 9 4 6 _ c a c h e _ f n s )
.long arm946_flush_kern_cache_all
.long arm946_flush_user_cache_all
.long arm946_flush_user_cache_range
.long arm946_coherent_kern_range
.long arm946_coherent_user_range
.long arm946_flush_kern_dcache_page
.long arm946_dma_inv_range
.long arm946_dma_clean_range
.long arm946_dma_flush_range
ENTRY( c p u _ a r m 9 4 6 _ d c a c h e _ c l e a n _ a r e a )
# 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
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
subs r1 , r1 , #C A C H E _ D L I N E S I Z E
bhi 1 b
# endif
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain WB
mov p c , l r
_ _ INIT
.type _ _ arm9 4 6 _ s e t u p , #f u n c t i o n
__arm946_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 memory region 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
mov r0 , #0x0000003F @ base = 0, size = 4GB
mcr p15 , 0 , r0 , c6 , c0 , 0 @ set region 0, default
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
ldr r1 , = ( C O N F I G _ D R A M _ S I Z E > > 1 2 ) @ size of RAM (must be >= 4KB)
mov r2 , #10 @ 11 is the minimum (4KB)
1 : add r2 , r2 , #1 @ area size *= 2
mov r1 , r1 , l s r #1
bne 1 b @ count not zero r-shift
orr r0 , r0 , r2 , l s l #1 @ the region register value
orr r0 , r0 , #1 @ set enable bit
mcr p15 , 0 , r0 , c6 , c1 , 0 @ set region 1, RAM
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
ldr r1 , = ( C O N F I G _ F L A S H _ S I Z E > > 1 2 ) @ size of FLASH (must be >= 4KB)
mov r2 , #10 @ 11 is the minimum (4KB)
1 : add r2 , r2 , #1 @ area size *= 2
mov r1 , r1 , l s r #1
bne 1 b @ count not zero r-shift
orr r0 , r0 , r2 , l s l #1 @ the region register value
orr r0 , r0 , #1 @ set enable bit
mcr p15 , 0 , r0 , c6 , c2 , 0 @ set region 2, ROM/FLASH
mov r0 , #0x06
mcr p15 , 0 , r0 , c2 , c0 , 0 @ region 1,2 d-cacheable
mcr p15 , 0 , r0 , c2 , c0 , 1 @ region 1,2 i-cacheable
# 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
/ *
* Access P e r m i s s i o n S e t t i n g s f o r f u t u r e p e r m i s s i o n c o n t r o l b y P U .
*
* priv. u s e r
* region 0 ( w h o l e ) r w - - : b00 0 1
* region 1 ( R A M ) r w r w : b00 1 1
* region 2 ( F L A S H ) r w r - : b00 1 0
* region 3 ~ 7 ( n o n e ) - - - - : b00 0 0
* /
mov r0 , #0x00000031
orr r0 , r0 , #0x00000200
mcr p15 , 0 , r0 , c5 , c0 , 2 @ set data access permission
mcr p15 , 0 , r0 , c5 , c0 , 3 @ set inst. access permission
mrc p15 , 0 , r0 , c1 , c0 @ get control register
orr r0 , r0 , #0x00001000 @ I-cache
orr r0 , r0 , #0x00000005 @ MPU/D-cache
# ifdef C O N F I G _ C P U _ C A C H E _ R O U N D _ R O B I N
orr r0 , r0 , #0x00004000 @ .1.. .... .... ....
# endif
mov p c , l r
.size _ _ arm9 4 6 _ s e t u p , . - _ _ a r m 9 4 6 _ s e t u p
_ _ INITDATA
/ *
* Purpose : F u n c t i o n p o i n t e r s u s e d t o a c c e s s a b o v e f u n c t i o n s - a l l c a l l s
* come t h r o u g h t h e s e
* /
.type arm9 4 6 _ p r o c e s s o r _ f u n c t i o n s , #o b j e c t
ENTRY( a r m 9 4 6 _ p r o c e s s o r _ f u n c t i o n s )
2006-09-28 21:46:16 +09:00
.word nommu_early_abort
2006-09-26 17:38:32 +09:00
.word cpu_arm946_proc_init
.word cpu_arm946_proc_fin
.word cpu_arm946_reset
.word cpu_arm946_do_idle
.word cpu_arm946_dcache_clean_area
.word cpu_arm946_switch_mm
.word 0 @ cpu_*_set_pte
.size arm9 4 6 _ p r o c e s s o r _ f u n c t i o n s , . - a r m 9 4 6 _ p r o c e s s o r _ f u n c t i o n s
.section " .rodata "
.type cpu_ a r c h _ n a m e , #o b j e c t
cpu_arch_name :
.asciz " armv5 t e "
.size cpu_ a r c h _ n a m e , . - c p u _ a r c h _ n a m e
.type cpu_ e l f _ n a m e , #o b j e c t
cpu_elf_name :
.asciz " v5 t "
.size cpu_ e l f _ n a m e , . - c p u _ e l f _ n a m e
.type cpu_ a r m 9 4 6 _ n a m e , #o b j e c t
cpu_arm946_name :
.ascii " ARM9 4 6 E - S "
.size cpu_ a r m 9 4 6 _ n a m e , . - c p u _ a r m 9 4 6 _ n a m e
.align
.section " .proc .info .init " , # alloc, #e x e c i n s t r
.type _ _ arm9 4 6 _ p r o c _ i n f o ,#o b j e c t
__arm946_proc_info :
.long 0x41009460
.long 0xff00fff0
.long 0
b _ _ a r m 9 4 6 _ s e t u p
.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_arm946_name
.long arm946_processor_functions
.long 0
.long 0
.long arm940_cache_fns
.size _ _ arm9 4 6 _ p r o c _ i n f o , . - _ _ a r m 9 4 6 _ p r o c _ i n f o