DF-5229 / decode_fw.py
#!/usr/bin/env python3 """Decode the in-tree uuencoded radeon CIK UVD firmware blobs and dump common_firmware_header fields (struct from sys/dev/drm/radeon/radeon_ucode.h).""" import binascii, glob, struct, os BASE = "sys/contrib/dev/drm/radeonfw" if not os.path.isdir(BASE): BASE = "dfbsd-upstream/sys/contrib/dev/drm/radeonfw" def uudecode(path): out = b"" started = False for raw in open(path, "rb").read().split(b"\n"): l = raw.rstrip(b"\r") if not started: if l.startswith(b"begin "): started = True continue if l == b"end" or l == b"`" or l == b"": if l == b"end": break continue try: out += binascii.a2b_uu(l) except binascii.Error: # truncated final line variant try: out += binascii.a2b_uu(l + b" ") except binascii.Error: pass return out for f in sorted(glob.glob(BASE + "/*uvd*.bin.uu")) + sorted(glob.glob(BASE + "/*uvd*.uu")): blob = uudecode(f) if not blob: print(f, "-> decode FAILED") continue sz, hdr, fmt, fver, uver = struct.unpack_from("<IIIII", blob, 0) vmaj, vmin, fam = (uver >> 24) & 0xFF, (uver >> 8) & 0xFF, uver & 0xFF print(f"{os.path.basename(f)}: datasize={len(blob)} (0x{len(blob):x}) " f"size_bytes={sz} header_size={hdr} (0x{hdr:x}) fmt={fmt:#x} " f"ucode_version={uver:#010x} -> v{vmaj}.{vmin} family={fam} " f"datasize%4096={len(blob) % 4096}") |