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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10944>
This commit is contained in:
Rob Clark 2021-05-20 17:12:35 -07:00 committed by Marge Bot
parent 2876253f28
commit 184f474574
5 changed files with 91 additions and 52 deletions

View File

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

View File

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

View File

@ -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 {

View File

@ -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;

View File

@ -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(" + ");