Skip to content

Commit 307b998

Browse files
committed
drivers/flash: Add new API function flash_mmap
The commit adds new API function flash_map with supporting flash_driver_api callback type. The new function is provided to allow accessing flash devices, in particular internal SoC flash devices, via processor address space. Signed-off-by: Dominik Ermel <[email protected]>
1 parent 75463fe commit 307b998

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

drivers/flash/flash_handlers.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ static inline int z_vrfy_flash_get_size(const struct device *dev, uint64_t *size
4545
}
4646
#include <zephyr/syscalls/flash_get_size_mrsh.c>
4747

48+
static inline int z_vrfy_flash_mmap(const struct device *dev, void **base,
49+
uint64_t *size, uint32_t flags)
50+
{
51+
K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH));
52+
K_OOPS(K_SYSCALL_MEMORY_READ(*base, sizeof(*base)));
53+
K_OOPS(K_SYSCALL_MEMORY_WRITE(*base, sizeof(*base)));
54+
K_OOPS(K_SYSCALL_MEMORY_READ(size, sizeof(*size)));
55+
K_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(*size)));
56+
return z_impl_flash_mmap((const struct device *)dev, base, size, flags);
57+
}
58+
#include <zephyr/syscalls/flash_mmap_mrsh.c>
59+
4860
static inline size_t z_vrfy_flash_get_write_block_size(const struct device *dev)
4961
{
5062
K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH));

include/zephyr/drivers/flash.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,15 @@ typedef int (*flash_api_get_size)(const struct device *dev, uint64_t *size);
169169

170170
typedef const struct flash_parameters* (*flash_api_get_parameters)(const struct device *dev);
171171

172+
/**
173+
* @brief Get device mapping to processor address space.
174+
*
175+
* When supported by driver this function will try to map device to MPU address
176+
* space, either to default memory address or to requeste one.
177+
*/
178+
typedef int (*flash_api_mmap)(const struct device *dev, void **base, uint64_t *size,
179+
uint32_t flags);
180+
172181
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
173182
/**
174183
* @brief Retrieve a flash device's layout.
@@ -208,6 +217,7 @@ __subsystem struct flash_driver_api {
208217
flash_api_erase erase;
209218
flash_api_get_parameters get_parameters;
210219
flash_api_get_size get_size;
220+
flash_api_mmap mmap;
211221
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
212222
flash_api_pages_layout page_layout;
213223
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
@@ -334,6 +344,56 @@ static inline int z_impl_flash_erase(const struct device *dev, off_t offset,
334344
return rc;
335345
}
336346

347+
/** Map at custom address */
348+
#define FLASH_MMAP_F_CUSTOM_ADDR BIT(0)
349+
/** Map for read */
350+
#define FLASH_MMAP_F_READ BIT(1)
351+
/** Map for write */
352+
#define FLASH_MMAP_F_WRITE BIT(2)
353+
354+
/**
355+
* @brief Get device mapping to processor address space
356+
*
357+
* Function returns base address for memory mapping of device to address space
358+
* and size of the device mapped. Internal SoC memory and some XIP memories
359+
* may be addressable through the same address space as device RAM, which allows
360+
* data transfers via memcpy or direct access to storage by casting address
361+
* range to data structures.
362+
* Not all processors may support the feature and its usage should be well
363+
* tested in user code, because while, for example, flash_read would return
364+
* -EINVAL error in case when attempting read out of device range, directly
365+
* accessing memory beyond given range may invoke CPU fault.
366+
*
367+
* @param dev device to get mapping for
368+
* @param base pointer to void pointer for memory address, in case when
369+
* FLASH_MMAP_CUSTOM_ADDR flag is set this is also read as desired
370+
* address to map device to.
371+
* @param size pointer to variable where device size will be reported.
372+
* @param flags flags describing desired access and mapping.
373+
*
374+
* @return 0 on success, -ENOTSUP when driver does not support mapping,
375+
* -EINVAL in case, when selected flags are not supported.
376+
*/
377+
378+
__syscall int flash_mmap(const struct device *dev, void **base, uint64_t *size,
379+
uint32_t flags);
380+
381+
static inline int z_impl_flash_mmap(const struct device *dev, void **base,
382+
uint64_t *size, uint32_t flags)
383+
{
384+
int rc = -ENOSYS;
385+
386+
const struct flash_driver_api *api =
387+
(const struct flash_driver_api *)dev->api;
388+
389+
if (api->mmap != NULL) {
390+
rc = api->mmap(dev, base, size, flags);
391+
}
392+
393+
return rc;
394+
}
395+
396+
337397
/**
338398
* @brief Get device size in bytes.
339399
*

0 commit comments

Comments
 (0)