static void _log_handler (char const *log_domain, GLogLevelFlags log_level, char const *message, gpointer user_data) { char const *topic; char const *location = NULL; unsigned topic_flag = 0; /* A bit of a hack, the domain has the format "ytstenut\0topic", * so look what's past the \0 for the topic. */ topic = &log_domain[strlen (log_domain) + 1]; if (0 != g_strcmp0 ("unspecified", topic)) { location = &topic[strlen (topic) + 1]; if (location[0] == '.' && location[1] == '/') location += 2; } if (_debug_flags) { /* == We are in debug mode. == */ for (unsigned i = 1; i < G_N_ELEMENTS (_debug_keys); i++) { if (0 == g_strcmp0 (topic, _debug_keys[i].key)) { topic_flag = _debug_keys[i].value; break; } } if (_debug_flags & topic_flag) { if (YTS_DEBUG_BRIEF & _debug_flags) { log_brief (log_level, location ? location : topic, message); } else { log_default (log_domain, log_level, topic, location, message); } } } else { /* == Not in debug mode == * Only print debug messages (there should not be any in a tarball release), * and exceptions. */ GLogLevelFlags log_mask = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_DEBUG; if (log_level & log_mask) { log_default (log_domain, log_level, topic, location, message); } } }
void send_td(sio2_transfer_data_t *td) { int i; #ifndef XSIO2MAN log_default(LOG_TRS); #endif for (i = 0; i < 4; i++) { sio2_portN_ctrl1_set(i, td->port_ctrl1[i]); sio2_portN_ctrl2_set(i, td->port_ctrl2[i]); } #ifndef XSIO2MAN log_portdata(td->port_ctrl1, td->port_ctrl2); #endif for (i = 0; i < 16; i++) sio2_regN_set(i, td->regdata[i]); #ifndef XSIO2MAN log_regdata(td->regdata); #endif if (td->in_size) { for (i = 0; i < td->in_size; i++) sio2_data_out(td->in[i]); #ifndef XSIO2MAN log_data(LOG_TRS_DATA, td->in, td->in_size); #endif } if (td->in_dma.addr) { dmac_request(IOP_DMAC_SIO2in, td->in_dma.addr, td->in_dma.size, td->in_dma.count, DMAC_FROM_MEM); dmac_transfer(IOP_DMAC_SIO2in); #ifndef XSIO2MAN log_dma(LOG_TRS_DMA_IN, &td->in_dma); #endif } if (td->out_dma.addr) { dmac_request(IOP_DMAC_SIO2out, td->out_dma.addr, td->out_dma.size, td->out_dma.count, DMAC_TO_MEM); dmac_transfer(IOP_DMAC_SIO2out); #ifndef XSIO2MAN log_dma(LOG_TRS_DMA_OUT, &td->out_dma); #endif } }
void recv_td(sio2_transfer_data_t *td) { int i; #ifndef XSIO2MAN log_default(LOG_TRR); #endif td->stat6c = sio2_stat6c_get(); td->stat70 = sio2_stat70_get(); td->stat74 = sio2_stat74_get(); #ifndef XSIO2MAN log_stat(td->stat6c, td->stat70, td->stat74); #endif if (td->out_size) { for (i = 0; i < td->out_size; i++) td->out[i] = sio2_data_in(); #ifndef XSIO2MAN log_data(LOG_TRR_DATA, td->out, td->out_size); #endif } }
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; } }