From 36c4ad743a6c26c5095d5f0748419f7b5e97a7c3 Mon Sep 17 00:00:00 2001 From: Manikantan R Date: Tue, 7 Jul 2026 16:48:30 +0530 Subject: [PATCH 1/2] spf : add HPCM module API definitions Add the HPCM public API header with module configuration, shared buffer setup, mode reporting, and host buffer done event definitions. Include the new header in the SPF source list so the API is packaged with the exported module interfaces Signed-off-by: Manikantan R --- spf/Makefile.am | 1 + spf/api/modules/hpcm_api.h | 460 +++++++++++++++++++++++++++++++++++++ 2 files changed, 461 insertions(+) create mode 100644 spf/api/modules/hpcm_api.h diff --git a/spf/Makefile.am b/spf/Makefile.am index 5b51abf..b776cfc 100644 --- a/spf/Makefile.am +++ b/spf/Makefile.am @@ -75,6 +75,7 @@ spf_sources = ./api/apm/apm_api.h \ ./api/modules/gate_api.h \ ./api/modules/hw_core_api.h \ ./api/modules/hw_intf_cmn_api.h \ + ./api/modules/hpcm_api.h \ ./api/modules/i2s_api.h \ ./api/modules/imcl_fwk_intent_api.h \ ./api/modules/imcl_spm_intent_api.h \ diff --git a/spf/api/modules/hpcm_api.h b/spf/api/modules/hpcm_api.h new file mode 100644 index 0000000..2a25a80 --- /dev/null +++ b/spf/api/modules/hpcm_api.h @@ -0,0 +1,460 @@ +#ifndef HPCM_API_H +#define HPCM_API_H + +/** + * \file hpcm_api.h + * \brief + * This file contains APIs supported by HPCM module + * + * \copyright + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** @h2xml_title1 {HPCM Module} + @h2xml_title_agile_rev {HPCM Module} + @h2xml_title_date {June 23, 2021} +*/ + +/*============================================================================== + Include Files +==============================================================================*/ + +#include "ar_defs.h" +#include "module_cmn_api.h" + +/*========================================================================== + Macros +========================================================================== */ + +/* Max number of input ports of HPCM module */ +#define HPCM_MAX_IN_PORTS 0x1 + +/* Max number of output ports of HPCM module */ +#define HPCM_MAX_OUT_PORTS 0x1 + +/* Stack size of HPCM module */ +#define HPCM_STACK_SIZE_IN_BYTES 2048 + +#define HPCM_NONE_MODE 0x0 + +/* Indicates read mode of the module. + HPCM delivers the data to client if configured in this mode. */ +#define HPCM_READ_MODE 0x1 + +/* Indicates write mode of the module. + Client injects data if HPCM is configured in this mode. +*/ +#define HPCM_WRITE_MODE 0x2 + +/* Indicates the mode where module is configured for both + read and write. + First, client reads the data from module + and then injects the data. +*/ +#define HPCM_READ_WRITE_MODE 0x3 + +/* Bit to be set in mask of EVENT_ID_HPCM_HOST_BUF_DONE to indicate the + info regd number of buffers to be used by client*/ +#define HPCM_NUM_BUF_BIT ( 1 << 2 ) + +/* Bit to set in mask of EVENT_ID_HPCM_HOST_BUF_DONE, + to indicate the error occured during read processing */ +#define HPCM_READ_ERROR_BIT ( 1 << 3 ) + +/* Bit to set in mask of EVENT_ID_HPCM_HOST_BUF_DONE, + to indicate the error occured during write processing */ +#define HPCM_WRITE_ERROR_BIT (1 << 4 ) + +/* Native frame size. If frame size is set to this + value by client, it indicates that client's frame size + can be same as container's frame size*/ +#define HPCM_FRAME_SIZE_NATIVE 0x0 + +/* Frame size of 10ms */ +#define HPCM_FRAME_SIZE_10_MS (10) + +/* Frame size of 20ms */ +#define HPCM_FRAME_SIZE_20_MS (20) + +/*============================================================================== + Param HPCM Config +==============================================================================*/ +#define PARAM_ID_HPCM_CONFIG 0x08001378 + +/** @h2xmlp_parameter {"PARAM_ID_HPCM_CONFIG", PARAM_ID_HPCM_CONFIG} + @h2xmlp_description {Parameter used to enable module and send HPCM configuration.} + @h2xmlp_toolPolicy {Calibration} +*/ + +typedef struct param_id_hpcm_config_t param_id_hpcm_config_t; + + +#include "spf_begin_pack.h" +struct param_id_hpcm_config_t +{ + uint32_t enable; +/**< @h2xmle_description {Specifies whether the module needs to be enabled or disabled.} + @h2xmle_default {0x0} + @h2xmle_rangeList {"Disable"= 0; + "Enable"=1} + @h2xmle_policy {Basic}*/ + + uint16_t mode; +/**< @h2xmle_description {Specifies the operating mode of this module. + Valid only when enable flag is set.} + @h2xmle_default {0x0} + @h2xmle_rangeList {"HPCM_NONE_MODE" = HPCM_NONE_MODE; + "HPCM_READ_MODE"= HPCM_READ_MODE; + "HPCM_WRITE_MODE"= HPCM_WRITE_MODE; + "HPCM_READ_WRITE_MODE"= HPCM_READ_WRITE_MODE} + @h2xmle_policy {Basic}*/ + + uint16_t num_channels; +/**< @h2xmle_description {Number of channels associated with read/write buffer. + Valid only when enable flag is set.} + @h2xmle_default {1} + @h2xmle_rangeList {"1"=1} + @h2xmle_policy {Basic}*/ + + uint32_t sampling_rate; +/**< @h2xmle_description {Sampling rate of the data written by client(in Hz). + Valid only when enable flag is set.} + @h2xmle_default {0x1f40} + @h2xmle_rangeList {"8000" = 8000; + "16000"= 16000; + "32000"= 32000; + "48000"= 48000; + "96000"= 96000} + @h2xmle_policy {Basic}*/ + + uint32_t duration_ms; +/**< @h2xmle_description {Frame size of buffer(in milliseconds). + Size of 0 indicates that client will receive + buffer of size equal to container frame size. + Frame size of 10ms is valid only for Tx module. + + This field is valid only when enable flag is set.} + @h2xmle_default {0x0} + @h2xmle_rangeList {"HPCM_FRAME_SIZE_NATIVE" = 0; + "HPCM_FRAME_SIZE_10_MS" = 10; + "HPCM_FRAME_SIZE_20_MS" = 20} + @h2xmle_policy {Basic}*/ + + uint32_t reserved; +/**< @h2xmle_description {Reserved field for alignment. Must be set to 0.} + @h2xmle_default {0x0} + @h2xmle_readOnly {true}*/ +} +#include "spf_end_pack.h" +; + + +/*============================================================================== + Param HPCM Buffer Config +==============================================================================*/ +#define PARAM_ID_HPCM_DATA_BUF_CFG 0x08001379 + +typedef struct param_id_hpcm_data_buf_cfg_t param_id_hpcm_data_buf_cfg_t; + +/** + @h2xmlp_parameter {"PARAM_ID_HPCM_DATA_BUF_CFG", PARAM_ID_HPCM_DATA_BUF_CFG} + @h2xmlp_description {Parameter sent by the client indicating that read/write + buffers are available for the module to use.} + @h2xmlp_toolPolicy {Calibration} +*/ +#include "spf_begin_pack.h" +struct param_id_hpcm_data_buf_cfg_t +{ + uint32_t mask; +/**< @h2xmle_description {Indicates which(read/write) buffers are available} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} + + @h2xmle_bitfield {0x00000001} + @h2xmle_bitName {Bit_0_READ_BUF} + @h2xmle_description {Availability of read buffer} + @h2xmle_bitfieldEnd + + @h2xmle_bitfield {0x00000002} + @h2xmle_bitName {Bit_1_WRITE_BUF} + @h2xmle_description {Availability of write buffer} + @h2xmle_bitfieldEnd + + @h2xmle_bitfield {0xFFFFFFFC} + @h2xmle_bitName {Bit_31_2_Reserved} + @h2xmle_description {Reserved Bit[31:2]} + @h2xmle_visibility {hide} + @h2xmle_bitfieldEnd +*/ + + uint32_t rd_mem_map_handle; + /**< @h2xmle_description {Memory map handle of the shared memory + corresponding to read buffers. + Valid only when read mode is enabled.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t wr_mem_map_handle; + /**< @h2xmle_description {Memory map handle of the shared memory + corresponding to read buffers. + Valid only when write mode is enabled.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t rd_buff_addr_lsw; +/**< @h2xmle_description {Lower 32 bits of shared memory address of read buffer + to be filled with data from module. + Address is valid if mask field indicates that read + buffer is available.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t rd_buff_addr_msw; +/**< @h2xmle_description {Upper 32 bits of shared memory address of read buffer + to be filled with data from module. + Address is valid if mask field indicates that read + buffer is available. + The 64-bit number formed by rd_buff_addr_lsw and + rd_buff_addr_msw must be 32-byte aligned and must + have been previously mapped} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t wr_buff_addr_lsw; +/**< @h2xmle_description {Lower 32 bits of the shared memory of the write buffer + that contains the data to inject at the module. + Address is valid if mask field indicates that write + buffer is available.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t wr_buff_addr_msw; +/**< @h2xmle_description {Upper 32 bits of the shared memory of the write buffer + that contains the data to inject at the module. + Address is valid if mask field indicates that write + buffer is available. + The 64-bit number formed by wr_buff_addr_lsw and + wr_buff_addr_msw must be 32-byte aligned and must + have been previously mapped} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t rd_buff_size; +/**< @h2xmle_description {Maximum size(in bytes) of the read buffer to be filled. + This value is valid if the mask field indicates + that the read buffer is to be filled.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t wr_buff_size; +/**< @h2xmle_description {Size(in bytes) of the write buffer to be consumed. + This value is valid if the mask field indicates + that the write buffer is to be consumed.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + +} +#include "spf_end_pack.h" +; + +/*============================================================================== + HPCM mode Event +==============================================================================*/ +#define EVENT_ID_HPCM_MODE_INFO 0x08001A96 +typedef struct event_id_hpcm_mode_t event_id_hpcm_mode_t; +#include "spf_begin_pack.h" +struct event_id_hpcm_mode_t +{ + uint32_t hpcm_staggered_mode; +/**< @h2xmle_description {hpcm staggered mode} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0x0000001} + @h2xmle_policy {Basic} +*/ +} +#include "spf_end_pack.h" +; +/*============================================================================== + Buf Done Event +==============================================================================*/ +#define EVENT_ID_HPCM_HOST_BUF_DONE 0x0800137A +typedef struct event_id_hpcm_host_buf_done_t event_id_hpcm_host_buf_done_t; + +/** + @h2xmlp_parameter {"EVENT_ID_HPCM_HOST_BUF_DONE", EVENT_ID_HPCM_HOST_BUF_DONE} + @h2xmlp_description {Event raised by the module indicating that module has finished + processing the buffer pushed previously using PARAM_ID_HPCM_DATA_BUF_CFG + and buffer can be reclaimed by client.} + @h2xmlp_ToolPolicy {NO_SUPPORT} +*/ +#include "spf_begin_pack.h" +struct event_id_hpcm_host_buf_done_t +{ + uint32_t mask; +/**< @h2xmle_description {Notifies about which buffer is filled/consumed} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} + + @h2xmle_bitfield {0x00000001} + @h2xmle_bitName {Bit_0_READ_BUF} + @h2xmle_description {When set to 1, indicates that read buffer is filled.} + @h2xmle_bitfieldEnd + + @h2xmle_bitfield {0x00000002} + @h2xmle_bitName {Bit_1_WRITE_BUF} + @h2xmle_description {When set to 1, indicates that write buffer is consumed.} + @h2xmle_bitfieldEnd + + @h2xmle_bitfield {0x00000004} + @h2xmle_bitName {Bit_2_NUM_BUF} + @h2xmle_description {Indicates that buffer size and duration are provided} + @h2xmle_bitfieldEnd + + @h2xmle_bitfield {0x00000008} + @h2xmle_bitName {Bit_3_READ_ERROR} + @h2xmle_description {Indicates the error if occured during read processing} + @h2xmle_bitfieldEnd + + @h2xmle_bitfield {0x00000010} + @h2xmle_bitName {Bit_4_WRITE_ERROR} + @h2xmle_description {Indicates the error if occured during write processing} + @h2xmle_bitfieldEnd + + @h2xmle_bitfield {0xFFFFFFE0} + @h2xmle_bitName {Bit_31_5_Reserved} + @h2xmle_description {Reserved Bit[31:5]} + @h2xmle_visibility {hide} + @h2xmle_bitfieldEnd +*/ + + uint32_t rd_buff_addr_lsw; +/**< @h2xmle_description {Lower 32 bits of shared memory address of read buffer + that has been filled with data from module. + Address is valid if mask field indicates that read + buffer is filled.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t rd_buff_addr_msw; +/**< @h2xmle_description {Upper 32 bits of shared memory address of read buffer + that has been filled with data from module. + Address is valid if mask field indicates that read + buffer is filled. + This shared memory buffer is same as the one that was + provided by client using PARAM_ID_HPCM_HOST_BUF_CFG.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t wr_buff_addr_lsw; +/**< @h2xmle_description {Lower 32 bits of the shared memory of the consumed write buffer. + Address is valid if mask field indicates that write + buffer is consumed.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t wr_buff_addr_msw; +/**< @h2xmle_description {Upper 32 bits of the shared memory of the consumed write buffer. + Address is valid if mask field indicates that write + buffer is consumed. + This shared memory buffer is same as the one that was + provided by client using PARAM_ID_HPCM_HOST_BUF_CFG.}} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t rd_buff_size; +/**< @h2xmle_description {Size of read buffer filled by module. + This value is valid if the mask field indicates + that the read buffer is filled.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t wr_buff_size; +/**< @h2xmle_description {Requested size of the next buffer to be pushed. + This value is valid if the mask field indicates + that the write buffer is consumed.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ + + uint32_t num_buffers; +/**< @h2xmle_description {Number of buffers required from client. + Client needs to allocate buffer of max size + before sending PARAM_ID_HPCM_CONFIG. On receiving + num_buffers value, it needs to partition the + buffers and send PARAM_ID_HPCM_DATA_BUF_CFG accordingly.} + @h2xmle_default {0x00000000} + @h2xmle_range {0x00000000..0xFFFFFFFF} + @h2xmle_policy {Basic} +*/ +} +#include "spf_end_pack.h" +; + +/*============================================================================== + Module ID and Module Supported Info +==============================================================================*/ +#define MODULE_ID_HPCM 0x070010DD +/** + @h2xmlm_module {"MODULE_ID_HPCM", MODULE_ID_HPCM} + @h2xmlm_displayName {"HPCM"} + @h2xmlm_description { Host PCM module enables client to read/write the PCM data \n + in the Voice Tx/Rx path.\n + - This module supports the following parameter IDs:\n + - #PARAM_ID_HPCM_CONFIG\n + - #PARAM_ID_HPCM_DATA_BUF_CFG\n + - #EVENT_ID_HPCM_HOST_BUF_DONE\n + - Supported Input Media Format: \n + - Data Format : FIXED \n + - fmt_id : Don't care \n + - Sample Rates : 8000, 16000, 32000, 48000, 96000\n + - Number of channels : 1 \n + - Channel type : Don't care \n + - Bits per sample : 16 \n + - Q format : Q15 \n + - Interleaving : de-interleaved unpacked \n + - Signed/unsigned : Signed \n} + @h2xmlm_dataMaxInputPorts {HPCM_MAX_IN_PORTS} + @h2xmlm_dataMaxOutputPorts {HPCM_MAX_OUT_PORTS} + @h2xmlm_supportedContTypes {APM_CONTAINER_TYPE_GC, APM_CONTAINER_TYPE_SC} + @h2xmlm_isOffloadable {false} + @h2xmlm_stackSize {HPCM_STACK_SIZE_IN_BYTES} + @h2xmlm_toolPolicy { Calibration } + + @{ <-- Start of the Module --> + @h2xml_Select {"param_id_hpcm_config_t"} + @h2xmlp_description {Parameter used to enable module and send HPCM configuration.} + @h2xmlm_InsertParameter + + @} <-- End of the Module --> **/ +#endif // HPCM_API_H + From 606722529a429556c579274cf910fed1aafc2d3b Mon Sep 17 00:00:00 2001 From: Manikantan R Date: Tue, 7 Jul 2026 16:56:47 +0530 Subject: [PATCH 2/2] gsl: add HPCM buffer handling support Routes HPCM read and write buffers through the HPCM data buffer configuration command when the cached module id identifies an HPCM module. Module id with datapath MIID data is cached so normal shared-memory paths continue for other modules. HPCM host buffer done events are handled inside GSL by mapping returned physical addresses to internal buffers, marking them available, signaling waiters, and issuing client callbacks for blocking, non-blocking, and shmem modes. Signed-off-by: Manikantan R --- gsl/inc/gsl_datapath.h | 15 +++ gsl/src/gsl_datapath.c | 235 +++++++++++++++++++++++++++++++++++++++-- gsl/src/gsl_graph.c | 16 ++- 3 files changed, 255 insertions(+), 11 deletions(-) diff --git a/gsl/inc/gsl_datapath.h b/gsl/inc/gsl_datapath.h index 0f92573..7b2b659 100644 --- a/gsl/inc/gsl_datapath.h +++ b/gsl/inc/gsl_datapath.h @@ -20,6 +20,7 @@ #include "gsl_intf.h" #include "gsl_common.h" #include "gsl_msg_builder.h" +#include "hpcm_api.h" #ifdef __cplusplus extern "C" { @@ -164,6 +165,8 @@ struct gsl_data_path_info { uint32_t master_proc_id; bool_t is_shmem_supported; + + uint32_t module_id; }; /** @@ -355,6 +358,18 @@ int32_t gsl_wait_for_all_buffs_to_be_avail(struct gsl_data_path_info *dp_info); int32_t gsl_dp_queue_read_buffers_to_spf(struct gsl_data_path_info *dp_info); +/** + * \brief handles hpcm buff handling on read/write datapath + * + * \param[in] datapath: pointer to datapath + * \param[in] cb: client callback registered with GSL + * \param[in] client_data: pointer to payload for client callback + * \param[in] payload: hpcm payload + * + */ +void gsl_handle_hpcm_buff_done(struct gsl_data_path_info *datapath, + gsl_cb_func_ptr cb, void *client_data, void *payload); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/gsl/src/gsl_datapath.c b/gsl/src/gsl_datapath.c index 8d55867..10c0117 100644 --- a/gsl/src/gsl_datapath.c +++ b/gsl/src/gsl_datapath.c @@ -522,6 +522,73 @@ static struct gsl_metadata_buff_internal *gsl_dequeue_internal_md_buff( return gsl_md_buff; } +static int32_t gsl_hpcm_data_buf_cfg(struct gsl_data_path_info *dp_info, + struct gsl_buff_internal *buff, uintptr_t offset, + uint32_t size, uint32_t buff_idx, uint32_t flags, uint64_t timestamp) +{ + int32_t rc = AR_EOK; + struct apm_cmd_header_t *apm_hdr = NULL; + struct apm_module_param_data_t *param_hdr = NULL; + struct param_id_hpcm_data_buf_cfg_t *buf_cfg_cmd = NULL; + uint8_t *spf_cmd; + uint32_t spf_cmd_sz = 0; + struct gpr_packet_t *send_pkt; + uint64_t tmp; + + spf_cmd_sz = GSL_ALIGN_8BYTE(sizeof(*apm_hdr) + sizeof(*param_hdr) + + sizeof(*buf_cfg_cmd)); + + rc = gsl_allocate_gpr_packet(APM_CMD_SET_CFG, dp_info->src_port, + dp_info->miid, spf_cmd_sz, buff_idx, dp_info->master_proc_id, &send_pkt); + + if (rc) { + GSL_ERR("Failed to allocate GPR packet %d", rc); + goto exit; + } + + spf_cmd = GPR_PKT_GET_PAYLOAD(uint8_t, send_pkt); + gsl_memset(spf_cmd, 0, spf_cmd_sz); + + apm_hdr = (struct apm_cmd_header_t *)spf_cmd; + param_hdr = (struct apm_module_param_data_t *) + (spf_cmd + sizeof(*apm_hdr)); + buf_cfg_cmd = (struct param_id_hpcm_data_buf_cfg_t *)(spf_cmd + + sizeof(*apm_hdr) + sizeof(*param_hdr)); + + apm_hdr->payload_size = spf_cmd_sz - sizeof(*apm_hdr); + param_hdr->module_instance_id = dp_info->miid; + param_hdr->param_id = PARAM_ID_HPCM_DATA_BUF_CFG; + param_hdr->param_size = sizeof(*buf_cfg_cmd); + + tmp = buff->gsl_msg.shmem.spf_addr + offset; + + GSL_VERBOSE("buff_idx %d flags %d tmp 0x%llX", buff_idx, flags, tmp); + if (flags == GSL_DATA_DIR_WRITE) { + buf_cfg_cmd->mask = GSL_DATA_DIR_WRITE + 1; + buf_cfg_cmd->wr_buff_addr_lsw = (uint32_t)tmp; + buf_cfg_cmd->wr_buff_addr_msw = (uint32_t)(tmp >> 32); + buf_cfg_cmd->wr_buff_size = size; + buf_cfg_cmd->wr_mem_map_handle = buff->gsl_msg.shmem.spf_mmap_handle; + } else if (flags == GSL_DATA_DIR_READ) { + buf_cfg_cmd->mask = GSL_DATA_DIR_READ + 1; + buf_cfg_cmd->rd_buff_addr_lsw = (uint32_t)tmp; + buf_cfg_cmd->rd_buff_addr_msw = (uint32_t)(tmp >> 32); + buf_cfg_cmd->rd_buff_size = size; + buf_cfg_cmd->rd_mem_map_handle = buff->gsl_msg.shmem.spf_mmap_handle; + } + + GSL_VERBOSE("Send HPCM Command to Spf dir %d p_addr 0x%llX, size %u", + flags, tmp, size); + + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&send_pkt, + &dp_info->dp_signal); + if (rc) + GSL_ERR("HPCM Command failed with %d", rc); + +exit: + return rc; +} + /* * update the spf returned metadata status and size to tail entry in the * internal metadata buff list @@ -1483,9 +1550,14 @@ static int32_t gsl_dp_write_heap(struct gsl_data_path_info *dp_info, goto exit; } } - - rc = gsl_dp_write_shmem(dp_info, internal_buf, internal_md_buf, 0, - buf_idx, write_buff_size, buff); + if (dp_info->module_id == MODULE_ID_HPCM){ + GSL_INFO("HOSTPC Data Write usecase"); + rc = gsl_hpcm_data_buf_cfg(dp_info, internal_buf, 0, write_buff_size, + buf_idx, GSL_DATA_DIR_WRITE, buff->timestamp); + } else { + rc = gsl_dp_write_shmem(dp_info, internal_buf, internal_md_buf, 0, + buf_idx, write_buff_size, buff); + } if (rc != AR_EOK) { GSL_VERBOSE("gsl_dp_write_shmem fail rc=%d", rc); goto exit; @@ -1680,10 +1752,15 @@ static int32_t gsl_dp_read_heap(struct gsl_data_path_info *dp_info, internal_md_buf->size = buff->metadata_size; } } - - /* queue the shmem buffer back to spf */ - rc = gsl_dp_read_shmem(dp_info, internal_buf, internal_md_buf, 0, - dp_info->config.buff_size, buf_idx); + if (dp_info->module_id == MODULE_ID_HPCM){ + GSL_INFO("HPCM Read Buff Usecase"); + rc = gsl_hpcm_data_buf_cfg(dp_info, internal_buf, 0, read_buff_size, + buf_idx, GSL_DATA_DIR_READ, 0); + } else { + /* queue the shmem buffer back to spf */ + rc = gsl_dp_read_shmem(dp_info, internal_buf, internal_md_buf, 0, + dp_info->config.buff_size, buf_idx); + } if (rc != AR_EOK) goto exit; } @@ -2517,12 +2594,150 @@ int32_t gsl_dp_queue_read_buffers_to_spf(struct gsl_data_path_info *dp_info) dp_info->config.max_metadata_size; } } - - gsl_dp_read_shmem(dp_info, internal_buff, - internal_md_buf, 0, dp_info->config.buff_size, i); + if (dp_info->module_id == MODULE_ID_HPCM) { + GSL_VERBOSE("Queuing Initial Read buffers for HPCM"); + gsl_hpcm_data_buf_cfg(dp_info, internal_buff, 0, dp_info->config.buff_size, + i, GSL_DATA_DIR_READ, 0); + } else { + gsl_dp_read_shmem(dp_info, internal_buff, + internal_md_buf, 0, dp_info->config.buff_size, i); + } } } } return rc; } + +static uint32_t gsl_hpcm_get_buff_idx(uint32_t buff_addr_lsw, uint32_t buff_addr_msw, + struct gsl_buff_internal * buff_list, uint32_t num_buff) +{ + uint32_t buff_idx = 0; + for (buff_idx = 0; buff_idx < num_buff; buff_idx++) { + if ((buff_addr_msw == (uint32_t)(buff_list[buff_idx].gsl_msg.shmem.spf_addr >> 32)) && + (buff_addr_lsw == (uint32_t)(buff_list[buff_idx].gsl_msg.shmem.spf_addr) )) { + break; + } + } + return buff_idx; +} + +void gsl_handle_hpcm_buff_done(struct gsl_data_path_info *datapath, + gsl_cb_func_ptr cb, void *client_data, void *payload) +{ + struct event_id_hpcm_host_buf_done_t *buf_done = (struct event_id_hpcm_host_buf_done_t *)payload; + struct gsl_data_path_info *dp_info = NULL; + uint32_t data_mode, buff_idx = 0, pa_msw = 0, pa_lsw = 0, status = 0; + struct gsl_buff_internal *gsl_buff = NULL; + /* used to pass to client in callback */ + struct gsl_event_read_write_done_payload rw_done_payload; + uint64_t pa, offset; + struct gsl_event_cb_params ev; + + GSL_VERBOSE("HPCM Buf Done: mask %d num_buffers %d", buf_done->mask, buf_done->num_buffers); + if (buf_done->mask & (GSL_DATA_DIR_READ+1)) { + buff_idx = gsl_hpcm_get_buff_idx(buf_done->rd_buff_addr_lsw, + buf_done->rd_buff_addr_msw, + &datapath->buff_list[0], + datapath->config.num_buffs); + + if (buff_idx == datapath->config.num_buffs) { + GSL_ERR("HPCM: read buffer address not found in buff_list"); + goto exit; + } + + /* read case */ + dp_info = datapath; + gsl_buff = &dp_info->buff_list[buff_idx]; + ev.event_id = GSL_EVENT_ID_READ_DONE; + status = buf_done->mask & (1 << 3); + pa_msw = buf_done->rd_buff_addr_msw; + pa_lsw = buf_done->rd_buff_addr_lsw; + gsl_buff->size_from_spf = buf_done->rd_buff_size; + gsl_buff->spf_timestamp = 0; + gsl_buff->spf_flags = 0; + + /* below needed to pass data back to client in shmem mode */ + rw_done_payload.tag = dp_info->cached_tag; + rw_done_payload.buff.flags = 0; + rw_done_payload.buff.timestamp = 0; + GSL_VERBOSE("HPCM Read_Done buf idx %d, size_from_spf %d", + buff_idx, gsl_buff->size_from_spf); + GSL_VERBOSE("rd_lsw 0x%lX rd_msw 0x%lX rd_size %d ", + buf_done->rd_buff_addr_lsw, + buf_done->rd_buff_addr_msw, + buf_done->rd_buff_size); + } else if (buf_done->mask & (GSL_DATA_DIR_WRITE+1)) { + buff_idx = gsl_hpcm_get_buff_idx(buf_done->wr_buff_addr_lsw, + buf_done->wr_buff_addr_msw, + &datapath->buff_list[0], + datapath->config.num_buffs); + + if (buff_idx == datapath->config.num_buffs) { + GSL_ERR("HPCM: write buffer address not found in buff_list"); + goto exit; + } + + /* write case */ + dp_info = datapath; + gsl_buff = &dp_info->buff_list[buff_idx]; + ev.event_id = GSL_EVENT_ID_WRITE_DONE; + status = buf_done->mask & (1 << 4); + pa_msw = buf_done->wr_buff_addr_msw; + pa_lsw = buf_done->wr_buff_addr_lsw; + rw_done_payload.tag = dp_info->cached_tag; + gsl_buff->size_from_spf = 0; + GSL_VERBOSE("HPCM Write_Done buf idx %d size_from_spf %u", + buff_idx, buf_done->wr_buff_size); + GSL_VERBOSE("wr_lsw 0x%lX wr_msw 0x%lX wr_size %d ", + buf_done->wr_buff_addr_lsw, + buf_done->wr_buff_addr_msw, + buf_done->wr_buff_size); + if (buf_done->wr_buff_size == 0) + goto exit; + } else { + if (buf_done->mask & (4)) { + GSL_ERR("SPF_HOST_PCM_TIMETICK num_buffers %d ", buf_done->num_buffers); + } + goto exit; + } + + data_mode = dp_info->config.attributes & GSL_ATTRIBUTES_DATA_MODE_MASK; + + if (data_mode == GSL_DATA_MODE_BLOCKING) { + gsl_mark_buffer_as_avail(dp_info, buff_idx); + gsl_signal_set(&dp_info->dp_signal, + GSL_SIG_EVENT_MASK_SPF_RSP, status, NULL); + } else if (data_mode == GSL_DATA_MODE_NON_BLOCKING) { + gsl_mark_buffer_as_avail(dp_info, buff_idx); + ev.event_payload = NULL; + ev.event_payload_size = 0; + ev.source_module_id = GSL_EVENT_SRC_MODULE_ID_GSL; + if (cb) + cb(&ev, client_data); + + /* + * below signal set is needed during close as gsl_graph_close waits for + * all buffers to come back from Spf + */ + gsl_signal_set(&dp_info->dp_signal, + GSL_SIG_EVENT_MASK_SPF_RSP, status, NULL); + + } else if ((data_mode == GSL_DATA_MODE_SHMEM) && gsl_buff) { + pa = GSL_TO_64_BIT(pa_msw, pa_lsw); + offset = pa - gsl_buff->gsl_msg.shmem.spf_addr; + rw_done_payload.buff.addr = (uint8_t *)(gsl_buff->gsl_msg.shmem.v_addr) + + offset; + rw_done_payload.buff.size = gsl_buff->size_from_spf; + + /* issue the callback to client */ + /* note client must copy in cb context */ + ev.event_payload = &rw_done_payload; + ev.event_payload_size = sizeof(struct gsl_event_read_write_done_payload); + ev.source_module_id = GSL_EVENT_SRC_MODULE_ID_GSL; + if (cb) + cb(&ev, client_data); + } +exit: + return; +} diff --git a/gsl/src/gsl_graph.c b/gsl/src/gsl_graph.c index 7b795a4..2935db9 100644 --- a/gsl/src/gsl_graph.c +++ b/gsl/src/gsl_graph.c @@ -361,7 +361,20 @@ static uint32_t gsl_gpr_callback(gpr_packet_t *packet, void *cb_data) ev.source_module_id = packet->src_port; ev.event_payload = (void *)((int8_t *)module_ev + sizeof(struct apm_module_event_t)); - graph->cb(&ev, graph->client_data); + if (EVENT_ID_HPCM_HOST_BUF_DONE == module_ev->event_id){ + GSL_DBG("EVENT_ID_HPCM_HOST_BUF_DONE event received \n"); + struct gsl_data_path_info *dp_info = NULL; + struct event_id_hpcm_host_buf_done_t *buf_done = + (struct event_id_hpcm_host_buf_done_t *)ev.event_payload; + if (buf_done->mask & (GSL_DATA_DIR_READ+1)) { + dp_info = &graph->read_info; + } else if (buf_done->mask & (GSL_DATA_DIR_WRITE+1)) { + dp_info = &graph->write_info; + } + gsl_handle_hpcm_buff_done(dp_info, graph->cb, graph->client_data, ev.event_payload); + } else { + graph->cb(&ev, graph->client_data); + } gpr_rc = __gpr_cmd_free(packet); break; default: @@ -4014,6 +4027,7 @@ static int32_t gsl_graph_cache_datapath_miid(struct gsl_graph *graph, dp_info->cached_tag = tag; dp_info->master_proc_id = proc_module_info->proc_module_list->proc_domain_id; + dp_info->module_id = proc_module_info->proc_module_list->module_entry[0].module_id; free_module_info: gsl_mem_free(proc_module_info->proc_module_list);