0d100eb84fee92ebf0a517c452e7a79f28b75789
The BBA has two interrupt levels and we implemented only one. Both drivers' handlers are identical in shape -- libogc2's bba_event_handler and Swiss's exi_coroutine: status = bba_cmd_in8(0x03); /* COMMAND level */ bba_cmd_out8(0x02, BBA_CMD_IRMASKALL); if (status & 0x80) bba_interrupt(); /* ONLY then the MAC level */ and bba_interrupt() is what reads register-space IR/IMR and calls bba_start_rx(). Bit 7 of command register 0x03 means "a MAC interrupt is pending". r_cmd_ir was write-1-clear with nothing ever setting it, so a command read of 0x03 returned 0x00, every branch of both handlers fell through, and NEITHER DRIVER WOULD EVER HAVE PROCESSED A RECEIVED FRAME. Our own tooling could not have caught it: gc_bba_test and netboot poll RWP/IR directly and never use the interrupt path, so the whole command-level mechanism was untested and unused. Green suite, dead interface. cmd_ir[7] is now a live level equal to (IR & IMR) != 0, and INT_N is (cmd_ir & cmd_imr) != 0. A level rather than a latch because both drivers clear the MAC IR inside bba_interrupt() and only then write-1-clear command 0x03: a latched bit would be cleared by that write even if a new frame had arrived in between, while a level stays asserted as long as the condition does. INT_N honouring the command-level mask is what stops the line re-asserting while a handler runs (IRMASKALL on entry, IRMASKNONE on exit). r_cmd_imr resets to 0xF8 since the real power-on value is unknown and both drivers set it explicitly first thing. T13 and T13b cover it, both mutation-tested: reading the latched bits only leaves 0x00 after an RI, and ignoring the command mask leaves INT_N asserted through IRMASKALL. Also records in CLAUDE.md which driver actually talks to us, since Swiss has several back-ends and it is easy to read the wrong one: cube/patches/bba/ has one file per chip (bba.c is ours; enc28j60.c, w5500.c, w6100.c, w6300.c are other adapters), Swiss's menu networking goes through libogc2's gcif.c, and cube/patches/bba/bba.c is the in-game patch driver. Detection is by EXI device ID, so returning 04 02 02 00 is what gets us handed to the BBA path at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
No description provided
Languages
Python
84.9%
C
12.4%
Shell
1.1%
Dockerfile
0.7%
Makefile
0.4%
Other
0.5%