Mesa (main): freedreno/afuc: Add emulator support to run bootstrap
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Jun 1 00:30:14 UTC 2021
Module: Mesa
Branch: main
Commit: df14af6480c3d70134a9308f8028d5627867f572
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=df14af6480c3d70134a9308f8028d5627867f572
Author: Rob Clark <robdclark at chromium.org>
Date: Thu May 27 12:18:53 2021 -0700
freedreno/afuc: Add emulator support to run bootstrap
Run until the packet-table is populated, so the disassembler can use
this to know the offsets of various pm4 packet handlers without having
to rely on heuristics.
Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10944>
---
src/freedreno/afuc/emu-ui.c | 3 +++
src/freedreno/afuc/emu.c | 52 +++++++++++++++++++++++++++++++++++++++------
src/freedreno/afuc/emu.h | 11 ++++++++++
3 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/src/freedreno/afuc/emu-ui.c b/src/freedreno/afuc/emu-ui.c
index 0b24ea5f3aa..0af04808947 100644
--- a/src/freedreno/afuc/emu-ui.c
+++ b/src/freedreno/afuc/emu-ui.c
@@ -508,6 +508,9 @@ emu_dump_state_change(struct emu *emu)
{
unsigned i;
+ if (emu->quiet)
+ return;
+
/* Print the GPRs that changed: */
BITSET_FOREACH_SET (i, emu->gpr_regs.written, EMU_NUM_GPR_REGS) {
dump_gpr_register(emu, i);
diff --git a/src/freedreno/afuc/emu.c b/src/freedreno/afuc/emu.c
index f7296352848..959761d3d78 100644
--- a/src/freedreno/afuc/emu.c
+++ b/src/freedreno/afuc/emu.c
@@ -191,7 +191,7 @@ emu_instr(struct emu *emu, afuc_instr *instr)
if (instr->control.flags == 0x4) {
emu_set_gpr_reg(emu, instr->control.src2, src2 + instr->control.uimm);
- } else if (instr->control.flags) {
+ } else if (instr->control.flags && !emu->quiet) {
printf("unhandled flags: %x\n", instr->control.flags);
}
@@ -203,7 +203,7 @@ emu_instr(struct emu *emu, afuc_instr *instr)
if (instr->control.flags == 0x4) {
emu_set_gpr_reg(emu, instr->control.src2, src2 + instr->control.uimm);
- } else if (instr->control.flags) {
+ } else if (instr->control.flags && !emu->quiet) {
printf("unhandled flags: %x\n", instr->control.flags);
}
@@ -218,7 +218,7 @@ emu_instr(struct emu *emu, afuc_instr *instr)
if (instr->control.flags == 0x4) {
uint32_t src2 = emu_get_gpr_reg(emu, instr->control.src2);
emu_set_gpr_reg(emu, instr->control.src2, src2 + instr->control.uimm);
- } else if (instr->control.flags) {
+ } else if (instr->control.flags && !emu->quiet) {
printf("unhandled flags: %x\n", instr->control.flags);
}
@@ -235,7 +235,7 @@ emu_instr(struct emu *emu, afuc_instr *instr)
if (instr->control.flags == 0x4) {
uint32_t src2 = emu_get_gpr_reg(emu, instr->control.src2);
emu_set_gpr_reg(emu, instr->control.src2, src2 + instr->control.uimm);
- } else if (instr->control.flags) {
+ } else if (instr->control.flags && !emu->quiet) {
printf("unhandled flags: %x\n", instr->control.flags);
}
@@ -382,6 +382,20 @@ emu_step(struct emu *emu)
emu_dump_state_change(emu);
}
+void
+emu_run_bootstrap(struct emu *emu)
+{
+ EMU_CONTROL_REG(PACKET_TABLE_WRITE_ADDR);
+
+ emu->quiet = true;
+ emu->run_mode = true;
+
+ while (emu_get_reg32(emu, &PACKET_TABLE_WRITE_ADDR) < 0x80) {
+ emu_step(emu);
+ }
+}
+
+
static void
check_access(struct emu *emu, uintptr_t gpuaddr, unsigned sz)
{
@@ -435,10 +449,34 @@ emu_init(struct emu *emu)
mem_write_dword(emu, EMU_INSTR_BASE + (4 * i), emu->instrs[i]);
}
- printf("instruction base: %p\n", (void *)(uintptr_t)EMU_INSTR_BASE);
+ EMU_GPU_REG(CP_SQE_INSTR_BASE);
+ EMU_GPU_REG(CP_LPAC_SQE_INSTR_BASE);
/* Setup the address of the SQE fw, just use the normal CPU ptr address: */
- EMU_GPU_REG(CP_SQE_INSTR_BASE);
- emu_set_reg64(emu, &CP_SQE_INSTR_BASE, EMU_INSTR_BASE);
+ if (emu->lpac) {
+ emu_set_reg64(emu, &CP_LPAC_SQE_INSTR_BASE, EMU_INSTR_BASE);
+ } else {
+ emu_set_reg64(emu, &CP_SQE_INSTR_BASE, EMU_INSTR_BASE);
+ }
+
+ 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);
+ }
}
+void
+emu_fini(struct emu *emu)
+{
+ uint32_t *instrs = emu->instrs;
+ unsigned sizedwords = emu->sizedwords;
+ unsigned gpu_id = emu->gpu_id;
+
+ munmap(emu->gpumem, EMU_MEMORY_SIZE);
+ memset(emu, 0, sizeof(*emu));
+
+ emu->instrs = instrs;
+ emu->sizedwords = sizedwords;
+ emu->gpu_id = gpu_id;
+}
diff --git a/src/freedreno/afuc/emu.h b/src/freedreno/afuc/emu.h
index d8bc4f0b98e..1ff84c72198 100644
--- a/src/freedreno/afuc/emu.h
+++ b/src/freedreno/afuc/emu.h
@@ -149,8 +149,17 @@ struct emu_draw_state {
* Emulated hw state.
*/
struct emu {
+ /**
+ * In bootstrap mode, execute bootstrap without outputting anything.
+ * Useful to (for example) extract packet-table.
+ */
+ bool quiet;
+
+ bool lpac;
+
uint32_t *instrs;
unsigned sizedwords;
+ unsigned gpu_id;
struct emu_control_regs control_regs;
struct emu_pipe_regs pipe_regs;
@@ -214,7 +223,9 @@ struct emu {
* API for disasm to use:
*/
void emu_step(struct emu *emu);
+void emu_run_bootstrap(struct emu *emu);
void emu_init(struct emu *emu);
+void emu_fini(struct emu *emu);
/*
* Internal APIs
More information about the mesa-commit
mailing list