mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-05 22:00:11 +01:00
freedreno/afuc: Initial a7xx support
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23949>
This commit is contained in:
parent
6fd0007447
commit
e690d88d69
11 changed files with 437 additions and 39 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, ®_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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue