2022-02-10 11:19:42 +05:30
/* SPDX-License-Identifier: GPL-2.0-only */
/ *
* Copyright ( c ) 2 0 2 1 W e s t e r n D i g i t a l C o r p o r a t i o n o r i t s a f f i l i a t e s .
* Copyright ( c ) 2 0 2 2 V e n t a n a M i c r o S y s t e m s I n c .
* /
# include < l i n u x / l i n k a g 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 / c s r . h >
2022-04-19 20:02:16 -07:00
# include < a s m / x i p _ f i x u p . h >
2022-02-10 11:19:42 +05:30
.text
.altmacro
.option norelax
ENTRY( _ _ c p u _ s u s p e n d _ e n t e r )
/* Save registers (except A0 and T0-T6) */
REG_ S r a , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ R A ) ( a0 )
REG_ S s p , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S P ) ( a0 )
REG_ S g p , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ G P ) ( a0 )
REG_ S t p , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ T P ) ( a0 )
REG_ S s0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 0 ) ( a0 )
REG_ S s1 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 1 ) ( a0 )
REG_ S a1 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 1 ) ( a0 )
REG_ S a2 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 2 ) ( a0 )
REG_ S a3 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 3 ) ( a0 )
REG_ S a4 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 4 ) ( a0 )
REG_ S a5 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 5 ) ( a0 )
REG_ S a6 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 6 ) ( a0 )
REG_ S a7 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 7 ) ( a0 )
REG_ S s2 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 2 ) ( a0 )
REG_ S s3 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 3 ) ( a0 )
REG_ S s4 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 4 ) ( a0 )
REG_ S s5 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 5 ) ( a0 )
REG_ S s6 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 6 ) ( a0 )
REG_ S s7 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 7 ) ( a0 )
REG_ S s8 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 8 ) ( a0 )
REG_ S s9 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 9 ) ( a0 )
REG_ S s10 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 1 0 ) ( a0 )
REG_ S s11 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 1 1 ) ( a0 )
/* Save CSRs */
csrr t 0 , C S R _ E P C
REG_ S t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ E P C ) ( a0 )
csrr t 0 , C S R _ S T A T U S
REG_ S t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S T A T U S ) ( a0 )
csrr t 0 , C S R _ T V A L
REG_ S t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ B A D A D D R ) ( a0 )
csrr t 0 , C S R _ C A U S E
REG_ S t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ C A U S E ) ( a0 )
/* Return non-zero value */
li a0 , 1
/* Return to C code */
ret
END( _ _ c p u _ s u s p e n d _ e n t e r )
ENTRY( _ _ c p u _ r e s u m e _ e n t e r )
/* Load the global pointer */
.option push
.option norelax
la g p , _ _ g l o b a l _ p o i n t e r $
.option pop
# ifdef C O N F I G _ M M U
/* Save A0 and A1 */
add t 0 , a0 , z e r o
add t 1 , a1 , z e r o
/* Enable MMU */
la a0 , s w a p p e r _ p g _ d i r
XIP_ F I X U P _ O F F S E T a0
call r e l o c a t e _ e n a b l e _ m m u
/* Restore A0 and A1 */
add a0 , t 0 , z e r o
add a1 , t 1 , z e r o
# endif
/* Make A0 point to suspend context */
add a0 , a1 , z e r o
/* Restore CSRs */
REG_ L t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ E P C ) ( a0 )
csrw C S R _ E P C , t 0
REG_ L t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S T A T U S ) ( a0 )
csrw C S R _ S T A T U S , t 0
REG_ L t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ B A D A D D R ) ( a0 )
csrw C S R _ T V A L , t 0
REG_ L t 0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ C A U S E ) ( a0 )
csrw C S R _ C A U S E , t 0
/* Restore registers (except A0 and T0-T6) */
REG_ L r a , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ R A ) ( a0 )
REG_ L s p , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S P ) ( a0 )
REG_ L g p , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ G P ) ( a0 )
REG_ L t p , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ T P ) ( a0 )
REG_ L s0 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 0 ) ( a0 )
REG_ L s1 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 1 ) ( a0 )
REG_ L a1 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 1 ) ( a0 )
REG_ L a2 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 2 ) ( a0 )
REG_ L a3 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 3 ) ( a0 )
REG_ L a4 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 4 ) ( a0 )
REG_ L a5 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 5 ) ( a0 )
REG_ L a6 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 6 ) ( a0 )
REG_ L a7 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ A 7 ) ( a0 )
REG_ L s2 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 2 ) ( a0 )
REG_ L s3 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 3 ) ( a0 )
REG_ L s4 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 4 ) ( a0 )
REG_ L s5 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 5 ) ( a0 )
REG_ L s6 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 6 ) ( a0 )
REG_ L s7 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 7 ) ( a0 )
REG_ L s8 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 8 ) ( a0 )
REG_ L s9 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 9 ) ( a0 )
REG_ L s10 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 1 0 ) ( a0 )
REG_ L s11 , ( S U S P E N D _ C O N T E X T _ R E G S + P T _ S 1 1 ) ( a0 )
/* Return zero value */
add a0 , z e r o , z e r o
/* Return to C code */
ret
END( _ _ c p u _ r e s u m e _ e n t e r )