mirror of
https://github.com/libretro/RetroArch
synced 2025-02-06 00:39:53 +00:00
(Netplay/Wii) Launch compatibility patch (#14230)
This commit is contained in:
parent
2c3c9e1e71
commit
d7a30f2a18
@ -20,6 +20,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/iosupport.h>
|
||||
|
||||
#include <gccore.h>
|
||||
@ -161,142 +162,163 @@ static void gx_devthread(void *a)
|
||||
extern char gx_rom_path[PATH_MAX_LENGTH];
|
||||
#endif
|
||||
|
||||
static void frontend_gx_get_env(
|
||||
int *argc, char *argv[],
|
||||
static void frontend_gx_get_env(int *argc, char *argv[],
|
||||
void *args, void *params_data)
|
||||
{
|
||||
char *last_slash = NULL;
|
||||
char *device_end = NULL;
|
||||
#if defined(HAVE_LOGGER) && !defined(IS_SALAMANDER)
|
||||
logger_init();
|
||||
#endif
|
||||
char *slash;
|
||||
#ifndef IS_SALAMANDER
|
||||
|
||||
/* This situation can happen on some loaders so we really need some
|
||||
fake args or else retroarch will just crash on parsing NULL pointers */
|
||||
if(*argc == 0 || !argv)
|
||||
{
|
||||
struct rarch_main_wrap *args = (struct rarch_main_wrap*)params_data;
|
||||
if (args)
|
||||
{
|
||||
args->touched = true;
|
||||
args->no_content = false;
|
||||
args->verbose = false;
|
||||
args->config_path = NULL;
|
||||
args->sram_path = NULL;
|
||||
args->state_path = NULL;
|
||||
args->content_path = NULL;
|
||||
args->libretro_path = NULL;
|
||||
}
|
||||
}
|
||||
struct rarch_main_wrap *params = (struct rarch_main_wrap*)params_data;
|
||||
#endif
|
||||
|
||||
#ifdef HW_DOL
|
||||
chdir("carda:/retroarch");
|
||||
#endif
|
||||
getcwd(g_defaults.dirs[DEFAULT_DIR_CORE], PATH_MAX_LENGTH);
|
||||
#if defined(HW_RVL) && !defined(IS_SALAMANDER)
|
||||
/* When using external loaders(Wiiflow etc.), getcwd doesn't return the path correctly and
|
||||
* as a result the cfg file is not found. */
|
||||
if (*argc > 2 && argv[1] != NULL && argv[2] != NULL)
|
||||
|
||||
getcwd(g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
|
||||
|
||||
#ifndef IS_SALAMANDER
|
||||
#ifdef HAVE_LOGGER
|
||||
logger_init();
|
||||
#endif
|
||||
|
||||
/* This situation can happen on some loaders so we really need some fake
|
||||
args or else RetroArch will just crash on parsing NULL pointers. */
|
||||
if (*argc <= 0 || !argv)
|
||||
{
|
||||
if (strncmp("usb1", argv[0], 4) == 0 || strncmp("usb2", argv[0], 4) == 0)
|
||||
if (params)
|
||||
{
|
||||
strncpy(g_defaults.dirs[DEFAULT_DIR_CORE],argv[0], strlen(argv[0]));
|
||||
strncpy(g_defaults.dirs[DEFAULT_DIR_CORE]," usb", 4);
|
||||
memmove(g_defaults.dirs[DEFAULT_DIR_CORE], g_defaults.dirs[DEFAULT_DIR_CORE]+1, strlen(g_defaults.dirs[DEFAULT_DIR_CORE]));
|
||||
}
|
||||
if(gx_devices[GX_DEVICE_SD].mounted)
|
||||
{
|
||||
chdir("sd:/");
|
||||
}
|
||||
else if(gx_devices[GX_DEVICE_USB].mounted)
|
||||
{
|
||||
chdir("usb:/");
|
||||
params->content_path = NULL;
|
||||
params->sram_path = NULL;
|
||||
params->state_path = NULL;
|
||||
params->config_path = NULL;
|
||||
params->libretro_path = NULL;
|
||||
params->verbose = false;
|
||||
params->no_content = false;
|
||||
params->touched = true;
|
||||
}
|
||||
}
|
||||
#ifdef HW_RVL
|
||||
else if (*argc > 2 &&
|
||||
!string_is_empty(argv[1]) && !string_is_empty(argv[2]))
|
||||
{
|
||||
#ifdef HAVE_NETWORKING
|
||||
/* If the process was forked for netplay purposes,
|
||||
DO NOT touch the arguments. */
|
||||
if (!string_is_equal(argv[1], "-H") && !string_is_equal(argv[1], "-C"))
|
||||
#endif
|
||||
last_slash = strrchr(g_defaults.dirs[DEFAULT_DIR_CORE], '/');
|
||||
if (last_slash)
|
||||
*last_slash = 0;
|
||||
device_end = strchr(g_defaults.dirs[DEFAULT_DIR_CORE], '/');
|
||||
if (device_end)
|
||||
snprintf(g_defaults.dirs[DEFAULT_DIR_PORT], sizeof(g_defaults.dirs[DEFAULT_DIR_PORT]),
|
||||
"%.*s/retroarch", device_end - g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE]);
|
||||
else
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PORT], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"retroarch", sizeof(g_defaults.dirs[DEFAULT_DIR_PORT]));
|
||||
{
|
||||
/* When using external loaders (Wiiflow, etc),
|
||||
getcwd doesn't return the path correctly and as a result,
|
||||
the cfg file is not found. */
|
||||
if (string_starts_with(argv[0], "usb1") ||
|
||||
string_starts_with(argv[0], "usb2"))
|
||||
{
|
||||
strcpy_literal(g_defaults.dirs[DEFAULT_DIR_CORE], "usb");
|
||||
strlcat(g_defaults.dirs[DEFAULT_DIR_CORE], argv[0] + 4,
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
|
||||
}
|
||||
|
||||
/* System paths */
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY]));
|
||||
#ifdef HAVE_VIDEO_LAYOUT
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"layouts", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT]));
|
||||
/* Needed on Wii; loaders follow a dumb standard where the path and
|
||||
filename are separate in the argument list. */
|
||||
if (params)
|
||||
{
|
||||
static char path[PATH_MAX_LENGTH];
|
||||
|
||||
fill_pathname_join(path, argv[1], argv[2], sizeof(path));
|
||||
|
||||
params->content_path = path;
|
||||
params->sram_path = NULL;
|
||||
params->state_path = NULL;
|
||||
params->config_path = NULL;
|
||||
params->libretro_path = NULL;
|
||||
params->verbose = false;
|
||||
params->no_content = false;
|
||||
params->touched = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (gx_devices[GX_DEVICE_SD].mounted)
|
||||
chdir("sd:/");
|
||||
else if (gx_devices[GX_DEVICE_USB].mounted)
|
||||
chdir("usb:/");
|
||||
}
|
||||
#endif
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS], g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"cheats", sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS]));
|
||||
|
||||
/* User paths */
|
||||
fill_pathname_join(g_defaults.path_config, g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
"retroarch.cfg", sizeof(g_defaults.path_config));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"savefiles", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"savestates", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"logs", sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
"config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]));
|
||||
|
||||
#ifdef IS_SALAMANDER
|
||||
if (*argc > 2 && argv[1] != NULL && argv[2] != NULL)
|
||||
#else
|
||||
if (*argc > 2 && argv &&
|
||||
!string_is_empty(argv[1]) && !string_is_empty(argv[2]))
|
||||
fill_pathname_join(gx_rom_path, argv[1], argv[2], sizeof(gx_rom_path));
|
||||
else
|
||||
gx_rom_path[0] = '\0';
|
||||
#else
|
||||
#ifdef HW_RVL
|
||||
/* needed on Wii; loaders follow a dumb standard where the path and
|
||||
* filename are separate in the argument list */
|
||||
if (*argc > 2 && argv[1] != NULL && argv[2] != NULL)
|
||||
{
|
||||
static char path[PATH_MAX_LENGTH];
|
||||
struct rarch_main_wrap *args = (struct rarch_main_wrap*)params_data;
|
||||
|
||||
*path = '\0';
|
||||
|
||||
if (args)
|
||||
{
|
||||
fill_pathname_join(path, argv[1], argv[2], sizeof(path));
|
||||
|
||||
args->touched = true;
|
||||
args->no_content = false;
|
||||
args->verbose = false;
|
||||
args->config_path = NULL;
|
||||
args->sram_path = NULL;
|
||||
args->state_path = NULL;
|
||||
args->content_path = path;
|
||||
args->libretro_path = NULL;
|
||||
}
|
||||
}
|
||||
*gx_rom_path = '\0';
|
||||
#endif
|
||||
|
||||
slash = strrchr(g_defaults.dirs[DEFAULT_DIR_CORE], '/');
|
||||
if (slash)
|
||||
*slash = '\0';
|
||||
strlcpy(g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_PORT]));
|
||||
slash = strchr(g_defaults.dirs[DEFAULT_DIR_PORT], '/');
|
||||
if (slash)
|
||||
*slash = '\0';
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PORT],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "retroarch",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_PORT]));
|
||||
|
||||
/* System paths */
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "info",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "autoconfig",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "overlays",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY]));
|
||||
#ifdef HAVE_VIDEO_LAYOUT
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "layouts",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT]));
|
||||
#endif
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "filters/video",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "filters/audio",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "assets",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS],
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "cheats",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS]));
|
||||
/* User paths */
|
||||
fill_pathname_join(g_defaults.path_config,
|
||||
g_defaults.dirs[DEFAULT_DIR_CORE], "retroarch.cfg",
|
||||
sizeof(g_defaults.path_config));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "system",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "savefiles",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "savestates",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "playlists",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_LOGS],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "logs",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_LOGS]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "remaps",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG],
|
||||
g_defaults.dirs[DEFAULT_DIR_PORT], "config",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]));
|
||||
|
||||
#ifndef IS_SALAMANDER
|
||||
dir_check_defaults("custom.ini");
|
||||
#endif
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <ogc/lwp_threads.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <file/file_path.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <paths.h>
|
||||
@ -37,6 +38,10 @@
|
||||
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#if !defined(IS_SALAMANDER) && defined(HAVE_NETWORKING)
|
||||
#include "../../network/netplay/netplay.h"
|
||||
#endif
|
||||
|
||||
#define EXECUTE_ADDR ((uint8_t *) 0x91800000)
|
||||
#define BOOTER_ADDR ((uint8_t *) 0x93000000)
|
||||
#define ARGS_ADDR ((uint8_t *) 0x93200000)
|
||||
@ -120,29 +125,78 @@ static void dol_copy_argv_path(const char *dolpath, const char *argpath)
|
||||
DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length);
|
||||
}
|
||||
|
||||
static void dol_copy_raw_argv(const char *dolpath,
|
||||
const void *args, size_t size)
|
||||
{
|
||||
struct __argv *argv = (struct __argv*)ARGS_ADDR;
|
||||
char *cmdline = (char*)++argv;
|
||||
|
||||
memset(argv, 0, sizeof(*argv));
|
||||
|
||||
argv->argvMagic = ARGV_MAGIC;
|
||||
argv->commandLine = cmdline;
|
||||
|
||||
/* a device-less fullpath */
|
||||
if (dolpath[0] == '/')
|
||||
strlcpy(cmdline, __system_argv->argv[0],
|
||||
strchr(__system_argv->argv[0], ':') - __system_argv->argv[0] + 2);
|
||||
/* a relative path */
|
||||
else if (!string_starts_with(dolpath, "sd:/") &&
|
||||
!string_starts_with(dolpath, "usb:/") &&
|
||||
!string_starts_with(dolpath, "carda:/") &&
|
||||
!string_starts_with(dolpath, "cardb:/"))
|
||||
fill_pathname_parent_dir(cmdline, __system_argv->argv[0],
|
||||
PATH_MAX_LENGTH);
|
||||
/* fullpath */
|
||||
else
|
||||
*cmdline = '\0';
|
||||
|
||||
argv->length = (int)strlcat(cmdline, dolpath, PATH_MAX_LENGTH);
|
||||
argv->length += 1;
|
||||
|
||||
memcpy(cmdline + argv->length, args, size);
|
||||
argv->length += size;
|
||||
|
||||
DCFlushRange(argv, sizeof(*argv) + argv->length);
|
||||
}
|
||||
|
||||
/* WARNING: after we move any data
|
||||
* into EXECUTE_ADDR, we can no longer use any
|
||||
* heap memory and are restricted to the stack only. */
|
||||
void system_exec_wii(const char *_path, bool should_load_game)
|
||||
{
|
||||
size_t size, booter_size;
|
||||
FILE *fp = NULL;
|
||||
void *dol = NULL;
|
||||
char path[PATH_MAX_LENGTH] = {0};
|
||||
char game_path[PATH_MAX_LENGTH] = {0};
|
||||
char path[PATH_MAX_LENGTH];
|
||||
char args[PATH_MAX_LENGTH];
|
||||
size_t args_size;
|
||||
size_t size;
|
||||
FILE *fp;
|
||||
void *dol;
|
||||
#ifndef IS_SALAMANDER
|
||||
bool original_verbose = verbosity_is_enabled();
|
||||
bool verbosity = verbosity_is_enabled();
|
||||
#endif
|
||||
|
||||
args_size = 0;
|
||||
|
||||
/* copy heap info into stack so it survives
|
||||
* us moving the .dol into MEM2. */
|
||||
strlcpy(path, _path, sizeof(path));
|
||||
|
||||
if (should_load_game)
|
||||
{
|
||||
#ifdef IS_SALAMANDER
|
||||
strlcpy(game_path, gx_rom_path, sizeof(game_path));
|
||||
#ifndef IS_SALAMANDER
|
||||
#ifdef HAVE_NETWORKING
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
|
||||
if (net_st->fork_args.size)
|
||||
{
|
||||
memcpy(args, net_st->fork_args.args, net_st->fork_args.size);
|
||||
args_size = net_st->fork_args.size;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
strlcpy(args, path_get(RARCH_PATH_CONTENT), sizeof(args));
|
||||
#else
|
||||
strlcpy(game_path, path_get(RARCH_PATH_CONTENT), sizeof(game_path));
|
||||
strlcpy(args, gx_rom_path, sizeof(args));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -180,21 +234,25 @@ void system_exec_wii(const char *_path, bool should_load_game)
|
||||
memmove(EXECUTE_ADDR, dol, size);
|
||||
DCFlushRange(EXECUTE_ADDR, size);
|
||||
|
||||
dol_copy_argv_path(path, should_load_game ? game_path : NULL);
|
||||
if (args_size)
|
||||
dol_copy_raw_argv(path, args, args_size);
|
||||
else
|
||||
dol_copy_argv_path(path, should_load_game ? args : NULL);
|
||||
|
||||
booter_size = booter_end - booter_start;
|
||||
memcpy(BOOTER_ADDR, booter_start, booter_size);
|
||||
DCFlushRange(BOOTER_ADDR, booter_size);
|
||||
size = booter_end - booter_start;
|
||||
memcpy(BOOTER_ADDR, booter_start, size);
|
||||
DCFlushRange(BOOTER_ADDR, size);
|
||||
|
||||
SYS_ResetSystem(SYS_SHUTDOWN,0,0);
|
||||
__lwp_thread_stopmultitasking((void (*)(void)) BOOTER_ADDR);
|
||||
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
|
||||
__lwp_thread_stopmultitasking((void (*)(void))BOOTER_ADDR);
|
||||
|
||||
exit:
|
||||
(void)0;
|
||||
#ifndef IS_SALAMANDER
|
||||
if (original_verbose)
|
||||
if (verbosity)
|
||||
verbosity_enable();
|
||||
else
|
||||
verbosity_disable();
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user