diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | bl2/bl2_main.c | 129 | ||||
-rw-r--r-- | include/bl32/payloads/tlk.h | 1 | ||||
-rw-r--r-- | services/spd/tlkd/tlkd_main.c | 113 |
4 files changed, 115 insertions, 130 deletions
@@ -42,8 +42,6 @@ VERSION_MINOR := 1 V := 0 # Debug build DEBUG := 0 -# Build architecture -ARCH := aarch64 # Build platform DEFAULT_PLAT := fvp PLAT := ${DEFAULT_PLAT} diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index 29ca0a5..fb79f04 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -205,23 +205,28 @@ static int load_bl30(void) &bl30_image_info, NULL); - if (e == 0) { + if (e) + return e; + #if TRUSTED_BOARD_BOOT - e = auth_verify_obj(AUTH_BL30_IMG, - bl30_image_info.image_base, - bl30_image_info.image_size); - if (e) { - ERROR("Failed to authenticate BL3-0 image.\n"); - panic(); - } - - /* After working with data, invalidate the data cache */ - inv_dcache_range(bl30_image_info.image_base, - (size_t)bl30_image_info.image_size); + e = auth_verify_obj(AUTH_BL30_IMG, + bl30_image_info.image_base, + bl30_image_info.image_size); + if (e) { + ERROR("Failed to authenticate BL3-0 image.\n"); + return e; + } + + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl30_image_info.image_base, + (size_t)bl30_image_info.image_size); #endif /* TRUSTED_BOARD_BOOT */ - /* The subsequent handling of BL3-0 is platform specific */ - bl2_plat_handle_bl30(&bl30_image_info); + /* The subsequent handling of BL3-0 is platform specific */ + e = bl2_plat_handle_bl30(&bl30_image_info); + if (e) { + ERROR("Failure in platform-specific handling of BL3-0 image.\n"); + return e; } #endif /* BL30_BASE */ @@ -256,25 +261,25 @@ static int load_bl31(bl31_params_t *bl2_to_bl31_params, BL31_BASE, bl2_to_bl31_params->bl31_image_info, bl31_ep_info); + if (e) + return e; - if (e == 0) { #if TRUSTED_BOARD_BOOT - e = auth_verify_obj(AUTH_BL31_IMG, - bl2_to_bl31_params->bl31_image_info->image_base, - bl2_to_bl31_params->bl31_image_info->image_size); - if (e) { - ERROR("Failed to authenticate BL3-1 image.\n"); - panic(); - } - - /* After working with data, invalidate the data cache */ - inv_dcache_range(bl2_to_bl31_params->bl31_image_info->image_base, + e = auth_verify_obj(AUTH_BL31_IMG, + bl2_to_bl31_params->bl31_image_info->image_base, + bl2_to_bl31_params->bl31_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-1 image.\n"); + return e; + } + + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl31_image_info->image_base, (size_t)bl2_to_bl31_params->bl31_image_info->image_size); #endif /* TRUSTED_BOARD_BOOT */ - bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, - bl31_ep_info); - } + bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, + bl31_ep_info); return e; } @@ -309,30 +314,31 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params) bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info); - if (e == 0) { + if (e) + return e; + #if TRUSTED_BOARD_BOOT - /* Image is present. Check if there is a valid certificate */ - if (bl32_cert_error) { - ERROR("Failed to authenticate BL3-2 certificates.\n"); - panic(); - } - - e = auth_verify_obj(AUTH_BL32_IMG, - bl2_to_bl31_params->bl32_image_info->image_base, - bl2_to_bl31_params->bl32_image_info->image_size); - if (e) { - ERROR("Failed to authenticate BL3-2 image.\n"); - panic(); - } - /* After working with data, invalidate the data cache */ - inv_dcache_range(bl2_to_bl31_params->bl32_image_info->image_base, + /* Image is present. Check if there is a valid certificate */ + if (bl32_cert_error) { + ERROR("Failed to authenticate BL3-2 certificates.\n"); + return bl32_cert_error; + } + + e = auth_verify_obj(AUTH_BL32_IMG, + bl2_to_bl31_params->bl32_image_info->image_base, + bl2_to_bl31_params->bl32_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-2 image.\n"); + return e; + } + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl32_image_info->image_base, (size_t)bl2_to_bl31_params->bl32_image_info->image_size); #endif /* TRUSTED_BOARD_BOOT */ - bl2_plat_set_bl32_ep_info( - bl2_to_bl31_params->bl32_image_info, - bl2_to_bl31_params->bl32_ep_info); - } + bl2_plat_set_bl32_ep_info( + bl2_to_bl31_params->bl32_image_info, + bl2_to_bl31_params->bl32_ep_info); #endif /* BL32_BASE */ return e; @@ -361,23 +367,24 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params) bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info); - if (e == 0) { + if (e) + return e; + #if TRUSTED_BOARD_BOOT - e = auth_verify_obj(AUTH_BL33_IMG, - bl2_to_bl31_params->bl33_image_info->image_base, - bl2_to_bl31_params->bl33_image_info->image_size); - if (e) { - ERROR("Failed to authenticate BL3-3 image.\n"); - panic(); - } - /* After working with data, invalidate the data cache */ - inv_dcache_range(bl2_to_bl31_params->bl33_image_info->image_base, + e = auth_verify_obj(AUTH_BL33_IMG, + bl2_to_bl31_params->bl33_image_info->image_base, + bl2_to_bl31_params->bl33_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-3 image.\n"); + return e; + } + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl33_image_info->image_base, (size_t)bl2_to_bl31_params->bl33_image_info->image_size); #endif /* TRUSTED_BOARD_BOOT */ - bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, - bl2_to_bl31_params->bl33_ep_info); - } + bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, + bl2_to_bl31_params->bl33_ep_info); return e; } diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h index 910f50f..bdfcc9a 100644 --- a/include/bl32/payloads/tlk.h +++ b/include/bl32/payloads/tlk.h @@ -52,7 +52,6 @@ #define TLK_PREEMPTED (0x32000002 | (1 << 31)) #define TLK_ENTRY_DONE (0x32000003 | (1 << 31)) #define TLK_VA_TRANSLATE (0x32000004 | (1 << 31)) -#define TLK_FID_SHARED_MEMBUF (0x32000005 | (1 << 31)) /* * Trusted Application specific function IDs diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c index c22203b..3532beb 100644 --- a/services/spd/tlkd/tlkd_main.c +++ b/services/spd/tlkd/tlkd_main.c @@ -65,36 +65,6 @@ DEFINE_SVC_UUID(tlk_uuid, int32_t tlkd_init(void); -/* - * The number of arguments/results to save during a SMC call for TLK. - */ -#define TLK_SHDBUF_SIZE 4 - -/******************************************************************************* - * Shared memory buffer for passing SMC args/results to TLK - ******************************************************************************/ -typedef struct tlk_args_results { - uint64_t args[TLK_SHDBUF_SIZE]; -} tlk_args_results_t; - -static tlk_args_results_t *tlk_args_results_buf; - -/* - * Helper function to store args from TLK and pass results back - */ -static inline void store_tlk_args_results(uint64_t x0, uint64_t x1, uint64_t x2, - uint64_t x3) -{ - /* store arguments sent by TLK */ - tlk_args_results_buf->args[0] = x0; - tlk_args_results_buf->args[1] = x1; - tlk_args_results_buf->args[2] = x2; - tlk_args_results_buf->args[3] = x3; - - flush_dcache_range((uint64_t)tlk_args_results_buf, - sizeof(tlk_args_results_t)); -} - /******************************************************************************* * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type * (aarch32/aarch64) if not already known and initialises the context for entry @@ -187,8 +157,9 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid, uint64_t flags) { cpu_context_t *ns_cpu_context; + gp_regs_t *gp_regs; uint32_t ns; - uint64_t vaddr, type, par; + uint64_t par; /* Passing a NULL context is a critical programming error */ assert(handle); @@ -226,7 +197,7 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid, cm_el1_sysregs_context_restore(NON_SECURE); cm_set_next_eret_context(NON_SECURE); - SMC_RET1(ns_cpu_context, tlk_args_results_buf->args[0]); + SMC_RET1(ns_cpu_context, x1); /* * Request from non secure world to resume the preempted @@ -281,7 +252,7 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid, case TLK_TA_LAUNCH_OP: case TLK_TA_SEND_EVENT: - if (!ns || !tlk_args_results_buf) + if (!ns) SMC_RET1(handle, SMC_UNK); /* @@ -308,41 +279,67 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid, */ set_std_smc_active_flag(tlk_ctx.state); - /* Save args for use by the SP on return */ - store_tlk_args_results(smc_fid, x1, x2, x3); - /* * We are done stashing the non-secure context. Ask the * secure payload to do the work now. */ cm_el1_sysregs_context_restore(SECURE); cm_set_next_eret_context(SECURE); - SMC_RET0(&tlk_ctx.cpu_ctx); + + /* + * TLK is a 32-bit Trusted OS and so expects the SMC + * arguments via r0-r7. TLK expects the monitor frame + * registers to be 64-bits long. Hence, we pass x0 in + * r0-r1, x1 in r2-r3, x3 in r4-r5 and x4 in r6-r7. + * + * As smc_fid is a uint32 value, r1 contains 0. + */ + gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); + write_ctx_reg(gp_regs, CTX_GPREG_X4, (uint32_t)x2); + write_ctx_reg(gp_regs, CTX_GPREG_X5, (uint32_t)(x2 >> 32)); + write_ctx_reg(gp_regs, CTX_GPREG_X6, (uint32_t)x3); + write_ctx_reg(gp_regs, CTX_GPREG_X7, (uint32_t)(x3 >> 32)); + SMC_RET4(&tlk_ctx.cpu_ctx, smc_fid, 0, (uint32_t)x1, + (uint32_t)(x1 >> 32)); /* - * Translate NS/EL1-S virtual addresses + * Translate NS/EL1-S virtual addresses. + * + * x1 = virtual address + * x3 = type (NS/S) + * + * Returns PA:lo in r0, PA:hi in r1. */ case TLK_VA_TRANSLATE: - if (ns || !tlk_args_results_buf) + + /* Should be invoked only by secure world */ + if (ns) SMC_RET1(handle, SMC_UNK); - /* virtual address and type: ns/s */ - vaddr = tlk_args_results_buf->args[0]; - type = tlk_args_results_buf->args[1]; + /* NS virtual addresses are 64-bit long */ + if (x3 & TLK_TRANSLATE_NS_VADDR) + x1 = (uint32_t)x1 | (x2 << 32); - par = tlkd_va_translate(vaddr, type); + if (!x1) + SMC_RET1(handle, SMC_UNK); + + /* + * TODO: Sanity check x1. This would require platform + * support. + */ - /* Save PA for use by the SP on return */ - store_tlk_args_results(par, 0, 0, 0); + /* virtual address and type: ns/s */ + par = tlkd_va_translate(x1, x3); - SMC_RET0(handle); + /* return physical address in r0-r1 */ + SMC_RET4(handle, (uint32_t)par, (uint32_t)(par >> 32), 0, 0); /* * This is a request from the SP to mark completion of * a standard function ID. */ case TLK_REQUEST_DONE: - if (ns || !tlk_args_results_buf) + if (ns) SMC_RET1(handle, SMC_UNK); /* @@ -366,14 +363,14 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid, */ cm_el1_sysregs_context_restore(NON_SECURE); cm_set_next_eret_context(NON_SECURE); - SMC_RET1(ns_cpu_context, tlk_args_results_buf->args[0]); + SMC_RET1(ns_cpu_context, x1); /* * This function ID is used only by the SP to indicate it has * finished initialising itself after a cold boot */ case TLK_ENTRY_DONE: - if (ns || !tlk_args_results_buf) + if (ns) SMC_RET1(handle, SMC_UNK); /* @@ -388,23 +385,7 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid, * into the SP. Jump back to the original C runtime * context. */ - tlkd_synchronous_sp_exit(&tlk_ctx, tlk_args_results_buf->args[0]); - - /* - * This is a request from the secure payload to register - * shared memory to pass SMC args/results between EL1, EL3. - */ - case TLK_FID_SHARED_MEMBUF: - if (ns || !x1) - SMC_RET1(handle, SMC_UNK); - - /* - * TODO: Check if the passed memory pointer is valid. Might - * require a call into the platform code. - */ - - tlk_args_results_buf = (tlk_args_results_t *)x1; - SMC_RET0(handle); + tlkd_synchronous_sp_exit(&tlk_ctx, x1); /* * Return the number of service function IDs implemented to |