blob: a45355a5e535fc712bad08e4ffec7030900f108e [file] [log] [blame]
David Vinczecea8b592019-10-29 16:09:51 +01001/*
Sherry Zhang6e0f3242021-03-08 12:18:31 +08002 * Copyright (c) 2019-2021, 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"
Sherry Zhang6e0f3242021-03-08 12:18:31 +080012#include "bootutil_priv.h"
David Vinczecea8b592019-10-29 16:09:51 +010013#include "bootutil/bootutil_log.h"
14#include "Driver_Flash.h"
15
Mark Horvath8576e382021-03-12 10:24:55 +010016extern const struct flash_area flash_map[];
17extern const int flash_map_entry_num;
David Vinczecea8b592019-10-29 16:09:51 +010018
19/*
Sherry Zhang6e0f3242021-03-08 12:18:31 +080020 * Check the target address in the flash_area_xxx operation.
21 */
22static bool is_range_valid(const struct flash_area *area,
23 uint32_t off,
24 uint32_t len)
25{
26 uint32_t size;
27
28 if (!area) {
29 return false;
30 }
31
32 if (!boot_u32_safe_add(&size, off, len)) {
33 return false;
34 }
35
36 if (area->fa_size < size) {
37 return false;
38 }
39
40 return true;
41}
42
43/*
David Vinczecea8b592019-10-29 16:09:51 +010044 * `open` a flash area. The `area` in this case is not the individual
45 * sectors, but describes the particular flash area in question.
46 */
47int flash_area_open(uint8_t id, const struct flash_area **area)
48{
49 int i;
50
51 BOOT_LOG_DBG("area %d", id);
52
53 for (i = 0; i < flash_map_entry_num; i++) {
54 if (id == flash_map[i].fa_id) {
55 break;
56 }
57 }
58 if (i == flash_map_entry_num) {
59 return -1;
60 }
61
62 *area = &flash_map[i];
63 return 0;
64}
65
66void flash_area_close(const struct flash_area *area)
67{
68 /* Nothing to do. */
69}
70
71int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
72 uint32_t len)
73{
74 BOOT_LOG_DBG("read area=%d, off=%#x, len=%#x", area->fa_id, off, len);
Sherry Zhang6e0f3242021-03-08 12:18:31 +080075
76 if (!is_range_valid(area, off, len)) {
77 return -1;
78 }
79
Michel Jaouen26f6c022020-12-03 10:37:22 +010080 return DRV_FLASH_AREA(area)->ReadData(area->fa_off + off, dst, len);
David Vinczecea8b592019-10-29 16:09:51 +010081}
82
83int flash_area_write(const struct flash_area *area, uint32_t off,
84 const void *src, uint32_t len)
85{
86 BOOT_LOG_DBG("write area=%d, off=%#x, len=%#x", area->fa_id, off, len);
Sherry Zhang6e0f3242021-03-08 12:18:31 +080087
88 if (!is_range_valid(area, off, len)) {
89 return -1;
90 }
91
Michel Jaouen26f6c022020-12-03 10:37:22 +010092 return DRV_FLASH_AREA(area)->ProgramData(area->fa_off + off, src, len);
David Vinczecea8b592019-10-29 16:09:51 +010093}
94
95int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
96{
97 ARM_FLASH_INFO *flash_info;
98 uint32_t deleted_len = 0;
99 int32_t rc = 0;
100
101 BOOT_LOG_DBG("erase area=%d, off=%#x, len=%#x", area->fa_id, off, len);
Sherry Zhang6e0f3242021-03-08 12:18:31 +0800102
103 if (!is_range_valid(area, off, len)) {
104 return -1;
105 }
106
Michel Jaouen26f6c022020-12-03 10:37:22 +0100107 flash_info = DRV_FLASH_AREA(area)->GetInfo();
David Vinczecea8b592019-10-29 16:09:51 +0100108
109 if (flash_info->sector_info == NULL) {
110 /* Uniform sector layout */
111 while (deleted_len < len) {
Michel Jaouen26f6c022020-12-03 10:37:22 +0100112 rc = DRV_FLASH_AREA(area)->EraseSector(area->fa_off + off);
David Vinczecea8b592019-10-29 16:09:51 +0100113 if (rc != 0) {
114 break;
115 }
116 deleted_len += flash_info->sector_size;
117 off += flash_info->sector_size;
118 }
119 } else {
120 /* Inhomogeneous sector layout, explicitly defined
121 * Currently not supported.
122 */
123 }
124
125 return rc;
126}
127
128uint32_t flash_area_align(const struct flash_area *area)
129{
130 ARM_FLASH_INFO *flash_info;
131
Michel Jaouen26f6c022020-12-03 10:37:22 +0100132 flash_info = DRV_FLASH_AREA(area)->GetInfo();
David Vinczecea8b592019-10-29 16:09:51 +0100133 return flash_info->program_unit;
134}