From b93f59e15cdf7308b6e7f760c87fadf1b6f491bd Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Thu, 26 Oct 2017 13:24:34 -0700 Subject: [PATCH] drivers: uart: add system call handlers Certain interrupt-driven APIs were excluded as they are intended only to be called from ISRs, or involve registering a callback which runs in interrupt context. Signed-off-by: Andrew Boie --- drivers/serial/Makefile | 2 ++ drivers/serial/uart_handlers.c | 66 ++++++++++++++++++++++++++++++++++ include/uart.h | 65 ++++++++++++++++++++++++--------- 3 files changed, 116 insertions(+), 17 deletions(-) create mode 100644 drivers/serial/uart_handlers.c diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 4723dadee44..bb9fcd0e312 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -20,3 +20,5 @@ obj-$(CONFIG_UART_FE310) += uart_fe310.o obj-$(CONFIG_UART_ESP32) += uart_esp32.o obj-$(CONFIG_UART_GECKO) += uart_gecko.o obj-$(CONFIG_UART_MSP432P4XX) += uart_msp432p4xx.o + +obj-$(CONFIG_USERSPACE) += uart_handlers.o diff --git a/drivers/serial/uart_handlers.c b/drivers/serial/uart_handlers.c new file mode 100644 index 00000000000..a0f318f9d1f --- /dev/null +++ b/drivers/serial/uart_handlers.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define UART_SIMPLE(name_) \ + _SYSCALL_HANDLER1_SIMPLE(name_, K_OBJ_DRIVER_UART, struct device *) + +#define UART_SIMPLE_VOID(name_) \ + _SYSCALL_HANDLER1_SIMPLE_VOID(name_, K_OBJ_DRIVER_UART, \ + struct device *) + +UART_SIMPLE(uart_err_check); + +_SYSCALL_HANDLER(uart_poll_in, dev, p_char) +{ + _SYSCALL_OBJ(dev, K_OBJ_DRIVER_UART); + _SYSCALL_MEMORY_WRITE(p_char, sizeof(unsigned char)); + return _impl_uart_poll_in((struct device *)dev, + (unsigned char *)p_char); +} + +_SYSCALL_HANDLER(uart_poll_out, dev, out_char) +{ + _SYSCALL_OBJ(dev, K_OBJ_DRIVER_UART); + return _impl_uart_poll_out((struct device *)dev, out_char); +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +UART_SIMPLE_VOID(uart_irq_tx_enable); +UART_SIMPLE_VOID(uart_irq_tx_disable); +UART_SIMPLE_VOID(uart_irq_rx_enable); +UART_SIMPLE_VOID(uart_irq_rx_disable); +UART_SIMPLE_VOID(uart_irq_err_enable); +UART_SIMPLE_VOID(uart_irq_err_disable); +UART_SIMPLE(uart_irq_is_pending); +UART_SIMPLE(uart_irq_update); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#ifdef CONFIG_UART_LINE_CTRL +_SYSCALL_HANDLER(uart_line_ctrl_set, dev, ctrl, val) +{ + _SYSCALL_OBJ(dev, K_OBJ_DRIVER_UART); + return _impl_uart_line_ctrl_set((struct device *)dev, ctrl, val); +} + +_SYSCALL_HANDLER(uart_line_ctrl_get, dev, ctrl, val); +{ + _SYSCALL_OBJ(dev, K_OBJ_DRIVER_UART); + _SYSCALL_MEMORY_WRITE(val, sizeof(u32_t)); + return _impl_uart_line_ctrl_get((struct device *)dev, ctrl, + (u32_t *)val); +} +#endif /* CONFIG_UART_LINE_CTRL */ + +#ifdef CONFIG_UART_DRV_CMD +_SYSCALL_HANDLER(uart_drv_cmd, dev, cmd, p) +{ + _SYSCALL_OBJ(dev, K_OBJ_DRIVER_UART); + return _impl_uart_drv_cmd((struct device *)dev, cmd, p); +} +#endif /* CONFIG_UART_DRV_CMD */ diff --git a/include/uart.h b/include/uart.h index 5c29e92e9fe..4804d30cfca 100644 --- a/include/uart.h +++ b/include/uart.h @@ -183,7 +183,9 @@ struct uart_driver_api { * @retval UART_ERROR_BREAK if a break error was detected. * @retval 0 Otherwise. */ -static inline int uart_err_check(struct device *dev) +__syscall int uart_err_check(struct device *dev); + +static inline int _impl_uart_err_check(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -205,7 +207,9 @@ static inline int uart_err_check(struct device *dev) * input buffer was empty). * @retval -ENOTSUP If the operation is not supported. */ -static inline int uart_poll_in(struct device *dev, unsigned char *p_char) +__syscall int uart_poll_in(struct device *dev, unsigned char *p_char); + +static inline int _impl_uart_poll_in(struct device *dev, unsigned char *p_char) { const struct uart_driver_api *api = dev->driver_api; @@ -227,8 +231,11 @@ static inline int uart_poll_in(struct device *dev, unsigned char *p_char) * * @retval char Sent character. */ -static inline unsigned char uart_poll_out(struct device *dev, - unsigned char out_char) +__syscall unsigned char uart_poll_out(struct device *dev, + unsigned char out_char); + +static inline unsigned char _impl_uart_poll_out(struct device *dev, + unsigned char out_char) { const struct uart_driver_api *api = dev->driver_api; @@ -306,7 +313,9 @@ static inline int uart_fifo_read(struct device *dev, u8_t *rx_data, * * @return N/A */ -static inline void uart_irq_tx_enable(struct device *dev) +__syscall void uart_irq_tx_enable(struct device *dev); + +static inline void _impl_uart_irq_tx_enable(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -321,7 +330,9 @@ static inline void uart_irq_tx_enable(struct device *dev) * * @return N/A */ -static inline void uart_irq_tx_disable(struct device *dev) +__syscall void uart_irq_tx_disable(struct device *dev); + +static inline void _impl_uart_irq_tx_disable(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -363,7 +374,9 @@ static inline int uart_irq_tx_ready(struct device *dev) * * @return N/A */ -static inline void uart_irq_rx_enable(struct device *dev) +__syscall void uart_irq_rx_enable(struct device *dev); + +static inline void _impl_uart_irq_rx_enable(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -379,7 +392,9 @@ static inline void uart_irq_rx_enable(struct device *dev) * * @return N/A */ -static inline void uart_irq_rx_disable(struct device *dev) +__syscall void uart_irq_rx_disable(struct device *dev); + +static inline void _impl_uart_irq_rx_disable(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -459,7 +474,9 @@ static inline int uart_irq_rx_ready(struct device *dev) * * @return N/A */ -static inline void uart_irq_err_enable(struct device *dev) +__syscall void uart_irq_err_enable(struct device *dev); + +static inline void _impl_uart_irq_err_enable(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -476,7 +493,9 @@ static inline void uart_irq_err_enable(struct device *dev) * @retval 1 If an IRQ is ready. * @retval 0 Otherwise. */ -static inline void uart_irq_err_disable(struct device *dev) +__syscall void uart_irq_err_disable(struct device *dev); + +static inline void _impl_uart_irq_err_disable(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -493,8 +512,9 @@ static inline void uart_irq_err_disable(struct device *dev) * @retval 1 If an IRQ is pending. * @retval 0 Otherwise. */ +__syscall int uart_irq_is_pending(struct device *dev); -static inline int uart_irq_is_pending(struct device *dev) +static inline int _impl_uart_irq_is_pending(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -512,7 +532,9 @@ static inline int uart_irq_is_pending(struct device *dev) * * @retval 1 Always. */ -static inline int uart_irq_update(struct device *dev) +__syscall int uart_irq_update(struct device *dev); + +static inline int _impl_uart_irq_update(struct device *dev) { const struct uart_driver_api *api = dev->driver_api; @@ -558,8 +580,11 @@ static inline void uart_irq_callback_set(struct device *dev, * @retval 0 If successful. * @retval failed Otherwise. */ -static inline int uart_line_ctrl_set(struct device *dev, - u32_t ctrl, u32_t val) +__syscall int uart_line_ctrl_set(struct device *dev, + u32_t ctrl, u32_t val); + +static inline int _impl_uart_line_ctrl_set(struct device *dev, + u32_t ctrl, u32_t val) { const struct uart_driver_api *api = dev->driver_api; @@ -580,8 +605,10 @@ static inline int uart_line_ctrl_set(struct device *dev, * @retval 0 If successful. * @retval failed Otherwise. */ -static inline int uart_line_ctrl_get(struct device *dev, - u32_t ctrl, u32_t *val) +__syscall int uart_line_ctrl_get(struct device *dev, u32_t ctrl, u32_t *val); + +static inline int _impl_uart_line_ctrl_get(struct device *dev, + u32_t ctrl, u32_t *val) { const struct uart_driver_api *api = dev->driver_api; @@ -609,7 +636,9 @@ static inline int uart_line_ctrl_get(struct device *dev, * @retval 0 If successful. * @retval failed Otherwise. */ -static inline int uart_drv_cmd(struct device *dev, u32_t cmd, u32_t p) +__syscall int uart_drv_cmd(struct device *dev, u32_t cmd, u32_t p); + +static inline int _impl_uart_drv_cmd(struct device *dev, u32_t cmd, u32_t p) { const struct uart_driver_api *api = dev->driver_api; @@ -630,4 +659,6 @@ static inline int uart_drv_cmd(struct device *dev, u32_t cmd, u32_t p) * @} */ +#include + #endif /* __INCuarth */