#!/usr/bin/env python3 """Read-only BAR0 probe for GA100 GPC floorsweep fuses (OPT_GPC_DISABLE / OPT_GPC_DEFECTIVE). Never writes to BAR0. Requires root to mmap /sys/bus/pci/devices//resource0. """ import mmap import os import struct import subprocess import sys REG_GPC_DISABLE = 0x00820350 REG_GPC_DEFECTIVE = 0x008205C4 PAGE = 0x1000 def find_ga100_cards(pattern="GA100"): """Return [(bdf, label)] for PCI devices whose lspci name matches pattern.""" try: out = subprocess.check_output(["lspci", "-D"], text=True) except FileNotFoundError: sys.exit("lspci not found; install pciutils or pass BDFs another way") except subprocess.CalledProcessError as e: sys.exit(f"lspci failed: {e}") cards = [] for line in out.splitlines(): if pattern in line: bdf = line.split(None, 1)[0] cards.append((bdf, bdf.split(":")[1])) return cards def read_reg(bdf, addr): path = f"/sys/bus/pci/devices/{bdf}/resource0" if not os.path.exists(path): raise OSError(f"no BAR0 (resource0 missing, device has no MMIO?)") if os.path.getsize(path) <= addr: raise OSError(f"BAR0 too small for offset 0x{addr:x}") fd = os.open(path, os.O_RDONLY | os.O_SYNC) try: base = addr - (addr % PAGE) off = addr - base m = mmap.mmap(fd, PAGE, mmap.MAP_SHARED, mmap.PROT_READ, offset=base) try: return struct.unpack_from("