blob: 3448425b42811abbc5bea61706f7fb8ef4a396d4 [file] [log] [blame]
Steve Muckle0a9c0872022-02-16 05:58:07 +00001/*******************************************************************************
2* Copyright (C) 2018 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 use this Software with Cadence processor cores only and
7* not with any other processors and platforms, subject to
8* the following conditions:
9*
10* The above copyright notice and this permission notice shall be included
11* in all copies or substantial portions of the Software.
12*
13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21******************************************************************************/
22
23/*******************************************************************************
24 * xf-msg.h
25 *
26 * Internal messages, and message queues.
27 *
28 *******************************************************************************/
29
30#ifndef __XF_H
31#error "xf-msg.h mustn't be included directly"
32#endif
33
34/*******************************************************************************
35 * Types definitions
36 ******************************************************************************/
37
38/* ...forward declaration */
39typedef struct xf_message xf_message_t;
40
41/* ...audio command/response message (internal to DSP processing framework) */
42struct xf_message
43{
44 /* ...pointer to next item in the list */
45 xf_message_t *next;
46
47 /* ...shmem session_id */
48 u32 id;
49
50 /* ...operation code */
51 u32 opcode;
52
53 /* ...length of attached message buffer */
54 u32 length;
55
56 /* ...message buffer (translated virtual address) */
57 void *buffer;
58#ifndef XAF_ENABLE_NON_HIKEY
59 uint64_t v_buffer;
60#endif
61};
62
63/* ...cache-line aligned message buffer */
64XF_ALIGNED_TYPEDEF(xf_message_t, __xf_message_t);
65
66/* ...message pool definition */
67typedef struct xf_msg_pool
68{
69 /* ...array of aligned messages */
70 __xf_message_t *p;
71
72 /* ...pointer to first free item in the pool */
73 __xf_message_t *head;
74
75 /* ...total size of the pool */
76 u32 n;
77
78} xf_msg_pool_t;
79
80/* ...message accessor */
81static inline xf_message_t * xf_msg_pool_item(xf_msg_pool_t *pool, u32 i)
82{
83 return (xf_message_t *) &pool->p[i];
84}
85
86/*******************************************************************************
87 * Message queue data
88 ******************************************************************************/
89
90/* ...message queue (single-linked FIFO list) */
91typedef struct xf_msg_queue
92{
93 /* ...head of the queue */
94 xf_message_t *head;
95
96 /* ...tail pointer */
97 xf_message_t *tail;
98
99} xf_msg_queue_t;
100
101/*******************************************************************************
102 * Message queue API
103 ******************************************************************************/
104
105/* ...initialize message queue */
106static inline void xf_msg_queue_init(xf_msg_queue_t *queue)
107{
108 queue->head = queue->tail = NULL;
109}
110
111/* ...push message in FIFO queue */
112static inline int xf_msg_enqueue(xf_msg_queue_t *queue, xf_message_t *m)
113{
114 int empty = (queue->head == NULL);
115
116 /* ...set list terminating pointer */
117 m->next = NULL;
118
119 if (empty)
120 queue->head = m;
121 else
122 queue->tail->next = m;
123
124 /* ...advance tail pointer */
125 queue->tail = m;
126
127 /* ...return emptiness status */
128 return empty;
129}
130
131#define xf_msg_enqueue(queue, m) \
132({ \
133 BUG((m)->next != NULL, _x("message is active: %p"), (m)); \
134 (xf_msg_enqueue)((queue), (m)); \
135})
136
137/* ...retrieve (pop) next message from FIFO queue */
138static inline xf_message_t * xf_msg_dequeue(xf_msg_queue_t *queue)
139{
140 xf_message_t *m = queue->head;
141
142 /* ...check if there is anything in the queue and dequeue it */
143 if (m != NULL)
144 {
145 /* ...advance head to the next entry in the queue */
146 if ((queue->head = m->next) == NULL)
147 queue->tail = NULL;
148
149 /* ...debug - wipe out next pointer */
150 m->next = NULL;
151 }
152
153 return m;
154}
155
156/* ...test if message queue is empty */
157static inline int xf_msg_queue_empty(xf_msg_queue_t *queue)
158{
159 return (queue->head == NULL);
160}
161
162/* ...get message queue head pointer */
163static inline xf_message_t * xf_msg_queue_head(xf_msg_queue_t *queue)
164{
165 return queue->head;
166}
167
168/* ...check if message belongs to a pool */
169static inline int xf_msg_from_pool(xf_msg_pool_t *pool, xf_message_t *m)
170{
171 return (u32)((__xf_message_t*)m - pool->p) < pool->n;
172}
173
174/*******************************************************************************
175 * Global message pool API
176 ******************************************************************************/
177
178/* ...submit message execution on local DSP core */
179extern void xf_msg_schedule(xf_message_t *m, u32 ts);
180
181/* ...schedule message execution from ISR context */
182extern void xf_msg_schedule_isr(xf_message_t *m);
183
184/* ...submit message for execution on some DSP */
185extern void xf_msg_submit(xf_message_t *m);
186
187/* ...cancel local (scheduled on current core) message execution */
188extern void xf_msg_cancel(xf_message_t *m);
189
190/* ...complete message processing */
191extern void xf_msg_complete(xf_message_t *m);
192
193/* ...complete message from ISR context */
194extern void xf_msg_complete_isr(xf_message_t *m);
195
196/* ...allocate message pool on specific core */
197extern int xf_msg_pool_init(xf_msg_pool_t *pool, u32 n, u32 core);
198
199/* ...allocate message from a pool (no concurrent access from other cores) */
200extern xf_message_t * xf_msg_pool_get(xf_msg_pool_t *pool);
201
202/* ...return message back to the pool (no concurrent access from other cores) */
203extern void xf_msg_pool_put(xf_msg_pool_t *pool, xf_message_t *m);
204
205/* ...destroy message pool */
206extern void xf_msg_pool_destroy(xf_msg_pool_t *pool, u32 core);
207
208/* ...indicate whether pool of free messages is empty */
209extern int xf_message_pool_empty(void);
210
211/* ...initialize global pool of messages */
212extern void xf_message_pool_init(void);
213
214/*******************************************************************************
215 * Auxiliary helpers
216 ******************************************************************************/
217
218/* ...send response message to caller */
219static inline void xf_response(xf_message_t *m)
220{
221 xf_msg_complete(m);
222}
223
224/* ...send response message with output buffer */
225static inline void xf_response_data(xf_message_t *m, u32 length)
226{
227 /* ...adjust message output buffer */
228 m->length = length;
229
230 /* ...return message to originator */
231 xf_msg_complete(m);
232}
233
234/* ...send generic "ok" message (no data buffer) */
235static inline void xf_response_ok(xf_message_t *m)
236{
237 /* ...adjust message output buffer */
238 m->length = 0;
239
240 /* ...return message to originator */
241 xf_msg_complete(m);
242}
243
244/* ...send error-response message */
245static inline void xf_response_err(xf_message_t *m)
246{
247 /* ...set generic error message */
248 m->opcode = XF_UNREGISTER, m->length = 0;
249
250 /* ...return message to originator */
251 xf_msg_complete(m);
252}