diff options
| author | user <user@clank> | 2026-09-24 12:43:33 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-24 12:43:33 +0200 |
| commit | a9b5ea82b0061ae6b20579356c6e6566ecf97461 (patch) | |
| tree | 273200b1e6635d21a071ee699efdaf45f03e4948 /psp_emu | |
| parent | Mark ifwi_parse_model as diverging from firmware; revert an attempted fix (diff) | |
| download | amd-psp-re-a9b5ea82b0061ae6b20579356c6e6566ecf97461.tar.gz amd-psp-re-a9b5ea82b0061ae6b20579356c6e6566ecf97461.tar.xz amd-psp-re-a9b5ea82b0061ae6b20579356c6e6566ecf97461.zip | |
Retract the "flat ring oracle": the readback address was wrong, not the path
A previous commit concluded full_system's ring response path was unfaithful
because LOAD_TA, INVOKE_CMD and an invalid command 0x55 all reported status 0,
where hardware returns 0x100 for an unknown id. That conclusion was wrong.
The firmware writes the response into the ALIAS copy of the command buffer
(cmdbuf + 0x04000000), not into cmdbuf itself. Reading cmdbuf returns a stale 0
for every command -- indistinguishable from a flat oracle. Sentinel-testing both
copies shows the alias carrying real values: invalid 0x55 -> 0x100,
GET_FW_ATTESTATION -> 0xffff0008.
Added Ring.response() in harness/mailbox.py, which reads the correct address and
documents why, so this cannot recur. Emulated statuses now match the RX 7900 XTX
table 5/6:
0x00/0x55/0x99/0xfe -> 0x100 MATCH unknown command
0x03 INVOKE_CMD -> 0x117 MATCH bad session
0x02 UNLOAD_TA -> 0x11a vs hw 0x117, state-dependent
That also corrects the RAS finding from two commits ago. With the right
readback, LOAD_TA returns 0xffff000b -- it FAILS. It only read as 0 because of
the stale address, so "LOAD_TA registers no session" was really "LOAD_TA
fails", and INVOKE_CMD's 0x117 is simply the honest consequence. Finding why
LOAD_TA returns 0xffff000b is now the concrete next step, and it is a real
question rather than a harness artefact.
ras_in_fullsys.py updated to use Ring.response(). Suite green.
Diffstat (limited to 'psp_emu')
| -rw-r--r-- | psp_emu/harness/mailbox.py | 21 | ||||
| -rw-r--r-- | psp_emu/harness/ras_in_fullsys.py | 7 |
2 files changed, 26 insertions, 2 deletions
diff --git a/psp_emu/harness/mailbox.py b/psp_emu/harness/mailbox.py index 1b008d0..ba1133b 100644 --- a/psp_emu/harness/mailbox.py +++ b/psp_emu/harness/mailbox.py @@ -158,6 +158,27 @@ class Ring: except Exception: pass + RESP_OFF = 0x360 # psp_gfx_cmd_resp.resp.status, verified on hardware + + def response(self): + """Read the firmware's response status for the last submitted command. + + IMPORTANT: the firmware writes the response into the ALIAS copy of the + command buffer (`cmdbuf + ALIAS`), not into `cmdbuf` itself. Reading + `cmdbuf` gives a stale 0 for every command, which looks exactly like a + flat oracle and silently invalidates any status comparison -- an earlier + session concluded "full_system's ring response path is unfaithful" on + that basis, and it was the readback that was wrong, not the path. + + Verified against hardware semantics: an unknown command id returns + 0x100 here, the same value an RX 7900 XTX returns + (HW-VALIDATION-RX7900XTX.md). + """ + import struct + raw = bytes(self.c.uc.mem_read(self.cmdbuf + self.ALIAS + self.RESP_OFF, 8)) + status, session = struct.unpack("<2I", raw) + return status, session + def submit(self, cmd_id, buf_extra=b"", timeout=5.0, probe=None): import struct buf = bytearray(0x400) diff --git a/psp_emu/harness/ras_in_fullsys.py b/psp_emu/harness/ras_in_fullsys.py index 33e87a3..47c31ab 100644 --- a/psp_emu/harness/ras_in_fullsys.py +++ b/psp_emu/harness/ras_in_fullsys.py @@ -80,8 +80,11 @@ def main(): ring = M.Ring(c, irqs, BM.RING_PA, BM.RING_SZ, BM.CMDBUF_PA, run) def resp(): - raw = bytes(c.uc.mem_read(BM.CMDBUF_PA + RESP_OFF, 8)) - return struct.unpack("<2I", raw) + # Read via Ring.response(): the firmware writes the response into the + # ALIAS copy of the command buffer, not into cmdbuf itself. Reading + # cmdbuf returns a stale 0 for everything, which previously looked like + # a flat status oracle and made the session id read as 0. + return ring.response() boot_blocks = len(ras_blocks) print("RAS blocks from boot alone : %d" % boot_blocks) |
