#!/usr/bin/env python3 import socket, struct, sys, signal from tinygrad.runtime.support.system import PCIDevice, RemoteCmd, System, REMOTE_REQ, REMOTE_RESP from tinygrad.runtime.support.am.amdev import AMMemoryManager from tinygrad.runtime.support.system import FileIOInterface from tinygrad.device import Device, TinyELF from tinygrad.helpers import DEBUG, Target, to_mv def resp(resp0=0, resp1=0, status=0): return struct.pack(REMOTE_RESP, status, resp0, resp1) def resp_err(msg): return resp(len(err:=msg.encode()), status=1) + err discovered_devices: list[tuple[type, str]] = [] opened_devices: dict[int, PCIDevice] = {} mapped_bars: dict[tuple[int, int], object] = {} programs: list = [] def handle(conn, cmd, dev_id, bar, arg0, arg1, arg2): if cmd == RemoteCmd.PING: return conn.sendall(resp()) if cmd == RemoteCmd.PROBE: payload = conn.recv(arg1, socket.MSG_WAITALL) if arg1 > 0 else b"" filter_devices: dict[int, list[int]] = {} for i in range(0, len(payload), 8): mask, dev = struct.unpack('= len(discovered_devices): raise RuntimeError(f"device {dev_id} not probed") cl, pcibus = discovered_devices[dev_id] opened_devices[dev_id] = cl("SV", pcibus) pci_dev = opened_devices[dev_id] if cmd == RemoteCmd.MAP_BAR: if (dev_id, bar) not in mapped_bars: mapped_bars[(dev_id, bar)] = pci_dev.map_bar(bar) conn.sendall(resp(*pci_dev.bar_info(bar)) + struct.pack('= 4: print(f"cmd={RemoteCmd(cmd).name} dev={dev_id} bar={bar} arg0={arg0:#x} arg1={arg1:#x} arg2={arg2:#x}") try: handle(conn, cmd, dev_id, bar, arg0, arg1, arg2) except ConnectionError: raise except Exception as e: if cmd in {RemoteCmd.MMIO_WRITE, RemoteCmd.SYSMEM_WRITE} or (cmd == RemoteCmd.EXEC_PROG and not arg2): raise ConnectionError(f"posted command failed: {e}") print(f"ERROR: {e}") conn.sendall(resp_err(str(e))) if __name__ == "__main__": signal.signal(signal.SIGTERM, lambda *_: sys.exit(0)) System.reserve_va(AMMemoryManager.va_allocator.base, AMMemoryManager.va_allocator.size) port = int(sys.argv[1]) if len(sys.argv) > 1 else 6667 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(("0.0.0.0", port)) server.listen(1) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.connect(("8.8.8.8", 80)); ip = s.getsockname()[0] finally: s.close() print(f"listening on {ip}:{port}", flush=True) while True: conn, addr = server.accept() conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) for bt in [socket.SO_SNDBUF, socket.SO_RCVBUF]: conn.setsockopt(socket.SOL_SOCKET, bt, 64 << 20) try: serve(conn) except ConnectionError: print("disconnected") finally: conn.close()