#include "pxa255_DMA.h" #include "mem.h" #define REG_DAR 0 #define REG_SAR 1 #define REG_TAR 2 #define REG_CR 3 #define REG_CSR 4 static void pxa255dmaPrvChannelRegWrite(_UNUSED_ Pxa255dma* dma, UInt8 channel, UInt8 reg, UInt32 val){ if(val){ //we start with zeros, so non-zero writes are all we care about const char* regs[] = {"DADDR", "SADDR", "TADDR", "CR", "CSR"}; err_str("dma: writes unimpl!"); // err_str("PXA255 dma engine: writes unimpl! (writing 0x"); // err_hex(val); // err_str(" to channel "); // err_dec(channel); // err_str(" reg "); // err_str(regs[reg]); // err_str(". Halting.\r\n"); while(1); } } static UInt32 pxa255dmaPrvChannelRegRead(_UNUSED_ Pxa255dma* dma, _UNUSED_ UInt8 channel, _UNUSED_ UInt8 reg){ return 0; } static Boolean pxa255dmaPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){ Pxa255dma* dma = userData; UInt8 reg, set; UInt32 val = 0; if(size != 4) { err_str(__FILE__ ": Unexpected "); // err_str(write ? "write" : "read"); // err_str(" of "); // err_dec(size); // err_str(" bytes to 0x"); // err_hex(pa); // err_str("\r\n"); return true; //we do not support non-word accesses } pa = (pa - PXA255_DMA_BASE) >> 2; if(write){ val = *(UInt32*)buf; switch(pa >> 6){ //weird, but quick way to avoide repeated if-then-elses. this is faster case 0: if(pa < 16){ reg = REG_CSR; set = pa; pxa255dmaPrvChannelRegWrite(dma, set, reg, val); } break; case 1: pa -= 64; if(pa < 40) dma->CMR[pa] = val; break; case 2: pa -= 128; set = pa >> 2; reg = pa & 3; pxa255dmaPrvChannelRegWrite(dma, set, reg, val); break; } } else{ switch(pa >> 6){ //weird, but quick way to avoide repeated if-then-elses. this is faster case 0: if(pa < 16){ reg = REG_CSR; set = pa; val = pxa255dmaPrvChannelRegRead(dma, set, reg); } break; case 1: pa -= 64; if(pa < 40) val = dma->CMR[pa]; break; case 2: pa -= 128; set = pa >> 2; reg = pa & 3; val = pxa255dmaPrvChannelRegRead(dma, set, reg); break; } *(UInt32*)buf = val; } return true; } Boolean pxa255dmaInit(Pxa255dma* dma, ArmMem* physMem, Pxa255ic* ic){ __mem_zero(dma, sizeof(Pxa255dma)); dma->ic = ic; dma->mem = physMem; return memRegionAdd(physMem, PXA255_DMA_BASE, PXA255_DMA_SIZE, pxa255dmaPrvMemAccessF, dma); }