Skip to content

Commit a57c0cb

Browse files
Zade222Zadeis
andauthored
Psp go internal storage fix (#19100)
* fix(psp): derive user data path from launch device vice hardcoded ms0: - Extract the storage prefix (ms0:/ or ef0:/) from the executable's path so user data lives on the same device RetroArch was launched from in order to fix PSP Go EF0 storage compatibility - Fall back to ms0:/ when the path doesn't contain a recognizable device prefix * fix(bootstrap): use sceKernelLoadExecVSHEf2 for ef0: paths on PSP Go On PSP Go installs to internal flash RetroArch relaunches cores through sceKernelLoadExecVSHMs2, the Memory Stick loader, which fails when handed an ef0: path. Route ef0: targets through the internal flash loader instead so core loads and relaunches work from internal storage. - Add LoadExecEf.S importing sceKernelLoadExecVSHEf2 (NID 0x032A7938) from the LoadExecForKernel PRX, ms0: and all other paths keep using sceKernelLoadExecVSHMs2 - Branch on the ef0: prefix in exitspawn_kernel (main.c) - Add LoadExecEf.o to the PRX Makefile OBJS NID 0x032A7938 is documented in uOFW (src/kd/loadexec) and PSPLibDoc (PSPGoLibDoc/6.61), the sceKernelLoadExecVSHEf2 name is just an alias for the otherwise unnamed export. Tested on PSP Go (6.61 CFW). Core swap loads from ef0: with config persisting, ms0: path is unchanged so no regression. * fix(bootstrap): add LoadExecEf.o to PRX OBJS so the EF2 import links The previous commit added LoadExecEf.S with the sceKernelLoadExecVSHEf2 import stub but forgot to wire it into the PRX build, so the object never got compiled in and the link failed with an undefined reference and the PSP CI caught it. Adding LoadExecEf.o to OBJS fixes it so the stub assembles and the EF2 loader resolves at link time. --------- Co-authored-by: Zadeis <tyler.bibeault@pm.me>
1 parent f029189 commit a57c0cb

4 files changed

Lines changed: 26 additions & 3 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.set noreorder
2+
3+
#include "pspimport.s"
4+
5+
IMPORT_START "LoadExecForKernel",0x00010000
6+
IMPORT_FUNC "LoadExecForKernel",0x032A7938,sceKernelLoadExecVSHEf2

bootstrap/psp1/kernel_functions_prx/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
TARGET = kernel_functions
2-
OBJS = main.o
2+
OBJS = main.o LoadExecEf.o
33
PSP_FW_VERSION = 150
44

55
INCDIR =

bootstrap/psp1/kernel_functions_prx/main.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
PSP_MODULE_INFO("kernel_functions", PSP_MODULE_KERNEL, 0, 0);
88
PSP_MAIN_THREAD_ATTR(0);
99

10+
extern int sceKernelLoadExecVSHEf2(const char *file,
11+
struct SceKernelLoadExecVSHParam *param);
12+
1013
void exitspawn_kernel(const char *fileName, SceSize args, void *argp)
1114
{
1215
int k1;
@@ -25,7 +28,10 @@ void exitspawn_kernel(const char *fileName, SceSize args, void *argp)
2528
game_param.unk5 = 0x10000;
2629

2730
k1 = pspSdkSetK1(0);
28-
sceKernelLoadExecVSHMs2(fileName, &game_param);
31+
if (!strncmp(fileName, "ef0:", 4))
32+
sceKernelLoadExecVSHEf2(fileName, &game_param);
33+
else
34+
sceKernelLoadExecVSHMs2(fileName, &game_param);
2935
pspSdkSetK1(k1);
3036
}
3137

frontend/drivers/platform_psp.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,18 @@ static void frontend_psp_get_env_settings(int *argc, char *argv[],
142142
strlcpy(eboot_path, argv[0], sizeof(eboot_path));
143143
/* for PSP, use uppercase directories, and no trailing slashes
144144
otherwise mkdir fails */
145-
strlcpy(user_path, "ms0:/PSP/RETROARCH", sizeof(user_path));
145+
/* Derive the user data root from the storage device RetroArch was
146+
launched from (such as "ms0:/" or "ef0:/" on PSP Go). That way user
147+
data follows the binary instead of being hardcoded to ms0: */
148+
if (strlen(eboot_path) >= 5 && eboot_path[4] == '/')
149+
{
150+
strlcpy(user_path, eboot_path, sizeof(user_path));
151+
user_path[5] = '\0';
152+
}
153+
else
154+
strlcpy(user_path, "ms0:/", sizeof(user_path));
155+
strlcat(user_path, "PSP/RETROARCH", sizeof(user_path));
156+
RARCH_LOG("[PSP]: Using %s for user data.\n", user_path);
146157

147158
fill_pathname_basedir(g_defaults.dirs[DEFAULT_DIR_PORT], argv[0],
148159
sizeof(g_defaults.dirs[DEFAULT_DIR_PORT]));

0 commit comments

Comments
 (0)