/* RetroArch - A frontend for libretro. * Copyright (C) 2010-2013 - Hans-Kristian Arntzen * Copyright (C) 2011-2013 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #include #if defined(__CELLOS_LV2__) #include #include #include #include #include #include #elif defined(_XBOX) #include #elif defined(HW_RVL) #include #include #include #include #include #include #include #include #define EXECUTE_ADDR ((uint8_t *) 0x91800000) #define BOOTER_ADDR ((uint8_t *) 0x93000000) #define ARGS_ADDR ((uint8_t *) 0x93200000) extern uint8_t _binary_wii_app_booter_app_booter_bin_start[]; extern uint8_t _binary_wii_app_booter_app_booter_bin_end[]; #define booter_start _binary_wii_app_booter_app_booter_bin_start #define booter_end _binary_wii_app_booter_app_booter_bin_end #elif defined(HW_DOL) #include "../ngc/sidestep.h" #endif #include "rarch_console_exec.h" #include "../retroarch_logger.h" #ifdef HW_RVL // NOTE: this does not update the path to point to the new loading .dol file. // we only need it for keeping the current directory anyway. void dol_copy_argv_path(void) { struct __argv *argv = (struct __argv *) ARGS_ADDR; memset(ARGS_ADDR, 0, sizeof(struct __argv)); char *cmdline = (char *) ARGS_ADDR + sizeof(struct __argv); argv->argvMagic = ARGV_MAGIC; argv->commandLine = cmdline; size_t len = strlen(__system_argv->argv[0]); memcpy(cmdline, __system_argv->argv[0], ++len); cmdline[len++] = 0; cmdline[len++] = 0; argv->length = len; DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length); } #endif void rarch_console_exec(const char *path) { RARCH_LOG("Attempt to load executable: [%s].\n", path); #if defined(_XBOX) XLaunchNewImage(path, NULL); #elif defined(__CELLOS_LV2__) char spawn_data[256]; for(unsigned int i = 0; i < sizeof(spawn_data); ++i) spawn_data[i] = i & 0xff; char spawn_data_size[16]; snprintf(spawn_data_size, sizeof(spawn_data_size), "%d", 256); const char * const spawn_argv[] = { spawn_data_size, "test argv for", "sceNpDrmProcessExitSpawn2()", NULL }; SceNpDrmKey * k_licensee = NULL; int ret = sceNpDrmProcessExitSpawn2(k_licensee, path, (const char** const)spawn_argv, NULL, (sys_addr_t)spawn_data, 256, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M); if(ret < 0) { RARCH_WARN("SELF file is not of NPDRM type, trying another approach to boot it...\n"); sys_game_process_exitspawn(path, NULL, NULL, NULL, 0, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M); } sceNpTerm(); sys_net_finalize_network(); cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); #elif defined(HW_RVL) FILE * fp = fopen(path, "rb"); if (fp == NULL) { RARCH_ERR("Could not execute DOL file.\n"); return; } fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0, SEEK_SET); fread(EXECUTE_ADDR, 1, size, fp); fclose(fp); DCFlushRange(EXECUTE_ADDR, size); dol_copy_argv_path(); fatUnmount("carda:"); fatUnmount("cardb:"); fatUnmount("sd:"); fatUnmount("usb:"); __io_wiisd.shutdown(); __io_usbstorage.shutdown(); size_t booter_size = booter_end - booter_start; memcpy(BOOTER_ADDR, booter_start, booter_size); DCFlushRange(BOOTER_ADDR, booter_size); RARCH_LOG("jumping to %08x\n", (unsigned) BOOTER_ADDR); SYS_ResetSystem(SYS_SHUTDOWN,0,0); __lwp_thread_stopmultitasking((void (*)(void)) BOOTER_ADDR); #elif defined(HW_DOL) DOLtoARAM(path); #else RARCH_WARN("External loading of executables is not supported for this platform.\n"); #endif }