2005-04-16 15:20:36 -07:00
/ *
* linux/ a r c h / a r m / b o o t / c o m p r e s s e d / h e a d . S
*
* Copyright ( C ) 1 9 9 6 - 2 0 0 2 R u s s e l l K i n g
2006-03-27 10:21:34 +01:00
* Copyright ( C ) 2 0 0 4 H y o k S . C h o i ( M P U s u p p o r t )
2005-04-16 15:20:36 -07: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 .
* /
# include < l i n u x / l i n k a g e . h >
/ *
* Debugging s t u f f
*
* Note t h a t t h e s e m a c r o s m u s t n o t c o n t a i n a n y c o d e w h i c h i s n o t
* 1 0 0 % relocatable. A n y a t t e m p t t o d o s o w i l l r e s u l t i n a c r a s h .
* Please s e l e c t o n e o f t h e f o l l o w i n g w h e n t u r n i n g o n d e b u g g i n g .
* /
# ifdef D E B U G
2005-05-03 12:18:46 +01:00
# if d e f i n e d ( C O N F I G _ D E B U G _ I C E D C C )
2005-04-16 15:20:36 -07:00
.macro loadsp, r b
.endm
2005-11-16 14:59:51 +00:00
.macro writeb, c h , r b
2005-05-03 12:18:46 +01:00
mcr p14 , 0 , \ c h , c0 , c1 , 0
2005-04-16 15:20:36 -07:00
.endm
2005-05-03 12:18:46 +01:00
# else
2005-11-16 14:59:51 +00:00
# include < a s m / a r c h / d e b u g - m a c r o . S >
2005-05-03 12:18:46 +01:00
.macro writeb, c h , r b
senduart \ c h , \ r b
2005-04-16 15:20:36 -07:00
.endm
2005-05-03 12:18:46 +01:00
2005-11-16 14:59:51 +00:00
# if d e f i n e d ( C O N F I G _ A R C H _ S A 1 1 0 0 )
2005-04-16 15:20:36 -07:00
.macro loadsp, r b
mov \ r b , #0x80000000 @ physical base address
2005-11-16 14:59:51 +00:00
# ifdef C O N F I G _ D E B U G _ L L _ S E R 3
2005-04-16 15:20:36 -07:00
add \ r b , \ r b , #0x00050000 @ Ser3
2005-11-16 14:59:51 +00:00
# else
2005-04-16 15:20:36 -07:00
add \ r b , \ r b , #0x00010000 @ Ser1
2005-11-16 14:59:51 +00:00
# endif
2005-04-16 15:20:36 -07:00
.endm
# elif d e f i n e d ( C O N F I G _ A R C H _ S 3 C 2 4 1 0 )
2005-05-03 12:18:46 +01:00
.macro loadsp, r b
2005-04-16 15:20:36 -07:00
mov \ r b , #0x50000000
add \ r b , \ r b , #0x4000 * C O N F I G _ S 3 C 2 4 1 0 _ L O W L E V E L _ U A R T _ P O R T
.endm
# else
2005-11-16 14:59:51 +00:00
.macro loadsp, r b
addruart \ r b
.endm
2005-04-16 15:20:36 -07:00
# endif
2005-05-03 12:18:46 +01:00
# endif
2005-04-16 15:20:36 -07:00
# endif
.macro kputc,v a l
mov r0 , \ v a l
bl p u t c
.endm
.macro kphex,v a l ,l e n
mov r0 , \ v a l
mov r1 , #\ l e n
bl p h e x
.endm
.macro debug_reloc_start
# ifdef D E B U G
kputc #' \n '
kphex r6 , 8 / * p r o c e s s o r i d * /
kputc #' : '
kphex r7 , 8 / * a r c h i t e c t u r e i d * /
kputc #' : '
mrc p15 , 0 , r0 , c1 , c0
kphex r0 , 8 / * c o n t r o l r e g * /
kputc #' \n '
kphex r5 , 8 / * d e c o m p r e s s e d k e r n e l s t a r t * /
kputc #' - '
2006-01-12 17:17:57 +00:00
kphex r9 , 8 / * d e c o m p r e s s e d k e r n e l e n d * /
2005-04-16 15:20:36 -07:00
kputc #' > '
kphex r4 , 8 / * k e r n e l e x e c u t i o n a d d r e s s * /
kputc #' \n '
# endif
.endm
.macro debug_reloc_end
# ifdef D E B U G
kphex r5 , 8 / * e n d o f k e r n e l * /
kputc #' \n '
mov r0 , r4
bl m e m d u m p / * d u m p 2 5 6 b y t e s a t s t a r t o f k e r n e l * /
# endif
.endm
.section " .start " , # alloc, #e x e c i n s t r
/ *
* sort o u t d i f f e r e n t c a l l i n g c o n v e n t i o n s
* /
.align
start :
.type start,#f u n c t i o n
.rept 8
mov r0 , r0
.endr
b 1 f
.word 0x016f2818 @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
1 : mov r7 , r1 @ save architecture ID
2006-01-12 17:17:57 +00:00
mov r8 , r2 @ save atags pointer
2005-04-16 15:20:36 -07:00
# ifndef _ _ A R M _ A R C H _ 2 _ _
/ *
* Booting f r o m A n g e l - n e e d t o e n t e r S V C m o d e a n d d i s a b l e
* FIQs/ I R Q s ( n u m e r i c d e f i n i t i o n s f r o m a n g e l a r m . h s o u r c e ) .
* We o n l y d o t h i s i f w e w e r e i n u s e r m o d e o n e n t r y .
* /
mrs r2 , c p s r @ get current mode
tst r2 , #3 @ not user?
bne n o t _ a n g e l
mov r0 , #0x17 @ angel_SWIreason_EnterSVC
swi 0 x12 3 4 5 6 @ angel_SWI_ARM
not_angel :
mrs r2 , c p s r @ turn off interrupts to
orr r2 , r2 , #0xc0 @ prevent angel from running
msr c p s r _ c , r2
# else
teqp p c , #0x0c000003 @ turn off interrupts
# endif
/ *
* Note t h a t s o m e c a c h e f l u s h i n g a n d o t h e r s t u f f m a y
* be n e e d e d h e r e - i s t h e r e a n A n g e l S W I c a l l f o r t h i s ?
* /
/ *
* some a r c h i t e c t u r e s p e c i f i c c o d e c a n b e i n s e r t e d
2006-01-12 17:17:57 +00:00
* by t h e l i n k e r h e r e , b u t i t s h o u l d p r e s e r v e r7 , r8 , a n d r9 .
2005-04-16 15:20:36 -07:00
* /
.text
adr r0 , L C 0
ldmia r0 , { r1 , r2 , r3 , r4 , r5 , r6 , i p , s p }
subs r0 , r0 , r1 @ calculate the delta offset
@ if delta is zero, we are
beq n o t _ r e l o c a t e d @ running at the address we
@ were linked at.
/ *
* We' r e r u n n i n g a t a d i f f e r e n t a d d r e s s . W e n e e d t o f i x
* up v a r i o u s p o i n t e r s :
* r5 - z I m a g e b a s e a d d r e s s
* r6 - G O T s t a r t
* ip - G O T e n d
* /
add r5 , r5 , r0
add r6 , r6 , r0
add i p , i p , r0
# ifndef C O N F I G _ Z B O O T _ R O M
/ *
* If w e ' r e r u n n i n g f u l l y P I C = = = C O N F I G _ Z B O O T _ R O M = n ,
* we n e e d t o f i x u p p o i n t e r s i n t o t h e B S S r e g i o n .
* r2 - B S S s t a r t
* r3 - B S S e n d
* sp - s t a c k p o i n t e r
* /
add r2 , r2 , r0
add r3 , r3 , r0
add s p , s p , r0
/ *
* Relocate a l l e n t r i e s i n t h e G O T t a b l e .
* /
1 : ldr r1 , [ r6 , #0 ] @ relocate entries in the GOT
add r1 , r1 , r0 @ table. This fixes up the
str r1 , [ r6 ] , #4 @ C references.
cmp r6 , i p
blo 1 b
# else
/ *
* Relocate e n t r i e s i n t h e G O T t a b l e . W e o n l y r e l o c a t e
* the e n t r i e s t h a t a r e o u t s i d e t h e ( r e l o c a t e d ) B S S r e g i o n .
* /
1 : ldr r1 , [ r6 , #0 ] @ relocate entries in the GOT
cmp r1 , r2 @ entry < bss_start ||
cmphs r3 , r1 @ _end < entry
addlo r1 , r1 , r0 @ table. This fixes up the
str r1 , [ r6 ] , #4 @ C references.
cmp r6 , i p
blo 1 b
# endif
not_relocated : mov r0 , #0
1 : str r0 , [ r2 ] , #4 @ clear bss
str r0 , [ r2 ] , #4
str r0 , [ r2 ] , #4
str r0 , [ r2 ] , #4
cmp r2 , r3
blo 1 b
/ *
* The C r u n t i m e e n v i r o n m e n t s h o u l d n o w b e s e t u p
* sufficiently. T u r n t h e c a c h e o n , s e t u p s o m e
* pointers, a n d s t a r t d e c o m p r e s s i n g .
* /
bl c a c h e _ o n
mov r1 , s p @ malloc space above stack
add r2 , s p , #0x10000 @ 64k max
/ *
* Check t o s e e i f w e w i l l o v e r w r i t e o u r s e l v e s .
* r4 = f i n a l k e r n e l a d d r e s s
* r5 = s t a r t o f t h i s i m a g e
* r2 = e n d o f m a l l o c s p a c e ( a n d t h e r e f o r e t h i s i m a g e )
* We b a s i c a l l y w a n t :
* r4 > = r2 - > O K
* r4 + i m a g e l e n g t h < = r5 - > O K
* /
cmp r4 , r2
bhs w o n t _ o v e r w r i t e
add r0 , r4 , #4096 * 1 0 2 4 @ 4MB largest kernel size
cmp r0 , r5
bls w o n t _ o v e r w r i t e
mov r5 , r2 @ decompress after malloc space
mov r0 , r5
mov r3 , r7
bl d e c o m p r e s s _ k e r n e l
add r0 , r0 , #127
bic r0 , r0 , #127 @ align the kernel length
/ *
* r0 = d e c o m p r e s s e d k e r n e l l e n g t h
* r1 - r3 = u n u s e d
* r4 = k e r n e l e x e c u t i o n a d d r e s s
* r5 = d e c o m p r e s s e d k e r n e l s t a r t
* r6 = p r o c e s s o r I D
* r7 = a r c h i t e c t u r e I D
2006-01-12 17:17:57 +00:00
* r8 = a t a g s p o i n t e r
* r9 - r14 = c o r r u p t e d
2005-04-16 15:20:36 -07:00
* /
add r1 , r5 , r0 @ end of decompressed kernel
adr r2 , r e l o c _ s t a r t
ldr r3 , L C 1
add r3 , r2 , r3
2006-01-12 17:17:57 +00:00
1 : ldmia r2 ! , { r9 - r14 } @ copy relocation code
stmia r1 ! , { r9 - r14 }
ldmia r2 ! , { r9 - r14 }
stmia r1 ! , { r9 - r14 }
2005-04-16 15:20:36 -07:00
cmp r2 , r3
blo 1 b
bl c a c h e _ c l e a n _ f l u s h
add p c , r5 , r0 @ call relocation code
/ *
* We' r e n o t i n d a n g e r o f o v e r w r i t i n g o u r s e l v e s . D o t h i s t h e s i m p l e w a y .
*
* r4 = k e r n e l e x e c u t i o n a d d r e s s
* r7 = a r c h i t e c t u r e I D
* /
wont_overwrite : mov r0 , r4
mov r3 , r7
bl d e c o m p r e s s _ k e r n e l
b c a l l _ k e r n e l
.type LC0 , #o b j e c t
LC0 : .word L C 0 @ r1
.word __bss_start @ r2
.word _end @ r3
.word zreladdr @ r4
.word _start @ r5
.word _got_start @ r6
.word _got_end @ ip
.word user_ s t a c k + 4 0 9 6 @ sp
LC1 : .word r e l o c _ e n d - r e l o c _ s t a r t
.size LC0 , . - L C 0
# ifdef C O N F I G _ A R C H _ R P C
.globl params
params : ldr r0 , =params_phys
mov p c , l r
.ltorg
.align
# endif
/ *
* Turn o n t h e c a c h e . W e n e e d t o s e t u p s o m e p a g e t a b l e s s o t h a t w e
* can h a v e b o t h t h e I a n d D c a c h e s o n .
*
* We p l a c e t h e p a g e t a b l e s 1 6 k d o w n f r o m t h e k e r n e l e x e c u t i o n a d d r e s s ,
* and w e h o p e t h a t n o t h i n g e l s e i s u s i n g i t . I f w e ' r e u s i n g i t , w e
* will g o p o p !
*
* On e n t r y ,
* r4 = k e r n e l e x e c u t i o n a d d r e s s
* r6 = p r o c e s s o r I D
* r7 = a r c h i t e c t u r e n u m b e r
2006-01-12 17:17:57 +00:00
* r8 = a t a g s p o i n t e r
* r9 = r u n - t i m e a d d r e s s o f " s t a r t " ( ? ? ? )
2005-04-16 15:20:36 -07:00
* On e x i t ,
2006-01-12 17:17:57 +00:00
* r1 , r2 , r3 , r9 , r10 , r12 c o r r u p t e d
2005-04-16 15:20:36 -07:00
* This r o u t i n e m u s t p r e s e r v e :
2006-01-12 17:17:57 +00:00
* r4 , r5 , r6 , r7 , r8
2005-04-16 15:20:36 -07:00
* /
.align 5
cache_on : mov r3 , #8 @ cache_on function
b c a l l _ c a c h e _ f n
2006-03-27 10:21:34 +01:00
/ *
* Initialize t h e h i g h e s t p r i o r i t y p r o t e c t i o n r e g i o n , P R 7
* to c o v e r a l l 3 2 b i t a d d r e s s a n d c a c h e a b l e a n d b u f f e r a b l e .
* /
__armv4_mpu_cache_on :
mov r0 , #0x3f @ 4G, the whole
mcr p15 , 0 , r0 , c6 , c7 , 0 @ PR7 Area Setting
mcr p15 , 0 , r0 , c6 , c7 , 1
mov r0 , #0x80 @ PR7
mcr p15 , 0 , r0 , c2 , c0 , 0 @ D-cache on
mcr p15 , 0 , r0 , c2 , c0 , 1 @ I-cache on
mcr p15 , 0 , r0 , c3 , c0 , 0 @ write-buffer on
mov r0 , #0xc000
mcr p15 , 0 , r0 , c5 , c0 , 1 @ I-access permission
mcr p15 , 0 , r0 , c5 , c0 , 0 @ D-access permission
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
mcr p15 , 0 , r0 , c7 , c5 , 0 @ flush(inval) I-Cache
mcr p15 , 0 , r0 , c7 , c6 , 0 @ flush(inval) D-Cache
mrc p15 , 0 , r0 , c1 , c0 , 0 @ read control reg
@ ...I .... ..D. WC.M
orr r0 , r0 , #0x002d @ .... .... ..1. 11.1
orr r0 , r0 , #0x1000 @ ...1 .... .... ....
mcr p15 , 0 , r0 , c1 , c0 , 0 @ write control reg
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c5 , 0 @ flush(inval) I-Cache
mcr p15 , 0 , r0 , c7 , c6 , 0 @ flush(inval) D-Cache
mov p c , l r
__armv3_mpu_cache_on :
mov r0 , #0x3f @ 4G, the whole
mcr p15 , 0 , r0 , c6 , c7 , 0 @ PR7 Area Setting
mov r0 , #0x80 @ PR7
mcr p15 , 0 , r0 , c2 , c0 , 0 @ cache on
mcr p15 , 0 , r0 , c3 , c0 , 0 @ write-buffer on
mov r0 , #0xc000
mcr p15 , 0 , r0 , c5 , c0 , 0 @ access permission
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 , 0 @ invalidate whole cache v3
mrc p15 , 0 , r0 , c1 , c0 , 0 @ read control reg
@ .... .... .... WC.M
orr r0 , r0 , #0x000d @ .... .... .... 11.1
mov r0 , #0
mcr p15 , 0 , r0 , c1 , c0 , 0 @ write control reg
mcr p15 , 0 , r0 , c7 , c0 , 0 @ invalidate whole cache v3
mov p c , l r
2005-04-16 15:20:36 -07:00
__setup_mmu : sub r3 , r4 , #16384 @ Page directory size
bic r3 , r3 , #0xff @ Align the pointer
bic r3 , r3 , #0x3f00
/ *
* Initialise t h e p a g e t a b l e s , t u r n i n g o n t h e c a c h e a b l e a n d b u f f e r a b l e
* bits f o r t h e R A M a r e a o n l y .
* /
mov r0 , r3
2006-01-12 17:17:57 +00:00
mov r9 , r0 , l s r #18
mov r9 , r9 , l s l #18 @ start of RAM
add r10 , r9 , #0x10000000 @ a reasonable RAM size
2005-04-16 15:20:36 -07:00
mov r1 , #0x12
orr r1 , r1 , #3 < < 1 0
add r2 , r3 , #16384
2006-01-18 22:38:51 +00:00
1 : cmp r1 , r9 @ if virt > start of RAM
2005-04-16 15:20:36 -07:00
orrhs r1 , r1 , #0x0c @ set cacheable, bufferable
2006-01-12 17:17:57 +00:00
cmp r1 , r10 @ if virt > end of RAM
2005-04-16 15:20:36 -07:00
bichs r1 , r1 , #0x0c @ clear cacheable, bufferable
str r1 , [ r0 ] , #4 @ 1:1 mapping
add r1 , r1 , #1048576
teq r0 , r2
bne 1 b
/ *
* If e v e r w e a r e r u n n i n g f r o m F l a s h , t h e n w e s u r e l y w a n t t h e c a c h e
* to b e e n a b l e d a l s o f o r o u r e x e c u t i o n i n s t a n c e . . . W e m a p 2 M B o f i t
* so t h e r e i s n o m a p o v e r l a p p r o b l e m f o r u p t o 1 M B c o m p r e s s e d k e r n e l .
* If t h e e x e c u t i o n i s i n R A M t h e n w e w o u l d o n l y b e d u p l i c a t i n g t h e a b o v e .
* /
mov r1 , #0x1e
orr r1 , r1 , #3 < < 1 0
mov r2 , p c , l s r #20
orr r1 , r1 , r2 , l s l #20
add r0 , r3 , r2 , l s l #2
str r1 , [ r0 ] , #4
add r1 , r1 , #1048576
str r1 , [ r0 ]
mov p c , l r
2006-03-24 09:53:18 +00:00
__armv4_mmu_cache_on :
2005-04-16 15:20:36 -07:00
mov r12 , l r
bl _ _ s e t u p _ m m u
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
mcr p15 , 0 , r0 , c8 , c7 , 0 @ flush I,D TLBs
mrc p15 , 0 , r0 , c1 , c0 , 0 @ read control reg
orr r0 , r0 , #0x5000 @ I-cache enable, RR cache replacement
orr r0 , r0 , #0x0030
2006-03-24 09:53:18 +00:00
bl _ _ c o m m o n _ m m u _ c a c h e _ o n
2005-04-16 15:20:36 -07:00
mov r0 , #0
mcr p15 , 0 , r0 , c8 , c7 , 0 @ flush I,D TLBs
mov p c , r12
2006-03-24 09:53:18 +00:00
__arm6_mmu_cache_on :
2005-04-16 15:20:36 -07:00
mov r12 , l r
bl _ _ s e t u p _ m m u
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 , 0 @ invalidate whole cache v3
mcr p15 , 0 , r0 , c5 , c0 , 0 @ invalidate whole TLB v3
mov r0 , #0x30
2006-03-24 09:53:18 +00:00
bl _ _ c o m m o n _ m m u _ c a c h e _ o n
2005-04-16 15:20:36 -07:00
mov r0 , #0
mcr p15 , 0 , r0 , c5 , c0 , 0 @ invalidate whole TLB v3
mov p c , r12
2006-03-24 09:53:18 +00:00
__common_mmu_cache_on :
2005-04-16 15:20:36 -07:00
# ifndef D E B U G
orr r0 , r0 , #0x000d @ Write buffer, mmu
# endif
mov r1 , #- 1
mcr p15 , 0 , r3 , c2 , c0 , 0 @ load page table pointer
mcr p15 , 0 , r1 , c3 , c0 , 0 @ load domain access control
2006-07-01 21:29:32 +01:00
b 1 f
.align 5 @ cache line aligned
1 : mcr p15 , 0 , r0 , c1 , c0 , 0 @ load control register
mrc p15 , 0 , r0 , c1 , c0 , 0 @ and read it back to
sub p c , l r , r0 , l s r #32 @ properly flush pipeline
2005-04-16 15:20:36 -07:00
/ *
* All c o d e f o l l o w i n g t h i s l i n e i s r e l o c a t a b l e . I t i s r e l o c a t e d b y
* the a b o v e c o d e t o t h e e n d o f t h e d e c o m p r e s s e d k e r n e l i m a g e a n d
* executed t h e r e . D u r i n g t h i s t i m e , w e h a v e n o s t a c k s .
*
* r0 = d e c o m p r e s s e d k e r n e l l e n g t h
* r1 - r3 = u n u s e d
* r4 = k e r n e l e x e c u t i o n a d d r e s s
* r5 = d e c o m p r e s s e d k e r n e l s t a r t
* r6 = p r o c e s s o r I D
* r7 = a r c h i t e c t u r e I D
2006-01-12 17:17:57 +00:00
* r8 = a t a g s p o i n t e r
* r9 - r14 = c o r r u p t e d
2005-04-16 15:20:36 -07:00
* /
.align 5
2006-01-12 17:17:57 +00:00
reloc_start : add r9 , r5 , r0
2005-04-16 15:20:36 -07:00
debug_ r e l o c _ s t a r t
mov r1 , r4
1 :
.rept 4
2006-01-12 17:17:57 +00:00
ldmia r5 ! , { r0 , r2 , r3 , r10 - r14 } @ relocate kernel
stmia r1 ! , { r0 , r2 , r3 , r10 - r14 }
2005-04-16 15:20:36 -07:00
.endr
2006-01-12 17:17:57 +00:00
cmp r5 , r9
2005-04-16 15:20:36 -07:00
blo 1 b
debug_ r e l o c _ e n d
call_kernel : bl c a c h e _ c l e a n _ f l u s h
bl c a c h e _ o f f
2006-01-12 17:17:57 +00:00
mov r0 , #0 @ must be zero
2005-04-16 15:20:36 -07:00
mov r1 , r7 @ restore architecture number
2006-01-12 17:17:57 +00:00
mov r2 , r8 @ restore atags pointer
2005-04-16 15:20:36 -07:00
mov p c , r4 @ call kernel
/ *
* Here f o l l o w t h e r e l o c a t a b l e c a c h e s u p p o r t f u n c t i o n s f o r t h e
* various p r o c e s s o r s . T h i s i s a g e n e r i c h o o k f o r l o c a t i n g a n
* entry a n d j u m p i n g t o a n i n s t r u c t i o n a t t h e s p e c i f i e d o f f s e t
* from t h e s t a r t o f t h e b l o c k . P l e a s e n o t e t h i s i s a l l p o s i t i o n
* independent c o d e .
*
* r1 = c o r r u p t e d
* r2 = c o r r u p t e d
* r3 = b l o c k o f f s e t
* r6 = c o r r u p t e d
* r1 2 = c o r r u p t e d
* /
call_cache_fn : adr r12 , p r o c _ t y p e s
mrc p15 , 0 , r6 , c0 , c0 @ get processor ID
1 : ldr r1 , [ r12 , #0 ] @ get value
ldr r2 , [ r12 , #4 ] @ get mask
eor r1 , r1 , r6 @ (real ^ match)
tst r1 , r2 @ & mask
addeq p c , r12 , r3 @ call cache function
add r12 , r12 , #4 * 5
b 1 b
/ *
* Table f o r c a c h e o p e r a t i o n s . T h i s i s b a s i c a l l y :
* - CPU I D m a t c h
* - CPU I D m a s k
* - ' cache o n ' m e t h o d i n s t r u c t i o n
* - ' cache o f f ' m e t h o d i n s t r u c t i o n
* - ' cache f l u s h ' m e t h o d i n s t r u c t i o n
*
* We m a t c h a n e n t r y u s i n g : ( ( r e a l _ i d ^ m a t c h ) & m a s k ) = = 0
*
* Writethrough c a c h e s g e n e r a l l y o n l y n e e d ' o n ' a n d ' o f f '
* methods. W r i t e b a c k c a c h e s _ m u s t _ h a v e t h e f l u s h m e t h o d
* defined.
* /
.type proc_ t y p e s ,#o b j e c t
proc_types :
.word 0x41560600 @ ARM6/610
.word 0xffffffe0
2006-03-24 09:53:18 +00:00
b _ _ a r m 6 _ m m u _ c a c h e _ o f f @ works, but slow
b _ _ a r m 6 _ m m u _ c a c h e _ o f f
2005-04-16 15:20:36 -07:00
mov p c , l r
2006-03-24 09:53:18 +00:00
@ b __arm6_mmu_cache_on @ untested
@ b __arm6_mmu_cache_off
@ b __armv3_mmu_cache_flush
2005-04-16 15:20:36 -07:00
.word 0x00000000 @ old ARM ID
.word 0x0000f000
mov p c , l r
mov p c , l r
mov p c , l r
.word 0x41007000 @ ARM7/710
.word 0xfff8fe00
2006-03-24 09:53:18 +00:00
b _ _ a r m 7 _ m m u _ c a c h e _ o f f
b _ _ a r m 7 _ m m u _ c a c h e _ o f f
2005-04-16 15:20:36 -07:00
mov p c , l r
.word 0x41807200 @ ARM720T (writethrough)
.word 0xffffff00
2006-03-24 09:53:18 +00:00
b _ _ a r m v4 _ m m u _ c a c h e _ o n
b _ _ a r m v4 _ m m u _ c a c h e _ o f f
2005-04-16 15:20:36 -07:00
mov p c , l r
2006-03-27 10:21:34 +01:00
.word 0x41007400 @ ARM74x
.word 0xff00ff00
b _ _ a r m v3 _ m p u _ c a c h e _ o n
b _ _ a r m v3 _ m p u _ c a c h e _ o f f
b _ _ a r m v3 _ m p u _ c a c h e _ f l u s h
.word 0x41009400 @ ARM94x
.word 0xff00ff00
b _ _ a r m v4 _ m p u _ c a c h e _ o n
b _ _ a r m v4 _ m p u _ c a c h e _ o f f
b _ _ a r m v4 _ m p u _ c a c h e _ f l u s h
2005-04-16 15:20:36 -07:00
.word 0x00007000 @ ARM7 IDs
.word 0x0000f000
mov p c , l r
mov p c , l r
mov p c , l r
@ Everything from here on will be the new ID system.
.word 0x4401a100 @ sa110 / sa1100
.word 0xffffffe0
2006-03-24 09:53:18 +00:00
b _ _ a r m v4 _ m m u _ c a c h e _ o n
b _ _ a r m v4 _ m m u _ c a c h e _ o f f
b _ _ a r m v4 _ m m u _ c a c h e _ f l u s h
2005-04-16 15:20:36 -07:00
.word 0x6901b110 @ sa1110
.word 0xfffffff0
2006-03-24 09:53:18 +00:00
b _ _ a r m v4 _ m m u _ c a c h e _ o n
b _ _ a r m v4 _ m m u _ c a c h e _ o f f
b _ _ a r m v4 _ m m u _ c a c h e _ f l u s h
2005-04-16 15:20:36 -07:00
@ These match on the architecture ID
.word 0x00020000 @ ARMv4T
.word 0x000f0000
2006-03-24 09:53:18 +00:00
b _ _ a r m v4 _ m m u _ c a c h e _ o n
b _ _ a r m v4 _ m m u _ c a c h e _ o f f
b _ _ a r m v4 _ m m u _ c a c h e _ f l u s h
2005-04-16 15:20:36 -07:00
.word 0x00050000 @ ARMv5TE
.word 0x000f0000
2006-03-24 09:53:18 +00:00
b _ _ a r m v4 _ m m u _ c a c h e _ o n
b _ _ a r m v4 _ m m u _ c a c h e _ o f f
b _ _ a r m v4 _ m m u _ c a c h e _ f l u s h
2005-04-16 15:20:36 -07:00
.word 0x00060000 @ ARMv5TEJ
.word 0x000f0000
2006-03-24 09:53:18 +00:00
b _ _ a r m v4 _ m m u _ c a c h e _ o n
b _ _ a r m v4 _ m m u _ c a c h e _ o f f
b _ _ a r m v4 _ m m u _ c a c h e _ f l u s h
2005-04-16 15:20:36 -07:00
2006-06-18 16:21:50 +01:00
.word 0x0007b000 @ ARMv6
.word 0x0007f000
2006-03-24 09:53:18 +00:00
b _ _ a r m v4 _ m m u _ c a c h e _ o n
b _ _ a r m v4 _ m m u _ c a c h e _ o f f
b _ _ a r m v6 _ m m u _ c a c h e _ f l u s h
2005-04-16 15:20:36 -07:00
.word 0 @ unrecognised type
.word 0
mov p c , l r
mov p c , l r
mov p c , l r
.size proc_ t y p e s , . - p r o c _ t y p e s
/ *
* Turn o f f t h e C a c h e a n d M M U . A R M v3 d o e s n o t s u p p o r t
* reading t h e c o n t r o l r e g i s t e r , b u t A R M v4 d o e s .
*
* On e n t r y , r6 = p r o c e s s o r I D
* On e x i t , r0 , r1 , r2 , r3 , r12 c o r r u p t e d
* This r o u t i n e m u s t p r e s e r v e : r4 , r6 , r7
* /
.align 5
cache_off : mov r3 , #12 @ cache_off function
b c a l l _ c a c h e _ f n
2006-03-27 10:21:34 +01:00
__armv4_mpu_cache_off :
mrc p15 , 0 , r0 , c1 , c0
bic r0 , r0 , #0x000d
mcr p15 , 0 , r0 , c1 , c0 @ turn MPU and cache off
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c10 , 4 @ drain write buffer
mcr p15 , 0 , r0 , c7 , c6 , 0 @ flush D-Cache
mcr p15 , 0 , r0 , c7 , c5 , 0 @ flush I-Cache
mov p c , l r
__armv3_mpu_cache_off :
mrc p15 , 0 , r0 , c1 , c0
bic r0 , r0 , #0x000d
mcr p15 , 0 , r0 , c1 , c0 , 0 @ turn MPU and cache off
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 , 0 @ invalidate whole cache v3
mov p c , l r
2006-03-24 09:53:18 +00:00
__armv4_mmu_cache_off :
2005-04-16 15:20:36 -07:00
mrc p15 , 0 , r0 , c1 , c0
bic r0 , r0 , #0x000d
mcr p15 , 0 , r0 , c1 , c0 @ turn MMU and cache off
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c7 @ invalidate whole cache v4
mcr p15 , 0 , r0 , c8 , c7 @ invalidate whole TLB v4
mov p c , l r
2006-03-24 09:53:18 +00:00
__arm6_mmu_cache_off :
2005-04-16 15:20:36 -07:00
mov r0 , #0x00000030 @ ARM6 control reg.
2006-03-24 09:53:18 +00:00
b _ _ a r m v3 _ m m u _ c a c h e _ o f f
2005-04-16 15:20:36 -07:00
2006-03-24 09:53:18 +00:00
__arm7_mmu_cache_off :
2005-04-16 15:20:36 -07:00
mov r0 , #0x00000070 @ ARM7 control reg.
2006-03-24 09:53:18 +00:00
b _ _ a r m v3 _ m m u _ c a c h e _ o f f
2005-04-16 15:20:36 -07:00
2006-03-24 09:53:18 +00:00
__armv3_mmu_cache_off :
2005-04-16 15:20:36 -07:00
mcr p15 , 0 , r0 , c1 , c0 , 0 @ turn MMU and cache off
mov r0 , #0
mcr p15 , 0 , r0 , c7 , c0 , 0 @ invalidate whole cache v3
mcr p15 , 0 , r0 , c5 , c0 , 0 @ invalidate whole TLB v3
mov p c , l r
/ *
* Clean a n d f l u s h t h e c a c h e t o m a i n t a i n c o n s i s t e n c y .
*
* On e n t r y ,
* r6 = p r o c e s s o r I D
* On e x i t ,
* r1 , r2 , r3 , r11 , r12 c o r r u p t e d
* This r o u t i n e m u s t p r e s e r v e :
* r0 , r4 , r5 , r6 , r7
* /
.align 5
cache_clean_flush :
mov r3 , #16
b c a l l _ c a c h e _ f n
2006-03-27 10:21:34 +01:00
__armv4_mpu_cache_flush :
mov r2 , #1
mov r3 , #0
mcr p15 , 0 , i p , c7 , c6 , 0 @ invalidate D cache
mov r1 , #7 < < 5 @ 8 segments
1 : orr r3 , r1 , #63 < < 2 6 @ 64 entries
2 : mcr p15 , 0 , r3 , c7 , c14 , 2 @ clean & invalidate D index
subs r3 , r3 , #1 < < 2 6
bcs 2 b @ entries 63 to 0
subs r1 , r1 , #1 < < 5
bcs 1 b @ segments 7 to 0
teq r2 , #0
mcrne 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
2006-03-24 09:53:18 +00:00
__armv6_mmu_cache_flush :
2005-04-16 15:20:36 -07:00
mov r1 , #0
mcr p15 , 0 , r1 , c7 , c14 , 0 @ clean+invalidate D
mcr p15 , 0 , r1 , c7 , c5 , 0 @ invalidate I+BTB
mcr p15 , 0 , r1 , c7 , c15 , 0 @ clean+invalidate unified
mcr p15 , 0 , r1 , c7 , c10 , 4 @ drain WB
mov p c , l r
2006-03-24 09:53:18 +00:00
__armv4_mmu_cache_flush :
2005-04-16 15:20:36 -07:00
mov r2 , #64 * 1 0 2 4 @ default: 32K dcache size (*2)
mov r11 , #32 @ default: 32 byte line size
mrc p15 , 0 , r3 , c0 , c0 , 1 @ read cache type
teq r3 , r6 @ cache ID register present?
beq n o _ c a c h e _ i d
mov r1 , r3 , l s r #18
and r1 , r1 , #7
mov r2 , #1024
mov r2 , r2 , l s l r1 @ base dcache size *2
tst r3 , #1 < < 1 4 @ test M bit
addne r2 , r2 , r2 , l s r #1 @ +1/2 size if M == 1
mov r3 , r3 , l s r #12
and r3 , r3 , #3
mov r11 , #8
mov r11 , r11 , l s l r3 @ cache line size in bytes
no_cache_id :
bic r1 , p c , #63 @ align to longest cache line
add r2 , r1 , r2
1 : ldr r3 , [ r1 ] , r11 @ s/w flush D cache
teq r1 , r2
bne 1 b
mcr p15 , 0 , r1 , c7 , c5 , 0 @ flush I cache
mcr p15 , 0 , r1 , c7 , c6 , 0 @ flush D cache
mcr p15 , 0 , r1 , c7 , c10 , 4 @ drain WB
mov p c , l r
2006-03-24 09:53:18 +00:00
__armv3_mmu_cache_flush :
2006-03-27 10:21:34 +01:00
__armv3_mpu_cache_flush :
2005-04-16 15:20:36 -07:00
mov r1 , #0
mcr p15 , 0 , r0 , c7 , c0 , 0 @ invalidate whole cache v3
mov p c , l r
/ *
* Various d e b u g g i n g r o u t i n e s f o r p r i n t i n g h e x c h a r a c t e r s a n d
* memory, w h i c h a g a i n m u s t b e r e l o c a t a b l e .
* /
# ifdef D E B U G
.type phexbuf,#o b j e c t
phexbuf : .space 12
.size phexbuf, . - p h e x b u f
phex : adr r3 , p h e x b u f
mov r2 , #0
strb r2 , [ r3 , r1 ]
1 : subs r1 , r1 , #1
movmi r0 , r3
bmi p u t s
and r2 , r0 , #15
mov r0 , r0 , l s r #4
cmp r2 , #10
addge r2 , r2 , #7
add r2 , r2 , #' 0 '
strb r2 , [ r3 , r1 ]
b 1 b
puts : loadsp r3
1 : ldrb r2 , [ r0 ] , #1
teq r2 , #0
moveq p c , l r
2005-05-03 12:18:46 +01:00
2 : writeb r2 , r3
2005-04-16 15:20:36 -07:00
mov r1 , #0x00020000
3 : subs r1 , r1 , #1
bne 3 b
teq r2 , #' \n '
moveq r2 , #' \r '
beq 2 b
teq r0 , #0
bne 1 b
mov p c , l r
putc :
mov r2 , r0
mov r0 , #0
loadsp r3
b 2 b
memdump : mov r12 , r0
mov r10 , l r
mov r11 , #0
2 : mov r0 , r11 , l s l #2
add r0 , r0 , r12
mov r1 , #8
bl p h e x
mov r0 , #' : '
bl p u t c
1 : mov r0 , #' '
bl p u t c
ldr r0 , [ r12 , r11 , l s l #2 ]
mov r1 , #8
bl p h e x
and r0 , r11 , #7
teq r0 , #3
moveq r0 , #' '
bleq p u t c
and r0 , r11 , #7
add r11 , r11 , #1
teq r0 , #7
bne 1 b
mov r0 , #' \n '
bl p u t c
cmp r11 , #64
blt 2 b
mov p c , r10
# endif
reloc_end :
.align
.section " .stack " , " w"
user_stack : .space 4096