1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  * Copyright (c) 2015 Runtime Inc
4  * Copyright (c) 2019-2024, Arm Limited.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 /*
10  * Original code taken from mcuboot project at:
11  * https://github.com/mcu-tools/mcuboot
12  * Git SHA of the original version: ac55554059147fff718015be9f4bd3108123f50a
13  */
14 
15 #include <errno.h>
16 #include "target.h"
17 #include "tfm_hal_device_header.h"
18 #include "Driver_Flash.h"
19 #include "sysflash/sysflash.h"
20 #include "flash_map/flash_map.h"
21 #include "flash_map_backend/flash_map_backend.h"
22 #include "bootutil/bootutil_log.h"
23 
flash_device_base(uint8_t fd_id,uintptr_t * ret)24 __WEAK int flash_device_base(uint8_t fd_id, uintptr_t *ret)
25 {
26     if (fd_id != FLASH_DEVICE_ID) {
27         BOOT_LOG_ERR("invalid flash ID %d; expected %d",
28                      fd_id, FLASH_DEVICE_ID);
29         return -1;
30     }
31     *ret = FLASH_DEVICE_BASE;
32     return 0;
33 }
34 
35 /*
36  * This depends on the mappings defined in flash_map.h.
37  * MCUBoot uses continuous numbering for the primary slot, the secondary slot,
38  * and the scratch while TF-M might number it differently.
39  */
flash_area_id_from_multi_image_slot(int image_index,int slot)40 int flash_area_id_from_multi_image_slot(int image_index, int slot)
41 {
42     switch (slot) {
43     case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
44     case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
45     case 2: return FLASH_AREA_IMAGE_SCRATCH;
46     }
47 
48     return -1; /* flash_area_open will fail on that */
49 }
50 
flash_area_id_from_image_slot(int slot)51 int flash_area_id_from_image_slot(int slot)
52 {
53     return flash_area_id_from_multi_image_slot(0, slot);
54 }
55 
flash_area_id_to_multi_image_slot(int image_index,int area_id)56 int flash_area_id_to_multi_image_slot(int image_index, int area_id)
57 {
58     if (area_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
59         return 0;
60     }
61     if (area_id == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
62         return 1;
63     }
64 
65     BOOT_LOG_ERR("invalid flash area ID");
66     return -1;
67 }
68 
flash_area_id_to_image_slot(int area_id)69 int flash_area_id_to_image_slot(int area_id)
70 {
71     return flash_area_id_to_multi_image_slot(0, area_id);
72 }
73 
flash_area_erased_val(const struct flash_area * fap)74 uint8_t flash_area_erased_val(const struct flash_area *fap)
75 {
76     return DRV_FLASH_AREA(fap)->GetInfo()->erased_value;
77 }
78 
flash_area_read_is_empty(const struct flash_area * fa,uint32_t off,void * dst,uint32_t len)79 int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
80         void *dst, uint32_t len)
81 {
82     uint32_t i;
83     uint8_t *u8dst;
84     int rc;
85 
86     BOOT_LOG_DBG("read_is_empty area=%d, off=%#x, len=%#x",
87                  fa->fa_id, off, len);
88     rc = flash_area_read(fa, off, dst, len);
89     if (rc) {
90         return -1;
91     }
92 
93     u8dst = (uint8_t*)dst;
94 
95     for (i = 0; i < len; i++) {
96         if (u8dst[i] != flash_area_erased_val(fa)) {
97             return 0;
98         }
99     }
100 
101     return 1;
102 }
103