intel/tools: Use gen_device_name_to_pci_device_id in aubinator
[mesa.git] / src / intel / tools / aubinator.c
index fcb46073f3086a7eaf7f10cf96868d623356f89f..77bad29051e1415f8ec316a3acfdcb6b36a20e57 100644 (file)
@@ -223,6 +223,81 @@ handle_trace_header(uint32_t *p)
    aubinator_init(aub_pci_id, app_name);
 }
 
+static void
+handle_memtrace_version(uint32_t *p)
+{
+   int header_length = p[0] & 0xffff;
+   char app_name[64];
+   int app_name_len = MIN2(4 * (header_length + 1 - 5), ARRAY_SIZE(app_name) - 1);
+   int pci_id_len = 0;
+   int aub_pci_id = 0;
+
+   strncpy(app_name, (char *)&p[5], app_name_len);
+   app_name[app_name_len] = 0;
+   sscanf(app_name, "PCI-ID=%i %n", &aub_pci_id, &pci_id_len);
+   if (pci_id == 0)
+      pci_id = aub_pci_id;
+   aubinator_init(aub_pci_id, app_name + pci_id_len);
+}
+
+static void
+handle_memtrace_reg_write(uint32_t *p)
+{
+   uint32_t offset = p[1];
+   uint32_t value = p[5];
+   int engine;
+   static int render_elsp_writes = 0;
+   static int blitter_elsp_writes = 0;
+
+   if (offset == 0x2230) {
+      render_elsp_writes++;
+      engine = GEN_ENGINE_RENDER;
+   } else if (offset == 0x22230) {
+      blitter_elsp_writes++;
+      engine = GEN_ENGINE_BLITTER;
+   } else {
+      return;
+   }
+
+   if (render_elsp_writes > 3)
+      render_elsp_writes = 0;
+   else if (blitter_elsp_writes > 3)
+      blitter_elsp_writes = 0;
+   else
+      return;
+
+   uint8_t *pphwsp = (uint8_t*)gtt + (value & 0xfffff000);
+   const uint32_t pphwsp_size = 4096;
+   uint32_t *context = (uint32_t*)(pphwsp + pphwsp_size);
+   uint32_t ring_buffer_head = context[5];
+   uint32_t ring_buffer_tail = context[7];
+   uint32_t ring_buffer_start = context[9];
+   uint32_t *commands = (uint32_t*)((uint8_t*)gtt + ring_buffer_start + ring_buffer_head);
+   (void)engine; /* TODO */
+   gen_print_batch(&batch_ctx, commands, ring_buffer_tail - ring_buffer_head, 0);
+}
+
+static void
+handle_memtrace_mem_write(uint32_t *p)
+{
+   uint64_t address = *(uint64_t*)&p[1];
+   uint32_t address_space = p[3] >> 28;
+   uint32_t size = p[4];
+   uint32_t *data = p + 5;
+
+   if (address_space != 1)
+      return;
+
+   if (gtt_size < address + size) {
+      fprintf(stderr, "overflow gtt space: %s\n", strerror(errno));
+      exit(EXIT_FAILURE);
+   }
+
+   memcpy((char *) gtt + address, data, size);
+   if (gtt_end < address + size)
+      gtt_end = address + size;
+}
+
 struct aub_file {
    FILE *stream;
 
@@ -292,35 +367,14 @@ aub_file_stdin(void)
 
 /* Newer version AUB opcode */
 #define OPCODE_NEW_AUB      0x2e
-#define SUBOPCODE_VERSION   0x00
+#define SUBOPCODE_REG_POLL  0x02
 #define SUBOPCODE_REG_WRITE 0x03
 #define SUBOPCODE_MEM_POLL  0x05
 #define SUBOPCODE_MEM_WRITE 0x06
+#define SUBOPCODE_VERSION   0x0e
 
 #define MAKE_GEN(major, minor) ( ((major) << 8) | (minor) )
 
-struct {
-   const char *name;
-   uint32_t gen;
-} device_map[] = {
-   { "bwr", MAKE_GEN(4, 0) },
-   { "cln", MAKE_GEN(4, 0) },
-   { "blc", MAKE_GEN(4, 0) },
-   { "ctg", MAKE_GEN(4, 0) },
-   { "el", MAKE_GEN(4, 0) },
-   { "il", MAKE_GEN(4, 0) },
-   { "sbr", MAKE_GEN(6, 0) },
-   { "ivb", MAKE_GEN(7, 0) },
-   { "lrb2", MAKE_GEN(0, 0) },
-   { "hsw", MAKE_GEN(7, 5) },
-   { "vlv", MAKE_GEN(7, 0) },
-   { "bdw", MAKE_GEN(8, 0) },
-   { "skl", MAKE_GEN(9, 0) },
-   { "chv", MAKE_GEN(8, 0) },
-   { "bxt", MAKE_GEN(9, 0) },
-   { "cnl", MAKE_GEN(10, 0) },
-};
-
 enum {
    AUB_ITEM_DECODE_OK,
    AUB_ITEM_DECODE_FAILED,
@@ -330,7 +384,7 @@ enum {
 static int
 aub_file_decode_batch(struct aub_file *file)
 {
-   uint32_t *p, h, device, data_type, *new_cursor;
+   uint32_t *p, h, *new_cursor;
    int header_length, bias;
 
    if (file->end - file->cursor < 1)
@@ -374,25 +428,19 @@ aub_file_decode_batch(struct aub_file *file)
    case MAKE_HEADER(TYPE_AUB, OPCODE_AUB, SUBOPCODE_BMP):
       break;
    case MAKE_HEADER(TYPE_AUB, OPCODE_NEW_AUB, SUBOPCODE_VERSION):
-      fprintf(outfile, "version block: dw1 %08x\n", p[1]);
-      device = (p[1] >> 8) & 0xff;
-      fprintf(outfile, "  device %s\n", device_map[device].name);
+      handle_memtrace_version(p);
       break;
    case MAKE_HEADER(TYPE_AUB, OPCODE_NEW_AUB, SUBOPCODE_REG_WRITE):
-      fprintf(outfile, "register write block: (dwords %d)\n", h & 0xffff);
-      fprintf(outfile, "  reg 0x%x, data 0x%x\n", p[1], p[5]);
+      handle_memtrace_reg_write(p);
       break;
    case MAKE_HEADER(TYPE_AUB, OPCODE_NEW_AUB, SUBOPCODE_MEM_WRITE):
-      fprintf(outfile, "memory write block (dwords %d):\n", h & 0xffff);
-      fprintf(outfile, "  address 0x%"PRIx64"\n", *(uint64_t *) &p[1]);
-      data_type = (p[3] >> 20) & 0xff;
-      if (data_type != 0)
-         fprintf(outfile, "  data type 0x%x\n", data_type);
-      fprintf(outfile, "  address space 0x%x\n", (p[3] >> 28) & 0xf);
+      handle_memtrace_mem_write(p);
       break;
    case MAKE_HEADER(TYPE_AUB, OPCODE_NEW_AUB, SUBOPCODE_MEM_POLL):
       fprintf(outfile, "memory poll block (dwords %d):\n", h & 0xffff);
       break;
+   case MAKE_HEADER(TYPE_AUB, OPCODE_NEW_AUB, SUBOPCODE_REG_POLL):
+      break;
    default:
       fprintf(outfile, "unknown block type=0x%x, opcode=0x%x, "
              "subopcode=0x%x (%08x)\n", TYPE(h), OPCODE(h), SUBOPCODE(h), h);
@@ -501,22 +549,6 @@ int main(int argc, char *argv[])
    struct aub_file *file;
    int c, i;
    bool help = false, pager = true;
-   const struct {
-      const char *name;
-      int pci_id;
-   } gens[] = {
-      { "ilk", 0x0046 }, /* Intel(R) Ironlake Mobile */
-      { "snb", 0x0126 }, /* Intel(R) Sandybridge Mobile GT2 */
-      { "ivb", 0x0166 }, /* Intel(R) Ivybridge Mobile GT2 */
-      { "hsw", 0x0416 }, /* Intel(R) Haswell Mobile GT2 */
-      { "byt", 0x0155 }, /* Intel(R) Bay Trail */
-      { "bdw", 0x1616 }, /* Intel(R) HD Graphics 5500 (Broadwell GT2) */
-      { "chv", 0x22B3 }, /* Intel(R) HD Graphics (Cherryview) */
-      { "skl", 0x1912 }, /* Intel(R) HD Graphics 530 (Skylake GT2) */
-      { "kbl", 0x591D }, /* Intel(R) Kabylake GT2 */
-      { "bxt", 0x0A84 },  /* Intel(R) HD Graphics (Broxton) */
-      { "cnl", 0x5A52 },  /* Intel(R) HD Graphics (Cannonlake) */
-   };
    const struct option aubinator_opts[] = {
       { "help",       no_argument,       (int *) &help,                 true },
       { "no-pager",   no_argument,       (int *) &pager,                false },
@@ -533,19 +565,17 @@ int main(int argc, char *argv[])
    i = 0;
    while ((c = getopt_long(argc, argv, "", aubinator_opts, &i)) != -1) {
       switch (c) {
-      case 'g':
-         for (i = 0; i < ARRAY_SIZE(gens); i++) {
-            if (!strcmp(optarg, gens[i].name)) {
-               pci_id = gens[i].pci_id;
-               break;
-            }
-         }
-         if (i == ARRAY_SIZE(gens)) {
+      case 'g': {
+         const int id = gen_device_name_to_pci_device_id(optarg);
+         if (id < 0) {
             fprintf(stderr, "can't parse gen: '%s', expected ivb, byt, hsw, "
                                    "bdw, chv, skl, kbl or bxt\n", optarg);
             exit(EXIT_FAILURE);
+         } else {
+            pci_id = id;
          }
          break;
+      }
       case 'c':
          if (optarg == NULL || strcmp(optarg, "always") == 0)
             option_color = COLOR_ALWAYS;