summaryrefslogtreecommitdiff
path: root/bl1
diff options
context:
space:
mode:
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>2017-05-12 16:51:59 +0100
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>2017-06-01 14:52:12 +0100
commit9d6fc3c32162cf4c6146a8f918c0790848686086 (patch)
treed4303c60f517d08f1ad4581edd21a0dc417d89d6 /bl1
parent128daee29868a8a4a7cf00508126ea68311fd1cc (diff)
FWU: Introduce FWU_SMC_IMAGE_RESET
This SMC is as a means for the image loading state machine to go from COPYING, COPIED or AUTHENTICATED states to RESET state. Previously, this was only done when the authentication of an image failed or when the execution of the image finished. Documentation updated. Change-Id: Ida6d4c65017f83ae5e27465ec36f54499c6534d9 Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Diffstat (limited to 'bl1')
-rw-r--r--bl1/bl1_fwu.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index 43bb4d2b..205ea922 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -40,6 +40,8 @@ static register_t bl1_fwu_image_resume(register_t image_param,
unsigned int flags);
static int bl1_fwu_sec_image_done(void **handle,
unsigned int flags);
+static int bl1_fwu_image_reset(unsigned int image_id,
+ unsigned int flags);
__dead2 static void bl1_fwu_done(void *client_cookie, void *reserved);
/*
@@ -47,6 +49,9 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved);
*/
static unsigned int sec_exec_image_id = INVALID_IMAGE_ID;
+/* Authentication status of each image. */
+extern unsigned int auth_img_flags[];
+
void cm_set_next_context(void *cpu_context);
/*******************************************************************************
@@ -78,6 +83,9 @@ register_t bl1_fwu_smc_handler(unsigned int smc_fid,
case FWU_SMC_SEC_IMAGE_DONE:
SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags));
+ case FWU_SMC_IMAGE_RESET:
+ SMC_RET1(handle, bl1_fwu_image_reset(x1, flags));
+
case FWU_SMC_UPDATE_DONE:
bl1_fwu_done((void *)x1, NULL);
/* We should never return from bl1_fwu_done() */
@@ -666,3 +674,56 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved)
bl1_plat_fwu_done(client_cookie, reserved);
assert(0);
}
+
+/*******************************************************************************
+ * This function resets an image to IMAGE_STATE_RESET. It fails if the image is
+ * being executed.
+ ******************************************************************************/
+static int bl1_fwu_image_reset(unsigned int image_id, unsigned int flags)
+{
+ image_desc_t *image_desc = bl1_plat_get_image_desc(image_id);
+
+ if ((!image_desc) || (GET_SECURITY_STATE(flags) == SECURE)) {
+ WARN("BL1-FWU: Reset not allowed due to invalid args\n");
+ return -EPERM;
+ }
+
+ switch (image_desc->state) {
+
+ case IMAGE_STATE_RESET:
+ /* Nothing to do. */
+ break;
+
+ case IMAGE_STATE_INTERRUPTED:
+ case IMAGE_STATE_AUTHENTICATED:
+ case IMAGE_STATE_COPIED:
+ case IMAGE_STATE_COPYING:
+
+ if (bl1_fwu_remove_loaded_id(image_id)) {
+ WARN("BL1-FWU: Image reset couldn't find the image ID\n");
+ return -EPERM;
+ }
+
+ /* Clear the memory.*/
+ zero_normalmem((void *)image_desc->image_info.image_base,
+ image_desc->copied_size);
+ flush_dcache_range(image_desc->image_info.image_base,
+ image_desc->copied_size);
+
+ /* Reset status variables */
+ image_desc->copied_size = 0;
+ image_desc->image_info.image_size = 0;
+ image_desc->state = IMAGE_STATE_RESET;
+
+ /* Clear authentication state */
+ auth_img_flags[image_id] = 0;
+
+ break;
+
+ case IMAGE_STATE_EXECUTED:
+ default:
+ assert(0);
+ }
+
+ return 0;
+}