Skip to content

Commit 95b5898

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 65a57f0 commit 95b5898

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

src/ipc/ipc4/helper.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,98 @@ struct ipc_comp_dev *ipc_get_comp_by_ppl_id(struct ipc *ipc, uint16_t type,
229229
return NULL;
230230
}
231231

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

375+
#if CONFIG_LIBRARY
376+
static inline char *ipc4_get_pipe_create_data(void)
377+
{
378+
struct ipc *ipc = ipc_get();
379+
char *data = (char *)ipc->comp_data + sizeof(struct ipc4_pipeline_create);
380+
381+
return data;
382+
}
383+
#else
384+
__cold static inline char *ipc4_get_pipe_create_data(void)
385+
{
386+
assert_can_be_cold();
387+
388+
return (char *)MAILBOX_HOSTBOX_BASE;
389+
}
390+
#endif
391+
283392
/* Only called from ipc4_new_pipeline(), which is __cold */
284393
__cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
285394
{
@@ -293,6 +402,14 @@ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
293402
if (!cpu_is_me(pipe_desc->extension.r.core_id))
294403
return ipc4_process_on_core(pipe_desc->extension.r.core_id, false);
295404

405+
if (pipe_desc->extension.r.payload) {
406+
char *data;
407+
408+
data = ipc4_get_pipe_create_data();
409+
410+
ipc4_create_pipeline_payload_decode(data);
411+
}
412+
296413
return ipc4_create_pipeline(pipe_desc);
297414
}
298415

0 commit comments

Comments
 (0)