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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#!/usr/bin/env python3
"""Read PSP-block SMN registers on the card, using the NV22 memory map as a
hypothesis for NV31.
READ ONLY. Nothing here writes a register.
The map is Navi22 and the card is Navi31, so every address is a guess until
proven. The first thing this does is a positive control: MP0_SMN_C2PMSG_58 is at
SMN 0x581E8 by the map's own layout (C2PMSG_32 @ 0x58180, +4 per index), and we
already know that register reads 0x310036 on this card via tinygrad's own path.
If the control fails, the SMN route or the map does not transfer and NOTHING
below it means anything.
"""
import sys, time
from tinygrad import Device
adev = Device["AMD"].iface.dev_impl
def smn_read(addr):
adev.reg("regBIF_BX0_PCIE_INDEX2").write(addr & 0xFFFFFFFF)
hi = (addr >> 32) & 0xFF
if hi:
adev.reg("regBIF_BX0_PCIE_INDEX2_HI").write(hi)
v = adev.reg("regBIF_BX0_PCIE_DATA2").read()
if hi:
adev.reg("regBIF_BX0_PCIE_INDEX2_HI").write(0)
return v
C2PMSG_32 = 0x58180
CONTROL_ADDR = C2PMSG_32 + (58 - 32) * 4 # MP0_SMN_C2PMSG_58
CONTROL_EXPECT = adev.reg("regMP0_SMN_C2PMSG_58").read()
print("positive control: MP0_SMN_C2PMSG_58")
got = smn_read(CONTROL_ADDR)
print(" via tinygrad reg() : %#010x" % CONTROL_EXPECT)
print(" via SMN %#08x : %#010x" % (CONTROL_ADDR, got))
if got != CONTROL_EXPECT or CONTROL_EXPECT == 0:
print("\n CONTROL FAILED -- SMN route or NV22 map does not transfer.")
print(" RESULT NOT REPORTABLE")
raise SystemExit(2)
print(" control OK: the SMN path works and MP0 addresses transfer\n")
# second control: an address that should read as something other than the first,
# so we are not just seeing a stuck data register
alt = smn_read(C2PMSG_32 + (81 - 32) * 4) # heartbeat, must differ
print(" second control: C2PMSG_81 (heartbeat) = %#010x distinct from C2PMSG_58: %s\n"
% (alt, alt != got))
REGS = [
("MP0_MMU_SRAM_FLOP_START_ADDR", 0x03710000),
("MP0_MMU_SRAM_ACC_VIOLATION_LOG_ADDR", 0x03710008),
("MP0_MMU_SRAM_ACC_VIOLATION_LOG_STATUS", 0x0371000C),
("MP0_MMU_MISC_CNTL", 0x03710010),
("MP0_MMU_ACCESS_ERR_LOG", 0x03710014),
("MP0_MMU_SRAM_UNSECURE_BAR", 0x03710018),
("MP0_CONFIG", 0x03710004),
("MP0_BOOTROM_REVID", 0x03700048),
("MP0_COLD_BOOT_EVENTS", 0x03700054),
("MP0_WARM_BOOT_EVENTS", 0x03700058),
("MP0_ACC_VIOL_LOG0", 0x037000B4),
("MP0_ACC_VIOL_LOG1", 0x037000B8),
("MP0_NS_PROT_FAULT_STATUS_0", 0x037000C8),
("MP0_AEB_JTAG_DBG_CTRL", 0x037001D4),
("MP0_AEB_JTAG_DBG_CTRL_LOCK", 0x037001D8),
("MP_ROM_ACC_VIOLATION_LOG_ADDR", 0x03760000),
("MP_ROM_ACC_VIOLATION_LOG_STATUS", 0x03760004),
("MP_ROM_MISC_CNTL", 0x03760008),
("SMNIF_ACC_VIOLATION_LOG_ADDR", 0x037200D4),
("SMNIF_ACC_VIOLATION_LOG_STATUS", 0x037200D8),
("SMNIF_LPBK_WR_VIOL_ADDR", 0x037200DC),
("SMNIF_LPBK_RD_VIOL_ADDR", 0x037200E4),
("SMNIF_AXI_READ_ERROR_COUNTER", 0x0372010C),
("SMNIF_AXI_WRITE_ERROR_COUNTER", 0x03720108),
("DMAC_ACC_VIOLATION_LOG_ADDR", 0x03A71000),
("DMAC_ACC_VIOLATION_LOG_STATUS", 0x03A71004),
("MP0_FW_DEBUG_CNT0", 0x03810008),
("MP0_FW_DEBUG_SIGNAL0", 0x03810018),
]
print("%-42s %-12s" % ("register (NV22 map address)", "value"))
vals = {}
for name, addr in REGS:
try:
v = smn_read(addr)
except Exception as e:
print(" %-40s READ FAILED %s" % (name, type(e).__name__)); continue
vals[name] = v
print(" %-40s %#010x" % (name, v))
allv = list(vals.values())
print("\n distinct values: %d of %d (all-identical would mean the aperture is "
"not really decoding)" % (len(set(allv)), len(allv)))
|