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
|
#!/usr/bin/env python3
"""GFX commands 13 and 37: the last unread entries in GFX-HANDLER-COVERAGE.md.
That audit closed every documented command and all undocumented ones except 13 and 37
(`bl_rpc_misc`), which were never read. This asks the hardware what they do: send each with a
zeroed command struct, then with a few filled fields, and record status and timing.
Benign outcomes are a clean error (command unsupported) or success. A stall would be a new
DoS; a status that varies with our input means the command consumes host data and deserves
static follow-up.
"""
import ctypes, struct, sys, time
sys.path.insert(0,'/root/psp/hw')
from tinygrad import Device
import tinygrad.runtime.autogen.am.am as am
from ring_wrap import install
adev=Device["AMD"].iface.dev_impl; psp=adev.psp
submit=install(psp,adev)
def alloc(n):
pa=adev.mm.palloc(n,align=0x1000,zero=True,boot=False); return pa,adev.paddr2mc(pa)
pa,mc=alloc(0x8000)
def send(cid, fill=None, tag=''):
c=am.struct_psp_gfx_cmd_resp(cmd_id=cid)
raw=memoryview(c).cast('B')
if fill is not None:
for off in range(16, 64, 4): struct.pack_into('<I', raw, off, fill)
t0=time.time()
try: r=submit(c); st=r.resp.status&0xFFFFFFFF
except Exception as e:
try: st=int(str(e).strip().split()[-1])&0xFFFFFFFF
except Exception: st=-1
dt=time.time()-t0
print(' cmd %-3d %-22s -> %#-12x %.1fs%s'%(cid,tag,st,dt,' <<< HANG' if dt>5 else ''), flush=True)
return st
for cid in (13, 37):
a=send(cid, None, 'zeroed')
b=send(cid, mc & 0xFFFFFFFF, 'fields=buffer addr')
c_=send(cid, 0xFFFFFFFF, 'fields=0xffffffff')
print(' input-sensitive: %s'%('YES' if len({a,b,c_})>1 else 'no'), flush=True)
# control: a known-rejected command id
send(39, None, 'control (SRIOV, rejected)')
|