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.stde...@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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to