diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c index 43bb4d2..205ea92 100644 --- a/bl1/bl1_fwu.c +++ b/bl1/bl1_fwu.c @@ -40,6 +40,8 @@ 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 @@ */ 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 @@ 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 @@ 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 56ef15c..e3eec26 100644 --- a/docs/firmware-update.md +++ b/docs/firmware-update.md @@ -117,6 +117,7 @@ * 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 @@ 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 8f4f992..1544523 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))