diff options
-rw-r--r-- | bl1/bl1_fwu.c | 83 | ||||
-rw-r--r-- | include/plat/common/platform.h | 2 | ||||
-rw-r--r-- | plat/arm/board/juno/juno_bl1_setup.c | 2 | ||||
-rw-r--r-- | plat/common/plat_bl1_common.c | 2 |
4 files changed, 46 insertions, 43 deletions
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c index 05759212..80ce831a 100644 --- a/bl1/bl1_fwu.c +++ b/bl1/bl1_fwu.c @@ -58,13 +58,12 @@ static int bl1_fwu_image_auth(unsigned int image_id, static int bl1_fwu_image_execute(unsigned int image_id, void **handle, unsigned int flags); -static register_t bl1_fwu_image_resume(unsigned int image_id, - register_t image_param, +static register_t bl1_fwu_image_resume(register_t image_param, void **handle, unsigned int flags); static int bl1_fwu_sec_image_done(void **handle, unsigned int flags); -__dead2 static void bl1_fwu_done(void *cookie, void *reserved); +__dead2 static void bl1_fwu_done(void *client_cookie, void *reserved); /* * This keeps track of last executed secure image id. @@ -95,13 +94,13 @@ register_t bl1_fwu_smc_handler(unsigned int smc_fid, SMC_RET1(handle, bl1_fwu_image_execute(x1, &handle, flags)); case FWU_SMC_IMAGE_RESUME: - SMC_RET1(handle, bl1_fwu_image_resume(x1, x2, &handle, flags)); + SMC_RET1(handle, bl1_fwu_image_resume(x1, &handle, flags)); case FWU_SMC_SEC_IMAGE_DONE: SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags)); case FWU_SMC_UPDATE_DONE: - bl1_fwu_done(cookie, NULL); + bl1_fwu_done((void *)x1, NULL); /* We should never return from bl1_fwu_done() */ default: @@ -363,6 +362,7 @@ static int bl1_fwu_image_execute(unsigned int image_id, /* * Execution is NOT allowed if: + * image_id is invalid OR * Caller is from Secure world OR * Image is Non-Secure OR * Image is Non-Executable OR @@ -393,40 +393,41 @@ static int bl1_fwu_image_execute(unsigned int image_id, } /******************************************************************************* - * This function is responsible for resuming Secure/Non-Secure images. + * This function is responsible for resuming execution in the other security + * world ******************************************************************************/ -static register_t bl1_fwu_image_resume(unsigned int image_id, - register_t image_param, +static register_t bl1_fwu_image_resume(register_t image_param, void **handle, unsigned int flags) { image_desc_t *image_desc; unsigned int resume_sec_state; + unsigned int caller_sec_state = GET_SEC_STATE(flags); - if (GET_SEC_STATE(flags) == SECURE) { - /* Get the image descriptor for last executed secure image id. */ - image_desc = bl1_plat_get_image_desc(sec_exec_image_id); - - if ((!image_desc) || (image_desc->state != IMAGE_STATE_EXECUTED)) { - WARN("BL1-FWU: Resume not allowed for secure image " - "due to invalid state\n"); + /* Get the image descriptor for last executed secure image id. */ + image_desc = bl1_plat_get_image_desc(sec_exec_image_id); + if (caller_sec_state == NON_SECURE) { + if (!image_desc) { + WARN("BL1-FWU: Resume not allowed due to no available" + "secure image\n"); return -EPERM; } + } else { + /* image_desc must be valid for secure world callers */ + assert(image_desc); + } + + assert(GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE); + assert(GET_EXEC_STATE(image_desc->image_info.h.attr) == EXECUTABLE); + + if (caller_sec_state == SECURE) { + assert(image_desc->state == IMAGE_STATE_EXECUTED); /* Update the flags. */ image_desc->state = IMAGE_STATE_INTERRUPTED; resume_sec_state = NON_SECURE; } else { - /* Get the image descriptor for image id to be resumed. */ - image_desc = bl1_plat_get_image_desc(image_id); - - /* Make sure image is secure and was interrupted. */ - if ((!image_desc) || - (GET_SEC_STATE(image_desc->ep_info.h.attr) == NON_SECURE) || - (image_desc->state != IMAGE_STATE_INTERRUPTED)) { - WARN("BL1-FWU: Resume not allowed for NS image/ invalid state\n"); - return -EPERM; - } + assert(image_desc->state == IMAGE_STATE_INTERRUPTED); /* Update the flags. */ image_desc->state = IMAGE_STATE_EXECUTED; @@ -434,7 +435,7 @@ static register_t bl1_fwu_image_resume(unsigned int image_id, } /* Save the EL1 system registers of calling world. */ - cm_el1_sysregs_context_save(GET_SEC_STATE(flags)); + cm_el1_sysregs_context_save(caller_sec_state); /* Restore the EL1 system registers of resuming world. */ cm_el1_sysregs_context_restore(resume_sec_state); @@ -443,7 +444,7 @@ static register_t bl1_fwu_image_resume(unsigned int image_id, cm_set_next_eret_context(resume_sec_state); INFO("BL1-FWU: Resuming %s world context\n", - (resume_sec_state == SECURE) ? "Secure" : "Normal"); + (resume_sec_state == SECURE) ? "secure" : "normal"); *handle = cm_get_context(resume_sec_state); return image_param; @@ -454,21 +455,23 @@ static register_t bl1_fwu_image_resume(unsigned int image_id, ******************************************************************************/ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) { + image_desc_t *image_desc; - /* Get the image descriptor for last executed secure image id. */ - image_desc_t *image_desc = bl1_plat_get_image_desc(sec_exec_image_id); - - /* - * Make sure caller is from secure world - * and the image is in EXECUTED state. - */ - if ((!image_desc) || - (GET_SEC_STATE(flags) == NON_SECURE) || - (image_desc->state != IMAGE_STATE_EXECUTED)) { - WARN("BL1-FWU: Done not allowed for NS caller/ invalid state\n"); + /* Make sure caller is from the secure world */ + if (GET_SEC_STATE(flags) == NON_SECURE) { + WARN("BL1-FWU: Image done not allowed from normal world\n"); return -EPERM; } + /* Get the image descriptor for last executed secure image id */ + image_desc = bl1_plat_get_image_desc(sec_exec_image_id); + + /* image_desc must correspond to a valid secure executing image */ + assert(image_desc); + assert(GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE); + assert(GET_EXEC_STATE(image_desc->image_info.h.attr) == EXECUTABLE); + assert(image_desc->state == IMAGE_STATE_EXECUTED); + /* Update the flags. */ image_desc->state = IMAGE_STATE_RESET; sec_exec_image_id = INVALID_IMAGE_ID; @@ -492,13 +495,13 @@ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) * This function provides the opportunity for users to perform any * platform specific handling after the Firmware update is done. ******************************************************************************/ -__dead2 static void bl1_fwu_done(void *cookie, void *reserved) +__dead2 static void bl1_fwu_done(void *client_cookie, void *reserved) { NOTICE("BL1-FWU: *******FWU Process Completed*******\n"); /* * Call platform done function. */ - bl1_plat_fwu_done(cookie, reserved); + bl1_plat_fwu_done(client_cookie, reserved); assert(0); } diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index c21f9ee8..687c2212 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -121,7 +121,7 @@ struct image_desc *bl1_plat_get_image_desc(unsigned int image_id); * The following functions are used by firmware update * feature and may optionally be overridden. */ -__dead2 void bl1_plat_fwu_done(void *cookie, void *reserved); +__dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved); /******************************************************************************* diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 61a57381..e805c9a3 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -72,7 +72,7 @@ void bl1_plat_set_ep_info(unsigned int image_id, /******************************************************************************* * On Juno clear SYS_NVFLAGS and wait for watchdog reset. ******************************************************************************/ -__dead2 void bl1_plat_fwu_done(void *cookie, void *rsvd_ptr) +__dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) { unsigned int *nv_flags_clr = (unsigned int *) (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR); diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c index aee9440a..e637aaf0 100644 --- a/plat/common/plat_bl1_common.c +++ b/plat/common/plat_bl1_common.c @@ -69,7 +69,7 @@ image_desc_t *bl1_plat_get_image_desc(unsigned int image_id) return &bl2_img_desc; } -__dead2 void bl1_plat_fwu_done(void *cookie, void *rsvd_ptr) +__dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) { while (1) wfi(); |