Add remote get_attribute for cross core connection

To support pipelines connection between cores, ipc4_create_buffer()
must be able to create buffer shared between source and sink
components created on different cores. ipc4_create_buffer() requires
source component obs size. When both source and sink components
created on same core, ipc4_create_buffer() is executed on that core,
otherwise it is executed of core 0 (IPC processing core). So for the
case when source and sink components are created on different cores
comp_get_attribute_remote() is used to receive source obs size.

Signed-off-by: Serhiy Katsyuba <serhiy.katsyuba@intel.com>
This commit is contained in:
Serhiy Katsyuba 2023-07-14 17:52:19 +02:00 committed by Liam Girdwood
parent a63a877dbe
commit 071ba084a6
4 changed files with 68 additions and 1 deletions

View File

@ -158,7 +158,23 @@ static int idc_ipc4_unbind(uint32_t comp_id)
return comp_unbind(ipc_dev->cd, bu);
}
#endif
static int idc_get_attribute(uint32_t comp_id)
{
struct ipc_comp_dev *ipc_dev;
struct idc_payload *idc_payload;
struct get_attribute_remote_payload *get_attr_payload;
ipc_dev = ipc_get_comp_by_id(ipc_get(), comp_id);
if (!ipc_dev)
return -ENODEV;
idc_payload = idc_payload_get(*idc_get(), cpu_get_id());
get_attr_payload = (struct get_attribute_remote_payload *)idc_payload;
return comp_get_attribute(ipc_dev->cd, get_attr_payload->type, get_attr_payload->value);
}
#endif /* CONFIG_IPC_MAJOR_4 */
/**
* \brief Executes IDC component params message.
@ -368,6 +384,9 @@ void idc_cmd(struct idc_msg *msg)
case iTS(IDC_MSG_UNBIND):
ret = idc_ipc4_unbind(msg->extension);
break;
case iTS(IDC_MSG_GET_ATTRIBUTE):
ret = idc_get_attribute(msg->extension);
break;
#endif
case iTS(IDC_MSG_PARAMS):
ret = idc_params(msg->extension);

View File

@ -208,15 +208,61 @@ static inline int comp_prepare(struct comp_dev *dev)
int comp_copy(struct comp_dev *dev);
#if CONFIG_IPC_MAJOR_4
struct get_attribute_remote_payload {
uint32_t type;
void *value;
};
static inline int comp_ipc4_get_attribute_remote(struct comp_dev *dev, uint32_t type,
void *value)
{
struct ipc4_base_module_cfg *base_cfg;
struct get_attribute_remote_payload payload = {};
struct idc_msg msg = { IDC_MSG_GET_ATTRIBUTE,
IDC_EXTENSION(dev->ipc_config.id), dev->ipc_config.core,
sizeof(payload), &payload};
int ret;
/* Only COMP_ATTR_BASE_CONFIG is supported for remote access */
if (type != COMP_ATTR_BASE_CONFIG)
return -EINVAL;
base_cfg = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*base_cfg));
if (!base_cfg)
return -ENOMEM;
payload.type = type;
payload.value = base_cfg;
ret = idc_send_msg(&msg, IDC_BLOCKING);
if (ret == 0)
memcpy_s(value, sizeof(struct ipc4_base_module_cfg),
base_cfg, sizeof(struct ipc4_base_module_cfg));
rfree(base_cfg);
return ret;
}
#endif /* CONFIG_IPC_MAJOR_4 */
/** See comp_ops::get_attribute */
static inline int comp_get_attribute(struct comp_dev *dev, uint32_t type,
void *value)
{
#if CONFIG_IPC_MAJOR_4
if (dev->drv->ops.get_attribute)
return cpu_is_me(dev->ipc_config.core) ?
dev->drv->ops.get_attribute(dev, type, value) :
comp_ipc4_get_attribute_remote(dev, type, value);
return 0;
#else
if (dev->drv->ops.get_attribute)
return dev->drv->ops.get_attribute(dev, type, value);
return 0;
#endif
}
/** See comp_ops::set_attribute */

View File

@ -103,6 +103,7 @@
#define IDC_MSG_BIND IDC_TYPE(0xD)
#define IDC_MSG_UNBIND IDC_TYPE(0xE)
#define IDC_MSG_GET_ATTRIBUTE IDC_TYPE(0xF)
#define IDC_HEADER_TO_AMS_SLOT_MASK(x) (x & 0xFFFF)

View File

@ -104,6 +104,7 @@
#define IDC_MSG_BIND IDC_TYPE(0xD)
#define IDC_MSG_UNBIND IDC_TYPE(0xE)
#define IDC_MSG_GET_ATTRIBUTE IDC_TYPE(0xF)
/** \brief IDC_MSG_SECONDARY_CORE_CRASHED header fields. */
#define IDC_SCC_CORE_SHIFT 0