component: add set of helper functions for large config configuration

This commit rewrites functions responsible for large config configuration
from detect_test component and puts them in component.c file as
generic ones - as a result they can be used by other components.

Signed-off-by: Bartosz Kokoszko <bartoszx.kokoszko@linux.intel.com>
This commit is contained in:
Bartosz Kokoszko 2020-05-04 15:49:29 +02:00 committed by Marcin Maka
parent 4f1090d083
commit a2d1e1efdc
6 changed files with 214 additions and 1 deletions

View File

@ -5,6 +5,7 @@ add_subdirectory(arch)
add_subdirectory(ipc)
add_subdirectory(audio)
add_subdirectory(lib)
add_subdirectory(math)
add_local_sources(sof spinlock.c)
if(CONFIG_LIBRARY)
@ -14,7 +15,6 @@ endif()
add_subdirectory(debug)
add_subdirectory(drivers)
add_subdirectory(init)
add_subdirectory(math)
add_subdirectory(schedule)
if (CONFIG_TRACE)

View File

@ -326,6 +326,158 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag,
return 0;
}
void comp_free_model_data(struct comp_dev *dev, struct comp_model_data *model)
{
if (!model->data)
return;
rfree(model->data);
model->data = NULL;
model->data_size = 0;
model->crc = 0;
model->data_pos = 0;
}
int comp_alloc_model_data(struct comp_dev *dev, struct comp_model_data *model,
uint32_t size)
{
if (!size)
return 0;
comp_free_model_data(dev, model);
model->data = rballoc(0, SOF_MEM_CAPS_RAM, size);
if (!model->data) {
comp_err(dev, "comp_alloc_model_data(): model->data rballoc failed");
return -ENOMEM;
}
bzero(model->data, size);
model->data_size = size;
model->data_pos = 0;
model->crc = 0;
return 0;
}
int comp_set_model(struct comp_dev *dev, struct comp_model_data *model,
struct sof_ipc_ctrl_data *cdata)
{
bool done = false;
int ret = 0;
comp_dbg(dev, "comp_set_model() msg_index = %d, num_elems = %d, remaining = %d ",
cdata->msg_index, cdata->num_elems,
cdata->elems_remaining);
/* in case when the current package is the first, we should allocate
* memory for whole model data
*/
if (!cdata->msg_index) {
ret = comp_alloc_model_data(dev, model, cdata->data->size);
if (ret < 0)
return ret;
}
/* return an error in case when we do not have allocated memory for
* model data
*/
if (!model->data) {
comp_err(dev, "comp_set_model(): buffer not allocated");
return -ENOMEM;
}
if (!cdata->elems_remaining) {
/* when we receive the last package and do not fill the whole
* allocated buffer, we return an error
*/
if (cdata->num_elems + model->data_pos < model->data_size) {
comp_err(dev, "comp_set_model(): not enough data to fill the buffer");
// TODO: handle this situation
return -EINVAL;
}
/* the whole data were received properly */
done = true;
comp_dbg(dev, "comp_set_model(): final package received");
}
/* return an error in case when received data exceed allocated
* memory
*/
if (cdata->num_elems > model->data_size - model->data_pos) {
comp_err(dev, "comp_set_model(): too much data");
return -EINVAL;
}
ret = memcpy_s((char *)model->data + model->data_pos,
model->data_size - model->data_pos,
cdata->data->data, cdata->num_elems);
assert(!ret);
/* update data_pos variable with received number of elements (num_elem)
*/
model->data_pos += cdata->num_elems;
/* Update crc value when done */
if (done) {
model->crc = crc32(0, model->data, model->data_size);
comp_dbg(dev, "comp_set_model() done, memory_size = 0x%x, crc = 0x%08x",
model->data_size, model->crc);
}
return 0;
}
int comp_get_model(struct comp_dev *dev, struct comp_model_data *model,
struct sof_ipc_ctrl_data *cdata, int size)
{
size_t bs;
int ret = 0;
comp_dbg(dev, "comp_get_model() msg_index = %d, num_elems = %d, remaining = %d ",
cdata->msg_index, cdata->num_elems,
cdata->elems_remaining);
/* Copy back to user space */
if (model->data) {
/* reset data_pos variable in case of copying first element */
if (!cdata->msg_index) {
model->data_pos = 0;
comp_dbg(dev, "comp_get_model() model data_size = 0x%x",
model->data_size);
}
bs = cdata->num_elems;
/* return an error in case of mismatch between num_elems and
* required size
*/
if (bs > size) {
comp_err(dev, "comp_get_model(): invalid size %d", bs);
return -EINVAL;
}
/* copy required size of data */
ret = memcpy_s(cdata->data->data, size,
(char *)model->data + model->data_pos,
bs);
assert(!ret);
cdata->data->abi = SOF_ABI_VERSION;
cdata->data->size = model->data_size;
model->data_pos += bs;
} else {
comp_err(dev, "comp_get_model(): !model->data");
ret = -EINVAL;
}
return ret;
}
struct comp_dev *comp_make_shared(struct comp_dev *dev)
{
struct list_item *old_bsource_list = &dev->bsource_list;

View File

@ -472,6 +472,16 @@ struct comp_copy_limits {
int sink_frame_bytes;
};
/** \brief Struct for large component configs */
struct comp_model_data {
uint32_t data_size; /**< size of component's model data */
void *data; /**< pointer to model data */
uint32_t crc; /**< crc value of model data */
uint32_t data_pos; /**< indicates a data position in data
* sending/receiving process
*/
};
/** \brief Computes size of the component device including ipc config. */
#define COMP_SIZE(x) \
(sizeof(struct comp_dev) - sizeof(struct sof_ipc_comp) + sizeof(x))
@ -725,6 +735,45 @@ void comp_get_copy_limits_with_lock(struct comp_buffer *source,
buffer_unlock(source, source_flags);
}
/**
* Frees data for large component configurations.
*
* @param dev Component device
* @param model Component model struct
*/
void comp_free_model_data(struct comp_dev *dev, struct comp_model_data *model);
/**
* Allocates data for large component configurations.
*
* @param dev Component device
* @param model Component model struct
* @param size Required size.
*/
int comp_alloc_model_data(struct comp_dev *dev, struct comp_model_data *model,
uint32_t size);
/**
* Gets model data for large component configurations.
*
* @param dev Component device
* @param model Component model struct
* @param cdata IPC ctrl data
*/
int comp_set_model(struct comp_dev *dev, struct comp_model_data *model,
struct sof_ipc_ctrl_data *cdata);
/**
*
* Set model data for large component configurations.
*
* @param dev Component device
* @param model Component model struct
* @param cdata IPC ctrl data
* @param size Required size
*/
int comp_get_model(struct comp_dev *dev, struct comp_model_data *model,
struct sof_ipc_ctrl_data *cdata, int size);
/**
* Called by component in params() function in order to set and update some of
* downstream (playback) or upstream (capture) buffer parameters with pcm

View File

@ -1,3 +1,9 @@
# SPDX-License-Identifier: BSD-3-Clause
add_local_sources(sof numbers.c trig.c decibels.c)
if(BUILD_LIBRARY)
return()
endif()
add_local_sources(sof trig.c decibels.c)

View File

@ -38,6 +38,11 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, int32_t bytes)
{
}
uint32_t crc32(uint32_t base, const void *data, uint32_t bytes)
{
return 0;
}
struct sof *sof_get(void)
{
return &sof;

View File

@ -12,6 +12,7 @@
#include <stdio.h>
#include <sof/sof.h>
#include <sof/audio/component_ext.h>
#include <sof/math/numbers.h>
#include <sof/audio/format.h>
#define DEBUG_MSG_LEN 256