Skip to content

Psp go internal storage fix#19100

Merged
LibretroAdmin merged 4 commits into
libretro:masterfrom
Zade222:PSPGoFix
Jun 12, 2026
Merged

Psp go internal storage fix#19100
LibretroAdmin merged 4 commits into
libretro:masterfrom
Zade222:PSPGoFix

Conversation

@Zade222

@Zade222 Zade222 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Description

An issue I encountered a couple of years ago, and I recently found to still be present, was when retroarch is installed to the internal storage of the PSP Go with no memory stick it errors and is unable to save or read the config as it is hard coded to look for the related files on the memory stick.

I made changes to the PSP driver to check the path of the booted eboot and derive the related retroarch folder location from that.

While that resolved the initial load of retroarch to look for and save the config to the internal or external storage depending on where it is installed, when loading content or swapping a core the functionality didn't persist.

This necessitated an additional kernel firmware function that's not present in the PSP SDK. I added an ef0: branch in the kernel relaunch path (exitspawn_kernel) that routes internal-flash targets through a newly imported sceKernelLoadExecVSHEf2 instead of the semory stick sceKernelLoadExecVSHMs2. That way when content is loaded or a core is swapped the corrected location is followed for the core files as otherwise it would hard code to the memory stick again and potentially crash if one is not present in the system.

The EF2 loader is imported by NID 0x032A7938 from the firmware library LoadExecForKernel (module sceLoadExec.prx). It's documented in two independent reverse engineering sources:

  1. uOFW (uofw/uofw):
  • src/kd/loadexec/exports.exp: PSP_EXPORT_FUNC_NID(LoadExecForKernel_032A7938, 0x032A7938) found here.
  • src/kd/loadexec/loadexec.c: shows the function issues an SCE_EXEC_FILE_APITYPE_EF2 (internal-flash) load, the ef0: counterpart of sceKernelLoadExecVSHMs2 (APITYPE_MS2) found here.
  1. Spenon-dev/PSPLibDoc: PSPGoLibDoc/6.61/Export/kd/loadexec_05g.xml, NID 0x032A7938, name LoadExecForKernel_032A7938. This is a PSP Go 6.61 firmware NID dump which is the exact model and firmware these fixes were validated on found here.

The firmware export is unnamed in both sources (just LoadExecForKernel_032A7938). The alias sceKernelLoadExecVSHEf2 is chosen for this fix, mirroring the existing SDK name sceKernelLoadExecVSHMs2 that way it's clear what it maps to.

The EF2 NID resolves correctly on 6.61 custom firmware alongside the SDK's existing Ms2 import as validated on device and explained below.

Related Issues

This addresses issue #6550 and #14405

Related Pull Requests

Not required for this PR to function but this PR supersedes PR #6599

Testing

I have verified on a PSP Go with custom 6.61 firmware that these fixes work. I have tested it installed both on internal storage without a card present, on internal storage with memory card present but no files on memory card and on a memory card. I also tested it in PPSSPP, as I do not have non PSP Go hardware, to ensure there were no regressions there either. Config saving and loading works from the intended paths. Core swapping and content loading works as intended.

Documentation Changes

A note and/or warning should be added to the psp install page (found here) so it's more explicitly stated how this now works so if some confusion occurs the install guide and notes can be easily pointed to. I'll follow through with that once I finish drafting this PR.

AI Disclosure

I used AI to find relevant files in both retroarch and the PSP SDK to verify information and research potential solutions. Logic was written by myself.

Zadeis and others added 3 commits June 8, 2026 18:42
- 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
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.
@Zade222 Zade222 marked this pull request as draft June 9, 2026 17:16
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.
@Zade222

Zade222 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

Woops missed one of the file changes to the MAKEFILE. Now it's in place so the CI should pass. Sorry about that!

@LibretroAdmin LibretroAdmin marked this pull request as ready for review June 10, 2026 02:29
@Zade222

Zade222 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Docs change PR is 1150. Should be ready for review.

@LibretroAdmin LibretroAdmin merged commit a57c0cb into libretro:master Jun 12, 2026
43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants