diff --git a/common/runtime_svc.c b/common/runtime_svc.c index b8af6cd..df0d64c 100644 --- a/common/runtime_svc.c +++ b/common/runtime_svc.c @@ -52,6 +52,34 @@ / sizeof(rt_svc_desc_t)) /******************************************************************************* + * Function to invoke the registered `handle` corresponding to the smc_fid. + ******************************************************************************/ +uintptr_t handle_runtime_svc(uint32_t smc_fid, + void *cookie, + void *handle, + unsigned int flags) +{ + u_register_t x1, x2, x3, x4; + int index, idx; + const rt_svc_desc_t *rt_svc_descs; + + assert(handle); + idx = get_unique_oen_from_smc_fid(smc_fid); + assert(idx >= 0 && idx < MAX_RT_SVCS); + + index = rt_svc_descs_indices[idx]; + if (index < 0 || index >= RT_SVC_DECS_NUM) + SMC_RET1(handle, SMC_UNK); + + rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START; + + get_smc_params_from_ctx(handle, x1, x2, x3, x4); + + return rt_svc_descs[index].handle(smc_fid, x1, x2, x3, x4, cookie, + handle, flags); +} + +/******************************************************************************* * Simple routine to sanity check a runtime service descriptor before using it ******************************************************************************/ static int32_t validate_rt_svc_desc(const rt_svc_desc_t *desc) diff --git a/include/common/runtime_svc.h b/include/common/runtime_svc.h index adafcee..514f334 100644 --- a/include/common/runtime_svc.h +++ b/include/common/runtime_svc.h @@ -43,10 +43,17 @@ * Constants to allow the assembler access a runtime service * descriptor */ +#ifdef AARCH32 +#define RT_SVC_SIZE_LOG2 4 +#define RT_SVC_DESC_INIT 8 +#define RT_SVC_DESC_HANDLE 12 +#else #define RT_SVC_SIZE_LOG2 5 -#define SIZEOF_RT_SVC_DESC (1 << RT_SVC_SIZE_LOG2) #define RT_SVC_DESC_INIT 16 #define RT_SVC_DESC_HANDLE 24 +#endif /* AARCH32 */ +#define SIZEOF_RT_SVC_DESC (1 << RT_SVC_SIZE_LOG2) + /* * The function identifier has 6 bits for the owning entity number and @@ -123,10 +130,22 @@ ((call_type & FUNCID_TYPE_MASK) \ << FUNCID_OEN_WIDTH)) +/* + * This macro generates the unique owning entity number from the SMC Function + * ID. This unique oen is used to access an entry in the + * 'rt_svc_descs_indices' array to invoke the corresponding runtime service + * handler during SMC handling. + */ +#define get_unique_oen_from_smc_fid(fid) \ + get_unique_oen(((fid) >> FUNCID_OEN_SHIFT), \ + ((fid) >> FUNCID_TYPE_SHIFT)) + /******************************************************************************* * Function & variable prototypes ******************************************************************************/ void runtime_svc_init(void); +uintptr_t handle_runtime_svc(uint32_t smc_fid, void *cookie, void *handle, + unsigned int flags); extern uintptr_t __RT_SVC_DESCS_START__; extern uintptr_t __RT_SVC_DESCS_END__; void init_crash_reporting(void); diff --git a/include/lib/aarch64/smcc_helpers.h b/include/lib/aarch64/smcc_helpers.h index 617a5bc..6e63383 100644 --- a/include/lib/aarch64/smcc_helpers.h +++ b/include/lib/aarch64/smcc_helpers.h @@ -82,5 +82,17 @@ ((const uint32_t *) &(_uuid))[2], \ ((const uint32_t *) &(_uuid))[3]) +/* + * Helper macro to retrieve the SMC parameters from cpu_context_t. + */ +#define get_smc_params_from_ctx(_hdl, _x1, _x2, _x3, _x4) \ + do { \ + const gp_regs_t *regs = get_gpregs_ctx(_hdl); \ + _x1 = read_ctx_reg(regs, CTX_GPREG_X1); \ + _x2 = read_ctx_reg(regs, CTX_GPREG_X2); \ + _x3 = read_ctx_reg(regs, CTX_GPREG_X3); \ + _x4 = read_ctx_reg(regs, CTX_GPREG_X4); \ + } while (0) + #endif /*__ASSEMBLY__*/ #endif /* __SMCC_HELPERS_H__ */