On SI..VI platforms this allows access to SMC registers without kernel access.

Signed-off-by: Tom St Denis <[email protected]>

(v2):  Use difference instances of accessors to SMC as well as properly break 
out
use_pci/!use_pci support in the umr_read_smc/umr_write_smc functions.
---
 src/app/main.c        |   4 +-
 src/app/scan.c        |   4 +-
 src/lib/mmio.c        | 128 +++++++++++++++++++++++++++++++++++++++++---------
 src/lib/read_sgpr.c   |   4 +-
 src/lib/read_vram.c   |   6 +--
 src/lib/wave_status.c |   8 ++--
 src/umr.h             |   4 +-
 7 files changed, 121 insertions(+), 37 deletions(-)

diff --git a/src/app/main.c b/src/app/main.c
index 60bf20480fd3..bcca76225727 100644
--- a/src/app/main.c
+++ b/src/app/main.c
@@ -224,7 +224,7 @@ int main(int argc, char **argv)
                                if (!asic)
                                        asic = get_asic();
                                if (!memcmp(argv[i+1], "0x", 2) && 
sscanf(argv[i+1], "%"SCNx32, &reg) == 1 && sscanf(argv[i+2], "%"SCNx32, &val) 
== 1)
-                                       umr_write_reg(asic, reg, val);
+                                       umr_write_reg(asic, reg, val, REG_MMIO);
                                else
                                        umr_set_register(asic, argv[i+1], 
argv[i+2]);
                                i += 2;
@@ -271,7 +271,7 @@ int main(int argc, char **argv)
                                        asic = get_asic();
 
                                if (!memcmp(argv[i+1], "0x", 2) && 
sscanf(argv[i+1], "%"SCNx32, &reg) == 1) {
-                                       reg = umr_read_reg(asic, reg);
+                                       reg = umr_read_reg(asic, reg, REG_MMIO);
                                        printf("0x%08lx\n", (unsigned long)reg);
                                } else {
                                        str = strstr(argv[i+1], ".");
diff --git a/src/app/scan.c b/src/app/scan.c
index 0e1f9e3f94b5..29a3e46ba3f7 100644
--- a/src/app/scan.c
+++ b/src/app/scan.c
@@ -87,10 +87,10 @@ int umr_scan_asic(struct umr_asic *asic, char *asicname, 
char *ipname, char *reg
                                                                r = -1;
                                                                goto error;
                                                        }
-                                               } else if 
(asic->blocks[i]->regs[j].type == REG_MMIO) {
+                                               } else if 
(asic->blocks[i]->regs[j].type == REG_MMIO || asic->blocks[i]->regs[j].type == 
REG_SMC) {
                                                        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);
+                                                       
asic->blocks[i]->regs[j].value = umr_read_reg(asic, 
asic->blocks[i]->regs[j].addr * (asic->blocks[i]->regs[j].type == REG_MMIO ? 4 
: 1), asic->blocks[i]->regs[j].type);
                                                        if (options.use_bank && 
options.no_kernel)
                                                                
umr_grbm_select_index(asic, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
                                                }
diff --git a/src/lib/mmio.c b/src/lib/mmio.c
index 22110e09a9b4..dfd9f0d33e5d 100644
--- a/src/lib/mmio.c
+++ b/src/lib/mmio.c
@@ -24,36 +24,55 @@
  */
 #include "umr.h"
 
-uint32_t umr_read_reg(struct umr_asic *asic, uint64_t addr)
+static uint32_t umr_smc_read(struct umr_asic *asic, uint64_t addr)
 {
-       uint32_t value=0;
-       if (addr == 0xFFFFFFFF)
-               fprintf(stderr, "[BUG]: reading from addr==0xFFFFFFFF is likely 
a bug\n");
-
-       if (asic->pci.mem && !(addr & ~0xFFFFFULL)) { // only use pci if 
enabled and not using high bits 
-               return asic->pci.mem[addr/4];
+       uint32_t value;
+       if (asic->options.use_pci) {
+               switch (asic->config.gfx.family) {
+                       case 110: // SI
+                       case 120: // CIK
+                       case 130: // VI
+                               umr_write_reg_by_name(asic, 
"mmSMC_IND_INDEX_1", addr);
+                               return umr_read_reg_by_name(asic, 
"mmSMC_IND_DATA_1");
+                       case 135: // CZ
+                               umr_write_reg_by_name(asic, 
"mmMP0PUB_IND_INDEX_1", addr);
+                               return umr_read_reg_by_name(asic, 
"mmMP0PUB_IND_DATA_1");
+                       default:
+                               fprintf(stderr, "[BUG] Unsupported family type 
in umr_smc_read()\n");
+                               return 0;
+               }
        } else {
-               if (lseek(asic->fd.mmio, addr, SEEK_SET) < 0)
-                       perror("Cannot seek to MMIO address");
-               if (read(asic->fd.mmio, &value, 4) != 4)
-                       perror("Cannot read from MMIO reg");
+               if (lseek(asic->fd.smc, addr, SEEK_SET) < 0)
+                       perror("Cannot seek to SMC address");
+               if (read(asic->fd.smc, &value, 4) != 4)
+                       perror("Cannot read from SMC reg");
                return value;
        }
+
 }
 
-int umr_write_reg(struct umr_asic *asic, uint64_t addr, uint32_t value)
+static uint32_t umr_smc_write(struct umr_asic *asic, uint64_t addr, uint32_t 
value)
 {
-       if (addr == 0xFFFFFFFF)
-               fprintf(stderr, "[BUG]: reading from addr==0xFFFFFFFF is likely 
a bug\n");
-
-       if (asic->pci.mem && !(addr & ~0xFFFFFULL)) {
-               asic->pci.mem[addr/4] = value;
+       if (asic->options.use_pci) {
+               switch (asic->config.gfx.family) {
+                       case 110: // SI
+                       case 120: // CIK
+                       case 130: // VI
+                               umr_write_reg_by_name(asic, 
"mmSMC_IND_INDEX_1", addr);
+                               return umr_write_reg_by_name(asic, 
"mmSMC_IND_DATA_1", value);
+                       case 135: // CZ
+                               umr_write_reg_by_name(asic, 
"mmMP0PUB_IND_INDEX_1", addr);
+                               return umr_write_reg_by_name(asic, 
"mmMP0PUB_IND_DATA_1", value);
+                       default:
+                               fprintf(stderr, "[BUG] Unsupported family type 
in umr_smc_read()\n");
+                               return -1;
+               }
        } else {
-               if (lseek(asic->fd.mmio, addr, SEEK_SET) < 0) {
+               if (lseek(asic->fd.smc, addr, SEEK_SET) < 0) {
                        perror("Cannot seek to MMIO address");
                        return -1;
                }
-               if (write(asic->fd.mmio, &value, 4) != 4) {
+               if (write(asic->fd.smc, &value, 4) != 4) {
                        perror("Cannot write to MMIO reg");
                        return -1;
                }
@@ -61,14 +80,79 @@ int umr_write_reg(struct umr_asic *asic, uint64_t addr, 
uint32_t value)
        return 0;
 }
 
+uint32_t umr_read_reg(struct umr_asic *asic, uint64_t addr, enum regclass type)
+{
+       uint32_t value=0;
+       if (addr == 0xFFFFFFFF)
+               fprintf(stderr, "[BUG]: reading from addr==0xFFFFFFFF is likely 
a bug\n");
+
+       switch (type) {
+               case REG_MMIO:
+                       if (asic->pci.mem && !(addr & ~0xFFFFFULL)) { // only 
use pci if enabled and not using high bits 
+                               return asic->pci.mem[addr/4];
+                       } else {
+                               if (lseek(asic->fd.mmio, addr, SEEK_SET) < 0)
+                                       perror("Cannot seek to MMIO address");
+                               if (read(asic->fd.mmio, &value, 4) != 4)
+                                       perror("Cannot read from MMIO reg");
+                               return value;
+                       }
+                       break;
+               case REG_SMC:
+                       return umr_smc_read(asic, addr);
+               default:
+                       fprintf(stderr, "[BUG] Unsupported register type in 
umr_read_reg().\n");
+                       return 0;
+       }
+}
+
+int umr_write_reg(struct umr_asic *asic, uint64_t addr, uint32_t value, enum 
regclass type)
+{
+       if (addr == 0xFFFFFFFF)
+               fprintf(stderr, "[BUG]: reading from addr==0xFFFFFFFF is likely 
a bug\n");
+
+       switch (type) {
+               case REG_MMIO:
+                       if (asic->pci.mem && !(addr & ~0xFFFFFULL)) {
+                               asic->pci.mem[addr/4] = value;
+                       } else {
+                               if (lseek(asic->fd.mmio, addr, SEEK_SET) < 0) {
+                                       perror("Cannot seek to MMIO address");
+                                       return -1;
+                               }
+                               if (write(asic->fd.mmio, &value, 4) != 4) {
+                                       perror("Cannot write to MMIO reg");
+                                       return -1;
+                               }
+                       }
+                       break;
+               case REG_SMC:
+                       return umr_smc_write(asic, addr, value);
+               default:
+                       fprintf(stderr, "[BUG] Unsupported register type in 
umr_write_reg().\n");
+                       return -1;
+       }
+       return 0;
+}
+
 uint32_t umr_read_reg_by_name(struct umr_asic *asic, char *name)
 {
-       return umr_read_reg(asic, umr_find_reg(asic, name) * 4);
+       struct umr_reg *reg;
+       reg = umr_find_reg_data(asic, name);
+       if (reg)
+               return umr_read_reg(asic, reg->addr * (reg->type == REG_MMIO ? 
4 : 1), reg->type);
+       else
+               return 0;
 }
 
 int umr_write_reg_by_name(struct umr_asic *asic, char *name, uint32_t value)
 {
-       return umr_write_reg(asic, umr_find_reg(asic, name) * 4, value);
+       struct umr_reg *reg;
+       reg = umr_find_reg_data(asic, name);
+       if (reg)
+               return umr_write_reg(asic, reg->addr * (reg->type == REG_MMIO ? 
4 : 1), value, reg->type);
+       else
+               return -1;
 }
 
 uint32_t umr_bitslice_reg(struct umr_asic *asic, struct umr_reg *reg, char 
*bitname, uint32_t regvalue)
@@ -141,7 +225,7 @@ int umr_grbm_select_index(struct umr_asic *asic, uint32_t 
se, uint32_t sh, uint3
                } else {
                        data |= umr_bitslice_compose_value(asic, grbm_idx, 
"SH_INDEX", instance);
                }
-               return umr_write_reg(asic, grbm_idx->addr * 4, data);
+               return umr_write_reg(asic, grbm_idx->addr * 4, data, REG_MMIO);
        } else {
                return -1;
        }
diff --git a/src/lib/read_sgpr.c b/src/lib/read_sgpr.c
index 858657cc83c4..cceb189c1854 100644
--- a/src/lib/read_sgpr.c
+++ b/src/lib/read_sgpr.c
@@ -41,9 +41,9 @@ static void wave_read_regs_via_mmio(struct umr_asic *asic, 
uint32_t simd,
                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);
+               umr_write_reg(asic, ind_index->addr * 4, data, REG_MMIO);
                while (num--)
-                       *(out++) = umr_read_reg(asic, ind_data->addr * 4);
+                       *(out++) = umr_read_reg(asic, ind_data->addr * 4, 
REG_MMIO);
        } else {
                fprintf(stderr, "[BUG]: The required SQ_IND_{INDEX,DATA} 
registers are not found on the asic <%s>\n", asic->asicname);
                return;
diff --git a/src/lib/read_vram.c b/src/lib/read_vram.c
index 502153dceaa5..3d458db8fa11 100644
--- a/src/lib/read_vram.c
+++ b/src/lib/read_vram.c
@@ -43,9 +43,9 @@ static void read_via_mmio(struct umr_asic *asic, uint64_t 
address, uint32_t size
        }
 
        while (size) {
-               umr_write_reg(asic, MM_INDEX, address | 0x80000000);
-               umr_write_reg(asic, MM_INDEX_HI, address >> 31);
-               *out++ = umr_read_reg(asic, MM_DATA);
+               umr_write_reg(asic, MM_INDEX, address | 0x80000000, REG_MMIO);
+               umr_write_reg(asic, MM_INDEX_HI, address >> 31, REG_MMIO);
+               *out++ = umr_read_reg(asic, MM_DATA, REG_MMIO);
                size -= 4;
                address += 4;
        }
diff --git a/src/lib/wave_status.c b/src/lib/wave_status.c
index 27bd6a4c86ed..6b8098e69a09 100644
--- a/src/lib/wave_status.c
+++ b/src/lib/wave_status.c
@@ -42,8 +42,8 @@ static int umr_get_wave_sq_info_vi(struct umr_asic *asic, 
unsigned se, unsigned
                return -1;
        }
 
-       umr_write_reg(asic, index|bank, 8 << 16);
-       value = umr_read_reg(asic, data|bank);
+       umr_write_reg(asic, index|bank, 8 << 16, REG_MMIO);
+       value = umr_read_reg(asic, data|bank, REG_MMIO);
        ws->sq_info.busy = value & 1;
        ws->sq_info.wave_level = (value >> 4) & 0x3F;
        return 0;
@@ -62,8 +62,8 @@ static uint32_t wave_read_ind(struct umr_asic *asic, uint32_t 
simd, uint32_t wav
                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);
+               umr_write_reg(asic, ind_index->addr * 4, data, REG_MMIO);
+               return umr_read_reg(asic, ind_data->addr * 4, REG_MMIO);
        } else {
                fprintf(stderr, "[BUG]: The required SQ_IND_{INDEX,DATA} 
registers are not found on the asic <%s>\n", asic->asicname);
                return -1;
diff --git a/src/umr.h b/src/umr.h
index ccfac5da6438..cc17e256a834 100644
--- a/src/umr.h
+++ b/src/umr.h
@@ -471,8 +471,8 @@ uint32_t umr_find_reg(struct umr_asic *asic, char *regname);
 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);
+uint32_t umr_read_reg(struct umr_asic *asic, uint64_t addr, enum regclass 
type);
+int umr_write_reg(struct umr_asic *asic, uint64_t addr, uint32_t value, enum 
regclass type);
 
 // read/write a register given a name
 uint32_t umr_read_reg_by_name(struct umr_asic *asic, char *name);
-- 
2.12.0

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to