@@ -230,6 +230,101 @@ 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+ if (size > MAILBOX_HOSTBOX_SIZE ) {
263+ tr_err (& ipc_tr , "Payload size too large: %u : %#x" , hdr -> payload_words ,
264+ * ((uint32_t * )hdr ));
265+ }
266+ tr_info (& ipc_tr , "payload size %u array %u: %#x" , hdr -> payload_words , hdr -> data_obj_array ,
267+ * ((uint32_t * )hdr ));
268+
269+ #ifdef CONFIG_DCACHE_LINE_SIZE
270+ if (!IS_ENABLED (CONFIG_LIBRARY ) && ALIGN_UP (size , cache_line_size ) > hdr_cache_size )
271+ sys_cache_data_invd_range ((__sparse_force void __sparse_cache * )
272+ ((char * )data + hdr_cache_size ),
273+ ALIGN_UP (size , cache_line_size ) - hdr_cache_size );
274+ #endif
275+
276+ obj = (const struct ipc4_pipeline_ext_object * )(hdr + 1 );
277+ while (!last_object ) {
278+ const struct ipc4_pipeline_ext_object * next_obj ;
279+
280+ /* Check if there is space for the object header */
281+ if ((char * )(obj + 1 ) - data > size ) {
282+ tr_err (& ipc_tr , "obj header overflow, %u > %zu" ,
283+ (char * )(obj + 1 ) - data , size );
284+ return - EINVAL ;
285+ }
286+
287+ /* Calculate would be next object position and check if current object fits */
288+ next_obj = (const struct ipc4_pipeline_ext_object * )
289+ (((const uint32_t * )(obj + 1 )) + obj -> object_words );
290+ if ((char * )next_obj - data > size ) {
291+ tr_err (& ipc_tr , "object size overflow, %u > %zu" ,
292+ (char * )next_obj - data , size );
293+ return - EINVAL ;
294+ }
295+
296+ switch (obj -> object_id ) {
297+ case IPC4_GLB_PIPE_EXT_OBJ_ID_MEM_DATA :
298+ {
299+ /* Get mem_data struct that follows the obj struct */
300+ const struct ipc4_pipeline_ext_obj_mem_data * mem_data =
301+ (const struct ipc4_pipeline_ext_obj_mem_data * )(obj + 1 );
302+
303+ if (obj -> object_words * sizeof (uint32_t ) < sizeof (* mem_data )) {
304+ tr_err (& ipc_tr , "mem_data object does not fit %zu < %zu" ,
305+ obj -> object_words * sizeof (uint32_t ), sizeof (* mem_data ));
306+ break ;
307+ }
308+ tr_info (& ipc_tr ,
309+ "init_ext_obj_mem_data domain %u stack %u interim %u lifetime %u shared %u" ,
310+ mem_data -> domain_id , mem_data -> stack_bytes ,
311+ mem_data -> interim_heap_bytes , mem_data -> lifetime_heap_bytes ,
312+ mem_data -> shared_bytes );
313+ break ;
314+ }
315+ default :
316+ tr_warn (& ipc_tr , "Unknown ext init object id %u of %u words" ,
317+ obj -> object_id , obj -> object_words );
318+ }
319+ /* Read the last object flag from obj header */
320+ last_object = obj -> last_object ;
321+ /* Move to next object */
322+ obj = next_obj ;
323+ }
324+
325+ return 0 ;
326+ }
327+
233328__cold static int ipc4_create_pipeline (struct ipc4_pipeline_create * pipe_desc )
234329{
235330 struct ipc_comp_dev * ipc_pipe ;
@@ -281,6 +376,23 @@ __cold static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
281376 return IPC4_SUCCESS ;
282377}
283378
379+ #if CONFIG_LIBRARY
380+ static inline char * ipc4_get_pipe_create_data (void )
381+ {
382+ struct ipc * ipc = ipc_get ();
383+ char * data = (char * )ipc -> comp_data + sizeof (struct ipc4_pipeline_create );
384+
385+ return data ;
386+ }
387+ #else
388+ __cold static inline char * ipc4_get_pipe_create_data (void )
389+ {
390+ assert_can_be_cold ();
391+
392+ return (char * )MAILBOX_HOSTBOX_BASE ;
393+ }
394+ #endif
395+
284396/* Only called from ipc4_new_pipeline(), which is __cold */
285397__cold int ipc_pipeline_new (struct ipc * ipc , ipc_pipe_new * _pipe_desc )
286398{
@@ -294,6 +406,14 @@ __cold int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
294406 if (!cpu_is_me (pipe_desc -> extension .r .core_id ))
295407 return ipc4_process_on_core (pipe_desc -> extension .r .core_id , false);
296408
409+ if (pipe_desc -> extension .r .payload ) {
410+ char * data ;
411+
412+ data = ipc4_get_pipe_create_data ();
413+
414+ ipc4_create_pipeline_payload_decode (data );
415+ }
416+
297417 return ipc4_create_pipeline (pipe_desc );
298418}
299419
0 commit comments