aboutsummaryrefslogtreecommitdiffstats
path: root/psp_out/df_psp_probe.py
blob: 9ed3855c6658c48f62014907c3c5ed3a5a13f0cb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
"""Is the "$PSP" at DF 0xd800000 real structure, or another artifact?
Checks: control addresses, interleave stability, longer dump, and whether the
bytes actually parse as a PSP directory table."""
import sys, struct
sys.path.insert(0,"/Users/user/src/tinygrad"); sys.path.insert(0,"/Users/user/dev/amd-psp-re/psp_out")
from tinygrad import Device
import regguard
d=Device["AMD"]; adev=d.iface.dev_impl
def rd(a):
    adev.wreg(14,a&0xffffffff); return adev.rreg(15)
def bs(v): return struct.unpack('<I',struct.pack('>I',v&0xffffffff))[0]
B=0xd800000
print("=== 1. regguard with tight + far controls ===")
r=regguard.classify_read(rd,[B,B+4,B+0xc,B+0x10],
    controls=[B-0x1000,B+0x1000,B-0x10000,B+0x100000,0x0badf000])
for k,v in r.items(): print("   %-12s %s"%(hex(k) if isinstance(k,int) else k,v))
print("\n=== 2. interleave stability (stale latch?) ===")
seq=[rd(B),rd(0x0badf000),rd(B),rd(B+4),rd(B),rd(0x16600),rd(B)]
print("   B,bogus,B,B+4,B,THM,B =",[hex(x) for x in seq])
print("   B stable:",seq[0]==seq[2]==seq[4]==seq[6])
print("\n=== 3. dump 0x80 dwords from %#x ==="%B)
dw=[rd(B+4*i) for i in range(0x80)]
for i in range(0,0x80,8):
    print("   +%03x: %s"%(i*4," ".join("%08x"%x for x in dw[i:i+8])))
print("\n=== 4. does it parse as an AMD PSP directory? ===")
raw=b"".join(struct.pack('<I',x) for x in dw)
magic=raw[:4]; cksum,=struct.unpack_from('<I',raw,4); n,=struct.unpack_from('<I',raw,8)
print("   magic=%r  checksum=%#x  num_entries=%d  reserved=%#x"%(magic,cksum,n,struct.unpack_from('<I',raw,12)[0]))
if magic==b'$PSP' and 0<n<64:
    print("   entries (type, subprog, size, addr):")
    for i in range(min(n,12)):
        o=16+16*i
        if o+16>len(raw): break
        t=raw[o]; sp=raw[o+1]; sz,=struct.unpack_from('<I',raw,o+8); ad,=struct.unpack_from('<Q',raw,o+8) if o+16<=len(raw) else (0,)
        sz,=struct.unpack_from('<I',raw,o+4); adr,=struct.unpack_from('<Q',raw,o+8)
        print("     [%2d] type=%#04x subprog=%#x size=%#010x addr=%#018x"%(i,t,sp,sz,adr))
else:
    print("   does NOT parse as a directory (magic or count implausible)")
print("\n=== 5. compare with the on-disk flash image we already hold ===")
try:
    fl=open('flash_BIOS2_KNOWNGOOD_20260917.bin','rb').read()
    off=fl.find(b'$PSP')
    print("   on-disk flash: first $PSP at %#x ; first 32B: %s"%(off, fl[off:off+32].hex()))
    print("   DF window     first 32B: %s"%raw[:32].hex())
    print("   IDENTICAL: %s"%(fl[off:off+32]==raw[:32]))
except Exception as e: print("   (no flash image: %s)"%e)
print("\nMEMSIZE=%s sos_alive=%s"%(hex(adev.rreg(0xde3)),adev.psp.is_sos_alive()))