@@ -229,6 +229,77 @@ 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+ size_t size = hdr -> payload_words * sizeof (uint32_t );
242+ bool last_object = !hdr -> data_obj_array ;
243+
244+ if (hdr -> payload_words * sizeof (uint32_t ) < sizeof (* hdr )) {
245+ tr_err (& ipc_tr , "Payload size too small: %u : %#x" , hdr -> payload_words ,
246+ * ((uint32_t * )hdr ));
247+ return - EINVAL ;
248+ }
249+
250+ tr_info (& ipc_tr , "payload size %u array %u: %#x" , hdr -> payload_words , hdr -> data_obj_array ,
251+ * ((uint32_t * )hdr ));
252+
253+ obj = (const struct ipc4_pipeline_ext_object * )(hdr + 1 );
254+ while (!last_object ) {
255+ const struct ipc4_pipeline_ext_object * next_obj ;
256+
257+ /* Check if there is space for the object header */
258+ if ((char * )(obj + 1 ) - data > size ) {
259+ tr_err (& ipc_tr , "obj header overflow, %u > %u" ,
260+ (char * )(obj + 1 ) - data , size );
261+ return - EINVAL ;
262+ }
263+
264+ /* Calculate would be next object position and check if current object fits */
265+ next_obj = (const struct ipc4_pipeline_ext_object * )
266+ (((uint32_t * )(obj + 1 )) + obj -> object_words );
267+ if ((char * )next_obj - data > size ) {
268+ tr_err (& ipc_tr , "object size overflow, %u > %u" ,
269+ (char * )obj - data , size );
270+ return - EINVAL ;
271+ }
272+
273+ switch (obj -> object_id ) {
274+ case IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA :
275+ {
276+ /* Get mem_data struct that follows the obj struct */
277+ const struct ipc4_pipeline_ext_obj_mem_data * mem_data =
278+ (const struct ipc4_pipeline_ext_obj_mem_data * )(obj + 1 );
279+
280+ if (obj -> object_words * sizeof (uint32_t ) < sizeof (* mem_data )) {
281+ tr_err (& ipc_tr , "mem_data object does not fit %u < %u" ,
282+ obj -> object_words * sizeof (uint32_t ), sizeof (* mem_data ));
283+ return - EINVAL ;
284+ }
285+ tr_info (& ipc_tr , "init_ext_obj_mem_data domain %u stack %u heap %u static %u" ,
286+ mem_data -> domain_id , mem_data -> stack_bytes , mem_data -> heap_bytes ,
287+ mem_data -> static_bytes );
288+ break ;
289+ }
290+ default :
291+ tr_info (& ipc_tr , "Unknown ext init object id %u of %u words" ,
292+ obj -> object_id , obj -> object_words );
293+ }
294+ /* Read the last object flag from obj header */
295+ last_object = obj -> last_object ;
296+ /* Move to next object */
297+ obj = next_obj ;
298+ }
299+
300+ return 0 ;
301+ }
302+
232303__cold static int ipc4_create_pipeline (struct ipc4_pipeline_create * pipe_desc )
233304{
234305 struct ipc_comp_dev * ipc_pipe ;
@@ -280,6 +351,23 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
280351 return IPC4_SUCCESS ;
281352}
282353
354+ #if CONFIG_LIBRARY
355+ static inline char * ipc4_get_pipe_create_data (void )
356+ {
357+ struct ipc * ipc = ipc_get ();
358+ char * data = (char * )ipc -> comp_data + sizeof (struct ipc4_pipeline_create );
359+
360+ return data ;
361+ }
362+ #else
363+ __cold static inline char * ipc4_get_pipe_create_data (void )
364+ {
365+ assert_can_be_cold ();
366+
367+ return (char * )MAILBOX_HOSTBOX_BASE ;
368+ }
369+ #endif
370+
283371/* Only called from ipc4_new_pipeline(), which is __cold */
284372__cold int ipc_pipeline_new (struct ipc * ipc , ipc_pipe_new * _pipe_desc )
285373{
@@ -293,6 +381,16 @@ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
293381 if (!cpu_is_me (pipe_desc -> extension .r .core_id ))
294382 return ipc4_process_on_core (pipe_desc -> extension .r .core_id , false);
295383
384+ if (pipe_desc -> extension .r .payload ) {
385+ char * data ;
386+
387+ dcache_invalidate_region ((__sparse_force void __sparse_cache * )MAILBOX_HOSTBOX_BASE ,
388+ MAILBOX_HOSTBOX_SIZE );
389+ data = ipc4_get_pipe_create_data ();
390+
391+ ipc4_create_pipeline_payload_decode (data );
392+ }
393+
296394 return ipc4_create_pipeline (pipe_desc );
297395}
298396
0 commit comments