Advertisement
Guest User

G2 DMA

a guest
Jan 5th, 2022
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.47 KB | None | 0 0
  1. /* the address of the sound ram from the SH4 side */
  2. #define G2_ARAM    0xa0800000
  3.  
  4. #define G2_DMA_TO_DEVICE    0
  5. #define G2_DMA_FROM_DEVICE  1
  6.  
  7. typedef struct {
  8.     uint32      ext_addr;       /* External address (SPU-RAM or parallel port) */
  9.     uint32      sh4_addr;       /* SH-4 Address */
  10.     uint32      size;           /* Size in bytes; all addresses and sizes must be 32-byte aligned */
  11.     uint32      dir;            /* 0: cpu->ext; 1: ext->cpu */
  12.     uint32      mode;           /* 5 for SPU transfer */
  13.     uint32      ctrl1;          /* b0 */
  14.     uint32      ctrl2;          /* b0 */
  15.     uint32      stop;         /* ?? */
  16. } g2_dma_ctrl_t;
  17.  
  18. typedef struct {
  19.     uint32      ext_addr;
  20.     uint32      sh4_addr;
  21.     uint32      size;
  22.     uint32      status;
  23. } g2_dma_stat_t;
  24.  
  25. typedef struct {
  26.     g2_dma_ctrl_t   dma[4];
  27.     uint32      u1[4];          /* ?? */
  28.     uint32      wait_state;
  29.     uint32      u2[10];         /* ?? */
  30.     uint32      magic;
  31.     g2_dma_stat_t   dma_stat[4];
  32. } g2_dma_reg_t;
  33.  
  34. #define G2_REGS (*(volatile g2_dma_reg_t *)0xa05f7800)
  35. #define G2_FIFO (*(volatile int*)0xa05f688c)
  36.  
  37. static inline void G2PauseDMA(int channel) {
  38.     G2_REGS.dma[channel].stop = -1;
  39. }
  40. static inline void G2ResumeDMA(int channel) {
  41.     G2_REGS.dma[channel].stop = 0;
  42. }
  43.  
  44. static inline int G2DMAInProgress(int channel) {
  45.     return G2_REGS.dma[channel].ctrl2 & 1;
  46. }
  47.  
  48. static semaphore_t dma_done[4];
  49. static int dma_blocking[4];
  50. static g2_dma_callback_t dma_callback[4];
  51. static ptr_t dma_cbdata[4];
  52.  
  53. static void G2DMAIRQHandler(uint32 code) {
  54.     int chn = code - ASIC_EVT_G2_DMA0;
  55.  
  56.     if(chn < 0 || chn > 3) {
  57.         //panic("wrong channel received in g2_dma_irq");
  58.         //return;
  59.         //printf("wrong channel received in g2_dma_irq");
  60.         chn = 1;
  61.     }
  62.  
  63.     /* VP : changed the order of things so that we can chain dma calls */
  64.  
  65.     // Signal the calling thread to continue, if any.
  66.     if(dma_blocking[chn]) {
  67.         sem_signal(&dma_done[chn]);
  68.         thd_schedule(1, 0);
  69.         dma_blocking[chn] = 0;
  70.     }
  71.  
  72.     // Call the callback, if any.
  73.     if(dma_callback[chn]) {
  74.         dma_callback[chn](dma_cbdata[chn]);
  75.     }
  76.  
  77. }
  78.  
  79. int G2DMATransfer(void *from, void * dest, uint32 length, int block,
  80.         g2_dma_callback_t callback, ptr_t cbdata, uint32 dir, uint32 g2chn) {
  81.  
  82.     if(g2chn > 3) {
  83.         errno = EINVAL;
  84.         return -1;
  85.     }
  86.  
  87.     /* Check alignments */
  88.     if(((uint32)from) & 31) {
  89.         dbglog(DBG_ERROR, "g2_dma: unaligned source DMA %p\n", from);
  90.         errno = EFAULT;
  91.         return -1;
  92.     }
  93.  
  94.     if(((uint32)dest) & 31) {
  95.         dbglog(DBG_ERROR, "g2_dma: unaligned dest DMA %p\n", dest);
  96.         errno = EFAULT;
  97.         return -1;
  98.     }
  99.  
  100.     if(((uint32)length) & 31) {
  101.         dbglog(DBG_ERROR, "g2_dma: unaligned length DMA %p\n", dest);
  102.         errno = EFAULT;
  103.         return -1;
  104.     }
  105.     dma_blocking[g2chn] = block;
  106.     dma_callback[g2chn] = callback;
  107.     dma_cbdata[g2chn] = cbdata;
  108.    
  109.     /* Start the DMA transfer */
  110.     G2_REGS.dma[g2chn].ctrl1 = 0;
  111.     G2_REGS.dma[g2chn].ctrl2 = 0;
  112.     G2_REGS.dma[g2chn].ext_addr = ((uint32)dest) & 0x1fffffe0;
  113.     G2_REGS.dma[g2chn].sh4_addr = ((uint32)from) & 0x1fffffe0;
  114.     G2_REGS.dma[g2chn].size = (length & ~31) | 0x80000000;
  115.     G2_REGS.dma[g2chn].dir = dir;
  116.     G2_REGS.dma[g2chn].mode = 5;
  117.     G2_REGS.dma[g2chn].ctrl1 = 1;
  118.     G2_REGS.dma[g2chn].ctrl2 = 1;
  119.  
  120.     /* Wait for us to be signaled */
  121.     if(block)
  122.         sem_wait(&dma_done[g2chn]);
  123.  
  124.     return 0;
  125. }
  126.  
  127. //Poll for DMA completion with G2DMAInProgress(0)
  128. void StartBackgroundAudioDMA(void *src, uint32 dst, int size) {
  129.     G2DMATransfer(src, (void*)G2_ARAM + dst, size, 0,0,0, G2_DMA_TO_DEVICE, 0);
  130. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement