From e7bd7bf2282d4a9e75e67165cad8d9982f654154 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Fri, 28 Dec 2018 08:22:25 +0100 Subject: [PATCH] dsp: Support FIFO output in DMA --- hw/xbox/dsp/dsp.c | 9 ++++++--- hw/xbox/dsp/dsp.h | 8 ++++++-- hw/xbox/dsp/dsp_dma.c | 33 ++++++++++++++++++++++++++++----- hw/xbox/dsp/dsp_dma.h | 3 ++- hw/xbox/mcpx_apu.c | 4 ++-- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/hw/xbox/dsp/dsp.c b/hw/xbox/dsp/dsp.c index bf9b6dbe28..ce576ecd78 100644 --- a/hw/xbox/dsp/dsp.c +++ b/hw/xbox/dsp/dsp.c @@ -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); } diff --git a/hw/xbox/dsp/dsp.h b/hw/xbox/dsp/dsp.h index b862c5a8df..0b18fa0c45 100644 --- a/hw/xbox/dsp/dsp.h +++ b/hw/xbox/dsp/dsp.h @@ -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); diff --git a/hw/xbox/dsp/dsp_dma.c b/hw/xbox/dsp/dsp_dma.c index 1ce35be980..0b43f3bef1 100644 --- a/hw/xbox/dsp/dsp_dma.c +++ b/hw/xbox/dsp/dsp_dma.c @@ -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; ise.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)