rpmsg_lite.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * Copyright (c) 2014, Mentor Graphics Corporation
  3. * Copyright (c) 2015 Xilinx, Inc.
  4. * Copyright (c) 2016 Freescale Semiconductor, Inc.
  5. * Copyright 2016-2023 NXP
  6. * Copyright 2021 ACRIOS Systems s.r.o.
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright notice,
  15. * this list of conditions and the following disclaimer in the documentation
  16. * and/or other materials provided with the distribution.
  17. * 3. Neither the name of the copyright holder nor the names of its
  18. * contributors may be used to endorse or promote products derived from this
  19. * software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  25. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. * POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #ifndef RPMSG_LITE_H_
  34. #define RPMSG_LITE_H_
  35. #if defined(__cplusplus)
  36. extern "C" {
  37. #endif
  38. #include <stddef.h>
  39. #include "rpmsg_compiler.h"
  40. #include "virtqueue.h"
  41. #include "rpmsg_env.h"
  42. #include "llist.h"
  43. #include "rpmsg_default_config.h"
  44. //! @addtogroup rpmsg_lite
  45. //! @{
  46. /*******************************************************************************
  47. * Definitions
  48. ******************************************************************************/
  49. #define RL_VERSION "5.1.0" /*!< Current RPMsg Lite version */
  50. /* Shared memory "allocator" parameters */
  51. #define RL_WORD_SIZE (sizeof(uint32_t))
  52. #define RL_WORD_ALIGN_UP(a) \
  53. (((((uintptr_t)(a)) & (RL_WORD_SIZE - 1U)) != 0U) ? ((((uintptr_t)(a)) & (~(RL_WORD_SIZE - 1U))) + 4U) : \
  54. ((uintptr_t)(a)))
  55. #define RL_WORD_ALIGN_DOWN(a) \
  56. (((((uintptr_t)(a)) & (RL_WORD_SIZE - 1U)) != 0U) ? (((uintptr_t)(a)) & (~(RL_WORD_SIZE - 1U))) : ((uintptr_t)(a)))
  57. /* Definitions for device types , null pointer, etc.*/
  58. #define RL_SUCCESS (0)
  59. #define RL_NULL ((void *)0)
  60. #define RL_REMOTE (0)
  61. #define RL_MASTER (1)
  62. #define RL_TRUE (1UL)
  63. #define RL_FALSE (0UL)
  64. #define RL_ADDR_ANY (0xFFFFFFFFU)
  65. #define RL_RELEASE (0)
  66. #define RL_HOLD (1)
  67. #define RL_DONT_BLOCK (0)
  68. #define RL_BLOCK (~0UL)
  69. /* Error macros. */
  70. #define RL_ERRORS_BASE (-5000)
  71. #define RL_ERR_NO_MEM (RL_ERRORS_BASE - 1)
  72. #define RL_ERR_BUFF_SIZE (RL_ERRORS_BASE - 2)
  73. #define RL_ERR_PARAM (RL_ERRORS_BASE - 3)
  74. #define RL_ERR_DEV_ID (RL_ERRORS_BASE - 4)
  75. #define RL_ERR_MAX_VQ (RL_ERRORS_BASE - 5)
  76. #define RL_ERR_NO_BUFF (RL_ERRORS_BASE - 6)
  77. #define RL_NOT_READY (RL_ERRORS_BASE - 7)
  78. #define RL_ALREADY_DONE (RL_ERRORS_BASE - 8)
  79. /* Init flags */
  80. #define RL_NO_FLAGS (0U)
  81. /* rpmsg_std_hdr contains a reserved field,
  82. * this implementation of RPMSG uses this reserved
  83. * field to hold the idx and totlen of the buffer
  84. * not being returned to the vring in the receive
  85. * callback function. This way, the no-copy API
  86. * can use this field to return the buffer later.
  87. */
  88. struct rpmsg_hdr_reserved
  89. {
  90. uint16_t rfu; /* reserved for future usage */
  91. uint16_t idx;
  92. };
  93. RL_PACKED_BEGIN
  94. /*!
  95. * Common header for all rpmsg messages.
  96. * Every message sent/received on the rpmsg bus begins with this header.
  97. */
  98. struct rpmsg_std_hdr
  99. {
  100. uint32_t src; /*!< source endpoint address */
  101. uint32_t dst; /*!< destination endpoint address */
  102. struct rpmsg_hdr_reserved reserved; /*!< reserved for future use */
  103. uint16_t len; /*!< length of payload (in bytes) */
  104. uint16_t flags; /*!< message flags */
  105. } RL_PACKED_END;
  106. RL_PACKED_BEGIN
  107. /*!
  108. * Common message structure.
  109. * Contains the header and the payload.
  110. */
  111. struct rpmsg_std_msg
  112. {
  113. struct rpmsg_std_hdr hdr; /*!< RPMsg message header */
  114. uint8_t data[1]; /*!< bytes of message payload data */
  115. } RL_PACKED_END;
  116. /*! \typedef rl_ept_rx_cb_t
  117. \brief Receive callback function type.
  118. */
  119. typedef int32_t (*rl_ept_rx_cb_t)(void *payload, uint32_t payload_len, uint32_t src, void *priv);
  120. /*!
  121. * RPMsg Lite Endpoint structure
  122. */
  123. struct rpmsg_lite_endpoint
  124. {
  125. uint32_t addr; /*!< endpoint address */
  126. rl_ept_rx_cb_t rx_cb; /*!< ISR callback function */
  127. void *rx_cb_data; /*!< ISR callback data */
  128. void *rfu; /*!< reserved for future usage */
  129. /* 16 bytes aligned on 32bit architecture */
  130. };
  131. /*!
  132. * RPMsg Lite Endpoint static context
  133. */
  134. struct rpmsg_lite_ept_static_context
  135. {
  136. struct rpmsg_lite_endpoint ept; /*!< memory for endpoint structure */
  137. struct llist node; /*!< memory for linked list node structure */
  138. };
  139. /*!
  140. * Structure describing the local instance
  141. * of RPMSG lite communication stack and
  142. * holds all runtime variables needed internally
  143. * by the stack.
  144. */
  145. struct rpmsg_lite_instance
  146. {
  147. struct virtqueue *rvq; /*!< receive virtqueue */
  148. struct virtqueue *tvq; /*!< transmit virtqueue */
  149. struct llist *rl_endpoints; /*!< linked list of endpoints */
  150. LOCK *lock; /*!< local RPMsg Lite mutex lock */
  151. #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
  152. LOCK_STATIC_CONTEXT lock_static_ctxt; /*!< Static context for lock object creation */
  153. #endif
  154. uint32_t link_state; /*!< state of the link, up/down*/
  155. char *sh_mem_base; /*!< base address of the shared memory */
  156. uint32_t sh_mem_remaining; /*!< amount of remaining unused buffers in shared memory */
  157. uint32_t sh_mem_total; /*!< total amount of buffers in shared memory */
  158. struct virtqueue_ops const *vq_ops; /*!< ops functions table pointer */
  159. #if defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
  160. void *env; /*!< pointer to the environment layer context */
  161. #endif
  162. #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
  163. struct vq_static_context vq_ctxt[2];
  164. #endif
  165. uint32_t link_id; /*!< linkID of this rpmsg_lite instance */
  166. };
  167. /*******************************************************************************
  168. * API
  169. ******************************************************************************/
  170. /* Exported API functions */
  171. /*!
  172. * @brief Initializes the RPMsg-Lite communication stack.
  173. * Must be called prior to any other RPMSG lite API.
  174. * To be called by the master side.
  175. *
  176. * @param shmem_addr Shared memory base used for this instance of RPMsg-Lite
  177. * @param shmem_length Length of memory area given by previous parameter
  178. * @param link_id Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h
  179. * @param init_flags Initialization flags
  180. * @param env_cfg Initialization data for the environement RPMsg-Lite layer, used when
  181. * the environment layer uses its own context (RL_USE_ENVIRONMENT_CONTEXT)
  182. * @param static_context RPMsg-Lite preallocated context pointer, used in case of static api (RL_USE_STATIC_API)
  183. *
  184. * @return New RPMsg-Lite instance pointer or RL_NULL.
  185. *
  186. */
  187. #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
  188. struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr,
  189. size_t shmem_length,
  190. uint32_t link_id,
  191. uint32_t init_flags,
  192. struct rpmsg_lite_instance *static_context);
  193. #elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
  194. struct rpmsg_lite_instance *rpmsg_lite_master_init(
  195. void *shmem_addr, size_t shmem_length, uint32_t link_id, uint32_t init_flags, void *env_cfg);
  196. #else
  197. struct rpmsg_lite_instance *rpmsg_lite_master_init(void *shmem_addr,
  198. size_t shmem_length,
  199. uint32_t link_id,
  200. uint32_t init_flags);
  201. #endif
  202. /**
  203. * @brief Initializes the RPMsg-Lite communication stack.
  204. * Must be called prior to any other RPMsg-Lite API.
  205. * To be called by the remote side.
  206. *
  207. * @param shmem_addr Shared memory base used for this instance of RPMsg-Lite
  208. * @param link_id Link ID used to define the rpmsg-lite instance, see rpmsg_platform.h
  209. * @param init_flags Initialization flags
  210. * @param env_cfg Initialization data for the environement RPMsg-Lite layer, used when
  211. * the environment layer uses its own context (RL_USE_ENVIRONMENT_CONTEXT)
  212. * @param static_context RPMsg-Lite preallocated context pointer, used in case of static api (RL_USE_STATIC_API)
  213. *
  214. * @return New RPMsg-Lite instance pointer or RL_NULL.
  215. *
  216. */
  217. #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
  218. struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr,
  219. uint32_t link_id,
  220. uint32_t init_flags,
  221. struct rpmsg_lite_instance *static_context);
  222. #elif defined(RL_USE_ENVIRONMENT_CONTEXT) && (RL_USE_ENVIRONMENT_CONTEXT == 1)
  223. struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr,
  224. uint32_t link_id,
  225. uint32_t init_flags,
  226. void *env_cfg);
  227. #else
  228. struct rpmsg_lite_instance *rpmsg_lite_remote_init(void *shmem_addr, uint32_t link_id, uint32_t init_flags);
  229. #endif
  230. /*!
  231. *
  232. * @brief Deinitialized the RPMsg-Lite communication stack
  233. * This function always succeeds.
  234. * rpmsg_lite_init() can be called again after this
  235. * function has been called.
  236. *
  237. * @param rpmsg_lite_dev RPMsg-Lite instance
  238. *
  239. * @return Status of function execution, RL_SUCCESS on success.
  240. */
  241. int32_t rpmsg_lite_deinit(struct rpmsg_lite_instance *rpmsg_lite_dev);
  242. /*!
  243. * @brief Create a new rpmsg endpoint, which can be used
  244. * for communication.
  245. *
  246. * @param rpmsg_lite_dev RPMsg-Lite instance
  247. * @param addr Desired address, RL_ADDR_ANY for automatic selection
  248. * @param rx_cb Callback function called on receive
  249. * @param rx_cb_data Callback data pointer, passed to rx_cb
  250. * @param ept_context Endpoint preallocated context pointer, used in case of static api (RL_USE_STATIC_API)
  251. *
  252. * @return RL_NULL on error, new endpoint pointer on success.
  253. *
  254. */
  255. #if defined(RL_USE_STATIC_API) && (RL_USE_STATIC_API == 1)
  256. struct rpmsg_lite_endpoint *rpmsg_lite_create_ept(struct rpmsg_lite_instance *rpmsg_lite_dev,
  257. uint32_t addr,
  258. rl_ept_rx_cb_t rx_cb,
  259. void *rx_cb_data,
  260. struct rpmsg_lite_ept_static_context *ept_context);
  261. #else
  262. struct rpmsg_lite_endpoint *rpmsg_lite_create_ept(struct rpmsg_lite_instance *rpmsg_lite_dev,
  263. uint32_t addr,
  264. rl_ept_rx_cb_t rx_cb,
  265. void *rx_cb_data);
  266. #endif
  267. /*!
  268. * @brief This function deletes rpmsg endpoint and performs cleanup.
  269. *
  270. * @param rpmsg_lite_dev RPMsg-Lite instance
  271. * @param rl_ept Pointer to endpoint to destroy
  272. *
  273. */
  274. int32_t rpmsg_lite_destroy_ept(struct rpmsg_lite_instance *rpmsg_lite_dev, struct rpmsg_lite_endpoint *rl_ept);
  275. /*!
  276. *
  277. * @brief Sends a message contained in data field of length size
  278. * to the remote endpoint with address dst.
  279. * ept->addr is used as source address in the rpmsg header
  280. * of the message being sent.
  281. *
  282. * @param rpmsg_lite_dev RPMsg-Lite instance
  283. * @param ept Sender endpoint
  284. * @param dst Remote endpoint address
  285. * @param data Payload buffer
  286. * @param size Size of payload, in bytes
  287. * @param timeout Timeout in ms, 0 if nonblocking
  288. *
  289. * @return Status of function execution, RL_SUCCESS on success.
  290. *
  291. */
  292. int32_t rpmsg_lite_send(struct rpmsg_lite_instance *rpmsg_lite_dev,
  293. struct rpmsg_lite_endpoint *ept,
  294. uint32_t dst,
  295. char *data,
  296. uint32_t size,
  297. uintptr_t timeout);
  298. /*!
  299. * @brief Function to get the link state
  300. *
  301. * @param rpmsg_lite_dev RPMsg-Lite instance pointer
  302. *
  303. * @return RL_TRUE when link up, RL_FALSE when down.
  304. *
  305. */
  306. uint32_t rpmsg_lite_is_link_up(struct rpmsg_lite_instance *rpmsg_lite_dev);
  307. /*!
  308. * @brief Function to wait until the link is up. Returns RL_TRUE
  309. * once the link_state is set or RL_FALSE in case of timeout.
  310. *
  311. * @param rpmsg_lite_dev RPMsg-Lite instance pointer
  312. * @param timeout Timeout in ms, 0 if nonblocking
  313. *
  314. * @return RL_TRUE when link up, RL_FALSE when timeout.
  315. *
  316. */
  317. uint32_t rpmsg_lite_wait_for_link_up(struct rpmsg_lite_instance *rpmsg_lite_dev, uint32_t timeout);
  318. #if defined(RL_API_HAS_ZEROCOPY) && (RL_API_HAS_ZEROCOPY == 1)
  319. /*!
  320. * @brief Releases the rx buffer for future reuse in vring.
  321. * This API can be called at process context when the
  322. * message in rx buffer is processed.
  323. *
  324. * @param rpmsg_lite_dev RPMsg-Lite instance
  325. * @param rxbuf Rx buffer with message payload
  326. *
  327. * @return Status of function execution, RL_SUCCESS on success.
  328. */
  329. int32_t rpmsg_lite_release_rx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, void *rxbuf);
  330. /*!
  331. * @brief Allocates the tx buffer for message payload.
  332. *
  333. * This API can only be called at process context to get the tx buffer in vring. By this way, the
  334. * application can directly put its message into the vring tx buffer without copy from an application buffer.
  335. * It is the application responsibility to correctly fill the allocated tx buffer by data and passing correct
  336. * parameters to the rpmsg_lite_send_nocopy() function to perform data no-copy-send mechanism.
  337. *
  338. * @param rpmsg_lite_dev RPMsg-Lite instance
  339. * @param[in] size Pointer to store maximum payload size available
  340. * @param[in] timeout Integer, wait upto timeout ms or not for buffer to become available
  341. *
  342. * @return The tx buffer address on success and RL_NULL on failure.
  343. *
  344. * @see rpmsg_lite_send_nocopy
  345. */
  346. void *rpmsg_lite_alloc_tx_buffer(struct rpmsg_lite_instance *rpmsg_lite_dev, uint32_t *size, uintptr_t timeout);
  347. /*!
  348. * @brief Sends a message in tx buffer allocated by rpmsg_lite_alloc_tx_buffer()
  349. *
  350. * This function sends txbuf of length len to the remote dst address,
  351. * and uses ept->addr as the source address.
  352. * The application has to take the responsibility for:
  353. * 1. tx buffer allocation (rpmsg_lite_alloc_tx_buffer())
  354. * 2. filling the data to be sent into the pre-allocated tx buffer
  355. * 3. not exceeding the buffer size when filling the data
  356. * 4. data cache coherency
  357. *
  358. * After the rpmsg_lite_send_nocopy() function is issued the tx buffer is no more owned
  359. * by the sending task and must not be touched anymore unless the rpmsg_lite_send_nocopy()
  360. * function fails and returns an error.
  361. *
  362. * @param rpmsg_lite_dev RPMsg-Lite instance
  363. * @param[in] ept Sender endpoint pointer
  364. * @param[in] dst Destination address
  365. * @param[in] data TX buffer with message filled
  366. * @param[in] size Length of payload
  367. *
  368. * @return 0 on success and an appropriate error value on failure.
  369. *
  370. * @see rpmsg_lite_alloc_tx_buffer
  371. */
  372. int32_t rpmsg_lite_send_nocopy(struct rpmsg_lite_instance *rpmsg_lite_dev,
  373. struct rpmsg_lite_endpoint *ept,
  374. uint32_t dst,
  375. void *data,
  376. uint32_t size);
  377. #endif /* RL_API_HAS_ZEROCOPY */
  378. //! @}
  379. #if defined(__cplusplus)
  380. }
  381. #endif
  382. #endif /* RPMSG_LITE_H_ */