Stop GPIF streaming before boot/shutdown to prevent bus contention

Stock firmware (0x1D62-0x1D6A) calls GPIF abort (0x1919) while the
BCM4500 is held in reset, before programming init blocks.  If BOOT_8PSK
is called while streaming is active, GPIF and I2C contend for the
BCM4500's bus, corrupting init block writes.

Add gpif_stop() guard at the top of bcm4500_boot() and
bcm4500_shutdown() — matches the stock firmware's safety sequence.

Code: 15,171 / 15,360 bytes (+16 bytes, 189 spare)
This commit is contained in:
Ryan Malloy 2026-02-20 12:03:17 -07:00
parent dffef75b06
commit 0259950dfb

View File

@ -1097,6 +1097,9 @@ fail_exit:
return FALSE;
}
/* Forward declaration: gpif_stop() defined in streaming section below */
static void gpif_stop(void);
/*
* BCM4500 full boot sequence, reverse-engineered from stock firmware
* FUN_CODE_1D4F (reset/power) + FUN_CODE_10F2 (PLL config from EEPROM)
@ -1115,6 +1118,13 @@ fail_exit:
static BOOL bcm4500_boot(void) {
boot_stage = 1; /* Stage 1: GPIO setup */
/* Safety: stop streaming if active. Stock firmware (0x1D62-0x1D6A)
* asserts reset then calls GPIF abort (0x1919) before init. GPIF and
* I2C share the BCM4500's attention concurrent access causes bus
* contention that corrupts init block writes. */
if (config_status & BM_ARMED)
gpif_stop();
/* P3.7, P3.6, P3.5 HIGH (idle state for control lines) */
IOD |= 0xE0;
@ -1193,9 +1203,16 @@ static BOOL bcm4500_boot(void) {
/*
* BCM4500 shutdown -- reverse of boot.
* From stock firmware FUN_CODE_1D4F shutdown path at 0x1D93.
* From stock firmware FUN_CODE_1D4F error path at 0x1D93:
* ANL 6Dh,#BCh (clear init/fw/gpif flags)
* CLR bit_09h (clear streaming)
* LCALL 1919h (GPIF abort)
* PA1=0, PA2=1 (restore normal GPIO)
* CLR bit_08h (mark not booted)
*/
static void bcm4500_shutdown(void) {
if (config_status & BM_ARMED)
gpif_stop();
/* Power off: P0.1 LOW (enable off), P0.2 HIGH (disable) */
IOA = (IOA & ~PIN_PWR_EN) | PIN_PWR_DIS;
}