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