2019-05-27 08:55:01 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2014-01-15 10:31:53 +00:00
/ *
* Copyright ( C ) 2 0 1 3 I m a g i n a t i o n T e c h n o l o g i e s
2017-10-25 17:04:33 -07:00
* Author : Paul B u r t o n < p a u l . b u r t o n @mips.com>
2014-01-15 10:31:53 +00:00
* /
# include < a s m / a d d r s p a c e . h >
# include < a s m / a s m . h >
# include < a s m / a s m - o f f s e t s . 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 >
2014-07-21 14:35:56 +01:00
# include < a s m / e v a . h >
2014-01-15 10:31:53 +00:00
# include < a s m / m i p s r e g s . h >
2014-04-14 12:04:27 +01:00
# include < a s m / m i p s m t r e g s . h >
2014-04-14 11:00:56 +01:00
# include < a s m / p m . h >
2014-01-15 10:31:53 +00:00
2016-02-03 03:15:33 +00:00
# define G C R _ C P C _ B A S E _ O F S 0 x00 8 8
2014-04-14 12:04:27 +01:00
# define G C R _ C L _ C O H E R E N C E _ O F S 0 x20 0 8
# define G C R _ C L _ I D _ O F S 0 x20 2 8
2017-06-02 14:48:55 -07:00
# define C P C _ C L _ V C _ S T O P _ O F S 0 x20 2 0
2016-02-03 03:15:33 +00:00
# define C P C _ C L _ V C _ R U N _ O F S 0 x20 2 8
2014-04-14 12:04:27 +01:00
.extern mips_cm_base
.set noreorder
2015-09-22 11:12:10 -07:00
# ifdef C O N F I G _ 6 4 B I T
# define S T A T U S _ B I T D E P S S T 0 _ K X
# else
# define S T A T U S _ B I T D E P S 0
# endif
2015-09-22 11:12:11 -07:00
# ifdef C O N F I G _ M I P S _ C P S _ N S 1 6 5 5 0
# define D U M P _ E X C E P ( n a m e ) \
PTR_ L A a0 , 8 f ; \
jal m i p s _ c p s _ b e v _ d u m p ; \
nop; \
TEXT( n a m e )
# else / * ! C O N F I G _ M I P S _ C P S _ N S 1 6 5 5 0 * /
# define D U M P _ E X C E P ( n a m e )
# endif / * ! C O N F I G _ M I P S _ C P S _ N S 1 6 5 5 0 * /
2014-04-14 12:04:27 +01:00
/ *
* Set d e s t t o n o n - z e r o i f t h e c o r e s u p p o r t s t h e M T A S E , e l s e z e r o . I f
* MT i s n o t s u p p o r t e d t h e n b r a n c h t o n o m t .
* /
.macro has_mt dest, n o m t
2015-09-22 11:12:13 -07:00
mfc0 \ d e s t , C P 0 _ C O N F I G , 1
2014-04-14 12:04:27 +01:00
bgez \ d e s t , \ n o m t
mfc0 \ d e s t , C P 0 _ C O N F I G , 2
bgez \ d e s t , \ n o m t
mfc0 \ d e s t , C P 0 _ C O N F I G , 3
andi \ d e s t , \ d e s t , M I P S _ C O N F 3 _ M T
beqz \ d e s t , \ n o m t
2015-08-05 15:42:36 -07:00
nop
2014-04-14 12:04:27 +01:00
.endm
2014-01-15 10:31:53 +00:00
2016-02-03 03:15:33 +00:00
/ *
* Set d e s t t o n o n - z e r o i f t h e c o r e s u p p o r t s M I P S r6 m u l t i t h r e a d i n g
* ( ie. V P s ) , e l s e z e r o . I f M I P S r6 m u l t i t h r e a d i n g i s n o t s u p p o r t e d t h e n
* branch t o n o m t .
* /
.macro has_vp dest, n o m t
mfc0 \ d e s t , C P 0 _ C O N F I G , 1
bgez \ d e s t , \ n o m t
mfc0 \ d e s t , C P 0 _ C O N F I G , 2
bgez \ d e s t , \ n o m t
mfc0 \ d e s t , C P 0 _ C O N F I G , 3
bgez \ d e s t , \ n o m t
mfc0 \ d e s t , C P 0 _ C O N F I G , 4
bgez \ d e s t , \ n o m t
mfc0 \ d e s t , C P 0 _ C O N F I G , 5
andi \ d e s t , \ d e s t , M I P S _ C O N F 5 _ V P
beqz \ d e s t , \ n o m t
nop
.endm
2016-02-03 03:15:31 +00:00
/* Calculate an uncached address for the CM GCRs */
.macro cmgcrb dest
.set push
.set noat
MFC0 $ 1 , C P 0 _ C M G C R B A S E
PTR_ S L L $ 1 , $ 1 , 4
PTR_ L I \ d e s t , U N C A C _ B A S E
PTR_ A D D U \ d e s t , \ d e s t , $ 1
.set pop
.endm
2014-01-15 10:31:53 +00:00
.section .text .cps - vec
.balign 0x1000
LEAF( m i p s _ c p s _ c o r e _ e n t r y )
/ *
2015-09-22 11:12:12 -07:00
* These f i r s t 4 b y t e s w i l l b e p a t c h e d b y c p s _ s m p _ s e t u p t o l o a d t h e
* CCA t o u s e i n t o r e g i s t e r s0 .
2014-01-15 10:31:53 +00:00
* /
2014-04-16 11:10:57 +01:00
.word 0
2014-01-15 10:31:53 +00:00
/* Check whether we're here due to an NMI */
mfc0 k 0 , C P 0 _ S T A T U S
and k 0 , k 0 , S T 0 _ N M I
beqz k 0 , n o t _ n m i
nop
/* This is an NMI */
2015-07-01 09:13:29 +01:00
PTR_ L A k 0 , n m i _ h a n d l e r
2014-01-15 10:31:53 +00:00
jr k 0
nop
not_nmi :
/* Setup Cause */
li t 0 , C A U S E F _ I V
mtc0 t 0 , C P 0 _ C A U S E
/* Setup Status */
2015-09-22 11:12:10 -07:00
li t 0 , S T 0 _ C U 1 | S T 0 _ C U 0 | S T 0 _ B E V | S T A T U S _ B I T D E P S
2014-01-15 10:31:53 +00:00
mtc0 t 0 , C P 0 _ S T A T U S
2016-02-03 03:15:32 +00:00
/* Skip cache & coherence setup if we're already coherent */
cmgcrb v1
lw s7 , G C R _ C L _ C O H E R E N C E _ O F S ( v1 )
bnez s7 , 1 f
nop
2016-02-03 03:15:30 +00:00
/* Initialize the L1 caches */
jal m i p s _ c p s _ c a c h e _ i n i t
2014-01-15 10:31:53 +00:00
nop
2016-02-03 03:15:32 +00:00
/* Enter the coherent domain */
li t 0 , 0 x f f
sw t 0 , G C R _ C L _ C O H E R E N C E _ O F S ( v1 )
ehb
2014-04-16 11:10:57 +01:00
/* Set Kseg0 CCA to that in s0 */
2016-02-03 03:15:32 +00:00
1 : mfc0 t 0 , C P 0 _ C O N F I G
2014-01-15 10:31:53 +00:00
ori t 0 , 0 x7
2014-04-16 11:10:57 +01:00
xori t 0 , 0 x7
or t 0 , t 0 , s0
2014-01-15 10:31:53 +00:00
mtc0 t 0 , C P 0 _ C O N F I G
ehb
/* Jump to kseg0 */
2015-07-01 09:13:29 +01:00
PTR_ L A t 0 , 1 f
2014-01-15 10:31:53 +00:00
jr t 0
nop
2014-04-14 12:04:27 +01:00
/ *
2016-02-03 03:15:32 +00:00
* We' r e u p , c a c h e d & c o h e r e n t . P e r f o r m a n y E V A i n i t i a l i z a t i o n n e c e s s a r y
* before w e a c c e s s m e m o r y .
2014-04-14 12:04:27 +01:00
* /
2016-02-03 03:15:32 +00:00
1 : eva_ i n i t
2014-07-21 14:35:56 +01:00
2016-02-03 03:15:31 +00:00
/* Retrieve boot configuration pointers */
jal m i p s _ c p s _ g e t _ b o o t c f g
nop
2016-02-03 03:15:32 +00:00
/* Skip core-level init if we started up coherent */
bnez s7 , 1 f
nop
/* Perform any further required core-level initialisation */
jal m i p s _ c p s _ c o r e _ i n i t
nop
2014-01-15 10:31:53 +00:00
/ *
2014-04-14 12:04:27 +01:00
* Boot a n y o t h e r V P E s w i t h i n t h i s c o r e t h a t s h o u l d b e o n l i n e , a n d
* deactivate t h i s V P E i f i t s h o u l d b e o f f l i n e .
2014-01-15 10:31:53 +00:00
* /
2016-02-03 03:15:31 +00:00
move a1 , t 9
2014-04-14 12:04:27 +01:00
jal m i p s _ c p s _ b o o t _ v p e s
2016-02-03 03:15:31 +00:00
move a0 , v0
2014-01-15 10:31:53 +00:00
/* Off we go! */
2016-02-03 03:15:32 +00:00
1 : PTR_ L t 1 , V P E B O O T C F G _ P C ( v1 )
2016-02-03 03:15:31 +00:00
PTR_ L g p , V P E B O O T C F G _ G P ( v1 )
PTR_ L s p , V P E B O O T C F G _ S P ( v1 )
2014-01-15 10:31:53 +00:00
jr t 1
nop
END( m i p s _ c p s _ c o r e _ e n t r y )
.org 0x200
LEAF( e x c e p _ t l b f i l l )
2015-09-22 11:12:11 -07:00
DUMP_ E X C E P ( " T L B F i l l " )
2014-01-15 10:31:53 +00:00
b .
nop
END( e x c e p _ t l b f i l l )
.org 0x280
LEAF( e x c e p _ x t l b f i l l )
2015-09-22 11:12:11 -07:00
DUMP_ E X C E P ( " X T L B F i l l " )
2014-01-15 10:31:53 +00:00
b .
nop
END( e x c e p _ x t l b f i l l )
.org 0x300
LEAF( e x c e p _ c a c h e )
2015-09-22 11:12:11 -07:00
DUMP_ E X C E P ( " C a c h e " )
2014-01-15 10:31:53 +00:00
b .
nop
END( e x c e p _ c a c h e )
.org 0x380
LEAF( e x c e p _ g e n e x )
2015-09-22 11:12:11 -07:00
DUMP_ E X C E P ( " G e n e r a l " )
2014-01-15 10:31:53 +00:00
b .
nop
END( e x c e p _ g e n e x )
.org 0x400
LEAF( e x c e p _ i n t e x )
2015-09-22 11:12:11 -07:00
DUMP_ E X C E P ( " I n t e r r u p t " )
2014-01-15 10:31:53 +00:00
b .
nop
END( e x c e p _ i n t e x )
.org 0x480
LEAF( e x c e p _ e j t a g )
2015-07-01 09:13:29 +01:00
PTR_ L A k 0 , e j t a g _ d e b u g _ h a n d l e r
2014-01-15 10:31:53 +00:00
jr k 0
nop
END( e x c e p _ e j t a g )
2014-04-14 12:04:27 +01:00
LEAF( m i p s _ c p s _ c o r e _ i n i t )
2015-08-05 15:42:38 -07:00
# ifdef C O N F I G _ M I P S _ M T _ S M P
2014-04-14 12:04:27 +01:00
/* Check that the core implements the MT ASE */
has_ m t t 0 , 3 f
.set push
2017-11-14 12:01:20 +00:00
.set MIPS_ISA_LEVEL_RAW
2014-04-14 12:04:27 +01:00
.set mt
/* Only allow 1 TC per VPE to execute... */
dmt
/* ...and for the moment only 1 VPE */
dvpe
2015-07-01 09:13:29 +01:00
PTR_ L A t 1 , 1 f
2014-04-14 12:04:27 +01:00
jr. h b t 1
nop
/* Enter VPE configuration state */
1 : mfc0 t 0 , C P 0 _ M V P C O N T R O L
ori t 0 , t 0 , M V P C O N T R O L _ V P C
mtc0 t 0 , C P 0 _ M V P C O N T R O L
/* Retrieve the number of VPEs within the core */
mfc0 t 0 , C P 0 _ M V P C O N F 0
srl t 0 , t 0 , M V P C O N F 0 _ P V P E _ S H I F T
andi t 0 , t 0 , ( M V P C O N F 0 _ P V P E > > M V P C O N F 0 _ P V P E _ S H I F T )
2015-07-01 09:13:31 +01:00
addiu t a3 , t 0 , 1
2014-04-14 12:04:27 +01:00
/* If there's only 1, we're done */
beqz t 0 , 2 f
nop
/* Loop through each VPE within this core */
2015-07-01 09:13:31 +01:00
li t a1 , 1
2014-04-14 12:04:27 +01:00
1 : /* Operate on the appropriate TC */
2015-07-01 09:13:31 +01:00
mtc0 t a1 , C P 0 _ V P E C O N T R O L
2014-04-14 12:04:27 +01:00
ehb
/* Bind TC to VPE (1:1 TC:VPE mapping) */
2015-07-01 09:13:31 +01:00
mttc0 t a1 , C P 0 _ T C B I N D
2014-04-14 12:04:27 +01:00
/* Set exclusive TC, non-active, master */
li t 0 , V P E C O N F 0 _ M V P
2015-07-01 09:13:31 +01:00
sll t 1 , t a1 , V P E C O N F 0 _ X T C _ S H I F T
2014-04-14 12:04:27 +01:00
or t 0 , t 0 , t 1
mttc0 t 0 , C P 0 _ V P E C O N F 0
/* Set TC non-active, non-allocatable */
mttc0 z e r o , C P 0 _ T C S T A T U S
/* Set TC halted */
li t 0 , T C H A L T _ H
mttc0 t 0 , C P 0 _ T C H A L T
/* Next VPE */
2015-07-01 09:13:31 +01:00
addiu t a1 , t a1 , 1
slt t 0 , t a1 , t a3
2014-04-14 12:04:27 +01:00
bnez t 0 , 1 b
nop
/* Leave VPE configuration state */
2 : mfc0 t 0 , C P 0 _ M V P C O N T R O L
xori t 0 , t 0 , M V P C O N T R O L _ V P C
mtc0 t 0 , C P 0 _ M V P C O N T R O L
3 : .set p o p
# endif
jr r a
nop
END( m i p s _ c p s _ c o r e _ i n i t )
2016-02-03 03:15:31 +00:00
/ * *
* mips_ c p s _ g e t _ b o o t c f g ( ) - r e t r i e v e b o o t c o n f i g u r a t i o n p o i n t e r s
*
* Returns : pointer t o s t r u c t c o r e _ b o o t _ c o n f i g i n v0 , p o i n t e r t o
* struct v p e _ b o o t _ c o n f i g i n v1 , V P E I D i n t 9
* /
LEAF( m i p s _ c p s _ g e t _ b o o t c f g )
2014-04-14 12:04:27 +01:00
/* Calculate a pointer to this cores struct core_boot_config */
2016-02-03 03:15:31 +00:00
cmgcrb t 0
2015-08-05 15:42:35 -07:00
lw t 0 , G C R _ C L _ I D _ O F S ( t 0 )
2014-04-14 12:04:27 +01:00
li t 1 , C O R E B O O T C F G _ S I Z E
mul t 0 , t 0 , t 1
2015-07-01 09:13:29 +01:00
PTR_ L A t 1 , m i p s _ c p s _ c o r e _ b o o t c f g
2015-07-01 09:13:33 +01:00
PTR_ L t 1 , 0 ( t 1 )
2016-02-03 03:15:31 +00:00
PTR_ A D D U v0 , t 0 , t 1
2014-04-14 12:04:27 +01:00
/* Calculate this VPEs ID. If the core doesn't support MT use 0 */
2015-08-05 15:42:36 -07:00
li t 9 , 0
2016-02-03 03:15:33 +00:00
# if d e f i n e d ( C O N F I G _ C P U _ M I P S R 6 )
has_ v p t a2 , 1 f
/ *
* Assume n o n - c o n t i g u o u s n u m b e r i n g . P e r h a p s s o m e d a y w e ' l l n e e d
* to h a n d l e c o n t i g u o u s V P n u m b e r i n g , b u t n o s u c h s y s t e m s y e t
* exist.
* /
2017-08-12 19:49:34 -07:00
mfc0 t 9 , C P 0 _ G L O B A L N U M B E R
andi t 9 , t 9 , M I P S _ G L O B A L N U M B E R _ V P
2016-02-03 03:15:33 +00:00
# elif d e f i n e d ( C O N F I G _ M I P S _ M T _ S M P )
2015-07-01 09:13:31 +01:00
has_ m t t a2 , 1 f
2014-04-14 12:04:27 +01:00
/* Find the number of VPEs present in the core */
mfc0 t 1 , C P 0 _ M V P C O N F 0
srl t 1 , t 1 , M V P C O N F 0 _ P V P E _ S H I F T
andi t 1 , t 1 , M V P C O N F 0 _ P V P E > > M V P C O N F 0 _ P V P E _ S H I F T
2014-11-24 14:40:11 +00:00
addiu t 1 , t 1 , 1
2014-04-14 12:04:27 +01:00
/* Calculate a mask for the VPE ID from EBase.CPUNum */
clz t 1 , t 1
li t 2 , 3 1
subu t 1 , t 2 , t 1
li t 2 , 1
sll t 1 , t 2 , t 1
addiu t 1 , t 1 , - 1
/* Retrieve the VPE ID from EBase.CPUNum */
mfc0 t 9 , $ 1 5 , 1
and t 9 , t 9 , t 1
2015-08-05 15:42:37 -07:00
# endif
2014-04-14 12:04:27 +01:00
1 : /* Calculate a pointer to this VPEs struct vpe_boot_config */
li t 1 , V P E B O O T C F G _ S I Z E
2016-02-03 03:15:31 +00:00
mul v1 , t 9 , t 1
PTR_ L t a3 , C O R E B O O T C F G _ V P E C O N F I G ( v0 )
PTR_ A D D U v1 , v1 , t a3
2014-04-14 12:04:27 +01:00
jr r a
nop
2016-02-03 03:15:31 +00:00
END( m i p s _ c p s _ g e t _ b o o t c f g )
LEAF( m i p s _ c p s _ b o o t _ v p e s )
2017-03-21 14:39:19 +00:00
lw t a2 , C O R E B O O T C F G _ V P E M A S K ( a0 )
2016-02-03 03:15:31 +00:00
PTR_ L t a3 , C O R E B O O T C F G _ V P E C O N F I G ( a0 )
2016-02-03 03:15:33 +00:00
# if d e f i n e d ( C O N F I G _ C P U _ M I P S R 6 )
has_ v p t 0 , 5 f
/* Find base address of CPC */
cmgcrb t 3
PTR_ L t 1 , G C R _ C P C _ B A S E _ O F S ( t 3 )
PTR_ L I t 2 , ~ 0 x7 f f f
and t 1 , t 1 , t 2
PTR_ L I t 2 , U N C A C _ B A S E
PTR_ A D D t 1 , t 1 , t 2
2017-06-02 14:48:55 -07:00
/* Start any other VPs that ought to be running */
2016-02-03 03:15:33 +00:00
PTR_ S t a2 , C P C _ C L _ V C _ R U N _ O F S ( t 1 )
2017-06-02 14:48:55 -07:00
/* Ensure this VP stops running if it shouldn't be */
not t a2
PTR_ S t a2 , C P C _ C L _ V C _ S T O P _ O F S ( t 1 )
2016-02-03 03:15:33 +00:00
ehb
# elif d e f i n e d ( C O N F I G _ M I P S _ M T )
2014-04-14 12:04:27 +01:00
2016-02-03 03:15:31 +00:00
/* If the core doesn't support MT then return */
has_ m t t 0 , 5 f
/* Enter VPE configuration state */
2018-02-02 14:36:40 +00:00
.set push
.set MIPS_ISA_LEVEL_RAW
.set mt
2014-04-14 12:04:27 +01:00
dvpe
2018-02-02 14:36:40 +00:00
.set pop
2015-07-01 09:13:29 +01:00
PTR_ L A t 1 , 1 f
2014-04-14 12:04:27 +01:00
jr. h b t 1
nop
1 : mfc0 t 1 , C P 0 _ M V P C O N T R O L
ori t 1 , t 1 , M V P C O N T R O L _ V P C
mtc0 t 1 , C P 0 _ M V P C O N T R O L
ehb
/* Loop through each VPE */
2015-07-01 09:13:31 +01:00
move t 8 , t a2
li t a1 , 0
2014-04-14 12:04:27 +01:00
/* Check whether the VPE should be running. If not, skip it */
2015-07-01 09:13:31 +01:00
1 : andi t 0 , t a2 , 1
2014-04-14 12:04:27 +01:00
beqz t 0 , 2 f
nop
/* Operate on the appropriate TC */
mfc0 t 0 , C P 0 _ V P E C O N T R O L
ori t 0 , t 0 , V P E C O N T R O L _ T A R G T C
xori t 0 , t 0 , V P E C O N T R O L _ T A R G T C
2015-07-01 09:13:31 +01:00
or t 0 , t 0 , t a1
2014-04-14 12:04:27 +01:00
mtc0 t 0 , C P 0 _ V P E C O N T R O L
ehb
2018-02-02 14:36:40 +00:00
.set push
.set MIPS_ISA_LEVEL_RAW
.set mt
2014-04-14 12:04:27 +01:00
/* Skip the VPE if its TC is not halted */
mftc0 t 0 , C P 0 _ T C H A L T
beqz t 0 , 2 f
nop
/* Calculate a pointer to the VPEs struct vpe_boot_config */
li t 0 , V P E B O O T C F G _ S I Z E
2015-07-01 09:13:31 +01:00
mul t 0 , t 0 , t a1
addu t 0 , t 0 , t a3
2014-04-14 12:04:27 +01:00
/* Set the TC restart PC */
lw t 1 , V P E B O O T C F G _ P C ( t 0 )
mttc0 t 1 , C P 0 _ T C R E S T A R T
/* Set the TC stack pointer */
lw t 1 , V P E B O O T C F G _ S P ( t 0 )
mttgpr t 1 , s p
/* Set the TC global pointer */
lw t 1 , V P E B O O T C F G _ G P ( t 0 )
mttgpr t 1 , g p
/* Copy config from this VPE */
mfc0 t 0 , C P 0 _ C O N F I G
mttc0 t 0 , C P 0 _ C O N F I G
2016-05-18 17:12:36 +01:00
/ *
* Copy t h e E V A c o n f i g f r o m t h i s V P E i f t h e C P U s u p p o r t s i t .
* CONFIG3 m u s t e x i s t t o b e r u n n i n g M T s t a r t u p - j u s t r e a d i t .
* /
mfc0 t 0 , C P 0 _ C O N F I G , 3
and t 0 , t 0 , M I P S _ C O N F 3 _ S C
beqz t 0 , 3 f
nop
mfc0 t 0 , C P 0 _ S E G C T L 0
mttc0 t 0 , C P 0 _ S E G C T L 0
mfc0 t 0 , C P 0 _ S E G C T L 1
mttc0 t 0 , C P 0 _ S E G C T L 1
mfc0 t 0 , C P 0 _ S E G C T L 2
mttc0 t 0 , C P 0 _ S E G C T L 2
3 :
2014-04-14 12:04:27 +01:00
/* Ensure no software interrupts are pending */
mttc0 z e r o , C P 0 _ C A U S E
mttc0 z e r o , C P 0 _ S T A T U S
/* Set TC active, not interrupt exempt */
mftc0 t 0 , C P 0 _ T C S T A T U S
li t 1 , ~ T C S T A T U S _ I X M T
and t 0 , t 0 , t 1
ori t 0 , t 0 , T C S T A T U S _ A
mttc0 t 0 , C P 0 _ T C S T A T U S
/* Clear the TC halt bit */
mttc0 z e r o , C P 0 _ T C H A L T
/* Set VPE active */
mftc0 t 0 , C P 0 _ V P E C O N F 0
ori t 0 , t 0 , V P E C O N F 0 _ V P A
mttc0 t 0 , C P 0 _ V P E C O N F 0
/* Next VPE */
2015-07-01 09:13:31 +01:00
2 : srl t a2 , t a2 , 1
addiu t a1 , t a1 , 1
bnez t a2 , 1 b
2014-04-14 12:04:27 +01:00
nop
/* Leave VPE configuration state */
mfc0 t 1 , C P 0 _ M V P C O N T R O L
xori t 1 , t 1 , M V P C O N T R O L _ V P C
mtc0 t 1 , C P 0 _ M V P C O N T R O L
ehb
evpe
2018-02-02 14:36:40 +00:00
.set pop
2014-04-14 12:04:27 +01:00
/* Check whether this VPE is meant to be running */
li t 0 , 1
2016-02-03 03:15:31 +00:00
sll t 0 , t 0 , a1
2014-04-14 12:04:27 +01:00
and t 0 , t 0 , t 8
bnez t 0 , 2 f
nop
/* This VPE should be offline, halt the TC */
li t 0 , T C H A L T _ H
mtc0 t 0 , C P 0 _ T C H A L T
2015-07-01 09:13:29 +01:00
PTR_ L A t 0 , 1 f
2014-04-14 12:04:27 +01:00
1 : jr. h b t 0
nop
2018-02-02 14:36:40 +00:00
2 :
2014-04-14 12:04:27 +01:00
2015-08-05 15:42:38 -07:00
# endif / * C O N F I G _ M I P S _ M T _ S M P * /
2014-04-14 12:04:27 +01:00
/* Return */
2016-02-03 03:15:31 +00:00
5 : jr r a
2014-04-14 12:04:27 +01:00
nop
END( m i p s _ c p s _ b o o t _ v p e s )
2014-04-14 11:00:56 +01:00
2016-02-03 03:15:30 +00:00
LEAF( m i p s _ c p s _ c a c h e _ i n i t )
/ *
* Clear t h e b i t s u s e d t o i n d e x t h e c a c h e s . N o t e t h a t t h e a r c h i t e c t u r e
* dictates t h a t w r i t i n g t o a n y o f T a g L o o r T a g H i s e l e c t s 0 o r 2 s h o u l d
* be v a l i d f o r a l l M I P S 3 2 C P U s , e v e n t h o s e f o r w h i c h s a i d w r i t e s a r e
* unnecessary.
* /
mtc0 z e r o , C P 0 _ T A G L O , 0
mtc0 z e r o , C P 0 _ T A G H I , 0
mtc0 z e r o , C P 0 _ T A G L O , 2
mtc0 z e r o , C P 0 _ T A G H I , 2
ehb
/* Primary cache configuration is indicated by Config1 */
mfc0 v0 , C P 0 _ C O N F I G , 1
/* Detect I-cache line size */
_ EXT t 0 , v0 , M I P S _ C O N F 1 _ I L _ S H F , M I P S _ C O N F 1 _ I L _ S Z
beqz t 0 , i c a c h e _ d o n e
li t 1 , 2
sllv t 0 , t 1 , t 0
/* Detect I-cache size */
_ EXT t 1 , v0 , M I P S _ C O N F 1 _ I S _ S H F , M I P S _ C O N F 1 _ I S _ S Z
xori t 2 , t 1 , 0 x7
beqz t 2 , 1 f
li t 3 , 3 2
addiu t 1 , t 1 , 1
sllv t 1 , t 3 , t 1
1 : /* At this point t1 == I-cache sets per way */
_ EXT t 2 , v0 , M I P S _ C O N F 1 _ I A _ S H F , M I P S _ C O N F 1 _ I A _ S Z
addiu t 2 , t 2 , 1
mul t 1 , t 1 , t 0
mul t 1 , t 1 , t 2
li a0 , C K S E G 0
PTR_ A D D a1 , a0 , t 1
1 : cache I n d e x _ S t o r e _ T a g _ I , 0 ( a0 )
PTR_ A D D a0 , a0 , t 0
bne a0 , a1 , 1 b
nop
icache_done :
/* Detect D-cache line size */
_ EXT t 0 , v0 , M I P S _ C O N F 1 _ D L _ S H F , M I P S _ C O N F 1 _ D L _ S Z
beqz t 0 , d c a c h e _ d o n e
li t 1 , 2
sllv t 0 , t 1 , t 0
/* Detect D-cache size */
_ EXT t 1 , v0 , M I P S _ C O N F 1 _ D S _ S H F , M I P S _ C O N F 1 _ D S _ S Z
xori t 2 , t 1 , 0 x7
beqz t 2 , 1 f
li t 3 , 3 2
addiu t 1 , t 1 , 1
sllv t 1 , t 3 , t 1
1 : /* At this point t1 == D-cache sets per way */
_ EXT t 2 , v0 , M I P S _ C O N F 1 _ D A _ S H F , M I P S _ C O N F 1 _ D A _ S Z
addiu t 2 , t 2 , 1
mul t 1 , t 1 , t 0
mul t 1 , t 1 , t 2
li a0 , C K S E G 0
PTR_ A D D U a1 , a0 , t 1
PTR_ S U B U a1 , a1 , t 0
1 : cache I n d e x _ S t o r e _ T a g _ D , 0 ( a0 )
bne a0 , a1 , 1 b
PTR_ A D D a0 , a0 , t 0
dcache_done :
jr r a
nop
END( m i p s _ c p s _ c a c h e _ i n i t )
2014-04-14 11:00:56 +01:00
# if d e f i n e d ( C O N F I G _ M I P S _ C P S _ P M ) & & d e f i n e d ( C O N F I G _ C P U _ P M )
/* Calculate a pointer to this CPUs struct mips_static_suspend_state */
.macro psstate dest
.set push
.set noat
lw $ 1 , T I _ C P U ( g p )
sll $ 1 , $ 1 , L O N G L O G
2015-07-01 09:13:29 +01:00
PTR_ L A \ d e s t , _ _ p e r _ c p u _ o f f s e t
2014-04-14 11:00:56 +01:00
addu $ 1 , $ 1 , \ d e s t
lw $ 1 , 0 ( $ 1 )
2015-07-01 09:13:29 +01:00
PTR_ L A \ d e s t , c p s _ c p u _ s t a t e
2014-04-14 11:00:56 +01:00
addu \ d e s t , \ d e s t , $ 1
.set pop
.endm
LEAF( m i p s _ c p s _ p m _ s a v e )
/* Save CPU state */
SUSPEND_ S A V E _ R E G S
psstate t 1
SUSPEND_ S A V E _ S T A T I C
jr v0
nop
END( m i p s _ c p s _ p m _ s a v e )
LEAF( m i p s _ c p s _ p m _ r e s t o r e )
/* Restore CPU state */
psstate t 1
RESUME_ R E S T O R E _ S T A T I C
RESUME_ R E S T O R E _ R E G S _ R E T U R N
END( m i p s _ c p s _ p m _ r e s t o r e )
# endif / * C O N F I G _ M I P S _ C P S _ P M & & C O N F I G _ C P U _ P M * /