Skip to content

D-10: skip SIF CMD teardown before embedded loader handoff on non-reset IOP#402

Open
Copilot wants to merge 1 commit intoBETA-11-playfrom
copilot/fix-d10-popsloader-black-screen
Open

D-10: skip SIF CMD teardown before embedded loader handoff on non-reset IOP#402
Copilot wants to merge 1 commit intoBETA-11-playfrom
copilot/fix-d10-popsloader-black-screen

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 19, 2026

HDD-backed POPSTARTER.ELF black-screens because ExecuteViaEmbeddedLoader calls SifExitCmd() unconditionally before ExecPS2(loader) — even on HDD paths where the IOP was never reset. SifExitCmd() sends a terminate packet to the IOP's SIF CMD handler, putting it in "waiting-for-re-init" state. The embedded loader starts with a zeroed .bss, calls SifInitRpc(0)SifInitCmd()SifSendCmd(SIF_CMD_INIT_CMD, ...), and waits for an IOP acknowledgment that never arrives. Permanent hang.

Root cause

ExecuteViaEmbeddedLoader applies the same SifExitIopHeap / SifExitRpc / SifExitCmd teardown regardless of whether the IOP was reset. For non-HDD reboot paths this is fine — prepare_reboot_exec_environment() already reset the IOP before this point. For HDD-backed paths the IOP is still running with all modules loaded, and terminating its SIF CMD handler breaks the loader's ability to re-establish RPC.

Consistent with DECISIONS.md line 101 ("the embedded-loader boundary only became stable once EE-side SIF teardown before ExecPS2 was removed") and with reference launchers (wLaunchELF) that do not call SifExitCmd before their embedded loader on a non-reset IOP.

Change

src/elf_loader/src/elf.c — gate SIF teardown on IOP-reset status:

/* SifExitCmd() terminates the IOP SIF CMD handler. On a non-reset IOP
 * this prevents the loader's SifInitRpc(0) from completing.
 * Non-HDD paths go through prepare_reboot_exec_environment() first
 * (IOP already reset), so the full teardown is correct there.
 */
if (!is_hdd_backed_exec_path(partition_context)) {
    SifExitIopHeap();
    SifExitRpc();
    SifExitCmd();
}
FlushCache(0);
FlushCache(2);
ret = ExecPS2((void *)boot_header->entry, 0, final_argc, launch_argv);
  • Non-HDD reboot paths: teardown unchanged.
  • HDD-backed paths: teardown skipped; IOP SIF CMD handler stays active; loader's SifInitRpc(0) gets an immediate IOP response.

Docs

DECISIONS.md, STATE.md, ROADMAP.md, README.md, QA_REGRESSION_MATRIX.md updated. Hardware result marked Unknown (verify on hardware).

SifExitCmd() in ExecuteViaEmbeddedLoader sends a terminate packet to the
IOP SIF CMD handler. On a non-reset IOP the handler enters
waiting-for-re-init state. The loader then calls SifInitRpc(0) which
sends SIF_CMD_INIT_CMD to the IOP and waits for a response that never
arrives — hanging forever = black screen.

For HDD-backed paths the IOP is never reset before this call. Skip
SifExitIopHeap/SifExitRpc/SifExitCmd so the IOP SIF CMD handler stays
active and responds to the loader's SifInitRpc(0) immediately.

Non-HDD reboot paths go through prepare_reboot_exec_environment() first
which resets the IOP; the full teardown is correct for that case and is
preserved unchanged.

This mechanism is consistent with DECISIONS.md line 101 (removing SIF
teardown before ExecPS2 stabilized the HDD loader boundary in earlier
diagnostics) and with reference launchers (wLaunchELF) which do not call
SifExitCmd before their embedded loader on a non-reset IOP.

Update README.md, STATE.md, ROADMAP.md, DECISIONS.md, and
QA_REGRESSION_MATRIX.md. Hardware result: Unknown (verify on hardware).

Agent-Logs-Url: https://github.com/NathanNeurotic/POPSLoader/sessions/64668836-b163-4b06-a989-f9d72b52c2aa

Co-authored-by: NathanNeurotic <109461996+NathanNeurotic@users.noreply.github.com>
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