Repository navigation
fix(iop): serve the cdvdfsv RPC family from a ROM-resident HLE service - #403
Open
LeandroSSB wants to merge 3 commits into
Open
LeandroSSB wants to merge 3 commits into
LeandroSSB wants to merge 3 commits into
Conversation
Games bind the cdvdman/cdvdfsv SIF RPC endpoints (Ccmd 0x80000592, Scmd 0x80000593, Stcmd 0x80000595, search 0x8000059A) during libcdvd init and poll client->server until a server descriptor is published. Those servers live in the IOP ROM, so no disc module ever registers them and the bind loop never completes: SLUS_215.97 spins forever in SifBindRpc(0x80000593) before any file access. Add a cdvdman IopService that owns the four SIDs with no module aliases (ROM modules are always resident). It claims the family's RPCs and answers with the neutral ready/no-error/zero-data payload, logging unmodeled commands (rate-limited, debug metric) so real semantics can follow observed traffic. Test note: ps2xTest PS2IopSubsystem gains a case asserting the four SIDs are bindable without module loads, Scmd 0x27 is claimed and replies success, and unknown Scmd commands are answered plus logged. Suite 447/447. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
After the cdvdfsv family became bindable, SLUS_215.97 reached the next
stage of its libcdvd init: SifCallRpc(Scmd 0x80000593, 0x27, ..., 12-byte
receive), then a poll of the receive buffer's first word. The neutral
zeroed answer kept the game in that poll forever (3.6k cycles in 60s,
~61Hz, alternated with the syscall-stub WaitSema helpers).
Answer the handshake with {1, 0, 0}: nonzero first word unlocks the
poll, neutral drive state in the two words the game copies aside.
Test note: the PS2IopSubsystem cdvdman case now asserts the Scmd 0x27
reply's first word is nonzero. Suite 447/447.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The success assert for the Scmd 0x27 boot handshake only checked the
first reply word for nonzero, which the 0xCC poison prefill already
satisfies: a service that claims the RPC but never writes the reply
buffer would pass. writeBootHandshakeReply answers {1,0,0}, so pin the
assertion to the actual success word.
Suite 448/448.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
cdvdman/cdvdfsv register their EE-facing RPC servers from the IOP ROM at boot — they never arrive as disc IRX modules. The runtime only published services from load-emulated modules, so the four cdvdfsv SIDs (Ccmd
0x80000592, Scmd0x80000593, Stcmd0x80000595, search0x8000059A) had no owner: the libcdvd bind (sceSifBindRpcpolling untilclient->server != 0) spun forever, and nosceCdReadever issued.With bind fixed, the boot handshake (
SifCallRpc(scmd, 0x27, ...)) received a zeroed buffer and the caller spun onrecv[0] == 0.Fix
cdvdman(the mcserv/libsd/dbcman pattern; no module aliases — it is ROM-resident, not a loadable module) publishing the four cdvdfsv routes.handleRpcanswers a neutral ready / no-error / zero payload and logs unmodeled commands (rate-limited,unknown_rpc_logsmetric) so unknown Scmd/Ccmd traffic stays visible without spamming.writeBootHandshakeReplyanswers{1, 0, 0}on Scmd 0x27 (the boot-denominator handshake: success word 1, no error, zero payload) so the EE caller leaves the handshake spin.Test
ps2_iop_tests"cdvdman ROM service serves the cdvdfsv RPC family": the four SIDs bind without any module load, the reply is delivered to the receive buffer, unknown commands are answered neutral + logged; the handshake first word is pinned == 1 (the original!= 0assertion was satisfied by 0xCC prefill poison — a false positive, hardened in a follow-up commit here).Measured (MOH:Vanguard boot)
Bind delay loop 13.132 enters → 1; bind → call → callback cycle 3.644x / 60 s (~61 Hz); the game exits the handshake and issues 1.867
sceCdRead(LBN 0x10)PVD probes.Related: #358 (Mana Khemia) documents the cdvdfsv bind gap; #359 fixes
sceCdLayerSearchFile/loadModuleBuffer/sceSifSearchModuleByAddress— complementary, it does not publish the cdvdfsv servers or answer the Scmd 0x27 handshake, which is the half this PR covers.🤖 Generated with Claude Code
Suite evidence
Fresh configure+build of
ps2x_testson this branch (VS 2022, Release): 447/447 passed, 0 failed.