diff --git a/src/freedreno/.gitlab-ci/reference/afuc_test.asm b/src/freedreno/.gitlab-ci/reference/afuc_test.asm
index 6d39634487a..bd3ac583838 100644
--- a/src/freedreno/.gitlab-ci/reference/afuc_test.asm
+++ b/src/freedreno/.gitlab-ci/reference/afuc_test.asm
@@ -2,7 +2,7 @@
; Version: 01000001
[01000001]
-[01000078]
+[0100007e]
mov $01, 0x830 ; CP_SQE_INSTR_BASE
mov $02, 0x2
cwrite $01, [$00 + @REG_READ_ADDR], 0x0
@@ -56,27 +56,35 @@ mov $02, 0xff
waitin
mov $01, $data
-CP_SET_SECURE_MODE:
-mov $02, $data
-setsecure $02, #l52
-l50:
-jump #l50
-nop
-l52:
+CP_SET_BIN_DATA5:
+sread $02, [$00 + %SP], 0x0
+swrite $02, [$00 + %SP], 0x0
+mov $02, 0x7
+(rep)swrite $data, [$02 + 0x001], 0x4
waitin
mov $01, $data
-fxn54:
-l54:
+CP_SET_SECURE_MODE:
+mov $02, $data
+setsecure $02, #l58
+l56:
+jump #l56
+nop
+l58:
+waitin
+mov $01, $data
+
+fxn60:
+l60:
cmp $04, $02, $03
-breq $04, b0, #l61
-brne $04, b1, #l59
-breq $04, b2, #l54
+breq $04, b0, #l67
+brne $04, b1, #l65
+breq $04, b2, #l60
sub $03, $03, $02
-l59:
-jump #l54
+l65:
+jump #l60
sub $02, $02, $03
-l61:
+l67:
ret
nop
@@ -85,7 +93,7 @@ cwrite $data, [$00 + @REG_READ_ADDR], 0x0
add $02, $regdata, 0x42
addhi $03, $00, $regdata
sub $02, $02, $regdata
-call #fxn54
+call #fxn60
subhi $03, $03, $regdata
and $02, $02, $regdata
or $02, $02, 0x1
@@ -110,14 +118,14 @@ mov $03, $data
mov $04, $data
mov $05, $data
mov $06, $data
-l90:
-breq $06, 0x0, #l96
+l96:
+breq $06, 0x0, #l102
cwrite $03, [$00 + @LOAD_STORE_HI], 0x0
load $07, [$02 + 0x4], 0x4
cwrite $05, [$00 + @LOAD_STORE_HI], 0x0
-jump #l90
+jump #l96
store $07, [$04 + 0x4], 0x4
-l96:
+l102:
waitin
mov $01, $data
@@ -134,15 +142,15 @@ mov $01, $data
IN_PREEMPT:
cread $02, [$00 + 0x101], 0x0
-brne $02, 0x1, #l116
+brne $02, 0x1, #l122
nop
-preemptleave #l50
+preemptleave #l56
nop
nop
nop
waitin
mov $01, $data
-l116:
+l122:
iret
nop
@@ -196,7 +204,6 @@ CP_REG_WRITE:
CP_REG_WR_NO_CTXT:
CP_RUN_OPENCL:
CP_SCRATCH_TO_REG:
-CP_SET_BIN_DATA5:
CP_SET_BIN_DATA5_OFFSET:
CP_SET_CONSTANT:
CP_SET_CTXSWITCH_IB:
@@ -268,131 +275,131 @@ UNKN96:
UNKN97:
waitin
mov $01, $data
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[0000006b]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[0000003f]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000025]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000022]
-[00000076]
-[00000076]
-[00000076]
-[0000002c]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[00000071]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[00000045]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
[00000030]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000062]
-[00000076]
-[00000055]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
-[00000076]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[00000025]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[00000022]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000002c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[00000036]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[00000068]
+[0000007c]
+[0000005b]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
+[0000007c]
diff --git a/src/freedreno/.gitlab-ci/reference/afuc_test.fw b/src/freedreno/.gitlab-ci/reference/afuc_test.fw
index e48cb0bde0b..9d04c143a1f 100644
Binary files a/src/freedreno/.gitlab-ci/reference/afuc_test.fw and b/src/freedreno/.gitlab-ci/reference/afuc_test.fw differ
diff --git a/src/freedreno/.gitlab-ci/traces/afuc_test.asm b/src/freedreno/.gitlab-ci/traces/afuc_test.asm
index 089100d2d0a..3d1997d54e1 100644
--- a/src/freedreno/.gitlab-ci/traces/afuc_test.asm
+++ b/src/freedreno/.gitlab-ci/traces/afuc_test.asm
@@ -94,6 +94,15 @@ mov $02, 0xff
waitin
mov $01, $data
+CP_SET_BIN_DATA5:
+; test SQE registers
+sread $02, [$00 + %SP], 0x0
+swrite $02, [$00 + %SP], 0x0
+mov $02, 7
+(rep)swrite $data, [$02 + 1], 0x4
+waitin
+mov $01, $data
+
CP_SET_SECURE_MODE:
; test setsecure
mov $02, $data
@@ -244,7 +253,6 @@ CP_IM_LOAD_IMMEDIATE:
CP_BLIT:
CP_SET_CONSTANT:
CP_SET_BIN_DATA5_OFFSET:
-CP_SET_BIN_DATA5:
UNKN48:
CP_RUN_OPENCL:
CP_LOAD_STATE6_GEOM:
diff --git a/src/freedreno/afuc/README.rst b/src/freedreno/afuc/README.rst
index c9e70e11f8a..e8f5fd35a30 100644
--- a/src/freedreno/afuc/README.rst
+++ b/src/freedreno/afuc/README.rst
@@ -276,6 +276,17 @@ but on a6xx::
cwrite $0b, [$05 + @IB1_BASE+0x1], 0x0
cwrite $04, [$05 + @IB1_DWORDS], 0x0
+.. _afuc-sqe-regs:
+
+SQE Registers
+=============
+
+Starting with a6xx, the state of the SQE processor itself can be accessed
+through ``sread``/``swrite`` instructions that work identically to
+``cread``/``cwrite``. For example, this includes the state of the
+``call``/``ret`` stack. This is mainly used during the preemption routine but
+it's also used to set the entrypoint for preemption.
+
.. _afuc-read:
Reading Memory and Registers
diff --git a/src/freedreno/afuc/afuc.h b/src/freedreno/afuc/afuc.h
index c45e89d776f..2a2f4157bf6 100644
--- a/src/freedreno/afuc/afuc.h
+++ b/src/freedreno/afuc/afuc.h
@@ -103,6 +103,13 @@ typedef enum {
OPC_STORE,
OPC_LOAD,
+ /* A6xx added new opcodes that let you read/write the state of the
+ * SQE processor itself, like the call stack. This is mostly used by
+ * preemption but is also used to set the preempt routine entrypoint.
+ */
+ OPC_SREAD,
+ OPC_SWRITE,
+
OPC_BRNEI, /* relative branch (if $src != immed) */
OPC_BREQI, /* relative branch (if $src == immed) */
OPC_BRNEB, /* relative branch (if bit not set) */
@@ -172,6 +179,7 @@ struct afuc_instr {
};
void print_control_reg(uint32_t id);
+void print_sqe_reg(uint32_t id);
void print_pipe_reg(uint32_t id);
#endif /* _AFUC_H_ */
diff --git a/src/freedreno/afuc/afuc.xml b/src/freedreno/afuc/afuc.xml
index 80bde72a283..e07ae81bc08 100644
--- a/src/freedreno/afuc/afuc.xml
+++ b/src/freedreno/afuc/afuc.xml
@@ -670,6 +670,25 @@ SOFTWARE.
+
+ Write to a SQE register.
+
+
+ {REP}swrite {SRC}, [{OFFSET} + {SQEREG}], 0x{FLAGS}
+
+
+
+
+ 1
+ 10101
+
+
+
+
+
+
+
+
@@ -719,6 +738,25 @@ SOFTWARE.
10111
+
+ Read from a SQE register.
+
+
+ {REP}sread {DST}, [{OFFSET} + {SQEREG}], 0x{FLAGS}
+
+
+
+
+
+
+
+
+
+
+ 1
+ 10111
+
+
diff --git a/src/freedreno/afuc/asm.c b/src/freedreno/afuc/asm.c
index 545aac09a54..a38bddf39e0 100644
--- a/src/freedreno/afuc/asm.c
+++ b/src/freedreno/afuc/asm.c
@@ -210,6 +210,13 @@ parse_control_reg(const char *name)
return afuc_control_reg(name + 1);
}
+unsigned
+parse_sqe_reg(const char *name)
+{
+ /* skip leading "%" */
+ return afuc_sqe_reg(name + 1);
+}
+
static void
emit_jumptable(int outfd)
{
diff --git a/src/freedreno/afuc/asm.h b/src/freedreno/afuc/asm.h
index fa899fe531c..ced8c6a2546 100644
--- a/src/freedreno/afuc/asm.h
+++ b/src/freedreno/afuc/asm.h
@@ -90,6 +90,7 @@ parse_bit(const char *str)
}
unsigned parse_control_reg(const char *name);
+unsigned parse_sqe_reg(const char *name);
/* string trailing ':' off label: */
static inline const char *
diff --git a/src/freedreno/afuc/disasm.c b/src/freedreno/afuc/disasm.c
index fd9e0de7b96..4de6def772f 100644
--- a/src/freedreno/afuc/disasm.c
+++ b/src/freedreno/afuc/disasm.c
@@ -88,6 +88,18 @@ print_control_reg(uint32_t id)
}
}
+void
+print_sqe_reg(uint32_t id)
+{
+ char *name = afuc_sqe_reg_name(id);
+ if (name) {
+ printf("@%s", name);
+ free(name);
+ } else {
+ printf("0x%03x", id);
+ }
+}
+
void
print_pipe_reg(uint32_t id)
{
@@ -118,6 +130,14 @@ field_print_cb(struct isa_print_state *state, const char *field_name, uint64_t v
} else {
isa_print(state, "0x%03x", (unsigned)val);
}
+ } else if (!strcmp(field_name, "SQEREG")) {
+ char *name = afuc_sqe_reg_name(val);
+ if (name) {
+ isa_print(state, "%%%s", name);
+ free(name);
+ } else {
+ isa_print(state, "0x%03x", (unsigned)val);
+ }
}
}
diff --git a/src/freedreno/afuc/emu-regs.c b/src/freedreno/afuc/emu-regs.c
index 7d6f8b38c4b..cc514453c04 100644
--- a/src/freedreno/afuc/emu-regs.c
+++ b/src/freedreno/afuc/emu-regs.c
@@ -106,6 +106,21 @@ emu_set_control_reg(struct emu *emu, unsigned n, uint32_t val)
}
}
+uint32_t
+emu_get_sqe_reg(struct emu *emu, unsigned n)
+{
+ assert(n < ARRAY_SIZE(emu->sqe_regs.val));
+ return emu->sqe_regs.val[n];
+}
+
+void
+emu_set_sqe_reg(struct emu *emu, unsigned n, uint32_t val)
+{
+ assert(n < ARRAY_SIZE(emu->sqe_regs.val));
+ BITSET_SET(emu->sqe_regs.written, n);
+ emu->sqe_regs.val[n] = val;
+}
+
static uint32_t
emu_get_pipe_reg(struct emu *emu, unsigned n)
{
diff --git a/src/freedreno/afuc/emu-ui.c b/src/freedreno/afuc/emu-ui.c
index 240aac31685..4d2753bf4b0 100644
--- a/src/freedreno/afuc/emu-ui.c
+++ b/src/freedreno/afuc/emu-ui.c
@@ -223,6 +223,28 @@ dump_control_register(struct emu *emu, unsigned n)
}
}
+static void
+dump_sqe_register(struct emu *emu, unsigned n)
+{
+ printf(" SQE: ");
+ print_sqe_reg(n);
+ printf(": ");
+ if (BITSET_TEST(emu->sqe_regs.written, n)) {
+ printdelta("%08x\n", emu->sqe_regs.val[n]);
+ } else {
+ printf("%08x\n", emu->sqe_regs.val[n]);
+ }
+}
+
+static void
+dump_sqe_registers(struct emu *emu)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(emu->sqe_regs.val); i++) {
+ dump_sqe_register(emu, i);
+ }
+}
+
+
static void
dump_gpumem(struct emu *emu, uintptr_t addr)
{
@@ -289,6 +311,24 @@ emu_dump_control_prompt(struct emu *emu)
dump_control_register(emu, offset);
}
+static void
+emu_write_sqe_prompt(struct emu *emu)
+{
+ clear_line();
+ printf(" SQE register (name or offset) and value: ");
+
+ const char *name;
+ const char *value;
+
+ if (read_two_values(&name, &value))
+ return;
+
+ unsigned offset = afuc_sqe_reg(name);
+ uint32_t val = strtoul(value, NULL, 0);
+
+ emu_set_sqe_reg(emu, offset, val);
+}
+
static void
emu_write_gpu_prompt(struct emu *emu)
{
@@ -364,7 +404,7 @@ emu_dump_prompt(struct emu *emu)
{
do {
clear_line();
- printf(" dump: GPR (r)egisters, (c)ontrol register, (g)pu register, (m)emory: ");
+ printf(" dump: GPR (r)egisters, (c)ontrol register, (s)qe registers, (g)pu register, (m)emory: ");
int c = readchar();
printf("%c\n", c);
@@ -375,6 +415,10 @@ emu_dump_prompt(struct emu *emu)
*/
dump_gpr_registers(emu);
break;
+ } else if (c == 's') {
+ /* Similarly, just dump all the SQE registers */
+ dump_sqe_registers(emu);
+ break;
} else if (c == 'c') {
emu_dump_control_prompt(emu);
break;
@@ -396,7 +440,7 @@ emu_write_prompt(struct emu *emu)
{
do {
clear_line();
- printf(" write: GPR (r)egister, (c)ontrol register, (g)pu register, (m)emory: ");
+ printf(" write: GPR (r)egister, (c)ontrol register, (s)sqe register, (g)pu register, (m)emory: ");
int c = readchar();
printf("%c\n", c);
@@ -404,6 +448,9 @@ emu_write_prompt(struct emu *emu)
if (c == 'r') {
emu_write_gpr_prompt(emu);
break;
+ } else if (c == 's') {
+ emu_write_sqe_prompt(emu);
+ break;
} else if (c == 'c') {
emu_write_control_prompt(emu);
break;
@@ -512,6 +559,7 @@ void
emu_clear_state_change(struct emu *emu)
{
memset(emu->control_regs.written, 0, sizeof(emu->control_regs.written));
+ memset(emu->sqe_regs.written, 0, sizeof(emu->sqe_regs.written));
memset(emu->pipe_regs.written, 0, sizeof(emu->pipe_regs.written));
memset(emu->gpu_regs.written, 0, sizeof(emu->gpu_regs.written));
memset(emu->gpr_regs.written, 0, sizeof(emu->gpr_regs.written));
@@ -543,6 +591,10 @@ emu_dump_state_change(struct emu *emu)
dump_control_register(emu, i);
}
+ BITSET_FOREACH_SET (i, emu->sqe_regs.written, EMU_NUM_SQE_REGS) {
+ dump_sqe_register(emu, i);
+ }
+
if (emu->gpumem_written != ~0) {
dump_gpumem(emu, emu->gpumem_written);
}
diff --git a/src/freedreno/afuc/emu.c b/src/freedreno/afuc/emu.c
index 2bdda3a5c97..29a482a8748 100644
--- a/src/freedreno/afuc/emu.c
+++ b/src/freedreno/afuc/emu.c
@@ -235,6 +235,32 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
emu_get_control_reg(emu, src1 + instr->immed));
break;
}
+ case OPC_SWRITE: {
+ uint32_t src1 = emu_get_gpr_reg(emu, instr->src1);
+ uint32_t src2 = emu_get_gpr_reg(emu, instr->src2);
+
+ if (instr->bit == 0x4) {
+ emu_set_gpr_reg(emu, instr->src2, src2 + instr->immed);
+ } else if (instr->bit && !emu->quiet) {
+ printf("unhandled flags: %x\n", instr->bit);
+ }
+
+ emu_set_sqe_reg(emu, src2 + instr->immed, src1);
+ break;
+ }
+ case OPC_SREAD: {
+ uint32_t src1 = emu_get_gpr_reg(emu, instr->src1);
+
+ if (instr->bit == 0x4) {
+ emu_set_gpr_reg(emu, instr->src1, src1 + instr->immed);
+ } else if (instr->bit && !emu->quiet) {
+ printf("unhandled flags: %x\n", instr->bit);
+ }
+
+ emu_set_gpr_reg(emu, instr->dst,
+ emu_get_sqe_reg(emu, src1 + instr->immed));
+ break;
+ }
case OPC_LOAD: {
uintptr_t addr = load_store_addr(emu, instr->src1) +
instr->immed;
diff --git a/src/freedreno/afuc/emu.h b/src/freedreno/afuc/emu.h
index e978d097aaa..12834ed1b66 100644
--- a/src/freedreno/afuc/emu.h
+++ b/src/freedreno/afuc/emu.h
@@ -48,6 +48,13 @@ struct emu_control_regs {
uint32_t val[EMU_NUM_CONTROL_REGS];
};
+#define EMU_NUM_SQE_REGS 0x10
+
+struct emu_sqe_regs {
+ BITSET_DECLARE(written, EMU_NUM_SQE_REGS);
+ uint32_t val[EMU_NUM_SQE_REGS];
+};
+
#define EMU_NUM_GPU_REGS 0x10000
struct emu_gpu_regs {
@@ -166,6 +173,7 @@ struct emu {
unsigned gpu_id;
struct emu_control_regs control_regs;
+ struct emu_sqe_regs sqe_regs;
struct emu_pipe_regs pipe_regs;
struct emu_gpu_regs gpu_regs;
struct emu_gpr_regs gpr_regs;
@@ -185,7 +193,9 @@ struct emu {
/* (r)un mode, don't stop for input until next waitin: */
bool run_mode;
- /* carry-bits for add/sub for addhi/subhi */
+ /* carry-bits for add/sub for addhi/subhi
+ * TODO: this is probably in a SQE register somewhere
+ */
uint32_t carry;
/* call-stack of saved PCs.. I expect this to be a fixed size, but not
@@ -252,6 +262,9 @@ void emu_set_gpu_reg(struct emu *emu, unsigned n, uint32_t val);
uint32_t emu_get_control_reg(struct emu *emu, unsigned n);
void emu_set_control_reg(struct emu *emu, unsigned n, uint32_t val);
+uint32_t emu_get_sqe_reg(struct emu *emu, unsigned n);
+void emu_set_sqe_reg(struct emu *emu, unsigned n, uint32_t val);
+
/* Register helpers for fixed fxn emulation, to avoid lots of boilerplate
* for accessing other pipe/control registers.
*
diff --git a/src/freedreno/afuc/lexer.l b/src/freedreno/afuc/lexer.l
index 9383ea1273e..5ee639a2972 100644
--- a/src/freedreno/afuc/lexer.l
+++ b/src/freedreno/afuc/lexer.l
@@ -47,6 +47,7 @@ extern YYSTYPE yylval;
"$"[a-zA-Z][a-zA-Z0-9]* yylval.num = parse_reg(yytext); return T_REGISTER;
"b"[0-9][0-9]* yylval.num = parse_bit(yytext); return T_BIT;
"@"[a-zA-Z_][a-zA-Z0-9_]* yylval.num = parse_control_reg(yytext); return T_CONTROL_REG;
+"%"[a-zA-Z_][a-zA-Z0-9_]* yylval.num = parse_sqe_reg(yytext); return T_SQE_REG;
"#"[a-zA-Z_][a-zA-Z0-9_]* yylval.str = strdup(yytext+1); return T_LABEL_REF; /* label reference */
[a-zA-Z_][a-zA-Z0-9_]*":" yylval.str = parse_label_decl(yytext); return T_LABEL_DECL; /* label declaration */
"["[0-9a-fA-F][0-9a-fA-F]*"]" yylval.num = parse_literal(yytext); return T_LITERAL;
@@ -78,6 +79,8 @@ extern YYSTYPE yylval;
"mov" return TOKEN(T_OP_MOV);
"cwrite" return TOKEN(T_OP_CWRITE);
"cread" return TOKEN(T_OP_CREAD);
+"swrite" return TOKEN(T_OP_SWRITE);
+"sread" return TOKEN(T_OP_SREAD);
"store" return TOKEN(T_OP_STORE);
"load" return TOKEN(T_OP_LOAD);
"brne" return TOKEN(T_OP_BRNE);
diff --git a/src/freedreno/afuc/parser.y b/src/freedreno/afuc/parser.y
index 39ce7f44c61..5fbfaf2d209 100644
--- a/src/freedreno/afuc/parser.y
+++ b/src/freedreno/afuc/parser.y
@@ -121,6 +121,7 @@ label(const char *str)
%token T_INT
%token T_HEX
%token T_CONTROL_REG
+%token T_SQE_REG
%token T_LABEL_DECL
%token T_LABEL_REF
%token T_LITERAL
@@ -153,6 +154,8 @@ label(const char *str)
%token T_OP_MOV
%token T_OP_CWRITE
%token T_OP_CREAD
+%token T_OP_SWRITE
+%token T_OP_SREAD
%token T_OP_STORE
%token T_OP_LOAD
%token T_OP_BRNE
@@ -254,8 +257,10 @@ alu_instr: alu_2src_instr
load_op: T_OP_LOAD { new_instr(OPC_LOAD); }
| T_OP_CREAD { new_instr(OPC_CREAD); }
+| T_OP_SREAD { new_instr(OPC_SREAD); }
store_op: T_OP_STORE { new_instr(OPC_STORE); }
| T_OP_CWRITE { new_instr(OPC_CWRITE); }
+| T_OP_SWRITE { new_instr(OPC_SWRITE); }
load_instr: load_op reg ',' '[' reg '+' immediate ']' ',' immediate {
dst($2); src1($5); immed($7); bit($10);
@@ -286,4 +291,6 @@ immediate: T_HEX
| T_INT
| T_CONTROL_REG
| T_CONTROL_REG '+' immediate { $$ = $1 + $3; }
+| T_SQE_REG
+| T_SQE_REG '+' immediate { $$ = $1 + $3; }
diff --git a/src/freedreno/afuc/util.c b/src/freedreno/afuc/util.c
index 65f7560a7ad..3789df46a6b 100644
--- a/src/freedreno/afuc/util.c
+++ b/src/freedreno/afuc/util.c
@@ -35,6 +35,7 @@
static struct rnndeccontext *ctx;
static struct rnndb *db;
static struct rnndomain *control_regs;
+static struct rnndomain *sqe_regs;
static struct rnndomain *pipe_regs;
struct rnndomain *dom[2];
static struct rnnenum *pm4_packets;
@@ -86,6 +87,24 @@ afuc_control_reg(const char *name)
return reg(control_regs, "control", name);
}
+/**
+ * Map offset to SQE reg name (or NULL), caller frees
+ */
+char *
+afuc_sqe_reg_name(unsigned id)
+{
+ return reg_name(sqe_regs, id);
+}
+
+/**
+ * Map SQE reg name to offset.
+ */
+unsigned
+afuc_sqe_reg(const char *name)
+{
+ return reg(sqe_regs, "SQE", name);
+}
+
/**
* Map offset to control reg name (or NULL), caller frees
*/
@@ -292,6 +311,7 @@ int afuc_util_init(int gpuver, bool colors)
dom[0] = rnn_finddomain(db, name);
dom[1] = rnn_finddomain(db, "AXXX");
control_regs = rnn_finddomain(db, control_reg_name);
+ sqe_regs = rnn_finddomain(db, "A6XX_SQE_REG");
pipe_regs = rnn_finddomain(db, pipe_reg_name);
rnndec_varadd(ctx, "chip", variant);
diff --git a/src/freedreno/afuc/util.h b/src/freedreno/afuc/util.h
index e63de5e2769..f03af7c742d 100644
--- a/src/freedreno/afuc/util.h
+++ b/src/freedreno/afuc/util.h
@@ -33,6 +33,9 @@
unsigned afuc_control_reg(const char *name);
char * afuc_control_reg_name(unsigned id);
+unsigned afuc_sqe_reg(const char *name);
+char * afuc_sqe_reg_name(unsigned id);
+
unsigned afuc_pipe_reg(const char *name);
char * afuc_pipe_reg_name(unsigned id);
bool afuc_pipe_reg_is_void(unsigned id);
diff --git a/src/freedreno/registers/adreno/adreno_control_regs.xml b/src/freedreno/registers/adreno/adreno_control_regs.xml
index 04697a78c60..0d28e0985f9 100644
--- a/src/freedreno/registers/adreno/adreno_control_regs.xml
+++ b/src/freedreno/registers/adreno/adreno_control_regs.xml
@@ -4,10 +4,34 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
+
+
+
+
+ Instruction to jump to when the CP is preempted to perform a
+ context switch, initialized to entry 15 of the jump table at
+ bootup.
+
+
+
+ Stack Pointer for call/ret return address stack
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -30,12 +54,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
-
- Instruction to jump to when the CP is preempted to perform a
- context switch, initialized to entry 15 of the jump table at
- bootup.
-
-