2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / a r m / m m / p r o c - a r m 6 ,7 . S
*
* Copyright ( C ) 1 9 9 7 - 2 0 0 0 R u s s e l l K i n g
2006-06-28 17:10:01 +04:00
* hacked f o r n o n - p a g e d - M M b y H y o k S . C h o i , 2 0 0 3 .
2005-04-17 02:20:36 +04:00
*
* 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 .
*
* These a r e t h e l o w l e v e l a s s e m b l e r f o r p e r f o r m i n g c a c h e a n d T L B
* functions o n t h e A R M 6 1 0 & A R M 7 1 0 .
* /
# 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 >
2005-09-09 23:08:59 +04:00
# include < a s m / a s m - o f f s e t s . h >
2008-09-07 22:15:31 +04:00
# include < a s m / h w c a p . h >
2006-03-16 17:44:36 +03:00
# include < a s m / p g t a b l e - h w d e f . h >
2005-04-17 02:20:36 +04:00
# include < a s m / p g t a b l e . h >
# include < a s m / p t r a c e . h >
2008-09-06 20:19:08 +04:00
# include " p r o c - m a c r o s . S "
2005-04-17 02:20:36 +04:00
ENTRY( c p u _ a r m 6 _ d c a c h e _ c l e a n _ a r e a )
ENTRY( c p u _ a r m 7 _ d c a c h e _ c l e a n _ a r e a )
mov p c , l r
/ *
* Function : arm6 _ 7 _ d a t a _ a b o r t ( )
*
2011-06-26 19:01:26 +04:00
* Params : r2 = p t _ r e g s
* : r4 = a b o r t e d c o n t e x t p c
2011-06-26 17:35:07 +04:00
* : r5 = a b o r t e d c o n t e x t p s r
2005-04-17 02:20:36 +04:00
*
* Purpose : o b t a i n i n f o r m a t i o n a b o u t c u r r e n t a b o r t e d i n s t r u c t i o n
*
2011-06-27 15:27:47 +04:00
* Returns : r4 - r5 , r10 - r11 , r13 p r e s e r v e d
2005-04-17 02:20:36 +04:00
* /
ENTRY( c p u _ a r m 7 _ d a t a _ a b o r t )
mrc p15 , 0 , r1 , c5 , c0 , 0 @ get FSR
mrc p15 , 0 , r0 , c6 , c0 , 0 @ get FAR
2011-06-26 17:35:07 +04:00
ldr r8 , [ r4 ] @ read arm instruction
2005-09-04 13:13:48 +04:00
tst r8 , #1 < < 2 0 @ L = 0 -> write?
orreq r1 , r1 , #1 < < 1 1 @ yes.
2005-04-17 02:20:36 +04:00
and r7 , r8 , #15 < < 2 4
add p c , p c , r7 , l s r #22 @ Now branch to the relevant processing routine
nop
/* 0 */ b . d a t a _ u n k n o w n
2011-06-26 19:01:26 +04:00
/* 1 */ b d o _ D a t a A b o r t @ swp
2005-04-17 02:20:36 +04:00
/* 2 */ b . d a t a _ u n k n o w n
/* 3 */ b . d a t a _ u n k n o w n
/* 4 */ b . d a t a _ a r m _ l a t e l d r p o s t c o n s t @ ldr rd, [rn], #m
/* 5 */ b . d a t a _ a r m _ l a t e l d r p r e c o n s t @ ldr rd, [rn, #m]
/* 6 */ b . d a t a _ a r m _ l a t e l d r p o s t r e g @ ldr rd, [rn], rm
/* 7 */ b . d a t a _ a r m _ l a t e l d r p r e r e g @ ldr rd, [rn, rm]
/* 8 */ b . d a t a _ a r m _ l d m s t m @ ldm*a rn, <rlist>
/* 9 */ b . d a t a _ a r m _ l d m s t m @ ldm*b rn, <rlist>
/* a */ b . d a t a _ u n k n o w n
/* b */ b . d a t a _ u n k n o w n
2011-06-26 19:01:26 +04:00
/* c */ b d o _ D a t a A b o r t @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
/* d */ b d o _ D a t a A b o r t @ ldc rd, [rn, #m]
2005-04-17 02:20:36 +04:00
/* e */ b . d a t a _ u n k n o w n
/* f */
.data_unknown : @ Part of jumptable
2011-06-26 17:35:07 +04:00
mov r0 , r4
2005-04-17 02:20:36 +04:00
mov r1 , r8
2011-06-26 19:01:26 +04:00
b b a d d a t a a b o r t
2005-04-17 02:20:36 +04:00
ENTRY( c p u _ a r m 6 _ d a t a _ a b o r t )
mrc p15 , 0 , r1 , c5 , c0 , 0 @ get FSR
mrc p15 , 0 , r0 , c6 , c0 , 0 @ get FAR
2011-06-26 17:35:07 +04:00
ldr r8 , [ r4 ] @ read arm instruction
2005-09-04 13:13:48 +04:00
tst r8 , #1 < < 2 0 @ L = 0 -> write?
orreq r1 , r1 , #1 < < 1 1 @ yes.
2005-04-17 02:20:36 +04:00
and r7 , r8 , #14 < < 2 4
teq r7 , #8 < < 2 4 @ was it ldm/stm
2011-06-26 19:01:26 +04:00
bne d o _ D a t a A b o r t
2005-04-17 02:20:36 +04:00
.data_arm_ldmstm :
tst r8 , #1 < < 2 1 @ check writeback bit
2011-06-26 19:01:26 +04:00
beq d o _ D a t a A b o r t @ no writeback -> no fixup
2005-04-17 02:20:36 +04:00
mov r7 , #0x11
orr r7 , r7 , #0x1100
and r6 , r8 , r7
2011-06-26 17:42:02 +04:00
and r9 , r8 , r7 , l s l #1
add r6 , r6 , r9 , l s r #1
and r9 , r8 , r7 , l s l #2
add r6 , r6 , r9 , l s r #2
and r9 , r8 , r7 , l s l #3
add r6 , r6 , r9 , l s r #3
2005-04-17 02:20:36 +04:00
add r6 , r6 , r6 , l s r #8
add r6 , r6 , r6 , l s r #4
and r6 , r6 , #15 @ r6 = no. of registers to transfer.
2011-06-27 15:27:47 +04:00
and r9 , r8 , #15 < < 1 6 @ Extract 'n' from instruction
ldr r7 , [ r2 , r9 , l s r #14 ] @ Get register 'Rn'
2005-04-17 02:20:36 +04:00
tst r8 , #1 < < 2 3 @ Check U bit
subne r7 , r7 , r6 , l s l #2 @ Undo increment
addeq r7 , r7 , r6 , l s l #2 @ Undo decrement
2011-06-27 15:27:47 +04:00
str r7 , [ r2 , r9 , l s r #14 ] @ Put register 'Rn'
2011-06-26 19:01:26 +04:00
b d o _ D a t a A b o r t
2005-04-17 02:20:36 +04:00
.data_arm_apply_r6_and_rn :
2011-06-27 15:27:47 +04:00
and r9 , r8 , #15 < < 1 6 @ Extract 'n' from instruction
ldr r7 , [ r2 , r9 , l s r #14 ] @ Get register 'Rn'
2005-04-17 02:20:36 +04:00
tst r8 , #1 < < 2 3 @ Check U bit
subne r7 , r7 , r6 @ Undo incrmenet
addeq r7 , r7 , r6 @ Undo decrement
2011-06-27 15:27:47 +04:00
str r7 , [ r2 , r9 , l s r #14 ] @ Put register 'Rn'
2011-06-26 19:01:26 +04:00
b d o _ D a t a A b o r t
2005-04-17 02:20:36 +04:00
.data_arm_lateldrpreconst :
tst r8 , #1 < < 2 1 @ check writeback bit
2011-06-26 19:01:26 +04:00
beq d o _ D a t a A b o r t @ no writeback -> no fixup
2005-04-17 02:20:36 +04:00
.data_arm_lateldrpostconst :
2011-06-27 15:23:11 +04:00
movs r6 , r8 , l s l #20 @ Get offset
2011-06-26 19:01:26 +04:00
beq d o _ D a t a A b o r t @ zero -> no fixup
2011-06-27 15:27:47 +04:00
and r9 , r8 , #15 < < 1 6 @ Extract 'n' from instruction
ldr r7 , [ r2 , r9 , l s r #14 ] @ Get register 'Rn'
2005-04-17 02:20:36 +04:00
tst r8 , #1 < < 2 3 @ Check U bit
2011-06-27 15:23:11 +04:00
subne r7 , r7 , r6 , l s r #20 @ Undo increment
addeq r7 , r7 , r6 , l s r #20 @ Undo decrement
2011-06-27 15:27:47 +04:00
str r7 , [ r2 , r9 , l s r #14 ] @ Put register 'Rn'
2011-06-26 19:01:26 +04:00
b d o _ D a t a A b o r t
2005-04-17 02:20:36 +04:00
.data_arm_lateldrprereg :
tst r8 , #1 < < 2 1 @ check writeback bit
2011-06-26 19:01:26 +04:00
beq d o _ D a t a A b o r t @ no writeback -> no fixup
2005-04-17 02:20:36 +04:00
.data_arm_lateldrpostreg :
and r7 , r8 , #15 @ Extract 'm' from instruction
2011-06-27 12:52:54 +04:00
ldr r6 , [ r2 , r7 , l s l #2 ] @ Get register 'Rm'
2011-06-27 15:27:47 +04:00
mov r9 , r8 , l s r #7 @ get shift count
ands r9 , r9 , #31
2005-04-17 02:20:36 +04:00
and r7 , r8 , #0x70 @ get shift type
orreq r7 , r7 , #8 @ shift count = 0
add p c , p c , r7
nop
2011-06-27 15:27:47 +04:00
mov r6 , r6 , l s l r9 @ 0: LSL #!0
2005-04-17 02:20:36 +04:00
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n @ 1: LSL #0
nop
b . d a t a _ u n k n o w n @ 2: MUL?
nop
b . d a t a _ u n k n o w n @ 3: MUL?
nop
2011-06-27 15:27:47 +04:00
mov r6 , r6 , l s r r9 @ 4: LSR #!0
2005-04-17 02:20:36 +04:00
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n
mov r6 , r6 , l s r #32 @ 5: LSR #32
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n
b . d a t a _ u n k n o w n @ 6: MUL?
nop
b . d a t a _ u n k n o w n @ 7: MUL?
nop
2011-06-27 15:27:47 +04:00
mov r6 , r6 , a s r r9 @ 8: ASR #!0
2005-04-17 02:20:36 +04:00
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n
mov r6 , r6 , a s r #32 @ 9: ASR #32
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n
b . d a t a _ u n k n o w n @ A: MUL?
nop
b . d a t a _ u n k n o w n @ B: MUL?
nop
2011-06-27 15:27:47 +04:00
mov r6 , r6 , r o r r9 @ C: ROR #!0
2005-04-17 02:20:36 +04:00
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n
mov r6 , r6 , r r x @ D: RRX
b . d a t a _ a r m _ a p p l y _ r6 _ a n d _ r n
b . d a t a _ u n k n o w n @ E: MUL?
nop
b . d a t a _ u n k n o w n @ F: MUL?
/ *
* Function : arm6 _ 7 _ p r o c _ i n i t ( v o i d )
* : arm6 _ 7 _ p r o c _ f i n ( v o i d )
*
* Notes : T h i s p r o c e s s o r d o e s n o t r e q u i r e t h e s e
* /
ENTRY( c p u _ a r m 6 _ p r o c _ i n i t )
ENTRY( c p u _ a r m 7 _ p r o c _ i n i t )
mov p c , l r
ENTRY( c p u _ a r m 6 _ p r o c _ f i n )
ENTRY( c p u _ a r m 7 _ p r o c _ f i n )
mov r0 , #0x31 @ ....S..DP...M
mcr p15 , 0 , r0 , c1 , c0 , 0 @ disable caches
mov p c , l r
ENTRY( c p u _ a r m 6 _ d o _ i d l e )
ENTRY( c p u _ a r m 7 _ d o _ i d l e )
mov p c , l r
/ *
* Function : arm6 _ 7 _ s w i t c h _ m m ( u n s i g n e d l o n g p g d _ p h y s )
* Params : p g d _ p h y s P h y s i c a l a d d r e s s o f p a g e t a b l e
* Purpose : P e r f o r m a t a s k s w i t c h , s a v i n g t h e o l d p r o c e s s e s s t a t e , a n d r e s t o r i n g
* the n e w .
* /
ENTRY( c p u _ a r m 6 _ s w i t c h _ m m )
ENTRY( c p u _ a r m 7 _ s w i t c h _ m m )
2006-06-28 17:10:01 +04:00
# ifdef C O N F I G _ M M U
2005-04-17 02:20:36 +04:00
mov r1 , #0
mcr p15 , 0 , r1 , c7 , c0 , 0 @ flush cache
mcr p15 , 0 , r0 , c2 , c0 , 0 @ update page table ptr
mcr p15 , 0 , r1 , c5 , c0 , 0 @ flush TLBs
2006-06-28 17:10:01 +04:00
# endif
2005-04-17 02:20:36 +04:00
mov p c , l r
/ *
2006-12-13 17:34:43 +03:00
* Function : arm6 _ 7 _ s e t _ p t e _ e x t ( p t e _ t * p t e p , p t e _ t p t e , u n s i g n e d i n t e x t )
2005-04-17 02:20:36 +04:00
* Params : r0 = A d d r e s s t o s e t
* : r1 = v a l u e t o s e t
* Purpose : S e t a P T E a n d f l u s h i t o u t o f a n y W B c a c h e
* /
2008-09-06 20:19:08 +04:00
.align 5
2006-12-13 17:34:43 +03:00
ENTRY( c p u _ a r m 6 _ s e t _ p t e _ e x t )
ENTRY( c p u _ a r m 7 _ s e t _ p t e _ e x t )
2006-06-28 17:10:01 +04:00
# ifdef C O N F I G _ M M U
2008-09-06 20:19:08 +04:00
armv3 _ s e t _ p t e _ e x t w c _ d i s a b l e =0
2006-06-28 17:10:01 +04:00
# endif / * C O N F I G _ M M U * /
2008-09-06 20:19:08 +04:00
mov p c , l r
2005-04-17 02:20:36 +04:00
/ *
* Function : _ arm6 _ 7 _ r e s e t
* 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 6 _ r e s e t )
ENTRY( c p u _ a r m 7 _ r e s e t )
mov r1 , #0
mcr p15 , 0 , r1 , c7 , c0 , 0 @ flush cache
2006-06-28 17:10:01 +04:00
# ifdef C O N F I G _ M M U
2005-04-17 02:20:36 +04:00
mcr p15 , 0 , r1 , c5 , c0 , 0 @ flush TLB
2006-06-28 17:10:01 +04:00
# endif
2005-04-17 02:20:36 +04:00
mov r1 , #0x30
mcr p15 , 0 , r1 , c1 , c0 , 0 @ turn off MMU etc
mov p c , r0
2010-10-01 18:37:05 +04:00
_ _ CPUINIT
2005-04-17 02:20:36 +04:00
.type _ _ arm6 _ s e t u p , #f u n c t i o n
__arm6_setup : mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 @ flush caches on v3
2006-06-28 17:10:01 +04:00
# ifdef C O N F I G _ M M U
2005-04-17 02:20:36 +04:00
mcr p15 , 0 , r0 , c5 , c0 @ flush TLBs on v3
mov r0 , #0x3d @ . ..RS BLDP WCAM
orr r0 , r0 , #0x100 @ . ..01 0011 1101
2006-06-28 17:10:01 +04:00
# else
mov r0 , #0x3c @ . ..RS BLDP WCA.
# endif
2005-04-17 02:20:36 +04:00
mov p c , l r
.size _ _ arm6 _ s e t u p , . - _ _ a r m 6 _ s e t u p
.type _ _ arm7 _ s e t u p , #f u n c t i o n
__arm7_setup : mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 @ flush caches on v3
2006-06-28 17:10:01 +04:00
# ifdef C O N F I G _ M M U
2005-04-17 02:20:36 +04:00
mcr p15 , 0 , r0 , c5 , c0 @ flush TLBs on v3
mcr p15 , 0 , r0 , c3 , c0 @ load domain access register
mov r0 , #0x7d @ . ..RS BLDP WCAM
orr r0 , r0 , #0x100 @ . ..01 0111 1101
2006-06-28 17:10:01 +04:00
# else
mov r0 , #0x7c @ . ..RS BLDP WCA.
# endif
2005-04-17 02:20:36 +04:00
mov p c , l r
.size _ _ arm7 _ s e t u p , . - _ _ a r m 7 _ s e t u p
_ _ INITDATA
2011-06-23 20:18:31 +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 6 , d a b o r t =cpu_arm6_data_abort , p a b o r t =legacy_pabort
define_ p r o c e s s o r _ f u n c t i o n s a r m 7 , d a b o r t =cpu_arm7_data_abort , p a b o r t =legacy_pabort
2005-04-17 02:20:36 +04:00
.section " .rodata "
2011-06-23 20:18:31 +04:00
string c p u _ a r c h _ n a m e , " a r m v3 "
string c p u _ e l f _ n a m e , " v3 "
string c p u _ a r m 6 _ n a m e , " A R M 6 "
string c p u _ a r m 6 1 0 _ n a m e , " A R M 6 1 0 "
string c p u _ a r m 7 _ n a m e , " A R M 7 "
string c p u _ a r m 7 1 0 _ n a m e , " A R M 7 1 0 "
2005-04-17 02:20:36 +04:00
.align
2005-09-20 19:35:03 +04:00
.section " .proc .info .init " , # alloc, #e x e c i n s t r
2005-04-17 02:20:36 +04:00
2011-06-23 20:18:31 +04:00
.macro arm67_proc_info name : req, c p u _ v a l : r e q , c p u _ m a s k : r e q , c p u _ n a m e : r e q , \
cpu_mm_mmu_flags : req, c p u _ f l u s h : r e q , c p u _ p r o c _ f u n c s : r e q
.type _ _ \ name\ ( ) _ p r o c _ i n f o , #o b j e c t
_ _ \ name\ ( ) _ p r o c _ i n f o :
.long \ cpu_ v a l
.long \ cpu_ m a s k
.long \ cpu_ m m _ m m u _ f l a g s
2006-06-29 21:24:21 +04:00
.long PMD_TYPE_SECT | \
PMD_ B I T 4 | \
PMD_ S E C T _ A P _ W R I T E | \
PMD_ S E C T _ A P _ R E A D
2011-06-23 20:18:31 +04:00
b \ c p u _ f l u s h
2005-04-17 02:20:36 +04:00
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_ 2 6 B I T
2011-06-23 20:18:31 +04:00
.long \ cpu_ n a m e
.long \ cpu_ p r o c _ f u n c s
2005-04-17 02:20:36 +04:00
.long v3_tlb_fns
.long v3_user_fns
.long v3_cache_fns
2011-06-23 20:18:31 +04:00
.size _ _ \ name\ ( ) _ p r o c _ i n f o , . - _ _ \ n a m e \ ( ) _ p r o c _ i n f o
.endm
arm6 7 _ p r o c _ i n f o a r m 6 , 0 x41 5 6 0 6 0 0 , 0 x f f f f f f f0 , c p u _ a r m 6 _ n a m e , \
0 x0 0 0 0 0 c1 e , _ _ a r m 6 _ s e t u p , a r m 6 _ p r o c e s s o r _ f u n c t i o n s
arm6 7 _ p r o c _ i n f o a r m 6 1 0 , 0 x41 5 6 0 6 1 0 , 0 x f f f f f f f0 , c p u _ a r m 6 1 0 _ n a m e , \
0 x0 0 0 0 0 c1 e , _ _ a r m 6 _ s e t u p , a r m 6 _ p r o c e s s o r _ f u n c t i o n s
arm6 7 _ p r o c _ i n f o a r m 7 , 0 x41 0 0 7 0 0 0 , 0 x f f f f f f00 , c p u _ a r m 7 _ n a m e , \
0 x0 0 0 0 0 c1 e , _ _ a r m 7 _ s e t u p , a r m 7 _ p r o c e s s o r _ f u n c t i o n s
arm6 7 _ p r o c _ i n f o a r m 7 1 0 , 0 x41 0 0 7 1 0 0 , 0 x f f f8 f f00 , c p u _ a r m 7 1 0 _ n a m e , \
PMD_ T Y P E _ S E C T | \
2005-04-17 02:20:36 +04:00
PMD_ S E C T _ B U F F E R A B L E | \
PMD_ S E C T _ C A C H E A B L E | \
PMD_ B I T 4 | \
PMD_ S E C T _ A P _ W R I T E | \
2011-06-23 20:18:31 +04:00
PMD_ S E C T _ A P _ R E A D , \
_ _ arm7 _ s e t u p , a r m 7 _ p r o c e s s o r _ f u n c t i o n s