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
48
49
|
"""READ-ONLY survey of the DCE (display) register space, with regguard controls.
Why: ASD's display paths read DCE registers via SVC 0x7B. asd_encoder_state_check
branches on (reg & 0x31) == 0x21 and, on the non-matching path, performs the
unbounded table index (LATENT-ASD-ENCODER-STATE-CHECK-UNBOUNDED-INDEX.md).
If the host can reach those registers, it may be able to drive ASD's display
state machine with no monitor and no display driver.
WRITES NOTHING.
"""
import sys
sys.path.insert(0,"/Users/user/src/tinygrad"); sys.path.insert(0,"/Users/user/dev/amd-psp-re/psp_out")
from tinygrad import Device
from tinygrad.runtime.autogen.am import am
import regguard
d=Device["AMD"]; adev=d.iface.dev_impl
NAME={k[:-5]:v for k,v in vars(am).items() if k.endswith('_HWIP') and isinstance(v,int)}
def rd(a):
adev.wreg(14,a&0xffffffff); return adev.rreg(15)
hw=NAME['DCE']; off=adev.regs_offset[hw]
print("DCE ip_ver=%s instances=%d"%(adev.ip_ver.get(hw),len(off)))
for inst in sorted(off): print(" inst%d bases: %s"%(inst,[hex(x) for x in off[inst]]))
print("\n--- per-base classification (read-only, with controls) ---")
real=[]
for inst in sorted(off):
for base in off[inst]:
if base < 0x40: # tiny pseudo-bases: probe them anyway but note
pass
addrs=[base+4*i for i in (0,1,2,5)]
ctrls=[base+0x1000, 0x0badf000, base+0x40000]
if base>=0x2000: ctrls.append(base-0x1000)
r=regguard.classify_read(rd,addrs,controls=ctrls)
vals=" ".join("%08x"%rd(a) for a in addrs)
p=r['_path']
tag="REAL" if p.startswith("USABLE") else p.split()[0]
if tag=="REAL": real.append(base)
print(" %#011x %-6s %s [%s]"%(base,tag,vals,p[:44]))
print("\nREAL DCE bases: %s"%[hex(x) for x in real])
# DCE register space is normally a big contiguous block; probe a wider sweep
print("\n--- wide sweep for any decoding DCE-ish region (step 0x400, read-only) ---")
hits=[]
for a in range(0x0000, 0x10000, 0x400):
v=rd(a)
import struct
bsv=struct.unpack('<I',struct.pack('>I',a))[0]
if v not in (0,0xffffffff) and v!=bsv: hits.append((a,v))
print(" candidate live dwords in 0x0..0x10000: %d"%len(hits))
for a,v in hits[:24]: print(" %#08x = %08x"%(a,v))
print("\nMEMSIZE=%s sos_alive=%s"%(hex(adev.rreg(0xde3)),adev.psp.is_sos_alive()))
|