1 /*
2  * Copyright (c) 2017 Nordic Semiconductor ASA
3  * Copyright (c) 2015 Runtime Inc
4  * Copyright (c) 2023 Sensorfy B.V.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 /**
10  * @file
11  * @brief Public API for flash map
12  */
13 
14 #ifndef ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_
15 #define ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_
16 
17 /**
18  * @brief Abstraction over flash partitions/areas and their drivers
19  *
20  * @defgroup flash_area_api flash area Interface
21  * @ingroup storage_apis
22  * @{
23  */
24 
25 /*
26  * This API makes it possible to operate on flash areas easily and
27  * effectively.
28  *
29  * The system contains global data about flash areas. Every area
30  * contains an ID number, offset, and length.
31  */
32 
33 /**
34  *
35  */
36 #include <zephyr/types.h>
37 #include <stddef.h>
38 #include <sys/types.h>
39 #include <zephyr/device.h>
40 #include <zephyr/devicetree.h>
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /** Provided for compatibility with MCUboot */
47 #define SOC_FLASH_0_ID 0
48 /** Provided for compatibility with MCUboot */
49 #define SPI_FLASH_0_ID 1
50 
51 /**
52  * @brief Flash partition
53  *
54  * This structure represents a fixed-size partition on a flash device.
55  * Each partition contains one or more flash sectors.
56  */
57 struct flash_area {
58 	/** ID number */
59 	uint8_t fa_id;
60 	uint16_t pad16;
61 	/** Start offset from the beginning of the flash device */
62 	off_t fa_off;
63 	/** Total size */
64 	size_t fa_size;
65 	/** Backing flash device */
66 	const struct device *fa_dev;
67 #if CONFIG_FLASH_MAP_LABELS
68 	/** Partition label if defined in DTS. Otherwise nullptr; */
69 	const char *fa_label;
70 #endif
71 };
72 
73 /**
74  * @brief Structure for transfer flash sector boundaries
75  *
76  * This template is used for presentation of flash memory structure. It
77  * consumes much less RAM than @ref flash_area
78  */
79 struct flash_sector {
80 	/** Sector offset from the beginning of the flash device */
81 	off_t fs_off;
82 	/** Sector size in bytes */
83 	size_t fs_size;
84 };
85 
86 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY)
87 /**
88  * @brief Structure for verify flash region integrity
89  *
90  * This is used to pass data to be used to check flash integrity using SHA-256
91  * algorithm.
92  */
93 struct flash_area_check {
94 	const uint8_t *match;		/** 256 bits match vector */
95 	size_t clen;			/** Content len to be compared */
96 	size_t off;			/** Start Offset */
97 	uint8_t *rbuf;			/** Temporary read buffer  */
98 	size_t rblen;			/** Size of read buffer */
99 };
100 
101 /**
102  * Verify flash memory length bytes integrity from a flash area. The start
103  * point is indicated by an offset value.
104  *
105  * @param[in] fa	Flash area
106  * @param[in] fic	Flash area check integrity data
107  *
108  * @return  0 on success, negative errno code on fail
109  */
110 int flash_area_check_int_sha256(const struct flash_area *fa,
111 				const struct flash_area_check *fac);
112 #endif
113 
114 /**
115  * @brief Retrieve partitions flash area from the flash_map.
116  *
117  * Function Retrieves flash_area from flash_map for given partition.
118  *
119  * @param[in]  id ID of the flash partition.
120  * @param[out] fa Pointer which has to reference flash_area. If
121  * @p ID is unknown, it will be NULL on output.
122  *
123  * @return  0 on success, -EACCES if the flash_map is not available ,
124  * -ENOENT if @p ID is unknown, -ENODEV if there is no driver attached
125  * to the area.
126  */
127 int flash_area_open(uint8_t id, const struct flash_area **fa);
128 
129 /**
130  * @brief Close flash_area
131  *
132  * Reserved for future usage and external projects compatibility reason.
133  * Currently is NOP.
134  *
135  * @param[in] fa Flash area to be closed.
136  */
137 void flash_area_close(const struct flash_area *fa);
138 
139 /**
140  * @brief Read flash area data
141  *
142  * Read data from flash area. Area readout boundaries are asserted before read
143  * request. API has the same limitation regard read-block alignment and size
144  * as wrapped flash driver.
145  *
146  * @param[in]  fa  Flash area
147  * @param[in]  off Offset relative from beginning of flash area to read
148  * @param[out] dst Buffer to store read data
149  * @param[in]  len Number of bytes to read
150  *
151  * @return  0 on success, negative errno code on fail.
152  */
153 int flash_area_read(const struct flash_area *fa, off_t off, void *dst,
154 		    size_t len);
155 
156 /**
157  * @brief Write data to flash area
158  *
159  * Write data to flash area. Area write boundaries are asserted before write
160  * request. API has the same limitation regard write-block alignment and size
161  * as wrapped flash driver.
162  *
163  * @param[in]  fa  Flash area
164  * @param[in]  off Offset relative from beginning of flash area to write
165  * @param[in]  src Buffer with data to be written
166  * @param[in]  len Number of bytes to write
167  *
168  * @return  0 on success, negative errno code on fail.
169  */
170 int flash_area_write(const struct flash_area *fa, off_t off, const void *src,
171 		     size_t len);
172 
173 /**
174  * @brief Erase flash area
175  *
176  * Erase given flash area range. Area boundaries are asserted before erase
177  * request. API has the same limitation regard erase-block alignment and size
178  * as wrapped flash driver.
179  *
180  * @param[in] fa  Flash area
181  * @param[in] off Offset relative from beginning of flash area.
182  * @param[in] len Number of bytes to be erase
183  *
184  * @return  0 on success, negative errno code on fail.
185  */
186 int flash_area_erase(const struct flash_area *fa, off_t off, size_t len);
187 
188 /**
189  * @brief Get write block size of the flash area
190  *
191  * Currently write block size might be treated as read block size, although
192  * most of drivers supports unaligned readout.
193  *
194  * @param[in] fa Flash area
195  *
196  * @return Alignment restriction for flash writes in [B].
197  */
198 uint32_t flash_area_align(const struct flash_area *fa);
199 
200 /**
201  * Retrieve info about sectors within the area.
202  *
203  * @param[in]  fa_id    Given flash area ID
204  * @param[out] sectors  buffer for sectors data
205  * @param[in,out] count On input Capacity of @p sectors, on output number of
206  * sectors Retrieved.
207  *
208  * @return  0 on success, negative errno code on fail. Especially returns
209  * -ENOMEM if There are too many flash pages on the flash_area to fit in the
210  * array.
211  */
212 int flash_area_get_sectors(int fa_id, uint32_t *count,
213 			   struct flash_sector *sectors);
214 
215 /**
216  * Flash map iteration callback
217  *
218  * @param fa flash area
219  * @param user_data User supplied data
220  *
221  */
222 typedef void (*flash_area_cb_t)(const struct flash_area *fa,
223 				void *user_data);
224 
225 /**
226  * Iterate over flash map
227  *
228  * @param user_cb User callback
229  * @param user_data User supplied data
230  */
231 void flash_area_foreach(flash_area_cb_t user_cb, void *user_data);
232 
233 /**
234  * Check whether given flash area has supporting flash driver
235  * in the system.
236  *
237  * @param[in] fa Flash area.
238  *
239  * @return 1 On success. -ENODEV if no driver match.
240  */
241 int flash_area_has_driver(const struct flash_area *fa);
242 
243 /**
244  * Get driver for given flash area.
245  *
246  * @param[in] fa Flash area.
247  *
248  * @return device driver.
249  */
250 const struct device *flash_area_get_device(const struct flash_area *fa);
251 
252 #if CONFIG_FLASH_MAP_LABELS
253 /**
254  * Get the label property from the device tree
255  *
256  * @param[in] fa Flash area.
257  *
258  * @return The label property if it is defined, otherwise NULL
259  */
260 const char *flash_area_label(const struct flash_area *fa);
261 #endif
262 
263 /**
264  * Get the value expected to be read when accessing any erased
265  * flash byte.
266  * This API is compatible with the MCUBoot's porting layer.
267  *
268  * @param fa Flash area.
269  *
270  * @return Byte value of erase memory.
271  */
272 uint8_t flash_area_erased_val(const struct flash_area *fa);
273 
274 #define FLASH_AREA_LABEL_EXISTS(label) __DEPRECATED_MACRO \
275 	DT_HAS_FIXED_PARTITION_LABEL(label)
276 
277 #define FLASH_AREA_LABEL_STR(lbl) __DEPRECATED_MACRO \
278 	DT_PROP(DT_NODE_BY_FIXED_PARTITION_LABEL(lbl), label)
279 
280 #define FLASH_AREA_ID(label) __DEPRECATED_MACRO \
281 	DT_FIXED_PARTITION_ID(DT_NODE_BY_FIXED_PARTITION_LABEL(label))
282 
283 #define FLASH_AREA_OFFSET(label) __DEPRECATED_MACRO \
284 	DT_REG_ADDR(DT_NODE_BY_FIXED_PARTITION_LABEL(label))
285 
286 #define FLASH_AREA_SIZE(label) __DEPRECATED_MACRO \
287 	DT_REG_SIZE(DT_NODE_BY_FIXED_PARTITION_LABEL(label))
288 
289 /**
290  * Returns non-0 value if fixed-partition of given DTS node label exists.
291  *
292  * @param label DTS node label
293  *
294  * @return non-0 if fixed-partition node exists and is enabled;
295  *	   0 if node does not exist, is not enabled or is not fixed-partition.
296  */
297 #define FIXED_PARTITION_EXISTS(label) DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(label))
298 
299 /**
300  * Get flash area ID from fixed-partition DTS node label
301  *
302  * @param label DTS node label of a partition
303  *
304  * @return flash area ID
305  */
306 #define FIXED_PARTITION_ID(label) DT_FIXED_PARTITION_ID(DT_NODELABEL(label))
307 
308 /**
309  * Get fixed-partition offset from DTS node label
310  *
311  * @param label DTS node label of a partition
312  *
313  * @return fixed-partition offset, as defined for the partition in DTS.
314  */
315 #define FIXED_PARTITION_OFFSET(label) DT_REG_ADDR(DT_NODELABEL(label))
316 
317 /**
318  * Get fixed-partition size for DTS node label
319  *
320  * @param label DTS node label
321  *
322  * @return fixed-partition offset, as defined for the partition in DTS.
323  */
324 #define FIXED_PARTITION_SIZE(label) DT_REG_SIZE(DT_NODELABEL(label))
325 
326 /**
327  * Get device pointer for device the area/partition resides on
328  *
329  * @param label DTS node label of a partition
330  *
331  * @return const struct device type pointer
332  */
333 #define FLASH_AREA_DEVICE(label) \
334 	DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODE_BY_FIXED_PARTITION_LABEL(label)))
335 
336 /**
337  * Get device pointer for device the area/partition resides on
338  *
339  * @param label DTS node label of a partition
340  *
341  * @return Pointer to a device.
342  */
343 #define FIXED_PARTITION_DEVICE(label) \
344 	DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label)))
345 
346 #ifdef __cplusplus
347 }
348 #endif
349 
350 /**
351  * @}
352  */
353 
354 #endif /* ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_ */
355