aboutsummaryrefslogtreecommitdiffstats
path: root/bridge/eb_hammer_test.py
blob: b9bdac4696ee08ac720d81cd4836fae82152e9cf (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
import struct, sys
from tinygrad import Device
adev = Device["AMD"].iface.dev_impl

# locate the USB controller object (has pcie_mem_read + usb.control_write)
def find_ctrl(root):
    seen=set(); stack=[root]
    while stack:
        o=stack.pop()
        if id(o) in seen: continue
        seen.add(id(o))
        if hasattr(o,'pcie_mem_read') and hasattr(o,'usb'): return o
        for a in ('iface','dev_impl','usb','controller','ctrl','backend','_iface','pci'):
            if hasattr(o,a):
                try: stack.append(getattr(o,a))
                except Exception: pass
    return None
c1=Device["AMD"].iface.ctrl; ctrl=c1 if hasattr(c1,"pcie_mem_read") else adev.doorbell64.usb
print("controller:", type(ctrl).__name__ if ctrl else None)
assert ctrl is not None, "could not find USB controller"

# scratch VRAM page -> PCIe/MC address the TLP engine targets
pa = adev.mm.palloc(0x1000, align=0x1000, zero=True, boot=False)
mc = adev.paddr2mc(pa)
print("scratch paddr=%#x  mc(TLP addr)=%#x" % (pa, mc))

def eb(addr, valA, valB, iters, fmt=0x60, byte_en=0x0F):
    payload = struct.pack('<QII', addr & 0xFFFFFFFFFFFFFFFF, valA & 0xFFFFFFFF, valB & 0xFFFFFFFF)
    payload += bytes([0x48,0x4D,0x52,0x01])   # arming magic 'HMR\x01'
    assert len(payload)==20, len(payload)
    ctrl.usb.control_write(0xEB, value=iters & 0xFFFF, index=(fmt | (byte_en<<8)), data=payload, timeout=5000)

def rd(addr): return struct.unpack('<I', ctrl.pcie_mem_read(addr, 4))[0]

print("before            :", hex(rd(mc)))
eb(mc, 0xCAFEBABE, 0xCAFEBABE, 1)
v1 = rd(mc); print("after A=B=CAFEBABE :", hex(v1), "->", "PASS" if v1==0xCAFEBABE else "FAIL")

eb(mc, 0x11223344, 0xAABBCCDD, 2000)
v2 = rd(mc); print("after A/B x2000    :", hex(v2), "-> last=B=AABBCCDD:", "PASS" if v2==0xAABBCCDD else "FAIL")

# no-magic safety: wrong magic must be a no-op (value stays v2)
bad = struct.pack('<QII', mc, 0xDEAD0000, 0xDEAD0000) + bytes([0,0,0,0])
ctrl.usb.control_write(0xEB, value=1, index=(0x60|0x0F00), data=bad, timeout=5000)
v3 = rd(mc); print("after NO-magic     :", hex(v3), "-> must stay AABBCCDD (gated):", "PASS" if v3==0xAABBCCDD else "FAIL")