diff options
Diffstat (limited to 'hifi/xaf/hifi-dpf/include/xf-msg.h')
-rw-r--r-- | hifi/xaf/hifi-dpf/include/xf-msg.h | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/hifi/xaf/hifi-dpf/include/xf-msg.h b/hifi/xaf/hifi-dpf/include/xf-msg.h new file mode 100644 index 00000000..3448425b --- /dev/null +++ b/hifi/xaf/hifi-dpf/include/xf-msg.h @@ -0,0 +1,252 @@ +/******************************************************************************* +* Copyright (C) 2018 Cadence Design Systems, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to use this Software with Cadence processor cores only and +* not with any other processors and platforms, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************************/ + +/******************************************************************************* + * xf-msg.h + * + * Internal messages, and message queues. + * + *******************************************************************************/ + +#ifndef __XF_H +#error "xf-msg.h mustn't be included directly" +#endif + +/******************************************************************************* + * Types definitions + ******************************************************************************/ + +/* ...forward declaration */ +typedef struct xf_message xf_message_t; + +/* ...audio command/response message (internal to DSP processing framework) */ +struct xf_message +{ + /* ...pointer to next item in the list */ + xf_message_t *next; + + /* ...shmem session_id */ + u32 id; + + /* ...operation code */ + u32 opcode; + + /* ...length of attached message buffer */ + u32 length; + + /* ...message buffer (translated virtual address) */ + void *buffer; +#ifndef XAF_ENABLE_NON_HIKEY + uint64_t v_buffer; +#endif +}; + +/* ...cache-line aligned message buffer */ +XF_ALIGNED_TYPEDEF(xf_message_t, __xf_message_t); + +/* ...message pool definition */ +typedef struct xf_msg_pool +{ + /* ...array of aligned messages */ + __xf_message_t *p; + + /* ...pointer to first free item in the pool */ + __xf_message_t *head; + + /* ...total size of the pool */ + u32 n; + +} xf_msg_pool_t; + +/* ...message accessor */ +static inline xf_message_t * xf_msg_pool_item(xf_msg_pool_t *pool, u32 i) +{ + return (xf_message_t *) &pool->p[i]; +} + +/******************************************************************************* + * Message queue data + ******************************************************************************/ + +/* ...message queue (single-linked FIFO list) */ +typedef struct xf_msg_queue +{ + /* ...head of the queue */ + xf_message_t *head; + + /* ...tail pointer */ + xf_message_t *tail; + +} xf_msg_queue_t; + +/******************************************************************************* + * Message queue API + ******************************************************************************/ + +/* ...initialize message queue */ +static inline void xf_msg_queue_init(xf_msg_queue_t *queue) +{ + queue->head = queue->tail = NULL; +} + +/* ...push message in FIFO queue */ +static inline int xf_msg_enqueue(xf_msg_queue_t *queue, xf_message_t *m) +{ + int empty = (queue->head == NULL); + + /* ...set list terminating pointer */ + m->next = NULL; + + if (empty) + queue->head = m; + else + queue->tail->next = m; + + /* ...advance tail pointer */ + queue->tail = m; + + /* ...return emptiness status */ + return empty; +} + +#define xf_msg_enqueue(queue, m) \ +({ \ + BUG((m)->next != NULL, _x("message is active: %p"), (m)); \ + (xf_msg_enqueue)((queue), (m)); \ +}) + +/* ...retrieve (pop) next message from FIFO queue */ +static inline xf_message_t * xf_msg_dequeue(xf_msg_queue_t *queue) +{ + xf_message_t *m = queue->head; + + /* ...check if there is anything in the queue and dequeue it */ + if (m != NULL) + { + /* ...advance head to the next entry in the queue */ + if ((queue->head = m->next) == NULL) + queue->tail = NULL; + + /* ...debug - wipe out next pointer */ + m->next = NULL; + } + + return m; +} + +/* ...test if message queue is empty */ +static inline int xf_msg_queue_empty(xf_msg_queue_t *queue) +{ + return (queue->head == NULL); +} + +/* ...get message queue head pointer */ +static inline xf_message_t * xf_msg_queue_head(xf_msg_queue_t *queue) +{ + return queue->head; +} + +/* ...check if message belongs to a pool */ +static inline int xf_msg_from_pool(xf_msg_pool_t *pool, xf_message_t *m) +{ + return (u32)((__xf_message_t*)m - pool->p) < pool->n; +} + +/******************************************************************************* + * Global message pool API + ******************************************************************************/ + +/* ...submit message execution on local DSP core */ +extern void xf_msg_schedule(xf_message_t *m, u32 ts); + +/* ...schedule message execution from ISR context */ +extern void xf_msg_schedule_isr(xf_message_t *m); + +/* ...submit message for execution on some DSP */ +extern void xf_msg_submit(xf_message_t *m); + +/* ...cancel local (scheduled on current core) message execution */ +extern void xf_msg_cancel(xf_message_t *m); + +/* ...complete message processing */ +extern void xf_msg_complete(xf_message_t *m); + +/* ...complete message from ISR context */ +extern void xf_msg_complete_isr(xf_message_t *m); + +/* ...allocate message pool on specific core */ +extern int xf_msg_pool_init(xf_msg_pool_t *pool, u32 n, u32 core); + +/* ...allocate message from a pool (no concurrent access from other cores) */ +extern xf_message_t * xf_msg_pool_get(xf_msg_pool_t *pool); + +/* ...return message back to the pool (no concurrent access from other cores) */ +extern void xf_msg_pool_put(xf_msg_pool_t *pool, xf_message_t *m); + +/* ...destroy message pool */ +extern void xf_msg_pool_destroy(xf_msg_pool_t *pool, u32 core); + +/* ...indicate whether pool of free messages is empty */ +extern int xf_message_pool_empty(void); + +/* ...initialize global pool of messages */ +extern void xf_message_pool_init(void); + +/******************************************************************************* + * Auxiliary helpers + ******************************************************************************/ + +/* ...send response message to caller */ +static inline void xf_response(xf_message_t *m) +{ + xf_msg_complete(m); +} + +/* ...send response message with output buffer */ +static inline void xf_response_data(xf_message_t *m, u32 length) +{ + /* ...adjust message output buffer */ + m->length = length; + + /* ...return message to originator */ + xf_msg_complete(m); +} + +/* ...send generic "ok" message (no data buffer) */ +static inline void xf_response_ok(xf_message_t *m) +{ + /* ...adjust message output buffer */ + m->length = 0; + + /* ...return message to originator */ + xf_msg_complete(m); +} + +/* ...send error-response message */ +static inline void xf_response_err(xf_message_t *m) +{ + /* ...set generic error message */ + m->opcode = XF_UNREGISTER, m->length = 0; + + /* ...return message to originator */ + xf_msg_complete(m); +} |