From 0259950dfb66c6ae6f589122bb97fa4e2a288367 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Fri, 20 Feb 2026 12:03:17 -0700 Subject: [PATCH] Stop GPIF streaming before boot/shutdown to prevent bus contention MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- firmware/skywalker1.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/firmware/skywalker1.c b/firmware/skywalker1.c index 5430c17..acd8fd8 100644 --- a/firmware/skywalker1.c +++ b/firmware/skywalker1.c @@ -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; }