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
|
"""Pretty-print the host-accessible MMIO / register map for this card.
Sources, all authoritative:
* PCI BARs as the bridge/driver actually mapped them
* the card's own IP discovery table (base addresses per IP instance)
* tinygrad's register-window bookkeeping (regs_offset)
SAFETY: read-only, and deliberately no high-offset BAR0 pokes (those raise a
TLP error that wedges PCIe until a power cycle).
"""
import sys
sys.path.insert(0,"/Users/user/src/tinygrad")
from tinygrad import Device
from tinygrad.runtime.autogen.am import am
d=Device["AMD"]; adev=d.iface.dev_impl
pci=getattr(d.iface,'pci_dev',None) or getattr(adev,'pci_dev',None)
def hdr(t):
print("\n"+"="*104); print(t); print("="*104)
hdr("1. PCI BARs (what the host can touch directly)")
print("%-6s %-18s %-14s %-12s %s"%("BAR","base","size","mapped?","use"))
USE={0:"VRAM aperture (frame buffer, 24 GB) - high offsets WEDGE PCIe",
2:"Doorbell aperture (ring doorbells)",
5:"MMIO register aperture (all IP registers, incl. PSP/SMU mailboxes)"}
for i in range(6):
try: info=pci.bar_info(i)
except Exception as e: continue
base,size = (info[0],info[1]) if isinstance(info,(tuple,list)) and len(info)>=2 else (info,0)
if not base and not size: continue
print(" %-4d %-18s %-14s %-12s %s"%(i,hex(base) if isinstance(base,int) else str(base),
hex(size) if isinstance(size,int) else str(size),"yes",USE.get(i,"")))
print(" vram_bar index = %s large_bar=%s"%(getattr(d.iface,'vram_bar','?'),getattr(adev,'large_bar','?')))
print("\n BAR5 is addressed by tinygrad as DWORD indices (reg.addr), not byte offsets")
print(" vram_size = %#x (%d MB)"%(adev.vram_size, adev.vram_size>>20))
hdr("2. Indirect windows reachable THROUGH BAR5 (widen the reach beyond the aperture)")
rows=[("SMN (System Management Network)","PCIE_INDEX2 / PCIE_DATA2","BAR5 dword 14 / 15",
"32-bit SMN address space: MP0/MP1/THM/SMUIO/BIF..."),
("RSMU","regBIF_BX_PF0_RSMU_INDEX/_DATA","(same decode as PCIE_INDEX2)",
"verified byte-identical to the PCIe window - NOT a second path"),
("PCIE config","PCIE_INDEX/PCIE_DATA","BAR5","PCIe core config space"),
("GPUVM apertures","MC_VM_* regs","BAR5","translate VRAM/system memory")]
print("%-34s %-34s %-22s %s"%("window","index/data regs","location","reaches"))
for a,b,c,e in rows: print(" %-32s %-34s %-22s %s"%(a,b,c,e))
hdr("3. Mailboxes the host can drive (confirmed reachable)")
mb=[("PSP (MP0)","C2PMSG_N = BAR5 + 0x58224 + 4*(N-73)","ring doorbell 0x58100.., resp 0x582CC/0x582D0",
"LOAD_TA/INVOKE/SETUP_TMR... fuzzed extensively"),
("SMU (MP1)","MSG=C2PMSG_66 ARG=C2PMSG_82 RESP=C2PMSG_90","via SMN MP1 base",
"79 PPSMC msgs + 13 tables; audited"),
("TSU","C2PMSG_115/116 + doorbell 73","BAR5","OUT OF SCOPE (flash) per CONSTRAINTS.md")]
print("%-12s %-42s %-44s"%("block","registers","notes"))
for a,b,c,e in mb:
print(" %-10s %-42s %s"%(a,b,c)); print(" %-10s %-42s -> %s"%("","",e))
hdr("4. IP blocks and their register bases, from the card's OWN discovery table")
ipn={}
try:
ipn=adev.ip_ver
except Exception: pass
NAME={}
for k,v in vars(am).items():
if k.endswith('_HWIP') and isinstance(v,int): NAME[v]=k[:-5]
seen={}
off=getattr(adev,'regs_offset',None)
if isinstance(off,dict):
for hwip,inst in sorted(off.items(), key=lambda t:(str(t[0]))):
nm=NAME.get(hwip, str(hwip))
try: bases=[hex(x) for x in (inst if isinstance(inst,(list,tuple)) else [inst])]
except Exception: bases=[str(inst)]
seen[nm]=bases
print("%-16s %-10s %s"%("IP block","ip_ver","register base(s) (SMN / aperture addresses)"))
for nm in sorted(seen):
hw=[k for k,v in NAME.items() if v==nm]
ver=ipn.get(hw[0]) if hw and isinstance(ipn,dict) else None
b=seen[nm]
flat=[]
for x in b:
flat.append(x)
print(" %-14s %-10s %s"%(nm, str(ver) if ver else "-", ", ".join(flat[:6])+(" ..." if len(flat)>6 else "")))
print("\n total IP entries: %d"%len(seen))
|