Besides of standard flash operations like write or erase, flash controllers also support additional features like write protection or readout protection. These features are not available in every flash controller, what's more controllers can implement it in a different way. It doesn't make sense to add a separate flash API function for every flash controller feature, because it could be unique (supported on small number of flash controllers) or the API won't be able to represent the same feature on every flash controller. Extended operation interface provides flexible way for supporting flash controller features. Code space is divided equally into Zephyr codes (MSb == 0) and vendor codes (MSb == 1). This way we can easily add extended operations to the drivers without cluttering the API or problems with API incompatibility. Extended operation can be promoted from vendor codes to Zephyr codes if the feature is available in most flash controllers and can be represented in the same way. Signed-off-by: Patryk Duda <pdk@semihalf.com>
120 lines
3.6 KiB
C
120 lines
3.6 KiB
C
/*
|
|
* Copyright (c) 2017 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/syscall_handler.h>
|
|
#include <zephyr/drivers/flash.h>
|
|
|
|
static inline int z_vrfy_flash_read(const struct device *dev, off_t offset,
|
|
void *data, size_t len)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, read));
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, len));
|
|
return z_impl_flash_read((const struct device *)dev, offset,
|
|
(void *)data,
|
|
len);
|
|
}
|
|
#include <syscalls/flash_read_mrsh.c>
|
|
|
|
static inline int z_vrfy_flash_write(const struct device *dev, off_t offset,
|
|
const void *data, size_t len)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, write));
|
|
Z_OOPS(Z_SYSCALL_MEMORY_READ(data, len));
|
|
return z_impl_flash_write((const struct device *)dev, offset,
|
|
(const void *)data, len);
|
|
}
|
|
#include <syscalls/flash_write_mrsh.c>
|
|
|
|
static inline size_t z_vrfy_flash_get_write_block_size(const struct device *dev)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH));
|
|
return z_impl_flash_get_write_block_size(dev);
|
|
}
|
|
#include <syscalls/flash_get_write_block_size_mrsh.c>
|
|
|
|
static inline const struct flash_parameters *z_vrfy_flash_get_parameters(const struct device *dev)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, get_parameters));
|
|
return z_impl_flash_get_parameters(dev);
|
|
}
|
|
#include <syscalls/flash_get_parameters_mrsh.c>
|
|
|
|
#ifdef CONFIG_FLASH_PAGE_LAYOUT
|
|
static inline int z_vrfy_flash_get_page_info_by_offs(const struct device *dev,
|
|
off_t offs,
|
|
struct flash_pages_info *info)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout));
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info)));
|
|
return z_impl_flash_get_page_info_by_offs((const struct device *)dev,
|
|
offs,
|
|
(struct flash_pages_info *)info);
|
|
}
|
|
#include <syscalls/flash_get_page_info_by_offs_mrsh.c>
|
|
|
|
static inline int z_vrfy_flash_get_page_info_by_idx(const struct device *dev,
|
|
uint32_t idx,
|
|
struct flash_pages_info *info)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout));
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(info, sizeof(struct flash_pages_info)));
|
|
return z_impl_flash_get_page_info_by_idx((const struct device *)dev,
|
|
idx,
|
|
(struct flash_pages_info *)info);
|
|
}
|
|
#include <syscalls/flash_get_page_info_by_idx_mrsh.c>
|
|
|
|
static inline size_t z_vrfy_flash_get_page_count(const struct device *dev)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, page_layout));
|
|
return z_impl_flash_get_page_count((const struct device *)dev);
|
|
}
|
|
#include <syscalls/flash_get_page_count_mrsh.c>
|
|
|
|
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
|
|
|
#ifdef CONFIG_FLASH_JESD216_API
|
|
|
|
static inline int z_vrfy_flash_sfdp_read(const struct device *dev,
|
|
off_t offset,
|
|
void *data, size_t len)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, sfdp_read));
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, len));
|
|
return z_impl_flash_sfdp_read(dev, offset, data, len);
|
|
}
|
|
#include <syscalls/flash_sfdp_read.c>
|
|
|
|
static inline int z_vrfy_flash_read_jedec_id(const struct device *dev,
|
|
uint8_t *id)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, read_jedec_id));
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(id, 3));
|
|
return z_impl_flash_read_jedec_id(dev, id);
|
|
}
|
|
#include <syscalls/flash_sfdp_jedec_id.c>
|
|
|
|
#endif /* CONFIG_FLASH_JESD216_API */
|
|
|
|
#ifdef CONFIG_FLASH_EX_OP_ENABLED
|
|
|
|
static inline int z_vrfy_flash_ex_op(const struct device *dev, uint16_t code,
|
|
const uintptr_t in, void *out)
|
|
{
|
|
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, ex_op));
|
|
|
|
/*
|
|
* If the code is a vendor code, then ex_op function have to perform
|
|
* verification. Zephyr codes should be verified here, but currently
|
|
* there are no Zephyr extended codes yet.
|
|
*/
|
|
|
|
return z_impl_flash_ex_op(dev, code, in, out);
|
|
}
|
|
#include <syscalls/flash_ex_op_mrsh.c>
|
|
|
|
#endif /* CONFIG_FLASH_EX_OP_ENABLED */
|