blob: 4286f86e66c5a2e2b238f2248a099a4886d56ebe [file] [log] [blame]
David Vinczecea8b592019-10-29 16:09:51 +01001/*
David Vincze225c58f2019-12-09 17:32:48 +01002 * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
David Vinczecea8b592019-10-29 16:09:51 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stdbool.h>
9#include "target.h"
David Vinczecea8b592019-10-29 16:09:51 +010010#include "flash_map/flash_map.h"
David Vincze225c58f2019-12-09 17:32:48 +010011#include "flash_map_backend/flash_map_backend.h"
David Vinczecea8b592019-10-29 16:09:51 +010012#include "bootutil/bootutil_log.h"
13#include "Driver_Flash.h"
14
Michel Jaouen26f6c022020-12-03 10:37:22 +010015/* When undefined FLASH_DEV_NAME_0 or FLASH_DEVICE_ID_0 , default */
16#if !defined(FLASH_DEV_NAME_0) || !defined(FLASH_DEVICE_ID_0)
17#define FLASH_DEV_NAME_0 FLASH_DEV_NAME
18#define FLASH_DEVICE_ID_0 FLASH_DEVICE_ID
19#endif
20
21/* When undefined FLASH_DEV_NAME_1 or FLASH_DEVICE_ID_1 , default */
22#if !defined(FLASH_DEV_NAME_1) || !defined(FLASH_DEVICE_ID_1)
23#define FLASH_DEV_NAME_1 FLASH_DEV_NAME
24#define FLASH_DEVICE_ID_1 FLASH_DEVICE_ID
25#endif
26
27/* When undefined FLASH_DEV_NAME_2 or FLASH_DEVICE_ID_2 , default */
28#if !defined(FLASH_DEV_NAME_2) || !defined(FLASH_DEVICE_ID_2)
29#define FLASH_DEV_NAME_2 FLASH_DEV_NAME
30#define FLASH_DEVICE_ID_2 FLASH_DEVICE_ID
31#endif
32
33/* When undefined FLASH_DEV_NAME_3 or FLASH_DEVICE_ID_3 , default */
34#if !defined(FLASH_DEV_NAME_3) || !defined(FLASH_DEVICE_ID_3)
35#define FLASH_DEV_NAME_3 FLASH_DEV_NAME
36#define FLASH_DEVICE_ID_3 FLASH_DEVICE_ID
37#endif
38
39/* When undefined FLASH_DEV_NAME_SCRATCH or FLASH_DEVICE_ID_SCRATCH , default */
40#if !defined(FLASH_DEV_NAME_SCRATCH) || !defined(FLASH_DEVICE_ID_SCRATCH)
41#define FLASH_DEV_NAME_SCRATCH FLASH_DEV_NAME
42#define FLASH_DEVICE_ID_SCRATCH FLASH_DEVICE_ID
43#endif
David Vinczecea8b592019-10-29 16:09:51 +010044
Balint Matyi69e2d2e2020-07-08 10:53:54 +010045#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
46
Michel Jaouen26f6c022020-12-03 10:37:22 +010047/* Flash device names must be specified by target */
48extern ARM_DRIVER_FLASH FLASH_DEV_NAME_0;
49extern ARM_DRIVER_FLASH FLASH_DEV_NAME_1;
50extern ARM_DRIVER_FLASH FLASH_DEV_NAME_2;
51extern ARM_DRIVER_FLASH FLASH_DEV_NAME_3;
52extern ARM_DRIVER_FLASH FLASH_DEV_NAME_SCRATCH;
53
David Vinczecea8b592019-10-29 16:09:51 +010054static const struct flash_area flash_map[] = {
55 {
56 .fa_id = FLASH_AREA_0_ID,
Michel Jaouen26f6c022020-12-03 10:37:22 +010057 .fa_device_id = FLASH_DEVICE_ID_0,
58 .fa_driver = &FLASH_DEV_NAME_0,
David Vinczecea8b592019-10-29 16:09:51 +010059 .fa_off = FLASH_AREA_0_OFFSET,
60 .fa_size = FLASH_AREA_0_SIZE,
61 },
62 {
63 .fa_id = FLASH_AREA_2_ID,
Michel Jaouen26f6c022020-12-03 10:37:22 +010064 .fa_device_id = FLASH_DEVICE_ID_2,
65 .fa_driver = &FLASH_DEV_NAME_2,
David Vinczecea8b592019-10-29 16:09:51 +010066 .fa_off = FLASH_AREA_2_OFFSET,
67 .fa_size = FLASH_AREA_2_SIZE,
68 },
69#if (MCUBOOT_IMAGE_NUMBER == 2)
70 {
71 .fa_id = FLASH_AREA_1_ID,
Michel Jaouen26f6c022020-12-03 10:37:22 +010072 .fa_device_id = FLASH_DEVICE_ID_1,
73 .fa_driver = &FLASH_DEV_NAME_1,
David Vinczecea8b592019-10-29 16:09:51 +010074 .fa_off = FLASH_AREA_1_OFFSET,
75 .fa_size = FLASH_AREA_1_SIZE,
76 },
77 {
78 .fa_id = FLASH_AREA_3_ID,
Michel Jaouen26f6c022020-12-03 10:37:22 +010079 .fa_device_id = FLASH_DEVICE_ID_3,
80 .fa_driver = &FLASH_DEV_NAME_3,
David Vinczecea8b592019-10-29 16:09:51 +010081 .fa_off = FLASH_AREA_3_OFFSET,
82 .fa_size = FLASH_AREA_3_SIZE,
83 },
84#endif
85 {
86 .fa_id = FLASH_AREA_SCRATCH_ID,
Michel Jaouen26f6c022020-12-03 10:37:22 +010087 .fa_device_id = FLASH_DEVICE_ID_SCRATCH,
88 .fa_driver = &FLASH_DEV_NAME_SCRATCH,
David Vinczecea8b592019-10-29 16:09:51 +010089 .fa_off = FLASH_AREA_SCRATCH_OFFSET,
90 .fa_size = FLASH_AREA_SCRATCH_SIZE,
91 },
92};
93
94static const int flash_map_entry_num = ARRAY_SIZE(flash_map);
95
96/*
97 * `open` a flash area. The `area` in this case is not the individual
98 * sectors, but describes the particular flash area in question.
99 */
100int flash_area_open(uint8_t id, const struct flash_area **area)
101{
102 int i;
103
104 BOOT_LOG_DBG("area %d", id);
105
106 for (i = 0; i < flash_map_entry_num; i++) {
107 if (id == flash_map[i].fa_id) {
108 break;
109 }
110 }
111 if (i == flash_map_entry_num) {
112 return -1;
113 }
114
115 *area = &flash_map[i];
116 return 0;
117}
118
119void flash_area_close(const struct flash_area *area)
120{
121 /* Nothing to do. */
122}
123
124int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
125 uint32_t len)
126{
127 BOOT_LOG_DBG("read area=%d, off=%#x, len=%#x", area->fa_id, off, len);
Michel Jaouen26f6c022020-12-03 10:37:22 +0100128 return DRV_FLASH_AREA(area)->ReadData(area->fa_off + off, dst, len);
David Vinczecea8b592019-10-29 16:09:51 +0100129}
130
131int flash_area_write(const struct flash_area *area, uint32_t off,
132 const void *src, uint32_t len)
133{
134 BOOT_LOG_DBG("write area=%d, off=%#x, len=%#x", area->fa_id, off, len);
Michel Jaouen26f6c022020-12-03 10:37:22 +0100135 return DRV_FLASH_AREA(area)->ProgramData(area->fa_off + off, src, len);
David Vinczecea8b592019-10-29 16:09:51 +0100136}
137
138int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
139{
140 ARM_FLASH_INFO *flash_info;
141 uint32_t deleted_len = 0;
142 int32_t rc = 0;
143
144 BOOT_LOG_DBG("erase area=%d, off=%#x, len=%#x", area->fa_id, off, len);
Michel Jaouen26f6c022020-12-03 10:37:22 +0100145 flash_info = DRV_FLASH_AREA(area)->GetInfo();
David Vinczecea8b592019-10-29 16:09:51 +0100146
147 if (flash_info->sector_info == NULL) {
148 /* Uniform sector layout */
149 while (deleted_len < len) {
Michel Jaouen26f6c022020-12-03 10:37:22 +0100150 rc = DRV_FLASH_AREA(area)->EraseSector(area->fa_off + off);
David Vinczecea8b592019-10-29 16:09:51 +0100151 if (rc != 0) {
152 break;
153 }
154 deleted_len += flash_info->sector_size;
155 off += flash_info->sector_size;
156 }
157 } else {
158 /* Inhomogeneous sector layout, explicitly defined
159 * Currently not supported.
160 */
161 }
162
163 return rc;
164}
165
166uint32_t flash_area_align(const struct flash_area *area)
167{
168 ARM_FLASH_INFO *flash_info;
169
Michel Jaouen26f6c022020-12-03 10:37:22 +0100170 flash_info = DRV_FLASH_AREA(area)->GetInfo();
David Vinczecea8b592019-10-29 16:09:51 +0100171 return flash_info->program_unit;
172}