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