816848a474
- Ghidra decompilation of v1.02-v1.19 blobs (118 functions) - 53 functions renamed, 79 MMIO registers mapped to TRM - 45 timeout-less poll loops identified and patched - Production patcher (patch_prod.py) and QEMU emulator - Comprehensive analysis, frequency tables, community research Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
49 lines
1.9 KiB
Python
49 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""RK3588 DDR Blob Patcher - converts infinite poll loops to single checks."""
|
|
import struct, os
|
|
|
|
def patch_blob(inpath, outpath):
|
|
with open(inpath, 'rb') as f:
|
|
blob = bytearray(f.read())
|
|
|
|
patched = 0
|
|
patches = []
|
|
NOP = 0xD503201F
|
|
|
|
for i in range(0, len(blob) - 12, 4):
|
|
inst = struct.unpack_from('<I', blob, i)[0]
|
|
if (inst & 0xFF000010) == 0x54000000:
|
|
imm19 = (inst >> 5) & 0x7FFFF
|
|
if imm19 & 0x40000:
|
|
offset = -((~imm19 & 0x7FFFF) + 1) * 4
|
|
if -16 <= offset <= -4:
|
|
loop_start = i + offset
|
|
has_load = False
|
|
for j in range(loop_start, i, 4):
|
|
w = struct.unpack_from('<I', blob, j)[0]
|
|
if (w & 0xFFC00000) in (0xB9400000, 0xF9400000, 0xB9800000):
|
|
has_load = True
|
|
break
|
|
if has_load:
|
|
cond = inst & 0xF
|
|
cond_names = ['EQ','NE','CS','CC','MI','PL','VS','VC','HI','LS','GE','LT','GT','LE','AL','NV']
|
|
old = struct.unpack_from('<I', blob, i)[0]
|
|
struct.pack_into('<I', blob, i, NOP)
|
|
patches.append((i, old, cond_names[cond], offset))
|
|
patched += 1
|
|
|
|
with open(outpath, 'wb') as f:
|
|
f.write(blob)
|
|
|
|
print(f'Patched {patched} tight poll loops:')
|
|
for addr, old, cond, offset in patches:
|
|
print(f' 0x{addr:05x}: B.{cond} {offset} -> NOP')
|
|
|
|
return patched, len(blob)
|
|
|
|
infile = '/opt/rkbin/bin/rk35/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.19.bin'
|
|
outfile = '/opt/work/rk3588_ddr_v1.19_patched.bin'
|
|
n, size = patch_blob(infile, outfile)
|
|
orig_size = os.path.getsize(infile)
|
|
print(f'\nOriginal: {orig_size}, Patched: {size} ({"MATCH" if orig_size == size else "MISMATCH!"})')
|