From adc38df11ac51952565682ebaaa029fb1af5e733 Mon Sep 17 00:00:00 2001 From: Marek Novak Date: Tue, 12 Mar 2019 13:34:45 +0100 Subject: [PATCH] Release March 2019, version 2.2.0 --- lib/common/llist.c | 6 +- .../platform/imx6sx_m4/rpmsg_platform.h | 41 +- .../platform/imx7d_m4/rpmsg_platform.h | 43 +- .../platform/lpc5410x/rpmsg_platform.h | 41 +- .../platform/lpc5411x/rpmsg_platform.h | 43 +- lib/include/rpmsg_compiler.h | 39 +- lib/include/rpmsg_default_config.h | 93 ++- lib/include/rpmsg_env.h | 133 +++- lib/include/rpmsg_lite.h | 21 +- lib/include/virtio_ring.h | 10 +- lib/include/virtqueue.h | 10 +- .../porting/environment/rpmsg_env_bm.c | 8 +- .../porting/environment/rpmsg_env_freertos.c | 35 +- .../porting/environment/rpmsg_env_qnx.c | 692 ++++++++++++++++++ .../porting/environment/rpmsg_env_qnx.h | 55 ++ .../porting/environment/rpmsg_env_zephyr.c | 650 ++++++++++++++++ .../platform/imx6sx_m4/rpmsg_platform.c | 143 ++-- .../imx6sx_m4/rpmsg_platform_zephyr_ipm.c | 268 +++++++ .../platform/imx7d_m4/rpmsg_platform.c | 143 ++-- .../imx7d_m4/rpmsg_platform_zephyr_ipm.c | 268 +++++++ .../platform/lpc5410x/rpmsg_platform.c | 168 ++--- .../platform/lpc5411x/rpmsg_platform.c | 168 ++--- .../lpc5411x/rpmsg_platform_zephyr_ipm.c | 256 +++++++ lib/rpmsg_lite/rpmsg_lite.c | 108 ++- lib/rpmsg_lite/rpmsg_ns.c | 13 +- lib/rpmsg_lite/rpmsg_queue.c | 3 +- lib/virtio/virtqueue.c | 34 +- 27 files changed, 2947 insertions(+), 545 deletions(-) create mode 100644 lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.c create mode 100644 lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.h create mode 100644 lib/rpmsg_lite/porting/environment/rpmsg_env_zephyr.c create mode 100644 lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform_zephyr_ipm.c create mode 100644 lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform_zephyr_ipm.c create mode 100644 lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform_zephyr_ipm.c diff --git a/lib/common/llist.c b/lib/common/llist.c index e8e0720..82d16dd 100644 --- a/lib/common/llist.c +++ b/lib/common/llist.c @@ -55,12 +55,12 @@ */ void add_to_list(struct llist **head, struct llist *node) { - if (!node) + if (node == LIST_NULL) { return; } - if (*head) + if (*head != LIST_NULL) { /* Place the new element at the start of list. */ node->next = *head; @@ -88,7 +88,7 @@ void add_to_list(struct llist **head, struct llist *node) */ void remove_from_list(struct llist **head, struct llist *node) { - if (!(*head) || !(node)) + if ((*head == LIST_NULL) || (node == LIST_NULL)) { return; } diff --git a/lib/include/platform/imx6sx_m4/rpmsg_platform.h b/lib/include/platform/imx6sx_m4/rpmsg_platform.h index a6b99f4..09ff503 100644 --- a/lib/include/platform/imx6sx_m4/rpmsg_platform.h +++ b/lib/include/platform/imx6sx_m4/rpmsg_platform.h @@ -1,39 +1,14 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _MACHINE_SYSTEM_H -#define _MACHINE_SYSTEM_H +#ifndef _RPMSG_PLATFORM_H +#define _RPMSG_PLATFORM_H /* RPMSG MU channel index */ #define RPMSG_MU_CHANNEL (1) @@ -61,12 +36,12 @@ #define RL_PLATFORM_HIGHEST_LINK_ID (0) /* platform interrupt related functions */ -int platform_init_interrupt(int vector_id, void *isr_data); -int platform_deinit_interrupt(int vector_id); +int platform_init_interrupt(unsigned int vector_id, void *isr_data); +int platform_deinit_interrupt(unsigned int vector_id); int platform_interrupt_enable(unsigned int vector_id); int platform_interrupt_disable(unsigned int vector_id); int platform_in_isr(void); -void platform_notify(int vector_id); +void platform_notify(unsigned int vector_id); /* platform low-level time-delay (busy loop) */ void platform_time_delay(int num_msec); @@ -83,4 +58,4 @@ int platform_init(void); int platform_deinit(void); void rpmsg_handler(void); -#endif /* _MACHINE_SYSTEM_H */ +#endif /* _RPMSG_PLATFORM_H */ diff --git a/lib/include/platform/imx7d_m4/rpmsg_platform.h b/lib/include/platform/imx7d_m4/rpmsg_platform.h index a6b99f4..a01d3ee 100644 --- a/lib/include/platform/imx7d_m4/rpmsg_platform.h +++ b/lib/include/platform/imx7d_m4/rpmsg_platform.h @@ -1,39 +1,14 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _MACHINE_SYSTEM_H -#define _MACHINE_SYSTEM_H +#ifndef _RPMSG_PLATFORM_H +#define _RPMSG_PLATFORM_H /* RPMSG MU channel index */ #define RPMSG_MU_CHANNEL (1) @@ -57,16 +32,16 @@ #define RL_GET_LINK_ID(id) (((id)&0xFFFFFFFE) >> 1) #define RL_GET_Q_ID(id) ((id)&0x1) -#define RL_PLATFORM_IMX6SX_M4_LINK_ID (0) +#define RL_PLATFORM_IMX7D_M4_LINK_ID (0) #define RL_PLATFORM_HIGHEST_LINK_ID (0) /* platform interrupt related functions */ -int platform_init_interrupt(int vector_id, void *isr_data); -int platform_deinit_interrupt(int vector_id); +int platform_init_interrupt(unsigned int vector_id, void *isr_data); +int platform_deinit_interrupt(unsigned int vector_id); int platform_interrupt_enable(unsigned int vector_id); int platform_interrupt_disable(unsigned int vector_id); int platform_in_isr(void); -void platform_notify(int vector_id); +void platform_notify(unsigned int vector_id); /* platform low-level time-delay (busy loop) */ void platform_time_delay(int num_msec); @@ -83,4 +58,4 @@ int platform_init(void); int platform_deinit(void); void rpmsg_handler(void); -#endif /* _MACHINE_SYSTEM_H */ +#endif /* _RPMSG_PLATFORM_H */ diff --git a/lib/include/platform/lpc5410x/rpmsg_platform.h b/lib/include/platform/lpc5410x/rpmsg_platform.h index 9b95f81..d38b78c 100644 --- a/lib/include/platform/lpc5410x/rpmsg_platform.h +++ b/lib/include/platform/lpc5410x/rpmsg_platform.h @@ -1,39 +1,14 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _MACHINE_SYSTEM_H -#define _MACHINE_SYSTEM_H +#ifndef _RPMSG_PLATFORM_H +#define _RPMSG_PLATFORM_H /* * No need to align the VRING as defined in Linux because LPC54102 is not intended @@ -59,12 +34,12 @@ #define RL_PLATFORM_HIGHEST_LINK_ID (0) /* platform interrupt related functions */ -int platform_init_interrupt(int vector_id, void *isr_data); -int platform_deinit_interrupt(int vector_id); +int platform_init_interrupt(unsigned int vector_id, void *isr_data); +int platform_deinit_interrupt(unsigned int vector_id); int platform_interrupt_enable(unsigned int vector_id); int platform_interrupt_disable(unsigned int vector_id); int platform_in_isr(void); -void platform_notify(int vector_id); +void platform_notify(unsigned int vector_id); /* platform low-level time-delay (busy loop) */ void platform_time_delay(int num_msec); @@ -80,4 +55,4 @@ void *platform_patova(unsigned long addr); int platform_init(void); int platform_deinit(void); -#endif /* _MACHINE_SYSTEM_H */ +#endif /* _RPMSG_PLATFORM_H */ diff --git a/lib/include/platform/lpc5411x/rpmsg_platform.h b/lib/include/platform/lpc5411x/rpmsg_platform.h index 5ac2674..bb97360 100644 --- a/lib/include/platform/lpc5411x/rpmsg_platform.h +++ b/lib/include/platform/lpc5411x/rpmsg_platform.h @@ -1,39 +1,14 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _MACHINE_SYSTEM_H -#define _MACHINE_SYSTEM_H +#ifndef _RPMSG_PLATFORM_H +#define _RPMSG_PLATFORM_H /* * No need to align the VRING as defined in Linux because LPC5411x is not intended @@ -59,18 +34,18 @@ #define RL_PLATFORM_HIGHEST_LINK_ID (0) /* platform interrupt related functions */ -int platform_init_interrupt(int vector_id, void *isr_data); -int platform_deinit_interrupt(int vector_id); +int platform_init_interrupt(unsigned int vector_id, void *isr_data); +int platform_deinit_interrupt(unsigned int vector_id); int platform_interrupt_enable(unsigned int vector_id); int platform_interrupt_disable(unsigned int vector_id); int platform_in_isr(void); -void platform_notify(int vector_id); +void platform_notify(unsigned int vector_id); /* platform low-level time-delay (busy loop) */ void platform_time_delay(int num_msec); /* platform memory functions */ -void platform_map_mem_region(unsigned int va, unsigned int pa, unsigned int size, unsigned int flags); +void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsigned int size, unsigned int flags); void platform_cache_all_flush_invalidate(void); void platform_cache_disable(void); unsigned long platform_vatopa(void *addr); @@ -80,4 +55,4 @@ void *platform_patova(unsigned long addr); int platform_init(void); int platform_deinit(void); -#endif /* _MACHINE_SYSTEM_H */ +#endif /* _RPMSG_PLATFORM_H */ diff --git a/lib/include/rpmsg_compiler.h b/lib/include/rpmsg_compiler.h index 56fbf3e..6befb77 100644 --- a/lib/include/rpmsg_compiler.h +++ b/lib/include/rpmsg_compiler.h @@ -57,10 +57,33 @@ #define RL_PACKED_END #endif -/* GNUC */ -#elif defined(__GNUC__) +/* ARM GCC */ +#elif defined(__CC_ARM) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) -#define MEM_BARRIER() asm volatile("dsb" : : : "memory") +#if (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) +#include +#endif + +#define MEM_BARRIER() __schedule_barrier() + +#ifndef RL_PACKED_BEGIN +#define RL_PACKED_BEGIN _Pragma("pack(1U)") +#endif + +#ifndef RL_PACKED_END +#define RL_PACKED_END _Pragma("pack()") +#endif + +/* XCC HiFi4 */ +#elif defined(__XCC__) + +/* + * The XCC HiFi4 compiler is compatible with GNU compiler, with restrictions. + * For ARM __schedule_barrier, there's no identical intrinsic in HiFi4. + * A complete synchronization barrier would require initialize and wait ops. + * Here use NOP instead, similar to ARM __nop. +*/ +#define MEM_BARRIER() __asm__ __volatile__("nop" : : : "memory") #ifndef RL_PACKED_BEGIN #define RL_PACKED_BEGIN @@ -70,17 +93,17 @@ #define RL_PACKED_END __attribute__((__packed__)) #endif -/* ARM GCC */ -#elif defined(__CC_ARM) +/* GNUC */ +#elif defined(__GNUC__) -#define MEM_BARRIER() __schedule_barrier() +#define MEM_BARRIER() __asm__ volatile("dsb" : : : "memory") #ifndef RL_PACKED_BEGIN -#define RL_PACKED_BEGIN _Pragma("pack(1U)") +#define RL_PACKED_BEGIN #endif #ifndef RL_PACKED_END -#define RL_PACKED_END _Pragma("pack()") +#define RL_PACKED_END __attribute__((__packed__)) #endif #else diff --git a/lib/include/rpmsg_default_config.h b/lib/include/rpmsg_default_config.h index 13f3af6..e64fd46 100644 --- a/lib/include/rpmsg_default_config.h +++ b/lib/include/rpmsg_default_config.h @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,51 +39,124 @@ #include "rpmsg_config.h" #endif -/* default values */ -/* START { */ +/*! + * @addtogroup config + * @{ + * @file + */ + +//! @name Configuration options +//@{ + +//! @def RL_MS_PER_INTERVAL +//! +//! Delay in milliseconds used in non-blocking API functions for polling. +//! The default value is 1. #ifndef RL_MS_PER_INTERVAL #define RL_MS_PER_INTERVAL (1) #endif +//! @def RL_BUFFER_PAYLOAD_SIZE +//! +//! Size of the buffer payload, it must be equal to (240, 496, 1008, ...) +//! [2^n - 16]. +//! The default value is 496. #ifndef RL_BUFFER_PAYLOAD_SIZE #define RL_BUFFER_PAYLOAD_SIZE (496) #endif +//! @def RL_BUFFER_COUNT +//! +//! Number of the buffers, it must be power of two (2, 4, ...). +//! The default value is 2. #ifndef RL_BUFFER_COUNT #define RL_BUFFER_COUNT (2) #endif +//! @def RL_API_HAS_ZEROCOPY +//! +//! Zero-copy API functions enabled/disabled. +//! The default value is 1 (enabled). #ifndef RL_API_HAS_ZEROCOPY #define RL_API_HAS_ZEROCOPY (1) #endif +//! @def RL_USE_STATIC_API +//! +//! Static API functions (no dynamic allocation) enabled/disabled. +//! The default value is 0 (static API disabled). #ifndef RL_USE_STATIC_API #define RL_USE_STATIC_API (0) #endif +//! @def RL_CLEAR_USED_BUFFERS +//! +//! Clearing used buffers before returning back to the pool of free buffers +//! enabled/disabled. +//! The default value is 0 (disabled). #ifndef RL_CLEAR_USED_BUFFERS #define RL_CLEAR_USED_BUFFERS (0) #endif -/* Do not use in RPMsg-Lite to Linux configuration */ +//! @def RL_USE_MCMGR_IPC_ISR_HANDLER +//! +//! When enabled IPC interrupts are managed by the Multicore Manager (IPC +//! interrupts router), when disabled RPMsg-Lite manages IPC interrupts +//! by itself. +//! The default value is 0 (no MCMGR IPC ISR handler used). +#ifndef RL_USE_MCMGR_IPC_ISR_HANDLER +#define RL_USE_MCMGR_IPC_ISR_HANDLER (0) +#endif + +//! @def RL_USE_ENVIRONMENT_CONTEXT +//! +//! When enabled the environment layer uses its own context. +//! Added for QNX port mainly, but can be used if required. +//! The default value is 0 (no context, saves some RAM). +#ifndef RL_USE_ENVIRONMENT_CONTEXT +#define RL_USE_ENVIRONMENT_CONTEXT (0) +#endif + + +//! @def RL_DEBUG_CHECK_BUFFERS +//! +//! Do not use in RPMsg-Lite to Linux configuration #ifndef RL_DEBUG_CHECK_BUFFERS #define RL_DEBUG_CHECK_BUFFERS (0) #endif -#ifndef RL_USE_MCMGR_IPC_ISR_HANDLER -#define RL_USE_MCMGR_IPC_ISR_HANDLER (0) -#endif + +//! @def RL_HANG +//! +//! Default implementation of hang assert function + static inline void RL_HANG(void) + { + while(1) + { + + } + } + + +//! @def RL_ASSERT +//! +//! Assert implementation. #ifndef RL_ASSERT #define RL_ASSERT_BOOL(b) \ do \ { \ if (!(b)) \ - while (1) \ - ; \ + { \ + RL_HANG(); \ + } \ } while (0); #define RL_ASSERT(x) RL_ASSERT_BOOL((x)!=0) + + + + #endif -/* } END */ +//@} #endif /* _RPMSG_DEFAULT_CONFIG_H */ diff --git a/lib/include/rpmsg_env.h b/lib/include/rpmsg_env.h index d40e7e6..bea8a63 100644 --- a/lib/include/rpmsg_env.h +++ b/lib/include/rpmsg_env.h @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -86,20 +86,32 @@ * * Initializes OS/BM environment. * + * @param env_context Pointer to preallocated environment context data + * @param env_init_data Initialization data for the environment layer + * * @returns - execution status */ - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +int env_init(void ** env_context, void * env_init_data); +#else int env_init(void); +#endif /*! * env_deinit * * Uninitializes OS/BM environment. * + * @param env_context Pointer to environment context data + * * @returns - execution status */ - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +int env_deinit(void *env_context); +#else int env_deinit(void); +#endif + /*! * ------------------------------------------------------------------------- * @@ -157,23 +169,33 @@ int env_strncmp(char *dest, const char *src, unsigned long len); * * Converts logical address to physical address * - * @param address - pointer to logical address + * @param env Pointer to environment context data + * @param address Pointer to logical address * * @return - physical address */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +unsigned long env_map_vatopa(void *env, void *address); +#else unsigned long env_map_vatopa(void *address); +#endif /*! * env_map_patova * * Converts physical address to logical address * - * @param address - pointer to physical address + * @param env_context Pointer to environment context data + * @param address Pointer to physical address * * @return - logical address * */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +void *env_map_patova(void * env, unsigned long address); +#else void *env_map_patova(unsigned long address); +#endif /*! *----------------------------------------------------------------------------- @@ -319,39 +341,57 @@ void env_sleep_msec(int num_msec); * * Registers interrupt handler data for the given interrupt vector. * - * @param vector_id - virtual interrupt vector number - * @param data - interrupt handler data (virtqueue) + * @param env Pointer to environment context data + * @param vector_id Virtual interrupt vector number + * @param data Interrupt handler data (virtqueue) */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +void env_register_isr(void *env, int vector_id, void *data); +#else void env_register_isr(int vector_id, void *data); +#endif /*! * env_unregister_isr * * Unregisters interrupt handler data for the given interrupt vector. * - * @param vector_id - virtual interrupt vector number + * @param env Pointer to environment context data + * @param vector_id Virtual interrupt vector number */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +void env_unregister_isr(void *env, int vector_id); +#else void env_unregister_isr(int vector_id); +#endif /*! * env_enable_interrupt * * Enables the given interrupt * - * @param vector_id - virtual interrupt vector number + * @param env Pointer to environment context data + * @param vector_id Virtual interrupt vector number */ - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +void env_enable_interrupt(void *env, unsigned int vector_id); +#else void env_enable_interrupt(unsigned int vector_id); +#endif /*! * env_disable_interrupt * * Disables the given interrupt. * - * @param vector_id - virtual interrupt vector number + * @param env Pointer to environment context data + * @param vector_id Virtual interrupt vector number */ - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +void env_disable_interrupt(void *env, unsigned int vector_id); +#else void env_disable_interrupt(unsigned int vector_id); +#endif /*! * env_map_memory @@ -417,9 +457,9 @@ typedef void LOCK; * * Creates a message queue. * - * @param queue - pointer to created queue - * @param length - maximum number of elements in the queue - * @param item_size - queue element size in bytes + * @param queue Pointer to created queue + * @param length Maximum number of elements in the queue + * @param item_size Queue element size in bytes * * @return - status of function execution */ @@ -430,7 +470,7 @@ int env_create_queue(void **queue, int length, int element_size); * * Deletes the message queue. * - * @param queue - queue to delete + * @param queue Queue to delete */ void env_delete_queue(void *queue); @@ -440,9 +480,9 @@ void env_delete_queue(void *queue); * * Put an element in a queue. * - * @param queue - queue to put element in - * @param msg - pointer to the message to be put into the queue - * @param timeout_ms - timeout in ms + * @param queue Queue to put element in + * @param msg Pointer to the message to be put into the queue + * @param timeout_ms Timeout in ms * * @return - status of function execution */ @@ -454,9 +494,9 @@ int env_put_queue(void *queue, void *msg, int timeout_ms); * * Get an element out of a queue. * - * @param queue - queue to get element from - * @param msg - pointer to a memory to save the message - * @param timeout_ms - timeout in ms + * @param queue Queue to get element from + * @param msg Pointer to a memory to save the message + * @param timeout_ms Timeout in ms * * @return - status of function execution */ @@ -468,7 +508,7 @@ int env_get_queue(void *queue, void *msg, int timeout_ms); * * Get current queue size. * - * @param queue - queue pointer + * @param queue Queue pointer * * @return - Number of queued items in the queue */ @@ -480,9 +520,52 @@ int env_get_current_queue_size(void *queue); * * Invoke RPMSG/IRQ callback * - * @param vector - RPMSG IRQ vector ID. + * @param env Pointer to environment context data + * @param vector RPMSG IRQ vector ID. */ - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +void env_isr(void *env, int vector); +#else void env_isr(int vector); +#endif + + +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +/*! + * env_get_platform_context + * + * Get the platform layer context from the environment platform context + * + * @param env Pointer to environment context data + * + * @return Pointer to platform context data + */ +void * env_get_platform_context(void * env_context); + +/*! + * env_init_interrupt + * + * Initialize the ISR data for given virtqueue interrupt + * + * @param env Pointer to environment context data + * @param vq_id Virtqueue ID + * @param isr_data Pointer to initial ISR data + * + * @return Execution status, 0 on success + */ +int env_init_interrupt(void *env, int vq_id, void *isr_data); + +/*! + * env_deinit_interrupt + * + * Deinitialize the ISR data for given virtqueue interrupt + * + * @param env Pointer to environment context data + * @param vq_id Virtqueue ID + * + * @return Execution status, 0 on success + */ +int env_deinit_interrupt(void *env, int vq_id); +#endif #endif /* _RPMSG_ENV_H_ */ diff --git a/lib/include/rpmsg_lite.h b/lib/include/rpmsg_lite.h index c42d82a..14a5f3f 100644 --- a/lib/include/rpmsg_lite.h +++ b/lib/include/rpmsg_lite.h @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ extern "C" { #include "rpmsg_env.h" #include "llist.h" #include "rpmsg_compiler.h" +#include "rpmsg_default_config.h" //! @addtogroup rpmsg_lite //! @{ @@ -50,7 +51,7 @@ extern "C" { * Definitions ******************************************************************************/ -#define RL_VERSION "2.0.0" /*!< Current RPMsg Lite version */ +#define RL_VERSION "2.2.0" /*!< Current RPMsg Lite version */ /* Shared memory "allocator" parameters */ #define RL_WORD_SIZE (sizeof(unsigned long)) @@ -131,6 +132,9 @@ struct rpmsg_lite_instance unsigned int sh_mem_remaining; /*!< remaining free bytes of shared memory */ unsigned int sh_mem_total; /*!< total size of shared memory */ struct virtqueue_ops const *vq_ops; /*!< ops functions table pointer */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + void *env; /*!< pointer to the environment layer context */ +#endif #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1) struct vq_static_context vq_ctxt[2]; @@ -152,8 +156,9 @@ struct rpmsg_lite_instance * @param shmem_length Length of memory area given by previous parameter * @param link_id Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h * @param init_flags Initialization flags + * @param env_cfg Initialization data for the environement RPMsg-Lite layer * @param static_context RPMsg-Lite preallocated context pointer, used in case of static api (RL_USE_STATIC_API) -* + * * @return New RPMsg-Lite instance pointer or NULL. * */ @@ -163,6 +168,12 @@ struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, int link_id, uint32_t init_flags, struct rpmsg_lite_instance *static_context); +#elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, + size_t shmem_length, + int link_id, + uint32_t init_flags, + void *env_cfg); #else struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, size_t shmem_length, @@ -178,6 +189,8 @@ struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, * @param shmem_addr Shared memory base used for this instance of RPMsg-Lite * @param link_id Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h * @param init_flags Initialization flags + * @param env_cfg Initialization data for the environement RPMsg-Lite layer + * @param static_context RPMsg-Lite preallocated context pointer, used in case of static api (RL_USE_STATIC_API) * * @return New RPMsg-Lite instance pointer or NULL. * @@ -187,6 +200,8 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id, uint32_t init_flags, struct rpmsg_lite_instance *static_context); +#elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id, uint32_t init_flags, void *env_cfg); #else struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id, uint32_t init_flags); #endif diff --git a/lib/include/virtio_ring.h b/lib/include/virtio_ring.h index f27405c..18dffb4 100644 --- a/lib/include/virtio_ring.h +++ b/lib/include/virtio_ring.h @@ -34,20 +34,20 @@ #define VIRTIO_RING_H /* This marks a buffer as continuing via the next field. */ -#define VRING_DESC_F_NEXT 1 +#define VRING_DESC_F_NEXT 1U /* This marks a buffer as write-only (otherwise read-only). */ -#define VRING_DESC_F_WRITE 2 +#define VRING_DESC_F_WRITE 2U /* This means the buffer contains a list of buffer descriptors. */ -#define VRING_DESC_F_INDIRECT 4 +#define VRING_DESC_F_INDIRECT 4U /* The Host uses this in used->flags to advise the Guest: don't kick me * when you add a buffer. It's unreliable, so it's simply an * optimization. Guest will still kick if it's out of buffers. */ -#define VRING_USED_F_NO_NOTIFY 1 +#define VRING_USED_F_NO_NOTIFY 1U /* The Guest uses this in avail->flags to advise the Host: don't * interrupt me when you consume a buffer. It's unreliable, so it's * simply an optimization. */ -#define VRING_AVAIL_F_NO_INTERRUPT 1 +#define VRING_AVAIL_F_NO_INTERRUPT 1U /* VirtIO ring descriptors: 16 bytes. * These can chain together via "next". */ diff --git a/lib/include/virtqueue.h b/lib/include/virtqueue.h index 427e77e..d24f0e2 100644 --- a/lib/include/virtqueue.h +++ b/lib/include/virtqueue.h @@ -3,6 +3,8 @@ /*- * Copyright (c) 2011, Bryan Venteicher + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +32,7 @@ */ #include +#include "rpmsg_default_config.h" typedef uint8_t boolean; #include "virtio_ring.h" @@ -66,8 +69,8 @@ typedef uint8_t boolean; * handling vq_free_cnt. */ #define VQ_RING_DESC_CHAIN_END (32768) -#define VIRTQUEUE_FLAG_INDIRECT (0x0001) -#define VIRTQUEUE_FLAG_EVENT_IDX (0x0002) +#define VIRTQUEUE_FLAG_INDIRECT (0x0001U) +#define VIRTQUEUE_FLAG_EVENT_IDX (0x0002U) #define VIRTQUEUE_MAX_NAME_SZ (32) /* mind the alignment */ /* Support for indirect buffer descriptors. */ @@ -137,6 +140,9 @@ struct virtqueue uint16_t padd; /* aligned to 32bits after this: */ void *priv; /* private pointer, upper layer instance pointer */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + void *env; /* private pointer to environment layer internal context */ +#endif }; /* struct to hold vring specific information */ diff --git a/lib/rpmsg_lite/porting/environment/rpmsg_env_bm.c b/lib/rpmsg_lite/porting/environment/rpmsg_env_bm.c index 0185e79..ea432ac 100644 --- a/lib/rpmsg_lite/porting/environment/rpmsg_env_bm.c +++ b/lib/rpmsg_lite/porting/environment/rpmsg_env_bm.c @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,6 +64,10 @@ struct isr_info }; static struct isr_info isr_table[ISR_COUNT]; +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + /*! * env_init * @@ -214,7 +218,7 @@ void env_mb(void) } /*! - * osalr_mb - implementation + * env_rmb - implementation */ void env_rmb(void) { diff --git a/lib/rpmsg_lite/porting/environment/rpmsg_env_freertos.c b/lib/rpmsg_lite/porting/environment/rpmsg_env_freertos.c index 2ac3ba9..82bb323 100644 --- a/lib/rpmsg_lite/porting/environment/rpmsg_env_freertos.c +++ b/lib/rpmsg_lite/porting/environment/rpmsg_env_freertos.c @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,6 +57,14 @@ static int env_init_counter = 0; SemaphoreHandle_t env_sema = NULL; +/* RL_ENV_MAX_MUTEX_COUNT is an arbitrary count greater than 'count' + if the inital count is 1, this function behaves as a mutex + if it is greater than 1, it acts as a "resource allocator" with + the maximum of 'count' resources available. + Currently, only the first use-case is applicable/applied in RPMsg-Lite. + */ +#define RL_ENV_MAX_MUTEX_COUNT (10) + /* Max supported ISR counts */ #define ISR_COUNT (32) /*! @@ -68,6 +76,10 @@ struct isr_info }; static struct isr_info isr_table[ISR_COUNT]; +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + /*! * env_in_isr * @@ -117,7 +129,7 @@ int env_init(void) * if needed and other tasks to wait for the * blocking to be done. * This is in ENV layer as this is ENV specific.*/ - xSemaphoreTake(env_sema, portMAX_DELAY); + (void)xSemaphoreTake(env_sema, portMAX_DELAY); xSemaphoreGive(env_sema); return 0; } @@ -263,7 +275,7 @@ void env_mb(void) } /*! - * osalr_mb - implementation + * env_rmb - implementation */ void env_rmb(void) { @@ -306,7 +318,12 @@ void *env_map_patova(unsigned long address) */ int env_create_mutex(void **lock, int count) { - *lock = xSemaphoreCreateCounting(10, count); + if(count > RL_ENV_MAX_MUTEX_COUNT) + { + return -1; + } + + *lock = xSemaphoreCreateCounting(RL_ENV_MAX_MUTEX_COUNT, count); if (*lock) { return 0; @@ -337,9 +354,9 @@ void env_delete_mutex(void *lock) void env_lock_mutex(void *lock) { SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)lock; - if (!env_in_isr()) + if (env_in_isr() == 0) { - xSemaphoreTake(xSemaphore, portMAX_DELAY); + (void)xSemaphoreTake(xSemaphore, portMAX_DELAY); } } @@ -351,7 +368,7 @@ void env_lock_mutex(void *lock) void env_unlock_mutex(void *lock) { SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)lock; - if (!env_in_isr()) + if (env_in_isr() == 0) { xSemaphoreGive(xSemaphore); } @@ -400,7 +417,7 @@ void env_acquire_sync_lock(void *lock) } else { - xSemaphoreTake(xSemaphore, portMAX_DELAY); + (void)xSemaphoreTake(xSemaphore, portMAX_DELAY); } } @@ -563,7 +580,7 @@ void env_isr(int vector) * * @param queue - pointer to created queue * @param length - maximum number of elements in the queue - * @param item_size - queue element size in bytes + * @param element_size - queue element size in bytes * * @return - status of function execution */ diff --git a/lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.c b/lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.c new file mode 100644 index 0000000..d82f4cc --- /dev/null +++ b/lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.c @@ -0,0 +1,692 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * Copyright (c) 2015 Xilinx, Inc. + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/************************************************************************** + * FILE NAME + * + * rpmsg_env_qnx.c + * + * + * DESCRIPTION + * + * This file is QNX Implementation of env layer. + * + * + **************************************************************************/ + +#include "rpmsg_env.h" +#include "rpmsg_platform.h" +#include "virtqueue.h" + +#include +#include +#include +#include +#include "rpmsg_env_qnx.h" + +#if __PTR_BITS__ > 32 + #include + #include +#else + #include +#endif + +/* Max supported ISR counts */ +#define ISR_COUNT (32) + +#if (!defined(RL_USE_ENVIRONMENT_CONTEXT)) || (RL_USE_ENVIRONMENT_CONTEXT != 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 1" +#endif + + +/** + * Structure to keep track of registered ISR's. + */ +struct isr_info { + void *data; + volatile unsigned enabled; +}; + +/** + * Structure to hold queue information + */ +typedef struct env_queue { + mqd_t mqd; + size_t msg_len; +} env_queue_t; + +/** + * Env. context structure + */ +typedef struct env_context { + void *platform_context; /* Pointer to platform context */ + unsigned long pa; /* Physical address of memory pool reserved for rpmsg */ + void *va; /* Virtual address of the memory pool */ + struct isr_info isr_table[ISR_COUNT]; /* Table with registered Virt. queue data */ +} env_context_t; + +/** + * Returns pointer to platform context. + * + * @param env_context Pointer to env. context + * + * @return Pointer to platform context + */ +void *env_get_platform_context(void * env_context) +{ + env_context_t * env = env_context; + return env->platform_context; +} + +/*! + * env_init + * + * Initializes OS/BM environment. + * + */ +int env_init(void ** env_context, void * env_init_data) +{ + rpmsg_env_init_t *init = env_init_data; + imx_rpmsg_env_cfg_t *user_cfg; + + if (init) { + user_cfg = init->user_input; + env_context_t *ctx = env_allocate_memory(sizeof(env_context_t)); + if (!ctx) { + return -1; + } + /* Save virtual and phy address of mmaped memory region */ + ctx->pa = init->pa; + ctx->va = init->va; + /* Initialize platform, dereference user_input to get platform cfg address */ + if (platform_init(&ctx->platform_context, ctx, user_cfg ? user_cfg->platform_cfg : NULL) != 0) { + env_free_memory(ctx); + return -1; + } + *env_context = ctx; + return 0; + } + return -1; +} + +/*! + * env_deinit + * + * Uninitializes OS/BM environment. + * + * @returns - execution status + */ +int env_deinit(void *env_context) +{ + env_context_t *ctx = env_context; + platform_deinit(ctx->platform_context); + env_free_memory(ctx); + return 0; +} + +/*! + * env_allocate_memory - implementation + * + * @param size + */ +void *env_allocate_memory(unsigned int size) +{ + return malloc(size); +} + +/*! + * env_free_memory - implementation + * + * @param ptr + */ +void env_free_memory(void *ptr) +{ + free(ptr); +} + +/*! + * + * env_memset - implementation + * + * @param ptr + * @param value + * @param size + */ +void env_memset(void *ptr, int value, unsigned long size) +{ + memset(ptr, value, size); +} + +/*! + * + * env_memcpy - implementation + * + * @param dst + * @param src + * @param len + */ +void env_memcpy(void *dst, void const *src, unsigned long len) +{ + memcpy(dst, src, len); +} + +/*! + * + * env_strcmp - implementation + * + * @param dst + * @param src + */ + +int env_strcmp(const char *dst, const char *src) +{ + return (strcmp(dst, src)); +} + +/*! + * + * env_strncpy - implementation + * + * @param dest + * @param src + * @param len + */ +void env_strncpy(char *dest, const char *src, unsigned long len) +{ + strncpy(dest, src, len); +} + +/*! + * + * env_strncmp - implementation + * + * @param dest + * @param src + * @param len + */ +int env_strncmp(char *dest, const char *src, unsigned long len) +{ + return (strncmp(dest, src, len)); +} + +/*! + * + * env_mb - implementation + * + */ +void env_mb(void) +{ + dsb(); +} + +/*! + * env_rmb - implementation + */ +void env_rmb(void) +{ + dsb(); +} + +/*! + * env_wmb - implementation + */ +void env_wmb(void) +{ + dsb(); +} + +/*! + * env_map_vatopa - implementation + * + * @param address + */ +unsigned long env_map_vatopa(void *env, void *address) +{ +#if IMX_MMAP_VA_ON_PA + return ((unsigned long)address); +#else + /* This is faster then mem_offset64() */ + env_context_t * ctx = env; + uint64_t va = (uint64_t) address; + uint64_t va_start = (uint64_t) ctx->va; + uint64_t pa = ctx->pa + (va - va_start); + return pa; +#endif +} + +/*! + * env_map_patova - implementation + * + * @param address + */ +void *env_map_patova(void *env, unsigned long address) +{ +#if IMX_MMAP_VA_ON_PA + return ((void *)address); +#else + env_context_t * ctx = env; + uint64_t va_start = (uint64_t) ctx->va; + uint64_t va = (va_start + (address - ctx->pa)); + return (void *)va; +#endif +} + +/*! + * env_create_mutex + * + * Creates a mutex with the given initial count. + * + */ +int env_create_mutex(void **lock, int count) +{ + *lock = env_allocate_memory(sizeof(pthread_mutex_t)); + if (!(*lock)) { + return -1; + } + if (pthread_mutex_init((pthread_mutex_t *)*lock, NULL) != EOK) { + env_free_memory(*lock); + *lock = NULL; + return -1; + } + return 0; +} + +/*! + * env_delete_mutex + * + * Deletes the given lock + * + */ +void env_delete_mutex(void *lock) +{ + pthread_mutex_destroy(lock); + env_free_memory(lock); +} + +/*! + * env_lock_mutex + * + * Tries to acquire the lock, if lock is not available then call to + * this function will suspend. + */ +void env_lock_mutex(void *lock) +{ + pthread_mutex_lock(lock); +} + +/*! + * env_unlock_mutex + * + * Releases the given lock. + */ +void env_unlock_mutex(void *lock) +{ + pthread_mutex_unlock(lock); +} + +/*! + * env_create_sync_lock + * + * Creates a synchronization lock primitive. It is used + * when signal has to be sent from the interrupt context to main + * thread context. + */ +int env_create_sync_lock(void **lock, int state) +{ + return env_create_mutex(lock, state); /* state=1 .. initially free */ + +} + +/*! + * env_delete_sync_lock + * + * Deletes the given lock + * + */ +void env_delete_sync_lock(void *lock) +{ + if (lock) { + env_delete_mutex(lock); + } +} + +/*! + * env_acquire_sync_lock + * + * Tries to acquire the lock, if lock is not available then call to + * this function waits for lock to become available. + */ +void env_acquire_sync_lock(void *lock) +{ + env_lock_mutex(lock); +} + +/*! + * env_release_sync_lock + * + * Releases the given lock. + */ +void env_release_sync_lock(void *lock) +{ + env_unlock_mutex(lock); +} + +/*! + * env_sleep_msec + * + * Suspends the calling thread for given time , in msecs. + */ +void env_sleep_msec(int num_msec) +{ + delay(num_msec); +} + +/*! + * env_register_isr + * + * Registers interrupt handler data for the given interrupt vector. + * + * @param vector_id - virtual interrupt vector number + * @param data - interrupt handler data (virtqueue) + */ +void env_register_isr(void *env, int vector_id, void *data) +{ + + env_context_t * ctx = env; + + RL_ASSERT(vector_id < ISR_COUNT); + if (vector_id < ISR_COUNT) { + ctx->isr_table[vector_id].data = data; + } + +} + +/*! + * env_unregister_isr + * + * Unregisters interrupt handler data for the given interrupt vector. + * + * @param vector_id - virtual interrupt vector number + */ +void env_unregister_isr(void *env, int vector_id) +{ + env_context_t * ctx = env; + + RL_ASSERT(vector_id < ISR_COUNT); + if (vector_id < ISR_COUNT) { + ctx->isr_table[vector_id].data = NULL; + ctx->isr_table[vector_id].enabled = 0; + } +} + +/*! + * env_enable_interrupt + * + * Enables the given interrupt + * + * @param vector_id - virtual interrupt vector number + */ +void env_enable_interrupt(void *env, unsigned int vector_id) +{ + env_context_t * ctx = env; + + RL_ASSERT(vector_id < ISR_COUNT); + if (vector_id < ISR_COUNT) { + ctx->isr_table[vector_id].enabled = 1; + } +} + +/*! + * env_disable_interrupt + * + * Disables the given interrupt + * + * @param vector_id - virtual interrupt vector number + */ +void env_disable_interrupt(void *env, unsigned int vector_id) +{ + env_context_t * ctx = env; + + RL_ASSERT(vector_id < ISR_COUNT); + if (vector_id < ISR_COUNT) { + ctx->isr_table[vector_id].enabled = 0; + } +} + +/*! + * env_map_memory + * + * Enables memory mapping for given memory region. + * + * @param pa - physical address of memory + * @param va - logical address of memory + * @param size - memory size + * param flags - flags for cache/uncached and access type + */ +void env_map_memory(unsigned int pa, unsigned int va, unsigned int size, unsigned int flags) +{ + platform_map_mem_region(va, pa, size, flags); +} + +/*! + * env_disable_cache + * + * Disables system caches. + * + */ +void env_disable_cache(void) +{ + platform_cache_all_flush_invalidate(); + platform_cache_disable(); +} + +/*! + * + * env_get_timestamp + * + * Returns a 64 bit time stamp. + * + * + */ +unsigned long long env_get_timestamp(void) +{ + fprintf(stderr, "%s unsupported\n", __FUNCTION__); + return 0; +} + +/*========================================================= */ +/* Util data / functions */ + +/** + * Called from receive thread + * + * @param env Pointer to env context + * @param vector Vector ID. + */ +void env_isr(void * env, int vector) +{ + struct isr_info *info; + env_context_t *ctx = env; + + RL_ASSERT(vector < ISR_COUNT); + if (vector < ISR_COUNT) { + info = &ctx->isr_table[vector]; + if (info->enabled) { + virtqueue_notification((struct virtqueue *)info->data); + } + } +} + +/** + * Called by rpmsg to init an interrupt + * + * @param env Pointer to env context. + * @param vq_id Virt. queue ID. + * @param isr_data Pointer to interrupt data. + * + * @return Execution status. + */ +int env_init_interrupt(void *env, int vq_id, void *isr_data) +{ + env_register_isr(env, vq_id, isr_data); + return 0; +} + +/** + * Called by rpmsg to deinit an interrupt. + * + * @param env Pointer to env context. + * @param vq_id Virt. queue ID. + * + * @return Execution status. + */ +int env_deinit_interrupt(void *env, int vq_id) +{ + env_unregister_isr(env, vq_id); + return 0; +} + +/** + * env_create_queue + * + * Creates a message queue. + * + * @param queue - pointer to created queue + * @param length - maximum number of elements in the queue + * @param element_size - queue element size in bytes + * + * @return - status of function execution + */ +int env_create_queue(void **queue, int length, int element_size) +{ + char name[100]; + struct mq_attr mqstat; + env_queue_t * q = env_allocate_memory(sizeof(env_queue_t)); + if (!q) { + return -1; + } + /* Creates a unique queue in /dev/mq/PID_virtaddr_length */ + sprintf(name, "/%u_0x%lx_%u", getpid(), (uint64_t)q, length); + mqstat.mq_maxmsg = length; + mqstat.mq_msgsize = element_size; + mqstat.mq_flags = 0; + mqstat.mq_curmsgs = 0; + mqstat.mq_recvwait = 0; + mqstat.mq_sendwait = 0; + q->msg_len = element_size; + q->mqd = mq_open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &mqstat); + if (q->mqd == -1) { + env_free_memory(q); + fprintf(stderr, "mq_open failed: %s\n", strerror(errno)); + return -1; + } + /* Return queue */ + *queue = q; + return 0; +} + +/*! + * env_delete_queue + * + * Deletes the message queue. + * + * @param queue - queue to delete + */ +void env_delete_queue(void *queue) +{ + env_queue_t * q = queue; + + mq_close(q->mqd); + env_free_memory(queue); +} + +/*! + * env_put_queue + * + * Put an element in a queue. + * + * @param queue - queue to put element in + * @param msg - pointer to the message to be put into the queue + * @param timeout_ms - timeout in ms + * + * @return - status of function execution + */ +int env_put_queue(void *queue, void *msg, int timeout_ms) +{ + env_queue_t * q = queue; + + if (mq_send(q->mqd, (const char *)msg, q->msg_len, 0)) { + fprintf(stderr, "mq_send failed: %s\n", strerror(errno)); + return 0; + } + return 1; +} + +/*! + * env_get_queue + * + * Get an element out of a queue. + * + * @param queue - queue to get element from + * @param msg - pointer to a memory to save the message + * @param timeout_ms - timeout in ms + * + * @return - status of function execution + */ +int env_get_queue(void *queue, void *msg, int timeout_ms) +{ + env_queue_t * q = queue; + if (mq_receive(q->mqd, msg, q->msg_len, NULL) == -1) { + fprintf(stderr, "mq_receive failed: %s\n", strerror(errno)); + return 0; + } + return 1; +} + +/*! + * env_get_current_queue_size + * + * Get current queue size. + * + * @param queue - queue pointer + * + * @return - Number of queued items in the queue + */ +int env_get_current_queue_size(void *queue) +{ + struct mq_attr mqstat; + env_queue_t * q = queue; + if (mq_getattr(q->mqd, &mqstat) != -1) { + return mqstat.mq_curmsgs; + } + return 0; +} diff --git a/lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.h b/lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.h new file mode 100644 index 0000000..26abbbc --- /dev/null +++ b/lib/rpmsg_lite/porting/environment/rpmsg_env_qnx.h @@ -0,0 +1,55 @@ +/* + * Copyright 2016-2019 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/************************************************************************** + * FILE NAME + * + * rpmsg_env_qnx.h + * + * + * DESCRIPTION + * + * This file is QNX header file of env layer. + * + * + **************************************************************************/ +#ifndef RPMSG_ENV_QNX_H +#define RPMSG_ENV_QNX_H + +#include + +typedef struct rpmsg_env_init { + void *user_input; /* Pointer to user init cfg */ + unsigned long pa; /* Physical address of memory pool reserved for rpmsg */ + void *va; /* Virtual address of the memory pool */ +} rpmsg_env_init_t; + +#endif diff --git a/lib/rpmsg_lite/porting/environment/rpmsg_env_zephyr.c b/lib/rpmsg_lite/porting/environment/rpmsg_env_zephyr.c new file mode 100644 index 0000000..02399b1 --- /dev/null +++ b/lib/rpmsg_lite/porting/environment/rpmsg_env_zephyr.c @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2014, Mentor Graphics Corporation + * Copyright (c) 2015 Xilinx, Inc. + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/************************************************************************** + * FILE NAME + * + * rpmsg_zephyr_env.c + * + * + * DESCRIPTION + * + * This file is Zephyr RTOS Implementation of env layer for OpenAMP. + * + * + **************************************************************************/ + +#include "rpmsg_env.h" +#include +#include "rpmsg_platform.h" +#include "virtqueue.h" +#include "rpmsg_compiler.h" + +#include +#include + + +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + +/* RL_ENV_MAX_MUTEX_COUNT is an arbitrary count greater than 'count' + if the inital count is 1, this function behaves as a mutex + if it is greater than 1, it acts as a "resource allocator" with + the maximum of 'count' resources available. + Currently, only the first use-case is applicable/applied in RPMsg-Lite. + */ +#define RL_ENV_MAX_MUTEX_COUNT (10) + +static int env_init_counter = 0; +static struct k_sem env_sema = {0}; + +/* Max supported ISR counts */ +#define ISR_COUNT (32) +/*! + * Structure to keep track of registered ISR's. + */ +struct isr_info +{ + void *data; +}; +static struct isr_info isr_table[ISR_COUNT]; + +/*! + * env_in_isr + * + * @returns - true, if currently in ISR + * + */ +static int env_in_isr(void) +{ + return platform_in_isr(); +} + +/*! + * env_init + * + * Initializes OS/BM environment. + * + */ +int env_init(void) +{ + int retval; + k_sched_lock(); /* stop scheduler */ + /* verify 'env_init_counter' */ + RL_ASSERT(env_init_counter >= 0); + if (env_init_counter < 0) + { + k_sched_unlock(); /* re-enable scheduler */ + return -1; + } + env_init_counter++; + /* multiple call of 'env_init' - return ok */ + if (env_init_counter <= 1) + { + /* first call */ + k_sem_init(&env_sema, 0, 1); + memset(isr_table, 0, sizeof(isr_table)); + k_sched_unlock(); + retval = platform_init(); + k_sem_give(&env_sema); + + return retval; + } + else + { + k_sched_unlock(); + /* Get the semaphore and then return it, + * this allows for platform_init() to block + * if needed and other tasks to wait for the + * blocking to be done. + * This is in ENV layer as this is ENV specific.*/ + k_sem_take(&env_sema, K_FOREVER); + k_sem_give(&env_sema); + return 0; + } +} + +/*! + * env_deinit + * + * Uninitializes OS/BM environment. + * + * @returns - execution status + */ +int env_deinit(void) +{ + int retval; + + k_sched_lock(); /* stop scheduler */ + /* verify 'env_init_counter' */ + RL_ASSERT(env_init_counter > 0); + if (env_init_counter <= 0) + { + k_sched_unlock(); /* re-enable scheduler */ + return -1; + } + + /* counter on zero - call platform deinit */ + env_init_counter--; + /* multiple call of 'env_deinit' - return ok */ + if (env_init_counter <= 0) + { + /* last call */ + memset(isr_table, 0, sizeof(isr_table)); + retval = platform_deinit(); + k_sem_reset(&env_sema); + k_sched_unlock(); + + return retval; + } + else + { + k_sched_unlock(); + return 0; + } +} + +/*! + * env_allocate_memory - implementation + * + * @param size + */ +void *env_allocate_memory(unsigned int size) +{ + return (k_malloc(size)); +} + +/*! + * env_free_memory - implementation + * + * @param ptr + */ +void env_free_memory(void *ptr) +{ + if (ptr != NULL) + { + k_free(ptr); + } +} + +/*! + * + * env_memset - implementation + * + * @param ptr + * @param value + * @param size + */ +void env_memset(void *ptr, int value, unsigned long size) +{ + memset(ptr, value, size); +} + +/*! + * + * env_memcpy - implementation + * + * @param dst + * @param src + * @param len + */ +void env_memcpy(void *dst, void const *src, unsigned long len) +{ + memcpy(dst, src, len); +} + +/*! + * + * env_strcmp - implementation + * + * @param dst + * @param src + */ + +int env_strcmp(const char *dst, const char *src) +{ + return (strcmp(dst, src)); +} + +/*! + * + * env_strncpy - implementation + * + * @param dst + * @param src + * @param len + */ +void env_strncpy(char *dst, const char *src, unsigned long len) +{ + strncpy(dst, src, len); +} + +/*! + * + * env_strncmp - implementation + * + * @param dst + * @param src + * @param len + */ +int env_strncmp(char *dst, const char *src, unsigned long len) +{ + return (strncmp(dst, src, len)); +} + +/*! + * + * env_mb - implementation + * + */ +void env_mb(void) +{ + MEM_BARRIER(); +} + +/*! + * env_rmb - implementation + */ +void env_rmb(void) +{ + MEM_BARRIER(); +} + +/*! + * env_wmb - implementation + */ +void env_wmb(void) +{ + MEM_BARRIER(); +} + +/*! + * env_map_vatopa - implementation + * + * @param address + */ +unsigned long env_map_vatopa(void *address) +{ + return platform_vatopa(address); +} + +/*! + * env_map_patova - implementation + * + * @param address + */ +void *env_map_patova(unsigned long address) +{ + return platform_patova(address); +} + +/*! + * env_create_mutex + * + * Creates a mutex with the given initial count. + * + */ +int env_create_mutex(void **lock, int count) +{ + struct k_sem *semaphore_ptr; + + semaphore_ptr = (struct k_sem *)env_allocate_memory(sizeof(struct k_sem)); + if(semaphore_ptr == NULL) + { + return -1; + } + + if(count > RL_ENV_MAX_MUTEX_COUNT) + { + return -1; + } + + k_sem_init(semaphore_ptr, count, RL_ENV_MAX_MUTEX_COUNT); + *lock = (void*)semaphore_ptr; + return 0; +} + +/*! + * env_delete_mutex + * + * Deletes the given lock + * + */ +void env_delete_mutex(void *lock) +{ + k_sem_reset(lock); + env_free_memory(lock); +} + +/*! + * env_lock_mutex + * + * Tries to acquire the lock, if lock is not available then call to + * this function will suspend. + */ +void env_lock_mutex(void *lock) +{ + if (env_in_isr() == 0) + { + k_sem_take((struct k_sem *)lock, K_FOREVER); + } +} + +/*! + * env_unlock_mutex + * + * Releases the given lock. + */ +void env_unlock_mutex(void *lock) +{ + if (env_in_isr() == 0) + { + k_sem_give((struct k_sem *)lock); + } +} + +/*! + * env_create_sync_lock + * + * Creates a synchronization lock primitive. It is used + * when signal has to be sent from the interrupt context to main + * thread context. + */ +int env_create_sync_lock(void **lock, int state) +{ + return env_create_mutex(lock, state); /* state=1 .. initially free */ +} + +/*! + * env_delete_sync_lock + * + * Deletes the given lock + * + */ +void env_delete_sync_lock(void *lock) +{ + if (lock) + { + env_delete_mutex(lock); + } +} + +/*! + * env_acquire_sync_lock + * + * Tries to acquire the lock, if lock is not available then call to + * this function waits for lock to become available. + */ +void env_acquire_sync_lock(void *lock) +{ + if (lock) + { + env_lock_mutex(lock); + } +} + +/*! + * env_release_sync_lock + * + * Releases the given lock. + */ +void env_release_sync_lock(void *lock) +{ + if (lock) + { + env_unlock_mutex(lock); + } +} + +/*! + * env_sleep_msec + * + * Suspends the calling thread for given time , in msecs. + */ +void env_sleep_msec(int num_msec) +{ + k_sleep(num_msec); +} + +/*! + * env_register_isr + * + * Registers interrupt handler data for the given interrupt vector. + * + * @param vector_id - virtual interrupt vector number + * @param data - interrupt handler data (virtqueue) + */ +void env_register_isr(int vector_id, void *data) +{ + RL_ASSERT(vector_id < ISR_COUNT); + if (vector_id < ISR_COUNT) + { + isr_table[vector_id].data = data; + } +} + +/*! + * env_unregister_isr + * + * Unregisters interrupt handler data for the given interrupt vector. + * + * @param vector_id - virtual interrupt vector number + */ +void env_unregister_isr(int vector_id) +{ + RL_ASSERT(vector_id < ISR_COUNT); + if (vector_id < ISR_COUNT) + { + isr_table[vector_id].data = NULL; + } +} + +/*! + * env_enable_interrupt + * + * Enables the given interrupt + * + * @param vector_id - interrupt vector number + */ + +void env_enable_interrupt(unsigned int vector_id) +{ + platform_interrupt_enable(vector_id); +} + +/*! + * env_disable_interrupt + * + * Disables the given interrupt + * + * @param vector_id - interrupt vector number + */ + +void env_disable_interrupt(unsigned int vector_id) +{ + platform_interrupt_disable(vector_id); +} + +/*! + * env_map_memory + * + * Enables memory mapping for given memory region. + * + * @param pa - physical address of memory + * @param va - logical address of memory + * @param size - memory size + * param flags - flags for cache/uncached and access type + */ + +void env_map_memory(unsigned int pa, unsigned int va, unsigned int size, unsigned int flags) +{ + platform_map_mem_region(va, pa, size, flags); +} + +/*! + * env_disable_cache + * + * Disables system caches. + * + */ + +void env_disable_cache(void) +{ + platform_cache_all_flush_invalidate(); + platform_cache_disable(); +} + +/*========================================================= */ +/* Util data / functions */ + +void env_isr(int vector) +{ + struct isr_info *info; + RL_ASSERT(vector < ISR_COUNT); + if (vector < ISR_COUNT) + { + info = &isr_table[vector]; + virtqueue_notification((struct virtqueue *)info->data); + } +} + +/* + * env_create_queue + * + * Creates a message queue. + * + * @param queue - pointer to created queue + * @param length - maximum number of elements in the queue + * @param element_size - queue element size in bytes + * + * @return - status of function execution + */ +int env_create_queue(void **queue, int length, int element_size) +{ + struct k_msgq *queue_ptr = NULL; + char *msgq_buffer_ptr = NULL; + + queue_ptr = (struct k_msgq *)env_allocate_memory(sizeof(struct k_msgq)); + msgq_buffer_ptr = (char *)env_allocate_memory(length * element_size); + if((queue_ptr == NULL) || (msgq_buffer_ptr == NULL)) + { + return -1; + } + k_msgq_init(queue_ptr, msgq_buffer_ptr, element_size, length); + + *queue = (void*)queue_ptr; + return 0; +} + +/*! + * env_delete_queue + * + * Deletes the message queue. + * + * @param queue - queue to delete + */ + +void env_delete_queue(void *queue) +{ + k_msgq_purge((struct k_msgq*)queue); + env_free_memory(((struct k_msgq*)queue)->buffer_start); + env_free_memory(queue); +} + +/*! + * env_put_queue + * + * Put an element in a queue. + * + * @param queue - queue to put element in + * @param msg - pointer to the message to be put into the queue + * @param timeout_ms - timeout in ms + * + * @return - status of function execution + */ + +int env_put_queue(void *queue, void *msg, int timeout_ms) +{ + if(env_in_isr()) + { + timeout_ms = 0; /* force timeout == 0 when in ISR */ + } + + if (0 == k_msgq_put((struct k_msgq*)queue, msg, timeout_ms)) + { + return 1; + } + return 0; +} + +/*! + * env_get_queue + * + * Get an element out of a queue. + * + * @param queue - queue to get element from + * @param msg - pointer to a memory to save the message + * @param timeout_ms - timeout in ms + * + * @return - status of function execution + */ + +int env_get_queue(void *queue, void *msg, int timeout_ms) +{ + + if(env_in_isr()) + { + timeout_ms = 0; /* force timeout == 0 when in ISR */ + } + + if (0 == k_msgq_get((struct k_msgq*)queue, msg, timeout_ms)) + { + return 1; + } + return 0; +} + +/*! + * env_get_current_queue_size + * + * Get current queue size. + * + * @param queue - queue pointer + * + * @return - Number of queued items in the queue + */ + +int env_get_current_queue_size(void *queue) +{ + return k_msgq_num_used_get((struct k_msgq*)queue); +} diff --git a/lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform.c b/lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform.c index 15d1335..69f87e5 100644 --- a/lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform.c +++ b/lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform.c @@ -1,37 +1,11 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#include #include #include #include "rpmsg_platform.h" @@ -40,56 +14,76 @@ #include "board.h" #include "mu_imx.h" -#define APP_MU_IRQ_PRIORITY (3) +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + +#define APP_MU_IRQ_PRIORITY (3U) static int isr_counter = 0; static int disable_counter = 0; -static void *lock; +static void *platform_lock; + -int platform_init_interrupt(int vq_id, void *isr_data) +void platform_global_isr_disable(void) +{ + __asm volatile("cpsid i"); +} + + +void platform_global_isr_enable(void) +{ + __asm volatile("cpsie i"); +} + +int platform_init_interrupt(unsigned int vector_id, void *isr_data) { /* Register ISR to environment layer */ - env_register_isr(vq_id, isr_data); + env_register_isr(vector_id, isr_data); /* Prepare the MU Hardware, enable channel 1 interrupt */ - env_lock_mutex(lock); + env_lock_mutex(platform_lock); - assert(0 <= isr_counter); + RL_ASSERT(0 <= isr_counter); if (!isr_counter) + { MU_EnableRxFullInt(MUB, RPMSG_MU_CHANNEL); + } isr_counter++; - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -int platform_deinit_interrupt(int vq_id) +int platform_deinit_interrupt(unsigned int vector_id) { - /* Prepare the MU Hardware, enable channel 1 interrupt */ - env_lock_mutex(lock); + /* Prepare the MU Hardware */ + env_lock_mutex(platform_lock); - assert(0 < isr_counter); + RL_ASSERT(0 < isr_counter); isr_counter--; if (!isr_counter) + { MU_DisableRxFullInt(MUB, RPMSG_MU_CHANNEL); + } /* Unregister ISR from environment layer */ - env_unregister_isr(vq_id); + env_unregister_isr(vector_id); - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -void platform_notify(int vq_id) +void platform_notify(unsigned int vector_id) { /* As Linux suggests, use MU->Data Channle 1 as communication channel */ - uint32_t msg = (RL_GET_Q_ID(vq_id)) << 16; + uint32_t msg = (RL_GET_Q_ID(vector_id)) << 16; - env_lock_mutex(lock); + env_lock_mutex(platform_lock); MU_SendMsg(MUB, RPMSG_MU_CHANNEL, msg); - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); } /* @@ -104,6 +98,11 @@ void rpmsg_handler(void) channel = msg >> 16; env_isr(channel); } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif return; } @@ -149,26 +148,26 @@ int platform_in_isr(void) /** * platform_interrupt_enable * - * Enable peripheral-related interrupt with passed priority and type. + * Enable peripheral-related interrupt * - * @param vq_id Vector ID that need to be converted to IRQ number - * @param trigger_type IRQ active level - * @param trigger_type IRQ priority + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked.. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_enable(unsigned int vq_id) +int platform_interrupt_enable(unsigned int vector_id) { - assert(0 < disable_counter); + RL_ASSERT(0 < disable_counter); - __asm volatile("cpsid i"); + platform_global_isr_disable(); disable_counter--; if (!disable_counter) + { NVIC_EnableIRQ(MU_M4_IRQn); - __asm volatile("cpsie i"); - return (vq_id); + } + platform_global_isr_enable(); + return (vector_id); } /** @@ -176,24 +175,25 @@ int platform_interrupt_enable(unsigned int vq_id) * * Disable peripheral-related interrupt. * - * @param vq_id Vector ID that need to be converted to IRQ number + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_disable(unsigned int vq_id) +int platform_interrupt_disable(unsigned int vector_id) { - assert(0 <= disable_counter); + RL_ASSERT(0 <= disable_counter); - __asm volatile("cpsid i"); - // virtqueues use the same NVIC vector - // if counter is set - the interrupts are disabled + platform_global_isr_disable(); + /* virtqueues use the same NVIC vector + if counter is set - the interrupts are disabled */ if (!disable_counter) + { NVIC_DisableIRQ(MU_M4_IRQn); - + } disable_counter++; - __asm volatile("cpsie i"); - return (vq_id); + platform_global_isr_enable(); + return (vector_id); } /** @@ -212,7 +212,7 @@ void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsig * Dummy implementation * */ -void platform_cache_all_flush_invalidate() +void platform_cache_all_flush_invalidate(void) { } @@ -222,7 +222,7 @@ void platform_cache_all_flush_invalidate() * Dummy implementation * */ -void platform_cache_disable() +void platform_cache_disable(void) { } @@ -264,7 +264,10 @@ int platform_init(void) NVIC_EnableIRQ(BOARD_MU_IRQ_NUM); /* Create lock used in multi-instanced RPMsg */ - env_create_mutex(&lock, 1); + if(0 != env_create_mutex(&platform_lock, 1)) + { + return -1; + } return 0; } @@ -277,7 +280,7 @@ int platform_init(void) int platform_deinit(void) { /* Delete lock used in multi-instanced RPMsg */ - env_delete_mutex(lock); - lock = NULL; + env_delete_mutex(platform_lock); + platform_lock = NULL; return 0; } diff --git a/lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform_zephyr_ipm.c b/lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform_zephyr_ipm.c new file mode 100644 index 0000000..04c9a48 --- /dev/null +++ b/lib/rpmsg_lite/porting/platform/imx6sx_m4/rpmsg_platform_zephyr_ipm.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include "rpmsg_platform.h" +#include "rpmsg_env.h" +#include + + +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + + +static int isr_counter = 0; +static int disable_counter = 0; +static void *platform_lock; +static struct device *ipm_handle = NULL; + +void platform_ipm_callback(void *context, u32_t id, volatile void *data) +{ + if (id != RPMSG_MU_CHANNEL) + { + return; + } + + /* Data to be transmitted from Master */ + if (*(uint32_t*)data == 0U) + { + env_isr(0); + } + + /* Data to be received from Master */ + if (*(uint32_t*)data == 0x10000U) + { + env_isr(1); + } +} + +void platform_global_isr_disable(void) +{ + __asm volatile("cpsid i"); +} + +void platform_global_isr_enable(void) +{ + __asm volatile("cpsie i"); +} + +int platform_init_interrupt(unsigned int vector_id, void *isr_data) +{ + /* Register ISR to environment layer */ + env_register_isr(vector_id, isr_data); + + env_lock_mutex(platform_lock); + + RL_ASSERT(0 <= isr_counter); + + isr_counter++; + + env_unlock_mutex(platform_lock); + + return 0; +} + +int platform_deinit_interrupt(unsigned int vector_id) +{ + /* Prepare the MU Hardware */ + env_lock_mutex(platform_lock); + + RL_ASSERT(0 < isr_counter); + isr_counter--; + if ((!isr_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 0); + } + + /* Unregister ISR from environment layer */ + env_unregister_isr(vector_id); + + env_unlock_mutex(platform_lock); + + return 0; +} + +void platform_notify(unsigned int vector_id) +{ + int status; + switch (RL_GET_LINK_ID(vector_id)) + { + case RL_PLATFORM_IMX6SX_M4_LINK_ID: + env_lock_mutex(platform_lock); + uint32_t data = (RL_GET_Q_ID(vector_id) << 16); + RL_ASSERT(ipm_handle); + do { + status = ipm_send(ipm_handle, 0, RPMSG_MU_CHANNEL, &data, sizeof(uint32_t)); + } while (status == EBUSY); + env_unlock_mutex(platform_lock); + return; + + default: + return; + } +} + +/** + * platform_in_isr + * + * Return whether CPU is processing IRQ + * + * @return True for IRQ, false otherwise. + * + */ +int platform_in_isr(void) +{ + return (0 != k_is_in_isr()); +} + +/** + * platform_interrupt_enable + * + * Enable peripheral-related interrupt + * + * @param vector_id Virtual vector ID that needs to be converted to IRQ number + * + * @return vector_id Return value is never checked. + * + */ +int platform_interrupt_enable(unsigned int vector_id) +{ + RL_ASSERT(0 < disable_counter); + + platform_global_isr_disable(); + disable_counter--; + + if ((!disable_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 1); + } + platform_global_isr_enable(); + return (vector_id); +} + +/** + * platform_interrupt_disable + * + * Disable peripheral-related interrupt. + * + * @param vector_id Virtual vector ID that needs to be converted to IRQ number + * + * @return vector_id Return value is never checked. + * + */ +int platform_interrupt_disable(unsigned int vector_id) +{ + RL_ASSERT(0 <= disable_counter); + + platform_global_isr_disable(); + /* virtqueues use the same NVIC vector + if counter is set - the interrupts are disabled */ + if ((!disable_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 0); + } + + disable_counter++; + platform_global_isr_enable(); + return (vector_id); +} + +/** + * platform_map_mem_region + * + * Dummy implementation + * + */ +void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsigned int size, unsigned int flags) +{ +} + +/** + * platform_cache_all_flush_invalidate + * + * Dummy implementation + * + */ +void platform_cache_all_flush_invalidate(void) +{ +} + +/** + * platform_cache_disable + * + * Dummy implementation + * + */ +void platform_cache_disable(void) +{ +} + +/** + * platform_vatopa + * + * Dummy implementation + * + */ +unsigned long platform_vatopa(void *addr) +{ + return ((unsigned long)addr); +} + +/** + * platform_patova + * + * Dummy implementation + * + */ +void *platform_patova(unsigned long addr) +{ + return ((void *)addr); +} + +/** + * platform_init + * + * platform/environment init + */ +int platform_init(void) +{ + /* Get IPM device handle */ + ipm_handle = device_get_binding(DT_NXP_IMX_MU_MU_B_LABEL); + if(!ipm_handle) + { + return -1; + } + + /* Register application callback with no context */ + ipm_register_callback(ipm_handle, platform_ipm_callback, NULL); + + /* Create lock used in multi-instanced RPMsg */ + if(0 != env_create_mutex(&platform_lock, 1)) + { + return -1; + } + + return 0; +} + +/** + * platform_deinit + * + * platform/environment deinit process + */ +int platform_deinit(void) +{ + /* Delete lock used in multi-instanced RPMsg */ + env_delete_mutex(platform_lock); + platform_lock = NULL; + return 0; +} + diff --git a/lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform.c b/lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform.c index 15d1335..69f87e5 100644 --- a/lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform.c +++ b/lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform.c @@ -1,37 +1,11 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#include #include #include #include "rpmsg_platform.h" @@ -40,56 +14,76 @@ #include "board.h" #include "mu_imx.h" -#define APP_MU_IRQ_PRIORITY (3) +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + +#define APP_MU_IRQ_PRIORITY (3U) static int isr_counter = 0; static int disable_counter = 0; -static void *lock; +static void *platform_lock; + -int platform_init_interrupt(int vq_id, void *isr_data) +void platform_global_isr_disable(void) +{ + __asm volatile("cpsid i"); +} + + +void platform_global_isr_enable(void) +{ + __asm volatile("cpsie i"); +} + +int platform_init_interrupt(unsigned int vector_id, void *isr_data) { /* Register ISR to environment layer */ - env_register_isr(vq_id, isr_data); + env_register_isr(vector_id, isr_data); /* Prepare the MU Hardware, enable channel 1 interrupt */ - env_lock_mutex(lock); + env_lock_mutex(platform_lock); - assert(0 <= isr_counter); + RL_ASSERT(0 <= isr_counter); if (!isr_counter) + { MU_EnableRxFullInt(MUB, RPMSG_MU_CHANNEL); + } isr_counter++; - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -int platform_deinit_interrupt(int vq_id) +int platform_deinit_interrupt(unsigned int vector_id) { - /* Prepare the MU Hardware, enable channel 1 interrupt */ - env_lock_mutex(lock); + /* Prepare the MU Hardware */ + env_lock_mutex(platform_lock); - assert(0 < isr_counter); + RL_ASSERT(0 < isr_counter); isr_counter--; if (!isr_counter) + { MU_DisableRxFullInt(MUB, RPMSG_MU_CHANNEL); + } /* Unregister ISR from environment layer */ - env_unregister_isr(vq_id); + env_unregister_isr(vector_id); - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -void platform_notify(int vq_id) +void platform_notify(unsigned int vector_id) { /* As Linux suggests, use MU->Data Channle 1 as communication channel */ - uint32_t msg = (RL_GET_Q_ID(vq_id)) << 16; + uint32_t msg = (RL_GET_Q_ID(vector_id)) << 16; - env_lock_mutex(lock); + env_lock_mutex(platform_lock); MU_SendMsg(MUB, RPMSG_MU_CHANNEL, msg); - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); } /* @@ -104,6 +98,11 @@ void rpmsg_handler(void) channel = msg >> 16; env_isr(channel); } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif return; } @@ -149,26 +148,26 @@ int platform_in_isr(void) /** * platform_interrupt_enable * - * Enable peripheral-related interrupt with passed priority and type. + * Enable peripheral-related interrupt * - * @param vq_id Vector ID that need to be converted to IRQ number - * @param trigger_type IRQ active level - * @param trigger_type IRQ priority + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked.. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_enable(unsigned int vq_id) +int platform_interrupt_enable(unsigned int vector_id) { - assert(0 < disable_counter); + RL_ASSERT(0 < disable_counter); - __asm volatile("cpsid i"); + platform_global_isr_disable(); disable_counter--; if (!disable_counter) + { NVIC_EnableIRQ(MU_M4_IRQn); - __asm volatile("cpsie i"); - return (vq_id); + } + platform_global_isr_enable(); + return (vector_id); } /** @@ -176,24 +175,25 @@ int platform_interrupt_enable(unsigned int vq_id) * * Disable peripheral-related interrupt. * - * @param vq_id Vector ID that need to be converted to IRQ number + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_disable(unsigned int vq_id) +int platform_interrupt_disable(unsigned int vector_id) { - assert(0 <= disable_counter); + RL_ASSERT(0 <= disable_counter); - __asm volatile("cpsid i"); - // virtqueues use the same NVIC vector - // if counter is set - the interrupts are disabled + platform_global_isr_disable(); + /* virtqueues use the same NVIC vector + if counter is set - the interrupts are disabled */ if (!disable_counter) + { NVIC_DisableIRQ(MU_M4_IRQn); - + } disable_counter++; - __asm volatile("cpsie i"); - return (vq_id); + platform_global_isr_enable(); + return (vector_id); } /** @@ -212,7 +212,7 @@ void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsig * Dummy implementation * */ -void platform_cache_all_flush_invalidate() +void platform_cache_all_flush_invalidate(void) { } @@ -222,7 +222,7 @@ void platform_cache_all_flush_invalidate() * Dummy implementation * */ -void platform_cache_disable() +void platform_cache_disable(void) { } @@ -264,7 +264,10 @@ int platform_init(void) NVIC_EnableIRQ(BOARD_MU_IRQ_NUM); /* Create lock used in multi-instanced RPMsg */ - env_create_mutex(&lock, 1); + if(0 != env_create_mutex(&platform_lock, 1)) + { + return -1; + } return 0; } @@ -277,7 +280,7 @@ int platform_init(void) int platform_deinit(void) { /* Delete lock used in multi-instanced RPMsg */ - env_delete_mutex(lock); - lock = NULL; + env_delete_mutex(platform_lock); + platform_lock = NULL; return 0; } diff --git a/lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform_zephyr_ipm.c b/lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform_zephyr_ipm.c new file mode 100644 index 0000000..f9d63dc --- /dev/null +++ b/lib/rpmsg_lite/porting/platform/imx7d_m4/rpmsg_platform_zephyr_ipm.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include "rpmsg_platform.h" +#include "rpmsg_env.h" +#include + + +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + + +static int isr_counter = 0; +static int disable_counter = 0; +static void *platform_lock; +static struct device *ipm_handle = NULL; + +void platform_ipm_callback(void *context, u32_t id, volatile void *data) +{ + if (id != RPMSG_MU_CHANNEL) + { + return; + } + + /* Data to be transmitted from Master */ + if (*(uint32_t*)data == 0U) + { + env_isr(0); + } + + /* Data to be received from Master */ + if (*(uint32_t*)data == 0x10000U) + { + env_isr(1); + } +} + +void platform_global_isr_disable(void) +{ + __asm volatile("cpsid i"); +} + +void platform_global_isr_enable(void) +{ + __asm volatile("cpsie i"); +} + +int platform_init_interrupt(unsigned int vector_id, void *isr_data) +{ + /* Register ISR to environment layer */ + env_register_isr(vector_id, isr_data); + + env_lock_mutex(platform_lock); + + RL_ASSERT(0 <= isr_counter); + + isr_counter++; + + env_unlock_mutex(platform_lock); + + return 0; +} + +int platform_deinit_interrupt(unsigned int vector_id) +{ + /* Prepare the MU Hardware */ + env_lock_mutex(platform_lock); + + RL_ASSERT(0 < isr_counter); + isr_counter--; + if ((!isr_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 0); + } + + /* Unregister ISR from environment layer */ + env_unregister_isr(vector_id); + + env_unlock_mutex(platform_lock); + + return 0; +} + +void platform_notify(unsigned int vector_id) +{ + int status; + switch (RL_GET_LINK_ID(vector_id)) + { + case RL_PLATFORM_IMX7D_M4_LINK_ID: + env_lock_mutex(platform_lock); + uint32_t data = (RL_GET_Q_ID(vector_id) << 16); + RL_ASSERT(ipm_handle); + do { + status = ipm_send(ipm_handle, 0, RPMSG_MU_CHANNEL, &data, sizeof(uint32_t)); + } while (status == EBUSY); + env_unlock_mutex(platform_lock); + return; + + default: + return; + } +} + +/** + * platform_in_isr + * + * Return whether CPU is processing IRQ + * + * @return True for IRQ, false otherwise. + * + */ +int platform_in_isr(void) +{ + return (0 != k_is_in_isr()); +} + +/** + * platform_interrupt_enable + * + * Enable peripheral-related interrupt + * + * @param vector_id Virtual vector ID that needs to be converted to IRQ number + * + * @return vector_id Return value is never checked. + * + */ +int platform_interrupt_enable(unsigned int vector_id) +{ + RL_ASSERT(0 < disable_counter); + + platform_global_isr_disable(); + disable_counter--; + + if ((!disable_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 1); + } + platform_global_isr_enable(); + return (vector_id); +} + +/** + * platform_interrupt_disable + * + * Disable peripheral-related interrupt. + * + * @param vector_id Virtual vector ID that needs to be converted to IRQ number + * + * @return vector_id Return value is never checked. + * + */ +int platform_interrupt_disable(unsigned int vector_id) +{ + RL_ASSERT(0 <= disable_counter); + + platform_global_isr_disable(); + /* virtqueues use the same NVIC vector + if counter is set - the interrupts are disabled */ + if ((!disable_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 0); + } + + disable_counter++; + platform_global_isr_enable(); + return (vector_id); +} + +/** + * platform_map_mem_region + * + * Dummy implementation + * + */ +void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsigned int size, unsigned int flags) +{ +} + +/** + * platform_cache_all_flush_invalidate + * + * Dummy implementation + * + */ +void platform_cache_all_flush_invalidate(void) +{ +} + +/** + * platform_cache_disable + * + * Dummy implementation + * + */ +void platform_cache_disable(void) +{ +} + +/** + * platform_vatopa + * + * Dummy implementation + * + */ +unsigned long platform_vatopa(void *addr) +{ + return ((unsigned long)addr); +} + +/** + * platform_patova + * + * Dummy implementation + * + */ +void *platform_patova(unsigned long addr) +{ + return ((void *)addr); +} + +/** + * platform_init + * + * platform/environment init + */ +int platform_init(void) +{ + /* Get IPM device handle */ + ipm_handle = device_get_binding(DT_NXP_IMX_MU_MU_B_LABEL); + if(!ipm_handle) + { + return -1; + } + + /* Register application callback with no context */ + ipm_register_callback(ipm_handle, platform_ipm_callback, NULL); + + /* Create lock used in multi-instanced RPMsg */ + if(0 != env_create_mutex(&platform_lock, 1)) + { + return -1; + } + + return 0; +} + +/** + * platform_deinit + * + * platform/environment deinit process + */ +int platform_deinit(void) +{ + /* Delete lock used in multi-instanced RPMsg */ + env_delete_mutex(platform_lock); + platform_lock = NULL; + return 0; +} + diff --git a/lib/rpmsg_lite/porting/platform/lpc5410x/rpmsg_platform.c b/lib/rpmsg_lite/porting/platform/lpc5410x/rpmsg_platform.c index 2962b6b..bcfef17 100644 --- a/lib/rpmsg_lite/porting/platform/lpc5410x/rpmsg_platform.c +++ b/lib/rpmsg_lite/porting/platform/lpc5410x/rpmsg_platform.c @@ -1,37 +1,11 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#include #include #include @@ -45,9 +19,13 @@ #include "mcmgr.h" #endif +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + static int isr_counter = 0; static int disable_counter = 0; -static void *lock; +static void *platform_lock; #if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1) static void mcmgr_event_handler(uint16_t vring_idx, void *context) @@ -58,7 +36,7 @@ static void mcmgr_event_handler(uint16_t vring_idx, void *context) void MAILBOX_IRQHandler(void) { mailbox_cpu_id_t cpu_id; -#if defined(__CM4_CMSIS_VERSION) +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) cpu_id = kMAILBOX_CM4; #else cpu_id = kMAILBOX_CM0Plus; @@ -76,77 +54,92 @@ void MAILBOX_IRQHandler(void) MAILBOX_ClearValueBits(MAILBOX, cpu_id, 0x02); env_isr(1); } -} + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt */ #if defined __CORTEX_M && (__CORTEX_M == 4U) __DSB(); #endif +} #endif -int platform_init_interrupt(int vq_id, void *isr_data) +void platform_global_isr_disable(void) +{ + __asm volatile("cpsid i"); +} + + +void platform_global_isr_enable(void) +{ + __asm volatile("cpsie i"); +} + +int platform_init_interrupt(unsigned int vector_id, void *isr_data) { /* Register ISR to environment layer */ - env_register_isr(vq_id, isr_data); + env_register_isr(vector_id, isr_data); - env_lock_mutex(lock); + env_lock_mutex(platform_lock); - assert(0 <= isr_counter); + RL_ASSERT(0 <= isr_counter); if (!isr_counter) - -#if defined(__CM4_CMSIS_VERSION) + { +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) NVIC_SetPriority(MAILBOX_IRQn, 5); #else NVIC_SetPriority(MAILBOX_IRQn, 2); #endif + } isr_counter++; - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -int platform_deinit_interrupt(int vq_id) +int platform_deinit_interrupt(unsigned int vector_id) { /* Prepare the MU Hardware */ - env_lock_mutex(lock); + env_lock_mutex(platform_lock); - assert(0 < isr_counter); + RL_ASSERT(0 < isr_counter); isr_counter--; if (!isr_counter) + { NVIC_DisableIRQ(MAILBOX_IRQn); + } /* Unregister ISR from environment layer */ - env_unregister_isr(vq_id); + env_unregister_isr(vector_id); - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -void platform_notify(int vq_id) +void platform_notify(unsigned int vector_id) { #if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1) - env_lock_mutex(lock); - MCMGR_TriggerEventForce(kMCMGR_RemoteRPMsgEvent, RL_GET_Q_ID(vq_id)); - env_unlock_mutex(lock); + env_lock_mutex(platform_lock); + MCMGR_TriggerEventForce(kMCMGR_RemoteRPMsgEvent, RL_GET_Q_ID(vector_id)); + env_unlock_mutex(platform_lock); #else /* Only single RPMsg-Lite instance (LINK_ID) is defined for this dual core device. Extend this statement in case multiple instances of RPMsg-Lite are needed. */ - switch (RL_GET_LINK_ID(vq_id)) + switch (RL_GET_LINK_ID(vector_id)) { case RL_PLATFORM_LPC5410x_M4_M0_LINK_ID: - env_lock_mutex(lock); + env_lock_mutex(platform_lock); /* Write directly into the Mailbox register, no need to wait until the content is cleared (consumed by the receiver side) because the same walue of the virtqueu ID is written into this register when trigerring the ISR for the receiver side. The whole queue of received buffers for associated virtqueue is handled in the ISR then. */ -#if defined(__CM4_CMSIS_VERSION) - MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM0Plus, (1 << RL_GET_Q_ID(vq_id))); +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) + MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM0Plus, (1 << RL_GET_Q_ID(vector_id))); #else - MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM4, (1 << RL_GET_Q_ID(vq_id))); + MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM4, (1 << RL_GET_Q_ID(vector_id))); #endif - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return; default: @@ -196,26 +189,26 @@ int platform_in_isr(void) /** * platform_interrupt_enable * - * Enable peripheral-related interrupt with passed priority and type. + * Enable peripheral-related interrupt * - * @param vq_id Vector ID that need to be converted to IRQ number - * @param trigger_type IRQ active level - * @param trigger_type IRQ priority + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked.. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_enable(unsigned int vq_id) +int platform_interrupt_enable(unsigned int vector_id) { - assert(0 < disable_counter); + RL_ASSERT(0 < disable_counter); - __asm volatile("cpsid i"); + platform_global_isr_disable(); disable_counter--; if (!disable_counter) + { NVIC_EnableIRQ(MAILBOX_IRQn); - __asm volatile("cpsie i"); - return (vq_id); + } + platform_global_isr_enable(); + return (vector_id); } /** @@ -223,24 +216,25 @@ int platform_interrupt_enable(unsigned int vq_id) * * Disable peripheral-related interrupt. * - * @param vq_id Vector ID that need to be converted to IRQ number + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_disable(unsigned int vq_id) +int platform_interrupt_disable(unsigned int vector_id) { - assert(0 <= disable_counter); + RL_ASSERT(0 <= disable_counter); - __asm volatile("cpsid i"); - // virtqueues use the same NVIC vector - // if counter is set - the interrupts are disabled + platform_global_isr_disable(); + /* virtqueues use the same NVIC vector + if counter is set - the interrupts are disabled */ if (!disable_counter) + { NVIC_DisableIRQ(MAILBOX_IRQn); - + } disable_counter++; - __asm volatile("cpsie i"); - return (vq_id); + platform_global_isr_enable(); + return (vector_id); } /** @@ -259,7 +253,7 @@ void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsig * Dummy implementation * */ -void platform_cache_all_flush_invalidate() +void platform_cache_all_flush_invalidate(void) { } @@ -269,7 +263,7 @@ void platform_cache_all_flush_invalidate() * Dummy implementation * */ -void platform_cache_disable() +void platform_cache_disable(void) { } @@ -303,13 +297,21 @@ void *platform_patova(unsigned long addr) int platform_init(void) { #if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1) - MCMGR_RegisterEvent(kMCMGR_RemoteRPMsgEvent, mcmgr_event_handler, NULL); + mcmgr_status_t retval; + retval = MCMGR_RegisterEvent(kMCMGR_RemoteRPMsgEvent, mcmgr_event_handler, NULL); + if(kStatus_MCMGR_Success != retval) + { + return -1; + } #else MAILBOX_Init(MAILBOX); #endif /* Create lock used in multi-instanced RPMsg */ - env_create_mutex(&lock, 1); + if(0 != env_create_mutex(&platform_lock, 1)) + { + return -1; + } return 0; } @@ -323,18 +325,20 @@ int platform_deinit(void) { /* Important for LPC54102 - do not deinit mailbox, if there is a pending ISR on the other core! */ -#if defined(__CM4_CMSIS_VERSION) +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) while (0 != MAILBOX_GetValue(MAILBOX, kMAILBOX_CM0Plus)) - ; + { + } #else while (0 != MAILBOX_GetValue(MAILBOX, kMAILBOX_CM4)) - ; + { + } #endif MAILBOX_Deinit(MAILBOX); /* Delete lock used in multi-instanced RPMsg */ - env_delete_mutex(lock); - lock = NULL; + env_delete_mutex(platform_lock); + platform_lock = NULL; return 0; } diff --git a/lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform.c b/lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform.c index c0c3b8c..beb02f4 100644 --- a/lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform.c +++ b/lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform.c @@ -1,37 +1,11 @@ /* - * The Clear BSD License * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted (subject to the limitations in the disclaimer below) provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ -#include #include #include @@ -45,9 +19,13 @@ #include "mcmgr.h" #endif +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + static int isr_counter = 0; static int disable_counter = 0; -static void *lock; +static void *platform_lock; #if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1) static void mcmgr_event_handler(uint16_t vring_idx, void *context) @@ -58,7 +36,7 @@ static void mcmgr_event_handler(uint16_t vring_idx, void *context) void MAILBOX_IRQHandler(void) { mailbox_cpu_id_t cpu_id; -#if defined(__CM4_CMSIS_VERSION) +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) cpu_id = kMAILBOX_CM4; #else cpu_id = kMAILBOX_CM0Plus; @@ -76,77 +54,92 @@ void MAILBOX_IRQHandler(void) MAILBOX_ClearValueBits(MAILBOX, cpu_id, 0x02); env_isr(1); } -} + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt */ #if defined __CORTEX_M && (__CORTEX_M == 4U) __DSB(); #endif +} #endif -int platform_init_interrupt(int vq_id, void *isr_data) +void platform_global_isr_disable(void) +{ + __asm volatile("cpsid i"); +} + + +void platform_global_isr_enable(void) +{ + __asm volatile("cpsie i"); +} + +int platform_init_interrupt(unsigned int vector_id, void *isr_data) { /* Register ISR to environment layer */ - env_register_isr(vq_id, isr_data); + env_register_isr(vector_id, isr_data); - env_lock_mutex(lock); + env_lock_mutex(platform_lock); - assert(0 <= isr_counter); + RL_ASSERT(0 <= isr_counter); if (!isr_counter) - -#if defined(__CM4_CMSIS_VERSION) + { +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) NVIC_SetPriority(MAILBOX_IRQn, 5); #else NVIC_SetPriority(MAILBOX_IRQn, 2); #endif + } isr_counter++; - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -int platform_deinit_interrupt(int vq_id) +int platform_deinit_interrupt(unsigned int vector_id) { /* Prepare the MU Hardware */ - env_lock_mutex(lock); + env_lock_mutex(platform_lock); - assert(0 < isr_counter); + RL_ASSERT(0 < isr_counter); isr_counter--; if (!isr_counter) + { NVIC_DisableIRQ(MAILBOX_IRQn); + } /* Unregister ISR from environment layer */ - env_unregister_isr(vq_id); + env_unregister_isr(vector_id); - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return 0; } -void platform_notify(int vq_id) +void platform_notify(unsigned int vector_id) { #if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1) - env_lock_mutex(lock); - MCMGR_TriggerEventForce(kMCMGR_RemoteRPMsgEvent, RL_GET_Q_ID(vq_id)); - env_unlock_mutex(lock); + env_lock_mutex(platform_lock); + MCMGR_TriggerEventForce(kMCMGR_RemoteRPMsgEvent, RL_GET_Q_ID(vector_id)); + env_unlock_mutex(platform_lock); #else /* Only single RPMsg-Lite instance (LINK_ID) is defined for this dual core device. Extend this statement in case multiple instances of RPMsg-Lite are needed. */ - switch (RL_GET_LINK_ID(vq_id)) + switch (RL_GET_LINK_ID(vector_id)) { case RL_PLATFORM_LPC5411x_M4_M0_LINK_ID: - env_lock_mutex(lock); + env_lock_mutex(platform_lock); /* Write directly into the Mailbox register, no need to wait until the content is cleared (consumed by the receiver side) because the same walue of the virtqueu ID is written into this register when trigerring the ISR for the receiver side. The whole queue of received buffers for associated virtqueue is handled in the ISR then. */ -#if defined(__CM4_CMSIS_VERSION) - MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM0Plus, (1 << RL_GET_Q_ID(vq_id))); +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) + MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM0Plus, (1 << RL_GET_Q_ID(vector_id))); #else - MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM4, (1 << RL_GET_Q_ID(vq_id))); + MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM4, (1 << RL_GET_Q_ID(vector_id))); #endif - env_unlock_mutex(lock); + env_unlock_mutex(platform_lock); return; default: @@ -196,26 +189,26 @@ int platform_in_isr(void) /** * platform_interrupt_enable * - * Enable peripheral-related interrupt with passed priority and type. + * Enable peripheral-related interrupt * - * @param vq_id Vector ID that need to be converted to IRQ number - * @param trigger_type IRQ active level - * @param trigger_type IRQ priority + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked.. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_enable(unsigned int vq_id) +int platform_interrupt_enable(unsigned int vector_id) { - assert(0 < disable_counter); + RL_ASSERT(0 < disable_counter); - __asm volatile("cpsid i"); + platform_global_isr_disable(); disable_counter--; if (!disable_counter) + { NVIC_EnableIRQ(MAILBOX_IRQn); - __asm volatile("cpsie i"); - return (vq_id); + } + platform_global_isr_enable(); + return (vector_id); } /** @@ -223,24 +216,25 @@ int platform_interrupt_enable(unsigned int vq_id) * * Disable peripheral-related interrupt. * - * @param vq_id Vector ID that need to be converted to IRQ number + * @param vector_id Virtual vector ID that needs to be converted to IRQ number * - * @return vq_id. Return value is never checked. + * @return vector_id Return value is never checked. * */ -int platform_interrupt_disable(unsigned int vq_id) +int platform_interrupt_disable(unsigned int vector_id) { - assert(0 <= disable_counter); + RL_ASSERT(0 <= disable_counter); - __asm volatile("cpsid i"); - // virtqueues use the same NVIC vector - // if counter is set - the interrupts are disabled + platform_global_isr_disable(); + /* virtqueues use the same NVIC vector + if counter is set - the interrupts are disabled */ if (!disable_counter) + { NVIC_DisableIRQ(MAILBOX_IRQn); - + } disable_counter++; - __asm volatile("cpsie i"); - return (vq_id); + platform_global_isr_enable(); + return (vector_id); } /** @@ -259,7 +253,7 @@ void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsig * Dummy implementation * */ -void platform_cache_all_flush_invalidate() +void platform_cache_all_flush_invalidate(void) { } @@ -269,7 +263,7 @@ void platform_cache_all_flush_invalidate() * Dummy implementation * */ -void platform_cache_disable() +void platform_cache_disable(void) { } @@ -303,13 +297,21 @@ void *platform_patova(unsigned long addr) int platform_init(void) { #if defined(RL_USE_MCMGR_IPC_ISR_HANDLER) && (RL_USE_MCMGR_IPC_ISR_HANDLER == 1) - MCMGR_RegisterEvent(kMCMGR_RemoteRPMsgEvent, mcmgr_event_handler, NULL); + mcmgr_status_t retval; + retval = MCMGR_RegisterEvent(kMCMGR_RemoteRPMsgEvent, mcmgr_event_handler, NULL); + if(kStatus_MCMGR_Success != retval) + { + return -1; + } #else MAILBOX_Init(MAILBOX); #endif /* Create lock used in multi-instanced RPMsg */ - env_create_mutex(&lock, 1); + if(0 != env_create_mutex(&platform_lock, 1)) + { + return -1; + } return 0; } @@ -323,18 +325,20 @@ int platform_deinit(void) { /* Important for LPC5411x - do not deinit mailbox, if there is a pending ISR on the other core! */ -#if defined(__CM4_CMSIS_VERSION) +#if defined(FSL_FEATURE_MAILBOX_SIDE_A) while (0 != MAILBOX_GetValue(MAILBOX, kMAILBOX_CM0Plus)) - ; + { + } #else while (0 != MAILBOX_GetValue(MAILBOX, kMAILBOX_CM4)) - ; + { + } #endif MAILBOX_Deinit(MAILBOX); /* Delete lock used in multi-instanced RPMsg */ - env_delete_mutex(lock); - lock = NULL; + env_delete_mutex(platform_lock); + platform_lock = NULL; return 0; } diff --git a/lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform_zephyr_ipm.c b/lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform_zephyr_ipm.c new file mode 100644 index 0000000..e5f73e2 --- /dev/null +++ b/lib/rpmsg_lite/porting/platform/lpc5411x/rpmsg_platform_zephyr_ipm.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include "rpmsg_platform.h" +#include "rpmsg_env.h" +#include + +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +#error "This RPMsg-Lite port requires RL_USE_ENVIRONMENT_CONTEXT set to 0" +#endif + +static int isr_counter = 0; +static int disable_counter = 0; +static void *platform_lock; +static struct device *ipm_handle = NULL; + +void platform_ipm_callback(void *context, u32_t id, volatile void *data) +{ + if ((*(uint32_t*)data) & 0x01) + { + env_isr(0); + } + if ((*(uint32_t*)data) & 0x02) + { + env_isr(1); + } +} + +void platform_global_isr_disable(void) +{ + __asm volatile("cpsid i"); +} + + +void platform_global_isr_enable(void) +{ + __asm volatile("cpsie i"); +} + +int platform_init_interrupt(unsigned int vector_id, void *isr_data) +{ + /* Register ISR to environment layer */ + env_register_isr(vector_id, isr_data); + + env_lock_mutex(platform_lock); + + RL_ASSERT(0 <= isr_counter); + + isr_counter++; + + env_unlock_mutex(platform_lock); + + return 0; +} + +int platform_deinit_interrupt(unsigned int vector_id) +{ + /* Prepare the MU Hardware */ + env_lock_mutex(platform_lock); + + RL_ASSERT(0 < isr_counter); + isr_counter--; + if ((!isr_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 0); + } + + /* Unregister ISR from environment layer */ + env_unregister_isr(vector_id); + + env_unlock_mutex(platform_lock); + + return 0; +} + +void platform_notify(unsigned int vector_id) +{ + switch (RL_GET_LINK_ID(vector_id)) + { + case RL_PLATFORM_LPC5411x_M4_M0_LINK_ID: + env_lock_mutex(platform_lock); + uint32_t data = (1 << RL_GET_Q_ID(vector_id)); + RL_ASSERT(ipm_handle); + ipm_send(ipm_handle, 0, 0, &data, sizeof(uint32_t)); + env_unlock_mutex(platform_lock); + return; + + default: + return; + } +} + +/** + * platform_in_isr + * + * Return whether CPU is processing IRQ + * + * @return True for IRQ, false otherwise. + * + */ +int platform_in_isr(void) +{ + return (0 != k_is_in_isr()); +} + +/** + * platform_interrupt_enable + * + * Enable peripheral-related interrupt + * + * @param vector_id Virtual vector ID that needs to be converted to IRQ number + * + * @return vector_id Return value is never checked. + * + */ +int platform_interrupt_enable(unsigned int vector_id) +{ + RL_ASSERT(0 < disable_counter); + + platform_global_isr_disable(); + disable_counter--; + + if ((!disable_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 1); + } + platform_global_isr_enable(); + return (vector_id); +} + +/** + * platform_interrupt_disable + * + * Disable peripheral-related interrupt. + * + * @param vector_id Virtual vector ID that needs to be converted to IRQ number + * + * @return vector_id Return value is never checked. + * + */ +int platform_interrupt_disable(unsigned int vector_id) +{ + RL_ASSERT(0 <= disable_counter); + + platform_global_isr_disable(); + /* virtqueues use the same NVIC vector + if counter is set - the interrupts are disabled */ + if ((!disable_counter) && (ipm_handle != NULL)) + { + ipm_set_enabled(ipm_handle, 0); + } + + disable_counter++; + platform_global_isr_enable(); + return (vector_id); +} + +/** + * platform_map_mem_region + * + * Dummy implementation + * + */ +void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr, unsigned int size, unsigned int flags) +{ +} + +/** + * platform_cache_all_flush_invalidate + * + * Dummy implementation + * + */ +void platform_cache_all_flush_invalidate(void) +{ +} + +/** + * platform_cache_disable + * + * Dummy implementation + * + */ +void platform_cache_disable(void) +{ +} + +/** + * platform_vatopa + * + * Dummy implementation + * + */ +unsigned long platform_vatopa(void *addr) +{ + return ((unsigned long)addr); +} + +/** + * platform_patova + * + * Dummy implementation + * + */ +void *platform_patova(unsigned long addr) +{ + return ((void *)addr); +} + +/** + * platform_init + * + * platform/environment init + */ +int platform_init(void) +{ + /* Get IPM device handle */ + ipm_handle = device_get_binding(DT_NXP_LPC_MAILBOX_0_LABEL); + if(!ipm_handle) + { + return -1; + } + + /* Register application callback with no context */ + ipm_register_callback(ipm_handle, platform_ipm_callback, NULL); + + /* Create lock used in multi-instanced RPMsg */ + if(0 != env_create_mutex(&platform_lock, 1)) + { + return -1; + } + + return 0; +} + +/** + * platform_deinit + * + * platform/environment deinit process + */ +int platform_deinit(void) +{ + /* Delete lock used in multi-instanced RPMsg */ + env_delete_mutex(platform_lock); + platform_lock = NULL; + return 0; +} + diff --git a/lib/rpmsg_lite/rpmsg_lite.c b/lib/rpmsg_lite/rpmsg_lite.c index 73714f6..f152e6e 100644 --- a/lib/rpmsg_lite/rpmsg_lite.c +++ b/lib/rpmsg_lite/rpmsg_lite.c @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,11 +40,11 @@ RL_PACKED_BEGIN */ struct rpmsg_std_hdr { - unsigned long src; /*!< source endpoint address */ - unsigned long dst; /*!< destination endpoint address */ - unsigned long reserved; /*!< reserved for future use */ - unsigned short len; /*!< length of payload (in bytes) */ - unsigned short flags; /*!< message flags */ + uint32_t src; /*!< source endpoint address */ + uint32_t dst; /*!< destination endpoint address */ + uint32_t reserved; /*!< reserved for future use */ + uint16_t len; /*!< length of payload (in bytes) */ + uint16_t flags; /*!< message flags */ } RL_PACKED_END; RL_PACKED_BEGIN @@ -55,7 +55,7 @@ RL_PACKED_BEGIN struct rpmsg_std_msg { struct rpmsg_std_hdr hdr; /*!< RPMsg message header */ - unsigned char data[1]; /*!< bytes of message payload data */ + uint8_t data[1]; /*!< bytes of message payload data */ } RL_PACKED_END; /* rpmsg_std_hdr contains a reserved field, @@ -67,8 +67,8 @@ struct rpmsg_std_msg */ struct rpmsg_hdr_reserved { - unsigned short rfu; /* reserved for future usage */ - unsigned short idx; + uint16_t rfu; /* reserved for future usage */ + uint16_t idx; }; /* Interface which is used to interact with the virtqueue layer, @@ -388,7 +388,12 @@ static const struct virtqueue_ops remote_vq_ops = { /* helper function for virtqueue notification */ static void virtqueue_notify(struct virtqueue *vq) { +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + struct rpmsg_lite_instance * inst = vq->priv; + platform_notify(inst->env ? env_get_platform_context(inst->env) : NULL, vq->vq_queue_index); +#else platform_notify(vq->vq_queue_index); +#endif } /************************************************* @@ -753,13 +758,13 @@ int rpmsg_lite_send_nocopy(struct rpmsg_lite_instance *rpmsg_lite_dev, RL_ASSERT( /* master check */ ((rpmsg_lite_dev->vq_ops == &master_vq_ops) && - (data >= (rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE))) && - (data <= (rpmsg_lite_dev->sh_mem_base + (2*RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) || + (data >= (void *)(rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE))) && + (data <= (void *)(rpmsg_lite_dev->sh_mem_base + (2*RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) || /* remote check */ ((rpmsg_lite_dev->vq_ops == &remote_vq_ops) && - (data >= rpmsg_lite_dev->sh_mem_base) && - (data <= (rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) + (data >= (void *)rpmsg_lite_dev->sh_mem_base) && + (data <= (void *)(rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) ) #endif @@ -813,13 +818,13 @@ int rpmsg_lite_release_rx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, voi RL_ASSERT( /* master check */ ((rpmsg_lite_dev->vq_ops == &master_vq_ops) && - (rxbuf >= rpmsg_lite_dev->sh_mem_base) && - (rxbuf <= (rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) || + (rxbuf >= (void *)rpmsg_lite_dev->sh_mem_base) && + (rxbuf <= (void *)(rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) || /* remote check */ ((rpmsg_lite_dev->vq_ops == &remote_vq_ops) && - (rxbuf >= (rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE))) && - (rxbuf <= (rpmsg_lite_dev->sh_mem_base + (2*RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) + (rxbuf >= (void *)(rpmsg_lite_dev->sh_mem_base + (RL_BUFFER_COUNT*RL_BUFFER_SIZE))) && + (rxbuf <= (void *)(rpmsg_lite_dev->sh_mem_base + (2*RL_BUFFER_COUNT*RL_BUFFER_SIZE)))) ) #endif @@ -854,6 +859,12 @@ int rpmsg_lite_release_rx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, voi #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1) struct rpmsg_lite_instance *rpmsg_lite_master_init( void *shmem_addr, size_t shmem_length, int link_id, uint32_t init_flags, struct rpmsg_lite_instance *static_context) +#elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, + size_t shmem_length, + int link_id, + uint32_t init_flags, + void *env_cfg) #else struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, size_t shmem_length, @@ -900,8 +911,11 @@ struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, #endif env_memset(rpmsg_lite_dev, 0, sizeof(struct rpmsg_lite_instance)); - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + status = env_init(&rpmsg_lite_dev->env, env_cfg); +#else status = env_init(); +#endif if (status != RL_SUCCESS) { #if !(defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)) @@ -963,6 +977,9 @@ struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, /* virtqueue has reference to the RPMsg Lite instance */ vqs[idx]->priv = (void *)rpmsg_lite_dev; +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + vqs[idx]->env = rpmsg_lite_dev->env; +#endif } status = env_create_mutex((LOCK *)&rpmsg_lite_dev->lock, 1); @@ -1017,6 +1034,15 @@ struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, } /* Install ISRs */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + env_init_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index, rpmsg_lite_dev->rvq); + env_init_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index, rpmsg_lite_dev->tvq); + env_disable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index); + env_disable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index); + rpmsg_lite_dev->link_state = 1; + env_enable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index); + env_enable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index); +#else platform_init_interrupt(rpmsg_lite_dev->rvq->vq_queue_index, rpmsg_lite_dev->rvq); platform_init_interrupt(rpmsg_lite_dev->tvq->vq_queue_index, rpmsg_lite_dev->tvq); env_disable_interrupt(rpmsg_lite_dev->rvq->vq_queue_index); @@ -1024,6 +1050,7 @@ struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr, rpmsg_lite_dev->link_state = 1; env_enable_interrupt(rpmsg_lite_dev->rvq->vq_queue_index); env_enable_interrupt(rpmsg_lite_dev->tvq->vq_queue_index); +#endif /* * Let the remote device know that Master is ready for @@ -1039,6 +1066,8 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id, uint32_t init_flags, struct rpmsg_lite_instance *static_context) +#elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) +struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id, uint32_t init_flags, void *env_cfg) #else struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id, uint32_t init_flags) #endif @@ -1076,8 +1105,12 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id #endif env_memset(rpmsg_lite_dev, 0, sizeof(struct rpmsg_lite_instance)); - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + status = env_init(&rpmsg_lite_dev->env, env_cfg); +#else status = env_init(); +#endif + if (status != RL_SUCCESS) { #if !(defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)) @@ -1091,6 +1124,7 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id callback[0] = rpmsg_lite_tx_callback; callback[1] = rpmsg_lite_rx_callback; rpmsg_lite_dev->vq_ops = &remote_vq_ops; + rpmsg_lite_dev->sh_mem_base = (char *)RL_WORD_ALIGN_UP(shmem_addr + RL_VRING_OVERHEAD); /* Create virtqueue for each vring. */ for (idx = 0; idx < 2; idx++) @@ -1118,6 +1152,9 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id /* virtqueue has reference to the RPMsg Lite instance */ vqs[idx]->priv = (void *)rpmsg_lite_dev; +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + vqs[idx]->env = rpmsg_lite_dev->env; +#endif } status = env_create_mutex((LOCK *)&rpmsg_lite_dev->lock, 1); @@ -1134,6 +1171,15 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id rpmsg_lite_dev->rvq = vqs[1]; /* Install ISRs */ +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + env_init_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index, rpmsg_lite_dev->rvq); + env_init_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index, rpmsg_lite_dev->tvq); + env_disable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index); + env_disable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index); + rpmsg_lite_dev->link_state = 0; + env_enable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index); + env_enable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index); +#else platform_init_interrupt(rpmsg_lite_dev->rvq->vq_queue_index, rpmsg_lite_dev->rvq); platform_init_interrupt(rpmsg_lite_dev->tvq->vq_queue_index, rpmsg_lite_dev->tvq); env_disable_interrupt(rpmsg_lite_dev->rvq->vq_queue_index); @@ -1141,6 +1187,7 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id rpmsg_lite_dev->link_state = 0; env_enable_interrupt(rpmsg_lite_dev->rvq->vq_queue_index); env_enable_interrupt(rpmsg_lite_dev->tvq->vq_queue_index); +#endif return rpmsg_lite_dev; } @@ -1157,18 +1204,27 @@ struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, int link_id int rpmsg_lite_deinit(struct rpmsg_lite_instance *rpmsg_lite_dev) { - if (!rpmsg_lite_dev) + if (rpmsg_lite_dev == NULL) { return RL_ERR_PARAM; } - if (!(rpmsg_lite_dev->rvq && rpmsg_lite_dev->tvq && rpmsg_lite_dev->lock)) + if (!((rpmsg_lite_dev->rvq != NULL) && (rpmsg_lite_dev->tvq != NULL) && (rpmsg_lite_dev->lock != NULL))) { /* ERROR - trying to initialize uninitialized RPMSG? */ - RL_ASSERT((rpmsg_lite_dev->rvq && rpmsg_lite_dev->tvq && rpmsg_lite_dev->lock)); + RL_ASSERT((rpmsg_lite_dev->rvq != NULL) && (rpmsg_lite_dev->tvq != NULL) && (rpmsg_lite_dev->lock != NULL)); return RL_ERR_PARAM; } +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + env_disable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index); + env_disable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index); + rpmsg_lite_dev->link_state = 0; + env_enable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index); + env_enable_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index); + env_deinit_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->rvq->vq_queue_index); + env_deinit_interrupt(rpmsg_lite_dev->env, rpmsg_lite_dev->tvq->vq_queue_index); +#else env_disable_interrupt(rpmsg_lite_dev->rvq->vq_queue_index); env_disable_interrupt(rpmsg_lite_dev->tvq->vq_queue_index); rpmsg_lite_dev->link_state = 0; @@ -1177,6 +1233,7 @@ int rpmsg_lite_deinit(struct rpmsg_lite_instance *rpmsg_lite_dev) platform_deinit_interrupt(rpmsg_lite_dev->rvq->vq_queue_index); platform_deinit_interrupt(rpmsg_lite_dev->tvq->vq_queue_index); +#endif #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1) virtqueue_free_static(rpmsg_lite_dev->rvq); @@ -1187,12 +1244,15 @@ int rpmsg_lite_deinit(struct rpmsg_lite_instance *rpmsg_lite_dev) #endif /* RL_USE_STATIC_API */ env_delete_mutex(rpmsg_lite_dev->lock); +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + env_deinit(rpmsg_lite_dev->env); +#else + env_deinit(); +#endif #if !(defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)) env_free_memory(rpmsg_lite_dev); #endif /* RL_USE_STATIC_API */ - env_deinit(); - return RL_SUCCESS; } diff --git a/lib/rpmsg_lite/rpmsg_ns.c b/lib/rpmsg_lite/rpmsg_ns.c index 5a749ad..0cf0b16 100644 --- a/lib/rpmsg_lite/rpmsg_ns.c +++ b/lib/rpmsg_lite/rpmsg_ns.c @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,9 +32,10 @@ #include "rpmsg_lite.h" #include "rpmsg_ns.h" +#include /* from rpmsg_lite.c { */ -extern volatile struct rpmsg_lite_instance rpmsg_lite_dev; + int rpmsg_lite_format_message(struct rpmsg_lite_instance *rpmsg_lite_dev, unsigned long src, unsigned long dst, @@ -62,8 +63,8 @@ RL_PACKED_BEGIN struct rpmsg_ns_msg { char name[RL_NS_NAME_SIZE]; - unsigned long addr; - unsigned long flags; + uint32_t addr; + uint32_t flags; } RL_PACKED_END; /*! @@ -180,12 +181,12 @@ int rpmsg_ns_announce(struct rpmsg_lite_instance *rpmsg_lite_dev, { struct rpmsg_ns_msg ns_msg; - if (!ept_name) + if (ept_name == NULL) { return RL_ERR_PARAM; } - if (!new_ept) + if (new_ept == NULL) { return RL_ERR_PARAM; } diff --git a/lib/rpmsg_lite/rpmsg_queue.c b/lib/rpmsg_lite/rpmsg_queue.c index 19cc5a9..7452abb 100644 --- a/lib/rpmsg_lite/rpmsg_queue.c +++ b/lib/rpmsg_lite/rpmsg_queue.c @@ -2,7 +2,7 @@ * Copyright (c) 2014, Mentor Graphics Corporation * Copyright (c) 2015 Xilinx, Inc. * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,7 +39,6 @@ typedef struct short int len; } rpmsg_queue_rx_cb_data_t; -extern volatile struct rpmsg_lite_instance rpmsg_lite_dev; int rpmsg_queue_rx_cb(void *payload, int payload_len, unsigned long src, void *priv) { diff --git a/lib/virtio/virtqueue.c b/lib/virtio/virtqueue.c index 0564bfb..6e3c2f6 100644 --- a/lib/virtio/virtqueue.c +++ b/lib/virtio/virtqueue.c @@ -1,7 +1,10 @@ /*- * Copyright (c) 2011, Bryan Venteicher + * Copyright (c) 2016 Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP * All rights reserved. * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -212,7 +215,11 @@ int virtqueue_fill_avail_buffers(struct virtqueue *vq, void *buffer, uint32_t le head_idx = vq->vq_desc_head_idx; dp = &vq->vq_ring.desc[head_idx]; +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + dp->addr = env_map_vatopa(vq->env, buffer); +#else dp->addr = env_map_vatopa(buffer); +#endif dp->len = len; dp->flags = VRING_DESC_F_WRITE; @@ -245,7 +252,7 @@ void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len, uint16_t *idx) VQUEUE_BUSY(vq, used_read); - used_idx = vq->vq_used_cons_idx & (vq->vq_nentries - 1); + used_idx = (uint16_t)(vq->vq_used_cons_idx & ((uint16_t)(vq->vq_nentries - 1U))); uep = &vq->vq_ring.used->ring[used_idx]; env_rmb(); @@ -261,7 +268,11 @@ void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len, uint16_t *idx) VQUEUE_IDLE(vq, used_read); +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + return env_map_patova(vq->env, vq->vq_ring.desc[desc_idx].addr); +#else return env_map_patova(vq->vq_ring.desc[desc_idx].addr); +#endif } /*! @@ -337,12 +348,15 @@ void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, VQUEUE_BUSY(vq, avail_read); - head_idx = vq->vq_available_idx++ & (vq->vq_nentries - 1); + head_idx = (uint16_t)(vq->vq_available_idx++ & ((uint16_t)(vq->vq_nentries - 1U))); *avail_idx = vq->vq_ring.avail->ring[head_idx]; env_rmb(); - +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + buffer = env_map_patova(vq->env, vq->vq_ring.desc[*avail_idx].addr); +#else buffer = env_map_patova(vq->vq_ring.desc[*avail_idx].addr); +#endif *len = vq->vq_ring.desc[*avail_idx].len; VQUEUE_IDLE(vq, avail_read); @@ -486,16 +500,16 @@ void virtqueue_dump(struct virtqueue *vq) */ uint32_t virtqueue_get_desc_size(struct virtqueue *vq) { - uint16_t head_idx = 0; - uint16_t avail_idx = 0; - uint32_t len = 0; + uint16_t head_idx; + uint16_t avail_idx; + uint32_t len; if (vq->vq_available_idx == vq->vq_ring.avail->idx) { return 0; } - head_idx = vq->vq_available_idx & (vq->vq_nentries - 1); + head_idx = (uint16_t)(vq->vq_available_idx & ((uint16_t)(vq->vq_nentries - 1U))); avail_idx = vq->vq_ring.avail->ring[head_idx]; len = vq->vq_ring.desc[avail_idx].len; @@ -524,7 +538,11 @@ static uint16_t vq_ring_add_buffer( VQASSERT(vq, head_idx != VQ_RING_DESC_CHAIN_END, "premature end of free desc chain"); dp = &desc[head_idx]; +#if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1) + dp->addr = env_map_vatopa(vq->env, buffer); +#else dp->addr = env_map_vatopa(buffer); +#endif dp->len = length; dp->flags = VRING_DESC_F_WRITE; @@ -565,7 +583,7 @@ static void vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx) * currently running on another CPU, we can keep it processing the new * descriptor. */ - avail_idx = vq->vq_ring.avail->idx & (vq->vq_nentries - 1); + avail_idx = (uint16_t)(vq->vq_ring.avail->idx & ((uint16_t)(vq->vq_nentries - 1U))); vq->vq_ring.avail->ring[avail_idx] = desc_idx; env_wmb();