Hello world test for gc7000

Change-Id: I85636dc8a29782d00c387fc43af64f82ff15c068
diff --git a/src/cmdstream_fuchsia.h b/src/cmdstream_fuchsia.h
new file mode 100644
index 0000000..d18c9de
--- /dev/null
+++ b/src/cmdstream_fuchsia.h
@@ -0,0 +1,45 @@
+#ifndef H_CMDSTREAM_FUCHSIA
+#define H_CMDSTREAM_FUCHSIA
+
+#include <stdint.h>
+
+struct etna_dev {
+    uint32_t placeholder;
+};
+
+struct etna_cmd_stream {
+    uint32_t placeholder;
+};
+
+struct etna_bo {
+    uint32_t placeholder;
+};
+
+struct drm_test_info {
+    struct etna_dev* dev;
+    struct etna_cmd_stream* stream;
+};
+
+enum {
+    ETNA_RELOC_WRITE = 1,
+    ETNA_RELOC_READ = 2,
+};
+
+enum {
+    DRM_ETNA_GEM_CACHE_UNCACHED = 1,
+};
+
+void etna_set_state(struct etna_cmd_stream *stream, uint32_t address, uint32_t value);
+void etna_set_state_from_bo(struct etna_cmd_stream *stream,
+        uint32_t address, struct etna_bo *bo, uint32_t reloc_flags);
+void etna_stall(struct etna_cmd_stream *stream, uint32_t from, uint32_t to);
+
+struct etna_bo* etna_bo_new(void* dev, uint32_t size, uint32_t flags);
+void* etna_bo_map(struct etna_bo* bo);
+
+void etna_cmd_stream_finish(struct etna_cmd_stream* stream);
+
+struct drm_test_info* drm_test_setup(int argc, char** argv);
+void drm_test_teardown(struct drm_test_info* info);
+
+#endif // H_CMDSTREAM_FUCHSIA
diff --git a/src/etnaviv_cl_test_gc7000.c b/src/etnaviv_cl_test_gc7000.c
new file mode 100644
index 0000000..96ffa12
--- /dev/null
+++ b/src/etnaviv_cl_test_gc7000.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2016 Etnaviv Project.
+ * Distributed under the MIT software license, see the accompanying
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.
+ */
+/* Basic "hello world" test */
+/* Adapted from etnaviv_cl_test_gc3000 for GC7000, Fuchsia */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(__Fuchsia__)
+#include "cmdstream_fuchsia.h"
+#else
+#include "drm_setup.h"
+#include "cmdstream.h"
+#endif
+
+#include "hw/state.xml.h"
+#include "hw/state_3d.xml.h"
+#include "hw/common.xml.h"
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+uint32_t hello_code[] = {
+/*   0: */ 0x00801000, 0x00000000, 0x00000000, 0x20000008,  /* mov  t0.x___, void, void, u0.xxxx */
+/*   2: */ 0x00801033, 0x00000800, 0x90000050, 0x7400048f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*   3: */ 0x00801033, 0x00000800, 0x900000d0, 0x7400065f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*   4: */ 0x00801033, 0x00000c00, 0x90000150, 0x740006cf,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*   5: */ 0x00801033, 0x00000c00, 0x900001d0, 0x740006cf,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*   6: */ 0x00801033, 0x00000c00, 0x90000250, 0x740006ff,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*   7: */ 0x00801033, 0x00000c00, 0x900002d0, 0x740002cf,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*   8: */ 0x00801033, 0x00000c00, 0x90000350, 0x7400020f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*   9: */ 0x00801033, 0x00000c00, 0x900003d0, 0x7400057f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*  10: */ 0x00801033, 0x00000c00, 0x90000450, 0x740006ff,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*  11: */ 0x00801033, 0x00000c00, 0x900004d0, 0x7400072f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*  12: */ 0x00801033, 0x00000c00, 0x90000550, 0x740006cf,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*  13: */ 0x00801033, 0x00000c00, 0x900005d0, 0x7400064f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*  14: */ 0x00801033, 0x00000c00, 0x90000650, 0x7400021f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*  15: */ 0x00801033, 0x00000c00, 0x900006d0, 0x7400000f,  /* store.s8 mem.x___, t0.xxxx, ?, ? */
+/*  16: */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,  /* nop  void, void, void, void */
+};
+
+static void gen_cmd_stream(struct etna_cmd_stream *stream, struct etna_bo *code, struct etna_bo *bmp)
+{
+    etna_set_state(stream, VIVS_PA_SYSTEM_MODE, VIVS_PA_SYSTEM_MODE_PROVOKING_VERTEX_LAST | VIVS_PA_SYSTEM_MODE_HALF_PIXEL_CENTER);
+    etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENCL);
+    etna_set_state(stream, VIVS_VS_HALTI5_UNK15600, 0x00000002);
+    etna_set_state(stream, VIVS_NTE_DESCRIPTOR_UNK14C40, 0x1);
+    etna_stall(stream, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+
+    etna_set_state(stream, VIVS_PS_INPUT_COUNT, VIVS_PS_INPUT_COUNT_COUNT(1) | VIVS_PS_INPUT_COUNT_UNK8(31));
+    etna_set_state(stream, VIVS_PS_TEMP_REGISTER_CONTROL, VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(4));
+    etna_set_state(stream, VIVS_VS_OUTPUT_COUNT, 0);
+    etna_set_state(stream, VIVS_CL_UNK00924, 0);
+
+    etna_set_state_from_bo(stream, VIVS_SH_HALTI5_UNIFORMS(0), bmp, ETNA_RELOC_WRITE);
+    etna_set_state(stream, VIVS_SH_HALTI5_UNIFORMS(1), 0x1100);
+
+    etna_set_state(stream, VIVS_PA_HALTI5_UNK00A90(0), VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(0x0));
+    etna_set_state(stream, VIVS_PS_HALTI5_UNK01080(0), VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(0x0));
+    etna_set_state(stream, VIVS_PS_TEMP_REGISTER_CONTROL, VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(4));
+
+    etna_set_state(stream, VIVS_PS_HALTI5_UNK01058, 0x00000000);
+    etna_set_state(stream, VIVS_PS_UNIFORM_BASE, 0x0);
+    etna_set_state(stream, VIVS_PS_NEWRANGE_LOW, 0);
+    etna_set_state(stream, VIVS_PS_NEWRANGE_HIGH, 0x10);
+
+    etna_set_state_from_bo(stream, VIVS_PS_INST_ADDR, code, ETNA_RELOC_READ);
+
+    etna_set_state(stream, VIVS_VS_HALTI5_UNK15600, 0x00000002);
+    etna_set_state(stream, VIVS_VS_ICACHE_CONTROL, 0x1);
+    etna_set_state(stream, VIVS_PS_HALTI5_UNK01094, 0xF);
+
+    etna_set_state(stream, VIVS_PS_INPUT_COUNT, 0x00001F01);
+    etna_set_state(stream, VIVS_PS_INPUT_COUNT + 0x4, 0x00000008);
+    etna_set_state(stream, VIVS_PS_INPUT_COUNT + 0x8, 0x00000F00);
+
+    etna_set_state(stream, VIVS_VS_HALTI5_UNK008A0, 0);
+    etna_set_state(stream, VIVS_PA_HALTI5_UNK00AA8, 0);
+    etna_set_state(stream, VIVS_PA_ATTRIBUTE_ELEMENT_COUNT, VIVS_PA_ATTRIBUTE_ELEMENT_COUNT_UNK0(0x0) | VIVS_PA_ATTRIBUTE_ELEMENT_COUNT_COUNT(0x0));
+    etna_set_state(stream, VIVS_GL_VARYING_TOTAL_COMPONENTS, VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(0x0));
+    etna_set_state(stream, VIVS_GL_UNK03834, 0x0);
+    etna_set_state(stream, VIVS_PS_CONTROL_EXT, 0x0);
+    etna_set_state(stream, VIVS_VS_LOAD_BALANCING, 0xF3F0000);
+    etna_set_state(stream, VIVS_VS_OUTPUT_COUNT, 1);
+    etna_set_state(stream, VIVS_GL_HALTI5_UNK03888, 0);
+    etna_set_state(stream, VIVS_PS_UNK01048, 0);
+
+    etna_set_state(stream, VIVS_CL_CONFIG, 0x03000001);
+    etna_set_state(stream, VIVS_CL_UNK00924, 0x00010000);
+    etna_set_state(stream, VIVS_CL_THREAD_ALLOCATION, 0x1);
+    etna_set_state(stream, VIVS_CL_UNK0092C, 0x0);
+    etna_set_state(stream, VIVS_CL_UNK00934, 0x0);
+    etna_set_state(stream, VIVS_CL_UNK0093C, 0x0);
+    etna_set_state(stream, VIVS_CL_HALTI5_UNK00958, 0x1);
+    etna_set_state(stream, VIVS_CL_HALTI5_UNK0095C, 0x1);
+    etna_set_state(stream, VIVS_CL_HALTI5_UNK00960, 0x1);
+
+    etna_set_state(stream, VIVS_CL_UNK00940, 0x00000000);
+    etna_set_state(stream, VIVS_CL_UNK00940 + 0x4, 0xFFFFFFFF);
+    etna_set_state(stream, VIVS_CL_UNK00940 + 0x8, 0xFFFFFFFF);
+    etna_set_state(stream, VIVS_CL_UNK00940 + 0xC, 0x00000000);
+    etna_set_state(stream, VIVS_CL_UNK00940 + 0x10, 0x000003FF);
+    etna_set_state(stream, VIVS_CL_UNK00940 + 0x14, 0x000003FF);
+
+    etna_set_state(stream, VIVS_CL_KICKER, 0xbadabeeb);
+    etna_set_state(stream, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_TEXTURE | VIVS_GL_FLUSH_CACHE_SHADER_L1);
+
+    etna_stall(stream, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+
+    etna_set_state(stream, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_DEPTH | VIVS_GL_FLUSH_CACHE_COLOR);
+}
+
+#if defined(__Fuchsia__)
+int etnaviv_cl_test_gc7000(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+    struct drm_test_info *info;
+    struct etna_bo *bmp, *code;
+    static const size_t out_size = 65536;
+    static const size_t code_size = 4096;
+    if ((info = drm_test_setup(argc, argv)) == NULL) {
+        return 1;
+    }
+
+    code = etna_bo_new(info->dev, code_size, DRM_ETNA_GEM_CACHE_UNCACHED);
+    if (!code) {
+        fprintf(stderr, "Unable to allocate buffer\n");
+        goto out;
+    }
+    memcpy(etna_bo_map(code), hello_code, sizeof(hello_code));
+
+    bmp = etna_bo_new(info->dev, out_size, DRM_ETNA_GEM_CACHE_UNCACHED);
+    if (!bmp) {
+        fprintf(stderr, "Unable to allocate buffer\n");
+        goto out;
+    }
+    memset(etna_bo_map(bmp), 0xFF, out_size);
+
+    /* generate command sequence */
+    gen_cmd_stream(info->stream, code, bmp);
+
+    etna_cmd_stream_finish(info->stream);
+
+    const unsigned char *data = etna_bo_map(bmp);
+
+    const char kHelloWorld[] = "Hello, World!";
+    if (strncmp((char*)data, kHelloWorld, sizeof(kHelloWorld)) == 0) {
+        drm_test_teardown(info);
+        return 0;
+    }
+
+    printf("Unexpected result:\n");
+    for(int i=0; i<0x100; ++i) {
+        printf("%02x ", data[i]);
+    }
+    printf("\n");
+
+out:
+    drm_test_teardown(info);
+    return 1;
+}
diff --git a/src/hw/state_3d.xml.h b/src/hw/state_3d.xml.h
index 887033f..3082538 100644
--- a/src/hw/state_3d.xml.h
+++ b/src/hw/state_3d.xml.h
@@ -351,6 +351,12 @@
 
 #define VIVS_CL_UNK00924					0x00000924
 
+#define VIVS_CL_UNK0092C					0x0000092C
+
+#define VIVS_CL_UNK00934					0x00000934
+
+#define VIVS_CL_UNK0093C					0x0000093C
+
 #define VIVS_CL_UNK00940					0x00000940
 
 #define VIVS_CL_UNK00944					0x00000944