ec82764bef
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>
127 lines
4.7 KiB
Markdown
127 lines
4.7 KiB
Markdown
# Ch300 closeout — MMI3 PCPYH; another adjacent-syscall surfaces
|
|
|
|
**Status:** Closed. Codex's PCPYH semantics (sa=0x1B, $rs-ignored,
|
|
broadcast low halfword of each $rt doubleword) implemented and
|
|
tested. **Verdict from re-running qbert.elf:**
|
|
`elf_first_unhandled_syscall (pc=0x00112A84 $v1=0x17 (=23))`. qbert
|
|
advanced 28,655 → **28,708 retires (+53)** through PCPYH and into
|
|
another syscall.
|
|
|
|
## What landed — `rtl/ee/ee_core_stub.sv`
|
|
|
|
Five surgical edits via the Ch278/281/283 MMI narrow-decode
|
|
pattern:
|
|
|
|
1. `localparam MMI3_PCPYH = 5'h1B` alongside MMI3_PCPYUD (0x0E).
|
|
2. `is_pcpyh` decode flag.
|
|
3. `is_pcpyh` added to `is_rtype_alu` and `is_mmi_wb`; `!is_pcpyh`
|
|
added to MMI nop_class exclusion.
|
|
4. **Low-32 mirror arm:** `rtype_alu_wb = {rt128_val[15:0],
|
|
rt128_val[15:0]}` — broadcasts h0 across the low 32 (the
|
|
regfile mirror sees `{h0,h0}`).
|
|
5. **Full-128 writeback:** `rtype_alu128_wb = {{4{rt128_val[79:64]}},
|
|
{4{rt128_val[15:0]}}}` — broadcasts h0 across low 64 lanes and
|
|
h4 across high 64 lanes. Exactly Codex's spec.
|
|
|
|
`$rs` is architecturally ignored — the decode uses opcode+funct+sa
|
|
only, no rs check. The TB's Case 2 verifies this.
|
|
|
|
## Focused TB — `tb_ee_core_pcpyh.sv`
|
|
|
|
Three cases:
|
|
|
|
1. **Exact qbert encoding asserted** == `0x70081EE9`. Seeds
|
|
gpr128[$t0] via PCPYLD($t0, $t1, $t2) where $t1 low 16 = 0xABCD
|
|
(→ h4) and $t2 low 16 = 0x1234 (→ h0). Then PCPYH $v1, $t0.
|
|
Verified:
|
|
- `regfile[$v1] = 0x12341234`
|
|
- `gpr128[$v1][63:0] = 0x1234_1234_1234_1234`
|
|
- `gpr128[$v1][127:64] = 0xABCD_ABCD_ABCD_ABCD`
|
|
2. **$rs-ignored check:** PCPYH $t3, $t0 with rs=$v1 (non-zero).
|
|
Asserts gpr128[$t3] == gpr128[$v1] (same full 128-bit result;
|
|
$rs change has no effect).
|
|
3. **Narrow decode:** neighbor MMI3 sa=0x1C (unallocated) still
|
|
traps under strict mode.
|
|
|
|
Result: `retired=16 halt=0 trap=1 errors=0 PASS`. The TB also
|
|
verifies the full SUMMARY line shows the broadcast pattern in
|
|
hex.
|
|
|
|
## Makefile + regression
|
|
|
|
- `tb_ee_core_pcpyh` target.
|
|
- Added to both PHONY list and `run:` master list.
|
|
- Regression: 176 → **177**.
|
|
|
|
## qbert progression
|
|
|
|
| Chapter | Blocker | retire_count |
|
|
|---|---|---|
|
|
| Post-Ch299 (gate poke) | MMI3 PCPYH at 0x00110BB4 | 28,655 |
|
|
| **Post-Ch300 (PCPYH)** | **syscall $v1=0x17 at 0x00112A84** | **28,708 (+53)** |
|
|
|
|
Small advance (+53) because qbert went immediately from the PCPYH
|
|
into the next syscall. The new blocker is in a different code
|
|
region (PC 0x00112A84 is near earlier syscall sites — close to
|
|
the Ch289 0x78 area at 0x00112AA4).
|
|
|
|
## Ch301 framing — syscall 0x17
|
|
|
|
```
|
|
$v1 = 0x17 (= 23)
|
|
$a0 = 0x00000005 (channel id 5, same as Ch290/291)
|
|
$a1 = 0x00000000
|
|
$a2 = 0xFFFFFFFF (-1, sentinel?)
|
|
$a3 = 0x00137568 (NEW context pointer, NOT the global ctx 0x001328C0)
|
|
```
|
|
|
|
Notable shifts from earlier syscalls:
|
|
- `$a3` has CHANGED again: previously 0x001328C0 (global ctx),
|
|
then 0x00137568 (different region — looks like a per-channel
|
|
state buffer? same low byte as the Ch299 halt's $a0=0x00137540).
|
|
- `$a0 = 5` matches the channel id used in Ch290/291 (the DMAC
|
|
handler-install pair). So qbert is doing channel-5-specific
|
|
cleanup or query.
|
|
- `$a2 = -1` is unusual — often a "no filter" or "all" sentinel.
|
|
|
|
PS2 syscall 0x17 (= 23) in standard tables is commonly cited as
|
|
`SetVTLBRefillHandler` or `iWakeupThread` or similar. The
|
|
$a0=channel pattern fits a per-channel kernel call.
|
|
|
|
Mechanical recipe: 9th narrow $v0=0 case in the dispatcher +
|
|
runner observer with full arg snapshot. Standard Ch289-pattern
|
|
extension.
|
|
|
|
## Pattern review (30 chapters)
|
|
|
|
| Era | Chapters | Effect |
|
|
|-----|----------|--------|
|
|
| Opcode-blocker | Ch271..Ch286 | R5900 opcodes |
|
|
| MMIO stubs | Ch287..Ch288 | DMAC ctrl + per-channel |
|
|
| Syscall HLE narrow | Ch273/285/289/290/291/293/296/297 | $v0=0 narrow cases |
|
|
| Narrow NOP-class | Ch286/292 | side-effect-free accepts |
|
|
| Inflection #1 | Ch293 | first wait loop |
|
|
| Investigation #1 | Ch294 | bit-17 syscall poll |
|
|
| Experimental unblock #1 | Ch295 | $a0-aware HLE |
|
|
| Inflection #2 | Ch297 | second wait loop |
|
|
| Investigation #2 | Ch298 | memory poll at 0x001329C0 |
|
|
| Experimental unblock #2 | Ch299 | TB-side gate poke |
|
|
| **MMI op** | **Ch300 (PCPYH)** | **mechanical MMI extension** |
|
|
|
|
The chapter cadence is now well-mixed: opcode chapters, MMIO
|
|
chapters, syscall HLE chapters, narrow NOP-class chapters, and
|
|
investigation/unblock 3-chapter cycles. All productive.
|
|
|
|
## Files changed
|
|
|
|
- `rtl/ee/ee_core_stub.sv` — 5 surgical edits (localparam, decode
|
|
flag, is_rtype_alu/is_mmi_wb/nop_class wiring, two writeback
|
|
arms).
|
|
- `sim/tb/integration/tb_ee_core_pcpyh.sv` — new focused TB.
|
|
- `sim/Makefile` — target + both regression lists.
|
|
|
|
## Regression
|
|
|
|
**177/177 PASS** (was 176 in Ch299; +1 for the new
|
|
tb_ee_core_pcpyh).
|