diff --git a/ar_osal/Makefile.am b/ar_osal/Makefile.am index 02de8e8..1542ff0 100644 --- a/ar_osal/Makefile.am +++ b/ar_osal/Makefile.am @@ -66,6 +66,10 @@ if LIBDIAG_HEADERS AM_CFLAGS += -DUSE_LIBDIAG_HEADERS endif +if MDSP_PROC +AM_CFLAGS += -DMDSP_PROC +endif + if ARGS_USE_SYSLOG AM_CFLAGS += -DAR_OSAL_USE_SYSLOG endif diff --git a/ar_osal/api/ar_osal_shmem.h b/ar_osal/api/ar_osal_shmem.h index b3198d2..e0390f7 100644 --- a/ar_osal/api/ar_osal_shmem.h +++ b/ar_osal/api/ar_osal_shmem.h @@ -283,6 +283,30 @@ int32_t ar_shmem_hyp_assign_phys(ar_shmem_hyp_assign_phys_info *info); */ int32_t ar_shmem_get_uid(uint64_t alloc_handle, uint64_t *uid); +/** + * \brief End CPU access for a DMA-BUF-backed shared memory buffer. + * + * The dma-buf exporter may perform CPU cache maintenance before device access. + * + * \param[in] info: pointer to ar_shmem_info returned by ar_shmem_alloc(). + * \return + * 0 -- Success + * Nonzero -- Failure + */ +int32_t ar_shmem_sync_for_device(ar_shmem_info *info); + +/** + * \brief Start CPU access for a DMA-BUF-backed shared memory buffer. + * + * The dma-buf exporter may perform CPU cache maintenance before CPU reads or writes. + * + * \param[in] info: pointer to ar_shmem_info returned by ar_shmem_alloc(). + * \return + * 0 -- Success + * Nonzero -- Failure + */ +int32_t ar_shmem_sync_for_cpu(ar_shmem_info *info); + /** * \brief ar_shmem_deinit. * @@ -297,4 +321,3 @@ int32_t ar_shmem_deinit(void); #endif /*__cplusplus*/ #endif /* #ifndef AR_OSAL_SHMEM_H */ - diff --git a/ar_osal/src/linux/qcom/ar_osal_shmem.c b/ar_osal/src/linux/qcom/ar_osal_shmem.c index 9bcc27b..95f3535 100644 --- a/ar_osal/src/linux/qcom/ar_osal_shmem.c +++ b/ar_osal/src/linux/qcom/ar_osal_shmem.c @@ -70,6 +70,16 @@ int32_t ar_shmem_get_uid(uint64_t alloc_handle, uint64_t *uid) return AR_EUNSUPPORTED; } +int32_t ar_shmem_sync_for_device(ar_shmem_info *info) +{ + return are_on_apps ? AR_EOK : ar_shmem_dsp_sync_for_device(info); +} + +int32_t ar_shmem_sync_for_cpu(ar_shmem_info *info) +{ + return are_on_apps ? AR_EOK : ar_shmem_dsp_sync_for_cpu(info); +} + int32_t ar_shmem_deinit(void) { int32_t rc = are_on_apps ? ar_shmem_ap_deinit() : ar_shmem_dsp_deinit(); diff --git a/ar_osal/src/linux/qcom/ar_osal_shmem_db.c b/ar_osal/src/linux/qcom/ar_osal_shmem_db.c index 2ce5325..8f23cc6 100644 --- a/ar_osal/src/linux/qcom/ar_osal_shmem_db.c +++ b/ar_osal/src/linux/qcom/ar_osal_shmem_db.c @@ -80,6 +80,72 @@ static ar_shmem_pdata_t *pdata = NULL; static pthread_mutex_t ar_shmem_lock = PTHREAD_MUTEX_INITIALIZER; +static int32_t ar_shmem_dsp_sync_dma_buf(ar_shmem_info *info, + uint64_t sync_flags, bool cpu_access) +{ + int32_t status = AR_EOK; + ar_shmem_handle_data_t *shmem_handle = NULL; + struct dma_buf_sync sync; + + memset(&sync, 0, sizeof(sync)); + + pthread_mutex_lock(&ar_shmem_lock); + + if (pdata == NULL) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, "%s:not in init state\n", __func__); + status = AR_EBADPARAM; + goto end; + } + + if (info == NULL || info->metadata == 0) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, + "%s:invalid info %pK metadata 0x%llx\n", + __func__, info, info ? (unsigned long long)info->metadata : 0); + status = AR_EBADPARAM; + goto end; + } + + shmem_handle = (ar_shmem_handle_data_t *)(intptr_t)info->metadata; + if (shmem_handle == NULL || shmem_handle->heap_fd < 0) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, + "%s:invalid shmem handle %pK fd %d\n", + __func__, shmem_handle, shmem_handle ? shmem_handle->heap_fd : -1); + status = AR_EBADPARAM; + goto end; + } + + if (shmem_handle->dma_sync_flag == cpu_access) + goto end; + + sync.flags = sync_flags; + status = ioctl(shmem_handle->heap_fd, DMA_BUF_IOCTL_SYNC, &sync); + if (status) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, + "%s: DMA heap sync failed, errno: %d status:%d\n", + __func__, errno, status); + status = AR_EUNEXPECTED; + goto end; + } + + shmem_handle->dma_sync_flag = cpu_access; + +end: + pthread_mutex_unlock(&ar_shmem_lock); + return status; +} + +int32_t ar_shmem_dsp_sync_for_device(ar_shmem_info *info) +{ + return ar_shmem_dsp_sync_dma_buf(info, + DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW, false); +} + +int32_t ar_shmem_dsp_sync_for_cpu(ar_shmem_info *info) +{ + return ar_shmem_dsp_sync_dma_buf(info, + DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW, true); +} + /** * \brief ar_shmem_validate_sys_id * internal function to validate supported SYS IDs. diff --git a/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h b/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h index b9a40f2..b8acacb 100644 --- a/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h +++ b/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h @@ -22,4 +22,6 @@ int32_t ar_shmem_dsp_free(ar_shmem_info *info); int32_t ar_shmem_dsp_map(ar_shmem_info *info); int32_t ar_shmem_dsp_unmap(ar_shmem_info *info); int32_t ar_shmem_dsp_hyp_assign_phys(ar_shmem_hyp_assign_phys_info *info); +int32_t ar_shmem_dsp_sync_for_device(ar_shmem_info *info); +int32_t ar_shmem_dsp_sync_for_cpu(ar_shmem_info *info); int32_t ar_shmem_dsp_deinit(void); diff --git a/configure.ac b/configure.ac index 3814ba7..04950bf 100644 --- a/configure.ac +++ b/configure.ac @@ -97,6 +97,12 @@ AC_ARG_WITH([audio_dma_support], [with_audio_dma_support=no]) AM_CONDITIONAL([AUDIO_DMA_SUPPORT], [test "x${with_audio_dma_support}" = "xyes"]) +AC_ARG_WITH([mdsp-proc], + AS_HELP_STRING([--with-mdsp-proc],[Enable MDSP processor support (default is no)]), + [with_mdsp_proc=$withval], + [with_mdsp_proc=no]) +AM_CONDITIONAL([MDSP_PROC], [test "x${with_mdsp_proc}" = "xyes"]) + AC_ARG_WITH([libdiag_headers], AS_HELP_STRING([--with-libdiag_headers],[use libdiag headers only (default is no)]), [with_libdiag_headers=$withval], diff --git a/gsl/Makefile.am b/gsl/Makefile.am index d4dd1a9..53752a1 100644 --- a/gsl/Makefile.am +++ b/gsl/Makefile.am @@ -65,6 +65,10 @@ libar_gsl_la_SOURCES = $(gsl_c_sources) libar_gsl_la_CFLAGS = $(AM_CFLAGS) libar_gsl_la_LDFLAGS = -shared -version-number @LT_VERSION_NUMBER@ +if MDSP_PROC +libar_gsl_la_CFLAGS += -DMDSP_PROC +endif + if USES_ATS_DATA_LOGGING libar_gsl_la_CFLAGS += -DATS_DATA_LOGGING libar_gsl_la_CPPFLAGS = -DATS_DATA_LOGGING diff --git a/gsl/inc/gsl_shmem_mgr.h b/gsl/inc/gsl_shmem_mgr.h index a44410a..2da3972 100644 --- a/gsl/inc/gsl_shmem_mgr.h +++ b/gsl/inc/gsl_shmem_mgr.h @@ -90,6 +90,10 @@ int32_t gsl_shmem_map_dynamic_pd(struct gsl_shmem_alloc_data *alloc_data, uint32_t flags, uint32_t ss_mask, uint32_t master_proc_id); int32_t gsl_shmem_unmap_dynamic_pd(struct gsl_shmem_alloc_data *alloc_data, uint32_t ss_mask, uint32_t master_proc_id); +int32_t gsl_shmem_sync_for_device( + const struct gsl_shmem_alloc_data *alloc_data); +int32_t gsl_shmem_sync_for_cpu( + const struct gsl_shmem_alloc_data *alloc_data); void gsl_shmem_cache_pending_memmap_packets(uint32_t master_proc_id, void *gpr_packet); uint32_t gsl_shmem_check_and_unmap_cache_pending_packets(uint32_t master_proc_id); diff --git a/gsl/src/gsl_graph.c b/gsl/src/gsl_graph.c index 7b795a4..0172f72 100644 --- a/gsl/src/gsl_graph.c +++ b/gsl/src/gsl_graph.c @@ -26,6 +26,7 @@ #include "gsl_subgraph_pool.h" #include "gsl_common.h" #include "gsl_msg_builder.h" +#include "gsl_shmem_mgr.h" #include "gsl_spf_ss_state.h" #include "gsl_mdf_utils.h" @@ -43,6 +44,22 @@ struct gsl_blob { void *buf; /**< pointer to the blob */ }; +static int32_t gsl_msg_sync_oob_for_device(gsl_msg_t *msg) +{ + if (!msg || !msg->shmem.handle) + return AR_EOK; + + return gsl_shmem_sync_for_device(&msg->shmem); +} + +static int32_t gsl_msg_sync_oob_for_cpu(gsl_msg_t *msg) +{ + if (!msg || !msg->shmem.handle) + return AR_EOK; + + return gsl_shmem_sync_for_cpu(&msg->shmem); +} + /* Used to return tags and module info data sorted by processor id to client */ struct gsl_module_id_proc_info_entry { uint32_t proc_domain_id; // process the modules are running on @@ -544,6 +561,10 @@ static int32_t gsl_apm_config_oob(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG], &rsp_pkt); if (rc) { @@ -552,6 +573,10 @@ static int32_t gsl_apm_config_oob(struct gsl_graph *graph, } if (opcode == APM_CMD_GET_CFG) { + rc = gsl_msg_sync_oob_for_cpu(&gsl_msg); + if (rc) + goto free_msg; + get_cfg_rsp = GPR_PKT_GET_PAYLOAD(struct apm_cmd_rsp_get_cfg_t, rsp_pkt); /* @@ -881,6 +906,10 @@ static int32_t gsl_graph_send_nonpersist_cal(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, cmd_header->payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto exit; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG]); if (rc) @@ -2408,12 +2437,17 @@ static int32_t gsl_graph_close_sgids_and_connections(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, close_pld_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP3_CMD_SIG]); if (rc) GSL_ERR("Graph close failed:%d", rc); } +free_msg: gsl_msg_free(&gsl_msg); exit: @@ -3234,6 +3268,10 @@ static int32_t gsl_graph_open_sgids_and_connections(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*open_cmd), gsl_msg.payload, graph_open_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_gsl_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP1_CMD_SIG]); if (rc) { @@ -3793,6 +3831,10 @@ int32_t gsl_graph_set_config(struct gsl_graph *graph, GSL_LOG_PKT("send_pkt", graph->src_port, gsl_msg.gpr_packet, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, cmd_header->payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG]); if (rc) @@ -5352,11 +5394,16 @@ int32_t gsl_graph_change_set_config_helper(struct gsl_graph *graph, GSL_LOG_PKT("send_pkt", graph->src_port, gsl_msg.gpr_packet, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, cmd_header->payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG]); if (rc) GSL_ERR("Graph set config failed %d", rc); +free_msg: gsl_msg_free(&gsl_msg); exit: return rc; diff --git a/gsl/src/gsl_msg_builder.c b/gsl/src/gsl_msg_builder.c index 93811f5..7a5d688 100644 --- a/gsl/src/gsl_msg_builder.c +++ b/gsl/src/gsl_msg_builder.c @@ -104,6 +104,14 @@ int32_t gsl_msg_alloc_ext(uint32_t opcode, uint32_t src_port, oob_payload_size); goto exit; } + rc = gsl_shmem_sync_for_cpu(&msg->shmem); + if (rc) { + __gpr_cmd_free(msg->gpr_packet); + gsl_shmem_free(&msg->shmem); + GSL_ERR("Failed to sync shared mem for cpu size %d rc %d", + oob_payload_size, rc); + goto exit; + } } msg->payload = msg->shmem.v_addr; } diff --git a/gsl/src/gsl_shmem_mgr.c b/gsl/src/gsl_shmem_mgr.c index 7ca3a04..e6ca159 100644 --- a/gsl/src/gsl_shmem_mgr.c +++ b/gsl/src/gsl_shmem_mgr.c @@ -1217,6 +1217,30 @@ int32_t gsl_shmem_alloc_ext(uint32_t size_bytes, uint32_t spf_ss_mask, return rc; } +int32_t gsl_shmem_sync_for_device( + const struct gsl_shmem_alloc_data *alloc_data) +{ + struct gsl_shmem_page *page; + + if (!alloc_data || !alloc_data->handle) + return AR_EBADPARAM; + + page = alloc_data->handle; + return ar_shmem_sync_for_device(&page->shmem_info); +} + +int32_t gsl_shmem_sync_for_cpu( + const struct gsl_shmem_alloc_data *alloc_data) +{ + struct gsl_shmem_page *page; + + if (!alloc_data || !alloc_data->handle) + return AR_EBADPARAM; + + page = alloc_data->handle; + return ar_shmem_sync_for_cpu(&page->shmem_info); +} + int32_t gsl_shmem_free(struct gsl_shmem_alloc_data *alloc_data) { struct gsl_shmem_page *page;