From 184f4745741a8143238404a8168c36ae76156fc1 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 20 May 2021 17:12:35 -0700 Subject: [PATCH] freedreno/afuc: Clean up special regs Allow for different mnemonics depending on whether they are used as source or destination register, to better reflect what they do. Signed-off-by: Rob Clark Part-of: --- src/freedreno/.gitlab-ci/reference/afuc_test.asm | 28 +++++++-------- src/freedreno/.gitlab-ci/traces/afuc_test.asm | 30 ++++++++-------- src/freedreno/afuc/afuc.h | 29 ++++++++++++++++ src/freedreno/afuc/asm.h | 12 ++++--- src/freedreno/afuc/disasm.c | 44 ++++++++++++++---------- 5 files changed, 91 insertions(+), 52 deletions(-) diff --git a/src/freedreno/.gitlab-ci/reference/afuc_test.asm b/src/freedreno/.gitlab-ci/reference/afuc_test.asm index 90ad19f..7316504 100644 --- a/src/freedreno/.gitlab-ci/reference/afuc_test.asm +++ b/src/freedreno/.gitlab-ci/reference/afuc_test.asm @@ -53,24 +53,24 @@ fxn00: CP_REG_RMW: cwrite $data, [$00 + @REG_READ_ADDR], 0x0 - add $02, $addr2, 0x0042 - addhi $03, $00, $addr2 - sub $02, $02, $addr2 + add $02, $regdata, 0x0042 + addhi $03, $00, $regdata + sub $02, $02, $regdata call #fxn00 - subhi $03, $03, $addr2 - and $02, $02, $addr2 + subhi $03, $03, $regdata + and $02, $02, $regdata or $02, $02, 0x0001 xor $02, $02, 0x0001 not $02, $02 - shl $02, $02, $addr2 - ushr $02, $02, $addr2 - ishr $02, $02, $addr2 - rot $02, $02, $addr2 - min $02, $02, $addr2 - max $02, $02, $addr2 - mul8 $02, $02, $addr2 + shl $02, $02, $regdata + ushr $02, $02, $regdata + ishr $02, $02, $regdata + rot $02, $02, $regdata + min $02, $02, $regdata + max $02, $02, $regdata + mul8 $02, $02, $regdata msb $02, $02 - mov $addr2, $data + mov $usraddr, $data mov $data, $02 waitin mov $01, $data @@ -97,7 +97,7 @@ CP_MEM_TO_MEM: cwrite $data, [$00 + @LOAD_STORE_HI], 0x0 mov $rem, $data cwrite $rem, [$00 + @MEM_READ_DWORDS], 0x0 - (rep)store $addr, [$02 + 0x004], 0x4 + (rep)store $memdata, [$02 + 0x004], 0x4 waitin mov $01, $data diff --git a/src/freedreno/.gitlab-ci/traces/afuc_test.asm b/src/freedreno/.gitlab-ci/traces/afuc_test.asm index da66dff..57bec84 100644 --- a/src/freedreno/.gitlab-ci/traces/afuc_test.asm +++ b/src/freedreno/.gitlab-ci/traces/afuc_test.asm @@ -97,26 +97,26 @@ ret nop CP_REG_RMW: -; Test various ALU instructions, and read/write $addr2 +; Test various ALU instructions, and read/write $regdata cwrite $data, [$00 + @REG_READ_ADDR], 0x0 -add $02, $addr2, 0x42 -addhi $03, $00, $addr2 -sub $02, $02, $addr2 +add $02, $regdata, 0x42 +addhi $03, $00, $regdata +sub $02, $02, $regdata call #euclid -subhi $03, $03, $addr2 -and $02, $02, $addr2 +subhi $03, $03, $regdata +and $02, $02, $regdata or $02, $02, 0x1 xor $02, $02, 0x1 not $02, $02 -shl $02, $02, $addr2 -ushr $02, $02, $addr2 -ishr $02, $02, $addr2 -rot $02, $02, $addr2 -min $02, $02, $addr2 -max $02, $02, $addr2 -mul8 $02, $02, $addr2 +shl $02, $02, $regdata +ushr $02, $02, $regdata +ishr $02, $02, $regdata +rot $02, $02, $regdata +min $02, $02, $regdata +max $02, $02, $regdata +mul8 $02, $02, $regdata msb $02, $02 -mov $addr2, $data +mov $usraddr, $data mov $data, $02 waitin mov $01, $data @@ -148,7 +148,7 @@ mov $02, $data cwrite $data, [$00 + @LOAD_STORE_HI], 0x0 mov $rem, $data cwrite $rem, [$00 + @MEM_READ_DWORDS], 0x0 -(rep)store $addr, [$02 + 0x004], 0x4 +(rep)store $memdata, [$02 + 0x004], 0x4 waitin mov $01, $data diff --git a/src/freedreno/afuc/afuc.h b/src/freedreno/afuc/afuc.h index a423119..8ec8506 100644 --- a/src/freedreno/afuc/afuc.h +++ b/src/freedreno/afuc/afuc.h @@ -110,6 +110,35 @@ typedef enum { OPC_SETSECURE = 0x3b, /* switch secure mode on/off */ } afuc_opc; +/** + * Special GPR registers: + * + * Notes: (applicable to a6xx, double check a5xx) + * + * 0x1d: + * $addr: writes configure GPU reg address to read/write + * (does not respect CP_PROTECT) + * $memdata: reads from FIFO filled based on MEM_READ_DWORDS/ + * MEM_READ_ADDR + * 0x1e: (note different mnemonic for src vs dst) + * $usraddr: writes configure GPU reg address to read/write, + * respecting CP_PROTECT + * $regdata: reads from FIFO filled based on REG_READ_DWORDS/ + * REG_READ_ADDR + * 0x1f: + * $data: reads from from pm4 input stream + * $data: writes to stream configured by write to $addr + * or $usraddr + */ +typedef enum { + REG_REM = 0x1c, + REG_MEMDATA = 0x1d, /* when used as src */ + REG_ADDR = 0x1d, /* when used as dst */ + REG_REGDATA = 0x1e, /* when used as src */ + REG_USRADDR = 0x1e, /* when used as dst */ + REG_DATA = 0x1f, +} afuc_reg; + typedef union PACKED { /* addi, subi, andi, ori, xori, etc: */ struct PACKED { diff --git a/src/freedreno/afuc/asm.h b/src/freedreno/afuc/asm.h index 3f5931f..da75c31 100644 --- a/src/freedreno/afuc/asm.h +++ b/src/freedreno/afuc/asm.h @@ -70,11 +70,15 @@ parse_reg(const char *str) long int ret; if (!strcmp(str, "$rem")) - return 0x1c; + return REG_REM; + else if (!strcmp(str, "$memdata")) + return REG_MEMDATA; else if (!strcmp(str, "$addr")) - return 0x1d; - else if (!strcmp(str, "$addr2")) - return 0x1e; + return REG_ADDR; + else if (!strcmp(str, "$regdata")) + return REG_REGDATA; + else if (!strcmp(str, "$usraddr")) + return REG_USRADDR; else if (!strcmp(str, "$data")) return 0x1f; diff --git a/src/freedreno/afuc/disasm.c b/src/freedreno/afuc/disasm.c index cd5de77..6dfccb2 100644 --- a/src/freedreno/afuc/disasm.c +++ b/src/freedreno/afuc/disasm.c @@ -65,34 +65,33 @@ print_gpu_reg(uint32_t regbase) #define printlbl(fmt, ...) afuc_printc(AFUC_LBL, fmt, ##__VA_ARGS__) static void -print_reg(unsigned reg) +print_src(unsigned reg) { - // XXX seems like *reading* $00 --> literal zero?? - // seems like read from $1c gives packet remaining len?? - // $01 current packet header, writing to $01 triggers - // parsing header and jumping to appropriate handler. - if (reg == 0x1c) + if (reg == REG_REM) printf("$rem"); /* remainding dwords in packet */ - else if (reg == 0x1d) - printf("$addr"); - else if (reg == 0x1e) - printf("$addr2"); // XXX - else if (reg == 0x1f) + else if (reg == REG_MEMDATA) + printf("$memdata"); + else if (reg == REG_REGDATA) + printf("$regdata"); + else if (reg == REG_DATA) printf("$data"); else printf("$%02x", reg); } static void -print_src(unsigned reg) -{ - print_reg(reg); -} - -static void print_dst(unsigned reg) { - print_reg(reg); + if (reg == REG_REM) + printf("$rem"); /* remainding dwords in packet */ + else if (reg == REG_ADDR) + printf("$addr"); + else if (reg == REG_USRADDR) + printf("$usraddr"); + else if (reg == REG_DATA) + printf("$data"); + else + printf("$%02x", reg); } static void @@ -518,12 +517,14 @@ disasm_instr(uint32_t *instrs, unsigned pc) printf("(rep)"); bool is_control_reg = true; + bool is_store = true; if (gpuver >= 6) { switch (opc) { case OPC_CWRITE6: printf("cwrite "); break; case OPC_CREAD6: + is_store = false; printf("cread "); break; case OPC_STORE6: @@ -532,6 +533,7 @@ disasm_instr(uint32_t *instrs, unsigned pc) break; case OPC_LOAD6: is_control_reg = false; + is_store = false; printf("load "); break; default: @@ -543,6 +545,7 @@ disasm_instr(uint32_t *instrs, unsigned pc) printf("cwrite "); break; case OPC_CREAD5: + is_store = false; printf("cread "); break; default: @@ -551,7 +554,10 @@ disasm_instr(uint32_t *instrs, unsigned pc) } } - print_src(instr->control.src1); + if (is_store) + print_src(instr->control.src1); + else + print_dst(instr->control.src1); printf(", ["); print_src(instr->control.src2); printf(" + "); -- 2.7.4