summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2016-01-18 14:30:42 +0000
committerRussell King <rmk@arm.linux.org.uk>2016-01-18 14:30:42 +0000
commitd782ea474e5222d3ee1bee008c68a999a565be96 (patch)
treec7269a4acaf5ed5cdb813e3ef90f0cb4c172115f
Initial commit
Add sources for etna-gpu-tools Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--Makefile70
-rwxr-xr-xbin2img.in37
-rw-r--r--detile/viv-demultitile.c110
-rw-r--r--diff/viv-cmd-diff.c170
-rw-r--r--dump/viv-unpack.c271
-rw-r--r--include/etnaviv_drm.h329
-rw-r--r--include/etnaviv_dump.h54
-rw-r--r--include/hw/common.xml.h285
-rw-r--r--include/hw/state.xml.h351
-rw-r--r--info/features.h216
-rw-r--r--info/viv_info.c196
-rwxr-xr-xtools/hexdump-idx-162
-rwxr-xr-xtools/hexdump-mmu2
-rw-r--r--udev/99-local-devcoredump.rules.in1
-rwxr-xr-xudev/devcoredump.in14
15 files changed, 2108 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c0c2bb0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,70 @@
+pkgconfig :=pkg-config
+prefix :=/usr/local
+bindir :=$(prefix)/bin
+sbindir :=$(prefix)/sbin
+crashdir :=/var/crash
+udevrulesdir :=/etc/udev/rules.d/
+unpackdir :=/tmp
+etnaviv_dir :=/shared/etna_viv
+etnaviv_inc :=$(etnaviv_dir)/src/etnaviv
+libdrm_cflags :=$(shell $(pkgconfig) --cflags libdrm)
+libdrm_ldflags :=$(shell $(pkgconfig) --libs libdrm)
+
+CPPFLAGS :=-D_GNU_SOURCE -D_LARGEFILE64_SOURCE -Iinclude
+CFLAGS_COMMON :=-O2 -Wall -std=c99
+CFLAGS =$(CFLAGS_COMMON) $(CFLAGS_$(notdir $@))
+LDLIBS =$(LDLIBS_$(notdir $@))
+SED :=sed
+SEDARGS :=s|@sbindir@|$(sbindir)|g;s|@crashdir@|$(crashdir)|g;s|@unpackdir@|$(unpackdir)|g
+BINPROGS :=bin2img detile/viv-demultitile diff/viv-cmd-diff info/viv_info
+SBINPROGS :=dump/viv-unpack udev/devcoredump
+UDEVRULES :=udev/99-local-devcoredump.rules
+PROGS :=$(BINPROGS) $(SBINPROGS) $(UDEVRULES)
+
+all: $(PROGS)
+
+install: all
+ install -m 755 -o root -g root $(SBINPROGS) $(sbindir)
+ install -m 644 -o root -g root $(UDEVRULES) $(udevrulesdir)
+ install -m 755 -o root -g root $(BINPROGS) $(bindir)
+
+uninstall:
+ $(RM) $(patsubst %,$(sbindir)/%,$(notdir $(SBINPROGS)))
+ $(RM) $(patsubst %,$(udevrulesdir)/%,$(notdir $(UDEVRULES)))
+ $(RM) $(patsubst %,$(bindir)/%,$(notdir $(BINPROGS)))
+
+clean:
+ $(RM) $(PROGS) *.[oas] */*.[oas]
+
+%: %.in
+ $(SED) "$(SEDARGS)" $< > $@
+
+info/features.h: include/hw/common.xml.h
+ { \
+ for n in chipFeatures chipMinorFeatures0 chipMinorFeatures1 chipMinorFeatures2 chipMinorFeatures3 chipMinorFeatures4; do \
+ echo "static struct feature vivante_$${n}[] __maybe_unused = {"; \
+ echo "#define FEATURE(x) { $${n}_##x, #x }"; \
+ sed -n "s/#define $${n}_\([^[:space:]]*\).*/\tFEATURE(\1),/p" $<; \
+ echo "#undef FEATURE"; \
+ echo "};"; \
+ done; \
+ } > $@
+
+detile/viv-demultitile.o: detile/viv-demultitile.c
+
+detile/viv-demultitile: detile/viv-demultitile.o
+
+diff/viv-cmd-diff.o: diff/viv-cmd-diff.c include/hw/state.xml.h
+
+diff/viv-cmd-diff: diff/viv-cmd-diff.o
+
+dump/viv-unpack.o: dump/viv-unpack.c \
+ include/hw/state.xml.h include/etnaviv_dump.h
+
+dump/viv-unpack: dump/viv-unpack.o
+
+LDLIBS_viv_info :=$(libdrm_ldflags)
+info/viv_info: info/viv_info.o
+
+CFLAGS_viv_info.o :=$(libdrm_cflags)
+info/viv_info.o: info/viv_info.c info/features.h
diff --git a/bin2img.in b/bin2img.in
new file mode 100755
index 0000000..08dbce7
--- /dev/null
+++ b/bin2img.in
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+'''
+Convert binary framebuffer to an image
+'''
+from __future__ import print_function, division, unicode_literals
+import argparse,struct
+from binascii import b2a_hex
+
+def parse_arguments():
+ parser = argparse.ArgumentParser(description='Convert binary framebuffer to an image.')
+ parser.add_argument('input', metavar='INFILE', type=str,
+ help='Texture raw file')
+ parser.add_argument('output', metavar='OUTFILE', type=str,
+ help='Output image')
+ parser.add_argument('-w', dest='img_width', type=int,
+ help='Width of image to export')
+ return parser.parse_args()
+
+def main():
+ args = parse_arguments()
+ with open(args.input, 'rb') as f:
+ data = f.read()
+
+ if args.img_width is None:
+ print('Specify width of image with -w')
+ exit(1)
+
+ width = args.img_width
+ height = len(data)//(width*4)
+
+ from PIL import Image
+ img = Image.frombuffer("RGBX", (width, height), data, "raw", "RGBX", 0, 1)
+ img = img.convert("RGB")
+ img.save(args.output)
+
+if __name__ == '__main__':
+ main()
diff --git a/detile/viv-demultitile.c b/detile/viv-demultitile.c
new file mode 100644
index 0000000..1162bef
--- /dev/null
+++ b/detile/viv-demultitile.c
@@ -0,0 +1,110 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+static void detile_gen(void *dst, void *src, unsigned int unit_size,
+ unsigned int tile_width, unsigned int tile_height,
+ unsigned int blocks_x, unsigned int blocks_y)
+{
+ unsigned int major_x, minor_x, major_y, minor_y;
+ unsigned int tile_size = tile_width * tile_height;
+ unsigned int tile_stride = tile_size * blocks_x;
+ unsigned int src_p, dst_p;
+
+ for (major_y = 0; major_y < blocks_y; major_y++) {
+ for (minor_y = 0; minor_y < tile_height; minor_y++) {
+ unsigned int dst_y = major_y * tile_height + minor_y;
+
+ for (major_x = 0; major_x < blocks_x; major_x++) {
+ for (minor_x = 0; minor_x < tile_width; minor_x++) {
+ unsigned int dst_x = major_x * tile_width + minor_x;
+ unsigned int src_maj = major_y * tile_stride + major_x * tile_size;
+ unsigned int src_min = minor_y * tile_width + minor_x;
+
+ dst_p = (dst_y * tile_width * blocks_x + dst_x) * unit_size;
+ src_p = (src_maj + src_min) * unit_size;
+ memcpy(dst + dst_p, src + src_p, unit_size);
+ }
+ }
+ }
+ }
+}
+
+static void demultitile(void *dst, void *src, unsigned ps, unsigned w, unsigned h)
+{
+ void *tmp = malloc(ps * w * h);
+ void *src_u, *src_l;
+ unsigned int tile_bytes;
+ unsigned int tile_stride;
+ unsigned int tile_w = w / 4;
+ unsigned int tile_h = h / 4;
+ int x, y;
+
+ /*
+ * u1 u2 l1 l2 u5 u6 l5 l6
+ * l3 l4 u3 u4 l7 l8 u7 u8
+ */
+
+ tile_bytes = ps * 4 * 4; /* each 4x4 tile */
+ tile_stride = tile_bytes * tile_w; /* one full row of tiles */
+
+ src_u = src;
+ src_l = src + tile_stride * tile_h / 2;
+
+ fprintf(stderr, "tile bytes = 0x%x\n", tile_bytes);
+ fprintf(stderr, "tile stride = 0x%x\n", tile_stride);
+ fprintf(stderr, "u -> l = 0x%x\n", src_l - src_u);
+
+ for (y = 0; y < tile_h / 2; y++) {
+ void *dpyu = tmp + y * 2 * tile_stride;
+ void *dpyl = dpyu + tile_stride;
+ void *spyu = src_u + y * tile_stride; /* upper half */
+ void *spyl = src_l + y * tile_stride; /* lower half */
+ for (x = 0; x < tile_w / 4; x++) {
+ void *dpu = dpyu + x * 4 * tile_bytes;
+ void *dpl = dpyl + x * 4 * tile_bytes;
+ void *spu = spyu + x * 4 * tile_bytes;
+ void *spl = spyl + x * 4 * tile_bytes;
+
+ memcpy(dpu, spu, 2 * tile_bytes);
+ memcpy(dpu + 2 * tile_bytes, spl, 2 * tile_bytes);
+ memcpy(dpl, spl + 2 * tile_bytes, 2 * tile_bytes);
+ memcpy(dpl + 2 * tile_bytes, spu + 2 * tile_bytes, 2 * tile_bytes);
+ }
+ }
+
+ detile_gen(dst, tmp, ps, 4, 4, tile_w, tile_h);
+ free(tmp);
+}
+
+static void detile(void *dst, void *src, unsigned ps, unsigned w, unsigned h)
+{
+ detile_gen(dst, src, ps, 4, 4, w / 4, h / 4);
+}
+
+int main(int argc, char *argv[])
+{
+ struct stat st;
+ void *ptr, *out;
+
+ if (fstat(0, &st) == -1) {
+ perror("failed to stat");
+ return 1;
+ }
+
+ ptr = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, 0, 0);
+ if (ptr == (void *)-1) {
+ perror("failed to mmap");
+ return 1;
+ }
+
+ out = malloc(st.st_size);
+
+ demultitile(out, ptr, 4, 256, 256);
+
+ write(1, out, st.st_size);
+ return 0;
+}
diff --git a/diff/viv-cmd-diff.c b/diff/viv-cmd-diff.c
new file mode 100644
index 0000000..c895835
--- /dev/null
+++ b/diff/viv-cmd-diff.c
@@ -0,0 +1,170 @@
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+
+#include "hw/state.xml.h"
+
+enum {
+ MAX_STATE = (0xffff + 1) * 4,
+};
+
+static uint32_t address_states[] = {
+ VIVS_FE_INDEX_STREAM_BASE_ADDR,
+ VIVS_FE_VERTEX_STREAM_BASE_ADDR,
+ 0x1410,
+ 0x1430,
+ 0x1460,
+ 0x1480,
+ 0x1608,
+ 0x1610,
+};
+
+struct state {
+ uint32_t state[MAX_STATE];
+ uint32_t draw_op[6];
+};
+
+static int read_state(int fd, struct state *state)
+{
+ uint32_t data[0x400];
+ uint32_t word[2];
+ unsigned num, addr, i;
+ int ret;
+
+ do {
+ ret = read(fd, word, sizeof(word));
+ if (ret <= 0)
+ return ret;
+ if (ret != sizeof(word))
+ return -1;
+
+ switch (word[0] >> 27) {
+ case 0:
+ break;
+ case 1: /* load state */
+ num = (word[0] >> 16) & 0x3ff;
+ addr = word[0] & 0xffff;
+ if (addr == VIVS_FE_VERTEX_ELEMENT_CONFIG(0) >> 2)
+ memset(&state->state[0x600 >> 2], 0, sizeof(uint32_t) * 16);
+ state->state[addr++] = word[1];
+ num--;
+ if (num) {
+ i = (num + 1) & ~1;
+ ret = read(fd, data, sizeof(uint32_t) * i);
+ if (ret <= 0)
+ return ret;
+ for (i = 0; i < num; i++)
+ state->state[addr++] = data[i];
+ }
+ break;
+ case 2:
+ memset(state->state, 0xaa, sizeof(state->state));
+ break;
+ case 3:
+ case 9:
+ break;
+
+ case 5:
+ ret = read(fd, data, sizeof(uint32_t) * 2);
+ if (ret <= 0)
+ return ret;
+ state->draw_op[0] = word[0];
+ state->draw_op[1] = word[1];
+ memcpy(&state->draw_op[2], data, sizeof(uint32_t) * 2);
+ state->state[VIVS_FE_INDEX_STREAM_CONTROL >> 2] = 0;
+ return 1;
+
+ case 6:
+ ret = read(fd, data, sizeof(uint32_t) * 4);
+ if (ret <= 0)
+ return ret;
+ state->draw_op[0] = word[0];
+ state->draw_op[1] = word[1];
+ memcpy(&state->draw_op[2], data, sizeof(uint32_t) * 4);
+ return 1;
+
+ default:
+ fprintf(stderr, "Unknown opcode: %08x\n", word[0]);
+ fprintf(stderr, "Position: 0x%llx\n",
+ (unsigned long long) lseek(fd, 0, SEEK_CUR));
+ return -1;
+ }
+ } while (1);
+}
+
+static int diff_files(const char *file1, const char *file2)
+{
+ struct state state[2];
+ off_t pos[2], new_pos[2];
+ int fd[2];
+
+ fd[0] = open(file1, O_RDONLY);
+ if (fd[0] == -1)
+ error(1, errno, "%s", file1);
+ fd[1] = open(file2, O_RDONLY);
+ if (fd[1] == -1)
+ error(1, errno, "%s", file2);
+
+ memset(state, 0, sizeof(state));
+
+ do {
+ int i, ret;
+
+ for (i = 0; i < 2; i++) {
+ pos[i] = lseek(fd[i], 0, SEEK_CUR);
+ if (pos[i] == (off_t)-1)
+ error(2, errno, "lseek");
+ ret = read_state(fd[i], &state[i]);
+ if (ret < 0)
+ error(2, errno, "read");
+ if (ret == 0)
+ return 0;
+ new_pos[i] = lseek(fd[i], 0, SEEK_CUR);
+ }
+
+ for (i = 0; i < sizeof(address_states) / sizeof(uint32_t); i++) {
+ uint32_t idx = address_states[i] >> 2;
+
+ state[0].state[idx] = state[1].state[idx];
+ }
+
+ memset(&state[0].state[0x1600 >> 2], 0, 0x44);
+ memset(&state[1].state[0x1600 >> 2], 0, 0x44);
+
+ if (memcmp(state[0].state, state[1].state, sizeof(state[0].state))) {
+ printf("State differences:\n"
+ " %s offset 0x%llx - 0x%llx\n"
+ " %s offset 0x%llx - 0x%llx\n",
+ file1, (unsigned long long)pos[0], (unsigned long long)new_pos[0],
+ file2, (unsigned long long)pos[1], (unsigned long long)new_pos[1]);
+ for (i = 0; i < sizeof(state[0].state) / sizeof(uint32_t); i++) {
+ if (state[0].state[i] != state[1].state[i]) {
+ printf("%05x: %08x -> %08x\n",
+ i << 2, state[0].state[i], state[1].state[i]);
+ state[1].state[i] = state[0].state[i];
+ }
+ }
+ }
+ if (memcmp(state[0].draw_op, state[1].draw_op, sizeof(state[0].draw_op))) {
+ printf("Draw op differs:\n"
+ " %s offset 0x%llx\n"
+ " %s offset 0x%llx\n",
+ file1, (unsigned long long)pos[0],
+ file2, (unsigned long long)pos[1]);
+ }
+ } while (1);
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s FILE1 FILE2\n", argv[0]);
+ return 1;
+ }
+
+ return diff_files(argv[1], argv[2]);
+}
diff --git a/dump/viv-unpack.c b/dump/viv-unpack.c
new file mode 100644
index 0000000..03c6fd7
--- /dev/null
+++ b/dump/viv-unpack.c
@@ -0,0 +1,271 @@
+#include <stdint.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "etnaviv_dump.h"
+#include "hw/state.xml.h"
+
+static const char *buf_name[] = {
+ "reg",
+ "mmu",
+ "ring",
+ "cmd",
+ "bomap",
+ "bo",
+};
+
+struct etnaviv_dump_hdr {
+ uint32_t magic;
+ uint32_t axi;
+ uint32_t idle;
+ uint32_t dma;
+ uint32_t state;
+ uint32_t last[2];
+ struct {
+ uint32_t offset;
+ uint32_t size;
+ uint32_t iova;
+ uint16_t type;
+ uint16_t map_offset;
+ } obj[0];
+};
+
+static const char idle_units[12][4] = {
+ "FE", "DE", "PE", "SH", "PA", "SE", "RA", "TX", "VG", "IM", "FP", "TS",
+};
+
+static const char *cmdstate[32] = {
+ "idle", "dec", "adr0", "load0", "adr1", "load1", "3dadr", "3dcmd",
+ "3dcntl", "3didxcntl", "initreqdma", "drawidx", "draw", "2drect0",
+ "2drect1", "2ddata0", "2ddata1", "waitfifo", "wait", "link", "end",
+ "stall",
+};
+
+static const char *cmddmastate[4] = {
+ "idle", "start", "req", "end"
+};
+
+static const char *cmdfetchstate[4] = {
+ "idle", "ramvalid", "valid", "",
+};
+
+static const char *reqdmastate[4] = {
+ "idle", "waitidx", "cal", "",
+};
+
+static const char *calstate[4] = {
+ "idle", "ldadr", "idxcalc", "",
+};
+
+static char *reg_decode(char *buf, size_t size, uint32_t reg, uint32_t val)
+{
+ unsigned int i;
+ char *p;
+
+ switch (reg) {
+ case 0x004: /* idle */
+ p = buf;
+ p += sprintf(p, "Idle:");
+ for (i = 0; i < 12; i++)
+ p += sprintf(p, " %s%c", idle_units[i],
+ val & (1 << i) ? '+' : '-');
+ return buf;
+ case 0x660: /* dma debug */
+ p = buf;
+ p += sprintf(p, "Cmd: [%s DMA: %s Fetch: %s] Req %s Cal %s",
+ cmdstate[val & 31],
+ cmddmastate[(val >> 8) & 3],
+ cmdfetchstate[(val >> 10) & 3],
+ reqdmastate[(val >> 12) & 3],
+ calstate[(val >> 14) & 3]);
+ return buf;
+ case 0x664:
+ return "Command DMA address";
+ case 0x668:
+ return "FE fetched word 0";
+ case 0x66c:
+ return "FE fetched word 1";
+ default:
+ return NULL;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ struct etnaviv_dump_object_header *hdr;
+ struct etnaviv_dump_object_header *h_regs, *h_bomap, *h_mmu;
+ struct stat st;
+ unsigned int nr_bufs, i, err;
+ uint32_t dma_addr;
+ int dump_fd, dma_buf;
+ void *file;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s DUMPFILE DIR\n", argv[0]);
+ return 1;
+ }
+
+ dump_fd = open(argv[1], O_RDONLY);
+ if (dump_fd == -1) {
+ perror("open dump file");
+ return 1;
+ }
+
+ if (fstat(dump_fd, &st) == -1) {
+ perror("fstat");
+ close(dump_fd);
+ return 1;
+ }
+
+ file = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, dump_fd, 0);
+ if (file == (void *)-1) {
+ perror("mmap");
+ close(dump_fd);
+ return 1;
+ }
+
+ close(dump_fd);
+
+ hdr = file;
+ if (hdr[0].magic != ETDUMP_MAGIC) {
+ munmap(hdr, st.st_size);
+ fprintf(stderr, "%s: invalid dump file\n",
+ argv[1]);
+ return 2;
+ }
+
+ h_mmu = NULL;
+ h_regs = NULL;
+ h_bomap = NULL;
+
+ for (nr_bufs = i = 0;
+ hdr[i].magic == ETDUMP_MAGIC && nr_bufs == 0; i++) {
+ switch (hdr[i].type) {
+ case ETDUMP_BUF_MMU:
+ h_mmu = &hdr[i];
+ break;
+
+ case ETDUMP_BUF_REG:
+ h_regs = &hdr[i];
+ break;
+
+ case ETDUMP_BUF_BOMAP:
+ h_bomap = &hdr[i];
+ break;
+
+ case ETDUMP_BUF_END:
+ nr_bufs = i;
+ break;
+ }
+ }
+
+ if (nr_bufs == 0) {
+ fprintf(stderr, "%s: no buffers\n", argv[1]);
+ return 3;
+ }
+
+ /* Parse the register dump to find the DMA address */
+ dma_addr = 0;
+ dma_buf = -1;
+ if (h_regs) {
+ struct etnaviv_dump_registers *regs = file + h_regs->file_offset;
+ unsigned int num = h_regs->file_size / sizeof(*regs);
+
+ printf("=== Register dump\n");
+ for (i = 0; i < num; i++) {
+ char buf[128], *p;
+ if (regs[i].reg == VIVS_FE_DMA_ADDRESS)
+ dma_addr = regs[i].value;
+ p = reg_decode(buf, sizeof(buf), regs[i].reg, regs[i].value);
+ printf("%08x = %08x%s%s\n",
+ regs[i].reg, regs[i].value,
+ p ? " " : "", p ? p : "");
+ }
+
+ /* Find the DMA buffer */
+ for (i = 0; i < nr_bufs; i++) {
+ if (hdr[i].type != ETDUMP_BUF_RING &&
+ hdr[i].type != ETDUMP_BUF_CMD)
+ continue;
+ if (dma_addr >= hdr[i].iova &&
+ dma_addr < hdr[i].iova + hdr[i].file_size)
+ dma_buf = i;
+ }
+ }
+
+ printf("=== Buffers\n");
+ printf(" %-3s %-5s %-8s %-8s\n", "Num", "Name", "IOVA", "Size");
+ for (i = 0; i < nr_bufs; i++) {
+ printf("%c%3u %-5s %08llx %08x %8u\n",
+ i == dma_buf ? '*' : ' ',
+ i, buf_name[hdr[i].type],
+ hdr[i].iova, hdr[i].file_size, hdr[i].file_size);
+ }
+
+ for (i = 0; i < nr_bufs; i++) {
+ char name[80];
+ int fd;
+
+ if (hdr[i].type == ETDUMP_BUF_MMU) {
+ sprintf(name, "%s/mmu.bin", argv[2]);
+ } else if (hdr[i].type == ETDUMP_BUF_BOMAP) {
+ sprintf(name, "%s/bomap.bin", argv[2]);
+ } else if (hdr[i].type == ETDUMP_BUF_RING) {
+ sprintf(name, "%s/ring.bin", argv[2]);
+ } else if (hdr[i].type == ETDUMP_BUF_CMD) {
+ if (hdr[i].iova == 0)
+ continue;
+
+ sprintf(name, "%s/cmd-%08llx.bin", argv[2],
+ hdr[i].iova);
+ } else {
+ if (hdr[i].iova == 0)
+ continue;
+
+ sprintf(name, "%s/bo-%08llx.bin", argv[2],
+ hdr[i].iova);
+ }
+
+ fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd >= 0) {
+ write(fd, file + hdr[i].file_offset,
+ hdr[i].file_size);
+ close(fd);
+ }
+ }
+
+ if (h_mmu && h_bomap) {
+ uint32_t *mmu = file + h_mmu->file_offset;
+ uint64_t *bomap = file + h_bomap->file_offset;
+
+ printf("Checking MMU entries...");
+ err = 0;
+ for (i = 0; i < nr_bufs; i++) {
+ unsigned int mmu_ofs, bm_ofs, num_pages, j;
+
+ if (hdr[i].type != ETDUMP_BUF_BO ||
+ hdr[i].iova < 0x80000000)
+ continue;
+
+ num_pages = hdr[i].file_size >> 12;
+ mmu_ofs = (hdr[i].iova - 0x80000000) >> 12;
+ bm_ofs = hdr[i].data[0];
+
+ for (j = 0; j < num_pages; j++)
+ if (mmu[mmu_ofs + j] != bomap[bm_ofs + j]) {
+ if (!err)
+ printf(" failed\n");
+ printf("Buf %u Offset %08x: %08x %08llx\n", i,
+ j << 12, mmu[mmu_ofs + j], bomap[bm_ofs + j]);
+ err = 1;
+ }
+ }
+ if (!err)
+ printf(" ok\n");
+ }
+
+ return 0;
+}
diff --git a/include/etnaviv_drm.h b/include/etnaviv_drm.h
new file mode 100644
index 0000000..3f8b91e
--- /dev/null
+++ b/include/etnaviv_drm.h
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ETNAVIV_DRM_H__
+#define __ETNAVIV_DRM_H__
+
+#define ETNAVIV_DATE_RMK 20130625
+#define ETNAVIV_DATE_PENGUTRONIX 20150302
+#define ETNAVIV_DATE_PENGUTRONIX2 20150910
+#define ETNAVIV_DATE_PENGUTRONIX3 20151126
+#define ETNAVIV_DATE_PENGUTRONIX4 20151214
+#define ETNAVIV_DATE ETNAVIV_DATE_PENGUTRONIX
+
+#include <stddef.h>
+#include "drm.h"
+
+/* Please note that modifications to all structs defined here are
+ * subject to backwards-compatibility constraints:
+ * 1) Do not use pointers, use uint64_t instead for 32 bit / 64 bit
+ * user/kernel compatibility
+ * 2) Keep fields aligned to their size
+ * 3) Because of how drm_ioctl() works, we can add new fields at
+ * the end of an ioctl if some care is taken: drm_ioctl() will
+ * zero out the new fields at the tail of the ioctl, so a zero
+ * value should have a backwards compatible meaning. And for
+ * output params, userspace won't see the newly added output
+ * fields.. so that has to be somehow ok.
+ */
+
+#define ETNADRM_PIPE_3D 0x00
+#define ETNADRM_PIPE_2D 0x01
+#define ETNADRM_PIPE_VG 0x02
+
+#if ETNAVIV_DATE == ETNAVIV_DATE_PENGUTRONIX
+#define ETNA_MAX_PIPES 4
+#else
+#define ETNA_MAX_PIPES 3
+#endif
+
+/* timeouts are specified in clock-monotonic absolute times (to simplify
+ * restarting interrupted ioctls). The following struct is logically the
+ * same as 'struct timespec' but 32/64b ABI safe.
+ */
+struct drm_etnaviv_timespec {
+ int64_t tv_sec; /* seconds */
+ int64_t tv_nsec; /* nanoseconds */
+};
+
+#define ETNAVIV_PARAM_GPU_MODEL 0x01
+#define ETNAVIV_PARAM_GPU_REVISION 0x02
+#define ETNAVIV_PARAM_GPU_FEATURES_0 0x03
+#define ETNAVIV_PARAM_GPU_FEATURES_1 0x04
+#define ETNAVIV_PARAM_GPU_FEATURES_2 0x05
+#define ETNAVIV_PARAM_GPU_FEATURES_3 0x06
+#define ETNAVIV_PARAM_GPU_FEATURES_4 0x07
+
+#define ETNAVIV_PARAM_GPU_STREAM_COUNT 0x10
+#define ETNAVIV_PARAM_GPU_REGISTER_MAX 0x11
+#define ETNAVIV_PARAM_GPU_THREAD_COUNT 0x12
+#define ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE 0x13
+#define ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT 0x14
+#define ETNAVIV_PARAM_GPU_PIXEL_PIPES 0x15
+#define ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE 0x16
+#define ETNAVIV_PARAM_GPU_BUFFER_SIZE 0x17
+#define ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT 0x18
+#define ETNAVIV_PARAM_GPU_NUM_CONSTANTS 0x19
+
+//#define MSM_PARAM_GMEM_SIZE 0x02
+
+struct drm_etnaviv_param {
+ uint32_t pipe; /* in, ETNA_PIPE_x */
+ uint32_t param; /* in, ETNAVIV_PARAM_x */
+ uint64_t value; /* out (get_param) or in (set_param) */
+};
+
+/*
+ * GEM buffers:
+ */
+
+#define ETNA_BO_CMDSTREAM 0x00000001
+#define ETNA_BO_CACHE_MASK 0x000f0000
+/* cache modes */
+#define ETNA_BO_CACHED 0x00010000
+#define ETNA_BO_WC 0x00020000
+#define ETNA_BO_UNCACHED 0x00040000
+#if ETNAVIV_DATE == ETNAVIV_DATE_PENGUTRONIX
+/* map flags */
+#define ETNA_BO_FORCE_MMU 0x00100000
+#endif
+
+struct drm_etnaviv_gem_new {
+ uint64_t size; /* in */
+ uint32_t flags; /* in, mask of ETNA_BO_x */
+ uint32_t handle; /* out */
+};
+
+struct drm_etnaviv_gem_info {
+ uint32_t handle; /* in */
+ uint32_t pad;
+ uint64_t offset; /* out, offset to pass to mmap() */
+};
+
+#define ETNA_PREP_READ 0x01
+#define ETNA_PREP_WRITE 0x02
+#define ETNA_PREP_NOSYNC 0x04
+
+struct drm_etnaviv_gem_cpu_prep {
+ uint32_t handle; /* in */
+ uint32_t op; /* in, mask of ETNA_PREP_x */
+ struct drm_etnaviv_timespec timeout; /* in */
+};
+
+struct drm_etnaviv_gem_cpu_fini {
+ uint32_t handle; /* in */
+};
+
+/*
+ * Cmdstream Submission:
+ */
+
+/* The value written into the cmdstream is logically:
+ *
+ * ((relocbuf->gpuaddr + reloc_offset) << shift) | or
+ *
+ * When we have GPU's w/ >32bit ptrs, it should be possible to deal
+ * with this by emit'ing two reloc entries with appropriate shift
+ * values. Or a new ETNA_SUBMIT_CMD_x type would also be an option.
+ *
+ * NOTE that reloc's must be sorted by order of increasing submit_offset,
+ * otherwise EINVAL.
+ */
+struct drm_etnaviv_gem_submit_reloc_r20151214 {
+ uint32_t submit_offset; /* in, offset from submit_bo */
+ uint32_t reloc_idx; /* in, index of reloc_bo buffer */
+ uint64_t reloc_offset; /* in, offset from start of reloc_bo */
+ uint32_t flags; /* in, placeholder for now */
+};
+
+struct drm_etnaviv_gem_submit_reloc_r20150302 {
+ uint32_t submit_offset; /* in, offset from submit_bo */
+ uint32_t reloc_idx; /* in, index of reloc_bo buffer */
+ uint64_t reloc_offset; /* in, offset from start of reloc_bo */
+};
+
+/* Original API */
+struct drm_etnaviv_gem_submit_reloc_r20130625 {
+ uint32_t submit_offset; /* in, offset from submit_bo */
+ uint32_t or; /* in, value OR'd with result */
+ int32_t shift; /* in, amount of left shift (can be negative) */
+ uint32_t reloc_idx; /* in, index of reloc_bo buffer */
+ uint64_t reloc_offset; /* in, offset from start of reloc_bo */
+};
+
+/* submit-types:
+ * BUF - this cmd buffer is executed normally.
+ * IB_TARGET_BUF - this cmd buffer is an IB target. Reloc's are
+ * processed normally, but the kernel does not setup an IB to
+ * this buffer in the first-level ringbuffer
+ * CTX_RESTORE_BUF - only executed if there has been a GPU context
+ * switch since the last SUBMIT ioctl
+ */
+#define ETNA_SUBMIT_CMD_BUF 0x0001
+#if ETNAVIV_DATE == ETNAVIV_DATE_PENGUTRONIX
+#define ETNA_SUBMIT_CMD_CTX_RESTORE_BUF 0x0002
+#else
+#define ETNA_SUBMIT_CMD_IB_TARGET_BUF 0x0002
+#define ETNA_SUBMIT_CMD_CTX_RESTORE_BUF 0x0003
+#endif
+struct drm_etnaviv_gem_submit_cmd_r20150302 {
+ uint32_t type; /* in, one of ETNA_SUBMIT_CMD_x */
+ uint32_t submit_idx; /* in, index of submit_bo cmdstream buffer */
+ uint32_t submit_offset; /* in, offset into submit_bo */
+ uint32_t size; /* in, cmdstream size */
+ uint32_t pad;
+ uint32_t nr_relocs; /* in, number of submit_reloc's */
+ uint64_t relocs; /* in, ptr to array of submit_reloc's */
+};
+
+struct drm_etnaviv_gem_submit_cmd_r20130625 {
+ uint32_t type; /* in, one of ETNA_SUBMIT_CMD_x */
+ uint32_t submit_idx; /* in, index of submit_bo cmdstream buffer */
+ uint32_t submit_offset; /* in, offset into submit_bo */
+ uint32_t size; /* in, cmdstream size */
+ uint32_t pad;
+ uint32_t nr_relocs; /* in, number of submit_reloc's */
+ uint64_t relocs; /* in, ptr to array of submit_reloc's */
+};
+
+/* Each buffer referenced elsewhere in the cmdstream submit (ie. the
+ * cmdstream buffer(s) themselves or reloc entries) has one (and only
+ * one) entry in the submit->bos[] table.
+ *
+ * As a optimization, the current buffer (gpu virtual address) can be
+ * passed back through the 'presumed' field. If on a subsequent reloc,
+ * userspace passes back a 'presumed' address that is still valid,
+ * then patching the cmdstream for this entry is skipped. This can
+ * avoid kernel needing to map/access the cmdstream bo in the common
+ * case.
+ */
+#define ETNA_SUBMIT_BO_READ 0x0001
+#define ETNA_SUBMIT_BO_WRITE 0x0002
+struct drm_etnaviv_gem_submit_bo {
+ uint32_t flags; /* in, mask of ETNA_SUBMIT_BO_x */
+ uint32_t handle; /* in, GEM handle */
+ uint64_t presumed; /* in/out, presumed buffer address */
+};
+
+/* Each cmdstream submit consists of a table of buffers involved, and
+ * one or more cmdstream buffers. This allows for conditional execution
+ * (context-restore), and IB buffers needed for per tile/bin draw cmds.
+ */
+struct drm_etnaviv_gem_submit_r20150910 {
+ uint32_t fence; /* out */
+ uint32_t pipe; /* in, ETNA_PIPE_x */
+ uint32_t exec_state; /* in, initial execution state (ETNA_PIPE_x) */
+ uint32_t nr_bos; /* in, number of submit_bo's */
+ uint32_t nr_relocs; /* in, number of submit_reloc's */
+ uint32_t stream_size; /* in, cmdstream size */
+ uint64_t bos; /* in, ptr to array of submit_bo's */
+ uint64_t relocs; /* in, ptr to array of submit_reloc's */
+ uint64_t stream; /* in, ptr to cmdstream */
+};
+
+struct drm_etnaviv_gem_submit_r20150302 {
+ uint32_t pipe; /* in, ETNA_PIPE_x */
+ uint32_t exec_state;
+ uint32_t fence; /* out */
+ uint32_t nr_bos; /* in, number of submit_bo's */
+ uint32_t nr_cmds; /* in, number of submit_cmd's */
+ uint32_t pad;
+ uint64_t bos; /* in, ptr to array of submit_bo's */
+ uint64_t cmds; /* in, ptr to array of submit_cmd's */
+};
+
+/* Original submission structure */
+struct drm_etnaviv_gem_submit_r20130625 {
+ uint32_t pipe; /* in, ETNA_PIPE_x */
+ uint32_t fence; /* out */
+ uint32_t nr_bos; /* in, number of submit_bo's */
+ uint32_t nr_cmds; /* in, number of submit_cmd's */
+ uint64_t bos; /* in, ptr to array of submit_bo's */
+ uint64_t cmds; /* in, ptr to array of submit_cmd's */
+};
+
+/* The normal way to synchronize with the GPU is just to CPU_PREP on
+ * a buffer if you need to access it from the CPU (other cmdstream
+ * submission from same or other contexts, PAGE_FLIP ioctl, etc, all
+ * handle the required synchronization under the hood). This ioctl
+ * mainly just exists as a way to implement the gallium pipe_fence
+ * APIs without requiring a dummy bo to synchronize on.
+ */
+struct drm_etnaviv_wait_fence_r20130625 {
+ uint32_t pipe; /* in, ETNA_PIPE_x */
+ uint32_t fence; /* in */
+ struct drm_etnaviv_timespec timeout; /* in */
+};
+
+#define ETNA_WAIT_NONBLOCK 0x01
+struct drm_etnaviv_wait_fence_r20151126 {
+ __u32 pipe; /* in */
+ __u32 fence; /* in */
+ __u32 flags; /* in, mask of ETNA_WAIT_x */
+ __u32 pad;
+ struct drm_etnaviv_timespec timeout; /* in */
+};
+
+#define ETNA_USERPTR_READ 0x01
+#define ETNA_USERPTR_WRITE 0x02
+struct drm_etnaviv_gem_userptr {
+ uint64_t user_ptr; /* in, page aligned user pointer */
+ uint64_t user_size; /* in, page aligned user size */
+ uint32_t flags; /* in, flags */
+ uint32_t handle; /* out, non-zero handle */
+};
+
+struct drm_etnaviv_gem_wait_r20130625 {
+ __u32 pipe; /* in */
+ __u32 handle; /* in, bo to be waited for */
+ struct drm_etnaviv_timespec timeout; /* in */
+};
+
+struct drm_etnaviv_gem_wait_r20151126 {
+ __u32 pipe; /* in */
+ __u32 handle; /* in, bo to be waited for */
+ __u32 flags; /* in, mask of ETNA_WAIT_x */
+ __u32 pad;
+ struct drm_etnaviv_timespec timeout; /* in */
+};
+
+#define DRM_ETNAVIV_GET_PARAM 0x00
+#define DRM_ETNAVIV_SET_PARAM 0x01
+#define DRM_ETNAVIV_GEM_NEW 0x02
+#define DRM_ETNAVIV_GEM_INFO 0x03
+#define DRM_ETNAVIV_GEM_CPU_PREP 0x04
+#define DRM_ETNAVIV_GEM_CPU_FINI 0x05
+#define DRM_ETNAVIV_GEM_SUBMIT 0x06
+#define DRM_ETNAVIV_WAIT_FENCE 0x07
+#define DRM_ETNAVIV_GEM_USERPTR 0x08
+#define DRM_ETNAVIV_GEM_WAIT 0x09
+#define DRM_ETNAVIV_NUM_IOCTLS 0x0a
+
+#define DRM_IOCTL_ETNAVIV_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GET_PARAM, struct drm_etnaviv_param)
+#define DRM_IOCTL_ETNAVIV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_NEW, struct drm_etnaviv_gem_new)
+#define DRM_IOCTL_ETNAVIV_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_INFO, struct drm_etnaviv_gem_info)
+#define DRM_IOCTL_ETNAVIV_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_CPU_PREP, struct drm_etnaviv_gem_cpu_prep)
+#define DRM_IOCTL_ETNAVIV_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_CPU_FINI, struct drm_etnaviv_gem_cpu_fini)
+#define DRM_IOCTL_ETNAVIV_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_SUBMIT, struct drm_etnaviv_gem_submit)
+#define DRM_IOCTL_ETNAVIV_WAIT_FENCE DRM_IOW (DRM_COMMAND_BASE + DRM_ETNAVIV_WAIT_FENCE, struct drm_etnaviv_wait_fence)
+#define DRM_IOCTL_ETNAVIV_GEM_WAIT DRM_IOW (DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_WAIT, struct drm_etnaviv_gem_wait)
+
+#define __STR(x) #x
+#define _STR(x) __STR(x)
+#define ETNAVIV_DATE_STR _STR(ETNAVIV_DATE)
+
+#endif /* __ETNAVIV_DRM_H__ */
diff --git a/include/etnaviv_dump.h b/include/etnaviv_dump.h
new file mode 100644
index 0000000..97f2f8d
--- /dev/null
+++ b/include/etnaviv_dump.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Etnaviv Project
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Etnaviv devcoredump file definitions
+ */
+#ifndef ETNAVIV_DUMP_H
+#define ETNAVIV_DUMP_H
+
+#include <linux/types.h>
+
+enum {
+ ETDUMP_MAGIC = 0x414e5445,
+ ETDUMP_BUF_REG = 0,
+ ETDUMP_BUF_MMU,
+ ETDUMP_BUF_RING,
+ ETDUMP_BUF_CMD,
+ ETDUMP_BUF_BOMAP,
+ ETDUMP_BUF_BO,
+ ETDUMP_BUF_END,
+};
+
+struct etnaviv_dump_object_header {
+ __le32 magic;
+ __le32 type;
+ __le32 file_offset;
+ __le32 file_size;
+ __le64 iova;
+ __le32 data[2];
+};
+
+/* Registers object, an array of these */
+struct etnaviv_dump_registers {
+ __le32 reg;
+ __le32 value;
+};
+
+#ifdef __KERNEL__
+struct etnaviv_gpu;
+void etnaviv_core_dump(struct etnaviv_gpu *gpu);
+#endif
+
+#endif
diff --git a/include/hw/common.xml.h b/include/hw/common.xml.h
new file mode 100644
index 0000000..97a7071
--- /dev/null
+++ b/include/hw/common.xml.h
@@ -0,0 +1,285 @@
+#ifndef COMMON_XML
+#define COMMON_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- state.xml ( 18940 bytes, from 2015-12-12 08:59:16)
+- common.xml ( 18379 bytes, from 2014-07-14 14:44:55)
+- state_hi.xml ( 24309 bytes, from 2015-12-12 09:02:53)
+- state_2d.xml ( 51520 bytes, from 2015-12-12 08:59:16)
+- state_3d.xml ( 54570 bytes, from 2014-07-14 14:44:55)
+- state_vg.xml ( 5942 bytes, from 2014-07-14 14:44:55)
+
+Copyright (C) 2014
+*/
+
+
+#define PIPE_ID_PIPE_3D 0x00000000
+#define PIPE_ID_PIPE_2D 0x00000001
+#define SYNC_RECIPIENT_FE 0x00000001
+#define SYNC_RECIPIENT_RA 0x00000005
+#define SYNC_RECIPIENT_PE 0x00000007
+#define SYNC_RECIPIENT_DE 0x0000000b
+#define SYNC_RECIPIENT_VG 0x0000000f
+#define SYNC_RECIPIENT_TESSELATOR 0x00000010
+#define SYNC_RECIPIENT_VG2 0x00000011
+#define SYNC_RECIPIENT_TESSELATOR2 0x00000012
+#define SYNC_RECIPIENT_VG3 0x00000013
+#define SYNC_RECIPIENT_TESSELATOR3 0x00000014
+#define ENDIAN_MODE_NO_SWAP 0x00000000
+#define ENDIAN_MODE_SWAP_16 0x00000001
+#define ENDIAN_MODE_SWAP_32 0x00000002
+#define chipModel_GC300 0x00000300
+#define chipModel_GC320 0x00000320
+#define chipModel_GC350 0x00000350
+#define chipModel_GC355 0x00000355
+#define chipModel_GC400 0x00000400
+#define chipModel_GC410 0x00000410
+#define chipModel_GC420 0x00000420
+#define chipModel_GC450 0x00000450
+#define chipModel_GC500 0x00000500
+#define chipModel_GC530 0x00000530
+#define chipModel_GC600 0x00000600
+#define chipModel_GC700 0x00000700
+#define chipModel_GC800 0x00000800
+#define chipModel_GC860 0x00000860
+#define chipModel_GC880 0x00000880
+#define chipModel_GC1000 0x00001000
+#define chipModel_GC2000 0x00002000
+#define chipModel_GC2100 0x00002100
+#define chipModel_GC4000 0x00004000
+#define RGBA_BITS_R 0x00000001
+#define RGBA_BITS_G 0x00000002
+#define RGBA_BITS_B 0x00000004
+#define RGBA_BITS_A 0x00000008
+#define chipFeatures_FAST_CLEAR 0x00000001
+#define chipFeatures_SPECIAL_ANTI_ALIASING 0x00000002
+#define chipFeatures_PIPE_3D 0x00000004
+#define chipFeatures_DXT_TEXTURE_COMPRESSION 0x00000008
+#define chipFeatures_DEBUG_MODE 0x00000010
+#define chipFeatures_Z_COMPRESSION 0x00000020
+#define chipFeatures_YUV420_SCALER 0x00000040
+#define chipFeatures_MSAA 0x00000080
+#define chipFeatures_DC 0x00000100
+#define chipFeatures_PIPE_2D 0x00000200
+#define chipFeatures_ETC1_TEXTURE_COMPRESSION 0x00000400
+#define chipFeatures_FAST_SCALER 0x00000800
+#define chipFeatures_HIGH_DYNAMIC_RANGE 0x00001000
+#define chipFeatures_YUV420_TILER 0x00002000
+#define chipFeatures_MODULE_CG 0x00004000
+#define chipFeatures_MIN_AREA 0x00008000
+#define chipFeatures_NO_EARLY_Z 0x00010000
+#define chipFeatures_NO_422_TEXTURE 0x00020000
+#define chipFeatures_BUFFER_INTERLEAVING 0x00040000
+#define chipFeatures_BYTE_WRITE_2D 0x00080000
+#define chipFeatures_NO_SCALER 0x00100000
+#define chipFeatures_YUY2_AVERAGING 0x00200000
+#define chipFeatures_HALF_PE_CACHE 0x00400000
+#define chipFeatures_HALF_TX_CACHE 0x00800000
+#define chipFeatures_YUY2_RENDER_TARGET 0x01000000
+#define chipFeatures_MEM32 0x02000000
+#define chipFeatures_PIPE_VG 0x04000000
+#define chipFeatures_VGTS 0x08000000
+#define chipFeatures_FE20 0x10000000
+#define chipFeatures_BYTE_WRITE_3D 0x20000000
+#define chipFeatures_RS_YUV_TARGET 0x40000000
+#define chipFeatures_32_BIT_INDICES 0x80000000
+#define chipMinorFeatures0_FLIP_Y 0x00000001
+#define chipMinorFeatures0_DUAL_RETURN_BUS 0x00000002
+#define chipMinorFeatures0_ENDIANNESS_CONFIG 0x00000004
+#define chipMinorFeatures0_TEXTURE_8K 0x00000008
+#define chipMinorFeatures0_CORRECT_TEXTURE_CONVERTER 0x00000010
+#define chipMinorFeatures0_SPECIAL_MSAA_LOD 0x00000020
+#define chipMinorFeatures0_FAST_CLEAR_FLUSH 0x00000040
+#define chipMinorFeatures0_2DPE20 0x00000080
+#define chipMinorFeatures0_CORRECT_AUTO_DISABLE 0x00000100
+#define chipMinorFeatures0_RENDERTARGET_8K 0x00000200
+#define chipMinorFeatures0_2BITPERTILE 0x00000400
+#define chipMinorFeatures0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED 0x00000800
+#define chipMinorFeatures0_SUPER_TILED 0x00001000
+#define chipMinorFeatures0_VG_20 0x00002000
+#define chipMinorFeatures0_TS_EXTENDED_COMMANDS 0x00004000
+#define chipMinorFeatures0_COMPRESSION_FIFO_FIXED 0x00008000
+#define chipMinorFeatures0_HAS_SIGN_FLOOR_CEIL 0x00010000
+#define chipMinorFeatures0_VG_FILTER 0x00020000
+#define chipMinorFeatures0_VG_21 0x00040000
+#define chipMinorFeatures0_SHADER_HAS_W 0x00080000
+#define chipMinorFeatures0_HAS_SQRT_TRIG 0x00100000
+#define chipMinorFeatures0_MORE_MINOR_FEATURES 0x00200000
+#define chipMinorFeatures0_MC20 0x00400000
+#define chipMinorFeatures0_MSAA_SIDEBAND 0x00800000
+#define chipMinorFeatures0_BUG_FIXES0 0x01000000
+#define chipMinorFeatures0_VAA 0x02000000
+#define chipMinorFeatures0_BYPASS_IN_MSAA 0x04000000
+#define chipMinorFeatures0_HZ 0x08000000
+#define chipMinorFeatures0_NEW_TEXTURE 0x10000000
+#define chipMinorFeatures0_2D_A8_TARGET 0x20000000
+#define chipMinorFeatures0_CORRECT_STENCIL 0x40000000
+#define chipMinorFeatures0_ENHANCE_VR 0x80000000
+#define chipMinorFeatures1_RSUV_SWIZZLE 0x00000001
+#define chipMinorFeatures1_V2_COMPRESSION 0x00000002
+#define chipMinorFeatures1_VG_DOUBLE_BUFFER 0x00000004
+#define chipMinorFeatures1_EXTRA_EVENT_STATES 0x00000008
+#define chipMinorFeatures1_NO_STRIPING_NEEDED 0x00000010
+#define chipMinorFeatures1_TEXTURE_STRIDE 0x00000020
+#define chipMinorFeatures1_BUG_FIXES3 0x00000040
+#define chipMinorFeatures1_AUTO_DISABLE 0x00000080
+#define chipMinorFeatures1_AUTO_RESTART_TS 0x00000100
+#define chipMinorFeatures1_DISABLE_PE_GATING 0x00000200
+#define chipMinorFeatures1_L2_WINDOWING 0x00000400
+#define chipMinorFeatures1_HALF_FLOAT 0x00000800
+#define chipMinorFeatures1_PIXEL_DITHER 0x00001000
+#define chipMinorFeatures1_TWO_STENCIL_REFERENCE 0x00002000
+#define chipMinorFeatures1_EXTENDED_PIXEL_FORMAT 0x00004000
+#define chipMinorFeatures1_CORRECT_MIN_MAX_DEPTH 0x00008000
+#define chipMinorFeatures1_2D_DITHER 0x00010000
+#define chipMinorFeatures1_BUG_FIXES5 0x00020000
+#define chipMinorFeatures1_NEW_2D 0x00040000
+#define chipMinorFeatures1_NEW_FP 0x00080000
+#define chipMinorFeatures1_TEXTURE_HALIGN 0x00100000
+#define chipMinorFeatures1_NON_POWER_OF_TWO 0x00200000
+#define chipMinorFeatures1_LINEAR_TEXTURE_SUPPORT 0x00400000
+#define chipMinorFeatures1_HALTI0 0x00800000
+#define chipMinorFeatures1_CORRECT_OVERFLOW_VG 0x01000000
+#define chipMinorFeatures1_NEGATIVE_LOG_FIX 0x02000000
+#define chipMinorFeatures1_RESOLVE_OFFSET 0x04000000
+#define chipMinorFeatures1_OK_TO_GATE_AXI_CLOCK 0x08000000
+#define chipMinorFeatures1_MMU_VERSION 0x10000000
+#define chipMinorFeatures1_WIDE_LINE 0x20000000
+#define chipMinorFeatures1_BUG_FIXES6 0x40000000
+#define chipMinorFeatures1_FC_FLUSH_STALL 0x80000000
+#define chipMinorFeatures2_LINE_LOOP 0x00000001
+#define chipMinorFeatures2_LOGIC_OP 0x00000002
+#define chipMinorFeatures2_UNK2 0x00000004
+#define chipMinorFeatures2_SUPERTILED_TEXTURE 0x00000008
+#define chipMinorFeatures2_UNK4 0x00000010
+#define chipMinorFeatures2_RECT_PRIMITIVE 0x00000020
+#define chipMinorFeatures2_COMPOSITION 0x00000040
+#define chipMinorFeatures2_CORRECT_AUTO_DISABLE_COUNT 0x00000080
+#define chipMinorFeatures2_UNK8 0x00000100
+#define chipMinorFeatures2_UNK9 0x00000200
+#define chipMinorFeatures2_UNK10 0x00000400
+#define chipMinorFeatures2_HALTI1 0x00000800
+#define chipMinorFeatures2_UNK12 0x00001000
+#define chipMinorFeatures2_UNK13 0x00002000
+#define chipMinorFeatures2_UNK14 0x00004000
+#define chipMinorFeatures2_EXTRA_TEXTURE_STATE 0x00008000
+#define chipMinorFeatures2_FULL_DIRECTFB 0x00010000
+#define chipMinorFeatures2_2D_TILING 0x00020000
+#define chipMinorFeatures2_THREAD_WALKER_IN_PS 0x00040000
+#define chipMinorFeatures2_TILE_FILLER 0x00080000
+#define chipMinorFeatures2_UNK20 0x00100000
+#define chipMinorFeatures2_2D_MULTI_SOURCE_BLIT 0x00200000
+#define chipMinorFeatures2_UNK22 0x00400000
+#define chipMinorFeatures2_UNK23 0x00800000
+#define chipMinorFeatures2_UNK24 0x01000000
+#define chipMinorFeatures2_MIXED_STREAMS 0x02000000
+#define chipMinorFeatures2_2D_420_L2CACHE 0x04000000
+#define chipMinorFeatures2_UNK27 0x08000000
+#define chipMinorFeatures2_2D_NO_INDEX8_BRUSH 0x10000000
+#define chipMinorFeatures2_TEXTURE_TILED_READ 0x20000000
+#define chipMinorFeatures2_UNK30 0x40000000
+#define chipMinorFeatures2_UNK31 0x80000000
+#define chipMinorFeatures3_ROTATION_STALL_FIX 0x00000001
+#define chipMinorFeatures3_UNK1 0x00000002
+#define chipMinorFeatures3_2D_MULTI_SOURCE_BLT_EX 0x00000004
+#define chipMinorFeatures3_UNK3 0x00000008
+#define chipMinorFeatures3_UNK4 0x00000010
+#define chipMinorFeatures3_UNK5 0x00000020
+#define chipMinorFeatures3_UNK6 0x00000040
+#define chipMinorFeatures3_UNK7 0x00000080
+#define chipMinorFeatures3_FAST_MSAA 0x00000100
+#define chipMinorFeatures3_UNK9 0x00000200
+#define chipMinorFeatures3_BUG_FIXES10 0x00000400
+#define chipMinorFeatures3_UNK11 0x00000800
+#define chipMinorFeatures3_BUG_FIXES11 0x00001000
+#define chipMinorFeatures3_UNK13 0x00002000
+#define chipMinorFeatures3_UNK14 0x00004000
+#define chipMinorFeatures3_UNK15 0x00008000
+#define chipMinorFeatures3_UNK16 0x00010000
+#define chipMinorFeatures3_UNK17 0x00020000
+#define chipMinorFeatures3_ACE 0x00040000
+#define chipMinorFeatures3_UNK19 0x00080000
+#define chipMinorFeatures3_UNK20 0x00100000
+#define chipMinorFeatures3_UNK21 0x00200000
+#define chipMinorFeatures3_UNK22 0x00400000
+#define chipMinorFeatures3_UNK23 0x00800000
+#define chipMinorFeatures3_UNK24 0x01000000
+#define chipMinorFeatures3_UNK25 0x02000000
+#define chipMinorFeatures3_NEW_HZ 0x04000000
+#define chipMinorFeatures3_UNK27 0x08000000
+#define chipMinorFeatures3_UNK28 0x10000000
+#define chipMinorFeatures3_UNK29 0x20000000
+#define chipMinorFeatures3_UNK30 0x40000000
+#define chipMinorFeatures3_UNK31 0x80000000
+#define chipMinorFeatures4_UNK0 0x00000001
+#define chipMinorFeatures4_UNK1 0x00000002
+#define chipMinorFeatures4_UNK2 0x00000004
+#define chipMinorFeatures4_UNK3 0x00000008
+#define chipMinorFeatures4_UNK4 0x00000010
+#define chipMinorFeatures4_UNK5 0x00000020
+#define chipMinorFeatures4_UNK6 0x00000040
+#define chipMinorFeatures4_UNK7 0x00000080
+#define chipMinorFeatures4_UNK8 0x00000100
+#define chipMinorFeatures4_UNK9 0x00000200
+#define chipMinorFeatures4_UNK10 0x00000400
+#define chipMinorFeatures4_UNK11 0x00000800
+#define chipMinorFeatures4_UNK12 0x00001000
+#define chipMinorFeatures4_UNK13 0x00002000
+#define chipMinorFeatures4_UNK14 0x00004000
+#define chipMinorFeatures4_UNK15 0x00008000
+#define chipMinorFeatures4_HALTI2 0x00010000
+#define chipMinorFeatures4_UNK17 0x00020000
+#define chipMinorFeatures4_SMALL_MSAA 0x00040000
+#define chipMinorFeatures4_UNK19 0x00080000
+#define chipMinorFeatures4_UNK20 0x00100000
+#define chipMinorFeatures4_UNK21 0x00200000
+#define chipMinorFeatures4_UNK22 0x00400000
+#define chipMinorFeatures4_UNK23 0x00800000
+#define chipMinorFeatures4_UNK24 0x01000000
+#define chipMinorFeatures4_UNK25 0x02000000
+#define chipMinorFeatures4_UNK26 0x04000000
+#define chipMinorFeatures4_UNK27 0x08000000
+#define chipMinorFeatures4_UNK28 0x10000000
+#define chipMinorFeatures4_UNK29 0x20000000
+#define chipMinorFeatures4_UNK30 0x40000000
+#define chipMinorFeatures4_UNK31 0x80000000
+#define chipMinorFeatures5_UNK0 0x00000001
+#define chipMinorFeatures5_UNK1 0x00000002
+#define chipMinorFeatures5_UNK2 0x00000004
+#define chipMinorFeatures5_UNK3 0x00000008
+#define chipMinorFeatures5_UNK4 0x00000010
+#define chipMinorFeatures5_UNK5 0x00000020
+#define chipMinorFeatures5_UNK6 0x00000040
+#define chipMinorFeatures5_UNK7 0x00000080
+#define chipMinorFeatures5_UNK8 0x00000100
+#define chipMinorFeatures5_HALTI3 0x00000200
+#define chipMinorFeatures5_UNK10 0x00000400
+#define chipMinorFeatures5_UNK11 0x00000800
+#define chipMinorFeatures5_UNK12 0x00001000
+#define chipMinorFeatures5_UNK13 0x00002000
+#define chipMinorFeatures5_UNK14 0x00004000
+#define chipMinorFeatures5_UNK15 0x00008000
+#define chipMinorFeatures5_UNK16 0x00010000
+#define chipMinorFeatures5_UNK17 0x00020000
+#define chipMinorFeatures5_UNK18 0x00040000
+#define chipMinorFeatures5_UNK19 0x00080000
+#define chipMinorFeatures5_UNK20 0x00100000
+#define chipMinorFeatures5_UNK21 0x00200000
+#define chipMinorFeatures5_UNK22 0x00400000
+#define chipMinorFeatures5_UNK23 0x00800000
+#define chipMinorFeatures5_UNK24 0x01000000
+#define chipMinorFeatures5_UNK25 0x02000000
+#define chipMinorFeatures5_UNK26 0x04000000
+#define chipMinorFeatures5_UNK27 0x08000000
+#define chipMinorFeatures5_UNK28 0x10000000
+#define chipMinorFeatures5_UNK29 0x20000000
+#define chipMinorFeatures5_UNK30 0x40000000
+#define chipMinorFeatures5_UNK31 0x80000000
+
+#endif /* COMMON_XML */
diff --git a/include/hw/state.xml.h b/include/hw/state.xml.h
new file mode 100644
index 0000000..363a8ad
--- /dev/null
+++ b/include/hw/state.xml.h
@@ -0,0 +1,351 @@
+#ifndef STATE_XML
+#define STATE_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- state.xml ( 18940 bytes, from 2015-12-12 08:59:16)
+- common.xml ( 18379 bytes, from 2014-07-14 14:44:55)
+- state_hi.xml ( 24309 bytes, from 2015-12-12 09:02:53)
+- state_2d.xml ( 51520 bytes, from 2015-12-12 08:59:16)
+- state_3d.xml ( 54570 bytes, from 2014-07-14 14:44:55)
+- state_vg.xml ( 5942 bytes, from 2014-07-14 14:44:55)
+
+Copyright (C) 2015
+*/
+
+
+#define VARYING_COMPONENT_USE_UNUSED 0x00000000
+#define VARYING_COMPONENT_USE_USED 0x00000001
+#define VARYING_COMPONENT_USE_POINTCOORD_X 0x00000002
+#define VARYING_COMPONENT_USE_POINTCOORD_Y 0x00000003
+#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK 0x000000ff
+#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT 0
+#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE(x) (((x) << FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT) & FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK)
+#define VIVS_FE 0x00000000
+
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG(i0) (0x00000600 + 0x4*(i0))
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG__ESIZE 0x00000004
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG__LEN 0x00000010
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__MASK 0x0000000f
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__SHIFT 0
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_BYTE 0x00000000
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_BYTE 0x00000001
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_SHORT 0x00000002
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_SHORT 0x00000003
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_INT 0x00000004
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_INT 0x00000005
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT 0x00000008
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_HALF_FLOAT 0x00000009
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FIXED 0x0000000b
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_INT_10_10_10_2 0x0000000c
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_INT_10_10_10_2 0x0000000d
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK 0x00000030
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT 4
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK)
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE 0x00000080
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__MASK 0x00000700
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__SHIFT 8
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM__MASK)
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__MASK 0x00003000
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__SHIFT 12
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM__MASK)
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE__MASK 0x0000c000
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE__SHIFT 14
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF 0x00000000
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_ON 0x00008000
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_START__MASK 0x00ff0000
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_START__SHIFT 16
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_START(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_START__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_START__MASK)
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_END__MASK 0xff000000
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_END__SHIFT 24
+#define VIVS_FE_VERTEX_ELEMENT_CONFIG_END(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_END__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_END__MASK)
+
+#define VIVS_FE_CMD_STREAM_BASE_ADDR 0x00000640
+
+#define VIVS_FE_INDEX_STREAM_BASE_ADDR 0x00000644
+
+#define VIVS_FE_INDEX_STREAM_CONTROL 0x00000648
+#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE__MASK 0x00000003
+#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE__SHIFT 0
+#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR 0x00000000
+#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT 0x00000001
+#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT 0x00000002
+
+#define VIVS_FE_VERTEX_STREAM_BASE_ADDR 0x0000064c
+
+#define VIVS_FE_VERTEX_STREAM_CONTROL 0x00000650
+
+#define VIVS_FE_COMMAND_ADDRESS 0x00000654
+
+#define VIVS_FE_COMMAND_CONTROL 0x00000658
+#define VIVS_FE_COMMAND_CONTROL_PREFETCH__MASK 0x0000ffff
+#define VIVS_FE_COMMAND_CONTROL_PREFETCH__SHIFT 0
+#define VIVS_FE_COMMAND_CONTROL_PREFETCH(x) (((x) << VIVS_FE_COMMAND_CONTROL_PREFETCH__SHIFT) & VIVS_FE_COMMAND_CONTROL_PREFETCH__MASK)
+#define VIVS_FE_COMMAND_CONTROL_ENABLE 0x00010000
+
+#define VIVS_FE_DMA_STATUS 0x0000065c
+
+#define VIVS_FE_DMA_DEBUG_STATE 0x00000660
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE__MASK 0x0000001f
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE__SHIFT 0
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_IDLE 0x00000000
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_DEC 0x00000001
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_ADR0 0x00000002
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_LOAD0 0x00000003
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_ADR1 0x00000004
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_LOAD1 0x00000005
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DADR 0x00000006
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DCMD 0x00000007
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DCNTL 0x00000008
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_3DIDXCNTL 0x00000009
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_INITREQDMA 0x0000000a
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_DRAWIDX 0x0000000b
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_DRAW 0x0000000c
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DRECT0 0x0000000d
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DRECT1 0x0000000e
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DDATA0 0x0000000f
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_2DDATA1 0x00000010
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_WAITFIFO 0x00000011
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_WAIT 0x00000012
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_LINK 0x00000013
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_END 0x00000014
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_STATE_STALL 0x00000015
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE__MASK 0x00000300
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE__SHIFT 8
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_IDLE 0x00000000
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_START 0x00000100
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_REQ 0x00000200
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_DMA_STATE_END 0x00000300
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE__MASK 0x00000c00
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE__SHIFT 10
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE_IDLE 0x00000000
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE_RAMVALID 0x00000400
+#define VIVS_FE_DMA_DEBUG_STATE_CMD_FETCH_STATE_VALID 0x00000800
+#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE__MASK 0x00003000
+#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE__SHIFT 12
+#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE_IDLE 0x00000000
+#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE_WAITIDX 0x00001000
+#define VIVS_FE_DMA_DEBUG_STATE_REQ_DMA_STATE_CAL 0x00002000
+#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE__MASK 0x0000c000
+#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE__SHIFT 14
+#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE_IDLE 0x00000000
+#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE_LDADR 0x00004000
+#define VIVS_FE_DMA_DEBUG_STATE_CAL_STATE_IDXCALC 0x00008000
+#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE__MASK 0x00030000
+#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE__SHIFT 16
+#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE_IDLE 0x00000000
+#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE_CKCACHE 0x00010000
+#define VIVS_FE_DMA_DEBUG_STATE_VE_REQ_STATE_MISS 0x00020000
+
+#define VIVS_FE_DMA_ADDRESS 0x00000664
+
+#define VIVS_FE_DMA_LOW 0x00000668
+
+#define VIVS_FE_DMA_HIGH 0x0000066c
+
+#define VIVS_FE_AUTO_FLUSH 0x00000670
+
+#define VIVS_FE_UNK00678 0x00000678
+
+#define VIVS_FE_UNK0067C 0x0000067c
+
+#define VIVS_FE_VERTEX_STREAMS(i0) (0x00000000 + 0x4*(i0))
+#define VIVS_FE_VERTEX_STREAMS__ESIZE 0x00000004
+#define VIVS_FE_VERTEX_STREAMS__LEN 0x00000008
+
+#define VIVS_FE_VERTEX_STREAMS_BASE_ADDR(i0) (0x00000680 + 0x4*(i0))
+
+#define VIVS_FE_VERTEX_STREAMS_CONTROL(i0) (0x000006a0 + 0x4*(i0))
+
+#define VIVS_FE_UNK00700(i0) (0x00000700 + 0x4*(i0))
+#define VIVS_FE_UNK00700__ESIZE 0x00000004
+#define VIVS_FE_UNK00700__LEN 0x00000010
+
+#define VIVS_FE_UNK00740(i0) (0x00000740 + 0x4*(i0))
+#define VIVS_FE_UNK00740__ESIZE 0x00000004
+#define VIVS_FE_UNK00740__LEN 0x00000010
+
+#define VIVS_FE_UNK00780(i0) (0x00000780 + 0x4*(i0))
+#define VIVS_FE_UNK00780__ESIZE 0x00000004
+#define VIVS_FE_UNK00780__LEN 0x00000010
+
+#define VIVS_GL 0x00000000
+
+#define VIVS_GL_PIPE_SELECT 0x00003800
+#define VIVS_GL_PIPE_SELECT_PIPE__MASK 0x00000001
+#define VIVS_GL_PIPE_SELECT_PIPE__SHIFT 0
+#define VIVS_GL_PIPE_SELECT_PIPE(x) (((x) << VIVS_GL_PIPE_SELECT_PIPE__SHIFT) & VIVS_GL_PIPE_SELECT_PIPE__MASK)
+
+#define VIVS_GL_EVENT 0x00003804
+#define VIVS_GL_EVENT_EVENT_ID__MASK 0x0000001f
+#define VIVS_GL_EVENT_EVENT_ID__SHIFT 0
+#define VIVS_GL_EVENT_EVENT_ID(x) (((x) << VIVS_GL_EVENT_EVENT_ID__SHIFT) & VIVS_GL_EVENT_EVENT_ID__MASK)
+#define VIVS_GL_EVENT_FROM_FE 0x00000020
+#define VIVS_GL_EVENT_FROM_PE 0x00000040
+#define VIVS_GL_EVENT_SOURCE__MASK 0x00001f00
+#define VIVS_GL_EVENT_SOURCE__SHIFT 8
+#define VIVS_GL_EVENT_SOURCE(x) (((x) << VIVS_GL_EVENT_SOURCE__SHIFT) & VIVS_GL_EVENT_SOURCE__MASK)
+
+#define VIVS_GL_SEMAPHORE_TOKEN 0x00003808
+#define VIVS_GL_SEMAPHORE_TOKEN_FROM__MASK 0x0000001f
+#define VIVS_GL_SEMAPHORE_TOKEN_FROM__SHIFT 0
+#define VIVS_GL_SEMAPHORE_TOKEN_FROM(x) (((x) << VIVS_GL_SEMAPHORE_TOKEN_FROM__SHIFT) & VIVS_GL_SEMAPHORE_TOKEN_FROM__MASK)
+#define VIVS_GL_SEMAPHORE_TOKEN_TO__MASK 0x00001f00
+#define VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT 8
+#define VIVS_GL_SEMAPHORE_TOKEN_TO(x) (((x) << VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT) & VIVS_GL_SEMAPHORE_TOKEN_TO__MASK)
+
+#define VIVS_GL_FLUSH_CACHE 0x0000380c
+#define VIVS_GL_FLUSH_CACHE_DEPTH 0x00000001
+#define VIVS_GL_FLUSH_CACHE_COLOR 0x00000002
+#define VIVS_GL_FLUSH_CACHE_TEXTURE 0x00000004
+#define VIVS_GL_FLUSH_CACHE_PE2D 0x00000008
+#define VIVS_GL_FLUSH_CACHE_TEXTUREVS 0x00000010
+#define VIVS_GL_FLUSH_CACHE_SHADER_L1 0x00000020
+#define VIVS_GL_FLUSH_CACHE_SHADER_L2 0x00000040
+
+#define VIVS_GL_FLUSH_MMU 0x00003810
+#define VIVS_GL_FLUSH_MMU_FLUSH_FEMMU 0x00000001
+#define VIVS_GL_FLUSH_MMU_FLUSH_UNK1 0x00000002
+#define VIVS_GL_FLUSH_MMU_FLUSH_UNK2 0x00000004
+#define VIVS_GL_FLUSH_MMU_FLUSH_PEMMU 0x00000008
+#define VIVS_GL_FLUSH_MMU_FLUSH_UNK4 0x00000010
+
+#define VIVS_GL_VERTEX_ELEMENT_CONFIG 0x00003814
+
+#define VIVS_GL_MULTI_SAMPLE_CONFIG 0x00003818
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__MASK 0x00000003
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES__SHIFT 0
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE 0x00000000
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X 0x00000001
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X 0x00000002
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_MASK 0x00000008
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__MASK 0x000000f0
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__SHIFT 4
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES(x) (((x) << VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__SHIFT) & VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES__MASK)
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_ENABLES_MASK 0x00000100
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__MASK 0x00007000
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__SHIFT 12
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12(x) (((x) << VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__SHIFT) & VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12__MASK)
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK12_MASK 0x00008000
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__MASK 0x00030000
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__SHIFT 16
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16(x) (((x) << VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__SHIFT) & VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16__MASK)
+#define VIVS_GL_MULTI_SAMPLE_CONFIG_UNK16_MASK 0x00080000
+
+#define VIVS_GL_VARYING_TOTAL_COMPONENTS 0x0000381c
+#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__MASK 0x000000ff
+#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__SHIFT 0
+#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(x) (((x) << VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__SHIFT) & VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__MASK)
+
+#define VIVS_GL_VARYING_NUM_COMPONENTS 0x00003820
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__MASK 0x00000007
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__SHIFT 0
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__MASK)
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__MASK 0x00000070
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__SHIFT 4
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__MASK)
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__MASK 0x00000700
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__SHIFT 8
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__MASK)
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__MASK 0x00007000
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__SHIFT 12
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__MASK)
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__MASK 0x00070000
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__SHIFT 16
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__MASK)
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__MASK 0x00700000
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__SHIFT 20
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__MASK)
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__MASK 0x07000000
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__SHIFT 24
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__MASK)
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__MASK 0x70000000
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__SHIFT 28
+#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__MASK)
+
+#define VIVS_GL_VARYING_COMPONENT_USE(i0) (0x00003828 + 0x4*(i0))
+#define VIVS_GL_VARYING_COMPONENT_USE__ESIZE 0x00000004
+#define VIVS_GL_VARYING_COMPONENT_USE__LEN 0x00000002
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP0__MASK 0x00000003
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP0__SHIFT 0
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP0(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP0__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP0__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP1__MASK 0x0000000c
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP1__SHIFT 2
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP1(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP1__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP1__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP2__MASK 0x00000030
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP2__SHIFT 4
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP2(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP2__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP2__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP3__MASK 0x000000c0
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP3__SHIFT 6
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP3(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP3__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP3__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP4__MASK 0x00000300
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP4__SHIFT 8
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP4(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP4__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP4__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP5__MASK 0x00000c00
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP5__SHIFT 10
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP5(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP5__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP5__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP6__MASK 0x00003000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP6__SHIFT 12
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP6(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP6__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP6__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP7__MASK 0x0000c000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP7__SHIFT 14
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP7(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP7__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP7__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP8__MASK 0x00030000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP8__SHIFT 16
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP8(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP8__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP8__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP9__MASK 0x000c0000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP9__SHIFT 18
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP9(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP9__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP9__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP10__MASK 0x00300000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP10__SHIFT 20
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP10(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP10__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP10__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP11__MASK 0x00c00000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP11__SHIFT 22
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP11(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP11__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP11__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP12__MASK 0x03000000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP12__SHIFT 24
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP12(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP12__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP12__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP13__MASK 0x0c000000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP13__SHIFT 26
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP13(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP13__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP13__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP14__MASK 0x30000000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP14__SHIFT 28
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP14(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP14__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP14__MASK)
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP15__MASK 0xc0000000
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT 30
+#define VIVS_GL_VARYING_COMPONENT_USE_COMP15(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP15__MASK)
+
+#define VIVS_GL_UNK03834 0x00003834
+
+#define VIVS_GL_UNK03838 0x00003838
+
+#define VIVS_GL_API_MODE 0x0000384c
+#define VIVS_GL_API_MODE_OPENGL 0x00000000
+#define VIVS_GL_API_MODE_OPENVG 0x00000001
+#define VIVS_GL_API_MODE_OPENCL 0x00000002
+
+#define VIVS_GL_CONTEXT_POINTER 0x00003850
+
+#define VIVS_GL_UNK03A00 0x00003a00
+
+#define VIVS_GL_STALL_TOKEN 0x00003c00
+#define VIVS_GL_STALL_TOKEN_FROM__MASK 0x0000001f
+#define VIVS_GL_STALL_TOKEN_FROM__SHIFT 0
+#define VIVS_GL_STALL_TOKEN_FROM(x) (((x) << VIVS_GL_STALL_TOKEN_FROM__SHIFT) & VIVS_GL_STALL_TOKEN_FROM__MASK)
+#define VIVS_GL_STALL_TOKEN_TO__MASK 0x00001f00
+#define VIVS_GL_STALL_TOKEN_TO__SHIFT 8
+#define VIVS_GL_STALL_TOKEN_TO(x) (((x) << VIVS_GL_STALL_TOKEN_TO__SHIFT) & VIVS_GL_STALL_TOKEN_TO__MASK)
+#define VIVS_GL_STALL_TOKEN_FLIP0 0x40000000
+#define VIVS_GL_STALL_TOKEN_FLIP1 0x80000000
+
+#define VIVS_DUMMY 0x00000000
+
+#define VIVS_DUMMY_DUMMY 0x0003fffc
+
+
+#endif /* STATE_XML */
diff --git a/info/features.h b/info/features.h
new file mode 100644
index 0000000..c1ef793
--- /dev/null
+++ b/info/features.h
@@ -0,0 +1,216 @@
+static struct feature vivante_chipFeatures[] __maybe_unused = {
+#define FEATURE(x) { chipFeatures_##x, #x }
+ FEATURE(FAST_CLEAR),
+ FEATURE(SPECIAL_ANTI_ALIASING),
+ FEATURE(PIPE_3D),
+ FEATURE(DXT_TEXTURE_COMPRESSION),
+ FEATURE(DEBUG_MODE),
+ FEATURE(Z_COMPRESSION),
+ FEATURE(YUV420_SCALER),
+ FEATURE(MSAA),
+ FEATURE(DC),
+ FEATURE(PIPE_2D),
+ FEATURE(ETC1_TEXTURE_COMPRESSION),
+ FEATURE(FAST_SCALER),
+ FEATURE(HIGH_DYNAMIC_RANGE),
+ FEATURE(YUV420_TILER),
+ FEATURE(MODULE_CG),
+ FEATURE(MIN_AREA),
+ FEATURE(NO_EARLY_Z),
+ FEATURE(NO_422_TEXTURE),
+ FEATURE(BUFFER_INTERLEAVING),
+ FEATURE(BYTE_WRITE_2D),
+ FEATURE(NO_SCALER),
+ FEATURE(YUY2_AVERAGING),
+ FEATURE(HALF_PE_CACHE),
+ FEATURE(HALF_TX_CACHE),
+ FEATURE(YUY2_RENDER_TARGET),
+ FEATURE(MEM32),
+ FEATURE(PIPE_VG),
+ FEATURE(VGTS),
+ FEATURE(FE20),
+ FEATURE(BYTE_WRITE_3D),
+ FEATURE(RS_YUV_TARGET),
+ FEATURE(32_BIT_INDICES),
+#undef FEATURE
+};
+static struct feature vivante_chipMinorFeatures0[] __maybe_unused = {
+#define FEATURE(x) { chipMinorFeatures0_##x, #x }
+ FEATURE(FLIP_Y),
+ FEATURE(DUAL_RETURN_BUS),
+ FEATURE(ENDIANNESS_CONFIG),
+ FEATURE(TEXTURE_8K),
+ FEATURE(CORRECT_TEXTURE_CONVERTER),
+ FEATURE(SPECIAL_MSAA_LOD),
+ FEATURE(FAST_CLEAR_FLUSH),
+ FEATURE(2DPE20),
+ FEATURE(CORRECT_AUTO_DISABLE),
+ FEATURE(RENDERTARGET_8K),
+ FEATURE(2BITPERTILE),
+ FEATURE(SEPARATE_TILE_STATUS_WHEN_INTERLEAVED),
+ FEATURE(SUPER_TILED),
+ FEATURE(VG_20),
+ FEATURE(TS_EXTENDED_COMMANDS),
+ FEATURE(COMPRESSION_FIFO_FIXED),
+ FEATURE(HAS_SIGN_FLOOR_CEIL),
+ FEATURE(VG_FILTER),
+ FEATURE(VG_21),
+ FEATURE(SHADER_HAS_W),
+ FEATURE(HAS_SQRT_TRIG),
+ FEATURE(MORE_MINOR_FEATURES),
+ FEATURE(MC20),
+ FEATURE(MSAA_SIDEBAND),
+ FEATURE(BUG_FIXES0),
+ FEATURE(VAA),
+ FEATURE(BYPASS_IN_MSAA),
+ FEATURE(HZ),
+ FEATURE(NEW_TEXTURE),
+ FEATURE(2D_A8_TARGET),
+ FEATURE(CORRECT_STENCIL),
+ FEATURE(ENHANCE_VR),
+#undef FEATURE
+};
+static struct feature vivante_chipMinorFeatures1[] __maybe_unused = {
+#define FEATURE(x) { chipMinorFeatures1_##x, #x }
+ FEATURE(RSUV_SWIZZLE),
+ FEATURE(V2_COMPRESSION),
+ FEATURE(VG_DOUBLE_BUFFER),
+ FEATURE(EXTRA_EVENT_STATES),
+ FEATURE(NO_STRIPING_NEEDED),
+ FEATURE(TEXTURE_STRIDE),
+ FEATURE(BUG_FIXES3),
+ FEATURE(AUTO_DISABLE),
+ FEATURE(AUTO_RESTART_TS),
+ FEATURE(DISABLE_PE_GATING),
+ FEATURE(L2_WINDOWING),
+ FEATURE(HALF_FLOAT),
+ FEATURE(PIXEL_DITHER),
+ FEATURE(TWO_STENCIL_REFERENCE),
+ FEATURE(EXTENDED_PIXEL_FORMAT),
+ FEATURE(CORRECT_MIN_MAX_DEPTH),
+ FEATURE(2D_DITHER),
+ FEATURE(BUG_FIXES5),
+ FEATURE(NEW_2D),
+ FEATURE(NEW_FP),
+ FEATURE(TEXTURE_HALIGN),
+ FEATURE(NON_POWER_OF_TWO),
+ FEATURE(LINEAR_TEXTURE_SUPPORT),
+ FEATURE(HALTI0),
+ FEATURE(CORRECT_OVERFLOW_VG),
+ FEATURE(NEGATIVE_LOG_FIX),
+ FEATURE(RESOLVE_OFFSET),
+ FEATURE(OK_TO_GATE_AXI_CLOCK),
+ FEATURE(MMU_VERSION),
+ FEATURE(WIDE_LINE),
+ FEATURE(BUG_FIXES6),
+ FEATURE(FC_FLUSH_STALL),
+#undef FEATURE
+};
+static struct feature vivante_chipMinorFeatures2[] __maybe_unused = {
+#define FEATURE(x) { chipMinorFeatures2_##x, #x }
+ FEATURE(LINE_LOOP),
+ FEATURE(LOGIC_OP),
+ FEATURE(UNK2),
+ FEATURE(SUPERTILED_TEXTURE),
+ FEATURE(UNK4),
+ FEATURE(RECT_PRIMITIVE),
+ FEATURE(COMPOSITION),
+ FEATURE(CORRECT_AUTO_DISABLE_COUNT),
+ FEATURE(UNK8),
+ FEATURE(UNK9),
+ FEATURE(UNK10),
+ FEATURE(HALTI1),
+ FEATURE(UNK12),
+ FEATURE(UNK13),
+ FEATURE(UNK14),
+ FEATURE(EXTRA_TEXTURE_STATE),
+ FEATURE(FULL_DIRECTFB),
+ FEATURE(2D_TILING),
+ FEATURE(THREAD_WALKER_IN_PS),
+ FEATURE(TILE_FILLER),
+ FEATURE(UNK20),
+ FEATURE(2D_MULTI_SOURCE_BLIT),
+ FEATURE(UNK22),
+ FEATURE(UNK23),
+ FEATURE(UNK24),
+ FEATURE(MIXED_STREAMS),
+ FEATURE(2D_420_L2CACHE),
+ FEATURE(UNK27),
+ FEATURE(2D_NO_INDEX8_BRUSH),
+ FEATURE(TEXTURE_TILED_READ),
+ FEATURE(UNK30),
+ FEATURE(UNK31),
+#undef FEATURE
+};
+static struct feature vivante_chipMinorFeatures3[] __maybe_unused = {
+#define FEATURE(x) { chipMinorFeatures3_##x, #x }
+ FEATURE(ROTATION_STALL_FIX),
+ FEATURE(UNK1),
+ FEATURE(2D_MULTI_SOURCE_BLT_EX),
+ FEATURE(UNK3),
+ FEATURE(UNK4),
+ FEATURE(UNK5),
+ FEATURE(UNK6),
+ FEATURE(UNK7),
+ FEATURE(FAST_MSAA),
+ FEATURE(UNK9),
+ FEATURE(BUG_FIXES10),
+ FEATURE(UNK11),
+ FEATURE(BUG_FIXES11),
+ FEATURE(UNK13),
+ FEATURE(UNK14),
+ FEATURE(UNK15),
+ FEATURE(UNK16),
+ FEATURE(UNK17),
+ FEATURE(ACE),
+ FEATURE(UNK19),
+ FEATURE(UNK20),
+ FEATURE(UNK21),
+ FEATURE(UNK22),
+ FEATURE(UNK23),
+ FEATURE(UNK24),
+ FEATURE(UNK25),
+ FEATURE(NEW_HZ),
+ FEATURE(UNK27),
+ FEATURE(UNK28),
+ FEATURE(UNK29),
+ FEATURE(UNK30),
+ FEATURE(UNK31),
+#undef FEATURE
+};
+static struct feature vivante_chipMinorFeatures4[] __maybe_unused = {
+#define FEATURE(x) { chipMinorFeatures4_##x, #x }
+ FEATURE(UNK0),
+ FEATURE(UNK1),
+ FEATURE(UNK2),
+ FEATURE(UNK3),
+ FEATURE(UNK4),
+ FEATURE(UNK5),
+ FEATURE(UNK6),
+ FEATURE(UNK7),
+ FEATURE(UNK8),
+ FEATURE(UNK9),
+ FEATURE(UNK10),
+ FEATURE(UNK11),
+ FEATURE(UNK12),
+ FEATURE(UNK13),
+ FEATURE(UNK14),
+ FEATURE(UNK15),
+ FEATURE(HALTI2),
+ FEATURE(UNK17),
+ FEATURE(SMALL_MSAA),
+ FEATURE(UNK19),
+ FEATURE(UNK20),
+ FEATURE(UNK21),
+ FEATURE(UNK22),
+ FEATURE(UNK23),
+ FEATURE(UNK24),
+ FEATURE(UNK25),
+ FEATURE(UNK26),
+ FEATURE(UNK27),
+ FEATURE(UNK28),
+ FEATURE(UNK29),
+ FEATURE(UNK30),
+ FEATURE(UNK31),
+#undef FEATURE
+};
diff --git a/info/viv_info.c b/info/viv_info.c
new file mode 100644
index 0000000..504ddd4
--- /dev/null
+++ b/info/viv_info.c
@@ -0,0 +1,196 @@
+/* Get info about vivante device */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <xf86drm.h>
+
+#include "etnaviv_drm.h"
+#include "hw/common.xml.h"
+
+#ifdef __GNUC__
+#define __maybe_unused __attribute__((unused))
+#else
+#define __maybe_unused
+#endif
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+struct feature {
+ uint32_t mask;
+ const char *name;
+};
+
+#include "features.h"
+
+static void print_features(uint32_t feature, const struct feature *f, size_t n)
+{
+ unsigned int i = 0;
+ while (n--) {
+ bool flag = feature & f->mask;
+ printf(" %c %2u:%-32s\n",
+ flag ? '+' : '-', i, f->name);
+ f++;
+ i++;
+ }
+ printf("\n");
+}
+
+struct param {
+ uint32_t param;
+ const char *format;
+ struct feature *tbl;
+ size_t tbl_sz;
+ void (*decode)(uint32_t value);
+};
+
+static struct param params[] = {
+ {
+ .param = ETNAVIV_PARAM_GPU_MODEL,
+ .format = "Chip model: GC%x\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_REVISION,
+ .format = "Chip revision: 0x%04x\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_FEATURES_0,
+ .format = "Chip features: 0x%08x\n",
+ .tbl = vivante_chipFeatures,
+ .tbl_sz = ARRAY_SIZE(vivante_chipFeatures),
+ }, {
+ .param = ETNAVIV_PARAM_GPU_FEATURES_1,
+ .format = "Chip minor features 0: 0x%08x\n",
+ .tbl = vivante_chipMinorFeatures0,
+ .tbl_sz = ARRAY_SIZE(vivante_chipMinorFeatures0),
+ }, {
+ .param = ETNAVIV_PARAM_GPU_FEATURES_2,
+ .format = "Chip minor features 1: 0x%08x\n",
+ .tbl = vivante_chipMinorFeatures1,
+ .tbl_sz = ARRAY_SIZE(vivante_chipMinorFeatures1),
+ }, {
+ .param = ETNAVIV_PARAM_GPU_FEATURES_3,
+ .format = "Chip minor features 2: 0x%08x\n",
+ .tbl = vivante_chipMinorFeatures2,
+ .tbl_sz = ARRAY_SIZE(vivante_chipMinorFeatures2),
+ }, {
+ .param = ETNAVIV_PARAM_GPU_FEATURES_4,
+ .format = "Chip minor features 3: 0x%08x\n",
+ .tbl = vivante_chipMinorFeatures3,
+ .tbl_sz = ARRAY_SIZE(vivante_chipMinorFeatures3),
+ }, {
+ .param = ETNAVIV_PARAM_GPU_STREAM_COUNT,
+ .format = "Stream count: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_REGISTER_MAX,
+ .format = "Register max: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_THREAD_COUNT,
+ .format = "Thread count: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT,
+ .format = "Shader core count: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE,
+ .format = "Vertex cache size: %ukB\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE,
+ .format = "Vertex output buffer size: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_PIXEL_PIPES,
+ .format = "Pixel pipes: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT,
+ .format = "Instruction count: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_NUM_CONSTANTS,
+ .format = "Num constants: %u\n",
+ }, {
+ .param = ETNAVIV_PARAM_GPU_BUFFER_SIZE,
+ .format = "Buffer size: %u\n",
+ },
+};
+
+static int open_render(void)
+{
+ drmVersionPtr version;
+ char buf[64];
+ int minor, fd, rc;
+
+ for (minor = 0; minor < 64; minor++) {
+ snprintf(buf, sizeof(buf), "%s/renderD%d",
+ DRM_DIR_NAME, 128 + minor);
+
+ fd = open(buf, O_RDWR);
+ if (fd == -1)
+ continue;
+
+ version = drmGetVersion(fd);
+ if (version) {
+ rc = strcmp(version->name, "etnaviv");
+ drmFreeVersion(version);
+
+ if (rc == 0)
+ return fd;
+ }
+
+ close(fd);
+ }
+
+ return -1;
+}
+
+static void show_one_gpu(int fd, int pipe)
+{
+ struct drm_etnaviv_param req;
+ int i;
+
+ req.pipe = pipe;
+
+ printf("********** core: %i ***********\n", pipe);
+ printf("* Chip identity:\n");
+ for (i = 0; i < ARRAY_SIZE(params); i++) {
+ uint32_t val;
+
+ req.param = params[i].param;
+ if (drmCommandWriteRead(fd, DRM_ETNAVIV_GET_PARAM, &req, sizeof(req)))
+ continue;
+
+ val = req.value;
+
+ printf(params[i].format, val);
+ if (params[i].tbl)
+ print_features(val, params[i].tbl, params[i].tbl_sz);
+ }
+ printf("\n");
+}
+
+int main()
+{
+ struct drm_etnaviv_param req;
+ int fd, pipe;
+
+ fd = open_render();
+ if (fd == -1) {
+ perror("Cannot open device");
+ exit(1);
+ }
+
+ for (pipe = 0; pipe < 5; pipe++) {
+ req.pipe = pipe;
+ req.param = ETNAVIV_PARAM_GPU_MODEL;
+ if (drmCommandWriteRead(fd, DRM_ETNAVIV_GET_PARAM, &req, sizeof(req)))
+ continue;
+
+ show_one_gpu(fd, pipe);
+ }
+
+ close(fd);
+
+ return 0;
+}
+
diff --git a/tools/hexdump-idx-16 b/tools/hexdump-idx-16
new file mode 100755
index 0000000..7b6e78c
--- /dev/null
+++ b/tools/hexdump-idx-16
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec hexdump -e '"%4.4_ax" 3/2 " %4.4x" "\n"' "$@"
diff --git a/tools/hexdump-mmu b/tools/hexdump-mmu
new file mode 100755
index 0000000..dae76de
--- /dev/null
+++ b/tools/hexdump-mmu
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec hexdump -e '"%6.6_ax" 8 " %8.8x" "\n"' $*
diff --git a/udev/99-local-devcoredump.rules.in b/udev/99-local-devcoredump.rules.in
new file mode 100644
index 0000000..47e3690
--- /dev/null
+++ b/udev/99-local-devcoredump.rules.in
@@ -0,0 +1 @@
+ACTION=="add", SUBSYSTEM=="devcoredump", RUN+="@sbindir@/devcoredump /sys/%p"
diff --git a/udev/devcoredump.in b/udev/devcoredump.in
new file mode 100755
index 0000000..70a1573
--- /dev/null
+++ b/udev/devcoredump.in
@@ -0,0 +1,14 @@
+#!/bin/sh -e
+D=`date '+%Y%m%d%H%M%S'`
+CRASHDIR="@crashdir@"
+UNPACKDIR="@unpackdir@"
+
+CRASH_BIN="$CRASHDIR/etnaviv-$D.bin"
+CRASH_DIR="$UNPACKDIR/etnaviv-$D"
+
+# Copy the crash dump
+cat "$1/data" > "$CRASH_BIN"
+
+# Unpack it into @unpackdir@
+mkdir "$CRASH_DIR"
+exec "@sbindir@/viv-unpack" "$CRASH_BIN" "$CRASH_DIR" > "$CRASH_DIR/log.txt"