diff --git a/DECISIONS.md b/DECISIONS.md index 80730258..456745f4 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -130,6 +130,11 @@ Each entry records: - the latest hardware re-test on that stripped selectorless line still black-screened, while the only recorded move away from a black screen happened before the selector was stripped. - current working rule from repo evidence: POPSTARTER itself does not need slot preservation, launch CWD, partition context, or other carried runtime state after exec, but it does still want its selector in `argv[0]`. Current source therefore restores selector-only `argv[0]` for HDD-backed POPSTARTER while keeping partition context only as loader metadata so the HDD ELF can be loaded cleanly. - current source still keeps the `R2` selector-path experiment for HDD game launches, but that remains secondary to restoring and preserving the non-HDD POPSTARTER baseline for HDD titles. + - latest user hardware report from the 2026-04-02 GitHub artifact (`cd76569`) still black-screened on `D-10`. + - audit identified the specific mechanism behind the persistent black screen: `ExecuteViaEmbeddedLoader` calls `SifExitCmd()` unconditionally before `ExecPS2(loader)`, sending a "terminate" packet to the IOP's SIF command handler; on a non-reset IOP the SIF CMD module enters a "waiting-for-re-init" state and stops processing EE commands; the embedded loader's `SifInitRpc(0)` (via `SifInitCmd()`) then sends `SIF_CMD_INIT_CMD` to the IOP and waits for a response that never arrives, causing `SifInitRpc(0)` to hang forever = black screen. + - this mechanism directly explains the recorded DECISIONS.md line 101 finding ("the embedded-loader boundary only became stable once EE-side SIF teardown before ExecPS2 was removed from the parent handoff") and is consistent with reference launchers such as `wLaunchELF` which do not call `SifExitCmd` before handing off to an embedded loader on a non-reset IOP. + - for non-HDD reboot paths, `prepare_reboot_exec_environment()` already resets the IOP before `ExecuteViaEmbeddedLoader` is called, so `SifExitCmd()` is then safe and appropriate. + - current source now conditionally skips `SifExitIopHeap`, `SifExitRpc`, and `SifExitCmd` in `ExecuteViaEmbeddedLoader` when `partition_context` is HDD-backed; this keeps the IOP's SIF CMD module active so the loader's `SifInitRpc(0)` receives an immediate response; non-HDD reboot paths continue to call the full teardown sequence. Hardware on this exact line is `Unknown (verify on hardware)`. - `BOOT.ELF` after HDD page init: - repo history shows the BOOT.ELF modal originally used a simpler non-reboot `System.loadELF(elf_path, 0, elf_path)` path without launch-CWD setup, and later source changed it to `reboot_iop = 1` plus launch-CWD. - a later 2026-03-29 hardware report said BOOT.ELF still behaved incorrectly once HDD runtime had been initialized, which points more narrowly at carried HDD/IOP state than BOOT.ELF lookup itself. diff --git a/QA_REGRESSION_MATRIX.md b/QA_REGRESSION_MATRIX.md index e170651f..5cd79000 100644 --- a/QA_REGRESSION_MATRIX.md +++ b/QA_REGRESSION_MATRIX.md @@ -128,6 +128,7 @@ This file is the authoritative detailed run ledger for CI and hardware outcomes. | 2026-03-29 | Unknown (not reported) | HDD boot; HDD sidecar/cwd `POPSTARTER.ELF`; HDD game on the child-remount/cold-parent partition-aware line | D-10 | FAIL: black screen | | 2026-03-29 | Unknown (not reported) | HDD boot; HDD sidecar/cwd `POPSTARTER.ELF`; HDD game on the selectorless stripped current `HEAD` line | D-10 | FAIL: black screen | | 2026-04-02 | Unknown (not reported) | HDD boot; HDD sidecar/cwd `POPSTARTER.ELF`; HDD game on latest GitHub artifact from CI-focused line (`cd76569`) | D-10 | FAIL: black screen | +| 2026-04-19 | Unknown (not reported) | HDD boot; HDD sidecar/cwd `POPSTARTER.ELF`; HDD game on no-SIF-teardown HDD-path source (`SifExitCmd` skipped before `ExecPS2(loader)` when IOP not reset) | D-10 | Unknown (verify on hardware) | | 2026-03-29 | Unknown (not reported) | HDD boot; default/Profile 1 sidecar/cwd `POPSTARTER.ELF` on HDD; entered HDD page; Exit -> `BOOT.ELF` on the cold-prep/no-forced-reboot BOOT.ELF line | U-10 | FAIL: freeze | | 2026-03-29 | Unknown (not reported) | HDD boot; default/Profile 1 sidecar/cwd `POPSTARTER.ELF` on HDD; entered HDD page; Exit -> `BOOT.ELF` on the restored-standard-prep/no-forced-reboot BOOT.ELF line | U-10 | FAIL: freeze | | YYYY-MM-DD | SCPH-xxxxx | USB/MMCE/MX4SIO/HDD details | e.g. S-01,S-02,D-02 | PASS/FAIL + notes | diff --git a/README.md b/README.md index 54a46fc8..ecc8bc09 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # POPSLoader -Last updated: 2026-04-02 +Last updated: 2026-04-19 POPSLoader is a PlayStation 2 launcher for POPStarter, built on Enceladus runtime components and driven primarily by embedded Lua scripts. @@ -68,6 +68,8 @@ Reported hardware issues currently being tracked are: - audit then found another remaining carry-over in parent-side launch prep: `PrepareForExternalELFLaunch(...)` still auto-kept the mounted `pfsN` slot whenever the exec path itself was on `pfsN:/...`. Current source now suppresses that implicit exec-slot keep specifically for HDD-backed POPSTARTER, so the stripped line no longer preserves the mounted parent slot just because the executable was resolved there. - the latest hardware re-test on that stripped selectorless line still black-screened, and the only recorded move away from a black screen happened before the selector was stripped. Current source therefore restores selector-only `argv[0]` for HDD-backed POPSTARTER while still avoiding slot/CWD preservation and keeping partition context only as loader metadata. - clarification: POPSTARTER itself is not believed to require slot preservation, launch CWD, partition context, or carried runtime state after exec. Current source again gives POPSTARTER only its selector in `argv[0]`; the loader still keeps partition metadata only so the HDD ELF can be loaded cleanly. + - audit then identified the mechanism behind the persistent black screen: `ExecuteViaEmbeddedLoader` called `SifExitCmd()` unconditionally before `ExecPS2(loader)`; on a non-reset IOP, `SifExitCmd()` sends a "terminate" to the IOP's SIF CMD handler, putting it in a "waiting-for-re-init" state; the loader's `SifInitRpc(0)` then sends `SIF_CMD_INIT_CMD` to the IOP but gets no response — `SifInitRpc(0)` hangs = black screen. This mechanism is consistent with DECISIONS.md line 101 and with reference launchers (wLaunchELF) that do not call `SifExitCmd` before their embedded loader on a non-reset IOP. + - current repo line now conditionally skips `SifExitIopHeap`, `SifExitRpc`, and `SifExitCmd` in `ExecuteViaEmbeddedLoader` when `partition_context` is HDD-backed, so the IOP SIF CMD handler stays active and the loader's `SifInitRpc(0)` completes without hanging; non-HDD reboot paths retain the full teardown. Hardware on this exact line is `Unknown (verify on hardware)`. - detailed per-artifact experiment chronology lives in `QA_REGRESSION_MATRIX.md` and `DECISIONS.md`. - HDD game with non-HDD POPSTARTER (`D-15`) - user later confirmed on 2026-03-28 that USB boot + USB Profile 1 sidecar/cwd `POPSTARTER.ELF` + HDD game now passes on hardware. @@ -228,6 +230,8 @@ The workflow uses the `ps2dev/ps2dev` container and validates packaging after bu - the later stripped direct-HDD-ELF line moved `D-10` back to a returned `rc=-1`, but the popup also showed the launcher was still probing/opening `pfs3:/.../POPSTARTER.ELF` while separately trying to exec a rewritten `pfs:/.../POPSTARTER.ELF`. - current repo line now removes that stale exec-path rewrite from the stripped HDD-backed POPSTARTER experiment, keeps the reboot/embedded-loader path plus loader-only partition metadata, and restores selector-only `argv[0]` because the selectorless stripped line still black-screened while the only recorded non-black-screen boundary preceded the strip. - clarification: POPSTARTER itself is not believed to require slot preservation, launch CWD, partition context, or carried runtime state after exec; current source again passes only the selector in `argv[0]` while keeping the loader-side state prep minimal. + - audit identified the mechanism behind the persistent black screen: `ExecuteViaEmbeddedLoader` called `SifExitCmd()` unconditionally before `ExecPS2(loader)`; on a non-reset IOP, `SifExitCmd()` puts the IOP's SIF CMD handler in "waiting-for-re-init" state; the loader's `SifInitRpc(0)` then hangs waiting for a response that never comes = black screen. This is consistent with DECISIONS.md line 101 and reference launchers (wLaunchELF) that do not call `SifExitCmd` before their embedded loader on a non-reset IOP. + - current repo line now conditionally skips `SifExitIopHeap`, `SifExitRpc`, and `SifExitCmd` in `ExecuteViaEmbeddedLoader` when `partition_context` is HDD-backed; non-HDD reboot paths retain the full teardown. Hardware on this exact line is `Unknown (verify on hardware)`. - see `QA_REGRESSION_MATRIX.md` and `DECISIONS.md` for the detailed experiment chronology. - `D-14` HDD-backed POPSTARTER with non-HDD game: - reported failing. diff --git a/ROADMAP.md b/ROADMAP.md index 0c6fb72d..6ced6104 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,4 +1,4 @@ -Last updated: 2026-04-02 +Last updated: 2026-04-19 # ROADMAP @@ -17,11 +17,8 @@ Last updated: 2026-04-02 - Audit also found a Lua binding bug: the trailing reboot partition context was only recognized when `System.loadELF(...)` had at least four Lua arguments, so the HDD reboot path could not actually pass loader-only partition metadata in the three-argument form. Current source now accepts that form as well. - Audit then found one more regression in the exact HDD child-loader path now in use: older child-loader source reloaded `SIO2MAN`, `MCMAN`, and `MCSERV` after HDD `SifIopReset(\"\")`, while later `HEAD` had drifted to jump straight to `ExecPS2`. Current source now uses a no-reset-first child-loader handoff for partition-aware HDD POPSTARTER with bounded mounted-path load fallback (`fileXio` segment load first, mounted-path `SifLoadElf` fallback, then `SifExitRpc`/`ExecPS2` without child-side reset/module reload); hardware on this exact line is still `Unknown (verify on hardware)`. - Latest user hardware report from the 2026-04-02 GitHub artifact (`cd76569`) still black-screened on `D-10`. -- Audit then found another remaining carry-over in parent-side launch prep: `PrepareForExternalELFLaunch(...)` still auto-kept the mounted `pfsN` slot whenever the exec path itself was on `pfsN:/...`. Current source now suppresses that implicit exec-slot keep specifically for HDD-backed POPSTARTER. -- The current hypothesis boundary is now narrower again: preserve the later loader/binding fixes, but give HDD-backed POPSTARTER back its selector-only `argv[0]` because the selectorless line did not improve hardware behavior. -- Current repo line also restores the generic reboot exec path in `src/elf_loader/src/elf.c` to the repo's older embedded-loader handoff style after the post-reset cleanup/module-reload contract from `src/system.cpp`. -- Treat slot preservation, launch CWD preservation, partition context, and other carried launch-state prep as non-goals for POPSTARTER itself. Current source now gives POPSTARTER only its selector in `argv[0]` while keeping loader-side partition metadata only as the minimum needed to load the HDD ELF. -- The latest EE-side HDD direct-load workaround was reverted after it did not fix `D-10` and coincided with a reported HDD-game regression when POPSTARTER stayed on the non-HDD boot device. +- Audit identified the mechanism behind the persistent black screen: `ExecuteViaEmbeddedLoader` called `SifExitCmd()` unconditionally before `ExecPS2(loader)`; on a non-reset IOP, `SifExitCmd()` sends a "terminate" to the IOP's SIF CMD handler; the loader's `SifInitRpc(0)` then hangs waiting for a response that never comes = black screen. Reference launchers (wLaunchELF) do not call `SifExitCmd` before their embedded loader on a non-reset IOP. +- Current repo line now conditionally skips `SifExitIopHeap`, `SifExitRpc`, and `SifExitCmd` in `ExecuteViaEmbeddedLoader` when `partition_context` is HDD-backed; non-HDD reboot paths retain the full teardown sequence. Hardware on this exact line is `Unknown (verify on hardware)`. - `HDD (exFAT)` and `SMB (v1)` remain intentionally unimplemented menu entries. - Detailed experiment chronology lives in `QA_REGRESSION_MATRIX.md` and `DECISIONS.md`. @@ -33,7 +30,7 @@ Last updated: 2026-04-02 - HDD game launched from HDD (PFS), - `POPSTARTER.ELF` resolved from HDD sidecar/CWD or configured HDD path, - current reported result: black-screen hang. - - current no-reset-first iteration keeps selector-only `argv[0]` and loader partition metadata, removes the child-side post-load reset/module-reload stage, and now uses mounted-path fileXio-first with mounted-path `SifLoadElf` fallback for the partition-aware HDD POPSTARTER child-loader load step. + - current no-reset-first iteration keeps selector-only `argv[0]` and loader partition metadata, removes the child-side post-load reset/module-reload stage, uses mounted-path fileXio-first with mounted-path `SifLoadElf` fallback for the partition-aware HDD POPSTARTER child-loader load step, and now skips `SifExitIopHeap`/`SifExitRpc`/`SifExitCmd` before `ExecPS2(loader)` when the IOP was not reset. - preserve `D-15`, `D-12`, `D-16`, `U-05`, and shared Profile 1/default sidecar behavior while iterating. - treat `D-14` as the paired non-HDD-game repro for the same HDD-backed POPSTARTER blocker. - use `QA_REGRESSION_MATRIX.md` for the full experiment chronology instead of rebuilding that ledger here. diff --git a/STATE.md b/STATE.md index 59261342..1c8d3741 100644 --- a/STATE.md +++ b/STATE.md @@ -1,4 +1,4 @@ -Last updated: 2026-04-02 +Last updated: 2026-04-19 # STATE @@ -104,11 +104,12 @@ POPSLoader is a PS2 launcher for POPStarter built on Enceladus runtime pieces, w - current source now applies a no-reset-first child-loader handoff for partition-aware HDD POPSTARTER, but updates the load order to a bounded reference-style fallback: after mount on `pfs0:`, the child tries mounted-path fileXio segment copy first and falls back to mounted-path `SifLoadElf` if needed, then exits RPC and jumps via `ExecPS2` without a second child-side `SifIopReset("")` + module-reload stage; hardware on this exact line is `Unknown (verify on hardware)`. - latest user hardware report from the 2026-04-02 GitHub artifact (`cd76569`) still black-screened on `D-10`. - audit then found another remaining carry-over in parent-side launch prep: `PrepareForExternalELFLaunch(...)` still auto-kept the mounted `pfsN` slot whenever the exec path itself was on `pfsN:/...`. Current source now suppresses that implicit exec-slot keep specifically for HDD-backed POPSTARTER, so the stripped line no longer preserves the mounted parent slot just because the executable was resolved there. - - current source now restores more of the original parent-side embedded-loader jump contract in `src/elf_loader/src/elf.c`: BRAM wipe plus `SifInitRpc`/`SifLoadFileInit`/`SifLoadFileExit` before the copy, and `SifExitIopHeap`/`SifExitRpc`/`SifExitCmd` before the final `ExecPS2`. - the latest hardware re-test on that stripped selectorless line still black-screened, while the only recorded move away from a black screen happened on an earlier selector-passing line. - current source therefore keeps the safer embedded-loader fix that avoids `printf`/`snprintf` in that environment, returns the actual embedded-loader `ExecPS2` result instead of collapsing it to `-1`, restores selector-only `argv[0]` for HDD-backed POPSTARTER, restores partition context only as loader metadata so the child avoids the newer `fileXio` shortcut, normalizes stale canonical profile-path state so Profile 1/default no longer silently keeps another profile's HDD path, and keeps the older iomanX-aware `fileXio` load path only as the fallback for direct `pfs:` / `hdd:` loads with no HDD partition context. - current working clarification: POPSTARTER itself is not believed to require slot preservation, launch CWD, partition context, or carried runtime state after exec. Current source again gives POPSTARTER only its selector in `argv[0]`; the loader-side partition metadata remains only to get the HDD ELF loaded. - - latest recorded hardware still ends in failure on later GitHub artifacts, so `D-10` remains a recorded hardware FAIL even though one 2026-03-29 artifact briefly moved the boundary to `rc=-1`. + - audit then identified the mechanism behind the persistent black screen: `ExecuteViaEmbeddedLoader` called `SifExitCmd()` unconditionally before `ExecPS2(loader)`; on a non-reset IOP `SifExitCmd()` sends a "terminate" packet to the IOP's SIF CMD handler, putting it in a "waiting-for-re-init" state; the loader's `SifInitRpc(0)` then sends `SIF_CMD_INIT_CMD` to the IOP but gets no response, so `SifInitRpc(0)` hangs = black screen. This mechanism is consistent with DECISIONS.md line 101 and with reference launchers that do not call `SifExitCmd` before their embedded loader on a non-reset IOP. + - current source now conditionally skips `SifExitIopHeap`, `SifExitRpc`, and `SifExitCmd` in `ExecuteViaEmbeddedLoader` when `partition_context` is HDD-backed; non-HDD reboot paths retain the full teardown. Hardware on this exact line is `Unknown (verify on hardware)`. + - latest recorded hardware still ends in failure on later GitHub artifacts, so `D-10` remains a recorded hardware FAIL; current exact-line result is `Unknown (verify on hardware)`. - `D-14` HDD-backed POPSTARTER with non-HDD game: - reported failing on hardware. - repro: launch a non-HDD title while `POPSTARTER.ELF` itself is configured on HDD. diff --git a/src/elf_loader/src/elf.c b/src/elf_loader/src/elf.c index 83335cdb..3cfc9802 100644 --- a/src/elf_loader/src/elf.c +++ b/src/elf_loader/src/elf.c @@ -377,9 +377,26 @@ static int ExecuteViaEmbeddedLoader(const char *partition_context, const char *l } } - SifExitIopHeap(); - SifExitRpc(); - SifExitCmd(); + /* For HDD-backed handoffs the IOP was not reset before this call. + * SifExitCmd() sends a "terminate" packet to the IOP's SIF command + * handler, which puts the IOP's SIF CMD module into a + * waiting-for-re-init state. The embedded loader then starts fresh + * (C-runtime zeros .bss) and calls SifInitRpc(0), which sends a new + * SIF_CMD_INIT_CMD to the IOP. On a non-reset IOP that received a + * prior "terminate", the SIF CMD module does not respond to the new + * init command and SifInitRpc(0) hangs forever = black screen. + * Skip the teardown so the IOP SIF handler stays active; the + * loader's SifInitRpc(0) then finds a responsive IOP and completes + * without hanging. + * For non-HDD paths, prepare_reboot_exec_environment() has already + * reset the IOP before this function is called, so the full teardown + * sequence is correct and must be preserved. + */ + if (!is_hdd_backed_exec_path(partition_context)) { + SifExitIopHeap(); + SifExitRpc(); + SifExitCmd(); + } FlushCache(0); FlushCache(2);