Skip to content

IOP: Reset recompiler and map RAM mirrors on IOP soft reset#14288

Draft
fjtrujy wants to merge 1 commit intoPCSX2:masterfrom
fjtrujy:fix-iop-soft-reset-reclut
Draft

IOP: Reset recompiler and map RAM mirrors on IOP soft reset#14288
fjtrujy wants to merge 1 commit intoPCSX2:masterfrom
fjtrujy:fix-iop-soft-reset-reclut

Conversation

@fjtrujy
Copy link
Copy Markdown
Contributor

@fjtrujy fjtrujy commented Apr 12, 2026

Summary

Fixes IOP soft reset (SifIopReset) crashing with stale recompiler blocks.

When SifIopReset triggers (SBUS_F240 bit 19), psxReset() reloads the IOP BIOS kernel into RAM but does not flush the IOP recompiler cache. The recompiler keeps stale compiled x86 blocks for IOP RAM addresses that now contain different code. When the fresh kernel executes, the recompiler serves old translations, causing the IOP to crash on garbage instructions (psxUNK).

Changes

  1. psxCpu->Reset() after psxReset() in the SBUS_F240 handler — flushes all cached recompiler blocks, forcing fresh recompilation from the new RAM contents. This is the critical fix.

  2. Map IOP RAM mirrors in recLUT (kuseg pages 0x0000-0x1DFF) — the PS2 IOP mirrors its 2MB RAM across the entire kuseg address space. The BIOS uses mirrored addresses during soft resets (e.g. 0x0d000100 → physical 0x00000100). Without mirrored pages in recLUT, code at mirrored addresses hits unmapped pages.

How it was found

Tested with ps2link performing SifIopReset via ps2client reset. Without the fix:

  • psxReset() reloads the IOP kernel
  • IOP starts executing (DEV9 hardware detection runs)
  • Recompiler serves stale blocks → psxUNK: f0000102 crash
  • The "Soft reboot" log message never appears after the reset

With the fix, the recompiler cache is flushed and the IOP reboots cleanly.

Test plan

  • ps2client reset performs a clean IOP soft reboot
  • Consecutive ps2client reset commands work
  • ps2client execee + ps2client reset cycle works
  • No regression in normal game boot (which also uses IOP soft resets during BIOS init)

@Ziemas
Copy link
Copy Markdown
Contributor

Ziemas commented Apr 12, 2026

Hm this doesn't sound quite right to me, if I make a simple executable that just calls SifResetIop() it doesn't crash.

Reading 0x0d000100 on a real PS2 seems to result in a bus error as well.

dsidb R> iw 0x0d000100
*** Bus Error

When SifIopReset triggers (SBUS_F240 bit 19), psxReset() reloads the
IOP BIOS kernel into RAM but does not flush the IOP recompiler cache.
The recompiler keeps stale compiled blocks for IOP RAM addresses that
now contain different code. When the fresh kernel executes, the
recompiler serves old translations, causing the IOP to crash on
garbage instructions (psxUNK).

Add psxCpu->Reset() after psxReset() in the SBUS_F240 handler to
flush all cached recompiler blocks. This forces fresh recompilation
from the new RAM contents, allowing IOP soft resets to complete
correctly. This fixes SifIopReset as used by ps2link and other
PS2 homebrew that perform runtime IOP resets.

Additionally, map IOP RAM mirrors throughout kuseg (pages 0x0000-
0x1DFF) in the recompiler lookup table. The PS2 IOP mirrors its
2MB RAM across the entire kuseg address space (0x00000000-
0x1DFFFFFF). The BIOS uses these mirrored addresses during IOP
soft resets (e.g. jumping to 0x0d000100 which mirrors to physical
0x00000100). Without the mirrored pages in recLUT, code execution
at mirrored addresses would hit unmapped pages.
@fjtrujy fjtrujy force-pushed the fix-iop-soft-reset-reclut branch from cd8806b to f69eeaf Compare April 12, 2026 19:56
@fjtrujy fjtrujy changed the title IOP: Map IOP RAM mirrors in recompiler lookup table IOP: Reset recompiler and map RAM mirrors on IOP soft reset Apr 12, 2026
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