From 9d6fc3c32162cf4c6146a8f918c0790848686086 Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Fri, 12 May 2017 16:51:59 +0100 Subject: [PATCH] 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 --- bl1/bl1_fwu.c | 61 +++++++++++++++++++++++++++++++++++++++++ docs/firmware-update.md | 22 ++++++++++++++- include/bl1/bl1.h | 5 ++-- 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c index 43bb4d2ba..205ea9223 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; +} diff --git a/docs/firmware-update.md b/docs/firmware-update.md index 56ef15cbb..e3eec26f9 100644 --- a/docs/firmware-update.md +++ b/docs/firmware-update.md @@ -117,6 +117,7 @@ The following is a brief description of the supported states: * RESET: This is the initial state of every image at the start of FWU. Authentication failure also leads to this state. A secure image may yield to this state if it has completed execution. + It can also be reached by using `FWU_SMC_IMAGE_RESET`. * COPYING: This is the state of a secure image while BL1 is copying it in blocks from non-secure to secure memory. @@ -356,9 +357,28 @@ function `bl1_plat_fwu_done`, passing the optional argument `client_cookie` as a `void *`. The SMC does not return. +### FWU_SMC_IMAGE_RESET + + Arguments: + uint32_t function ID : 0x16 + unsigned int image_id + + Return: + int : 0 (Success) + : -EPERM + + Pre-conditions: + if (secure world caller) return -EPERM + if (image in EXECUTED) return -EPERM + +This SMC sets the state of an image to RESET and zeroes the memory used by it. + +This is only allowed if the image is not being executed. + + - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved._ +_Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved._ [Porting Guide]: ./porting-guide.md diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h index 8f4f992cd..154452351 100644 --- a/include/bl1/bl1.h +++ b/include/bl1/bl1.h @@ -39,11 +39,12 @@ #define FWU_SMC_IMAGE_RESUME 0x13 #define FWU_SMC_SEC_IMAGE_DONE 0x14 #define FWU_SMC_UPDATE_DONE 0x15 +#define FWU_SMC_IMAGE_RESET 0x16 /* * Number of FWU calls (above) implemented */ -#define FWU_NUM_SMC_CALLS 6 +#define FWU_NUM_SMC_CALLS 7 #if TRUSTED_BOARD_BOOT # define BL1_NUM_SMC_CALLS (FWU_NUM_SMC_CALLS + 4) @@ -56,7 +57,7 @@ * calls from the SMC function ID */ #define FWU_SMC_FID_START FWU_SMC_IMAGE_COPY -#define FWU_SMC_FID_END FWU_SMC_UPDATE_DONE +#define FWU_SMC_FID_END FWU_SMC_IMAGE_RESET #define is_fwu_fid(_fid) \ ((_fid >= FWU_SMC_FID_START) && (_fid <= FWU_SMC_FID_END))