dsp: Support FIFO output in DMA

This commit is contained in:
Jannik Vogel 2018-12-28 08:22:25 +01:00 committed by mborgerson
parent 2e660193a0
commit e7bd7bf228
5 changed files with 44 additions and 13 deletions

View File

@ -56,7 +56,9 @@ struct DSPState {
static uint32_t read_peripheral(dsp_core_t* core, uint32_t address);
static void write_peripheral(dsp_core_t* core, uint32_t address, uint32_t value);
DSPState* dsp_init(void* scratch_rw_opaque, dsp_scratch_rw_func scratch_rw)
DSPState *dsp_init(void *rw_opaque,
dsp_scratch_rw_func scratch_rw,
dsp_fifo_rw_func fifo_rw)
{
DPRINTF("dsp_init\n");
@ -67,8 +69,9 @@ DSPState* dsp_init(void* scratch_rw_opaque, dsp_scratch_rw_func scratch_rw)
dsp->core.write_peripheral = write_peripheral;
dsp->dma.core = &dsp->core;
dsp->dma.scratch_rw_opaque = scratch_rw_opaque;
dsp->dma.rw_opaque = rw_opaque;
dsp->dma.scratch_rw = scratch_rw;
dsp->dma.fifo_rw = fifo_rw;
dsp_reset(dsp);
@ -176,7 +179,7 @@ void dsp_run(DSPState* dsp, int cycles)
void dsp_bootstrap(DSPState* dsp)
{
// scratch memory is dma'd in to pram by the bootrom
dsp->dma.scratch_rw(dsp->dma.scratch_rw_opaque,
dsp->dma.scratch_rw(dsp->dma.rw_opaque,
(uint8_t*)dsp->core.pram, 0, 0x800*4, false);
}

View File

@ -32,10 +32,14 @@
typedef struct DSPState DSPState;
typedef void (*dsp_scratch_rw_func)(
void* opaque, uint8_t* ptr, uint32_t addr, size_t len, bool dir);
void *opaque, uint8_t *ptr, uint32_t addr, size_t len, bool dir);
typedef void (*dsp_fifo_rw_func)(
void *opaque, uint8_t *ptr, unsigned int index, size_t len, bool dir);
/* Dsp commands */
DSPState* dsp_init(void* scratch_rw_opaque, dsp_scratch_rw_func scratch_rw);
DSPState *dsp_init(void *rw_opaque,
dsp_scratch_rw_func scratch_rw,
dsp_fifo_rw_func fifo_rw);
void dsp_destroy(DSPState* dsp);
void dsp_reset(DSPState* dsp);

View File

@ -221,6 +221,7 @@ static void dsp_dma_run(DSPDMAState *s)
scratch_size);
size_t transfer_size = count * item_size;
uint8_t* scratch_buf = calloc(count, item_size);
if (direction) {
@ -241,13 +242,35 @@ static void dsp_dma_run(DSPDMAState *s)
}
}
// write to scratch memory
s->scratch_rw(s->scratch_rw_opaque,
scratch_buf, scratch_addr, count*item_size, 1);
/* FIXME: Move to function; then reuse for both directions */
switch (buf_id) {
case 0x0:
case 0x1:
case 0x2:
case 0x3: {
unsigned int fifo_index = buf_id;
s->fifo_rw(s->rw_opaque,
scratch_buf, fifo_index, transfer_size, 1);
break;
}
case 0xE:
case 0xF:
s->scratch_rw(s->rw_opaque,
scratch_buf, scratch_addr, transfer_size, 1);
break;
default:
fprintf(stderr, "Unknown DSP DMA buffer: 0x%x\n", buf_id);
assert(false);
break;
}
} else {
/* FIXME: Support FIFOs */
assert(buf_id == 0xE || buf_id == 0xF);
// read from scratch memory
s->scratch_rw(s->scratch_rw_opaque,
scratch_buf, scratch_addr, count*item_size, 0);
s->scratch_rw(s->rw_opaque,
scratch_buf, scratch_addr, transfer_size, 0);
int i;
for (i=0; i<count; i++) {

View File

@ -36,8 +36,9 @@ typedef enum DSPDMARegister {
typedef struct DSPDMAState {
dsp_core_t* core;
void* scratch_rw_opaque;
void *rw_opaque;
dsp_scratch_rw_func scratch_rw;
dsp_fifo_rw_func fifo_rw;
uint32_t configuration;
uint32_t control;

View File

@ -873,8 +873,8 @@ static void mcpx_apu_realize(PCIDevice *dev, Error **errp)
d->se.frame_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, se_frame, d);
d->gp.dsp = dsp_init(d, gp_scratch_rw);
d->ep.dsp = dsp_init(d, ep_scratch_rw);
d->gp.dsp = dsp_init(d, gp_scratch_rw, gp_fifo_rw);
d->ep.dsp = dsp_init(d, ep_scratch_rw, ep_fifo_rw);
}
static void mcpx_apu_class_init(ObjectClass *klass, void *data)