Skip to content

Commit 14ffd2f

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 14ffd2f

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
@@ -230,6 +230,98 @@ 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+
263+
tr_info(&ipc_tr, "payload size %u array %u: %#x", hdr->payload_words, hdr->data_obj_array,
264+
*((uint32_t *)hdr));
265+
266+
#ifdef CONFIG_DCACHE_LINE_SIZE
267+
if (!IS_ENABLED(CONFIG_LIBRARY) && ALIGN_UP(size, cache_line_size) > hdr_cache_size)
268+
sys_cache_data_invd_range((__sparse_force void __sparse_cache *)
269+
((char *)data + hdr_cache_size),
270+
ALIGN_UP(size, cache_line_size) - hdr_cache_size);
271+
#endif
272+
273+
obj = (const struct ipc4_pipeline_ext_object *)(hdr + 1);
274+
while (!last_object) {
275+
const struct ipc4_pipeline_ext_object *next_obj;
276+
277+
/* Check if there is space for the object header */
278+
if ((char *)(obj + 1) - data > size) {
279+
tr_err(&ipc_tr, "obj header overflow, %u > %zu",
280+
(char *)(obj + 1) - data, size);
281+
return -EINVAL;
282+
}
283+
284+
/* Calculate would be next object position and check if current object fits */
285+
next_obj = (const struct ipc4_pipeline_ext_object *)
286+
(((const uint32_t *)(obj + 1)) + obj->object_words);
287+
if ((char *)next_obj - data > size) {
288+
tr_err(&ipc_tr, "object size overflow, %u > %zu",
289+
(char *)next_obj - data, size);
290+
return -EINVAL;
291+
}
292+
293+
switch (obj->object_id) {
294+
case IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA:
295+
{
296+
/* Get mem_data struct that follows the obj struct */
297+
const struct ipc4_pipeline_ext_obj_mem_data *mem_data =
298+
(const struct ipc4_pipeline_ext_obj_mem_data *)(obj + 1);
299+
300+
if (obj->object_words * sizeof(uint32_t) < sizeof(*mem_data)) {
301+
tr_err(&ipc_tr, "mem_data object does not fit %zu < %zu",
302+
obj->object_words * sizeof(uint32_t), sizeof(*mem_data));
303+
break;
304+
}
305+
tr_info(&ipc_tr,
306+
"init_ext_obj_mem_data domain %u stack %u interim %u lifetime %u shared %u",
307+
mem_data->domain_id, mem_data->stack_bytes,
308+
mem_data->interim_heap_bytes, mem_data->lifetime_heap_bytes,
309+
mem_data->shared_bytes);
310+
break;
311+
}
312+
default:
313+
tr_warn(&ipc_tr, "Unknown ext init object id %u of %u words",
314+
obj->object_id, obj->object_words);
315+
}
316+
/* Read the last object flag from obj header */
317+
last_object = obj->last_object;
318+
/* Move to next object */
319+
obj = next_obj;
320+
}
321+
322+
return 0;
323+
}
324+
233325
__cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
234326
{
235327
struct ipc_comp_dev *ipc_pipe;
@@ -281,6 +373,23 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
281373
return IPC4_SUCCESS;
282374
}
283375

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

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

0 commit comments

Comments
 (0)