2011-01-15 18:15:45 +08:00
/ *
* linux/ a r c h / u n i c o r e 3 2 / k e r n e l / h e a d . S
*
* Code s p e c i f i c t o P K U n i t y S o C a n d U n i C o r e I S A
*
* Copyright ( C ) 2 0 0 1 - 2 0 1 0 G U A N X u e - t a o
*
* 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 >
# include < a s m / p t r a c e . h >
# include < g e n e r a t e d / a s m - o f f s e t s . h >
# include < a s m / m e m o r y . h >
# include < a s m / t h r e a d _ i n f o . h >
2012-03-28 18:30:03 +01:00
# include < a s m / h w d e f - c o p r o . h >
2011-01-15 18:15:45 +08:00
# include < a s m / p g t a b l e - h w d e f . h >
# if ( P H Y S _ O F F S E T & 0 x00 3 f f f f f )
# error " P H Y S _ O F F S E T m u s t b e a t a n e v e n 4 M i B b o u n d a r y ! "
# endif
# define K E R N E L _ R A M _ V A D D R ( P A G E _ O F F S E T + K E R N E L _ I M A G E _ S T A R T )
# define K E R N E L _ R A M _ P A D D R ( P H Y S _ O F F S E T + K E R N E L _ I M A G E _ S T A R T )
# define K E R N E L _ P G D _ P A D D R ( K E R N E L _ R A M _ P A D D R - 0 x10 0 0 )
# define K E R N E L _ P G D _ V A D D R ( K E R N E L _ R A M _ V A D D R - 0 x10 0 0 )
# define K E R N E L _ S T A R T K E R N E L _ R A M _ V A D D R
# define K E R N E L _ E N D _ e n d
/ *
* swapper_ p g _ d i r i s t h e v i r t u a l a d d r e s s o f t h e i n i t i a l p a g e t a b l e .
* We p l a c e t h e p a g e t a b l e s 4 K b e l o w K E R N E L _ R A M _ V A D D R . T h e r e f o r e , w e m u s t
* make s u r e t h a t K E R N E L _ R A M _ V A D D R i s c o r r e c t l y s e t . C u r r e n t l y , w e e x p e c t
* the l e a s t s i g n i f i c a n t 1 6 b i t s t o b e 0 x80 0 0 , b u t w e c o u l d p r o b a b l y
* relax t h i s r e s t r i c t i o n t o K E R N E L _ R A M _ V A D D R > = P A G E _ O F F S E T + 0 x10 0 0 .
* /
# if ( K E R N E L _ R A M _ V A D D R & 0 x f f f f ) ! = 0 x80 0 0
# error K E R N E L _ R A M _ V A D D R m u s t s t a r t a t 0 x X X X X 8 0 0 0
# endif
.globl swapper_pg_dir
.equ swapper_ p g _ d i r , K E R N E L _ R A M _ V A D D R - 0 x10 0 0
/ *
* Kernel s t a r t u p e n t r y p o i n t .
* - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* This i s n o r m a l l y c a l l e d f r o m t h e d e c o m p r e s s o r c o d e . T h e r e q u i r e m e n t s
* are : MMU = o f f , D - c a c h e = o f f , I - c a c h e = d o n t c a r e
*
* This c o d e i s m o s t l y p o s i t i o n i n d e p e n d e n t , s o i f y o u l i n k t h e k e r n e l a t
* 0 xc0 0 0 8 0 0 0 , y o u c a l l t h i s a t _ _ p a ( 0 x c00 0 8 0 0 0 ) .
* /
_ _ HEAD
ENTRY( s t e x t )
@ set asr
mov r0 , #P R I V _ M O D E @ e n s u r e p r i v m o d e
or r0 , #P S R _ R _ B I T | P S R _ I _ B I T @ d i s a b l e i r q s
mov. a a s r , r0
@ process identify
movc r0 , p0 . c0 , #0 @ cpuid
movl r1 , 0 x f f00 f f f f @ mask
movl r2 , 0 x4 d00 0 8 6 3 @ value
and r0 , r1 , r0
cxor. a r0 , r2
bne _ _ e r r o r _ p @ invalid processor id
/ *
* Clear t h e 4 K l e v e l 1 s w a p p e r p a g e t a b l e
* /
movl r0 , #K E R N E L _ P G D _ P A D D R @ p a g e t a b l e a d d r e s s
mov r1 , #0
add r2 , r0 , #0x1000
101 : stw. w r1 , [ r0 ] + , #4
stw. w r1 , [ r0 ] + , #4
stw. w r1 , [ r0 ] + , #4
stw. w r1 , [ r0 ] + , #4
cxor. a r0 , r2
bne 1 0 1 b
movl r4 , #K E R N E L _ P G D _ P A D D R @ p a g e t a b l e a d d r e s s
mov r7 , #P M D _ T Y P E _ S E C T | P M D _ P R E S E N T @ p a g e s i z e : s e c t i o n
or r7 , r7 , #P M D _ S E C T _ C A C H E A B L E @ c a c h e a b l e
or r7 , r7 , #P M D _ S E C T _ R E A D | P M D _ S E C T _ W R I T E | P M D _ S E C T _ E X E C
/ *
* Create i d e n t i t y m a p p i n g f o r f i r s t 4 M B o f k e r n e l t o
* cater f o r t h e M M U e n a b l e . T h i s i d e n t i t y m a p p i n g
* will b e r e m o v e d b y p a g i n g _ i n i t ( ) . W e u s e o u r c u r r e n t p r o g r a m
* counter t o d e t e r m i n e c o r r e s p o n d i n g s e c t i o n b a s e a d d r e s s .
* /
mov r6 , p c
mov r6 , r6 > > #22 @ start of kernel section
or r1 , r7 , r6 < < #22 @ flags + kernel base
stw r1 , [ r4 + ] , r6 < < #2 @ identity mapping
/ *
* Now s e t u p t h e p a g e t a b l e s f o r o u r k e r n e l d i r e c t
* mapped r e g i o n .
* /
add r0 , r4 , #( K E R N E L _ S T A R T & 0xff000000 ) > > 2 0
stw. w r1 , [ r0 + ] , #( K E R N E L _ S T A R T & 0x00c00000 ) > > 2 0
movl r6 , #( K E R N E L _ E N D - 1 )
add r0 , r0 , #4
add r6 , r4 , r6 > > #20
102 : csub. a r0 , r6
add r1 , r1 , #1 < < 2 2
bua 1 0 3 f
stw. w r1 , [ r0 ] + , #4
b 1 0 2 b
103 :
/ *
* Then m a p f i r s t 4 M B o f r a m i n c a s e i t c o n t a i n s o u r b o o t p a r a m s .
* /
add r0 , r4 , #P A G E _ O F F S E T > > 20
or r6 , r7 , #( P H Y S _ O F F S E T & 0xffc00000 )
stw r6 , [ r0 ]
ldw r15 , _ _ s w i t c h _ d a t a @ address to jump to after
/ *
* Initialise T L B , C a c h e s , a n d M M U s t a t e r e a d y t o s w i t c h t h e M M U
* on.
* /
mov r0 , #0
movc p0 . c5 , r0 , #28 @ cache invalidate all
nop8
movc p0 . c6 , r0 , #6 @ TLB invalidate all
nop8
/ *
* . .V . . . . . . .TB IDAM
* . .1 . . . . . . .01 1111
* /
movl r0 , #0x201f @ control register setting
/ *
* Setup c o m m o n b i t s b e f o r e f i n a l l y e n a b l i n g t h e M M U . E s s e n t i a l l y
* this i s j u s t l o a d i n g t h e p a g e t a b l e p o i n t e r a n d d o m a i n a c c e s s
* registers.
* /
# ifndef C O N F I G _ A L I G N M E N T _ T R A P
andn r0 , r0 , #C R _ A
# endif
# ifdef C O N F I G _ C P U _ D C A C H E _ D I S A B L E
andn r0 , r0 , #C R _ D
# endif
# 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
andn r0 , r0 , #C R _ B
# endif
# ifdef C O N F I G _ C P U _ I C A C H E _ D I S A B L E
andn r0 , r0 , #C R _ I
# endif
movc p0 . c2 , r4 , #0 @ set pgd
b _ _ t u r n _ m m u _ o n
ENDPROC( s t e x t )
/ *
2011-03-30 22:57:33 -03:00
* Enable t h e M M U . T h i s c o m p l e t e l y c h a n g e s t h e s t r u c t u r e o f t h e v i s i b l e
2011-01-15 18:15:45 +08:00
* memory s p a c e . Y o u w i l l n o t b e a b l e t o t r a c e e x e c u t i o n t h r o u g h t h i s .
*
* r0 = c p #0 c o n t r o l r e g i s t e r
* r1 5 = * v i r t u a l * a d d r e s s t o j u m p t o u p o n c o m p l e t i o n
* /
.align 5
__turn_mmu_on :
mov r0 , r0
movc p0 . c1 , r0 , #0 @ write control reg
nop @ fetch inst by phys addr
mov p c , r15
nop8 @ fetch inst by phys addr
ENDPROC( _ _ t u r n _ m m u _ o n )
/ *
* Setup t h e i n i t i a l p a g e t a b l e s . W e o n l y s e t u p t h e b a r e s t
* amount w h i c h a r e r e q u i r e d t o g e t t h e k e r n e l r u n n i n g , w h i c h
* generally m e a n s m a p p i n g i n t h e k e r n e l c o d e .
*
* r9 = c p u i d
* r1 0 = p r o c i n f o
*
* Returns :
* r0 , r3 , r6 , r7 c o r r u p t e d
* r4 = p h y s i c a l p a g e t a b l e a d d r e s s
* /
.ltorg
.align 2
.type _ _ switch_ d a t a , % o b j e c t
__switch_data :
.long __mmap_switched
.long __bss_start @ r6
.long _end @ r7
.long cr_alignment @ r8
.long init_thread_union + THREAD_ S T A R T _ S P @ sp
/ *
* The f o l l o w i n g f r a g m e n t o f c o d e i s e x e c u t e d w i t h t h e M M U o n i n M M U m o d e ,
* and u s e s a b s o l u t e a d d r e s s e s ; this is not position independent.
*
* r0 = c p #0 c o n t r o l r e g i s t e r
* /
__mmap_switched :
adr r3 , _ _ s w i t c h _ d a t a + 4
ldm. w ( r6 , r7 , r8 ) , [ r3 ] +
ldw s p , [ r3 ]
mov f p , #0 @ Clear BSS (and zero fp)
203 : csub. a r6 , r7
bea 2 0 4 f
stw. w f p , [ r6 ] + ,#4
b 2 0 3 b
204 :
andn r1 , r0 , #C R _ A @ C l e a r ' A ' b i t
stm ( r0 , r1 ) , [ r8 ] + @ Save control register values
b s t a r t _ k e r n e l
ENDPROC( _ _ m m a p _ s w i t c h e d )
/ *
* Exception h a n d l i n g . S o m e t h i n g w e n t w r o n g a n d w e c a n ' t p r o c e e d . W e
* ought t o t e l l t h e u s e r , b u t s i n c e w e d o n ' t h a v e a n y g u a r a n t e e t h a t
* we' r e e v e n r u n n i n g o n t h e r i g h t a r c h i t e c t u r e , w e d o v i r t u a l l y n o t h i n g .
*
* If C O N F I G _ D E B U G _ L L i s s e t w e t r y t o p r i n t o u t s o m e t h i n g a b o u t t h e e r r o r
* and h o p e f o r t h e b e s t ( u s e f u l i f b o o t l o a d e r f a i l s t o p a s s a p r o p e r
* machine I D f o r e x a m p l e ) .
* /
__error_p :
# ifdef C O N F I G _ D E B U G _ L L
adr r0 , s t r _ p1
b. l p r i n t a s c i i
mov r0 , r9
b. l p r i n t h e x8
adr r0 , s t r _ p2
b. l p r i n t a s c i i
901 : nop8
b 9 0 1 b
str_p1 : .asciz " \nError: unrecognized processor variant (0x "
str_p2 : .asciz " ).\n "
.align
# endif
ENDPROC( _ _ e r r o r _ p )