2019-05-27 09:55:21 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2016-01-04 17:44:32 +03:00
/ *
* Copyright ( c ) 2 0 1 5 , L i n a r o L i m i t e d
* /
# include < l i n u x / l i n k a g e . h >
2017-02-01 20:28:28 +03:00
# include < l i n u x / a r m - s m c c c . h >
2018-12-07 21:08:18 +03:00
2016-01-04 17:44:32 +03:00
# include < a s m / a s m - o f f s e t s . h >
2018-12-07 21:08:18 +03:00
# include < a s m / a s s e m b l e r . h >
2021-06-03 21:41:18 +03:00
# include < a s m / t h r e a d _ i n f o . h >
/ *
* If w e h a v e S M C C C v1 . 3 a n d ( a s i s l i k e l y ) n o S V E s t a t e i n
* the r e g i s t e r s t h e n s e t t h e S M C C C h i n t b i t t o s a y t h e r e ' s n o
* need t o p r e s e r v e i t . D o t h i s b y d i r e c t l y a d j u s t i n g t h e S M C C C
* function v a l u e w h i c h i s a l r e a d y s t o r e d i n x0 r e a d y t o b e c a l l e d .
* /
SYM_ F U N C _ S T A R T ( _ _ a r m _ s m c c c _ s v e _ c h e c k )
ldr_ l x16 , s m c c c _ h a s _ s v e _ h i n t
cbz x16 , 2 f
get_ c u r r e n t _ t a s k x16
ldr x16 , [ x16 , #T S K _ T I _ F L A G S ]
tbnz x16 , #T I F _ F O R E I G N _ F P S T A T E , 1 f / / A n y l i v e F P s t a t e ?
tbnz x16 , #T I F _ S V E , 2 f / / D o e s t h a t s t a t e i n c l u d e S V E ?
1 : orr x0 , x0 , A R M _ S M C C C _ 1 _ 3 _ S V E _ H I N T
2 : ret
SYM_ F U N C _ E N D ( _ _ a r m _ s m c c c _ s v e _ c h e c k )
EXPORT_ S Y M B O L ( _ _ a r m _ s m c c c _ s v e _ c h e c k )
2016-01-04 17:44:32 +03:00
.macro SMCCC instr
2021-07-21 10:18:35 +03:00
stp x29 , x30 , [ s p , #- 16 ] !
mov x29 , s p
2021-06-03 21:41:18 +03:00
alternative_ i f A R M 6 4 _ S V E
bl _ _ a r m _ s m c c c _ s v e _ c h e c k
alternative_ e l s e _ n o p _ e n d i f
2016-01-04 17:44:32 +03:00
\ instr #0
2021-07-21 10:18:35 +03:00
ldr x4 , [ s p , #16 ]
2016-01-04 17:44:32 +03:00
stp x0 , x1 , [ x4 , #A R M _ S M C C C _ R E S _ X 0 _ O F F S ]
stp x2 , x3 , [ x4 , #A R M _ S M C C C _ R E S _ X 2 _ O F F S ]
2021-07-21 10:18:35 +03:00
ldr x4 , [ s p , #24 ]
2017-02-01 20:28:28 +03:00
cbz x4 , 1 f / * n o q u i r k s t r u c t u r e * /
ldr x9 , [ x4 , #A R M _ S M C C C _ Q U I R K _ I D _ O F F S ]
cmp x9 , #A R M _ S M C C C _ Q U I R K _ Q C O M _ A 6
b. n e 1 f
str x6 , [ x4 , A R M _ S M C C C _ Q U I R K _ S T A T E _ O F F S ]
2021-07-21 10:18:35 +03:00
1 : ldp x29 , x30 , [ s p ] , #16
ret
2016-01-04 17:44:32 +03:00
.endm
/ *
* void a r m _ s m c c c _ s m c ( u n s i g n e d l o n g a0 , u n s i g n e d l o n g a1 , u n s i g n e d l o n g a2 ,
* unsigned l o n g a3 , u n s i g n e d l o n g a4 , u n s i g n e d l o n g a5 ,
2017-02-01 20:28:27 +03:00
* unsigned l o n g a6 , u n s i g n e d l o n g a7 , s t r u c t a r m _ s m c c c _ r e s * r e s ,
* struct a r m _ s m c c c _ q u i r k * q u i r k )
2016-01-04 17:44:32 +03:00
* /
2020-05-01 14:54:29 +03:00
SYM_ F U N C _ S T A R T ( _ _ a r m _ s m c c c _ s m c )
2016-01-04 17:44:32 +03:00
SMCCC s m c
2020-05-01 14:54:29 +03:00
SYM_ F U N C _ E N D ( _ _ a r m _ s m c c c _ s m c )
2018-12-07 21:08:18 +03:00
EXPORT_ S Y M B O L ( _ _ a r m _ s m c c c _ s m c )
2016-01-04 17:44:32 +03:00
/ *
* void a r m _ s m c c c _ h v c ( u n s i g n e d l o n g a0 , u n s i g n e d l o n g a1 , u n s i g n e d l o n g a2 ,
* unsigned l o n g a3 , u n s i g n e d l o n g a4 , u n s i g n e d l o n g a5 ,
2017-02-01 20:28:27 +03:00
* unsigned l o n g a6 , u n s i g n e d l o n g a7 , s t r u c t a r m _ s m c c c _ r e s * r e s ,
* struct a r m _ s m c c c _ q u i r k * q u i r k )
2016-01-04 17:44:32 +03:00
* /
2020-05-01 14:54:29 +03:00
SYM_ F U N C _ S T A R T ( _ _ a r m _ s m c c c _ h v c )
2016-01-04 17:44:32 +03:00
SMCCC h v c
2020-05-01 14:54:29 +03:00
SYM_ F U N C _ E N D ( _ _ a r m _ s m c c c _ h v c )
2018-12-07 21:08:18 +03:00
EXPORT_ S Y M B O L ( _ _ a r m _ s m c c c _ h v c )
2021-05-18 19:36:18 +03:00
.macro SMCCC_1_2 instr
/* Save `res` and free a GPR that won't be clobbered */
stp x1 , x19 , [ s p , #- 16 ] !
/* Ensure `args` won't be clobbered while loading regs in next step */
mov x19 , x0
/* Load the registers x0 - x17 from the struct arm_smccc_1_2_regs */
ldp x0 , x1 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 0 _ O F F S ]
ldp x2 , x3 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 2 _ O F F S ]
ldp x4 , x5 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 4 _ O F F S ]
ldp x6 , x7 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 6 _ O F F S ]
ldp x8 , x9 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 8 _ O F F S ]
ldp x10 , x11 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 0 _ O F F S ]
ldp x12 , x13 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 2 _ O F F S ]
ldp x14 , x15 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 4 _ O F F S ]
ldp x16 , x17 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 6 _ O F F S ]
\ instr #0
/* Load the `res` from the stack */
ldr x19 , [ s p ]
/* Store the registers x0 - x17 into the result structure */
stp x0 , x1 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 0 _ O F F S ]
stp x2 , x3 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 2 _ O F F S ]
stp x4 , x5 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 4 _ O F F S ]
stp x6 , x7 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 6 _ O F F S ]
stp x8 , x9 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 8 _ O F F S ]
stp x10 , x11 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 0 _ O F F S ]
stp x12 , x13 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 2 _ O F F S ]
stp x14 , x15 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 4 _ O F F S ]
stp x16 , x17 , [ x19 , #A R M _ S M C C C _ 1 _ 2 _ R E G S _ X 1 6 _ O F F S ]
/* Restore original x19 */
ldp x z r , x19 , [ s p ] , #16
ret
.endm
/ *
* void a r m _ s m c c c _ 1 _ 2 _ h v c ( c o n s t s t r u c t a r m _ s m c c c _ 1 _ 2 _ r e g s * a r g s ,
* struct a r m _ s m c c c _ 1 _ 2 _ r e g s * r e s ) ;
* /
SYM_ F U N C _ S T A R T ( a r m _ s m c c c _ 1 _ 2 _ h v c )
SMCCC_ 1 _ 2 h v c
SYM_ F U N C _ E N D ( a r m _ s m c c c _ 1 _ 2 _ h v c )
EXPORT_ S Y M B O L ( a r m _ s m c c c _ 1 _ 2 _ h v c )
/ *
* void a r m _ s m c c c _ 1 _ 2 _ s m c ( c o n s t s t r u c t a r m _ s m c c c _ 1 _ 2 _ r e g s * a r g s ,
* struct a r m _ s m c c c _ 1 _ 2 _ r e g s * r e s ) ;
* /
SYM_ F U N C _ S T A R T ( a r m _ s m c c c _ 1 _ 2 _ s m c )
SMCCC_ 1 _ 2 s m c
SYM_ F U N C _ E N D ( a r m _ s m c c c _ 1 _ 2 _ s m c )
EXPORT_ S Y M B O L ( a r m _ s m c c c _ 1 _ 2 _ s m c )