2005-06-24 09:01:16 +04:00
/ *
* arch/ x t e n s a / k e r n e l / h e a d . S
*
* Xtensa P r o c e s s o r s t a r t u p c o d e .
*
* This f i l e i s s u b j e c t t o t h e t e r m s a n d c o n d i t i o n s o f t h e G N U G e n e r a l P u b l i c
* License. S e e t h e f i l e " C O P Y I N G " i n t h e m a i n d i r e c t o r y o f t h i s a r c h i v e
* for m o r e d e t a i l s .
*
2013-01-05 04:57:17 +04:00
* Copyright ( C ) 2 0 0 1 - 2 0 0 8 T e n s i l i c a I n c .
2005-06-24 09:01:16 +04:00
*
* Chris Z a n k e l < c h r i s @zankel.net>
* Marc G a u t h i e r < m a r c @tensilica.com, marc@alumni.uwaterloo.ca>
* Joe T a y l o r < j o e @tensilica.com, joetylr@yahoo.com>
* Kevin C h e a
* /
# include < a s m / p r o c e s s o r . h >
# include < a s m / p a g e . h >
2006-12-10 13:18:48 +03:00
# include < a s m / c a c h e a s m . h >
2012-11-19 07:00:41 +04:00
# include < a s m / i n i t i a l i z e _ m m u . h >
2013-10-17 02:42:26 +04:00
# include < a s m / m x r e g s . h >
2005-06-24 09:01:16 +04:00
2009-04-26 06:10:57 +04:00
# include < l i n u x / i n i t . h >
2007-06-01 04:48:07 +04:00
# include < l i n u x / l i n k a g e . h >
2005-06-24 09:01:16 +04:00
/ *
* This m o d u l e c o n t a i n s t h e e n t r y c o d e f o r k e r n e l i m a g e s . I t p e r f o r m s t h e
* minimal s e t u p n e e d e d t o c a l l t h e g e n e r i c C r o u t i n e s .
*
* Prerequisites :
*
* - The k e r n e l i m a g e h a s b e e n l o a d e d t o t h e a c t u a l a d d r e s s w h e r e i t w a s
* compiled t o .
* - a2 c o n t a i n s e i t h e r 0 o r a p o i n t e r t o a l i s t o f b o o t p a r a m e t e r s .
* ( see s e t u p . c f o r m o r e d e t a i l s )
*
* /
/ *
* _ start
*
* The b o o t l o a d e r p a s s e s a p o i n t e r t o a l i s t o f b o o t p a r a m e t e r s i n a2 .
* /
/ * The f i r s t b y t e s o f t h e k e r n e l i m a g e m u s t b e a n i n s t r u c t i o n , s o w e
* manually a l l o c a t e a n d d e f i n e t h e l i t e r a l c o n s t a n t w e n e e d f o r a j x
* instruction.
* /
2009-04-26 06:10:57 +04:00
_ _ HEAD
2012-12-03 15:01:43 +04:00
.begin no- a b s o l u t e - l i t e r a l s
2012-11-17 04:16:20 +04:00
ENTRY( _ s t a r t )
2012-12-03 15:01:43 +04:00
/* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
wsr a2 , e x c s a v e 1
2013-10-17 02:42:26 +04:00
_ j _ S e t u p O C D
2012-12-03 15:01:43 +04:00
.align 4
.literal_position
.Lstartup :
.word _startup
2005-06-24 09:01:16 +04:00
.align 4
2013-10-17 02:42:26 +04:00
_SetupOCD :
/ *
* Initialize W B , W S , a n d c l e a r P S . E X C M ( t o a l l o w l o o p i n s t r u c t i o n s ) .
* Set I n t e r r u p t L e v e l j u s t b e l o w X C H A L _ D E B U G L E V E L t o a l l o w
* xt- g d b t o s i n g l e s t e p v i a D E B U G e x c e p t i o n s r e c e i v e d d i r e c t l y
* by o c d .
* /
movi a1 , 1
movi a0 , 0
wsr a1 , w i n d o w s t a r t
wsr a0 , w i n d o w b a s e
rsync
movi a1 , L O C K L E V E L
wsr a1 , p s
rsync
2012-12-03 15:01:43 +04:00
.global _SetupMMU
_SetupMMU :
Offset = _ S e t u p M M U - _ s t a r t
# ifdef C O N F I G _ I N I T I A L I Z E _ X T E N S A _ M M U _ I N S I D E _ V M L I N U X
initialize_ m m u
2013-06-09 04:52:11 +04:00
# if d e f i n e d ( C O N F I G _ M M U ) & & X C H A L _ H A V E _ P T P _ M M U & & X C H A L _ H A V E _ S P A N N I N G _ W A Y
rsr a2 , e x c s a v e 1
movi a3 , 0 x08 0 0 0 0 0 0
bgeu a2 , a3 , 1 f
movi a3 , 0 x d00 0 0 0 0 0
add a2 , a2 , a3
wsr a2 , e x c s a v e 1
1 :
# endif
2012-12-03 15:01:43 +04:00
# endif
.end no- a b s o l u t e - l i t e r a l s
l3 2 r a0 , . L s t a r t u p
2005-06-24 09:01:16 +04:00
jx a0
2012-11-17 04:16:20 +04:00
ENDPROC( _ s t a r t )
2013-10-17 02:42:28 +04:00
_ _ REF
2012-12-03 15:01:43 +04:00
.literal_position
2012-11-17 04:16:20 +04:00
ENTRY( _ s t a r t u p )
2005-06-24 09:01:16 +04:00
/* Set a0 to 0 for the remaining initialization. */
movi a0 , 0
2014-10-04 05:12:27 +04:00
# if X C H A L _ H A V E _ V E C B A S E
movi a2 , V E C B A S E _ R E S E T _ V A D D R
wsr a2 , v e c b a s e
# endif
2005-06-24 09:01:16 +04:00
/* Clear debugging registers. */
# if X C H A L _ H A V E _ D E B U G
2013-03-04 03:40:42 +04:00
# if X C H A L _ N U M _ I B R E A K > 0
2012-10-15 03:55:38 +04:00
wsr a0 , i b r e a k e n a b l e
2013-03-04 03:40:42 +04:00
# endif
2012-10-15 03:55:38 +04:00
wsr a0 , i c o u n t
2005-06-24 09:01:16 +04:00
movi a1 , 1 5
2012-10-15 03:55:38 +04:00
wsr a0 , i c o u n t l e v e l
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:48 +03:00
.set _ index, 0
2016-03-03 18:34:29 +03:00
.rept XCHAL_NUM_DBREAK
2012-10-15 03:55:38 +04:00
wsr a0 , S R E G _ D B R E A K C + _ i n d e x
2006-12-10 13:18:48 +03:00
.set _ index, _ i n d e x + 1
.endr
2005-06-24 09:01:16 +04:00
# endif
/* Clear CCOUNT (not really necessary, but nice) */
2012-10-15 03:55:38 +04:00
wsr a0 , c c o u n t # n o t r e a l l y n e c e s s a r y , b u t n i c e
2005-06-24 09:01:16 +04:00
/* Disable zero-loops. */
# if X C H A L _ H A V E _ L O O P S
2012-10-15 03:55:38 +04:00
wsr a0 , l c o u n t
2005-06-24 09:01:16 +04:00
# endif
/* Disable all timers. */
2006-12-10 13:18:48 +03:00
.set _ index, 0
2012-12-11 01:26:22 +04:00
.rept XCHAL_NUM_TIMERS
2012-10-15 03:55:38 +04:00
wsr a0 , S R E G _ C C O M P A R E + _ i n d e x
2006-12-10 13:18:48 +03:00
.set _ index, _ i n d e x + 1
.endr
2005-06-24 09:01:16 +04:00
/* Interrupt initialization. */
movi a2 , X C H A L _ I N T T Y P E _ M A S K _ S O F T W A R E | X C H A L _ I N T T Y P E _ M A S K _ E X T E R N _ E D G E
2012-10-15 03:55:38 +04:00
wsr a0 , i n t e n a b l e
wsr a2 , i n t c l e a r
2005-06-24 09:01:16 +04:00
/* Disable coprocessors. */
2012-12-11 01:26:23 +04:00
# if X C H A L _ H A V E _ C P
2012-10-15 03:55:38 +04:00
wsr a0 , c p e n a b l e
2005-06-24 09:01:16 +04:00
# endif
/ * Initialize t h e c a c h e s .
2006-12-10 13:18:48 +03:00
* a2 , a3 a r e j u s t w o r k i n g r e g i s t e r s ( c l o b b e r e d ) .
2005-06-24 09:01:16 +04:00
* /
2006-12-10 13:18:48 +03:00
# if X C H A L _ D C A C H E _ L I N E _ L O C K A B L E
_ _ _ unlock_ d c a c h e _ a l l a2 a3
# endif
# if X C H A L _ I C A C H E _ L I N E _ L O C K A B L E
_ _ _ unlock_ i c a c h e _ a l l a2 a3
# endif
_ _ _ invalidate_ d c a c h e _ a l l a2 a3
_ _ _ invalidate_ i c a c h e _ a l l a2 a3
isync
2005-06-24 09:01:16 +04:00
2013-10-17 02:42:26 +04:00
# ifdef C O N F I G _ H A V E _ S M P
movi a2 , C C O N # M X E x t e r n a l R e g i s t e r t o C o n f i g u r e C a c h e
movi a3 , 1
wer a3 , a2
# endif
/* Setup stack and enable window exceptions (keep irqs disabled) */
movi a1 , s t a r t _ i n f o
l3 2 i a1 , a1 , 0
movi a2 , ( 1 < < P S _ W O E _ B I T ) | L O C K L E V E L
# WOE=1 , I N T L E V E L =LOCKLEVEL , U M =0
wsr a2 , p s # ( e n a b l e r e g - w i n d o w s ; p r o g m o d e s t a c k )
rsync
# ifdef C O N F I G _ S M P
/ *
* Notice t h a t w e a s s u m e w i t h S M P t h a t c o r e s h a v e P R I D
* supported b y t h e c o r e s .
* /
rsr a2 , p r i d
bnez a2 , . L b o o t _ s e c o n d a r y
# endif / * C O N F I G _ S M P * /
2005-06-24 09:01:16 +04:00
/ * Unpack d a t a s e c t i o n s
*
* The l i n k e r s c r i p t u s e d t o b u i l d t h e L i n u x k e r n e l i m a g e
* creates a t a b l e l o c a t e d a t _ _ b o o t _ r e l o c _ t a b l e _ s t a r t
* that c o n t a n s t h e i n f o r m a t i o n w h a t d a t a n e e d s t o b e u n p a c k e d .
*
* Uses a2 - a7 .
* /
movi a2 , _ _ b o o t _ r e l o c _ t a b l e _ s t a r t
movi a3 , _ _ b o o t _ r e l o c _ t a b l e _ e n d
1 : beq a2 , a3 , 3 f # n o m o r e e n t r i e s ?
l3 2 i a4 , a2 , 0 # s t a r t d e s t i n a t i o n ( i n R A M )
l3 2 i a5 , a2 , 4 # e n d d e s i n a t i o n ( i n R A M )
l3 2 i a6 , a2 , 8 # s t a r t s o u r c e ( i n R O M )
addi a2 , a2 , 1 2 # n e x t e n t r y
beq a4 , a5 , 1 b # s k i p , e m p t y e n t r y
beq a4 , a6 , 1 b # s k i p , s o u r c e a n d d e s t . a r e t h e s a m e
2 : l3 2 i a7 , a6 , 0 # l o a d w o r d
addi a6 , a6 , 4
s3 2 i a7 , a4 , 0 # s t o r e w o r d
addi a4 , a4 , 4
bltu a4 , a5 , 2 b
j 1 b
3 :
/ * All c o d e a n d i n i t i a l i z e d d a t a s e g m e n t s h a v e b e e n c o p i e d .
* Now c l e a r t h e B S S s e g m e n t .
* /
2010-05-02 10:05:29 +04:00
movi a2 , _ _ b s s _ s t a r t # s t a r t o f B S S
movi a3 , _ _ b s s _ s t o p # e n d o f B S S
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:48 +03:00
_ _ loopt a2 , a3 , a4 , 2
2005-06-24 09:01:16 +04:00
s3 2 i a0 , a2 , 0
2015-09-24 23:11:53 +03:00
_ _ endla a2 , a3 , 4
2005-06-24 09:01:16 +04:00
# if X C H A L _ D C A C H E _ I S _ W R I T E B A C K
/ * After u n p a c k i n g , f l u s h t h e w r i t e b a c k c a c h e t o m e m o r y s o t h e
* instructions/ d a t a a r e a v a i l a b l e .
* /
2006-12-10 13:18:48 +03:00
_ _ _ flush_ d c a c h e _ a l l a2 a3
2005-06-24 09:01:16 +04:00
# endif
2012-12-03 15:01:43 +04:00
memw
isync
_ _ _ invalidate_ i c a c h e _ a l l a2 a3
isync
2005-06-24 09:01:16 +04:00
2013-10-17 02:42:26 +04:00
movi a6 , 0
2012-10-15 03:55:38 +04:00
xsr a6 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
/* init_arch kick-starts the linux kernel */
movi a4 , i n i t _ a r c h
callx4 a4
movi a4 , s t a r t _ k e r n e l
callx4 a4
should_never_return :
j s h o u l d _ n e v e r _ r e t u r n
2013-10-17 02:42:26 +04:00
# ifdef C O N F I G _ S M P
.Lboot_secondary :
movi a2 , c p u _ s t a r t _ c c o u n t
1 :
l3 2 i a3 , a2 , 0
beqi a3 , 0 , 1 b
movi a3 , 0
s3 2 i a3 , a2 , 0
memw
1 :
l3 2 i a3 , a2 , 0
beqi a3 , 0 , 1 b
wsr a3 , c c o u n t
movi a3 , 0
s3 2 i a3 , a2 , 0
memw
movi a6 , 0
wsr a6 , e x c s a v e 1
movi a4 , s e c o n d a r y _ s t a r t _ k e r n e l
callx4 a4
j s h o u l d _ n e v e r _ r e t u r n
# endif / * C O N F I G _ S M P * /
2012-11-17 04:16:20 +04:00
ENDPROC( _ s t a r t u p )
2005-06-24 09:01:16 +04:00
2013-10-17 02:42:28 +04:00
# ifdef C O N F I G _ H O T P L U G _ C P U
ENTRY( c p u _ r e s t a r t )
# if X C H A L _ D C A C H E _ I S _ W R I T E B A C K
_ _ _ flush_ i n v a l i d a t e _ d c a c h e _ a l l a2 a3
# else
_ _ _ invalidate_ d c a c h e _ a l l a2 a3
# endif
memw
movi a2 , C C O N # M X E x t e r n a l R e g i s t e r t o C o n f i g u r e C a c h e
movi a3 , 0
wer a3 , a2
extw
rsr a0 , p r i d
neg a2 , a0
movi a3 , c p u _ s t a r t _ i d
s3 2 i a2 , a3 , 0
# if X C H A L _ D C A C H E _ I S _ W R I T E B A C K
dhwbi a3 , 0
# endif
1 :
l3 2 i a2 , a3 , 0
dhi a3 , 0
bne a2 , a0 , 1 b
/ *
* Initialize W B , W S , a n d c l e a r P S . E X C M ( t o a l l o w l o o p i n s t r u c t i o n s ) .
* Set I n t e r r u p t L e v e l j u s t b e l o w X C H A L _ D E B U G L E V E L t o a l l o w
* xt- g d b t o s i n g l e s t e p v i a D E B U G e x c e p t i o n s r e c e i v e d d i r e c t l y
* by o c d .
* /
movi a1 , 1
movi a0 , 0
wsr a1 , w i n d o w s t a r t
wsr a0 , w i n d o w b a s e
rsync
movi a1 , L O C K L E V E L
wsr a1 , p s
rsync
j _ s t a r t u p
ENDPROC( c p u _ r e s t a r t )
# endif / * C O N F I G _ H O T P L U G _ C P U * /
2013-10-17 02:42:26 +04:00
/ *
* DATA s e c t i o n
* /
.section " .data .init .refok "
.align 4
ENTRY( s t a r t _ i n f o )
.long init_thread_union + KERNEL_ S T A C K _ S I Z E
2007-06-01 04:48:07 +04:00
/ *
* BSS s e c t i o n
* /
2009-09-21 02:14:14 +04:00
_ _ PAGE_ A L I G N E D _ B S S
2009-03-04 18:21:31 +03:00
# ifdef C O N F I G _ M M U
2007-06-01 04:48:07 +04:00
ENTRY( s w a p p e r _ p g _ d i r )
.fill PAGE_ S I Z E , 1 , 0
2012-11-17 04:16:20 +04:00
END( s w a p p e r _ p g _ d i r )
2009-03-04 18:21:31 +03:00
# endif
2007-06-01 04:48:07 +04:00
ENTRY( e m p t y _ z e r o _ p a g e )
.fill PAGE_ S I Z E , 1 , 0
2012-11-17 04:16:20 +04:00
END( e m p t y _ z e r o _ p a g e )