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