blob: 7676da2f7335aad22188b0d4b567f77b5634e0a6 [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
15/* Flash device name must be specified by target */
16extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
17
Balint Matyi69e2d2e2020-07-08 10:53:54 +010018#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
19
David Vinczecea8b592019-10-29 16:09:51 +010020static const struct flash_area flash_map[] = {
21 {
22 .fa_id = FLASH_AREA_0_ID,
23 .fa_device_id = FLASH_DEVICE_ID,
24 .fa_off = FLASH_AREA_0_OFFSET,
25 .fa_size = FLASH_AREA_0_SIZE,
26 },
27 {
28 .fa_id = FLASH_AREA_2_ID,
29 .fa_device_id = FLASH_DEVICE_ID,
30 .fa_off = FLASH_AREA_2_OFFSET,
31 .fa_size = FLASH_AREA_2_SIZE,
32 },
33#if (MCUBOOT_IMAGE_NUMBER == 2)
34 {
35 .fa_id = FLASH_AREA_1_ID,
36 .fa_device_id = FLASH_DEVICE_ID,
37 .fa_off = FLASH_AREA_1_OFFSET,
38 .fa_size = FLASH_AREA_1_SIZE,
39 },
40 {
41 .fa_id = FLASH_AREA_3_ID,
42 .fa_device_id = FLASH_DEVICE_ID,
43 .fa_off = FLASH_AREA_3_OFFSET,
44 .fa_size = FLASH_AREA_3_SIZE,
45 },
46#endif
47 {
48 .fa_id = FLASH_AREA_SCRATCH_ID,
49 .fa_device_id = FLASH_DEVICE_ID,
50 .fa_off = FLASH_AREA_SCRATCH_OFFSET,
51 .fa_size = FLASH_AREA_SCRATCH_SIZE,
52 },
53};
54
55static const int flash_map_entry_num = ARRAY_SIZE(flash_map);
56
57/*
58 * `open` a flash area. The `area` in this case is not the individual
59 * sectors, but describes the particular flash area in question.
60 */
61int flash_area_open(uint8_t id, const struct flash_area **area)
62{
63 int i;
64
65 BOOT_LOG_DBG("area %d", id);
66
67 for (i = 0; i < flash_map_entry_num; i++) {
68 if (id == flash_map[i].fa_id) {
69 break;
70 }
71 }
72 if (i == flash_map_entry_num) {
73 return -1;
74 }
75
76 *area = &flash_map[i];
77 return 0;
78}
79
80void flash_area_close(const struct flash_area *area)
81{
82 /* Nothing to do. */
83}
84
85int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
86 uint32_t len)
87{
88 BOOT_LOG_DBG("read area=%d, off=%#x, len=%#x", area->fa_id, off, len);
89 return FLASH_DEV_NAME.ReadData(area->fa_off + off, dst, len);
90}
91
92int flash_area_write(const struct flash_area *area, uint32_t off,
93 const void *src, uint32_t len)
94{
95 BOOT_LOG_DBG("write area=%d, off=%#x, len=%#x", area->fa_id, off, len);
96 return FLASH_DEV_NAME.ProgramData(area->fa_off + off, src, len);
97}
98
99int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
100{
101 ARM_FLASH_INFO *flash_info;
102 uint32_t deleted_len = 0;
103 int32_t rc = 0;
104
105 BOOT_LOG_DBG("erase area=%d, off=%#x, len=%#x", area->fa_id, off, len);
106 flash_info = FLASH_DEV_NAME.GetInfo();
107
108 if (flash_info->sector_info == NULL) {
109 /* Uniform sector layout */
110 while (deleted_len < len) {
111 rc = FLASH_DEV_NAME.EraseSector(area->fa_off + off);
112 if (rc != 0) {
113 break;
114 }
115 deleted_len += flash_info->sector_size;
116 off += flash_info->sector_size;
117 }
118 } else {
119 /* Inhomogeneous sector layout, explicitly defined
120 * Currently not supported.
121 */
122 }
123
124 return rc;
125}
126
127uint32_t flash_area_align(const struct flash_area *area)
128{
129 ARM_FLASH_INFO *flash_info;
130
131 flash_info = FLASH_DEV_NAME.GetInfo();
132 return flash_info->program_unit;
133}