373 lines
15 KiB
C
373 lines
15 KiB
C
|
/*
|
||
|
* 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_ */
|