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.0.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 /** Provided for compatibility with MCUboot */
49 #define SOC_FLASH_0_ID 0
50 /** Provided for compatibility with MCUboot */
51 #define SPI_FLASH_0_ID 1
52 
53 /**
54  * @brief Flash partition
55  *
56  * This structure represents a fixed-size partition on a flash device.
57  * Each partition contains one or more flash sectors.
58  */
59 struct flash_area {
60 	/** ID number */
61 	uint8_t fa_id;
62 	uint16_t pad16;
63 	/** Start offset from the beginning of the flash device */
64 	off_t fa_off;
65 	/** Total size */
66 	size_t fa_size;
67 	/** Backing flash device */
68 	const struct device *fa_dev;
69 #if CONFIG_FLASH_MAP_LABELS
70 	/** Partition label if defined in DTS. Otherwise nullptr; */
71 	const char *fa_label;
72 #endif
73 };
74 
75 /**
76  * @brief Structure for transfer flash sector boundaries
77  *
78  * This template is used for presentation of flash memory structure. It
79  * consumes much less RAM than @ref flash_area
80  */
81 struct flash_sector {
82 	/** Sector offset from the beginning of the flash device */
83 	off_t fs_off;
84 	/** Sector size in bytes */
85 	size_t fs_size;
86 };
87 
88 #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY)
89 /**
90  * @brief Structure for verify flash region integrity
91  *
92  * This is used to pass data to be used to check flash integrity using SHA-256
93  * algorithm.
94  */
95 struct flash_area_check {
96 	const uint8_t *match;		/** 256 bits match vector */
97 	size_t clen;			/** Content len to be compared */
98 	size_t off;			/** Start Offset */
99 	uint8_t *rbuf;			/** Temporary read buffer  */
100 	size_t rblen;			/** Size of read buffer */
101 };
102 
103 /**
104  * Verify flash memory length bytes integrity from a flash area. The start
105  * point is indicated by an offset value.
106  *
107  * @param[in] fa	Flash area
108  * @param[in] fic	Flash area check integrity data
109  *
110  * @return  0 on success, negative errno code on fail
111  */
112 int flash_area_check_int_sha256(const struct flash_area *fa,
113 				const struct flash_area_check *fac);
114 #endif
115 
116 /**
117  * @brief Retrieve partitions flash area from the flash_map.
118  *
119  * Function Retrieves flash_area from flash_map for given partition.
120  *
121  * @param[in]  id ID of the flash partition.
122  * @param[out] fa Pointer which has to reference flash_area. If
123  * @p ID is unknown, it will be NULL on output.
124  *
125  * @return  0 on success, -EACCES if the flash_map is not available ,
126  * -ENOENT if @p ID is unknown, -ENODEV if there is no driver attached
127  * to the area.
128  */
129 int flash_area_open(uint8_t id, const struct flash_area **fa);
130 
131 /**
132  * @brief Close flash_area
133  *
134  * Reserved for future usage and external projects compatibility reason.
135  * Currently is NOP.
136  *
137  * @param[in] fa Flash area to be closed.
138  */
139 void flash_area_close(const struct flash_area *fa);
140 
141 /**
142  * @brief Read flash area data
143  *
144  * Read data from flash area. Area readout boundaries are asserted before read
145  * request. API has the same limitation regard read-block alignment and size
146  * as wrapped flash driver.
147  *
148  * @param[in]  fa  Flash area
149  * @param[in]  off Offset relative from beginning of flash area to read
150  * @param[out] dst Buffer to store read data
151  * @param[in]  len Number of bytes to read
152  *
153  * @return  0 on success, negative errno code on fail.
154  */
155 int flash_area_read(const struct flash_area *fa, off_t off, void *dst,
156 		    size_t len);
157 
158 /**
159  * @brief Write data to flash area
160  *
161  * Write data to flash area. Area write boundaries are asserted before write
162  * request. API has the same limitation regard write-block alignment and size
163  * as wrapped flash driver.
164  *
165  * @param[in]  fa  Flash area
166  * @param[in]  off Offset relative from beginning of flash area to write
167  * @param[in]  src Buffer with data to be written
168  * @param[in]  len Number of bytes to write
169  *
170  * @return  0 on success, negative errno code on fail.
171  */
172 int flash_area_write(const struct flash_area *fa, off_t off, const void *src,
173 		     size_t len);
174 
175 /**
176  * @brief Erase flash area
177  *
178  * Erase given flash area range. Area boundaries are asserted before erase
179  * request. API has the same limitation regard erase-block alignment and size
180  * as wrapped flash driver.
181  *
182  * @param[in] fa  Flash area
183  * @param[in] off Offset relative from beginning of flash area.
184  * @param[in] len Number of bytes to be erase
185  *
186  * @return  0 on success, negative errno code on fail.
187  */
188 int flash_area_erase(const struct flash_area *fa, off_t off, size_t len);
189 
190 /**
191  * @brief Erase flash area or fill with erase-value
192  *
193  * On program-erase devices this function behaves exactly like flash_area_erase.
194  * On RAM non-volatile device it will call erase, if driver provides such
195  * callback, or will fill given range with erase-value defined by driver.
196  * This function should be only used by code that has not been written
197  * to directly support devices that do not require erase and rely on
198  * device being erased prior to some operations.
199  * Note that emulated erase, on devices that do not require, is done
200  * via write, which affects endurance of device.
201  *
202  * @see flash_area_erase()
203  * @see flash_flatten()
204  *
205  * @param[in] fa  Flash area
206  * @param[in] off Offset relative from beginning of flash area.
207  * @param[in] len Number of bytes to be erase
208  *
209  * @return  0 on success, negative errno code on fail.
210  */
211 int flash_area_flatten(const struct flash_area *fa, off_t off, size_t len);
212 
213 /**
214  * @brief Get write block size of the flash area
215  *
216  * Currently write block size might be treated as read block size, although
217  * most of drivers supports unaligned readout.
218  *
219  * @param[in] fa Flash area
220  *
221  * @return Alignment restriction for flash writes in [B].
222  */
223 uint32_t flash_area_align(const struct flash_area *fa);
224 
225 /**
226  * Retrieve info about sectors within the area.
227  *
228  * @param[in]  fa_id    Given flash area ID
229  * @param[out] sectors  buffer for sectors data
230  * @param[in,out] count On input Capacity of @p sectors, on output number of
231  * sectors Retrieved.
232  *
233  * @return  0 on success, negative errno code on fail. Especially returns
234  * -ENOMEM if There are too many flash pages on the flash_area to fit in the
235  * array.
236  */
237 int flash_area_get_sectors(int fa_id, uint32_t *count,
238 			   struct flash_sector *sectors);
239 
240 /**
241  * Flash map iteration callback
242  *
243  * @param fa flash area
244  * @param user_data User supplied data
245  *
246  */
247 typedef void (*flash_area_cb_t)(const struct flash_area *fa,
248 				void *user_data);
249 
250 /**
251  * Iterate over flash map
252  *
253  * @param user_cb User callback
254  * @param user_data User supplied data
255  */
256 void flash_area_foreach(flash_area_cb_t user_cb, void *user_data);
257 
258 /**
259  * Check whether given flash area has supporting flash driver
260  * in the system.
261  *
262  * @param[in] fa Flash area.
263  *
264  * @return 1 On success. -ENODEV if no driver match.
265  */
266 int flash_area_has_driver(const struct flash_area *fa);
267 
268 /**
269  * Get driver for given flash area.
270  *
271  * @param[in] fa Flash area.
272  *
273  * @return device driver.
274  */
275 const struct device *flash_area_get_device(const struct flash_area *fa);
276 
277 #if CONFIG_FLASH_MAP_LABELS
278 /**
279  * Get the label property from the device tree
280  *
281  * @param[in] fa Flash area.
282  *
283  * @return The label property if it is defined, otherwise NULL
284  */
285 const char *flash_area_label(const struct flash_area *fa);
286 #endif
287 
288 /**
289  * Get the value expected to be read when accessing any erased
290  * flash byte.
291  * This API is compatible with the MCUBoot's porting layer.
292  *
293  * @param fa Flash area.
294  *
295  * @return Byte value of erase memory.
296  */
297 uint8_t flash_area_erased_val(const struct flash_area *fa);
298 
299 /**
300  * Returns non-0 value if fixed-partition of given DTS node label exists.
301  *
302  * @param label DTS node label
303  *
304  * @return non-0 if fixed-partition node exists and is enabled;
305  *	   0 if node does not exist, is not enabled or is not fixed-partition.
306  */
307 #define FIXED_PARTITION_EXISTS(label) DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(label))
308 
309 /**
310  * Get flash area ID from fixed-partition DTS node label
311  *
312  * @param label DTS node label of a partition
313  *
314  * @return flash area ID
315  */
316 #define FIXED_PARTITION_ID(label) DT_FIXED_PARTITION_ID(DT_NODELABEL(label))
317 
318 /**
319  * Get fixed-partition offset from DTS node label
320  *
321  * @param label DTS node label of a partition
322  *
323  * @return fixed-partition offset, as defined for the partition in DTS.
324  */
325 #define FIXED_PARTITION_OFFSET(label) DT_REG_ADDR(DT_NODELABEL(label))
326 
327 /**
328  * Get fixed-partition offset from DTS node
329  *
330  * @param node DTS node of a partition
331  *
332  * @return fixed-partition offset, as defined for the partition in DTS.
333  */
334 #define FIXED_PARTITION_NODE_OFFSET(node) DT_REG_ADDR(node)
335 
336 /**
337  * Get fixed-partition size for DTS node label
338  *
339  * @param label DTS node label
340  *
341  * @return fixed-partition offset, as defined for the partition in DTS.
342  */
343 #define FIXED_PARTITION_SIZE(label) DT_REG_SIZE(DT_NODELABEL(label))
344 
345 /**
346  * Get fixed-partition size for DTS node
347  *
348  * @param node DTS node of a partition
349  *
350  * @return fixed-partition size, as defined for the partition in DTS.
351  */
352 #define FIXED_PARTITION_NODE_SIZE(node) DT_REG_SIZE(node)
353 
354 /**
355  * Get device pointer for device the area/partition resides on
356  *
357  * @param label DTS node label of a partition
358  *
359  * @return const struct device type pointer
360  */
361 #define FLASH_AREA_DEVICE(label) \
362 	DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODE_BY_FIXED_PARTITION_LABEL(label)))
363 
364 /**
365  * Get device pointer for device the area/partition resides on
366  *
367  * @param label DTS node label of a partition
368  *
369  * @return Pointer to a device.
370  */
371 #define FIXED_PARTITION_DEVICE(label) \
372 	DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label)))
373 
374 /**
375  * Get device pointer for device the area/partition resides on
376  *
377  * @param node DTS node of a partition
378  *
379  * @return Pointer to a device.
380  */
381 #define FIXED_PARTITION_NODE_DEVICE(node) \
382 	DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(node))
383 
384 #ifdef __cplusplus
385 }
386 #endif
387 
388 /**
389  * @}
390  */
391 
392 #endif /* ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_ */
393