summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bl1/bl1_fwu.c83
-rw-r--r--include/plat/common/platform.h2
-rw-r--r--plat/arm/board/juno/juno_bl1_setup.c2
-rw-r--r--plat/common/plat_bl1_common.c2
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();