void SIO2_TransferInit4 ( void ) { SetEventFlag ( s_EventFlag, 0x00000100 ); WaitEventFlag ( s_EventFlag, 0x00000200, 0, NULL ); ClearEventFlag ( s_EventFlag, ~0x00000200 ); } /* end SIO2_TransferInit4 */
s32 padEnd(void) { if(padman_init != 0) { int port,slot; for(port = 0; port < 2; port++) for(slot=0; slot < 4; slot++) { if((openSlots[port] >> slot) & 0x1) padPortClose(port, slot, 1); } SetEventFlag(vblankData.eventflag, EF_EXIT_THREAD); vblankData.padEnd = 1; WaitEventFlag(vblankData.eventflag, EF_VB_WAIT_THREAD_EXIT, 0x11, 0); DeleteThreadsEventFlag( &vblankData ); while(ReleaseVblankHandler(0, (void*)VblankStart) != 0) M_PRINTF("Release VB_START failed.\n"); while(ReleaseVblankHandler(1, VblankEnd) != 0) M_PRINTF("Release VB_END failed.\n"); padman_init = 0; }
void SIO2_TransferInit3 ( void ) { SetEventFlag ( s_EventFlag, 0x00000040 ); WaitEventFlag ( s_EventFlag, 0x00000080, 0, NULL ); ClearEventFlag ( s_EventFlag, ~0x00000080 ); } /* end SIO2_TransferInit3 */
/* 48 */ void sio2_mtap_transfer_init() { SetEventFlag(event_flag, EF_MTAP_TRANSFER_INIT); WaitEventFlag(event_flag, EF_MTAP_TRANSFER_READY, 0, NULL); ClearEventFlag(event_flag, ~EF_MTAP_TRANSFER_READY); }
void SIO2_TransferInit0 ( void ) { SetEventFlag ( s_EventFlag, 0x00000001 ); WaitEventFlag ( s_EventFlag, 0x00000002, 0, NULL ); ClearEventFlag ( s_EventFlag, ~0x00000002 ); } /* end SIO2_TransferInit0 */
///////////////////////////////////////////////////////////////////////[0E] void SifInitRpc(int mode){ u32 x; _dprintf("%s\n", __FUNCTION__); SifInitCmd(); CpuSuspendIntr(&x); if (sifInitRpc){ CpuResumeIntr(x); }else{ sifInitRpc=1; rpc_common.paddr=(RPC_PACKET*)bufx; rpc_common.size=32; rpc_common.paddr2=0; rpc_common.size2=0; rpc_common.next=(RPC_PACKET*)bufy; rpc_common.count=32; rpc_common.base=0; rpc_common.pid=1; SifAddCmdHandler(0x80000008, (cmdh_func)cmd80000008_END, &rpc_common); SifAddCmdHandler(0x80000009, (cmdh_func)cmd80000009_BIND, &rpc_common); SifAddCmdHandler(0x8000000A, (cmdh_func)cmd8000000A_CALL, &rpc_common); SifAddCmdHandler(0x8000000C, (cmdh_func)cmd8000000C_RDATA, &rpc_common); CpuResumeIntr(x); ((SifCmdSRData*)bufx)->rno =0; ((SifCmdSRData*)bufx)->value=1; SifSendCmd(0x80000001, (void*)bufx, sizeof(SifCmdSRData), 0, 0, 0); } WaitEventFlag(GetSystemStatusFlag(), 0x800, 0, 0); }
void SIO2_TransferInit1 ( void ) { SetEventFlag ( s_EventFlag, 0x00000004 ); WaitEventFlag ( s_EventFlag, 0x00000008, 0, NULL ); ClearEventFlag ( s_EventFlag, ~0x00000008 ); } /* end SIO2_TransferInit1 */
/* 25 */ int sio2_transfer(sio2_transfer_data_t *td) { transfer_data = td; SetEventFlag(event_flag, EF_TRANSFER_START); WaitEventFlag(event_flag, EF_TRANSFER_FINISH, 0, NULL); ClearEventFlag(event_flag, ~EF_TRANSFER_FINISH); return 1; }
int SIO2_Transfer ( SIO2_TransferData* apData ) { s_pTransferData = apData; SetEventFlag ( s_EventFlag, 0x00000400 ); WaitEventFlag ( s_EventFlag, 0x00000800, 0, NULL ); ClearEventFlag ( s_EventFlag, ~0x00000800 ); return 1; } /* end SIO2_Transfer */
void UBUFThread(void *arg){ void (*RequestResponseHandler)(unsigned int header, volatile unsigned int *buffer, unsigned int nQuads); unsigned int data, DataBufferLevel; u32 ef_bits; while(1){ WaitEventFlag(IntrEventFlag, iLinkEventBusReset|iLinkEventURx, WEF_OR, &ef_bits); ClearEventFlag(IntrEventFlag, ~(iLinkEventBusReset|iLinkEventURx)); while((DataBufferLevel=ILINKRegisterBase->ubufReceiveLevel)>0){ data=ILINKRegisterBase->ubufReceive; iDEBUG_PRINTF("Handling UBUF data... handler: 0x%02lx.\n", (data>>4)&0xF); RequestResponseHandler=RequestHandlers[(data>>4)&0xF]; RequestResponseHandler(data, (volatile unsigned int *)&ILINKRegisterBase->ubufReceive, DataBufferLevel-1); } } }
void callbackThreadFunc(void *arg) { u32 eventRes; int intrStat; IoRequest *req; IoRequest reqCopy; while (1) { WaitEventFlag(callbackEvent, 1, WEF_CLEAR | WEF_OR, &eventRes); do { CpuSuspendIntr(&intrStat); req = cbListStart; if (req) { if (req->next) req->next->prev = req->prev; else cbListEnd = req->prev; if (req->prev) req->prev->next = req->next; else cbListStart = req->next; } CpuResumeIntr(intrStat); if (req) { memcpy(&reqCopy, req, sizeof(IoRequest)); usbdLock(); freeIoRequest(req); usbdUnlock(); if (reqCopy.userCallbackProc) { SetGP(req->gpSeg); reqCopy.userCallbackProc(reqCopy.resultCode, reqCopy.transferedBytes, reqCopy.userCallbackArg); SetGP(&_gp); } } } while (req); } }
void update_slot_numbers_thread() { while(1) { u32 resbits, port; s32 slots; WaitEventFlag(event_flag, EF_UPDATE_SLOTS | EF_EXIT_THREAD, 0x11, &resbits); if((resbits & EF_EXIT_THREAD) == 1) { SetEventFlag(event_flag, 0x4); ExitThread(); } for(port=0; port < 4; port++) { if(state_open[port] == 1) { if(state_getcon[port] == 0) slots = get_slot_number(port, 10); else slots = get_slot_number(port, 0); if(slots < 0) { state_slots[port] = 1; state_getcon[port] = 0; } else { state_slots[port] = slots; state_getcon[port] = 1; } } } } }
static void write_thread(void *arg) { USE_SPD_REGS; volatile iop_dmac_chan_t *dev9_chan = (volatile iop_dmac_chan_t *)DEV9_DMAC_BASE; struct eng_args *args = (struct eng_args *)arg; ata_dma_transfer_t *t = &dma_transfer; u32 res; while (1) { while (SleepThread() || WaitSema(args->semid)) ; ClearEventFlag(args->evflg, 0); dma_setup(1); EnableIntr(IOP_IRQ_DMA_DEV9); /* Initiate the DMA transfer. */ dev9_chan->madr = (u32)dma_buffer; dev9_chan->bcr = ((t->size / 128) << 16) | 32; dev9_chan->chcr = 0x01000201; SPD_REG8(0x4e) = t->command; /* ATA command register. */ SPD_REG8(SPD_R_PIO_DIR) = 1; SPD_REG8(SPD_R_PIO_DATA) = 0; SPD_REG8(SPD_R_XFR_CTRL) |= 0x80; WaitEventFlag(args->evflg, (EF_DMA_DONE|EF_ATA_DONE), 0x11, &res); SPD_REG8(SPD_R_XFR_CTRL) &= 0x7f; DisableIntr(IOP_IRQ_DMA_DEV9, NULL); /* If we got the ATA end signal, force stop the transfer. */ if (res & EF_ATA_DONE) dma_stop(1); SignalSema(args->semid); } }
int NetManSetLinkMode(int mode){ int result, evfid; WaitSema(NetManIOSemaID); if(MainNetIF!=NULL){ evfid = MainNetIF->EventFlagID; ClearEventFlag(evfid, ~NETMAN_NETIF_EVF_DOWN); result = MainNetIF->ioctl(NETMAN_NETIF_IOCTL_ETH_SET_LINK_MODE, &mode, sizeof(mode), NULL, 0); } else{ evfid = -1; result = -1; } SignalSema(NetManIOSemaID); if(result == 0 && evfid >= 0) WaitEventFlag(evfid, NETMAN_NETIF_EVF_DOWN, WEF_OR, NULL); //Wait for the IF to go down. return result; }
///////////////////////////////////////////////////////////////////////[04] void SifInitCmd(){ __printf("iopSifInitCmd\n"); SifSetIOPEEflags(0x20000); WaitEventFlag(cmd_common.systemStatusFlag, 0x100, 0, 0); }
static void _MainThread ( void* apParam ) { u32 lBits[ 4 ]; u32 lEventFlag; while ( 1 ) { WaitEventFlag ( s_EventFlag, 0x00000155, 1, lBits ); if ( lBits[ 0 ] & 0x00000001 ) { /* SIO2_TransferInit0 */ ClearEventFlag ( s_EventFlag, ~0x00000001 ); lEventFlag = 0x00000002; } else if ( lBits[ 0 ] & 0x00000004 ) { /* SIO2_TransferInit1 */ ClearEventFlag ( s_EventFlag, ~0x00000004 ); lEventFlag = 0x00000008; } else if ( lBits[ 0 ] & 0x00000010 ) { /* SIO2_TransferInit2 */ ClearEventFlag ( s_EventFlag, ~0x00000010 ); lEventFlag = 0x00000020; } else if ( lBits[ 0 ] & 0x00000040 ) { /* SIO2_TransferInit3 */ ClearEventFlag ( s_EventFlag, ~0x00000040 ); lEventFlag = 0x00000080; } else if ( lBits[ 0 ] & 0x00000100 ) { /* SIO2_TransferInit4 */ ClearEventFlag ( s_EventFlag, ~0x00000100 ); lEventFlag = 0x00000200; } else break; loop: SetEventFlag ( s_EventFlag, lEventFlag ); WaitEventFlag ( s_EventFlag, 0x00001400, 1, lBits ); /* SIO2_Transfer or SIO2_TransferReset */ if ( lBits[ 0 ] & 0x00001000 ) { /* SIO2_TransferReset */ ClearEventFlag ( s_EventFlag, ~0x00001000 ); continue; } /* end if */ ClearEventFlag ( s_EventFlag, ~0x00000400 ); /* SIO2_Transfer */ SIO2_SwitchCtrlC (); _Send ( s_pTransferData ); SIO2_SwitchCtrl1 (); WaitEventFlag ( s_EventFlag, 0x00002000, 0, NULL ); ClearEventFlag ( s_EventFlag, ~0x00002000 ); _Recv ( s_pTransferData ); lEventFlag = 0x00000800; goto loop; } /* end while */ } /* end _MainThread */
static void MainThread(void *arg) { while(1) { u32 port, slot; mainThreadCount++; if( mainThreadCount % 30 == 0 ) sio2_mtap_update_slots(); for(port=0; port < 2; port++) { for(slot=0; slot < 4; slot++) { if( ((openSlots[port] >> slot) & 0x1) == 1) { pdSetActive(port, slot, 0); padState[port][slot].stat70bit = pdGetStat70bit(port, slot); if(padState[port][slot].runTask != TASK_NONE) { if(padState[port][slot].runTask == TASK_PORT_CLOSE) { padState[port][slot].currentTask = padState[port][slot].runTask; padState[port][slot].runTask = TASK_NONE; padState[port][slot].reqState = PAD_RSTAT_BUSY; SetEventFlag(padState[port][slot].eventflag, EF_EXIT_THREAD); } else { if(padState[port][slot].currentTask == TASK_UPDATE_PAD) { // Start Task StartThread(padState[port][slot].taskTid, NULL); padState[port][slot].currentTask = padState[port][slot].runTask; padState[port][slot].runTask = TASK_NONE; padState[port][slot].reqState = PAD_RSTAT_BUSY; } else { padState[port][slot].runTask = TASK_NONE; padState[port][slot].reqState = PAD_RSTAT_FAILED; } } } } switch(padState[port][slot].currentTask) { case TASK_UPDATE_PAD: { SetEventFlag(padState[port][slot].eventflag, EF_UPDATE_PAD); WaitEventFlag(padState[port][slot].eventflag, EF_PAD_TRANSFER_START, 0x10, 0); pdSetActive(port, slot, 1); } break; case TASK_QUERY_PAD: { padState[port][slot].buttonDataReady = 0; SetEventFlag(padState[port][slot].eventflag, EF_QUERY_PAD); WaitEventFlag(padState[port][slot].eventflag, EF_PAD_TRANSFER_START, 0x10, 0); pdSetActive(port, slot, 1); } break; case TASK_PORT_CLOSE: { if(GetThreadsStatus( &padState[port][slot] ) == 1) { padState[port][slot].currentTask = TASK_NONE; padState[port][slot].reqState = PAD_RSTAT_COMPLETE; openSlots[port] ^= (1 << slot); DeleteThreads( &padState[port][slot] ); SetEventFlag(padState[port][slot].eventflag, EF_PORT_CLOSE); } } break; case TASK_SET_MAIN_MODE: { padState[port][slot].buttonDataReady = 0; SetEventFlag(padState[port][slot].eventflag, EF_SET_MAIN_MODE); WaitEventFlag(padState[port][slot].eventflag, EF_PAD_TRANSFER_START, 0x10, 0); pdSetActive(port, slot, 1); } break; case TASK_SET_ACT_ALIGN: { padState[port][slot].buttonDataReady = 0; SetEventFlag(padState[port][slot].eventflag, EF_SET_ACT_ALIGN); WaitEventFlag(padState[port][slot].eventflag, EF_PAD_TRANSFER_START, 0x10, 0); pdSetActive(port, slot, 1); } break; case TASK_SET_BUTTON_INFO: { padState[port][slot].buttonDataReady = 0; SetEventFlag(padState[port][slot].eventflag, EF_SET_SET_BUTTON_INFO); WaitEventFlag(padState[port][slot].eventflag, EF_PAD_TRANSFER_START, 0x10, 0); pdSetActive(port, slot, 1); } break; case TASK_SET_VREF_PARAM: { padState[port][slot].buttonDataReady = 0; SetEventFlag(padState[port][slot].eventflag, EF_SET_VREF_PARAM); WaitEventFlag(padState[port][slot].eventflag, EF_PAD_TRANSFER_START, 0x10, 0); pdSetActive(port, slot, 1); } break; } } } // Transfer is started in VblankStart vblankData.stopTransfer = 0; WaitClearEvent(vblankData.eventflag, EF_VB_TRANSFER_DONE, WEF_AND|WEF_CLEAR, NULL); if( (openSlots[0] != 0) || (openSlots[1] != 0)) { for(port=0; port < 2; port++) { for(slot=0; slot < 4; slot++) { if(pdIsActive(port, slot) == 1) { /* Signal transfer done and wait to task (reading sio2 data) to be done. */ SetEventFlag(padState[port][slot].eventflag, EF_PAD_TRANSFER_DONE); WaitEventFlag(padState[port][slot].eventflag, EF_TASK_DONE, 0x10, 0); } } } } // Send pad data to EE DmaSendEE(); mainThreadCount2++; // s7 // Check for disconnected controllers if(mainThreadCount2 >= 8) { if(mainThreadCount % 30 != 0) { if( pdIsActive(pad_port, pad_slot) == 1) { if( padState[pad_port][pad_slot].state == PAD_STATE_DISCONN) pad_portdata[pad_port] &= ~(1 << pad_slot); // clear slot else pad_portdata[pad_port] |= (1 << pad_slot); // set slot } else { if( pdCheckConnection(pad_port, pad_slot) == 1) pad_portdata[pad_port] |= (1 << pad_slot); // set slot else pad_portdata[pad_port] &= ~(1 << pad_slot); // clear slot } //Move onto the next slot pad_slot++; if(pad_slot >= 4) { //Move onto the next port pad_slot = 0; pad_port++; if(pad_port >= 2) pad_port = 0; } mainThreadCount2 = 0; } } } }
void main_thread(void *unused) { u32 resbits[4]; while (1) { #ifndef XSIO2MAN log_flush(0); #endif WaitEventFlag(event_flag, EF_PAD_TRANSFER_INIT | EF_MC_TRANSFER_INIT | EF_MTAP_TRANSFER_INIT, 1, resbits); if (resbits[0] & EF_PAD_TRANSFER_INIT) { ClearEventFlag(event_flag, ~EF_PAD_TRANSFER_INIT); SetEventFlag(event_flag, EF_PAD_TRANSFER_READY); #ifndef XSIO2MAN log_default(LOG_PAD_READY); #endif } else if (resbits[0] & EF_MC_TRANSFER_INIT) { ClearEventFlag(event_flag, ~EF_MC_TRANSFER_INIT); SetEventFlag(event_flag, EF_MC_TRANSFER_READY); #ifndef XSIO2MAN log_default(LOG_MC_READY); #endif } else if (resbits[0] & EF_MTAP_TRANSFER_INIT) { ClearEventFlag(event_flag, ~EF_MTAP_TRANSFER_INIT); SetEventFlag(event_flag, EF_MTAP_TRANSFER_READY); #ifndef XSIO2MAN log_default(LOG_MTAP_READY); #endif } else { EPRINTF("Unknown event %08lx. Exiting.\n", resbits[0]); return; } transfer_loop: WaitEventFlag(event_flag, EF_TRANSFER_START | EF_TRANSFER_RESET, 1, resbits); if (resbits[0] & EF_TRANSFER_RESET) { ClearEventFlag(event_flag, ~EF_TRANSFER_RESET); #ifndef XSIO2MAN log_default(LOG_RESET); #endif continue; } ClearEventFlag(event_flag, ~EF_TRANSFER_START); sio2_ctrl_set(sio2_ctrl_get() | 0xc); send_td(transfer_data); sio2_ctrl_set(sio2_ctrl_get() | 1); WaitEventFlag(event_flag, EF_SIO2_INTR_COMPLETE, 0, NULL); ClearEventFlag(event_flag, ~EF_SIO2_INTR_COMPLETE); recv_td(transfer_data); SetEventFlag(event_flag, EF_TRANSFER_FINISH); /* Bah... this is needed to get the initial dump from XMCMAN, but it will kill the IOP when XPADMAN is spamming... TODO I guess the correct solution is to do all logging in a dedicated thread. */ // log_flush(1); goto transfer_loop; } }
/* Hardware event handling threads. */ static void iLinkIntrCBHandlingThread(void *arg){ #ifdef SIF_CALLBACKS_12_13 SifCmdHeader_t SifCmdData; #endif int nNodes, i, targetDeviceID, nodeID, result; static const unsigned char PayloadSizeLookupTable[]={ 7, /* S100; 2^(7+2)=512 */ 8, /* S200; 2^(8+2)=1024 */ 9, /* S400; 2^(9+2)=2048 */ }; while(1){ WaitEventFlag(sbp2_event_flag, BUS_RESET_COMPLETE, WEF_AND|WEF_CLEAR, NULL); /* Disconnect all currently connected nodes. */ for(i=0; i<MAX_DEVICES; i++){ if(SBP2Devices[i].trContext>=0){ releaseSBP2Device(&SBP2Devices[i]); iLinkTrFree(SBP2Devices[i].trContext); SBP2Devices[i].trContext = -1; #ifdef SIF_CALLBACKS_12_13 if(SBP2Devices[i].IsConnected){ SifCmdData.size=sizeof(SifCmdData); SifCmdData.dest=NULL; SifCmdData.cid=13; sceSifSendCmd(SifCmdData.cid, &SifCmdData, sizeof(SifCmdData), NULL, NULL, 0); } #endif } } if((nNodes=iLinkGetNodeCount())<0) XPRINTF("Critical error: Failure getting the number of nodes!\n"); /* Error. */ XPRINTF("BUS RESET DETECTED. Nodes: %d\n", nNodes); XPRINTF("Local Node: 0x%08x.\n", iLinkGetLocalNodeID()); //DelayThread(500000); /* Give the devices on the bus some time to initialize themselves (The SBP-2 standard states that a maximum of 5 seconds may be given). */ targetDeviceID=0; for(i=0; i<nNodes; i++){ if(targetDeviceID>=MAX_DEVICES){ XPRINTF("Warning! There are more devices that what can be connected to.\n"); break; } XPRINTF("Attempting to initialize unit %d...\n", i); /* 16-bit node ID = BUS NUMBER (Upper 10 bits) followed by the NODE ID (Lower 6 bits). */ if((nodeID=iLinkFindUnit(i, 0x0609e, 0x010483))<0){ XPRINTF("Error: Unit %d is not a valid SBP-2 device. Code: %d.\n", i, nodeID); continue; } XPRINTF("Detected SBP-2 device.\n"); SBP2Devices[targetDeviceID].InitiatorNodeID=iLinkGetLocalNodeID(); XPRINTF("Local Node: 0x%08x.\n", SBP2Devices[targetDeviceID].InitiatorNodeID); #if 0 if(SBP2Devices[targetDeviceID].IsConnected){ /* Already connected to the device. */ if(SBP2Devices[targetDeviceID].nodeID==nodeID){ /* Make sure that we're attempting to re-connect to the same device. */ if(ieee1394_SendManagementORB(SBP2_RECONNECT_REQUEST, &SBP2Devices[i])<0){ XPRINTF("Error reconnecting to the SBP-2 device %u.\n", nodeID); } else{ XPRINTF("Successfully reconnected to SBP-2 device %u.", nodeID); targetDeviceID++; continue; } } else SBP2Devices[targetDeviceID].IsConnected=0; } #endif SBP2Devices[targetDeviceID].IsConnected=0; /* Attempt a login into the device. */ SBP2Devices[targetDeviceID].nodeID=nodeID; if((result=initSBP2Disk(&SBP2Devices[targetDeviceID]))<0){ XPRINTF("Error initializing the device. Code: %d.\n", result); continue; } SBP2Devices[targetDeviceID].trContext=iLinkTrAlloc(nodeID, iLinkGetNodeMaxSpeed(nodeID)); if(SBP2Devices[targetDeviceID].trContext>=0){ XPRINTF("Connected device as node 0x%08x.\n", SBP2Devices[targetDeviceID].nodeID); XPRINTF("Generation number: %d.\n", iLinkGetGenerationNumber()); SBP2Devices[targetDeviceID].speed=iLinkGetNodeTrSpeed(SBP2Devices[targetDeviceID].trContext); XPRINTF("Current speed: %d.\n", SBP2Devices[targetDeviceID].speed); SBP2Devices[targetDeviceID].max_payload=PayloadSizeLookupTable[SBP2Devices[targetDeviceID].speed]; if(initConfigureSBP2Device(&SBP2Devices[targetDeviceID])>=0){ SBP2Devices[targetDeviceID].IsConnected=1; targetDeviceID++; #ifdef SIF_CALLBACKS_12_13 SifCmdData.size=sizeof(SifCmdData); SifCmdData.dest=NULL; SifCmdData.cid=12; sceSifSendCmd(SifCmdData.cid, &SifCmdData, sizeof(SifCmdData), NULL, NULL, 0); #endif } } else XPRINTF("Error allocating a transaction.\n"); } for(; targetDeviceID<MAX_DEVICES; targetDeviceID++) SBP2Devices[targetDeviceID].IsConnected=0; /* Mark the unused device slots as being unused. */ } }