"""DECISIVE: is the RAS TRIGGER_ERROR range check inverted? dram_range_query returns: 0xFFFF0001 address IS inside a valid DRAM range 0 address is NOT in any range (also: not-initialised / recovery) 0xFFFF0006 address has bits above bit 43 and ras_dram_range_config does `CBZ R0 -> proceed`, i.e. proceeds on 0. If that is the real polarity, then: VALID in-range address -> rejected with 40986 INVALID out-of-range -> ACCEPTED, proceeds to program the UMC inject regs which is exactly backwards. Test with addresses whose validity we know. """ import ctypes,struct,collections from tinygrad import Device from tinygrad.runtime.autogen.am import am from tinygrad.helpers import lo32,hi32 d=Device["AMD"]; adev=d.iface.dev_impl; psp=adev.psp SZ=ctypes.sizeof(am.struct_psp_gfx_cmd_resp); P='/Users/user/dev/amd-psp-re/psp_out/'; S=0x8000 def stat(): return int.from_bytes(bytes(adev.vram.view(psp.cmd_paddr,SZ)[:])[864:868],"little") def alloc(n): pa=adev.mm.palloc(n,align=0x1000,zero=True); return pa,adev.paddr2mc(pa) def load(cmd,blob): ap,amc=alloc(0x40000); cp,cmc=alloc(S) adev.vram.view(ap,len(blob))[:]=blob; adev.gmc.flush_hdp() adev.vram.view(psp.cmd_paddr,SZ)[:]=b"\x00"*SZ c=am.struct_psp_gfx_cmd_resp(cmd_id=cmd); t=c.cmd.cmd_load_ta t.app_phy_addr_hi,t.app_phy_addr_lo=hi32(amc),lo32(amc); t.app_len=len(blob) t.cmd_buf_phy_addr_hi,t.cmd_buf_phy_addr_lo=hi32(cmc),lo32(cmc); t.cmd_buf_len=S return psp._ring_submit(c).resp.session_id, cp def inv(sid,shm,buf,tc): adev.vram.view(shm,S)[:]=bytes(buf); adev.gmc.flush_hdp() adev.vram.view(psp.cmd_paddr,SZ)[:]=b"\x00"*SZ ic=am.struct_psp_gfx_cmd_resp(cmd_id=am.GFX_CMD_ID_INVOKE_CMD); iv=ic.cmd.cmd_invoke_cmd iv.session_id,iv.ta_cmd_id=sid,tc try: psp._ring_submit(ic); ps=0 except RuntimeError: ps=stat() except TimeoutError: return "TIMEOUT",None return ps, bytes(adev.vram.view(shm,S)[:]) ras,rsh=load(am.GFX_CMD_ID_LOAD_TA, open(P+'ras_full.bin','rb').read()) # a definitely-valid VRAM address we own mypa,mymc=alloc(0x10000) print("RAS sid=%s our VRAM buffer: pa=%#x mc=%#x MEMSIZE=%s"%(ras,mypa,mymc,hex(adev.rreg(0xde3)))) def trigger(addr, blk=2, v5=0): b=bytearray(S); base=0x10 struct.pack_into('>32) & 0xffffffff) struct.pack_into(' %s"%(label,addr,NAMES.get(r,str(r)))) print("\n=== addresses that ARE valid DRAM (ours / low VRAM) ===") for lbl,a in (("our allocated VRAM buffer (mc)",mymc), ("our allocated VRAM buffer (pa)",mypa), ("low VRAM 0x9a000",0x9a000), ("VRAM 0x1600000",0x1600000)): for v5 in (0,4): show(lbl+" v5=%d"%v5, a, v5=v5) print("\n=== addresses that are NOT valid DRAM ===") for lbl,a in (("zero",0),("tiny 0x40",0x40),("0xdead000",0xdead000), ("huge but <2^44 0xFFFFFFFF000",0xFFFFFFFF000), ("above bit43 (should be 0xFFFF0006)",0x1FFFFFFFF000)): for v5 in (0,4): show(lbl+" v5=%d"%v5, a, v5=v5) print("\nMEMSIZE=%s sos_alive=%s"%(hex(adev.rreg(0xde3)),psp.is_sos_alive()))