Skip to content

Commit

Permalink
audio: host-zephyr: Allocate DMA block configuration on heap
Browse files Browse the repository at this point in the history
Currently, the DMA block configuration (struct dma_block_config)
is placed on the stack during host_common_params(). Later on,
host_copy_one_shot() tries to re-configure the DMAC driver
using the same block configuration that's located in a stack
frame that's no longer valid. As such, allocate a DMA
block configuration on the heap during host_common_params()
which can be used later on (e.g: during host_copy_one_shot())
to reconfigure the DMAC.

Signed-off-by: Laurentiu Mihalcea <[email protected]>
  • Loading branch information
LaurentiuM1234 authored and dbaluta committed Feb 20, 2024
1 parent 1233a22 commit 3681e09
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions src/audio/host-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
struct dma_sg_config *config = &hd->config;
struct dma_sg_elem *sg_elem;
struct dma_config *dma_cfg = &hd->z_config;
struct dma_block_config dma_block_cfg;
struct dma_block_config *dma_block_cfg;
uint32_t period_count;
uint32_t period_bytes;
uint32_t buffer_size;
Expand Down Expand Up @@ -890,12 +890,21 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
hd->chan->period = config->period;

memset(dma_cfg, 0, sizeof(*dma_cfg));
memset(&dma_block_cfg, 0, sizeof(dma_block_cfg));

dma_block_cfg = rzalloc(SOF_MEM_ZONE_RUNTIME, 0,
SOF_MEM_CAPS_RAM,
sizeof(*dma_block_cfg));

if (!dma_block_cfg) {
comp_err(dev, "host_common_params: dma_block_config allocation failed");
err = -ENOMEM;
goto err_release_channel;
}

dma_cfg->block_count = 1;
dma_cfg->source_data_size = config->src_width;
dma_cfg->dest_data_size = config->dest_width;
dma_cfg->head_block = &dma_block_cfg;
dma_cfg->head_block = dma_block_cfg;

for (i = 0; i < config->elem_array.count; i++) {
sg_elem = config->elem_array.elems + i;
Expand All @@ -912,33 +921,31 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
buffer_addr = addr;
}

dma_block_cfg.block_size = buffer_bytes;
dma_block_cfg->block_size = buffer_bytes;

switch (config->direction) {
case DMA_DIR_LMEM_TO_HMEM:
dma_cfg->channel_direction = MEMORY_TO_HOST;
dma_block_cfg.source_address = buffer_addr;
dma_block_cfg->source_address = buffer_addr;
break;
case DMA_DIR_HMEM_TO_LMEM:
dma_cfg->channel_direction = HOST_TO_MEMORY;
dma_block_cfg.dest_address = buffer_addr;
dma_block_cfg->dest_address = buffer_addr;
break;
}

err = dma_config(hd->chan->dma->z_dev, hd->chan->index, dma_cfg);
if (err < 0) {
comp_err(dev, "host_params(): dma_config() failed");
dma_release_channel(hd->dma->z_dev, hd->chan->index);
hd->chan = NULL;
return err;
goto err_free_block_cfg;
}

err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_COPY_ALIGNMENT,
&hd->dma_copy_align);

if (err < 0) {
comp_err(dev, "host_params(): dma_get_attribute()");
return err;
goto err_free_block_cfg;
}

/* minimal copied data shouldn't be less than alignment */
Expand All @@ -952,6 +959,15 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
host_copy_normal;

return 0;

err_free_block_cfg:
dma_cfg->head_block = NULL;
rfree(dma_block_cfg);
err_release_channel:
dma_release_channel(hd->dma->z_dev, hd->chan->index);
hd->chan = NULL;

return err;
}

static int host_params(struct comp_dev *dev,
Expand Down Expand Up @@ -1024,6 +1040,10 @@ void host_common_reset(struct host_data *hd, uint16_t state)
hd->dma_buffer = NULL;
}

/* free DMA block configuration */
if (hd->z_config.head_block)
rfree(hd->z_config.head_block);

/* reset buffer pointers */
hd->local_pos = 0;
hd->report_pos = 0;
Expand Down

0 comments on commit 3681e09

Please sign in to comment.