aboutsummaryrefslogtreecommitdiffstats
path: root/psp_out/smn_probe2.py
blob: b29a98def76c41a172c4aa5065d09ec4c9f30c51 (plain) (blame)
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
#!/usr/bin/env python3
"""Distinguish a real SMN read from an address echo.

The first pass looked like it read 28 PSP registers. It did not: every "value"
was the byte-reversed address (0x03710008 -> 0x08007103). A distinctness check
passed and meant nothing, because echoes of distinct addresses are distinct.

The right invariant is: value != byteswap(address). READ ONLY.
"""
import struct
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


def bswap(x):
    return struct.unpack("<I", struct.pack(">I", x & 0xFFFFFFFF))[0]


def classify(addr):
    v = smn_read(addr)
    if v == bswap(addr):
        return v, "ECHO (not decoded)"
    if v == 0xFFFFFFFF:
        return v, "all-ones (no responder)"
    return v, "DECODED"


print("%-40s %-12s %s" % ("register", "value", "verdict"))
REGS = [
    ("CONTROL MP0_SMN_C2PMSG_58", 0x581E8),
    ("CONTROL MP0_SMN_C2PMSG_81", 0x58224),
    ("MP0_MMU_SRAM_UNSECURE_BAR", 0x03710018),
    ("MP0_MMU_SRAM_ACC_VIOLATION_LOG_ADDR", 0x03710008),
    ("MP0_AEB_JTAG_DBG_CTRL", 0x037001D4),
    ("MP0_AEB_JTAG_DBG_CTRL_LOCK", 0x037001D8),
    ("MP0_NS_PROT_FAULT_STATUS_0", 0x037000C8),
    ("MP0_BOOTROM_REVID", 0x03700048),
    ("MP0_COLD_BOOT_EVENTS", 0x03700054),
    ("MP_ROM_MISC_CNTL", 0x03760008),
    ("SMNIF_ACC_VIOLATION_LOG_ADDR", 0x037200D4),
    ("DMAC_ACC_VIOLATION_LOG_ADDR", 0x03A71000),
    ("MP1_MMU_SRAM_UNSECURE_BAR", 0x03A10060),
    ("MP0_FW_DEBUG_CNT0", 0x03810008),
]
dec = 0
for name, addr in REGS:
    v, verd = classify(addr)
    dec += verd == "DECODED"
    print("   %-38s %#010x %s" % (name, v, verd))

print("\n   decoded: %d of %d" % (dec, len(REGS)))
print("\nSweep: which SMN regions decode at all? (16 addresses per region)")
for base, label in ((0x00058000, "MP0 C2PMSG window (known good)"),
                    (0x03700000, "MP_MP0CRU"),
                    (0x03710000, "MP_MP0MMU"),
                    (0x03720000, "MP_MPSMNIF"),
                    (0x03760000, "MP_MPROM"),
                    (0x03810000, "MP0 FW debug"),
                    (0x03A00000, "MP_MP1CRU"),
                    (0x03A71000, "MP_MPDMAC")):
    n = 0
    for i in range(16):
        a = base + i * 4
        v = smn_read(a)
        if v != bswap(a) and v != 0xFFFFFFFF:
            n += 1
    print("   %-34s %2d/16 decoded" % (label, n))