#!/usr/bin/env python3 """The MP0 FW-debug SMN window decodes from the host. Is it live PSP state? READ ONLY. A register that decodes is only interesting if it carries information; a window of constant zeros is decoded and useless. So: dump it, sample it over time, and sample it across real PSP work (a TA load + invoke). """ import struct, time from tinygrad import Device import tinygrad.runtime.autogen.am.am as am adev = Device["AMD"].iface.dev_impl psp = adev.psp def smn_read(addr): adev.reg("regBIF_BX0_PCIE_INDEX2").write(addr & 0xFFFFFFFF) return adev.reg("regBIF_BX0_PCIE_DATA2").read() def bswap(x): return struct.unpack("I", x & 0xFFFFFFFF))[0] BASE = 0x03810000 N = 32 def snap(): return [smn_read(BASE + i * 4) for i in range(N)] a = snap() print("MP0 FW-debug window %#x, %d dwords:" % (BASE, N)) for i in range(0, N, 4): print(" +%#04x %s" % (i * 4, " ".join("%08x" % a[i + j] for j in range(4)))) echo = [i for i in range(N) if a[i] == bswap(BASE + i * 4)] print(" echoing (not decoded) offsets: %s" % ([hex(i * 4) for i in echo] or "none")) time.sleep(2.0) b = snap() chg = [i for i in range(N) if a[i] != b[i]] print("\n changed over 2s idle: %s" % ([hex(i * 4) for i in chg] or "none")) # now across real PSP work: load the RAS TA and invoke a command d = open("/tmp/ta.bin", "rb").read() ua = struct.unpack_from("> 32 c.cmd.cmd_load_ta.app_len = len(blob) 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 r = psp._ring_submit(c) sess = r.resp.session_id shared = adev.vram.view(cmdb, 0x10000, "B") shared[0:4] = struct.pack(" %08x" % (i * 4, before[i], after[i]))