Add experimental I2C debugging and EEPROM analysis tools
One-off diagnostic scripts from experiments 0xD7-0xDB investigating the I2C BERR deadlock. Documents the systematic elimination of software-only recovery approaches: - i2c_host_test.py: Proved 0xA0 register writes cannot drive I2C bus - i2c_register_test.py: Tested I2C register writability from host - i2c_recovery_boot.py: Attempted I2C state machine recovery via boot - eeprom_flash_a0.py: Host-side EEPROM flash attempt (failed) - boot_ab_test.py / boot_test.py: EEPROM boot reliability testing - a8_autoclear_test.py: BCM4500 command register auto-clear behavior - addr_gateway_test.py: BCM3440 gateway address routing analysis - stock_fw_compare.py / stock_fw_test.py: Stock vs custom fw analysis
This commit is contained in:
parent
97c1000d8b
commit
0d6facb321
16 changed files with 3279 additions and 0 deletions
77
tools/eeprom_sentinel_scan.py
Normal file
77
tools/eeprom_sentinel_scan.py
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Find the count=0 sentinel in the BCM4500 firmware data at 0x4000+."""
|
||||
import sys
|
||||
sys.path.insert(0, 'tools')
|
||||
from skywalker_lib import SkyWalker1
|
||||
|
||||
CMD_EEPROM_READ = 0xC0
|
||||
sw = SkyWalker1()
|
||||
sw.open()
|
||||
|
||||
|
||||
def ee(addr, length):
|
||||
return sw._vendor_in(CMD_EEPROM_READ, value=addr, index=length, length=length)
|
||||
|
||||
|
||||
print('=== Scanning for count=0 sentinel from 0x4000 ===')
|
||||
print()
|
||||
|
||||
blocks = 0
|
||||
total_bytes = 0
|
||||
addr = 0x4000
|
||||
|
||||
while addr < 0x8000:
|
||||
data = ee(addr, 20)
|
||||
count = data[0]
|
||||
|
||||
if count == 0:
|
||||
print(f' SENTINEL FOUND at 0x{addr:04X} after {blocks} blocks ({total_bytes} payload bytes)')
|
||||
break
|
||||
|
||||
if count > 16:
|
||||
print(f' INVALID count=0x{count:02X} at 0x{addr:04X} after {blocks} blocks')
|
||||
# Show context
|
||||
for ctx_addr in range(max(0x4000, addr - 60), addr + 60, 20):
|
||||
d = ee(ctx_addr, 20)
|
||||
marker = ' ← INVALID' if ctx_addr == addr else ''
|
||||
print(f' 0x{ctx_addr:04X}: count={d[0]:3d} A9=0x{d[1]:02X} AA=0x{d[2]:02X}{marker}')
|
||||
break
|
||||
|
||||
# Valid block
|
||||
a9 = data[1]
|
||||
aa = data[2]
|
||||
ab_bytes = count
|
||||
total_bytes += ab_bytes
|
||||
|
||||
if blocks < 5 or blocks % 100 == 0:
|
||||
ab = data[4:4 + min(count, 8)]
|
||||
print(f' Block {blocks:4d} @ 0x{addr:04X}: count={count:2d} A9=0x{a9:02X} AA=0x{aa:02X} '
|
||||
f'AB=[{ab.hex(" ")}{"..." if count > 8 else ""}]')
|
||||
|
||||
blocks += 1
|
||||
addr += 20
|
||||
|
||||
else:
|
||||
print(f' NO SENTINEL found before 0x8000 ({blocks} blocks scanned)')
|
||||
|
||||
print()
|
||||
print(f'Summary: {blocks} blocks, {total_bytes} payload bytes')
|
||||
print(f'Address range: 0x4000 - 0x{addr:04X}')
|
||||
|
||||
# Show the sentinel and what follows
|
||||
if addr < 0x8000:
|
||||
print()
|
||||
print(f'--- Data around sentinel at 0x{addr:04X} ---')
|
||||
for a in range(max(0x4000, addr - 40), addr + 60, 20):
|
||||
d = ee(a, 20)
|
||||
cnt = d[0]
|
||||
if cnt == 0:
|
||||
print(f' 0x{a:04X}: [SENTINEL count=0] rest: {d[1:].hex(" ")}')
|
||||
elif 1 <= cnt <= 16:
|
||||
print(f' 0x{a:04X}: count={cnt} A9=0x{d[1]:02X} AA=0x{d[2]:02X}')
|
||||
else:
|
||||
print(f' 0x{a:04X}: [non-PLL: 0x{cnt:02X}] {d[:16].hex(" ")}')
|
||||
|
||||
sw.close()
|
||||
print()
|
||||
print('=== Done ===')
|
||||
Loading…
Add table
Add a link
Reference in a new issue