800*320工程文件+初始demo提交

This commit is contained in:
2024-03-07 16:46:43 +08:00
parent 33e6eb45b3
commit 70ec3005bb
3306 changed files with 3374364 additions and 2563 deletions

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright 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 Mentor Graphics Corporation 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
*
* llist.h
*
* COMPONENT
*
* OpenAMP stack.
*
* DESCRIPTION
*
* Header file for linked list service.
*
**************************************************************************/
#ifndef LLIST_H_
#define LLIST_H_
#include <stdint.h>
struct llist
{
void *data;
uint32_t attr;
struct llist *next;
struct llist *prev;
};
void add_to_list(struct llist **head, struct llist *node);
void remove_from_list(struct llist **head, struct llist *node);
#endif /* LLIST_H_ */

View File

@ -0,0 +1,59 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RPMSG_PLATFORM_H_
#define RPMSG_PLATFORM_H_
#include <stdint.h>
/*
* No need to align the VRING as defined in Linux because RT500 is not intended
* to run the Linux
*/
#ifndef VRING_ALIGN
#define VRING_ALIGN (0x10U)
#endif
/* contains pool of descriptos and two circular buffers */
#ifndef VRING_SIZE
#define VRING_SIZE (0x80UL)
#endif
/* size of shared memory + 2*VRING size */
#define RL_VRING_OVERHEAD (2UL * VRING_SIZE)
#define RL_GET_VQ_ID(link_id, queue_id) (((queue_id)&0x1U) | (((link_id) << 1U) & 0xFFFFFFFEU))
#define RL_GET_LINK_ID(id) (((id)&0xFFFFFFFEU) >> 1U)
#define RL_GET_Q_ID(id) ((id)&0x1U)
#define RL_PLATFORM_IMXRT500_LINK_ID (0U)
#define RL_PLATFORM_HIGHEST_LINK_ID (0U)
/* platform interrupt related functions */
int32_t platform_init_interrupt(uint32_t vector_id, void *isr_data);
int32_t platform_deinit_interrupt(uint32_t vector_id);
int32_t platform_interrupt_enable(uint32_t vector_id);
int32_t platform_interrupt_disable(uint32_t vector_id);
int32_t platform_in_isr(void);
void platform_notify(uint32_t vector_id);
/* platform low-level time-delay (busy loop) */
void platform_time_delay(uint32_t num_msec);
/* platform memory functions */
void platform_map_mem_region(uint32_t vrt_addr, uint32_t phy_addr, uint32_t size, uint32_t flags);
void platform_cache_all_flush_invalidate(void);
void platform_cache_disable(void);
uint32_t platform_vatopa(void *addr);
void *platform_patova(uint32_t addr);
/* platform init/deinit */
int32_t platform_init(void);
int32_t platform_deinit(void);
int32_t platform_reinit(void);
#endif /* RPMSG_PLATFORM_H_ */

View File

@ -0,0 +1,58 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RPMSG_PLATFORM_H_
#define RPMSG_PLATFORM_H_
#include <stdint.h>
/*
* No need to align the VRING as defined in Linux because RT500 is not intended
* to run the Linux
*/
#ifndef VRING_ALIGN
#define VRING_ALIGN (0x10U)
#endif
/* contains pool of descriptos and two circular buffers */
#ifndef VRING_SIZE
#define VRING_SIZE (0x400UL)
#endif
/* size of shared memory + 2*VRING size */
#define RL_VRING_OVERHEAD (2UL * VRING_SIZE)
#define RL_GET_VQ_ID(link_id, queue_id) (((queue_id)&0x1U) | (((link_id) << 1U) & 0xFFFFFFFEU))
#define RL_GET_LINK_ID(id) (((id)&0xFFFFFFFEU) >> 1U)
#define RL_GET_Q_ID(id) ((id)&0x1U)
#define RL_PLATFORM_IMXRT500_LINK_ID (0U)
#define RL_PLATFORM_HIGHEST_LINK_ID (0U)
/* platform interrupt related functions */
int32_t platform_init_interrupt(uint32_t vector_id, void *isr_data);
int32_t platform_deinit_interrupt(uint32_t vector_id);
int32_t platform_interrupt_enable(uint32_t vector_id);
int32_t platform_interrupt_disable(uint32_t vector_id);
int32_t platform_in_isr(void);
void platform_notify(uint32_t vector_id);
/* platform low-level time-delay (busy loop) */
void platform_time_delay(uint32_t num_msec);
/* platform memory functions */
void platform_map_mem_region(uint32_t vrt_addr, uint32_t phy_addr, uint32_t size, uint32_t flags);
void platform_cache_all_flush_invalidate(void);
void platform_cache_disable(void);
uint32_t platform_vatopa(void *addr);
void *platform_patova(uint32_t addr);
/* platform init/deinit */
int32_t platform_init(void);
int32_t platform_deinit(void);
#endif /* RPMSG_PLATFORM_H_ */

View File

@ -0,0 +1,58 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RPMSG_PLATFORM_H_
#define RPMSG_PLATFORM_H_
#include <stdint.h>
/*
* No need to align the VRING as defined in Linux because RT600 is not intended
* to run the Linux
*/
#ifndef VRING_ALIGN
#define VRING_ALIGN (0x10U)
#endif
/* contains pool of descriptos and two circular buffers */
#ifndef VRING_SIZE
#define VRING_SIZE (0x400UL)
#endif
/* size of shared memory + 2*VRING size */
#define RL_VRING_OVERHEAD (2UL * VRING_SIZE)
#define RL_GET_VQ_ID(link_id, queue_id) (((queue_id)&0x1U) | (((link_id) << 1U) & 0xFFFFFFFEU))
#define RL_GET_LINK_ID(id) (((id)&0xFFFFFFFEU) >> 1U)
#define RL_GET_Q_ID(id) ((id)&0x1U)
#define RL_PLATFORM_IMXRT600_LINK_ID (0U)
#define RL_PLATFORM_HIGHEST_LINK_ID (0U)
/* platform interrupt related functions */
int32_t platform_init_interrupt(uint32_t vector_id, void *isr_data);
int32_t platform_deinit_interrupt(uint32_t vector_id);
int32_t platform_interrupt_enable(uint32_t vector_id);
int32_t platform_interrupt_disable(uint32_t vector_id);
int32_t platform_in_isr(void);
void platform_notify(uint32_t vector_id);
/* platform low-level time-delay (busy loop) */
void platform_time_delay(uint32_t num_msec);
/* platform memory functions */
void platform_map_mem_region(uint32_t vrt_addr, uint32_t phy_addr, uint32_t size, uint32_t flags);
void platform_cache_all_flush_invalidate(void);
void platform_cache_disable(void);
uint32_t platform_vatopa(void *addr);
void *platform_patova(uint32_t addr);
/* platform init/deinit */
int32_t platform_init(void);
int32_t platform_deinit(void);
#endif /* RPMSG_PLATFORM_H_ */

View File

@ -0,0 +1,92 @@
#ifndef _RPMSG_H
#define _RPMSG_H
#include <stdint.h>
#include "rpmsg_lite.h"
/* Exported macro ------------------------------------------------------------*/
#define RPMSG_MSG_TYPE_MASTER_READY 0x00000001
#define RPMSG_MSG_TYPE_REMOTE_READY 0x00000002
#define RPMSG_MSG_TYPE_SYNC_INVOKE 0x00000003
#define RPMSG_MSG_TYPE_SYNC_RETURN 0x00000004
#define RPMSG_MSG_TYPE_ASYNC_MSG 0x00000005
#define RPMSG_SYNC_FUNC_MSG(type, sub_type) (((type)<<16) | (sub_type))
#define RPSMG_SYNC_FUNC_TYPE(func_id) ((func_id)>>16)
#define RPSMG_SYNC_FUNC_SUB_TYPE(func_id) ((func_id) & 0xffff)
#define RPMSG_SYNC_FUNC_TYPE_TEST 0x0001
#define RPMSG_SYNC_FUNC_TYPE_DSP 0x0002
#define RPMSG_SYNC_FUNC_TYPE_AUDIO 0x0003
#define RPMSG_SYNC_FUNC_TYPE_LVGL 0x0004
#define RPMSG_SYNC_FUNC_TYPE_FREETYPE 0x0005
#define RPMSG_SYNC_FUNC_SUM RPMSG_SYNC_FUNC_MSG(RPMSG_SYNC_FUNC_TYPE_TEST, 0x0001)
/** @addtogroup rpmsg syncronize invoke message definations
* @{
*/
struct rpmsg_sync_msg_sum_t {
uint32_t x;
uint32_t y;
};
/**
* @}
*/
/** @addtogroup rpmsg asyncronize message definations
* @{
*/
struct rpmsg_async_msg_t {
uint32_t msg_id;
union {
void *param;
uint32_t dsp_req_frq;
} p;
};
/**
* @}
*/
struct rpmsg_msg_t {
uint32_t msg_type;
union {
struct {
uint32_t func_id;
void *param;
} sync_func;
struct {
uint32_t status;
uint32_t result;
} sync_ret;
struct rpmsg_async_msg_t async_msg;
} p;
};
/*-----------------------------------------------------------------------------------*/
/* Exported functions ---------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
uint32_t rpmsg_sync_invoke(struct rpmsg_lite_instance *rpmsg, uint32_t func_id, void *param, uint32_t *ret);
uint32_t rpmsg_send_async(struct rpmsg_lite_instance *rpmsg, struct rpmsg_async_msg_t *async_msg);
uint32_t rpmsg_send_sync_ret(struct rpmsg_lite_instance *rpmsg, uint32_t status, uint32_t ret);
struct rpmsg_lite_instance *rpmsg_master_init(void (*recv)(struct rpmsg_lite_instance *rpmsg, struct rpmsg_msg_t *msg));
struct rpmsg_lite_instance *rpmsg_remote_init(void (*recv)(struct rpmsg_lite_instance *rpmsg, struct rpmsg_msg_t *msg));
void rpmsg_wait_master_ready(struct rpmsg_lite_instance *rpmsg);
void rpmsg_destroy(struct rpmsg_lite_instance *rpmsg);
uint32_t rpmsg_recv_msg(struct rpmsg_lite_instance *rpmsg, struct rpmsg_msg_t **msg, uint32_t *msg_len);
struct rpmsg_lite_instance *rpmsg_get_remote_instance(void);
struct rpmsg_lite_instance *rpmsg_get_master_instance(void);
void rpmsg_remote_recover(void);
#endif // _RPMSG_H

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016 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_compiler.h
*
* DESCRIPTION
*
* This file defines compiler-specific macros.
*
***************************************************************************/
#ifndef RPMSG_COMPILER_H_
#define RPMSG_COMPILER_H_
/* IAR ARM build tools */
#if defined(__ICCARM__)
#include <intrinsics.h>
#define MEM_BARRIER() __DSB()
#ifndef RL_PACKED_BEGIN
#define RL_PACKED_BEGIN __packed
#endif
#ifndef RL_PACKED_END
#define RL_PACKED_END
#endif
/* ARM GCC */
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
#if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
#include <arm_compat.h>
#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
#endif
#ifndef RL_PACKED_END
#define RL_PACKED_END __attribute__((__packed__))
#endif
/* GNUC */
#elif defined(__GNUC__)
#define MEM_BARRIER() __asm__ volatile("dsb" : : : "memory")
#ifndef RL_PACKED_BEGIN
#define RL_PACKED_BEGIN
#endif
#ifndef RL_PACKED_END
#define RL_PACKED_END __attribute__((__packed__))
#endif
#else
/* There is no default definition here to avoid wrong structures packing in case of not supported compiler */
#error Please implement the structure packing macros for your compiler here!
#endif
#endif /* RPMSG_COMPILER_H_ */

View File

@ -0,0 +1,169 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2021 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.
*/
#ifndef RPMSG_DEFAULT_CONFIG_H_
#define RPMSG_DEFAULT_CONFIG_H_
#define RL_USE_CUSTOM_CONFIG (1)
#if RL_USE_CUSTOM_CONFIG
#include "rpmsg_config.h"
#endif
/*!
* @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]. Ensure the same value is defined on both sides of rpmsg
//! communication. The default value is 496U.
#ifndef RL_BUFFER_PAYLOAD_SIZE
#define RL_BUFFER_PAYLOAD_SIZE (496U)
#endif
//! @def RL_BUFFER_COUNT
//!
//! Number of the buffers, it must be power of two (2, 4, ...).
//! The default value is 2U.
//! Note this value defines the buffer count for one direction of the rpmsg
//! communication only, i.e. if the default value of 2 is used
//! in rpmsg_config.h files for the master and the remote side, 4 buffers
//! in total are created in the shared memory.
#ifndef RL_BUFFER_COUNT
#define RL_BUFFER_COUNT (2U)
#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
//! @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
//! @def RL_ALLOW_CONSUMED_BUFFERS_NOTIFICATION
//!
//! When enabled the opposite side is notified each time received buffers
//! are consumed and put into the queue of available buffers.
//! Enable this option in RPMsg-Lite to Linux configuration to allow unblocking
//! of the Linux blocking send.
//! The default value is 0 (RPMsg-Lite to RPMsg-Lite communication).
#ifndef RL_ALLOW_CONSUMED_BUFFERS_NOTIFICATION
#define RL_ALLOW_CONSUMED_BUFFERS_NOTIFICATION (0)
#endif
//! @def RL_HANG
//!
//! Default implementation of hang assert function
static inline void RL_HANG(void)
{
for (;;)
{
}
}
//! @def RL_ASSERT
//!
//! Assert implementation.
#ifndef RL_ASSERT
#define RL_ASSERT_BOOL(b) \
do \
{ \
if (!(b)) \
{ \
RL_HANG(); \
} \
} while (0 == 1);
#define RL_ASSERT(x) RL_ASSERT_BOOL((int32_t)(x) != 0)
#endif
//@}
#endif /* RPMSG_DEFAULT_CONFIG_H_ */

View File

@ -0,0 +1,583 @@
/*
* 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.h
*
* COMPONENT
*
* OpenAMP stack.
*
* DESCRIPTION
*
* This file defines abstraction layer for OpenAMP stack. The implementor
* must provide definition of all the functions.
*
* DATA STRUCTURES
*
* none
*
* FUNCTIONS
*
* env_allocate_memory
* env_free_memory
* env_memset
* env_memcpy
* env_strncpy
* env_print
* env_map_vatopa
* env_map_patova
* env_mb
* env_rmb
* env_wmb
* env_create_mutex
* env_delete_mutex
* env_lock_mutex
* env_unlock_mutex
* env_sleep_msec
* env_disable_interrupt
* env_enable_interrupt
* env_create_queue
* env_delete_queue
* env_put_queue
* env_get_queue
*
**************************************************************************/
#ifndef RPMSG_ENV_H_
#define RPMSG_ENV_H_
#include <stdint.h>
#include "rpmsg_default_config.h"
#include "rpmsg_platform.h"
/*!
* env_init
*
* 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)
int32_t env_init(void **env_context, void *env_init_data);
#else
int32_t 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)
int32_t env_deinit(void *env_context);
#else
int32_t env_deinit(void);
#endif
/*!
* -------------------------------------------------------------------------
*
* Dynamic memory management functions. The parameters
* are similar to standard c functions.
*
*-------------------------------------------------------------------------
**/
/*!
* env_allocate_memory
*
* Allocates memory with the given size.
*
* @param size - size of memory to allocate
*
* @return - pointer to allocated memory
*/
void *env_allocate_memory(uint32_t size);
/*!
* env_free_memory
*
* Frees memory pointed by the given parameter.
*
* @param ptr - pointer to memory to free
*/
void env_free_memory(void *ptr);
/*!
* -------------------------------------------------------------------------
*
* RTL Functions
*
*-------------------------------------------------------------------------
*/
void env_memset(void *ptr, int32_t value, uint32_t size);
void env_memcpy(void *dst, void const *src, uint32_t len);
int32_t env_strcmp(const char *dst, const char *src);
void env_strncpy(char *dest, const char *src, uint32_t len);
int32_t env_strncmp(char *dest, const char *src, uint32_t len);
#ifdef MCUXPRESSO_SDK
/* MCUXpresso_SDK's PRINTF used in SDK examples */
#include "fsl_debug_console.h"
#if defined SDK_DEBUGCONSOLE && (SDK_DEBUGCONSOLE != DEBUGCONSOLE_DISABLE)
#define env_print(...) (void)PRINTF(__VA_ARGS__)
#else
#define env_print(...)
#endif
#else
/* When RPMsg_Lite being used outside of MCUXpresso_SDK use your own env_print
implemenetation to avoid conflict with Misra 21.6 rule */
#include <stdio.h>
#define env_print(...) printf(__VA_ARGS__)
#endif /* MCUXPRESSO_SDK */
/*!
*-----------------------------------------------------------------------------
*
* Functions to convert physical address to virtual address and vice versa.
*
*-----------------------------------------------------------------------------
*/
/*!
* env_map_vatopa
*
* Converts logical address to physical 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)
uint32_t env_map_vatopa(void *env, void *address);
#else
uint32_t env_map_vatopa(void *address);
#endif
/*!
* env_map_patova
*
* Converts physical address to logical 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, uint32_t address);
#else
void *env_map_patova(uint32_t address);
#endif
/*!
*-----------------------------------------------------------------------------
*
* Abstractions for memory barrier instructions.
*
*-----------------------------------------------------------------------------
*/
/*!
* env_mb
*
* Inserts memory barrier.
*/
void env_mb(void);
/*!
* env_rmb
*
* Inserts read memory barrier
*/
void env_rmb(void);
/*!
* env_wmb
*
* Inserts write memory barrier
*/
void env_wmb(void);
/*!
*-----------------------------------------------------------------------------
*
* Abstractions for OS lock primitives.
*
*-----------------------------------------------------------------------------
*/
/*!
* env_create_mutex
*
* Creates a mutex with given initial count.
*
* @param lock - pointer to created mutex
* @param count - initial count 0 or 1
*
* @return - status of function execution
*/
int32_t env_create_mutex(void **lock, int32_t count);
/*!
* env_delete_mutex
*
* Deletes the given lock.
*
* @param lock - mutex to delete
*/
void env_delete_mutex(void *lock);
/*!
* env_lock_mutex
*
* Tries to acquire the lock, if lock is not available then call to
* this function will suspend.
*
* @param lock - mutex to lock
*
*/
void env_lock_mutex(void *lock);
/*!
* env_unlock_mutex
*
* Releases the given lock.
*
* @param lock - mutex to unlock
*/
void env_unlock_mutex(void *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.
*
* @param lock - pointer to created sync lock object
* @param state - initial state , lock or unlocked
*
* @returns - status of function execution
*/
//#define LOCKED 0
//#define UNLOCKED 1
int32_t env_create_sync_lock(void **lock, int32_t state);
/*!
* env_create_sync_lock
*
* Deletes given sync lock object.
*
* @param lock - sync lock to delete.
*
*/
void env_delete_sync_lock(void *lock);
/*!
* env_acquire_sync_lock
*
* Tries to acquire the sync lock.
*
* @param lock - sync lock to acquire.
*/
void env_acquire_sync_lock(void *lock);
/*!
* env_release_sync_lock
*
* Releases synchronization lock.
*
* @param lock - sync lock to release.
*/
void env_release_sync_lock(void *lock);
/*!
* env_sleep_msec
*
* Suspends the calling thread for given time in msecs.
*
* @param num_msec - delay in msecs
*/
void env_sleep_msec(uint32_t num_msec);
/*!
* env_register_isr
*
* Registers interrupt handler data for the given interrupt vector.
*
* @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, uint32_t vector_id, void *data);
#else
void env_register_isr(uint32_t vector_id, void *data);
#endif
/*!
* env_unregister_isr
*
* Unregisters interrupt handler data for the given interrupt vector.
*
* @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, uint32_t vector_id);
#else
void env_unregister_isr(uint32_t vector_id);
#endif
/*!
* env_enable_interrupt
*
* Enables the given interrupt
*
* @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, uint32_t vector_id);
#else
void env_enable_interrupt(uint32_t vector_id);
#endif
/*!
* env_disable_interrupt
*
* Disables the given interrupt.
*
* @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, uint32_t vector_id);
#else
void env_disable_interrupt(uint32_t vector_id);
#endif
/*!
* 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
*
* Currently only first byte of flag parameter is used and bits mapping is defined as follow;
*
* Cache bits
* 0x0000_0001 = No cache
* 0x0000_0010 = Write back
* 0x0000_0100 = Write through
* 0x0000_x000 = Not used
*
* Memory types
*
* 0x0001_xxxx = Memory Mapped
* 0x0010_xxxx = IO Mapped
* 0x0100_xxxx = Shared
* 0x1000_xxxx = TLB
*/
/* Macros for caching scheme used by the shared memory */
#define UNCACHED (1 << 0)
#define WB_CACHE (1 << 1)
#define WT_CACHE (1 << 2)
/* Memory Types */
#define MEM_MAPPED (1 << 4)
#define IO_MAPPED (1 << 5)
#define SHARED_MEM (1 << 6)
#define TLB_MEM (1 << 7)
void env_map_memory(uint32_t pa, uint32_t va, uint32_t size, uint32_t flags);
/*!
* env_get_timestamp
*
* Returns a 64 bit time stamp.
*
*
*/
uint64_t env_get_timestamp(void);
/*!
* env_disable_cache
*
* Disables system caches.
*
*/
void env_disable_cache(void);
typedef void LOCK;
/*!
* env_create_queue
*
* 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
*
* @return - status of function execution
*/
int32_t env_create_queue(void **queue, int32_t length, int32_t element_size);
/*!
* env_delete_queue
*
* Deletes the message queue.
*
* @param queue Queue to delete
*/
void env_delete_queue(void *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
*/
int32_t env_put_queue(void *queue, void *msg, uint32_t timeout_ms);
/*!
* 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
*/
int32_t env_get_queue(void *queue, void *msg, uint32_t timeout_ms);
/*!
* env_get_current_queue_size
*
* Get current queue size.
*
* @param queue Queue pointer
*
* @return - Number of queued items in the queue
*/
int32_t env_get_current_queue_size(void *queue);
/*!
* env_isr
*
* Invoke RPMSG/IRQ callback
*
* @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, uint32_t vector);
#else
void env_isr(uint32_t 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
*/
int32_t env_init_interrupt(void *env, int32_t 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
*/
int32_t env_deinit_interrupt(void *env, int32_t vq_id);
#endif
#endif /* RPMSG_ENV_H_ */

View File

@ -0,0 +1,372 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016-2020 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.
*/
#ifndef RPMSG_LITE_H_
#define RPMSG_LITE_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include <stddef.h>
#include "virtqueue.h"
#include "rpmsg_env.h"
#include "llist.h"
#include "rpmsg_compiler.h"
#include "rpmsg_default_config.h"
//! @addtogroup rpmsg_lite
//! @{
/*******************************************************************************
* Definitions
******************************************************************************/
#define RL_VERSION "3.1.2" /*!< Current RPMsg Lite version */
/* Shared memory "allocator" parameters */
#define RL_WORD_SIZE (sizeof(uint32_t))
#define RL_WORD_ALIGN_UP(a) \
(((((uint32_t)a) & (RL_WORD_SIZE - 1U)) != 0U) ? ((((uint32_t)a) & (~(RL_WORD_SIZE - 1U))) + 4U) : ((uint32_t)a))
#define RL_WORD_ALIGN_DOWN(a) \
(((((uint32_t)a) & (RL_WORD_SIZE - 1U)) != 0U) ? (((uint32_t)a) & (~(RL_WORD_SIZE - 1U))) : ((uint32_t)a))
/* Definitions for device types , null pointer, etc.*/
#define RL_SUCCESS (0)
#define RL_NULL ((void *)0)
#define RL_REMOTE (0)
#define RL_MASTER (1)
#define RL_TRUE (1U)
#define RL_FALSE (0U)
#define RL_ADDR_ANY (0xFFFFFFFFU)
#define RL_RELEASE (0)
#define RL_HOLD (1)
#define RL_DONT_BLOCK (0)
#define RL_BLOCK (0xFFFFFFFFU)
/* Error macros. */
#define RL_ERRORS_BASE (-5000)
#define RL_ERR_NO_MEM (RL_ERRORS_BASE - 1)
#define RL_ERR_BUFF_SIZE (RL_ERRORS_BASE - 2)
#define RL_ERR_PARAM (RL_ERRORS_BASE - 3)
#define RL_ERR_DEV_ID (RL_ERRORS_BASE - 4)
#define RL_ERR_MAX_VQ (RL_ERRORS_BASE - 5)
#define RL_ERR_NO_BUFF (RL_ERRORS_BASE - 6)
#define RL_NOT_READY (RL_ERRORS_BASE - 7)
#define RL_ALREADY_DONE (RL_ERRORS_BASE - 8)
/* Init flags */
#define RL_NO_FLAGS (0)
/*! \typedef rl_ept_rx_cb_t
\brief Receive callback function type.
*/
typedef int32_t (*rl_ept_rx_cb_t)(void *payload, uint32_t payload_len, uint32_t src, void *priv);
/*!
* RPMsg Lite Endpoint structure
*/
struct rpmsg_lite_endpoint
{
uint32_t addr; /*!< endpoint address */
rl_ept_rx_cb_t rx_cb; /*!< ISR callback function */
void *rx_cb_data; /*!< ISR callback data */
void *rfu; /*!< reserved for future usage */
/* 16 bytes aligned on 32bit architecture */
};
/*!
* RPMsg Lite Endpoint static context
*/
struct rpmsg_lite_ept_static_context
{
struct rpmsg_lite_endpoint ept; /*!< memory for endpoint structure */
struct llist node; /*!< memory for linked list node structure */
};
/*!
* Structure describing the local instance
* of RPMSG lite communication stack and
* holds all runtime variables needed internally
* by the stack.
*/
struct rpmsg_lite_instance
{
struct virtqueue *rvq; /*!< receive virtqueue */
struct virtqueue *tvq; /*!< transmit virtqueue */
struct llist *rl_endpoints; /*!< linked list of endpoints */
LOCK *lock; /*!< local RPMsg Lite mutex lock */
uint32_t link_state; /*!< state of the link, up/down*/
char *sh_mem_base; /*!< base address of the shared memory */
uint32_t sh_mem_remaining; /*!< amount of remaining unused buffers in shared memory */
uint32_t sh_mem_total; /*!< total amount of buffers in 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];
#endif
};
/*******************************************************************************
* API
******************************************************************************/
/* Exported API functions */
/*!
* @brief Initializes the RPMsg-Lite communication stack.
* Must be called prior to any other RPMSG lite API.
* To be called by the master side.
*
* @param shmem_addr Shared memory base used for this instance of RPMsg-Lite
* @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, used when
* the environment layer uses its own context (RL_USE_ENVIRONMENT_CONTEXT)
* @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 RL_NULL.
*
*/
#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,
uint32_t 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, uint32_t 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,
uint32_t link_id,
uint32_t init_flags);
#endif
/**
* @brief Initializes the RPMsg-Lite communication stack.
* Must be called prior to any other RPMsg-Lite API.
* To be called by the remote side.
*
* @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, used when
* the environment layer uses its own context (RL_USE_ENVIRONMENT_CONTEXT)
* @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 RL_NULL.
*
*/
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr,
uint32_t 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,
uint32_t link_id,
uint32_t init_flags,
void *env_cfg);
#else
struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, uint32_t link_id, uint32_t init_flags);
#endif
/*!
*
* @brief Reset RPMsg-Lite communication stack. To be called by the remote side.
* When system wake up from sleep state, master side(DSP) will be reinitialized. Remote side
* should call this function to recover enviroment to reset state.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
*/
void rpmsg_lite_remote_env_reset(struct rpmsg_lite_instance *rpmsg_lite_dev);
/*!
*
* @brief Deinitialized the RPMsg-Lite communication stack
* This function always succeeds.
* rpmsg_lite_init() can be called again after this
* function has been called.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
*
* @return Status of function execution, RL_SUCCESS on success.
*/
int32_t rpmsg_lite_deinit(struct rpmsg_lite_instance *rpmsg_lite_dev);
/*!
* @brief Create a new rpmsg endpoint, which can be used
* for communication.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param addr Desired address, RL_ADDR_ANY for automatic selection
* @param rx_cb Callback function called on receive
* @param rx_cb_data Callback data pointer, passed to rx_cb
* @param ept_context Endpoint preallocated context pointer, used in case of static api (RL_USE_STATIC_API)
*
* @return RL_NULL on error, new endpoint pointer on success.
*
*/
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
struct rpmsg_lite_endpoint *rpmsg_lite_create_ept(struct rpmsg_lite_instance *rpmsg_lite_dev,
uint32_t addr,
rl_ept_rx_cb_t rx_cb,
void *rx_cb_data,
struct rpmsg_lite_ept_static_context *ept_context);
#else
struct rpmsg_lite_endpoint *rpmsg_lite_create_ept(struct rpmsg_lite_instance *rpmsg_lite_dev,
uint32_t addr,
rl_ept_rx_cb_t rx_cb,
void *rx_cb_data);
#endif
/*!
* @brief This function deletes rpmsg endpoint and performs cleanup.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param rl_ept Pointer to endpoint to destroy
*
*/
int32_t rpmsg_lite_destroy_ept(struct rpmsg_lite_instance *rpmsg_lite_dev, struct rpmsg_lite_endpoint *rl_ept);
/*!
*
* @brief Sends a message contained in data field of length size
* to the remote endpoint with address dst.
* ept->addr is used as source address in the rpmsg header
* of the message being sent.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param ept Sender endpoint
* @param dst Remote endpoint address
* @param data Payload buffer
* @param size Size of payload, in bytes
* @param timeout Timeout in ms, 0 if nonblocking
*
* @return Status of function execution, RL_SUCCESS on success.
*
*/
int32_t rpmsg_lite_send(struct rpmsg_lite_instance *rpmsg_lite_dev,
struct rpmsg_lite_endpoint *ept,
uint32_t dst,
char *data,
uint32_t size,
uint32_t timeout);
/*!
* @brief Function to get the link state
*
* @param rpmsg_lite_dev RPMsg-Lite instance
*
* @return True when link up, false when down.
*
*/
int32_t rpmsg_lite_is_link_up(struct rpmsg_lite_instance *rpmsg_lite_dev);
#if defined(RL_API_HAS_ZEROCOPY) && (RL_API_HAS_ZEROCOPY == 1)
/*!
* @brief Releases the rx buffer for future reuse in vring.
* This API can be called at process context when the
* message in rx buffer is processed.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param rxbuf Rx buffer with message payload
*
* @return Status of function execution, RL_SUCCESS on success.
*/
int32_t rpmsg_lite_release_rx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, void *rxbuf);
int32_t rpmsg_lite_release_rx_buffer_dur_recover(struct rpmsg_lite_instance *rpmsg_lite_dev, void *rxbuf);
/*!
* @brief Allocates the tx buffer for message payload.
*
* This API can only be called at process context to get the tx buffer in vring. By this way, the
* application can directly put its message into the vring tx buffer without copy from an application buffer.
* It is the application responsibility to correctly fill the allocated tx buffer by data and passing correct
* parameters to the rpmsg_lite_send_nocopy() function to perform data no-copy-send mechanism.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] size Pointer to store maximum payload size available
* @param[in] timeout Integer, wait upto timeout ms or not for buffer to become available
*
* @return The tx buffer address on success and RL_NULL on failure.
*
* @see rpmsg_lite_send_nocopy
*/
void *rpmsg_lite_alloc_tx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, uint32_t *size, uint32_t timeout);
/*!
* @brief Sends a message in tx buffer allocated by rpmsg_lite_alloc_tx_buffer()
*
* This function sends txbuf of length len to the remote dst address,
* and uses ept->addr as the source address.
* The application has to take the responsibility for:
* 1. tx buffer allocation (rpmsg_lite_alloc_tx_buffer())
* 2. filling the data to be sent into the pre-allocated tx buffer
* 3. not exceeding the buffer size when filling the data
* 4. data cache coherency
*
* After the rpmsg_lite_send_nocopy() function is issued the tx buffer is no more owned
* by the sending task and must not be touched anymore unless the rpmsg_lite_send_nocopy()
* function fails and returns an error.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] ept Sender endpoint pointer
* @param[in] dst Destination address
* @param[in] data TX buffer with message filled
* @param[in] size Length of payload
*
* @return 0 on success and an appropriate error value on failure.
*
* @see rpmsg_lite_alloc_tx_buffer
*/
int32_t rpmsg_lite_send_nocopy(struct rpmsg_lite_instance *rpmsg_lite_dev,
struct rpmsg_lite_endpoint *ept,
uint32_t dst,
void *data,
uint32_t size);
#endif /* RL_API_HAS_ZEROCOPY */
//! @}
#if defined(__cplusplus)
}
#endif
#endif /* RPMSG_LITE_H_ */

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016 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.
*/
#ifndef RPMSG_NS_H_
#define RPMSG_NS_H_
#include "rpmsg_lite.h"
//! @addtogroup rpmsg_ns
//! @{
#define RL_NS_EPT_ADDR (0x35u)
/* Up to 32 flags available */
enum rpmsg_ns_flags
{
RL_NS_CREATE = 0,
RL_NS_DESTROY = 1,
};
/*! \typedef rpmsg_ns_new_ept_cb
\brief New endpoint NS callback function type.
*/
typedef void (*rpmsg_ns_new_ept_cb)(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data);
struct rpmsg_ns_callback_data
{
rpmsg_ns_new_ept_cb cb;
void *user_data;
};
struct rpmsg_ns_context
{
struct rpmsg_lite_endpoint *ept;
struct rpmsg_ns_callback_data *cb_ctxt;
};
typedef struct rpmsg_ns_context *rpmsg_ns_handle;
struct rpmsg_ns_static_context_container
{
struct rpmsg_lite_ept_static_context ept_ctxt;
struct rpmsg_ns_callback_data cb_ctxt;
struct rpmsg_ns_context ns_ctxt;
};
typedef struct rpmsg_ns_static_context_container rpmsg_ns_static_context;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/* Exported API functions */
/*!
* @brief Registers application nameservice callback
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param app_cb Application nameservice callback
* @param user_data Application nameservice callback data
*
* @return RL_NULL on error, NameService handle on success.
*
*/
#if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
rpmsg_ns_handle rpmsg_ns_bind(struct rpmsg_lite_instance *rpmsg_lite_dev,
rpmsg_ns_new_ept_cb app_cb,
void *user_data,
rpmsg_ns_static_context *ns_ept_ctxt);
#else
rpmsg_ns_handle rpmsg_ns_bind(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_ns_new_ept_cb app_cb, void *user_data);
#endif /* RL_USE_STATIC_API */
/*!
* @brief Unregisters application nameservice callback and cleans up
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param handle NameService handle
*
* @return Status of function execution, RL_SUCCESS on success.
*
*/
int32_t rpmsg_ns_unbind(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_ns_handle handle);
/*!
* @brief Sends name service announcement to remote device
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param new_ept New endpoint to announce
* @param ept_name Name for the announced endpoint
* @param flags Channel creation/deletion flags
*
* @return Status of function execution, RL_SUCCESS on success
*
*/
int32_t rpmsg_ns_announce(struct rpmsg_lite_instance *rpmsg_lite_dev,
struct rpmsg_lite_endpoint *new_ept,
const char *ept_name,
uint32_t flags);
//! @}
#if defined(__cplusplus)
}
#endif
#endif /* RPMSG_NS_H_ */

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* Copyright (c) 2015 Xilinx, Inc.
* Copyright (c) 2016 Freescale Semiconductor, Inc.
* Copyright 2016 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.
*/
#ifndef RPMSG_QUEUE_H_
#define RPMSG_QUEUE_H_
#include "rpmsg_lite.h"
//! @addtogroup rpmsg_queue
//! @{
/*! \typedef rpmsg_queue_handle
\brief Rpmsg queue handle type.
*/
typedef void *rpmsg_queue_handle;
/* RL_API_HAS_ZEROCOPY has to be enabled for RPMsg Queue to work */
#if defined(RL_API_HAS_ZEROCOPY) && (RL_API_HAS_ZEROCOPY == 1)
/*******************************************************************************
* API
******************************************************************************/
/* Exported API functions */
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief
* This callback needs to be registered with an endpoint
*
* @param payload Pointer to the buffer containing received data
* @param payload_len Size of data received, in bytes
* @param src Pointer to address of the endpoint from which data is received
* @param priv Private data provided during endpoint creation
*
* @return RL_HOLD or RL_RELEASE to release or hold the buffer in payload
*/
int32_t rpmsg_queue_rx_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv);
/*!
* @brief
* Create a RPMsg queue which can be used
* for blocking reception.
*
* @param rpmsg_lite_dev RPMsg Lite instance
*
* @return RPMsg queue handle or RL_NULL
*
*/
rpmsg_queue_handle rpmsg_queue_create(struct rpmsg_lite_instance *rpmsg_lite_dev);
/*!
* @brief
* Destroy a queue and clean up.
* Do not destroy a queue which is registered with an active endpoint!
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] q RPMsg queue handle to destroy
*
* @return Status of function execution
*
*/
int32_t rpmsg_queue_destroy(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_queue_handle q);
/*!
* @brief
* blocking receive function - blocking version of the received function that can be called from an RTOS task.
* The data is copied from the receive buffer into the user supplied buffer.
*
* This is the "receive with copy" version of the RPMsg receive function. This version is simple
* to use but it requires copying data from shared memory into the user space buffer.
* The user has no obligation or burden to manage the shared memory buffers.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] q RPMsg queue handle to listen on
* @param[in] data Pointer to the user buffer the received data are copied to
* @param[out] len Pointer to an int variable that will contain the number of bytes actually copied into the
* buffer
* @param[in] maxlen Maximum number of bytes to copy (received buffer size)
* @param[out] src Pointer to address of the endpoint from which data is received
* @param[in] timeout Timeout, in milliseconds, to wait for a message. A value of 0 means don't wait (non-blocking
* call).
* A value of 0xffffffff means wait forever (blocking call).
*
* @return Status of function execution
*
* @see rpmsg_queue_recv_nocopy
*/
int32_t rpmsg_queue_recv(struct rpmsg_lite_instance *rpmsg_lite_dev,
rpmsg_queue_handle q,
uint32_t *src,
char *data,
uint32_t maxlen,
uint32_t *len,
uint32_t timeout);
/*!
* @brief
* blocking receive function - blocking version of the received function that can be called from an RTOS task.
* The data is NOT copied into the user-app. buffer.
*
* This is the "zero-copy receive" version of the RPMsg receive function. No data is copied.
* Only the pointer to the data is returned. This version is fast, but it requires the user to manage
* buffer allocation. Specifically, the user must decide when a buffer is no longer in use and
* make the appropriate API call to free it, see rpmsg_queue_nocopy_free().
*
* @param rpmsg_lite_dev RPMsg Lite instance
* @param[in] q RPMsg queue handle to listen on
* @param[out] data Pointer to the RPMsg buffer of the shared memory where the received data is stored
* @param[out] len Pointer to an int variable that that will contain the number of valid bytes in the RPMsg
* buffer
* @param[out] src Pointer to address of the endpoint from which data is received
* @param[in] timeout Timeout, in milliseconds, to wait for a message. A value of 0 means don't wait (non-blocking
* call).
* A value of 0xffffffff means wait forever (blocking call).
*
* @return Status of function execution.
*
* @see rpmsg_queue_nocopy_free
* @see rpmsg_queue_recv
*/
int32_t rpmsg_queue_recv_nocopy(struct rpmsg_lite_instance *rpmsg_lite_dev,
rpmsg_queue_handle q,
uint32_t *src,
char **data,
uint32_t *len,
uint32_t timeout);
/*!
* @brief This function frees a buffer previously returned by rpmsg_queue_recv_nocopy().
*
* Once the zero-copy mechanism of receiving data is used, this function
* has to be called to free a buffer and to make it available for the next data
* transfer.
*
* @param rpmsg_lite_dev RPMsg-Lite instance
* @param[in] data Pointer to the RPMsg buffer of the shared memory that has to be freed
*
* @return Status of function execution.
*
* @see rpmsg_queue_recv_nocopy
*/
int32_t rpmsg_queue_nocopy_free(struct rpmsg_lite_instance *rpmsg_lite_dev, void *data);
/*!
* @brief This function returns the number of pending messages in the queue.
*
* @param[in] q RPMsg queue handle
*
* @return Number of pending messages in the queue.
*/
int32_t rpmsg_queue_get_current_size(rpmsg_queue_handle q);
//! @}
#if defined(__cplusplus)
}
#endif
#endif /* RL_API_HAS_ZEROCOPY */
#endif /* RPMSG_QUEUE_H_ */

View File

@ -0,0 +1,168 @@
/*-
* Copyright Rusty Russell IBM Corporation 2007.
* Copyright 2019 NXP
* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers.
*
* 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 IBM 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 IBM 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.
*
* $FreeBSD$
*/
#ifndef VIRTIO_RING_H
#define VIRTIO_RING_H
/* This marks a buffer as continuing via the next field. */
#define VRING_DESC_F_NEXT 1U
/* This marks a buffer as write-only (otherwise read-only). */
#define VRING_DESC_F_WRITE 2U
/* This means the buffer contains a list of buffer descriptors. */
#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 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 1U
/* VirtIO ring descriptors: 16 bytes.
* These can chain together via "next". */
struct vring_desc
{
/* Address (guest-physical). */
uint64_t addr;
/* Length. */
uint32_t len;
/* The flags as indicated above. */
uint16_t flags;
/* We chain unused descriptors via this, too. */
uint16_t next;
};
struct vring_avail
{
uint16_t flags;
uint16_t idx;
uint16_t ring[1];
};
/* uint32_t is used here for ids for padding reasons. */
struct vring_used_elem
{
/* Index of start of used descriptor chain. */
uint32_t id;
/* Total length of the descriptor chain which was written to. */
uint32_t len;
};
struct vring_used
{
uint16_t flags;
uint16_t idx;
struct vring_used_elem ring[1];
};
struct vring
{
uint32_t num;
struct vring_desc *desc;
struct vring_avail *avail;
struct vring_used *used;
};
/* The standard layout for the ring is a continuous chunk of memory which
* looks like this. We assume num is a power of 2.
*
* struct vring {
* # The actual descriptors (16 bytes each)
* struct vring_desc desc[num];
*
* # A ring of available descriptor heads with free-running index.
* __u16 avail_flags;
* __u16 avail_idx;
* __u16 available[num];
* __u16 used_event_idx;
*
* # Padding to the next align boundary.
* char pad[];
*
* # A ring of used descriptor heads with free-running index.
* __u16 used_flags;
* __u16 used_idx;
* struct vring_used_elem used[num];
* __u16 avail_event_idx;
* };
*
* NOTE: for VirtIO PCI, align is 4096.
*/
/*
* We publish the used event index at the end of the available ring, and vice
* versa. They are at the end for backwards compatibility.
*/
#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
#define vring_avail_event(vr) ((vr)->used->ring[(vr)->num].id)
static inline int32_t vring_size(uint32_t num, uint32_t align)
{
uint32_t size;
size = num * sizeof(struct vring_desc);
size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) + sizeof(uint16_t);
size = (size + align - 1UL) & ~(align - 1UL);
size += sizeof(struct vring_used) + (num * sizeof(struct vring_used_elem)) + sizeof(uint16_t);
return ((int32_t)size);
}
static inline void vring_init(struct vring *vr, uint32_t num, uint8_t *p, uint32_t align)
{
vr->num = num;
vr->desc = (struct vring_desc *)(void *)p;
vr->avail = (struct vring_avail *)(void *)(p + num * sizeof(struct vring_desc));
vr->used = (struct vring_used *)(((uint32_t)&vr->avail->ring[num] + align - 1UL) & ~(align - 1UL));
}
/*
* The following is used with VIRTIO_RING_F_EVENT_IDX.
*
* Assuming a given event_idx value from the other size, if we have
* just incremented index from old to new_idx, should we trigger an
* event?
*/
static inline int32_t vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
{
if ((uint16_t)(new_idx - event_idx - 1U) < (uint16_t)(new_idx - old))
{
return 1;
}
else
{
return 0;
}
}
#endif /* VIRTIO_RING_H */

View File

@ -0,0 +1,249 @@
#ifndef VIRTQUEUE_H_
#define VIRTQUEUE_H_
/*-
* Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
* 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 unmodified, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* $FreeBSD$
*/
#include <stdbool.h>
#include <stdint.h>
#include "rpmsg_default_config.h"
typedef uint8_t boolean;
#include "virtio_ring.h"
#include "llist.h"
/*Error Codes*/
#define VQ_ERROR_BASE (-3000)
#define ERROR_VRING_FULL (VQ_ERROR_BASE - 1)
#define ERROR_INVLD_DESC_IDX (VQ_ERROR_BASE - 2)
#define ERROR_EMPTY_RING (VQ_ERROR_BASE - 3)
#define ERROR_NO_MEM (VQ_ERROR_BASE - 4)
#define ERROR_VRING_MAX_DESC (VQ_ERROR_BASE - 5)
#define ERROR_VRING_ALIGN (VQ_ERROR_BASE - 6)
#define ERROR_VRING_NO_BUFF (VQ_ERROR_BASE - 7)
#define ERROR_VQUEUE_INVLD_PARAM (VQ_ERROR_BASE - 8)
#define VQUEUE_SUCCESS (0)
#define VQUEUE_DEBUG (false)
/* This is temporary macro to replace C NULL support.
* At the moment all the RTL specific functions are present in env.
* */
#define VQ_NULL ((void *)0)
/* The maximum virtqueue size is 2^15. Use that value as the end of
* descriptor chain terminator since it will never be a valid index
* in the descriptor table. This is used to verify we are correctly
* handling vq_free_cnt.
*/
#define VQ_RING_DESC_CHAIN_END (32768)
#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. */
#define VIRTIO_RING_F_INDIRECT_DESC (1 << 28)
/* Support to suppress interrupt until specific index is reached. */
#define VIRTIO_RING_F_EVENT_IDX (1 << 29)
/*
* Hint on how long the next interrupt should be postponed. This is
* only used when the EVENT_IDX feature is negotiated.
*/
typedef enum
{
VQ_POSTPONE_SHORT,
VQ_POSTPONE_LONG,
VQ_POSTPONE_EMPTIED /* Until all available desc are used. */
} vq_postpone_t;
/* local virtqueue representation, not in shared memory */
struct virtqueue
{
/* 32bit aligned { */
char vq_name[VIRTQUEUE_MAX_NAME_SZ];
uint32_t vq_flags;
int32_t vq_alignment;
int32_t vq_ring_size;
void *vq_ring_mem;
void (*callback_fc)(struct virtqueue *vq);
void (*notify_fc)(struct virtqueue *vq);
int32_t vq_max_indirect_size;
int32_t vq_indirect_mem_size;
struct vring vq_ring;
/* } 32bit aligned */
/* 16bit aligned { */
uint16_t vq_queue_index;
uint16_t vq_nentries;
uint16_t vq_free_cnt;
uint16_t vq_queued_cnt;
/*
* Head of the free chain in the descriptor table. If
* there are no free descriptors, this will be set to
* VQ_RING_DESC_CHAIN_END.
*/
uint16_t vq_desc_head_idx;
/*
* Last consumed descriptor in the used table,
* trails vq_ring.used->idx.
*/
uint16_t vq_used_cons_idx;
/*
* Last consumed descriptor in the available table -
* used by the consumer side.
*/
uint16_t vq_available_idx;
/* } 16bit aligned */
boolean avail_read; /* 8bit wide */
boolean avail_write; /* 8bit wide */
boolean used_read; /* 8bit wide */
boolean used_write; /* 8bit wide */
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 */
struct vring_alloc_info
{
void *phy_addr;
uint32_t align;
uint16_t num_descs;
uint16_t pad;
};
struct vq_static_context
{
struct virtqueue vq;
};
typedef void vq_callback(struct virtqueue *vq);
typedef void vq_notify(struct virtqueue *vq);
#if (VQUEUE_DEBUG == true)
#define VQASSERT_BOOL(_vq, _exp, _msg) \
do \
{ \
if (!(_exp)) \
{ \
env_print("%s: %s - " _msg, __func__, (_vq)->vq_name); \
while (1) \
; \
} \
} while (0)
#define VQASSERT(_vq, _exp, _msg) VQASSERT_BOOL(_vq, (_exp) != 0, _msg)
#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx) VQASSERT((_vq), (_idx) < (_vq)->vq_nentries, "invalid ring index")
#define VQ_PARAM_CHK(condition, status_var, status_err) \
if ((status_var == 0) && (condition)) \
{ \
status_var = status_err; \
}
#define VQUEUE_BUSY(vq, dir) \
if ((vq)->dir == false) \
(vq)->dir = true; \
else \
VQASSERT(vq, (vq)->dir == false, "VirtQueue already in use")
#define VQUEUE_IDLE(vq, dir) ((vq)->dir = false)
#else
#define KASSERT(cond, str)
#define VQASSERT(_vq, _exp, _msg)
#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx)
#define VQ_PARAM_CHK(condition, status_var, status_err)
#define VQUEUE_BUSY(vq, dir)
#define VQUEUE_IDLE(vq, dir)
#endif
int32_t virtqueue_create(uint16_t id,
const char *name,
struct vring_alloc_info *ring,
void (*callback_fc)(struct virtqueue *vq),
void (*notify_fc)(struct virtqueue *vq),
struct virtqueue **v_queue);
int32_t virtqueue_create_static(uint16_t id,
const char *name,
struct vring_alloc_info *ring,
void (*callback_fc)(struct virtqueue *vq),
void (*notify_fc)(struct virtqueue *vq),
struct virtqueue **v_queue,
struct vq_static_context *vq_ctxt);
void virtqueue_reinit(struct virtqueue *vq);
int32_t virtqueue_add_buffer(struct virtqueue *vq, uint16_t head_idx);
int32_t virtqueue_fill_used_buffers(struct virtqueue *vq, void *buffer, uint32_t len);
int32_t virtqueue_fill_avail_buffers(struct virtqueue *vq, void *buffer, uint32_t len);
void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len, uint16_t *idx);
void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, uint32_t *len);
int32_t virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx, uint32_t len);
void virtqueue_disable_cb(struct virtqueue *vq);
int32_t virtqueue_enable_cb(struct virtqueue *vq);
void virtqueue_kick(struct virtqueue *vq);
void virtqueue_free(struct virtqueue *vq);
void virtqueue_free_static(struct virtqueue *vq);
void virtqueue_dump(struct virtqueue *vq);
void virtqueue_notification(struct virtqueue *vq);
uint32_t virtqueue_get_desc_size(struct virtqueue *vq);
uint32_t virtqueue_get_buffer_length(struct virtqueue *vq, uint16_t idx);
void vq_ring_init(struct virtqueue *vq);
#endif /* VIRTQUEUE_H_ */