Fix command-space writes, and replay libogc's real init sequence
Second protocol mismatch found the same way as the descriptor: by disassembling libogc's own driver instead of trusting our notes. COMMAND SPACE IS A 2-BYTE HEADER + DATA PHASE, not a single 4-byte transfer. CLAUDE.md said [0x40|reg, 00, 00, data] and the decoder followed it, waiting for a fourth byte and consuming the DATA byte as header byte 2 -- so every command-space WRITE was silently dropped. libogc's __bba_init writes command register 2 (its interrupt mask) at both the start and the end of init, so none of that took effect. What it actually sends: EXI_Imm (len=2, write) -> 42 00 the whole header, 0x4000 | (reg << 8) EXI_Sync EXI_ImmEx(len=1, write) -> 00 the data Three bytes between CS fall and CS rise. The device-ID read survived the wrong decode only because SPIMode3Slave answers it on a fast path independent of this FSM -- which is precisely why no test caught it: the only command-space traffic under test bypassed the decoder being tested. CHDR_2/CHDR_3 are replaced by CMD_WRITE, which takes the data byte straight after header byte 1 and auto-increments the command register so a multi-byte command write behaves like the register-space path. cmd_wreg latches the target because the write applies a cycle later, by which time cmd_reg has moved on. bba_register_file T10 writes command register 2 and reads it back, and is mutation-tested: restoring the 4-byte decode fails it. Also replaces the GUESSED init sequence in CLAUDE.md with the real transaction list. The old one was wrong in three ways that matter: libogc READS the MAC out of PAR0-5 rather than writing one (so our reset value is what the console uses), IMR is 0xDF not 0x86, and it writes RWP (0x0016/17) and RHBP (0x001A/1B) which the register file does not accept. The latter is harmless today -- RHBP is 0x000F, matching our hardcoded 15-page ring -- but a driver configuring a smaller ring would be ignored while the assembler kept writing outside it. New gc_bba_test suite 7 "libogc init" replays the sequence on hardware: cmd-space write (2-byte header, read back), MAC readable (one 6-byte PAR read, Nintendo OUI), and init replay (all 30 writes in order, then NWAYS/HIPR/NCRA.SR must still read correctly -- the old guessed header format turned a NWAYS read into an NCRA reset, so a misdecoded write is a real risk). bba.c gains bba_cmd_write/bba_cmd_read in libogc's shape. Every module testbench and bba_top at EXI_HALF=1/2/8 pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,6 +102,43 @@ int bba_devid(u8 id[4])
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* COMMAND-space access: a 2-BYTE header then a data phase -- three bytes
|
||||
* total for a single-byte write, NOT a 4-byte transfer. This is the shape
|
||||
* libogc's own driver uses (gcif.o, __bba_init):
|
||||
*
|
||||
* EXI_Imm (len=2, write) -> [0x40|reg, 0x00] write, or [reg, 0x00] read
|
||||
* EXI_Sync
|
||||
* EXI_ImmEx(len=N, write/read)
|
||||
*
|
||||
* The device-ID query is the same form with reg 0 and a 4-byte read, which is
|
||||
* why bba_devid above looks like this too. */
|
||||
int bba_cmd_write(u8 creg, u8 val)
|
||||
{
|
||||
int rc;
|
||||
u16 h = (u16)(((0x40 | (creg & 0x3F)) << 8));
|
||||
if ((rc = begin()) < 0) return rc;
|
||||
if (EXI_Imm(BBA_EXI_CHAN, &h, 2, EXI_WRITE, NULL) <= 0) { end(); return -3; }
|
||||
if (EXI_Sync(BBA_EXI_CHAN) <= 0) { end(); return -4; }
|
||||
gap();
|
||||
if (EXI_ImmEx(BBA_EXI_CHAN, &val, 1, EXI_WRITE) <= 0) { end(); return -5; }
|
||||
end();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bba_cmd_read(u8 creg)
|
||||
{
|
||||
int rc;
|
||||
u8 v = 0;
|
||||
u16 h = (u16)(((creg & 0x3F) << 8));
|
||||
if ((rc = begin()) < 0) return rc;
|
||||
if (EXI_Imm(BBA_EXI_CHAN, &h, 2, EXI_WRITE, NULL) <= 0) { end(); return -3; }
|
||||
if (EXI_Sync(BBA_EXI_CHAN) <= 0) { end(); return -4; }
|
||||
gap();
|
||||
if (EXI_ImmEx(BBA_EXI_CHAN, &v, 1, EXI_READ) <= 0) { end(); return -5; }
|
||||
end();
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
int bba_r8(u16 addr)
|
||||
{
|
||||
u8 v;
|
||||
|
||||
Reference in New Issue
Block a user