freedreno/afuc: Initial a7xx support

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23949>
This commit is contained in:
Connor Abbott 2023-06-27 17:24:35 +02:00 committed by Marge Bot
parent 6fd0007447
commit e690d88d69
11 changed files with 437 additions and 39 deletions

View file

@ -60,9 +60,13 @@ typedef enum {
ALU(MIN)
ALU(MAX)
ALU(CMP) /* compare src to immed */
ALU(BIC) /* AND with second source negated */
OPC_SETBIT, /* Set or clear a bit dynamically */
OPC_MOVI, /* move immediate */
OPC_SETBIT, /* Set a bit */
OPC_SETBITI, /* Set a bit */
OPC_CLRBIT, /* Clear a bit */
OPC_UBFX, /* Unsigned BitField eXtract */
OPC_BFI, /* BitField Insert */
#undef ALU
/* Return the most-significant bit of src2, or 0 if src2 == 0 (the

View file

@ -184,6 +184,17 @@ SOFTWARE.
<field name="SRC1" low="21" high="25" type="#src"/>
</bitset>
<bitset name="#alu-2src-immed12" extends="#instruction-rep">
<display>
{REP}{NAME} {DST}, {SRC1}, 0x{RIMMED}
</display>
<field name="RIMMED" low="0" high="11" type="hex"/>
<field name="DST" low="16" high="20" type="#dst"/>
<field name="SRC1" low="21" high="25" type="#src"/>
<pattern low="27" high="31">10010</pattern>
</bitset>
<bitset name="#alu-1src-immed" extends="#instruction-rep">
<display>
{REP}{NAME} {DST}, 0x{IMMED}
@ -270,67 +281,151 @@ SOFTWARE.
</bitset>
<bitset name="shl" extends="#alu-2src">
<gen max="6"/>
<pattern low="0" high="4">01001</pattern>
</bitset>
<bitset name="shli" displayname="shl" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">01001</pattern>
</bitset>
<bitset name="shl" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">10010</pattern>
</bitset>
<bitset name="shli" displayname="shl" extends="#alu-2src-immed12">
<gen min="7"/>
<pattern low="12" high="15">0010</pattern>
</bitset>
<bitset name="ushr" extends="#alu-2src">
<doc>0-extending right shift</doc>
<gen max="6"/>
<pattern low="0" high="4">01010</pattern>
</bitset>
<bitset name="ushri" displayname="ushr" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">01010</pattern>
</bitset>
<bitset name="ushr" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">10011</pattern>
</bitset>
<bitset name="ushri" displayname="ushr" extends="#alu-2src-immed12">
<gen min="7"/>
<pattern low="12" high="15">0011</pattern>
</bitset>
<bitset name="ishr" extends="#alu-2src">
<doc>sign-extending right shift</doc>
<gen max="6"/>
<pattern low="0" high="4">01011</pattern>
</bitset>
<bitset name="ishri" displayname="ishr" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">01011</pattern>
</bitset>
<bitset name="ishr" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">10100</pattern>
</bitset>
<bitset name="ishri" displayname="ishr" extends="#alu-2src-immed12">
<gen min="7"/>
<pattern low="12" high="15">0100</pattern>
</bitset>
<bitset name="rot" extends="#alu-2src">
<doc>Rotate left (left shift with wraparound)</doc>
<gen max="6"/>
<pattern low="0" high="4">01100</pattern>
</bitset>
<bitset name="roti" displayname="rot" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">01100</pattern>
</bitset>
<bitset name="rot" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">10101</pattern>
</bitset>
<bitset name="roti" displayname="rot" extends="#alu-2src-immed12">
<gen min="7"/>
<pattern low="12" high="15">0101</pattern>
</bitset>
<bitset name="mul8" extends="#alu-2src">
<doc>Multiply low 8 bits of each source to produce a 16-bit result</doc>
<gen max="6"/>
<pattern low="0" high="4">01101</pattern>
</bitset>
<bitset name="mul8i" displayname="mul8" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">01101</pattern>
</bitset>
<bitset name="mul8" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">01100</pattern>
</bitset>
<bitset name="mul8i" displayname="mul8" extends="#alu-2src-immed">
<gen min="7"/>
<pattern low="27" high="31">01100</pattern>
</bitset>
<bitset name="min" extends="#alu-2src">
<doc>Unsigned minimum</doc>
<gen max="6"/>
<pattern low="0" high="4">01110</pattern>
</bitset>
<bitset name="mini" displayname="min" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">01110</pattern>
</bitset>
<bitset name="min" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">01010</pattern>
</bitset>
<bitset name="mini" displayname="min" extends="#alu-2src-immed">
<gen min="7"/>
<pattern low="27" high="31">01010</pattern>
</bitset>
<bitset name="max" extends="#alu-2src">
<doc>Unsigned maximum</doc>
<gen max="6"/>
<pattern low="0" high="4">01111</pattern>
</bitset>
<bitset name="maxi" displayname="max" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">01111</pattern>
</bitset>
<bitset name="max" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">01011</pattern>
</bitset>
<bitset name="maxi" displayname="max" extends="#alu-2src-immed">
<gen min="7"/>
<pattern low="27" high="31">01011</pattern>
</bitset>
<bitset name="cmp" extends="#alu-2src">
<doc>
Compare two sources and produce a bitfield:
@ -340,19 +435,47 @@ SOFTWARE.
Often a "branch on bit set/unset" instruction is used on the
result to implement a compare-and-branch macro.
</doc>
<gen max="6"/>
<pattern low="0" high="4">10000</pattern>
</bitset>
<bitset name="cmpi" displayname="cmp" extends="#alu-2src-immed">
<gen max="6"/>
<pattern low="27" high="31">10000</pattern>
</bitset>
<bitset name="cmp" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">01101</pattern>
</bitset>
<bitset name="cmpi" displayname="cmp" extends="#alu-2src-immed">
<gen min="7"/>
<pattern low="27" high="31">01101</pattern>
</bitset>
<bitset name="bic" extends="#alu-2src">
<gen min="7"/>
<pattern low="0" high="4">01001</pattern>
</bitset>
<bitset name="bici" displayname="bic" extends="#alu-2src-immed">
<gen min="7"/>
<pattern low="27" high="31">01001</pattern>
</bitset>
<bitset name="msb" extends="#alu-1src">
<doc>Return the most-significant bit of src2, or 0 if src2 == 0</doc>
<gen max="6"/>
<pattern low="0" high="4">10100</pattern>
</bitset>
<bitset name="#setclrbit" extends="#instruction-rep">
<bitset name="msb" extends="#alu-1src">
<gen min="7"/>
<pattern low="0" high="4">11001</pattern>
</bitset>
<bitset name="#setclrbit6" extends="#instruction-rep">
<display>
{REP}{NAME} {DST}, {SRC}, b{BIT}
</display>
@ -368,17 +491,87 @@ SOFTWARE.
</encode>
</bitset>
<bitset name="setbit" extends="#setclrbit">
<bitset name="#setclrbit7" extends="#instruction-rep">
<display>
{REP}{NAME} {DST}, {SRC}, b{BIT}
</display>
<field name="BIT" low="1" high="5" type="uint"/>
<pattern low="6" high="11">xxxxxx</pattern>
<pattern low="12" high="15">0110</pattern>
<field name="DST" low="16" high="20" type="#dst"/>
<field name="SRC" low="21" high="25" type="#src"/>
<pattern low="27" high="31">10010</pattern>
<encode>
<map name="SRC">src->src1</map>
</encode>
</bitset>
<bitset name="setbiti" displayname="setbit" extends="#setclrbit6">
<doc>Set a given bit to 1</doc>
<gen max="6"/>
<pattern pos="0">1</pattern>
</bitset>
<bitset name="clrbit" extends="#setclrbit">
<bitset name="clrbit" extends="#setclrbit6">
<doc>Clear a given bit, i.e. set it to 0</doc>
<gen max="6"/>
<pattern pos="0">0</pattern>
</bitset>
<bitset name="movi" extends="#instruction-rep">
<bitset name="setbiti" displayname="setbit" extends="#setclrbit7">
<gen min="7"/>
<pattern pos="0">1</pattern>
</bitset>
<bitset name="clrbit" extends="#setclrbit7">
<gen min="7"/>
<pattern pos="0">0</pattern>
</bitset>
<bitset name="setbit" extends="#alu-2src">
<doc>
Set or clear a given bit. This is the non-immediate form of
setbit/clrbit. Bits 1-5 of src2 are the bit to set, bit 0 is the
value to set it to.
</doc>
<gen min="7"/>
<pattern low="0" high="4">10110</pattern>
</bitset>
<bitset name="#bitfield-immed" extends="#instruction-rep">
<display>
{REP}{NAME} {DST}, {SRC}, b{LO}, b{HI}
</display>
<field name="LO" low="0" high="4" type="uint"/>
<field name="HI" low="5" high="9" type="uint"/>
<pattern low="10" high="11">xx</pattern>
<field name="DST" low="16" high="20" type="#dst"/>
<field name="SRC" low="21" high="25" type="#src"/>
<pattern low="27" high="31">10010</pattern>
<encode>
<map name="LO">src->bit</map>
<map name="HI">src->immed</map>
<map name="SRC">src->src1</map>
</encode>
</bitset>
<bitset name="ubfx" extends="#bitfield-immed">
<doc>Unsigned BitField eXtract</doc>
<gen min="7"/>
<pattern low="12" high="15">0111</pattern>
</bitset>
<bitset name="bfi" extends="#bitfield-immed">
<doc>BitField Insert</doc>
<gen min="7"/>
<pattern low="12" high="15">1000</pattern>
</bitset>
<bitset name="#movi" extends="#instruction-rep">
<doc>Special move-immediate instruction with a shift</doc>
<override>
<expr>{SHIFT} == 0</expr>
@ -393,13 +586,22 @@ SOFTWARE.
<field name="RIMMED" low="0" high="15" type="hex"/>
<field name="DST" low="16" high="20" type="#dst"/>
<field name="SHIFT" low="21" high="25" type="uint"/>
<pattern low="27" high="31">10001</pattern>
<encode>
<map name="SHIFT">src->shift</map>
</encode>
</bitset>
<bitset name="movi" extends="#movi">
<gen max="6"/>
<pattern low="27" high="31">10001</pattern>
</bitset>
<bitset name="movi" extends="#movi">
<gen min="7"/>
<pattern low="27" high="31">01110</pattern>
</bitset>
<bitset name="#control" extends="#instruction-rep">
<field name="FLAGS" low="12" high="15" type="hex"/>
<field name="OFFSET" low="21" high="25" type="#src"/>

View file

@ -225,12 +225,15 @@ static void
disasm(struct emu *emu)
{
uint32_t sizedwords = emu->sizedwords;
uint32_t lpac_offset = 0;
uint32_t lpac_offset = 0, bv_offset = 0;
EMU_GPU_REG(CP_SQE_INSTR_BASE);
EMU_GPU_REG(CP_LPAC_SQE_INSTR_BASE);
EMU_CONTROL_REG(BV_INSTR_BASE);
EMU_CONTROL_REG(LPAC_INSTR_BASE);
emu_init(emu);
emu->processor = EMU_PROC_SQE;
struct isa_decode_options options;
struct decode_state state;
@ -246,12 +249,22 @@ disasm(struct emu *emu)
emu_run_bootstrap(emu);
/* Figure out if we have LPAC SQE appended: */
if (emu_get_reg64(emu, &CP_LPAC_SQE_INSTR_BASE)) {
lpac_offset = emu_get_reg64(emu, &CP_LPAC_SQE_INSTR_BASE) -
emu_get_reg64(emu, &CP_SQE_INSTR_BASE);
/* Figure out if we have BV/LPAC SQE appended: */
if (gpuver >= 7) {
bv_offset = emu_get_reg64(emu, &BV_INSTR_BASE) -
emu_get_reg64(emu, &CP_SQE_INSTR_BASE);
bv_offset /= 4;
lpac_offset = emu_get_reg64(emu, &LPAC_INSTR_BASE) -
emu_get_reg64(emu, &CP_SQE_INSTR_BASE);
lpac_offset /= 4;
sizedwords = lpac_offset;
sizedwords = MIN2(bv_offset, lpac_offset);
} else {
if (emu_get_reg64(emu, &CP_LPAC_SQE_INSTR_BASE)) {
lpac_offset = emu_get_reg64(emu, &CP_LPAC_SQE_INSTR_BASE) -
emu_get_reg64(emu, &CP_SQE_INSTR_BASE);
lpac_offset /= 4;
sizedwords = lpac_offset;
}
}
setup_packet_table(&options, emu->jmptbl, ARRAY_SIZE(emu->jmptbl));
@ -271,25 +284,51 @@ disasm(struct emu *emu)
/* print instructions: */
isa_disasm(emu->instrs, sizedwords * 4, stdout, &options);
if (!lpac_offset)
return;
if (bv_offset) {
printf(";\n");
printf("; BV microcode:\n");
printf(";\n");
printf(";\n");
printf("; LPAC microcode:\n");
printf(";\n");
emu_fini(emu);
emu_fini(emu);
emu->processor = EMU_PROC_BV;
emu->instrs += bv_offset;
emu->sizedwords -= bv_offset;
emu->lpac = true;
emu->instrs += lpac_offset;
emu->sizedwords -= lpac_offset;
emu_init(emu);
emu_run_bootstrap(emu);
emu_init(emu);
emu_run_bootstrap(emu);
setup_packet_table(&options, emu->jmptbl, ARRAY_SIZE(emu->jmptbl));
setup_packet_table(&options, emu->jmptbl, ARRAY_SIZE(emu->jmptbl));
uint32_t sizedwords = lpac_offset - bv_offset;
isa_disasm(emu->instrs, emu->sizedwords * 4, stdout, &options);
isa_disasm(emu->instrs, sizedwords * 4, stdout, &options);
emu->instrs -= bv_offset;
emu->sizedwords += bv_offset;
}
if (lpac_offset) {
printf(";\n");
printf("; LPAC microcode:\n");
printf(";\n");
emu_fini(emu);
emu->processor = EMU_PROC_LPAC;
emu->instrs += lpac_offset;
emu->sizedwords -= lpac_offset;
emu_init(emu);
emu_run_bootstrap(emu);
setup_packet_table(&options, emu->jmptbl, ARRAY_SIZE(emu->jmptbl));
isa_disasm(emu->instrs, emu->sizedwords * 4, stdout, &options);
emu->instrs -= lpac_offset;
emu->sizedwords += lpac_offset;
}
}
static void

View file

@ -62,6 +62,9 @@ emu_set_control_reg(struct emu *emu, unsigned n, uint32_t val)
EMU_CONTROL_REG(PACKET_TABLE_WRITE_ADDR);
EMU_CONTROL_REG(REG_WRITE);
EMU_CONTROL_REG(REG_WRITE_ADDR);
EMU_CONTROL_REG(BV_CNTL);
EMU_CONTROL_REG(LPAC_CNTL);
EMU_CONTROL_REG(THREAD_SYNC);
assert(n < ARRAY_SIZE(emu->control_regs.val));
BITSET_SET(emu->control_regs.written, n);
@ -86,6 +89,18 @@ emu_set_control_reg(struct emu *emu, unsigned n, uint32_t val)
emu_set_gpu_reg(emu, write_addr++, val);
emu_set_reg32(emu, &REG_WRITE_ADDR, write_addr | (flags << 16));
} else if (gpuver >= 7 && n == emu_reg_offset(&BV_CNTL)) {
/* This is sort-of a hack, but emulate what the BV bootstrap routine
* does so that the main bootstrap routine doesn't get stuck.
*/
emu_set_reg32(emu, &THREAD_SYNC,
emu_get_reg32(emu, &THREAD_SYNC) & ~(1u << 1));
} else if (gpuver >= 7 && n == emu_reg_offset(&LPAC_CNTL)) {
/* This is sort-of a hack, but emulate what the LPAC bootstrap routine
* does so that the main bootstrap routine doesn't get stuck.
*/
emu_set_reg32(emu, &THREAD_SYNC,
emu_get_reg32(emu, &THREAD_SYNC) & ~(1u << 2));
} else if (is_draw_state_control_reg(n)) {
emu_set_draw_state_reg(emu, n, val);
}

View file

@ -39,8 +39,6 @@
#include "emu.h"
#include "util.h"
extern int gpuver;
#define rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
#define rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
@ -99,10 +97,17 @@ emu_alu(struct emu *emu, afuc_opc opc, uint32_t src1, uint32_t src2)
else if (src1 == src2)
return 0x2b;
return 0x1e;
case OPC_BIC:
return src1 & ~src2;
case OPC_MSB:
if (!src2)
return 0;
return util_last_bit(src2) - 1;
case OPC_SETBIT: {
unsigned bit = src2 >> 1;
unsigned val = src2 & 1;
return (src1 & ~(1u << bit)) | (val << bit);
}
default:
printf("unhandled alu opc: 0x%02x\n", opc);
exit(1);
@ -132,7 +137,7 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
case OPC_NOP:
break;
case OPC_MSB:
case OPC_ADD ... OPC_CMP: {
case OPC_ADD ... OPC_BIC: {
uint32_t val = emu_alu(emu, instr->opc,
emu_get_gpr_reg(emu, instr->src1),
instr->has_immed ? instr->immed :
@ -180,7 +185,7 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
emu_set_gpr_reg(emu, instr->dst, val);
break;
}
case OPC_SETBIT: {
case OPC_SETBITI: {
uint32_t src = emu_get_gpr_reg(emu, instr->src1);
emu_set_gpr_reg(emu, instr->dst, src | (1u << instr->bit));
break;
@ -190,6 +195,20 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
emu_set_gpr_reg(emu, instr->dst, src & ~(1u << instr->bit));
break;
}
case OPC_UBFX: {
uint32_t src = emu_get_gpr_reg(emu, instr->src1);
unsigned lo = instr->bit, hi = instr->immed;
uint32_t dst = (src >> lo) & BITFIELD_MASK(hi - lo + 1);
emu_set_gpr_reg(emu, instr->dst, dst);
break;
}
case OPC_BFI: {
uint32_t src = emu_get_gpr_reg(emu, instr->src1);
unsigned lo = instr->bit, hi = instr->immed;
src = (src & BITFIELD_MASK(hi - lo + 1)) << lo;
emu_set_gpr_reg(emu, instr->dst, emu_get_gpr_reg(emu, instr->dst) | src);
break;
}
case OPC_CWRITE: {
uint32_t src1 = emu_get_gpr_reg(emu, instr->src1);
uint32_t src2 = emu_get_gpr_reg(emu, instr->src2);
@ -473,15 +492,29 @@ emu_init(struct emu *emu)
EMU_GPU_REG(CP_SQE_INSTR_BASE);
EMU_GPU_REG(CP_LPAC_SQE_INSTR_BASE);
EMU_CONTROL_REG(BV_INSTR_BASE);
EMU_CONTROL_REG(LPAC_INSTR_BASE);
/* Setup the address of the SQE fw, just use the normal CPU ptr address: */
if (emu->lpac) {
emu_set_reg64(emu, &CP_LPAC_SQE_INSTR_BASE, EMU_INSTR_BASE);
} else {
switch (emu->processor) {
case EMU_PROC_SQE:
emu_set_reg64(emu, &CP_SQE_INSTR_BASE, EMU_INSTR_BASE);
break;
case EMU_PROC_BV:
emu_set_reg64(emu, &BV_INSTR_BASE, EMU_INSTR_BASE);
break;
case EMU_PROC_LPAC:
if (gpuver >= 7)
emu_set_reg64(emu, &LPAC_INSTR_BASE, EMU_INSTR_BASE);
else
emu_set_reg64(emu, &CP_LPAC_SQE_INSTR_BASE, EMU_INSTR_BASE);
break;
}
if (emu->gpu_id == 660) {
if (emu->gpu_id == 730) {
emu_set_control_reg(emu, 0xef, 1 << 21);
emu_set_control_reg(emu, 0, 7 << 28);
} else if (emu->gpu_id == 660) {
emu_set_control_reg(emu, 0, 3 << 28);
} else if (emu->gpu_id == 650) {
emu_set_control_reg(emu, 0, 1 << 28);

View file

@ -31,6 +31,8 @@
#include "afuc.h"
extern int gpuver;
#define EMU_NUM_GPR_REGS 32
struct emu_gpr_regs {
@ -153,7 +155,11 @@ struct emu {
*/
bool quiet;
bool lpac;
enum {
EMU_PROC_SQE,
EMU_PROC_BV,
EMU_PROC_LPAC,
} processor;
uint32_t *instrs;
unsigned sizedwords;

View file

@ -69,9 +69,12 @@ extern YYSTYPE yylval;
"min" return TOKEN(T_OP_MIN);
"max" return TOKEN(T_OP_MAX);
"cmp" return TOKEN(T_OP_CMP);
"bic" return TOKEN(T_OP_BIC);
"msb" return TOKEN(T_OP_MSB);
"setbit" return TOKEN(T_OP_SETBIT);
"clrbit" return TOKEN(T_OP_CLRBIT);
"ubfx" return TOKEN(T_OP_UBFX);
"bfi" return TOKEN(T_OP_BFI);
"mov" return TOKEN(T_OP_MOV);
"cwrite" return TOKEN(T_OP_CWRITE);
"cread" return TOKEN(T_OP_CREAD);

View file

@ -144,9 +144,12 @@ label(const char *str)
%token <tok> T_OP_MIN
%token <tok> T_OP_MAX
%token <tok> T_OP_CMP
%token <tok> T_OP_BIC
%token <tok> T_OP_MSB
%token <tok> T_OP_SETBIT
%token <tok> T_OP_CLRBIT
%token <tok> T_OP_BFI
%token <tok> T_OP_UBFX
%token <tok> T_OP_MOV
%token <tok> T_OP_CWRITE
%token <tok> T_OP_CREAD
@ -226,20 +229,28 @@ alu_2src_op: T_OP_ADD { new_instr(OPC_ADD); }
| T_OP_MIN { new_instr(OPC_MIN); }
| T_OP_MAX { new_instr(OPC_MAX); }
| T_OP_CMP { new_instr(OPC_CMP); }
| T_OP_BIC { new_instr(OPC_BIC); }
alu_2src_instr: alu_2src_op reg ',' reg ',' reg { dst($2); src1($4); src2($6); }
| alu_2src_op reg ',' reg ',' immediate { dst($2); src1($4); immed($6); }
alu_clrsetbit_op: T_OP_SETBIT { new_instr(OPC_SETBIT); }
| T_OP_CLRBIT { new_instr(OPC_CLRBIT); }
alu_setbit_src2: T_BIT { bit($1); instr->opc = OPC_SETBITI; }
| reg { src2($1); }
alu_clrsetbit_instr: alu_clrsetbit_op reg ',' reg ',' T_BIT { dst($2); src1($4); bit($6); }
alu_clrsetbit_instr: T_OP_SETBIT reg ',' reg ',' alu_setbit_src2 { new_instr(OPC_SETBIT); dst($2); src1($4); }
| T_OP_CLRBIT reg ',' reg ',' T_BIT { new_instr(OPC_CLRBIT); dst($2); src1($4); bit($6); }
alu_bitfield_op: T_OP_UBFX { new_instr(OPC_UBFX); }
| T_OP_BFI { new_instr(OPC_BFI); }
alu_bitfield_instr: alu_bitfield_op reg ',' reg ',' T_BIT ',' T_BIT { dst($2); src1($4); bit($6); immed($8); }
alu_instr: alu_2src_instr
| alu_msb_instr
| alu_not_instr
| alu_mov_instr
| alu_clrsetbit_instr
| alu_bitfield_instr
load_op: T_OP_LOAD { new_instr(OPC_LOAD); }
| T_OP_CREAD { new_instr(OPC_CREAD); }

View file

@ -252,17 +252,25 @@ afuc_printc(enum afuc_color c, const char *fmt, ...)
int afuc_util_init(int gpuver, bool colors)
{
char *name, *control_reg_name;
char *name, *control_reg_name, *variant;
char *pipe_reg_name = NULL;
switch (gpuver) {
case 7:
name = "A6XX";
variant = "A7XX";
control_reg_name = "A7XX_CONTROL_REG";
pipe_reg_name = "A7XX_PIPE_REG";
break;
case 6:
name = "A6XX";
variant = "A6XX";
control_reg_name = "A6XX_CONTROL_REG";
pipe_reg_name = "A6XX_PIPE_REG";
break;
case 5:
name = "A5XX";
variant = "A5XX";
control_reg_name = "A5XX_CONTROL_REG";
pipe_reg_name = "A5XX_PIPE_REG";
break;
@ -286,7 +294,7 @@ int afuc_util_init(int gpuver, bool colors)
control_regs = rnn_finddomain(db, control_reg_name);
pipe_regs = rnn_finddomain(db, pipe_reg_name);
rnndec_varadd(ctx, "chip", name);
rnndec_varadd(ctx, "chip", variant);
pm4_packets = rnn_findenum(ctx->db, "adreno_pm4_type3_packets");

View file

@ -239,6 +239,15 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
</domain>
<domain name="A7XX_CONTROL_REG" width="32">
<reg32 name="RB_RPTR" offset="0x001"/>
<reg32 name="PREEMPT_INSTR" offset="0x004"/>
<reg64 name="IB1_BASE" offset="0x010"/>
<reg32 name="IB1_DWORDS" offset="0x012"/>
<reg64 name="IB2_BASE" offset="0x014"/>
<reg32 name="IB2_DWORDS" offset="0x016"/>
<reg64 name="IB3_BASE" offset="0x018"/>
<reg32 name="IB3_DWORDS" offset="0x01a"/>
<reg64 name="MEM_READ_ADDR" offset="0x01c"/>
<reg32 name="MEM_READ_DWORDS" offset="0x01e"/>
@ -250,10 +259,46 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
<reg32 name="REG_READ_DWORDS" offset="0x038"/>
<reg32 name="REG_READ_ADDR" offset="0x039"/>
<doc> Controls whether RB, IB1, IB2, IB3, or SDS is executed </doc>
<reg32 name="IB_LEVEL" offset="0x054"/>
<doc> Controls high 32 bits used by load and store afuc instructions </doc>
<reg32 name="LOAD_STORE_HI" offset="0x058"/>
<doc> Used to initialize the jump table for handling packets at bootup </doc>
<reg32 name="PACKET_TABLE_WRITE_ADDR" offset="0x060"/>
<reg32 name="PACKET_TABLE_WRITE" offset="0x061"/>
<reg64 name="BV_INSTR_BASE" offset="0x0d6"/>
<reg32 name="BV_CNTL" offset="0x0d8"/>
<reg64 name="LPAC_INSTR_BASE" offset="0x0d9"/>
<reg32 name="LPAC_CNTL" offset="0x0db"/>
<reg32 name="GLOBAL_TIMESTAMP" offset="0x0e2"/>
<reg32 name="LOCAL_TIMESTAMP" offset="0x0e3"/>
<reg32 name="PREEMPT_ENABLE" offset="0x071"/>
<doc>
Register used to create critical sections when reading/writing
shared memory (0x200-0x2ff). Each bit contains a lock. Writing 1
to the bit initiates a lock, reads return 1 once the lock is
taken. Writing 0 unlocks.
</doc>
<reg32 name="COPROCESSOR_LOCK" offset="0x0b1"/>
<!-- 0x100-0x1ff - thread-private scratch space as before -->
<!-- 0x200-0x2ff - global register space for cross-thread communication -->
<doc>
The low 3 bits are used as a semaphore to let SQE wait for other
coprocessors to start. SQE sets it to 0x7 before starting the
coprocessors, then each coprocessor atomically clears a bit.
Other bits are used for CP_THREAD_CONTROL::SYNC_THREADS and
other internal syncing.
</doc>
<reg32 name="THREAD_SYNC" offset="0x23f"/>
</domain>
</database>

View file

@ -36,6 +36,9 @@ CP_WAIT_MEM_WRITES:
</domain>
<domain name="A6XX_PIPE_REG" width="32">
<!-- This replaces RBBM_WAIT_FOR_GPU_IDLE_CMD starting with a650_sqe.fw -->
<reg32 name="WAIT_FOR_IDLE" offset="0x80" type="void"/>
<!-- This replaces CP_WFI_PEND_CTR on a3xx-a5xx -->
<reg32 name="WFI_PEND_DECR" offset="0x81" type="void"/>
<!-- This is only used for WRITE_PRIMITIVE_COUNTS/ZPASS_DONE events -->
@ -78,6 +81,35 @@ CP_WAIT_MEM_WRITES:
</domain>
<domain name="A7XX_PIPE_REG" width="32">
<reg32 name="WFI_PEND_DECR" offset="0x81" type="void"/>
<reg32 name="WAIT_MEM_WRITES" offset="0x84" type="void"/>
<reg32 name="WAIT_FOR_IDLE" offset="0x87" type="void"/>
<reg64 name="NRT_ADDR" offset="0xa0"/>
<reg32 name="NRT_DATA" offset="0xa2"/>
<reg64 name="EVENT_TS_ADDR" offset="0xe8"/>
<reg32 name="EVENT_TS_CTRL" offset="0xea">
<enum name="a7xx_ts_memspace">
<value value="0" name="NO_MEMORY"/>
<value value="1" name="EXTERNAL_MEMORY"/>
<value value="2" name="ON_CHIP_MEMORY"/>
</enum>
<bitfield name="MEMSPACE" low="0" high="1" type="a7xx_ts_memspace"/>
<enum name="a7xx_ts_value">
<value value="0" name="NO_VALUE"/>
<value value="1" name="VALUE_DATA_32B"/> <!-- write low 32b of EVENT_TS_DATA -->
<value value="2" name="VALUE_DATA_64B"/> <!-- write all 64b of EVENT_TS_DATA -->
<value value="3" name="ALWAYS_ON"/> <!-- write CP_ALWAYS_ON_COUNTER -->
<value value="4" name="REGISTER"/> <!-- interpret EVENT_TS_DATA as a register offset/count -->
</enum>
<bitfield name="VALUE" low="3" high="5" type="a7xx_ts_value"/>
<bitfield name="INTERRUPT" pos="6" type="boolean"/>
<!-- which interrupt bit to trigger -->
<bitfield name="IRQNO" low="7" high="11"/>
</reg32>
<reg64 name="EVENT_TS_DATA" offset="0xeb"/>
</domain>
</database>