void wifiModulesPatch1() { tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceThreadManager" ); //a0 = 4, change partition id to 4 if ( fw_version == FW_371 ) threadman_offset = 0x00010B30; else if ( fw_version == FW_380 || fw_version == FW_390 ) threadman_offset = 0x00010CB8; else if ( fw_version == FW_401 ) threadman_offset = 0x00012154; else if ( fw_version == FW_500 || fw_version == FW_550 ) threadman_offset = 0x000121E0; _sw( 0x34040004, pMod->text_addr + threadman_offset ); pMod = ( tSceModule * )sceKernelFindModuleByName( "sceModuleManager" ); //a3 stack size 0x40000 -> 0x10000 if ( fw_version == FW_371 ) modulemgr_offset = 0x000076A0; else if ( fw_version == FW_380 || fw_version == FW_390 ) modulemgr_offset = 0x00007C9C; else if ( fw_version == FW_401 ) modulemgr_offset = 0x00007C50; else if ( fw_version == FW_500 ) modulemgr_offset = 0x00007C84; //added for 5.50 else if ( fw_version == FW_550 ) modulemgr_offset = 0x00007F80; _sw( 0x3C070001, pMod->text_addr + modulemgr_offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
void patchMemPartitionInfo() { if ( model == PSP_MODEL_STANDARD ) sceKernelSetDdrMemoryProtection( ( void * )0x88300000, 0x00100000, 0xf ); else sceKernelSetDdrMemoryProtection( ( void * )0x88600000, 0x00200000, 0xf ); tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceSystemMemoryManager" ); // 0x02001021 move $v0 $s0 int offset = 0x00001304; if ( fw_version == FW_371 || fw_version == FW_380 || fw_version == FW_390 ) { offset = 0x00001304; //for 3.71, 3.80, 3.90 } else if ( fw_version == FW_401 ) { offset = 0x00003A68; //for 4.01 } else if ( fw_version == FW_500 || fw_version == FW_550 ) { offset = 0x00003AA8; //for 5.00 } _sw( 0x02001021, pMod->text_addr + offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); PspSysmemPartitionInfo info; memset( &info, 0, sizeof( PspSysmemPartitionInfo ) ); info.size = sizeof( PspSysmemPartitionInfo ); PspSysmemPartitionInfo * p_info = ( PspSysmemPartitionInfo * )sceKernelQueryMemoryPartitionInfo( 4, &info ); if ( model == PSP_MODEL_STANDARD ) p_info->startaddr = 0x08300000; else p_info->startaddr = 0x08600000; p_info->attr = 0xf; //restore _sw( 0x00001021, pMod->text_addr + offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
void restoreLoadExecVSHCommon() { _sw( LoadExecVSHCommon_ori[0].val, LoadExecVSHCommon_ori[0].addr ); _sw( LoadExecVSHCommon_ori[1].val, LoadExecVSHCommon_ori[1].addr ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
int sub_00000588(void) { int intr; void (*ptr)(u32) = (void*)g_func_1200; (*ptr)(0); open_iso(); intr = sceKernelCpuSuspendIntr(); /* sceUmdManGetUmdDiscInfo patch */ _sw(0xE0000800, g_sceNp9660_driver_text_addr + g_offs->Data1); _sw(0x00000009, g_sceNp9660_driver_text_addr + g_offs->Data2); _sw(g_total_blocks, g_sceNp9660_driver_text_addr + g_offs->Data3); _sw(g_total_blocks, g_sceNp9660_driver_text_addr + g_offs->Data4); _sw(0x00000000, g_sceNp9660_driver_text_addr + g_offs->Data5); sceKernelCpuResumeIntr(intr); if(g_data_1204 == 0) { g_data_1204 = 1; sceKernelDelayThread(800000); } clear_cache(); sceKernelSetQTGP3(g_umddata); return 0; }
int InitME(volatile struct me_struct *mei, int devkitVersion) { unsigned int k1; k1 = pspSdkSetK1(0); if (mei == 0) { pspSdkSetK1(k1); return -1; } // initialize the MediaEngine Instance mei->start = 0; mei->done = 1; mei->func = 0; mei->param = 0; mei->result = 0; mei->precache_len = 0; mei->precache_addr = 0; mei->postcache_len = 0; mei->postcache_addr = 0; mei->signals = 0; mei->init = 1; // start the MediaEngine memcpy((void *)0xbfc00040, me_stub, (int)(me_stub_end - me_stub)); _sw((unsigned int)me_loop, 0xbfc00600); // k0 _sw((unsigned int)mei, 0xbfc00604); // a0 sceKernelDcacheWritebackAll(); if (devkitVersion < 0x03070110) { sceSysregMeResetEnable(); sceSysregMeBusClockEnable(); sceSysregMeResetDisable(); } else { sceSysregMeResetEnable371(); sceSysregMeBusClockEnable371(); sceSysregMeResetDisable371(); } //Find SceMeRpc and disable it(causes indefinate wait when handling events, like suspend) PspSysEventHandler *handlers = sceKernelReferSysEventHandler(); while (handlers != NULL){ if (strcmp(handlers->name, "SceMeRpc") == 0){ handler = handlers; sceKernelUnregisterSysEventHandler(handler); break; } handlers = handlers->next; } pspSdkSetK1(k1); return 0; }
void patch_sceLoadExec(void) { //find loadexec module SceModule2 * loadexec = (SceModule2*)sctrlKernelFindModuleByName("sceLoadExec"); //allow all user levels to call sceKernelExitVSHVSH (needed for installer reboot) _sw(0x10000008, loadexec->text_addr + g_offs->loadexec_patch_other.sceKernelExitVSHVSHCheck1); _sw(NOP, loadexec->text_addr + g_offs->loadexec_patch_other.sceKernelExitVSHVSHCheck1); }
void wifiModulesPatch3() { tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceModuleManager" ); //restore _sw( 0x02403821, pMod->text_addr + modulemgr_offset ); pMod = ( tSceModule * )sceKernelFindModuleByName( "sceThreadManager" ); //restore _sw( 0x02402021, pMod->text_addr + threadman_offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
/** * Remember you have to export the hooker function if using syscall hook */ int hook_import_bynid(SceModule *pMod, char *library, unsigned int nid, void *func, int syscall) { PspModuleImport *pImp; void *stubTab; int stubLen; int i = 0; if(pMod == NULL) return -1; stubTab = pMod->stub_top; stubLen = pMod->stub_size; while(i<stubLen) { pImp = (PspModuleImport*)(stubTab+i); if((pImp->name) && (strcmp(pImp->name, library) == 0)) { int j; for(j=0; j<pImp->funcCount; j++) { if(pImp->fnids[j] == nid) { void *addr = (void*)(&pImp->funcs[j*2]); if(syscall) { u32 syscall_num; syscall_num = sctrlKernelQuerySystemCall(func); if(syscall_num == (u32)-1) { printk("%s: cannot find syscall in %s_%08X\n", __func__, library, nid); return -1; } _sw(0x03E00008, (u32)addr); _sw(MAKE_SYSCALL(syscall_num), (u32)(addr + 4)); } else { _sw(MAKE_JUMP(func), (u32)addr); _sw(NOP, (u32)(addr + 4)); } sceKernelDcacheWritebackInvalidateRange(addr, 8); sceKernelIcacheInvalidateRange(addr, 8); } } } i += (pImp->entLen * 4); } return 0; }
void sioSetBaud(int baud) { int div1, div2; // rate set using the rough formula div1 = (PSP_UART_CLK / baud) >> 6 and // div2 = (PSP_UART_CLK / baud) & 0x3F // The uart4 driver actually uses a slightly different formula for div 2 (it // adds 32 before doing the AND, but it doesn't seem to make a difference div1 = PSP_UART_CLK / baud; div2 = div1 & 0x3F; div1 >>= 6; _sw(div1, PSP_UART4_DIV1); _sw(div2, PSP_UART4_DIV2); _sw(0x60, PSP_UART4_CTRL); }
/** * Remember you have to export the hooker function if using syscall hook */ int hook_import_bynid(SceModule *pMod, char *library, unsigned int nid, void *func) { PspModuleImport *pImp; void *stubTab; int stubLen; int i = 0; if(pMod == NULL) return -1; stubTab = pMod->stub_top; stubLen = pMod->stub_size; while(i<stubLen) { pImp = (PspModuleImport*)(stubTab+i); if((pImp->name) && (strcmp(pImp->name, library) == 0)) { int j; for(j=0; j<pImp->funcCount; j++) { if(pImp->fnids[j] == nid) { void *addr = (void*)(&pImp->funcs[j*2]); if(func == NULL) { _sw(0x03E00008, (u32)addr); _sw(NOP, (u32)(addr + 4)); } else { // Partition Check SceModule2 * mod = (SceModule2 *)pMod; if(((mod->text_addr & 0x80000000) && (((uint32_t)func) & 0x80000000)) || ((mod->text_addr & 0x80000000) == 0 && (((uint32_t)func) & 0x80000000) == 0)) { REDIRECT_FUNCTION(func, addr); } else { _sw(0x03E00008, (u32)addr); _sw(MAKE_SYSCALL(sctrlKernelQuerySystemCall(func)), (u32)(addr + 4)); } } sceKernelDcacheWritebackInvalidateRange(addr, 8); sceKernelIcacheInvalidateRange(addr, 8); } } } i += (pImp->entLen * 4); } return 0; }
static int popcorn_patch_chain(SceModule2 *mod) { printk("%s: %s\n", __func__, mod->modname); if (0 == strcmp(mod->modname, "pops")) { u32 text_addr = mod->text_addr; printk("%s: patching pops\n", __func__); if(g_is_custom_ps1) { patch_decompress_data(text_addr); } if(g_icon0_status) { patch_icon0_size(text_addr); } sceMeAudio_67CD7972 = (void*)sctrlHENFindFunction("scePops_Manager", "sceMeAudio", g_offs->pops_patch.sceMeAudio_67CD7972_NID); hook_import_bynid((SceModule*)mod, "sceMeAudio", g_offs->pops_patch.sceMeAudio_67CD7972_NID, _sceMeAudio_67CD7972, 1); _sw(0x24020001, text_addr + g_offs->pops_patch.manualNameCheck[psp_model]); sync_cache(); } if( conf.noanalog ) { patch_analog_imports((SceModule*)mod); } if(g_previous) return g_previous(mod); return 0; }
static void patch_icon0_size(u32 text_addr) { u32 patch_addr; patch_addr = text_addr + g_offs->pops_patch.ICON0SizeOffset[psp_model]; _sw(0x24050000 | (sizeof(g_icon_png) & 0xFFFF), patch_addr); }
static int place_syscall_stub(void* func, void *addr) { u32 syscall_num; extern u32 sceKernelQuerySystemCall(void *func); syscall_num = sceKernelQuerySystemCall(func); if(syscall_num == (u32)-1) { return -1; } _sw(0x03E00008, (u32)addr); _sw(((syscall_num<<6)|12), (u32)(addr+4)); return 0; }
int InitME(volatile struct me_struct *mei, int devkitVersion) { unsigned int k1; k1 = pspSdkSetK1(0); if (mei == 0) { pspSdkSetK1(k1); return -1; } // initialize the MediaEngine Instance mei->start = 0; mei->done = 1; mei->func = 0; mei->param = 0; mei->result = 0; mei->precache_len = 0; mei->precache_addr = 0; mei->postcache_len = 0; mei->postcache_addr = 0; mei->signals = 0; mei->init = 1; // start the MediaEngine memcpy((void *)0xbfc00040, me_stub, (int)(me_stub_end - me_stub)); _sw((unsigned int)me_loop, 0xbfc00600); // k0 _sw((unsigned int)mei, 0xbfc00604); // a0 sceKernelDcacheWritebackAll(); if (devkitVersion < 0x03070110) { sceSysregMeResetEnable(); sceSysregMeBusClockEnable(); sceSysregMeResetDisable(); } else { sceSysregMeResetEnable371(); sceSysregMeBusClockEnable371(); sceSysregMeResetDisable371(); } pspSdkSetK1(k1); return 0; }
// Read out the interrupt state and clear it static int intr_handler(void *arg) { u32 stat; stat = _lw(0xBE500040); _sw(stat, 0xBE500044); sceKernelDisableIntr(PSP_HPREMOTE_INT); sceKernelSetEventFlag(g_eventflag, EVENT_SIO); return -1; }
void kernel_function() { /* Set k1 */ asm("move $k1, $0\n"); /* Repair sysmem */ _sw(0x0200D821, 0x8800F714); _sw(0x3C038801, 0x8800F718); _sw(0x8C654384, 0x8800F71C); /* Patch loadexec */ SceModule2 *mod = _sceKernelFindModuleByName("sceLoadExec"); u32 text_addr = mod->text_addr; MAKE_JUMP(text_addr + 0x2E30, Reboot_Entry); /* Allow LoadExecVSH in whatever user level */ _sh(0x1000, text_addr + 0x241E); _sw(0, text_addr + 0x2460); _sceKernelIcacheInvalidateAll(); _sceKernelDcacheWritebackInvalidateAll(); MakeFileList(); /* Load Eboot */ int (* LoadExecVSH)(int apitype, const char *file, struct SceKernelLoadExecVSHParam *param, int unk2) = (void *)text_addr + 0x23D0; char program[64]; strcpy(program, rebootex_config.savedata_path); strcat(program, "/MENU.PBP"); struct SceKernelLoadExecVSHParam param; memset(¶m, 0, sizeof(param)); param.size = sizeof(param); param.argp = program; param.args = strlen(param.argp) + 1; param.key = "game"; LoadExecVSH(PSP_INIT_APITYPE_MS2, program, ¶m, 0x10000); }
// 0x000003D8 int myKernelStartThread(SceUID thid, SceSize arglen, void *argp) { if(g_SceNpUmdMount_thid == thid) { SceModule2 *pMod; pMod = (SceModule2*) sceKernelFindModuleByName("sceNp9660_driver"); g_sceNp9660_driver_text_addr = pMod->text_addr; // 6.30: 0x00003C34 // 6.20: move to 0x00003BD8: jal InitForKernel_29DAA63F _sw(0x3C028000, g_sceNp9660_driver_text_addr + g_offs->InitForKernelCall); // jal InitForKernel_23458221 to lui $v0, 0x00008000 // 6.30: 0x00003C4C // 6.20: move to 0x00003BF0: jal sub_00000000 _sw(MAKE_CALL(sub_00000588), g_sceNp9660_driver_text_addr + g_offs->Func1); // 6.30: 0x000043B4 // 6.20: move to 0x00004358: jal sub_00004388 _sw(MAKE_CALL(sub_00000054), g_sceNp9660_driver_text_addr + g_offs->Func2); // jal sub_3948 to jal sub_00000054 // 6.30: 0x0000590C // 6.20: move to 0x0000582C: jal sub_00004388 _sw(MAKE_CALL(sub_00000054), g_sceNp9660_driver_text_addr + g_offs->Func3); // jal sub_3948 to jal sub_00000054 // 6.30: 0x00007D08 // 6.20: move to 0x00007C28 _sw(MAKE_JUMP(sub_00000514), g_sceNp9660_driver_text_addr + g_offs->sceIoClose); // hook sceIoClose import // 6.30: 0x00003680 // 6.20: move to 0x00003624 g_func_1200 = pMod->text_addr + g_offs->Func4; printk("g_func_1200 0x%08X\n", (uint)g_func_1200); // sub_2f30 // 6.30: 0x00004F8C // 6.20: move to 0x00004EAC g_func_1208 = pMod->text_addr + g_offs->Func5; printk("g_func_1208 0x%08X\n", (uint)g_func_1208); // sub_4494 // 6.30: 0x00004FFC // 6.20: move to 0x00004F1C g_func_121C = pMod->text_addr + g_offs->Func6; printk("g_func_121C 0x%08X\n", (uint)g_func_121C); // sub_44ec clear_cache(); } return sceKernelStartThread(thid, arglen, argp); }
void unlock_high_memory(u32 forced) { if(!is_homebrews_runlevel() && !forced && !g_high_memory_enabled) { return; } //unlock memory unsigned int i = 0; for(; i < 0x40; i += 4) { _sw(0xFFFFFFFF, 0xBC000040 + i); } }
static void patch_scePops_Manager(void) { SceModule2 *mod; u32 text_addr; size_t i; mod = (SceModule2*) sceKernelFindModuleByName("scePops_Manager"); text_addr = mod->text_addr; for(i=0; i<NELEMS(g_io_hooks); ++i) { hook_import_bynid((SceModule*)mod, "IoFileMgrForKernel", g_io_hooks[i].nid, g_io_hooks[i].fp, 0); } if(g_offs->popsman_patch.get_rif_path != 0xDEADBEEF) { _get_rif_path = (void*)(text_addr + g_offs->popsman_patch.get_rif_path); _sw(MAKE_CALL(&get_rif_path), text_addr + g_offs->popsman_patch.get_rif_path_call1); _sw(MAKE_CALL(&get_rif_path), text_addr + g_offs->popsman_patch.get_rif_path_call2); } sceNpDrmGetVersionKey = (void*)sctrlHENFindFunction("scePspNpDrm_Driver", "scePspNpDrm_driver", 0x0F9547E6); scePspNpDrm_driver_9A34AC9F = (void*)sctrlHENFindFunction("scePspNpDrm_Driver", "scePspNpDrm_driver", 0x9A34AC9F); if(g_offs->popsman_patch.sceNpDrmGetVersionKeyCall != 0xDEADBEEF) { _sw(MAKE_CALL(_sceNpDrmGetVersionKey), text_addr + g_offs->popsman_patch.sceNpDrmGetVersionKeyCall); } if(g_offs->popsman_patch.scePspNpDrm_driver_9A34AC9F_Call != 0xDEADBEEF) { _sw(MAKE_CALL(_scePspNpDrm_driver_9A34AC9F), text_addr + g_offs->popsman_patch.scePspNpDrm_driver_9A34AC9F_Call); } // remove the check in scePopsManLoadModule that only allows loading module below the FW 3.XX if(g_offs->popsman_patch.scePopsManLoadModuleCheck != 0xDEADBEEF) { _sw(NOP, text_addr + g_offs->popsman_patch.scePopsManLoadModuleCheck); } if (g_is_custom_ps1) { for(i=0; i<NELEMS(g_amctrl_hooks); ++i) { hook_import_bynid((SceModule*)mod, "sceAmctrl_driver", g_amctrl_hooks[i].nid, g_amctrl_hooks[i].fp, 0); } } }
int sio_getc() { /* Do we have something in the RX FIFO? */ if (_lw(SIO_ISR) & 0xf00) { u8 b = _lb(SIO_RXFIFO); _sw(7, SIO_ISR); return b; } /* Return EOF. */ return -1; }
void patch_sceSystemMemoryManager(void) { int i; // allow invalid complied sdk version for(i=0; i<NELEMS(g_offs->sysmem_patch.sysmemforuser_patch); ++i) { if(g_offs->sysmem_patch.sysmemforuser_patch[i].offset == 0xFFFF) continue; _sw(g_offs->sysmem_patch.sysmemforuser_patch[i].value | 0x10000000, SYSMEM_TEXT_ADDR + g_offs->sysmem_patch.sysmemforuser_patch[i].offset); } }
void wifiModulesPatch2() { if ( fw_version == FW_550 ) { //module renamed to sceNet_Service in 5.50 tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceNet_Service" ); //a2 partid = 4 of ifhandle _sw( 0x34050004, pMod->text_addr + 0x000014D8 ); //for 5.50 } else { tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceNetInterface_Service" ); _sw( 0x34050004, pMod->text_addr + 0x00001440 ); //for 3.71, 3.80, 3.90, 4.01, 5.00 } tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceNet_Library" ); unsigned int net_offset = 0; if ( fw_version == FW_371 || fw_version == FW_380 || fw_version == FW_390 ) net_offset = 0x00001800; else if ( fw_version == FW_401 ) net_offset = 0x00002320; else if ( fw_version == FW_500 || fw_version == FW_550 ) net_offset = 0x00002348; _sw( 0x34020002, pMod->text_addr + net_offset ); _sw( 0xAFA20000, pMod->text_addr + net_offset + 0x4 ); _sw( 0x3C020000, pMod->text_addr + net_offset + 0xC ); pMod = ( tSceModule * )sceKernelFindModuleByName( "sceModuleManager" ); //a3 stack size 0x10000 -> 0x4000 _sw( 0x34074000, pMod->text_addr + modulemgr_offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
/* Initialize the SIO. The lcr_* parameters are passed as is, so you'll need to use the SIO_LCR_* register values. You can pass 0 for all of the lcr_* params to get the standard 8N1 setting (8 data bits, no parity checking, 1 stop bit). Note: Unlike the BIOS sio_init() routine, we always base the baud rate on the CPU clock. */ void sio_init(u32 baudrate, u8 lcr_ueps, u8 lcr_upen, u8 lcr_usbl, u8 lcr_umode) { u32 brd; /* Baud rate divisor. */ u8 bclk = 0; /* Baud rate generator clock. */ _sw(LCR_SCS_VAL|((lcr_ueps & 1) << 4)|((lcr_upen & 1) << 3)| ((lcr_usbl & 1) << 2)|(lcr_umode & 1), SIO_LCR); /* Disable all interrupts. */ _sw(0, SIO_IER); /* Reset the FIFOs. */ _sw(SIO_FCR_FRSTE|SIO_FCR_RFRST|SIO_FCR_TFRST, SIO_FCR); /* Enable them. */ _sw(0, SIO_FCR); brd = CPUCLK / (baudrate * 256); while ((brd >= 256) && (++bclk < 4)) brd /= 4; _sw((bclk << 8) | brd, SIO_BGR); }
// mode: 0 - OFW 1 - CFW void patch_sceLoadExec(int mode) { SceModule2 * loadexec = (SceModule2*)sctrlKernelFindModuleByName("sceLoadExec"); u32 text_addr; struct sceLoadExecPatch *patch; if (loadexec == NULL) { return; } text_addr = loadexec->text_addr; if(psp_model == PSP_GO) { // PSP-N1000 patch = &g_offs->loadexec_patch_05g; } else { patch = &g_offs->loadexec_patch_other; } //save LoadReboot function LoadReboot = (void*)loadexec->text_addr; if(mode == 0) { //restore LoadReboot _sw(MAKE_CALL(LoadReboot), loadexec->text_addr + patch->LoadRebootCall); //restore jmp to 0x88600000 _sw(0x3C018860, loadexec->text_addr + patch->RebootJump); } else if(mode == 1) { //replace LoadReboot function _sw(MAKE_CALL(load_reboot), loadexec->text_addr + patch->LoadRebootCall); //patch Rebootex position to 0x88FC0000 _sw(0x3C0188FC, loadexec->text_addr + patch->RebootJump); // lui $at, 0x88FC } sync_cache(); }
void disable_PauseGame(u32 text_addr) { int i, apitype; if(psp_model != PSP_GO) { return; } apitype = sceKernelInitApitype(); if(g_high_memory_enabled || (conf.iso_cache && apitype == 0x125)) { for(i=0; i<g_offs->impose_patch.nr_nop; i++) { _sw(NOP, text_addr + g_offs->impose_patch.offset + i * 4); } } }
int sub_00000514(int fd) { int ret; ret = sceIoClose(fd); if(fd == g_iso_fd) { g_iso_fd = -1; _sw(-1, g_sceNp9660_driver_text_addr + g_offs->StoreFd); clear_cache(); return ret; } else { return ret; } }
static int patch_decompress_data(u32 text_addr) { int ret; void *stub_addr, *patch_addr; stub_addr = (void*)(text_addr + g_offs->pops_patch.decomp[psp_model].stub_offset); patch_addr = (void*)(text_addr + g_offs->pops_patch.decomp[psp_model].patch_offset); ret = place_syscall_stub(decompress_data, stub_addr); if (ret != 0) { printk("%s: place_syscall_stub -> 0x%08X\n", __func__, ret); return -1; } _sw(MAKE_CALL(stub_addr), (u32)patch_addr); return 0; }
static void dma_stop(int val) { USE_SPD_REGS; u8 if_ctrl; _sw(0, DEV9_DMAC_CHCR); SPD_REG8(SPD_R_XFR_CTRL) = 0; SPD_REG8(SPD_R_IF_CTRL) = SPD_REG8(SPD_R_IF_CTRL) & 0xfb; if (val) { if_ctrl = SPD_REG8(SPD_R_IF_CTRL); SPD_REG8(SPD_R_IF_CTRL) = SPD_IF_ATA_RESET; DelayThread(100); SPD_REG8(SPD_R_IF_CTRL) = if_ctrl; } /*M_PRINTF("ATA DMA force break\n");*/ }
int main(void) { SceCtrlData pad; pspDebugScreenInit(); SetupCallbacks(); /* Install our custom exception handler. If this was NULL then the default would be used */ pspDebugInstallErrorHandler(MyExceptionHandler); sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); pspDebugScreenPrintf("Exception Sample\n\n"); pspDebugScreenPrintf("You have two choices, press O for a bus error or X for a breakpoint\n\n"); while(1) { sceCtrlReadBufferPositive(&pad, 1); if(pad.Buttons & PSP_CTRL_CIRCLE) { /* Cause a bus error */ _sw(0, 0); } if(pad.Buttons & PSP_CTRL_CROSS) { /* Cause a break exception */ asm( "break\r\n" ); } sceDisplayWaitVblankStart(); } /* We will never end up here, hopefully */ printf("End\n"); sceKernelExitDeleteThread(0); return 0; }
int _start(int argc, char *argv[]) { iop_event_t event; int semid, evflg, res; if ((semid = CreateMutex(IOP_MUTEX_UNLOCKED)) < 0) { E_PRINTF("Unable to create %s (error %d).\n", "semaphore", semid); return 1; } eng_args.semid = semid; event.attr = event.bits = 0; if ((evflg = CreateEventFlag(&event)) < 0) { E_PRINTF("Unable to create %s (error %d).\n", "event flag", evflg); return 1; } eng_args.evflg = evflg; CpuEnableIntr(); DisableIntr(IOP_IRQ_DMA_DEV9, NULL); if ((res = RegisterIntrHandler(IOP_IRQ_DMA_DEV9, 1, dev9_dma_handler, &eng_args.evflg))) { E_PRINTF("Unable to register 0x%02x intr handler (error %d).\n", IOP_IRQ_DMA_DEV9, res); return 1; } _sw(_lw(0xbf801570) | 0x80, 0xbf801570); if ((res = ata_engine_init(&eng_args)) < 0) { E_PRINTF("Unable to initialize the %s DMA engine.\n", "ATA"); return 1; } if ((res = smap_engine_init(&eng_args)) < 0) { E_PRINTF("Unable to initialize the %s DMA engine.\n", "SMAP"); return 1; } M_PRINTF("ATA/SMAP DMA relay module initialized.\n"); return 0; }