Skip to content

Commit ea3b7a3

Browse files
author
Jyri Sarha
committed
ipc4: helper: Add ipc4_create_pipeline_payload_decode() and call it
Add ipc4_create_pipeline_payload_decode() and call it if struct ipc4_pipeline_create's extension.r.payload bit is set. The function decodes the message payload, logs the contents, but does not store the information anywhere. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com> SQUASH ipc4: Handler: Add ipc4_create_pipeline_payload_decode() and call it
1 parent 3cbfc8b commit ea3b7a3

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

src/ipc/ipc4/helper.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,101 @@ struct ipc_comp_dev *ipc_get_comp_by_ppl_id(struct ipc *ipc, uint16_t type,
230230
return NULL;
231231
}
232232

233+
/*
234+
* This function currently only decodes the payload and prints out
235+
* data it finds, but it does not store it anywhere.
236+
*/
237+
__cold static int ipc4_create_pipeline_payload_decode(char *data)
238+
{
239+
const struct ipc4_pipeline_ext_payload *hdr =
240+
(struct ipc4_pipeline_ext_payload *)data;
241+
const struct ipc4_pipeline_ext_object *obj;
242+
#ifdef CONFIG_DCACHE_LINE_SIZE
243+
size_t cache_line_size = CONFIG_DCACHE_LINE_SIZE;
244+
size_t hdr_cache_size = ALIGN_UP(sizeof(*hdr), cache_line_size);
245+
#endif
246+
bool last_object;
247+
size_t size;
248+
249+
#ifdef CONFIG_DCACHE_LINE_SIZE
250+
if (!IS_ENABLED(CONFIG_LIBRARY))
251+
sys_cache_data_invd_range((__sparse_force void __sparse_cache *)data,
252+
hdr_cache_size);
253+
#endif
254+
size = hdr->payload_words * sizeof(uint32_t);
255+
last_object = !hdr->data_obj_array;
256+
257+
if (size < sizeof(*hdr)) {
258+
tr_err(&ipc_tr, "Payload size too small: %u : %#x", hdr->payload_words,
259+
*((uint32_t *)hdr));
260+
return -EINVAL;
261+
}
262+
if (size > MAILBOX_HOSTBOX_SIZE) {
263+
tr_err(&ipc_tr, "Payload size too large: %u : %#x", hdr->payload_words,
264+
*((uint32_t *)hdr));
265+
}
266+
tr_info(&ipc_tr, "payload size %u array %u: %#x", hdr->payload_words, hdr->data_obj_array,
267+
*((uint32_t *)hdr));
268+
269+
#ifdef CONFIG_DCACHE_LINE_SIZE
270+
if (!IS_ENABLED(CONFIG_LIBRARY) && ALIGN_UP(size, cache_line_size) > hdr_cache_size)
271+
sys_cache_data_invd_range((__sparse_force void __sparse_cache *)
272+
((char *)data + hdr_cache_size),
273+
ALIGN_UP(size, cache_line_size) - hdr_cache_size);
274+
#endif
275+
276+
obj = (const struct ipc4_pipeline_ext_object *)(hdr + 1);
277+
while (!last_object) {
278+
const struct ipc4_pipeline_ext_object *next_obj;
279+
280+
/* Check if there is space for the object header */
281+
if ((char *)(obj + 1) - data > size) {
282+
tr_err(&ipc_tr, "obj header overflow, %u > %zu",
283+
(char *)(obj + 1) - data, size);
284+
return -EINVAL;
285+
}
286+
287+
/* Calculate would be next object position and check if current object fits */
288+
next_obj = (const struct ipc4_pipeline_ext_object *)
289+
(((const uint32_t *)(obj + 1)) + obj->object_words);
290+
if ((char *)next_obj - data > size) {
291+
tr_err(&ipc_tr, "object size overflow, %u > %zu",
292+
(char *)next_obj - data, size);
293+
return -EINVAL;
294+
}
295+
296+
switch (obj->object_id) {
297+
case IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA:
298+
{
299+
/* Get mem_data struct that follows the obj struct */
300+
const struct ipc4_pipeline_ext_obj_mem_data *mem_data =
301+
(const struct ipc4_pipeline_ext_obj_mem_data *)(obj + 1);
302+
303+
if (obj->object_words * sizeof(uint32_t) < sizeof(*mem_data)) {
304+
tr_err(&ipc_tr, "mem_data object does not fit %zu < %zu",
305+
obj->object_words * sizeof(uint32_t), sizeof(*mem_data));
306+
break;
307+
}
308+
tr_info(&ipc_tr,
309+
"init_ext_obj_mem_data domain %u stack %u interim %u lifetime %u shared %u",
310+
mem_data->domain_id, mem_data->stack_bytes,
311+
mem_data->interim_heap_bytes, mem_data->lifetime_heap_bytes,
312+
mem_data->shared_bytes);
313+
break;
314+
}
315+
default:
316+
tr_warn(&ipc_tr, "Unknown ext init object id %u of %u words",
317+
obj->object_id, obj->object_words);
318+
}
319+
/* Read the last object flag from obj header */
320+
last_object = obj->last_object;
321+
/* Move to next object */
322+
obj = next_obj;
323+
}
324+
325+
return 0;
326+
}
327+
233328
__cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
234329
{
235330
struct ipc_comp_dev *ipc_pipe;
@@ -281,6 +376,23 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
281376
return IPC4_SUCCESS;
282377
}
283378

379+
#if CONFIG_LIBRARY
380+
static inline char *ipc4_get_pipe_create_data(void)
381+
{
382+
struct ipc *ipc = ipc_get();
383+
char *data = (char *)ipc->comp_data + sizeof(struct ipc4_pipeline_create);
384+
385+
return data;
386+
}
387+
#else
388+
__cold static inline char *ipc4_get_pipe_create_data(void)
389+
{
390+
assert_can_be_cold();
391+
392+
return (char *)MAILBOX_HOSTBOX_BASE;
393+
}
394+
#endif
395+
284396
/* Only called from ipc4_new_pipeline(), which is __cold */
285397
__cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
286398
{
@@ -294,6 +406,14 @@ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
294406
if (!cpu_is_me(pipe_desc->extension.r.core_id))
295407
return ipc4_process_on_core(pipe_desc->extension.r.core_id, false);
296408

409+
if (pipe_desc->extension.r.payload) {
410+
char *data;
411+
412+
data = ipc4_get_pipe_create_data();
413+
414+
ipc4_create_pipeline_payload_decode(data);
415+
}
416+
297417
return ipc4_create_pipeline(pipe_desc);
298418
}
299419

0 commit comments

Comments
 (0)