/* bba.h — raw EXI transport to the re-bba-rb adapter in Serial Port 1. * * Deliberately NOT libogc's bba network driver: this talks to the register * file directly so every check gets its own pass/fail and a failure points at * a specific register rather than at "networking". */ #ifndef BBA_H #define BBA_H #include /* Serial Port 1 == EXI channel 0, device 2. */ #define BBA_EXI_CHAN EXI_CHANNEL_0 #define BBA_EXI_DEV EXI_DEVICE_2 /* Register map (see CLAUDE.md "Key Registers"). */ #define REG_NCRA 0x00 #define REG_IMR 0x08 #define REG_IR 0x09 #define REG_RWP_LO 0x16 #define REG_RWP_HI 0x17 #define REG_RRP_LO 0x18 #define REG_PAR0 0x20 #define REG_PAR4 0x24 #define REG_NWAYS 0x31 #define REG_TWD_LO 0x34 #define REG_TWD_HI 0x35 #define REG_HIPR 0x3A #define REG_TXDATA 0x48 #define SPRAM_BASE 0x0100 /* NCRA bits */ #define NCRA_RESET 0x01 #define NCRA_ST0 0x02 #define NCRA_SR 0x08 /* IR bits */ #define IR_RI 0x02 #define IR_TI 0x04 /* Expected constants */ #define NWAYS_LINKUP 0x17 #define HIPR_PRESENT 0x01 /* EXI clock index, EXI_SPEED1MHZ(0) .. EXI_SPEED32MHZ(5). The nominal 32 MHz * index is really ~27 MHz on hardware (see CLAUDE.md); the capture domain * oversamples it 2x at 54 MHz. Settable so the suite can sweep it. */ extern u32 bba_speed; /* All return 0 on success, negative on an EXI-layer failure. */ /* Immediate read of `len` (1..4) bytes from `addr`. * Clocks EXACTLY `len` bytes: over-clocking a register read leaves stale * prefetched bytes queued in the gateware and desynchronises the NEXT * transaction (hardware-confirmed 2026-09-30). Never pad this. */ int bba_read(u16 addr, void *buf, u32 len); /* Immediate write of `len` (1..4) bytes to `addr`. */ int bba_write(u16 addr, const void *buf, u32 len); /* Convenience single-byte helpers. bba_r8 returns the byte, or <0 on error. */ int bba_r8(u16 addr); int bba_w8(u16 addr, u8 val); /* SPRAM / DMA-style read: any address >= 0x0100 streams until CS deasserts, * so `len` may exceed 4 and the header's 2-bit length field is ignored. */ int bba_stream(u16 addr, void *buf, u32 len); /* Stream `len` bytes into the TXDATA port. One byte per EXI transaction: * the register file's effective address auto-increments per data byte, so a * multi-byte write to 0x48 would spill into 0x49+ instead of the FIFO. */ int bba_tx_bytes(const u8 *buf, u32 len); #endif