Mesa (main): freedreno/afuc: Use emulator to extract jmptbl

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 1 00:30:14 UTC 2021


Module: Mesa
Branch: main
Commit: ff5e17f1f85c93aa0c0c1004938a21145b0f8b5d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ff5e17f1f85c93aa0c0c1004938a21145b0f8b5d

Author: Rob Clark <robdclark at chromium.org>
Date:   Mon May 24 11:00:28 2021 -0700

freedreno/afuc: Use emulator to extract jmptbl

This runs through the SQE bootstrap code to extract the packet-table,
rather than relying on heuristics.  As a bonus, it can detect the start
of the LPAC fw in a660+ fw so that we can properly decode the LPAC fw
and packet-table.

Note that this decodes the jmptable as normal instructions, which is a
change in behavior from the previous heuristic based jmptbl extraction.
Not sure if that is a good or bad thing.

For a5xx, for now the legacy heuristic based jmptable decoding is
preserved, at least until enough control regs are figured out.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10944>

---

 src/freedreno/.gitlab-ci/reference/afuc_test.asm | 128 +++++++++++++++++++++++
 src/freedreno/afuc/disasm.c                      | 103 +++++++++++++++---
 2 files changed, 215 insertions(+), 16 deletions(-)

diff --git a/src/freedreno/.gitlab-ci/reference/afuc_test.asm b/src/freedreno/.gitlab-ci/reference/afuc_test.asm
index c68460477bb..920aa4d49d3 100644
--- a/src/freedreno/.gitlab-ci/reference/afuc_test.asm
+++ b/src/freedreno/.gitlab-ci/reference/afuc_test.asm
@@ -260,3 +260,131 @@ UNKN126:
 UNKN127:
         waitin
         mov $01, $data
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [0000006b]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [0000003f]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000025]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000022]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [0000002c]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000030]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000062]  ; nop
+        [00000076]  ; nop
+        [00000055]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
+        [00000076]  ; nop
diff --git a/src/freedreno/afuc/disasm.c b/src/freedreno/afuc/disasm.c
index 8de7991ebbd..d7b322a1022 100644
--- a/src/freedreno/afuc/disasm.c
+++ b/src/freedreno/afuc/disasm.c
@@ -758,7 +758,81 @@ setup_labels(uint32_t *instrs, uint32_t sizedwords)
 }
 
 static void
-disasm(uint32_t *buf, int sizedwords)
+disasm(struct emu *emu)
+{
+   uint32_t sizedwords = emu->sizedwords;
+   uint32_t lpac_offset = 0;
+
+   EMU_GPU_REG(CP_SQE_INSTR_BASE);
+   EMU_GPU_REG(CP_LPAC_SQE_INSTR_BASE);
+
+   emu_init(emu);
+
+#ifdef BOOTSTRAP_DEBUG
+   while (true) {
+      disasm_instr(emu->instrs, emu->gpr_regs.pc);
+      emu_step(emu);
+   }
+#endif
+
+   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);
+      lpac_offset /= 4;
+      sizedwords = lpac_offset;
+   }
+
+   setup_packet_table(emu->jmptbl, ARRAY_SIZE(emu->jmptbl));
+   setup_labels(emu->instrs, emu->sizedwords);
+
+   /* TODO add option to emulate LPAC SQE instead: */
+   if (emulator) {
+      /* Start from clean slate: */
+      emu_fini(emu);
+      emu_init(emu);
+
+      while (true) {
+         disasm_instr(emu->instrs, emu->gpr_regs.pc);
+         emu_step(emu);
+      }
+   }
+
+   /* print instructions: */
+   for (int i = 0; i < sizedwords; i++) {
+      disasm_instr(emu->instrs, i);
+   }
+
+   if (!lpac_offset)
+      return;
+
+   printf(";\n");
+   printf("; LPAC microcode:\n");
+   printf(";\n");
+
+   emu_fini(emu);
+
+   emu->lpac = true;
+   emu->instrs += lpac_offset;
+   emu->sizedwords -= lpac_offset;
+
+   emu_init(emu);
+   emu_run_bootstrap(emu);
+
+   setup_packet_table(emu->jmptbl, ARRAY_SIZE(emu->jmptbl));
+   setup_labels(emu->instrs, emu->sizedwords);
+
+   /* print instructions: */
+   for (int i = 0; i < emu->sizedwords; i++) {
+      disasm_instr(emu->instrs, i);
+   }
+}
+
+
+static void
+disasm_legacy(uint32_t *buf, int sizedwords)
 {
    uint32_t *instrs = buf;
    const int jmptbl_start = instrs[1] & 0xffff;
@@ -773,20 +847,6 @@ disasm(uint32_t *buf, int sizedwords)
     */
    setup_labels(instrs, jmptbl_start);
 
-   if (emulator) {
-      struct emu state = {
-            .instrs = instrs,
-            .sizedwords = sizedwords,
-      };
-
-      emu_init(&state);
-
-      while (true) {
-         disasm_instr(instrs, state.gpr_regs.pc);
-         emu_step(&state);
-      }
-   }
-
    /* print instructions: */
    for (i = 0; i < jmptbl_start; i++) {
       disasm_instr(instrs, i);
@@ -898,7 +958,18 @@ main(int argc, char **argv)
 
    printf("; Disassembling microcode: %s\n", file);
    printf("; Version: %08x\n\n", buf[1]);
-   disasm(&buf[1], sz / 4 - 1);
+
+   if (gpuver < 6) {
+      disasm_legacy(&buf[1], sz / 4 - 1);
+   } else {
+      struct emu emu = {
+            .instrs = &buf[1],
+            .sizedwords = sz / 4 - 1,
+            .gpu_id = gpu_id,
+      };
+
+      disasm(&emu);
+   }
 
    return 0;
 }



More information about the mesa-commit mailing list