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
50
51
52
53
54
55
56
57
58
59
|
#!/usr/bin/env python3
"""Was the 'wall' an address boundary, or exhaustion caused by the sweep itself?
The sweep's failures began at PA 0x3ef00000, which was ALSO probe #1006. The
failing value was (PA>>16)+0x101 -- but since PA = n*0x100000, that is exactly
16*n + 257. Address-derived and count-derived are indistinguishable in that data.
A fresh process probes 0x3ff00000 and 0x40000000 fine, which already argues
against the address hypothesis. This settles it: probe ONE fixed, known-good
address repeatedly and see whether it degrades at the same count.
LOAD_TA allocates a session on every successful load and this probe never
unloads, so session exhaustion is the obvious candidate.
"""
import sys, time
sys.path.insert(0, "/root/psp/work")
from tinygrad import Device
import tinygrad.runtime.autogen.am.am as am
def main():
adev = Device["AMD"].iface.dev_impl
cmd_pa = adev.mm.palloc(0x10000, align=0x1000, zero=True, boot=False)
mcc = adev.paddr2mc(cmd_pa)
FIXED = 0x20000000 # one address, known good, never changes
def probe(pa):
mc = adev.paddr2mc(pa)
c = am.struct_psp_gfx_cmd_resp(cmd_id=am.GFX_CMD_ID_LOAD_TA)
c.cmd.cmd_load_ta.app_phy_addr_lo = mc & 0xFFFFFFFF
c.cmd.cmd_load_ta.app_phy_addr_hi = mc >> 32
c.cmd.cmd_load_ta.app_len = 0x1000
c.cmd.cmd_load_ta.cmd_buf_phy_addr_lo = mcc & 0xFFFFFFFF
c.cmd.cmd_load_ta.cmd_buf_phy_addr_hi = mcc >> 32
c.cmd.cmd_load_ta.cmd_buf_len = 0x10000
t = time.time()
try: st = adev.psp._ring_submit(c).resp.status
except Exception as e:
try: st = int(str(e).strip().split()[-1])
except Exception: st = -1
return st, time.time() - t
print("probing ONE fixed address %#x repeatedly" % FIXED)
first_bad = None
for n in range(1, 1400):
st, dt = probe(FIXED)
if st != 0x34 or dt > 0.5:
if first_bad is None:
first_bad = n
print(" FIRST DEVIATION at probe #%d: status=%#x (%.2fs)" % (n, st, dt))
print(" -> 16*n+257 = %#x (PA>>16)+0x101 = %#x"
% (16 * n + 257, (FIXED >> 16) + 0x101))
if n > (first_bad + 3): break
if n % 250 == 0: print(" ... probe #%d status=%#x %.3fs" % (n, st, dt))
if first_bad is None:
print(" no deviation in 1399 probes at a fixed address")
print()
print("=> %s" % ("COUNT-dependent: the 'wall' was exhaustion, not an address boundary"
if first_bad else "not count-dependent at this address"))
return 0
sys.exit(main())
|