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
113 lines
3.3 KiB
Python
113 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Deep EEPROM scan — find the real PLL data location."""
|
|
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)
|
|
|
|
|
|
def hex_line(addr, data):
|
|
hex_str = ' '.join(f'{b:02X}' for b in data)
|
|
return f'{addr:04X}: {hex_str}'
|
|
|
|
|
|
# Dump 0x3F00-0x4100 (area around the boundary — zero gap between FX2 and BCM firmware?)
|
|
print('=== Region around FX2 firmware end (0x2530) ===')
|
|
for addr in range(0x2530, 0x2600, 16):
|
|
d = ee(addr, 16)
|
|
print(f' {hex_line(addr, d)}')
|
|
|
|
print()
|
|
print('=== Region 0x3F00-0x4080 (end of first 16KB, start of second) ===')
|
|
for addr in range(0x3F00, 0x4080, 16):
|
|
d = ee(addr, 16)
|
|
print(f' {hex_line(addr, d)}')
|
|
|
|
# Check the END of the AT24C256 (0x7F00-0x7FFF)
|
|
print()
|
|
print('=== End of EEPROM 0x7F00-0x7FFF ===')
|
|
for addr in range(0x7F00, 0x8000, 16):
|
|
d = ee(addr, 16)
|
|
print(f' {hex_line(addr, d)}')
|
|
|
|
# Parse the second image at 0x4000 to find its end
|
|
print()
|
|
print('=== Parsing 0x4000 as C2-like records ===')
|
|
offset = 0x4000
|
|
# First check if it's a C2 header
|
|
header = ee(0x4000, 4)
|
|
print(f' Header bytes: {header.hex(" ")}')
|
|
# Could be: [len_hi, len_lo, addr_hi, addr_lo]
|
|
rec_len = (header[0] << 8) | header[1]
|
|
rec_addr = (header[2] << 8) | header[3]
|
|
print(f' As record: len={rec_len} (0x{rec_len:04X}), addr=0x{rec_addr:04X}')
|
|
print()
|
|
|
|
# Try parsing as load records (same format as C2 but without the 8-byte header)
|
|
offset = 0x4000
|
|
print(' Attempting record parse:')
|
|
total_size = 0
|
|
while offset < 0x7000:
|
|
hdr = ee(offset, 4)
|
|
rlen = (hdr[0] << 8) | hdr[1]
|
|
raddr = (hdr[2] << 8) | hdr[3]
|
|
|
|
if rlen == 0x8001:
|
|
print(f' [{total_size}] END MARKER at 0x{offset:04X} → entry=0x{raddr:04X}')
|
|
offset += 4
|
|
break
|
|
elif rlen == 0 or rlen > 0x4000:
|
|
print(f' [{total_size}] STOP at 0x{offset:04X}: len=0x{rlen:04X} addr=0x{raddr:04X}')
|
|
# Dump surrounding bytes
|
|
d = ee(offset, 32)
|
|
print(f' Bytes: {d.hex(" ")}')
|
|
offset += 4
|
|
break
|
|
|
|
end = raddr + rlen - 1
|
|
print(f' [{total_size}] {rlen:5d} bytes at EEPROM 0x{offset:04X} → 0x{raddr:04X}-0x{end:04X}')
|
|
offset += 4 + rlen
|
|
total_size += rlen
|
|
if total_size > 30000:
|
|
print(' (aborting, too much data)')
|
|
break
|
|
|
|
print(f' Second image ends at: 0x{offset:04X}')
|
|
print()
|
|
|
|
# Check immediately after second image for PLL data
|
|
print(f'=== After second image: 0x{offset:04X}-0x{offset+256:04X} ===')
|
|
for addr in range(offset, offset + 256, 16):
|
|
d = ee(addr, 16)
|
|
print(f' {hex_line(addr, d)}')
|
|
|
|
# Also check for PLL blocks at this offset
|
|
print()
|
|
print(f'=== PLL block scan starting at 0x{offset:04X} ===')
|
|
for addr in range(offset, offset + 400, 20):
|
|
block = ee(addr, 20)
|
|
count = block[0]
|
|
if count == 0:
|
|
print(f' 0x{addr:04X}: [sentinel count=0]')
|
|
break
|
|
elif 1 <= count <= 16:
|
|
ab = block[4:4 + count]
|
|
print(f' 0x{addr:04X}: count={count} A9=0x{block[1]:02X} AA=0x{block[2]:02X} '
|
|
f'unused=0x{block[3]:02X} AB=[{ab.hex(" ")}]')
|
|
else:
|
|
print(f' 0x{addr:04X}: NOT PLL (first byte=0x{count:02X})')
|
|
# But continue scanning
|
|
pass
|
|
|
|
sw.close()
|
|
print()
|
|
print('=== Done ===')
|