@@ -229,6 +229,79 @@ 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 ,
286+ "init_ext_obj_mem_data domain %u stack %u interim %u lifetime %u shared %u" ,
287+ mem_data -> domain_id , mem_data -> stack_bytes ,
288+ mem_data -> interim_heap_bytes , mem_data -> lifetime_heap_bytes ,
289+ mem_data -> shared_bytes );
290+ break ;
291+ }
292+ default :
293+ tr_info (& ipc_tr , "Unknown ext init object id %u of %u words" ,
294+ obj -> object_id , obj -> object_words );
295+ }
296+ /* Read the last object flag from obj header */
297+ last_object = obj -> last_object ;
298+ /* Move to next object */
299+ obj = next_obj ;
300+ }
301+
302+ return 0 ;
303+ }
304+
232305__cold static int ipc4_create_pipeline (struct ipc4_pipeline_create * pipe_desc )
233306{
234307 struct ipc_comp_dev * ipc_pipe ;
@@ -280,6 +353,23 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
280353 return IPC4_SUCCESS ;
281354}
282355
356+ #if CONFIG_LIBRARY
357+ static inline char * ipc4_get_pipe_create_data (void )
358+ {
359+ struct ipc * ipc = ipc_get ();
360+ char * data = (char * )ipc -> comp_data + sizeof (struct ipc4_pipeline_create );
361+
362+ return data ;
363+ }
364+ #else
365+ __cold static inline char * ipc4_get_pipe_create_data (void )
366+ {
367+ assert_can_be_cold ();
368+
369+ return (char * )MAILBOX_HOSTBOX_BASE ;
370+ }
371+ #endif
372+
283373/* Only called from ipc4_new_pipeline(), which is __cold */
284374__cold int ipc_pipeline_new (struct ipc * ipc , ipc_pipe_new * _pipe_desc )
285375{
@@ -293,6 +383,16 @@ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
293383 if (!cpu_is_me (pipe_desc -> extension .r .core_id ))
294384 return ipc4_process_on_core (pipe_desc -> extension .r .core_id , false);
295385
386+ if (pipe_desc -> extension .r .payload ) {
387+ char * data ;
388+
389+ dcache_invalidate_region ((__sparse_force void __sparse_cache * )MAILBOX_HOSTBOX_BASE ,
390+ MAILBOX_HOSTBOX_SIZE );
391+ data = ipc4_get_pipe_create_data ();
392+
393+ ipc4_create_pipeline_payload_decode (data );
394+ }
395+
296396 return ipc4_create_pipeline (pipe_desc );
297397}
298398
0 commit comments