[PATCH umr] Add 'no_kernel' option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This flag allows umr to perform some operations it would normally
need the kernel for in userspace.  This is useful if the kernel driver
is misbehaving.  Don't use this on a healthy system as it could invoke
race conditions.

This flag enables userland activities such as

- reading/writing MMIO registers (with bank selection)
- reading wave status and SGPR registers

Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
---
 doc/umr.1             |  5 +++
 src/app/main.c        |  5 ++-
 src/app/scan.c        |  6 +++-
 src/app/set_bit.c     |  4 +++
 src/app/set_reg.c     |  4 +++
 src/lib/discover.c    | 49 +++++++++++++++++----------
 src/lib/mmio.c        | 57 ++++++++++++++++++++++++++++++-
 src/lib/read_sgpr.c   | 58 +++++++++++++++++++++++++-------
 src/lib/wave_status.c | 92 ++++++++++++++++++++++++++++++++++++++++++---------
 src/umr.h             | 23 +++++++++++--
 10 files changed, 252 insertions(+), 51 deletions(-)

diff --git a/doc/umr.1 b/doc/umr.1
index 90be2d6316ce..50ce03330b5c 100644
--- a/doc/umr.1
+++ b/doc/umr.1
@@ -138,6 +138,11 @@ separated strings.
      Enable colour output for --top command, scales from blue, green, yellow, to red.  Also
      accepted is 'use_color'.
 
+.B 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.
+
 .SH "Notes"
 
 - The "Waves" field in the DRM section of --top only works if GFX PG has been disabled.  Otherwise,
diff --git a/src/app/main.c b/src/app/main.c
index 96a790cbec7c..1d9ef9edceb8 100644
--- a/src/app/main.c
+++ b/src/app/main.c
@@ -109,6 +109,9 @@ static void parse_options(char *str)
 			options.quiet = 1;
 		} else if (!strcmp(option, "follow_ib")) {
 			options.follow_ib = 1;
+		} else if (!strcmp(option, "no_kernel")) {
+			options.no_kernel = 1;
+			options.use_pci = 1;
 		} else {
 			printf("error: Unknown option [%s]\n", option);
 			exit(EXIT_FAILURE);
@@ -413,7 +416,7 @@ int main(int argc, char **argv)
 	"\n\t\tRead 'size' bytes (in hex) from a given address (in hex) to stdout. Optionally"
 	"\n\t\tspecify the VMID (in decimal) treating the address as a virtual address instead.\n"
 "\n\t--option -O <string>[,<string>,...]\n\t\tEnable various flags: risky, bits, bitsfull, empty_log, follow, named, many,"
-	"\n\t\tuse_pci, use_colour, read_smc, quiet.\n"
+	"\n\t\tuse_pci, use_colour, read_smc, quiet, no_kernel.\n"
 "\n\n", UMR_BUILD_VER, UMR_BUILD_REV);
 			exit(EXIT_SUCCESS);
 		} else {
diff --git a/src/app/scan.c b/src/app/scan.c
index e91fbd4649c8..3320509f8be2 100644
--- a/src/app/scan.c
+++ b/src/app/scan.c
@@ -88,7 +88,11 @@ int umr_scan_asic(struct umr_asic *asic, char *asicname, char *ipname, char *reg
 								goto error;
 							}
 						} else if (asic->blocks[i]->regs[j].type == REG_MMIO) {
-							asic->blocks[i]->regs[j].value = asic->pci.mem[asic->blocks[i]->regs[j].addr];
+							if (options.use_bank && options.no_kernel)
+								umr_grbm_select_index(asic, options.se_bank, options.sh_bank, options.instance_bank);
+							asic->blocks[i]->regs[j].value = umr_read_reg(asic, asic->blocks[i]->regs[j].addr * 4);
+							if (options.use_bank && options.no_kernel)
+								umr_grbm_select_index(asic, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
 						}
 						if (regname[0]) {
 							if (options.named)
diff --git a/src/app/set_bit.c b/src/app/set_bit.c
index bed7ee858b6a..49f6c4750b8a 100644
--- a/src/app/set_bit.c
+++ b/src/app/set_bit.c
@@ -96,9 +96,13 @@ int umr_set_register_bit(struct umr_asic *asic, char *regpath, char *regvalue)
 										}
 									}
 								} else if (asic->blocks[i]->regs[j].type == REG_MMIO) {
+									if (options.use_bank && options.no_kernel)
+										umr_grbm_select_index(asic, options.se_bank, options.sh_bank, options.instance_bank);
 									copy = asic->pci.mem[asic->blocks[i]->regs[j].addr] & ~mask;
 									copy |= (value << asic->blocks[i]->regs[j].bits[k].start) & mask;
 									asic->pci.mem[asic->blocks[i]->regs[j].addr] = copy;
+									if (options.use_bank && options.no_kernel)
+										umr_grbm_select_index(asic, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
 									if (!options.quiet) printf("%s <= 0x%08lx\n", regpath, (unsigned long)copy);
 								}
 								return 0;
diff --git a/src/app/set_reg.c b/src/app/set_reg.c
index ed8f708e977f..acc8228cf421 100644
--- a/src/app/set_reg.c
+++ b/src/app/set_reg.c
@@ -84,7 +84,11 @@ int umr_set_register(struct umr_asic *asic, char *regpath, char *regvalue)
 								}
 							}
 						} else if (asic->blocks[i]->regs[j].type == REG_MMIO) {
+							if (options.use_bank && options.no_kernel)
+								umr_grbm_select_index(asic, options.se_bank, options.sh_bank, options.instance_bank);
 							asic->pci.mem[asic->blocks[i]->regs[j].addr] = value;
+							if (options.use_bank && options.no_kernel)
+								umr_grbm_select_index(asic, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
 						}
 						return 0;
 					}
diff --git a/src/lib/discover.c b/src/lib/discover.c
index c9c2f74a4818..5a6d7e47b0c2 100644
--- a/src/lib/discover.c
+++ b/src/lib/discover.c
@@ -111,24 +111,37 @@ struct umr_asic *umr_discover_asic(struct umr_options *options)
 
 	if (asic) {
 		memcpy(&asic->options, options, sizeof(*options));
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs", asic->instance);
-		asic->fd.mmio = open(fname, O_RDWR);
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs_didt", asic->instance);
-		asic->fd.didt = open(fname, O_RDWR);
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs_pcie", asic->instance);
-		asic->fd.pcie = open(fname, O_RDWR);
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs_smc", asic->instance);
-		asic->fd.smc = open(fname, O_RDWR);
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_sensors", asic->instance);
-		asic->fd.sensors = open(fname, O_RDWR);
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_wave", asic->instance);
-		asic->fd.wave = open(fname, O_RDWR);
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_vram", asic->instance);
-		asic->fd.vram = open(fname, O_RDWR);
-		snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_gpr", asic->instance);
-		asic->fd.gpr = open(fname, O_RDWR);
-		asic->fd.drm = -1; // default to closed
-		// if appending to the fd list remember to update close_asic() and discover_by_did()...
+		if (!asic->options.no_kernel) {
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs", asic->instance);
+			asic->fd.mmio = open(fname, O_RDWR);
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs_didt", asic->instance);
+			asic->fd.didt = open(fname, O_RDWR);
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs_pcie", asic->instance);
+			asic->fd.pcie = open(fname, O_RDWR);
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_regs_smc", asic->instance);
+			asic->fd.smc = open(fname, O_RDWR);
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_sensors", asic->instance);
+			asic->fd.sensors = open(fname, O_RDWR);
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_wave", asic->instance);
+			asic->fd.wave = open(fname, O_RDWR);
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_vram", asic->instance);
+			asic->fd.vram = open(fname, O_RDWR);
+			snprintf(fname, sizeof(fname)-1, "/sys/kernel/debug/dri/%d/amdgpu_gpr", asic->instance);
+			asic->fd.gpr = open(fname, O_RDWR);
+			asic->fd.drm = -1; // default to closed
+			// if appending to the fd list remember to update close_asic() and discover_by_did()...
+		} else {
+			// no files open!
+			asic->fd.mmio = -1;
+			asic->fd.didt = -1;
+			asic->fd.pcie = -1;
+			asic->fd.smc = -1;
+			asic->fd.sensors = -1;
+			asic->fd.wave = -1;
+			asic->fd.vram = -1;
+			asic->fd.gpr = -1;
+			asic->fd.drm = -1;
+		}
 
 		if (options->use_pci) {
 			// init PCI mapping
diff --git a/src/lib/mmio.c b/src/lib/mmio.c
index 5d7cdd3191a1..ca812817e018 100644
--- a/src/lib/mmio.c
+++ b/src/lib/mmio.c
@@ -85,9 +85,64 @@ uint32_t umr_bitslice_reg(struct umr_asic *asic, struct umr_reg *reg, char *bitn
 	return 0;
 }
 
+uint32_t umr_bitslice_compose_value(struct umr_asic *asic, struct umr_reg *reg, char *bitname, uint32_t regvalue)
+{
+	int i;
+	for (i = 0; i < reg->no_bits; i++) {
+		if (!strcmp(bitname, reg->bits[i].regname)) {
+			regvalue &= (1UL << (reg->bits[i].stop - reg->bits[i].start + 1)) - 1;
+			regvalue <<= reg->bits[i].start;
+			return regvalue;
+		}
+	}
+	fprintf(stderr, "BUG: Bitfield [%s] not found in reg [%s] on asic [%s]\n", bitname, reg->regname, asic->asicname);
+	return 0;
+}
+
 uint32_t umr_bitslice_reg_by_name(struct umr_asic *asic, char *regname, char *bitname, uint32_t regvalue)
 {
 	struct umr_reg *reg;
 	reg = umr_find_reg_data(asic, regname);
-	return umr_bitslice_reg(asic, reg, bitname, regvalue);
+	if (reg)
+		return umr_bitslice_reg(asic, reg, bitname, regvalue);
+	else
+		return 0;
+}
+
+uint32_t umr_bitslice_compose_value_by_name(struct umr_asic *asic, char *regname, char *bitname, uint32_t regvalue)
+{
+	struct umr_reg *reg;
+	reg = umr_find_reg_data(asic, regname);
+	if (reg)
+		return umr_bitslice_compose_value(asic, reg, bitname, regvalue);
+	else
+		return 0;
+}
+
+int umr_grbm_select_index(struct umr_asic *asic, uint32_t se, uint32_t sh, uint32_t instance)
+{
+	struct umr_reg *grbm_idx;
+	uint32_t data = 0;
+
+	grbm_idx = umr_find_reg_data(asic, "mmGRBM_GFX_INDEX");
+	if (grbm_idx) {
+		if (instance == 0xFFFFFFFF) {
+			data |= umr_bitslice_compose_value(asic, grbm_idx, "INSTANCE_BROADCAST_WRITES", 1);
+		} else {
+			data |= umr_bitslice_compose_value(asic, grbm_idx, "INSTANCE_INDEX", instance);
+		}
+		if (se == 0xFFFFFFFF) {
+			data |= umr_bitslice_compose_value(asic, grbm_idx, "SE_BROADCAST_WRITES", 1);
+		} else {
+			data |= umr_bitslice_compose_value(asic, grbm_idx, "SE_INDEX", instance);
+		}
+		if (sh == 0xFFFFFFFF) {
+			data |= umr_bitslice_compose_value(asic, grbm_idx, "SH_BROADCAST_WRITES", 1);
+		} else {
+			data |= umr_bitslice_compose_value(asic, grbm_idx, "SH_INDEX", instance);
+		}
+		return umr_write_reg(asic, grbm_idx->addr * 4, data);
+	} else {
+		return -1;
+	}
 }
diff --git a/src/lib/read_sgpr.c b/src/lib/read_sgpr.c
index f12983edcb04..8f799175b7ff 100644
--- a/src/lib/read_sgpr.c
+++ b/src/lib/read_sgpr.c
@@ -24,6 +24,33 @@
  */
 #include "umr.h"
 
+static void wave_read_regs_via_mmio(struct umr_asic *asic, uint32_t simd,
+			   uint32_t wave, uint32_t thread,
+			   uint32_t regno, uint32_t num, uint32_t *out)
+{
+	struct umr_reg *ind_index, *ind_data;
+	uint32_t data;
+
+	ind_index = umr_find_reg_data(asic, "mmSQ_IND_INDEX");
+	ind_data  = umr_find_reg_data(asic, "mmSQ_IND_DATA");
+
+	if (ind_index && ind_data) {
+		data = umr_bitslice_compose_value(asic, ind_index, "WAVE_ID", wave);
+		data |= umr_bitslice_compose_value(asic, ind_index, "SIMD_ID", simd);
+		data |= umr_bitslice_compose_value(asic, ind_index, "INDEX", regno);
+		data |= umr_bitslice_compose_value(asic, ind_index, "THREAD_ID", thread);
+		data |= umr_bitslice_compose_value(asic, ind_index, "FORCE_READ", 1);
+		data |= umr_bitslice_compose_value(asic, ind_index, "AUTO_INCR", 1);
+		umr_write_reg(asic, ind_index->addr * 4, data);
+		while (num--)
+			*(out++) = umr_read_reg(asic, ind_data->addr * 4);
+	} else {
+		fprintf(stderr, "[BUG] The required SQ_IND_{INDEX,DATA} registers are not found on the asic <%s>\n", asic->asicname);
+		return;
+	}
+}
+
+
 int umr_read_sgprs(struct umr_asic *asic, struct umr_wave_status *ws, uint32_t *dst)
 {
 	uint64_t addr, shift;
@@ -33,16 +60,23 @@ int umr_read_sgprs(struct umr_asic *asic, struct umr_wave_status *ws, uint32_t *
 	else
 		shift = 4;  // on VI allocations are in 16-dword blocks
 
-	addr =
-		(1ULL << 60)                             | // reading SGPRs
-		((uint64_t)ws->gpr_alloc.sgpr_base << shift) | // starting address to read from
-		((uint64_t)ws->hw_id.se_id << 12)        |
-		((uint64_t)ws->hw_id.sh_id << 20)        |
-		((uint64_t)ws->hw_id.cu_id << 28)        |
-		((uint64_t)ws->hw_id.wave_id << 36)      |
-		((uint64_t)ws->hw_id.simd_id << 44)      |
-		(0ULL << 52); // thread_id
-
-	lseek(asic->fd.gpr, addr, SEEK_SET);
-	return read(asic->fd.gpr, dst, 4 * ((ws->gpr_alloc.sgpr_size + 1) << shift));
+	if (!asic->options.no_kernel) {
+		addr =
+			(1ULL << 60)                             | // reading SGPRs
+			((uint64_t)ws->gpr_alloc.sgpr_base << shift) | // starting address to read from
+			((uint64_t)ws->hw_id.se_id << 12)        |
+			((uint64_t)ws->hw_id.sh_id << 20)        |
+			((uint64_t)ws->hw_id.cu_id << 28)        |
+			((uint64_t)ws->hw_id.wave_id << 36)      |
+			((uint64_t)ws->hw_id.simd_id << 44)      |
+			(0ULL << 52); // thread_id
+
+		lseek(asic->fd.gpr, addr, SEEK_SET);
+		return read(asic->fd.gpr, dst, 4 * ((ws->gpr_alloc.sgpr_size + 1) << shift));
+	} else {
+		umr_grbm_select_index(asic, ws->hw_id.se_id, ws->hw_id.sh_id, ws->hw_id.cu_id);
+		wave_read_regs_via_mmio(asic, ws->hw_id.simd_id, ws->hw_id.wave_id, ws->gpr_alloc.sgpr_base << shift, 0, (ws->gpr_alloc.sgpr_size + 1) << shift, dst);
+		umr_grbm_select_index(asic, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+		return 0;
+	}
 }
diff --git a/src/lib/wave_status.c b/src/lib/wave_status.c
index 695a1bb836d1..22f92c2caad5 100644
--- a/src/lib/wave_status.c
+++ b/src/lib/wave_status.c
@@ -49,20 +49,75 @@ static int umr_get_wave_sq_info_vi(struct umr_asic *asic, unsigned se, unsigned
 	return 0;
 }
 
+static uint32_t wave_read_ind(struct umr_asic *asic, uint32_t simd, uint32_t wave, uint32_t address)
+{
+	struct umr_reg *ind_index, *ind_data;
+	uint32_t data;
+
+	ind_index = umr_find_reg_data(asic, "mmSQ_IND_INDEX");
+	ind_data  = umr_find_reg_data(asic, "mmSQ_IND_DATA");
+
+	if (ind_index && ind_data) {
+		data = umr_bitslice_compose_value(asic, ind_index, "WAVE_ID", wave);
+		data |= umr_bitslice_compose_value(asic, ind_index, "SIMD_ID", simd);
+		data |= umr_bitslice_compose_value(asic, ind_index, "INDEX", address);
+		data |= umr_bitslice_compose_value(asic, ind_index, "FORCE_READ", 1);
+		umr_write_reg(asic, ind_index->addr * 4, data);
+		return umr_read_reg(asic, ind_data->addr * 4);
+	} else {
+		fprintf(stderr, "[BUG] The required SQ_IND_{INDEX,DATA} registers are not found on the asic <%s>\n", asic->asicname);
+		return -1;
+	}
+}
+
+
+static int read_wave_status_via_mmio(struct umr_asic *asic, uint32_t simd, uint32_t wave, uint32_t *dst, int *no_fields)
+{
+	/* type 0/1 wave data */
+	dst[(*no_fields)++] = (asic->family <= FAMILY_VI) ? 0 : 1;
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_STATUS")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_PC_LO")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_PC_HI")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_EXEC_LO")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_EXEC_HI")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_HW_ID")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_INST_DW0")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_INST_DW1")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_GPR_ALLOC")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_LDS_ALLOC")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_TRAPSTS")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_IB_STS")->addr);
+	if (asic->family <= FAMILY_VI) {
+		dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_TBA_LO")->addr);
+		dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_TBA_HI")->addr);
+		dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_TMA_LO")->addr);
+		dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_TMA_HI")->addr);
+	}
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_IB_DBG0")->addr);
+	dst[(*no_fields)++] = wave_read_ind(asic, simd, wave, umr_find_reg_data(asic, "ixSQ_WAVE_M0")->addr);
+
+	return 0;
+}
+
 static int umr_get_wave_status_vi(struct umr_asic *asic, unsigned se, unsigned sh, unsigned cu, unsigned simd, unsigned wave, struct umr_wave_status *ws)
 {
 	uint32_t x, value, buf[32];
 
 	memset(buf, 0, sizeof buf);
 
-	lseek(asic->fd.wave,
-		0 |
-		((uint64_t)se << 7) |
-		((uint64_t)sh << 15) |
-		((uint64_t)cu << 23) |
-		((uint64_t)wave << 31) |
-		((uint64_t)simd << 37), SEEK_SET);
-	read(asic->fd.wave, &buf, 32*4);
+	if (!asic->options.no_kernel) {
+		lseek(asic->fd.wave,
+			0 |
+			((uint64_t)se << 7) |
+			((uint64_t)sh << 15) |
+			((uint64_t)cu << 23) |
+			((uint64_t)wave << 31) |
+			((uint64_t)simd << 37), SEEK_SET);
+		read(asic->fd.wave, &buf, 32*4);
+	} else {
+		int n = 0;
+		read_wave_status_via_mmio(asic, simd, wave, &buf[0], &n);
+	}
 
 	if (buf[0] != 0) {
 		fprintf(stderr, "Was expecting type 0 wave data on a CZ/VI part!\n");
@@ -152,14 +207,19 @@ static int umr_get_wave_status_next(struct umr_asic *asic, unsigned se, unsigned
 
 	memset(buf, 0, sizeof buf);
 
-	lseek(asic->fd.wave,
-		0 |
-		((uint64_t)se << 7) |
-		((uint64_t)sh << 15) |
-		((uint64_t)cu << 23) |
-		((uint64_t)wave << 31) |
-		((uint64_t)simd << 37), SEEK_SET);
-	read(asic->fd.wave, &buf, 32*4);
+	if (!asic->options.no_kernel) {
+		lseek(asic->fd.wave,
+			0 |
+			((uint64_t)se << 7) |
+			((uint64_t)sh << 15) |
+			((uint64_t)cu << 23) |
+			((uint64_t)wave << 31) |
+			((uint64_t)simd << 37), SEEK_SET);
+		read(asic->fd.wave, &buf, 32*4);
+	} else {
+		int n = 0;
+		read_wave_status_via_mmio(asic, simd, wave, &buf[0], &n);
+	}
 
 	if (buf[0] != 1) {
 		fprintf(stderr, "Was expecting type 1 wave data on a FAMILY_AI part!\n");
diff --git a/src/umr.h b/src/umr.h
index 27d0015d17a3..b0b8fcb4cc72 100644
--- a/src/umr.h
+++ b/src/umr.h
@@ -171,7 +171,8 @@ struct umr_options {
 	    use_colour,
 	    read_smc,
 	    quiet,
-	    follow_ib;
+	    follow_ib,
+	    no_kernel;
 	unsigned
 	    instance_bank,
 	    se_bank,
@@ -453,15 +454,33 @@ int umr_read_sgprs(struct umr_asic *asic, struct umr_wave_status *ws, uint32_t *
 int umr_read_sensor(struct umr_asic *asic, int sensor, void *dst, int *size);
 
 /* mmio helpers */
+// init the mmio lookup table
+int umr_create_mmio_accel(struct umr_asic *asic);
+
+// find the word address of a register
 uint32_t umr_find_reg(struct umr_asic *asic, char *regname);
+
+// find the register data for a register
 struct umr_reg *umr_find_reg_data(struct umr_asic *asic, char *regname);
+
+// read/write a 32-bit register given a BYTE address
 uint32_t umr_read_reg(struct umr_asic *asic, uint64_t addr);
 int umr_write_reg(struct umr_asic *asic, uint64_t addr, uint32_t value);
+
+// read/write a register given a name
 uint32_t umr_read_reg_by_name(struct umr_asic *asic, char *name);
 int umr_write_reg_by_name(struct umr_asic *asic, char *name, uint32_t value);
+
+// slice a full register into bits (shifted into LSB)
 uint32_t umr_bitslice_reg(struct umr_asic *asic, struct umr_reg *reg, char *bitname, uint32_t regvalue);
 uint32_t umr_bitslice_reg_by_name(struct umr_asic *asic, char *regname, char *bitname, uint32_t regvalue);
-int umr_create_mmio_accel(struct umr_asic *asic);
+
+// compose a 32-bit register with a value and a bitfield
+uint32_t umr_bitslice_compose_value(struct umr_asic *asic, struct umr_reg *reg, char *bitname, uint32_t regvalue);
+uint32_t umr_bitslice_compose_value_by_name(struct umr_asic *asic, char *reg, char *bitname, uint32_t regvalue);
+
+// select a GRBM_GFX_IDX
+int umr_grbm_select_index(struct umr_asic *asic, uint32_t se, uint32_t sh, uint32_t instance);
 
 /* IB/ring decoding/dumping/etc */
 void umr_print_decode(struct umr_asic *asic, struct umr_ring_decoder *decoder, uint32_t ib);
-- 
2.12.0



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux