[umr] Improve --lookup command to allow register names.

Submitted by StDenis, Tom on July 5, 2017, 12:02 p.m.

Details

Message ID 20170705120243.13481-1-tom.stdenis@amd.com
State New
Headers show
Series "Improve --lookup command to allow register names." ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

StDenis, Tom July 5, 2017, 12:02 p.m.
This is handy if you are given a debug output with a register name and value
you want to decode.  For instance, a VM fault in the kernel log,

$ umr -i 1 -O bits --lookup mmVM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0803D00C
gmc81.mmVM_CONTEXT1_PROTECTION_FAULT_STATUS => 0x0803d00c
        .PROTECTIONS[0:7]                                                ==       12 (0x0000000c)
        .MEMORY_CLIENT_ID[12:20]                                         ==       61 (0x0000003d)
        .MEMORY_CLIENT_RW[24:24]                                         ==        0 (0x00000000)
        .VMID[25:28]                                                     ==        4 (0x00000004)
        .ATOMIC[29:29]                                                   ==        0 (0x00000000)

Signed-off-by: Tom St Denis <tom.stdenis@amd.com>
---
 doc/umr.1            |  5 +++--
 src/app/main.c       |  6 +++++-
 src/app/umr_lookup.c | 41 ++++++++++++++++++++++++++++-------------
 3 files changed, 36 insertions(+), 16 deletions(-)

Patch hide | download patch | download mbox

diff --git a/doc/umr.1 b/doc/umr.1
index d20184def2d3..601866a57a7e 100644
--- a/doc/umr.1
+++ b/doc/umr.1
@@ -32,8 +32,9 @@  Enumerate all AMDGPU supported devices.
 List all blocks attached to the asic that has been detected.
 .IP "--list-regs, -lr <string>"
 List all registers in an IP block (can use '-O bits' to list bitfields)
-.IP "--lookup, -lu <address> <number>"
-Look up an MMIO register by address and bitfield decode the value specified.
+.IP "--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.
 .IP "--write -w <string> <number>"
 Write a value specified in hex to a register specified with a complete
 register path in the form <
diff --git a/src/app/main.c b/src/app/main.c
index 822aa88afd85..ac3c25e2937e 100644
--- a/src/app/main.c
+++ b/src/app/main.c
@@ -393,12 +393,16 @@  int main(int argc, char **argv)
 "\n\t--bank, -b <se_bank> <sh_bank> <instance>\n\t\tSelect a GFX INSTANCE/SH/SE bank in decimal. Can use 'x' to denote broadcast.\n"
 "\n\t--force, -f <number>\n\t\tForce a PCIE DID number in hex or asic name.  Useful if amdgpu is"
 	"\n\t\tnot loaded or a display is not attached.\n"
+"\n\t--pci <device>"
+	"\n\t\tForce a specific PCI device using the domain:bus:slot.function format in hex."
+	"\n\t\tThis is useful when more than one GPU is available. If the amdgpu driver is"
+	"\n\t\tloaded the corresponding instance will be automatically detected.\n"
 "\n\t--print, -p\n\t\tEnable dumping of all device registers. (default: off)\n"
 "\n\t--config, -c\n\t\tPrint out configuation data read from kernel driver.\n"
 "\n\t--enumerate, -e\n\t\tEnumerate all AMDGPU devices detected.\n"
 "\n\t--list-blocks, -lb\n\t\tList IP blocks discovered for this device.\n"
 "\n\t--list-regs, -lr <string>\n\t\tList registers for a given IP block (can use '-O bits' to list bitfields).\n"
-"\n\t--lookup, -lu <address> <value>\n\t\tLook up bit decoding of an MMIO register by address.\n"
+"\n\t--lookup, -lu <address_or_regname> <value>\n\t\tLook up bit decoding of an MMIO register by address (with 0x prefix) or by register name.\n"
 "\n\t--write, -w <address> <number>\n\t\tWrite a value in hex to a register specified as a register path in the"
 	"\n\t\tform <asicname.ipname.regname>.  For instance \"tonga.uvd5.mmUVD_SOFT_RESET\"."
 	"\n\t\tCan be used multiple times to set multiple registers.  You can"
diff --git a/src/app/umr_lookup.c b/src/app/umr_lookup.c
index 3f3402ae34e7..d07130ab0dfa 100644
--- a/src/app/umr_lookup.c
+++ b/src/app/umr_lookup.c
@@ -27,23 +27,38 @@ 
 
 void umr_lookup(struct umr_asic *asic, char *address, char *value)
 {
-	int i, j, k;
+	int byaddress, i, j, k;
 	uint32_t regno, num;
 
-	sscanf(address, "%"SCNx32, &regno);
+	byaddress = sscanf(address, "0x%"SCNx32, &regno);
 	sscanf(value, "%"SCNx32, &num);
 
-	for (i = 0; i < asic->no_blocks; i++)
-	for (j = 0; j < asic->blocks[i]->no_regs; j++)
-		if (asic->blocks[i]->regs[j].type == REG_MMIO &&
-		    asic->blocks[i]->regs[j].addr == regno) {
-			printf("%s => 0x%08lx\n", asic->blocks[i]->regs[j].regname, (unsigned long)num);
-			for (k = 0; k < asic->blocks[i]->regs[j].no_bits; k++) {
-				uint32_t v;
-				v = (1UL << (asic->blocks[i]->regs[j].bits[k].stop + 1 - asic->blocks[i]->regs[j].bits[k].start)) - 1;
-				v &= (num >> asic->blocks[i]->regs[j].bits[k].start);
-				asic->blocks[i]->regs[j].bits[k].bitfield_print(asic, asic->asicname, asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, asic->blocks[i]->regs[j].bits[k].regname, asic->blocks[i]->regs[j].bits[k].start, asic->blocks[i]->regs[j].bits[k].stop, v);
+	if (byaddress) {
+		for (i = 0; i < asic->no_blocks; i++)
+		for (j = 0; j < asic->blocks[i]->no_regs; j++)
+			if (asic->blocks[i]->regs[j].type == REG_MMIO &&
+			    asic->blocks[i]->regs[j].addr == regno) {
+				printf("%s.%s => 0x%08lx\n", asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, (unsigned long)num);
+				for (k = 0; k < asic->blocks[i]->regs[j].no_bits; k++) {
+					uint32_t v;
+					v = (1UL << (asic->blocks[i]->regs[j].bits[k].stop + 1 - asic->blocks[i]->regs[j].bits[k].start)) - 1;
+					v &= (num >> asic->blocks[i]->regs[j].bits[k].start);
+					asic->blocks[i]->regs[j].bits[k].bitfield_print(asic, asic->asicname, asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, asic->blocks[i]->regs[j].bits[k].regname, asic->blocks[i]->regs[j].bits[k].start, asic->blocks[i]->regs[j].bits[k].stop, v);
+				}
 			}
-		}
+	} else {
+		for (i = 0; i < asic->no_blocks; i++)
+		for (j = 0; j < asic->blocks[i]->no_regs; j++)
+			if (asic->blocks[i]->regs[j].type == REG_MMIO &&
+			    !strcmp(asic->blocks[i]->regs[j].regname, address)) {
+				printf("%s.%s => 0x%08lx\n", asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, (unsigned long)num);
+				for (k = 0; k < asic->blocks[i]->regs[j].no_bits; k++) {
+					uint32_t v;
+					v = (1UL << (asic->blocks[i]->regs[j].bits[k].stop + 1 - asic->blocks[i]->regs[j].bits[k].start)) - 1;
+					v &= (num >> asic->blocks[i]->regs[j].bits[k].start);
+					asic->blocks[i]->regs[j].bits[k].bitfield_print(asic, asic->asicname, asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, asic->blocks[i]->regs[j].bits[k].regname, asic->blocks[i]->regs[j].bits[k].start, asic->blocks[i]->regs[j].bits[k].stop, v);
+				}
+			}
+	}
 }