2005-04-16 15:20:36 -07:00
/ *
* linux/ a r c h / a r m 2 6 / m m / p r o c - a r m 2 ,3 . S
*
* Copyright ( C ) 1 9 9 7 - 1 9 9 9 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 .
*
* MMU f u n c t i o n s f o r A R M 2 ,3
*
* 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
* and m e m o r y f u n c t i o n s o n A R M 2 , A R M 2 5 0 a n d A R M 3 p r o c e s s o r s .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
2005-09-09 20:35:55 +02:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-16 15:20:36 -07:00
# include < a s m / p r o c i n f o . h >
# include < a s m / p t r a c e . h >
/ *
* MEMC w o r k h o r s e c o d e . I t ' s b o t h a h o r s e w h i c h t h i n g s i t ' s a p i g .
* /
/ *
* Function : cpu_ m e m c _ u p d a t e _ e n t r y ( p g d _ t * p g d , u n s i g n e d l o n g p h y s _ p t e , u n s i g n e d l o n g a d d r )
* Params : p g d P a g e t a b l e s / M E M C m a p p i n g
* : phys_ p t e p h y s i c a l a d d r e s s , o r P T E
* : addr v i r t u a l a d d r e s s
* /
ENTRY( c p u _ m e m c _ u p d a t e _ e n t r y )
tst r1 , #P A G E _ P R E S E N T @ i s t h e p a g e p r e s e n t
orreq r1 , r1 , #P A G E _ O L D | P A G E _ C L E A N
moveq r2 , #0x01f00000
mov r3 , r1 , l s r #13 @ convert to physical page nr
and r3 , r3 , #0x3fc
adr i p , m e m c _ p h y s _ t a b l e _ 3 2
ldr r3 , [ i p , r3 ]
tst r1 , #P A G E _ O L D | P A G E _ N O T _ U S E R
biceq r3 , r3 , #0x200
tsteq r1 , #P A G E _ R E A D O N L Y | P A G E _ C L E A N
biceq r3 , r3 , #0x300
mov r2 , r2 , l s r #15 @ virtual -> nr
orr r3 , r3 , r2 , l s l #15
and r2 , r2 , #0x300
orr r3 , r3 , r2 , l s l #2
and r2 , r3 , #255
sub r0 , r0 , #256 * 4
str r3 , [ r0 , r2 , l s l #2 ]
strb r3 , [ r3 ]
movs p c , l r
/ *
* Params : r0 = p r e s e r v e d
* : r1 = m e m c t a b l e b a s e ( p r e s e r v e d )
* : r2 = p a g e t a b l e e n t r y
* : r3 = p r e s e r v e d
* : r4 = u n u s e d
* : r5 = m e m c p h y s i c a l a d d r e s s t r a n s l a t i o n t a b l e
* : ip = v i r t u a l a d d r e s s ( p r e s e r v e d )
* /
update_pte :
mov r4 , r2 , l s r #13
and r4 , r4 , #0x3fc
ldr r4 , [ r5 , r4 ] @ covert to MEMC page
tst r2 , #P A G E _ O L D | P A G E _ N O T _ U S E R @ c h e c k f o r M E M C r e a d
biceq r4 , r4 , #0x200
tsteq r2 , #P A G E _ R E A D O N L Y | P A G E _ C L E A N @ c h e c k f o r M E M C w r i t e
biceq r4 , r4 , #0x300
orr r4 , r4 , i p
and r2 , i p , #0x01800000
orr r4 , r4 , r2 , l s r #13
and r2 , r4 , #255
str r4 , [ r1 , r2 , l s l #2 ]
movs p c , l r
/ *
* Params : r0 = p r e s e r v e d
* : r1 = m e m c t a b l e b a s e ( p r e s e r v e d )
* : r2 = p a g e t a b l e b a s e
* : r3 = p r e s e r v e d
* : r4 = u n u s e d
* : r5 = m e m c p h y s i c a l a d d r e s s t r a n s l a t i o n t a b l e
* : ip = v i r t u a l a d d r e s s ( u p d a t e d )
* /
update_pte_table :
stmfd s p ! , { r0 , l r }
bic r0 , r2 , #3
1 : ldr r2 , [ r0 ] , #4 @ get entry
tst r2 , #P A G E _ P R E S E N T @ p a g e p r e s e n t
blne u p d a t e _ p t e @ process pte
add i p , i p , #32768 @ increment virt addr
ldr r2 , [ r0 ] , #4 @ get entry
tst r2 , #P A G E _ P R E S E N T @ p a g e p r e s e n t
blne u p d a t e _ p t e @ process pte
add i p , i p , #32768 @ increment virt addr
ldr r2 , [ r0 ] , #4 @ get entry
tst r2 , #P A G E _ P R E S E N T @ p a g e p r e s e n t
blne u p d a t e _ p t e @ process pte
add i p , i p , #32768 @ increment virt addr
ldr r2 , [ r0 ] , #4 @ get entry
tst r2 , #P A G E _ P R E S E N T @ p a g e p r e s e n t
blne u p d a t e _ p t e @ process pte
add i p , i p , #32768 @ increment virt addr
tst i p , #32768 * 3 1 @ finished?
bne 1 b
ldmfd s p ! , { r0 , p c } ^
/ *
* Function : cpu_ m e m c _ u p d a t e _ a l l ( p g d _ t * p g d )
* Params : p g d P a g e t a b l e s / M E M C m a p p i n g
* Notes : t h i s i s o p t i m i s e d f o r 3 2 k p a g e s
* /
ENTRY( c p u _ m e m c _ u p d a t e _ a l l )
stmfd s p ! , { r4 , r5 , l r }
bl c l e a r _ t a b l e s
sub r1 , r0 , #256 * 4 @ start of MEMC tables
adr r5 , m e m c _ p h y s _ t a b l e _ 3 2 @ Convert to logical page number
mov i p , #0 @ virtual address
1 : ldmia r0 ! , { r2 , r3 } @ load two pgd entries
tst r2 , #P A G E _ P R E S E N T @ i s p g d e n t r y p r e s e n t ?
addeq i p , i p , #1048576 @FIXME - PAGE_PRESENT is for PTEs technically...
blne u p d a t e _ p t e _ t a b l e
mov r2 , r3
tst r2 , #P A G E _ P R E S E N T @ i s p g d e n t r y p r e s e n t ?
addeq i p , i p , #1048576
blne u p d a t e _ p t e _ t a b l e
teq i p , #32 * 1 0 4 8 5 7 6
bne 1 b
ldmfd s p ! , { r4 , r5 , p c } ^
/ *
* Build t h e t a b l e t o m a p f r o m p h y s i c a l p a g e n u m b e r t o m e m c p a g e n u m b e r
* /
.type memc_ p h y s _ t a b l e _ 3 2 , #o b j e c t
memc_phys_table_32 :
.irp b7 , 0 x00 , 0 x80
.irp b6 , 0 x00 , 0 x02
.irp b5 , 0 x00 , 0 x04
.irp b4 , 0 x00 , 0 x01
.irp b3 , 0 x00 , 0 x40
.irp b2 , 0 x00 , 0 x20
.irp b1 , 0 x00 , 0 x10
.irp b0 , 0 x00 , 0 x08
.long 0x03800300 + \ b7 + \ b6 + \ b5 + \ b4 + \ b3 + \ b2 + \ b1 + \ b0
.endr
.endr
.endr
.endr
.endr
.endr
.endr
.endr
.size memc_ p h y s _ t a b l e _ 3 2 , . - m e m c _ p h y s _ t a b l e _ 3 2
/ *
* helper f o r c p u _ m e m c _ u p d a t e _ a l l , t h i s c l e a r s o u t a l l
* mappings, s e t t i n g t h e m c l o s e t o t h e t o p o f m e m o r y ,
* and i n a c c e s s i b l e ( 0 x01 f00 0 0 0 ) .
* Params : r0 = p a g e t a b l e p o i n t e r
* /
clear_tables : ldr r1 , _ a r m 3 _ s e t _ p g d - 4
ldr r2 , [ r1 ]
sub r1 , r0 , #256 * 4 @ start of MEMC tables
add r2 , r1 , r2 , l s l #2 @ end of tables
mov r3 , #0x03f00000 @ Default mapping (null mapping)
orr r3 , r3 , #0x00000f00
orr r4 , r3 , #1
orr r5 , r3 , #2
orr i p , r3 , #3
1 : stmia r1 ! , { r3 , r4 , r5 , i p }
add r3 , r3 , #4
add r4 , r4 , #4
add r5 , r5 , #4
add i p , i p , #4
stmia r1 ! , { r3 , r4 , r5 , i p }
add r3 , r3 , #4
add r4 , r4 , #4
add r5 , r5 , #4
add i p , i p , #4
teq r1 , r2
bne 1 b
mov p c , l r
/ *
* Function : * _ set_ p g d ( p g d _ t * p g d )
* Params : p g d N e w p a g e t a b l e s / M E M C m a p p i n g
* Purpose : u p d a t e M E M C h a r d w a r e w i t h n e w m a p p i n g
* /
.word page_nr @ extern - declared in mm-memc.c
_arm3_set_pgd : mcr p15 , 0 , r1 , c1 , c0 , 0 @ flush cache
_arm2_set_pgd : stmfd s p ! , { l r }
ldr r1 , _ a r m 3 _ s e t _ p g d - 4
ldr r2 , [ r1 ]
sub r0 , r0 , #256 * 4 @ start of MEMC tables
add r1 , r0 , r2 , l s l #2 @ end of tables
1 : ldmia r0 ! , { r2 , r3 , i p , l r }
strb r2 , [ r2 ]
strb r3 , [ r3 ]
strb i p , [ i p ]
strb l r , [ l r ]
ldmia r0 ! , { r2 , r3 , i p , l r }
strb r2 , [ r2 ]
strb r3 , [ r3 ]
strb i p , [ i p ]
strb l r , [ l r ]
teq r0 , r1
bne 1 b
ldmfd s p ! , { p c } ^
/ *
* Function : * _ proc_ i n i t ( v o i d )
* Purpose : I n i t i a l i s e t h e c a c h e c o n t r o l r e g i s t e r s
* /
_arm3_proc_init :
mov r0 , #0x001f0000
orr r0 , r0 , #0x0000ff00
orr r0 , r0 , #0x000000ff
mcr p15 , 0 , r0 , c3 , c0 @ ARM3 Cacheable
mcr p15 , 0 , r0 , c4 , c0 @ ARM3 Updateable
mov r0 , #0
mcr p15 , 0 , r0 , c5 , c0 @ ARM3 Disruptive
mcr p15 , 0 , r0 , c1 , c0 @ ARM3 Flush
mov r0 , #3
mcr p15 , 0 , r0 , c2 , c0 @ ARM3 Control
_arm2_proc_init :
movs p c , l r
/ *
* Function : * _ proc_ f i n ( v o i d )
* Purpose : F i n a l i s e p r o c e s s o r ( d i s a b l e c a c h e s )
* /
_arm3_proc_fin : mov r0 , #2
mcr p15 , 0 , r0 , c2 , c0
_arm2_proc_fin : orrs p c , l r , #P S R _ I _ B I T | P S R _ F _ B I T
/ *
* Function : * _ xchg_ 1 ( i n t n e w , v o l a t i l e v o i d * p t r )
* Params : n e w N e w v a l u e t o s t o r e a t . . .
* : ptr p o i n t e r t o b y t e - w i d e l o c a t i o n
* Purpose : P e r f o r m s a n e x c h a n g e o p e r a t i o n
* Returns : O r i g i n a l b y t e d a t a a t ' p t r '
* /
_arm2_xchg_1 : mov r2 , p c
orr r2 , r2 , #P S R _ I _ B I T
teqp r2 , #0
ldrb r2 , [ r1 ]
strb r0 , [ r1 ]
mov r0 , r2
movs p c , l r
_arm3_xchg_1 : swpb r0 , r0 , [ r1 ]
movs p c , l r
/ *
* Function : * _ xchg_ 4 ( i n t n e w , v o l a t i l e v o i d * p t r )
* Params : n e w N e w v a l u e t o s t o r e a t . . .
* : ptr p o i n t e r t o w o r d - w i d e l o c a t i o n
* Purpose : P e r f o r m s a n e x c h a n g e o p e r a t i o n
* Returns : O r i g i n a l w o r d d a t a a t ' p t r '
* /
_arm2_xchg_4 : mov r2 , p c
orr r2 , r2 , #P S R _ I _ B I T
teqp r2 , #0
ldr r2 , [ r1 ]
str r0 , [ r1 ]
mov r0 , r2
movs p c , l r
_arm3_xchg_4 : swp r0 , r0 , [ r1 ]
movs p c , l r
_arm2_3_check_bugs :
bics p c , l r , #P S R _ F _ B I T @ C l e a r F I Q d i s a b l e b i t
armvlsi_name : .asciz " ARM/VLSI "
_arm2_name : .asciz " ARM 2 "
_arm250_name : .asciz " ARM 250 "
_arm3_name : .asciz " ARM 3 "
.section " .init .text " , # alloc, #e x e c i n s t r
/ *
* 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
* /
.globl arm2_processor_functions
arm2_processor_functions :
.word _arm2_3_check_bugs
.word _arm2_proc_init
.word _arm2_proc_fin
.word _arm2_set_pgd
.word _arm2_xchg_1
.word _arm2_xchg_4
cpu_arm2_info :
.long armvlsi_name
.long _arm2_name
.globl arm250_processor_functions
arm250_processor_functions :
.word _arm2_3_check_bugs
.word _arm2_proc_init
.word _arm2_proc_fin
.word _arm2_set_pgd
.word _arm3_xchg_1
.word _arm3_xchg_4
cpu_arm250_info :
.long armvlsi_name
.long _arm250_name
.globl arm3_processor_functions
arm3_processor_functions :
.word _arm2_3_check_bugs
.word _arm3_proc_init
.word _arm3_proc_fin
.word _arm3_set_pgd
.word _arm3_xchg_1
.word _arm3_xchg_4
cpu_arm3_info :
.long armvlsi_name
.long _arm3_name
arm2_arch_name : .asciz " armv1 "
arm3_arch_name : .asciz " armv2 "
arm2_elf_name : .asciz " v1 "
arm3_elf_name : .asciz " v2 "
.align
.section " .proc .info " , # alloc, #e x e c i n s t r
.long 0x41560200
.long 0xfffffff0
.long arm2_arch_name
.long arm2_elf_name
.long 0
.long cpu_arm2_info
.long arm2_processor_functions
.long 0x41560250
.long 0xfffffff0
.long arm3_arch_name
.long arm3_elf_name
.long 0
.long cpu_arm250_info
.long arm250_processor_functions
.long 0x41560300
.long 0xfffffff0
.long arm3_arch_name
.long arm3_elf_name
.long 0
.long cpu_arm3_info
.long arm3_processor_functions