1 /*
2 * Copyright (c) 2017-2024 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 * @since 1.11
22 * @version 1.1.0
23 * @ingroup storage_apis
24 * @{
25 */
26
27 /*
28 * This API makes it possible to operate on flash areas easily and
29 * effectively.
30 *
31 * The system contains global data about flash areas. Every area
32 * contains an ID number, offset, and length.
33 */
34
35 /**
36 *
37 */
38 #include <zephyr/types.h>
39 #include <stddef.h>
40 #include <sys/types.h>
41 #include <zephyr/device.h>
42 #include <zephyr/devicetree.h>
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 /**
49 * @brief Flash partition
50 *
51 * This structure represents a fixed-size partition on a flash device.
52 * Each partition contains one or more flash sectors.
53 */
54 struct flash_area {
55 /** ID number */
56 uint8_t fa_id;
57 uint16_t pad16;
58 /** Start offset from the beginning of the flash device */
59 off_t fa_off;
60 /** Total size */
61 size_t fa_size;
62 /** Backing flash device */
63 const struct device *fa_dev;
64 #if CONFIG_FLASH_MAP_LABELS
65 /** Partition label if defined in DTS. Otherwise nullptr; */
66 const char *fa_label;
67 #endif
68 };
69
70 /**
71 * @brief Structure for transfer flash sector boundaries
72 *
73 * This template is used for presentation of flash memory structure. It
74 * consumes much less RAM than @ref flash_area
75 */
76 struct flash_sector {
77 /** Sector offset from the beginning of the flash device */
78 off_t fs_off;
79 /** Sector size in bytes */
80 size_t fs_size;
81 };
82
83 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY)
84 /**
85 * @brief Structure for verify flash region integrity
86 *
87 * This is used to pass data to be used to check flash integrity using SHA-256
88 * algorithm.
89 */
90 struct flash_area_check {
91 const uint8_t *match; /** 256 bits match vector */
92 size_t clen; /** Content len to be compared */
93 size_t off; /** Start Offset */
94 uint8_t *rbuf; /** Temporary read buffer */
95 size_t rblen; /** Size of read buffer */
96 };
97
98 /**
99 * Verify flash memory length bytes integrity from a flash area. The start
100 * point is indicated by an offset value.
101 *
102 * @param[in] fa Flash area
103 * @param[in] fic Flash area check integrity data
104 *
105 * @return 0 on success, negative errno code on fail
106 */
107 int flash_area_check_int_sha256(const struct flash_area *fa,
108 const struct flash_area_check *fac);
109 #endif
110
111 /**
112 * @brief Retrieve partitions flash area from the flash_map.
113 *
114 * Function Retrieves flash_area from flash_map for given partition.
115 *
116 * @param[in] id ID of the flash partition.
117 * @param[out] fa Pointer which has to reference flash_area. If
118 * @p ID is unknown, it will be NULL on output.
119 *
120 * @return 0 on success, -EACCES if the flash_map is not available ,
121 * -ENOENT if @p ID is unknown, -ENODEV if there is no driver attached
122 * to the area.
123 */
124 int flash_area_open(uint8_t id, const struct flash_area **fa);
125
126 /**
127 * @brief Close flash_area
128 *
129 * Reserved for future usage and external projects compatibility reason.
130 * Currently is NOP.
131 *
132 * @param[in] fa Flash area to be closed.
133 */
134 void flash_area_close(const struct flash_area *fa);
135
136 /**
137 * @brief Verify that a device assigned to flash area is ready for use.
138 *
139 * Indicates whether the provided flash area has a device known to be
140 * in a state where it can be used with Flash Map API.
141 *
142 * This can be used with struct flash_area pointers captured from FIXED_PARTITION().
143 * At minimum this means that the device has been successfully initialized.
144 *
145 * @param fa pointer to flash_area object to check.
146 *
147 * @retval true If the device is ready for use.
148 * @retval false If the device is not ready for use or if a NULL pointer is
149 * passed as flash area pointer or device pointer within flash area object
150 * is NULL.
151 */
flash_area_device_is_ready(const struct flash_area * fa)152 static ALWAYS_INLINE bool flash_area_device_is_ready(const struct flash_area *fa)
153 {
154 return (fa != NULL && device_is_ready(fa->fa_dev));
155 }
156
157 /**
158 * @brief Read flash area data
159 *
160 * Read data from flash area. Area readout boundaries are asserted before read
161 * request. API has the same limitation regard read-block alignment and size
162 * as wrapped flash driver.
163 *
164 * @param[in] fa Flash area
165 * @param[in] off Offset relative from beginning of flash area to read
166 * @param[out] dst Buffer to store read data
167 * @param[in] len Number of bytes to read
168 *
169 * @return 0 on success, negative errno code on fail.
170 */
171 int flash_area_read(const struct flash_area *fa, off_t off, void *dst,
172 size_t len);
173
174 /**
175 * @brief Write data to flash area
176 *
177 * Write data to flash area. Area write boundaries are asserted before write
178 * request. API has the same limitation regard write-block alignment and size
179 * as wrapped flash driver.
180 *
181 * @param[in] fa Flash area
182 * @param[in] off Offset relative from beginning of flash area to write
183 * @param[in] src Buffer with data to be written
184 * @param[in] len Number of bytes to write
185 *
186 * @return 0 on success, negative errno code on fail.
187 */
188 int flash_area_write(const struct flash_area *fa, off_t off, const void *src,
189 size_t len);
190
191 /**
192 * @brief Copy flash memory from one flash area to another.
193 *
194 * Copy data to flash area. Area boundaries are asserted before copy
195 * request.
196 *
197 * For more information, see flash_copy().
198 *
199 * @param[in] src_fa Source Flash area
200 * @param[in] src_off Offset relative from beginning of source flash area.
201 * @param[in] dst_fa Destination Flash area
202 * @param[in] dst_off Offset relative from beginning of destination flash area.
203 * @param[in] len Number of bytes to copy, in bytes.
204 * @param[out] buf Pointer to a buffer of size @a buf_size.
205 * @param[in] buf_size Size of the buffer pointed to by @a buf.
206 *
207 * @return 0 on success, negative errno code on fail.
208 */
209 int flash_area_copy(const struct flash_area *src_fa, off_t src_off,
210 const struct flash_area *dst_fa, off_t dst_off,
211 off_t len, uint8_t *buf, size_t buf_size);
212
213 /**
214 * @brief Erase flash area
215 *
216 * Erase given flash area range. Area boundaries are asserted before erase
217 * request. API has the same limitation regard erase-block alignment and size
218 * as wrapped flash driver.
219 *
220 * @param[in] fa Flash area
221 * @param[in] off Offset relative from beginning of flash area.
222 * @param[in] len Number of bytes to be erase
223 *
224 * @return 0 on success, negative errno code on fail.
225 */
226 int flash_area_erase(const struct flash_area *fa, off_t off, size_t len);
227
228 /**
229 * @brief Erase flash area or fill with erase-value
230 *
231 * On program-erase devices this function behaves exactly like flash_area_erase.
232 * On RAM non-volatile device it will call erase, if driver provides such
233 * callback, or will fill given range with erase-value defined by driver.
234 * This function should be only used by code that has not been written
235 * to directly support devices that do not require erase and rely on
236 * device being erased prior to some operations.
237 * Note that emulated erase, on devices that do not require, is done
238 * via write, which affects endurance of device.
239 *
240 * @see flash_area_erase()
241 * @see flash_flatten()
242 *
243 * @param[in] fa Flash area
244 * @param[in] off Offset relative from beginning of flash area.
245 * @param[in] len Number of bytes to be erase
246 *
247 * @return 0 on success, negative errno code on fail.
248 */
249 int flash_area_flatten(const struct flash_area *fa, off_t off, size_t len);
250
251 /**
252 * @brief Get write block size of the flash area
253 *
254 * Currently write block size might be treated as read block size, although
255 * most of drivers supports unaligned readout.
256 *
257 * @param[in] fa Flash area
258 *
259 * @return Alignment restriction for flash writes in [B].
260 */
261 uint32_t flash_area_align(const struct flash_area *fa);
262
263 /**
264 * Retrieve info about sectors within the area.
265 *
266 * @param[in] fa_id Given flash area ID
267 * @param[in,out] count On input Capacity of @p sectors, on output number of
268 * sectors Retrieved.
269 * @param[out] sectors buffer for sectors data
270 *
271 * @return 0 on success, negative errno code on fail. Especially returns
272 * -ENOMEM if There are too many flash pages on the flash_area to fit in the
273 * array.
274 */
275 int flash_area_get_sectors(int fa_id, uint32_t *count,
276 struct flash_sector *sectors);
277
278 /**
279 * Retrieve info about sectors within the area.
280 *
281 * @param[in] fa pointer to flash area object.
282 * @param[in,out] count On input Capacity of @p sectors, on output number of
283 * sectors retrieved.
284 * @param[out] sectors buffer for sectors data
285 *
286 * @return 0 on success, negative errno code on fail. Especially returns
287 * -ENOMEM if There are too many flash pages on the flash_area to fit in the
288 * array.
289 */
290 int flash_area_sectors(const struct flash_area *fa, uint32_t *count, struct flash_sector *sectors);
291
292 /**
293 * Flash map iteration callback
294 *
295 * @param fa flash area
296 * @param user_data User supplied data
297 *
298 */
299 typedef void (*flash_area_cb_t)(const struct flash_area *fa,
300 void *user_data);
301
302 /**
303 * Iterate over flash map
304 *
305 * @param user_cb User callback
306 * @param user_data User supplied data
307 */
308 void flash_area_foreach(flash_area_cb_t user_cb, void *user_data);
309
310 /**
311 * Check whether given flash area has supporting flash driver
312 * in the system.
313 *
314 * @param[in] fa Flash area.
315 *
316 * @return 1 On success. -ENODEV if no driver match.
317 */
318 int flash_area_has_driver(const struct flash_area *fa);
319
320 /**
321 * Get driver for given flash area.
322 *
323 * @param[in] fa Flash area.
324 *
325 * @return device driver.
326 */
327 const struct device *flash_area_get_device(const struct flash_area *fa);
328
329 #if CONFIG_FLASH_MAP_LABELS
330 /**
331 * Get the label property from the device tree
332 *
333 * @param[in] fa Flash area.
334 *
335 * @return The label property if it is defined, otherwise NULL
336 */
337 const char *flash_area_label(const struct flash_area *fa);
338 #endif
339
340 /**
341 * Get the value expected to be read when accessing any erased
342 * flash byte.
343 * This API is compatible with the MCUBoot's porting layer.
344 *
345 * @param fa Flash area.
346 *
347 * @return Byte value of erase memory.
348 */
349 uint8_t flash_area_erased_val(const struct flash_area *fa);
350
351 /**
352 * Returns non-0 value if fixed-partition or fixed-subpartition of given
353 * DTS node label exists.
354 *
355 * @param label DTS node label
356 *
357 * @return non-0 if fixed-partition node exists and is enabled;
358 * 0 if node does not exist, is not enabled or is not fixed-partition.
359 */
360 #define FIXED_PARTITION_EXISTS(label) \
361 UTIL_OR(DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(label)), \
362 DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)))
363
364 /**
365 * Get flash area ID from fixed-partition DTS node label
366 *
367 * @param label DTS node label of a partition
368 *
369 * @return flash area ID
370 */
371 #define FIXED_PARTITION_ID(label) DT_FIXED_PARTITION_ID(DT_NODELABEL(label))
372
373 /**
374 * Get fixed-partition or fixed-subpartition offset from DTS node label
375 *
376 * @param label DTS node label of a partition
377 *
378 * @return fixed-partition offset, as defined for the partition in DTS.
379 */
380 #define FIXED_PARTITION_OFFSET(label) DT_REG_ADDR(DT_NODELABEL(label))
381
382 /**
383 * Get fixed-partition or fixed-subpartition address from DTS node label
384 *
385 * @param label DTS node label of a partition or subpartition
386 *
387 * @return fixed-partition address, as defined for the partition in DTS.
388 */
389 #define FIXED_PARTITION_ADDRESS(label) \
390 (COND_CODE_1(DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)), \
391 (DT_FIXED_SUBPARTITION_ADDR(DT_NODELABEL(label))), \
392 (DT_FIXED_PARTITION_ADDR(DT_NODELABEL(label)))))
393
394 /**
395 * Get fixed-partition or fixed-subpartition address from DTS node
396 *
397 * @param node DTS node of a partition
398 *
399 * @return fixed-partition address, as defined for the partition in DTS.
400 */
401 #define FIXED_PARTITION_NODE_ADDRESS(node) \
402 (COND_CODE_1(DT_FIXED_SUBPARTITION_EXISTS(node), \
403 (DT_FIXED_SUBPARTITION_ADDR(node)), \
404 (DT_FIXED_PARTITION_ADDR(node))))
405
406 /**
407 * Get fixed-partition offset from DTS node
408 *
409 * @param node DTS node of a partition
410 *
411 * @return fixed-partition offset, as defined for the partition in DTS.
412 */
413 #define FIXED_PARTITION_NODE_OFFSET(node) DT_REG_ADDR(node)
414
415 /**
416 * Get fixed-partition size for DTS node label
417 *
418 * @param label DTS node label
419 *
420 * @return fixed-partition offset, as defined for the partition in DTS.
421 */
422 #define FIXED_PARTITION_SIZE(label) DT_REG_SIZE(DT_NODELABEL(label))
423
424 /**
425 * Get fixed-partition size for DTS node
426 *
427 * @param node DTS node of a partition
428 *
429 * @return fixed-partition size, as defined for the partition in DTS.
430 */
431 #define FIXED_PARTITION_NODE_SIZE(node) DT_REG_SIZE(node)
432
433 /**
434 * Get device pointer for device the area/partition resides on
435 *
436 * @param label DTS node label of a partition
437 *
438 * @return const struct device type pointer
439 */
440 #define FLASH_AREA_DEVICE(label) \
441 DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODE_BY_FIXED_PARTITION_LABEL(label)))
442
443 /**
444 * Get device pointer for device the area/partition resides on
445 *
446 * @param label DTS node label of a partition
447 *
448 * @return Pointer to a device.
449 */
450 #define FIXED_PARTITION_DEVICE(label) \
451 DEVICE_DT_GET(COND_CODE_1( \
452 DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)), \
453 (DT_MTD_FROM_FIXED_SUBPARTITION(DT_NODELABEL(label))), \
454 (DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label)))))
455 /**
456 * Get device pointer for device the area/partition resides on
457 *
458 * @param node DTS node of a partition
459 *
460 * @return Pointer to a device.
461 */
462 #define FIXED_PARTITION_NODE_DEVICE(node) \
463 DEVICE_DT_GET(COND_CODE_1( \
464 DT_FIXED_SUBPARTITION_EXISTS(node), \
465 (DT_MTD_FROM_FIXED_SUBPARTITION(node)), \
466 (DT_MTD_FROM_FIXED_PARTITION(node))))
467
468 /**
469 * Get the node identifier of the flash controller the area/partition resides on
470 *
471 * @param label DTS node label of a partition
472 *
473 * @return Pointer to a device.
474 */
475 #define FIXED_PARTITION_MTD(label) \
476 COND_CODE_1( \
477 DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)), \
478 (DT_MTD_FROM_FIXED_SUBPARTITION(DT_NODELABEL(label))), \
479 (DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))))
480
481 /**
482 * Get the node identifier of the flash controller the area/partition resides on
483 *
484 * @param node DTS node of a partition
485 *
486 * @return Pointer to a device.
487 */
488 #define FIXED_PARTITION_NODE_MTD(node) \
489 COND_CODE_1( \
490 DT_FIXED_SUBPARTITION_EXISTS(node), \
491 (DT_MTD_FROM_FIXED_SUBPARTITION(node)), \
492 (DT_MTD_FROM_FIXED_PARTITION(node)))
493
494 /**
495 * Get pointer to flash_area object by partition label
496 *
497 * @param label DTS node label of a partition
498 *
499 * @return Pointer to flash_area type object representing partition
500 */
501 #define FIXED_PARTITION(label) FIXED_PARTITION_1(DT_NODELABEL(label))
502
503 /**
504 * Get pointer to flash_area object by partition node in DTS
505 *
506 * @param node DTS node of a partition
507 *
508 * @return Pointer to flash_area type object representing partition
509 */
510 #define FIXED_PARTITION_BY_NODE(node) FIXED_PARTITION_1(node)
511
512 /** @cond INTERNAL_HIDDEN */
513 #define FIXED_PARTITION_1(node) FIXED_PARTITION_0(DT_DEP_ORD(node))
514 #define FIXED_PARTITION_0(ord) \
515 ((const struct flash_area *)&DT_CAT(global_fixed_partition_ORD_, ord))
516
517 #define DECLARE_PARTITION(node) DECLARE_PARTITION_0(DT_DEP_ORD(node))
518 #define DECLARE_PARTITION_0(ord) \
519 extern const struct flash_area DT_CAT(global_fixed_partition_ORD_, ord);
520 #define FOR_EACH_PARTITION_TABLE(table) DT_FOREACH_CHILD(table, DECLARE_PARTITION)
521
522 /* Generate declarations */
523 DT_FOREACH_STATUS_OKAY(fixed_partitions, FOR_EACH_PARTITION_TABLE)
524
525 #undef DECLARE_PARTITION
526 #undef DECLARE_PARTITION_0
527 #undef FOR_EACH_PARTITION_TABLE
528
529 #define FIXED_SUBPARTITION_1(node) FIXED_SUBPARTITION_0(DT_DEP_ORD(node))
530 #define FIXED_SUBPARTITION_0(ord) \
531 ((const struct flash_area *)&DT_CAT(global_fixed_subpartition_ORD_, ord))
532
533 #define DECLARE_SUBPARTITION(node) DECLARE_SUBPARTITION_0(DT_DEP_ORD(node))
534 #define DECLARE_SUBPARTITION_0(ord) \
535 extern const struct flash_area DT_CAT(global_fixed_subpartition_ORD_, ord);
536 #define FOR_EACH_SUBPARTITION_TABLE(table) DT_FOREACH_CHILD(table, DECLARE_SUBPARTITION)
537
538 /* Generate declarations */
539 DT_FOREACH_STATUS_OKAY(fixed_subpartitions, FOR_EACH_SUBPARTITION_TABLE)
540
541 #undef DECLARE_SUBPARTITION
542 #undef DECLARE_SUBPARTITION_0
543 #undef FOR_EACH_SUBPARTITION_TABLE
544 /** @endcond */
545
546 #ifdef __cplusplus
547 }
548 #endif
549
550 /**
551 * @}
552 */
553
554 #endif /* ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_ */
555