#include "kloadcore.h" #include "kintrman.h" #include "kdmacman.h" #include "ksifman.h" #define min(a, b) ((a)<(b)?(a):(b)) #define max(a, b) ((a)>(b)?(a):(b)) #define CONFIG_1450 (*(volatile int*)0xBF801450) #define BD0 (*(volatile int*)0xBD000000) //mscom #define BD1 (*(volatile int*)0xBD000010) //smcom #define BD2 (*(volatile int*)0xBD000020) //msflag #define BD3 (*(volatile int*)0xBD000030) //smflag #define BD4 (*(volatile int*)0xBD000040) #define BD5 (*(volatile int*)0xBD000050) #define BD6 (*(volatile int*)0xBD000060) #define BD7 (*(volatile int*)0xBD000070) int debug=1; #define _dprintf(fmt, args...) \ if (debug > 0) __printf("sifman: " fmt, ## args) struct sifData{ int data, words, count, addr; }; int sifSIF2Init =0, sifInit =0; struct sm_internal{ short id, //+000 some id...?!? res1; //+002 not used int index; //+004 current position in dma buffer struct sifData *crtbuf; //+008 address of current used buffer struct sifData buf1[32]; //+00C first buffer struct sifData buf2[32]; //+20C second buffer int (*function)(int);//+40C a function ?!? int param; //+410 a parameter for function int res2; //+414 not used } vars; struct sifData one; int res3, res4; int _start(int argc, char* argv); void RegisterSif0Handler(); /////////////////////////////////////////////////////////////////////// int getBD2_loopchanging(){ register int a, b; a=BD2; b=BD2; while (a!=b) { a=b; b=BD2; } return a; } /////////////////////////////////////////////////////////////////////// int getBD3_loopchanging(){ register int a, b; a=BD3; b=BD3; while (a!=b) { a=b; b=BD3; } return a; } ///////////////////////////////////////////////////////////////////////[04] void SifSIF2Init(){ if (sifSIF2Init!=0) return; DMAch_SIF2_CHCR = 0; //reset ch. 2 DMAch_DPCR|= 0x800; //enable dma ch. 2 DMAch_DPCR; sifSIF2Init =1; } ///////////////////////////////////////////////////////////////////////[05] void SifInit(){ u32 x, y; u32 msflag; _dprintf("%s: sifInit=%d\n", __FUNCTION__, sifInit); if (sifInit!=0) return; DMAch_DPCR2 |=0x8800; //enable dma ch. 9 and 10 DMAch_SIF9_CHCR = 0; DMAch_SIFA_CHCR = 0; SifSIF2Init(); if (CONFIG_1450 & 0x10) CONFIG_1450 |= 0x10; CONFIG_1450 |= 0x1; RegisterSif0Handler(); CpuSuspendIntr(&x); //intrman CpuEnableIntr(); //intrman _dprintf("%s: waiting EE...\n", __FUNCTION__); do { //EE kernel sif ready CpuSuspendIntr(&y); //intrman msflag = getBD2_loopchanging(); CpuResumeIntr(y); //intrman } while(!(msflag & 0x10000)); _dprintf("%s: EE ready\n", __FUNCTION__); CpuResumeIntr(x); //intrman SifSetDChain(); SifSetIOPrcvaddr(0); //sif1 receive buffer BD3 = 0x10000; //IOPEE_sifman_init BD3; sifInit =1; _dprintf("%s ok\n", __FUNCTION__); } ///////////////////////////////////////////////////////////////////////[02] void SifDeinit(){ int x; DisableIntr(INT_DMA9, &x); ReleaseIntrHandler(INT_DMA9); DMAch_SIF9_CHCR=0; DMAch_SIFA_CHCR=0; if (CONFIG_1450 & 0x10) CONFIG_1450 |= 0x10; } ///////////////////////////////////////////////////////////////////////[29] int SifCheckInit(){ return sifInit; } ///////////////////////////////////////////////////////////////////////[06] void SifSetDChain(){ if ((BD4 & 0x40) == 0) BD4=0x40; DMAch_SIFA_CHCR =0; DMAch_SIFA_BCR_size =32; DMAch_SIFA_CHCR =DMAf_08|DMAf_CO|DMAf_TR|DMAf_30;//EE->IOP (to memory) } ///////////////////////////////////////////////////////////////////////[30] void SifSet0CB(int (*_function)(int), int _param){ vars.function=_function; vars.param=_param; } ///////////////////////////////////////////////////////////////////////[31] void SifReset0CB(){ vars.function=NULL; vars.param=0; } /////////////////////////////////////////////////////////////////////// int Sif0Handler(void *common) { struct sm_internal *vars = (struct sm_internal *)common; int var_10; if (vars->function) vars->function(vars->param); if ((DMAch_SIF9_CHCR & DMAf_TR == 0) && (vars->index>0)) { DMAch_SIF9_CHCR =0; DMAch_SIF9_TADR =(int)vars->crtbuf; DMAch_SIF9_BCR =32; if (BD4 & 0x20 == 0) BD4 = 0x20; vars->id++; if (vars->crtbuf == vars->buf1){ vars->index=0; vars->crtbuf=vars->buf2; }else vars->crtbuf=vars->buf1; DMAch_SIF9_CHCR = DMAf_DR|DMAf_08|DMAf_CO|DMAf_LI|DMAf_TR;//IOP->EE (from memory) var_10=DMAch_SIF9_CHCR; } return 1; } /////////////////////////////////////////////////////////////////////// void RegisterSif0Handler(){ u32 x; vars.index=0; vars.crtbuf=vars.buf1; vars.function=NULL; vars.param=0; CpuSuspendIntr(&x); //intrman RegisterIntrHandler(INT_DMA9, 1, Sif0Handler, &vars); //intrman EnableIntr(INT_DMA9); //intrman CpuResumeIntr(x); //intrman } /////////////////////////////////////////////////////////////////////// void enqueue(struct sifman_DMA *psd){ vars.crtbuf[vars.index].data=(u32)psd->data & 0xFFFFFF; //16MB addressability if (psd->attr & SIF_DMA_INT_I) vars.crtbuf[vars.index].data |= 0x40000000; vars.crtbuf[vars.index].words=(psd->size + 3)/4 & 0xFFFFFF; vars.crtbuf[vars.index].count = ((psd->size + 3)/16 + (((psd->size + 3)/4) & 3)) | 0x10000000; if (psd->attr & SIF_DMA_INT_O) vars.crtbuf[vars.index].count |=0x80000000; vars.crtbuf[vars.index].addr = (u32)psd->addr & 0x1FFFFFFF; //512MB addresability vars.index++; } ///////////////////////////////////////////////////////////////////////[07] u32 SifSetDma(struct sifman_DMA *psd, int len){ int var_20; register unsigned int ret; int i; if (32-vars.index < len) return 0; //no place ret = vars.id; ret = (ret << 16) | ((vars.index & 0xFF) << 8) | (len & 0xFF); if (vars.index) vars.crtbuf[vars.index-1].data &= 0x7FFFFFFF; for (i=0; iEE var_20=DMAch_SIF9_CHCR; //?!? } return ret; } ///////////////////////////////////////////////////////////////////////[08] int SifDmaStat(u32 id){ if (DMAch_SIF9_CHCR & DMAf_TR){ if (id>>16 == vars.id) return 1; //waiting in queue if (id>>16+1 == vars.id) return 0; //running } return -1; //terminated } ///////////////////////////////////////////////////////////////////////[09] void SifSend(struct sifman_DMA sd){ sd.size = sd.size /4 + ((sd.size & 3) > 0); one.data = ((u32)sd.data & 0xFFFFFF) | 0x80000000; one.words= sd.size & 0xFFFFFF; if (sd.attr & SIF_DMA_INT_I) one.data |= 0x40000000; one.count = (sd.size/4 + ((sd.size & 3)>0)) | 0x10000000; if (sd.attr & SIF_DMA_INT_O) one.count|= 0x80000000; one.addr = (u32)sd.addr & 0xFFFFFFF; if (BD4 & 0x20 == 0) BD4=0x20; DMAch_SIF9_CHCR=0; DMAch_SIF9_TADR=(u32)&one; DMAch_SIF9_BCR_size=32; DMAch_SIF9_CHCR=DMAf_DR|DMAf_08|DMAf_CO|DMAf_LI|DMAf_TR; //IOP->EE DMAch_SIF9_CHCR; } ///////////////////////////////////////////////////////////////////////[10] void SifSendSync(){ while (DMAch_SIF9_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[11] int SifIsSending(){ return (DMAch_SIF9_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[12] void SifSetSIF0DMA(void *data, int size, int attr){ size=size/4 + ((size & 3)>0); if (BD4 & 0x20 == 0) BD4=0x20; DMAch_SIF9_CHCR=0; DMAch_SIF9_MADR=(u32)data & 0xFFFFFF; DMAch_SIF9_BCR_size=32; DMAch_SIF9_BCR_count=size/32 + ((size & 0x1F)>0); DMAch_SIF9_CHCR=DMAf_DR|DMAf_CO|DMAf_TR; DMAch_SIF9_CHCR; } ///////////////////////////////////////////////////////////////////////[13] void SifSendSync0(){ while (DMAch_SIF9_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[14] int SifIsSending0(){ return (DMAch_SIF9_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[15] void SifSetSIF1DMA(void *data, int size, int attr){ size=size/4 + ((size & 3)>0); if (BD4 & 0x40 == 0) BD4=0x40; DMAch_SIFA_CHCR=0; DMAch_SIFA_MADR=(u32)data & 0xFFFFFF; DMAch_SIFA_BCR_size=32; DMAch_SIFA_BCR_count=size/32 + ((size & 0x1F)>0); DMAch_SIFA_CHCR=DMAf_CO|DMAf_TR| (attr & SIF_DMA_BSN?DMAf_30:0); DMAch_SIFA_CHCR; } ///////////////////////////////////////////////////////////////////////[16] void SifSendSync1(){ while (DMAch_SIFA_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[17] int SifIsSending1(){ return (DMAch_SIFA_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[18] void SifSetSIF2DMA(void *data, int size, int attr){ size=size/4 + ((size & 3)>0); if (BD4 & 0x80 == 0) BD4=0x80; DMAch_SIF2_CHCR=0; DMAch_SIF2_MADR=(u32)data & 0xFFFFFF; DMAch_SIF2_BCR_size=min(size, 32); DMAch_SIF2_BCR_count=size/32 + ((size & 0x1F)>0); DMAch_SIF2_CHCR=DMAf_CO |DMAf_TR| ((attr & SIF_TO_EE ?DMAf_DR: (attr & SIF_DMA_BSN?DMAf_30:0))); DMAch_SIF2_CHCR; } ///////////////////////////////////////////////////////////////////////[19] void SifSendSync2(){ while (DMAch_SIF2_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[20] int SifIsSending2(){ return (DMAch_SIF2_CHCR & DMAf_TR); } ///////////////////////////////////////////////////////////////////////[21] int SifGetEEIOPflags(){ return getBD2_loopchanging(); } ///////////////////////////////////////////////////////////////////////[22] int SifSetEEIOPflags(int val){ BD2=val; return getBD2_loopchanging(); } ///////////////////////////////////////////////////////////////////////[23] int SifGetIOPEEflags(){ return getBD3_loopchanging(); } ///////////////////////////////////////////////////////////////////////[24] int SifSetIOPEEflags(int val){ BD3=val; return getBD3_loopchanging(); } ///////////////////////////////////////////////////////////////////////[25] int SifGetEErcvaddr(){ return BD0; } ///////////////////////////////////////////////////////////////////////[26] int SifGetIOPrcvaddr(){ return BD1; } ///////////////////////////////////////////////////////////////////////[27] int SifSetIOPrcvaddr(int val){ BD1=val; return BD1; } ///////////////////////////////////////////////////////////////////////[28] void SifSet1450_2(){ CONFIG_1450 |= 2; CONFIG_1450 &= ~2; CONFIG_1450; } ///////////////////////////////////////////////////////////////////////[01,03,32,33,34,35] void _retonly(){} //////////////////////////////entrypoint/////////////////////////////// struct export sifman_stub={ 0x41C00000, 0, VER(1, 1), // 1.1 => 0x101 0, "sifman", (func)_start, // entrypoint (func)_retonly, (func)SifDeinit, (func)_retonly, (func)SifSIF2Init, (func)SifInit, (func)SifSetDChain, (func)SifSetDma, (func)SifDmaStat, (func)SifSend, (func)SifSendSync, (func)SifIsSending, (func)SifSetSIF0DMA, (func)SifSendSync0, (func)SifIsSending0, (func)SifSetSIF1DMA, (func)SifSendSync1, (func)SifIsSending1, (func)SifSetSIF2DMA, (func)SifSendSync2, (func)SifIsSending2, (func)SifGetEEIOPflags, (func)SifSetEEIOPflags, (func)SifGetIOPEEflags, (func)SifSetIOPEEflags, (func)SifGetEErcvaddr, (func)SifGetIOPrcvaddr, (func)SifSetIOPrcvaddr, (func)SifSet1450_2, (func)SifCheckInit, (func)SifSet0CB, (func)SifReset0CB, (func)_retonly, (func)_retonly, (func)_retonly, (func)_retonly, 0 }; //////////////////////////////entrypoint///////////////////////////////[00] int _start(int argc, char* argv){ return RegisterLibraryEntries(&sifman_stub) > 0; }