Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* the address of the sound ram from the SH4 side */
- #define G2_ARAM 0xa0800000
- #define G2_DMA_TO_DEVICE 0
- #define G2_DMA_FROM_DEVICE 1
- typedef struct {
- uint32 ext_addr; /* External address (SPU-RAM or parallel port) */
- uint32 sh4_addr; /* SH-4 Address */
- uint32 size; /* Size in bytes; all addresses and sizes must be 32-byte aligned */
- uint32 dir; /* 0: cpu->ext; 1: ext->cpu */
- uint32 mode; /* 5 for SPU transfer */
- uint32 ctrl1; /* b0 */
- uint32 ctrl2; /* b0 */
- uint32 stop; /* ?? */
- } g2_dma_ctrl_t;
- typedef struct {
- uint32 ext_addr;
- uint32 sh4_addr;
- uint32 size;
- uint32 status;
- } g2_dma_stat_t;
- typedef struct {
- g2_dma_ctrl_t dma[4];
- uint32 u1[4]; /* ?? */
- uint32 wait_state;
- uint32 u2[10]; /* ?? */
- uint32 magic;
- g2_dma_stat_t dma_stat[4];
- } g2_dma_reg_t;
- #define G2_REGS (*(volatile g2_dma_reg_t *)0xa05f7800)
- #define G2_FIFO (*(volatile int*)0xa05f688c)
- static inline void G2PauseDMA(int channel) {
- G2_REGS.dma[channel].stop = -1;
- }
- static inline void G2ResumeDMA(int channel) {
- G2_REGS.dma[channel].stop = 0;
- }
- static inline int G2DMAInProgress(int channel) {
- return G2_REGS.dma[channel].ctrl2 & 1;
- }
- static semaphore_t dma_done[4];
- static int dma_blocking[4];
- static g2_dma_callback_t dma_callback[4];
- static ptr_t dma_cbdata[4];
- static void G2DMAIRQHandler(uint32 code) {
- int chn = code - ASIC_EVT_G2_DMA0;
- if(chn < 0 || chn > 3) {
- //panic("wrong channel received in g2_dma_irq");
- //return;
- //printf("wrong channel received in g2_dma_irq");
- chn = 1;
- }
- /* VP : changed the order of things so that we can chain dma calls */
- // Signal the calling thread to continue, if any.
- if(dma_blocking[chn]) {
- sem_signal(&dma_done[chn]);
- thd_schedule(1, 0);
- dma_blocking[chn] = 0;
- }
- // Call the callback, if any.
- if(dma_callback[chn]) {
- dma_callback[chn](dma_cbdata[chn]);
- }
- }
- int G2DMATransfer(void *from, void * dest, uint32 length, int block,
- g2_dma_callback_t callback, ptr_t cbdata, uint32 dir, uint32 g2chn) {
- if(g2chn > 3) {
- errno = EINVAL;
- return -1;
- }
- /* Check alignments */
- if(((uint32)from) & 31) {
- dbglog(DBG_ERROR, "g2_dma: unaligned source DMA %p\n", from);
- errno = EFAULT;
- return -1;
- }
- if(((uint32)dest) & 31) {
- dbglog(DBG_ERROR, "g2_dma: unaligned dest DMA %p\n", dest);
- errno = EFAULT;
- return -1;
- }
- if(((uint32)length) & 31) {
- dbglog(DBG_ERROR, "g2_dma: unaligned length DMA %p\n", dest);
- errno = EFAULT;
- return -1;
- }
- dma_blocking[g2chn] = block;
- dma_callback[g2chn] = callback;
- dma_cbdata[g2chn] = cbdata;
- /* Start the DMA transfer */
- G2_REGS.dma[g2chn].ctrl1 = 0;
- G2_REGS.dma[g2chn].ctrl2 = 0;
- G2_REGS.dma[g2chn].ext_addr = ((uint32)dest) & 0x1fffffe0;
- G2_REGS.dma[g2chn].sh4_addr = ((uint32)from) & 0x1fffffe0;
- G2_REGS.dma[g2chn].size = (length & ~31) | 0x80000000;
- G2_REGS.dma[g2chn].dir = dir;
- G2_REGS.dma[g2chn].mode = 5;
- G2_REGS.dma[g2chn].ctrl1 = 1;
- G2_REGS.dma[g2chn].ctrl2 = 1;
- /* Wait for us to be signaled */
- if(block)
- sem_wait(&dma_done[g2chn]);
- return 0;
- }
- //Poll for DMA completion with G2DMAInProgress(0)
- void StartBackgroundAudioDMA(void *src, uint32 dst, int size) {
- G2DMATransfer(src, (void*)G2_ARAM + dst, size, 0,0,0, G2_DMA_TO_DEVICE, 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement