2018-09-05 14:25:08 +08:00
/* SPDX-License-Identifier: GPL-2.0 */
/ / Copyright ( C ) 2 0 1 8 H a n g z h o u C - S K Y M i c r o s y s t e m s c o . ,l t d .
# include < l i n u x / l i n k a g e . h >
# include < a b i / e n t r y . h >
# include < a b i / p g t a b l e - b i t s . h >
# include < a s m / e r r n o . h >
# include < a s m / s e t u p . h >
# include < a s m / u n i s t d . h >
# include < a s m / a s m - o f f s e t s . h >
# include < l i n u x / t h r e a d s . h >
# include < a s m / s e t u p . h >
# include < a s m / p a g e . h >
# include < a s m / t h r e a d _ i n f o . h >
# define P T E _ I N D X _ M S K 0 x f f c
# define P T E _ I N D X _ S H I F T 1 0
# define _ P G D I R _ S H I F T 2 2
.macro tlbop_begin name, v a l 0 , v a l 1 , v a l 2
ENTRY( c s k y _ \ n a m e )
mtcr a3 , s s2
mtcr r6 , s s3
mtcr a2 , s s4
RD_ P G D R r6
RD_ M E H a3
# ifdef C O N F I G _ C P U _ H A S _ T L B I
tlbi. v a a s a3
sync. i s
btsti a3 , 3 1
bf 1 f
RD_ P G D R _ K r6
1 :
# else
bgeni a2 , 3 1
WR_ M C I R a2
bgeni a2 , 2 5
WR_ M C I R a2
# endif
bclri r6 , 0
lrw a2 , P H Y S _ O F F S E T
subu r6 , a2
bseti r6 , 3 1
mov a2 , a3
lsri a2 , _ P G D I R _ S H I F T
lsli a2 , 2
addu r6 , a2
ldw r6 , ( r6 )
lrw a2 , P H Y S _ O F F S E T
subu r6 , a2
bseti r6 , 3 1
lsri a3 , P T E _ I N D X _ S H I F T
lrw a2 , P T E _ I N D X _ M S K
and a3 , a2
addu r6 , a3
ldw a3 , ( r6 )
movi a2 , ( _ P A G E _ P R E S E N T | \ v a l 0 )
and a3 , a2
cmpne a3 , a2
bt \ n a m e
/* First read/write the page, just update the flags */
ldw a3 , ( r6 )
bgeni a2 , P A G E _ V A L I D _ B I T
bseti a2 , P A G E _ A C C E S S E D _ B I T
bseti a2 , \ v a l 1
bseti a2 , \ v a l 2
or a3 , a2
stw a3 , ( r6 )
/* Some cpu tlb-hardrefill bypass the cache */
# ifdef C O N F I G _ C P U _ N E E D _ T L B S Y N C
movi a2 , 0 x22
bseti a2 , 6
mtcr r6 , c r22
mtcr a2 , c r17
sync
# endif
mfcr a3 , s s2
mfcr r6 , s s3
mfcr a2 , s s4
rte
\ name :
mfcr a3 , s s2
mfcr r6 , s s3
mfcr a2 , s s4
SAVE_ A L L E P C _ K E E P
.endm
.macro tlbop_end is_ w r i t e
RD_ M E H a2
psrset e e , i e
mov a0 , s p
movi a1 , \ i s _ w r i t e
jbsr d o _ p a g e _ f a u l t
movi r11 _ s i g , 0 / * r11 = 0 , N o t a s y s c a l l . * /
jmpi r e t _ f r o m _ e x c e p t i o n
.endm
.text
tlbop_ b e g i n t l b i n v a l i d l , _ P A G E _ R E A D , P A G E _ V A L I D _ B I T , P A G E _ A C C E S S E D _ B I T
tlbop_ e n d 0
tlbop_ b e g i n t l b i n v a l i d s , _ P A G E _ W R I T E , P A G E _ D I R T Y _ B I T , P A G E _ M O D I F I E D _ B I T
tlbop_ e n d 1
tlbop_ b e g i n t l b m o d i f i e d , _ P A G E _ W R I T E , P A G E _ D I R T Y _ B I T , P A G E _ M O D I F I E D _ B I T
# ifndef C O N F I G _ C P U _ H A S _ L D S T E X
jbsr c s k y _ c m p x c h g _ f i x u p
# endif
tlbop_ e n d 1
ENTRY( c s k y _ s y s t e m c a l l )
SAVE_ A L L E P C _ I N C R E A S E
psrset e e , i e
lrw r11 , _ _ N R _ s y s c a l l s
cmphs s y s c a l l i d , r11 / * C h e c k n r o f s y s c a l l * /
bt r e t _ f r o m _ e x c e p t i o n
lrw r13 , s y s _ c a l l _ t a b l e
ixw r13 , s y s c a l l i d
ldw r11 , ( r13 )
cmpnei r11 , 0
bf r e t _ f r o m _ e x c e p t i o n
mov r9 , s p
bmaski r10 , T H R E A D _ S H I F T
andn r9 , r10
ldw r8 , ( r9 , T I N F O _ F L A G S )
btsti r8 , T I F _ S Y S C A L L _ T R A C E
bt 1 f
# if d e f i n e d ( _ _ C S K Y A B I V 2 _ _ )
subi s p , 8
stw r5 , ( s p , 0 x4 )
stw r4 , ( s p , 0 x0 )
jsr r11 / * D o s y s t e m c a l l * /
addi s p , 8
# else
jsr r11
# endif
stw a0 , ( s p , L S A V E _ A 0 ) / * S a v e r e t u r n v a l u e * /
jmpi r e t _ f r o m _ e x c e p t i o n
1 :
movi a0 , 0 / * e n t e r s y s t e m c a l l * /
mov a1 , s p / * s p = p t _ r e g s p o i n t e r * /
jbsr s y s c a l l _ t r a c e
/* Prepare args before do system call */
ldw a0 , ( s p , L S A V E _ A 0 )
ldw a1 , ( s p , L S A V E _ A 1 )
ldw a2 , ( s p , L S A V E _ A 2 )
ldw a3 , ( s p , L S A V E _ A 3 )
# if d e f i n e d ( _ _ C S K Y A B I V 2 _ _ )
subi s p , 8
stw r5 , ( s p , 0 x4 )
stw r4 , ( s p , 0 x0 )
# else
ldw r6 , ( s p , L S A V E _ A 4 )
ldw r7 , ( s p , L S A V E _ A 5 )
# endif
jsr r11 / * D o s y s t e m c a l l * /
# if d e f i n e d ( _ _ C S K Y A B I V 2 _ _ )
addi s p , 8
# endif
stw a0 , ( s p , L S A V E _ A 0 ) / * S a v e r e t u r n v a l u e * /
2018-12-09 13:18:15 +08:00
movi a0 , 1 / * l e a v e s y s t e m c a l l * /
mov a1 , s p / * r i g h t n o w , s p - - > p t _ r e g s * /
jbsr s y s c a l l _ t r a c e
br r e t _ f r o m _ e x c e p t i o n
2018-09-05 14:25:08 +08:00
ENTRY( r e t _ f r o m _ k e r n e l _ t h r e a d )
jbsr s c h e d u l e _ t a i l
mov a0 , r8
jsr r9
jbsr r e t _ f r o m _ e x c e p t i o n
ENTRY( r e t _ f r o m _ f o r k )
jbsr s c h e d u l e _ t a i l
mov r9 , s p
bmaski r10 , T H R E A D _ S H I F T
andn r9 , r10
ldw r8 , ( r9 , T I N F O _ F L A G S )
movi r11 _ s i g , 1
btsti r8 , T I F _ S Y S C A L L _ T R A C E
bf 3 f
movi a0 , 1
mov a1 , s p / * s p = p t _ r e g s p o i n t e r * /
jbsr s y s c a l l _ t r a c e
3 :
jbsr r e t _ f r o m _ e x c e p t i o n
ret_from_exception :
ld s y s c a l l i d , ( s p , L S A V E _ P S R )
btsti s y s c a l l i d , 3 1
bt 1 f
/ *
* Load a d d r e s s o f c u r r e n t - > t h r e a d _ i n f o , T h e n g e t a d d r e s s o f t a s k _ s t r u c t
* Get t a s k _ n e e d r e s h e d i n t a s k _ s t r u c t
* /
mov r9 , s p
bmaski r10 , T H R E A D _ S H I F T
andn r9 , r10
resume_userspace :
ldw r8 , ( r9 , T I N F O _ F L A G S )
andi r8 , ( _ T I F _ S I G P E N D I N G | _ T I F _ N O T I F Y _ R E S U M E | _ T I F _ N E E D _ R E S C H E D )
cmpnei r8 , 0
bt e x i t _ w o r k
1 : RESTORE_ A L L
exit_work :
btsti r8 , T I F _ N E E D _ R E S C H E D
bt w o r k _ r e s c h e d
/* If thread_info->flag is empty, RESTORE_ALL */
cmpnei r8 , 0
bf 1 b
mov a1 , s p
mov a0 , r8
mov a2 , r11 _ s i g / * s y s c a l l ? * /
btsti r8 , T I F _ S I G P E N D I N G / * d e l i v e r i n g a s i g n a l ? * /
/* prevent further restarts(set r11 = 0) */
clrt r11 _ s i g
jbsr d o _ n o t i f y _ r e s u m e / * d o s i g n a l s * /
br r e s u m e _ u s e r s p a c e
work_resched :
lrw s y s c a l l i d , r e t _ f r o m _ e x c e p t i o n
mov r15 , s y s c a l l i d / * R e t u r n a d d r e s s i n l i n k * /
jmpi s c h e d u l e
ENTRY( s y s _ r t _ s i g r e t u r n )
movi r11 _ s i g , 0
jmpi d o _ r t _ s i g r e t u r n
ENTRY( c s k y _ t r a p )
SAVE_ A L L E P C _ K E E P
psrset e e
movi r11 _ s i g , 0 / * r11 = 0 , N o t a s y s c a l l . * /
mov a0 , s p / * P u s h S t a c k p o i n t e r a r g * /
jbsr t r a p _ c / * C a l l C - l e v e l t r a p h a n d l e r * /
jmpi r e t _ f r o m _ e x c e p t i o n
/ *
* Prototype f r o m l i b c f o r a b i v1 :
* register u n s i g n e d i n t _ _ r e s u l t a s m ( " a0 " ) ;
* asm( " t r a p 3 " : " =r " ( _ _ r e s u l t ) : : ) ;
* /
ENTRY( c s k y _ g e t _ t l s )
USPTOKSP
/* increase epc for continue */
mfcr a0 , e p c
INCTRAP a0
mtcr a0 , e p c
/* get current task thread_info with kernel 8K stack */
bmaski a0 , T H R E A D _ S H I F T
not a0
subi s p , 1
and a0 , s p
addi s p , 1
/* get tls */
ldw a0 , ( a0 , T I N F O _ T P _ V A L U E )
KSPTOUSP
rte
ENTRY( c s k y _ i r q )
SAVE_ A L L E P C _ K E E P
psrset e e
movi r11 _ s i g , 0 / * r11 = 0 , N o t a s y s c a l l . * /
# ifdef C O N F I G _ P R E E M P T
mov r9 , s p / * G e t c u r r e n t s t a c k p o i n t e r * /
bmaski r10 , T H R E A D _ S H I F T
andn r9 , r10 / * G e t t h r e a d _ i n f o * /
/ *
* Get t a s k _ s t r u c t - > s t a c k . p r e e m p t _ c o u n t f o r c u r r e n t ,
* and i n c r e a s e 1 .
* /
ldw r8 , ( r9 , T I N F O _ P R E E M P T )
addi r8 , 1
stw r8 , ( r9 , T I N F O _ P R E E M P T )
# endif
mov a0 , s p
jbsr c s k y _ d o _ I R Q
# ifdef C O N F I G _ P R E E M P T
subi r8 , 1
stw r8 , ( r9 , T I N F O _ P R E E M P T )
cmpnei r8 , 0
bt 2 f
ldw r8 , ( r9 , T I N F O _ F L A G S )
btsti r8 , T I F _ N E E D _ R E S C H E D
bf 2 f
1 :
jbsr p r e e m p t _ s c h e d u l e _ i r q / * i r q e n / d i s a b l e i s d o n e i n s i d e * /
ldw r7 , ( r9 , T I N F O _ F L A G S ) / * g e t n e w t a s k s T I _ F L A G S * /
btsti r7 , T I F _ N E E D _ R E S C H E D
bt 1 b / * g o a g a i n * /
# endif
2 :
jmpi r e t _ f r o m _ e x c e p t i o n
/ *
* a0 = p r e v t a s k _ s t r u c t *
* a1 = n e x t t a s k _ s t r u c t *
* a0 = r e t u r n n e x t
* /
ENTRY( _ _ s w i t c h _ t o )
lrw a3 , T A S K _ T H R E A D
addu a3 , a0
mfcr a2 , p s r / * S a v e P S R v a l u e * /
stw a2 , ( a3 , T H R E A D _ S R ) / * S a v e P S R i n t a s k s t r u c t * /
bclri a2 , 6 / * D i s a b l e i n t e r r u p t s * /
mtcr a2 , p s r
SAVE_ S W I T C H _ S T A C K
stw s p , ( a3 , T H R E A D _ K S P )
/* Set up next process to run */
lrw a3 , T A S K _ T H R E A D
addu a3 , a1
ldw s p , ( a3 , T H R E A D _ K S P ) / * S e t n e x t k e r n e l s p * /
ldw a2 , ( a3 , T H R E A D _ S R ) / * S e t n e x t P S R * /
mtcr a2 , p s r
# if d e f i n e d ( _ _ C S K Y A B I V 2 _ _ )
addi r7 , a1 , T A S K _ T H R E A D _ I N F O
ldw t l s , ( r7 , T I N F O _ T P _ V A L U E )
# endif
RESTORE_ S W I T C H _ S T A C K
rts
ENDPROC( _ _ s w i t c h _ t o )