+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;
+}
+