@@ -424,8 +424,12 @@ __cold const struct ipc4_pipeline_set_state_data *ipc4_get_pipeline_data_wrapper
424424 return ipc4_get_pipeline_data ();
425425}
426426
427- /* Entry point for ipc4_pipeline_trigger(), therefore cannot be cold */
428- static int ipc4_set_pipeline_state (struct ipc4_message_request * ipc4 )
427+ /**
428+ * \brief Process SET_PIPELINE_STATE IPC4 message (prepare + trigger phases).
429+ * @param[in] ipc4 IPC4 message request.
430+ * @return 0 on success, IPC4 error code otherwise.
431+ */
432+ int ipc4_set_pipeline_state (struct ipc4_message_request * ipc4 )
429433{
430434 const struct ipc4_pipeline_set_state_data * ppl_data ;
431435 struct ipc4_pipeline_set_state state ;
@@ -809,7 +813,22 @@ __cold static int ipc4_unbind_module_instance(struct ipc4_message_request *ipc4)
809813 return ipc_comp_disconnect (ipc , (ipc_pipe_comp_connect * )& bu );
810814}
811815
812- static int ipc4_set_get_config_module_instance (struct ipc4_message_request * ipc4 , bool set )
816+ /**
817+ * @brief Process MOD_CONFIG_GET or MOD_CONFIG_SET in any execution context.
818+ *
819+ * Looks up the target component by module_id:instance_id, verifies the
820+ * driver supports get_attribute/set_attribute, and dispatches the
821+ * operation. For GET, the retrieved value is written to @p reply_ext.
822+ *
823+ * Callable from both the IPC kernel task and the IPC user thread.
824+ *
825+ * @param ipc4 Pointer to the IPC4 message request (primary + extension)
826+ * @param set true for CONFIG_SET, false for CONFIG_GET
827+ * @param reply_ext Output: receives the extension value for CONFIG_GET (may be NULL for SET)
828+ * @return IPC4 status code (0 on success)
829+ */
830+ __cold int ipc4_process_module_config (struct ipc4_message_request * ipc4 ,
831+ bool set , uint32_t * reply_ext )
813832{
814833 struct ipc4_module_config * config = (struct ipc4_module_config * )ipc4 ;
815834 int (* function )(struct comp_dev * dev , uint32_t type , void * value );
@@ -859,8 +878,21 @@ static int ipc4_set_get_config_module_instance(struct ipc4_message_request *ipc4
859878 ret = IPC4_INVALID_CONFIG_PARAM_ID ;
860879 }
861880
881+ if (!set && reply_ext )
882+ * reply_ext = config -> extension .dat ;
883+
884+ return ret ;
885+ }
886+
887+ static int ipc4_set_get_config_module_instance (struct ipc4_message_request * ipc4 , bool set )
888+ {
889+ uint32_t reply_ext ;
890+ int ret ;
891+
892+ ret = ipc4_process_module_config (ipc4 , set , & reply_ext );
893+
862894 if (!set )
863- msg_reply -> extension = config -> extension . dat ;
895+ msg_reply -> extension = reply_ext ;
864896
865897 return ret ;
866898}
@@ -990,6 +1022,108 @@ __cold static int ipc4_get_vendor_config_module_instance(struct comp_dev *dev,
9901022 return IPC4_SUCCESS ;
9911023}
9921024
1025+ __cold int ipc4_process_large_config_get (struct ipc4_message_request * ipc4 ,
1026+ uint32_t * reply_ext ,
1027+ uint32_t * reply_tx_size ,
1028+ void * * reply_tx_data )
1029+ {
1030+ struct ipc4_module_large_config_reply reply ;
1031+ struct ipc4_module_large_config config ;
1032+ char * data = ipc_get ()-> comp_data ;
1033+ const struct comp_driver * drv ;
1034+ struct comp_dev * dev = NULL ;
1035+ uint32_t data_offset ;
1036+
1037+ assert_can_be_cold ();
1038+
1039+ int ret = memcpy_s (& config , sizeof (config ), ipc4 , sizeof (* ipc4 ));
1040+
1041+ if (ret < 0 )
1042+ return IPC4_FAILURE ;
1043+
1044+ tr_dbg (& ipc_tr , "%x : %x" ,
1045+ (uint32_t )config .primary .r .module_id , (uint32_t )config .primary .r .instance_id );
1046+
1047+ /* get component dev for non-basefw since there is no
1048+ * component dev for basefw
1049+ */
1050+ if (config .primary .r .module_id ) {
1051+ uint32_t comp_id ;
1052+
1053+ comp_id = IPC4_COMP_ID (config .primary .r .module_id ,
1054+ config .primary .r .instance_id );
1055+ dev = ipc4_get_comp_dev (comp_id );
1056+ if (!dev )
1057+ return IPC4_MOD_INVALID_ID ;
1058+
1059+ drv = dev -> drv ;
1060+
1061+ /* Multicore disabled for userspace forwarding;
1062+ * non-userspace path retains ipc4_process_on_core()
1063+ */
1064+ } else {
1065+ drv = ipc4_get_comp_drv (config .primary .r .module_id );
1066+ }
1067+
1068+ if (!drv )
1069+ return IPC4_MOD_INVALID_ID ;
1070+
1071+ if (!drv -> ops .get_large_config )
1072+ return IPC4_INVALID_REQUEST ;
1073+
1074+ data_offset = config .extension .r .data_off_size ;
1075+
1076+ /* check for vendor param first */
1077+ if (config .extension .r .large_param_id == VENDOR_CONFIG_PARAM ) {
1078+ /* For now only vendor_config case uses payload from hostbox */
1079+ dcache_invalidate_region ((__sparse_force void __sparse_cache * )MAILBOX_HOSTBOX_BASE ,
1080+ config .extension .r .data_off_size );
1081+ ret = ipc4_get_vendor_config_module_instance (dev , drv ,
1082+ config .extension .r .init_block ,
1083+ config .extension .r .final_block ,
1084+ & data_offset ,
1085+ data ,
1086+ (const char * )MAILBOX_HOSTBOX_BASE );
1087+ } else {
1088+ #if CONFIG_LIBRARY
1089+ data += sizeof (reply );
1090+ #endif
1091+ ipc4_prepare_for_kcontrol_get (dev , config .extension .r .large_param_id ,
1092+ data , data_offset );
1093+
1094+ ret = drv -> ops .get_large_config (dev , config .extension .r .large_param_id ,
1095+ config .extension .r .init_block ,
1096+ config .extension .r .final_block ,
1097+ & data_offset , data );
1098+ }
1099+
1100+ /* set up ipc4 error code for reply data */
1101+ if (ret < 0 )
1102+ ret = IPC4_MOD_INVALID_ID ;
1103+
1104+ /* Copy host config and overwrite */
1105+ reply .extension .dat = config .extension .dat ;
1106+ reply .extension .r .data_off_size = data_offset ;
1107+
1108+ /* The last block, no more data */
1109+ if (!config .extension .r .final_block && data_offset < SOF_IPC_MSG_MAX_SIZE )
1110+ reply .extension .r .final_block = 1 ;
1111+
1112+ /* Indicate last block if error occurs */
1113+ if (ret )
1114+ reply .extension .r .final_block = 1 ;
1115+
1116+ /* no need to allocate memory for reply msg */
1117+ if (ret )
1118+ return ret ;
1119+
1120+ /* Output via parameters instead of msg_reply */
1121+ * reply_ext = reply .extension .dat ;
1122+ * reply_tx_size = data_offset ;
1123+ * reply_tx_data = data ;
1124+ return ret ;
1125+ }
1126+
9931127__cold static int ipc4_get_large_config_module_instance (struct ipc4_message_request * ipc4 )
9941128{
9951129 struct ipc4_module_large_config_reply reply ;
@@ -1182,6 +1316,77 @@ __cold static int ipc4_set_vendor_config_module_instance(struct comp_dev *dev,
11821316 data_off_size , data );
11831317}
11841318
1319+ __cold int ipc4_process_large_config_set (struct ipc4_message_request * ipc4 )
1320+ {
1321+ struct ipc4_module_large_config config ;
1322+ struct comp_dev * dev = NULL ;
1323+ const struct comp_driver * drv ;
1324+
1325+ assert_can_be_cold ();
1326+
1327+ int ret = memcpy_s (& config , sizeof (config ), ipc4 , sizeof (* ipc4 ));
1328+
1329+ if (ret < 0 )
1330+ return IPC4_FAILURE ;
1331+
1332+ dcache_invalidate_region ((__sparse_force void __sparse_cache * )MAILBOX_HOSTBOX_BASE ,
1333+ config .extension .r .data_off_size );
1334+ tr_dbg (& ipc_tr , "%x : %x" ,
1335+ (uint32_t )config .primary .r .module_id , (uint32_t )config .primary .r .instance_id );
1336+
1337+ if (config .primary .r .module_id ) {
1338+ uint32_t comp_id ;
1339+
1340+ comp_id = IPC4_COMP_ID (config .primary .r .module_id , config .primary .r .instance_id );
1341+ dev = ipc4_get_comp_dev (comp_id );
1342+ if (!dev )
1343+ return IPC4_MOD_INVALID_ID ;
1344+
1345+ drv = dev -> drv ;
1346+
1347+ /* Multicore disabled for userspace forwarding;
1348+ * non-userspace path retains ipc4_process_on_core()
1349+ */
1350+ } else {
1351+ drv = ipc4_get_comp_drv (config .primary .r .module_id );
1352+ }
1353+
1354+ if (!drv )
1355+ return IPC4_MOD_INVALID_ID ;
1356+
1357+ if (!drv -> ops .set_large_config )
1358+ return IPC4_INVALID_REQUEST ;
1359+
1360+ /* check for vendor param first */
1361+ if (config .extension .r .large_param_id == VENDOR_CONFIG_PARAM ) {
1362+ ret = ipc4_set_vendor_config_module_instance (dev , drv ,
1363+ (uint32_t )config .primary .r .module_id ,
1364+ (uint32_t )config .primary .r .instance_id ,
1365+ config .extension .r .init_block ,
1366+ config .extension .r .final_block ,
1367+ config .extension .r .data_off_size ,
1368+ (const char * )MAILBOX_HOSTBOX_BASE );
1369+ } else {
1370+ #if CONFIG_LIBRARY
1371+ struct ipc * ipc = ipc_get ();
1372+ const char * data = (const char * )ipc -> comp_data + sizeof (config );
1373+ #else
1374+ const char * data = (const char * )MAILBOX_HOSTBOX_BASE ;
1375+ #endif
1376+ ret = drv -> ops .set_large_config (dev , config .extension .r .large_param_id ,
1377+ config .extension .r .init_block , config .extension .r .final_block ,
1378+ config .extension .r .data_off_size , data );
1379+ if (ret < 0 ) {
1380+ ipc_cmd_err (& ipc_tr , "failed to set large_config_module_instance %x : %x" ,
1381+ (uint32_t )config .primary .r .module_id ,
1382+ (uint32_t )config .primary .r .instance_id );
1383+ ret = IPC4_INVALID_RESOURCE_ID ;
1384+ }
1385+ }
1386+
1387+ return ret ;
1388+ }
1389+
11851390__cold static int ipc4_set_large_config_module_instance (struct ipc4_message_request * ipc4 )
11861391{
11871392 struct ipc4_module_large_config config ;
0 commit comments