@@ -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