skywalker-1/tools/eeprom_pll_find.py

109 lines
3.4 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""Find the exact EEPROM address where PLL config starts.
The stock firmware's FUN_CODE_10F2 presumably finds the PLL data by
computing an offset from the C2 boot firmware structure. This script
parses the C2 records to find where the firmware ends, then checks
if PLL data immediately follows.
"""
import sys
sys.path.insert(0, 'tools')
from skywalker_lib import SkyWalker1
CMD_EEPROM_READ = 0xC0
sw = SkyWalker1()
sw.open()
def eeprom_read(addr, length):
return sw._vendor_in(CMD_EEPROM_READ, value=addr, index=length, length=length)
print('=== C2 Firmware Structure Analysis ===')
print()
# Read C2 header (8 bytes)
header = eeprom_read(0x0000, 8)
print(f'Header: {header.hex(" ")}')
assert header[0] == 0xC2, 'Not a C2 EEPROM!'
vid = header[2] << 8 | header[1]
pid = header[4] << 8 | header[3]
print(f' VID: 0x{vid:04X} PID: 0x{pid:04X}')
print()
# Parse C2 load records
offset = 8
records = []
print('C2 Load Records:')
while offset < 0x8000:
hdr = eeprom_read(offset, 4)
rec_len = (hdr[0] << 8) | hdr[1]
rec_addr = (hdr[2] << 8) | hdr[3]
if rec_len == 0x8001:
print(f' [{len(records)}] END MARKER at EEPROM 0x{offset:04X} → entry=0x{rec_addr:04X}')
records.append({'type': 'end', 'offset': offset, 'entry': rec_addr})
offset += 4
break
elif rec_len == 0 or rec_len > 0x4000:
print(f' [{len(records)}] INVALID at EEPROM 0x{offset:04X}: len=0x{rec_len:04X}')
records.append({'type': 'invalid', 'offset': offset})
offset += 4
break
end_addr = rec_addr + rec_len - 1
print(f' [{len(records)}] {rec_len:5d} bytes at EEPROM 0x{offset:04X} → RAM 0x{rec_addr:04X}-0x{end_addr:04X}')
records.append({'type': 'data', 'offset': offset, 'len': rec_len, 'addr': rec_addr})
offset += 4 + rec_len
print(f'\nFirmware ends at EEPROM offset: 0x{offset:04X}')
print()
# Check what's right after the firmware
print(f'--- Data immediately after firmware (0x{offset:04X}) ---')
for addr in range(offset, offset + 128, 16):
data = eeprom_read(addr, 16)
hex_str = ' '.join(f'{b:02X}' for b in data)
print(f' {addr:04X}: {hex_str}')
print()
# Now check: does PLL data start right after the C2 firmware?
print(f'--- PLL block check starting at 0x{offset:04X} ---')
for addr in range(offset, offset + 200, 20):
block = eeprom_read(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}: count=0x{count:02X} (invalid, not PLL data)')
break
print()
# Also check the known PLL location from the scan
print('--- Confirmed PLL data at 0x125C (from EEPROM scan) ---')
for addr in range(0x125C, 0x12C0, 20):
block = eeprom_read(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 (count=0x{count:02X})')
break
sw.close()
print()
print('=== Done ===')