//[module] SIO2MAN //[processor] IOP //[type] ELF-IRX //[size] ?(0x?) //[bios] ?(0x?-0x?) //[iopboot2] 21 //[loaded @] ? //[name] sio2man //[version] 0x101 //[memory map] 0xBF808200,0xBF808204,0xBF808208,0xBF80820C, // 0xBF808210,0xBF808214,0xBF808218,0xBF80821C, 16 entries // 0xBF808220,0xBF808224,0xBF808228,0xBF80822C, array // 0xBF808230,0xBF808234,0xBF808238,0xBF80823C, // 0xBF808240,0xBF808244,0xBF808248,0xBF80824C, // 0xBF808250,0xBF808254,0xBF808258,0xBF80825C, // 0xBF808260, 0xBF808268,0xBF80826C, // 0xBF808270,0xBF808274,0xBF808278,0xBF80827C, // 0xBF808280 //[handlers] - //[entry point] _start, (export_stub) //[made by] Herben #include #include #include "kdmacman.h" #include "kloadcore.h" #include "kintrman.h" #include #include struct sio2_packet { u32 recvVal1; // 0x00 u32 sendArray1[4]; // 0x04-0x10 u32 sendArray2[4]; // 0x14-0x20 u32 recvVal2; // 0x24 u32 sendArray3[16]; // 0x28-0x64 u32 recvVal3; // 0x68 int sendSize; // 0x6C int recvSize; // 0x70 u8 *sendBuf; // 0x74 u8 *recvBuf; // 0x78 u32 dmacAddress1; u32 dmacSize1; u32 dmacCount1; u32 dmacAddress2; u32 dmacSize2; u32 dmacCount2; }; struct sio2common { int evid; int thid; }; struct sio2common common; int sio2_initialized = 0; struct sio2_packet *packetAddr; int debug = 1; #define _dprintf(fmt, args...) if (debug > 0) printf(fmt, ## args) // if (debug > 0) printf("\033[0;32m" "sio2man: " "\033[0m" fmt, ## args) int _start(void); void nullSub(void); int sio2_init(void); void sio2_deInit(void); void sio2_setCtrl(u32 arg0); u32 sio2_getCtrl(void); u32 sio2_getRecv1(void); void sio2_setSend1(int entryNum, u32 val); u32 sio2_getSend1(int entryNum); void sio2_setSend2(int entryNum, u32 val); u32 sio2_getSend2(int entryNum); u32 sio2_getRecv2(void); void sio2_setSend3(int entryNum, u32 val); u32 sio2_getSend3(int entryNum); u32 sio2_getRecv3(void); void sio2_set8278(u32 arg0); u32 sio2_get8278(void); void sio2_set827C(u32 arg0); u32 sio2_get827C(void); void sio2_datain(u8 arg0); u8 sio2_dataout(void); void sio2_setIntr(u32 arg0); u32 sio2_getIntr(void); void sio2_signalExchange1(void); void sio2_signalExchange2(void); int sio2_packetExchange(struct sio2_packet *packet); struct export sio2man_stub={ 0x41C00000, 0, VER(1, 2), // 1.2 => 0x102 0, "sio2man", (func)_start, // 0 (func)nullSub, (func)sio2_deInit, (func)nullSub, (func)sio2_setCtrl, // 4 (func)sio2_getCtrl, (func)sio2_getRecv1, (func)sio2_setSend1, (func)sio2_getSend1, // 8 (func)sio2_setSend2, (func)sio2_getSend2, (func)sio2_getRecv2, (func)sio2_setSend3, // 12 (func)sio2_getSend3, (func)sio2_getRecv3, (func)sio2_set8278, (func)sio2_get8278, // 16 (func)sio2_set827C, (func)sio2_get827C, (func)sio2_datain, (func)sio2_dataout, // 20 (func)sio2_setIntr, (func)sio2_getIntr, (func)sio2_signalExchange1, (func)sio2_signalExchange2, // 24 (func)sio2_packetExchange, 0 }; #define INUM_sio2 17 #define HTYPE_C 1 int _start(void) { return sio2_init(); } void nullSub(void) { return; } void sio2_setCtrl(u32 arg0) { *(u32 *) (0xBF808268) = arg0; } u32 sio2_getCtrl(void) { return(*(u32 *) (0xBF808268)); } u32 sio2_getRecv1(void) { return(*(u32 *) (0xBF80826C)); } void sio2_setSend1(int entryNum, u32 val) { switch(entryNum) { case 0: *(u32 *) (0xBF808240) = val; break; case 1: *(u32 *) (0xBF808248) = val; break; case 2: *(u32 *) (0xBF808250) = val; break; case 3: *(u32 *) (0xBF808258) = val; break; } } u32 sio2_getSend1(int entryNum) { switch(entryNum) { case 0: return(*(u32 *) (0xBF808240)); case 1: return(*(u32 *) (0xBF808248)); case 2: return(*(u32 *) (0xBF808250)); case 3: return(*(u32 *) (0xBF808258)); } return(0); } void sio2_setSend2(int entryNum, u32 val) { switch(entryNum) { case 0: *(u32 *) (0xBF808244) = val; break; case 1: *(u32 *) (0xBF80824C) = val; break; case 2: *(u32 *) (0xBF808254) = val; break; case 3: *(u32 *) (0xBF80825C) = val; break; } } u32 sio2_getSend2(int entryNum) { switch(entryNum) { case 0: return(*(u32 *) (0xBF808244)); case 1: return(*(u32 *) (0xBF80824C)); case 2: return(*(u32 *) (0xBF808254)); case 3: return(*(u32 *) (0xBF80825C)); } return(0); } u32 sio2_getRecv2(void) { return(*(u32 *) (0xBF808270)); } void sio2_setSend3(int entryNum, u32 val) { if(entryNum < 16) *(u32 *) (0xBF808200 + (entryNum * 4)) = val; } u32 sio2_getSend3(int entryNum) { if(entryNum < 16) return(*(u32 *) (0xBF808200 + (entryNum * 4))); return(-1); } u32 sio2_getRecv3(void) { return(*(u32 *) (0xBF808274)); } void sio2_set8278(u32 arg0) { *(u32 *) (0xBF808278) = arg0; } u32 sio2_get8278(void) { return(*(u32 *) (0xBF808278)); } void sio2_set827C(u32 arg0) { *(u32 *) (0xBF80827C) = arg0; } u32 sio2_get827C(void) { return(*(u32 *) (0xBF80827C)); } void sio2_datain(u8 arg0) { *(u8 *) (0xBF808260) = arg0; } u8 sio2_dataout(void) { return(*(u8 *) (0xBF808264)); } void sio2_setIntr(u32 arg0) { *(u32 *) (0xBF808280) = arg0; } u32 sio2_getIntr(void) { return(*(u32 *) (0xBF808280)); } int sio2_createEventFlag(void) { iop_event_t param; param.attr = 2; param.option = 0; param.bits = 0; return(CreateEventFlag(¶m)); } void dumpbuf(u8 *buf, int size) { /* char str[1024]; char tmp[256]; int i; str[0] = 0; for(i = 0; i < size; i++) { sprintf(tmp, "%x, ", buf[i]); strcat(str, tmp); } printf("%s\n", str); */ } void sio2_sendPacket(struct sio2_packet *p) { int i; // _dprintf("%s: sendSize=%d\n", __FUNCTION__, p->sendSize); for(i = 0; i < 4; i++) { sio2_setSend1(i, p->sendArray1[i]); sio2_setSend2(i, p->sendArray2[i]); } for(i = 0; i < 16; i++) sio2_setSend3(i, p->sendArray3[i]); if (p->sendSize) { _dprintf("sendBuf: "); dumpbuf(p->sendBuf, p->sendSize); for(i = 0; i < p->sendSize; i++) { *(u8 *) (0xBF808260) = p->sendBuf[i]; } } if(p->dmacAddress1 != 0) { _dprintf("dmaAddress1=%x, dmacSize1=%x, dmacCount1=%x\n", p->dmacAddress1, p->dmacSize1, p->dmacCount1); dumpbuf((u8*)p->dmacAddress1, p->dmacSize1*p->dmacCount1); dmacSetDMA(DMAch_SIO2in, p->dmacAddress1, p->dmacSize1, p->dmacCount1, 1); // from memory dmacStartTransfer(DMAch_SIO2in); } if(p->dmacAddress2 != 0) { dmacSetDMA(DMAch_SIO2out, p->dmacAddress2, p->dmacSize2, p->dmacCount2, 0); // to memory dmacStartTransfer(DMAch_SIO2out); } } void sio2_recvPacket(struct sio2_packet *p) { int i; // _dprintf("%s: recvSize=%d\n", __FUNCTION__, p->recvSize); p->recvVal1 = *(u32 *) (0xBF80826C); p->recvVal2 = *(u32 *) (0xBF808270); p->recvVal3 = *(u32 *) (0xBF808274); if (p->recvSize) { _dprintf("recvBuf: "); for(i = 0; i < p->recvSize; i++) { p->recvBuf[i] = *(u8 *) (0xBF808264); printf("%x, ", p->recvBuf[i]); } // printf("\n"); } if (p->dmacAddress2 != 0) { dumpbuf((u8*)p->dmacAddress2, p->dmacSize2*p->dmacCount2); } } void sio2_basicThread(void* data) { unsigned long result[4]; //_dprintf("%s\n", __FUNCTION__); while(1) { WaitEventFlag(common.evid, 0x5, 0x01, result); if (result[0] & 0x01) { ClearEventFlag(common.evid, ~0x1); SetEventFlag(common.evid, 0x02); } else if (result[0] & 0x04) { ClearEventFlag(common.evid, ~0x4); SetEventFlag(common.evid, 0x08); } else { printf("sio2MAN: Woke up for unknown event(%08X)!\n", result[0]); return; } // Wait for application to call our export 25 WaitEventFlag(common.evid, 0x10, 0, NULL); ClearEventFlag(common.evid, ~0x10); *(u32 *) (0xBF808268) = (*(u32 *) (0xBF808268)) | 0x0C; sio2_sendPacket(packetAddr); *(u32 *) (0xBF808268) = (*(u32 *) (0xBF808268)) | 0x01; // Wait for the sio2 interrupt to occur WaitEventFlag(common.evid, 0x80, 0, NULL); ClearEventFlag(common.evid, ~0x80); // Recieve the reply packet sio2_recvPacket(packetAddr); SetEventFlag(common.evid, 0x20); WaitEventFlag(common.evid, 0x40, 0, NULL); ClearEventFlag(common.evid, ~0x40); } } int sio2_createBasicThread(void) { iop_thread_t param; param.attr = TH_C; param.option = 0; param.thread = &sio2_basicThread; param.stacksize = 0x2000; param.priority = 0x18; return(CreateThread(¶m)); } int sio2_interruptHandler(struct sio2common *c) { sio2_setIntr(sio2_getIntr()); iSetEventFlag(c->evid, 0x80); return(1); } // Export 0 int sio2_init(void) { u32 oldStat; // _dprintf("%s\n", __FUNCTION__); if(RegisterLibraryEntries(&sio2man_stub) != 0) { //printf("sio2MAN: Unable to register library entries!\n"); return(MODULE_NO_RESIDENT_END);//==1 } if(sio2_initialized != 0) { //printf("sio2MAN: Already initialized!\n"); return(MODULE_NO_RESIDENT_END); } sio2_initialized = 1; *(u32 *) (0xBF808268) = 0x3BC; common.evid = sio2_createEventFlag(); common.thid = sio2_createBasicThread(); CpuSuspendIntr(&oldStat); RegisterIntrHandler(INUM_sio2, HTYPE_C, &sio2_interruptHandler, &common); EnableIntr(INUM_sio2); CpuResumeIntr(oldStat); dmacSetVal(DMAch_SIO2in, 0x03); dmacSetVal(DMAch_SIO2out, 0x03); dmacEnableDMAch(DMAch_SIO2in); dmacEnableDMAch(DMAch_SIO2out); StartThread(common.thid, 0); // Start the "basicThread" return MODULE_RESIDENT_END; } void sio2_deInit(void) { u32 oldStat; // _dprintf("%s\n", __FUNCTION__); CpuSuspendIntr(&oldStat); DisableIntr(INUM_sio2, 0); ReleaseIntrHandler(INUM_sio2); CpuResumeIntr(oldStat); dmacDisableDMAch(DMAch_SIO2in); dmacDisableDMAch(DMAch_SIO2out); } void sio2_signalExchange1(void) { // _dprintf("%s\n", __FUNCTION__); // Signal the basic thread to let it know we want to do an exchange. SetEventFlag(common.evid, 0x01); // Wait for basic thread to acknowledge then clear the flag. WaitEventFlag(common.evid, 0x02, 0, NULL); ClearEventFlag(common.evid, ~0x2); } void sio2_signalExchange2(void) { // _dprintf("%s\n", __FUNCTION__); // Signal the basic thread to let it know we want to do an exchange. SetEventFlag(common.evid, 0x04); // Wait for basic thread to acknowledge then clear the flag. WaitEventFlag(common.evid, 0x08, 0, NULL); ClearEventFlag(common.evid, ~0x8); } int sio2_packetExchange(struct sio2_packet *packet) { // _dprintf("%s: %x\n", __FUNCTION__, packet); // Set the address of the packet. packetAddr = packet; // Let the basic thread know we have the address set for the exchange. SetEventFlag(common.evid, 0x10); // Wait for the basic thread to finish it's stuff. WaitEventFlag(common.evid, 0x20, 0, NULL); ClearEventFlag(common.evid, ~0x20); SetEventFlag(common.evid, 0x40); return 1; }