2011-11-16 05:25:45 +04:00
/ *
* 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 .
*
* Copyright ( C ) 2 0 1 1 b y K e v i n C e r n e k e e ( c e r n e k e e @gmail.com)
*
* Reset/ N M I / r e - e n t r y v e c t o r s f o r B M I P S p r o c e s s o r s
* /
# include < a s m / a s m . h >
# include < a s m / a s m m a c r o . h >
# include < a s m / c a c h e o p s . h >
2013-12-18 17:12:01 +04:00
# include < a s m / c p u . h >
2011-11-16 05:25:45 +04:00
# include < a s m / r e g d e f . h >
# include < a s m / m i p s r e g s . h >
# include < a s m / s t a c k f r a m e . h >
# include < a s m / a d d r s p a c e . h >
# include < a s m / h a z a r d s . h >
# include < a s m / b m i p s . h >
.macro BARRIER
.set mips32
_ ssnop
_ ssnop
_ ssnop
.set mips0
.endm
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Alternate C P U 1 s t a r t u p v e c t o r f o r B M I P S 4 3 5 0
*
* On s o m e s y s t e m s t h e b o o t l o a d e r h a s a l r e a d y s t a r t e d C P U 1 a n d c o n f i g u r e d
* it t o r e s u m e e x e c u t i o n a t 0 x80 0 0 _ 0 2 0 0 ( ! B E V I V v e c t o r ) w h e n i t i s
* triggered b y t h e S W 1 i n t e r r u p t . I f t h a t i s t h e c a s e w e t r y t o m o v e
* it t o a m o r e c o n v e n i e n t p l a c e : B M I P S _ W A R M _ R E S T A R T _ V E C @ 0x8000_0380.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
LEAF( b m i p s _ s m p _ m o v e v e c )
la k 0 , 1 f
li k 1 , C K S E G 1
or k 0 , k 1
jr k 0
1 :
/* clear IV, pending IPIs */
mtc0 z e r o , C P 0 _ C A U S E
/* re-enable IRQs to wait for SW1 */
li k 0 , S T 0 _ I E | S T 0 _ B E V | S T A T U S F _ I P 1
mtc0 k 0 , C P 0 _ S T A T U S
/* set up CPU1 CBR; move BASE to 0xa000_0000 */
li k 0 , 0 x f f40 0 0 0 0
mtc0 k 0 , $ 2 2 , 6
2013-07-24 20:12:11 +04:00
/* set up relocation vector address based on thread ID */
mfc0 k 1 , $ 2 2 , 3
srl k 1 , 1 6
andi k 1 , 0 x80 0 0
or k 1 , C K S E G 1 | B M I P S _ R E L O _ V E C T O R _ C O N T R O L _ 0
2011-11-16 05:25:45 +04:00
or k 0 , k 1
li k 1 , 0 x a00 8 0 0 0 0
sw k 1 , 0 ( k 0 )
/* wait here for SW1 interrupt from bmips_boot_secondary() */
wait
la k 0 , b m i p s _ r e s e t _ n m i _ v e c
li k 1 , C K S E G 1
or k 0 , k 1
jr k 0
END( b m i p s _ s m p _ m o v e v e c )
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Reset/ N M I v e c t o r
* For B M I P S p r o c e s s o r s t h a t c a n r e l o c a t e t h e i r e x c e p t i o n v e c t o r s , t h i s
* entire f u n c t i o n g e t s c o p i e d t o 0 x80 0 0 _ 0 0 0 0 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
NESTED( b m i p s _ r e s e t _ n m i _ v e c , P T _ S I Z E , s p )
.set push
.set noat
.align 4
# ifdef C O N F I G _ S M P
/* if the NMI bit is clear, assume this is a CPU1 reset instead */
li k 1 , ( 1 < < 1 9 )
mfc0 k 0 , C P 0 _ S T A T U S
and k 0 , k 1
beqz k 0 , b m i p s _ s m p _ e n t r y
# if d e f i n e d ( C O N F I G _ C P U _ B M I P S 5 0 0 0 )
2013-12-18 17:12:01 +04:00
mfc0 k 0 , C P 0 _ P R I D
li k 1 , P R I D _ I M P _ B M I P S 5 0 0 0
andi k 0 , 0 x f f00
bne k 0 , k 1 , 1 f
2011-11-16 05:25:45 +04:00
/* if we're not on core 0, this must be the SMP boot signal */
li k 1 , ( 3 < < 2 5 )
mfc0 k 0 , $ 2 2
and k 0 , k 1
bnez k 0 , b m i p s _ s m p _ e n t r y
2013-12-18 17:12:01 +04:00
1 :
# endif / * C O N F I G _ C P U _ B M I P S 5 0 0 0 * /
2011-11-16 05:25:45 +04:00
# endif / * C O N F I G _ S M P * /
/* nope, it's just a regular NMI */
SAVE_ A L L
move a0 , s p
/* clear EXL, ERL, BEV so that TLB refills still work */
mfc0 k 0 , C P 0 _ S T A T U S
li k 1 , S T 0 _ E R L | S T 0 _ E X L | S T 0 _ B E V | S T 0 _ I E
or k 0 , k 1
xor k 0 , k 1
mtc0 k 0 , C P 0 _ S T A T U S
BARRIER
/* jump to the NMI handler function */
la k 0 , n m i _ h a n d l e r
jr k 0
RESTORE_ A L L
2014-03-30 15:20:10 +04:00
.set arch=r4000
2011-11-16 05:25:45 +04:00
eret
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* CPU1 r e s e t v e c t o r ( u s e d f o r t h e i n i t i a l b o o t o n l y )
* This i s s t i l l p a r t o f b m i p s _ r e s e t _ n m i _ v e c ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
# ifdef C O N F I G _ S M P
bmips_smp_entry :
/* set up CP0 STATUS; enable FPU */
li k 0 , 0 x30 0 0 0 0 0 0
mtc0 k 0 , C P 0 _ S T A T U S
BARRIER
/* set local CP0 CONFIG to make kseg0 cacheable, write-back */
mfc0 k 0 , C P 0 _ C O N F I G
ori k 0 , 0 x07
xori k 0 , 0 x04
mtc0 k 0 , C P 0 _ C O N F I G
2013-12-18 17:12:01 +04:00
mfc0 k 0 , C P 0 _ P R I D
andi k 0 , 0 x f f00
2011-11-16 05:25:45 +04:00
# if d e f i n e d ( C O N F I G _ C P U _ B M I P S 4 3 5 0 ) | | d e f i n e d ( C O N F I G _ C P U _ B M I P S 4 3 8 0 )
2013-12-18 17:12:01 +04:00
li k 1 , P R I D _ I M P _ B M I P S 4 3 X X
bne k 0 , k 1 , 2 f
2011-11-16 05:25:45 +04:00
/* initialize CPU1's local I-cache */
li k 0 , 0 x80 0 0 0 0 0 0
li k 1 , 0 x80 0 1 0 0 0 0
mtc0 z e r o , $ 2 8
mtc0 z e r o , $ 2 8 , 1
BARRIER
1 : cache I n d e x _ S t o r e _ T a g _ I , 0 ( k 0 )
addiu k 0 , 1 6
bne k 0 , k 1 , 1 b
2013-12-18 17:12:01 +04:00
b 3 f
2 :
# endif / * C O N F I G _ C P U _ B M I P S 4 3 5 0 | | C O N F I G _ C P U _ B M I P S 4 3 8 0 * /
# if d e f i n e d ( C O N F I G _ C P U _ B M I P S 5 0 0 0 )
2011-11-16 05:25:45 +04:00
/* set exception vector base */
2013-12-18 17:12:01 +04:00
li k 1 , P R I D _ I M P _ B M I P S 5 0 0 0
bne k 0 , k 1 , 3 f
2011-11-16 05:25:45 +04:00
la k 0 , e b a s e
lw k 0 , 0 ( k 0 )
mtc0 k 0 , $ 1 5 , 1
BARRIER
2013-12-18 17:12:01 +04:00
# endif / * C O N F I G _ C P U _ B M I P S 5 0 0 0 * /
3 :
2011-11-16 05:25:45 +04:00
/* jump back to kseg0 in case we need to remap the kseg1 area */
la k 0 , 1 f
jr k 0
1 :
la k 0 , b m i p s _ e n a b l e _ x k s01
jalr k 0
/* use temporary stack to set up upper memory TLB */
li s p , B M I P S _ W A R M _ R E S T A R T _ V E C
la k 0 , p l a t _ w i r e d _ t l b _ s e t u p
jalr k 0
/* switch to permanent stack and continue booting */
2013-01-22 15:59:30 +04:00
.global bmips_secondary_reentry
2011-11-16 05:25:45 +04:00
bmips_secondary_reentry :
la k 0 , b m i p s _ s m p _ b o o t _ s p
lw s p , 0 ( k 0 )
la k 0 , b m i p s _ s m p _ b o o t _ g p
lw g p , 0 ( k 0 )
la k 0 , s t a r t _ s e c o n d a r y
jr k 0
# endif / * C O N F I G _ S M P * /
.align 4
2013-01-22 15:59:30 +04:00
.global bmips_reset_nmi_vec_end
2011-11-16 05:25:45 +04:00
bmips_reset_nmi_vec_end :
END( b m i p s _ r e s e t _ n m i _ v e c )
.set pop
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* CPU1 w a r m r e s t a r t v e c t o r ( u s e d f o r s e c o n d a n d s u b s e q u e n t b o o t s ) .
* Also u s e d f o r S 2 s t a n d b y r e c o v e r y ( P M ) .
* This e n t i r e f u n c t i o n g e t s c o p i e d t o ( B M I P S _ W A R M _ R E S T A R T _ V E C )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
LEAF( b m i p s _ s m p _ i n t _ v e c )
.align 4
mfc0 k 0 , C P 0 _ S T A T U S
ori k 0 , 0 x01
xori k 0 , 0 x01
mtc0 k 0 , C P 0 _ S T A T U S
eret
.align 4
2013-01-22 15:59:30 +04:00
.global bmips_smp_int_vec_end
2011-11-16 05:25:45 +04:00
bmips_smp_int_vec_end :
END( b m i p s _ s m p _ i n t _ v e c )
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* XKS0 1 s u p p o r t
* Certain C P U s s u p p o r t e x t e n d i n g k s e g 0 t o 1 0 2 4 M B .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
LEAF( b m i p s _ e n a b l e _ x k s01 )
# if d e f i n e d ( C O N F I G _ X K S 0 1 )
2013-12-18 17:12:01 +04:00
mfc0 t 0 , C P 0 _ P R I D
andi t 2 , t 0 , 0 x f f00
2011-11-16 05:25:45 +04:00
# if d e f i n e d ( C O N F I G _ C P U _ B M I P S 4 3 8 0 )
2013-12-18 17:12:01 +04:00
li t 1 , P R I D _ I M P _ B M I P S 4 3 X X
bne t 2 , t 1 , 1 f
andi t 0 , 0 x f f
addiu t 1 , t 0 , - P R I D _ R E V _ B M I P S 4 3 8 0 _ H I
bgtz t 1 , 2 f
addiu t 0 , - P R I D _ R E V _ B M I P S 4 3 8 0 _ L O
bltz t 0 , 2 f
2011-11-16 05:25:45 +04:00
mfc0 t 0 , $ 2 2 , 3
li t 1 , 0 x1 f f0
li t 2 , ( 1 < < 1 2 ) | ( 1 < < 9 )
or t 0 , t 1
xor t 0 , t 1
or t 0 , t 2
mtc0 t 0 , $ 2 2 , 3
BARRIER
2013-12-18 17:12:01 +04:00
b 2 f
1 :
# endif / * C O N F I G _ C P U _ B M I P S 4 3 8 0 * /
# if d e f i n e d ( C O N F I G _ C P U _ B M I P S 5 0 0 0 )
li t 1 , P R I D _ I M P _ B M I P S 5 0 0 0
bne t 2 , t 1 , 2 f
2011-11-16 05:25:45 +04:00
mfc0 t 0 , $ 2 2 , 5
li t 1 , 0 x01 f f
li t 2 , ( 1 < < 8 ) | ( 1 < < 5 )
or t 0 , t 1
xor t 0 , t 1
or t 0 , t 2
mtc0 t 0 , $ 2 2 , 5
BARRIER
2013-12-18 17:12:01 +04:00
# endif / * C O N F I G _ C P U _ B M I P S 5 0 0 0 * /
2 :
2011-11-16 05:25:45 +04:00
# endif / * d e f i n e d ( C O N F I G _ X K S 0 1 ) * /
jr r a
END( b m i p s _ e n a b l e _ x k s01 )