/* * Copyright (c) 2018 Nordic Semiconductor ASA * Copyright (c) 2015 Runtime Inc * Copyright (c) 2019-2020 Arm Limited. * * SPDX-License-Identifier: Apache-2.0 */ /* * Original code taken from mcuboot project at: * https://github.com/mcu-tools/mcuboot * Git SHA of the original version: ac55554059147fff718015be9f4bd3108123f50a */ #include #include "target.h" #include "cmsis.h" #include "Driver_Flash.h" #include "sysflash/sysflash.h" #include "flash_map/flash_map.h" #include "flash_map_backend/flash_map_backend.h" #include "bootutil/bootutil_log.h" __WEAK int flash_device_base(uint8_t fd_id, uintptr_t *ret) { if (fd_id != FLASH_DEVICE_ID) { BOOT_LOG_ERR("invalid flash ID %d; expected %d", fd_id, FLASH_DEVICE_ID); return -1; } *ret = FLASH_DEVICE_BASE; return 0; } /* * This depends on the mappings defined in flash_map.h. * MCUBoot uses continuous numbering for the primary slot, the secondary slot, * and the scratch while TF-M might number it differently. */ int flash_area_id_from_multi_image_slot(int image_index, int slot) { switch (slot) { case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index); case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index); case 2: return FLASH_AREA_IMAGE_SCRATCH; } return -1; /* flash_area_open will fail on that */ } int flash_area_id_from_image_slot(int slot) { return flash_area_id_from_multi_image_slot(0, slot); } int flash_area_id_to_multi_image_slot(int image_index, int area_id) { if (area_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) { return 0; } if (area_id == FLASH_AREA_IMAGE_SECONDARY(image_index)) { return 1; } BOOT_LOG_ERR("invalid flash area ID"); return -1; } int flash_area_id_to_image_slot(int area_id) { return flash_area_id_to_multi_image_slot(0, area_id); } uint8_t flash_area_erased_val(const struct flash_area *fap) { return DRV_FLASH_AREA(fap)->GetInfo()->erased_value; } int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off, void *dst, uint32_t len) { uint32_t i; uint8_t *u8dst; int rc; BOOT_LOG_DBG("read_is_empty area=%d, off=%#x, len=%#x", fa->fa_id, off, len); rc = DRV_FLASH_AREA(fa)->ReadData(fa->fa_off + off, dst, len); if (rc) { return -1; } u8dst = (uint8_t*)dst; for (i = 0; i < len; i++) { if (u8dst[i] != flash_area_erased_val(fa)) { return 0; } } return 1; }