1 /*
2 * Copyright (c) 2017 Nordic Semiconductor ASA
3 * Copyright (c) 2016 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /**
9 * @file
10 * @brief Public API for FLASH drivers
11 */
12
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_FLASH_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_FLASH_H_
15
16 /**
17 * @brief FLASH internal Interface
18 * @defgroup flash_internal_interface FLASH internal Interface
19 * @ingroup io_interfaces
20 * @{
21 */
22
23 #include <errno.h>
24
25 #include <zephyr/types.h>
26 #include <stddef.h>
27 #include <sys/types.h>
28 #include <zephyr/device.h>
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
35 struct flash_pages_layout {
36 size_t pages_count; /* count of pages sequence of the same size */
37 size_t pages_size;
38 };
39 #endif /* CONFIG_FLASH_PAGE_LAYOUT */
40
41 /**
42 * @}
43 */
44
45 /**
46 * @brief FLASH Interface
47 * @defgroup flash_interface FLASH Interface
48 * @ingroup io_interfaces
49 * @{
50 */
51
52 /**
53 * Flash memory parameters. Contents of this structure suppose to be
54 * filled in during flash device initialization and stay constant
55 * through a runtime.
56 */
57 struct flash_parameters {
58 const size_t write_block_size;
59 uint8_t erase_value; /* Byte value of erased flash */
60 };
61
62 /**
63 * @}
64 */
65
66 /**
67 * @addtogroup flash_internal_interface
68 * @{
69 */
70
71 typedef int (*flash_api_read)(const struct device *dev, off_t offset,
72 void *data,
73 size_t len);
74 /**
75 * @brief Flash write implementation handler type
76 *
77 * @note Any necessary write protection management must be performed by
78 * the driver, with the driver responsible for ensuring the "write-protect"
79 * after the operation completes (successfully or not) matches the write-protect
80 * state when the operation was started.
81 */
82 typedef int (*flash_api_write)(const struct device *dev, off_t offset,
83 const void *data, size_t len);
84
85 /**
86 * @brief Flash erase implementation handler type
87 *
88 * @note Any necessary erase protection management must be performed by
89 * the driver, with the driver responsible for ensuring the "erase-protect"
90 * after the operation completes (successfully or not) matches the erase-protect
91 * state when the operation was started.
92 */
93 typedef int (*flash_api_erase)(const struct device *dev, off_t offset,
94 size_t size);
95
96 typedef const struct flash_parameters* (*flash_api_get_parameters)(const struct device *dev);
97
98 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
99 /**
100 * @brief Retrieve a flash device's layout.
101 *
102 * A flash device layout is a run-length encoded description of the
103 * pages on the device. (Here, "page" means the smallest erasable
104 * area on the flash device.)
105 *
106 * For flash memories which have uniform page sizes, this routine
107 * returns an array of length 1, which specifies the page size and
108 * number of pages in the memory.
109 *
110 * Layouts for flash memories with nonuniform page sizes will be
111 * returned as an array with multiple elements, each of which
112 * describes a group of pages that all have the same size. In this
113 * case, the sequence of array elements specifies the order in which
114 * these groups occur on the device.
115 *
116 * @param dev Flash device whose layout to retrieve.
117 * @param layout The flash layout will be returned in this argument.
118 * @param layout_size The number of elements in the returned layout.
119 */
120 typedef void (*flash_api_pages_layout)(const struct device *dev,
121 const struct flash_pages_layout **layout,
122 size_t *layout_size);
123 #endif /* CONFIG_FLASH_PAGE_LAYOUT */
124
125 typedef int (*flash_api_sfdp_read)(const struct device *dev, off_t offset,
126 void *data, size_t len);
127 typedef int (*flash_api_read_jedec_id)(const struct device *dev, uint8_t *id);
128 typedef int (*flash_api_ex_op)(const struct device *dev, uint16_t code,
129 const uintptr_t in, void *out);
130
131 __subsystem struct flash_driver_api {
132 flash_api_read read;
133 flash_api_write write;
134 flash_api_erase erase;
135 flash_api_get_parameters get_parameters;
136 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
137 flash_api_pages_layout page_layout;
138 #endif /* CONFIG_FLASH_PAGE_LAYOUT */
139 #if defined(CONFIG_FLASH_JESD216_API)
140 flash_api_sfdp_read sfdp_read;
141 flash_api_read_jedec_id read_jedec_id;
142 #endif /* CONFIG_FLASH_JESD216_API */
143 #if defined(CONFIG_FLASH_EX_OP_ENABLED)
144 flash_api_ex_op ex_op;
145 #endif /* CONFIG_FLASH_EX_OP_ENABLED */
146 };
147
148 /**
149 * @}
150 */
151
152 /**
153 * @addtogroup flash_interface
154 * @{
155 */
156
157 /**
158 * @brief Read data from flash
159 *
160 * All flash drivers support reads without alignment restrictions on
161 * the read offset, the read size, or the destination address.
162 *
163 * @param dev : flash dev
164 * @param offset : Offset (byte aligned) to read
165 * @param data : Buffer to store read data
166 * @param len : Number of bytes to read.
167 *
168 * @return 0 on success, negative errno code on fail.
169 */
170 __syscall int flash_read(const struct device *dev, off_t offset, void *data,
171 size_t len);
172
z_impl_flash_read(const struct device * dev,off_t offset,void * data,size_t len)173 static inline int z_impl_flash_read(const struct device *dev, off_t offset,
174 void *data,
175 size_t len)
176 {
177 const struct flash_driver_api *api =
178 (const struct flash_driver_api *)dev->api;
179
180 return api->read(dev, offset, data, len);
181 }
182
183 /**
184 * @brief Write buffer into flash memory.
185 *
186 * All flash drivers support a source buffer located either in RAM or
187 * SoC flash, without alignment restrictions on the source address.
188 * Write size and offset must be multiples of the minimum write block size
189 * supported by the driver.
190 *
191 * Any necessary write protection management is performed by the driver
192 * write implementation itself.
193 *
194 * @param dev : flash device
195 * @param offset : starting offset for the write
196 * @param data : data to write
197 * @param len : Number of bytes to write
198 *
199 * @return 0 on success, negative errno code on fail.
200 */
201 __syscall int flash_write(const struct device *dev, off_t offset,
202 const void *data,
203 size_t len);
204
z_impl_flash_write(const struct device * dev,off_t offset,const void * data,size_t len)205 static inline int z_impl_flash_write(const struct device *dev, off_t offset,
206 const void *data, size_t len)
207 {
208 const struct flash_driver_api *api =
209 (const struct flash_driver_api *)dev->api;
210 int rc;
211
212 rc = api->write(dev, offset, data, len);
213
214 return rc;
215 }
216
217 /**
218 * @brief Erase part or all of a flash memory
219 *
220 * Acceptable values of erase size and offset are subject to
221 * hardware-specific multiples of page size and offset. Please check
222 * the API implemented by the underlying sub driver, for example by
223 * using flash_get_page_info_by_offs() if that is supported by your
224 * flash driver.
225 *
226 * Any necessary erase protection management is performed by the driver
227 * erase implementation itself.
228 *
229 * @param dev : flash device
230 * @param offset : erase area starting offset
231 * @param size : size of area to be erased
232 *
233 * @return 0 on success, negative errno code on fail.
234 *
235 * @see flash_get_page_info_by_offs()
236 * @see flash_get_page_info_by_idx()
237 */
238 __syscall int flash_erase(const struct device *dev, off_t offset, size_t size);
239
z_impl_flash_erase(const struct device * dev,off_t offset,size_t size)240 static inline int z_impl_flash_erase(const struct device *dev, off_t offset,
241 size_t size)
242 {
243 const struct flash_driver_api *api =
244 (const struct flash_driver_api *)dev->api;
245 int rc;
246
247 rc = api->erase(dev, offset, size);
248
249 return rc;
250 }
251
252 struct flash_pages_info {
253 off_t start_offset; /* offset from the base of flash address */
254 size_t size;
255 uint32_t index;
256 };
257
258 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
259 /**
260 * @brief Get the size and start offset of flash page at certain flash offset.
261 *
262 * @param dev flash device
263 * @param offset Offset within the page
264 * @param info Page Info structure to be filled
265 *
266 * @return 0 on success, -EINVAL if page of the offset doesn't exist.
267 */
268 __syscall int flash_get_page_info_by_offs(const struct device *dev,
269 off_t offset,
270 struct flash_pages_info *info);
271
272 /**
273 * @brief Get the size and start offset of flash page of certain index.
274 *
275 * @param dev flash device
276 * @param page_index Index of the page. Index are counted from 0.
277 * @param info Page Info structure to be filled
278 *
279 * @return 0 on success, -EINVAL if page of the index doesn't exist.
280 */
281 __syscall int flash_get_page_info_by_idx(const struct device *dev,
282 uint32_t page_index,
283 struct flash_pages_info *info);
284
285 /**
286 * @brief Get the total number of flash pages.
287 *
288 * @param dev flash device
289 *
290 * @return Number of flash pages.
291 */
292 __syscall size_t flash_get_page_count(const struct device *dev);
293
294 /**
295 * @brief Callback type for iterating over flash pages present on a device.
296 *
297 * The callback should return true to continue iterating, and false to halt.
298 *
299 * @param info Information for current page
300 * @param data Private data for callback
301 * @return True to continue iteration, false to halt iteration.
302 * @see flash_page_foreach()
303 */
304 typedef bool (*flash_page_cb)(const struct flash_pages_info *info, void *data);
305
306 /**
307 * @brief Iterate over all flash pages on a device
308 *
309 * This routine iterates over all flash pages on the given device,
310 * ordered by increasing start offset. For each page, it invokes the
311 * given callback, passing it the page's information and a private
312 * data object.
313 *
314 * @param dev Device whose pages to iterate over
315 * @param cb Callback to invoke for each flash page
316 * @param data Private data for callback function
317 */
318 void flash_page_foreach(const struct device *dev, flash_page_cb cb,
319 void *data);
320 #endif /* CONFIG_FLASH_PAGE_LAYOUT */
321
322 #if defined(CONFIG_FLASH_JESD216_API)
323 /**
324 * @brief Read data from Serial Flash Discoverable Parameters
325 *
326 * This routine reads data from a serial flash device compatible with
327 * the JEDEC JESD216 standard for encoding flash memory
328 * characteristics.
329 *
330 * Availability of this API is conditional on selecting
331 * @c CONFIG_FLASH_JESD216_API and support of that functionality in
332 * the driver underlying @p dev.
333 *
334 * @param dev device from which parameters will be read
335 * @param offset address within the SFDP region containing data of interest
336 * @param data where the data to be read will be placed
337 * @param len the number of bytes of data to be read
338 *
339 * @retval 0 on success
340 * @retval -ENOTSUP if the flash driver does not support SFDP access
341 * @retval negative values for other errors.
342 */
343 __syscall int flash_sfdp_read(const struct device *dev, off_t offset,
344 void *data, size_t len);
345
z_impl_flash_sfdp_read(const struct device * dev,off_t offset,void * data,size_t len)346 static inline int z_impl_flash_sfdp_read(const struct device *dev,
347 off_t offset,
348 void *data, size_t len)
349 {
350 int rv = -ENOTSUP;
351 const struct flash_driver_api *api =
352 (const struct flash_driver_api *)dev->api;
353
354 if (api->sfdp_read != NULL) {
355 rv = api->sfdp_read(dev, offset, data, len);
356 }
357 return rv;
358 }
359
360 /**
361 * @brief Read the JEDEC ID from a compatible flash device.
362 *
363 * @param dev device from which id will be read
364 * @param id pointer to a buffer of at least 3 bytes into which id
365 * will be stored
366 *
367 * @retval 0 on successful store of 3-byte JEDEC id
368 * @retval -ENOTSUP if flash driver doesn't support this function
369 * @retval negative values for other errors
370 */
371 __syscall int flash_read_jedec_id(const struct device *dev, uint8_t *id);
372
z_impl_flash_read_jedec_id(const struct device * dev,uint8_t * id)373 static inline int z_impl_flash_read_jedec_id(const struct device *dev,
374 uint8_t *id)
375 {
376 int rv = -ENOTSUP;
377 const struct flash_driver_api *api =
378 (const struct flash_driver_api *)dev->api;
379
380 if (api->read_jedec_id != NULL) {
381 rv = api->read_jedec_id(dev, id);
382 }
383 return rv;
384 }
385 #endif /* CONFIG_FLASH_JESD216_API */
386
387 /**
388 * @brief Get the minimum write block size supported by the driver
389 *
390 * The write block size supported by the driver might differ from the write
391 * block size of memory used because the driver might implements write-modify
392 * algorithm.
393 *
394 * @param dev flash device
395 *
396 * @return write block size in bytes.
397 */
398 __syscall size_t flash_get_write_block_size(const struct device *dev);
399
z_impl_flash_get_write_block_size(const struct device * dev)400 static inline size_t z_impl_flash_get_write_block_size(const struct device *dev)
401 {
402 const struct flash_driver_api *api =
403 (const struct flash_driver_api *)dev->api;
404
405 return api->get_parameters(dev)->write_block_size;
406 }
407
408
409 /**
410 * @brief Get pointer to flash_parameters structure
411 *
412 * Returned pointer points to a structure that should be considered
413 * constant through a runtime, regardless if it is defined in RAM or
414 * Flash.
415 * Developer is free to cache the structure pointer or copy its contents.
416 *
417 * @return pointer to flash_parameters structure characteristic for
418 * the device.
419 */
420 __syscall const struct flash_parameters *flash_get_parameters(const struct device *dev);
421
z_impl_flash_get_parameters(const struct device * dev)422 static inline const struct flash_parameters *z_impl_flash_get_parameters(const struct device *dev)
423 {
424 const struct flash_driver_api *api =
425 (const struct flash_driver_api *)dev->api;
426
427 return api->get_parameters(dev);
428 }
429
430 /**
431 * @brief Execute flash extended operation on given device
432 *
433 * Besides of standard flash operations like write or erase, flash controllers
434 * also support additional features like write protection or readout
435 * protection. These features are not available in every flash controller,
436 * what's more controllers can implement it in a different way.
437 *
438 * It doesn't make sense to add a separate flash API function for every flash
439 * controller feature, because it could be unique (supported on small number of
440 * flash controllers) or the API won't be able to represent the same feature on
441 * every flash controller.
442 *
443 * @param dev Flash device
444 * @param code Operation which will be executed on the device.
445 * @param in Pointer to input data used by operation. If operation doesn't
446 * need any input data it could be NULL.
447 * @param out Pointer to operation output data. If operation doesn't produce
448 * any output it could be NULL.
449 *
450 * @retval 0 on success.
451 * @retval -ENOTSUP if given device doesn't support extended operation.
452 * @retval -ENOSYS if support for extended operations is not enabled in Kconfig
453 * @retval negative value on extended operation errors.
454 */
455 __syscall int flash_ex_op(const struct device *dev, uint16_t code,
456 const uintptr_t in, void *out);
457
458 /*
459 * Extended operation interface provides flexible way for supporting flash
460 * controller features. Code space is divided equally into Zephyr codes
461 * (MSb == 0) and vendor codes (MSb == 1). This way we can easily add extended
462 * operations to the drivers without cluttering the API or problems with API
463 * incompatibility. Extended operation can be promoted from vendor codes to
464 * Zephyr codes if the feature is available in most flash controllers and
465 * can be represented in the same way.
466 *
467 * It's not forbidden to have operation in Zephyr codes and vendor codes for
468 * the same functionality. In this case, vendor operation could provide more
469 * specific access when abstraction in Zephyr counterpart is insufficient.
470 */
471 #define FLASH_EX_OP_VENDOR_BASE 0x8000
472 #define FLASH_EX_OP_IS_VENDOR(c) ((c) & FLASH_EX_OP_VENDOR_BASE)
473
z_impl_flash_ex_op(const struct device * dev,uint16_t code,const uintptr_t in,void * out)474 static inline int z_impl_flash_ex_op(const struct device *dev, uint16_t code,
475 const uintptr_t in, void *out)
476 {
477 #if defined(CONFIG_FLASH_EX_OP_ENABLED)
478 const struct flash_driver_api *api =
479 (const struct flash_driver_api *)dev->api;
480
481 if (api->ex_op == NULL) {
482 return -ENOTSUP;
483 }
484
485 return api->ex_op(dev, code, in, out);
486 #else
487 ARG_UNUSED(dev);
488 ARG_UNUSED(code);
489 ARG_UNUSED(in);
490 ARG_UNUSED(out);
491
492 return -ENOSYS;
493 #endif /* CONFIG_FLASH_EX_OP_ENABLED */
494 }
495
496 #ifdef __cplusplus
497 }
498 #endif
499
500 /**
501 * @}
502 */
503
504 #include <syscalls/flash.h>
505
506 #endif /* ZEPHYR_INCLUDE_DRIVERS_FLASH_H_ */
507