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 */ 11*2f370465SAntonio Nino Diaz #include <cassert.h> 12085e80ecSAntonio Nino Diaz #include <smccc_helpers.h> /* to include SMCCC definitions */ 13*2f370465SAntonio Nino Diaz #include <utils_def.h> 14532ed618SSoby Mathew 15532ed618SSoby Mathew /******************************************************************************* 16532ed618SSoby Mathew * Structure definition, typedefs & constants for the runtime service framework 17532ed618SSoby Mathew ******************************************************************************/ 18532ed618SSoby Mathew 19532ed618SSoby Mathew /* 20532ed618SSoby Mathew * Constants to allow the assembler access a runtime service 21532ed618SSoby Mathew * descriptor 22532ed618SSoby Mathew */ 231ae0a49aSSoby Mathew #ifdef AARCH32 241ae0a49aSSoby Mathew #define RT_SVC_SIZE_LOG2 4 251ae0a49aSSoby Mathew #define RT_SVC_DESC_INIT 8 261ae0a49aSSoby Mathew #define RT_SVC_DESC_HANDLE 12 271ae0a49aSSoby Mathew #else 28532ed618SSoby Mathew #define RT_SVC_SIZE_LOG2 5 29532ed618SSoby Mathew #define RT_SVC_DESC_INIT 16 30532ed618SSoby Mathew #define RT_SVC_DESC_HANDLE 24 311ae0a49aSSoby Mathew #endif /* AARCH32 */ 321ae0a49aSSoby Mathew #define SIZEOF_RT_SVC_DESC (1 << RT_SVC_SIZE_LOG2) 331ae0a49aSSoby Mathew 34532ed618SSoby Mathew 35532ed618SSoby Mathew /* 36*2f370465SAntonio Nino Diaz * In SMCCC 1.X, the function identifier has 6 bits for the owning entity number 37*2f370465SAntonio Nino Diaz * and a single bit for the type of smc call. When taken together, those values 38*2f370465SAntonio Nino Diaz * limit the maximum number of runtime services to 128. 39*2f370465SAntonio Nino Diaz * 40*2f370465SAntonio Nino Diaz * In SMCCC 2.X the type bit is always 1 and there are only 4 OEN bits in the 41*2f370465SAntonio Nino Diaz * compatibility namespace, so the total number of services is 16. The LSB of 42*2f370465SAntonio Nino Diaz * namespace is also added to these 4 bits to make space for the vendor service 43*2f370465SAntonio Nino Diaz * handler and so the total number of runtime services is 32. 44532ed618SSoby Mathew */ 45*2f370465SAntonio Nino Diaz #if SMCCC_MAJOR_VERSION == 1 46532ed618SSoby Mathew #define MAX_RT_SVCS 128 47*2f370465SAntonio Nino Diaz #elif SMCCC_MAJOR_VERSION == 2 48*2f370465SAntonio Nino Diaz #define MAX_RT_SVCS 32 49*2f370465SAntonio Nino Diaz #endif 50532ed618SSoby Mathew 51532ed618SSoby Mathew #ifndef __ASSEMBLY__ 52532ed618SSoby Mathew 53532ed618SSoby Mathew /* Prototype for runtime service initializing function */ 54532ed618SSoby Mathew typedef int32_t (*rt_svc_init_t)(void); 55532ed618SSoby Mathew 56532ed618SSoby Mathew /* 57532ed618SSoby Mathew * Prototype for runtime service SMC handler function. x0 (SMC Function ID) to 58532ed618SSoby Mathew * x4 are as passed by the caller. Rest of the arguments to SMC and the context 59532ed618SSoby Mathew * can be accessed using the handle pointer. The cookie parameter is reserved 60532ed618SSoby Mathew * for future use 61532ed618SSoby Mathew */ 62532ed618SSoby Mathew typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid, 63532ed618SSoby Mathew u_register_t x1, 64532ed618SSoby Mathew u_register_t x2, 65532ed618SSoby Mathew u_register_t x3, 66532ed618SSoby Mathew u_register_t x4, 67532ed618SSoby Mathew void *cookie, 68532ed618SSoby Mathew void *handle, 69532ed618SSoby Mathew u_register_t flags); 70532ed618SSoby Mathew typedef struct rt_svc_desc { 71532ed618SSoby Mathew uint8_t start_oen; 72532ed618SSoby Mathew uint8_t end_oen; 73*2f370465SAntonio Nino Diaz #if SMCCC_MAJOR_VERSION == 1 74532ed618SSoby Mathew uint8_t call_type; 75*2f370465SAntonio Nino Diaz #elif SMCCC_MAJOR_VERSION == 2 76*2f370465SAntonio Nino Diaz uint8_t is_vendor; 77*2f370465SAntonio Nino Diaz #endif 78532ed618SSoby Mathew const char *name; 79532ed618SSoby Mathew rt_svc_init_t init; 80532ed618SSoby Mathew rt_svc_handle_t handle; 81532ed618SSoby Mathew } rt_svc_desc_t; 82532ed618SSoby Mathew 83532ed618SSoby Mathew /* 84*2f370465SAntonio Nino Diaz * Convenience macros to declare a service descriptor 85532ed618SSoby Mathew */ 86*2f370465SAntonio Nino Diaz #if SMCCC_MAJOR_VERSION == 1 87*2f370465SAntonio Nino Diaz 88532ed618SSoby Mathew #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \ 89532ed618SSoby Mathew static const rt_svc_desc_t __svc_desc_ ## _name \ 90532ed618SSoby Mathew __section("rt_svc_descs") __used = { \ 91532ed618SSoby Mathew .start_oen = _start, \ 92532ed618SSoby Mathew .end_oen = _end, \ 93532ed618SSoby Mathew .call_type = _type, \ 94532ed618SSoby Mathew .name = #_name, \ 95532ed618SSoby Mathew .init = _setup, \ 96*2f370465SAntonio Nino Diaz .handle = _smch \ 97*2f370465SAntonio Nino Diaz } 98*2f370465SAntonio Nino Diaz 99*2f370465SAntonio Nino Diaz #elif SMCCC_MAJOR_VERSION == 2 100*2f370465SAntonio Nino Diaz 101*2f370465SAntonio Nino Diaz #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \ 102*2f370465SAntonio Nino Diaz static const rt_svc_desc_t __svc_desc_ ## _name \ 103*2f370465SAntonio Nino Diaz __section("rt_svc_descs") __used = { \ 104*2f370465SAntonio Nino Diaz .start_oen = _start, \ 105*2f370465SAntonio Nino Diaz .end_oen = _end, \ 106*2f370465SAntonio Nino Diaz .is_vendor = 0, \ 107*2f370465SAntonio Nino Diaz .name = #_name, \ 108*2f370465SAntonio Nino Diaz .init = _setup, \ 109*2f370465SAntonio Nino Diaz .handle = _smch, \ 110*2f370465SAntonio Nino Diaz }; \ 111*2f370465SAntonio Nino Diaz CASSERT((_type) == SMC_TYPE_FAST, rt_svc_type_check_ ## _name) 112*2f370465SAntonio Nino Diaz 113*2f370465SAntonio Nino Diaz /* 114*2f370465SAntonio Nino Diaz * The higher 16 entries of the runtime services are used for the vendor 115*2f370465SAntonio Nino Diaz * specific descriptor. 116*2f370465SAntonio Nino Diaz */ 117*2f370465SAntonio Nino Diaz #define DECLARE_RT_SVC_VENDOR(_setup, _smch) \ 118*2f370465SAntonio Nino Diaz static const rt_svc_desc_t __svc_desc_vendor \ 119*2f370465SAntonio Nino Diaz __section("rt_svc_descs") __used = { \ 120*2f370465SAntonio Nino Diaz .start_oen = 0, \ 121*2f370465SAntonio Nino Diaz .end_oen = 15, \ 122*2f370465SAntonio Nino Diaz .is_vendor = 1, \ 123*2f370465SAntonio Nino Diaz .name = "vendor_rt_svc", \ 124*2f370465SAntonio Nino Diaz .init = _setup, \ 125*2f370465SAntonio Nino Diaz .handle = _smch, \ 126*2f370465SAntonio Nino Diaz } 127*2f370465SAntonio Nino Diaz 128*2f370465SAntonio Nino Diaz #endif /* SMCCC_MAJOR_VERSION */ 129532ed618SSoby Mathew 130532ed618SSoby Mathew /* 131532ed618SSoby Mathew * Compile time assertions related to the 'rt_svc_desc' structure to: 132532ed618SSoby Mathew * 1. ensure that the assembler and the compiler view of the size 133532ed618SSoby Mathew * of the structure are the same. 134532ed618SSoby Mathew * 2. ensure that the assembler and the compiler see the initialisation 135532ed618SSoby Mathew * routine at the same offset. 136532ed618SSoby Mathew * 3. ensure that the assembler and the compiler see the handler 137532ed618SSoby Mathew * routine at the same offset. 138532ed618SSoby Mathew */ 139532ed618SSoby Mathew CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC), \ 140532ed618SSoby Mathew assert_sizeof_rt_svc_desc_mismatch); 141532ed618SSoby Mathew CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init), \ 142532ed618SSoby Mathew assert_rt_svc_desc_init_offset_mismatch); 143532ed618SSoby Mathew CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \ 144532ed618SSoby Mathew assert_rt_svc_desc_handle_offset_mismatch); 145532ed618SSoby Mathew 146532ed618SSoby Mathew 147*2f370465SAntonio Nino Diaz #if SMCCC_MAJOR_VERSION == 1 148532ed618SSoby Mathew /* 149532ed618SSoby Mathew * This macro combines the call type and the owning entity number corresponding 150532ed618SSoby Mathew * to a runtime service to generate a unique owning entity number. This unique 151532ed618SSoby Mathew * oen is used to access an entry in the 'rt_svc_descs_indices' array. The entry 152532ed618SSoby Mathew * contains the index of the service descriptor in the 'rt_svc_descs' array. 153532ed618SSoby Mathew */ 154b3323cd6SAntonio Nino Diaz #define get_unique_oen(oen, call_type) \ 155b3323cd6SAntonio Nino Diaz (((uint32_t)(oen) & FUNCID_OEN_MASK) | \ 156b3323cd6SAntonio Nino Diaz (((uint32_t)(call_type) & FUNCID_TYPE_MASK) << FUNCID_OEN_WIDTH)) 157532ed618SSoby Mathew 1581ae0a49aSSoby Mathew /* 1591ae0a49aSSoby Mathew * This macro generates the unique owning entity number from the SMC Function 160b3323cd6SAntonio Nino Diaz * ID. This unique oen is used to access an entry in the 'rt_svc_descs_indices' 161b3323cd6SAntonio Nino Diaz * array to invoke the corresponding runtime service handler during SMC 162b3323cd6SAntonio Nino Diaz * handling. 1631ae0a49aSSoby Mathew */ 1641ae0a49aSSoby Mathew #define get_unique_oen_from_smc_fid(fid) \ 165*2f370465SAntonio Nino Diaz get_unique_oen(GET_SMC_OEN(fid), GET_SMC_TYPE(fid)) 166*2f370465SAntonio Nino Diaz 167*2f370465SAntonio Nino Diaz #elif SMCCC_MAJOR_VERSION == 2 168*2f370465SAntonio Nino Diaz 169*2f370465SAntonio Nino Diaz /* 170*2f370465SAntonio Nino Diaz * This macro combines the owning entity number corresponding to a runtime 171*2f370465SAntonio Nino Diaz * service with one extra bit for the vendor namespace to generate an index into 172*2f370465SAntonio Nino Diaz * the 'rt_svc_descs_indices' array. The entry contains the index of the service 173*2f370465SAntonio Nino Diaz * descriptor in the 'rt_svc_descs' array. 174*2f370465SAntonio Nino Diaz */ 175*2f370465SAntonio Nino Diaz #define get_rt_desc_idx(oen, is_vendor) \ 176*2f370465SAntonio Nino Diaz (((uint32_t)(oen) & FUNCID_OEN_MASK) | \ 177*2f370465SAntonio Nino Diaz (((uint32_t)(is_vendor) & 1U) << FUNCID_OEN_WIDTH)) 178*2f370465SAntonio Nino Diaz 179*2f370465SAntonio Nino Diaz #endif 1801ae0a49aSSoby Mathew 181532ed618SSoby Mathew /******************************************************************************* 182532ed618SSoby Mathew * Function & variable prototypes 183532ed618SSoby Mathew ******************************************************************************/ 184532ed618SSoby Mathew void runtime_svc_init(void); 1851ae0a49aSSoby Mathew uintptr_t handle_runtime_svc(uint32_t smc_fid, void *cookie, void *handle, 1861ae0a49aSSoby Mathew unsigned int flags); 1879f85f9e3SJoel Hutton IMPORT_SYM(uintptr_t, __RT_SVC_DESCS_START__, RT_SVC_DESCS_START); 1889f85f9e3SJoel Hutton IMPORT_SYM(uintptr_t, __RT_SVC_DESCS_END__, RT_SVC_DESCS_END); 189532ed618SSoby Mathew void init_crash_reporting(void); 190532ed618SSoby Mathew 1917fabe1a8SRoberto Vargas extern uint8_t rt_svc_descs_indices[MAX_RT_SVCS]; 1927fabe1a8SRoberto Vargas 193532ed618SSoby Mathew #endif /*__ASSEMBLY__*/ 194532ed618SSoby Mathew #endif /* __RUNTIME_SVC_H__ */ 195