UMR(1)

πŸ“¦
version 1.0.11 Β· 3 versions
, in fedora 44

πŸ‘‘ UMR(1) πŸ‘‘

bestie, meet umr β€” the AMDGPU Userspace Register Debugger. she's the manual page you're reading rn, and she's that girl. πŸ’…


✨ NAME ✨

umr β€” AMDGPU Userspace Register Debugger


πŸ’– DESCRIPTION πŸ’–

okay so. umr is a tool to read and display, as well as write to AMDGPU device MMIO, PCIE, SMC, and DIDT registers via userspace. it can autodetect and scan AMDGPU devices (SI and up). no cap, it really does all that. πŸ”₯


πŸŽ€ Device Selection πŸŽ€

  • --database-path, -dbp <path> β€” point at a database path for register, ip, and asic model data. give her the receipts.
  • --gpu, -g <asicname>(@<instance> | =<pcidevice>) β€” pick a gpu by ASIC name plus either the instance number or the PCI bus identifier. for instance, "raven1@1" would pick the raven1 device in the 2nd DRI instance slot. similarly, "raven1=0000:06:00.0" would pick a raven1 device with the PCI bus address '0000:06:00.0'.
  • --instance, -i <number> β€” pick a device instance to work with. defaults to the 0'th device. the instance refers to a directory under /sys/kernel/debug/dri/ where 0 is the first card probed. 🫢
  • --force, -f <number> β€” force a PCIE Device ID in hex or by asic name. this is used in case the amdgpu driver is not yet loaded or a display is not yet attached. a . prefix will specify a virtual device which is handy for looking up register decodings for a device not present in the system, for instance, '.vega10'.
  • --pci <device> β€” force a specific PCI device using the domain:bus:slot.function format in hex. this is useful when more than one GPU is available. if the amdgpu driver is loaded the corresponding instance will be automatically detected. slay, autodetect. ✨
  • --by-pci <device> β€” like --pci but still uses the traditional debugfs path to interface with the hardware. this is useful for interacting with APIs that identify hardware by the PCI bus address.
  • --user-queue, -uq <client>.<queue> β€” (yeah, that's the whole line, no extra description given for this form 🫠)
  • --user-queue, -uq [<clienttype>,<client>,<queue>] β€” attach to a user queue specified by a given client and queue. where clienttype is 'kgd' or 'kfd', client is one of 'client=number', 'pid=number', or 'comm=string' to select a client by it's client number, process PID, or command name, and 'queue' is one of 'queue=number' or 'type=string'. for 'type' the string must be one of 'gfx', 'compute', or 'sdma'. for example: 'kfd,comm=ollama,queue=2' specifies a KFD client attached to the first instance of ollama and queue #2. iykyk. πŸ‘‘
  • --print-uq β€” print out all of the user queue information decoded. the tea is spilled, verbatim.
  • --gfxoff, -go <0 | 1> β€” turn on or off GFXOFF on select hardware. a non-zero value enables the GFXOFF feature and a zero value disables it.
  • --vm-partition, -vmp <-1, 0...n> β€” select a VM partition for all GPUVM accesses. default is -1 which refers to the 0'th instance of the VM hub which is not the same as specifying '0'. values above -1 are for ASICs with multiple IP instances. lowkey a trap if you skim it, so don't skim it. 😭
  • --vgpr-granularity, -vgpr <-1, 0...n> β€” specify the VGPR size granularity as a power of 2, e.g., '2' means 4 DWORDs per increment.
  • --option, -O <string>[,<string>,...] β€” specify options to the tool. multiple options can be specified as comma separated strings. options should be specified before --update or --force commands (among others) to enable options specified. and here's the whole menu of them, bestie, every single one:
    • quiet β€” disable various informative but not required (for functionality) outputs.
    • read_smc β€” enable scanning of SMC registers.
    • bits β€” enables displaying bitfields for scanned blocks.
    • bitsfull β€” enables displaying bitfields using their entire path for scanned blocks.
    • empty_log β€” empties the MMIO log after reading it.
    • no_follow_ib β€” instruct the --ring-stream command to not attempt to follow IBs pointed to by the packets in the ring.
    • no_follow_chained_ib β€” by default, umr will follow all IBs that have the CHAIN bit set regardless of the 'no_follow_ib' option. specifying this will disable following chained IBs as well.
    • use_pci β€” enable PCI access for MMIO instead of using debugfs. used by the --read, --top, --write, and --write-bit commands. does not currently support multiple instances of the same GPU (PCI device ID). note that access to non-MMIO registers might be disabled when using this flag. ⚠️
    • use_colour β€” enable colour output for --top command, scales from blue, green, yellow, to red. also accepted is 'use_color'.
    • no_kernel β€” disable using kernel files to access the device. implies ''use_pci''. this is meant to be used only if the KMD is hung or otherwise not working correctly. using it on live systems may result in race conditions.
fr fr, careful with this one on a live system. race conditions are not the vibe. πŸ’€
  • verbose β€” enable verbose diagnostics (used in --vram).
  • halt_waves β€” halt/resume all waves while reading wave status.
  • disasm_early_term β€” terminate shader disassembly when first s_endpgm is hit. this is required for older UMDs (or non-mesa UMDs) that don't use the quintuple 0xBF9F0000 to signal the true end of a shader.
  • no_disasm β€” disable shader disassembler logic (still outputs text just doesn't use LLVM to decode). useful if the linked llvm-dev doesn't support the hardware being debugged. avoids segfualts/asserts.
  • disasm_anyways β€” enable shader disassembly in --waves even if the rings aren't halted.
  • wave64 β€” enable full 64 wave disassembly.
  • full_shader β€” enable full shader disassembly in --waves when '-O bits' is used and the shader is found in a gfx or compute ring.
  • filter_shader_registers β€” filter the shader registers presented when running -RS.
  • no_fold_vm_decode β€” disable folding of PDEs when VM decoding multiple pages of memory. by default, when subsequent pages are decoded if PDEs match previous pages they are omitted to cut down on the verbosity of the output. this option disables this and will print the full chain of PDEs for every page decoded. πŸ¦‹
  • force_asic_file β€” force using a database .asic file matching in pci.did instead of IP discovery.
  • skip_gprs β€” skip reading SGPRS and VGPRS when scanning waves.
  • use_full_user_queue β€” read the entire user queue buffer from start to the WPTR. may result in undefined behaviour with some VM accessess. useful though if the SQ is blocked on something the CP has advanced past.
undefined behaviour is giving chaos, so know what you're doing before you flip this one. πŸ’…

🌸 Bank Selection 🌸

  • --bank, -b <se> <sh> <instance> β€” select a GRBM se/sh/instance bank in decimal. can use 'x' to denote a broadcast selection.
  • --sbank, -sb <me> <pipe> <queue> [vmid] β€” select a SRBM me/pipe/queue bank in decimal. VMID is optional (default: 0).
  • --cbank, -cb <context_reg_bank> β€” select a context register bank (value is multiplied by 0x1000). used for context registers in the range 0xA000..0xAFFF.

πŸ¦‹ Device Information πŸ¦‹

  • --config, -c β€” print out configuation data read from kernel driver.
  • --enumerate, -e β€” enumerate all AMDGPU supported devices. she's making a list, she's checking it twice. πŸŽ€
  • --list-blocks -lb β€” list all blocks attached to the asic that have been detected.
  • --list-regs, -lr <string> β€” list all registers in an IP block (can use '-O bits' to list bitfields).

πŸ’œ Register Access πŸ’œ

  • --lookup, -lu <address_or_regname> <number> β€” look up an MMIO register by address and bitfield decode the value specified (with 0x prefix) or by register name. the register name string must include the ipname, e.g., uvd6.mmUVD_CONTEXT_ID.
  • --write -w <string> <number> β€” write a value specified in hex to a register specified with a complete register path in the form < asicname.ipname.regname >. for example, fiji.uvd6.mmUVD_CGC_GATE. the value of asicname and/or ipname can be * to simplify scripting. this command can be used multiple times to write to multiple registers in a single invocation. multi-write? iconic. ✨
  • --writebit -wb <string> <number> β€” write a value specified in hex to a register bitfield specified with a complete register path as in the --write command.
  • --read, -r <string> β€” read a value from a register specified by a register path to stdout. this command uses the same syntax as the --write command but also allows * for the regname field to read an entire block. additionally, a * can be appended to a register name to read any register that contains a partial match. for instance, "*.vcn10.ADDR*" would read any register from the 'VCN10' block which contains 'ADDR' in the name.

πŸ”₯ Device Utilization πŸ”₯

  • --top, -t β€” summarize GPU utilization. can select a SE block with --bank. relevant options that apply are: use_colour and use_pci.
  • --waves, -wa [ <none> | <uq> | <ring_name> | <vmid>@<addr>.<size> ] β€” print out information about any active CU waves. note that if GFX power gating is enabled this command may result in a GPU hang. it's unlikely unless you're invoking it very rapidly. unlike the wave count reading in --top this command will operate regardless of whether GFX PG is enabled or not. can use bits to decode the wave bitfields. an optional ring name can be specified (default: gfx) to search for pointers to active shaders to find extra debugging information. alternatively, an IB can be specified by a vmid, address, and size (in hex bytes) triplet.
bestie, GPU hang is on the menu here. it's rare unless you're mashing this command, but it's there. 😭
  • --profiler, -prof [pixel= | vertex= | compute=]<nsamples> [ring] β€” capture 'nsamples' samples of wave data. optionally specify a ring to use when searching for IBs that point to shaders. defaults to 'gfx'. additionally, the type of shader can be selected for as well to only profile a given type of shader. πŸ“

🧠 Virtual Memory Access 🧠

okay so VMIDs in umr are 16-bit numbers and they're doing the absolute most β€” the lower 8 bits are the actual hardware VMID, and the upper 8 bits tell you which VM space you're living in. main character bits fr:

  • 0 β€” GFX hub
  • 1 β€” MM hub
  • 2 β€” VC0 hub
  • 3 β€” VC1 hub

so like, 0x107 means "the 7th VMID on the MM hub". slay πŸ’…

  • --vm-decode, -vm vmid@<address> <num_of_pages> β€” Decode the page mappings sitting at a given address (in hex) using the VMID you picked. That VMID can be hex (leading 0x) or plain decimal, your call. Heads up: this one quietly implies -O verbose for however long the command runs, so you don't have to go type that in yourself. 🫢
  • --vm-read, -vr [vmid@]<address> <size> β€” Read size bytes (in hex) from the address you gave (in hexadecimal), out of VRAM, straight to stdout. You can optionally drop a VMID in there (decimal, or hex with a 0x prefix) and then the address gets treated as a virtual address instead. Also you can use use_pci to go straight at VRAM. πŸ”₯
  • --vm-write, -vw [vmid@]<address> <size> β€” Write size bytes (in hex) to the address specified (in hexadecimal) into VRAM, reading the data from stdin.
  • --vm-write-word, -vww [vmid@]<address> <data> β€” Write a single 32-bit word data (in hex) to a given address (in hex), in host machine order.
  • --vm-disasm, -vdis [<vmid>@]<address> <size> β€” Disassemble size bytes (in hex) from a given address (in hex). cute trick: set the size to zero and umr will try to compute the shader size for you. ✨

πŸŒ€ Ring and PM4 Decoding πŸŒ€

  • --ring-stream, -RS <string>[range] β€” Read the contents of the ring named by the string amdgpu_ring_<string> β€” meaning you give it the string without the amdgpu_ring prefix. By default it reads and prints the entire ring, no notes. A range is optional and looks like '[start:end]'. The starting and ending addresses are non-negative integers, or the . (dot) symbol β€” and the dot means rptr when it's on the left side and wptr when it's on the right side. For instance, -RS gfx prints the entire gfx ring, -R gfx[0:16] prints the contents from 0 to 16 inclusively, and -RS gfx[.] or -RS gfx[.:.] prints the range [rptr,wptr]. Now when one range limit is a number and the other is the dot ., that number means a relative range before or after the corresponding ring pointer. So for instance, -RS sdma0[16:.] prints [wptr-16, wptr] words of the SDMA0 ring, and -RS sdma1[.:32] prints [rptr, rptr+32] double-words of the SDMA1 ring. And the contents of the ring is always interpreted, if it can be interpreted. periodt. πŸ’–
  • --dump-uq, -du β€” Dump the command submission attached to a given user queue β€” the one you selected with --user-queue. iykyk.
  • --dump-ib, -di [vmid@]address length [pm] β€” Dump an IB packet at an address, with an optional VMID. The length is in bytes. The decoder type <pm> is optional and defaults to PM4 packets. You can say 4 for PM4 packets, 3 for SDMA packets, 2 for MES packets, 1 for VPE packets, 5 for UMSCH packets, 6 for HSA packets, 7 for VCN decode, and 8 for VCN encode. πŸ¦‹
  • --dump-ib-file, -df filename [pm] β€” Dump an IB that's stored in a file, as a series of hexadecimal DWORDS, one per line. If the filename ends in .bin the file gets treated as binary, and if it ends in .ring it's treated as a ring copy and skips the first 12 bytes. You can optionally say 3 for SDMA packets, 2 for MES packets, 1 for VPE packets, 5 for UMSCH packets, 6 for HSA packets, 7 for VCN decode, and 8 for VCN encode. The default is PM4.
  • --header-dump, -hd [HEADER_DUMP_reg] β€” Dump the contents of the HEADER_DUMP buffer and decode the opcode into a human readable string. translating for the girlies πŸ’…
  • --print-cpc, -cpc β€” Dump CPC register data.
  • --print-sdma, -sdma β€” Dump SDMA register data.
  • --logscan, -ls β€” Read and display the contents of the MMIO register log. Usually you'll pair this with -O bits,empty_log so you get continual dumping of bit fields and the trace log gets emptied after. obsessed. ✨

⚑ Power and Clock ⚑

  • --power, -p β€” Read the content of clocks, temperature, and gpu loading at runtime. The option use_colour colourizes the output. 🌈
  • --clock-scan, -cs [clock] β€” Scan the current hierarchy value of each clock. Default lists all the hierarchy values of the clocks; otherwise it lists just the corresponding clock, e.g. sclk.
  • --clock-manual, -cm [clock] [value] β€” Set the value of the corresponding clock. The move here is: use -cs first to check the hierarchy values of the clock, then use -cm with a value to actually set that clock.
  • --clock-high, -ch β€” Set power_dpm_force_performance_level to high.
  • --clock-low, -cl β€” Set power_dpm_force_performance_level to low.
  • --clock-auto, -ca β€” Set power_dpm_force_performance_level to auto.
  • --ppt-read, -pptr [ppt_field_name] β€” Read a powerplay table value and print it to stdout. This command will print all the powerplay table information, or just the corresponding string in the powerplay table.
  • --gpu-metrics, -gm [delay] β€” Print the GPU metrics table for the device, and optionally keep reading continuously every delay milliseconds.
  • --power, -p β€” Read the content of clocks, temperature, and gpu loading at runtime. The option use_colour colourizes the output. (yes bestie, it's listed twice β€” that's just how the page is, and we respect the page πŸ™ˆ)

πŸŽ€ Video BIOS Information πŸŽ€

  • --vbios-info, -vi β€” Print Video BIOS information.

πŸ§ͺ Test Vector Generation πŸ§ͺ

  • --test-log, -tl <filename> β€” Log all MMIO/memory reads to a file.
  • --test-harness, -th <filename> β€” Use a test harness file instead of reading from the hardware. bye hardware πŸ‘‹

🌐 RUMR Commands 🌐

  • --rumr-client <server> β€” Run as a RUMR client, connecting to server, e.g. tcp://127.0.0.1:9000. You can also set the RUMR_SERVER_ADDR environment variable to tell umr to connect as a client β€” and with that env var set, you don't even need to pass --rumr-client. no cap. πŸ’œ
  • --rumr-server <server> β€” Run as a RUMR server, binding to server, e.g. tcp://127.0.0.1:9000.

πŸ–€ KFD Support πŸ–€

  • --runlist, -rls <node> β€” Dump any runlists for a given KFD node that you specify.
  • --dump-mqd vmid@virtualaddr engsel β€” Dump an MQD from a given VMID and virtual address, for a given engine and asic family. Engines are 0=compute, 2=sdma0, 3=sdma1, 4=gfx, 5=mes. πŸ’€

πŸ“œ Scriptware Support πŸ“œ

  • --script [commands] β€” Run a script helper command. Run it without any parameters to see the list of commands.

πŸ“ Notes πŸ“

  • The "Waves" field in the DRM section of --top only works if GFX PG has been disabled. Otherwise, GPU hangs occur frequently. When PG is enabled, it will just read a constant 0. 😭
fr fr, disable that PG first or you're gonna have a bad time.

🌸 Environmental Variables 🌸

  • UMR_LOGGER β€” Directory to output the "umr.log" file when capturing samples with the --top command.
  • UMR_DATABASE_PATH β€” Should be set to the top directory of the database tree used for register, IP, and ASIC model data.
  • RUMR_SERVER_ADDR β€” Specifies the server address the rumr client should connect to. You can set this to avoid needing to add --rumr-client to the command line.

πŸ—‚οΈ FILES πŸ—‚οΈ

  • ${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions/umr β€” contains completion for bash shells. You'd normally source this file in your ~/.bashrc.
  • ${CMAKE_INSTALL_PREFIX}/share/umr/database β€” contains database files for ASICs, IPs, and registers. UMR_DATABASE_PATH is usually set to point here.

and that's the whole page, bestie 🫢 this one's from AMD (c) 2022, dated February 2022, and it's the UMR(1) manual page β€” go forth and debug, you're gonna eat πŸ’…βœ¨πŸ‘‘

πŸ“¦ where this page comes from