xrp_api.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*
  2. * Copyright (c) 2016 - 2017 Cadence Design Systems Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sublicense, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included
  13. * in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. /*!
  24. * \file xrp_api.h
  25. * \brief This section defines XRP API.
  26. *
  27. * General API properties:
  28. * - All status pointers can be NULL.
  29. * - Reference counting is not meant to work across host/DSP boundary, i.e.
  30. * DSP may not retain the host buffer.
  31. * - A buffer allocated for one device can be passed as command parameter to
  32. * a different device; implementation should do reasonable thing, e.g. use
  33. * the original data if possible or transparently migrate it to suitable
  34. * memory.
  35. * - A group of API calls may be host side only, DSP side only, or usable on
  36. * both sides. When it's usable on both sides there may be additional
  37. * restrictions on the DSP side.
  38. */
  39. #ifndef _XRP_API_H
  40. #define _XRP_API_H
  41. #include <stddef.h>
  42. #include <stdint.h>
  43. #ifdef __cplusplus
  44. extern "C" {
  45. #endif
  46. /*
  47. * User API.
  48. */
  49. struct xrp_device;
  50. struct xrp_queue;
  51. struct xrp_buffer;
  52. struct xrp_buffer_group;
  53. struct xrp_event;
  54. struct xrp_report;
  55. /*!
  56. * Status codes of XRP calls.
  57. */
  58. enum xrp_status {
  59. /*! Call completed successfully. */
  60. XRP_STATUS_SUCCESS,
  61. /*! Call failed. */
  62. XRP_STATUS_FAILURE,
  63. /*! Call has not completed. */
  64. XRP_STATUS_PENDING,
  65. };
  66. enum xrp_access_flags {
  67. XRP_READ = 0x1,
  68. XRP_WRITE = 0x2,
  69. XRP_READ_WRITE = 0x3,
  70. };
  71. /*!
  72. * Types of information that may be queried for a buffer object.
  73. */
  74. enum xrp_buffer_info {
  75. /*! Size of the buffer. */
  76. XRP_BUFFER_SIZE_SIZE_T,
  77. /*! Host pointer of the buffer. */
  78. XRP_BUFFER_HOST_POINTER_PTR,
  79. XRP_BUFFER_PHY_ADDR,
  80. XRP_BUFFER_USER_ADDR,
  81. };
  82. /*!
  83. * Types of information that may be queried for a buffer group object.
  84. */
  85. enum xrp_buffer_group_info {
  86. /*! Access flags associated with a buffer. Requires buffer index. */
  87. XRP_BUFFER_GROUP_BUFFER_FLAGS_ENUM,
  88. /*! Number of buffers in the buffer group. Buffer index is ignored. */
  89. XRP_BUFFER_GROUP_SIZE_SIZE_T,
  90. };
  91. #define XRP_NAMESPACE_ID_SIZE 16
  92. /*!
  93. * \defgroup device_api Device API
  94. * These calls are available on the host side and on the DSP side with the
  95. * following restriction:
  96. * - only device 0 may be opened.
  97. * @{
  98. */
  99. /*!
  100. * Open device by index.
  101. * A device is reference counted and is opened with reference count of 1.
  102. * Devices are numbered sequentially starting at 0, they can be probed with
  103. * simple loop.
  104. * \param idx: device index to open
  105. * \param[out] status: operation status
  106. * \return pointer to the opened device or NULL in case of error
  107. */
  108. struct xrp_device *xrp_open_device(int idx, enum xrp_status *status);
  109. /*!
  110. * Increment device reference count.
  111. */
  112. void xrp_retain_device(struct xrp_device *device);
  113. /*!
  114. * Decrement device reference count (and free associated resources once the
  115. * counter gets down to zero).
  116. */
  117. void xrp_release_device(struct xrp_device *device);
  118. /*!
  119. * @}
  120. */
  121. /*!
  122. * \defgroup buffer_api Buffer API
  123. * These calls are available on the host side and on the DSP side with the
  124. * following restriction:
  125. * - buffers may not be created on the DSP side.
  126. * @{
  127. */
  128. /*!
  129. * Create memory buffer and allocate device-specific storage (host_ptr == NULL)
  130. * or use host buffer (host_ptr != NULL, treated as virtual address in the
  131. * current process).
  132. * A buffer is reference counted and is created with reference count of 1.
  133. * \param[out] status: operation status
  134. */
  135. struct xrp_buffer *xrp_create_buffer(struct xrp_device *device,
  136. size_t size, void *host_ptr,
  137. enum xrp_status *status);
  138. /*!
  139. * Increment buffer reference count.
  140. */
  141. void xrp_retain_buffer(struct xrp_buffer *buffer);
  142. /*!
  143. * Decrement buffer reference count (and free the storage if it was allocated
  144. * once the counter gets down to zero).
  145. */
  146. void xrp_release_buffer(struct xrp_buffer *buffer);
  147. /*!
  148. * Map subbuffer of the buffer. Buffer may be mapped multiple times.
  149. *
  150. * \param map_flags: access to the mapping requested by the mapper. Access
  151. * to buffers on DSP side is subject to restrictions set by the host side.
  152. * \param[out] status: operation status
  153. */
  154. void *xrp_map_buffer(struct xrp_buffer *buffer, size_t offset, size_t size,
  155. enum xrp_access_flags map_flags, enum xrp_status *status);
  156. /*!
  157. * Unmap previously mapped buffer.
  158. * \param[out] status: operation status
  159. */
  160. void xrp_unmap_buffer(struct xrp_buffer *buffer, void *p,
  161. enum xrp_status *status);
  162. /*!
  163. * Get information about the buffer object.
  164. *
  165. * \param info: information type to retrieve.
  166. * \param[out] out: pointer to return information to.
  167. * \param out_sz: size of out buffer.
  168. * \param[out] status: operation status
  169. */
  170. void xrp_buffer_get_info(struct xrp_buffer *buffer, enum xrp_buffer_info info,
  171. void *out, size_t out_sz, enum xrp_status *status);
  172. /*!
  173. * @}
  174. */
  175. /*!
  176. * \defgroup buffer_group_api Buffer Group API
  177. * These calls are available on the host side and on the DSP side with the
  178. * following restrictions:
  179. * - buffer groups may not be created on the DSP side;
  180. * - existing buffer groups may not be modified on the DSP side.
  181. * @{
  182. */
  183. /*!
  184. * Create a group of shared buffers. Group is reference counted and is
  185. * created with reference count of 1.
  186. * \param[out] status: operation status
  187. */
  188. struct xrp_buffer_group *xrp_create_buffer_group(enum xrp_status *status);
  189. /*!
  190. * Increment buffer group reference count.
  191. */
  192. void xrp_retain_buffer_group(struct xrp_buffer_group *group);
  193. /*!
  194. * Decrement group reference count (and free it once the counter gets down
  195. * to zero).
  196. */
  197. void xrp_release_buffer_group(struct xrp_buffer_group *group);
  198. /*!
  199. * Add buffer to the group and get its index.
  200. * This adds a reference to the buffer.
  201. *
  202. * \param access_flags: granted access. User of the buffer on the DSP side
  203. * will be able to map it only for this type of access.
  204. * \param[out] status: operation status
  205. */
  206. size_t xrp_add_buffer_to_group(struct xrp_buffer_group *group,
  207. struct xrp_buffer *buffer,
  208. enum xrp_access_flags access_flags,
  209. enum xrp_status *status);
  210. /*!
  211. * Put new buffer to the existing index in the group.
  212. * When operation succeeds it releases the buffer previously contained at
  213. * that index and adds a reference to the new buffer.
  214. *
  215. * \param access_flags: granted access. User of the buffer on the DSP side
  216. * will be able to map it only for this type of access.
  217. * \param[out] status: operation status
  218. */
  219. void xrp_set_buffer_in_group(struct xrp_buffer_group *group,
  220. size_t index,
  221. struct xrp_buffer *buffer,
  222. enum xrp_access_flags access_flags,
  223. enum xrp_status *status);
  224. /*!
  225. * Get buffer from the group by its index.
  226. * Buffer must be freed with release_buffer.
  227. * \param[out] status: operation status
  228. */
  229. struct xrp_buffer *xrp_get_buffer_from_group(struct xrp_buffer_group *group,
  230. size_t idx,
  231. enum xrp_status *status);
  232. /*!
  233. * Get information about the buffer group object.
  234. *
  235. * \param info: information type to retrieve.
  236. * \param idx: buffer index (if applicable).
  237. * \param[out] out: pointer to return information to.
  238. * \param out_sz: size of out buffer.
  239. * \param[out] status: operation status
  240. */
  241. void xrp_buffer_group_get_info(struct xrp_buffer_group *group,
  242. enum xrp_buffer_group_info info, size_t idx,
  243. void *out, size_t out_sz,
  244. enum xrp_status *status);
  245. /*!
  246. * @}
  247. */
  248. /*!
  249. * \defgroup queue_api Queue API
  250. * These calls are available only on the host side.
  251. * @{
  252. */
  253. /*!
  254. * Create queue to the default namespace of the device.
  255. * Queue is an ordered device communication channel. Queue is reference
  256. * counted and is created with reference count of 1.
  257. * \param[out] status: operation status
  258. */
  259. struct xrp_queue *xrp_create_queue(struct xrp_device *device,
  260. enum xrp_status *status);
  261. /*!
  262. * Create queue to the specified namespace of the device.
  263. * Queue is an ordered device communication channel. Queue is reference
  264. * counted and is created with reference count of 1.
  265. * \param[out] status: operation status
  266. */
  267. struct xrp_queue *xrp_create_ns_queue(struct xrp_device *device,
  268. const void *nsid,
  269. enum xrp_status *status);
  270. /*!
  271. * Create queue to the specified namespace of the device with specific
  272. * priority.
  273. * Queue is an ordered device communication channel. Queue is reference
  274. * counted and is created with reference count of 1.
  275. * \param[out] status: operation status
  276. */
  277. struct xrp_queue *xrp_create_nsp_queue(struct xrp_device *device,
  278. const void *nsid,
  279. int priority,
  280. enum xrp_status *status);
  281. /*!
  282. * Increment queue reference count.
  283. */
  284. void xrp_retain_queue(struct xrp_queue *queue);
  285. /*!
  286. * Decrement queue reference count (and free it once the counter gets down
  287. * to zero).
  288. */
  289. void xrp_release_queue(struct xrp_queue *queue);
  290. /*!
  291. * @}
  292. */
  293. /*!
  294. * \defgroup event_api Event API
  295. * These calls are available only on the host side.
  296. * @{
  297. */
  298. /*!
  299. * Increment event reference count.
  300. */
  301. void xrp_retain_event(struct xrp_event *event);
  302. /*!
  303. * Decrement event reference count (and free it once the counter gets down
  304. * to zero).
  305. */
  306. void xrp_release_event(struct xrp_event *event);
  307. /*!
  308. * Get status of the event/associated command.
  309. * The function may be called at any time, it sets *status to
  310. * XRP_STATUS_PENDING if the command has not been executed yet, or to the
  311. * command execution status. See status description of xrp_run_command_sync()
  312. * for the description of command execution status.
  313. * \param[out] status: operation status
  314. */
  315. void xrp_event_status(struct xrp_event *event, enum xrp_status *status);
  316. /*!
  317. * @}
  318. */
  319. /*!
  320. * \defgroup communication_api Communication API
  321. * These calls are available only on the host side.
  322. * @{
  323. */
  324. /*
  325. * Even more internal API related to command passing between cores.
  326. * These are tightly coupled to the host-DSP communication model and
  327. * are likely to be changed/enhanced as the model evolves.
  328. */
  329. /*!
  330. * Synchronously send command from host to DSP.
  331. *
  332. * When this is invoked on the host it synchronously runs a command on DSP,
  333. * passing a group of shared buffers and two additional (small) buffers
  334. * with opaque command description (in_data) and results (out_data).
  335. *
  336. * in_data is used at the function call and is not referenced afterwards.
  337. * out_data is updated with the value returned by DSP before the function
  338. * returns.
  339. *
  340. * Optimal processing is guaranteed for in_data and out_data buffers not
  341. * exceeding 16 bytes in size. Larger buffers may require additional data
  342. * copying depending on the implementation.
  343. *
  344. * status is the result of command execution. Command execution is
  345. * successful if the command was delivered to the DSP and the response was
  346. * delivered back. Otherwise the command execution has failed. IOW execution
  347. * success means that the out_data contains command-specific response received
  348. * from the DSP, execution failure means that out_data does not contain useful
  349. * information.
  350. *
  351. * \param[out] status: operation status
  352. */
  353. void xrp_run_command_sync(struct xrp_queue *queue,
  354. const void *in_data, size_t in_data_size,
  355. void *out_data, size_t out_data_size,
  356. struct xrp_buffer_group *buffer_group,
  357. enum xrp_status *status);
  358. /*!
  359. * Asynchronously send command from host to DSP.
  360. *
  361. * When this is invoked on the host it queues a command to DSP,
  362. * passing a group of shared buffers and two additional (small) buffers
  363. * with opaque command description (in_data) and results (out_data).
  364. *
  365. * in_data is used at the function call and is not referenced afterwards.
  366. * out_data must stay valid after this function call until command completion,
  367. * at which point it is updated with the value returned by DSP.
  368. *
  369. * Optimal processing is guaranteed for in_data and out_data buffers not
  370. * exceeding 16 bytes in size. Larger buffers may require additional data
  371. * copying depending on the implementation.
  372. *
  373. * If event is non-NULL then a pointer to an event corresponding to the
  374. * queued command is returned. This event can be waited for with xrp_wait,
  375. * it is signaled when the command execution is complete.
  376. * The returned event object is reference counted and is created with
  377. * reference count of 1.
  378. *
  379. * status is the result of command enqueuing. Command enqueuing is
  380. * successful if the command was enqueued on the host side and an associated
  381. * event has been returned (if requested). Otherwise the command enqueuing has
  382. * failed. IOW enqueuing success means that if event is non-NULL then *event
  383. * contains valid event, enqueuing failure means that *event does not contain
  384. * useful information.
  385. *
  386. * \param[out] status: operation status
  387. */
  388. void xrp_enqueue_command(struct xrp_queue *queue,
  389. const void *in_data, size_t in_data_size,
  390. void *out_data, size_t out_data_size,
  391. struct xrp_buffer_group *buffer_group,
  392. struct xrp_event **event,
  393. enum xrp_status *status);
  394. /*!
  395. * Wait for the event.
  396. * Waiting for already signaled event completes immediately.
  397. * Successful completion of this function does not alter the event state,
  398. * i.e. the event remains signaled.
  399. * status is the result of waiting, not the result of the command execution.
  400. * Use xrp_event_status() to get the command execution status.
  401. * \param[out] status: operation status
  402. */
  403. void xrp_wait(struct xrp_event *event, enum xrp_status *status);
  404. /*!
  405. * Wait for any event in the group.
  406. * Waiting for a group with already signaled event completes immediately.
  407. * Successful completion of this function does not alter the event state,
  408. * i.e. signaled events remain signaled.
  409. * status is the result of waiting, not the result of the command execution.
  410. * Use xrp_event_status() with individual events to get the corresponding
  411. * command execution status.
  412. *
  413. * \param[in] event: an array of pointers to events to wait for
  414. * \param[i] n_events: number of events in the events array
  415. * \param[out] status: operation status
  416. * \return index of a completed event in the event array
  417. */
  418. size_t xrp_wait_any(struct xrp_event **event, size_t n_events,
  419. enum xrp_status *status);
  420. int xrp_add_report_item_with_id(struct xrp_report *report,
  421. int (*cb)(void*context,void*data),
  422. int report_id,
  423. void* context,
  424. size_t data_size);
  425. int xrp_add_report_item(struct xrp_report *report,
  426. int (*cb)(void*context,void*data),
  427. void* context,
  428. size_t data_size);
  429. void xrp_remove_report_item(struct xrp_report *report,int report_id);
  430. struct xrp_report *xrp_create_reporter(struct xrp_device *device,size_t size);
  431. int xrp_release_reporter(struct xrp_device *device,struct xrp_report *report);
  432. void xrp_import_dma_buf(struct xrp_device *device, int fd,enum xrp_access_flags flag ,uint64_t *phy_addr,
  433. uint64_t *user_addr,size_t* size,enum xrp_status *status);
  434. void xrp_release_dma_buf(struct xrp_device *device, int fd,enum xrp_status *status);
  435. void xrp_flush_dma_buf(struct xrp_device *device, int fd,enum xrp_access_flags flag ,enum xrp_status *status);
  436. /*!
  437. * @}
  438. */
  439. /*!
  440. * \defgroup dsp_specific_api DSP-specific Interface (Library-Style)
  441. * These calls are available only on the DSP side.
  442. * @{
  443. */
  444. /*!
  445. * Check if there's a command from the host in the hardware queue.
  446. * Returns XRP_STATUS_PENDING if the queue is empty or XRP_STATUS_SUCCESS
  447. * if there is a command ready for processing.
  448. *
  449. * The check is quick and may be issued in any context.
  450. */
  451. enum xrp_status xrp_device_poll(struct xrp_device *device);
  452. /*!
  453. * Check if there's a command from the host in the hardware queue and invoke
  454. * command handler if there's one.
  455. * Returns XRP_STATUS_PENDING if the queue is empty, or the status returned by
  456. * the command handler.
  457. */
  458. enum xrp_status xrp_device_dispatch(struct xrp_device *device);
  459. /*!
  460. * Function type for command handler.
  461. *
  462. * This callback is called on the DSP side to process queued command.
  463. * in_data, out_data and buffer_group correspond to the same parameters of the
  464. * host side API calls.
  465. *
  466. * On return from this function buffer group and individual buffer reference
  467. * counters shall be restored to their entry values. out_data buffer shall be
  468. * updated with command return value.
  469. * Neither in_data nor out_data may be referenced after this function returns.
  470. *
  471. * Return value shall describe whether xrp_command_handler itself was
  472. * successful or not, not the command it was requested to run.
  473. * I.e. if the command was not recognized or its handler could not be called
  474. * due to insufficient memory, that's XRP_STATUS_FAILURE returned in status.
  475. * The host will also receive XRP_STATUS_FAILURE as a completion status.
  476. * If the command was run that's XRP_STATUS_SUCCESS regardless of the
  477. * command-specific status, which should be returned in out_data.
  478. *
  479. * \param handler_context: context that was passed to the
  480. * xrp_device_register_namespace
  481. */
  482. typedef enum xrp_status
  483. (xrp_command_handler)(void *handler_context,
  484. const void *in_data, size_t in_data_size,
  485. void *out_data, size_t out_data_size,
  486. struct xrp_buffer_group *buffer_group);
  487. /*!
  488. * Register namespace handler.
  489. *
  490. * There may be only one handler for a namespace, second attempt to register
  491. * a handler for the same namespace will fail.
  492. *
  493. * \param device: device for which namespace handler is registered
  494. * \param nsid: namespace identifier, XRP_NAMESPACE_ID_SIZE bytes long
  495. * \param handler: pointer to the handler function
  496. * \param handler_context: first argument that will be passed to the handler
  497. * function
  498. * \param[out] status: operation status
  499. */
  500. void xrp_device_register_namespace(struct xrp_device *device,
  501. const void *nsid,
  502. xrp_command_handler *handler,
  503. void *handler_context,
  504. enum xrp_status *status);
  505. /*!
  506. * Unregister namespace handler.
  507. *
  508. * Only registered namespace handler may be unregistered.
  509. *
  510. * \param device: device for which namespace handler is registered
  511. * \param nsid: namespace identifier, XRP_NAMESPACE_ID_SIZE bytes long
  512. * \param[out] status: operation status
  513. */
  514. void xrp_device_unregister_namespace(struct xrp_device *device,
  515. const void *nsid,
  516. enum xrp_status *status);
  517. /*!
  518. * Enable or disable shared memory cache management.
  519. * Note that this call does not change memory caching attributes, it only
  520. * enables flushing and invalidating used regions of shared memory in the
  521. * XRP code.
  522. *
  523. * \param device: device for which shared memory cache management state is
  524. * changed
  525. * \param enable: whether cache management shall be enabled (non-zero) or
  526. * disabled (0)
  527. */
  528. void xrp_device_enable_cache(struct xrp_device *device, int enable);
  529. /*!
  530. * @}
  531. */
  532. /*!
  533. * Helper function that terminates fast simulation.
  534. */
  535. void xrp_exit(void);
  536. #ifdef __cplusplus
  537. }
  538. #endif
  539. #endif