/* * Copyright (c) 2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * */ #include <stdint.h> #include "tfm_sp_log.h" #include "tfm_platform_api.h" #include "tfm_fwu.h" psa_status_t tfm_internal_fwu_initialize(psa_image_id_t image_id) { uint8_t image_type = (uint8_t)FWU_IMAGE_ID_GET_TYPE(image_id); uint8_t slot_id = (uint8_t)FWU_IMAGE_ID_GET_SLOT(image_id); /* Check the image slot, the target should be the staging slot. */ if (slot_id != FWU_IMAGE_ID_SLOT_STAGE) { LOG_ERRFMT("TFM FWU: invalid slot_id: %d", slot_id); return PSA_ERROR_INVALID_ARGUMENT; } return fwu_bootloader_staging_area_init(image_type); } psa_status_t tfm_internal_fwu_write(psa_image_id_t image_id, size_t block_offset, const void *block, size_t block_size) { uint8_t image_type = (uint8_t)FWU_IMAGE_ID_GET_TYPE(image_id); uint8_t slot_id = (uint8_t)FWU_IMAGE_ID_GET_SLOT(image_id); if ((block == NULL) || (slot_id != FWU_IMAGE_ID_SLOT_STAGE)) { return PSA_ERROR_INVALID_ARGUMENT; } return fwu_bootloader_load_image(image_type, block_offset, block, block_size); } psa_status_t tfm_internal_fwu_install(psa_image_id_t image_id, psa_image_id_t *dependency, psa_image_version_t *dependency_version) { uint8_t image_type = (uint8_t)FWU_IMAGE_ID_GET_TYPE(image_id); uint8_t slot_id = (uint8_t)FWU_IMAGE_ID_GET_SLOT(image_id); bl_image_id_t dependency_bl; psa_image_version_t version; psa_status_t result; /* Check the image slot, the target should be the staging slot. */ if (slot_id != FWU_IMAGE_ID_SLOT_STAGE) { LOG_ERRFMT("TFM FWU: invalid slot_id: %d", slot_id); return PSA_ERROR_INVALID_ARGUMENT; } result = fwu_bootloader_install_image(image_type, &dependency_bl, &version); if (result == PSA_ERROR_DEPENDENCY_NEEDED) { if (dependency == NULL || dependency_version == NULL) { return PSA_ERROR_INVALID_ARGUMENT; } *dependency = (psa_image_id_t)FWU_CALCULATE_IMAGE_ID(FWU_IMAGE_ID_SLOT_STAGE, dependency_bl, 0); *dependency_version = version; } return result; } psa_status_t tfm_internal_fwu_abort(psa_image_id_t image_id) { uint8_t image_type = (uint8_t)FWU_IMAGE_ID_GET_TYPE(image_id); uint8_t slot_id = (uint8_t)FWU_IMAGE_ID_GET_SLOT(image_id); if (slot_id != FWU_IMAGE_ID_SLOT_STAGE) { return PSA_ERROR_INVALID_ARGUMENT; } return fwu_bootloader_abort(image_type); } /* The image version of the given image. */ psa_status_t tfm_internal_fwu_query(psa_image_id_t image_id, psa_image_info_t *info) { uint8_t image_type = (uint8_t)FWU_IMAGE_ID_GET_TYPE(image_id); uint8_t slot_id = (uint8_t)FWU_IMAGE_ID_GET_SLOT(image_id); bool active_image = 0; if (slot_id == FWU_IMAGE_ID_SLOT_STAGE) { active_image = false; } else if (slot_id == FWU_IMAGE_ID_SLOT_ACTIVE) { active_image = true; } else { LOG_ERRFMT("TFM FWU: invalid slot_id: %d", slot_id); return PSA_ERROR_INVALID_ARGUMENT; } return fwu_bootloader_get_image_info(image_type, active_image, info); } void tfm_internal_fwu_request_reboot(void) { tfm_platform_system_reset(); } psa_status_t tfm_internal_fwu_accept(psa_image_id_t image_id) { uint8_t image_type = (uint8_t)FWU_IMAGE_ID_GET_TYPE(image_id); return fwu_bootloader_mark_image_accepted(image_type); }