RTL (GS rasterizer, EE core stub, platform bridge, LPDDR4B path), sim regression (272 TBs), docs, and tooling. Copyrighted PS2 content (BIOS, game code, GS dumps, and all dump-derived textures/traces) is excluded via .gitignore and stays local. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.7 KiB
Ch301 closeout — syscall 0x17 HLE; second paired-call pattern surfaces at 0x13
Status: Closed. Verdict from re-running qbert.elf:
elf_first_unhandled_syscall (pc=0x00112A64 $v1=0x13 (=19)) with
arguments identical to the just-HLE'd 0x17 call. qbert advanced
28,708 → 28,726 retires (+18) through the syscall 0x17 and
into a companion call.
The second paired-call pattern
| Field | Syscall 0x17 (Ch301) | Syscall 0x13 (Ch302 blocker) |
|---|---|---|
| PC | 0x00112A84 | 0x00112A64 |
| $a0 | 0x00000005 | 0x00000005 |
| $a1 | 0x00000000 | 0x00000000 |
| $a2 | 0xFFFFFFFF | 0xFFFFFFFF |
| $a3 | 0x00137568 | 0x00137568 |
All four args identical. This mirrors the Ch290/291 0x12/0x16
discovery — Add*Handler + Enable*Handler style paired calls.
PS2 syscall 19 (0x13) and syscall 23 (0x17) are adjacent in the
standard kernel table; plausibly a "set" + "register" pair for the
same per-channel resource.
The two paired-call discoveries on the syscall track:
- Ch290/291: 0x12 + 0x16 with
(5, fn_ptr, 0, global_ctx) - Ch301/Ch302: 0x17 + 0x13 with
(5, 0, -1, new_ctx_0x00137568)
Both involve $a0 = 5 (channel id). Different $a3 context
pointers though — the second pair uses a different kernel-state
region (0x00137568 vs 0x001328C0).
What landed
Dispatcher case — rtl/ee/ee_core_stub.sv
9th narrow $v0=0 case in the Ch273 dispatcher:
32'h0000_0017: begin
regfile[2] <= 32'd0;
gpr128[2] <= 128'd0;
pc <= pc + 32'd4;
retire_pulse <= 1'b1;
state <= S_IFETCH_REQ;
end
TB extension — tb_ee_core_syscall_hle.sv
Standard 4-slot subcase + latch + assertion + display. The TB now covers ten known syscall numbers (3C / 3D / 40 / 64 / 78 / 12 / 16 / 7A with $a0=0 and $a0=4 / 79 / 77 / 17) plus the unknown-halt path.
Runner observer — tb_ee_core_elf_runner.sv
6th observer in the library, second to use the richer distinct-tuple tracking (after Ch297 0x77). From qbert's run:
syscall_0x17 = count=1 distinct_tuples=1 first_pc=0x00112a84
$a0=0x00000005 $a1=0x00000000 $a2=0xffffffff $a3=0x00137568 → $v0=0
0x17 tuple[0] = (...same...) count=1
Single call with the args Codex flagged. count=1 means no iteration, no spin — qbert called 0x17 once and moved on. The $a3 context-shift Codex worried about is captured cleanly in the SUMMARY for downstream analysis.
qbert progression
| Chapter | Blocker | retire_count |
|---|---|---|
| Post-Ch300 (PCPYH) | syscall $v1=0x17 at 0x00112A84 | 28,708 |
| Post-Ch301 (syscall 0x17) | syscall $v1=0x13 at 0x00112A64 (identical args) | 28,726 (+18) |
The +18 retires include the 0x17 retire + 17 instructions of glue code + the 0x13 syscall trap. PC walks backward (0x00112A84 → 0x00112A64), same pattern as Ch290/291's paired-call discovery.
Ch302 framing — syscall 0x13
Args identical to the 0x17 call we just HLE'd. High-confidence mechanical recipe:
- 10th narrow $v0=0 case in the dispatcher.
- Runner observer with distinct-tuple tracking (will likely confirm count=1 with the same args — confirmation surface).
- Standard 4-slot TB subcase.
If qbert then progresses normally, the paired-call pattern is fully unblocked. If it misbranches or spins, the symmetric arg shape suggests we'd need to model the actual per-channel state mutation — but that's Ch303+ if needed.
Pattern review (31 chapters)
| Era | Effect |
|---|---|
| Opcode-blocker (Ch271..286) | exhausted |
| MMIO stubs (Ch287..288) | exhausted |
| Syscall HLE narrow (~10 cases now) | active |
| Narrow NOP-class (Ch286/292) | exhausted |
| Investigation/unblock cycles (Ch293-295, Ch297-299) | reusable pattern |
| MMI op extensions (Ch300+) | ride Ch283 gpr128 seam |
| Paired-call discoveries | 2 instances now (0x12/0x16, 0x17/0x13) |
The "paired-call" pattern is now the second observed structural discovery (after the "$a0-aware HLE" of Ch295). Both came out of the runner observer instrumentation Codex pushed for. Each one shortens the next chapter's framing time because the args are predictable.
Files changed
rtl/ee/ee_core_stub.sv— 1 new HLE case (~25 LOC with comment).sim/tb/integration/tb_ee_core_syscall_hle.sv— 4 new slots + 1 latch + 1 assertion + 1 display field.sim/tb/integration/tb_ee_core_elf_runner.sv— 1 new observer block (with distinct-tuple tracking) + SUMMARY display.
No new TB, no new Makefile target; regression count unchanged at 177/177.
Regression
177/177 PASS (unchanged from Ch300; no new TB).