xref: /rk3399_ARM-atf/include/common/runtime_svc.h (revision 9f85f9e3796f1c351bbc4c8436dc66d83c140b71)
1532ed618SSoby Mathew /*
27fabe1a8SRoberto Vargas  * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
3532ed618SSoby Mathew  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5532ed618SSoby Mathew  */
6532ed618SSoby Mathew 
7532ed618SSoby Mathew #ifndef __RUNTIME_SVC_H__
8532ed618SSoby Mathew #define __RUNTIME_SVC_H__
9532ed618SSoby Mathew 
10532ed618SSoby Mathew #include <bl_common.h>		/* to include exception types */
11085e80ecSAntonio Nino Diaz #include <smccc_helpers.h>	/* to include SMCCC definitions */
12532ed618SSoby Mathew 
13532ed618SSoby Mathew 
14532ed618SSoby Mathew /*******************************************************************************
15532ed618SSoby Mathew  * Structure definition, typedefs & constants for the runtime service framework
16532ed618SSoby Mathew  ******************************************************************************/
17532ed618SSoby Mathew 
18532ed618SSoby Mathew /*
19532ed618SSoby Mathew  * Constants to allow the assembler access a runtime service
20532ed618SSoby Mathew  * descriptor
21532ed618SSoby Mathew  */
221ae0a49aSSoby Mathew #ifdef AARCH32
231ae0a49aSSoby Mathew #define RT_SVC_SIZE_LOG2	4
241ae0a49aSSoby Mathew #define RT_SVC_DESC_INIT	8
251ae0a49aSSoby Mathew #define RT_SVC_DESC_HANDLE	12
261ae0a49aSSoby Mathew #else
27532ed618SSoby Mathew #define RT_SVC_SIZE_LOG2	5
28532ed618SSoby Mathew #define RT_SVC_DESC_INIT	16
29532ed618SSoby Mathew #define RT_SVC_DESC_HANDLE	24
301ae0a49aSSoby Mathew #endif /* AARCH32 */
311ae0a49aSSoby Mathew #define SIZEOF_RT_SVC_DESC	(1 << RT_SVC_SIZE_LOG2)
321ae0a49aSSoby Mathew 
33532ed618SSoby Mathew 
34532ed618SSoby Mathew /*
35532ed618SSoby Mathew  * The function identifier has 6 bits for the owning entity number and
36532ed618SSoby Mathew  * single bit for the type of smc call. When taken together these
37532ed618SSoby Mathew  * values limit the maximum number of runtime services to 128.
38532ed618SSoby Mathew  */
39532ed618SSoby Mathew #define MAX_RT_SVCS		128
40532ed618SSoby Mathew 
41532ed618SSoby Mathew #ifndef __ASSEMBLY__
42532ed618SSoby Mathew 
43532ed618SSoby Mathew /* Prototype for runtime service initializing function */
44532ed618SSoby Mathew typedef int32_t (*rt_svc_init_t)(void);
45532ed618SSoby Mathew 
46532ed618SSoby Mathew /*
47532ed618SSoby Mathew  * Prototype for runtime service SMC handler function. x0 (SMC Function ID) to
48532ed618SSoby Mathew  * x4 are as passed by the caller. Rest of the arguments to SMC and the context
49532ed618SSoby Mathew  * can be accessed using the handle pointer. The cookie parameter is reserved
50532ed618SSoby Mathew  * for future use
51532ed618SSoby Mathew  */
52532ed618SSoby Mathew typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
53532ed618SSoby Mathew 				  u_register_t x1,
54532ed618SSoby Mathew 				  u_register_t x2,
55532ed618SSoby Mathew 				  u_register_t x3,
56532ed618SSoby Mathew 				  u_register_t x4,
57532ed618SSoby Mathew 				  void *cookie,
58532ed618SSoby Mathew 				  void *handle,
59532ed618SSoby Mathew 				  u_register_t flags);
60532ed618SSoby Mathew typedef struct rt_svc_desc {
61532ed618SSoby Mathew 	uint8_t start_oen;
62532ed618SSoby Mathew 	uint8_t end_oen;
63532ed618SSoby Mathew 	uint8_t call_type;
64532ed618SSoby Mathew 	const char *name;
65532ed618SSoby Mathew 	rt_svc_init_t init;
66532ed618SSoby Mathew 	rt_svc_handle_t handle;
67532ed618SSoby Mathew } rt_svc_desc_t;
68532ed618SSoby Mathew 
69532ed618SSoby Mathew /*
70532ed618SSoby Mathew  * Convenience macro to declare a service descriptor
71532ed618SSoby Mathew  */
72532ed618SSoby Mathew #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
73532ed618SSoby Mathew 	static const rt_svc_desc_t __svc_desc_ ## _name \
74532ed618SSoby Mathew 		__section("rt_svc_descs") __used = { \
75532ed618SSoby Mathew 			.start_oen = _start, \
76532ed618SSoby Mathew 			.end_oen = _end, \
77532ed618SSoby Mathew 			.call_type = _type, \
78532ed618SSoby Mathew 			.name = #_name, \
79532ed618SSoby Mathew 			.init = _setup, \
80532ed618SSoby Mathew 			.handle = _smch }
81532ed618SSoby Mathew 
82532ed618SSoby Mathew /*
83532ed618SSoby Mathew  * Compile time assertions related to the 'rt_svc_desc' structure to:
84532ed618SSoby Mathew  * 1. ensure that the assembler and the compiler view of the size
85532ed618SSoby Mathew  *    of the structure are the same.
86532ed618SSoby Mathew  * 2. ensure that the assembler and the compiler see the initialisation
87532ed618SSoby Mathew  *    routine at the same offset.
88532ed618SSoby Mathew  * 3. ensure that the assembler and the compiler see the handler
89532ed618SSoby Mathew  *    routine at the same offset.
90532ed618SSoby Mathew  */
91532ed618SSoby Mathew CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC), \
92532ed618SSoby Mathew 	assert_sizeof_rt_svc_desc_mismatch);
93532ed618SSoby Mathew CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init), \
94532ed618SSoby Mathew 	assert_rt_svc_desc_init_offset_mismatch);
95532ed618SSoby Mathew CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \
96532ed618SSoby Mathew 	assert_rt_svc_desc_handle_offset_mismatch);
97532ed618SSoby Mathew 
98532ed618SSoby Mathew 
99532ed618SSoby Mathew /*
100532ed618SSoby Mathew  * This macro combines the call type and the owning entity number corresponding
101532ed618SSoby Mathew  * to a runtime service to generate a unique owning entity number. This unique
102532ed618SSoby Mathew  * oen is used to access an entry in the 'rt_svc_descs_indices' array. The entry
103532ed618SSoby Mathew  * contains the index of the service descriptor in the 'rt_svc_descs' array.
104532ed618SSoby Mathew  */
105532ed618SSoby Mathew #define get_unique_oen(oen, call_type)	((oen & FUNCID_OEN_MASK) |	\
106532ed618SSoby Mathew 					((call_type & FUNCID_TYPE_MASK) \
107532ed618SSoby Mathew 					 << FUNCID_OEN_WIDTH))
108532ed618SSoby Mathew 
1091ae0a49aSSoby Mathew /*
1101ae0a49aSSoby Mathew  * This macro generates the unique owning entity number from the SMC Function
1111ae0a49aSSoby Mathew  * ID.  This unique oen is used to access an entry in the
1121ae0a49aSSoby Mathew  * 'rt_svc_descs_indices' array to invoke the corresponding runtime service
1131ae0a49aSSoby Mathew  * handler during SMC handling.
1141ae0a49aSSoby Mathew  */
1151ae0a49aSSoby Mathew #define get_unique_oen_from_smc_fid(fid)		\
1161ae0a49aSSoby Mathew 	get_unique_oen(((fid) >> FUNCID_OEN_SHIFT),	\
1171ae0a49aSSoby Mathew 			((fid) >> FUNCID_TYPE_SHIFT))
1181ae0a49aSSoby Mathew 
119532ed618SSoby Mathew /*******************************************************************************
120532ed618SSoby Mathew  * Function & variable prototypes
121532ed618SSoby Mathew  ******************************************************************************/
122532ed618SSoby Mathew void runtime_svc_init(void);
1231ae0a49aSSoby Mathew uintptr_t handle_runtime_svc(uint32_t smc_fid, void *cookie, void *handle,
1241ae0a49aSSoby Mathew 						unsigned int flags);
125*9f85f9e3SJoel Hutton IMPORT_SYM(uintptr_t, __RT_SVC_DESCS_START__,		RT_SVC_DESCS_START);
126*9f85f9e3SJoel Hutton IMPORT_SYM(uintptr_t, __RT_SVC_DESCS_END__,		RT_SVC_DESCS_END);
127532ed618SSoby Mathew void init_crash_reporting(void);
128532ed618SSoby Mathew 
1297fabe1a8SRoberto Vargas extern uint8_t rt_svc_descs_indices[MAX_RT_SVCS];
1307fabe1a8SRoberto Vargas 
131532ed618SSoby Mathew #endif /*__ASSEMBLY__*/
132532ed618SSoby Mathew #endif /* __RUNTIME_SVC_H__ */
133