2009-01-07 23:14:39 +08:00
/ *
2009-09-24 14:11:24 +00:00
* BF5 6 1 c o r e B b o o t s t r a p f i l e
2009-01-07 23:14:39 +08:00
*
2009-09-24 14:11:24 +00:00
* Copyright 2 0 0 7 - 2 0 0 9 A n a l o g D e v i c e s I n c .
* Philippe G e r u m < r p m @xenomai.org>
2009-01-07 23:14:39 +08:00
*
2009-09-24 14:11:24 +00:00
* Licensed u n d e r t h e G P L - 2 o r l a t e r .
2009-01-07 23:14:39 +08:00
* /
# 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 / b l a c k f i n . h >
# include < a s m / a s m - o f f s e t s . h >
2009-12-28 11:13:51 +00:00
# include < a s m / t r a c e . h >
2009-01-07 23:14:39 +08:00
2010-08-05 07:49:26 +00:00
/ *
* This c o d e m u s t c o m e f i r s t a s C o r e B i s h a r d c o d e d ( i n h a r d w a r e )
* to s t a r t a t t h e b e g i n n i n g o f i t s L 1 i n s t r u c t i o n m e m o r y .
* /
.section .l1 .text .head
2009-01-07 23:14:39 +08:00
/* Lay the initial stack into the L1 scratch area of Core B */
# define I N I T I A L _ S T A C K ( C O R E B _ L 1 _ S C R A T C H _ S T A R T + L 1 _ S C R A T C H _ L E N G T H - 1 2 )
ENTRY( _ c o r e b _ t r a m p o l i n e _ s t a r t )
2011-05-29 16:05:03 -04:00
/* Enable Cycle Counter and Nesting Of Interrupts */
# ifdef C O N F I G _ B F I N _ S C R A T C H _ R E G _ C Y C L E S
R0 = S Y S C F G _ S N E N ;
# else
R0 = S Y S C F G _ S N E N | S Y S C F G _ C C E N ;
# endif
SYSCFG = R 0 ;
2009-01-07 23:14:39 +08:00
2011-05-29 16:05:03 -04:00
/ * Optimization r e g i s t e r t r i c k s : k e e p a b a s e v a l u e i n t h e
* reserved P r e g i s t e r s s o w e u s e t h e l o a d / s t o r e w i t h a n
* offset s y n t a x . R 0 = [ P 5 + < c o n s t a n t > ] ;
* P5 - c o r e M M R b a s e
* R6 - 0
* /
r6 = 0 ;
p5 . l = 0 ;
p5 . h = h i ( C O R E M M R _ B A S E ) ;
2009-12-28 11:13:51 +00:00
2011-05-29 16:05:03 -04:00
/* Zero out registers required by Blackfin ABI */
2009-01-07 23:14:39 +08:00
2011-05-29 16:05:03 -04:00
/* Disable circular buffers */
L0 = r6 ;
L1 = r6 ;
L2 = r6 ;
L3 = r6 ;
/* Disable hardware loops in case we were started by 'go' */
LC0 = r6 ;
LC1 = r6 ;
/ *
* Clear I T E S T _ C O M M A N D a n d D T E S T _ C O M M A N D r e g i s t e r s ,
* Leaving t h e s e a s n o n - z e r o c a n c o n f u s e t h e e m u l a t o r
* /
[ p5 + ( D T E S T _ C O M M A N D - C O R E M M R _ B A S E ) ] = r6 ;
[ p5 + ( I T E S T _ C O M M A N D - C O R E M M R _ B A S E ) ] = r6 ;
2009-08-07 01:20:58 +00:00
CSYNC;
2011-05-29 16:05:03 -04:00
trace_ b u f f e r _ i n i t ( p0 ,r0 ) ;
/* Turn off the icache */
r1 = [ p5 + ( I M E M _ C O N T R O L - C O R E M M R _ B A S E ) ] ;
BITCLR ( r1 , E N I C P L B _ P ) ;
[ p5 + ( I M E M _ C O N T R O L - C O R E M M R _ B A S E ) ] = r1 ;
2009-01-07 23:14:39 +08:00
SSYNC;
/* Turn off the dcache */
2011-05-29 16:05:03 -04:00
r1 = [ p5 + ( D M E M _ C O N T R O L - C O R E M M R _ B A S E ) ] ;
BITCLR ( r1 , E N D C P L B _ P ) ;
[ p5 + ( D M E M _ C O N T R O L - C O R E M M R _ B A S E ) ] = r1 ;
2009-01-07 23:14:39 +08:00
SSYNC;
/* in case of double faults, save a few things */
2011-05-29 23:12:51 -04:00
p1 . l = _ i n i t i a l _ p d a _ c o r e b ;
p1 . h = _ i n i t i a l _ p d a _ c o r e b ;
r4 = R E T X ;
2009-01-07 23:14:39 +08:00
# ifdef C O N F I G _ D E B U G _ D O U B L E F A U L T
/ * Only s a v e t h e s e i f w e a r e s t o r i n g t h e m ,
* This h a p p e n s h e r e , s i n c e L 1 g e t s c l o b b e r e d
* below
* /
GET_ P D A ( p0 , r0 ) ;
2011-05-29 23:12:51 -04:00
r0 = [ p0 + P D A _ D F _ R E T X ] ;
r1 = [ p0 + P D A _ D F _ D C P L B ] ;
r2 = [ p0 + P D A _ D F _ I C P L B ] ;
r3 = [ p0 + P D A _ D F _ S E Q S T A T ] ;
[ p1 + P D A _ I N I T _ D F _ R E T X ] = r0 ;
[ p1 + P D A _ I N I T _ D F _ D C P L B ] = r1 ;
[ p1 + P D A _ I N I T _ D F _ I C P L B ] = r2 ;
[ p1 + P D A _ I N I T _ D F _ S E Q S T A T ] = r3 ;
2009-01-07 23:14:39 +08:00
# endif
2011-05-29 23:12:51 -04:00
[ p1 + P D A _ I N I T _ R E T X ] = r4 ;
2009-01-07 23:14:39 +08:00
/* Initialize stack pointer */
sp. l = l o ( I N I T I A L _ S T A C K ) ;
sp. h = h i ( I N I T I A L _ S T A C K ) ;
fp = s p ;
usp = s p ;
/ * This s e c t i o n k e e p s t h e p r o c e s s o r i n s u p e r v i s o r m o d e
* during c o r e B s t a r t u p . B r a n c h e s t o t h e i d l e t a s k .
* /
/* EVT15 = _real_start */
p1 . l = _ c o r e b _ s t a r t ;
p1 . h = _ c o r e b _ s t a r t ;
2011-05-29 16:05:03 -04:00
[ p5 + ( E V T 1 5 - C O R E M M R _ B A S E ) ] = p1 ;
2009-01-07 23:14:39 +08:00
csync;
2011-05-29 16:05:03 -04:00
r0 = E V T _ I V G 1 5 ( z ) ;
sti r0 ;
2009-01-07 23:14:39 +08:00
raise 1 5 ;
p0 . l = . L W A I T _ H E R E ;
p0 . h = . L W A I T _ H E R E ;
reti = p0 ;
# if d e f i n e d ( A N O M A L Y _ 0 5 0 0 0 2 8 1 )
nop; nop; nop;
# endif
rti;
.LWAIT_HERE :
jump . L W A I T _ H E R E ;
ENDPROC( _ c o r e b _ t r a m p o l i n e _ s t a r t )
2010-01-28 10:46:55 +00:00
# ifdef C O N F I G _ H O T P L U G _ C P U
2009-12-28 11:13:51 +00:00
.section " .text "
2010-01-28 10:46:55 +00:00
ENTRY( _ c o r e b _ d i e )
2009-12-28 11:13:51 +00:00
sp. l = l o ( I N I T I A L _ S T A C K ) ;
sp. h = h i ( I N I T I A L _ S T A C K ) ;
fp = s p ;
usp = s p ;
CLI R 2 ;
SSYNC;
IDLE;
STI R 2 ;
R0 = I W R _ D I S A B L E _ A L L ;
2010-01-28 10:46:55 +00:00
P0 . H = h i ( S Y S M M R _ B A S E ) ;
P0 . L = l o ( S Y S M M R _ B A S E ) ;
[ P0 + ( S I C B _ I W R 0 - S Y S M M R _ B A S E ) ] = R 0 ;
[ P0 + ( S I C B _ I W R 1 - S Y S M M R _ B A S E ) ] = R 0 ;
SSYNC;
2009-12-28 11:13:51 +00:00
p0 . h = h i ( C O R E B _ L 1 _ C O D E _ S T A R T ) ;
p0 . l = l o ( C O R E B _ L 1 _ C O D E _ S T A R T ) ;
jump ( p0 ) ;
2010-01-28 10:46:55 +00:00
ENDPROC( _ c o r e b _ d i e )
# endif
2009-12-28 11:13:51 +00:00
2010-04-06 09:11:59 +00:00
_ _ INIT
2009-01-07 23:14:39 +08:00
ENTRY( _ c o r e b _ s t a r t )
[ - - sp] = r e t i ;
p0 . l = l o ( W D O G B _ C T L ) ;
p0 . h = h i ( W D O G B _ C T L ) ;
r0 = 0 x A D 6 ( z ) ;
w[ p0 ] = r0 ; /* Clear the watchdog. */
ssync;
/ *
* switch t o I D L E s t a c k .
* /
p0 . l = _ s e c o n d a r y _ s t a c k ;
p0 . h = _ s e c o n d a r y _ s t a c k ;
sp = [ p0 ] ;
usp = s p ;
fp = s p ;
2009-12-28 11:13:51 +00:00
# ifdef C O N F I G _ H O T P L U G _ C P U
p0 . l = _ h o t p l u g _ c o r e b ;
p0 . h = _ h o t p l u g _ c o r e b ;
r0 = [ p0 ] ;
cc = B I T T S T ( r0 , 0 ) ;
if c c j u m p 3 f ;
# endif
2009-01-07 23:14:39 +08:00
sp + = - 1 2 ;
call _ i n i t _ p d a
sp + = 1 2 ;
2009-12-28 11:13:51 +00:00
# ifdef C O N F I G _ H O T P L U G _ C P U
3 :
# endif
2009-01-07 23:14:39 +08:00
call _ s e c o n d a r y _ s t a r t _ k e r n e l ;
.L_exit :
jump. s . L _ e x i t ;
ENDPROC( _ c o r e b _ s t a r t )