1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  * Copyright (c) 2015 Runtime Inc
4  * Copyright (c) 2020 Embedded Planet
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the Licens
18  */
19 
20 #ifndef H_UTIL_FLASH_MAP_
21 #define H_UTIL_FLASH_MAP_
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /**
28  *
29  * Provides abstraction of flash regions for type of use.
30  * I.e. dude where's my image?
31  *
32  * System will contain a map which contains flash areas. Every
33  * region will contain flash identifier, offset within flash and length.
34  *
35  * 1. This system map could be in a file within filesystem (Initializer
36  * must know/figure out where the filesystem is at).
37  * 2. Map could be at fixed location for project (compiled to code)
38  * 3. Map could be at specific place in flash (put in place at mfg time).
39  *
40  * Note that the map you use must be valid for BSP it's for,
41  * match the linker scripts when platform executes from flash,
42  * and match the target offset specified in download script.
43  */
44 #include <inttypes.h>
45 
46 /**
47  * @brief Structure describing an area on a flash device.
48  *
49  * Multiple flash devices may be available in the system, each of
50  * which may have its own areas. For this reason, flash areas track
51  * which flash device they are part of.
52  */
53 struct flash_area {
54     /**
55      * This flash area's ID; unique in the system.
56      */
57     uint8_t fa_id;
58 
59     /**
60      * ID of the flash device this area is a part of.
61      */
62     uint8_t fa_device_id;
63 
64     uint16_t pad16;
65 
66     /**
67      * This area's offset, relative to the beginning of its flash
68      * device's storage.
69      */
70     uint32_t fa_off;
71 
72     /**
73      * This area's size, in bytes.
74      */
75     uint32_t fa_size;
76 };
77 
flash_area_get_id(const struct flash_area * fa)78 static inline uint8_t flash_area_get_id(const struct flash_area *fa)
79 {
80     return fa->fa_id;
81 }
82 
flash_area_get_device_id(const struct flash_area * fa)83 static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
84 {
85     return fa->fa_device_id;
86 }
87 
flash_area_get_off(const struct flash_area * fa)88 static inline uint32_t flash_area_get_off(const struct flash_area *fa)
89 {
90     return fa->fa_off;
91 }
92 
flash_area_get_size(const struct flash_area * fa)93 static inline uint32_t flash_area_get_size(const struct flash_area *fa)
94 {
95     return fa->fa_size;
96 }
97 
98 /**
99  * @brief Structure describing a sector within a flash area.
100  *
101  * Each sector has an offset relative to the start of its flash area
102  * (NOT relative to the start of its flash device), and a size. A
103  * flash area may contain sectors with different sizes.
104  */
105 struct flash_sector {
106     /**
107      * Offset of this sector, from the start of its flash area (not device).
108      */
109     uint32_t fs_off;
110 
111     /**
112      * Size of this sector, in bytes.
113      */
114     uint32_t fs_size;
115 };
116 
flash_sector_get_off(const struct flash_sector * fs)117 static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
118 {
119     return fs->fs_off;
120 }
121 
flash_sector_get_size(const struct flash_sector * fs)122 static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
123 {
124     return fs->fs_size;
125 }
126 
127 /*
128  * Start using flash area.
129  */
130 int flash_area_open(uint8_t id, const struct flash_area ** fapp);
131 
132 void flash_area_close(const struct flash_area * fap);
133 
134 /*
135  * Read/write/erase. Offset is relative from beginning of flash area.
136  */
137 int flash_area_read(const struct flash_area * fap, uint32_t off, void *dst,
138   uint32_t len);
139 int flash_area_write(const struct flash_area * fap, uint32_t off, const void *src,
140   uint32_t len);
141 int flash_area_erase(const struct flash_area * fap, uint32_t off, uint32_t len);
142 
143 /*
144  * Alignment restriction for flash writes.
145  */
146 uint32_t flash_area_align(const struct flash_area * fap);
147 
148 /*
149  * What is value is read from erased flash bytes.
150  */
151 uint8_t flash_area_erased_val(const struct flash_area * fap);
152 
153 /*
154  * Given flash area ID, return info about sectors within the area.
155  *
156  * Note: the sectors array has size MCUBOOT_MAX_IMG_SECTORS, and only that many elements should
157  * be stored into it.  However, if the flash area has more than MCUBOOT_MAX_IMG_SECTORS sectors,
158  * the count variable should be set to indicate the real sector count.  This will trigger the appropriate
159  * warning to be printed.
160  */
161 int flash_area_get_sectors(int fa_id, uint32_t *count,
162   struct flash_sector *sectors);
163 
164 
165 int flash_area_id_from_image_slot(int slot);
166 int flash_area_id_from_multi_image_slot(int image_index, int slot);
167 
168 
169 /**
170  * Converts the specified flash area ID and image index (in multi-image setup)
171  * to an image slot index.
172  *
173  * Returns image slot index (0 or 1), or -1 if ID doesn't correspond to an image
174  * slot.
175  */
176 int flash_area_id_to_multi_image_slot(int image_index, int area_id);
177 
178 #ifdef __cplusplus
179 }
180 #endif
181 
182 #endif /* H_UTIL_FLASH_MAP_ */
183