Home | History | Annotate | Download | only in common
      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