1 /*
2  * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef __RUNTIME_SVC_H__
8 #define __RUNTIME_SVC_H__
9 
10 #include <bl_common.h>		/* to include exception types */
11 #include <smcc_helpers.h>	/* to include SMCC definitions */
12 
13 
14 /*******************************************************************************
15  * Structure definition, typedefs & constants for the runtime service framework
16  ******************************************************************************/
17 
18 /*
19  * Constants to allow the assembler access a runtime service
20  * descriptor
21  */
22 #ifdef AARCH32
23 #define RT_SVC_SIZE_LOG2	4
24 #define RT_SVC_DESC_INIT	8
25 #define RT_SVC_DESC_HANDLE	12
26 #else
27 #define RT_SVC_SIZE_LOG2	5
28 #define RT_SVC_DESC_INIT	16
29 #define RT_SVC_DESC_HANDLE	24
30 #endif /* AARCH32 */
31 #define SIZEOF_RT_SVC_DESC	(1 << RT_SVC_SIZE_LOG2)
32 
33 
34 /*
35  * The function identifier has 6 bits for the owning entity number and
36  * single bit for the type of smc call. When taken together these
37  * values limit the maximum number of runtime services to 128.
38  */
39 #define MAX_RT_SVCS		128
40 
41 #ifndef __ASSEMBLY__
42 
43 /* Prototype for runtime service initializing function */
44 typedef int32_t (*rt_svc_init_t)(void);
45 
46 /*
47  * Prototype for runtime service SMC handler function. x0 (SMC Function ID) to
48  * x4 are as passed by the caller. Rest of the arguments to SMC and the context
49  * can be accessed using the handle pointer. The cookie parameter is reserved
50  * for future use
51  */
52 typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
53 				  u_register_t x1,
54 				  u_register_t x2,
55 				  u_register_t x3,
56 				  u_register_t x4,
57 				  void *cookie,
58 				  void *handle,
59 				  u_register_t flags);
60 typedef struct rt_svc_desc {
61 	uint8_t start_oen;
62 	uint8_t end_oen;
63 	uint8_t call_type;
64 	const char *name;
65 	rt_svc_init_t init;
66 	rt_svc_handle_t handle;
67 } rt_svc_desc_t;
68 
69 /*
70  * Convenience macro to declare a service descriptor
71  */
72 #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
73 	static const rt_svc_desc_t __svc_desc_ ## _name \
74 		__section("rt_svc_descs") __used = { \
75 			.start_oen = _start, \
76 			.end_oen = _end, \
77 			.call_type = _type, \
78 			.name = #_name, \
79 			.init = _setup, \
80 			.handle = _smch }
81 
82 /*
83  * Compile time assertions related to the 'rt_svc_desc' structure to:
84  * 1. ensure that the assembler and the compiler view of the size
85  *    of the structure are the same.
86  * 2. ensure that the assembler and the compiler see the initialisation
87  *    routine at the same offset.
88  * 3. ensure that the assembler and the compiler see the handler
89  *    routine at the same offset.
90  */
91 CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC), \
92 	assert_sizeof_rt_svc_desc_mismatch);
93 CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init), \
94 	assert_rt_svc_desc_init_offset_mismatch);
95 CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \
96 	assert_rt_svc_desc_handle_offset_mismatch);
97 
98 
99 /*
100  * This macro combines the call type and the owning entity number corresponding
101  * to a runtime service to generate a unique owning entity number. This unique
102  * oen is used to access an entry in the 'rt_svc_descs_indices' array. The entry
103  * contains the index of the service descriptor in the 'rt_svc_descs' array.
104  */
105 #define get_unique_oen(oen, call_type)	((oen & FUNCID_OEN_MASK) |	\
106 					((call_type & FUNCID_TYPE_MASK) \
107 					 << FUNCID_OEN_WIDTH))
108 
109 /*
110  * This macro generates the unique owning entity number from the SMC Function
111  * ID.  This unique oen is used to access an entry in the
112  * 'rt_svc_descs_indices' array to invoke the corresponding runtime service
113  * handler during SMC handling.
114  */
115 #define get_unique_oen_from_smc_fid(fid)		\
116 	get_unique_oen(((fid) >> FUNCID_OEN_SHIFT),	\
117 			((fid) >> FUNCID_TYPE_SHIFT))
118 
119 /*******************************************************************************
120  * Function & variable prototypes
121  ******************************************************************************/
122 void runtime_svc_init(void);
123 uintptr_t handle_runtime_svc(uint32_t smc_fid, void *cookie, void *handle,
124 						unsigned int flags);
125 extern uintptr_t __RT_SVC_DESCS_START__;
126 extern uintptr_t __RT_SVC_DESCS_END__;
127 void init_crash_reporting(void);
128 
129 #endif /*__ASSEMBLY__*/
130 #endif /* __RUNTIME_SVC_H__ */
131