summaryrefslogtreecommitdiffstats
path: root/tests/amdgpu
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 09:59:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 09:59:14 +0000
commit01bb4a6c21c225e55a84ac606a3b213909023ba0 (patch)
treeb5875af84ac1bd4015afede1015bb1761e5e85b3 /tests/amdgpu
parentInitial commit. (diff)
downloadlibdrm-01bb4a6c21c225e55a84ac606a3b213909023ba0.tar.xz
libdrm-01bb4a6c21c225e55a84ac606a3b213909023ba0.zip
Adding upstream version 2.4.120.upstream/2.4.120
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
l---------tests/amdgpu/.editorconfig1
-rw-r--r--tests/amdgpu/amdgpu_stress.c419
-rw-r--r--tests/amdgpu/amdgpu_test.c949
-rw-r--r--tests/amdgpu/amdgpu_test.h546
-rw-r--r--tests/amdgpu/basic_tests.c2556
-rw-r--r--tests/amdgpu/bo_tests.c317
-rw-r--r--tests/amdgpu/cp_dma_tests.c533
-rw-r--r--tests/amdgpu/cs_tests.c471
-rw-r--r--tests/amdgpu/deadlock_tests.c696
-rw-r--r--tests/amdgpu/decode_messages.h881
-rw-r--r--tests/amdgpu/frame.h1949
-rw-r--r--tests/amdgpu/hotunplug_tests.c447
-rw-r--r--tests/amdgpu/jpeg_tests.c579
-rw-r--r--tests/amdgpu/meson.build46
-rw-r--r--tests/amdgpu/ras_tests.c1003
-rw-r--r--tests/amdgpu/security_tests.c486
-rw-r--r--tests/amdgpu/shader_code.h153
-rw-r--r--tests/amdgpu/shader_code_gfx10.h202
-rw-r--r--tests/amdgpu/shader_code_gfx11.h320
-rw-r--r--tests/amdgpu/shader_code_gfx9.h204
-rw-r--r--tests/amdgpu/shader_code_hang.h104
-rw-r--r--tests/amdgpu/shader_test_util.c2156
-rw-r--r--tests/amdgpu/syncobj_tests.c314
-rw-r--r--tests/amdgpu/uvd_enc_tests.c491
-rw-r--r--tests/amdgpu/uve_ib.h527
-rw-r--r--tests/amdgpu/vce_ib.h335
-rw-r--r--tests/amdgpu/vce_tests.c764
-rw-r--r--tests/amdgpu/vcn_tests.c1652
-rw-r--r--tests/amdgpu/vm_tests.c270
29 files changed, 19371 insertions, 0 deletions
diff --git a/tests/amdgpu/.editorconfig b/tests/amdgpu/.editorconfig
new file mode 120000
index 0000000..70734e4
--- /dev/null
+++ b/tests/amdgpu/.editorconfig
@@ -0,0 +1 @@
+../../amdgpu/.editorconfig \ No newline at end of file
diff --git a/tests/amdgpu/amdgpu_stress.c b/tests/amdgpu/amdgpu_stress.c
new file mode 100644
index 0000000..f919351
--- /dev/null
+++ b/tests/amdgpu/amdgpu_stress.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "drm.h"
+#include "xf86drmMode.h"
+#include "xf86drm.h"
+#include "amdgpu.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#define MAX_CARDS_SUPPORTED 4
+#define NUM_BUFFER_OBJECTS 1024
+
+#define SDMA_PACKET(op, sub_op, e) ((((e) & 0xFFFF) << 16) | \
+ (((sub_op) & 0xFF) << 8) | \
+ (((op) & 0xFF) << 0))
+
+#define SDMA_OPCODE_COPY 1
+# define SDMA_COPY_SUB_OPCODE_LINEAR 0
+
+
+#define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \
+ (((b) & 0x1) << 26) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((cnt) & 0xFFFFF) << 0))
+#define SDMA_OPCODE_COPY_SI 3
+
+
+/** Help string for command line parameters */
+static const char usage[] =
+ "Usage: %s [-?h] [-b v|g|vg size] "
+ "[-c from to size count]\n"
+ "where:\n"
+ " b - Allocate a BO in VRAM, GTT or VRAM|GTT of size bytes.\n"
+ " This flag can be used multiple times. The first bo will\n"
+ " have id `1`, then second id `2`, ...\n"
+ " c - Copy size bytes from BO (bo_id1) to BO (bo_id2), count times\n"
+ " h - Display this help\n"
+ "\n"
+ "Sizes can be postfixes with k, m or g for kilo, mega and gigabyte scaling\n";
+
+/** Specified options strings for getopt */
+static const char options[] = "?hb:c:";
+
+/* Open AMD devices.
+ * Returns the fd of the first device it could open.
+ */
+static int amdgpu_open_device(void)
+{
+ drmDevicePtr devices[MAX_CARDS_SUPPORTED];
+ unsigned int i;
+ int drm_count;
+
+ drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED);
+ if (drm_count < 0) {
+ fprintf(stderr, "drmGetDevices2() returned an error %d\n",
+ drm_count);
+ return drm_count;
+ }
+
+ for (i = 0; i < drm_count; i++) {
+ drmVersionPtr version;
+ int fd;
+
+ /* If this is not PCI device, skip*/
+ if (devices[i]->bustype != DRM_BUS_PCI)
+ continue;
+
+ /* If this is not AMD GPU vender ID, skip*/
+ if (devices[i]->deviceinfo.pci->vendor_id != 0x1002)
+ continue;
+
+ if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER))
+ continue;
+
+ fd = open(devices[i]->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
+
+ /* This node is not available. */
+ if (fd < 0) continue;
+
+ version = drmGetVersion(fd);
+ if (!version) {
+ fprintf(stderr,
+ "Warning: Cannot get version for %s."
+ "Error is %s\n",
+ devices[i]->nodes[DRM_NODE_RENDER],
+ strerror(errno));
+ close(fd);
+ continue;
+ }
+
+ if (strcmp(version->name, "amdgpu")) {
+ /* This is not AMDGPU driver, skip.*/
+ drmFreeVersion(version);
+ close(fd);
+ continue;
+ }
+
+ drmFreeVersion(version);
+ drmFreeDevices(devices, drm_count);
+ return fd;
+ }
+
+ return -1;
+}
+
+amdgpu_device_handle device_handle;
+amdgpu_context_handle context_handle;
+
+amdgpu_bo_handle resources[NUM_BUFFER_OBJECTS];
+uint64_t virtual[NUM_BUFFER_OBJECTS];
+unsigned int num_buffers;
+uint32_t *pm4;
+
+int alloc_bo(uint32_t domain, uint64_t size)
+{
+ struct amdgpu_bo_alloc_request request = {};
+ amdgpu_bo_handle bo;
+ amdgpu_va_handle va;
+ uint64_t addr;
+ int r;
+
+ if (num_buffers >= NUM_BUFFER_OBJECTS)
+ return -ENOSPC;
+
+ request.alloc_size = size;
+ request.phys_alignment = 0;
+ request.preferred_heap = domain;
+ request.flags = 0;
+ r = amdgpu_bo_alloc(device_handle, &request, &bo);
+ if (r)
+ return r;
+
+ r = amdgpu_va_range_alloc(device_handle, amdgpu_gpu_va_range_general,
+ size, 0, 0, &addr, &va, 0);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_va_op_raw(device_handle, bo, 0, size, addr,
+ AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
+ AMDGPU_VM_PAGE_EXECUTABLE, AMDGPU_VA_OP_MAP);
+ if (r)
+ return r;
+
+ resources[num_buffers] = bo;
+ virtual[num_buffers] = addr;
+ fprintf(stdout, "Allocated BO number %u at 0x%" PRIx64 ", domain 0x%x, size %" PRIu64 "\n",
+ num_buffers++, addr, domain, size);
+ return 0;
+}
+
+int submit_ib(uint32_t from, uint32_t to, uint64_t size, uint32_t count)
+{
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_fence fence_status;
+ struct amdgpu_cs_ib_info ib_info;
+ uint64_t copied = size, delta;
+ struct timespec start, stop;
+
+ uint64_t src = virtual[from];
+ uint64_t dst = virtual[to];
+ uint32_t expired;
+ int i, r;
+
+ i = 0;
+ while (size) {
+ uint64_t bytes = size < 0x40000 ? size : 0x40000;
+
+ if (device_handle->info.family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, 0, 0, 0,
+ bytes);
+ pm4[i++] = 0xffffffff & dst;
+ pm4[i++] = 0xffffffff & src;
+ pm4[i++] = (0xffffffff00000000 & dst) >> 32;
+ pm4[i++] = (0xffffffff00000000 & src) >> 32;
+ } else {
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY,
+ SDMA_COPY_SUB_OPCODE_LINEAR,
+ 0);
+ if ( device_handle->info.family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = bytes - 1;
+ else
+ pm4[i++] = bytes;
+ pm4[i++] = 0;
+ pm4[i++] = 0xffffffff & src;
+ pm4[i++] = (0xffffffff00000000 & src) >> 32;
+ pm4[i++] = 0xffffffff & dst;
+ pm4[i++] = (0xffffffff00000000 & dst) >> 32;
+ }
+
+ size -= bytes;
+ src += bytes;
+ dst += bytes;
+ }
+
+ memset(&ib_info, 0, sizeof(ib_info));
+ ib_info.ib_mc_address = virtual[0];
+ ib_info.size = i;
+
+ memset(&ibs_request, 0, sizeof(ibs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_DMA;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = clock_gettime(CLOCK_MONOTONIC, &start);
+ if (r)
+ return errno;
+
+ r = amdgpu_bo_list_create(device_handle, num_buffers, resources, NULL,
+ &ibs_request.resources);
+ if (r)
+ return r;
+
+ for (i = 0; i < count; ++i) {
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+ }
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ memset(&fence_status, 0, sizeof(fence_status));
+ fence_status.ip_type = ibs_request.ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.ring = ibs_request.ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request.seq_no;
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ r = clock_gettime(CLOCK_MONOTONIC, &stop);
+ if (r)
+ return errno;
+
+ delta = stop.tv_nsec + stop.tv_sec * 1000000000UL;
+ delta -= start.tv_nsec + start.tv_sec * 1000000000UL;
+
+ fprintf(stdout, "Submitted %u IBs to copy from %u(%" PRIx64 ") to %u(%" PRIx64 ") %" PRIu64 " bytes took %" PRIu64 " usec\n",
+ count, from, virtual[from], to, virtual[to], copied, delta / 1000);
+ return 0;
+}
+
+void next_arg(int argc, char **argv, const char *msg)
+{
+ optarg = argv[optind++];
+ if (optind > argc || optarg[0] == '-') {
+ fprintf(stderr, "%s\n", msg);
+ exit(EXIT_FAILURE);
+ }
+}
+
+uint64_t parse_size(void)
+{
+ uint64_t size;
+ char ext[2];
+
+ ext[0] = 0;
+ if (sscanf(optarg, "%" PRIi64 "%1[kmgKMG]", &size, ext) < 1) {
+ fprintf(stderr, "Can't parse size arg: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ switch (ext[0]) {
+ case 'k':
+ case 'K':
+ size *= 1024;
+ break;
+ case 'm':
+ case 'M':
+ size *= 1024 * 1024;
+ break;
+ case 'g':
+ case 'G':
+ size *= 1024 * 1024 * 1024;
+ break;
+ default:
+ break;
+ }
+ return size;
+}
+
+int main(int argc, char **argv)
+{
+ uint32_t major_version, minor_version;
+ uint32_t domain, from, to, count;
+ uint64_t size;
+ int fd, r, c;
+
+ fd = amdgpu_open_device();
+ if (fd < 0) {
+ perror("Cannot open AMDGPU device");
+ exit(EXIT_FAILURE);
+ }
+
+ r = amdgpu_device_initialize(fd, &major_version, &minor_version, &device_handle);
+ if (r) {
+ fprintf(stderr, "amdgpu_device_initialize returned %d\n", r);
+ exit(EXIT_FAILURE);
+ }
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r) {
+ fprintf(stderr, "amdgpu_cs_ctx_create returned %d\n", r);
+ exit(EXIT_FAILURE);
+ }
+
+ if (argc == 1) {
+ fprintf(stderr, usage, argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ r = alloc_bo(AMDGPU_GEM_DOMAIN_GTT, 2ULL * 1024 * 1024);
+ if (r) {
+ fprintf(stderr, "Buffer allocation failed with %d\n", r);
+ exit(EXIT_FAILURE);
+ }
+
+ r = amdgpu_bo_cpu_map(resources[0], (void **)&pm4);
+ if (r) {
+ fprintf(stderr, "Buffer mapping failed with %d\n", r);
+ exit(EXIT_FAILURE);
+ }
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, options)) != -1) {
+ switch (c) {
+ case 'b':
+ if (!strcmp(optarg, "v"))
+ domain = AMDGPU_GEM_DOMAIN_VRAM;
+ else if (!strcmp(optarg, "g"))
+ domain = AMDGPU_GEM_DOMAIN_GTT;
+ else if (!strcmp(optarg, "vg"))
+ domain = AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT;
+ else {
+ fprintf(stderr, "Invalid domain: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ next_arg(argc, argv, "Missing buffer size");
+ size = parse_size();
+ if (size < getpagesize()) {
+ fprintf(stderr, "Buffer size to small %" PRIu64 "\n", size);
+ exit(EXIT_FAILURE);
+ }
+ r = alloc_bo(domain, size);
+ if (r) {
+ fprintf(stderr, "Buffer allocation failed with %d\n", r);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'c':
+ if (sscanf(optarg, "%u", &from) != 1) {
+ fprintf(stderr, "Can't parse from buffer: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ next_arg(argc, argv, "Missing to buffer");
+ if (sscanf(optarg, "%u", &to) != 1) {
+ fprintf(stderr, "Can't parse to buffer: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ next_arg(argc, argv, "Missing size");
+ size = parse_size();
+ next_arg(argc, argv, "Missing count");
+ count = parse_size();
+ r = submit_ib(from, to, size, count);
+ if (r) {
+ fprintf(stderr, "IB submission failed with %d\n", r);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case '?':
+ case 'h':
+ fprintf(stderr, usage, argv[0]);
+ exit(EXIT_SUCCESS);
+ default:
+ fprintf(stderr, usage, argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
new file mode 100644
index 0000000..ec78788
--- /dev/null
+++ b/tests/amdgpu/amdgpu_test.c
@@ -0,0 +1,949 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <stdarg.h>
+#include <stdint.h>
+#ifdef __linux__
+#include <linux/limits.h>
+#elif __FreeBSD__
+/* SPECNAMELEN in FreeBSD is defined here: */
+#include <sys/param.h>
+#endif
+#ifdef MAJOR_IN_MKDEV
+#include <sys/mkdev.h>
+#endif
+#ifdef MAJOR_IN_SYSMACROS
+#include <sys/sysmacros.h>
+#endif
+
+#include "drm.h"
+#include "xf86drmMode.h"
+#include "xf86drm.h"
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_internal.h"
+
+/* Test suite names */
+#define BASIC_TESTS_STR "Basic Tests"
+#define BO_TESTS_STR "BO Tests"
+#define CS_TESTS_STR "CS Tests"
+#define VCE_TESTS_STR "VCE Tests"
+#define VCN_TESTS_STR "VCN Tests"
+#define JPEG_TESTS_STR "JPEG Tests"
+#define UVD_ENC_TESTS_STR "UVD ENC Tests"
+#define DEADLOCK_TESTS_STR "Deadlock Tests"
+#define VM_TESTS_STR "VM Tests"
+#define RAS_TESTS_STR "RAS Tests"
+#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
+#define SECURITY_TESTS_STR "Security Tests"
+#define HOTUNPLUG_TESTS_STR "Hotunplug Tests"
+#define CP_DMA_TESTS_STR "CP DMA Tests"
+
+/**
+ * Open handles for amdgpu devices
+ *
+ */
+int drm_amdgpu[MAX_CARDS_SUPPORTED];
+
+/** Open render node to test */
+int open_render_node = 0; /* By default run most tests on primary node */
+
+/** The table of all known test suites to run */
+static CU_SuiteInfo suites[] = {
+ {
+ .pName = BASIC_TESTS_STR,
+ .pInitFunc = suite_basic_tests_init,
+ .pCleanupFunc = suite_basic_tests_clean,
+ .pTests = basic_tests,
+ },
+ {
+ .pName = BO_TESTS_STR,
+ .pInitFunc = suite_bo_tests_init,
+ .pCleanupFunc = suite_bo_tests_clean,
+ .pTests = bo_tests,
+ },
+ {
+ .pName = CS_TESTS_STR,
+ .pInitFunc = suite_cs_tests_init,
+ .pCleanupFunc = suite_cs_tests_clean,
+ .pTests = cs_tests,
+ },
+ {
+ .pName = VCE_TESTS_STR,
+ .pInitFunc = suite_vce_tests_init,
+ .pCleanupFunc = suite_vce_tests_clean,
+ .pTests = vce_tests,
+ },
+ {
+ .pName = VCN_TESTS_STR,
+ .pInitFunc = suite_vcn_tests_init,
+ .pCleanupFunc = suite_vcn_tests_clean,
+ .pTests = vcn_tests,
+ },
+ {
+ .pName = JPEG_TESTS_STR,
+ .pInitFunc = suite_jpeg_tests_init,
+ .pCleanupFunc = suite_jpeg_tests_clean,
+ .pTests = jpeg_tests,
+ },
+ {
+ .pName = UVD_ENC_TESTS_STR,
+ .pInitFunc = suite_uvd_enc_tests_init,
+ .pCleanupFunc = suite_uvd_enc_tests_clean,
+ .pTests = uvd_enc_tests,
+ },
+ {
+ .pName = DEADLOCK_TESTS_STR,
+ .pInitFunc = suite_deadlock_tests_init,
+ .pCleanupFunc = suite_deadlock_tests_clean,
+ .pTests = deadlock_tests,
+ },
+ {
+ .pName = VM_TESTS_STR,
+ .pInitFunc = suite_vm_tests_init,
+ .pCleanupFunc = suite_vm_tests_clean,
+ .pTests = vm_tests,
+ },
+ {
+ .pName = RAS_TESTS_STR,
+ .pInitFunc = suite_ras_tests_init,
+ .pCleanupFunc = suite_ras_tests_clean,
+ .pTests = ras_tests,
+ },
+ {
+ .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+ .pInitFunc = suite_syncobj_timeline_tests_init,
+ .pCleanupFunc = suite_syncobj_timeline_tests_clean,
+ .pTests = syncobj_timeline_tests,
+ },
+ {
+ .pName = SECURITY_TESTS_STR,
+ .pInitFunc = suite_security_tests_init,
+ .pCleanupFunc = suite_security_tests_clean,
+ .pTests = security_tests,
+ },
+ {
+ .pName = HOTUNPLUG_TESTS_STR,
+ .pInitFunc = suite_hotunplug_tests_init,
+ .pCleanupFunc = suite_hotunplug_tests_clean,
+ .pTests = hotunplug_tests,
+ },
+ {
+ .pName = CP_DMA_TESTS_STR,
+ .pInitFunc = suite_cp_dma_tests_init,
+ .pCleanupFunc = suite_cp_dma_tests_clean,
+ .pTests = cp_dma_tests,
+ },
+
+ CU_SUITE_INFO_NULL,
+};
+
+typedef CU_BOOL (*active__stat_func)(void);
+
+typedef struct Suites_Active_Status {
+ char* pName;
+ active__stat_func pActive;
+}Suites_Active_Status;
+
+static CU_BOOL always_active()
+{
+ return CU_TRUE;
+}
+
+static Suites_Active_Status suites_active_stat[] = {
+ {
+ .pName = BASIC_TESTS_STR,
+ .pActive = suite_basic_tests_enable,
+ },
+ {
+ .pName = BO_TESTS_STR,
+ .pActive = always_active,
+ },
+ {
+ .pName = CS_TESTS_STR,
+ .pActive = suite_cs_tests_enable,
+ },
+ {
+ .pName = VCE_TESTS_STR,
+ .pActive = suite_vce_tests_enable,
+ },
+ {
+ .pName = VCN_TESTS_STR,
+ .pActive = suite_vcn_tests_enable,
+ },
+ {
+ .pName = JPEG_TESTS_STR,
+ .pActive = suite_jpeg_tests_enable,
+ },
+ {
+ .pName = UVD_ENC_TESTS_STR,
+ .pActive = suite_uvd_enc_tests_enable,
+ },
+ {
+ .pName = DEADLOCK_TESTS_STR,
+ .pActive = suite_deadlock_tests_enable,
+ },
+ {
+ .pName = VM_TESTS_STR,
+ .pActive = suite_vm_tests_enable,
+ },
+ {
+ .pName = RAS_TESTS_STR,
+ .pActive = suite_ras_tests_enable,
+ },
+ {
+ .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+ .pActive = suite_syncobj_timeline_tests_enable,
+ },
+ {
+ .pName = SECURITY_TESTS_STR,
+ .pActive = suite_security_tests_enable,
+ },
+ {
+ .pName = HOTUNPLUG_TESTS_STR,
+ .pActive = suite_hotunplug_tests_enable,
+ },
+ {
+ .pName = CP_DMA_TESTS_STR,
+ .pActive = suite_cp_dma_tests_enable,
+ },
+};
+
+
+/*
+ * Display information about all suites and their tests
+ *
+ * NOTE: Must be run after registry is initialized and suites registered.
+ */
+static void display_test_suites(void)
+{
+ int iSuite;
+ int iTest;
+ CU_pSuite pSuite = NULL;
+ CU_pTest pTest = NULL;
+
+ printf("%5s: %2s: %8s: %s\n", "What", "ID", "Status", "Name");
+
+ for (iSuite = 0; suites[iSuite].pName != NULL; iSuite++) {
+
+ pSuite = CU_get_suite_by_index((unsigned int) iSuite + 1,
+ CU_get_registry());
+
+ if (!pSuite) {
+ fprintf(stderr, "Invalid suite id : %d\n", iSuite + 1);
+ continue;
+ }
+
+ printf("Suite: %2d: %8s: %s\n",
+ iSuite + 1,
+ pSuite->fActive ? "ENABLED" : "DISABLED",
+ suites[iSuite].pName);
+
+ if (!pSuite->fActive)
+ continue;
+
+ for (iTest = 0; suites[iSuite].pTests[iTest].pName != NULL;
+ iTest++) {
+ pTest = CU_get_test_by_index((unsigned int) iTest + 1,
+ pSuite);
+ if (!pTest) {
+ fprintf(stderr, "Invalid test id : %d\n", iTest + 1);
+ continue;
+ }
+ printf(" Test: %2d: %8s: %s\n",
+ iTest + 1,
+ pSuite->fActive && pTest->fActive ? "ENABLED" : "DISABLED",
+ suites[iSuite].pTests[iTest].pName);
+ }
+ }
+}
+
+/** Help string for command line parameters */
+static const char usage[] =
+ "Usage: %s [-hlpr] [-s <suite id>] [-e <s>[.<t>] [-e ...]] [-t <test id>] [-f] "
+ "[-b <pci_bus_id>] [-d <pci_device_id>]\n"
+ "Where,\n"
+ " -b Specify device's PCI bus id to run tests\n"
+ " -d Specify device's PCI device id to run tests (optional)\n"
+ " -e <s>[.<t>] Disable test <t> of suite <s>. If only <s> is given, then disable\n"
+ " the whole suite. Can be specified more than once on the command line\n"
+ " to disable multiple tests or suites.\n"
+ " -f Force executing inactive suite or test\n"
+ " -h Display this help\n"
+ " -l Display all test suites and their tests\n"
+ " -p Display information of AMDGPU devices in system\n"
+ " -r Run the tests on render node\n"
+ " -s <s> Enable only test suite <s>\n"
+ " -t <t> Enable only test <t> of test suite <s>\n";
+/** Specified options strings for getopt */
+static const char options[] = "hlrps:t:e:b:d:f";
+
+/* Open AMD devices.
+ * Return the number of AMD device opened.
+ */
+static int amdgpu_open_devices(int open_render_node)
+{
+ drmDevicePtr devices[MAX_CARDS_SUPPORTED];
+ int i;
+ int drm_node;
+ int amd_index = 0;
+ int drm_count;
+ int fd;
+ drmVersionPtr version;
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED; i++) {
+ drm_amdgpu[i] = -1;
+ }
+
+ drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED);
+
+ if (drm_count < 0) {
+ fprintf(stderr,
+ "drmGetDevices2() returned an error %d\n",
+ drm_count);
+ return 0;
+ }
+
+ for (i = 0; i < drm_count; i++) {
+ /* If this is not PCI device, skip*/
+ if (devices[i]->bustype != DRM_BUS_PCI)
+ continue;
+
+ /* If this is not AMD GPU vender ID, skip*/
+ if (devices[i]->deviceinfo.pci->vendor_id != 0x1002)
+ continue;
+
+ if (open_render_node)
+ drm_node = DRM_NODE_RENDER;
+ else
+ drm_node = DRM_NODE_PRIMARY;
+
+ fd = -1;
+ if (devices[i]->available_nodes & 1 << drm_node)
+ fd = open(
+ devices[i]->nodes[drm_node],
+ O_RDWR | O_CLOEXEC);
+
+ /* This node is not available. */
+ if (fd < 0) continue;
+
+ version = drmGetVersion(fd);
+ if (!version) {
+ fprintf(stderr,
+ "Warning: Cannot get version for %s."
+ "Error is %s\n",
+ devices[i]->nodes[drm_node],
+ strerror(errno));
+ close(fd);
+ continue;
+ }
+
+ if (strcmp(version->name, "amdgpu")) {
+ /* This is not AMDGPU driver, skip.*/
+ drmFreeVersion(version);
+ close(fd);
+ continue;
+ }
+
+ drmFreeVersion(version);
+
+ drm_amdgpu[amd_index] = fd;
+ amd_index++;
+ }
+
+ drmFreeDevices(devices, drm_count);
+ return amd_index;
+}
+
+/* Close AMD devices.
+ */
+void amdgpu_close_devices()
+{
+ int i;
+ for (i = 0; i < MAX_CARDS_SUPPORTED; i++)
+ if (drm_amdgpu[i] >=0) {
+ close(drm_amdgpu[i]);
+ }
+}
+
+/* Print AMD devices information */
+static void amdgpu_print_devices()
+{
+ int i;
+ drmDevicePtr device;
+
+ /* Open the first AMD device to print driver information. */
+ if (drm_amdgpu[0] >=0) {
+ /* Display AMD driver version information.*/
+ drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]);
+
+ if (retval == NULL) {
+ perror("Cannot get version for AMDGPU device");
+ return;
+ }
+
+ printf("Driver name: %s, Date: %s, Description: %s.\n",
+ retval->name, retval->date, retval->desc);
+ drmFreeVersion(retval);
+ }
+
+ /* Display information of AMD devices */
+ printf("Devices:\n");
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++)
+ if (drmGetDevice2(drm_amdgpu[i],
+ DRM_DEVICE_GET_PCI_REVISION,
+ &device) == 0) {
+ if (device->bustype == DRM_BUS_PCI) {
+ printf("PCI ");
+ printf(" domain:%04x",
+ device->businfo.pci->domain);
+ printf(" bus:%02x",
+ device->businfo.pci->bus);
+ printf(" device:%02x",
+ device->businfo.pci->dev);
+ printf(" function:%01x",
+ device->businfo.pci->func);
+ printf(" vendor_id:%04x",
+ device->deviceinfo.pci->vendor_id);
+ printf(" device_id:%04x",
+ device->deviceinfo.pci->device_id);
+ printf(" subvendor_id:%04x",
+ device->deviceinfo.pci->subvendor_id);
+ printf(" subdevice_id:%04x",
+ device->deviceinfo.pci->subdevice_id);
+ printf(" revision_id:%02x",
+ device->deviceinfo.pci->revision_id);
+ printf("\n");
+ }
+ drmFreeDevice(&device);
+ }
+}
+
+/* Find a match AMD device in PCI bus
+ * Return the index of the device or -1 if not found
+ */
+static int amdgpu_find_device(uint8_t bus, uint16_t dev)
+{
+ int i;
+ drmDevicePtr device;
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
+ if (drmGetDevice2(drm_amdgpu[i],
+ DRM_DEVICE_GET_PCI_REVISION,
+ &device) == 0) {
+ if (device->bustype == DRM_BUS_PCI)
+ if ((bus == 0xFF || device->businfo.pci->bus == bus) &&
+ device->deviceinfo.pci->device_id == dev) {
+ drmFreeDevice(&device);
+ return i;
+ }
+
+ drmFreeDevice(&device);
+ }
+ }
+
+ return -1;
+}
+
+static void amdgpu_disable_suites()
+{
+ amdgpu_device_handle device_handle;
+ uint32_t major_version, minor_version, family_id;
+ drmDevicePtr devices[MAX_CARDS_SUPPORTED];
+ int i, drm_count;
+ int size = sizeof(suites_active_stat) / sizeof(suites_active_stat[0]);
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return;
+
+ family_id = device_handle->info.family_id;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return;
+
+ drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED);
+
+ /* Set active status for suites based on their policies */
+ for (i = 0; i < size; ++i)
+ if (amdgpu_set_suite_active(suites_active_stat[i].pName,
+ suites_active_stat[i].pActive()))
+ fprintf(stderr, "suite deactivation failed - %s\n", CU_get_error_msg());
+
+ /* Explicitly disable specific tests due to known bugs or preferences */
+ /*
+ * BUG: Compute ring stalls and never recovers when the address is
+ * written after the command already submitted
+ */
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "compute ring block test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "sdma ring block test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "sdma ring corrupted header test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "sdma ring slow linear copy test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "bo eviction Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX8 and GFX9 only */
+ if (family_id < AMDGPU_FAMILY_VI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Sync dependency Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) {
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (GFX)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (Compute)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+ }
+
+ /* This test was ran on GFX9 only */
+ if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Draw Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "GPU reset Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* You need at least 2 devices for this */
+ if (drm_count < 2)
+ if (amdgpu_set_test_active(HOTUNPLUG_TESTS_STR, "Unplug with exported fence", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+}
+
+int test_device_index;
+
+int amdgpu_open_device_on_test_index(int render_node)
+{
+ int i;
+
+ if (amdgpu_open_devices(open_render_node) <= 0) {
+ perror("Cannot open AMDGPU device");
+ return -1;
+ }
+
+ if (test_device_index >= 0) {
+ /* Most tests run on device of drm_amdgpu[0].
+ * Swap the chosen device to drm_amdgpu[0].
+ */
+ i = drm_amdgpu[0];
+ drm_amdgpu[0] = drm_amdgpu[test_device_index];
+ drm_amdgpu[test_device_index] = i;
+ }
+
+ return 0;
+
+
+}
+
+
+static bool amdgpu_node_is_drm(int maj, int min)
+{
+#ifdef __linux__
+ char path[64];
+ struct stat sbuf;
+
+ snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm",
+ maj, min);
+ return stat(path, &sbuf) == 0;
+#elif defined(__FreeBSD__)
+ char name[SPECNAMELEN];
+
+ if (!devname_r(makedev(maj, min), S_IFCHR, name, sizeof(name)))
+ return 0;
+ /* Handle drm/ and dri/ as both are present in different FreeBSD version
+ * FreeBSD on amd64/i386/powerpc external kernel modules create node in
+ * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
+ * only device nodes in /dev/dri/ */
+ return (!strncmp(name, "drm/", 4) || !strncmp(name, "dri/", 4));
+#else
+ return maj == DRM_MAJOR;
+#endif
+}
+
+char *amdgpu_get_device_from_fd(int fd)
+{
+#ifdef __linux__
+ struct stat sbuf;
+ char path[PATH_MAX + 1];
+ unsigned int maj, min;
+
+ if (fstat(fd, &sbuf))
+ return NULL;
+
+ maj = major(sbuf.st_rdev);
+ min = minor(sbuf.st_rdev);
+
+ if (!amdgpu_node_is_drm(maj, min) || !S_ISCHR(sbuf.st_mode))
+ return NULL;
+
+ snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+ return strdup(path);
+#else
+ return NULL;
+#endif
+}
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(_A) (sizeof(_A)/sizeof(_A[0]))
+#endif
+
+static void amdgpu_test_disable(long suite, long test)
+{
+ const char *suite_name;
+
+ if (suite < 1)
+ return;
+
+ /* The array is 0-based, so subract 1. */
+ suite--;
+ if (suite >= ARRAY_SIZE(suites) - 1)
+ return;
+
+ suite_name = suites[suite].pName;
+ if (test < 1) {
+ fprintf(stderr, "Deactivating suite %s\n", suite_name);
+ amdgpu_set_suite_active(suite_name, CU_FALSE);
+ } else {
+ int ii;
+
+ /* The array is 0-based so subtract 1. */
+ test--;
+ for (ii = 0; suites[suite].pTests[ii].pName; ii++) {
+ if (ii == test) {
+ fprintf(stderr, "Deactivating %s:%s\n",
+ suite_name,
+ suites[suite].pTests[ii].pName);
+ amdgpu_set_test_active(suite_name,
+ suites[suite].pTests[ii].pName,
+ CU_FALSE);
+ break;
+ }
+ }
+
+ if (suites[suite].pTests[ii].pName == NULL)
+ fprintf(stderr, "No such suite.test %ld.%ld\n", suite, test);
+ }
+}
+
+/* The main() function for setting up and running the tests.
+ * Returns a CUE_SUCCESS on successful running, another
+ * CUnit error code on failure.
+ */
+int main(int argc, char **argv)
+{
+ int c; /* Character received from getopt */
+ int i = 0;
+ int suite_id = -1; /* By default run everything */
+ int test_id = -1; /* By default run all tests in the suite */
+ int pci_bus_id = -1; /* By default PC bus ID is not specified */
+ int pci_device_id = 0; /* By default PC device ID is zero */
+ int display_devices = 0;/* By default not to display devices' info */
+ CU_pSuite pSuite = NULL;
+ CU_pTest pTest = NULL;
+ int display_list = 0;
+ int force_run = 0;
+
+ /* Parse command line string.
+ * Process various command line options as early as possible.
+ */
+ opterr = 0; /* Do not print error messages from getopt */
+ while ((c = getopt(argc, argv, options)) != -1) {
+ switch (c) {
+ case 'h':
+ fprintf(stderr, usage, argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED; i++)
+ drm_amdgpu[i] = -1;
+
+ if (amdgpu_open_devices(open_render_node) <= 0) {
+ perror("Cannot open AMDGPU device");
+ exit(EXIT_FAILURE);
+ }
+
+ if (drm_amdgpu[0] < 0) {
+ perror("Cannot open AMDGPU device");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Parse command line string */
+ opterr = 0; /* Do not print error messages from getopt */
+ optind = 1;
+ while ((c = getopt(argc, argv, options)) != -1) {
+ switch (c) {
+ case 'p':
+ display_devices = 1;
+ break;
+ }
+ }
+
+ if (display_devices) {
+ amdgpu_print_devices();
+ amdgpu_close_devices();
+ exit(EXIT_SUCCESS);
+ }
+
+ /* Parse command line string */
+ opterr = 0; /* Do not print error messages from getopt */
+ optind = 1;
+ while ((c = getopt(argc, argv, options)) != -1) {
+ switch (c) {
+ case 'b':
+ pci_bus_id = atoi(optarg);
+ break;
+ case 'd':
+ sscanf(optarg, "%x", &pci_device_id);
+ break;
+ }
+ }
+
+ if (pci_bus_id > 0 || pci_device_id) {
+ /* A device was specified to run the test */
+ test_device_index = amdgpu_find_device(pci_bus_id,
+ pci_device_id);
+
+ if (test_device_index >= 0) {
+ /* Most tests run on device of drm_amdgpu[0].
+ * Swap the chosen device to drm_amdgpu[0].
+ */
+ i = drm_amdgpu[0];
+ drm_amdgpu[0] = drm_amdgpu[test_device_index];
+ drm_amdgpu[test_device_index] = i;
+ } else {
+ fprintf(stderr,
+ "The specified GPU device does not exist.\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Initialize test suites to run */
+
+ /* initialize the CUnit test registry */
+ if (CUE_SUCCESS != CU_initialize_registry()) {
+ amdgpu_close_devices();
+ return CU_get_error();
+ }
+
+ /* Register suites. */
+ if (CU_register_suites(suites) != CUE_SUCCESS) {
+ fprintf(stderr, "suite registration failed - %s\n",
+ CU_get_error_msg());
+ CU_cleanup_registry();
+ amdgpu_close_devices();
+ exit(EXIT_FAILURE);
+ }
+
+ /* Run tests using the CUnit Basic interface */
+ CU_basic_set_mode(CU_BRM_VERBOSE);
+
+ /* Disable suites and individual tests based on misc. conditions */
+ amdgpu_disable_suites();
+
+ /* Parse command line string */
+ opterr = 0; /* Do not print error messages from getopt */
+ optind = 1;
+ while ((c = getopt(argc, argv, options)) != -1) {
+ switch (c) {
+ case 'l':
+ display_list = 1;
+ break;
+ }
+ }
+
+ if (display_list) {
+ display_test_suites();
+ goto end;
+ }
+
+ /* Parse command line string */
+ opterr = 0; /* Do not print error messages from getopt */
+ optind = 1;
+ while ((c = getopt(argc, argv, options)) != -1) {
+ long esuite = -1;
+ long etest = -1;
+ char *endp;
+ switch (c) {
+ case 's':
+ suite_id = atoi(optarg);
+ break;
+ case 't':
+ test_id = atoi(optarg);
+ break;
+ case 'r':
+ open_render_node = 1;
+ break;
+ case 'f':
+ force_run = 1;
+ break;
+ case 'e':
+ esuite = strtol(optarg, &endp, 0);
+ if (endp == optarg) {
+ fprintf(stderr, "No digits given for -e argument\n");
+ goto end;
+ } else if (endp && *endp == '.' && esuite > 0) {
+ char *tt = endp + 1;
+ etest = strtol(tt, &endp, 0);
+ if (endp == tt) {
+ fprintf(stderr, "No digits given for test in -e s.t argument\n");
+ goto end;
+ } else if (endp && *endp != '\0') {
+ fprintf(stderr, "Bad input given for test in -e s.t argument\n");
+ goto end;
+ } else if (etest < 1) {
+ fprintf(stderr, "Test in -e s.t argument cannot be smaller than 1\n");
+ goto end;
+ }
+ } else if (endp && *endp != '\0') {
+ fprintf(stderr, "Bad input given for suite for -e s argument\n");
+ goto end;
+ } else if (esuite < 1) {
+ fprintf(stderr, "Suite in -e s argument cannot be smaller than 1\n");
+ goto end;
+ }
+ amdgpu_test_disable(esuite, etest);
+ break;
+ case 'h':
+ case 'p':
+ case 'b':
+ case 'd':
+ case 'l':
+ /* Those have been processed earlier.
+ */
+ break;
+ case '?':
+ default:
+ fprintf(stderr, "Unknown command line option '%c'. Try -h.\n",
+ c == '?' ? optopt : c);
+ goto end;
+ }
+ }
+
+ if (suite_id != -1) { /* If user specify particular suite? */
+ pSuite = CU_get_suite_by_index((unsigned int) suite_id,
+ CU_get_registry());
+
+ if (pSuite) {
+
+ if (force_run)
+ CU_set_suite_active(pSuite, CU_TRUE);
+
+ if (test_id != -1) { /* If user specify test id */
+ pTest = CU_get_test_by_index(
+ (unsigned int) test_id,
+ pSuite);
+ if (pTest) {
+ if (force_run)
+ CU_set_test_active(pTest, CU_TRUE);
+
+ CU_basic_run_test(pSuite, pTest);
+ }
+ else {
+ fprintf(stderr, "Invalid test id: %d\n",
+ test_id);
+ CU_cleanup_registry();
+ amdgpu_close_devices();
+ exit(EXIT_FAILURE);
+ }
+ } else
+ CU_basic_run_suite(pSuite);
+ } else {
+ fprintf(stderr, "Invalid suite id : %d\n",
+ suite_id);
+ CU_cleanup_registry();
+ amdgpu_close_devices();
+ exit(EXIT_FAILURE);
+ }
+ } else
+ CU_basic_run_tests();
+
+end:
+ CU_cleanup_registry();
+ amdgpu_close_devices();
+ return CU_get_error();
+}
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
new file mode 100644
index 0000000..e2ba043
--- /dev/null
+++ b/tests/amdgpu/amdgpu_test.h
@@ -0,0 +1,546 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _AMDGPU_TEST_H_
+#define _AMDGPU_TEST_H_
+
+#include "amdgpu.h"
+#include "amdgpu_drm.h"
+
+/**
+ * Define max. number of card in system which we are able to handle
+ */
+#define MAX_CARDS_SUPPORTED 128
+
+/* Forward reference for array to keep "drm" handles */
+extern int drm_amdgpu[MAX_CARDS_SUPPORTED];
+
+/* Global variables */
+extern int open_render_node;
+
+/************************* Basic test suite ********************************/
+
+/*
+ * Define basic test suite to serve as the starting point for future testing
+*/
+
+/**
+ * Initialize basic test suite
+ */
+int suite_basic_tests_init();
+
+/**
+ * Deinitialize basic test suite
+ */
+int suite_basic_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_basic_tests_enable(void);
+
+/**
+ * Tests in basic test suite
+ */
+extern CU_TestInfo basic_tests[];
+
+/**
+ * Initialize bo test suite
+ */
+int suite_bo_tests_init();
+
+/**
+ * Deinitialize bo test suite
+ */
+int suite_bo_tests_clean();
+
+/**
+ * Tests in bo test suite
+ */
+extern CU_TestInfo bo_tests[];
+
+/**
+ * Initialize cs test suite
+ */
+int suite_cs_tests_init();
+
+/**
+ * Deinitialize cs test suite
+ */
+int suite_cs_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_cs_tests_enable(void);
+
+/**
+ * Tests in cs test suite
+ */
+extern CU_TestInfo cs_tests[];
+
+/**
+ * Initialize vce test suite
+ */
+int suite_vce_tests_init();
+
+/**
+ * Deinitialize vce test suite
+ */
+int suite_vce_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vce_tests_enable(void);
+
+/**
+ * Tests in vce test suite
+ */
+extern CU_TestInfo vce_tests[];
+
+/**
++ * Initialize vcn test suite
++ */
+int suite_vcn_tests_init();
+
+/**
++ * Deinitialize vcn test suite
++ */
+int suite_vcn_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vcn_tests_enable(void);
+
+/**
++ * Tests in vcn test suite
++ */
+extern CU_TestInfo vcn_tests[];
+
+/**
++ * Initialize jpeg test suite
++ */
+int suite_jpeg_tests_init();
+
+/**
++ * Deinitialize jpeg test suite
++ */
+int suite_jpeg_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_jpeg_tests_enable(void);
+
+/**
++ * Tests in vcn test suite
++ */
+extern CU_TestInfo jpeg_tests[];
+
+/**
+ * Initialize uvd enc test suite
+ */
+int suite_uvd_enc_tests_init();
+
+/**
+ * Deinitialize uvd enc test suite
+ */
+int suite_uvd_enc_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_uvd_enc_tests_enable(void);
+
+/**
+ * Tests in uvd enc test suite
+ */
+extern CU_TestInfo uvd_enc_tests[];
+
+/**
+ * Initialize deadlock test suite
+ */
+int suite_deadlock_tests_init();
+
+/**
+ * Deinitialize deadlock test suite
+ */
+int suite_deadlock_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_deadlock_tests_enable(void);
+
+/**
+ * Tests in uvd enc test suite
+ */
+extern CU_TestInfo deadlock_tests[];
+
+/**
+ * Initialize vm test suite
+ */
+int suite_vm_tests_init();
+
+/**
+ * Deinitialize deadlock test suite
+ */
+int suite_vm_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vm_tests_enable(void);
+
+/**
+ * Tests in vm test suite
+ */
+extern CU_TestInfo vm_tests[];
+
+
+/**
+ * Initialize ras test suite
+ */
+int suite_ras_tests_init();
+
+/**
+ * Deinitialize deadlock test suite
+ */
+int suite_ras_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_ras_tests_enable(void);
+
+/**
+ * Tests in ras test suite
+ */
+extern CU_TestInfo ras_tests[];
+
+
+/**
+ * Initialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_init();
+
+/**
+ * Deinitialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_syncobj_timeline_tests_enable(void);
+
+/**
+ * Tests in syncobj timeline test suite
+ */
+extern CU_TestInfo syncobj_timeline_tests[];
+
+
+/**
+ * Initialize cp dma test suite
+ */
+int suite_cp_dma_tests_init();
+
+/**
+ * Deinitialize cp dma test suite
+ */
+int suite_cp_dma_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_cp_dma_tests_enable(void);
+
+/**
+ * Tests in cp dma test suite
+ */
+extern CU_TestInfo cp_dma_tests[];
+
+/**
+ * Initialize security test suite
+ */
+int suite_security_tests_init();
+
+/**
+ * Deinitialize security test suite
+ */
+int suite_security_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_security_tests_enable(void);
+
+/**
+ * Tests in security test suite
+ */
+extern CU_TestInfo security_tests[];
+
+extern void
+amdgpu_command_submission_write_linear_helper_with_secure(amdgpu_device_handle
+ device,
+ unsigned ip_type,
+ bool secure);
+
+extern void amdgpu_test_dispatch_helper(amdgpu_device_handle device_handle, unsigned ip);
+extern void amdgpu_test_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip);
+extern void amdgpu_test_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip);
+extern void amdgpu_test_draw_helper(amdgpu_device_handle device_handle);
+extern void amdgpu_test_draw_hang_helper(amdgpu_device_handle device_handle);
+extern void amdgpu_test_draw_hang_slow_helper(amdgpu_device_handle device_handle);
+
+/**
+ * Initialize hotunplug test suite
+ */
+int suite_hotunplug_tests_init();
+
+/**
+ * Deinitialize hotunplug test suite
+ */
+int suite_hotunplug_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_hotunplug_tests_enable(void);
+
+/**
+ * Tests in uvd enc test suite
+ */
+extern CU_TestInfo hotunplug_tests[];
+
+
+/**
+ * Helper functions
+ */
+static inline amdgpu_bo_handle gpu_mem_alloc(
+ amdgpu_device_handle device_handle,
+ uint64_t size,
+ uint64_t alignment,
+ uint32_t type,
+ uint64_t flags,
+ uint64_t *vmc_addr,
+ amdgpu_va_handle *va_handle)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle = NULL;
+ int r;
+
+ req.alloc_size = size;
+ req.phys_alignment = alignment;
+ req.preferred_heap = type;
+ req.flags = flags;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ return NULL;
+
+ if (vmc_addr && va_handle) {
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ size, alignment, 0, vmc_addr,
+ va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_free_bo;
+
+ r = amdgpu_bo_va_op(buf_handle, 0, size, *vmc_addr, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_free_va;
+ }
+
+ return buf_handle;
+
+error_free_va:
+ r = amdgpu_va_range_free(*va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+error_free_bo:
+ r = amdgpu_bo_free(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return NULL;
+}
+
+static inline int gpu_mem_free(amdgpu_bo_handle bo,
+ amdgpu_va_handle va_handle,
+ uint64_t vmc_addr,
+ uint64_t size)
+{
+ int r;
+
+ if (!bo)
+ return 0;
+
+ if (va_handle) {
+ r = amdgpu_bo_va_op(bo, 0, size, vmc_addr, 0,
+ AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ return r;
+
+ r = amdgpu_va_range_free(va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ return r;
+ }
+
+ r = amdgpu_bo_free(bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return r;
+}
+
+static inline int
+amdgpu_bo_alloc_wrap(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t flags,
+ amdgpu_bo_handle *bo)
+{
+ struct amdgpu_bo_alloc_request request = {};
+ amdgpu_bo_handle buf_handle;
+ int r;
+
+ request.alloc_size = size;
+ request.phys_alignment = alignment;
+ request.preferred_heap = heap;
+ request.flags = flags;
+
+ r = amdgpu_bo_alloc(dev, &request, &buf_handle);
+ if (r)
+ return r;
+
+ *bo = buf_handle;
+
+ return 0;
+}
+
+int amdgpu_bo_alloc_and_map_raw(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t alloc_flags,
+ uint64_t mapping_flags, amdgpu_bo_handle *bo, void **cpu,
+ uint64_t *mc_address,
+ amdgpu_va_handle *va_handle);
+
+static inline int
+amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t alloc_flags,
+ amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,
+ amdgpu_va_handle *va_handle)
+{
+ return amdgpu_bo_alloc_and_map_raw(dev, size, alignment, heap,
+ alloc_flags, 0, bo, cpu, mc_address, va_handle);
+}
+
+static inline int
+amdgpu_bo_unmap_and_free(amdgpu_bo_handle bo, amdgpu_va_handle va_handle,
+ uint64_t mc_addr, uint64_t size)
+{
+ amdgpu_bo_cpu_unmap(bo);
+ amdgpu_bo_va_op(bo, 0, size, mc_addr, 0, AMDGPU_VA_OP_UNMAP);
+ amdgpu_va_range_free(va_handle);
+ amdgpu_bo_free(bo);
+
+ return 0;
+
+}
+
+static inline int
+amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1,
+ amdgpu_bo_handle bo2, amdgpu_bo_list_handle *list)
+{
+ amdgpu_bo_handle resources[] = {bo1, bo2};
+
+ return amdgpu_bo_list_create(dev, bo2 ? 2 : 1, resources, NULL, list);
+}
+
+
+static inline CU_ErrorCode amdgpu_set_suite_active(const char *suite_name,
+ CU_BOOL active)
+{
+ CU_ErrorCode r = CU_set_suite_active(CU_get_suite(suite_name), active);
+
+ if (r != CUE_SUCCESS)
+ fprintf(stderr, "Failed to obtain suite %s\n", suite_name);
+
+ return r;
+}
+
+static inline CU_ErrorCode amdgpu_set_test_active(const char *suite_name,
+ const char *test_name, CU_BOOL active)
+{
+ CU_ErrorCode r;
+ CU_pSuite pSuite = CU_get_suite(suite_name);
+
+ if (!pSuite) {
+ fprintf(stderr, "Failed to obtain suite %s\n",
+ suite_name);
+ return CUE_NOSUITE;
+ }
+
+ r = CU_set_test_active(CU_get_test(pSuite, test_name), active);
+ if (r != CUE_SUCCESS)
+ fprintf(stderr, "Failed to obtain test %s\n", test_name);
+
+ return r;
+}
+
+
+static inline bool asic_is_gfx_pipe_removed(uint32_t family_id, uint32_t chip_id, uint32_t chip_rev)
+{
+
+ if (family_id != AMDGPU_FAMILY_AI)
+ return false;
+
+ switch (chip_id - chip_rev) {
+ /* Arcturus */
+ case 0x32:
+ /* Aldebaran */
+ case 0x3c:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void amdgpu_test_exec_cs_helper_raw(amdgpu_device_handle device_handle,
+ amdgpu_context_handle context_handle,
+ unsigned ip_type, int instance, int pm4_dw,
+ uint32_t *pm4_src, int res_cnt,
+ amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request,
+ bool secure);
+
+void amdgpu_close_devices();
+int amdgpu_open_device_on_test_index(int render_node);
+char *amdgpu_get_device_from_fd(int fd);
+
+#endif /* #ifdef _AMDGPU_TEST_H_ */
diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c
new file mode 100644
index 0000000..0e4a357
--- /dev/null
+++ b/tests/amdgpu/basic_tests.c
@@ -0,0 +1,2556 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#ifdef MAJOR_IN_SYSMACROS
+#include <sys/sysmacros.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
+#if HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+#include <sys/wait.h>
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "util_math.h"
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+static uint32_t chip_id;
+static uint32_t chip_rev;
+
+static void amdgpu_query_info_test(void);
+static void amdgpu_command_submission_gfx(void);
+static void amdgpu_command_submission_compute(void);
+static void amdgpu_command_submission_multi_fence(void);
+static void amdgpu_command_submission_sdma(void);
+static void amdgpu_userptr_test(void);
+static void amdgpu_semaphore_test(void);
+static void amdgpu_sync_dependency_test(void);
+static void amdgpu_bo_eviction_test(void);
+static void amdgpu_compute_dispatch_test(void);
+static void amdgpu_gfx_dispatch_test(void);
+static void amdgpu_draw_test(void);
+static void amdgpu_gpu_reset_test(void);
+static void amdgpu_stable_pstate_test(void);
+
+static void amdgpu_command_submission_write_linear_helper(unsigned ip_type);
+static void amdgpu_command_submission_const_fill_helper(unsigned ip_type);
+static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type);
+static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
+ unsigned ip_type,
+ int instance, int pm4_dw, uint32_t *pm4_src,
+ int res_cnt, amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request);
+
+CU_TestInfo basic_tests[] = {
+ { "Query Info Test", amdgpu_query_info_test },
+ { "Userptr Test", amdgpu_userptr_test },
+ { "bo eviction Test", amdgpu_bo_eviction_test },
+ { "Command submission Test (GFX)", amdgpu_command_submission_gfx },
+ { "Command submission Test (Compute)", amdgpu_command_submission_compute },
+ { "Command submission Test (Multi-Fence)", amdgpu_command_submission_multi_fence },
+ { "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
+ { "SW semaphore Test", amdgpu_semaphore_test },
+ { "Sync dependency Test", amdgpu_sync_dependency_test },
+ { "Dispatch Test (Compute)", amdgpu_compute_dispatch_test },
+ { "Dispatch Test (GFX)", amdgpu_gfx_dispatch_test },
+ { "Draw Test", amdgpu_draw_test },
+ { "GPU reset Test", amdgpu_gpu_reset_test },
+ { "Stable pstate Test", amdgpu_stable_pstate_test },
+ CU_TEST_INFO_NULL,
+};
+#define BUFFER_SIZE (MAX2(8 * 1024, getpagesize()))
+#define SDMA_PKT_HEADER_op_offset 0
+#define SDMA_PKT_HEADER_op_mask 0x000000FF
+#define SDMA_PKT_HEADER_op_shift 0
+#define SDMA_PKT_HEADER_OP(x) (((x) & SDMA_PKT_HEADER_op_mask) << SDMA_PKT_HEADER_op_shift)
+#define SDMA_OPCODE_CONSTANT_FILL 11
+# define SDMA_CONSTANT_FILL_EXTRA_SIZE(x) ((x) << 14)
+ /* 0 = byte fill
+ * 2 = DW fill
+ */
+#define SDMA_PACKET(op, sub_op, e) ((((e) & 0xFFFF) << 16) | \
+ (((sub_op) & 0xFF) << 8) | \
+ (((op) & 0xFF) << 0))
+#define SDMA_OPCODE_WRITE 2
+# define SDMA_WRITE_SUB_OPCODE_LINEAR 0
+# define SDMA_WRTIE_SUB_OPCODE_TILED 1
+
+#define SDMA_OPCODE_COPY 1
+# define SDMA_COPY_SUB_OPCODE_LINEAR 0
+
+#define SDMA_OPCODE_ATOMIC 10
+# define SDMA_ATOMIC_LOOP(x) ((x) << 0)
+ /* 0 - single_pass_atomic.
+ * 1 - loop_until_compare_satisfied.
+ */
+# define SDMA_ATOMIC_TMZ(x) ((x) << 2)
+ /* 0 - non-TMZ.
+ * 1 - TMZ.
+ */
+# define SDMA_ATOMIC_OPCODE(x) ((x) << 9)
+ /* TC_OP_ATOMIC_CMPSWAP_RTN_32 0x00000008
+ * same as Packet 3
+ */
+
+#define GFX_COMPUTE_NOP 0xffff1000
+#define SDMA_NOP 0x0
+
+/* PM4 */
+#define PACKET_TYPE0 0
+#define PACKET_TYPE1 1
+#define PACKET_TYPE2 2
+#define PACKET_TYPE3 3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) ((h) & 0xFFFF)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \
+ ((reg) & 0xFFFF) | \
+ ((n) & 0x3FFF) << 16)
+#define CP_PACKET2 0x80000000
+#define PACKET2_PAD_SHIFT 0
+#define PACKET2_PAD_MASK (0x3fffffff << 0)
+
+#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+
+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
+ (((op) & 0xFF) << 8) | \
+ ((n) & 0x3FFF) << 16)
+#define PACKET3_COMPUTE(op, n) PACKET3(op, n) | (1 << 1)
+
+/* Packet 3 types */
+#define PACKET3_NOP 0x10
+
+#define PACKET3_WRITE_DATA 0x37
+#define WRITE_DATA_DST_SEL(x) ((x) << 8)
+ /* 0 - register
+ * 1 - memory (sync - via GRBM)
+ * 2 - gl2
+ * 3 - gds
+ * 4 - reserved
+ * 5 - memory (async - direct)
+ */
+#define WR_ONE_ADDR (1 << 16)
+#define WR_CONFIRM (1 << 20)
+#define WRITE_DATA_CACHE_POLICY(x) ((x) << 25)
+ /* 0 - LRU
+ * 1 - Stream
+ */
+#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
+ /* 0 - me
+ * 1 - pfp
+ * 2 - ce
+ */
+
+#define PACKET3_ATOMIC_MEM 0x1E
+#define TC_OP_ATOMIC_CMPSWAP_RTN_32 0x00000008
+#define ATOMIC_MEM_COMMAND(x) ((x) << 8)
+ /* 0 - single_pass_atomic.
+ * 1 - loop_until_compare_satisfied.
+ */
+#define ATOMIC_MEM_CACHEPOLICAY(x) ((x) << 25)
+ /* 0 - lru.
+ * 1 - stream.
+ */
+#define ATOMIC_MEM_ENGINESEL(x) ((x) << 30)
+ /* 0 - micro_engine.
+ */
+
+#define PACKET3_DMA_DATA 0x50
+/* 1. header
+ * 2. CONTROL
+ * 3. SRC_ADDR_LO or DATA [31:0]
+ * 4. SRC_ADDR_HI [31:0]
+ * 5. DST_ADDR_LO [31:0]
+ * 6. DST_ADDR_HI [7:0]
+ * 7. COMMAND [30:21] | BYTE_COUNT [20:0]
+ */
+/* CONTROL */
+# define PACKET3_DMA_DATA_ENGINE(x) ((x) << 0)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_DMA_DATA_SRC_CACHE_POLICY(x) ((x) << 13)
+ /* 0 - LRU
+ * 1 - Stream
+ * 2 - Bypass
+ */
+# define PACKET3_DMA_DATA_SRC_VOLATILE (1 << 15)
+# define PACKET3_DMA_DATA_DST_SEL(x) ((x) << 20)
+ /* 0 - DST_ADDR using DAS
+ * 1 - GDS
+ * 3 - DST_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_DST_CACHE_POLICY(x) ((x) << 25)
+ /* 0 - LRU
+ * 1 - Stream
+ * 2 - Bypass
+ */
+# define PACKET3_DMA_DATA_DST_VOLATILE (1 << 27)
+# define PACKET3_DMA_DATA_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR using SAS
+ * 1 - GDS
+ * 2 - DATA
+ * 3 - SRC_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_CP_SYNC (1 << 31)
+/* COMMAND */
+# define PACKET3_DMA_DATA_DIS_WC (1 << 21)
+# define PACKET3_DMA_DATA_CMD_SRC_SWAP(x) ((x) << 22)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_DMA_DATA_CMD_DST_SWAP(x) ((x) << 24)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_DMA_DATA_CMD_SAS (1 << 26)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_DMA_DATA_CMD_DAS (1 << 27)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_DMA_DATA_CMD_SAIC (1 << 28)
+# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
+# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
+
+#define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \
+ (((b) & 0x1) << 26) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((cnt) & 0xFFFFF) << 0))
+#define SDMA_OPCODE_COPY_SI 3
+#define SDMA_OPCODE_CONSTANT_FILL_SI 13
+#define SDMA_NOP_SI 0xf
+#define GFX_COMPUTE_NOP_SI 0x80000000
+#define PACKET3_DMA_DATA_SI 0x41
+# define PACKET3_DMA_DATA_SI_ENGINE(x) ((x) << 27)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_DMA_DATA_SI_DST_SEL(x) ((x) << 20)
+ /* 0 - DST_ADDR using DAS
+ * 1 - GDS
+ * 3 - DST_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR using SAS
+ * 1 - GDS
+ * 2 - DATA
+ * 3 - SRC_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_CP_SYNC (1 << 31)
+
+
+#define PKT3_CONTEXT_CONTROL 0x28
+#define CONTEXT_CONTROL_LOAD_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+#define CONTEXT_CONTROL_LOAD_CE_RAM(x) (((unsigned)(x) & 0x1) << 28)
+#define CONTEXT_CONTROL_SHADOW_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+
+#define PKT3_CLEAR_STATE 0x12
+
+#define PKT3_SET_SH_REG 0x76
+#define PACKET3_SET_SH_REG_START 0x00002c00
+
+#define PKT3_SET_SH_REG_INDEX 0x9B
+
+#define PACKET3_DISPATCH_DIRECT 0x15
+#define PACKET3_EVENT_WRITE 0x46
+#define PACKET3_ACQUIRE_MEM 0x58
+#define PACKET3_SET_CONTEXT_REG 0x69
+#define PACKET3_SET_UCONFIG_REG 0x79
+#define PACKET3_DRAW_INDEX_AUTO 0x2D
+/* gfx 8 */
+#define mmCOMPUTE_PGM_LO 0x2e0c
+#define mmCOMPUTE_PGM_RSRC1 0x2e12
+#define mmCOMPUTE_TMPRING_SIZE 0x2e18
+#define mmCOMPUTE_USER_DATA_0 0x2e40
+#define mmCOMPUTE_USER_DATA_1 0x2e41
+#define mmCOMPUTE_RESOURCE_LIMITS 0x2e15
+#define mmCOMPUTE_NUM_THREAD_X 0x2e07
+
+
+
+#define SWAP_32(num) (((num & 0xff000000) >> 24) | \
+ ((num & 0x0000ff00) << 8) | \
+ ((num & 0x00ff0000) >> 8) | \
+ ((num & 0x000000ff) << 24))
+
+
+/* Shader code
+ * void main()
+{
+
+ float x = some_input;
+ for (unsigned i = 0; i < 1000000; i++)
+ x = sin(x);
+
+ u[0] = 42u;
+}
+*/
+
+static uint32_t shader_bin[] = {
+ SWAP_32(0x800082be), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0x040085bf),
+ SWAP_32(0x02810281), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0xfcff84bf),
+ SWAP_32(0xff0083be), SWAP_32(0x00f00000), SWAP_32(0xc10082be), SWAP_32(0xaa02007e),
+ SWAP_32(0x000070e0), SWAP_32(0x00000080), SWAP_32(0x000081bf)
+};
+
+#define CODE_OFFSET 512
+#define DATA_OFFSET 1024
+
+enum cs_type {
+ CS_BUFFERCLEAR,
+ CS_BUFFERCOPY,
+ CS_HANG,
+ CS_HANG_SLOW
+};
+
+static const uint32_t bufferclear_cs_shader_gfx9[] = {
+ 0x260000ff, 0x000003ff, 0xd1fd0000, 0x04010c08,
+ 0x7e020280, 0x7e040204, 0x7e060205, 0x7e080206,
+ 0x7e0a0207, 0xe01c2000, 0x80000200, 0xbf8c0000,
+ 0xbf810000
+};
+
+static const uint32_t bufferclear_cs_shader_gfx10[] = {
+ 0xD7460004, 0x04010C08, 0x7E000204, 0x7E020205,
+ 0x7E040206, 0x7E060207, 0xE01C2000, 0x80000004,
+ 0xBF810000
+};
+
+static const uint32_t bufferclear_cs_shader_registers_gfx9[][2] = {
+ {0x2e12, 0x000C0041}, //{ mmCOMPUTE_PGM_RSRC1, 0x000C0041 },
+ {0x2e13, 0x00000090}, //{ mmCOMPUTE_PGM_RSRC2, 0x00000090 },
+ {0x2e07, 0x00000040}, //{ mmCOMPUTE_NUM_THREAD_X, 0x00000040 },
+ {0x2e08, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Y, 0x00000001 },
+ {0x2e09, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Z, 0x00000001 }
+};
+
+static const uint32_t bufferclear_cs_shader_registers_num_gfx9 = 5;
+
+static const uint32_t buffercopy_cs_shader_gfx9[] = {
+ 0x260000ff, 0x000003ff, 0xd1fd0000, 0x04010c08,
+ 0x7e020280, 0xe00c2000, 0x80000200, 0xbf8c0f70,
+ 0xe01c2000, 0x80010200, 0xbf810000
+};
+
+static const uint32_t buffercopy_cs_shader_gfx10[] = {
+ 0xD7460001, 0x04010C08, 0xE00C2000, 0x80000201,
+ 0xBF8C3F70, 0xE01C2000, 0x80010201, 0xBF810000
+};
+
+static const uint32_t preamblecache_gfx9[] = {
+ 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0,
+ 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000,
+ 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0,
+ 0xc0016900, 0x208, 0x0, 0xc0016900, 0x290, 0x0,
+ 0xc0016900, 0x2a1, 0x0, 0xc0026900, 0x2ad, 0x0, 0x0,
+ 0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0,
+ 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0,
+ 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0xc0036900, 0x311, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0x1e, 0x20,
+ 0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0,
+ 0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x19, 0x0,
+ 0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0,
+ 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff,
+ 0xc0016900, 0x314, 0x0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0,
+ 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1,
+ 0xc0016900, 0x18, 0x2, 0xc0016900, 0x206, 0x300, 0xc0017900, 0x20000243, 0x0,
+ 0xc0017900, 0x248, 0xffffffff, 0xc0017900, 0x249, 0x0, 0xc0017900, 0x24a, 0x0,
+ 0xc0017900, 0x24b, 0x0
+};
+
+static const uint32_t preamblecache_gfx10[] = {
+ 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0,
+ 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000,
+ 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0,
+ 0xc0016900, 0x208, 0x0, 0xc0016900, 0x290, 0x0,
+ 0xc0016900, 0x2a1, 0x0, 0xc0026900, 0x2ad, 0x0, 0x0,
+ 0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0,
+ 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0,
+ 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0xc0046900, 0x310, 0, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0xe, 0x20,
+ 0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0,
+ 0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x6, 0x0,
+ 0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0,
+ 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff,
+ 0xc0016900, 0x314, 0x0, 0xc0016900, 0x10a, 0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0,
+ 0xc0016900, 0x2db, 0, 0xc0016900, 0x1d4, 0, 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1, 0xc0016900, 0xe, 0x2,
+ 0xc0016900, 0x206, 0x300, 0xc0016900, 0x212, 0x200, 0xc0017900, 0x7b, 0x20, 0xc0017a00, 0x20000243, 0x0,
+ 0xc0017900, 0x249, 0, 0xc0017900, 0x24a, 0, 0xc0017900, 0x24b, 0, 0xc0017900, 0x259, 0xffffffff,
+ 0xc0017900, 0x25f, 0, 0xc0017900, 0x260, 0, 0xc0017900, 0x262, 0,
+ 0xc0017600, 0x45, 0x0, 0xc0017600, 0x6, 0x0,
+ 0xc0067600, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0067600, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+};
+
+enum ps_type {
+ PS_CONST,
+ PS_TEX,
+ PS_HANG,
+ PS_HANG_SLOW
+};
+
+static const uint32_t ps_const_shader_gfx9[] = {
+ 0x7E000200, 0x7E020201, 0x7E040202, 0x7E060203,
+ 0xD2960000, 0x00020300, 0xD2960001, 0x00020702,
+ 0xC4001C0F, 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_const_shader_patchinfo_code_size_gfx9 = 6;
+
+static const uint32_t ps_const_shader_patchinfo_code_gfx9[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001801, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000300 },
+ { 0xD2960000, 0x00020300, 0xD2960001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2950000, 0x00020300, 0xD2950001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2940000, 0x00020300, 0xD2940001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2970000, 0x00020300, 0xD2970001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2980000, 0x00020300, 0xD2980001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC400180F, 0x03020100 }
+ }
+};
+
+static const uint32_t ps_const_shader_patchinfo_offset_gfx9[] = {
+ 0x00000004
+};
+
+static const uint32_t ps_num_sh_registers_gfx9 = 2;
+
+static const uint32_t ps_const_sh_registers_gfx9[][2] = {
+ {0x2C0A, 0x000C0040},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0040 },
+ {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 }
+};
+
+static const uint32_t ps_num_context_registers_gfx9 = 7;
+
+static const uint32_t ps_const_context_reg_gfx9[][2] = {
+ {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000000}, //{ mmSPI_PS_IN_CONTROL, 0x00000000 },
+ {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 }
+};
+
+static const uint32_t ps_const_shader_gfx10[] = {
+ 0x7E000200, 0x7E020201, 0x7E040202, 0x7E060203,
+ 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000,
+ 0xF8001C0F, 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_const_shader_patchinfo_code_size_gfx10 = 6;
+
+static const uint32_t ps_const_shader_patchinfo_code_gfx10[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000300 },
+ { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 },
+ { 0xD7690000, 0x00020300, 0xD7690001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xD7680000, 0x00020300, 0xD7680001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xD76A0000, 0x00020300, 0xD76A0001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xD76B0000, 0x00020300, 0xD76B0001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x03020100 }
+ }
+};
+
+static const uint32_t ps_const_shader_patchinfo_offset_gfx10[] = {
+ 0x00000004
+};
+
+static const uint32_t ps_num_sh_registers_gfx10 = 2;
+
+static const uint32_t ps_const_sh_registers_gfx10[][2] = {
+ {0x2C0A, 0x000C0000},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0000 },
+ {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 }
+};
+
+static const uint32_t ps_tex_shader_gfx9[] = {
+ 0xBEFC000C, 0xBE8E017E, 0xBEFE077E, 0xD4180000,
+ 0xD4190001, 0xD41C0100, 0xD41D0101, 0xF0800F00,
+ 0x00400206, 0xBEFE010E, 0xBF8C0F70, 0xD2960000,
+ 0x00020702, 0xD2960001, 0x00020B04, 0xC4001C0F,
+ 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_tex_shader_patchinfo_offset_gfx9[] = {
+ 0x0000000B
+};
+
+static const uint32_t ps_tex_shader_patchinfo_code_size_gfx9 = 6;
+
+static const uint32_t ps_tex_shader_patchinfo_code_gfx9[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001801, 0x00000002 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000302 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000502 },
+ { 0xD2960000, 0x00020702, 0xD2960001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2950000, 0x00020702, 0xD2950001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2940000, 0x00020702, 0xD2940001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2970000, 0x00020702, 0xD2970001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2980000, 0x00020702, 0xD2980001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC400180F, 0x05040302 }
+ }
+};
+
+static const uint32_t ps_tex_sh_registers_gfx9[][2] = {
+ {0x2C0A, 0x000C0081},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0081 },
+ {0x2C0B, 0x00000018}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000018 }
+};
+
+static const uint32_t ps_tex_context_reg_gfx9[][2] = {
+ {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000001}, //{ mmSPI_PS_IN_CONTROL, 0x00000001 },
+ {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 }
+};
+
+static const uint32_t ps_tex_shader_gfx10[] = {
+ 0xBEFC030C, 0xBE8E047E, 0xBEFE0A7E, 0xC8080000,
+ 0xC80C0100, 0xC8090001, 0xC80D0101, 0xF0800F0A,
+ 0x00400402, 0x00000003, 0xBEFE040E, 0xBF8C0F70,
+ 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000,
+ 0xF8001C0F, 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_tex_shader_patchinfo_offset_gfx10[] = {
+ 0x0000000C
+};
+
+static const uint32_t ps_tex_shader_patchinfo_code_size_gfx10 = 6;
+
+static const uint32_t ps_tex_shader_patchinfo_code_gfx10[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000004 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000504 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000704 },
+ { 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 },
+ { 0xD7690000, 0x00020B04, 0xD7690001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xD7680000, 0x00020B04, 0xD7680001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xD76A0000, 0x00020B04, 0xD76A0001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xD76B0000, 0x00020B04, 0xD76B0001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x07060504 }
+ }
+};
+
+static const uint32_t vs_RectPosTexFast_shader_gfx9[] = {
+ 0x7E000B00, 0x020000F3, 0xD042000A, 0x00010100,
+ 0x7E020202, 0x7E040200, 0x020000F3, 0x7E060206,
+ 0x7E080204, 0xD1000001, 0x002A0302, 0x7C840080,
+ 0x7E000200, 0x7E040203, 0x7E0A0201, 0xD1000003,
+ 0x002A0704, 0x7E0C0207, 0x7E0E0205, 0x00000101,
+ 0x00020505, 0x7E040208, 0x7E0A02F2, 0x00060903,
+ 0x00080D07, 0x7E0C0209, 0xC40008CF, 0x05020100,
+ 0xC400020F, 0x05060403, 0xBF810000
+};
+
+static const uint32_t vs_RectPosTexFast_shader_gfx10[] = {
+ 0x7E000B00, 0x060000F3, 0x7E020202, 0x7E040206,
+ 0x7C040080, 0x060000F3, 0xD5010001, 0x01AA0200,
+ 0x7E060203, 0xD5010002, 0x01AA0404, 0x7E080207,
+ 0x7C040080, 0xD5010000, 0x01A80101, 0xD5010001,
+ 0x01AA0601, 0x7E060208, 0x7E0A02F2, 0xD5010002,
+ 0x01A80902, 0xD5010004, 0x01AA0805, 0x7E0C0209,
+ 0xF80008CF, 0x05030100, 0xF800020F, 0x05060402,
+ 0xBF810000
+};
+
+static const uint32_t cached_cmd_gfx9[] = {
+ 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0,
+ 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020,
+ 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf,
+ 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x12,
+ 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0,
+ 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011,
+ 0xc0026900, 0x292, 0x20, 0x60201b8,
+ 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0
+};
+
+static const uint32_t cached_cmd_gfx10[] = {
+ 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0,
+ 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020,
+ 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf,
+ 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x18,
+ 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0,
+ 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011,
+ 0xc0026900, 0x292, 0x20, 0x6020000,
+ 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0
+};
+
+unsigned int memcpy_ps_hang[] = {
+ 0xFFFFFFFF, 0xBEFE0A7E, 0xBEFC0304, 0xC0C20100,
+ 0xC0800300, 0xC8080000, 0xC80C0100, 0xC8090001,
+ 0xC80D0101, 0xBF8C007F, 0xF0800F00, 0x00010002,
+ 0xBEFE040C, 0xBF8C0F70, 0xBF800000, 0xBF800000,
+ 0xF800180F, 0x03020100, 0xBF810000
+};
+
+struct amdgpu_test_shader {
+ uint32_t *shader;
+ uint32_t header_length;
+ uint32_t body_length;
+ uint32_t foot_length;
+};
+
+unsigned int memcpy_cs_hang_slow_ai_codes[] = {
+ 0xd1fd0000, 0x04010c08, 0xe00c2000, 0x80000100,
+ 0xbf8c0f70, 0xe01c2000, 0x80010100, 0xbf810000
+};
+
+struct amdgpu_test_shader memcpy_cs_hang_slow_ai = {
+ memcpy_cs_hang_slow_ai_codes,
+ 4,
+ 3,
+ 1
+};
+
+unsigned int memcpy_cs_hang_slow_rv_codes[] = {
+ 0x8e00860c, 0x32000000, 0xe00c2000, 0x80010100,
+ 0xbf8c0f70, 0xe01c2000, 0x80020100, 0xbf810000
+};
+
+struct amdgpu_test_shader memcpy_cs_hang_slow_rv = {
+ memcpy_cs_hang_slow_rv_codes,
+ 4,
+ 3,
+ 1
+};
+
+unsigned int memcpy_cs_hang_slow_nv_codes[] = {
+ 0xd7460000, 0x04010c08, 0xe00c2000, 0x80000100,
+ 0xbf8c0f70, 0xe01ca000, 0x80010100, 0xbf810000
+};
+
+struct amdgpu_test_shader memcpy_cs_hang_slow_nv = {
+ memcpy_cs_hang_slow_nv_codes,
+ 4,
+ 3,
+ 1
+};
+
+unsigned int memcpy_ps_hang_slow_ai_codes[] = {
+ 0xbefc000c, 0xbe8e017e, 0xbefe077e, 0xd4080000,
+ 0xd4090001, 0xd40c0100, 0xd40d0101, 0xf0800f00,
+ 0x00400002, 0xbefe010e, 0xbf8c0f70, 0xbf800000,
+ 0xbf800000, 0xbf800000, 0xbf800000, 0xc400180f,
+ 0x03020100, 0xbf810000
+};
+
+struct amdgpu_test_shader memcpy_ps_hang_slow_ai = {
+ memcpy_ps_hang_slow_ai_codes,
+ 7,
+ 2,
+ 9
+};
+
+int amdgpu_bo_alloc_and_map_raw(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t alloc_flags,
+ uint64_t mapping_flags, amdgpu_bo_handle *bo, void **cpu,
+ uint64_t *mc_address,
+ amdgpu_va_handle *va_handle)
+{
+ struct amdgpu_bo_alloc_request request = {};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle handle;
+ uint64_t vmc_addr;
+ int r;
+
+ request.alloc_size = size;
+ request.phys_alignment = alignment;
+ request.preferred_heap = heap;
+ request.flags = alloc_flags;
+
+ r = amdgpu_bo_alloc(dev, &request, &buf_handle);
+ if (r)
+ return r;
+
+ r = amdgpu_va_range_alloc(dev,
+ amdgpu_gpu_va_range_general,
+ size, alignment, 0, &vmc_addr,
+ &handle, 0);
+ if (r)
+ goto error_va_alloc;
+
+ r = amdgpu_bo_va_op_raw(dev, buf_handle, 0, ALIGN(size, getpagesize()), vmc_addr,
+ AMDGPU_VM_PAGE_READABLE |
+ AMDGPU_VM_PAGE_WRITEABLE |
+ AMDGPU_VM_PAGE_EXECUTABLE |
+ mapping_flags,
+ AMDGPU_VA_OP_MAP);
+ if (r)
+ goto error_va_map;
+
+ r = amdgpu_bo_cpu_map(buf_handle, cpu);
+ if (r)
+ goto error_cpu_map;
+
+ *bo = buf_handle;
+ *mc_address = vmc_addr;
+ *va_handle = handle;
+
+ return 0;
+
+ error_cpu_map:
+ amdgpu_bo_cpu_unmap(buf_handle);
+
+ error_va_map:
+ amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
+
+ error_va_alloc:
+ amdgpu_bo_free(buf_handle);
+ return r;
+}
+
+
+
+CU_BOOL suite_basic_tests_enable(void)
+{
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+
+ family_id = device_handle->info.family_id;
+ chip_id = device_handle->info.chip_external_rev;
+ chip_rev = device_handle->info.chip_rev;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ /* disable gfx engine basic test cases for some asics have no CPG */
+ if (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) {
+ if (amdgpu_set_test_active("Basic Tests",
+ "Command submission Test (GFX)",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+
+ if (amdgpu_set_test_active("Basic Tests",
+ "Command submission Test (Multi-Fence)",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+
+ if (amdgpu_set_test_active("Basic Tests",
+ "Sync dependency Test",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+ }
+
+ return CU_TRUE;
+}
+
+int suite_basic_tests_init(void)
+{
+ struct amdgpu_gpu_info gpu_info = {0};
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = gpu_info.family_id;
+
+ return CUE_SUCCESS;
+}
+
+int suite_basic_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+static void amdgpu_query_info_test(void)
+{
+ struct amdgpu_gpu_info gpu_info = {0};
+ uint32_t version, feature;
+ int r;
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0,
+ 0, &version, &feature);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_gfx_separate_ibs(void)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
+ void *ib_result_cpu, *ib_result_ce_cpu;
+ uint64_t ib_result_mc_address, ib_result_ce_mc_address;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle, va_handle_ce;
+ int r, i = 0;
+ struct drm_amdgpu_info_hw_ip info;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (info.hw_ip_version_major >= 11)
+ return;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_ce_handle, &ib_result_ce_cpu,
+ &ib_result_ce_mc_address, &va_handle_ce);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle,
+ ib_result_ce_handle, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_ce_cpu;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
+ ib_info[0].ib_mc_address = ib_result_ce_mc_address;
+ ib_info[0].size = i;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ /* IT_WAIT_ON_CE_COUNTER */
+ ptr = ib_result_cpu;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address;
+ ib_info[1].size = 2;
+
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.number_of_ibs = 2;
+ ibs_request.ibs = ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
+ ib_result_ce_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+}
+
+static void amdgpu_command_submission_gfx_shared_ib(void)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ int r, i = 0;
+ struct drm_amdgpu_info_hw_ip info;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (info.hw_ip_version_major >= 11)
+ return;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_cpu;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
+ ib_info[0].ib_mc_address = ib_result_mc_address;
+ ib_info[0].size = i;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ ptr = (uint32_t *)ib_result_cpu + 4;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address + 16;
+ ib_info[1].size = 2;
+
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.number_of_ibs = 2;
+ ibs_request.ibs = ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_gfx_cp_write_data(void)
+{
+ amdgpu_command_submission_write_linear_helper(AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_command_submission_gfx_cp_const_fill(void)
+{
+ amdgpu_command_submission_const_fill_helper(AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_command_submission_gfx_cp_copy_data(void)
+{
+ amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_bo_eviction_test(void)
+{
+ const int sdma_write_length = 1024;
+ const int pm4_dw = 256;
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle bo1, bo2, vram_max[2], gtt_max[2];
+ amdgpu_bo_handle *resources;
+ uint32_t *pm4;
+ struct amdgpu_cs_ib_info *ib_info;
+ struct amdgpu_cs_request *ibs_request;
+ uint64_t bo1_mc, bo2_mc;
+ volatile unsigned char *bo1_cpu, *bo2_cpu;
+ int i, j, r, loop1, loop2;
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+ amdgpu_va_handle bo1_va_handle, bo2_va_handle;
+ struct amdgpu_heap_info vram_info, gtt_info;
+
+ pm4 = calloc(pm4_dw, sizeof(*pm4));
+ CU_ASSERT_NOT_EQUAL(pm4, NULL);
+
+ ib_info = calloc(1, sizeof(*ib_info));
+ CU_ASSERT_NOT_EQUAL(ib_info, NULL);
+
+ ibs_request = calloc(1, sizeof(*ibs_request));
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* prepare resource */
+ resources = calloc(4, sizeof(amdgpu_bo_handle));
+ CU_ASSERT_NOT_EQUAL(resources, NULL);
+
+ r = amdgpu_query_heap_info(device_handle, AMDGPU_GEM_DOMAIN_VRAM,
+ 0, &vram_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_wrap(device_handle, vram_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0, &vram_max[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_alloc_wrap(device_handle, vram_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0, &vram_max[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_query_heap_info(device_handle, AMDGPU_GEM_DOMAIN_GTT,
+ 0, &gtt_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, &gtt_max[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, &gtt_max[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+
+ loop1 = loop2 = 0;
+ /* run 9 circle to test all mapping combination */
+ while(loop1 < 2) {
+ while(loop2 < 2) {
+ /* allocate UC bo1for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop1], &bo1,
+ (void**)&bo1_cpu, &bo1_mc,
+ &bo1_va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* set bo1 */
+ memset((void*)bo1_cpu, 0xaa, sdma_write_length);
+
+ /* allocate UC bo2 for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop2], &bo2,
+ (void**)&bo2_cpu, &bo2_mc,
+ &bo2_va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* clear bo2 */
+ memset((void*)bo2_cpu, 0, sdma_write_length);
+
+ resources[0] = bo1;
+ resources[1] = bo2;
+ resources[2] = vram_max[loop2];
+ resources[3] = gtt_max[loop2];
+
+ /* fulfill PM4: test DMA copy linear */
+ i = j = 0;
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, 0, 0, 0,
+ sdma_write_length);
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ } else {
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else
+ pm4[i++] = sdma_write_length;
+ pm4[i++] = 0;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ }
+
+ amdgpu_test_exec_cs_helper(context_handle,
+ AMDGPU_HW_IP_DMA, 0,
+ i, pm4,
+ 4, resources,
+ ib_info, ibs_request);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ while(i < sdma_write_length) {
+ CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa);
+ }
+ r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+ loop2++;
+ }
+ loop2 = 0;
+ loop1++;
+ }
+ amdgpu_bo_free(vram_max[0]);
+ amdgpu_bo_free(vram_max[1]);
+ amdgpu_bo_free(gtt_max[0]);
+ amdgpu_bo_free(gtt_max[1]);
+ /* clean resources */
+ free(resources);
+ free(ibs_request);
+ free(ib_info);
+ free(pm4);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+
+static void amdgpu_command_submission_gfx(void)
+{
+ /* write data using the CP */
+ amdgpu_command_submission_gfx_cp_write_data();
+ /* const fill using the CP */
+ amdgpu_command_submission_gfx_cp_const_fill();
+ /* copy data using the CP */
+ amdgpu_command_submission_gfx_cp_copy_data();
+ /* separate IB buffers for multi-IB submission */
+ amdgpu_command_submission_gfx_separate_ibs();
+ /* shared IB buffer for multi-IB submission */
+ amdgpu_command_submission_gfx_shared_ib();
+}
+
+static void amdgpu_semaphore_test(void)
+{
+ amdgpu_context_handle context_handle[2];
+ amdgpu_semaphore_handle sem;
+ amdgpu_bo_handle ib_result_handle[2];
+ void *ib_result_cpu[2];
+ uint64_t ib_result_mc_address[2];
+ struct amdgpu_cs_request ibs_request[2] = {0};
+ struct amdgpu_cs_ib_info ib_info[2] = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ uint32_t sdma_nop, gfx_nop;
+ amdgpu_bo_list_handle bo_list[2];
+ amdgpu_va_handle va_handle[2];
+ int r, i;
+ struct amdgpu_gpu_info gpu_info = {0};
+ unsigned gc_ip_type;
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ gc_ip_type = (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) ?
+ AMDGPU_HW_IP_COMPUTE : AMDGPU_HW_IP_GFX;
+
+ if (family_id == AMDGPU_FAMILY_SI) {
+ sdma_nop = SDMA_PACKET_SI(SDMA_NOP_SI, 0, 0, 0, 0);
+ gfx_nop = GFX_COMPUTE_NOP_SI;
+ } else {
+ sdma_nop = SDMA_PKT_HEADER_OP(SDMA_NOP);
+ gfx_nop = GFX_COMPUTE_NOP;
+ }
+
+ r = amdgpu_cs_create_semaphore(&sem);
+ CU_ASSERT_EQUAL(r, 0);
+ for (i = 0; i < 2; i++) {
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle[i]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle[i], &ib_result_cpu[i],
+ &ib_result_mc_address[i], &va_handle[i]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle[i],
+ NULL, &bo_list[i]);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ /* 1. same context different engine */
+ ptr = ib_result_cpu[0];
+ ptr[0] = sdma_nop;
+ ib_info[0].ib_mc_address = ib_result_mc_address[0];
+ ib_info[0].size = 1;
+
+ ibs_request[0].ip_type = AMDGPU_HW_IP_DMA;
+ ibs_request[0].number_of_ibs = 1;
+ ibs_request[0].ibs = &ib_info[0];
+ ibs_request[0].resources = bo_list[0];
+ ibs_request[0].fence_info.handle = NULL;
+ r = amdgpu_cs_submit(context_handle[0], 0,&ibs_request[0], 1);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_signal_semaphore(context_handle[0], AMDGPU_HW_IP_DMA, 0, 0, sem);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_wait_semaphore(context_handle[0], gc_ip_type, 0, 0, sem);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr = ib_result_cpu[1];
+ ptr[0] = gfx_nop;
+ ib_info[1].ib_mc_address = ib_result_mc_address[1];
+ ib_info[1].size = 1;
+
+ ibs_request[1].ip_type = gc_ip_type;
+ ibs_request[1].number_of_ibs = 1;
+ ibs_request[1].ibs = &ib_info[1];
+ ibs_request[1].resources = bo_list[1];
+ ibs_request[1].fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle[0], 0,&ibs_request[1], 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.context = context_handle[0];
+ fence_status.ip_type = gc_ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.fence = ibs_request[1].seq_no;
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE, 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ /* 2. same engine different context */
+ ptr = ib_result_cpu[0];
+ ptr[0] = gfx_nop;
+ ib_info[0].ib_mc_address = ib_result_mc_address[0];
+ ib_info[0].size = 1;
+
+ ibs_request[0].ip_type = gc_ip_type;
+ ibs_request[0].number_of_ibs = 1;
+ ibs_request[0].ibs = &ib_info[0];
+ ibs_request[0].resources = bo_list[0];
+ ibs_request[0].fence_info.handle = NULL;
+ r = amdgpu_cs_submit(context_handle[0], 0,&ibs_request[0], 1);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_signal_semaphore(context_handle[0], gc_ip_type, 0, 0, sem);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_wait_semaphore(context_handle[1], gc_ip_type, 0, 0, sem);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr = ib_result_cpu[1];
+ ptr[0] = gfx_nop;
+ ib_info[1].ib_mc_address = ib_result_mc_address[1];
+ ib_info[1].size = 1;
+
+ ibs_request[1].ip_type = gc_ip_type;
+ ibs_request[1].number_of_ibs = 1;
+ ibs_request[1].ibs = &ib_info[1];
+ ibs_request[1].resources = bo_list[1];
+ ibs_request[1].fence_info.handle = NULL;
+ r = amdgpu_cs_submit(context_handle[1], 0,&ibs_request[1], 1);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.context = context_handle[1];
+ fence_status.ip_type = gc_ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.fence = ibs_request[1].seq_no;
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE, 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ for (i = 0; i < 2; i++) {
+ r = amdgpu_bo_unmap_and_free(ib_result_handle[i], va_handle[i],
+ ib_result_mc_address[i], 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list[i]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle[i]);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ r = amdgpu_cs_destroy_semaphore(sem);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_compute_nop(void)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t *ptr;
+ uint32_t expired;
+ int r, instance;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip info;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_COMPUTE, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (instance = 0; (1 << instance) & info.available_rings; instance++) {
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ memset(ptr, 0, 16);
+ ptr[0]=PACKET3(PACKET3_NOP, 14);
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_COMPUTE;
+ ibs_request.ring = instance;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_COMPUTE;
+ fence_status.ip_instance = 0;
+ fence_status.ring = instance;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_compute_cp_write_data(void)
+{
+ amdgpu_command_submission_write_linear_helper(AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_command_submission_compute_cp_const_fill(void)
+{
+ amdgpu_command_submission_const_fill_helper(AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_command_submission_compute_cp_copy_data(void)
+{
+ amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_command_submission_compute(void)
+{
+ /* write data using the CP */
+ amdgpu_command_submission_compute_cp_write_data();
+ /* const fill using the CP */
+ amdgpu_command_submission_compute_cp_const_fill();
+ /* copy data using the CP */
+ amdgpu_command_submission_compute_cp_copy_data();
+ /* nop test */
+ amdgpu_command_submission_compute_nop();
+}
+
+/*
+ * caller need create/release:
+ * pm4_src, resources, ib_info, and ibs_request
+ * submit command stream described in ibs_request and wait for this IB accomplished
+ */
+void
+amdgpu_test_exec_cs_helper_raw(amdgpu_device_handle device_handle,
+ amdgpu_context_handle context_handle,
+ unsigned ip_type, int instance, int pm4_dw,
+ uint32_t *pm4_src, int res_cnt,
+ amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request,
+ bool secure)
+{
+ int r;
+ uint32_t expired;
+ uint32_t *ring_ptr;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_fence fence_status = {0};
+ amdgpu_bo_handle *all_res = alloca(sizeof(resources[0]) * (res_cnt + 1));
+ amdgpu_va_handle va_handle;
+
+ /* prepare CS */
+ CU_ASSERT_NOT_EQUAL(pm4_src, NULL);
+ CU_ASSERT_NOT_EQUAL(resources, NULL);
+ CU_ASSERT_NOT_EQUAL(ib_info, NULL);
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+ CU_ASSERT_TRUE(pm4_dw <= 1024);
+
+ /* allocate IB */
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* copy PM4 packet to ring from caller */
+ ring_ptr = ib_result_cpu;
+ memcpy(ring_ptr, pm4_src, pm4_dw * sizeof(*pm4_src));
+
+ ib_info->ib_mc_address = ib_result_mc_address;
+ ib_info->size = pm4_dw;
+ if (secure)
+ ib_info->flags |= AMDGPU_IB_FLAGS_SECURE;
+
+ ibs_request->ip_type = ip_type;
+ ibs_request->ring = instance;
+ ibs_request->number_of_ibs = 1;
+ ibs_request->ibs = ib_info;
+ ibs_request->fence_info.handle = NULL;
+
+ memcpy(all_res, resources, sizeof(resources[0]) * res_cnt);
+ all_res[res_cnt] = ib_result_handle;
+
+ r = amdgpu_bo_list_create(device_handle, res_cnt+1, all_res,
+ NULL, &ibs_request->resources);
+ CU_ASSERT_EQUAL(r, 0);
+
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+
+ /* submit CS */
+ r = amdgpu_cs_submit(context_handle, 0, ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(ibs_request->resources);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.ip_type = ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.ring = ibs_request->ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request->seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void
+amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
+ unsigned ip_type, int instance, int pm4_dw,
+ uint32_t *pm4_src, int res_cnt,
+ amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request)
+{
+ amdgpu_test_exec_cs_helper_raw(device_handle, context_handle,
+ ip_type, instance, pm4_dw, pm4_src,
+ res_cnt, resources, ib_info,
+ ibs_request, false);
+}
+
+void
+amdgpu_command_submission_write_linear_helper_with_secure(amdgpu_device_handle
+ device, unsigned
+ ip_type, bool secure)
+{
+ const int sdma_write_length = 128;
+ const int pm4_dw = 256;
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle bo;
+ amdgpu_bo_handle *resources;
+ uint32_t *pm4;
+ struct amdgpu_cs_ib_info *ib_info;
+ struct amdgpu_cs_request *ibs_request;
+ uint64_t bo_mc;
+ volatile uint32_t *bo_cpu;
+ uint32_t bo_cpu_origin;
+ int i, j, r, loop, ring_id;
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+ amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info;
+
+ pm4 = calloc(pm4_dw, sizeof(*pm4));
+ CU_ASSERT_NOT_EQUAL(pm4, NULL);
+
+ ib_info = calloc(1, sizeof(*ib_info));
+ CU_ASSERT_NOT_EQUAL(ib_info, NULL);
+
+ ibs_request = calloc(1, sizeof(*ibs_request));
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+
+ r = amdgpu_query_hw_ip_info(device, ip_type, 0, &hw_ip_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (i = 0; secure && (i < 2); i++)
+ gtt_flags[i] |= AMDGPU_GEM_CREATE_ENCRYPTED;
+
+ r = amdgpu_cs_ctx_create(device, &context_handle);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* prepare resource */
+ resources = calloc(1, sizeof(amdgpu_bo_handle));
+ CU_ASSERT_NOT_EQUAL(resources, NULL);
+
+ for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) {
+ loop = 0;
+ while(loop < 2) {
+ /* allocate UC bo for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device,
+ sdma_write_length * sizeof(uint32_t),
+ 4096, AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop], &bo, (void**)&bo_cpu,
+ &bo_mc, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* clear bo */
+ memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t));
+
+ resources[0] = bo;
+
+ /* fulfill PM4: test DMA write-linear */
+ i = j = 0;
+ if (ip_type == AMDGPU_HW_IP_DMA) {
+ if (family_id == AMDGPU_FAMILY_SI)
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_WRITE, 0, 0, 0,
+ sdma_write_length);
+ else
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
+ SDMA_WRITE_SUB_OPCODE_LINEAR,
+ secure ? SDMA_ATOMIC_TMZ(1) : 0);
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else if (family_id != AMDGPU_FAMILY_SI)
+ pm4[i++] = sdma_write_length;
+ while(j++ < sdma_write_length)
+ pm4[i++] = 0xdeadbeaf;
+ } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
+ (ip_type == AMDGPU_HW_IP_COMPUTE)) {
+ pm4[i++] = PACKET3(PACKET3_WRITE_DATA, 2 + sdma_write_length);
+ pm4[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ while(j++ < sdma_write_length)
+ pm4[i++] = 0xdeadbeaf;
+ }
+
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, secure);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ if (!secure) {
+ while(i < sdma_write_length) {
+ CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
+ }
+ } else if (ip_type == AMDGPU_HW_IP_GFX) {
+ memset((void*)pm4, 0, pm4_dw * sizeof(uint32_t));
+ pm4[i++] = PACKET3(PACKET3_ATOMIC_MEM, 7);
+ /* atomic opcode for 32b w/ RTN and ATOMIC_SWAPCMP_RTN
+ * command, 1-loop_until_compare_satisfied.
+ * single_pass_atomic, 0-lru
+ * engine_sel, 0-micro_engine
+ */
+ pm4[i++] = (TC_OP_ATOMIC_CMPSWAP_RTN_32 |
+ ATOMIC_MEM_COMMAND(1) |
+ ATOMIC_MEM_CACHEPOLICAY(0) |
+ ATOMIC_MEM_ENGINESEL(0));
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0x12345678;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0x100;
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, true);
+ } else if (ip_type == AMDGPU_HW_IP_DMA) {
+ /* restore the bo_cpu to compare */
+ bo_cpu_origin = bo_cpu[0];
+ memset((void*)pm4, 0, pm4_dw * sizeof(uint32_t));
+ /* atomic opcode for 32b w/ RTN and ATOMIC_SWAPCMP_RTN
+ * loop, 1-loop_until_compare_satisfied.
+ * single_pass_atomic, 0-lru
+ */
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_ATOMIC,
+ 0,
+ SDMA_ATOMIC_LOOP(1) |
+ SDMA_ATOMIC_TMZ(1) |
+ SDMA_ATOMIC_OPCODE(TC_OP_ATOMIC_CMPSWAP_RTN_32));
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0x12345678;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0x100;
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, true);
+ /* DMA's atomic behavir is unlike GFX
+ * If the comparing data is not equal to destination data,
+ * For GFX, loop again till gfx timeout(system hang).
+ * For DMA, loop again till timer expired and then send interrupt.
+ * So testcase can't use interrupt mechanism.
+ * We take another way to verify. When the comparing data is not
+ * equal to destination data, overwrite the source data to the destination
+ * buffer. Otherwise, original destination data unchanged.
+ * So if the bo_cpu data is overwritten, the result is passed.
+ */
+ CU_ASSERT_NOT_EQUAL(bo_cpu[0], bo_cpu_origin);
+
+ /* compare again for the case of dest_data != cmp_data */
+ i = 0;
+ /* restore again, here dest_data should be */
+ bo_cpu_origin = bo_cpu[0];
+ memset((void*)pm4, 0, pm4_dw * sizeof(uint32_t));
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_ATOMIC,
+ 0,
+ SDMA_ATOMIC_LOOP(1) |
+ SDMA_ATOMIC_TMZ(1) |
+ SDMA_ATOMIC_OPCODE(TC_OP_ATOMIC_CMPSWAP_RTN_32));
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0x87654321;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0x100;
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, true);
+ /* here bo_cpu[0] should be unchanged, still is 0x12345678, otherwise failed*/
+ CU_ASSERT_EQUAL(bo_cpu[0], bo_cpu_origin);
+ }
+
+ r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
+ sdma_write_length * sizeof(uint32_t));
+ CU_ASSERT_EQUAL(r, 0);
+ loop++;
+ }
+ }
+ /* clean resources */
+ free(resources);
+ free(ibs_request);
+ free(ib_info);
+ free(pm4);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
+{
+ amdgpu_command_submission_write_linear_helper_with_secure(device_handle,
+ ip_type,
+ false);
+}
+
+static void amdgpu_command_submission_sdma_write_linear(void)
+{
+ amdgpu_command_submission_write_linear_helper(AMDGPU_HW_IP_DMA);
+}
+
+static void amdgpu_command_submission_const_fill_helper(unsigned ip_type)
+{
+ const int sdma_write_length = 1024 * 1024;
+ const int pm4_dw = 256;
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle bo;
+ amdgpu_bo_handle *resources;
+ uint32_t *pm4;
+ struct amdgpu_cs_ib_info *ib_info;
+ struct amdgpu_cs_request *ibs_request;
+ uint64_t bo_mc;
+ volatile uint32_t *bo_cpu;
+ int i, j, r, loop, ring_id;
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+ amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info;
+
+ pm4 = calloc(pm4_dw, sizeof(*pm4));
+ CU_ASSERT_NOT_EQUAL(pm4, NULL);
+
+ ib_info = calloc(1, sizeof(*ib_info));
+ CU_ASSERT_NOT_EQUAL(ib_info, NULL);
+
+ ibs_request = calloc(1, sizeof(*ibs_request));
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+
+ r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* prepare resource */
+ resources = calloc(1, sizeof(amdgpu_bo_handle));
+ CU_ASSERT_NOT_EQUAL(resources, NULL);
+
+ for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) {
+ loop = 0;
+ while(loop < 2) {
+ /* allocate UC bo for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop], &bo, (void**)&bo_cpu,
+ &bo_mc, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* clear bo */
+ memset((void*)bo_cpu, 0, sdma_write_length);
+
+ resources[0] = bo;
+
+ /* fulfill PM4: test DMA const fill */
+ i = j = 0;
+ if (ip_type == AMDGPU_HW_IP_DMA) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_CONSTANT_FILL_SI,
+ 0, 0, 0,
+ sdma_write_length / 4);
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 16;
+ } else {
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0,
+ SDMA_CONSTANT_FILL_EXTRA_SIZE(2));
+ pm4[i++] = 0xffffffff & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0xdeadbeaf;
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else
+ pm4[i++] = sdma_write_length;
+ }
+ } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
+ (ip_type == AMDGPU_HW_IP_COMPUTE)) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4);
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) |
+ PACKET3_DMA_DATA_SI_DST_SEL(0) |
+ PACKET3_DMA_DATA_SI_SRC_SEL(2) |
+ PACKET3_DMA_DATA_SI_CP_SYNC;
+ pm4[i++] = 0xffffffff & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ } else {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
+ pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
+ PACKET3_DMA_DATA_DST_SEL(0) |
+ PACKET3_DMA_DATA_SRC_SEL(2) |
+ PACKET3_DMA_DATA_CP_SYNC;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0;
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ }
+ }
+
+ amdgpu_test_exec_cs_helper(context_handle,
+ ip_type, ring_id,
+ i, pm4,
+ 1, resources,
+ ib_info, ibs_request);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ while(i < (sdma_write_length / 4)) {
+ CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
+ }
+
+ r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+ loop++;
+ }
+ }
+ /* clean resources */
+ free(resources);
+ free(ibs_request);
+ free(ib_info);
+ free(pm4);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_sdma_const_fill(void)
+{
+ amdgpu_command_submission_const_fill_helper(AMDGPU_HW_IP_DMA);
+}
+
+static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type)
+{
+ const int sdma_write_length = 1024;
+ const int pm4_dw = 256;
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle bo1, bo2;
+ amdgpu_bo_handle *resources;
+ uint32_t *pm4;
+ struct amdgpu_cs_ib_info *ib_info;
+ struct amdgpu_cs_request *ibs_request;
+ uint64_t bo1_mc, bo2_mc;
+ volatile unsigned char *bo1_cpu, *bo2_cpu;
+ int i, j, r, loop1, loop2, ring_id;
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+ amdgpu_va_handle bo1_va_handle, bo2_va_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info;
+
+ pm4 = calloc(pm4_dw, sizeof(*pm4));
+ CU_ASSERT_NOT_EQUAL(pm4, NULL);
+
+ ib_info = calloc(1, sizeof(*ib_info));
+ CU_ASSERT_NOT_EQUAL(ib_info, NULL);
+
+ ibs_request = calloc(1, sizeof(*ibs_request));
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+
+ r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* prepare resource */
+ resources = calloc(2, sizeof(amdgpu_bo_handle));
+ CU_ASSERT_NOT_EQUAL(resources, NULL);
+
+ for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) {
+ loop1 = loop2 = 0;
+ /* run 9 circle to test all mapping combination */
+ while(loop1 < 2) {
+ while(loop2 < 2) {
+ /* allocate UC bo1for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop1], &bo1,
+ (void**)&bo1_cpu, &bo1_mc,
+ &bo1_va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* set bo1 */
+ memset((void*)bo1_cpu, 0xaa, sdma_write_length);
+
+ /* allocate UC bo2 for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop2], &bo2,
+ (void**)&bo2_cpu, &bo2_mc,
+ &bo2_va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* clear bo2 */
+ memset((void*)bo2_cpu, 0, sdma_write_length);
+
+ resources[0] = bo1;
+ resources[1] = bo2;
+
+ /* fulfill PM4: test DMA copy linear */
+ i = j = 0;
+ if (ip_type == AMDGPU_HW_IP_DMA) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI,
+ 0, 0, 0,
+ sdma_write_length);
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ } else {
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY,
+ SDMA_COPY_SUB_OPCODE_LINEAR,
+ 0);
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else
+ pm4[i++] = sdma_write_length;
+ pm4[i++] = 0;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ }
+ } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
+ (ip_type == AMDGPU_HW_IP_COMPUTE)) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4);
+ pm4[i++] = 0xfffffffc & bo1_mc;
+ pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) |
+ PACKET3_DMA_DATA_SI_DST_SEL(0) |
+ PACKET3_DMA_DATA_SI_SRC_SEL(0) |
+ PACKET3_DMA_DATA_SI_CP_SYNC |
+ (0xffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xfffffffc & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ } else {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
+ pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
+ PACKET3_DMA_DATA_DST_SEL(0) |
+ PACKET3_DMA_DATA_SRC_SEL(0) |
+ PACKET3_DMA_DATA_CP_SYNC;
+ pm4[i++] = 0xfffffffc & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xfffffffc & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ }
+ }
+
+ amdgpu_test_exec_cs_helper(context_handle,
+ ip_type, ring_id,
+ i, pm4,
+ 2, resources,
+ ib_info, ibs_request);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ while(i < sdma_write_length) {
+ CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa);
+ }
+ r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+ loop2++;
+ }
+ loop1++;
+ }
+ }
+ /* clean resources */
+ free(resources);
+ free(ibs_request);
+ free(ib_info);
+ free(pm4);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_sdma_copy_linear(void)
+{
+ amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_DMA);
+}
+
+static void amdgpu_command_submission_sdma(void)
+{
+ amdgpu_command_submission_sdma_write_linear();
+ amdgpu_command_submission_sdma_const_fill();
+ amdgpu_command_submission_sdma_copy_linear();
+}
+
+static void amdgpu_command_submission_multi_fence_wait_all(bool wait_all)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
+ void *ib_result_cpu, *ib_result_ce_cpu;
+ uint64_t ib_result_mc_address, ib_result_ce_mc_address;
+ struct amdgpu_cs_request ibs_request[2] = {0};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status[2] = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle, va_handle_ce;
+ int r;
+ int i = 0, ib_cs_num = 2;
+ struct drm_amdgpu_info_hw_ip info;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (info.hw_ip_version_major >= 11)
+ return;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_ce_handle, &ib_result_ce_cpu,
+ &ib_result_ce_mc_address, &va_handle_ce);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle,
+ ib_result_ce_handle, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_ce_cpu;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
+ ib_info[0].ib_mc_address = ib_result_ce_mc_address;
+ ib_info[0].size = i;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ /* IT_WAIT_ON_CE_COUNTER */
+ ptr = ib_result_cpu;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address;
+ ib_info[1].size = 2;
+
+ for (i = 0; i < ib_cs_num; i++) {
+ ibs_request[i].ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request[i].number_of_ibs = 2;
+ ibs_request[i].ibs = ib_info;
+ ibs_request[i].resources = bo_list;
+ ibs_request[i].fence_info.handle = NULL;
+ }
+
+ r = amdgpu_cs_submit(context_handle, 0,ibs_request, ib_cs_num);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (i = 0; i < ib_cs_num; i++) {
+ fence_status[i].context = context_handle;
+ fence_status[i].ip_type = AMDGPU_HW_IP_GFX;
+ fence_status[i].fence = ibs_request[i].seq_no;
+ }
+
+ r = amdgpu_cs_wait_fences(fence_status, ib_cs_num, wait_all,
+ AMDGPU_TIMEOUT_INFINITE,
+ &expired, NULL);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
+ ib_result_ce_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_multi_fence(void)
+{
+ amdgpu_command_submission_multi_fence_wait_all(true);
+ amdgpu_command_submission_multi_fence_wait_all(false);
+}
+
+static void amdgpu_userptr_test(void)
+{
+ int i, r, j;
+ uint32_t *pm4 = NULL;
+ uint64_t bo_mc;
+ void *ptr = NULL;
+ int pm4_dw = 256;
+ int sdma_write_length = 4;
+ amdgpu_bo_handle handle;
+ amdgpu_context_handle context_handle;
+ struct amdgpu_cs_ib_info *ib_info;
+ struct amdgpu_cs_request *ibs_request;
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+
+ pm4 = calloc(pm4_dw, sizeof(*pm4));
+ CU_ASSERT_NOT_EQUAL(pm4, NULL);
+
+ ib_info = calloc(1, sizeof(*ib_info));
+ CU_ASSERT_NOT_EQUAL(ib_info, NULL);
+
+ ibs_request = calloc(1, sizeof(*ibs_request));
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ posix_memalign(&ptr, sysconf(_SC_PAGE_SIZE), BUFFER_SIZE);
+ CU_ASSERT_NOT_EQUAL(ptr, NULL);
+ memset(ptr, 0, BUFFER_SIZE);
+
+ r = amdgpu_create_bo_from_user_mem(device_handle,
+ ptr, BUFFER_SIZE, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ BUFFER_SIZE, 1, 0, &bo_mc,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, bo_mc, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ handle = buf_handle;
+
+ j = i = 0;
+
+ if (family_id == AMDGPU_FAMILY_SI)
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_WRITE, 0, 0, 0,
+ sdma_write_length);
+ else
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
+ SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+ pm4[i++] = 0xffffffff & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else if (family_id != AMDGPU_FAMILY_SI)
+ pm4[i++] = sdma_write_length;
+
+ while (j++ < sdma_write_length)
+ pm4[i++] = 0xdeadbeaf;
+
+ if (!fork()) {
+ pm4[0] = 0x0;
+ exit(0);
+ }
+
+ amdgpu_test_exec_cs_helper(context_handle,
+ AMDGPU_HW_IP_DMA, 0,
+ i, pm4,
+ 1, &handle,
+ ib_info, ibs_request);
+ i = 0;
+ while (i < sdma_write_length) {
+ CU_ASSERT_EQUAL(((int*)ptr)[i++], 0xdeadbeaf);
+ }
+ free(ibs_request);
+ free(ib_info);
+ free(pm4);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, bo_mc, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_free(va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_free(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ free(ptr);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ wait(NULL);
+}
+
+static void amdgpu_sync_dependency_test(void)
+{
+ amdgpu_context_handle context_handle[2];
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, j, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ static uint32_t *ptr;
+ uint64_t seq_no;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 8192, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ i = 0;
+
+ memcpy(ptr + CODE_OFFSET , shader_bin, sizeof(shader_bin));
+
+ /* Dispatch minimal init config and verify it's executed */
+ ptr[i++] = PACKET3(PKT3_CONTEXT_CONTROL, 1);
+ ptr[i++] = 0x80000000;
+ ptr[i++] = 0x80000000;
+
+ ptr[i++] = PACKET3(PKT3_CLEAR_STATE, 0);
+ ptr[i++] = 0x80000000;
+
+
+ /* Program compute regs */
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START;
+ ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 8;
+ ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 40;
+
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_PGM_RSRC1 - PACKET3_SET_SH_REG_START;
+ /*
+ * 002c0040 COMPUTE_PGM_RSRC1 <- VGPRS = 0
+ SGPRS = 1
+ PRIORITY = 0
+ FLOAT_MODE = 192 (0xc0)
+ PRIV = 0
+ DX10_CLAMP = 1
+ DEBUG_MODE = 0
+ IEEE_MODE = 0
+ BULKY = 0
+ CDBG_USER = 0
+ *
+ */
+ ptr[i++] = 0x002c0040;
+
+
+ /*
+ * 00000010 COMPUTE_PGM_RSRC2 <- SCRATCH_EN = 0
+ USER_SGPR = 8
+ TRAP_PRESENT = 0
+ TGID_X_EN = 0
+ TGID_Y_EN = 0
+ TGID_Z_EN = 0
+ TG_SIZE_EN = 0
+ TIDIG_COMP_CNT = 0
+ EXCP_EN_MSB = 0
+ LDS_SIZE = 0
+ EXCP_EN = 0
+ *
+ */
+ ptr[i++] = 0x00000010;
+
+
+/*
+ * 00000100 COMPUTE_TMPRING_SIZE <- WAVES = 256 (0x100)
+ WAVESIZE = 0
+ *
+ */
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr[i++] = mmCOMPUTE_TMPRING_SIZE - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0x00000100;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_USER_DATA_0 - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0xffffffff & (ib_result_mc_address + DATA_OFFSET * 4);
+ ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr[i++] = mmCOMPUTE_RESOURCE_LIMITS - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 3);
+ ptr[i++] = mmCOMPUTE_NUM_THREAD_X - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+
+
+ /* Dispatch */
+ ptr[i++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 0x00000045; /* DISPATCH DIRECT field */
+
+
+ while (i & 7)
+ ptr[i++] = 0xffff1000; /* type3 nop packet */
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = i;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle[1], 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ seq_no = ibs_request.seq_no;
+
+
+
+ /* Prepare second command with dependency on the first */
+ j = i;
+ ptr[i++] = PACKET3(PACKET3_WRITE_DATA, 3);
+ ptr[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
+ ptr[i++] = 0xfffffffc & (ib_result_mc_address + DATA_OFFSET * 4);
+ ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
+ ptr[i++] = 99;
+
+ while (i & 7)
+ ptr[i++] = 0xffff1000; /* type3 nop packet */
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address + j * 4;
+ ib_info.size = i - j;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ ibs_request.number_of_dependencies = 1;
+
+ ibs_request.dependencies = calloc(1, sizeof(*ibs_request.dependencies));
+ ibs_request.dependencies[0].context = context_handle[1];
+ ibs_request.dependencies[0].ip_instance = 0;
+ ibs_request.dependencies[0].ring = 0;
+ ibs_request.dependencies[0].fence = seq_no;
+
+
+ r = amdgpu_cs_submit(context_handle[0], 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle[0];
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Expect the second command to wait for shader to complete */
+ CU_ASSERT_EQUAL(ptr[DATA_OFFSET], 99);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_ctx_free(context_handle[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free(ibs_request.dependencies);
+}
+
+static void amdgpu_compute_dispatch_test(void)
+{
+ amdgpu_test_dispatch_helper(device_handle, AMDGPU_HW_IP_COMPUTE);
+}
+static void amdgpu_gfx_dispatch_test(void)
+{
+ amdgpu_test_dispatch_helper(device_handle, AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_draw_test(void)
+{
+ amdgpu_test_draw_helper(device_handle);
+}
+static void amdgpu_gpu_reset_test(void)
+{
+ int r;
+ char debugfs_path[256], tmp[10];
+ int fd;
+ struct stat sbuf;
+ amdgpu_context_handle context_handle;
+ uint32_t hang_state, hangs;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = fstat(drm_amdgpu[0], &sbuf);
+ CU_ASSERT_EQUAL(r, 0);
+
+ sprintf(debugfs_path, "/sys/kernel/debug/dri/%d/amdgpu_gpu_recover", minor(sbuf.st_rdev));
+ fd = open(debugfs_path, O_RDONLY);
+ CU_ASSERT(fd >= 0);
+
+ r = read(fd, tmp, sizeof(tmp)/sizeof(char));
+ CU_ASSERT(r > 0);
+
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
+
+ close(fd);
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_compute_dispatch_test();
+ amdgpu_gfx_dispatch_test();
+}
+
+static void amdgpu_stable_pstate_test(void)
+{
+ int r;
+ amdgpu_context_handle context_handle;
+ uint32_t current_pstate = 0, new_pstate = 0;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_stable_pstate(context_handle,
+ AMDGPU_CTX_OP_GET_STABLE_PSTATE,
+ 0, &current_pstate);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(new_pstate, AMDGPU_CTX_STABLE_PSTATE_NONE);
+
+ r = amdgpu_cs_ctx_stable_pstate(context_handle,
+ AMDGPU_CTX_OP_SET_STABLE_PSTATE,
+ AMDGPU_CTX_STABLE_PSTATE_PEAK, NULL);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_stable_pstate(context_handle,
+ AMDGPU_CTX_OP_GET_STABLE_PSTATE,
+ 0, &new_pstate);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(new_pstate, AMDGPU_CTX_STABLE_PSTATE_PEAK);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c
new file mode 100644
index 0000000..8fc7fe2
--- /dev/null
+++ b/tests/amdgpu/bo_tests.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#define BUFFER_SIZE (4*1024)
+#define BUFFER_ALIGN (4*1024)
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static amdgpu_bo_handle buffer_handle;
+static uint64_t virtual_mc_base_address;
+static amdgpu_va_handle va_handle;
+
+static void amdgpu_bo_export_import(void);
+static void amdgpu_bo_metadata(void);
+static void amdgpu_bo_map_unmap(void);
+static void amdgpu_memory_alloc(void);
+static void amdgpu_mem_fail_alloc(void);
+static void amdgpu_bo_find_by_cpu_mapping(void);
+
+CU_TestInfo bo_tests[] = {
+ { "Export/Import", amdgpu_bo_export_import },
+ { "Metadata", amdgpu_bo_metadata },
+ { "CPU map/unmap", amdgpu_bo_map_unmap },
+ { "Memory alloc Test", amdgpu_memory_alloc },
+ { "Memory fail alloc Test", amdgpu_mem_fail_alloc },
+ { "Find bo by CPU mapping", amdgpu_bo_find_by_cpu_mapping },
+ CU_TEST_INFO_NULL,
+};
+
+int suite_bo_tests_init(void)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ uint64_t va;
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+
+ return CUE_SINIT_FAILED;
+ }
+
+ req.alloc_size = BUFFER_SIZE;
+ req.phys_alignment = BUFFER_ALIGN;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ BUFFER_SIZE, BUFFER_ALIGN, 0,
+ &va, &va_handle, 0);
+ if (r)
+ goto error_va_alloc;
+
+ r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, va, 0, AMDGPU_VA_OP_MAP);
+ if (r)
+ goto error_va_map;
+
+ buffer_handle = buf_handle;
+ virtual_mc_base_address = va;
+
+ return CUE_SUCCESS;
+
+error_va_map:
+ amdgpu_va_range_free(va_handle);
+
+error_va_alloc:
+ amdgpu_bo_free(buf_handle);
+ return CUE_SINIT_FAILED;
+}
+
+int suite_bo_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(buffer_handle, 0, BUFFER_SIZE,
+ virtual_mc_base_address, 0,
+ AMDGPU_VA_OP_UNMAP);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_va_range_free(va_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_bo_free(buffer_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static void amdgpu_bo_export_import_do_type(enum amdgpu_bo_handle_type type)
+{
+ struct amdgpu_bo_import_result res = {0};
+ uint32_t shared_handle;
+ int r;
+
+ r = amdgpu_bo_export(buffer_handle, type, &shared_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_import(device_handle, type, shared_handle, &res);
+ CU_ASSERT_EQUAL(r, 0);
+
+ CU_ASSERT_EQUAL(res.buf_handle, buffer_handle);
+ CU_ASSERT_EQUAL(res.alloc_size, BUFFER_SIZE);
+
+ r = amdgpu_bo_free(res.buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_bo_export_import(void)
+{
+ if (open_render_node) {
+ printf("(DRM render node is used. Skip export/Import test) ");
+ return;
+ }
+
+ amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_gem_flink_name);
+ amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_dma_buf_fd);
+}
+
+static void amdgpu_bo_metadata(void)
+{
+ struct amdgpu_bo_metadata meta = {0};
+ struct amdgpu_bo_info info = {0};
+ int r;
+
+ meta.size_metadata = 4;
+ meta.umd_metadata[0] = 0xdeadbeef;
+
+ r = amdgpu_bo_set_metadata(buffer_handle, &meta);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_query_info(buffer_handle, &info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ CU_ASSERT_EQUAL(info.metadata.size_metadata, 4);
+ CU_ASSERT_EQUAL(info.metadata.umd_metadata[0], 0xdeadbeef);
+}
+
+static void amdgpu_bo_map_unmap(void)
+{
+ uint32_t *ptr;
+ int i, r;
+
+ r = amdgpu_bo_cpu_map(buffer_handle, (void **)&ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_NOT_EQUAL(ptr, NULL);
+
+ for (i = 0; i < (BUFFER_SIZE / 4); ++i)
+ ptr[i] = 0xdeadbeef;
+
+ r = amdgpu_bo_cpu_unmap(buffer_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_memory_alloc(void)
+{
+ amdgpu_bo_handle bo;
+ amdgpu_va_handle va_handle;
+ uint64_t bo_mc;
+ int r;
+
+ /* Test visible VRAM */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test invisible VRAM */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GART Cacheable */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ 0, &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GART USWC */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_CREATE_CPU_GTT_USWC,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GDS */
+ bo = gpu_mem_alloc(device_handle, 1024, 0,
+ AMDGPU_GEM_DOMAIN_GDS, 0,
+ NULL, NULL);
+ r = gpu_mem_free(bo, NULL, 0, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GWS */
+ bo = gpu_mem_alloc(device_handle, 1, 0,
+ AMDGPU_GEM_DOMAIN_GWS, 0,
+ NULL, NULL);
+ r = gpu_mem_free(bo, NULL, 0, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test OA */
+ bo = gpu_mem_alloc(device_handle, 1, 0,
+ AMDGPU_GEM_DOMAIN_OA, 0,
+ NULL, NULL);
+ r = gpu_mem_free(bo, NULL, 0, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_mem_fail_alloc(void)
+{
+ int r;
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+
+ /* Test impossible mem allocation, 1TB */
+ req.alloc_size = 0xE8D4A51000;
+ req.phys_alignment = 4096;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;
+ req.flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, -ENOMEM);
+
+ if (!r) {
+ r = amdgpu_bo_free(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+}
+
+static void amdgpu_bo_find_by_cpu_mapping(void)
+{
+ amdgpu_bo_handle bo_handle, find_bo_handle;
+ amdgpu_va_handle va_handle;
+ void *bo_cpu;
+ uint64_t bo_mc_address;
+ uint64_t offset;
+ int r;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &bo_handle, &bo_cpu,
+ &bo_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_find_bo_by_cpu_mapping(device_handle,
+ bo_cpu,
+ 4096,
+ &find_bo_handle,
+ &offset);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(offset, 0);
+ CU_ASSERT_EQUAL(bo_handle->handle, find_bo_handle->handle);
+
+ atomic_dec(&find_bo_handle->refcount, 1);
+ r = amdgpu_bo_unmap_and_free(bo_handle, va_handle,
+ bo_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
diff --git a/tests/amdgpu/cp_dma_tests.c b/tests/amdgpu/cp_dma_tests.c
new file mode 100644
index 0000000..e82214f
--- /dev/null
+++ b/tests/amdgpu/cp_dma_tests.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 8
+
+#define DMA_SIZE 4097
+#define DMA_DATA_BYTE 0xea
+
+static bool do_p2p;
+
+static amdgpu_device_handle executing_device_handle;
+static uint32_t executing_device_major_version;
+static uint32_t executing_device_minor_version;
+
+static amdgpu_device_handle peer_exporting_device_handle;
+static uint32_t peer_exporting_device_major_version;
+static uint32_t peer_exporting_device_minor_version;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static uint32_t *ib_cpu;
+static uint64_t ib_mc_address;
+static amdgpu_va_handle ib_va_handle;
+static uint32_t num_dword;
+
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static uint8_t* reference_data;
+
+static void amdgpu_cp_dma_host_to_vram(void);
+static void amdgpu_cp_dma_vram_to_host(void);
+static void amdgpu_cp_dma_p2p_vram_to_vram(void);
+static void amdgpu_cp_dma_p2p_host_to_vram(void);
+static void amdgpu_cp_dma_p2p_vram_to_host(void);
+
+/**
+ * Tests in cp dma test suite
+ */
+CU_TestInfo cp_dma_tests[] = {
+ { "CP DMA write Host to VRAM", amdgpu_cp_dma_host_to_vram },
+ { "CP DMA write VRAM to Host", amdgpu_cp_dma_vram_to_host },
+
+ { "Peer to Peer CP DMA write VRAM to VRAM", amdgpu_cp_dma_p2p_vram_to_vram },
+ { "Peer to Peer CP DMA write Host to VRAM", amdgpu_cp_dma_p2p_host_to_vram },
+ { "Peer to Peer CP DMA write VRAM to Host", amdgpu_cp_dma_p2p_vram_to_host },
+ CU_TEST_INFO_NULL,
+};
+
+struct amdgpu_cp_dma_bo{
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t gpu_va;
+ uint64_t size;
+};
+
+static int allocate_bo_and_va(amdgpu_device_handle dev,
+ uint64_t size, uint64_t alignment,
+ uint32_t heap, uint64_t alloc_flags,
+ struct amdgpu_cp_dma_bo *bo) {
+ struct amdgpu_bo_alloc_request request = {};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t vmc_addr;
+ int r;
+
+ request.alloc_size = size;
+ request.phys_alignment = alignment;
+ request.preferred_heap = heap;
+ request.flags = alloc_flags;
+
+ r = amdgpu_bo_alloc(dev, &request, &buf_handle);
+ if (r)
+ goto error_bo_alloc;
+
+ r = amdgpu_va_range_alloc(dev, amdgpu_gpu_va_range_general,
+ size, alignment, 0,
+ &vmc_addr, &va_handle, 0);
+ if (r)
+ goto error_va_alloc;
+
+ r = amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr,
+ AMDGPU_VM_PAGE_READABLE |
+ AMDGPU_VM_PAGE_WRITEABLE |
+ AMDGPU_VM_PAGE_EXECUTABLE,
+ AMDGPU_VA_OP_MAP);
+ if (r)
+ goto error_va_map;
+
+ bo->buf_handle = buf_handle;
+ bo->va_handle = va_handle;
+ bo->gpu_va = vmc_addr;
+ bo->size = size;
+
+ return 0;
+
+error_va_map:
+ amdgpu_bo_va_op(buf_handle, 0,
+ size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
+
+error_va_alloc:
+ amdgpu_va_range_free(va_handle);
+
+error_bo_alloc:
+ amdgpu_bo_free(buf_handle);
+
+ return r;
+}
+
+static int import_dma_buf_to_bo(amdgpu_device_handle dev,
+ int dmabuf_fd, struct amdgpu_cp_dma_bo *bo) {
+ amdgpu_va_handle va_handle;
+ uint64_t vmc_addr;
+ int r;
+ struct amdgpu_bo_import_result bo_import_result = {};
+
+ r = amdgpu_bo_import(dev, amdgpu_bo_handle_type_dma_buf_fd,
+ dmabuf_fd, &bo_import_result);
+ if (r)
+ goto error_bo_import;
+
+ r = amdgpu_va_range_alloc(dev, amdgpu_gpu_va_range_general,
+ bo_import_result.alloc_size, 0, 0,
+ &vmc_addr, &va_handle, 0);
+ if (r)
+ goto error_va_alloc;
+
+ r = amdgpu_bo_va_op(bo_import_result.buf_handle, 0,
+ bo_import_result.alloc_size, vmc_addr,
+ AMDGPU_VM_PAGE_READABLE |
+ AMDGPU_VM_PAGE_WRITEABLE |
+ AMDGPU_VM_PAGE_EXECUTABLE,
+ AMDGPU_VA_OP_MAP);
+ if (r)
+ goto error_va_map;
+
+ bo->buf_handle = bo_import_result.buf_handle;
+ bo->va_handle = va_handle;
+ bo->gpu_va = vmc_addr;
+ bo->size = bo_import_result.alloc_size;
+
+ return 0;
+
+error_va_map:
+ amdgpu_bo_va_op(bo_import_result.buf_handle, 0,
+ bo_import_result.alloc_size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
+
+error_va_alloc:
+ amdgpu_va_range_free(va_handle);
+
+error_bo_import:
+ amdgpu_bo_free(bo_import_result.buf_handle);
+
+ return r;
+}
+
+static int free_bo(struct amdgpu_cp_dma_bo bo) {
+ int r;
+ r = amdgpu_bo_va_op(bo.buf_handle, 0,
+ bo.size, bo.gpu_va, 0, AMDGPU_VA_OP_UNMAP);
+ if(r)
+ return r;
+
+ r = amdgpu_va_range_free(bo.va_handle);
+ if(r)
+ return r;
+
+ r = amdgpu_bo_free(bo.buf_handle);
+ if(r)
+ return r;
+
+ return 0;
+}
+
+static int submit_and_sync() {
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ uint32_t family_id, chip_id, chip_rev;
+ unsigned gc_ip_type;
+ int r;
+
+ r = amdgpu_bo_list_create(executing_device_handle,
+ num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ family_id = executing_device_handle->info.family_id;
+ chip_id = executing_device_handle->info.chip_external_rev;
+ chip_rev = executing_device_handle->info.chip_rev;
+
+ gc_ip_type = (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) ?
+ AMDGPU_HW_IP_COMPUTE : AMDGPU_HW_IP_GFX;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = num_dword;
+
+ ibs_request.ip_type = gc_ip_type;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = gc_ip_type;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void cp_dma_cmd(struct amdgpu_cp_dma_bo src_bo,
+ struct amdgpu_cp_dma_bo dst_bo) {
+ _Static_assert(DMA_SIZE < (1 << 26), "DMA size exceeds CP DMA maximium!");
+
+ ib_cpu[0] = 0xc0055000;
+ ib_cpu[1] = 0x80000000;
+ ib_cpu[2] = src_bo.gpu_va & 0x00000000ffffffff;
+ ib_cpu[3] = (src_bo.gpu_va & 0xffffffff00000000) >> 32;
+ ib_cpu[4] = dst_bo.gpu_va & 0x00000000ffffffff;
+ ib_cpu[5] = (dst_bo.gpu_va & 0xffffffff00000000) >> 32;
+ // size is read from the lower 26bits.
+ ib_cpu[6] = ((1 << 26) - 1) & DMA_SIZE;
+ ib_cpu[7] = 0xffff1000;
+
+ num_dword = 8;
+
+ resources[0] = src_bo.buf_handle;
+ resources[1] = dst_bo.buf_handle;
+ resources[2] = ib_handle;
+ num_resources = 3;
+}
+
+static void amdgpu_cp_dma(uint32_t src_heap, uint32_t dst_heap) {
+ int r;
+ struct amdgpu_cp_dma_bo src_bo = {0};
+ struct amdgpu_cp_dma_bo dst_bo = {0};
+ void *src_bo_cpu;
+ void *dst_bo_cpu;
+
+ /* allocate the src bo, set its data to DMA_DATA_BYTE */
+ r = allocate_bo_and_va(executing_device_handle, DMA_SIZE, 4096,
+ src_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &src_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(src_bo.buf_handle, (void **)&src_bo_cpu);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(src_bo_cpu, DMA_DATA_BYTE, DMA_SIZE);
+
+ r = amdgpu_bo_cpu_unmap(src_bo.buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* allocate the dst bo and clear its content to all 0 */
+ r = allocate_bo_and_va(executing_device_handle, DMA_SIZE, 4096,
+ dst_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &dst_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(dst_bo.buf_handle, (void **)&dst_bo_cpu);
+ CU_ASSERT_EQUAL(r, 0);
+
+ _Static_assert(DMA_DATA_BYTE != 0, "Initialization data should be different from DMA data!");
+ memset(dst_bo_cpu, 0, DMA_SIZE);
+
+ /* record CP DMA command and dispatch the command */
+ cp_dma_cmd(src_bo, dst_bo);
+
+ r = submit_and_sync();
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* verify the dst bo is filled with DMA_DATA_BYTE */
+ CU_ASSERT_EQUAL(memcmp(dst_bo_cpu, reference_data, DMA_SIZE) == 0, true);
+
+ r = amdgpu_bo_cpu_unmap(dst_bo.buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = free_bo(src_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = free_bo(dst_bo);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cp_dma_p2p(uint32_t src_heap, uint32_t dst_heap) {
+ int r;
+ struct amdgpu_cp_dma_bo exported_bo = {0};
+ int dma_buf_fd;
+ int dma_buf_fd_dup;
+ struct amdgpu_cp_dma_bo src_bo = {0};
+ struct amdgpu_cp_dma_bo imported_dst_bo = {0};
+ void *exported_bo_cpu;
+ void *src_bo_cpu;
+
+ /* allocate a bo on the peer device and export it to dma-buf */
+ r = allocate_bo_and_va(peer_exporting_device_handle, DMA_SIZE, 4096,
+ src_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &exported_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* map the exported bo and clear its content to 0 */
+ _Static_assert(DMA_DATA_BYTE != 0, "Initialization data should be different from DMA data!");
+ r = amdgpu_bo_cpu_map(exported_bo.buf_handle, (void **)&exported_bo_cpu);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(exported_bo_cpu, 0, DMA_SIZE);
+
+ r = amdgpu_bo_export(exported_bo.buf_handle,
+ amdgpu_bo_handle_type_dma_buf_fd, (uint32_t*)&dma_buf_fd);
+ CU_ASSERT_EQUAL(r, 0);
+
+ // According to amdgpu_drm:
+ // "Buffer must be "imported" only using new "fd"
+ // (different from one used by "exporter")"
+ dma_buf_fd_dup = dup(dma_buf_fd);
+ r = close(dma_buf_fd);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* import the dma-buf to the executing device, imported bo is the DMA destination */
+ r = import_dma_buf_to_bo(
+ executing_device_handle, dma_buf_fd_dup, &imported_dst_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = close(dma_buf_fd_dup);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* allocate the src bo and set its content to DMA_DATA_BYTE */
+ r = allocate_bo_and_va(executing_device_handle, DMA_SIZE, 4096,
+ dst_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &src_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(src_bo.buf_handle, (void **)&src_bo_cpu);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(src_bo_cpu, DMA_DATA_BYTE, DMA_SIZE);
+
+ r = amdgpu_bo_cpu_unmap(src_bo.buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* record CP DMA command and dispatch the command */
+ cp_dma_cmd(src_bo, imported_dst_bo);
+
+ r = submit_and_sync();
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* verify the bo from the peer device is filled with DMA_DATA_BYTE */
+ CU_ASSERT_EQUAL(memcmp(exported_bo_cpu, reference_data, DMA_SIZE) == 0, true);
+
+ r = amdgpu_bo_cpu_unmap(exported_bo.buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = free_bo(exported_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = free_bo(imported_dst_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = free_bo(src_bo);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cp_dma_host_to_vram(void) {
+ amdgpu_cp_dma(AMDGPU_GEM_DOMAIN_GTT, AMDGPU_GEM_DOMAIN_VRAM);
+}
+
+static void amdgpu_cp_dma_vram_to_host(void) {
+ amdgpu_cp_dma(AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_GTT);
+}
+
+static void amdgpu_cp_dma_p2p_vram_to_vram(void) {
+ amdgpu_cp_dma_p2p(AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_VRAM);
+}
+
+static void amdgpu_cp_dma_p2p_host_to_vram(void) {
+ amdgpu_cp_dma_p2p(AMDGPU_GEM_DOMAIN_GTT, AMDGPU_GEM_DOMAIN_VRAM);
+}
+
+static void amdgpu_cp_dma_p2p_vram_to_host(void) {
+ amdgpu_cp_dma_p2p(AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_GTT);
+}
+
+int suite_cp_dma_tests_init() {
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0],
+ &executing_device_major_version,
+ &executing_device_minor_version,
+ &executing_device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_cs_ctx_create(executing_device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(executing_device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_handle, (void**)&ib_cpu,
+ &ib_mc_address, &ib_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ if (do_p2p) {
+ r = amdgpu_device_initialize(drm_amdgpu[1],
+ &peer_exporting_device_major_version,
+ &peer_exporting_device_minor_version,
+ &peer_exporting_device_handle);
+
+ if (r)
+ return CUE_SINIT_FAILED;
+ }
+
+ reference_data = (uint8_t*)malloc(DMA_SIZE);
+ if (!reference_data)
+ return CUE_SINIT_FAILED;
+ memset(reference_data, DMA_DATA_BYTE, DMA_SIZE);
+
+ return CUE_SUCCESS;
+}
+
+int suite_cp_dma_tests_clean() {
+ int r;
+
+ free(reference_data);
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
+ ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(executing_device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ if (do_p2p) {
+ r = amdgpu_device_deinitialize(peer_exporting_device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+CU_BOOL suite_cp_dma_tests_enable(void) {
+ int r = 0;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0],
+ &executing_device_major_version,
+ &executing_device_minor_version,
+ &executing_device_handle))
+ return CU_FALSE;
+
+ if (!(executing_device_handle->info.family_id >= AMDGPU_FAMILY_AI &&
+ executing_device_handle->info.family_id <= AMDGPU_FAMILY_NV)) {
+ printf("Testing device has ASIC that is not supported by CP-DMA test suite!\n");
+ return CU_FALSE;
+ }
+
+ if (amdgpu_device_deinitialize(executing_device_handle))
+ return CU_FALSE;
+
+ if (drm_amdgpu[1] >= 0) {
+ r = amdgpu_device_initialize(drm_amdgpu[1],
+ &peer_exporting_device_major_version,
+ &peer_exporting_device_minor_version,
+ &peer_exporting_device_handle);
+
+ if (r == 0 && (peer_exporting_device_handle->info.family_id >= AMDGPU_FAMILY_AI &&
+ peer_exporting_device_handle->info.family_id <= AMDGPU_FAMILY_NV)) {
+ do_p2p = true;
+ }
+
+ if (r == 0 && amdgpu_device_deinitialize(peer_exporting_device_handle) != 0) {
+ printf("Deinitialize peer_exporting_device_handle failed!\n");
+ return CU_FALSE;
+ }
+ }
+
+ if (!do_p2p) {
+ amdgpu_set_test_active("CP DMA Tests", "Peer to Peer CP DMA write VRAM to VRAM", CU_FALSE);
+ amdgpu_set_test_active("CP DMA Tests", "Peer to Peer CP DMA write Host to VRAM", CU_FALSE);
+ amdgpu_set_test_active("CP DMA Tests", "Peer to Peer CP DMA write VRAM to Host", CU_FALSE);
+ printf("Peer device is not opened or has ASIC not supported by the suite, skip all Peer to Peer tests.\n");
+ }
+
+ return CU_TRUE;
+}
diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c
new file mode 100644
index 0000000..f509678
--- /dev/null
+++ b/tests/amdgpu/cs_tests.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "decode_messages.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static uint64_t ib_mc_address;
+static uint32_t *ib_cpu;
+static amdgpu_va_handle ib_va_handle;
+
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static void amdgpu_cs_uvd_create(void);
+static void amdgpu_cs_uvd_decode(void);
+static void amdgpu_cs_uvd_destroy(void);
+
+CU_TestInfo cs_tests[] = {
+ { "UVD create", amdgpu_cs_uvd_create },
+ { "UVD decode", amdgpu_cs_uvd_decode },
+ { "UVD destroy", amdgpu_cs_uvd_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_cs_tests_enable(void)
+{
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+ chip_id = device_handle->info.chip_external_rev;
+ chip_rev = device_handle->info.chip_rev;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+
+ if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI ||
+ asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) {
+ printf("\n\nThe ASIC NOT support UVD, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ return CU_TRUE;
+}
+
+int suite_cs_tests_init(void)
+{
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ amdgpu_va_handle ib_result_va_handle;
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+
+ return CUE_SINIT_FAILED;
+ }
+
+ family_id = device_handle->info.family_id;
+ /* VI asic POLARIS10/11 have specific external_rev_id */
+ chip_rev = device_handle->info.chip_rev;
+ chip_id = device_handle->info.chip_external_rev;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address,
+ &ib_result_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ ib_handle = ib_result_handle;
+ ib_mc_address = ib_result_mc_address;
+ ib_cpu = ib_result_cpu;
+ ib_va_handle = ib_result_va_handle;
+
+ return CUE_SUCCESS;
+}
+
+int suite_cs_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
+ ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void uvd_cmd(uint64_t addr, unsigned cmd, int *idx)
+{
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC4 : 0x81C4;
+ ib_cpu[(*idx)++] = addr;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC5 : 0x81C5;
+ ib_cpu[(*idx)++] = addr >> 32;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC3 : 0x81C3;
+ ib_cpu[(*idx)++] = cmd << 1;
+}
+
+static void amdgpu_cs_uvd_create(void)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ uint64_t va = 0;
+ amdgpu_va_handle va_handle;
+ void *msg;
+ int i, r;
+
+ req.alloc_size = 4*1024;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ 4096, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(buf_handle, &msg);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memcpy(msg, uvd_create_msg, sizeof(uvd_create_msg));
+
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ ((uint8_t*)msg)[0x10] = 7;
+ /* chip beyond polaris 10/11 */
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
+ /* dpb size */
+ ((uint8_t*)msg)[0x28] = 0x00;
+ ((uint8_t*)msg)[0x29] = 0x94;
+ ((uint8_t*)msg)[0x2A] = 0x6B;
+ ((uint8_t*)msg)[0x2B] = 0x00;
+ }
+ }
+
+ r = amdgpu_bo_cpu_unmap(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ num_resources = 0;
+ resources[num_resources++] = buf_handle;
+ resources[num_resources++] = ib_handle;
+
+ i = 0;
+ uvd_cmd(va, 0x0, &i);
+ for (; i % 16; ++i)
+ ib_cpu[i] = 0x80000000;
+
+ r = submit(i, AMDGPU_HW_IP_UVD);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_uvd_decode(void)
+{
+ const unsigned dpb_size = 15923584, dt_size = 737280;
+ uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr;
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ uint64_t sum;
+ uint8_t *ptr;
+ int i, r;
+
+ req.alloc_size = 4*1024; /* msg */
+ req.alloc_size += 4*1024; /* fb */
+ if (family_id >= AMDGPU_FAMILY_VI)
+ req.alloc_size += 4096; /*it_scaling_table*/
+ req.alloc_size += ALIGN(sizeof(uvd_bitstream), 4*1024);
+ req.alloc_size += ALIGN(dpb_size, 4*1024);
+ req.alloc_size += ALIGN(dt_size, 4*1024);
+
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(buf_handle, (void **)&ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memcpy(ptr, uvd_decode_msg, sizeof(uvd_decode_msg));
+ memcpy(ptr + sizeof(uvd_decode_msg), avc_decode_msg, sizeof(avc_decode_msg));
+
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ ptr[0x10] = 7;
+ ptr[0x98] = 0x00;
+ ptr[0x99] = 0x02;
+ /* chip beyond polaris10/11 */
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
+ /* dpb size */
+ ptr[0x24] = 0x00;
+ ptr[0x25] = 0x94;
+ ptr[0x26] = 0x6B;
+ ptr[0x27] = 0x00;
+ /*ctx size */
+ ptr[0x2C] = 0x00;
+ ptr[0x2D] = 0xAF;
+ ptr[0x2E] = 0x50;
+ ptr[0x2F] = 0x00;
+ }
+ }
+
+ ptr += 4*1024;
+ memset(ptr, 0, 4*1024);
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ ptr += 4*1024;
+ memcpy(ptr, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
+ }
+
+ ptr += 4*1024;
+ memcpy(ptr, uvd_bitstream, sizeof(uvd_bitstream));
+
+ ptr += ALIGN(sizeof(uvd_bitstream), 4*1024);
+ memset(ptr, 0, dpb_size);
+
+ ptr += ALIGN(dpb_size, 4*1024);
+ memset(ptr, 0, dt_size);
+
+ num_resources = 0;
+ resources[num_resources++] = buf_handle;
+ resources[num_resources++] = ib_handle;
+
+ msg_addr = va;
+ fb_addr = msg_addr + 4*1024;
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ it_addr = fb_addr + 4*1024;
+ bs_addr = it_addr + 4*1024;
+ } else
+ bs_addr = fb_addr + 4*1024;
+ dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
+
+ ctx_addr = 0;
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
+ ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ }
+ }
+
+ dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
+
+ i = 0;
+ uvd_cmd(msg_addr, 0x0, &i);
+ uvd_cmd(dpb_addr, 0x1, &i);
+ uvd_cmd(dt_addr, 0x2, &i);
+ uvd_cmd(fb_addr, 0x3, &i);
+ uvd_cmd(bs_addr, 0x100, &i);
+
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ uvd_cmd(it_addr, 0x204, &i);
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64))
+ uvd_cmd(ctx_addr, 0x206, &i);
+ }
+
+ ib_cpu[i++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC6 : 0x81C6;
+ ib_cpu[i++] = 0x1;
+ for (; i % 16; ++i)
+ ib_cpu[i] = 0x80000000;
+
+ r = submit(i, AMDGPU_HW_IP_UVD);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* TODO: use a real CRC32 */
+ for (i = 0, sum = 0; i < dt_size; ++i)
+ sum += ptr[i];
+ CU_ASSERT_EQUAL(sum, SUM_DECODE);
+
+ r = amdgpu_bo_cpu_unmap(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_uvd_destroy(void)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ void *msg;
+ int i, r;
+
+ req.alloc_size = 4*1024;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(buf_handle, &msg);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memcpy(msg, uvd_destroy_msg, sizeof(uvd_destroy_msg));
+ if (family_id >= AMDGPU_FAMILY_VI)
+ ((uint8_t*)msg)[0x10] = 7;
+
+ r = amdgpu_bo_cpu_unmap(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ num_resources = 0;
+ resources[num_resources++] = buf_handle;
+ resources[num_resources++] = ib_handle;
+
+ i = 0;
+ uvd_cmd(va, 0x0, &i);
+ for (; i % 16; ++i)
+ ib_cpu[i] = 0x80000000;
+
+ r = submit(i, AMDGPU_HW_IP_UVD);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
diff --git a/tests/amdgpu/deadlock_tests.c b/tests/amdgpu/deadlock_tests.c
new file mode 100644
index 0000000..2928233
--- /dev/null
+++ b/tests/amdgpu/deadlock_tests.c
@@ -0,0 +1,696 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#if HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#include <pthread.h>
+
+
+/*
+ * This defines the delay in MS after which memory location designated for
+ * compression against reference value is written to, unblocking command
+ * processor
+ */
+#define WRITE_MEM_ADDRESS_DELAY_MS 100
+
+#define PACKET_TYPE3 3
+
+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
+ (((op) & 0xFF) << 8) | \
+ ((n) & 0x3FFF) << 16)
+
+#define PACKET3_WAIT_REG_MEM 0x3C
+#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0)
+ /* 0 - always
+ * 1 - <
+ * 2 - <=
+ * 3 - ==
+ * 4 - !=
+ * 5 - >=
+ * 6 - >
+ */
+#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4)
+ /* 0 - reg
+ * 1 - mem
+ */
+#define WAIT_REG_MEM_OPERATION(x) ((x) << 6)
+ /* 0 - wait_reg_mem
+ * 1 - wr_wait_wr_reg
+ */
+#define WAIT_REG_MEM_ENGINE(x) ((x) << 8)
+ /* 0 - me
+ * 1 - pfp
+ */
+
+#define PACKET3_WRITE_DATA 0x37
+#define WRITE_DATA_DST_SEL(x) ((x) << 8)
+ /* 0 - register
+ * 1 - memory (sync - via GRBM)
+ * 2 - gl2
+ * 3 - gds
+ * 4 - reserved
+ * 5 - memory (async - direct)
+ */
+#define WR_ONE_ADDR (1 << 16)
+#define WR_CONFIRM (1 << 20)
+#define WRITE_DATA_CACHE_POLICY(x) ((x) << 25)
+ /* 0 - LRU
+ * 1 - Stream
+ */
+#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
+ /* 0 - me
+ * 1 - pfp
+ * 2 - ce
+ */
+
+#define mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x54f
+
+#define SDMA_PKT_HEADER_OP(x) (x & 0xff)
+#define SDMA_OP_POLL_REGMEM 8
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static pthread_t stress_thread;
+static uint32_t *ptr;
+
+static uint32_t family_id;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+
+int use_uc_mtype = 0;
+
+static void amdgpu_deadlock_helper(unsigned ip_type);
+static void amdgpu_deadlock_gfx(void);
+static void amdgpu_deadlock_compute(void);
+static void amdgpu_illegal_reg_access();
+static void amdgpu_illegal_mem_access();
+static void amdgpu_deadlock_sdma(void);
+static void amdgpu_dispatch_hang_gfx(void);
+static void amdgpu_dispatch_hang_compute(void);
+static void amdgpu_dispatch_hang_slow_gfx(void);
+static void amdgpu_dispatch_hang_slow_compute(void);
+static void amdgpu_draw_hang_gfx(void);
+static void amdgpu_draw_hang_slow_gfx(void);
+static void amdgpu_hang_sdma(void);
+static void amdgpu_hang_slow_sdma(void);
+
+CU_BOOL suite_deadlock_tests_enable(void)
+{
+ CU_BOOL enable = CU_TRUE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+ chip_id = device_handle->info.chip_external_rev;
+ chip_rev = device_handle->info.chip_rev;
+
+ /*
+ * Only enable for ASICs supporting GPU reset and for which it's enabled
+ * by default (currently GFX8+ dGPUS and gfx9+ APUs). Note that Raven1
+ * did not support GPU reset, but newer variants do.
+ */
+ if (family_id == AMDGPU_FAMILY_SI ||
+ family_id == AMDGPU_FAMILY_KV ||
+ family_id == AMDGPU_FAMILY_CZ ||
+ family_id == AMDGPU_FAMILY_RV) {
+ printf("\n\nGPU reset is not enabled for the ASIC, deadlock suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) {
+ if (amdgpu_set_test_active("Deadlock Tests",
+ "gfx ring block test (set amdgpu.lockup_timeout=50)",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+ }
+
+ if (device_handle->info.family_id >= AMDGPU_FAMILY_AI)
+ use_uc_mtype = 1;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_deadlock_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_deadlock_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo deadlock_tests[] = {
+ { "gfx ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_gfx },
+ { "compute ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_compute },
+ { "sdma ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_sdma },
+ { "illegal reg access test", amdgpu_illegal_reg_access },
+ { "illegal mem access test (set amdgpu.vm_fault_stop=2)", amdgpu_illegal_mem_access },
+ { "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_gfx },
+ { "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_compute },
+ { "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_slow_gfx },
+ { "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_slow_compute },
+ { "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_gfx },
+ { "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_slow_gfx },
+ { "sdma ring corrupted header test (set amdgpu.lockup_timeout=50)", amdgpu_hang_sdma },
+ { "sdma ring slow linear copy test (set amdgpu.lockup_timeout=50)", amdgpu_hang_slow_sdma },
+ CU_TEST_INFO_NULL,
+};
+
+static void *write_mem_address(void *data)
+{
+ int i;
+
+ /* useconds_t range is [0, 1,000,000] so use loop for waits > 1s */
+ for (i = 0; i < WRITE_MEM_ADDRESS_DELAY_MS; i++)
+ usleep(1000);
+
+ ptr[256] = 0x1;
+
+ return 0;
+}
+
+static void amdgpu_deadlock_gfx(void)
+{
+ amdgpu_deadlock_helper(AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_deadlock_compute(void)
+{
+ amdgpu_deadlock_helper(AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_deadlock_helper(unsigned ip_type)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+
+ r = pthread_create(&stress_thread, NULL, write_mem_address, NULL);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map_raw(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, use_uc_mtype ? AMDGPU_VM_MTYPE_UC : 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+
+ ptr[0] = PACKET3(PACKET3_WAIT_REG_MEM, 5);
+ ptr[1] = (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
+ WAIT_REG_MEM_FUNCTION(4) | /* != */
+ WAIT_REG_MEM_ENGINE(0)); /* me */
+ ptr[2] = (ib_result_mc_address + 256*4) & 0xfffffffc;
+ ptr[3] = ((ib_result_mc_address + 256*4) >> 32) & 0xffffffff;
+ ptr[4] = 0x00000000; /* reference value */
+ ptr[5] = 0xffffffff; /* and mask */
+ ptr[6] = 0x00000004; /* poll interval */
+
+ for (i = 7; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+
+ ptr[256] = 0x0; /* the memory we wait on to change */
+
+
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = ip_type;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+ for (i = 0; i < 200; i++) {
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ }
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ pthread_join(stress_thread, NULL);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_deadlock_sdma(void)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t ring_id;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_DMA, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
+ r = pthread_create(&stress_thread, NULL, write_mem_address, NULL);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map_raw(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, use_uc_mtype ? AMDGPU_VM_MTYPE_UC : 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ i = 0;
+
+ ptr[i++] = SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
+ (0 << 26) | /* WAIT_REG_MEM */
+ (4 << 28) | /* != */
+ (1 << 31); /* memory */
+ ptr[i++] = (ib_result_mc_address + 256*4) & 0xfffffffc;
+ ptr[i++] = ((ib_result_mc_address + 256*4) >> 32) & 0xffffffff;
+ ptr[i++] = 0x00000000; /* reference value */
+ ptr[i++] = 0xffffffff; /* and mask */
+ ptr[i++] = 4 | /* poll interval */
+ (0xfff << 16); /* retry count */
+
+ for (; i < 16; i++)
+ ptr[i] = 0;
+
+ ptr[256] = 0x0; /* the memory we wait on to change */
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_DMA;
+ ibs_request.ring = ring_id;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ for (i = 0; i < 200; i++) {
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ }
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_DMA;
+ fence_status.ip_instance = 0;
+ fence_status.ring = ring_id;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ pthread_join(stress_thread, NULL);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void bad_access_helper(int reg_access)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map_raw(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ i = 0;
+
+ ptr[i++] = PACKET3(PACKET3_WRITE_DATA, 3);
+ ptr[i++] = (reg_access ? WRITE_DATA_DST_SEL(0) : WRITE_DATA_DST_SEL(5))| WR_CONFIRM;
+ ptr[i++] = reg_access ? mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR : 0xdeadbee0;
+ ptr[i++] = 0;
+ ptr[i++] = 0xdeadbeef;
+
+ for (; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_illegal_reg_access()
+{
+ bad_access_helper(1);
+}
+
+static void amdgpu_illegal_mem_access()
+{
+ bad_access_helper(0);
+}
+
+static void amdgpu_dispatch_hang_gfx(void)
+{
+ amdgpu_test_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_GFX);
+}
+static void amdgpu_dispatch_hang_compute(void)
+{
+ amdgpu_test_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_COMPUTE);
+}
+static void amdgpu_dispatch_hang_slow_gfx(void)
+{
+ amdgpu_test_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_GFX);
+}
+static void amdgpu_dispatch_hang_slow_compute(void)
+{
+ amdgpu_test_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_COMPUTE);
+}
+static void amdgpu_draw_hang_gfx(void)
+{
+ amdgpu_test_draw_hang_helper(device_handle);
+}
+static void amdgpu_draw_hang_slow_gfx(void)
+{
+ amdgpu_test_draw_hang_slow_helper(device_handle);
+}
+
+#define DMA_CORRUPTED_HEADER_HANG 1
+#define DMA_SLOW_LINEARCOPY_HANG 2
+
+static void amdgpu_hang_sdma_helper(unsigned hang_type)
+{
+ const int sdma_write_length = 1024;
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ amdgpu_bo_handle bo1, bo2;
+ amdgpu_bo_handle resources[3];
+ amdgpu_bo_list_handle bo_list;
+ void *ib_result_cpu;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_fence fence_status;
+ uint64_t bo1_mc, bo2_mc;
+ uint64_t ib_result_mc_address;
+ volatile unsigned char *bo1_cpu, *bo2_cpu;
+ amdgpu_va_handle bo1_va_handle, bo2_va_handle;
+ amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info;
+ int i, j, r;
+ uint32_t expired, ib_size;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_DMA, 0, &hw_ip_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (hang_type == DMA_CORRUPTED_HEADER_HANG)
+ ib_size = 4096;
+ else
+ ib_size = 4096 * 0x20000;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, ib_size, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ 0, &bo1,
+ (void**)&bo1_cpu, &bo1_mc,
+ &bo1_va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* set bo1 */
+ memset((void*)bo1_cpu, 0xaa, sdma_write_length);
+
+ /* allocate UC bo2 for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ 0, &bo2,
+ (void**)&bo2_cpu, &bo2_mc,
+ &bo2_va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* clear bo2 */
+ memset((void*)bo2_cpu, 0, sdma_write_length);
+
+ resources[0] = bo1;
+ resources[1] = bo2;
+ resources[2] = ib_result_handle;
+ r = amdgpu_bo_list_create(device_handle, 3,
+ resources, NULL, &bo_list);
+
+ /* fulfill PM4: with bad copy linear header */
+ ptr = ib_result_cpu;
+ i = 0;
+ if (hang_type == DMA_CORRUPTED_HEADER_HANG) {
+ ptr[i++] = 0x23decd3d;
+ ptr[i++] = sdma_write_length - 1;
+ ptr[i++] = 0;
+ ptr[i++] = 0xffffffff & bo1_mc;
+ ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ ptr[i++] = 0xffffffff & bo2_mc;
+ ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ } else {
+ for (j = 1; j < 0x20000; j++) {
+ ptr[i++] = 0x1;
+ ptr[i++] = sdma_write_length - 1;
+ ptr[i++] = 0;
+ ptr[i++] = 0xffffffff & bo1_mc;
+ ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ ptr[i++] = 0xffffffff & bo2_mc;
+ ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ ptr[i++] = 0x1;
+ ptr[i++] = sdma_write_length - 1;
+ ptr[i++] = 0;
+ ptr[i++] = 0xffffffff & bo2_mc;
+ ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ ptr[i++] = 0xffffffff & bo1_mc;
+ ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ }
+ }
+
+ /* exec command */
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = i;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_DMA;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_DMA;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_hang_sdma(void)
+{
+ amdgpu_hang_sdma_helper(DMA_CORRUPTED_HEADER_HANG);
+}
+static void amdgpu_hang_slow_sdma(void)
+{
+ amdgpu_hang_sdma_helper(DMA_SLOW_LINEARCOPY_HANG);
+}
diff --git a/tests/amdgpu/decode_messages.h b/tests/amdgpu/decode_messages.h
new file mode 100644
index 0000000..218cd77
--- /dev/null
+++ b/tests/amdgpu/decode_messages.h
@@ -0,0 +1,881 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _DECODE_MESSAGES_H_
+#define _DECODE_MESSAGES_H_
+
+#define SUM_DECODE 0x20345d8
+
+static const uint8_t uvd_create_msg[] = {
+ 0xe4,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x03,0x00,0x00,
+ 0xe0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xf9,0xf2,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t uvd_bitstream[] ={
+ 0x00,0x00,0x01,0x25,0xb8,0x20,0x20,0x21,0x44,0xc5,0x00,0x01,0x57,0x9b,0xef,0xbe,
+ 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
+ 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,
+ 0xbe,0xfb,0xef,0xbe,0xff,0x87,0xff,0xc2,0x58,0x0e,0x00,0x02,0x02,0xa0,0x00,0x20,
+ 0x3a,0x00,0x0d,0x00,0x01,0x01,0xa4,0xcb,0x94,0x73,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xaf,0x00,0x00,0x01,0x25,0x00,0xa2,0xb8,0x20,0x20,0x21,0x44,
+ 0xc5,0x00,0x01,0x57,0x9b,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,
+ 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
+ 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xff,0x87,0xff,0xc2,0x58,
+ 0x0e,0x00,0x02,0x02,0xa0,0x00,0x20,0x3a,0x00,0x0d,0x00,0x01,0x01,0xa4,0xcb,0x94,
+ 0x73,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xaf,0x00,0x00,0x01,0x25,
+ 0x00,0x51,0x2e,0x08,0x08,0x08,0x51,0x31,0x40,0x00,0x55,0xe6,0xfb,0xef,0xbe,0xfb,
+ 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,
+ 0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,
+ 0xfb,0xef,0xbf,0xe1,0xff,0xf0,0x96,0x03,0x80,0x00,0x80,0xa8,0x00,0x08,0x0e,0x80,
+ 0x03,0x40,0x00,0x40,0x69,0x32,0xe5,0x1c,0xfa,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xc0,0x00,0x00,0x01,0x25,0x00,0x79,0xae,0x08,0x08,0x08,0x51,0x31,
+ 0x40,0x00,0x55,0xe6,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,
+ 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
+ 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbf,0xe1,0xff,0xf0,0x96,0x03,
+ 0x80,0x00,0x80,0xa8,0x00,0x08,0x0e,0x80,0x03,0x40,0x00,0x40,0x69,0x32,0xe5,0x1c,
+ 0xfa,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xc0,0x00,0x00,0x01,0x25,
+ 0x00,0x28,0x8b,0x82,0x02,0x02,0x14,0x4c,0x50,0x00,0x15,0x79,0xbe,0xfb,0xef,0xbe,
+ 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
+ 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,
+ 0xbe,0xfb,0xef,0xf8,0x7f,0xfc,0x25,0x80,0xe0,0x00,0x20,0x2a,0x00,0x02,0x03,0xa0,
+ 0x00,0xd0,0x00,0x10,0x1a,0x4c,0xb9,0x47,0x3e,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
+ 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
+ 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
+ 0xeb,0xae,0xba,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t uvd_decode_msg[] = {
+ 0xe4,0x0d,0x00,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x80,0xf9,0xf2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0x80,0x07,0x00,0x00,0x60,0x09,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t avc_decode_msg[] = {
+ 0x02,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x85,0x00,0x00,0x00,0x88,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x01,0x00,0x03,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t uvd_destroy_msg[] = {
+ 0xe4,0x0d,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t uvd_it_scaling_table[] = {
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+};
+
+static const uint8_t vcn_dec_create_msg[] = {
+ 0x28,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x28,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,
+};
+
+static const uint8_t vcn_dec_decode_msg[] = {
+ 0x28,0x00,0x00,0x00,0x90,0x06,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
+ 0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xec,0x00,0x00,0x00,
+ 0x5c,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x94,0x6b,0x00,
+ 0x96,0x4e,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x50,0x00,
+ 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,
+ 0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0x80,0x07,0x00,0x00,0x60,0x09,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t vcn_dec_destroy_msg[] = {
+ 0x28,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t feedback_msg[] = {
+ 0x2c,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t jpeg_bitstream[] = {
+ 0xFF, 0xD8, 0xFF, 0xDB, 0x01, 0x06, 0x00, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08,
+ 0x08, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0C, 0x0C, 0x0B,
+ 0x0B, 0x0E, 0x0E, 0x0E, 0x11, 0x11, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC4, 0x00, 0x4B, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00, 0x08,
+ 0x03, 0x00, 0x22, 0x00, 0x01, 0x11, 0x00, 0x02, 0x11, 0x00, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00,
+ 0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00, 0x9F, 0xC0, 0x07, 0xFF, 0xD9, 0xFF, 0xD9,
+};
+
+#endif /* _DECODE_MESSAGES_H_ */
diff --git a/tests/amdgpu/frame.h b/tests/amdgpu/frame.h
new file mode 100644
index 0000000..335401c
--- /dev/null
+++ b/tests/amdgpu/frame.h
@@ -0,0 +1,1949 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _frame_h_
+#define _frame_h_
+
+static const uint8_t frame[] = {
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+ 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0xcd, 0x13, 0x67, 0xa2, 0x2b, 0xa5, 0x29,
+ 0x5d, 0xcb, 0xd5, 0xa4, 0x27, 0x2a, 0x62, 0x20, 0x70, 0x78, 0x6d, 0xe9, 0x1e, 0xeb, 0x25, 0xa6,
+ 0x62, 0x29, 0x13, 0xa4, 0xab, 0x29, 0x12, 0x35, 0x4c, 0x77, 0x73, 0x42, 0xe0, 0xd0, 0x62, 0xa5,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xad, 0x17, 0x5c, 0xc3, 0xdc, 0x41, 0x1e, 0xbe,
+ 0x4e, 0x90, 0xab, 0xbf, 0x86, 0x33, 0x1f, 0xeb, 0x15, 0xac, 0x64, 0x38, 0xd0, 0x44, 0xe6, 0x3e,
+ 0xe9, 0x50, 0x8f, 0x32, 0xbd, 0x18, 0x7a, 0x4a, 0xaa, 0x12, 0x61, 0x91, 0x62, 0xaa, 0xd9, 0x6e,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa4, 0xc6, 0x37, 0x7f, 0x6e, 0x6a, 0xa6, 0xd0,
+ 0xd6, 0x84, 0x51, 0x96, 0x13, 0xd6, 0xc4, 0x3e, 0x60, 0x36, 0x62, 0xbd, 0xd9, 0xe2, 0x78, 0xe3,
+ 0x83, 0x99, 0xda, 0x8e, 0x31, 0xd4, 0x64, 0x1f, 0xc7, 0x1b, 0xbe, 0xaa, 0x76, 0x22, 0x6b, 0x6b,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x69, 0xb0, 0x8a, 0xcc, 0x74, 0x17, 0x4c,
+ 0x98, 0xe1, 0xc1, 0xaa, 0x19, 0xe5, 0xc3, 0xce, 0x69, 0xb1, 0xe5, 0x62, 0xe7, 0x2f, 0xe0, 0xc4,
+ 0xe8, 0x25, 0x84, 0xe8, 0x5f, 0x84, 0xb0, 0xab, 0x40, 0x3b, 0x9e, 0x95, 0x27, 0x44, 0x1e, 0x7a,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe4, 0x77, 0xc8, 0x7d, 0xd2, 0x6e, 0xe5, 0x1f,
+ 0x8d, 0x33, 0x7c, 0x8e, 0x90, 0xbe, 0x1f, 0xb9, 0x5b, 0xc1, 0x5d, 0xdf, 0xc6, 0x23, 0x25, 0xc9,
+ 0x25, 0xb1, 0x13, 0x5e, 0x7c, 0x93, 0x67, 0xdf, 0x9b, 0x8f, 0x71, 0xb8, 0x34, 0xa4, 0x6b, 0xa1,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0xb8, 0x74, 0xbb, 0xa5, 0x3b, 0x40, 0x12,
+ 0x2b, 0x14, 0x43, 0x36, 0x93, 0x26, 0xe8, 0xda, 0x22, 0xcf, 0xc2, 0x69, 0xb0, 0xd0, 0x7a, 0xb1,
+ 0xc8, 0x2a, 0x92, 0x27, 0x94, 0x19, 0x97, 0xb3, 0x92, 0x65, 0xc5, 0x8d, 0xe8, 0xa6, 0xd0, 0x9b,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x88, 0x92, 0x2e, 0x4b, 0x64, 0xda, 0xce, 0x16,
+ 0x67, 0x70, 0xeb, 0x5c, 0x86, 0x6b, 0xc2, 0xe4, 0xbd, 0xdc, 0x46, 0x28, 0xd8, 0xd4, 0x19, 0x69,
+ 0xd5, 0xcf, 0x8e, 0x89, 0x40, 0x96, 0x7b, 0xb2, 0xc9, 0x5e, 0x18, 0xc6, 0xd6, 0xd2, 0x3c, 0x4a,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x50, 0x88, 0xb8, 0x9a, 0x8c, 0xc8, 0xae,
+ 0xae, 0xcd, 0x63, 0x62, 0xc3, 0x8a, 0x32, 0xb3, 0x5c, 0x1c, 0xa2, 0x55, 0x27, 0x55, 0x87, 0x6b,
+ 0x3e, 0x33, 0xd6, 0x70, 0xd0, 0x59, 0x76, 0xb0, 0xcd, 0x4a, 0x6e, 0x4a, 0xb1, 0xa1, 0x17, 0x24,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xc8, 0xb5, 0xe3, 0x7a, 0x17, 0x63, 0x70, 0xca,
+ 0x37, 0xbd, 0x1f, 0x72, 0x5e, 0x2f, 0x7c, 0xb7, 0xd2, 0xcb, 0xa8, 0xa9, 0x13, 0x98, 0x2b, 0x7e,
+ 0x74, 0x3f, 0x94, 0x6f, 0x8c, 0x1a, 0xce, 0x38, 0x61, 0x72, 0xe2, 0x18, 0x4e, 0xac, 0x5c, 0xc3,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x92, 0xd8, 0xb7, 0x88, 0xa8, 0x6e, 0xc5, 0xce,
+ 0x1f, 0x4a, 0x64, 0x3b, 0x1a, 0x21, 0x9f, 0xa6, 0x46, 0xe7, 0x1a, 0xcf, 0xc8, 0x20, 0xc1, 0x20,
+ 0x83, 0xbe, 0x5b, 0x99, 0x4d, 0xd4, 0x5e, 0xb3, 0xc3, 0x4b, 0xab, 0x3e, 0xc7, 0x85, 0xea, 0xc4,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x48, 0xe0, 0x84, 0xa8, 0x1d, 0x81, 0x62,
+ 0x74, 0x67, 0xb0, 0x32, 0x4c, 0x23, 0x56, 0xd0, 0x85, 0x9b, 0x20, 0xca, 0xb4, 0x49, 0xdd, 0xad,
+ 0x1f, 0xab, 0xcf, 0x16, 0x7d, 0xbd, 0x78, 0xb0, 0xd3, 0xa0, 0x5c, 0x50, 0xa1, 0xd7, 0x37, 0xa0,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x55, 0x97, 0xd6, 0x93, 0x6c, 0xd2, 0xa1,
+ 0x94, 0xc2, 0x2c, 0x51, 0x68, 0x34, 0x88, 0xc7, 0x8c, 0x1f, 0x3f, 0x93, 0x68, 0x86, 0xb1, 0xa5,
+ 0xe1, 0x56, 0x89, 0x20, 0xa5, 0xe2, 0x28, 0x9a, 0x11, 0x8f, 0xa4, 0xa7, 0x81, 0x6d, 0xe2, 0x87,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe2, 0x34, 0x79, 0x8d, 0xe2, 0xe1, 0xa3, 0x38,
+ 0x83, 0x3b, 0xb0, 0x7f, 0x4b, 0x2b, 0x44, 0xb7, 0x68, 0x21, 0x85, 0x79, 0x74, 0x8c, 0xbc, 0x65,
+ 0xbb, 0x16, 0xd0, 0x2a, 0xb7, 0x70, 0x13, 0x94, 0xc3, 0x87, 0x23, 0x46, 0x2f, 0xe3, 0xb7, 0xcf,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0xdd, 0x60, 0x5d, 0xc3, 0xd6, 0x75, 0x20,
+ 0x78, 0xbd, 0x49, 0x23, 0xaf, 0x1e, 0xa2, 0x14, 0xca, 0x81, 0x39, 0xbb, 0x19, 0xc2, 0x82, 0xde,
+ 0x68, 0xbe, 0xdb, 0xdd, 0xa4, 0x86, 0x51, 0xe7, 0xad, 0x2b, 0x25, 0xb0, 0xb7, 0x3d, 0xd0, 0xac,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x50, 0xa9, 0x7e, 0x3b, 0xc0, 0x41, 0x9a,
+ 0x6e, 0xd0, 0x8f, 0x4a, 0x21, 0xd1, 0xe1, 0x9f, 0xdb, 0xb6, 0xe2, 0x41, 0x4a, 0x15, 0xb5, 0x95,
+ 0x64, 0x97, 0xd3, 0x42, 0xc5, 0x63, 0xdd, 0xb7, 0x57, 0x6c, 0xc3, 0x54, 0x91, 0x2b, 0xdc, 0x52,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb2, 0xe1, 0x14, 0x37, 0x92, 0xea, 0xb8, 0xc3,
+ 0x95, 0x4b, 0x31, 0xab, 0x9b, 0xb8, 0x8f, 0xca, 0x66, 0x45, 0xae, 0x71, 0xaf, 0xb8, 0x2b, 0x57,
+ 0x87, 0x17, 0x90, 0x28, 0x98, 0x62, 0x47, 0x2c, 0xeb, 0x92, 0x79, 0x26, 0x52, 0x7d, 0x70, 0x88,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa3, 0x38, 0x7a, 0xe7, 0x7e, 0x27, 0x49, 0xbd,
+ 0xe2, 0xcc, 0x88, 0xe6, 0x36, 0xae, 0xd6, 0x7c, 0x48, 0xe3, 0xe6, 0x7d, 0x11, 0xd4, 0xa0, 0x3e,
+ 0x6e, 0x9d, 0xdb, 0x9b, 0xdc, 0xb0, 0x70, 0xdc, 0x58, 0x5b, 0xda, 0x99, 0x92, 0x65, 0x48, 0x86,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x52, 0x5c, 0x69, 0xd6, 0x8d, 0xb1, 0x5f,
+ 0xa3, 0x1c, 0xe1, 0x1e, 0x78, 0x15, 0x97, 0x9e, 0x44, 0xdf, 0x56, 0x60, 0x38, 0x18, 0x43, 0x1b,
+ 0xc1, 0x91, 0x6e, 0x48, 0x98, 0xe2, 0x19, 0x36, 0x9d, 0x6c, 0x23, 0x5a, 0x97, 0xa4, 0x26, 0x13,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x12, 0x33, 0x7a, 0x68, 0xb2, 0x29, 0x92, 0x81,
+ 0xa0, 0x5a, 0x9e, 0xd5, 0xbd, 0xb7, 0x4f, 0x13, 0x55, 0xb7, 0xe7, 0x73, 0x52, 0x32, 0x21, 0xbf,
+ 0x3a, 0x1b, 0xb1, 0x60, 0x19, 0x5f, 0x77, 0x8b, 0x7c, 0x2a, 0x87, 0x26, 0x82, 0x7f, 0x1d, 0xda,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xd6, 0xa3, 0xcd, 0xc3, 0x76, 0x48, 0x21, 0xd8,
+ 0x21, 0xab, 0x86, 0xc2, 0x5f, 0x57, 0xca, 0x7f, 0x38, 0x19, 0x4a, 0x20, 0xd6, 0xe8, 0x51, 0x22,
+ 0x5b, 0xb9, 0x24, 0xb8, 0x85, 0x87, 0x7b, 0xe1, 0x38, 0xbc, 0xdd, 0xad, 0xdd, 0xca, 0x1f, 0xc7,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4c, 0x1f, 0xdb, 0x80, 0xc3, 0xc0, 0x64,
+ 0xc3, 0x44, 0x9a, 0x1e, 0xd7, 0xd3, 0x1f, 0xa5, 0xba, 0xe3, 0x26, 0xe8, 0x7e, 0x8d, 0x5c, 0xaa,
+ 0xb1, 0x82, 0xc9, 0x3a, 0xd7, 0xd5, 0xb0, 0xd0, 0x45, 0x53, 0x8a, 0x65, 0x78, 0xe4, 0x6c, 0x86,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x7a, 0xc3, 0xdc, 0xbb, 0x6b, 0x44, 0x70,
+ 0x10, 0x86, 0x88, 0x5c, 0x2e, 0xdc, 0x25, 0x4b, 0xb7, 0xb1, 0x88, 0xca, 0x27, 0xb1, 0x83, 0x2c,
+ 0x21, 0x9c, 0xe2, 0xbf, 0xe4, 0x2a, 0x35, 0x19, 0xdc, 0x99, 0xbc, 0x4a, 0x44, 0xd6, 0x4d, 0x75,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x5b, 0x67, 0x73, 0x35, 0xe3, 0x3e, 0xb4,
+ 0x7a, 0x48, 0x13, 0x49, 0x47, 0xac, 0xdc, 0xa8, 0x1a, 0x2b, 0x44, 0xb4, 0xac, 0x99, 0x82, 0x13,
+ 0xc8, 0x7b, 0x7e, 0x9f, 0xeb, 0xab, 0xa2, 0xc8, 0xb2, 0x3e, 0x96, 0xd3, 0x53, 0x13, 0x33, 0x42,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0xdd, 0x42, 0x16, 0x1e, 0x35, 0x6a, 0xa0,
+ 0x5f, 0x93, 0x62, 0xc5, 0x6d, 0xc3, 0xde, 0x84, 0x4b, 0xdf, 0xde, 0xab, 0xbc, 0x31, 0xcd, 0xa1,
+ 0xa6, 0x10, 0x33, 0x48, 0x4c, 0x6f, 0x6a, 0xc0, 0xd8, 0x97, 0x2e, 0xb5, 0x48, 0x74, 0x70, 0x29,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0xd8, 0x5a, 0x9a, 0xc4, 0x1a, 0xd4, 0xa7,
+ 0x73, 0xc3, 0x1f, 0x10, 0x54, 0x95, 0x59, 0x16, 0x53, 0x88, 0x14, 0x30, 0xbd, 0x8c, 0x6f, 0x8d,
+ 0x19, 0x2f, 0xaf, 0x14, 0x88, 0xd6, 0x79, 0x33, 0xd6, 0xd6, 0x22, 0xb6, 0x9a, 0xa0, 0xcb, 0x90,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x93, 0xe1, 0xcc, 0x2f, 0x51, 0x67, 0x8a, 0x17,
+ 0xc3, 0xaa, 0x31, 0x31, 0x8c, 0xb3, 0xaa, 0x98, 0xb6, 0x5d, 0xe2, 0x6e, 0xa1, 0xcf, 0x10, 0xd4,
+ 0x8e, 0x6c, 0x93, 0xbd, 0x8b, 0xe9, 0x4f, 0x55, 0xdc, 0x3c, 0x4a, 0xad, 0x76, 0xcf, 0xea, 0xb7,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x50, 0x85, 0xcf, 0x57, 0x56, 0xa3, 0x1a,
+ 0x49, 0x25, 0xbe, 0x8d, 0x54, 0xa7, 0x78, 0x68, 0x76, 0x53, 0xc7, 0x59, 0x59, 0x66, 0xa1, 0xe4,
+ 0xa0, 0x68, 0x4d, 0x57, 0x85, 0x62, 0x2a, 0x56, 0x68, 0x38, 0x2b, 0xd3, 0xbd, 0x9a, 0xc4, 0xe0,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb9, 0x40, 0x3e, 0x19, 0x40, 0xab, 0x60, 0xba,
+ 0xbf, 0x68, 0xb8, 0xe7, 0xa3, 0x3c, 0x73, 0x9b, 0x12, 0x68, 0xca, 0x89, 0x3f, 0x45, 0x67, 0xbd,
+ 0xd9, 0x3c, 0xd4, 0xc0, 0xa5, 0x15, 0x98, 0x6a, 0x81, 0x8b, 0x38, 0x6e, 0x27, 0x4c, 0x30, 0x29,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xbd, 0x8a, 0x61, 0x55, 0x4f, 0xb8, 0x2b, 0x6b,
+ 0x3b, 0x19, 0xe2, 0x10, 0x44, 0xc7, 0x51, 0x4a, 0x3a, 0x3b, 0xc3, 0x3e, 0xab, 0xca, 0x84, 0x86,
+ 0xab, 0xe4, 0xa3, 0x5a, 0xa7, 0xaf, 0x4e, 0x80, 0xa0, 0x95, 0x94, 0xde, 0xd6, 0x6e, 0x2f, 0x68,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x36, 0x8c, 0x49, 0x53, 0x7a, 0x50, 0xcb,
+ 0x75, 0x13, 0xcb, 0xab, 0x92, 0x70, 0x14, 0x6a, 0x8d, 0x4c, 0x9c, 0x5c, 0xa5, 0x69, 0x46, 0x1d,
+ 0x99, 0x68, 0x71, 0x72, 0x44, 0x87, 0xe7, 0xa8, 0xe6, 0x99, 0x9d, 0xdb, 0x31, 0x86, 0xc9, 0x9c,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xdd, 0x7d, 0xe8, 0xd0, 0x1c, 0x30, 0x8d, 0x2d,
+ 0x56, 0x5a, 0x1f, 0x1d, 0xc2, 0xa2, 0x7f, 0xcb, 0xd8, 0xbc, 0xcb, 0x6e, 0x12, 0x6e, 0x26, 0x62,
+ 0xeb, 0x48, 0x32, 0x91, 0x7b, 0x59, 0x6d, 0xac, 0xc7, 0x7a, 0x34, 0x55, 0xc3, 0x54, 0x9c, 0xbf,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
+ 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0xea, 0xd9, 0x1f, 0xbd, 0xc9, 0x84, 0xe8,
+ 0xb1, 0x92, 0xc0, 0x7a, 0xde, 0x74, 0xe8, 0x87, 0xb1, 0xd6, 0x22, 0xc9, 0x19, 0x41, 0x7e, 0x36,
+ 0x62, 0xc6, 0x62, 0x99, 0x93, 0x4d, 0xa9, 0x7c, 0x5c, 0x23, 0x32, 0xe5, 0x5a, 0x4d, 0xbc, 0x87,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
+ 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
+ 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
+ 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
+ 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
+ 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
+ 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
+ 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+};
+#endif
diff --git a/tests/amdgpu/hotunplug_tests.c b/tests/amdgpu/hotunplug_tests.c
new file mode 100644
index 0000000..af933b1
--- /dev/null
+++ b/tests/amdgpu/hotunplug_tests.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "xf86drm.h"
+#include <pthread.h>
+
+#define GFX_COMPUTE_NOP 0xffff1000
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static char *sysfs_remove = NULL;
+static bool do_cs;
+
+CU_BOOL suite_hotunplug_tests_enable(void)
+{
+ CU_BOOL enable = CU_TRUE;
+ drmDevicePtr device;
+
+ if (drmGetDevice2(drm_amdgpu[0], DRM_DEVICE_GET_PCI_REVISION, &device)) {
+ printf("\n\nGPU Failed to get DRM device PCI info!\n");
+ return CU_FALSE;
+ }
+
+ if (device->bustype != DRM_BUS_PCI) {
+ printf("\n\nGPU device is not on PCI bus!\n");
+ amdgpu_device_deinitialize(device_handle);
+ return CU_FALSE;
+ }
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ /* Latest tested amdgpu version to work with all the tests */
+ if (minor_version < 46)
+ enable = false;
+
+ /* skip hotplug test on APUs */
+ if(device_handle->dev_info.ids_flags & AMDGPU_IDS_FLAGS_FUSION)
+ enable = false;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_hotunplug_tests_init(void)
+{
+ /* We need to open/close device at each test manually */
+ amdgpu_close_devices();
+
+ return CUE_SUCCESS;
+}
+
+int suite_hotunplug_tests_clean(void)
+{
+
+
+ return CUE_SUCCESS;
+}
+
+static int amdgpu_hotunplug_trigger(const char *pathname)
+{
+ int fd, len;
+
+ fd = open(pathname, O_WRONLY);
+ if (fd < 0)
+ return -errno;
+
+ len = write(fd, "1", 1);
+ close(fd);
+
+ return len;
+}
+
+static int amdgpu_hotunplug_setup_test()
+{
+ int r;
+ char *tmp_str;
+
+ if (amdgpu_open_device_on_test_index(open_render_node) < 0) {
+ printf("\n\n Failed to reopen device file!\n");
+ return CUE_SINIT_FAILED;
+
+
+
+ }
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ tmp_str = amdgpu_get_device_from_fd(drm_amdgpu[0]);
+ if (!tmp_str){
+ printf("\n\n Device path not found!\n");
+ return CUE_SINIT_FAILED;
+ }
+
+ sysfs_remove = realloc(tmp_str, strlen(tmp_str) * 2);
+ strcat(sysfs_remove, "/remove");
+
+ return 0;
+}
+
+static int amdgpu_hotunplug_teardown_test()
+{
+ if (amdgpu_device_deinitialize(device_handle))
+ return CUE_SCLEAN_FAILED;
+
+ amdgpu_close_devices();
+
+ if (sysfs_remove)
+ free(sysfs_remove);
+
+ return 0;
+}
+
+static inline int amdgpu_hotunplug_remove()
+{
+ return amdgpu_hotunplug_trigger(sysfs_remove);
+}
+
+static inline int amdgpu_hotunplug_rescan()
+{
+ return amdgpu_hotunplug_trigger("/sys/bus/pci/rescan");
+}
+
+static int amdgpu_cs_sync(amdgpu_context_handle context,
+ unsigned int ip_type,
+ int ring,
+ unsigned int seqno)
+{
+ struct amdgpu_cs_fence fence = {
+ .context = context,
+ .ip_type = ip_type,
+ .ring = ring,
+ .fence = seqno,
+ };
+ uint32_t expired;
+
+ return amdgpu_cs_query_fence_status(&fence,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+}
+
+static void *amdgpu_nop_cs()
+{
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ uint32_t *ptr;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ amdgpu_context_handle context;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ for (i = 0; i < 16; ++i)
+ ptr[i] = GFX_COMPUTE_NOP;
+
+ r = amdgpu_bo_list_create(device_handle, 1, &ib_result_handle, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+
+ while (do_cs)
+ amdgpu_cs_submit(context, 0, &ibs_request, 1);
+
+ amdgpu_cs_sync(context, AMDGPU_HW_IP_GFX, 0, ibs_request.seq_no);
+ amdgpu_bo_list_destroy(bo_list);
+ amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+
+ amdgpu_cs_ctx_free(context);
+
+ return (void *)0;
+}
+
+static pthread_t* amdgpu_create_cs_thread()
+{
+ int r;
+ pthread_t *thread = malloc(sizeof(*thread));
+ if (!thread)
+ return NULL;
+
+ do_cs = true;
+
+ r = pthread_create(thread, NULL, amdgpu_nop_cs, NULL);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Give thread enough time to start*/
+ usleep(100000);
+ return thread;
+}
+
+static void amdgpu_destroy_cs_thread(pthread_t *thread)
+{
+ void *status;
+
+ do_cs = false;
+
+ pthread_join(*thread, &status);
+ CU_ASSERT_EQUAL(status, 0);
+
+ free(thread);
+}
+
+
+static void amdgpu_hotunplug_test(bool with_cs)
+{
+ int r;
+ pthread_t *thread = NULL;
+
+ r = amdgpu_hotunplug_setup_test();
+ CU_ASSERT_EQUAL(r , 0);
+
+ if (with_cs) {
+ thread = amdgpu_create_cs_thread();
+ CU_ASSERT_NOT_EQUAL(thread, NULL);
+ }
+
+ r = amdgpu_hotunplug_remove();
+ CU_ASSERT_EQUAL(r > 0, 1);
+
+ if (with_cs)
+ amdgpu_destroy_cs_thread(thread);
+
+ r = amdgpu_hotunplug_teardown_test();
+ CU_ASSERT_EQUAL(r , 0);
+
+ r = amdgpu_hotunplug_rescan();
+ CU_ASSERT_EQUAL(r > 0, 1);
+}
+
+static void amdgpu_hotunplug_simple(void)
+{
+ amdgpu_hotunplug_test(false);
+}
+
+static void amdgpu_hotunplug_with_cs(void)
+{
+ amdgpu_hotunplug_test(true);
+}
+
+static void amdgpu_hotunplug_with_exported_bo(void)
+{
+ int r;
+ uint32_t dma_buf_fd;
+ unsigned int *ptr;
+ amdgpu_bo_handle bo_handle;
+
+ struct amdgpu_bo_alloc_request request = {
+ .alloc_size = 4096,
+ .phys_alignment = 4096,
+ .preferred_heap = AMDGPU_GEM_DOMAIN_GTT,
+ .flags = 0,
+ };
+
+ r = amdgpu_hotunplug_setup_test();
+ CU_ASSERT_EQUAL(r , 0);
+
+ amdgpu_bo_alloc(device_handle, &request, &bo_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_export(bo_handle, amdgpu_bo_handle_type_dma_buf_fd, &dma_buf_fd);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf_fd, 0);
+ CU_ASSERT_NOT_EQUAL(ptr, MAP_FAILED);
+
+ r = amdgpu_hotunplug_remove();
+ CU_ASSERT_EQUAL(r > 0, 1);
+
+ amdgpu_bo_free(bo_handle);
+
+ r = amdgpu_hotunplug_teardown_test();
+ CU_ASSERT_EQUAL(r , 0);
+
+ *ptr = 0xdeafbeef;
+
+ munmap(ptr, 4096);
+ close (dma_buf_fd);
+
+ r = amdgpu_hotunplug_rescan();
+ CU_ASSERT_EQUAL(r > 0, 1);
+}
+
+static void amdgpu_hotunplug_with_exported_fence(void)
+{
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ uint32_t *ptr, sync_obj_handle, sync_obj_handle2;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ uint32_t major2, minor2;
+ amdgpu_device_handle device2;
+ amdgpu_context_handle context;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status = {0};
+ int shared_fd;
+
+ r = amdgpu_hotunplug_setup_test();
+ CU_ASSERT_EQUAL(r , 0);
+
+ r = amdgpu_device_initialize(drm_amdgpu[1], &major2, &minor2, &device2);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ for (i = 0; i < 16; ++i)
+ ptr[i] = GFX_COMPUTE_NOP;
+
+ r = amdgpu_bo_list_create(device_handle, 1, &ib_result_handle, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+
+ CU_ASSERT_EQUAL(amdgpu_cs_submit(context, 0, &ibs_request, 1), 0);
+
+ fence_status.context = context;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ CU_ASSERT_EQUAL(amdgpu_cs_fence_to_handle(device_handle, &fence_status,
+ AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ,
+ &sync_obj_handle),
+ 0);
+
+ CU_ASSERT_EQUAL(amdgpu_cs_export_syncobj(device_handle, sync_obj_handle, &shared_fd), 0);
+
+ CU_ASSERT_EQUAL(amdgpu_cs_import_syncobj(device2, shared_fd, &sync_obj_handle2), 0);
+
+ CU_ASSERT_EQUAL(amdgpu_cs_destroy_syncobj(device_handle, sync_obj_handle), 0);
+
+ CU_ASSERT_EQUAL(amdgpu_bo_list_destroy(bo_list), 0);
+ CU_ASSERT_EQUAL(amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096), 0);
+ CU_ASSERT_EQUAL(amdgpu_cs_ctx_free(context), 0);
+
+ r = amdgpu_hotunplug_remove();
+ CU_ASSERT_EQUAL(r > 0, 1);
+
+ CU_ASSERT_EQUAL(amdgpu_cs_syncobj_wait(device2, &sync_obj_handle2, 1, 100000000, 0, NULL), 0);
+
+ CU_ASSERT_EQUAL(amdgpu_cs_destroy_syncobj(device2, sync_obj_handle2), 0);
+
+ amdgpu_device_deinitialize(device2);
+
+ r = amdgpu_hotunplug_teardown_test();
+ CU_ASSERT_EQUAL(r , 0);
+
+ r = amdgpu_hotunplug_rescan();
+ CU_ASSERT_EQUAL(r > 0, 1);
+}
+
+
+CU_TestInfo hotunplug_tests[] = {
+ { "Unplug card and rescan the bus to plug it back", amdgpu_hotunplug_simple },
+ { "Same as first test but with command submission", amdgpu_hotunplug_with_cs },
+ { "Unplug with exported bo", amdgpu_hotunplug_with_exported_bo },
+ { "Unplug with exported fence", amdgpu_hotunplug_with_exported_fence },
+ CU_TEST_INFO_NULL,
+};
diff --git a/tests/amdgpu/jpeg_tests.c b/tests/amdgpu/jpeg_tests.c
new file mode 100644
index 0000000..eccbfeb
--- /dev/null
+++ b/tests/amdgpu/jpeg_tests.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "amdgpu_test.h"
+#include "decode_messages.h"
+
+/* jpeg registers */
+#define mmUVD_JPEG_CNTL 0x0200
+#define mmUVD_JPEG_RB_BASE 0x0201
+#define mmUVD_JPEG_RB_WPTR 0x0202
+#define mmUVD_JPEG_RB_RPTR 0x0203
+#define mmUVD_JPEG_RB_SIZE 0x0204
+#define mmUVD_JPEG_TIER_CNTL2 0x021a
+#define mmUVD_JPEG_UV_TILING_CTRL 0x021c
+#define mmUVD_JPEG_TILING_CTRL 0x021e
+#define mmUVD_JPEG_OUTBUF_RPTR 0x0220
+#define mmUVD_JPEG_OUTBUF_WPTR 0x0221
+#define mmUVD_JPEG_PITCH 0x0222
+#define mmUVD_JPEG_INT_EN 0x0229
+#define mmUVD_JPEG_UV_PITCH 0x022b
+#define mmUVD_JPEG_INDEX 0x023e
+#define mmUVD_JPEG_DATA 0x023f
+#define mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH 0x0438
+#define mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW 0x0439
+#define mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH 0x045a
+#define mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW 0x045b
+#define mmUVD_CTX_INDEX 0x0528
+#define mmUVD_CTX_DATA 0x0529
+#define mmUVD_SOFT_RESET 0x05a0
+
+#define vcnipUVD_JPEG_DEC_SOFT_RST 0x402f
+#define vcnipUVD_JRBC_IB_COND_RD_TIMER 0x408e
+#define vcnipUVD_JRBC_IB_REF_DATA 0x408f
+#define vcnipUVD_LMI_JPEG_READ_64BIT_BAR_HIGH 0x40e1
+#define vcnipUVD_LMI_JPEG_READ_64BIT_BAR_LOW 0x40e0
+#define vcnipUVD_JPEG_RB_BASE 0x4001
+#define vcnipUVD_JPEG_RB_SIZE 0x4004
+#define vcnipUVD_JPEG_RB_WPTR 0x4002
+#define vcnipUVD_JPEG_PITCH 0x401f
+#define vcnipUVD_JPEG_UV_PITCH 0x4020
+#define vcnipJPEG_DEC_ADDR_MODE 0x4027
+#define vcnipJPEG_DEC_Y_GFX10_TILING_SURFACE 0x4024
+#define vcnipJPEG_DEC_UV_GFX10_TILING_SURFACE 0x4025
+#define vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH 0x40e3
+#define vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW 0x40e2
+#define vcnipUVD_JPEG_INDEX 0x402c
+#define vcnipUVD_JPEG_DATA 0x402d
+#define vcnipUVD_JPEG_TIER_CNTL2 0x400f
+#define vcnipUVD_JPEG_OUTBUF_RPTR 0x401e
+#define vcnipUVD_JPEG_OUTBUF_CNTL 0x401c
+#define vcnipUVD_JPEG_INT_EN 0x400a
+#define vcnipUVD_JPEG_CNTL 0x4000
+#define vcnipUVD_JPEG_RB_RPTR 0x4003
+#define vcnipUVD_JPEG_OUTBUF_WPTR 0x401d
+
+
+#define RDECODE_PKT_REG_J(x) ((unsigned)(x)&0x3FFFF)
+#define RDECODE_PKT_RES_J(x) (((unsigned)(x)&0x3F) << 18)
+#define RDECODE_PKT_COND_J(x) (((unsigned)(x)&0xF) << 24)
+#define RDECODE_PKT_TYPE_J(x) (((unsigned)(x)&0xF) << 28)
+#define RDECODE_PKTJ(reg, cond, type) (RDECODE_PKT_REG_J(reg) | \
+ RDECODE_PKT_RES_J(0) | \
+ RDECODE_PKT_COND_J(cond) | \
+ RDECODE_PKT_TYPE_J(type))
+
+#define UVD_BASE_INST0_SEG1 0x00007E00
+#define SOC15_REG_ADDR(reg) (UVD_BASE_INST0_SEG1 + reg)
+
+#define COND0 0
+#define COND1 1
+#define COND3 3
+#define TYPE0 0
+#define TYPE1 1
+#define TYPE3 3
+#define JPEG_DEC_DT_PITCH 0x100
+#define JPEG_DEC_BSD_SIZE 0x180
+#define JPEG_DEC_LUMA_OFFSET 0
+#define JPEG_DEC_CHROMA_OFFSET 0x1000
+#define JPEG_DEC_SUM 4096
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+struct amdgpu_jpeg_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+static uint32_t asic_id;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static amdgpu_va_handle ib_va_handle;
+static uint64_t ib_mc_address;
+static uint32_t *ib_cpu;
+static uint32_t len;
+
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+bool jpeg_direct_reg;
+
+static void set_reg_jpeg(unsigned reg, unsigned cond, unsigned type,
+ uint32_t val);
+static void send_cmd_bitstream(uint64_t addr);
+static void send_cmd_target(uint64_t addr);
+static void send_cmd_bitstream_direct(uint64_t addr);
+static void send_cmd_target_direct(uint64_t addr);
+
+static void amdgpu_cs_jpeg_decode(void);
+
+CU_TestInfo jpeg_tests[] = {
+ {"JPEG decode", amdgpu_cs_jpeg_decode},
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_jpeg_tests_enable(void)
+{
+ struct drm_amdgpu_info_hw_ip info;
+ int r;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version,
+ &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+ asic_id = device_handle->info.asic_id;
+ chip_rev = device_handle->info.chip_rev;
+ chip_id = device_handle->info.chip_external_rev;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_JPEG, 0, &info);
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ if (r != 0 || !info.available_rings ||
+ (family_id < AMDGPU_FAMILY_RV &&
+ (family_id == AMDGPU_FAMILY_AI &&
+ (chip_id - chip_rev) < 0x32))) { /* Arcturus */
+ printf("\n\nThe ASIC NOT support JPEG, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ if (info.hw_ip_version_major == 1)
+ jpeg_direct_reg = false;
+ else if (info.hw_ip_version_major > 1 && info.hw_ip_version_major <= 4)
+ jpeg_direct_reg = true;
+ else
+ return CU_FALSE;
+
+ return CU_TRUE;
+}
+
+int suite_jpeg_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version,
+ &device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = device_handle->info.family_id;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, &ib_handle,
+ (void **)&ib_cpu, &ib_mc_address, &ib_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+int suite_jpeg_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle, ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources, NULL,
+ &ibs_request.resources);
+ if (r)
+ return r;
+
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status, AMDGPU_TIMEOUT_INFINITE, 0,
+ &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void alloc_resource(struct amdgpu_jpeg_bo *jpeg_bo, unsigned size,
+ unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle, amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va, &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ jpeg_bo->addr = va;
+ jpeg_bo->handle = buf_handle;
+ jpeg_bo->size = req.alloc_size;
+ jpeg_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(jpeg_bo->handle, (void **)&jpeg_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(jpeg_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(jpeg_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_jpeg_bo *jpeg_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(jpeg_bo->handle, 0, jpeg_bo->size, jpeg_bo->addr, 0,
+ AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(jpeg_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(jpeg_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(jpeg_bo, 0, sizeof(*jpeg_bo));
+}
+
+static void set_reg_jpeg(unsigned reg, unsigned cond, unsigned type,
+ uint32_t val)
+{
+ ib_cpu[len++] = RDECODE_PKTJ(reg, cond, type);
+ ib_cpu[len++] = val;
+}
+
+/* send a bitstream buffer command */
+static void send_cmd_bitstream(uint64_t addr)
+{
+
+ /* jpeg soft reset */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
+
+ /* ensuring the Reset is asserted in SCLK domain */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
+
+ /* wait mem */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
+
+ /* ensuring the Reset is de-asserted in SCLK domain */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
+
+ /* set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH), COND0, TYPE0,
+ (addr >> 32));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW), COND0, TYPE0,
+ (unsigned int)addr);
+
+ /* set jpeg_rb_base */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_RB_BASE), COND0, TYPE0, 0);
+
+ /* set jpeg_rb_base */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_RB_SIZE), COND0, TYPE0, 0xFFFFFFF0);
+
+ /* set jpeg_rb_wptr */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_RB_WPTR), COND0, TYPE0,
+ (JPEG_DEC_BSD_SIZE >> 2));
+}
+
+/* send a target buffer command */
+static void send_cmd_target(uint64_t addr)
+{
+
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_PITCH), COND0, TYPE0,
+ (JPEG_DEC_DT_PITCH >> 4));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_UV_PITCH), COND0, TYPE0,
+ (JPEG_DEC_DT_PITCH >> 4));
+
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_TILING_CTRL), COND0, TYPE0, 0);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_UV_TILING_CTRL), COND0, TYPE0, 0);
+
+ /* set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH), COND0,
+ TYPE0, (addr >> 32));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW), COND0, TYPE0,
+ (unsigned int)addr);
+
+ /* set output buffer data address */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 0);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0,
+ JPEG_DEC_LUMA_OFFSET);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 1);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0,
+ JPEG_DEC_CHROMA_OFFSET);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_TIER_CNTL2), COND0, TYPE3, 0);
+
+ /* set output buffer read pointer */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_RPTR), COND0, TYPE0, 0);
+
+ /* enable error interrupts */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_INT_EN), COND0, TYPE0, 0xFFFFFFFE);
+
+ /* start engine command */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x6);
+
+ /* wait for job completion, wait for job JBSI fetch done */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0,
+ (JPEG_DEC_BSD_SIZE >> 2));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_RB_RPTR), COND0, TYPE3, 0xFFFFFFFF);
+
+ /* wait for job jpeg outbuf idle */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0xFFFFFFFF);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_WPTR), COND0, TYPE3,
+ 0x00000001);
+
+ /* stop engine */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x4);
+
+ /* asserting jpeg lmi drop */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0,
+ (1 << 23 | 1 << 0));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE1, 0);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0);
+
+ /* asserting jpeg reset */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
+
+ /* ensure reset is asserted in sclk domain */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
+
+ /* de-assert jpeg reset */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
+
+ /* ensure reset is de-asserted in sclk domain */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
+
+ /* de-asserting jpeg lmi drop */
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
+ set_reg_jpeg(SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0);
+}
+
+/* send a bitstream buffer command */
+static void send_cmd_bitstream_direct(uint64_t addr)
+{
+
+ /* jpeg soft reset */
+ set_reg_jpeg(vcnipUVD_JPEG_DEC_SOFT_RST, COND0, TYPE0, 1);
+
+ /* ensuring the Reset is asserted in SCLK domain */
+ set_reg_jpeg(vcnipUVD_JRBC_IB_COND_RD_TIMER, COND0, TYPE0, 0x01400200);
+ set_reg_jpeg(vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (0x1 << 0x10));
+ set_reg_jpeg(vcnipUVD_JPEG_DEC_SOFT_RST, COND3, TYPE3, (0x1 << 0x10));
+
+ /* wait mem */
+ set_reg_jpeg(vcnipUVD_JPEG_DEC_SOFT_RST, COND0, TYPE0, 0);
+
+ /* ensuring the Reset is de-asserted in SCLK domain */
+ set_reg_jpeg(vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (0 << 0x10));
+ set_reg_jpeg(vcnipUVD_JPEG_DEC_SOFT_RST, COND3, TYPE3, (0x1 << 0x10));
+
+ /* set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address */
+ set_reg_jpeg(vcnipUVD_LMI_JPEG_READ_64BIT_BAR_HIGH, COND0, TYPE0,
+ (addr >> 32));
+ set_reg_jpeg(vcnipUVD_LMI_JPEG_READ_64BIT_BAR_LOW, COND0, TYPE0, addr);
+
+ /* set jpeg_rb_base */
+ set_reg_jpeg(vcnipUVD_JPEG_RB_BASE, COND0, TYPE0, 0);
+
+ /* set jpeg_rb_base */
+ set_reg_jpeg(vcnipUVD_JPEG_RB_SIZE, COND0, TYPE0, 0xFFFFFFF0);
+
+ /* set jpeg_rb_wptr */
+ set_reg_jpeg(vcnipUVD_JPEG_RB_WPTR, COND0, TYPE0, (JPEG_DEC_BSD_SIZE >> 2));
+}
+
+/* send a target buffer command */
+static void send_cmd_target_direct(uint64_t addr)
+{
+
+ set_reg_jpeg(vcnipUVD_JPEG_PITCH, COND0, TYPE0, (JPEG_DEC_DT_PITCH >> 4));
+ set_reg_jpeg(vcnipUVD_JPEG_UV_PITCH, COND0, TYPE0, (JPEG_DEC_DT_PITCH >> 4));
+
+ set_reg_jpeg(vcnipJPEG_DEC_ADDR_MODE, COND0, TYPE0, 0);
+ set_reg_jpeg(vcnipJPEG_DEC_Y_GFX10_TILING_SURFACE, COND0, TYPE0, 0);
+ set_reg_jpeg(vcnipJPEG_DEC_UV_GFX10_TILING_SURFACE, COND0, TYPE0, 0);
+
+ /* set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address */
+ set_reg_jpeg(vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH, COND0, TYPE0,
+ (addr >> 32));
+ set_reg_jpeg(vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW, COND0, TYPE0, addr);
+
+ /* set output buffer data address */
+ set_reg_jpeg(vcnipUVD_JPEG_INDEX, COND0, TYPE0, 0);
+ set_reg_jpeg(vcnipUVD_JPEG_DATA, COND0, TYPE0, JPEG_DEC_LUMA_OFFSET);
+ set_reg_jpeg(vcnipUVD_JPEG_INDEX, COND0, TYPE0, 1);
+ set_reg_jpeg(vcnipUVD_JPEG_DATA, COND0, TYPE0, JPEG_DEC_CHROMA_OFFSET);
+ set_reg_jpeg(vcnipUVD_JPEG_TIER_CNTL2, COND0, 0, 0);
+
+ /* set output buffer read pointer */
+ set_reg_jpeg(vcnipUVD_JPEG_OUTBUF_RPTR, COND0, TYPE0, 0);
+ set_reg_jpeg(vcnipUVD_JPEG_OUTBUF_CNTL, COND0, TYPE0,
+ ((0x00001587 & (~0x00000180L)) | (0x1 << 0x7) | (0x1 << 0x6)));
+
+ /* enable error interrupts */
+ set_reg_jpeg(vcnipUVD_JPEG_INT_EN, COND0, TYPE0, 0xFFFFFFFE);
+
+ /* start engine command */
+ set_reg_jpeg(vcnipUVD_JPEG_CNTL, COND0, TYPE0, 0xE);
+
+ /* wait for job completion, wait for job JBSI fetch done */
+ set_reg_jpeg(vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0,
+ (JPEG_DEC_BSD_SIZE >> 2));
+ set_reg_jpeg(vcnipUVD_JRBC_IB_COND_RD_TIMER, COND0, TYPE0, 0x01400200);
+ set_reg_jpeg(vcnipUVD_JPEG_RB_RPTR, COND3, TYPE3, 0xFFFFFFFF);
+
+ /* wait for job jpeg outbuf idle */
+ set_reg_jpeg(vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, 0xFFFFFFFF);
+ set_reg_jpeg(vcnipUVD_JPEG_OUTBUF_WPTR, COND3, TYPE3, 0x00000001);
+
+ /* stop engine */
+ set_reg_jpeg(vcnipUVD_JPEG_CNTL, COND0, TYPE0, 0x4);
+}
+
+static void amdgpu_cs_jpeg_decode(void)
+{
+
+ struct amdgpu_jpeg_bo dec_buf;
+ int size, r;
+ uint8_t *dec;
+ int sum = 0, i, j;
+
+ size = 16 * 1024; /* 8K bitstream + 8K output */
+ num_resources = 0;
+ alloc_resource(&dec_buf, size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = dec_buf.handle;
+ resources[num_resources++] = ib_handle;
+ r = amdgpu_bo_cpu_map(dec_buf.handle, (void **)&dec_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memcpy(dec_buf.ptr, jpeg_bitstream, sizeof(jpeg_bitstream));
+
+ len = 0;
+
+ if (jpeg_direct_reg == true) {
+ send_cmd_bitstream_direct(dec_buf.addr);
+ send_cmd_target_direct(dec_buf.addr + (size / 2));
+ } else {
+ send_cmd_bitstream(dec_buf.addr);
+ send_cmd_target(dec_buf.addr + (size / 2));
+ }
+
+ amdgpu_bo_cpu_unmap(dec_buf.handle);
+ r = submit(len, AMDGPU_HW_IP_VCN_JPEG);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(dec_buf.handle, (void **)&dec_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ dec = dec_buf.ptr + (size / 2);
+
+ /* calculate result checksum */
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++)
+ sum += *((dec + JPEG_DEC_LUMA_OFFSET + i * JPEG_DEC_DT_PITCH) + j);
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 8; j++)
+ sum += *((dec + JPEG_DEC_CHROMA_OFFSET + i * JPEG_DEC_DT_PITCH) + j);
+
+ amdgpu_bo_cpu_unmap(dec_buf.handle);
+ CU_ASSERT_EQUAL(sum, JPEG_DEC_SUM);
+
+ free_resource(&dec_buf);
+}
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
new file mode 100644
index 0000000..8618f6a
--- /dev/null
+++ b/tests/amdgpu/meson.build
@@ -0,0 +1,46 @@
+# Copyright © 2017-2018 Intel Corporation
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+if dep_cunit.found()
+ amdgpu_test = executable(
+ 'amdgpu_test',
+ files(
+ 'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c',
+ 'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c',
+ 'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c', 'security_tests.c',
+ 'hotunplug_tests.c', 'jpeg_tests.c', 'cp_dma_tests.c', 'shader_test_util.c'
+ ),
+ dependencies : [dep_cunit, dep_threads, dep_atomic_ops],
+ include_directories : [inc_root, inc_drm, include_directories('../../amdgpu')],
+ link_with : [libdrm, libdrm_amdgpu],
+ install : with_install_tests,
+ )
+endif
+
+amdgpu_stress = executable(
+ 'amdgpu_stress',
+ files(
+ 'amdgpu_stress.c'
+ ),
+ dependencies : [dep_threads, dep_atomic_ops],
+ include_directories : [inc_root, inc_drm, include_directories('../../amdgpu')],
+ link_with : [libdrm, libdrm_amdgpu],
+ install : with_install_tests,
+)
diff --git a/tests/amdgpu/ras_tests.c b/tests/amdgpu/ras_tests.c
new file mode 100644
index 0000000..810bf17
--- /dev/null
+++ b/tests/amdgpu/ras_tests.c
@@ -0,0 +1,1003 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include "xf86drm.h"
+#include <limits.h>
+
+#define PATH_SIZE PATH_MAX
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+const char *ras_block_string[] = {
+ "umc",
+ "sdma",
+ "gfx",
+ "mmhub",
+ "athub",
+ "pcie_bif",
+ "hdp",
+ "xgmi_wafl",
+ "df",
+ "smn",
+ "sem",
+ "mp0",
+ "mp1",
+ "fuse",
+};
+
+#define ras_block_str(i) (ras_block_string[i])
+
+enum amdgpu_ras_block {
+ AMDGPU_RAS_BLOCK__UMC = 0,
+ AMDGPU_RAS_BLOCK__SDMA,
+ AMDGPU_RAS_BLOCK__GFX,
+ AMDGPU_RAS_BLOCK__MMHUB,
+ AMDGPU_RAS_BLOCK__ATHUB,
+ AMDGPU_RAS_BLOCK__PCIE_BIF,
+ AMDGPU_RAS_BLOCK__HDP,
+ AMDGPU_RAS_BLOCK__XGMI_WAFL,
+ AMDGPU_RAS_BLOCK__DF,
+ AMDGPU_RAS_BLOCK__SMN,
+ AMDGPU_RAS_BLOCK__SEM,
+ AMDGPU_RAS_BLOCK__MP0,
+ AMDGPU_RAS_BLOCK__MP1,
+ AMDGPU_RAS_BLOCK__FUSE,
+
+ AMDGPU_RAS_BLOCK__LAST
+};
+
+#define AMDGPU_RAS_BLOCK_COUNT AMDGPU_RAS_BLOCK__LAST
+#define AMDGPU_RAS_BLOCK_MASK ((1ULL << AMDGPU_RAS_BLOCK_COUNT) - 1)
+
+enum amdgpu_ras_gfx_subblock {
+ /* CPC */
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_START = 0,
+ AMDGPU_RAS_BLOCK__GFX_CPC_SCRATCH =
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPC_UCODE,
+ AMDGPU_RAS_BLOCK__GFX_DC_STATE_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_CSINVOC_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_STATE_ME2,
+ AMDGPU_RAS_BLOCK__GFX_DC_CSINVOC_ME2,
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME2,
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME2,
+ /* CPF */
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPF_ROQ_ME2 =
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPF_ROQ_ME1,
+ AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_END = AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ /* CPG */
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPG_DMA_ROQ =
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPG_DMA_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_END = AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ /* GDS */
+ AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_GDS_MEM = AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_GDS_INPUT_QUEUE,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PHY_CMD_RAM_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PHY_DATA_RAM_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PIPE_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PIPE_MEM,
+ /* SPI */
+ AMDGPU_RAS_BLOCK__GFX_SPI_SR_MEM,
+ /* SQ */
+ AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQ_SGPR = AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQ_LDS_D,
+ AMDGPU_RAS_BLOCK__GFX_SQ_LDS_I,
+ AMDGPU_RAS_BLOCK__GFX_SQ_VGPR,
+ AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_END = AMDGPU_RAS_BLOCK__GFX_SQ_VGPR,
+ /* SQC (3 ranges) */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_START,
+ /* SQC range 0 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_UTCL1_LFIFO =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU0_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU0_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_UTCL1_LFIFO,
+ /* SQC range 1 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_TAG_RAM =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_UTCL1_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_TAG_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_HIT_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_DIRTY_BIT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_BANK_RAM,
+ /* SQC range 2 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_TAG_RAM =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_UTCL1_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_TAG_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_HIT_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_DIRTY_BIT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_END,
+ /* TA */
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_DFIFO =
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_AFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FL_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FX_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_CFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_END = AMDGPU_RAS_BLOCK__GFX_TA_FS_CFIFO,
+ /* TCA */
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCA_HOLE_FIFO =
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCA_REQ_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCA_REQ_FIFO,
+ /* TCC (5 sub-ranges) */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_START,
+ /* TCC range 0 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_0_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_0,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DIRTY_BANK_0,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DIRTY_BANK_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_HIGH_RATE_TAG,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LOW_RATE_TAG,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_LOW_RATE_TAG,
+ /* TCC range 1 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_DEC =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_TRANSFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_TRANSFER,
+ /* TCC range 2 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_RETURN_DATA =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_RETURN_CONTROL,
+ AMDGPU_RAS_BLOCK__GFX_TCC_UC_ATOMIC_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRITE_RETURN,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRITE_CACHE_READ,
+ AMDGPU_RAS_BLOCK__GFX_TCC_SRC_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_SRC_FIFO_NEXT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_TAG_PROBE_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_TAG_PROBE_FIFO,
+ /* TCC range 3 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO_NEXT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO_NEXT_RAM,
+ /* TCC range 4 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRRET_TAG_WRITE_RETURN =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_ATOMIC_RETURN_BUFFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_ATOMIC_RETURN_BUFFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_END,
+ /* TCI */
+ AMDGPU_RAS_BLOCK__GFX_TCI_WRITE_RAM,
+ /* TCP */
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCP_CACHE_RAM =
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCP_LFIFO_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCP_CMD_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCP_VM_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCP_DB_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO0,
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO1,
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO1,
+ /* TD */
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_LO =
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_HI,
+ AMDGPU_RAS_BLOCK__GFX_TD_CS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_END = AMDGPU_RAS_BLOCK__GFX_TD_CS_FIFO,
+ /* EA (3 sub-ranges) */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_START,
+ /* EA range 0 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_CMDMEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_RRET_TAGMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_WRET_TAGMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIRD_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_DATAMEM,
+ /* EA range 1 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_PAGEMEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IORD_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IOWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IOWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIRD_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_PAGEMEM,
+ /* EA range 2 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D0MEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D1MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D2MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D3MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D3MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_END,
+ /* UTC VM L2 bank */
+ AMDGPU_RAS_BLOCK__UTC_VML2_BANK_CACHE,
+ /* UTC VM walker */
+ AMDGPU_RAS_BLOCK__UTC_VML2_WALKER,
+ /* UTC ATC L2 2MB cache */
+ AMDGPU_RAS_BLOCK__UTC_ATCL2_CACHE_2M_BANK,
+ /* UTC ATC L2 4KB cache */
+ AMDGPU_RAS_BLOCK__UTC_ATCL2_CACHE_4K_BANK,
+ AMDGPU_RAS_BLOCK__GFX_MAX
+};
+
+enum amdgpu_ras_error_type {
+ AMDGPU_RAS_ERROR__NONE = 0,
+ AMDGPU_RAS_ERROR__PARITY = 1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE = 2,
+ AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE = 4,
+ AMDGPU_RAS_ERROR__POISON = 8,
+};
+
+struct ras_inject_test_config {
+ char name[64];
+ char block[32];
+ int sub_block;
+ enum amdgpu_ras_error_type type;
+ uint64_t address;
+ uint64_t value;
+};
+
+struct ras_common_if {
+ enum amdgpu_ras_block block;
+ enum amdgpu_ras_error_type type;
+ uint32_t sub_block_index;
+ char name[32];
+};
+
+struct ras_inject_if {
+ struct ras_common_if head;
+ uint64_t address;
+ uint64_t value;
+};
+
+struct ras_debug_if {
+ union {
+ struct ras_common_if head;
+ struct ras_inject_if inject;
+ };
+ int op;
+};
+/* for now, only umc, gfx, sdma has implemented. */
+#define DEFAULT_RAS_BLOCK_MASK_INJECT ((1 << AMDGPU_RAS_BLOCK__UMC) |\
+ (1 << AMDGPU_RAS_BLOCK__GFX))
+#define DEFAULT_RAS_BLOCK_MASK_QUERY ((1 << AMDGPU_RAS_BLOCK__UMC) |\
+ (1 << AMDGPU_RAS_BLOCK__GFX))
+#define DEFAULT_RAS_BLOCK_MASK_BASIC (1 << AMDGPU_RAS_BLOCK__UMC |\
+ (1 << AMDGPU_RAS_BLOCK__SDMA) |\
+ (1 << AMDGPU_RAS_BLOCK__GFX))
+
+static uint32_t ras_block_mask_inject = DEFAULT_RAS_BLOCK_MASK_INJECT;
+static uint32_t ras_block_mask_query = DEFAULT_RAS_BLOCK_MASK_INJECT;
+static uint32_t ras_block_mask_basic = DEFAULT_RAS_BLOCK_MASK_BASIC;
+
+struct ras_test_mask {
+ uint32_t inject_mask;
+ uint32_t query_mask;
+ uint32_t basic_mask;
+};
+
+struct amdgpu_ras_data {
+ amdgpu_device_handle device_handle;
+ uint32_t id;
+ uint32_t capability;
+ struct ras_test_mask test_mask;
+};
+
+/* all devices who has ras supported */
+static struct amdgpu_ras_data devices[MAX_CARDS_SUPPORTED];
+static int devices_count;
+
+struct ras_DID_test_mask{
+ uint16_t device_id;
+ uint16_t revision_id;
+ struct ras_test_mask test_mask;
+};
+
+/* white list for inject test. */
+#define RAS_BLOCK_MASK_ALL {\
+ DEFAULT_RAS_BLOCK_MASK_INJECT,\
+ DEFAULT_RAS_BLOCK_MASK_QUERY,\
+ DEFAULT_RAS_BLOCK_MASK_BASIC\
+}
+
+#define RAS_BLOCK_MASK_QUERY_BASIC {\
+ 0,\
+ DEFAULT_RAS_BLOCK_MASK_QUERY,\
+ DEFAULT_RAS_BLOCK_MASK_BASIC\
+}
+
+static const struct ras_inject_test_config umc_ras_inject_test[] = {
+ {"ras_umc.1.0", "umc", 0, AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+};
+
+static const struct ras_inject_test_config gfx_ras_inject_test[] = {
+ {"ras_gfx.2.0", "gfx", AMDGPU_RAS_BLOCK__GFX_CPC_UCODE,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.1", "gfx", AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.2", "gfx", AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.3", "gfx", AMDGPU_RAS_BLOCK__GFX_SQ_LDS_D,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.4", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_UTCL1_LFIFO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.5", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_TAG_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.6", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_TAG_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.7", "gfx", AMDGPU_RAS_BLOCK__GFX_TA_FS_DFIFO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.8", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.9", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_0_1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.10", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_0,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.11", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.12", "gfx", AMDGPU_RAS_BLOCK__GFX_TCP_CACHE_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.13", "gfx", AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_LO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.14", "gfx", AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_CMDMEM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+};
+
+static const struct ras_DID_test_mask ras_DID_array[] = {
+ {0x66a1, 0x00, RAS_BLOCK_MASK_ALL},
+ {0x66a1, 0x01, RAS_BLOCK_MASK_ALL},
+ {0x66a1, 0x04, RAS_BLOCK_MASK_ALL},
+};
+
+static uint32_t amdgpu_ras_find_block_id_by_name(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) {
+ if (strcmp(name, ras_block_string[i]) == 0)
+ return i;
+ }
+
+ return ARRAY_SIZE(ras_block_string);
+}
+
+static char *amdgpu_ras_get_error_type_id(enum amdgpu_ras_error_type type)
+{
+ switch (type) {
+ case AMDGPU_RAS_ERROR__PARITY:
+ return "parity";
+ case AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE:
+ return "single_correctable";
+ case AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE:
+ return "multi_uncorrectable";
+ case AMDGPU_RAS_ERROR__POISON:
+ return "poison";
+ case AMDGPU_RAS_ERROR__NONE:
+ default:
+ return NULL;
+ }
+}
+
+static struct ras_test_mask amdgpu_ras_get_test_mask(drmDevicePtr device)
+{
+ int i;
+ static struct ras_test_mask default_test_mask = RAS_BLOCK_MASK_QUERY_BASIC;
+
+ for (i = 0; i < sizeof(ras_DID_array) / sizeof(ras_DID_array[0]); i++) {
+ if (ras_DID_array[i].device_id == device->deviceinfo.pci->device_id &&
+ ras_DID_array[i].revision_id == device->deviceinfo.pci->revision_id)
+ return ras_DID_array[i].test_mask;
+ }
+ return default_test_mask;
+}
+
+static uint32_t amdgpu_ras_lookup_capability(amdgpu_device_handle device_handle)
+{
+ union {
+ uint64_t feature_mask;
+ struct {
+ uint32_t enabled_features;
+ uint32_t supported_features;
+ };
+ } features = { 0 };
+ int ret;
+
+ ret = amdgpu_query_info(device_handle, AMDGPU_INFO_RAS_ENABLED_FEATURES,
+ sizeof(features), &features);
+ if (ret)
+ return 0;
+
+ return features.supported_features;
+}
+
+static int get_file_contents(char *file, char *buf, int size);
+
+static int amdgpu_ras_lookup_id(drmDevicePtr device)
+{
+ char path[PATH_SIZE];
+ char str[128];
+ drmPciBusInfo info;
+ int i;
+ int ret;
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED; i++) {
+ memset(str, 0, sizeof(str));
+ memset(&info, 0, sizeof(info));
+ snprintf(path, PATH_SIZE, "/sys/kernel/debug/dri/%d/name", i);
+ if (get_file_contents(path, str, sizeof(str)) <= 0)
+ continue;
+
+ ret = sscanf(str, "amdgpu dev=%04hx:%02hhx:%02hhx.%01hhx",
+ &info.domain, &info.bus, &info.dev, &info.func);
+ if (ret != 4)
+ continue;
+
+ if (memcmp(&info, device->businfo.pci, sizeof(info)) == 0)
+ return i;
+ }
+ return -1;
+}
+
+//helpers
+
+static int test_card;
+static char sysfs_path[PATH_SIZE];
+static char debugfs_path[PATH_SIZE];
+static uint32_t ras_mask;
+static amdgpu_device_handle device_handle;
+
+static void set_test_card(int card)
+{
+ test_card = card;
+ snprintf(sysfs_path, PATH_SIZE, "/sys/class/drm/card%d/device/ras/", devices[card].id);
+ snprintf(debugfs_path, PATH_SIZE, "/sys/kernel/debug/dri/%d/ras/", devices[card].id);
+ ras_mask = devices[card].capability;
+ device_handle = devices[card].device_handle;
+ ras_block_mask_inject = devices[card].test_mask.inject_mask;
+ ras_block_mask_query = devices[card].test_mask.query_mask;
+ ras_block_mask_basic = devices[card].test_mask.basic_mask;
+}
+
+static const char *get_ras_sysfs_root(void)
+{
+ return sysfs_path;
+}
+
+static const char *get_ras_debugfs_root(void)
+{
+ return debugfs_path;
+}
+
+static int set_file_contents(char *file, char *buf, int size)
+{
+ int n, fd;
+ fd = open(file, O_WRONLY);
+ if (fd == -1)
+ return -1;
+ n = write(fd, buf, size);
+ close(fd);
+ return n;
+}
+
+static int get_file_contents(char *file, char *buf, int size)
+{
+ int n, fd;
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ return -1;
+ n = read(fd, buf, size);
+ close(fd);
+ return n;
+}
+
+static int is_file_ok(char *file, int flags)
+{
+ int fd;
+
+ fd = open(file, flags);
+ if (fd == -1)
+ return -1;
+ close(fd);
+ return 0;
+}
+
+static int amdgpu_ras_is_feature_enabled(enum amdgpu_ras_block block)
+{
+ uint32_t feature_mask;
+ int ret;
+
+ ret = amdgpu_query_info(device_handle, AMDGPU_INFO_RAS_ENABLED_FEATURES,
+ sizeof(feature_mask), &feature_mask);
+ if (ret)
+ return -1;
+
+ return (1 << block) & feature_mask;
+}
+
+static int amdgpu_ras_is_feature_supported(enum amdgpu_ras_block block)
+{
+ return (1 << block) & ras_mask;
+}
+
+static int amdgpu_ras_invoke(struct ras_debug_if *data)
+{
+ char path[PATH_SIZE];
+ int ret;
+
+ snprintf(path, sizeof(path), "%s", get_ras_debugfs_root());
+ strncat(path, "ras_ctrl", sizeof(path) - strlen(path));
+
+ ret = set_file_contents(path, (char *)data, sizeof(*data))
+ - sizeof(*data);
+ return ret;
+}
+
+static int amdgpu_ras_query_err_count(enum amdgpu_ras_block block,
+ unsigned long *ue, unsigned long *ce)
+{
+ char buf[64];
+ char name[PATH_SIZE];
+
+ *ue = *ce = 0;
+
+ if (amdgpu_ras_is_feature_supported(block) <= 0)
+ return -1;
+
+ snprintf(name, sizeof(name), "%s", get_ras_sysfs_root());
+ strncat(name, ras_block_str(block), sizeof(name) - strlen(name));
+ strncat(name, "_err_count", sizeof(name) - strlen(name));
+
+ if (is_file_ok(name, O_RDONLY))
+ return 0;
+
+ if (get_file_contents(name, buf, sizeof(buf)) <= 0)
+ return -1;
+
+ if (sscanf(buf, "ue: %lu\nce: %lu", ue, ce) != 2)
+ return -1;
+
+ return 0;
+}
+
+static int amdgpu_ras_inject(enum amdgpu_ras_block block,
+ uint32_t sub_block, enum amdgpu_ras_error_type type,
+ uint64_t address, uint64_t value)
+{
+ struct ras_debug_if data = { .op = 2, };
+ struct ras_inject_if *inject = &data.inject;
+ int ret;
+
+ if (amdgpu_ras_is_feature_enabled(block) <= 0) {
+ fprintf(stderr, "block id(%d) is not valid\n", block);
+ return -1;
+ }
+
+ inject->head.block = block;
+ inject->head.type = type;
+ inject->head.sub_block_index = sub_block;
+ strncpy(inject->head.name, ras_block_str(block), sizeof(inject->head.name)-1);
+ inject->address = address;
+ inject->value = value;
+
+ ret = amdgpu_ras_invoke(&data);
+ CU_ASSERT_EQUAL(ret, 0);
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+//tests
+static void amdgpu_ras_features_test(int enable)
+{
+ struct ras_debug_if data;
+ int ret;
+ int i;
+
+ data.op = enable;
+ for (i = 0; i < AMDGPU_RAS_BLOCK__LAST; i++) {
+ struct ras_common_if head = {
+ .block = i,
+ .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
+ .sub_block_index = 0,
+ .name = "",
+ };
+
+ if (amdgpu_ras_is_feature_supported(i) <= 0)
+ continue;
+
+ data.head = head;
+
+ ret = amdgpu_ras_invoke(&data);
+ CU_ASSERT_EQUAL(ret, 0);
+
+ if (ret)
+ continue;
+
+ ret = enable ^ amdgpu_ras_is_feature_enabled(i);
+ CU_ASSERT_EQUAL(ret, 0);
+ }
+}
+
+static void amdgpu_ras_disable_test(void)
+{
+ int i;
+ for (i = 0; i < devices_count; i++) {
+ set_test_card(i);
+ amdgpu_ras_features_test(0);
+ }
+}
+
+static void amdgpu_ras_enable_test(void)
+{
+ int i;
+ for (i = 0; i < devices_count; i++) {
+ set_test_card(i);
+ amdgpu_ras_features_test(1);
+ }
+}
+
+static void __amdgpu_ras_ip_inject_test(const struct ras_inject_test_config *ip_test,
+ uint32_t size)
+{
+ int i, ret;
+ unsigned long old_ue, old_ce;
+ unsigned long ue, ce;
+ uint32_t block;
+ int timeout;
+ bool pass;
+
+ for (i = 0; i < size; i++) {
+ timeout = 3;
+ pass = false;
+
+ block = amdgpu_ras_find_block_id_by_name(ip_test[i].block);
+
+ /* Ensure one valid ip block */
+ if (block == ARRAY_SIZE(ras_block_string))
+ break;
+
+ /* Ensure RAS feature for the IP block is enabled by kernel */
+ if (amdgpu_ras_is_feature_supported(block) <= 0)
+ break;
+
+ ret = amdgpu_ras_query_err_count(block, &old_ue, &old_ce);
+ CU_ASSERT_EQUAL(ret, 0);
+ if (ret)
+ break;
+
+ ret = amdgpu_ras_inject(block,
+ ip_test[i].sub_block,
+ ip_test[i].type,
+ ip_test[i].address,
+ ip_test[i].value);
+ CU_ASSERT_EQUAL(ret, 0);
+ if (ret)
+ break;
+
+ while (timeout > 0) {
+ sleep(5);
+
+ ret = amdgpu_ras_query_err_count(block, &ue, &ce);
+ CU_ASSERT_EQUAL(ret, 0);
+ if (ret)
+ break;
+
+ if (old_ue != ue || old_ce != ce) {
+ pass = true;
+ sleep(20);
+ break;
+ }
+ timeout -= 1;
+ }
+ printf("\t Test %s@block %s, subblock %d, error_type %s, address %ld, value %ld: %s\n",
+ ip_test[i].name,
+ ip_test[i].block,
+ ip_test[i].sub_block,
+ amdgpu_ras_get_error_type_id(ip_test[i].type),
+ ip_test[i].address,
+ ip_test[i].value,
+ pass ? "Pass" : "Fail");
+ }
+}
+
+static void __amdgpu_ras_inject_test(void)
+{
+ printf("...\n");
+
+ /* run UMC ras inject test */
+ __amdgpu_ras_ip_inject_test(umc_ras_inject_test,
+ ARRAY_SIZE(umc_ras_inject_test));
+
+ /* run GFX ras inject test */
+ __amdgpu_ras_ip_inject_test(gfx_ras_inject_test,
+ ARRAY_SIZE(gfx_ras_inject_test));
+}
+
+static void amdgpu_ras_inject_test(void)
+{
+ int i;
+ for (i = 0; i < devices_count; i++) {
+ set_test_card(i);
+ __amdgpu_ras_inject_test();
+ }
+}
+
+static void __amdgpu_ras_query_test(void)
+{
+ unsigned long ue, ce;
+ int ret;
+ int i;
+
+ for (i = 0; i < AMDGPU_RAS_BLOCK__LAST; i++) {
+ if (amdgpu_ras_is_feature_supported(i) <= 0)
+ continue;
+
+ if (!((1 << i) & ras_block_mask_query))
+ continue;
+
+ ret = amdgpu_ras_query_err_count(i, &ue, &ce);
+ CU_ASSERT_EQUAL(ret, 0);
+ }
+}
+
+static void amdgpu_ras_query_test(void)
+{
+ int i;
+ for (i = 0; i < devices_count; i++) {
+ set_test_card(i);
+ __amdgpu_ras_query_test();
+ }
+}
+
+static void amdgpu_ras_basic_test(void)
+{
+ int ret;
+ int i;
+ int j;
+ uint32_t features;
+ char path[PATH_SIZE];
+
+ ret = is_file_ok("/sys/module/amdgpu/parameters/ras_mask", O_RDONLY);
+ CU_ASSERT_EQUAL(ret, 0);
+
+ for (i = 0; i < devices_count; i++) {
+ set_test_card(i);
+
+ ret = amdgpu_query_info(device_handle, AMDGPU_INFO_RAS_ENABLED_FEATURES,
+ sizeof(features), &features);
+ CU_ASSERT_EQUAL(ret, 0);
+
+ snprintf(path, sizeof(path), "%s", get_ras_debugfs_root());
+ strncat(path, "ras_ctrl", sizeof(path) - strlen(path));
+
+ ret = is_file_ok(path, O_WRONLY);
+ CU_ASSERT_EQUAL(ret, 0);
+
+ snprintf(path, sizeof(path), "%s", get_ras_sysfs_root());
+ strncat(path, "features", sizeof(path) - strlen(path));
+
+ ret = is_file_ok(path, O_RDONLY);
+ CU_ASSERT_EQUAL(ret, 0);
+
+ for (j = 0; j < AMDGPU_RAS_BLOCK__LAST; j++) {
+ ret = amdgpu_ras_is_feature_supported(j);
+ if (ret <= 0)
+ continue;
+
+ if (!((1 << j) & ras_block_mask_basic))
+ continue;
+
+ snprintf(path, sizeof(path), "%s", get_ras_sysfs_root());
+ strncat(path, ras_block_str(j), sizeof(path) - strlen(path));
+ strncat(path, "_err_count", sizeof(path) - strlen(path));
+
+ ret = is_file_ok(path, O_RDONLY);
+ CU_ASSERT_EQUAL(ret, 0);
+
+ snprintf(path, sizeof(path), "%s", get_ras_debugfs_root());
+ strncat(path, ras_block_str(j), sizeof(path) - strlen(path));
+ strncat(path, "_err_inject", sizeof(path) - strlen(path));
+
+ ret = is_file_ok(path, O_WRONLY);
+ CU_ASSERT_EQUAL(ret, 0);
+ }
+ }
+}
+
+CU_TestInfo ras_tests[] = {
+ { "ras basic test", amdgpu_ras_basic_test },
+ { "ras query test", amdgpu_ras_query_test },
+ { "ras inject test", amdgpu_ras_inject_test },
+ { "ras disable test", amdgpu_ras_disable_test },
+ { "ras enable test", amdgpu_ras_enable_test },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_ras_tests_enable(void)
+{
+ amdgpu_device_handle device_handle;
+ uint32_t major_version;
+ uint32_t minor_version;
+ int i;
+ drmDevicePtr device;
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
+ if (amdgpu_device_initialize(drm_amdgpu[i], &major_version,
+ &minor_version, &device_handle))
+ continue;
+
+ if (drmGetDevice2(drm_amdgpu[i],
+ DRM_DEVICE_GET_PCI_REVISION,
+ &device))
+ continue;
+
+ if (device->bustype == DRM_BUS_PCI &&
+ amdgpu_ras_lookup_capability(device_handle)) {
+ amdgpu_device_deinitialize(device_handle);
+ return CU_TRUE;
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ continue;
+ }
+
+ return CU_FALSE;
+}
+
+int suite_ras_tests_init(void)
+{
+ drmDevicePtr device;
+ amdgpu_device_handle device_handle;
+ uint32_t major_version;
+ uint32_t minor_version;
+ uint32_t capability;
+ struct ras_test_mask test_mask;
+ int id;
+ int i;
+ int r;
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
+ r = amdgpu_device_initialize(drm_amdgpu[i], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ continue;
+
+ if (drmGetDevice2(drm_amdgpu[i],
+ DRM_DEVICE_GET_PCI_REVISION,
+ &device)) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+ }
+
+ if (device->bustype != DRM_BUS_PCI) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+ }
+
+ capability = amdgpu_ras_lookup_capability(device_handle);
+ if (capability == 0) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+
+ }
+
+ id = amdgpu_ras_lookup_id(device);
+ if (id == -1) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+ }
+
+ test_mask = amdgpu_ras_get_test_mask(device);
+
+ devices[devices_count++] = (struct amdgpu_ras_data) {
+ device_handle, id, capability, test_mask,
+ };
+ }
+
+ if (devices_count == 0)
+ return CUE_SINIT_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+int suite_ras_tests_clean(void)
+{
+ int r;
+ int i;
+ int ret = CUE_SUCCESS;
+
+ for (i = 0; i < devices_count; i++) {
+ r = amdgpu_device_deinitialize(devices[i].device_handle);
+ if (r)
+ ret = CUE_SCLEAN_FAILED;
+ }
+ return ret;
+}
diff --git a/tests/amdgpu/security_tests.c b/tests/amdgpu/security_tests.c
new file mode 100644
index 0000000..e6c9f9a
--- /dev/null
+++ b/tests/amdgpu/security_tests.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#include <string.h>
+#include <unistd.h>
+#ifdef __FreeBSD__
+#include <sys/endian.h>
+#else
+#include <endian.h>
+#endif
+#include <strings.h>
+#include <xf86drm.h>
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static struct drm_amdgpu_info_hw_ip sdma_info;
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(_Arr) (sizeof(_Arr)/sizeof((_Arr)[0]))
+#endif
+
+
+/* --------------------- Secure bounce test ------------------------ *
+ *
+ * The secure bounce test tests that we can evict a TMZ buffer,
+ * and page it back in, via a bounce buffer, as it encryption/decryption
+ * depends on its physical address, and have the same data, i.e. data
+ * integrity is preserved.
+ *
+ * The steps are as follows (from Christian K.):
+ *
+ * Buffer A which is TMZ protected and filled by the CPU with a
+ * certain pattern. That the GPU is reading only random nonsense from
+ * that pattern is irrelevant for the test.
+ *
+ * This buffer A is then secure copied into buffer B which is also
+ * TMZ protected.
+ *
+ * Buffer B is moved around, from VRAM to GTT, GTT to SYSTEM,
+ * etc.
+ *
+ * Then, we use another secure copy of buffer B back to buffer A.
+ *
+ * And lastly we check with the CPU the pattern.
+ *
+ * Assuming that we don't have memory contention and buffer A stayed
+ * at the same place, we should still see the same pattern when read
+ * by the CPU.
+ *
+ * If we don't see the same pattern then something in the buffer
+ * migration code is not working as expected.
+ */
+
+#define SECURE_BOUNCE_TEST_STR "secure bounce"
+#define SECURE_BOUNCE_FAILED_STR SECURE_BOUNCE_TEST_STR " failed"
+
+#define PRINT_ERROR(_Res) fprintf(stderr, "%s:%d: %s (%d)\n", \
+ __func__, __LINE__, strerror(-(_Res)), _Res)
+
+#define PACKET_LCOPY_SIZE 7
+#define PACKET_NOP_SIZE 12
+
+struct sec_amdgpu_bo {
+ struct amdgpu_bo *bo;
+ struct amdgpu_va *va;
+};
+
+struct command_ctx {
+ struct amdgpu_device *dev;
+ struct amdgpu_cs_ib_info cs_ibinfo;
+ struct amdgpu_cs_request cs_req;
+ struct amdgpu_context *context;
+ int ring_id;
+};
+
+/**
+ * amdgpu_bo_alloc_map -- Allocate and map a buffer object (BO)
+ * @dev: The AMDGPU device this BO belongs to.
+ * @size: The size of the BO.
+ * @alignment: Alignment of the BO.
+ * @gem_domain: One of AMDGPU_GEM_DOMAIN_xyz.
+ * @alloc_flags: One of AMDGPU_GEM_CREATE_xyz.
+ * @sbo: the result
+ *
+ * Allocate a buffer object (BO) with the desired attributes
+ * as specified by the argument list and write out the result
+ * into @sbo.
+ *
+ * Return 0 on success and @sbo->bo and @sbo->va are set,
+ * or -errno on error.
+ */
+static int amdgpu_bo_alloc_map(struct amdgpu_device *dev,
+ unsigned size,
+ unsigned alignment,
+ unsigned gem_domain,
+ uint64_t alloc_flags,
+ struct sec_amdgpu_bo *sbo)
+{
+ void *cpu;
+ uint64_t mc_addr;
+
+ return amdgpu_bo_alloc_and_map_raw(dev,
+ size,
+ alignment,
+ gem_domain,
+ alloc_flags,
+ 0,
+ &sbo->bo,
+ &cpu, &mc_addr,
+ &sbo->va);
+}
+
+static void amdgpu_bo_unmap_free(struct sec_amdgpu_bo *sbo,
+ const uint64_t size)
+{
+ (void) amdgpu_bo_unmap_and_free(sbo->bo,
+ sbo->va,
+ sbo->va->address,
+ size);
+ sbo->bo = NULL;
+ sbo->va = NULL;
+}
+
+static void amdgpu_sdma_lcopy(uint32_t *packet,
+ const uint64_t dst,
+ const uint64_t src,
+ const uint32_t size,
+ const int secure)
+{
+ /* Set the packet to Linear copy with TMZ set.
+ */
+ packet[0] = htole32(secure << 18 | 1);
+ packet[1] = htole32(size-1);
+ packet[2] = htole32(0);
+ packet[3] = htole32((uint32_t)(src & 0xFFFFFFFFU));
+ packet[4] = htole32((uint32_t)(src >> 32));
+ packet[5] = htole32((uint32_t)(dst & 0xFFFFFFFFU));
+ packet[6] = htole32((uint32_t)(dst >> 32));
+}
+
+static void amdgpu_sdma_nop(uint32_t *packet, uint32_t nop_count)
+{
+ /* A packet of the desired number of NOPs.
+ */
+ packet[0] = htole32(nop_count << 16);
+ for ( ; nop_count > 0; nop_count--)
+ packet[nop_count-1] = 0;
+}
+
+/**
+ * amdgpu_bo_lcopy -- linear copy with TMZ set, using sDMA
+ * @dev: AMDGPU device to which both buffer objects belong to
+ * @dst: destination buffer object
+ * @src: source buffer object
+ * @size: size of memory to move, in bytes.
+ * @secure: Set to 1 to perform secure copy, 0 for clear
+ *
+ * Issues and waits for completion of a Linear Copy with TMZ
+ * set, to the sDMA engine. @size should be a multiple of
+ * at least 16 bytes.
+ */
+static void amdgpu_bo_lcopy(struct command_ctx *ctx,
+ struct sec_amdgpu_bo *dst,
+ struct sec_amdgpu_bo *src,
+ const uint32_t size,
+ int secure)
+{
+ struct amdgpu_bo *bos[] = { dst->bo, src->bo };
+ uint32_t packet[PACKET_LCOPY_SIZE];
+
+ amdgpu_sdma_lcopy(packet,
+ dst->va->address,
+ src->va->address,
+ size, secure);
+ amdgpu_test_exec_cs_helper_raw(ctx->dev, ctx->context,
+ AMDGPU_HW_IP_DMA, ctx->ring_id,
+ ARRAY_SIZE(packet), packet,
+ ARRAY_SIZE(bos), bos,
+ &ctx->cs_ibinfo, &ctx->cs_req,
+ secure == 1);
+}
+
+/**
+ * amdgpu_bo_move -- Evoke a move of the buffer object (BO)
+ * @dev: device to which this buffer object belongs to
+ * @bo: the buffer object to be moved
+ * @whereto: one of AMDGPU_GEM_DOMAIN_xyz
+ * @secure: set to 1 to submit secure IBs
+ *
+ * Evokes a move of the buffer object @bo to the GEM domain
+ * descibed by @whereto.
+ *
+ * Returns 0 on sucess; -errno on error.
+ */
+static int amdgpu_bo_move(struct command_ctx *ctx,
+ struct amdgpu_bo *bo,
+ uint64_t whereto,
+ int secure)
+{
+ struct amdgpu_bo *bos[] = { bo };
+ struct drm_amdgpu_gem_op gop = {
+ .handle = bo->handle,
+ .op = AMDGPU_GEM_OP_SET_PLACEMENT,
+ .value = whereto,
+ };
+ uint32_t packet[PACKET_NOP_SIZE];
+ int res;
+
+ /* Change the buffer's placement.
+ */
+ res = drmIoctl(ctx->dev->fd, DRM_IOCTL_AMDGPU_GEM_OP, &gop);
+ if (res)
+ return -errno;
+
+ /* Now issue a NOP to actually evoke the MM to move
+ * it to the desired location.
+ */
+ amdgpu_sdma_nop(packet, PACKET_NOP_SIZE);
+ amdgpu_test_exec_cs_helper_raw(ctx->dev, ctx->context,
+ AMDGPU_HW_IP_DMA, ctx->ring_id,
+ ARRAY_SIZE(packet), packet,
+ ARRAY_SIZE(bos), bos,
+ &ctx->cs_ibinfo, &ctx->cs_req,
+ secure == 1);
+ return 0;
+}
+
+/* Safe, O Sec!
+ */
+static const uint8_t secure_pattern[] = { 0x5A, 0xFE, 0x05, 0xEC };
+
+#define SECURE_BUFFER_SIZE (4 * 1024 * sizeof(secure_pattern))
+
+static void amdgpu_secure_bounce(void)
+{
+ struct sec_amdgpu_bo alice, bob;
+ struct command_ctx sb_ctx;
+ long page_size;
+ uint8_t *pp;
+ int res;
+
+ page_size = sysconf(_SC_PAGESIZE);
+
+ memset(&sb_ctx, 0, sizeof(sb_ctx));
+ sb_ctx.dev = device_handle;
+ res = amdgpu_cs_ctx_create(sb_ctx.dev, &sb_ctx.context);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ return;
+ }
+
+ /* Use the first present ring.
+ */
+ res = ffs(sdma_info.available_rings) - 1;
+ if (res == -1) {
+ PRINT_ERROR(-ENOENT);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ goto Out_free_ctx;
+ }
+ sb_ctx.ring_id = res;
+
+ /* Allocate a buffer named Alice in VRAM.
+ */
+ res = amdgpu_bo_alloc_map(device_handle,
+ SECURE_BUFFER_SIZE,
+ page_size,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_ENCRYPTED,
+ &alice);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ return;
+ }
+
+ /* Fill Alice with a pattern.
+ */
+ for (pp = alice.bo->cpu_ptr;
+ pp < (__typeof__(pp)) alice.bo->cpu_ptr + SECURE_BUFFER_SIZE;
+ pp += sizeof(secure_pattern))
+ memcpy(pp, secure_pattern, sizeof(secure_pattern));
+
+ /* Allocate a buffer named Bob in VRAM.
+ */
+ res = amdgpu_bo_alloc_map(device_handle,
+ SECURE_BUFFER_SIZE,
+ page_size,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_ENCRYPTED,
+ &bob);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ goto Out_free_Alice;
+ }
+
+ /* sDMA TMZ copy from Alice to Bob.
+ */
+ amdgpu_bo_lcopy(&sb_ctx, &bob, &alice, SECURE_BUFFER_SIZE, 1);
+
+ /* Move Bob to the GTT domain.
+ */
+ res = amdgpu_bo_move(&sb_ctx, bob.bo, AMDGPU_GEM_DOMAIN_GTT, 0);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ goto Out_free_all;
+ }
+
+ /* sDMA TMZ copy from Bob to Alice.
+ */
+ amdgpu_bo_lcopy(&sb_ctx, &alice, &bob, SECURE_BUFFER_SIZE, 1);
+
+ /* Verify the contents of Alice.
+ */
+ for (pp = alice.bo->cpu_ptr;
+ pp < (__typeof__(pp)) alice.bo->cpu_ptr + SECURE_BUFFER_SIZE;
+ pp += sizeof(secure_pattern)) {
+ res = memcmp(pp, secure_pattern, sizeof(secure_pattern));
+ if (res) {
+ fprintf(stderr, SECURE_BOUNCE_FAILED_STR);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ break;
+ }
+ }
+
+Out_free_all:
+ amdgpu_bo_unmap_free(&bob, SECURE_BUFFER_SIZE);
+Out_free_Alice:
+ amdgpu_bo_unmap_free(&alice, SECURE_BUFFER_SIZE);
+Out_free_ctx:
+ res = amdgpu_cs_ctx_free(sb_ctx.context);
+ CU_ASSERT_EQUAL(res, 0);
+}
+
+/* ----------------------------------------------------------------- */
+
+static void amdgpu_security_alloc_buf_test(void)
+{
+ amdgpu_bo_handle bo;
+ amdgpu_va_handle va_handle;
+ uint64_t bo_mc;
+ int r;
+
+ /* Test secure buffer allocation in VRAM */
+ bo = gpu_mem_alloc(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_ENCRYPTED,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test secure buffer allocation in system memory */
+ bo = gpu_mem_alloc(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_CREATE_ENCRYPTED,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test secure buffer allocation in invisible VRAM */
+ bo = gpu_mem_alloc(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_CREATE_ENCRYPTED |
+ AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_security_gfx_submission_test(void)
+{
+ amdgpu_command_submission_write_linear_helper_with_secure(device_handle,
+ AMDGPU_HW_IP_GFX,
+ true);
+}
+
+static void amdgpu_security_sdma_submission_test(void)
+{
+ amdgpu_command_submission_write_linear_helper_with_secure(device_handle,
+ AMDGPU_HW_IP_DMA,
+ true);
+}
+
+/* ----------------------------------------------------------------- */
+
+CU_TestInfo security_tests[] = {
+ { "allocate secure buffer test", amdgpu_security_alloc_buf_test },
+ { "graphics secure command submission", amdgpu_security_gfx_submission_test },
+ { "sDMA secure command submission", amdgpu_security_sdma_submission_test },
+ { SECURE_BOUNCE_TEST_STR, amdgpu_secure_bounce },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_security_tests_enable(void)
+{
+ CU_BOOL enable = CU_TRUE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+
+ if (!(device_handle->dev_info.ids_flags & AMDGPU_IDS_FLAGS_TMZ)) {
+ printf("\n\nDon't support TMZ (trust memory zone), security suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if ((major_version < 3) ||
+ ((major_version == 3) && (minor_version < 37))) {
+ printf("\n\nDon't support TMZ (trust memory zone), kernel DRM version (%d.%d)\n",
+ major_version, minor_version);
+ printf("is older, security suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_security_tests_init(void)
+{
+ int res;
+
+ res = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (res) {
+ PRINT_ERROR(res);
+ return CUE_SINIT_FAILED;
+ }
+
+ res = amdgpu_query_hw_ip_info(device_handle,
+ AMDGPU_HW_IP_DMA,
+ 0, &sdma_info);
+ if (res) {
+ PRINT_ERROR(res);
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_security_tests_clean(void)
+{
+ int res;
+
+ res = amdgpu_device_deinitialize(device_handle);
+ if (res)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
diff --git a/tests/amdgpu/shader_code.h b/tests/amdgpu/shader_code.h
new file mode 100644
index 0000000..74d32bb
--- /dev/null
+++ b/tests/amdgpu/shader_code.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _shader_code_h_
+#define _shader_code_h_
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+enum amdgpu_test_gfx_version {
+ AMDGPU_TEST_GFX_V9 = 0,
+ AMDGPU_TEST_GFX_V10,
+ AMDGPU_TEST_GFX_V11,
+ AMDGPU_TEST_GFX_MAX,
+};
+
+enum cs_type {
+ CS_BUFFERCLEAR = 0,
+ CS_BUFFERCOPY,
+ CS_HANG,
+ CS_HANG_SLOW,
+};
+
+enum ps_type {
+ PS_CONST,
+ PS_TEX,
+ PS_HANG,
+ PS_HANG_SLOW
+};
+
+enum vs_type {
+ VS_RECTPOSTEXFAST,
+};
+
+struct reg_info {
+ uint32_t reg_offset; ///< Memory mapped register offset
+ uint32_t reg_value; ///< register value
+};
+
+#include "shader_code_hang.h"
+#include "shader_code_gfx9.h"
+#include "shader_code_gfx10.h"
+#include "shader_code_gfx11.h"
+
+struct shader_test_cs_shader {
+ const uint32_t *shader;
+ uint32_t shader_size;
+ const struct reg_info *sh_reg;
+ uint32_t num_sh_reg;
+ const struct reg_info *context_reg;
+ uint32_t num_context_reg;
+};
+
+struct shader_test_ps_shader {
+ const uint32_t *shader;
+ unsigned shader_size;
+ const uint32_t patchinfo_code_size;
+ const uint32_t *patchinfo_code;
+ const uint32_t *patchinfo_code_offset;
+ const struct reg_info *sh_reg;
+ const uint32_t num_sh_reg;
+ const struct reg_info *context_reg;
+ const uint32_t num_context_reg;
+};
+
+struct shader_test_vs_shader {
+ const uint32_t *shader;
+ uint32_t shader_size;
+ const struct reg_info *sh_reg;
+ uint32_t num_sh_reg;
+ const struct reg_info *context_reg;
+ uint32_t num_context_reg;
+};
+
+static const struct shader_test_cs_shader shader_test_cs[AMDGPU_TEST_GFX_MAX][2] = {
+ // gfx9, cs_bufferclear
+ {{bufferclear_cs_shader_gfx9, sizeof(bufferclear_cs_shader_gfx9), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)},
+ // gfx9, cs_buffercopy
+ {buffercopy_cs_shader_gfx9, sizeof(buffercopy_cs_shader_gfx9), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)}},
+ // gfx10, cs_bufferclear
+ {{bufferclear_cs_shader_gfx10, sizeof(bufferclear_cs_shader_gfx10), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)},
+ // gfx10, cs_buffercopy
+ {buffercopy_cs_shader_gfx10, sizeof(bufferclear_cs_shader_gfx10), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)}},
+ // gfx11, cs_bufferclear
+ {{bufferclear_cs_shader_gfx11, sizeof(bufferclear_cs_shader_gfx11), bufferclear_cs_shader_registers_gfx11, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx11)},
+ // gfx11, cs_buffercopy
+ {buffercopy_cs_shader_gfx11, sizeof(bufferclear_cs_shader_gfx11), bufferclear_cs_shader_registers_gfx11, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx11)}},
+};
+
+#define SHADER_PS_INFO(_ps, _n) \
+ {ps_##_ps##_shader_gfx##_n, sizeof(ps_##_ps##_shader_gfx##_n), \
+ ps_##_ps##_shader_patchinfo_code_size_gfx##_n, \
+ ps_##_ps##_shader_patchinfo_code_gfx##_n, \
+ ps_##_ps##_shader_patchinfo_offset_gfx##_n, \
+ ps_##_ps##_sh_registers_gfx##_n, ps_##_ps##_num_sh_registers_gfx##_n, \
+ ps_##_ps##_context_registers_gfx##_n, ps_##_ps##_num_context_registers_gfx##_n}
+static const struct shader_test_ps_shader shader_test_ps[AMDGPU_TEST_GFX_MAX][2] = {
+ {SHADER_PS_INFO(const, 9), SHADER_PS_INFO(tex, 9)},
+ {SHADER_PS_INFO(const, 10), SHADER_PS_INFO(tex, 10)},
+ {SHADER_PS_INFO(const, 11), SHADER_PS_INFO(tex, 11)},
+};
+
+#define SHADER_VS_INFO(_vs, _n) \
+ {vs_##_vs##_shader_gfx##_n, sizeof(vs_##_vs##_shader_gfx##_n), \
+ vs_##_vs##_sh_registers_gfx##_n, vs_##_vs##_num_sh_registers_gfx##_n, \
+ vs_##_vs##_context_registers_gfx##_n, vs_##_vs##_num_context_registers_gfx##_n}
+static const struct shader_test_vs_shader shader_test_vs[AMDGPU_TEST_GFX_MAX][1] = {
+ {SHADER_VS_INFO(RectPosTexFast, 9)},
+ {SHADER_VS_INFO(RectPosTexFast, 10)},
+ {SHADER_VS_INFO(RectPosTexFast, 11)},
+};
+
+struct shader_test_gfx_info {
+ const uint32_t *preamble_cache;
+ uint32_t size_preamble_cache;
+ const uint32_t *cached_cmd;
+ uint32_t size_cached_cmd;
+ uint32_t sh_reg_base;
+ uint32_t context_reg_base;
+};
+
+#define SHADER_TEST_GFX_INFO(_n) \
+ preamblecache_gfx##_n, sizeof(preamblecache_gfx##_n), \
+ cached_cmd_gfx##_n, sizeof(cached_cmd_gfx##_n), \
+ sh_reg_base_gfx##_n, context_reg_base_gfx##_n
+
+static struct shader_test_gfx_info shader_test_gfx_info[AMDGPU_TEST_GFX_MAX] = {
+ {SHADER_TEST_GFX_INFO(9),},
+ {SHADER_TEST_GFX_INFO(10),},
+ {SHADER_TEST_GFX_INFO(11),},
+};
+#endif
diff --git a/tests/amdgpu/shader_code_gfx10.h b/tests/amdgpu/shader_code_gfx10.h
new file mode 100644
index 0000000..4849bbc
--- /dev/null
+++ b/tests/amdgpu/shader_code_gfx10.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _shader_code_gfx10_h_
+#define _shader_code_gfx10_h_
+
+static const uint32_t bufferclear_cs_shader_gfx10[] = {
+ 0xD7460004, 0x04010C08, 0x7E000204, 0x7E020205,
+ 0x7E040206, 0x7E060207, 0xE01C2000, 0x80000004,
+ 0xBF810000
+};
+
+static const uint32_t buffercopy_cs_shader_gfx10[] = {
+ 0xD7460001, 0x04010C08, 0xE00C2000, 0x80000201,
+ 0xBF8C3F70, 0xE01C2000, 0x80010201, 0xBF810000
+};
+
+static const uint32_t ps_const_shader_gfx10[] = {
+ 0x7E000200, 0x7E020201, 0x7E040202, 0x7E060203,
+ 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000,
+ 0xF8001C0F, 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_const_shader_patchinfo_code_size_gfx10 = 6;
+
+static const uint32_t ps_const_shader_patchinfo_code_gfx10[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000300 },
+ { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 },
+ { 0xD7690000, 0x00020300, 0xD7690001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xD7680000, 0x00020300, 0xD7680001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xD76A0000, 0x00020300, 0xD76A0001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xD76B0000, 0x00020300, 0xD76B0001, 0x00020702, 0xF8001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x03020100 }
+ }
+};
+
+static const uint32_t ps_const_shader_patchinfo_offset_gfx10[] = {
+ 0x00000004
+};
+
+static const uint32_t ps_const_num_sh_registers_gfx10 = 2;
+
+static const struct reg_info ps_const_sh_registers_gfx10[] = {
+ {0x2C0A, 0x000C0000},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0000 },
+ {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 }
+};
+
+static const struct reg_info ps_const_context_registers_gfx10[] =
+{
+ {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000000}, //{ mmSPI_PS_IN_CONTROL, 0x00000000 },
+ {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ }
+};
+
+static const uint32_t ps_const_num_context_registers_gfx10 = 7;
+
+static const uint32_t ps_tex_shader_gfx10[] = {
+ 0xBEFC030C, 0xBE8E047E, 0xBEFE0A7E, 0xC8080000,
+ 0xC80C0100, 0xC8090001, 0xC80D0101, 0xF0800F0A,
+ 0x00400402, 0x00000003, 0xBEFE040E, 0xBF8C0F70,
+ 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000,
+ 0xF8001C0F, 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_tex_shader_patchinfo_offset_gfx10[] = {
+ 0x0000000C
+};
+
+static const uint32_t ps_tex_shader_patchinfo_code_size_gfx10 = 6;
+
+static const uint32_t ps_tex_shader_patchinfo_code_gfx10[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000004 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000504 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000704 },
+ { 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 },
+ { 0xD7690000, 0x00020B04, 0xD7690001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xD7680000, 0x00020B04, 0xD7680001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xD76A0000, 0x00020B04, 0xD76A0001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xD76B0000, 0x00020B04, 0xD76B0001, 0x00020F06, 0xF8001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x07060504 }
+ }
+};
+
+static const struct reg_info ps_tex_sh_registers_gfx10[] =
+{
+ {0x2C0A, 0xc0081}, //0x020C0080 }, //{ mmSPI_SHADER_PGM_RSRC1_PS, 0x020C0080 },
+ {0x2C0B, 0x00000018 }, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000018 }
+};
+
+static const uint32_t ps_tex_num_sh_registers_gfx10 = 2;
+
+// Holds Context Register Information
+static const struct reg_info ps_tex_context_registers_gfx10[] =
+{
+ {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000001}, //{ mmSPI_PS_IN_CONTROL, 0x00000001 },
+ {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ }
+};
+
+static const uint32_t ps_tex_num_context_registers_gfx10 = 7;
+
+static const uint32_t vs_RectPosTexFast_shader_gfx10[] = {
+ 0x7E000B00, 0x060000F3, 0x7E020202, 0x7E040206,
+ 0x7C040080, 0x060000F3, 0xD5010001, 0x01AA0200,
+ 0x7E060203, 0xD5010002, 0x01AA0404, 0x7E080207,
+ 0x7C040080, 0xD5010000, 0x01A80101, 0xD5010001,
+ 0x01AA0601, 0x7E060208, 0x7E0A02F2, 0xD5010002,
+ 0x01A80902, 0xD5010004, 0x01AA0805, 0x7E0C0209,
+ 0xF80008CF, 0x05030100, 0xF800020F, 0x05060402,
+ 0xBF810000
+};
+
+static const struct reg_info vs_RectPosTexFast_sh_registers_gfx10[] =
+{
+ {0x2C4A, 0x080C0041 }, //{ mmSPI_SHADER_PGM_RSRC1_VS, 0x080C0041 },
+ {0x2C4B, 0x00000018 }, //{ mmSPI_SHADER_PGM_RSRC2_VS, 0x00000018 }
+};
+
+static const uint32_t vs_RectPosTexFast_num_sh_registers_gfx10 = 2;
+
+// Holds Context Register Information
+static const struct reg_info vs_RectPosTexFast_context_registers_gfx10[] =
+{
+ {0xA1B1, 0x00000000}, //{ mmSPI_VS_OUT_CONFIG, 0x00000000 },
+ {0xA1C3, 0x00000000}, //{ mmSPI_SHADER_POS_FORMAT, 0x00000000 /* Always 0 for now */}
+};
+
+static const uint32_t vs_RectPosTexFast_num_context_registers_gfx10 = 2;
+
+static const uint32_t preamblecache_gfx10[] = {
+ 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0,
+ 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000,
+ 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0,
+ 0xc0016900, 0x208, 0x0, 0xc0016900, 0x290, 0x0,
+ 0xc0016900, 0x2a1, 0x0, 0xc0026900, 0x2ad, 0x0, 0x0,
+ 0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0,
+ 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0,
+ 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0xc0046900, 0x310, 0, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0xe, 0x20,
+ 0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0,
+ 0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x6, 0x0,
+ 0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0,
+ 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff,
+ 0xc0016900, 0x314, 0x0, 0xc0016900, 0x10a, 0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0,
+ 0xc0016900, 0x2db, 0, 0xc0016900, 0x1d4, 0, 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1, 0xc0016900, 0xe, 0x2,
+ 0xc0016900, 0x206, 0x300, 0xc0016900, 0x212, 0x200, 0xc0017900, 0x7b, 0x20, 0xc0017a00, 0x20000243, 0x0,
+ 0xc0017900, 0x249, 0, 0xc0017900, 0x24a, 0, 0xc0017900, 0x24b, 0, 0xc0017900, 0x259, 0xffffffff,
+ 0xc0017900, 0x25f, 0, 0xc0017900, 0x260, 0, 0xc0017900, 0x262, 0,
+ 0xc0017600, 0x45, 0x0, 0xc0017600, 0x6, 0x0,
+ 0xc0067600, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0067600, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+};
+
+static const uint32_t cached_cmd_gfx10[] = {
+ 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0,
+ 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020,
+ 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf,
+ 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x18,
+ 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0,
+ 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011,
+ 0xc0026900, 0x292, 0x20, 0x6020000,
+ 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0
+};
+
+static const uint32_t sh_reg_base_gfx10 = 0x2C00;
+static const uint32_t context_reg_base_gfx10 = 0xA000;
+
+#endif
diff --git a/tests/amdgpu/shader_code_gfx11.h b/tests/amdgpu/shader_code_gfx11.h
new file mode 100644
index 0000000..d9ee0a7
--- /dev/null
+++ b/tests/amdgpu/shader_code_gfx11.h
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _shader_code_gfx11_h_
+#define _shader_code_gfx11_h_
+
+static const uint32_t bufferclear_cs_shader_gfx11[] = {
+ 0xB0802006, 0xBF840003, 0x360000FF, 0x000003FF,
+ 0x7E020205, 0x7E040206, 0x7E060207, 0xBF870004,
+ 0xD6460004, 0x04010C08, 0x7E000204, 0xE01C0000,
+ 0x80800004, 0xBFB60003, 0xBFB00000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000
+};
+
+static const struct reg_info bufferclear_cs_shader_registers_gfx11[] = {
+ {0x2e12, 0x600C0041}, //{ mmCOMPUTE_PGM_RSRC1, 0x600C0041 },
+ {0x2e13, 0x00000090}, //{ mmCOMPUTE_PGM_RSRC2, 0x00000090 },
+ {0x2e07, 0x00000040}, //{ mmCOMPUTE_NUM_THREAD_X, 0x00000040 },
+ {0x2e08, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Y, 0x00000001 },
+ {0x2e09, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Z, 0x00000001 }
+};
+
+static const uint32_t buffercopy_cs_shader_gfx11[] = {
+ 0xB0802006, 0xBF840003, 0x360000FF, 0x000003FF,
+ 0xBF870001, 0xD6460001, 0x04010C08, 0xE00C0000,
+ 0x80800201, 0xBF8903F7, 0xE01C0000, 0x80810201,
+ 0xBFB60003, 0xBFB00000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000
+};
+
+static const uint32_t ps_const_shader_gfx11[] = {
+ 0xB0802006, 0xBF840003, 0x7E000200, 0x7E020201,
+ 0x7E040202, 0x7E060203, 0x5E000300, 0x5E020702,
+ 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100,
+ 0xBFB00000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000
+};
+
+static const uint32_t ps_const_shader_patchinfo_code_size_gfx11 = 6;
+
+static const uint32_t ps_const_shader_patchinfo_code_gfx11[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000890, 0x00000000 }, // SI_EXPORT_FMT_ZERO
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000801, 0x00000000 }, // SI_EXPORT_FMT_32_R
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_32_GR
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000300 }, // SI_EXPORT_FMT_32_AR
+ { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_FP16_ABGR
+ { 0xD7220000, 0x00020300, 0xD7220001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_UNORM16_ABGR
+ { 0xD7210000, 0x00020300, 0xD7210001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SNORM16_ABGR
+ { 0xD7230000, 0x00020300, 0xD7230001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_uint32_t16_ABGR
+ { 0xD7240000, 0x00020300, 0xD7240001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SINT16_ABGR
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800080F, 0x03020100 } // SI_EXPORT_FMT_32_ABGR
+ }
+};
+
+static const uint32_t ps_const_shader_patchinfo_offset_gfx11[] = {
+ 0x00000006
+};
+
+static const uint32_t ps_const_num_sh_registers_gfx11 = 2;
+
+static const struct reg_info ps_const_sh_registers_gfx11[] = {
+ {0x2C0A, 0x020C0000}, //{ mmSPI_SHADER_PGM_RSRC1_PS, 0x020C0000 },
+ {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 }
+};
+
+static const struct reg_info ps_const_context_registers_gfx11[] = {
+ {0xA1B4, 0x00000002 }, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000000 }, //{ mmSPI_PS_IN_CONTROL, 0x00000000 },
+ {0xA08F, 0x0000000F }, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010 }, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000 }, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000 }, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004 }, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ }
+};
+
+static const uint32_t ps_const_num_context_registers_gfx11 = 7;
+
+static const uint32_t ps_tex_shader_gfx11[] =
+{
+ 0xB0802006, 0xBF840003, 0xBEFD000C, 0xBE8E017E,
+ 0xBEFE1D7E, 0xCE000003, 0xCE000102, 0xCD000104,
+ 0x040E0103, 0xCD000000, 0x040A0102, 0xBF870112,
+ 0xCD010703, 0x04120303, 0xCD010700, 0x04020302,
+ 0x8BFE0E7E, 0xF06C0F05, 0x08000003, 0x00000000,
+ 0xBEFE010E, 0xBF8903F7, 0x5E000300, 0x5E020702,
+ 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100,
+ 0xBFB00000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000
+};
+
+static const uint32_t ps_tex_shader_patchinfo_offset_gfx11[] =
+{
+ 0x00000016
+};
+
+// Denotes the Patch Info Code Length
+static const uint32_t ps_tex_shader_patchinfo_code_size_gfx11 = 6;
+
+static const uint32_t ps_tex_shader_patchinfo_code_gfx11[][10][6] =
+{
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000890, 0x00000000 }, // SI_EXPORT_FMT_ZERO
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000801, 0x00000000 }, // SI_EXPORT_FMT_32_R
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_32_GR
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000300 }, // SI_EXPORT_FMT_32_AR
+ { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_FP16_ABGR
+ { 0xD7220000, 0x00020300, 0xD7220001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_UNORM16_ABGR
+ { 0xD7210000, 0x00020300, 0xD7210001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SNORM16_ABGR
+ { 0xD7230000, 0x00020300, 0xD7230001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_uint32_t16_ABGR
+ { 0xD7240000, 0x00020300, 0xD7240001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SINT16_ABGR
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800080F, 0x03020100 } // SI_EXPORT_FMT_32_ABGR
+ }
+};
+// Holds Sh Register Information
+static const struct reg_info ps_tex_sh_registers_gfx11[] =
+{
+ {0x2C0A, 0x020C0081 }, //{ mmSPI_SHADER_PGM_RSRC1_PS, 0x020C0081 },
+ {0x2C0B, 0x00000018 } //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000018 }
+};
+
+static const uint32_t ps_tex_num_sh_registers_gfx11 = 2;
+
+// Holds Context Register Information
+static const struct reg_info ps_tex_context_registers_gfx11[] =
+{
+ {0xA1B4, 0x00000002 }, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000001 }, //{ mmSPI_PS_IN_CONTROL, 0x00000001 },
+ {0xA08F, 0x0000000F }, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010 }, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000 }, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000 }, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004 } //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ }
+};
+
+static const uint32_t ps_tex_num_context_registers_gfx11 = 7;
+
+
+static const uint32_t vs_RectPosTexFast_shader_gfx11[] =
+{
+ 0xB0802006, 0xBEFE01C1, 0xBF840003, 0xF408050A,
+ 0xF80000B0, 0xD71F0001, 0x000100C1, 0x9300FF03,
+ 0x00040018, 0x9301FF02, 0x0009000C, 0xBF870091,
+ 0xD7200001, 0x000202C1, 0xD60B0001, 0x04058000,
+ 0xBF870001, 0xD4490000, 0x00000301, 0xBE862100,
+ 0x7E040B05, 0xBFA5001C, 0x7E06020A, 0x7E08020E,
+ 0x7E0A020F, 0xBF8701B4, 0x060404F3, 0x7E140211,
+ 0x7E0E0210, 0x7C240480, 0x060404F3, 0xD5010003,
+ 0x01AA0608, 0xD5010004, 0x01AA080C, 0xBF870003,
+ 0xD4120012, 0x00010102, 0x7E04020B, 0xBEEA1F12,
+ 0xBF870483, 0xD5010008, 0x01AA080C, 0xD5010006,
+ 0x01AA0608, 0xBF870003, 0xD5010004, 0x004A0409,
+ 0xD5010009, 0x004A0A0D, 0xBEFE0106, 0x9302FF02,
+ 0x00090016, 0xBF870009, 0xD4C9007E, 0x00000501,
+ 0xBFA50002, 0xF8000941, 0x00000000, 0xBF89FFF0,
+ 0x8BFE0006, 0xD71F0000, 0x000100C1, 0xBFA50013,
+ 0x7E1602F2, 0x9300FF03, 0x00040018, 0x8B01FF05,
+ 0x00007FFF, 0xBF8704B2, 0xD7200000, 0x000200C1,
+ 0x7E0202F2, 0x84018901, 0x80018001, 0xBF870002,
+ 0xD60B0000, 0x04018000, 0xF80008CF, 0x01070406,
+ 0xBF89FC07, 0xE0744000, 0x01850800, 0xBFB00000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000,
+ 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000
+};
+
+static const struct reg_info vs_RectPosTexFast_sh_registers_gfx11[] =
+{
+ {0x2C8A, 0x020C00C2}, //{ mmSPI_SHADER_PGM_RSRC1_GS, 0x020C00C2 },
+ {0x2C8B, 0x0008001C}, //{ mmSPI_SHADER_PGM_RSRC2_GS, 0x0008001C }
+};
+
+static const uint32_t vs_RectPosTexFast_num_sh_registers_gfx11 = 2;
+
+// Holds Context Register Information
+static const struct reg_info vs_RectPosTexFast_context_registers_gfx11[] =
+{
+ {0xA1B1, 0x00000000}, //{ mmSPI_VS_OUT_CONFIG, 0x00000000 },
+ {0xA1C2, 0x00000001}, //{ mmSPI_SHADER_IDX_FORMAT, 0x00000001 },
+ {0xA1C3, 0x00000000}, //{ mmSPI_SHADER_POS_FORMAT, 0x00000000 /* Always 0 for now */},
+ {0xA2E4, 0x00000000}, //{ mmVGT_GS_INSTANCE_CNT, 0x00000000 },
+ {0xA2AB, 0x00000004}, //{ mmVGT_ESGS_RING_ITEMSIZE, 0x00000004 },
+ {0xA2CE, 0x00000001}, //{ mmVGT_GS_MAX_VERT_OUT, 0x00000001 }
+};
+
+static const uint32_t vs_RectPosTexFast_num_context_registers_gfx11 = 6;
+
+static const uint32_t preamblecache_gfx11[] = {
+ 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0,
+ 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000,
+ 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0, 0xc0016900, 0x208, 0x0,
+ 0xc0016900, 0x2a1, 0x0, 0xc0016900, 0x2ad, 0x0, 0xc0016900, 0x2dc, 0x0,
+ 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0xc0046900, 0x310, 0x0, 0x3, 0x0, 0x100000, 0xc0016900, 0x349, 0x0,
+ 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0, 0xc0016900, 0x376, 0x0,
+ 0xc0016900, 0x385, 0x0, 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0026900, 0x204, 0x90000, 0x4, 0xc0016900, 0x20c, 0x0, 0xc0026900, 0x20e, 0x0, 0x0,
+ 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff,
+ 0xc0016900, 0x314, 0x0, 0xc0016900, 0x10a, 0x0, 0xc0016900, 0x2a6, 0x0,
+ 0xc0016900, 0x210, 0x0, 0xc0016900, 0x2db, 0x0, 0xc0016900, 0x2e4, 0x0,
+ 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x0, 0xc0016900, 0x206, 0x300,
+ 0xc0016900, 0x212, 0x200, 0xc0016900, 0xf4, 0x0, 0xc0016900, 0x18, 0x0,
+ 0xc0016900, 0x1d4, 0xff, 0xc0016900, 0x2ce, 0x1, 0xc0016900, 0x2d3, 0x20001,
+ 0xc0016900, 0x1ff, 0x80, 0xc0016900, 0x2d5, 0x6012010, 0xc0017a00, 0x20000243, 0x0,
+ 0xc0017900, 0x249, 0x0, 0xc0017900, 0x24a, 0x0, 0xc0017900, 0x24b, 0x0,
+ 0xc0017900, 0x259, 0xffffffff, 0xc0017900, 0x25f, 0x0, 0xc0017900, 0x260, 0x0,
+ 0xc0017900, 0x262, 0x0, 0xc0017900, 0x444, 0x0, 0xc0017900, 0x445, 0x0,
+ 0xc0017600, 0x6, 0x0, 0xc0017600, 0x80, 0x0, 0xc0017600, 0xb0, 0x0,
+ 0xc0047600, 0xb2, 0x0, 0x0, 0x0, 0x0, 0xc0017600, 0x30, 0x0,
+ 0xc0047600, 0x32, 0x0, 0x0, 0x0, 0x0
+};
+
+static const uint32_t cached_cmd_gfx11[] = {
+ 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0,
+ 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020,
+ 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf,
+ 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0,
+ 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011,
+ 0xc0026900, 0x292, 0x20, 0x6020000,
+ 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0,
+ 0xc0046900, 0x1d5, 0x0, 0x0, 0x0, 0x0, 0xc0016900, 0x104, 0x4a00005,
+ 0xc0016900, 0x1f, 0xf2a0055, 0xc0017900, 0x266, 0x4
+};
+static const uint32_t sh_reg_base_gfx11 = 0x2C00;
+static const uint32_t context_reg_base_gfx11 = 0xA000;
+
+#endif
diff --git a/tests/amdgpu/shader_code_gfx9.h b/tests/amdgpu/shader_code_gfx9.h
new file mode 100644
index 0000000..3ad1ca8
--- /dev/null
+++ b/tests/amdgpu/shader_code_gfx9.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _shader_code_gfx9_h_
+#define _shader_code_gfx9_h_
+
+static const uint32_t bufferclear_cs_shader_gfx9[] = {
+ 0x260000ff, 0x000003ff, 0xd1fd0000, 0x04010c08,
+ 0x7e020280, 0x7e040204, 0x7e060205, 0x7e080206,
+ 0x7e0a0207, 0xe01c2000, 0x80000200, 0xbf8c0000,
+ 0xbf810000
+};
+
+static const struct reg_info bufferclear_cs_shader_registers_gfx9[] = {
+ {0x2e12, 0x000C0041}, //{ mmCOMPUTE_PGM_RSRC1, 0x000C0041 },
+ {0x2e13, 0x00000090}, //{ mmCOMPUTE_PGM_RSRC2, 0x00000090 },
+ {0x2e07, 0x00000040}, //{ mmCOMPUTE_NUM_THREAD_X, 0x00000040 },
+ {0x2e08, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Y, 0x00000001 },
+ {0x2e09, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Z, 0x00000001 }
+};
+
+static const uint32_t buffercopy_cs_shader_gfx9[] = {
+ 0x260000ff, 0x000003ff, 0xd1fd0000, 0x04010c08,
+ 0x7e020280, 0xe00c2000, 0x80000200, 0xbf8c0f70,
+ 0xe01c2000, 0x80010200, 0xbf810000
+};
+
+static const uint32_t ps_const_shader_gfx9[] = {
+ 0x7E000200, 0x7E020201, 0x7E040202, 0x7E060203,
+ 0xD2960000, 0x00020300, 0xD2960001, 0x00020702,
+ 0xC4001C0F, 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_const_shader_patchinfo_code_size_gfx9 = 6;
+
+static const uint32_t ps_const_shader_patchinfo_code_gfx9[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001801, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000300 },
+ { 0xD2960000, 0x00020300, 0xD2960001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2950000, 0x00020300, 0xD2950001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2940000, 0x00020300, 0xD2940001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2970000, 0x00020300, 0xD2970001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xD2980000, 0x00020300, 0xD2980001, 0x00020702, 0xC4001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC400180F, 0x03020100 }
+ }
+};
+
+static const uint32_t ps_const_shader_patchinfo_offset_gfx9[] = {
+ 0x00000004
+};
+
+static const uint32_t ps_const_num_sh_registers_gfx9 = 2;
+
+static const struct reg_info ps_const_sh_registers_gfx9[] = {
+ {0x2C0A, 0x000C0040},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0040 },
+ {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 }
+};
+
+static const uint32_t ps_const_num_context_registers_gfx9 = 7;
+
+static const struct reg_info ps_const_context_registers_gfx9[] = {
+ {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000000}, //{ mmSPI_PS_IN_CONTROL, 0x00000000 },
+ {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 }
+};
+
+static const uint32_t ps_tex_shader_gfx9[] = {
+ 0xBEFC000C, 0xBE8E017E, 0xBEFE077E, 0xD4180000,
+ 0xD4190001, 0xD41C0100, 0xD41D0101, 0xF0800F00,
+ 0x00400206, 0xBEFE010E, 0xBF8C0F70, 0xD2960000,
+ 0x00020702, 0xD2960001, 0x00020B04, 0xC4001C0F,
+ 0x00000100, 0xBF810000
+};
+
+static const uint32_t ps_tex_shader_patchinfo_offset_gfx9[] = {
+ 0x0000000B
+};
+
+static const uint32_t ps_tex_shader_patchinfo_code_size_gfx9 = 6;
+
+static const uint32_t ps_tex_shader_patchinfo_code_gfx9[][10][6] = {
+ {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001890, 0x00000000 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001801, 0x00000002 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000302 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000502 },
+ { 0xD2960000, 0x00020702, 0xD2960001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2950000, 0x00020702, 0xD2950001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2940000, 0x00020702, 0xD2940001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2970000, 0x00020702, 0xD2970001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xD2980000, 0x00020702, 0xD2980001, 0x00020B04, 0xC4001C0F, 0x00000100 },
+ { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC400180F, 0x05040302 }
+ }
+};
+
+static const uint32_t ps_tex_num_sh_registers_gfx9 = 2;
+static const struct reg_info ps_tex_sh_registers_gfx9[] = {
+ {0x2C0A, 0x000C0081},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0081 },
+ {0x2C0B, 0x00000018}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000018 }
+};
+
+static const uint32_t ps_tex_num_context_registers_gfx9 = 7;
+
+static const struct reg_info ps_tex_context_registers_gfx9[] = {
+ {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 },
+ {0xA1B6, 0x00000001}, //{ mmSPI_PS_IN_CONTROL, 0x00000001 },
+ {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F },
+ {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 },
+ {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 },
+ {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */},
+ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 }
+};
+
+static const uint32_t vs_RectPosTexFast_shader_gfx9[] = {
+ 0x7E000B00, 0x020000F3, 0xD042000A, 0x00010100,
+ 0x7E020202, 0x7E040200, 0x020000F3, 0x7E060206,
+ 0x7E080204, 0xD1000001, 0x002A0302, 0x7C840080,
+ 0x7E000200, 0x7E040203, 0x7E0A0201, 0xD1000003,
+ 0x002A0704, 0x7E0C0207, 0x7E0E0205, 0x00000101,
+ 0x00020505, 0x7E040208, 0x7E0A02F2, 0x00060903,
+ 0x00080D07, 0x7E0C0209, 0xC40008CF, 0x05020100,
+ 0xC400020F, 0x05060403, 0xBF810000
+};
+
+static const struct reg_info vs_RectPosTexFast_sh_registers_gfx9[] =
+{
+ {0x2C4A, 0x000C0081}, //{ mmSPI_SHADER_PGM_RSRC1_VS, 0x000C0081 },
+ {0x2C4B, 0x00000018}, //{ mmSPI_SHADER_PGM_RSRC2_VS, 0x00000018 }
+};
+
+static const uint32_t vs_RectPosTexFast_num_sh_registers_gfx9 = 2;
+
+// Holds Context Register Information
+static const struct reg_info vs_RectPosTexFast_context_registers_gfx9[] =
+{
+ {0xA1B1, 0x00000000}, //{ mmSPI_VS_OUT_CONFIG, 0x00000000 },
+ {0xA1C3, 0x00000000}, //{ mmSPI_SHADER_POS_FORMAT, 0x00000000 /* Always 0 for now */}
+};
+
+static const uint32_t vs_RectPosTexFast_num_context_registers_gfx9 = 2;
+
+static const uint32_t preamblecache_gfx9[] = {
+ 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0,
+ 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000,
+ 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0,
+ 0xc0016900, 0x208, 0x0, 0xc0016900, 0x290, 0x0,
+ 0xc0016900, 0x2a1, 0x0, 0xc0026900, 0x2ad, 0x0, 0x0,
+ 0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0,
+ 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0,
+ 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0xc0036900, 0x311, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0x1e, 0x20,
+ 0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0,
+ 0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x19, 0x0,
+ 0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0,
+ 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff,
+ 0xc0016900, 0x314, 0x0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0,
+ 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1,
+ 0xc0016900, 0x18, 0x2, 0xc0016900, 0x206, 0x300, 0xc0017900, 0x20000243, 0x0,
+ 0xc0017900, 0x248, 0xffffffff, 0xc0017900, 0x249, 0x0, 0xc0017900, 0x24a, 0x0,
+ 0xc0017900, 0x24b, 0x0
+};
+
+static const uint32_t cached_cmd_gfx9[] = {
+ 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0,
+ 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020,
+ 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf,
+ 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x12,
+ 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0,
+ 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011,
+ 0xc0026900, 0x292, 0x20, 0x60201b8,
+ 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0
+};
+
+static const uint32_t sh_reg_base_gfx9 = 0x2C00;
+static const uint32_t context_reg_base_gfx9 = 0xA000;
+
+#endif
diff --git a/tests/amdgpu/shader_code_hang.h b/tests/amdgpu/shader_code_hang.h
new file mode 100644
index 0000000..070bd71
--- /dev/null
+++ b/tests/amdgpu/shader_code_hang.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _shader_code_hang_h_
+#define _shader_code_hang_h_
+
+static const unsigned int memcpy_shader_hang[] = {
+ 0xFFFFFFFF, 0xBEFE0A7E, 0xBEFC0304, 0xC0C20100,
+ 0xC0800300, 0xC8080000, 0xC80C0100, 0xC8090001,
+ 0xC80D0101, 0xBF8C007F, 0xF0800F00, 0x00010002,
+ 0xBEFE040C, 0xBF8C0F70, 0xBF800000, 0xBF800000,
+ 0xF800180F, 0x03020100, 0xBF810000
+};
+
+struct shader_test_shader_bin {
+ const uint32_t *shader;
+ uint32_t header_length;
+ uint32_t body_length;
+ uint32_t foot_length;
+};
+
+static const unsigned int memcpy_cs_hang_slow_ai_codes[] = {
+ 0xd1fd0000, 0x04010c08, 0xe00c2000, 0x80000100,
+ 0xbf8c0f70, 0xe01c2000, 0x80010100, 0xbf810000
+};
+
+static struct shader_test_shader_bin memcpy_cs_hang_slow_ai = {
+ memcpy_cs_hang_slow_ai_codes, 4, 3, 1
+};
+
+static const unsigned int memcpy_cs_hang_slow_rv_codes[] = {
+ 0x8e00860c, 0x32000000, 0xe00c2000, 0x80010100,
+ 0xbf8c0f70, 0xe01c2000, 0x80020100, 0xbf810000
+};
+
+static struct shader_test_shader_bin memcpy_cs_hang_slow_rv = {
+ memcpy_cs_hang_slow_rv_codes, 4, 3, 1
+};
+
+static const unsigned int memcpy_cs_hang_slow_nv_codes[] = {
+ 0xd7460000, 0x04010c08, 0xe00c2000, 0x80000100,
+ 0xbf8c0f70, 0xe01ca000, 0x80010100, 0xbf810000
+};
+
+static struct shader_test_shader_bin memcpy_cs_hang_slow_nv = {
+ memcpy_cs_hang_slow_nv_codes, 4, 3, 1
+};
+
+
+static const unsigned int memcpy_ps_hang_slow_ai_codes[] = {
+ 0xbefc000c, 0xbe8e017e, 0xbefe077e, 0xd4080000,
+ 0xd4090001, 0xd40c0100, 0xd40d0101, 0xf0800f00,
+ 0x00400002, 0xbefe010e, 0xbf8c0f70, 0xbf800000,
+ 0xbf800000, 0xbf800000, 0xbf800000, 0xc400180f,
+ 0x03020100, 0xbf810000
+};
+
+static struct shader_test_shader_bin memcpy_ps_hang_slow_ai = {
+ memcpy_ps_hang_slow_ai_codes, 7, 2, 9
+};
+
+static const unsigned int memcpy_ps_hang_slow_navi10_codes[] = {
+ 0xBEFC030C,0xBE8E047E,0xBEFE0A7E,0xC8080000,
+ 0xC80C0100,0xC8090001,0xC80D0101,0xF0800F0A,
+ 0x00400402,0x00000003,0xBEFE040E,0xBF8C0F70,
+ 0xBF800000,0xBF800000,0xBF800000,0xBF800000,
+ 0xF800180F,0x07060504,0xBF810000
+};
+
+static struct shader_test_shader_bin memcpy_ps_hang_slow_navi10 = {
+ memcpy_ps_hang_slow_navi10_codes, 7, 3, 9
+};
+
+static const unsigned int memcpy_ps_hang_slow_navi21_codes[] = {
+ 0xBEFC030C, 0xBE8E047E, 0xBEFE0A7E, 0xC8080000, 0xC8000100, 0xC8090001, 0xC8010101, 0x87FE0E7E, // header
+ 0xF0800F0A, 0x00400002, 0x00000000, // body - image_sample instruction
+ 0xBFA3FFE3, 0xBEFE040E, 0xBF8C3F70, 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x03020100, 0xBF810000 // footer
+};
+
+static struct shader_test_shader_bin memcpy_ps_hang_slow_navi21 = {
+ memcpy_ps_hang_slow_navi21_codes, 8, 3, 10
+};
+
+#endif
diff --git a/tests/amdgpu/shader_test_util.c b/tests/amdgpu/shader_test_util.c
new file mode 100644
index 0000000..60148fb
--- /dev/null
+++ b/tests/amdgpu/shader_test_util.c
@@ -0,0 +1,2156 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include "CUnit/Basic.h"
+#include "amdgpu_test.h"
+#include "shader_code.h"
+
+#define PACKET3_DISPATCH_DIRECT 0x15
+#define PACKET3_CONTEXT_CONTROL 0x28
+#define PACKET3_DRAW_INDEX_AUTO 0x2D
+#define PACKET3_SET_CONTEXT_REG 0x69
+#define PACKET3_SET_SH_REG 0x76
+#define PACKET3_SET_SH_REG_OFFSET 0x77
+#define PACKET3_SET_UCONFIG_REG 0x79
+#define PACKET3_SET_SH_REG_INDEX 0x9B
+
+#define PACKET_TYPE3 3
+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
+ (((op) & 0xFF) << 8) | \
+ ((n) & 0x3FFF) << 16)
+#define PACKET3_COMPUTE(op, n) PACKET3(op, n) | (1 << 1)
+
+
+struct shader_test_bo {
+ amdgpu_bo_handle bo;
+ unsigned size;
+ unsigned heap;
+ void *ptr;
+ uint64_t mc_address;
+ amdgpu_va_handle va;
+};
+
+struct shader_test_draw {
+ struct shader_test_bo ps_bo;
+ enum ps_type ps_type;
+ struct shader_test_bo vs_bo;
+ enum vs_type vs_type;
+};
+struct shader_test_dispatch {
+ struct shader_test_bo cs_bo;
+ enum cs_type cs_type;
+};
+
+struct shader_test_info {
+ amdgpu_device_handle device_handle;
+ enum amdgpu_test_gfx_version version;
+ unsigned ip;
+ unsigned ring;
+ int hang;
+ int hang_slow;
+};
+
+struct shader_test_priv {
+ const struct shader_test_info *info;
+ unsigned cmd_curr;
+
+ union {
+ struct shader_test_draw shader_draw;
+ struct shader_test_dispatch shader_dispatch;
+ };
+ struct shader_test_bo vtx_attributes_mem;
+ struct shader_test_bo cmd;
+ struct shader_test_bo src;
+ struct shader_test_bo dst;
+};
+
+static int shader_test_bo_alloc(amdgpu_device_handle device_handle,
+ struct shader_test_bo *shader_test_bo)
+{
+ return amdgpu_bo_alloc_and_map(device_handle, shader_test_bo->size, 4096,
+ shader_test_bo->heap, 0,
+ &(shader_test_bo->bo), (void **)&(shader_test_bo->ptr),
+ &(shader_test_bo->mc_address), &(shader_test_bo->va));
+}
+
+static int shader_test_bo_free(struct shader_test_bo *shader_test_bo)
+{
+ return amdgpu_bo_unmap_and_free(shader_test_bo->bo, shader_test_bo->va,
+ shader_test_bo->mc_address,
+ shader_test_bo->size);
+}
+
+void shader_test_for_each(amdgpu_device_handle device_handle, unsigned ip,
+ void (*fn)(struct shader_test_info *test_info))
+{
+ int r;
+ uint32_t ring_id;
+ struct shader_test_info test_info = {0};
+ struct drm_amdgpu_info_hw_ip info = {0};
+
+ r = amdgpu_query_hw_ip_info(device_handle, ip, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings) {
+ printf("SKIP ... as there's no %s ring\n",
+ (ip == AMDGPU_HW_IP_GFX) ? "graphics": "compute");
+ return;
+ }
+
+ switch (info.hw_ip_version_major) {
+ case 9:
+ test_info.version = AMDGPU_TEST_GFX_V9;
+ break;
+ case 10:
+ test_info.version = AMDGPU_TEST_GFX_V10;
+ break;
+ case 11:
+ test_info.version = AMDGPU_TEST_GFX_V11;
+ break;
+ default:
+ printf("SKIP ... unsupported gfx version %d\n", info.hw_ip_version_major);
+ return;
+ }
+
+ test_info.device_handle = device_handle;
+ test_info.ip = ip;
+
+ printf("\n");
+ for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
+ printf("%s ring %d\n", (ip == AMDGPU_HW_IP_GFX) ? "graphics": "compute",
+ ring_id);
+ test_info.ring = ring_id;
+ fn(&test_info);
+ }
+}
+
+static void write_context_control(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ if (test_priv->info->ip == AMDGPU_HW_IP_GFX) {
+ ptr[i++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1);
+ ptr[i++] = 0x80000000;
+ ptr[i++] = 0x80000000;
+ }
+
+ test_priv->cmd_curr = i;
+}
+
+static void shader_test_load_shader_hang_slow(struct shader_test_bo *shader_bo,
+ struct shader_test_shader_bin *shader_bin)
+{
+ int i, j, loop;
+
+ loop = (shader_bo->size / sizeof(uint32_t) - shader_bin->header_length
+ - shader_bin->foot_length) / shader_bin->body_length;
+
+ memcpy(shader_bo->ptr, shader_bin->shader, shader_bin->header_length * sizeof(uint32_t));
+
+ j = shader_bin->header_length;
+ for (i = 0; i < loop; i++) {
+ memcpy(shader_bo->ptr + j,
+ shader_bin->shader + shader_bin->header_length,
+ shader_bin->body_length * sizeof(uint32_t));
+ j += shader_bin->body_length;
+ }
+
+ memcpy(shader_bo->ptr + j,
+ shader_bin->shader + shader_bin->header_length + shader_bin->body_length,
+ shader_bin->foot_length * sizeof(uint32_t));
+}
+
+static void amdgpu_dispatch_load_cs_shader_hang_slow(struct shader_test_priv *test_priv)
+{
+ struct amdgpu_gpu_info gpu_info = {0};
+ struct shader_test_shader_bin *cs_shader_bin;
+ int r;
+
+ r = amdgpu_query_gpu_info(test_priv->info->device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ switch (gpu_info.family_id) {
+ case AMDGPU_FAMILY_AI:
+ cs_shader_bin = &memcpy_cs_hang_slow_ai;
+ break;
+ case AMDGPU_FAMILY_RV:
+ cs_shader_bin = &memcpy_cs_hang_slow_rv;
+ break;
+ default:
+ cs_shader_bin = &memcpy_cs_hang_slow_nv;
+ break;
+ }
+
+ shader_test_load_shader_hang_slow(&test_priv->shader_dispatch.cs_bo, cs_shader_bin);
+}
+
+static void amdgpu_dispatch_load_cs_shader(struct shader_test_priv *test_priv)
+{
+ if (test_priv->info->hang) {
+ if (test_priv->info->hang_slow)
+ amdgpu_dispatch_load_cs_shader_hang_slow(test_priv);
+ else
+ memcpy(test_priv->shader_dispatch.cs_bo.ptr, memcpy_shader_hang,
+ sizeof(memcpy_shader_hang));
+ } else {
+ memcpy(test_priv->shader_dispatch.cs_bo.ptr,
+ shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type].shader,
+ shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type].shader_size);
+ }
+}
+
+static void amdgpu_dispatch_init_gfx9(struct shader_test_priv *test_priv)
+{
+ int i;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ /* Write context control and load shadowing register if necessary */
+ write_context_control(test_priv);
+
+ i = test_priv->cmd_curr;
+
+ /* Issue commands to set default compute state. */
+ /* clear mmCOMPUTE_START_Z - mmCOMPUTE_START_X */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 3);
+ ptr[i++] = 0x204;
+ i += 3;
+
+ /* clear mmCOMPUTE_TMPRING_SIZE */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x218;
+ ptr[i++] = 0;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_dispatch_init_gfx10(struct shader_test_priv *test_priv)
+{
+ int i;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ amdgpu_dispatch_init_gfx9(test_priv);
+
+ i = test_priv->cmd_curr;
+
+ /* mmCOMPUTE_SHADER_CHKSUM */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x22a;
+ ptr[i++] = 0;
+ /* mmCOMPUTE_REQ_CTRL */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 6);
+ ptr[i++] = 0x222;
+ i += 6;
+ /* mmCP_COHER_START_DELAY */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x7b;
+ ptr[i++] = 0x20;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_dispatch_init_gfx11(struct shader_test_priv *test_priv)
+{
+ int i;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ /* Write context control and load shadowing register if necessary */
+ write_context_control(test_priv);
+
+ i = test_priv->cmd_curr;
+
+ /* Issue commands to set default compute state. */
+ /* clear mmCOMPUTE_START_Z - mmCOMPUTE_START_X */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 3);
+ ptr[i++] = 0x204;
+ i += 3;
+
+ /* clear mmCOMPUTE_TMPRING_SIZE */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x218;
+ ptr[i++] = 0;
+
+ /* mmCOMPUTE_REQ_CTRL */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x222;
+ ptr[i++] = 0;
+
+ /* mmCOMPUTE_USER_ACCUM_0 .. 3*/
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x224;
+ i += 4;
+
+ /* mmCOMPUTE_SHADER_CHKSUM */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x22a;
+ ptr[i++] = 0;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_dispatch_init(struct shader_test_priv *test_priv)
+{
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ amdgpu_dispatch_init_gfx9(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ amdgpu_dispatch_init_gfx10(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ amdgpu_dispatch_init_gfx11(test_priv);
+ break;
+ }
+}
+
+static void amdgpu_dispatch_write_cumask(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ /* Issue commands to set cu mask used in current dispatch */
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE1 - mmCOMPUTE_STATIC_THREAD_MGMT_SE0 */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x216;
+ ptr[i++] = 0xffffffff;
+ ptr[i++] = 0xffffffff;
+ /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE3 - mmCOMPUTE_STATIC_THREAD_MGMT_SE2 */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x219;
+ ptr[i++] = 0xffffffff;
+ ptr[i++] = 0xffffffff;
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ case AMDGPU_TEST_GFX_V11:
+ /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE1 - mmCOMPUTE_STATIC_THREAD_MGMT_SE0 */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG_INDEX, 2);
+ ptr[i++] = 0x30000216;
+ ptr[i++] = 0xffffffff;
+ ptr[i++] = 0xffffffff;
+ /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE3 - mmCOMPUTE_STATIC_THREAD_MGMT_SE2 */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG_INDEX, 2);
+ ptr[i++] = 0x30000219;
+ ptr[i++] = 0xffffffff;
+ ptr[i++] = 0xffffffff;
+ break;
+ }
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_dispatch_write2hw_gfx9(struct shader_test_priv *test_priv)
+{
+ const struct shader_test_cs_shader *cs_shader = &shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type];
+ int j, i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ uint64_t shader_addr = test_priv->shader_dispatch.cs_bo.mc_address;
+
+ /* Writes shader state to HW */
+ /* set mmCOMPUTE_PGM_HI - mmCOMPUTE_PGM_LO */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x20c;
+ ptr[i++] = (shader_addr >> 8);
+ ptr[i++] = (shader_addr >> 40);
+ /* write sh regs*/
+ for (j = 0; j < cs_shader->num_sh_reg; j++) {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ /* - Gfx9ShRegBase */
+ ptr[i++] = cs_shader->sh_reg[j].reg_offset - shader_test_gfx_info[test_priv->info->version].sh_reg_base;
+ ptr[i++] = cs_shader->sh_reg[j].reg_value;
+ }
+
+ /* Write constant data */
+ if (CS_BUFFERCLEAR == test_priv->shader_dispatch.cs_type) {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x240;
+ ptr[i++] = test_priv->dst.mc_address;
+ ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000;
+ ptr[i++] = test_priv->dst.size / 16;
+ ptr[i++] = 0x74fac;
+
+ /* Sets a range of pixel shader constants */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x244;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ } else {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x240;
+ ptr[i++] = test_priv->src.mc_address;
+ ptr[i++] = (test_priv->src.mc_address >> 32) | 0x100000;
+ ptr[i++] = test_priv->src.size / 16;
+ ptr[i++] = 0x74fac;
+
+ /* Writes the UAV constant data to the SGPRs. */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x244;
+ ptr[i++] = test_priv->dst.mc_address;
+ ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000;
+ ptr[i++] = test_priv->dst.size / 16;
+ ptr[i++] = 0x74fac;
+ }
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_dispatch_write2hw_gfx10(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ const struct shader_test_cs_shader *cs_shader = &shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type];
+ int j;
+ uint64_t shader_addr = test_priv->shader_dispatch.cs_bo.mc_address;
+
+ /* Writes shader state to HW */
+ /* set mmCOMPUTE_PGM_HI - mmCOMPUTE_PGM_LO */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x20c;
+ ptr[i++] = (shader_addr >> 8);
+ ptr[i++] = (shader_addr >> 40);
+ /* write sh regs*/
+ for (j = 0; j < cs_shader->num_sh_reg; j++) {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ /* - Gfx9ShRegBase */
+ ptr[i++] = cs_shader->sh_reg[j].reg_offset - shader_test_gfx_info[test_priv->info->version].sh_reg_base;
+ ptr[i++] = cs_shader->sh_reg[j].reg_value;
+ }
+
+ /* mmCOMPUTE_PGM_RSRC3 */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x228;
+ ptr[i++] = 0;
+
+ if (CS_BUFFERCLEAR == test_priv->shader_dispatch.cs_type) {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x240;
+ ptr[i++] = test_priv->dst.mc_address;
+ ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000;
+ ptr[i++] = test_priv->dst.size / 16;
+ ptr[i++] = 0x1104bfac;
+
+ /* Sets a range of pixel shader constants */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x244;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ } else {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x240;
+ ptr[i++] = test_priv->src.mc_address;
+ ptr[i++] = (test_priv->src.mc_address >> 32) | 0x100000;
+ ptr[i++] = test_priv->src.size / 16;
+ ptr[i++] = 0x1104bfac;
+
+ /* Writes the UAV constant data to the SGPRs. */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x244;
+ ptr[i++] = test_priv->dst.mc_address;
+ ptr[i++] = (test_priv->dst.mc_address>> 32) | 0x100000;
+ ptr[i++] = test_priv->dst.size / 16;
+ ptr[i++] = 0x1104bfac;
+ }
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_dispatch_write2hw_gfx11(struct shader_test_priv *test_priv)
+{
+ enum amdgpu_test_gfx_version version = test_priv->info->version;
+ const struct shader_test_cs_shader *cs_shader = &shader_test_cs[version][test_priv->shader_dispatch.cs_type];
+ int j, i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ uint64_t shader_addr = test_priv->shader_dispatch.cs_bo.mc_address;
+
+ /* Writes shader state to HW */
+ /* set mmCOMPUTE_PGM_HI - mmCOMPUTE_PGM_LO */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x20c;
+ ptr[i++] = (shader_addr >> 8);
+ ptr[i++] = (shader_addr >> 40);
+
+ /* write sh regs*/
+ for (j = 0; j < cs_shader->num_sh_reg; j++) {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ /* - Gfx9ShRegBase */
+ ptr[i++] = cs_shader->sh_reg[j].reg_offset - shader_test_gfx_info[version].sh_reg_base;
+ ptr[i++] = cs_shader->sh_reg[j].reg_value;
+ if (cs_shader->sh_reg[j].reg_offset == 0x2E12)
+ ptr[i-1] &= ~(1<<29);
+ }
+
+ /* mmCOMPUTE_PGM_RSRC3 */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x228;
+ ptr[i++] = 0x3f0;
+
+ /* Write constant data */
+ /* Writes the texture resource constants data to the SGPRs */
+ if (CS_BUFFERCLEAR == test_priv->shader_dispatch.cs_type) {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x240;
+ ptr[i++] = test_priv->dst.mc_address;
+ ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000;
+ ptr[i++] = test_priv->dst.size / 16;
+ ptr[i++] = 0x1003dfac;
+
+ /* Sets a range of pixel shader constants */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x244;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ ptr[i++] = 0x22222222;
+ } else {
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x240;
+ ptr[i++] = test_priv->src.mc_address;
+ ptr[i++] = (test_priv->src.mc_address >> 32) | 0x100000;
+ ptr[i++] = test_priv->src.size / 16;
+ ptr[i++] = 0x1003dfac;
+
+ /* Writes the UAV constant data to the SGPRs. */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x244;
+ ptr[i++] = test_priv->dst.mc_address;
+ ptr[i++] = (test_priv->dst.mc_address>> 32) | 0x100000;
+ ptr[i++] = test_priv->dst.size / 16;
+ ptr[i++] = 0x1003dfac;
+ }
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_dispatch_write2hw(struct shader_test_priv *test_priv)
+{
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ amdgpu_dispatch_write2hw_gfx9(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ amdgpu_dispatch_write2hw_gfx10(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ amdgpu_dispatch_write2hw_gfx11(test_priv);
+ break;
+ }
+}
+
+static void amdgpu_dispatch_write_dispatch_cmd(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ /* clear mmCOMPUTE_RESOURCE_LIMITS */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x215;
+ ptr[i++] = 0;
+
+ /* dispatch direct command */
+ ptr[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3);
+ ptr[i++] = (test_priv->dst.size / 16 + 0x40 - 1 ) / 0x40;//0x10;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+
+ test_priv->cmd_curr = i;
+}
+static void amdgpu_test_dispatch_memset(struct shader_test_info *test_info)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle resources[3];
+ struct shader_test_priv test_priv;
+ struct shader_test_bo *cmd = &(test_priv.cmd);
+ struct shader_test_bo *dst = &(test_priv.dst);
+ struct shader_test_bo *shader = &(test_priv.shader_dispatch.cs_bo);
+ uint32_t *ptr_cmd;
+ uint8_t *ptr_dst;
+ int i, r;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info= {0};
+ amdgpu_bo_list_handle bo_list;
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ uint8_t cptr[16];
+
+ memset(&test_priv, 0, sizeof(test_priv));
+ test_priv.info = test_info;
+ test_priv.shader_dispatch.cs_type = CS_BUFFERCLEAR;
+ r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ cmd->size = 4096;
+ cmd->heap = AMDGPU_GEM_DOMAIN_GTT;
+ r = shader_test_bo_alloc(test_info->device_handle, cmd);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr_cmd = cmd->ptr;
+ memset(ptr_cmd, 0, cmd->size);
+
+ shader->size = 4096;
+ shader->heap = AMDGPU_GEM_DOMAIN_VRAM;
+ r = shader_test_bo_alloc(test_info->device_handle, shader);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(shader->ptr, 0, shader->size);
+ amdgpu_dispatch_load_cs_shader(&test_priv);
+
+ dst->size = 0x4000;
+ dst->heap = AMDGPU_GEM_DOMAIN_VRAM;
+ r = shader_test_bo_alloc(test_info->device_handle, dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_dispatch_init(&test_priv);
+
+ /* Issue commands to set cu mask used in current dispatch */
+ amdgpu_dispatch_write_cumask(&test_priv);
+
+ /* Writes shader state to HW */
+ amdgpu_dispatch_write2hw(&test_priv);
+
+ amdgpu_dispatch_write_dispatch_cmd(&test_priv);
+
+ i = test_priv.cmd_curr;
+ while (i & 7)
+ ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */
+ test_priv.cmd_curr = i;
+
+ resources[0] = dst->bo;
+ resources[1] = shader->bo;
+ resources[2] = cmd->bo;
+ r = amdgpu_bo_list_create(test_info->device_handle, 3, resources, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ib_info.ib_mc_address = cmd->mc_address;
+ ib_info.size = test_priv.cmd_curr;
+ ibs_request.ip_type = test_info->ip;
+ ibs_request.ring = test_info->ring;
+ ibs_request.resources = bo_list;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ /* submit CS */
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.ip_type = test_info->ip;
+ fence_status.ip_instance = 0;
+ fence_status.ring = test_info->ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request.seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ /* verify if memset test result meets with expected */
+ i = 0;
+ ptr_dst = (uint8_t *)(dst->ptr);
+ memset(cptr, 0x22, 16);
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0);
+ i = dst->size - 16;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0);
+ i = dst->size / 2;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0);
+
+ r = shader_test_bo_free(dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(shader);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(cmd);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static
+void amdgpu_test_dispatch_memcpy(struct shader_test_info *test_info)
+{
+ struct shader_test_priv test_priv;
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle resources[4];
+ struct shader_test_bo *cmd = &(test_priv.cmd);
+ struct shader_test_bo *src = &(test_priv.src);
+ struct shader_test_bo *dst = &(test_priv.dst);
+ struct shader_test_bo *shader = &(test_priv.shader_dispatch.cs_bo);
+ uint32_t *ptr_cmd;
+ uint8_t *ptr_src;
+ uint8_t *ptr_dst;
+ int i, r;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info= {0};
+ uint32_t expired, hang_state, hangs;
+ amdgpu_bo_list_handle bo_list;
+ struct amdgpu_cs_fence fence_status = {0};
+
+ memset(&test_priv, 0, sizeof(test_priv));
+ test_priv.info = test_info;
+ test_priv.cmd.size = 4096;
+ test_priv.cmd.heap = AMDGPU_GEM_DOMAIN_GTT;
+
+ test_priv.shader_dispatch.cs_bo.heap = AMDGPU_GEM_DOMAIN_VRAM;
+ test_priv.shader_dispatch.cs_type = CS_BUFFERCOPY;
+ test_priv.src.heap = AMDGPU_GEM_DOMAIN_VRAM;
+ test_priv.dst.heap = AMDGPU_GEM_DOMAIN_VRAM;
+ if (test_info->hang_slow) {
+ test_priv.shader_dispatch.cs_bo.size = 0x4000000;
+ test_priv.src.size = 0x4000000;
+ test_priv.dst.size = 0x4000000;
+ } else {
+ test_priv.shader_dispatch.cs_bo.size = 4096;
+ test_priv.src.size = 0x4000;
+ test_priv.dst.size = 0x4000;
+ }
+
+ r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_alloc(test_info->device_handle, cmd);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr_cmd = cmd->ptr;
+ memset(ptr_cmd, 0, cmd->size);
+
+ r = shader_test_bo_alloc(test_info->device_handle, shader);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(shader->ptr, 0, shader->size);
+ amdgpu_dispatch_load_cs_shader(&test_priv);
+
+ r = shader_test_bo_alloc(test_info->device_handle, src);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr_src = (uint8_t *)(src->ptr);
+ memset(ptr_src, 0x55, src->size);
+
+ r = shader_test_bo_alloc(test_info->device_handle, dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_dispatch_init(&test_priv);
+
+ /* Issue commands to set cu mask used in current dispatch */
+ amdgpu_dispatch_write_cumask(&test_priv);
+
+ /* Writes shader state to HW */
+ amdgpu_dispatch_write2hw(&test_priv);
+
+ amdgpu_dispatch_write_dispatch_cmd(&test_priv);
+
+ i = test_priv.cmd_curr;
+ while (i & 7)
+ ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */
+ test_priv.cmd_curr = i;
+
+ resources[0] = shader->bo;
+ resources[1] = src->bo;
+ resources[2] = dst->bo;
+ resources[3] = cmd->bo;
+ r = amdgpu_bo_list_create(test_info->device_handle, 4, resources, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ib_info.ib_mc_address = cmd->mc_address;
+ ib_info.size = test_priv.cmd_curr;
+ ibs_request.ip_type = test_info->ip;
+ ibs_request.ring = test_info->ring;
+ ibs_request.resources = bo_list;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.ip_type = test_info->ip;
+ fence_status.ip_instance = 0;
+ fence_status.ring = test_info->ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request.seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+
+ if (!test_info->hang) {
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ /* verify if memcpy test result meets with expected */
+ i = 0;
+ ptr_dst = (uint8_t *)dst->ptr;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0);
+ i = dst->size - 16;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0);
+ i = dst->size / 2;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0);
+ } else {
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
+ }
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(src);
+ CU_ASSERT_EQUAL(r, 0);
+ r = shader_test_bo_free(dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(shader);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(cmd);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void shader_test_dispatch_cb(struct shader_test_info *test_info)
+{
+ amdgpu_test_dispatch_memset(test_info);
+ amdgpu_test_dispatch_memcpy(test_info);
+}
+static void shader_test_dispatch_hang_cb(struct shader_test_info *test_info)
+{
+ test_info->hang = 0;
+ amdgpu_test_dispatch_memcpy(test_info);
+
+ test_info->hang = 1;
+ amdgpu_test_dispatch_memcpy(test_info);
+
+ test_info->hang = 0;
+ amdgpu_test_dispatch_memcpy(test_info);
+}
+
+static void shader_test_dispatch_hang_slow_cb(struct shader_test_info *test_info)
+{
+ test_info->hang = 0;
+ test_info->hang_slow = 0;
+ amdgpu_test_dispatch_memcpy(test_info);
+
+ test_info->hang = 1;
+ test_info->hang_slow = 1;
+ amdgpu_test_dispatch_memcpy(test_info);
+
+ test_info->hang = 0;
+ test_info->hang_slow = 0;
+ amdgpu_test_dispatch_memcpy(test_info);
+}
+
+void amdgpu_test_dispatch_helper(amdgpu_device_handle device_handle, unsigned ip)
+{
+ shader_test_for_each(device_handle, ip, shader_test_dispatch_cb);
+}
+
+void amdgpu_test_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip)
+{
+ shader_test_for_each(device_handle, ip, shader_test_dispatch_hang_cb);
+}
+
+void amdgpu_test_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip)
+{
+ shader_test_for_each(device_handle, ip, shader_test_dispatch_hang_slow_cb);
+}
+
+static void amdgpu_draw_load_ps_shader_hang_slow(struct shader_test_priv *test_priv)
+{
+ struct amdgpu_gpu_info gpu_info = {0};
+ struct shader_test_shader_bin *ps_shader_bin = &memcpy_ps_hang_slow_navi21;
+ int r;
+
+ r = amdgpu_query_gpu_info(test_priv->info->device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ switch (gpu_info.family_id) {
+ case AMDGPU_FAMILY_AI:
+ case AMDGPU_FAMILY_RV:
+ ps_shader_bin = &memcpy_ps_hang_slow_ai;
+ break;
+ case AMDGPU_FAMILY_NV:
+ if (gpu_info.chip_external_rev < 40)
+ ps_shader_bin = &memcpy_ps_hang_slow_navi10;
+ break;
+ }
+
+ shader_test_load_shader_hang_slow(&test_priv->shader_draw.ps_bo, ps_shader_bin);
+}
+
+static uint32_t round_up_size(uint32_t size)
+{
+ return (size + 255) & ~255;
+}
+static void amdgpu_draw_load_ps_shader(struct shader_test_priv *test_priv)
+{
+ uint8_t *ptr_shader = test_priv->shader_draw.ps_bo.ptr;
+ const struct shader_test_ps_shader *shader;
+ uint32_t shader_offset, num_export_fmt;
+ uint32_t mem_offset, patch_code_offset;
+ int i;
+
+ if (test_priv->info->hang) {
+ if (test_priv->info->hang_slow)
+ amdgpu_draw_load_ps_shader_hang_slow(test_priv);
+ else
+ memcpy(ptr_shader, memcpy_shader_hang, sizeof(memcpy_shader_hang));
+
+ return;
+ }
+
+ shader = &shader_test_ps[test_priv->info->version][test_priv->shader_draw.ps_type];
+ num_export_fmt = 10;
+ shader_offset = round_up_size(shader->shader_size);
+ /* write main shader program */
+ for (i = 0 ; i < num_export_fmt; i++) {
+ mem_offset = i * shader_offset;
+ memcpy(ptr_shader + mem_offset, shader->shader, shader->shader_size);
+ }
+
+ /* overwrite patch codes */
+ for (i = 0 ; i < num_export_fmt; i++) {
+ mem_offset = i * shader_offset + shader->patchinfo_code_offset[0] * sizeof(uint32_t);
+ patch_code_offset = i * shader->patchinfo_code_size;
+ memcpy(ptr_shader + mem_offset,
+ shader->patchinfo_code + patch_code_offset,
+ shader->patchinfo_code_size * sizeof(uint32_t));
+ }
+}
+
+/* load RectPosTexFast_VS */
+static void amdgpu_draw_load_vs_shader(struct shader_test_priv *test_priv)
+{
+ uint8_t *ptr_shader = test_priv->shader_draw.vs_bo.ptr;
+ const struct shader_test_vs_shader *shader = &shader_test_vs[test_priv->info->version][test_priv->shader_draw.vs_type];
+
+ memcpy(ptr_shader, shader->shader, shader->shader_size);
+}
+
+static void amdgpu_draw_init(struct shader_test_priv *test_priv)
+{
+ int i;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version];
+
+ /* Write context control and load shadowing register if necessary */
+ write_context_control(test_priv);
+ i = test_priv->cmd_curr;
+
+ if (test_priv->info->version == AMDGPU_TEST_GFX_V11) {
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x446;
+ ptr[i++] = (test_priv->vtx_attributes_mem.mc_address >> 16);
+ // mmSPI_ATTRIBUTE_RING_SIZE
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x447;
+ ptr[i++] = 0x20001;
+ }
+ memcpy(ptr + i, gfx_info->preamble_cache, gfx_info->size_preamble_cache);
+
+ test_priv->cmd_curr = i + gfx_info->size_preamble_cache/sizeof(uint32_t);
+}
+
+static void amdgpu_draw_setup_and_write_drawblt_surf_info_gfx9(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ /* setup color buffer */
+ /* offset reg
+ 0xA318 CB_COLOR0_BASE
+ 0xA319 CB_COLOR0_BASE_EXT
+ 0xA31A CB_COLOR0_ATTRIB2
+ 0xA31B CB_COLOR0_VIEW
+ 0xA31C CB_COLOR0_INFO
+ 0xA31D CB_COLOR0_ATTRIB
+ 0xA31E CB_COLOR0_DCC_CONTROL
+ 0xA31F CB_COLOR0_CMASK
+ 0xA320 CB_COLOR0_CMASK_BASE_EXT
+ 0xA321 CB_COLOR0_FMASK
+ 0xA322 CB_COLOR0_FMASK_BASE_EXT
+ 0xA323 CB_COLOR0_CLEAR_WORD0
+ 0xA324 CB_COLOR0_CLEAR_WORD1
+ 0xA325 CB_COLOR0_DCC_BASE
+ 0xA326 CB_COLOR0_DCC_BASE_EXT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 15);
+ ptr[i++] = 0x318;
+ ptr[i++] = test_priv->dst.mc_address >> 8;
+ ptr[i++] = test_priv->dst.mc_address >> 40;
+ ptr[i++] = test_priv->info->hang_slow ? 0x3ffc7ff : 0x7c01f;
+ ptr[i++] = 0;
+ ptr[i++] = 0x50438;
+ ptr[i++] = 0x10140000;
+ i += 9;
+
+ /* mmCB_MRT0_EPITCH */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1e8;
+ ptr[i++] = test_priv->info->hang_slow ? 0xfff : 0x1f;
+
+ /* 0xA32B CB_COLOR1_BASE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x32b;
+ ptr[i++] = 0;
+
+ /* 0xA33A CB_COLOR1_BASE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x33a;
+ ptr[i++] = 0;
+
+ /* SPI_SHADER_COL_FORMAT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1c5;
+ ptr[i++] = 9;
+
+ /* Setup depth buffer */
+ /* mmDB_Z_INFO */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2);
+ ptr[i++] = 0xe;
+ i += 2;
+
+ test_priv->cmd_curr = i;
+}
+static void amdgpu_draw_setup_and_write_drawblt_surf_info_gfx10(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ /* setup color buffer */
+ /* 0xA318 CB_COLOR0_BASE
+ 0xA319 CB_COLOR0_PITCH
+ 0xA31A CB_COLOR0_SLICE
+ 0xA31B CB_COLOR0_VIEW
+ 0xA31C CB_COLOR0_INFO
+ 0xA31D CB_COLOR0_ATTRIB
+ 0xA31E CB_COLOR0_DCC_CONTROL
+ 0xA31F CB_COLOR0_CMASK
+ 0xA320 CB_COLOR0_CMASK_SLICE
+ 0xA321 CB_COLOR0_FMASK
+ 0xA322 CB_COLOR0_FMASK_SLICE
+ 0xA323 CB_COLOR0_CLEAR_WORD0
+ 0xA324 CB_COLOR0_CLEAR_WORD1
+ 0xA325 CB_COLOR0_DCC_BASE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 14);
+ ptr[i++] = 0x318;
+ ptr[i++] = test_priv->dst.mc_address >> 8;
+ i += 3;
+ ptr[i++] = 0x50438;
+ i += 9;
+
+ /* 0xA390 CB_COLOR0_BASE_EXT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x390;
+ ptr[i++] = test_priv->dst.mc_address >> 40;
+
+ /* 0xA398 CB_COLOR0_CMASK_BASE_EXT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x398;
+ ptr[i++] = 0;
+
+ /* 0xA3A0 CB_COLOR0_FMASK_BASE_EXT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x3a0;
+ ptr[i++] = 0;
+
+ /* 0xA3A8 CB_COLOR0_DCC_BASE_EXT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x3a8;
+ ptr[i++] = 0;
+
+ /* 0xA3B0 CB_COLOR0_ATTRIB2 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x3b0;
+ ptr[i++] = test_priv->info->hang_slow ? 0x3ffc7ff : 0x7c01f;
+
+ /* 0xA3B8 CB_COLOR0_ATTRIB3 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x3b8;
+ ptr[i++] = 0x9014000;
+
+ /* 0xA32B CB_COLOR1_BASE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x32b;
+ ptr[i++] = 0;
+
+ /* 0xA33A CB_COLOR1_BASE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x33a;
+ ptr[i++] = 0;
+
+ /* SPI_SHADER_COL_FORMAT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1c5;
+ ptr[i++] = 9;
+
+ /* Setup depth buffer */
+ /* mmDB_Z_INFO */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2);
+ ptr[i++] = 0x10;
+ i += 2;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_draw_setup_and_write_drawblt_surf_info_gfx11(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ /* mmCB_COLOR0_BASE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x318;
+ ptr[i++] = test_priv->dst.mc_address >> 8;
+ /* mmCB_COLOR0_VIEW .. mmCB_COLOR0_DCC_CONTROL */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 4);
+ ptr[i++] = 0x31b;
+ i++;
+ ptr[i++] = 0x5040e;
+ i += 2;
+ /* mmCB_COLOR0_DCC_BASE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x325;
+ ptr[i++] = 0;
+ /* mmCB_COLOR0_BASE_EXT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x390;
+ ptr[i++] = (test_priv->dst.mc_address >> 40) & 0xFF;
+ /* mmCB_COLOR0_DCC_BASE_EXT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x3a8;
+ ptr[i++] = 0;
+ /* mmCB_COLOR0_ATTRIB2 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x3b0;
+ ptr[i++] = test_priv->info->hang_slow ? 0x1ffc7ff : 0x7c01f;
+ /* mmCB_COLOR0_ATTRIB3 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x3b8;
+ ptr[i++] = test_priv->info->hang_slow ? 0x1028000 : 0x1018000;
+ /* mmCB_COLOR0_INFO */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x32b;
+ ptr[i++] = 0;
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x33a;
+ ptr[i++] = 0;
+ /* mmSPI_SHADER_COL_FORMAT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1c5;
+ ptr[i++] = 0x9;
+ /* mmDB_Z_INFO */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2);
+ ptr[i++] = 0x10;
+ i += 2;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_draw_setup_and_write_drawblt_surf_info(struct shader_test_priv *test_priv)
+{
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ amdgpu_draw_setup_and_write_drawblt_surf_info_gfx9(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ amdgpu_draw_setup_and_write_drawblt_surf_info_gfx10(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ amdgpu_draw_setup_and_write_drawblt_surf_info_gfx11(test_priv);
+ break;
+ }
+}
+
+static void amdgpu_draw_setup_and_write_drawblt_state_gfx9(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version];
+
+ /* mmPA_SC_TILE_STEERING_OVERRIDE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0xd7;
+ ptr[i++] = 0;
+
+ ptr[i++] = 0xffff1000;
+ ptr[i++] = 0xc0021000;
+
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0xd7;
+ ptr[i++] = 1;
+
+ /* mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 16);
+ ptr[i++] = 0x2fe;
+ i += 16;
+
+ /* mmPA_SC_CENTROID_PRIORITY_0 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2);
+ ptr[i++] = 0x2f5;
+ i += 2;
+
+ memcpy(ptr + i, gfx_info->cached_cmd, gfx_info->size_cached_cmd);
+ if (test_priv->info->hang_slow)
+ *(ptr + i + 12) = 0x8000800;
+
+ test_priv->cmd_curr = i + gfx_info->size_cached_cmd/sizeof(uint32_t);
+}
+
+static void amdgpu_draw_setup_and_write_drawblt_state_gfx10(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version];
+
+ /* mmPA_SC_TILE_STEERING_OVERRIDE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0xd7;
+ ptr[i++] = 0;
+
+ ptr[i++] = 0xffff1000;
+ ptr[i++] = 0xc0021000;
+
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0xd7;
+ ptr[i++] = 0;
+
+ /* mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 16);
+ ptr[i++] = 0x2fe;
+ i += 16;
+
+ /* mmPA_SC_CENTROID_PRIORITY_0 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2);
+ ptr[i++] = 0x2f5;
+ i += 2;
+
+ memcpy(ptr + i, gfx_info->cached_cmd, gfx_info->size_cached_cmd);
+ if (test_priv->info->hang_slow)
+ *(ptr + i + 12) = 0x8000800;
+ i += gfx_info->size_cached_cmd/sizeof(uint32_t);
+
+ /* mmCB_RMI_GL2_CACHE_CONTROL */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x104;
+ ptr[i++] = 0x40aa0055;
+ /* mmDB_RMI_L2_CACHE_CONTROL */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1f;
+ ptr[i++] = 0x2a0055;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_draw_setup_and_write_drawblt_state_gfx11(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version];
+
+ /* mmPA_SC_TILE_STEERING_OVERRIDE */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0xd7;
+ ptr[i++] = 0;
+
+ ptr[i++] = 0xffff1000;
+ ptr[i++] = 0xc0021000;
+
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0xd7;
+ i++;
+
+ /* mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 16);
+ ptr[i++] = 0x2fe;
+ i += 16;
+
+ /* mmPA_SC_CENTROID_PRIORITY_0 */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2);
+ ptr[i++] = 0x2f5;
+ i += 2;
+
+ memcpy(ptr + i, gfx_info->cached_cmd, gfx_info->size_cached_cmd);
+ if (test_priv->info->hang_slow)
+ *(ptr + i + 12) = 0x8000800;
+
+ test_priv->cmd_curr = i + gfx_info->size_cached_cmd/sizeof(uint32_t);
+}
+
+static void amdgpu_draw_setup_and_write_drawblt_state(struct shader_test_priv *test_priv)
+{
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ amdgpu_draw_setup_and_write_drawblt_state_gfx9(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ amdgpu_draw_setup_and_write_drawblt_state_gfx10(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ amdgpu_draw_setup_and_write_drawblt_state_gfx11(test_priv);
+ break;
+ }
+}
+
+static void amdgpu_draw_vs_RectPosTexFast_write2hw_gfx9(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ uint64_t shader_addr = test_priv->shader_draw.vs_bo.mc_address;
+ enum ps_type ps = test_priv->shader_draw.ps_type;
+
+ /* mmPA_CL_VS_OUT_CNTL */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x207;
+ ptr[i++] = 0;
+
+ /* mmSPI_SHADER_PGM_RSRC3_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x46;
+ ptr[i++] = 0xffff;
+
+ /* mmSPI_SHADER_PGM_LO_VS...mmSPI_SHADER_PGM_HI_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x48;
+ ptr[i++] = shader_addr >> 8;
+ ptr[i++] = shader_addr >> 40;
+
+ /* mmSPI_SHADER_PGM_RSRC1_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x4a;
+ ptr[i++] = 0xc0081;
+
+ /* mmSPI_SHADER_PGM_RSRC2_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x4b;
+ ptr[i++] = 0x18;
+
+ /* mmSPI_VS_OUT_CONFIG */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1b1;
+ ptr[i++] = 2;
+
+ /* mmSPI_SHADER_POS_FORMAT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1c3;
+ ptr[i++] = 4;
+
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x4c;
+ i += 2;
+ ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000;
+ ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000;
+
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x50;
+ i += 2;
+ if (ps == PS_CONST) {
+ i += 2;
+ } else if (ps == PS_TEX) {
+ ptr[i++] = 0x3f800000;
+ ptr[i++] = 0x3f800000;
+ }
+
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x54;
+ i += 4;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_draw_vs_RectPosTexFast_write2hw_gfx10(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ uint64_t shader_addr = test_priv->shader_draw.vs_bo.mc_address;
+ enum ps_type ps = test_priv->shader_draw.ps_type;
+
+ /* mmPA_CL_VS_OUT_CNTL */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x207;
+ ptr[i++] = 0;
+
+ /* mmSPI_SHADER_PGM_RSRC3_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000046;
+ ptr[i++] = 0xffff;
+ /* mmSPI_SHADER_PGM_RSRC4_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000041;
+ ptr[i++] = 0xffff;
+
+ /* mmSPI_SHADER_PGM_LO_VS...mmSPI_SHADER_PGM_HI_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x48;
+ ptr[i++] = shader_addr >> 8;
+ ptr[i++] = shader_addr >> 40;
+
+ /* mmSPI_SHADER_PGM_RSRC1_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x4a;
+ ptr[i++] = 0xc0041;
+ /* mmSPI_SHADER_PGM_RSRC2_VS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = 0x4b;
+ ptr[i++] = 0x18;
+
+ /* mmSPI_VS_OUT_CONFIG */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1b1;
+ ptr[i++] = 2;
+
+ /* mmSPI_SHADER_POS_FORMAT */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1c3;
+ ptr[i++] = 4;
+
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x4c;
+ i += 2;
+ ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000;
+ ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000;
+
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x50;
+ i += 2;
+ if (ps == PS_CONST) {
+ i += 2;
+ } else if (ps == PS_TEX) {
+ ptr[i++] = 0x3f800000;
+ ptr[i++] = 0x3f800000;
+ }
+
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x54;
+ i += 4;
+
+ test_priv->cmd_curr = i;
+}
+
+
+static void amdgpu_draw_vs_RectPosTexFast_write2hw_gfx11(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+ const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version];
+ uint64_t shader_addr = test_priv->shader_draw.vs_bo.mc_address;
+ const struct shader_test_vs_shader *shader = &shader_test_vs[test_priv->info->version][test_priv->shader_draw.vs_type];
+ enum ps_type ps = test_priv->shader_draw.ps_type;
+ int j, offset;
+
+ /* mmPA_CL_VS_OUT_CNTL */
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x207;
+ ptr[i++] = 0;
+
+ /* mmSPI_SHADER_PGM_RSRC3_GS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000087;
+ ptr[i++] = 0xffff;
+ /* mmSPI_SHADER_PGM_RSRC4_GS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000081;
+ ptr[i++] = 0x1fff0001;
+
+ /* mmSPI_SHADER_PGM_LO_ES */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0xc8;
+ ptr[i++] = shader_addr >> 8;
+ ptr[i++] = shader_addr >> 40;
+
+ /* write sh reg */
+ for (j = 0; j < shader->num_sh_reg; j++) {
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = shader->sh_reg[j].reg_offset - gfx_info->sh_reg_base;
+ ptr[i++] = shader->sh_reg[j].reg_value;
+ }
+ /* write context reg */
+ for (j = 0; j < shader->num_context_reg; j++) {
+ switch (shader->context_reg[j].reg_offset) {
+ case 0xA1B1: //mmSPI_VS_OUT_CONFIG
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = shader->context_reg[j].reg_offset - gfx_info->context_reg_base;
+ ptr[i++] = 2;
+ break;
+ case 0xA1C3: //mmSPI_SHADER_POS_FORMAT
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = shader->context_reg[j].reg_offset - gfx_info->context_reg_base;
+ ptr[i++] = 4;
+ break;
+ case 0xA2E4: //mmVGT_GS_INSTANCE_CNT
+ case 0xA2CE: //mmVGT_GS_MAX_VERT_OUT
+ break;
+ default:
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = shader->context_reg[j].reg_offset - gfx_info->context_reg_base;
+ ptr[i++] = shader->context_reg[j].reg_value;
+ break;
+ }
+ }
+
+ // write constant
+ // dst rect
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x8c;
+ i += 2;
+ ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000;
+ ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000;
+ // src rect
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x90;
+ i += 2;
+ if (ps == PS_CONST) {
+ i += 2;
+ } else if (ps == PS_TEX) {
+ ptr[i++] = 0x3f800000;
+ ptr[i++] = 0x3f800000;
+ }
+
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr[i++] = 0x94;
+ i += 4;
+ // vtx_attributes_mem
+ ptr[i++] = 0xc02f1000;
+ offset = i * sizeof(uint32_t);
+ i += 44;
+ ptr[i++] = test_priv->vtx_attributes_mem.mc_address & 0xffffffff;
+ ptr[i++] = 0xc0100000 | ((test_priv->vtx_attributes_mem.mc_address >> 32) & 0xffff);
+ ptr[i++] = test_priv->vtx_attributes_mem.size / 16;
+ ptr[i++] = 0x2043ffac;
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_OFFSET, 2);
+ ptr[i++] = 0x98;
+ ptr[i++] = offset;
+ i++;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_draw_vs_RectPosTexFast_write2hw(struct shader_test_priv *test_priv)
+{
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ amdgpu_draw_vs_RectPosTexFast_write2hw_gfx9(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ amdgpu_draw_vs_RectPosTexFast_write2hw_gfx10(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ amdgpu_draw_vs_RectPosTexFast_write2hw_gfx11(test_priv);
+ break;
+ }
+}
+
+static void amdgpu_draw_ps_write2hw_gfx9_10(struct shader_test_priv *test_priv)
+{
+ int i, j;
+ uint64_t shader_addr = test_priv->shader_draw.ps_bo.mc_address;
+ const struct shader_test_ps_shader *ps = &shader_test_ps[test_priv->info->version][test_priv->shader_draw.ps_type];
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ i = test_priv->cmd_curr;
+
+ if (test_priv->info->version == AMDGPU_TEST_GFX_V9) {
+ /* 0x2c07 SPI_SHADER_PGM_RSRC3_PS
+ 0x2c08 SPI_SHADER_PGM_LO_PS
+ 0x2c09 SPI_SHADER_PGM_HI_PS */
+ /* multiplicator 9 is from SPI_SHADER_COL_FORMAT */
+ if (!test_priv->info->hang)
+ shader_addr += 256 * 9;
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 3);
+ ptr[i++] = 0x7;
+ ptr[i++] = 0xffff;
+ ptr[i++] = shader_addr >> 8;
+ ptr[i++] = shader_addr >> 40;
+ } else {
+ //if (!test_priv->info->hang)
+ shader_addr += 256 * 9;
+ /* 0x2c08 SPI_SHADER_PGM_LO_PS
+ 0x2c09 SPI_SHADER_PGM_HI_PS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x8;
+ ptr[i++] = shader_addr >> 8;
+ ptr[i++] = shader_addr >> 40;
+
+ /* mmSPI_SHADER_PGM_RSRC3_PS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000007;
+ ptr[i++] = 0xffff;
+ /* mmSPI_SHADER_PGM_RSRC4_PS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000001;
+ ptr[i++] = 0xffff;
+ }
+
+ for (j = 0; j < ps->num_sh_reg; j++) {
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = ps->sh_reg[j].reg_offset - 0x2c00;
+ ptr[i++] = ps->sh_reg[j].reg_value;
+ }
+
+ for (j = 0; j < ps->num_context_reg; j++) {
+ if (ps->context_reg[j].reg_offset != 0xA1C5) {
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = ps->context_reg[j].reg_offset - 0xa000;
+ ptr[i++] = ps->context_reg[j].reg_value;
+ }
+
+ if (ps->context_reg[j].reg_offset == 0xA1B4) {
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1b3;
+ ptr[i++] = 2;
+ }
+ }
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_draw_ps_write2hw_gfx11(struct shader_test_priv *test_priv)
+{
+ int i, j;
+ uint64_t shader_addr = test_priv->shader_draw.ps_bo.mc_address;
+ enum amdgpu_test_gfx_version version = test_priv->info->version;
+ const struct shader_test_ps_shader *ps = &shader_test_ps[version][test_priv->shader_draw.ps_type];
+ uint32_t *ptr = test_priv->cmd.ptr;
+ uint32_t export_shader_offset;
+
+ i = test_priv->cmd_curr;
+
+ /* SPI_SHADER_PGM_LO_PS
+ SPI_SHADER_PGM_HI_PS */
+ shader_addr >>= 8;
+ if (!test_priv->info->hang) {
+ export_shader_offset = (round_up_size(ps->shader_size) * 9) >> 8;
+ shader_addr += export_shader_offset;
+ }
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2);
+ ptr[i++] = 0x8;
+ ptr[i++] = shader_addr & 0xffffffff;
+ ptr[i++] = (shader_addr >> 32) & 0xffffffff;
+ /* mmSPI_SHADER_PGM_RSRC3_PS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000007;
+ ptr[i++] = 0xffff;
+ /* mmSPI_SHADER_PGM_RSRC4_PS */
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1);
+ ptr[i++] = 0x30000001;
+ ptr[i++] = 0x3fffff;
+
+ for (j = 0; j < ps->num_sh_reg; j++) {
+ ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1);
+ ptr[i++] = ps->sh_reg[j].reg_offset - shader_test_gfx_info[version].sh_reg_base;
+ ptr[i++] = ps->sh_reg[j].reg_value;
+ }
+
+ for (j = 0; j < ps->num_context_reg; j++) {
+ /* !mmSPI_SHADER_COL_FORMAT */
+ if (ps->context_reg[j].reg_offset != 0xA1C5) {
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = ps->context_reg[j].reg_offset - shader_test_gfx_info[version].context_reg_base;
+ ptr[i++] = ps->context_reg[j].reg_value;
+ }
+
+ /* mmSPI_PS_INPUT_ADDR */
+ if (ps->context_reg[j].reg_offset == 0xA1B4) {
+ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr[i++] = 0x1b3;
+ ptr[i++] = 2;
+ }
+ }
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_draw_ps_write2hw(struct shader_test_priv *test_priv)
+{
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ case AMDGPU_TEST_GFX_V10:
+ amdgpu_draw_ps_write2hw_gfx9_10(test_priv);
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ amdgpu_draw_ps_write2hw_gfx11(test_priv);
+ break;
+ }
+}
+
+static void amdgpu_draw_draw(struct shader_test_priv *test_priv)
+{
+ int i = test_priv->cmd_curr;
+ uint32_t *ptr = test_priv->cmd.ptr;
+
+ switch (test_priv->info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ /* mmIA_MULTI_VGT_PARAM */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x40000258;
+ ptr[i++] = 0xd00ff;
+ /* mmVGT_PRIMITIVE_TYPE */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x10000242;
+ ptr[i++] = 0x11;
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ /* mmGE_CNTL */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x25b;
+ ptr[i++] = 0xff;
+ /* mmVGT_PRIMITIVE_TYPE */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x242;
+ ptr[i++] = 0x11;
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ /* mmGE_CNTL */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x25b;
+ ptr[i++] = 0x80fc80;
+ /* mmVGT_PRIMITIVE_TYPE */
+ ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+ ptr[i++] = 0x242;
+ ptr[i++] = 0x11;
+ break;
+ }
+
+ ptr[i++] = PACKET3(PACKET3_DRAW_INDEX_AUTO, 1);
+ ptr[i++] = 3;
+ ptr[i++] = 2;
+
+ test_priv->cmd_curr = i;
+}
+
+static void amdgpu_memset_draw_test(struct shader_test_info *test_info)
+{
+ struct shader_test_priv test_priv;
+ amdgpu_context_handle context_handle;
+ struct shader_test_bo *ps_bo = &(test_priv.shader_draw.ps_bo);
+ struct shader_test_bo *vs_bo = &(test_priv.shader_draw.vs_bo);
+ struct shader_test_bo *dst = &(test_priv.dst);
+ struct shader_test_bo *cmd = &(test_priv.cmd);
+ struct shader_test_bo *vtx_attributes_mem = &(test_priv.vtx_attributes_mem);
+ amdgpu_bo_handle resources[5];
+ uint8_t *ptr_dst;
+ uint32_t *ptr_cmd;
+ int i, r;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ uint8_t cptr[16];
+
+ memset(&test_priv, 0, sizeof(test_priv));
+ test_priv.info = test_info;
+
+ r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ps_bo->size = 0x2000;
+ ps_bo->heap = AMDGPU_GEM_DOMAIN_VRAM;
+ r = shader_test_bo_alloc(test_info->device_handle, ps_bo);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(ps_bo->ptr, 0, ps_bo->size);
+
+ vs_bo->size = 4096;
+ vs_bo->heap = AMDGPU_GEM_DOMAIN_VRAM;
+ r = shader_test_bo_alloc(test_info->device_handle, vs_bo);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vs_bo->ptr, 0, vs_bo->size);
+
+ test_priv.shader_draw.ps_type = PS_CONST;
+ amdgpu_draw_load_ps_shader(&test_priv);
+
+ test_priv.shader_draw.vs_type = VS_RECTPOSTEXFAST;
+ amdgpu_draw_load_vs_shader(&test_priv);
+
+ cmd->size = 4096;
+ cmd->heap = AMDGPU_GEM_DOMAIN_GTT;
+ r = shader_test_bo_alloc(test_info->device_handle, cmd);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr_cmd = cmd->ptr;
+ memset(ptr_cmd, 0, cmd->size);
+
+ dst->size = 0x4000;
+ dst->heap = AMDGPU_GEM_DOMAIN_VRAM;
+ r = shader_test_bo_alloc(test_info->device_handle, dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (test_info->version == AMDGPU_TEST_GFX_V11) {
+ vtx_attributes_mem->size = 0x4040000;
+ vtx_attributes_mem->heap = AMDGPU_GEM_DOMAIN_VRAM;
+
+ r = shader_test_bo_alloc(test_info->device_handle, vtx_attributes_mem);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ amdgpu_draw_init(&test_priv);
+
+ amdgpu_draw_setup_and_write_drawblt_surf_info(&test_priv);
+
+ amdgpu_draw_setup_and_write_drawblt_state(&test_priv);
+
+ amdgpu_draw_vs_RectPosTexFast_write2hw(&test_priv);
+
+ amdgpu_draw_ps_write2hw(&test_priv);
+
+ i = test_priv.cmd_curr;
+ /* ps constant data */
+ ptr_cmd[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr_cmd[i++] = 0xc;
+ ptr_cmd[i++] = 0x33333333;
+ ptr_cmd[i++] = 0x33333333;
+ ptr_cmd[i++] = 0x33333333;
+ ptr_cmd[i++] = 0x33333333;
+ test_priv.cmd_curr = i;
+
+ amdgpu_draw_draw(&test_priv);
+
+ i = test_priv.cmd_curr;
+ while (i & 7)
+ ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */
+ test_priv.cmd_curr = i;
+
+ i = 0;
+ resources[i++] = dst->bo;
+ resources[i++] = ps_bo->bo;
+ resources[i++] = vs_bo->bo;
+ resources[i++] = cmd->bo;
+ if (vtx_attributes_mem->size)
+ resources[i++] = vtx_attributes_mem->bo;
+ r = amdgpu_bo_list_create(test_info->device_handle, i, resources, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ib_info.ib_mc_address = cmd->mc_address;
+ ib_info.size = test_priv.cmd_curr;
+ ibs_request.ip_type = test_info->ip;
+ ibs_request.ring = test_info->ring;
+ ibs_request.resources = bo_list;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ /* submit CS */
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.ip_type = test_info->ip;
+ fence_status.ip_instance = 0;
+ fence_status.ring = test_info->ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request.seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ /* verify if memset test result meets with expected */
+ i = 0;
+ ptr_dst = dst->ptr;
+ memset(cptr, 0x33, 16);
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0);
+ i = dst->size - 16;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0);
+ i = dst->size / 2;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0);
+
+ if (vtx_attributes_mem->size) {
+ r = shader_test_bo_free(vtx_attributes_mem);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ r = shader_test_bo_free(dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(cmd);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(ps_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(vs_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_memcpy_draw_test(struct shader_test_info *test_info)
+{
+ struct shader_test_priv test_priv;
+ amdgpu_context_handle context_handle;
+ struct shader_test_bo *ps_bo = &(test_priv.shader_draw.ps_bo);
+ struct shader_test_bo *vs_bo = &(test_priv.shader_draw.vs_bo);
+ struct shader_test_bo *src = &(test_priv.src);
+ struct shader_test_bo *dst = &(test_priv.dst);
+ struct shader_test_bo *cmd = &(test_priv.cmd);
+ struct shader_test_bo *vtx_attributes_mem = &(test_priv.vtx_attributes_mem);
+ amdgpu_bo_handle resources[6];
+ uint8_t *ptr_dst;
+ uint8_t *ptr_src;
+ uint32_t *ptr_cmd;
+ int i, r;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ uint32_t hang_state, hangs;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ struct amdgpu_cs_fence fence_status = {0};
+
+ memset(&test_priv, 0, sizeof(test_priv));
+ test_priv.info = test_info;
+ test_priv.cmd.size = 4096;
+ test_priv.cmd.heap = AMDGPU_GEM_DOMAIN_GTT;
+
+ ps_bo->heap = AMDGPU_GEM_DOMAIN_VRAM;
+ test_priv.shader_draw.ps_type = PS_TEX;
+ vs_bo->size = 4096;
+ vs_bo->heap = AMDGPU_GEM_DOMAIN_VRAM;
+ test_priv.shader_draw.vs_type = VS_RECTPOSTEXFAST;
+ test_priv.src.heap = AMDGPU_GEM_DOMAIN_VRAM;
+ test_priv.dst.heap = AMDGPU_GEM_DOMAIN_VRAM;
+ if (test_info->hang_slow) {
+ test_priv.shader_draw.ps_bo.size = 16*1024*1024;
+ test_priv.src.size = 0x4000000;
+ test_priv.dst.size = 0x4000000;
+ } else {
+ test_priv.shader_draw.ps_bo.size = 0x2000;
+ test_priv.src.size = 0x4000;
+ test_priv.dst.size = 0x4000;
+ }
+
+ r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_alloc(test_info->device_handle, ps_bo);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(ps_bo->ptr, 0, ps_bo->size);
+
+ r = shader_test_bo_alloc(test_info->device_handle, vs_bo);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vs_bo->ptr, 0, vs_bo->size);
+
+ amdgpu_draw_load_ps_shader(&test_priv);
+ amdgpu_draw_load_vs_shader(&test_priv);
+
+ r = shader_test_bo_alloc(test_info->device_handle, cmd);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr_cmd = cmd->ptr;
+ memset(ptr_cmd, 0, cmd->size);
+
+ r = shader_test_bo_alloc(test_info->device_handle, src);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr_src = src->ptr;
+ memset(ptr_src, 0x55, src->size);
+
+ r = shader_test_bo_alloc(test_info->device_handle, dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (test_info->version == AMDGPU_TEST_GFX_V11) {
+ vtx_attributes_mem->size = 0x4040000;
+ vtx_attributes_mem->heap = AMDGPU_GEM_DOMAIN_VRAM;
+
+ r = shader_test_bo_alloc(test_info->device_handle, vtx_attributes_mem);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ amdgpu_draw_init(&test_priv);
+
+ amdgpu_draw_setup_and_write_drawblt_surf_info(&test_priv);
+
+ amdgpu_draw_setup_and_write_drawblt_state(&test_priv);
+
+ amdgpu_draw_vs_RectPosTexFast_write2hw(&test_priv);
+
+ amdgpu_draw_ps_write2hw(&test_priv);
+
+ // write ps user constant data
+ i = test_priv.cmd_curr;
+ ptr_cmd[i++] = PACKET3(PACKET3_SET_SH_REG, 8);
+ switch (test_info->version) {
+ case AMDGPU_TEST_GFX_V9:
+ ptr_cmd[i++] = 0xc;
+ ptr_cmd[i++] = src->mc_address >> 8;
+ ptr_cmd[i++] = src->mc_address >> 40 | 0x10e00000;
+ ptr_cmd[i++] = test_info->hang_slow ? 0x1ffcfff : 0x7c01f;
+ ptr_cmd[i++] = 0x90500fac;
+ ptr_cmd[i++] = test_info->hang_slow ? 0x1ffe000 : 0x3e000;
+ i += 3;
+ break;
+ case AMDGPU_TEST_GFX_V10:
+ ptr_cmd[i++] = 0xc;
+ ptr_cmd[i++] = src->mc_address >> 8;
+ ptr_cmd[i++] = src->mc_address >> 40 | 0xc4b00000;
+ ptr_cmd[i++] = test_info->hang_slow ? 0x81ffc1ff : 0x8007c007;
+ ptr_cmd[i++] = 0x90500fac;
+ i += 2;
+ ptr_cmd[i++] = test_info->hang_slow ? 0 : 0x400;
+ i++;
+ break;
+ case AMDGPU_TEST_GFX_V11:
+ ptr_cmd[i++] = 0xc;
+ ptr_cmd[i++] = src->mc_address >> 8;
+ ptr_cmd[i++] = src->mc_address >> 40 | 0xc4b00000;
+ ptr_cmd[i++] = test_info->hang_slow ? 0x1ffc1ff : 0x7c007;
+ ptr_cmd[i++] = test_info->hang_slow ? 0x90a00fac : 0x90600fac;
+ i += 2;
+ ptr_cmd[i++] = 0x400;
+ i++;
+ break;
+ }
+
+ ptr_cmd[i++] = PACKET3(PACKET3_SET_SH_REG, 4);
+ ptr_cmd[i++] = 0x14;
+ ptr_cmd[i++] = 0x92;
+ i += 3;
+
+ ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr_cmd[i++] = 0x191;
+ ptr_cmd[i++] = 0;
+ test_priv.cmd_curr = i;
+
+ amdgpu_draw_draw(&test_priv);
+
+ i = test_priv.cmd_curr;
+ while (i & 7)
+ ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */
+ test_priv.cmd_curr = i;
+
+ i = 0;
+ resources[i++] = dst->bo;
+ resources[i++] = src->bo;
+ resources[i++] = ps_bo->bo;
+ resources[i++] = vs_bo->bo;
+ resources[i++] = cmd->bo;
+ if (vtx_attributes_mem->size)
+ resources[i++] = vtx_attributes_mem->bo;
+ r = amdgpu_bo_list_create(test_info->device_handle, i, resources, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ib_info.ib_mc_address = cmd->mc_address;
+ ib_info.size = test_priv.cmd_curr;
+ ibs_request.ip_type = test_info->ip;
+ ibs_request.ring = test_info->ring;
+ ibs_request.resources = bo_list;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.ip_type = test_info->ip;
+ fence_status.ip_instance = 0;
+ fence_status.ring = test_info->ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request.seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (!test_info->hang) {
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ /* verify if memcpy test result meets with expected */
+ i = 0;
+ ptr_dst = dst->ptr;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0);
+ i = dst->size - 16;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0);
+ i = dst->size / 2;
+ CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0);
+ } else {
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
+ }
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (vtx_attributes_mem->size) {
+ r = shader_test_bo_free(vtx_attributes_mem);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ r = shader_test_bo_free(src);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(cmd);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(ps_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = shader_test_bo_free(vs_bo);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void shader_test_draw_cb(struct shader_test_info *test_info)
+{
+ amdgpu_memset_draw_test(test_info);
+ amdgpu_memcpy_draw_test(test_info);
+}
+
+static void shader_test_draw_hang_cb(struct shader_test_info *test_info)
+{
+ test_info->hang = 0;
+ amdgpu_memcpy_draw_test(test_info);
+
+ test_info->hang = 1;
+ amdgpu_memcpy_draw_test(test_info);
+
+ test_info->hang = 0;
+ amdgpu_memcpy_draw_test(test_info);
+}
+
+static void shader_test_draw_hang_slow_cb(struct shader_test_info *test_info)
+{
+ test_info->hang = 0;
+ test_info->hang_slow = 0;
+ amdgpu_memcpy_draw_test(test_info);
+
+ test_info->hang = 1;
+ test_info->hang_slow = 1;
+ amdgpu_memcpy_draw_test(test_info);
+
+ test_info->hang = 0;
+ test_info->hang_slow = 0;
+ amdgpu_memcpy_draw_test(test_info);
+}
+
+
+void amdgpu_test_draw_helper(amdgpu_device_handle device_handle)
+{
+ shader_test_for_each(device_handle, AMDGPU_HW_IP_GFX, shader_test_draw_cb);
+}
+
+void amdgpu_test_draw_hang_helper(amdgpu_device_handle device_handle)
+{
+ shader_test_for_each(device_handle, AMDGPU_HW_IP_GFX, shader_test_draw_hang_cb);
+}
+
+void amdgpu_test_draw_hang_slow_helper(amdgpu_device_handle device_handle)
+{
+ shader_test_for_each(device_handle, AMDGPU_HW_IP_GFX, shader_test_draw_hang_slow_cb);
+}
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
new file mode 100644
index 0000000..690bea0
--- /dev/null
+++ b/tests/amdgpu/syncobj_tests.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+#include "xf86drm.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include <pthread.h>
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static uint32_t family_id;
+static uint32_t chip_id;
+static uint32_t chip_rev;
+
+static void amdgpu_syncobj_timeline_test(void);
+
+CU_BOOL suite_syncobj_timeline_tests_enable(void)
+{
+ int r;
+ uint64_t cap = 0;
+
+ r = drmGetCap(drm_amdgpu[0], DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+ if (r || cap == 0)
+ return CU_FALSE;
+
+ return CU_TRUE;
+}
+
+int suite_syncobj_timeline_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_syncobj_timeline_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo syncobj_timeline_tests[] = {
+ { "syncobj timeline test", amdgpu_syncobj_timeline_test },
+ CU_TEST_INFO_NULL,
+};
+
+#define GFX_COMPUTE_NOP 0xffff1000
+#define SDMA_NOP 0x0
+static int syncobj_command_submission_helper(uint32_t syncobj_handle, bool
+ wait_or_signal, uint64_t point)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct drm_amdgpu_cs_chunk chunks[2];
+ struct drm_amdgpu_cs_chunk_data chunk_data;
+ struct drm_amdgpu_cs_chunk_syncobj syncobj_data;
+ struct amdgpu_cs_fence fence_status;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ uint32_t expired;
+ int i, r;
+ uint64_t seq_no;
+ static uint32_t *ptr;
+ struct amdgpu_gpu_info gpu_info = {0};
+ unsigned gc_ip_type;
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ family_id = device_handle->info.family_id;
+ chip_id = device_handle->info.chip_external_rev;
+ chip_rev = device_handle->info.chip_rev;
+
+ gc_ip_type = (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) ?
+ AMDGPU_HW_IP_COMPUTE : AMDGPU_HW_IP_GFX;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+
+ for (i = 0; i < 16; ++i)
+ ptr[i] = wait_or_signal ? GFX_COMPUTE_NOP: SDMA_NOP;
+
+ chunks[0].chunk_id = AMDGPU_CHUNK_ID_IB;
+ chunks[0].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
+ chunks[0].chunk_data = (uint64_t)(uintptr_t)&chunk_data;
+ chunk_data.ib_data._pad = 0;
+ chunk_data.ib_data.va_start = ib_result_mc_address;
+ chunk_data.ib_data.ib_bytes = 16 * 4;
+ chunk_data.ib_data.ip_type = wait_or_signal ? gc_ip_type :
+ AMDGPU_HW_IP_DMA;
+ chunk_data.ib_data.ip_instance = 0;
+ chunk_data.ib_data.ring = 0;
+ chunk_data.ib_data.flags = AMDGPU_IB_FLAG_EMIT_MEM_SYNC;
+
+ chunks[1].chunk_id = wait_or_signal ?
+ AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT :
+ AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL;
+ chunks[1].length_dw = sizeof(struct drm_amdgpu_cs_chunk_syncobj) / 4;
+ chunks[1].chunk_data = (uint64_t)(uintptr_t)&syncobj_data;
+ syncobj_data.handle = syncobj_handle;
+ syncobj_data.point = point;
+ syncobj_data.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+ r = amdgpu_cs_submit_raw(device_handle,
+ context_handle,
+ bo_list,
+ 2,
+ chunks,
+ &seq_no);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = wait_or_signal ? gc_ip_type :
+ AMDGPU_HW_IP_DMA;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return r;
+}
+
+struct syncobj_point {
+ uint32_t syncobj_handle;
+ uint64_t point;
+};
+
+static void *syncobj_wait(void *data)
+{
+ struct syncobj_point *sp = (struct syncobj_point *)data;
+ int r;
+
+ r = syncobj_command_submission_helper(sp->syncobj_handle, true,
+ sp->point);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return (void *)(long)r;
+}
+
+static void *syncobj_signal(void *data)
+{
+ struct syncobj_point *sp = (struct syncobj_point *)data;
+ int r;
+
+ r = syncobj_command_submission_helper(sp->syncobj_handle, false,
+ sp->point);
+ CU_ASSERT_EQUAL(r, 0);
+
+ return (void *)(long)r;
+}
+
+static void amdgpu_syncobj_timeline_test(void)
+{
+ static pthread_t wait_thread;
+ static pthread_t signal_thread;
+ static pthread_t c_thread;
+ struct syncobj_point sp1, sp2, sp3;
+ uint32_t syncobj_handle;
+ uint64_t payload;
+ uint64_t wait_point, signal_point;
+ uint64_t timeout;
+ struct timespec tp;
+ int r, sync_fd;
+ void *tmp;
+
+ r = amdgpu_cs_create_syncobj2(device_handle, 0, &syncobj_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ // wait on point 5
+ sp1.syncobj_handle = syncobj_handle;
+ sp1.point = 5;
+ r = pthread_create(&wait_thread, NULL, syncobj_wait, &sp1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ // signal on point 10
+ sp2.syncobj_handle = syncobj_handle;
+ sp2.point = 10;
+ r = pthread_create(&signal_thread, NULL, syncobj_signal, &sp2);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = pthread_join(wait_thread, &tmp);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(tmp, 0);
+
+ r = pthread_join(signal_thread, &tmp);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(tmp, 0);
+
+ //query timeline payload
+ r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+ &payload, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(payload, 10);
+
+ //signal on point 16
+ sp3.syncobj_handle = syncobj_handle;
+ sp3.point = 16;
+ r = pthread_create(&c_thread, NULL, syncobj_signal, &sp3);
+ CU_ASSERT_EQUAL(r, 0);
+ //CPU wait on point 16
+ wait_point = 16;
+ timeout = 0;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ timeout = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+ timeout += 0x10000000000; //10s
+ r = amdgpu_cs_syncobj_timeline_wait(device_handle, &syncobj_handle,
+ &wait_point, 1, timeout,
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+ NULL);
+
+ CU_ASSERT_EQUAL(r, 0);
+ r = pthread_join(c_thread, &tmp);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(tmp, 0);
+
+ // export point 16 and import to point 18
+ r = amdgpu_cs_syncobj_export_sync_file2(device_handle, syncobj_handle,
+ 16,
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+ &sync_fd);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_syncobj_import_sync_file2(device_handle, syncobj_handle,
+ 18, sync_fd);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+ &payload, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(payload, 18);
+
+ // CPU signal on point 20
+ signal_point = 20;
+ r = amdgpu_cs_syncobj_timeline_signal(device_handle, &syncobj_handle,
+ &signal_point, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_syncobj_query(device_handle, &syncobj_handle,
+ &payload, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(payload, 20);
+
+ r = amdgpu_cs_destroy_syncobj(device_handle, syncobj_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+}
diff --git a/tests/amdgpu/uvd_enc_tests.c b/tests/amdgpu/uvd_enc_tests.c
new file mode 100644
index 0000000..b4251bc
--- /dev/null
+++ b/tests/amdgpu/uvd_enc_tests.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "frame.h"
+#include "uve_ib.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+struct amdgpu_uvd_enc_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+struct amdgpu_uvd_enc {
+ unsigned width;
+ unsigned height;
+ struct amdgpu_uvd_enc_bo session;
+ struct amdgpu_uvd_enc_bo vbuf;
+ struct amdgpu_uvd_enc_bo bs;
+ struct amdgpu_uvd_enc_bo fb;
+ struct amdgpu_uvd_enc_bo cpb;
+};
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static amdgpu_va_handle ib_va_handle;
+static uint64_t ib_mc_address;
+static uint32_t *ib_cpu;
+
+static struct amdgpu_uvd_enc enc;
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static void amdgpu_cs_uvd_enc_create(void);
+static void amdgpu_cs_uvd_enc_session_init(void);
+static void amdgpu_cs_uvd_enc_encode(void);
+static void amdgpu_cs_uvd_enc_destroy(void);
+
+
+CU_TestInfo uvd_enc_tests[] = {
+ { "UVD ENC create", amdgpu_cs_uvd_enc_create },
+ { "UVD ENC session init", amdgpu_cs_uvd_enc_session_init },
+ { "UVD ENC encode", amdgpu_cs_uvd_enc_encode },
+ { "UVD ENC destroy", amdgpu_cs_uvd_enc_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_uvd_enc_tests_enable(void)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_UVD_ENC, 0, &info);
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ if (!info.available_rings)
+ printf("\n\nThe ASIC NOT support UVD ENC, suite disabled.\n");
+
+ return (r == 0 && (info.available_rings ? CU_TRUE : CU_FALSE));
+}
+
+
+int suite_uvd_enc_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = device_handle->info.family_id;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_handle, (void**)&ib_cpu,
+ &ib_mc_address, &ib_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+int suite_uvd_enc_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
+ ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void alloc_resource(struct amdgpu_uvd_enc_bo *uvd_enc_bo,
+ unsigned size, unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ uvd_enc_bo->addr = va;
+ uvd_enc_bo->handle = buf_handle;
+ uvd_enc_bo->size = req.alloc_size;
+ uvd_enc_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(uvd_enc_bo->handle, (void **)&uvd_enc_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(uvd_enc_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(uvd_enc_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_uvd_enc_bo *uvd_enc_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(uvd_enc_bo->handle, 0, uvd_enc_bo->size,
+ uvd_enc_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(uvd_enc_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(uvd_enc_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(uvd_enc_bo, 0, sizeof(*uvd_enc_bo));
+}
+
+static void amdgpu_cs_uvd_enc_create(void)
+{
+ enc.width = 160;
+ enc.height = 128;
+
+ num_resources = 0;
+ alloc_resource(&enc.session, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.session.handle;
+ resources[num_resources++] = ib_handle;
+}
+
+static void check_result(struct amdgpu_uvd_enc *enc)
+{
+ uint64_t sum;
+ uint32_t s = 175602;
+ uint32_t *ptr, size;
+ int j, r;
+
+ r = amdgpu_bo_cpu_map(enc->fb.handle, (void **)&enc->fb.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr = (uint32_t *)enc->fb.ptr;
+ size = ptr[6];
+ r = amdgpu_bo_cpu_unmap(enc->fb.handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_map(enc->bs.handle, (void **)&enc->bs.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ for (j = 0, sum = 0; j < size; ++j)
+ sum += enc->bs.ptr[j];
+ CU_ASSERT_EQUAL(sum, s);
+ r = amdgpu_bo_cpu_unmap(enc->bs.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+}
+
+static void amdgpu_cs_uvd_enc_session_init(void)
+{
+ int len, r;
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0x000000d8;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_op_init, sizeof(uve_op_init));
+ len += sizeof(uve_op_init) / 4;
+
+ memcpy((ib_cpu + len), uve_session_init, sizeof(uve_session_init));
+ len += sizeof(uve_session_init) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_ctrl, sizeof(uve_layer_ctrl));
+ len += sizeof(uve_layer_ctrl) / 4;
+
+ memcpy((ib_cpu + len), uve_slice_ctrl, sizeof(uve_slice_ctrl));
+ len += sizeof(uve_slice_ctrl) / 4;
+
+ memcpy((ib_cpu + len), uve_spec_misc, sizeof(uve_spec_misc));
+ len += sizeof(uve_spec_misc) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_session_init, sizeof(uve_rc_session_init));
+ len += sizeof(uve_rc_session_init) / 4;
+
+ memcpy((ib_cpu + len), uve_deblocking_filter, sizeof(uve_deblocking_filter));
+ len += sizeof(uve_deblocking_filter) / 4;
+
+ memcpy((ib_cpu + len), uve_quality_params, sizeof(uve_quality_params));
+ len += sizeof(uve_quality_params) / 4;
+
+ memcpy((ib_cpu + len), uve_op_init_rc, sizeof(uve_op_init_rc));
+ len += sizeof(uve_op_init_rc) / 4;
+
+ memcpy((ib_cpu + len), uve_op_init_rc_vbv_level, sizeof(uve_op_init_rc_vbv_level));
+ len += sizeof(uve_op_init_rc_vbv_level) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_uvd_enc_encode(void)
+{
+ int len, r, i;
+ uint64_t luma_offset, chroma_offset;
+ uint32_t vbuf_size, bs_size = 0x003f4800, cpb_size;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
+ cpb_size = vbuf_size * 10;
+
+
+ num_resources = 0;
+ alloc_resource(&enc.fb, 4096, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.fb.handle;
+ alloc_resource(&enc.bs, bs_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.bs.handle;
+ alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.vbuf.handle;
+ alloc_resource(&enc.cpb, cpb_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.cpb.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(enc.vbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.vbuf.ptr, (frame + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.vbuf.ptr, ((frame + enc.height * enc.width) + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+
+ r = amdgpu_bo_cpu_unmap(enc.vbuf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0x000005e0;
+ ib_cpu[len++] = 0x00000001;
+ ib_cpu[len++] = 0x00000001;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_1, sizeof(uve_nalu_buffer_1));
+ len += sizeof(uve_nalu_buffer_1) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_2, sizeof(uve_nalu_buffer_2));
+ len += sizeof(uve_nalu_buffer_2) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_3, sizeof(uve_nalu_buffer_3));
+ len += sizeof(uve_nalu_buffer_3) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_4, sizeof(uve_nalu_buffer_4));
+ len += sizeof(uve_nalu_buffer_4) / 4;
+
+ memcpy((ib_cpu + len), uve_slice_header, sizeof(uve_slice_header));
+ len += sizeof(uve_slice_header) / 4;
+
+ ib_cpu[len++] = 0x00000254;
+ ib_cpu[len++] = 0x00000010;
+ ib_cpu[len++] = enc.cpb.addr >> 32;
+ ib_cpu[len++] = enc.cpb.addr;
+ memcpy((ib_cpu + len), uve_ctx_buffer, sizeof(uve_ctx_buffer));
+ len += sizeof(uve_ctx_buffer) / 4;
+
+ memcpy((ib_cpu + len), uve_bitstream_buffer, sizeof(uve_bitstream_buffer));
+ len += sizeof(uve_bitstream_buffer) / 4;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = enc.bs.addr >> 32;
+ ib_cpu[len++] = enc.bs.addr;
+ ib_cpu[len++] = 0x003f4800;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_feedback_buffer, sizeof(uve_feedback_buffer));
+ len += sizeof(uve_feedback_buffer) / 4;
+ ib_cpu[len++] = enc.fb.addr >> 32;
+ ib_cpu[len++] = enc.fb.addr;
+ ib_cpu[len++] = 0x00000010;
+ ib_cpu[len++] = 0x00000028;
+
+ memcpy((ib_cpu + len), uve_feedback_buffer_additional, sizeof(uve_feedback_buffer_additional));
+ len += sizeof(uve_feedback_buffer_additional) / 4;
+
+ memcpy((ib_cpu + len), uve_intra_refresh, sizeof(uve_intra_refresh));
+ len += sizeof(uve_intra_refresh) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_select, sizeof(uve_layer_select));
+ len += sizeof(uve_layer_select) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_layer_init, sizeof(uve_rc_layer_init));
+ len += sizeof(uve_rc_layer_init) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_select, sizeof(uve_layer_select));
+ len += sizeof(uve_layer_select) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_per_pic, sizeof(uve_rc_per_pic));
+ len += sizeof(uve_rc_per_pic) / 4;
+
+ unsigned luma_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16);
+ luma_offset = enc.vbuf.addr;
+ chroma_offset = luma_offset + luma_size;
+ ib_cpu[len++] = 0x00000054;
+ ib_cpu[len++] = 0x0000000c;
+ ib_cpu[len++] = 0x00000002;
+ ib_cpu[len++] = 0x003f4800;
+ ib_cpu[len++] = luma_offset >> 32;
+ ib_cpu[len++] = luma_offset;
+ ib_cpu[len++] = chroma_offset >> 32;
+ ib_cpu[len++] = chroma_offset;
+ memcpy((ib_cpu + len), uve_encode_param, sizeof(uve_encode_param));
+ ib_cpu[len] = ALIGN(enc.width, align);
+ ib_cpu[len + 1] = ALIGN(enc.width, align);
+ len += sizeof(uve_encode_param) / 4;
+
+ memcpy((ib_cpu + len), uve_op_speed_enc_mode, sizeof(uve_op_speed_enc_mode));
+ len += sizeof(uve_op_speed_enc_mode) / 4;
+
+ memcpy((ib_cpu + len), uve_op_encode, sizeof(uve_op_encode));
+ len += sizeof(uve_op_encode) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ check_result(&enc);
+
+ free_resource(&enc.fb);
+ free_resource(&enc.bs);
+ free_resource(&enc.vbuf);
+ free_resource(&enc.cpb);
+}
+
+static void amdgpu_cs_uvd_enc_destroy(void)
+{
+ int len, r;
+
+ num_resources = 0;
+ resources[num_resources++] = ib_handle;
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0xffffffff;
+ ib_cpu[len++] = 0x00000002;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_op_close, sizeof(uve_op_close));
+ len += sizeof(uve_op_close) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&enc.session);
+}
diff --git a/tests/amdgpu/uve_ib.h b/tests/amdgpu/uve_ib.h
new file mode 100644
index 0000000..cb72be2
--- /dev/null
+++ b/tests/amdgpu/uve_ib.h
@@ -0,0 +1,527 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _uve_ib_h_
+#define _uve_ib_h_
+
+static const uint32_t uve_session_info[] = {
+ 0x00000018,
+ 0x00000001,
+ 0x00000000,
+ 0x00010000,
+};
+
+static const uint32_t uve_task_info[] = {
+ 0x00000014,
+ 0x00000002,
+};
+
+static const uint32_t uve_session_init[] = {
+ 0x00000020,
+ 0x00000003,
+ 0x000000c0,
+ 0x00000080,
+ 0x00000020,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_layer_ctrl[] = {
+ 0x00000010,
+ 0x00000004,
+ 0x00000001,
+ 0x00000001,
+};
+
+static const uint32_t uve_layer_select[] = {
+ 0x0000000c,
+ 0x00000005,
+ 0x00000000,
+};
+
+static const uint32_t uve_slice_ctrl[] = {
+ 0x00000014,
+ 0x00000006,
+ 0x00000000,
+ 0x00000006,
+ 0x00000006,
+};
+
+static const uint32_t uve_spec_misc[] = {
+ 0x00000024,
+ 0x00000007,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+ 0x00000001,
+};
+
+static const uint32_t uve_rc_session_init[] = {
+ 0x00000010,
+ 0x00000008,
+ 0x00000000,
+ 0x00000040,
+};
+
+static const uint32_t uve_rc_layer_init[] = {
+ 0x00000028,
+ 0x00000009,
+ 0x001e8480,
+ 0x001e8480,
+ 0x0000001e,
+ 0x00000001,
+ 0x0001046a,
+ 0x0001046a,
+ 0x0001046a,
+ 0xaaaaaaaa,
+};
+
+static const uint32_t uve_deblocking_filter[] = {
+ 0x00000020,
+ 0x0000000e,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_quality_params[] = {
+ 0x00000014,
+ 0x0000000d,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_feedback_buffer[] = {
+ 0x0000001c,
+ 0x00000012,
+ 0x00000000,
+};
+
+static const uint32_t uve_feedback_buffer_additional[] = {
+ 0x00000108,
+ 0x00000014,
+ 0x00000001,
+ 0x00000010,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_nalu_buffer_1[] = {
+ 0x00000018,
+ 0x00000013,
+ 0x00000001,
+ 0x00000007,
+ 0x00000001,
+ 0x46011000,
+};
+
+static const uint32_t uve_nalu_buffer_2[] = {
+ 0x0000002c,
+ 0x00000013,
+ 0x00000002,
+ 0x0000001b,
+ 0x00000001,
+ 0x40010c01,
+ 0xffff0160,
+ 0x00000300,
+ 0xb0000003,
+ 0x00000300,
+ 0x962c0900,
+};
+
+static const uint32_t uve_nalu_buffer_3[] = {
+ 0x00000034,
+ 0x00000013,
+ 0x00000003,
+ 0x00000023,
+ 0x00000001,
+ 0x42010101,
+ 0x60000003,
+ 0x00b00000,
+ 0x03000003,
+ 0x0096a018,
+ 0x2020708f,
+ 0xcb924295,
+ 0x12e08000,
+};
+
+static const uint32_t uve_nalu_buffer_4[] = {
+ 0x0000001c,
+ 0x00000013,
+ 0x00000004,
+ 0x0000000b,
+ 0x00000001,
+ 0x4401e0f1,
+ 0x80992000,
+};
+
+static const uint32_t uve_slice_header[] = {
+ 0x000000c8,
+ 0x0000000b,
+ 0x28010000,
+ 0x40000000,
+ 0x60000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000002,
+ 0x00000010,
+ 0x00000003,
+ 0x00000000,
+ 0x00000002,
+ 0x00000002,
+ 0x00000004,
+ 0x00000000,
+ 0x00000001,
+ 0x00000000,
+ 0x00000002,
+ 0x00000003,
+ 0x00000005,
+ 0x00000000,
+ 0x00000002,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_encode_param[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xffffffff,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_intra_refresh[] = {
+ 0x00000014,
+ 0x0000000f,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+};
+
+static const uint32_t uve_ctx_buffer[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x000000a0,
+ 0x000000a0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_bitstream_buffer[] = {
+ 0x0000001c,
+ 0x00000011,
+};
+
+static const uint32_t uve_rc_per_pic[] = {
+ 0x00000024,
+ 0x0000000a,
+ 0x0000001a,
+ 0x00000000,
+ 0x00000033,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+};
+
+static const uint32_t uve_op_init[] = {
+ 0x00000008,
+ 0x08000001,
+};
+
+static const uint32_t uve_op_close[] = {
+ 0x00000008,
+ 0x08000002,
+};
+
+static const uint32_t uve_op_encode[] = {
+ 0x00000008,
+ 0x08000003,
+};
+
+static const uint32_t uve_op_init_rc[] = {
+ 0x00000008,
+ 0x08000004,
+};
+
+static const uint32_t uve_op_init_rc_vbv_level[] = {
+ 0x00000008,
+ 0x08000005,
+};
+
+static const uint32_t uve_op_speed_enc_mode[] = {
+ 0x00000008,
+ 0x08000006,
+};
+
+static const uint32_t uve_op_balance_enc_mode[] = {
+ 0x00000008,
+ 0x08000007,
+};
+
+static const uint32_t uve_op_quality_enc_mode[] = {
+ 0x00000008,
+ 0x08000008,
+};
+#endif /*_uve_ib_h*/
diff --git a/tests/amdgpu/vce_ib.h b/tests/amdgpu/vce_ib.h
new file mode 100644
index 0000000..f3108a0
--- /dev/null
+++ b/tests/amdgpu/vce_ib.h
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#ifndef _vce_ib_h_
+#define _vce_ib_h_
+
+static const uint32_t vce_session[] = {
+ 0x0000000c,
+ 0x00000001,
+ 0x400c0001,
+};
+
+static uint32_t vce_taskinfo[8] = {
+ 0x00000020,
+ 0x00000002,
+ 0xffffffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t vce_create[] = {
+ 0x00000030,
+ 0x01000001,
+ 0x00000000,
+ 0x00000042,
+ 0x0000002a,
+ 0x00000000,
+ 0x000000a0,
+ 0x00000080,
+ 0x000000a0,
+ 0x000000a0,
+ 0x00000010,
+ 0x00000201,
+};
+
+static const uint32_t vce_rate_ctrl[] = {
+ 0x00000070,
+ 0x04000005,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x0000001c,
+ 0x0000001c,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000033,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t vce_config_ext[] = {
+ 0x0000000c,
+ 0x04000001,
+ 0x00000003,
+};
+
+static const uint32_t vce_motion_est[] = {
+ 0x00000068,
+ 0x04000007,
+ 0x00000001,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000010,
+ 0x00000010,
+ 0x00000010,
+ 0x00000010,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x000000fe,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t vce_rdo[] = {
+ 0x0000004c,
+ 0x04000008,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t vce_pic_ctrl[] = {
+ 0x00000074,
+ 0x04000002,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000aa0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+ 0x00000002,
+ 0x00000001,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t vce_feedback[] = {
+ 0x00000014,
+ 0x05000005,
+ 0x00000000,
+ 0xffffffff,
+ 0x00000001,
+};
+
+static const uint32_t vce_context_buffer[] = {
+ 0x00000010,
+ 0x05000001,
+ 0x00000000,
+ 0xffffffff,
+};
+
+static const uint32_t vce_bs_buffer[] = {
+ 0x00000014,
+ 0x05000004,
+ 0x00000000,
+ 0xffffffff,
+ 0x00154000,
+};
+
+static const uint32_t vce_aux_buffer[] = {
+ 0x00000048,
+ 0x05000002,
+ 0x0000f000,
+ 0x00016800,
+ 0x0001e000,
+ 0x00025800,
+ 0x0002d000,
+ 0x00034800,
+ 0x0003c000,
+ 0x00043800,
+ 0x00007800,
+ 0x00007800,
+ 0x00007800,
+ 0x00007800,
+ 0x00007800,
+ 0x00007800,
+ 0x00007800,
+ 0x00007800,
+};
+
+static uint32_t vce_encode[88] = {
+ 0x00000160,
+ 0x03000001,
+ 0x00000011,
+ 0x00000000,
+ 0x00154000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xffffffff,
+ 0x00000000,
+ 0xffffffff,
+ 0x00000080,
+ 0x000000a0,
+ 0x000000a0,
+ 0x00010000,
+ 0x00000000,
+ 0x00000003,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xffffffff,
+ 0xffffffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xffffffff,
+ 0xffffffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xffffffff,
+ 0xffffffff,
+ 0xffffffff,
+ 0xffffffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t vce_destroy[] = {
+ 0x00000008,
+ 0x02000001,
+};
+
+static const uint32_t vce_mv_buffer[] = {
+ 0x00000038,
+ 0x0500000d,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+#endif /*_vce_ib_h*/
diff --git a/tests/amdgpu/vce_tests.c b/tests/amdgpu/vce_tests.c
new file mode 100644
index 0000000..9aa0a8e
--- /dev/null
+++ b/tests/amdgpu/vce_tests.c
@@ -0,0 +1,764 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#include "vce_ib.h"
+#include "frame.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+#define FW_53_0_03 ((53 << 24) | (0 << 16) | (03 << 8))
+
+struct amdgpu_vce_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+struct amdgpu_vce_encode {
+ unsigned width;
+ unsigned height;
+ struct amdgpu_vce_bo vbuf;
+ struct amdgpu_vce_bo bs[2];
+ struct amdgpu_vce_bo fb[2];
+ struct amdgpu_vce_bo cpb;
+ unsigned ib_len;
+ bool two_instance;
+ struct amdgpu_vce_bo mvrefbuf;
+ struct amdgpu_vce_bo mvb;
+ unsigned mvbuf_size;
+};
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+static uint32_t vce_harvest_config;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+static uint32_t ids_flags;
+static bool is_mv_supported = true;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static amdgpu_va_handle ib_va_handle;
+static uint64_t ib_mc_address;
+static uint32_t *ib_cpu;
+
+static struct amdgpu_vce_encode enc;
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static void amdgpu_cs_vce_create(void);
+static void amdgpu_cs_vce_encode(void);
+static void amdgpu_cs_vce_encode_mv(void);
+static void amdgpu_cs_vce_destroy(void);
+
+CU_TestInfo vce_tests[] = {
+ { "VCE create", amdgpu_cs_vce_create },
+ { "VCE encode", amdgpu_cs_vce_encode },
+ { "VCE MV dump", amdgpu_cs_vce_encode_mv },
+ { "VCE destroy", amdgpu_cs_vce_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_vce_tests_enable(void)
+{
+ uint32_t version, feature;
+ CU_BOOL ret_mv = CU_FALSE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+ chip_rev = device_handle->info.chip_rev;
+ chip_id = device_handle->info.chip_external_rev;
+ ids_flags = device_handle->info.ids_flags;
+
+ amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0,
+ 0, &version, &feature);
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI ||
+ asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) {
+ printf("\n\nThe ASIC NOT support VCE, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ if (!(chip_id == (chip_rev + 0x3C) || /* FIJI */
+ chip_id == (chip_rev + 0x50) || /* Polaris 10*/
+ chip_id == (chip_rev + 0x5A) || /* Polaris 11*/
+ chip_id == (chip_rev + 0x64) || /* Polaris 12*/
+ (family_id >= AMDGPU_FAMILY_AI && !ids_flags))) /* dGPU > Polaris */
+ printf("\n\nThe ASIC NOT support VCE MV, suite disabled\n");
+ else if (FW_53_0_03 > version)
+ printf("\n\nThe ASIC FW version NOT support VCE MV, suite disabled\n");
+ else
+ ret_mv = CU_TRUE;
+
+ if (ret_mv == CU_FALSE) {
+ amdgpu_set_test_active("VCE Tests", "VCE MV dump", ret_mv);
+ is_mv_supported = false;
+ }
+
+ return CU_TRUE;
+}
+
+int suite_vce_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+
+ return CUE_SINIT_FAILED;
+ }
+
+ family_id = device_handle->info.family_id;
+ vce_harvest_config = device_handle->info.vce_harvest_config;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_handle, (void**)&ib_cpu,
+ &ib_mc_address, &ib_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ memset(&enc, 0, sizeof(struct amdgpu_vce_encode));
+
+ return CUE_SUCCESS;
+}
+
+int suite_vce_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
+ ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void alloc_resource(struct amdgpu_vce_bo *vce_bo, unsigned size, unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ vce_bo->addr = va;
+ vce_bo->handle = buf_handle;
+ vce_bo->size = req.alloc_size;
+ vce_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(vce_bo->handle, (void **)&vce_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vce_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(vce_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_vce_bo *vce_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(vce_bo->handle, 0, vce_bo->size,
+ vce_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(vce_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(vce_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vce_bo, 0, sizeof(*vce_bo));
+}
+
+static void amdgpu_cs_vce_create(void)
+{
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ int len, r;
+
+ enc.width = vce_create[6];
+ enc.height = vce_create[7];
+
+ num_resources = 0;
+ alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.fb[0].handle;
+ resources[num_resources++] = ib_handle;
+
+ len = 0;
+ memcpy(ib_cpu, vce_session, sizeof(vce_session));
+ len += sizeof(vce_session) / 4;
+ memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
+ len += sizeof(vce_taskinfo) / 4;
+ memcpy((ib_cpu + len), vce_create, sizeof(vce_create));
+ ib_cpu[len + 8] = ALIGN(enc.width, align);
+ ib_cpu[len + 9] = ALIGN(enc.width, align);
+ if (is_mv_supported == true) {/* disableTwoInstance */
+ if (family_id >= AMDGPU_FAMILY_AI)
+ ib_cpu[len + 11] = 0x01000001;
+ else
+ ib_cpu[len + 11] = 0x01000201;
+ }
+ len += sizeof(vce_create) / 4;
+ memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
+ ib_cpu[len + 2] = enc.fb[0].addr >> 32;
+ ib_cpu[len + 3] = enc.fb[0].addr;
+ len += sizeof(vce_feedback) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_VCE);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&enc.fb[0]);
+}
+
+static void amdgpu_cs_vce_config(void)
+{
+ int len = 0, r;
+
+ memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
+ len += sizeof(vce_session) / 4;
+ memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
+ ib_cpu[len + 3] = 2;
+ ib_cpu[len + 6] = 0xffffffff;
+ len += sizeof(vce_taskinfo) / 4;
+ memcpy((ib_cpu + len), vce_rate_ctrl, sizeof(vce_rate_ctrl));
+ len += sizeof(vce_rate_ctrl) / 4;
+ memcpy((ib_cpu + len), vce_config_ext, sizeof(vce_config_ext));
+ len += sizeof(vce_config_ext) / 4;
+ memcpy((ib_cpu + len), vce_motion_est, sizeof(vce_motion_est));
+ len += sizeof(vce_motion_est) / 4;
+ memcpy((ib_cpu + len), vce_rdo, sizeof(vce_rdo));
+ len += sizeof(vce_rdo) / 4;
+ memcpy((ib_cpu + len), vce_pic_ctrl, sizeof(vce_pic_ctrl));
+ if (is_mv_supported == true)
+ ib_cpu[len + 27] = 0x00000001; /* encSliceMode */
+ len += sizeof(vce_pic_ctrl) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_VCE);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc)
+{
+
+ uint64_t luma_offset, chroma_offset;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16);
+ int len = 0, i, r;
+
+ luma_offset = enc->vbuf.addr;
+ chroma_offset = luma_offset + luma_size;
+
+ memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
+ len += sizeof(vce_session) / 4;
+ memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
+ len += sizeof(vce_taskinfo) / 4;
+ memcpy((ib_cpu + len), vce_bs_buffer, sizeof(vce_bs_buffer));
+ ib_cpu[len + 2] = enc->bs[0].addr >> 32;
+ ib_cpu[len + 3] = enc->bs[0].addr;
+ len += sizeof(vce_bs_buffer) / 4;
+ memcpy((ib_cpu + len), vce_context_buffer, sizeof(vce_context_buffer));
+ ib_cpu[len + 2] = enc->cpb.addr >> 32;
+ ib_cpu[len + 3] = enc->cpb.addr;
+ len += sizeof(vce_context_buffer) / 4;
+ memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 2 + i] = luma_size * 1.5 * (i + 2);
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 10 + i] = luma_size * 1.5;
+ len += sizeof(vce_aux_buffer) / 4;
+ memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
+ ib_cpu[len + 2] = enc->fb[0].addr >> 32;
+ ib_cpu[len + 3] = enc->fb[0].addr;
+ len += sizeof(vce_feedback) / 4;
+ memcpy((ib_cpu + len), vce_encode, sizeof(vce_encode));
+ ib_cpu[len + 9] = luma_offset >> 32;
+ ib_cpu[len + 10] = luma_offset;
+ ib_cpu[len + 11] = chroma_offset >> 32;
+ ib_cpu[len + 12] = chroma_offset;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
+ ib_cpu[len + 73] = luma_size * 1.5;
+ ib_cpu[len + 74] = luma_size * 2.5;
+ len += sizeof(vce_encode) / 4;
+ enc->ib_len = len;
+ if (!enc->two_instance) {
+ r = submit(len, AMDGPU_HW_IP_VCE);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+}
+
+static void amdgpu_cs_vce_encode_p(struct amdgpu_vce_encode *enc)
+{
+ uint64_t luma_offset, chroma_offset;
+ int len, i, r;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16);
+
+ len = (enc->two_instance) ? enc->ib_len : 0;
+ luma_offset = enc->vbuf.addr;
+ chroma_offset = luma_offset + luma_size;
+
+ if (!enc->two_instance) {
+ memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
+ len += sizeof(vce_session) / 4;
+ }
+ memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
+ len += sizeof(vce_taskinfo) / 4;
+ memcpy((ib_cpu + len), vce_bs_buffer, sizeof(vce_bs_buffer));
+ ib_cpu[len + 2] = enc->bs[1].addr >> 32;
+ ib_cpu[len + 3] = enc->bs[1].addr;
+ len += sizeof(vce_bs_buffer) / 4;
+ memcpy((ib_cpu + len), vce_context_buffer, sizeof(vce_context_buffer));
+ ib_cpu[len + 2] = enc->cpb.addr >> 32;
+ ib_cpu[len + 3] = enc->cpb.addr;
+ len += sizeof(vce_context_buffer) / 4;
+ memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 2 + i] = luma_size * 1.5 * (i + 2);
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 10 + i] = luma_size * 1.5;
+ len += sizeof(vce_aux_buffer) / 4;
+ memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
+ ib_cpu[len + 2] = enc->fb[1].addr >> 32;
+ ib_cpu[len + 3] = enc->fb[1].addr;
+ len += sizeof(vce_feedback) / 4;
+ memcpy((ib_cpu + len), vce_encode, sizeof(vce_encode));
+ ib_cpu[len + 2] = 0;
+ ib_cpu[len + 9] = luma_offset >> 32;
+ ib_cpu[len + 10] = luma_offset;
+ ib_cpu[len + 11] = chroma_offset >> 32;
+ ib_cpu[len + 12] = chroma_offset;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
+ ib_cpu[len + 18] = 0;
+ ib_cpu[len + 19] = 0;
+ ib_cpu[len + 56] = 3;
+ ib_cpu[len + 57] = 0;
+ ib_cpu[len + 58] = 0;
+ ib_cpu[len + 59] = luma_size * 1.5;
+ ib_cpu[len + 60] = luma_size * 2.5;
+ ib_cpu[len + 73] = 0;
+ ib_cpu[len + 74] = luma_size;
+ ib_cpu[len + 81] = 1;
+ ib_cpu[len + 82] = 1;
+ len += sizeof(vce_encode) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_VCE);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void check_result(struct amdgpu_vce_encode *enc)
+{
+ uint64_t sum;
+ uint32_t s[2] = {180325, 15946};
+ uint32_t *ptr, size;
+ int i, j, r;
+
+ for (i = 0; i < 2; ++i) {
+ r = amdgpu_bo_cpu_map(enc->fb[i].handle, (void **)&enc->fb[i].ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr = (uint32_t *)enc->fb[i].ptr;
+ size = ptr[4] - ptr[9];
+ r = amdgpu_bo_cpu_unmap(enc->fb[i].handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_map(enc->bs[i].handle, (void **)&enc->bs[i].ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ for (j = 0, sum = 0; j < size; ++j)
+ sum += enc->bs[i].ptr[j];
+ CU_ASSERT_EQUAL(sum, s[i]);
+ r = amdgpu_bo_cpu_unmap(enc->bs[i].handle);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+}
+
+static void amdgpu_cs_vce_encode(void)
+{
+ uint32_t vbuf_size, bs_size = 0x154000, cpb_size;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ int i, r;
+
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
+ cpb_size = vbuf_size * 10;
+ num_resources = 0;
+ alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.fb[0].handle;
+ alloc_resource(&enc.fb[1], 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.fb[1].handle;
+ alloc_resource(&enc.bs[0], bs_size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.bs[0].handle;
+ alloc_resource(&enc.bs[1], bs_size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.bs[1].handle;
+ alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.vbuf.handle;
+ alloc_resource(&enc.cpb, cpb_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.cpb.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(enc.vbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.vbuf.ptr, (frame + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.vbuf.ptr, ((frame + enc.height * enc.width) + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+
+ r = amdgpu_bo_cpu_unmap(enc.vbuf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_cs_vce_config();
+
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ vce_taskinfo[3] = 3;
+ amdgpu_cs_vce_encode_idr(&enc);
+ amdgpu_cs_vce_encode_p(&enc);
+ check_result(&enc);
+
+ /* two pipes */
+ vce_encode[16] = 0;
+ amdgpu_cs_vce_encode_idr(&enc);
+ amdgpu_cs_vce_encode_p(&enc);
+ check_result(&enc);
+
+ /* two instances */
+ if (vce_harvest_config == 0) {
+ enc.two_instance = true;
+ vce_taskinfo[2] = 0x83;
+ vce_taskinfo[4] = 1;
+ amdgpu_cs_vce_encode_idr(&enc);
+ vce_taskinfo[2] = 0xffffffff;
+ vce_taskinfo[4] = 2;
+ amdgpu_cs_vce_encode_p(&enc);
+ check_result(&enc);
+ }
+ } else {
+ vce_taskinfo[3] = 3;
+ vce_encode[16] = 0;
+ amdgpu_cs_vce_encode_idr(&enc);
+ amdgpu_cs_vce_encode_p(&enc);
+ check_result(&enc);
+ }
+
+ free_resource(&enc.fb[0]);
+ free_resource(&enc.fb[1]);
+ free_resource(&enc.bs[0]);
+ free_resource(&enc.bs[1]);
+ free_resource(&enc.vbuf);
+ free_resource(&enc.cpb);
+}
+
+static void amdgpu_cs_vce_mv(struct amdgpu_vce_encode *enc)
+{
+ uint64_t luma_offset, chroma_offset;
+ uint64_t mv_ref_luma_offset;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16);
+ int len = 0, i, r;
+
+ luma_offset = enc->vbuf.addr;
+ chroma_offset = luma_offset + luma_size;
+ mv_ref_luma_offset = enc->mvrefbuf.addr;
+
+ memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
+ len += sizeof(vce_session) / 4;
+ memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
+ len += sizeof(vce_taskinfo) / 4;
+ memcpy((ib_cpu + len), vce_bs_buffer, sizeof(vce_bs_buffer));
+ ib_cpu[len + 2] = enc->bs[0].addr >> 32;
+ ib_cpu[len + 3] = enc->bs[0].addr;
+ len += sizeof(vce_bs_buffer) / 4;
+ memcpy((ib_cpu + len), vce_context_buffer, sizeof(vce_context_buffer));
+ ib_cpu[len + 2] = enc->cpb.addr >> 32;
+ ib_cpu[len + 3] = enc->cpb.addr;
+ len += sizeof(vce_context_buffer) / 4;
+ memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 2 + i] = luma_size * 1.5 * (i + 2);
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 10 + i] = luma_size * 1.5;
+ len += sizeof(vce_aux_buffer) / 4;
+ memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
+ ib_cpu[len + 2] = enc->fb[0].addr >> 32;
+ ib_cpu[len + 3] = enc->fb[0].addr;
+ len += sizeof(vce_feedback) / 4;
+ memcpy((ib_cpu + len), vce_mv_buffer, sizeof(vce_mv_buffer));
+ ib_cpu[len + 2] = mv_ref_luma_offset >> 32;
+ ib_cpu[len + 3] = mv_ref_luma_offset;
+ ib_cpu[len + 4] = ALIGN(enc->width, align);
+ ib_cpu[len + 5] = ALIGN(enc->width, align);
+ ib_cpu[len + 6] = luma_size;
+ ib_cpu[len + 7] = enc->mvb.addr >> 32;
+ ib_cpu[len + 8] = enc->mvb.addr;
+ len += sizeof(vce_mv_buffer) / 4;
+ memcpy((ib_cpu + len), vce_encode, sizeof(vce_encode));
+ ib_cpu[len + 2] = 0;
+ ib_cpu[len + 3] = 0;
+ ib_cpu[len + 4] = 0x154000;
+ ib_cpu[len + 9] = luma_offset >> 32;
+ ib_cpu[len + 10] = luma_offset;
+ ib_cpu[len + 11] = chroma_offset >> 32;
+ ib_cpu[len + 12] = chroma_offset;
+ ib_cpu[len + 13] = ALIGN(enc->height, 16);;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
+ /* encDisableMBOffloading-encDisableTwoPipeMode-encInputPicArrayMode-encInputPicAddrMode */
+ ib_cpu[len + 16] = 0x01010000;
+ ib_cpu[len + 18] = 0; /* encPicType */
+ ib_cpu[len + 19] = 0; /* encIdrFlag */
+ ib_cpu[len + 20] = 0; /* encIdrPicId */
+ ib_cpu[len + 21] = 0; /* encMGSKeyPic */
+ ib_cpu[len + 22] = 0; /* encReferenceFlag */
+ ib_cpu[len + 23] = 0; /* encTemporalLayerIndex */
+ ib_cpu[len + 55] = 0; /* pictureStructure */
+ ib_cpu[len + 56] = 0; /* encPicType -ref[0] */
+ ib_cpu[len + 61] = 0; /* pictureStructure */
+ ib_cpu[len + 62] = 0; /* encPicType -ref[1] */
+ ib_cpu[len + 67] = 0; /* pictureStructure */
+ ib_cpu[len + 68] = 0; /* encPicType -ref1 */
+ ib_cpu[len + 81] = 1; /* frameNumber */
+ ib_cpu[len + 82] = 2; /* pictureOrderCount */
+ ib_cpu[len + 83] = 0xffffffff; /* numIPicRemainInRCGOP */
+ ib_cpu[len + 84] = 0xffffffff; /* numPPicRemainInRCGOP */
+ ib_cpu[len + 85] = 0xffffffff; /* numBPicRemainInRCGOP */
+ ib_cpu[len + 86] = 0xffffffff; /* numIRPicRemainInRCGOP */
+ ib_cpu[len + 87] = 0; /* remainedIntraRefreshPictures */
+ len += sizeof(vce_encode) / 4;
+
+ enc->ib_len = len;
+ r = submit(len, AMDGPU_HW_IP_VCE);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void check_mv_result(struct amdgpu_vce_encode *enc)
+{
+ uint64_t sum;
+ uint32_t s = 140790;
+ int j, r;
+
+ r = amdgpu_bo_cpu_map(enc->fb[0].handle, (void **)&enc->fb[0].ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_unmap(enc->fb[0].handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_map(enc->mvb.handle, (void **)&enc->mvb.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ for (j = 0, sum = 0; j < enc->mvbuf_size; ++j)
+ sum += enc->mvb.ptr[j];
+ CU_ASSERT_EQUAL(sum, s);
+ r = amdgpu_bo_cpu_unmap(enc->mvb.handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_vce_encode_mv(void)
+{
+ uint32_t vbuf_size, bs_size = 0x154000, cpb_size;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ int i, r;
+
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
+ enc.mvbuf_size = ALIGN(enc.width, 16) * ALIGN(enc.height, 16) / 8;
+ cpb_size = vbuf_size * 10;
+ num_resources = 0;
+ alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.fb[0].handle;
+ alloc_resource(&enc.bs[0], bs_size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.bs[0].handle;
+ alloc_resource(&enc.mvb, enc.mvbuf_size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.mvb.handle;
+ alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.vbuf.handle;
+ alloc_resource(&enc.mvrefbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.mvrefbuf.handle;
+ alloc_resource(&enc.cpb, cpb_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.cpb.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(enc.vbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.vbuf.ptr, (frame + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.vbuf.ptr, ((frame + enc.height * enc.width) + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+
+ r = amdgpu_bo_cpu_unmap(enc.vbuf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(enc.mvrefbuf.handle, (void **)&enc.mvrefbuf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(enc.mvrefbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.mvrefbuf.ptr, (frame + (enc.height - i -1) * enc.width), enc.width);
+ enc.mvrefbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.mvrefbuf.ptr,
+ ((frame + enc.height * enc.width) + (enc.height / 2 - i -1) * enc.width), enc.width);
+ enc.mvrefbuf.ptr += ALIGN(enc.width, align);
+ }
+
+ r = amdgpu_bo_cpu_unmap(enc.mvrefbuf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_cs_vce_config();
+
+ vce_taskinfo[3] = 3;
+ amdgpu_cs_vce_mv(&enc);
+ check_mv_result(&enc);
+
+ free_resource(&enc.fb[0]);
+ free_resource(&enc.bs[0]);
+ free_resource(&enc.vbuf);
+ free_resource(&enc.cpb);
+ free_resource(&enc.mvrefbuf);
+ free_resource(&enc.mvb);
+}
+
+static void amdgpu_cs_vce_destroy(void)
+{
+ int len, r;
+
+ num_resources = 0;
+ alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.fb[0].handle;
+ resources[num_resources++] = ib_handle;
+
+ len = 0;
+ memcpy(ib_cpu, vce_session, sizeof(vce_session));
+ len += sizeof(vce_session) / 4;
+ memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
+ ib_cpu[len + 3] = 1;
+ len += sizeof(vce_taskinfo) / 4;
+ memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
+ ib_cpu[len + 2] = enc.fb[0].addr >> 32;
+ ib_cpu[len + 3] = enc.fb[0].addr;
+ len += sizeof(vce_feedback) / 4;
+ memcpy((ib_cpu + len), vce_destroy, sizeof(vce_destroy));
+ len += sizeof(vce_destroy) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_VCE);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&enc.fb[0]);
+}
diff --git a/tests/amdgpu/vcn_tests.c b/tests/amdgpu/vcn_tests.c
new file mode 100644
index 0000000..c83fdb5
--- /dev/null
+++ b/tests/amdgpu/vcn_tests.c
@@ -0,0 +1,1652 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include "CUnit/Basic.h"
+
+#include <unistd.h>
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "decode_messages.h"
+#include "frame.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+#define DECODE_CMD_MSG_BUFFER 0x00000000
+#define DECODE_CMD_DPB_BUFFER 0x00000001
+#define DECODE_CMD_DECODING_TARGET_BUFFER 0x00000002
+#define DECODE_CMD_FEEDBACK_BUFFER 0x00000003
+#define DECODE_CMD_PROB_TBL_BUFFER 0x00000004
+#define DECODE_CMD_SESSION_CONTEXT_BUFFER 0x00000005
+#define DECODE_CMD_BITSTREAM_BUFFER 0x00000100
+#define DECODE_CMD_IT_SCALING_TABLE_BUFFER 0x00000204
+#define DECODE_CMD_CONTEXT_BUFFER 0x00000206
+
+#define DECODE_IB_PARAM_DECODE_BUFFER (0x00000001)
+
+#define DECODE_CMDBUF_FLAGS_MSG_BUFFER (0x00000001)
+#define DECODE_CMDBUF_FLAGS_DPB_BUFFER (0x00000002)
+#define DECODE_CMDBUF_FLAGS_BITSTREAM_BUFFER (0x00000004)
+#define DECODE_CMDBUF_FLAGS_DECODING_TARGET_BUFFER (0x00000008)
+#define DECODE_CMDBUF_FLAGS_FEEDBACK_BUFFER (0x00000010)
+#define DECODE_CMDBUF_FLAGS_IT_SCALING_BUFFER (0x00000200)
+#define DECODE_CMDBUF_FLAGS_CONTEXT_BUFFER (0x00000800)
+#define DECODE_CMDBUF_FLAGS_PROB_TBL_BUFFER (0x00001000)
+#define DECODE_CMDBUF_FLAGS_SESSION_CONTEXT_BUFFER (0x00100000)
+
+static bool vcn_dec_sw_ring = false;
+static bool vcn_unified_ring = false;
+
+#define H264_NAL_TYPE_NON_IDR_SLICE 1
+#define H264_NAL_TYPE_DP_A_SLICE 2
+#define H264_NAL_TYPE_DP_B_SLICE 3
+#define H264_NAL_TYPE_DP_C_SLICE 0x4
+#define H264_NAL_TYPE_IDR_SLICE 0x5
+#define H264_NAL_TYPE_SEI 0x6
+#define H264_NAL_TYPE_SEQ_PARAM 0x7
+#define H264_NAL_TYPE_PIC_PARAM 0x8
+#define H264_NAL_TYPE_ACCESS_UNIT 0x9
+#define H264_NAL_TYPE_END_OF_SEQ 0xa
+#define H264_NAL_TYPE_END_OF_STREAM 0xb
+#define H264_NAL_TYPE_FILLER_DATA 0xc
+#define H264_NAL_TYPE_SEQ_EXTENSION 0xd
+
+#define H264_START_CODE 0x000001
+
+struct amdgpu_vcn_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+typedef struct rvcn_decode_buffer_s {
+ unsigned int valid_buf_flag;
+ unsigned int msg_buffer_address_hi;
+ unsigned int msg_buffer_address_lo;
+ unsigned int dpb_buffer_address_hi;
+ unsigned int dpb_buffer_address_lo;
+ unsigned int target_buffer_address_hi;
+ unsigned int target_buffer_address_lo;
+ unsigned int session_contex_buffer_address_hi;
+ unsigned int session_contex_buffer_address_lo;
+ unsigned int bitstream_buffer_address_hi;
+ unsigned int bitstream_buffer_address_lo;
+ unsigned int context_buffer_address_hi;
+ unsigned int context_buffer_address_lo;
+ unsigned int feedback_buffer_address_hi;
+ unsigned int feedback_buffer_address_lo;
+ unsigned int luma_hist_buffer_address_hi;
+ unsigned int luma_hist_buffer_address_lo;
+ unsigned int prob_tbl_buffer_address_hi;
+ unsigned int prob_tbl_buffer_address_lo;
+ unsigned int sclr_coeff_buffer_address_hi;
+ unsigned int sclr_coeff_buffer_address_lo;
+ unsigned int it_sclr_table_buffer_address_hi;
+ unsigned int it_sclr_table_buffer_address_lo;
+ unsigned int sclr_target_buffer_address_hi;
+ unsigned int sclr_target_buffer_address_lo;
+ unsigned int cenc_size_info_buffer_address_hi;
+ unsigned int cenc_size_info_buffer_address_lo;
+ unsigned int mpeg2_pic_param_buffer_address_hi;
+ unsigned int mpeg2_pic_param_buffer_address_lo;
+ unsigned int mpeg2_mb_control_buffer_address_hi;
+ unsigned int mpeg2_mb_control_buffer_address_lo;
+ unsigned int mpeg2_idct_coeff_buffer_address_hi;
+ unsigned int mpeg2_idct_coeff_buffer_address_lo;
+} rvcn_decode_buffer_t;
+
+typedef struct rvcn_decode_ib_package_s {
+ unsigned int package_size;
+ unsigned int package_type;
+} rvcn_decode_ib_package_t;
+
+
+struct amdgpu_vcn_reg {
+ uint32_t data0;
+ uint32_t data1;
+ uint32_t cmd;
+ uint32_t nop;
+ uint32_t cntl;
+};
+
+typedef struct BufferInfo_t {
+ uint32_t numOfBitsInBuffer;
+ const uint8_t *decBuffer;
+ uint8_t decData;
+ uint32_t decBufferSize;
+ const uint8_t *end;
+} bufferInfo;
+
+typedef struct h264_decode_t {
+ uint8_t profile;
+ uint8_t level_idc;
+ uint8_t nal_ref_idc;
+ uint8_t nal_unit_type;
+ uint32_t pic_width, pic_height;
+ uint32_t slice_type;
+} h264_decode;
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+static uint32_t asic_id;
+static uint32_t chip_rev;
+static struct amdgpu_vcn_bo enc_buf;
+static struct amdgpu_vcn_bo cpb_buf;
+static uint32_t enc_task_id;
+
+static amdgpu_context_handle context_handle;
+static amdgpu_bo_handle ib_handle;
+static amdgpu_va_handle ib_va_handle;
+static uint64_t ib_mc_address;
+static uint32_t *ib_cpu;
+static uint32_t *ib_checksum;
+static uint32_t *ib_size_in_dw;
+
+static rvcn_decode_buffer_t *decode_buffer;
+struct amdgpu_vcn_bo session_ctx_buf;
+
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static uint8_t vcn_reg_index;
+static struct amdgpu_vcn_reg reg[] = {
+ {0x81c4, 0x81c5, 0x81c3, 0x81ff, 0x81c6},
+ {0x504, 0x505, 0x503, 0x53f, 0x506},
+ {0x10, 0x11, 0xf, 0x29, 0x26d},
+};
+
+uint32_t gWidth, gHeight, gSliceType;
+static uint32_t vcn_ip_version_major;
+static uint32_t vcn_ip_version_minor;
+static void amdgpu_cs_vcn_dec_create(void);
+static void amdgpu_cs_vcn_dec_decode(void);
+static void amdgpu_cs_vcn_dec_destroy(void);
+
+static void amdgpu_cs_vcn_enc_create(void);
+static void amdgpu_cs_vcn_enc_encode(void);
+static void amdgpu_cs_vcn_enc_destroy(void);
+
+static void amdgpu_cs_sq_head(uint32_t *base, int *offset, bool enc);
+static void amdgpu_cs_sq_ib_tail(uint32_t *end);
+static void h264_check_0s (bufferInfo * bufInfo, int count);
+static int32_t h264_se (bufferInfo * bufInfo);
+static inline uint32_t bs_read_u1(bufferInfo *bufinfo);
+static inline int bs_eof(bufferInfo *bufinfo);
+static inline uint32_t bs_read_u(bufferInfo* bufinfo, int n);
+static inline uint32_t bs_read_ue(bufferInfo* bufinfo);
+static uint32_t remove_03 (uint8_t *bptr, uint32_t len);
+static void scaling_list (uint32_t ix, uint32_t sizeOfScalingList, bufferInfo *bufInfo);
+static void h264_parse_sequence_parameter_set (h264_decode * dec, bufferInfo *bufInfo);
+static void h264_slice_header (h264_decode *dec, bufferInfo *bufInfo);
+static uint8_t h264_parse_nal (h264_decode *dec, bufferInfo *bufInfo);
+static uint32_t h264_find_next_start_code (uint8_t *pBuf, uint32_t bufLen);
+static int verify_checksum(uint8_t *buffer, uint32_t buffer_size);
+
+CU_TestInfo vcn_tests[] = {
+
+ { "VCN DEC create", amdgpu_cs_vcn_dec_create },
+ { "VCN DEC decode", amdgpu_cs_vcn_dec_decode },
+ { "VCN DEC destroy", amdgpu_cs_vcn_dec_destroy },
+
+ { "VCN ENC create", amdgpu_cs_vcn_enc_create },
+ { "VCN ENC encode", amdgpu_cs_vcn_enc_encode },
+ { "VCN ENC destroy", amdgpu_cs_vcn_enc_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_vcn_tests_enable(void)
+{
+ struct drm_amdgpu_info_hw_ip info;
+ bool enc_ring, dec_ring;
+ int r;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+ asic_id = device_handle->info.asic_id;
+ chip_rev = device_handle->info.chip_rev;
+ chip_id = device_handle->info.chip_external_rev;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_ENC, 0, &info);
+ if (!r) {
+ vcn_ip_version_major = info.hw_ip_version_major;
+ vcn_ip_version_minor = info.hw_ip_version_minor;
+ enc_ring = !!info.available_rings;
+ /* in vcn 4.0 it re-uses encoding queue as unified queue */
+ if (vcn_ip_version_major >= 4) {
+ vcn_unified_ring = true;
+ vcn_dec_sw_ring = true;
+ dec_ring = enc_ring;
+ } else {
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_DEC, 0, &info);
+ dec_ring = !!info.available_rings;
+ }
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ if (r) {
+ printf("\n\nASIC query hw info failed\n");
+ return CU_FALSE;
+ }
+
+ if (!(dec_ring || enc_ring) ||
+ (family_id < AMDGPU_FAMILY_RV &&
+ (family_id == AMDGPU_FAMILY_AI &&
+ (chip_id - chip_rev) < 0x32))) { /* Arcturus */
+ printf("\n\nThe ASIC NOT support VCN, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ if (!dec_ring) {
+ amdgpu_set_test_active("VCN Tests", "VCN DEC create", CU_FALSE);
+ amdgpu_set_test_active("VCN Tests", "VCN DEC decode", CU_FALSE);
+ amdgpu_set_test_active("VCN Tests", "VCN DEC destroy", CU_FALSE);
+ }
+
+ if (family_id == AMDGPU_FAMILY_AI || !enc_ring) {
+ amdgpu_set_test_active("VCN Tests", "VCN ENC create", CU_FALSE);
+ amdgpu_set_test_active("VCN Tests", "VCN ENC encode", CU_FALSE);
+ amdgpu_set_test_active("VCN Tests", "VCN ENC destroy", CU_FALSE);
+ }
+
+ if (vcn_ip_version_major == 1)
+ vcn_reg_index = 0;
+ else if (vcn_ip_version_major == 2 && vcn_ip_version_minor == 0)
+ vcn_reg_index = 1;
+ else if ((vcn_ip_version_major == 2 && vcn_ip_version_minor >= 5) ||
+ vcn_ip_version_major == 3)
+ vcn_reg_index = 2;
+
+ return CU_TRUE;
+}
+
+int suite_vcn_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = device_handle->info.family_id;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_handle, (void**)&ib_cpu,
+ &ib_mc_address, &ib_va_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+int suite_vcn_tests_clean(void)
+{
+ int r;
+
+ r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
+ ib_mc_address, IB_SIZE);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ r = amdgpu_device_deinitialize(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static void amdgpu_cs_sq_head(uint32_t *base, int *offset, bool enc)
+{
+ /* signature */
+ *(base + (*offset)++) = 0x00000010;
+ *(base + (*offset)++) = 0x30000002;
+ ib_checksum = base + (*offset)++;
+ ib_size_in_dw = base + (*offset)++;
+
+ /* engine info */
+ *(base + (*offset)++) = 0x00000010;
+ *(base + (*offset)++) = 0x30000001;
+ *(base + (*offset)++) = enc ? 2 : 3;
+ *(base + (*offset)++) = 0x00000000;
+}
+
+static void amdgpu_cs_sq_ib_tail(uint32_t *end)
+{
+ uint32_t size_in_dw;
+ uint32_t checksum = 0;
+
+ /* if the pointers are invalid, no need to process */
+ if (ib_checksum == NULL || ib_size_in_dw == NULL)
+ return;
+
+ size_in_dw = end - ib_size_in_dw - 1;
+ *ib_size_in_dw = size_in_dw;
+ *(ib_size_in_dw + 4) = size_in_dw * sizeof(uint32_t);
+
+ for (int i = 0; i < size_in_dw; i++)
+ checksum += *(ib_checksum + 2 + i);
+
+ *ib_checksum = checksum;
+
+ ib_checksum = NULL;
+ ib_size_in_dw = NULL;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info = {0};
+ struct amdgpu_cs_fence fence_status = {0};
+ uint32_t expired;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ if (r)
+ return r;
+
+ r = amdgpu_bo_list_destroy(ibs_request.resources);
+ if (r)
+ return r;
+
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void alloc_resource(struct amdgpu_vcn_bo *vcn_bo,
+ unsigned size, unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ vcn_bo->addr = va;
+ vcn_bo->handle = buf_handle;
+ vcn_bo->size = req.alloc_size;
+ vcn_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(vcn_bo->handle, (void **)&vcn_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vcn_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(vcn_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_vcn_bo *vcn_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(vcn_bo->handle, 0, vcn_bo->size,
+ vcn_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(vcn_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(vcn_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vcn_bo, 0, sizeof(*vcn_bo));
+}
+
+static void vcn_dec_cmd(uint64_t addr, unsigned cmd, int *idx)
+{
+ if (vcn_dec_sw_ring == false) {
+ ib_cpu[(*idx)++] = reg[vcn_reg_index].data0;
+ ib_cpu[(*idx)++] = addr;
+ ib_cpu[(*idx)++] = reg[vcn_reg_index].data1;
+ ib_cpu[(*idx)++] = addr >> 32;
+ ib_cpu[(*idx)++] = reg[vcn_reg_index].cmd;
+ ib_cpu[(*idx)++] = cmd << 1;
+ return;
+ }
+
+ /* Support decode software ring message */
+ if (!(*idx)) {
+ rvcn_decode_ib_package_t *ib_header;
+
+ if (vcn_unified_ring)
+ amdgpu_cs_sq_head(ib_cpu, idx, false);
+
+ ib_header = (rvcn_decode_ib_package_t *)&ib_cpu[*idx];
+ ib_header->package_size = sizeof(struct rvcn_decode_buffer_s) +
+ sizeof(struct rvcn_decode_ib_package_s);
+
+ (*idx)++;
+ ib_header->package_type = (DECODE_IB_PARAM_DECODE_BUFFER);
+ (*idx)++;
+
+ decode_buffer = (rvcn_decode_buffer_t *)&(ib_cpu[*idx]);
+ *idx += sizeof(struct rvcn_decode_buffer_s) / 4;
+ memset(decode_buffer, 0, sizeof(struct rvcn_decode_buffer_s));
+ }
+
+ switch(cmd) {
+ case DECODE_CMD_MSG_BUFFER:
+ decode_buffer->valid_buf_flag |= DECODE_CMDBUF_FLAGS_MSG_BUFFER;
+ decode_buffer->msg_buffer_address_hi = (addr >> 32);
+ decode_buffer->msg_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_DPB_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DPB_BUFFER);
+ decode_buffer->dpb_buffer_address_hi = (addr >> 32);
+ decode_buffer->dpb_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_DECODING_TARGET_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DECODING_TARGET_BUFFER);
+ decode_buffer->target_buffer_address_hi = (addr >> 32);
+ decode_buffer->target_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_FEEDBACK_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_FEEDBACK_BUFFER);
+ decode_buffer->feedback_buffer_address_hi = (addr >> 32);
+ decode_buffer->feedback_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_PROB_TBL_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_PROB_TBL_BUFFER);
+ decode_buffer->prob_tbl_buffer_address_hi = (addr >> 32);
+ decode_buffer->prob_tbl_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_SESSION_CONTEXT_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_SESSION_CONTEXT_BUFFER);
+ decode_buffer->session_contex_buffer_address_hi = (addr >> 32);
+ decode_buffer->session_contex_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_BITSTREAM_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_BITSTREAM_BUFFER);
+ decode_buffer->bitstream_buffer_address_hi = (addr >> 32);
+ decode_buffer->bitstream_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_IT_SCALING_TABLE_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_IT_SCALING_BUFFER);
+ decode_buffer->it_sclr_table_buffer_address_hi = (addr >> 32);
+ decode_buffer->it_sclr_table_buffer_address_lo = (addr);
+ break;
+ case DECODE_CMD_CONTEXT_BUFFER:
+ decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_CONTEXT_BUFFER);
+ decode_buffer->context_buffer_address_hi = (addr >> 32);
+ decode_buffer->context_buffer_address_lo = (addr);
+ break;
+ default:
+ printf("Not Support!\n");
+ }
+}
+
+static void amdgpu_cs_vcn_dec_create(void)
+{
+ struct amdgpu_vcn_bo msg_buf;
+ unsigned ip;
+ int len, r;
+
+ num_resources = 0;
+ alloc_resource(&msg_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
+ alloc_resource(&session_ctx_buf, 32 * 4096, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = msg_buf.handle;
+ resources[num_resources++] = session_ctx_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(msg_buf.ptr, 0, 4096);
+ memcpy(msg_buf.ptr, vcn_dec_create_msg, sizeof(vcn_dec_create_msg));
+
+ len = 0;
+
+ vcn_dec_cmd(session_ctx_buf.addr, 5, &len);
+ if (vcn_dec_sw_ring == true) {
+ vcn_dec_cmd(msg_buf.addr, 0, &len);
+ } else {
+ ib_cpu[len++] = reg[vcn_reg_index].data0;
+ ib_cpu[len++] = msg_buf.addr;
+ ib_cpu[len++] = reg[vcn_reg_index].data1;
+ ib_cpu[len++] = msg_buf.addr >> 32;
+ ib_cpu[len++] = reg[vcn_reg_index].cmd;
+ ib_cpu[len++] = 0;
+ for (; len % 16; ) {
+ ib_cpu[len++] = reg[vcn_reg_index].nop;
+ ib_cpu[len++] = 0;
+ }
+ }
+
+ if (vcn_unified_ring) {
+ amdgpu_cs_sq_ib_tail(ib_cpu + len);
+ ip = AMDGPU_HW_IP_VCN_ENC;
+ } else
+ ip = AMDGPU_HW_IP_VCN_DEC;
+
+ r = submit(len, ip);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&msg_buf);
+}
+
+static void amdgpu_cs_vcn_dec_decode(void)
+{
+ const unsigned dpb_size = 15923584, dt_size = 737280;
+ uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr, sum;
+ struct amdgpu_vcn_bo dec_buf;
+ int size, len, i, r;
+ unsigned ip;
+ uint8_t *dec;
+
+ size = 4*1024; /* msg */
+ size += 4*1024; /* fb */
+ size += 4096; /*it_scaling_table*/
+ size += ALIGN(sizeof(uvd_bitstream), 4*1024);
+ size += ALIGN(dpb_size, 4*1024);
+ size += ALIGN(dt_size, 4*1024);
+
+ num_resources = 0;
+ alloc_resource(&dec_buf, size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = dec_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(dec_buf.handle, (void **)&dec_buf.ptr);
+ dec = dec_buf.ptr;
+
+ CU_ASSERT_EQUAL(r, 0);
+ memset(dec_buf.ptr, 0, size);
+ memcpy(dec_buf.ptr, vcn_dec_decode_msg, sizeof(vcn_dec_decode_msg));
+ memcpy(dec_buf.ptr + sizeof(vcn_dec_decode_msg),
+ avc_decode_msg, sizeof(avc_decode_msg));
+
+ dec += 4*1024;
+ memcpy(dec, feedback_msg, sizeof(feedback_msg));
+ dec += 4*1024;
+ memcpy(dec, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
+
+ dec += 4*1024;
+ memcpy(dec, uvd_bitstream, sizeof(uvd_bitstream));
+
+ dec += ALIGN(sizeof(uvd_bitstream), 4*1024);
+
+ dec += ALIGN(dpb_size, 4*1024);
+
+ msg_addr = dec_buf.addr;
+ fb_addr = msg_addr + 4*1024;
+ it_addr = fb_addr + 4*1024;
+ bs_addr = it_addr + 4*1024;
+ dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
+ ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
+
+ len = 0;
+ vcn_dec_cmd(session_ctx_buf.addr, 0x5, &len);
+ vcn_dec_cmd(msg_addr, 0x0, &len);
+ vcn_dec_cmd(dpb_addr, 0x1, &len);
+ vcn_dec_cmd(dt_addr, 0x2, &len);
+ vcn_dec_cmd(fb_addr, 0x3, &len);
+ vcn_dec_cmd(bs_addr, 0x100, &len);
+ vcn_dec_cmd(it_addr, 0x204, &len);
+ vcn_dec_cmd(ctx_addr, 0x206, &len);
+
+ if (vcn_dec_sw_ring == false) {
+ ib_cpu[len++] = reg[vcn_reg_index].cntl;
+ ib_cpu[len++] = 0x1;
+ for (; len % 16; ) {
+ ib_cpu[len++] = reg[vcn_reg_index].nop;
+ ib_cpu[len++] = 0;
+ }
+ }
+
+ if (vcn_unified_ring) {
+ amdgpu_cs_sq_ib_tail(ib_cpu + len);
+ ip = AMDGPU_HW_IP_VCN_ENC;
+ } else
+ ip = AMDGPU_HW_IP_VCN_DEC;
+
+ r = submit(len, ip);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (i = 0, sum = 0; i < dt_size; ++i)
+ sum += dec[i];
+
+ CU_ASSERT_EQUAL(sum, SUM_DECODE);
+
+ free_resource(&dec_buf);
+}
+
+static void amdgpu_cs_vcn_dec_destroy(void)
+{
+ struct amdgpu_vcn_bo msg_buf;
+ unsigned ip;
+ int len, r;
+
+ num_resources = 0;
+ alloc_resource(&msg_buf, 1024, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = msg_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(msg_buf.ptr, 0, 1024);
+ memcpy(msg_buf.ptr, vcn_dec_destroy_msg, sizeof(vcn_dec_destroy_msg));
+
+ len = 0;
+ vcn_dec_cmd(session_ctx_buf.addr, 5, &len);
+ if (vcn_dec_sw_ring == true) {
+ vcn_dec_cmd(msg_buf.addr, 0, &len);
+ } else {
+ ib_cpu[len++] = reg[vcn_reg_index].data0;
+ ib_cpu[len++] = msg_buf.addr;
+ ib_cpu[len++] = reg[vcn_reg_index].data1;
+ ib_cpu[len++] = msg_buf.addr >> 32;
+ ib_cpu[len++] = reg[vcn_reg_index].cmd;
+ ib_cpu[len++] = 0;
+ for (; len % 16; ) {
+ ib_cpu[len++] = reg[vcn_reg_index].nop;
+ ib_cpu[len++] = 0;
+ }
+ }
+
+ if (vcn_unified_ring) {
+ amdgpu_cs_sq_ib_tail(ib_cpu + len);
+ ip = AMDGPU_HW_IP_VCN_ENC;
+ } else
+ ip = AMDGPU_HW_IP_VCN_DEC;
+
+ r = submit(len, ip);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&msg_buf);
+ free_resource(&session_ctx_buf);
+}
+
+static void amdgpu_cs_vcn_enc_create(void)
+{
+ int len, r;
+ uint32_t *p_task_size = NULL;
+ uint32_t task_offset = 0, st_offset;
+ uint32_t *st_size = NULL;
+ unsigned width = 160, height = 128, buf_size;
+ uint32_t fw_maj = 1, fw_min = 9;
+
+ if (vcn_ip_version_major == 2) {
+ fw_maj = 1;
+ fw_min = 1;
+ } else if (vcn_ip_version_major == 3) {
+ fw_maj = 1;
+ fw_min = 0;
+ }
+
+ gWidth = width;
+ gHeight = height;
+ buf_size = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2;
+ enc_task_id = 1;
+
+ num_resources = 0;
+ alloc_resource(&enc_buf, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT);
+ alloc_resource(&cpb_buf, buf_size * 2, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc_buf.handle;
+ resources[num_resources++] = cpb_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(enc_buf.handle, (void**)&enc_buf.ptr);
+ memset(enc_buf.ptr, 0, 128 * 1024);
+ r = amdgpu_bo_cpu_unmap(enc_buf.handle);
+
+ r = amdgpu_bo_cpu_map(cpb_buf.handle, (void**)&enc_buf.ptr);
+ memset(enc_buf.ptr, 0, buf_size * 2);
+ r = amdgpu_bo_cpu_unmap(cpb_buf.handle);
+
+ len = 0;
+
+ if (vcn_unified_ring)
+ amdgpu_cs_sq_head(ib_cpu, &len, true);
+
+ /* session info */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000001; /* RENCODE_IB_PARAM_SESSION_INFO */
+ ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0));
+ ib_cpu[len++] = enc_buf.addr >> 32;
+ ib_cpu[len++] = enc_buf.addr;
+ ib_cpu[len++] = 1; /* RENCODE_ENGINE_TYPE_ENCODE; */
+ *st_size = (len - st_offset) * 4;
+
+ /* task info */
+ task_offset = len;
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000002; /* RENCODE_IB_PARAM_TASK_INFO */
+ p_task_size = &ib_cpu[len++];
+ ib_cpu[len++] = enc_task_id++; /* task_id */
+ ib_cpu[len++] = 0; /* feedback */
+ *st_size = (len - st_offset) * 4;
+
+ /* op init */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x01000001; /* RENCODE_IB_OP_INITIALIZE */
+ *st_size = (len - st_offset) * 4;
+
+ /* session_init */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000003; /* RENCODE_IB_PARAM_SESSION_INIT */
+ ib_cpu[len++] = 1; /* RENCODE_ENCODE_STANDARD_H264 */
+ ib_cpu[len++] = width;
+ ib_cpu[len++] = height;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 0; /* pre encode mode */
+ ib_cpu[len++] = 0; /* chroma enabled : false */
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 0;
+ *st_size = (len - st_offset) * 4;
+
+ /* slice control */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00200001; /* RENCODE_H264_IB_PARAM_SLICE_CONTROL */
+ ib_cpu[len++] = 0; /* RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS */
+ ib_cpu[len++] = ALIGN(width, 16) / 16 * ALIGN(height, 16) / 16;
+ *st_size = (len - st_offset) * 4;
+
+ /* enc spec misc */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00200002; /* RENCODE_H264_IB_PARAM_SPEC_MISC */
+ ib_cpu[len++] = 0; /* constrained intra pred flag */
+ ib_cpu[len++] = 0; /* cabac enable */
+ ib_cpu[len++] = 0; /* cabac init idc */
+ ib_cpu[len++] = 1; /* half pel enabled */
+ ib_cpu[len++] = 1; /* quarter pel enabled */
+ ib_cpu[len++] = 100; /* BASELINE profile */
+ ib_cpu[len++] = 11; /* level */
+ if (vcn_ip_version_major >= 3) {
+ ib_cpu[len++] = 0; /* b_picture_enabled */
+ ib_cpu[len++] = 0; /* weighted_bipred_idc */
+ }
+ *st_size = (len - st_offset) * 4;
+
+ /* deblocking filter */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00200004; /* RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER */
+ ib_cpu[len++] = 0; /* disable deblocking filter idc */
+ ib_cpu[len++] = 0; /* alpha c0 offset */
+ ib_cpu[len++] = 0; /* tc offset */
+ ib_cpu[len++] = 0; /* cb offset */
+ ib_cpu[len++] = 0; /* cr offset */
+ *st_size = (len - st_offset) * 4;
+
+ /* layer control */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000004; /* RENCODE_IB_PARAM_LAYER_CONTROL */
+ ib_cpu[len++] = 1; /* max temporal layer */
+ ib_cpu[len++] = 1; /* no of temporal layer */
+ *st_size = (len - st_offset) * 4;
+
+ /* rc_session init */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000006; /* RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT */
+ ib_cpu[len++] = 0; /* rate control */
+ ib_cpu[len++] = 48; /* vbv buffer level */
+ *st_size = (len - st_offset) * 4;
+
+ /* quality params */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000009; /* RENCODE_IB_PARAM_QUALITY_PARAMS */
+ ib_cpu[len++] = 0; /* vbaq mode */
+ ib_cpu[len++] = 0; /* scene change sensitivity */
+ ib_cpu[len++] = 0; /* scene change min idr interval */
+ ib_cpu[len++] = 0;
+ if (vcn_ip_version_major >= 3)
+ ib_cpu[len++] = 0;
+ *st_size = (len - st_offset) * 4;
+
+ /* layer select */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000005; /* RENCODE_IB_PARAM_LAYER_SELECT */
+ ib_cpu[len++] = 0; /* temporal layer */
+ *st_size = (len - st_offset) * 4;
+
+ /* rc layer init */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000007; /* RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT */
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 25;
+ ib_cpu[len++] = 1;
+ ib_cpu[len++] = 0x01312d00;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 0;
+ *st_size = (len - st_offset) * 4;
+
+ /* layer select */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000005; /* RENCODE_IB_PARAM_LAYER_SELECT */
+ ib_cpu[len++] = 0; /* temporal layer */
+ *st_size = (len - st_offset) * 4;
+
+ /* rc per pic */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000008; /* RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE */
+ ib_cpu[len++] = 20;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 51;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 1;
+ ib_cpu[len++] = 0;
+ ib_cpu[len++] = 1;
+ ib_cpu[len++] = 0;
+ *st_size = (len - st_offset) * 4;
+
+ /* op init rc */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x01000004; /* RENCODE_IB_OP_INIT_RC */
+ *st_size = (len - st_offset) * 4;
+
+ /* op init rc vbv */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x01000005; /* RENCODE_IB_OP_INIT_RC_VBV_BUFFER_LEVEL */
+ *st_size = (len - st_offset) * 4;
+
+ *p_task_size = (len - task_offset) * 4;
+
+ if (vcn_unified_ring)
+ amdgpu_cs_sq_ib_tail(ib_cpu + len);
+
+ r = submit(len, AMDGPU_HW_IP_VCN_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static int32_t h264_se (bufferInfo * bufInfo)
+{
+ uint32_t ret;
+
+ ret = bs_read_ue (bufInfo);
+ if ((ret & 0x1) == 0) {
+ ret >>= 1;
+ int32_t temp = 0 - ret;
+ return temp;
+ }
+
+ return (ret + 1) >> 1;
+}
+
+static void h264_check_0s (bufferInfo * bufInfo, int count)
+{
+ uint32_t val;
+
+ val = bs_read_u (bufInfo, count);
+ if (val != 0) {
+ printf ("field error - %d bits should be 0 is %x\n", count, val);
+ }
+}
+
+static inline int bs_eof(bufferInfo * bufinfo)
+{
+ if (bufinfo->decBuffer >= bufinfo->end)
+ return 1;
+ else
+ return 0;
+}
+
+static inline uint32_t bs_read_u1(bufferInfo *bufinfo)
+{
+ uint32_t r = 0;
+ uint32_t temp = 0;
+
+ bufinfo->numOfBitsInBuffer--;
+ if (! bs_eof(bufinfo)) {
+ temp = (((bufinfo->decData)) >> bufinfo->numOfBitsInBuffer);
+ r = temp & 0x01;
+ }
+
+ if (bufinfo->numOfBitsInBuffer == 0) {
+ bufinfo->decBuffer++;
+ bufinfo->decData = *bufinfo->decBuffer;
+ bufinfo->numOfBitsInBuffer = 8;
+ }
+
+ return r;
+}
+
+static inline uint32_t bs_read_u(bufferInfo* bufinfo, int n)
+{
+ uint32_t r = 0;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ r |= ( bs_read_u1(bufinfo) << ( n - i - 1 ) );
+ }
+
+ return r;
+}
+
+static inline uint32_t bs_read_ue(bufferInfo* bufinfo)
+{
+ int32_t r = 0;
+ int i = 0;
+
+ while( (bs_read_u1(bufinfo) == 0) && (i < 32) && (!bs_eof(bufinfo))) {
+ i++;
+ }
+ r = bs_read_u(bufinfo, i);
+ r += (1 << i) - 1;
+ return r;
+}
+
+static uint32_t remove_03 (uint8_t * bptr, uint32_t len)
+{
+ uint32_t nal_len = 0;
+ while (nal_len + 2 < len) {
+ if (bptr[0] == 0 && bptr[1] == 0 && bptr[2] == 3) {
+ bptr += 2;
+ nal_len += 2;
+ len--;
+ memmove (bptr, bptr + 1, len - nal_len);
+ } else {
+ bptr++;
+ nal_len++;
+ }
+ }
+ return len;
+}
+
+static void scaling_list (uint32_t ix, uint32_t sizeOfScalingList, bufferInfo * bufInfo)
+{
+ uint32_t lastScale = 8, nextScale = 8;
+ uint32_t jx;
+ int deltaScale;
+
+ for (jx = 0; jx < sizeOfScalingList; jx++) {
+ if (nextScale != 0) {
+ deltaScale = h264_se (bufInfo);
+ nextScale = (lastScale + deltaScale + 256) % 256;
+ }
+ if (nextScale == 0) {
+ lastScale = lastScale;
+ } else {
+ lastScale = nextScale;
+ }
+ }
+}
+
+static void h264_parse_sequence_parameter_set (h264_decode * dec, bufferInfo * bufInfo)
+{
+ uint32_t temp;
+
+ dec->profile = bs_read_u (bufInfo, 8);
+ bs_read_u (bufInfo, 1); /* constaint_set0_flag */
+ bs_read_u (bufInfo, 1); /* constaint_set1_flag */
+ bs_read_u (bufInfo, 1); /* constaint_set2_flag */
+ bs_read_u (bufInfo, 1); /* constaint_set3_flag */
+ bs_read_u (bufInfo, 1); /* constaint_set4_flag */
+ bs_read_u (bufInfo, 1); /* constaint_set5_flag */
+
+
+ h264_check_0s (bufInfo, 2);
+ dec->level_idc = bs_read_u (bufInfo, 8);
+ bs_read_ue (bufInfo); /* SPS id*/
+
+ if (dec->profile == 100 || dec->profile == 110 ||
+ dec->profile == 122 || dec->profile == 144) {
+ uint32_t chroma_format_idc = bs_read_ue (bufInfo);
+ if (chroma_format_idc == 3) {
+ bs_read_u (bufInfo, 1); /* residual_colour_transform_flag */
+ }
+ bs_read_ue (bufInfo); /* bit_depth_luma_minus8 */
+ bs_read_ue (bufInfo); /* bit_depth_chroma_minus8 */
+ bs_read_u (bufInfo, 1); /* qpprime_y_zero_transform_bypass_flag */
+ uint32_t seq_scaling_matrix_present_flag = bs_read_u (bufInfo, 1);
+
+ if (seq_scaling_matrix_present_flag) {
+ for (uint32_t ix = 0; ix < 8; ix++) {
+ temp = bs_read_u (bufInfo, 1);
+ if (temp) {
+ scaling_list (ix, ix < 6 ? 16 : 64, bufInfo);
+ }
+ }
+ }
+ }
+
+ bs_read_ue (bufInfo); /* log2_max_frame_num_minus4 */
+ uint32_t pic_order_cnt_type = bs_read_ue (bufInfo);
+
+ if (pic_order_cnt_type == 0) {
+ bs_read_ue (bufInfo); /* log2_max_pic_order_cnt_lsb_minus4 */
+ } else if (pic_order_cnt_type == 1) {
+ bs_read_u (bufInfo, 1); /* delta_pic_order_always_zero_flag */
+ h264_se (bufInfo); /* offset_for_non_ref_pic */
+ h264_se (bufInfo); /* offset_for_top_to_bottom_field */
+ temp = bs_read_ue (bufInfo);
+ for (uint32_t ix = 0; ix < temp; ix++) {
+ h264_se (bufInfo); /* offset_for_ref_frame[index] */
+ }
+ }
+ bs_read_ue (bufInfo); /* num_ref_frames */
+ bs_read_u (bufInfo, 1); /* gaps_in_frame_num_flag */
+ uint32_t PicWidthInMbs = bs_read_ue (bufInfo) + 1;
+
+ dec->pic_width = PicWidthInMbs * 16;
+ uint32_t PicHeightInMapUnits = bs_read_ue (bufInfo) + 1;
+
+ dec->pic_height = PicHeightInMapUnits * 16;
+ uint32_t frame_mbs_only_flag = bs_read_u (bufInfo, 1);
+ if (!frame_mbs_only_flag) {
+ bs_read_u (bufInfo, 1); /* mb_adaptive_frame_field_flag */
+ }
+ bs_read_u (bufInfo, 1); /* direct_8x8_inference_flag */
+ temp = bs_read_u (bufInfo, 1);
+ if (temp) {
+ bs_read_ue (bufInfo); /* frame_crop_left_offset */
+ bs_read_ue (bufInfo); /* frame_crop_right_offset */
+ bs_read_ue (bufInfo); /* frame_crop_top_offset */
+ bs_read_ue (bufInfo); /* frame_crop_bottom_offset */
+ }
+ temp = bs_read_u (bufInfo, 1); /* VUI Parameters */
+}
+
+static void h264_slice_header (h264_decode * dec, bufferInfo * bufInfo)
+{
+ uint32_t temp;
+
+ bs_read_ue (bufInfo); /* first_mb_in_slice */
+ temp = bs_read_ue (bufInfo);
+ dec->slice_type = ((temp > 5) ? (temp - 5) : temp);
+}
+
+static uint8_t h264_parse_nal (h264_decode * dec, bufferInfo * bufInfo)
+{
+ uint8_t type = 0;
+
+ h264_check_0s (bufInfo, 1);
+ dec->nal_ref_idc = bs_read_u (bufInfo, 2);
+ dec->nal_unit_type = type = bs_read_u (bufInfo, 5);
+ switch (type)
+ {
+ case H264_NAL_TYPE_NON_IDR_SLICE:
+ case H264_NAL_TYPE_IDR_SLICE:
+ h264_slice_header (dec, bufInfo);
+ break;
+ case H264_NAL_TYPE_SEQ_PARAM:
+ h264_parse_sequence_parameter_set (dec, bufInfo);
+ break;
+ case H264_NAL_TYPE_PIC_PARAM:
+ case H264_NAL_TYPE_SEI:
+ case H264_NAL_TYPE_ACCESS_UNIT:
+ case H264_NAL_TYPE_SEQ_EXTENSION:
+ /* NOP */
+ break;
+ default:
+ printf ("Nal type unknown %d \n ", type);
+ break;
+ }
+ return type;
+}
+
+static uint32_t h264_find_next_start_code (uint8_t * pBuf, uint32_t bufLen)
+{
+ uint32_t val;
+ uint32_t offset, startBytes;
+
+ offset = startBytes = 0;
+ if (pBuf[0] == 0 && pBuf[1] == 0 && pBuf[2] == 0 && pBuf[3] == 1) {
+ pBuf += 4;
+ offset = 4;
+ startBytes = 1;
+ } else if (pBuf[0] == 0 && pBuf[1] == 0 && pBuf[2] == 1) {
+ pBuf += 3;
+ offset = 3;
+ startBytes = 1;
+ }
+ val = 0xffffffff;
+ while (offset < bufLen - 3) {
+ val <<= 8;
+ val |= *pBuf++;
+ offset++;
+ if (val == H264_START_CODE)
+ return offset - 4;
+
+ if ((val & 0x00ffffff) == H264_START_CODE)
+ return offset - 3;
+ }
+ if (bufLen - offset <= 3 && startBytes == 0) {
+ startBytes = 0;
+ return 0;
+ }
+
+ return offset;
+}
+
+static int verify_checksum(uint8_t *buffer, uint32_t buffer_size)
+{
+ uint32_t buffer_pos = 0;
+ int done = 0;
+ h264_decode dec;
+
+ memset(&dec, 0, sizeof(h264_decode));
+ do {
+ uint32_t ret;
+
+ ret = h264_find_next_start_code (buffer + buffer_pos,
+ buffer_size - buffer_pos);
+ if (ret == 0) {
+ done = 1;
+ if (buffer_pos == 0) {
+ fprintf (stderr,
+ "couldn't find start code in buffer from 0\n");
+ }
+ } else {
+ /* have a complete NAL from buffer_pos to end */
+ if (ret > 3) {
+ uint32_t nal_len;
+ bufferInfo bufinfo;
+
+ nal_len = remove_03 (buffer + buffer_pos, ret);
+ bufinfo.decBuffer = buffer + buffer_pos + (buffer[buffer_pos + 2] == 1 ? 3 : 4);
+ bufinfo.decBufferSize = (nal_len - (buffer[buffer_pos + 2] == 1 ? 3 : 4)) * 8;
+ bufinfo.end = buffer + buffer_pos + nal_len;
+ bufinfo.numOfBitsInBuffer = 8;
+ bufinfo.decData = *bufinfo.decBuffer;
+ h264_parse_nal (&dec, &bufinfo);
+ }
+ buffer_pos += ret; /* buffer_pos points to next code */
+ }
+ } while (done == 0);
+
+ if ((dec.pic_width == gWidth) &&
+ (dec.pic_height == gHeight) &&
+ (dec.slice_type == gSliceType))
+ return 0;
+ else
+ return -1;
+}
+
+static void check_result(struct amdgpu_vcn_bo fb_buf, struct amdgpu_vcn_bo bs_buf, int frame_type)
+{
+ uint32_t *fb_ptr;
+ uint8_t *bs_ptr;
+ uint32_t size;
+ int r;
+/* uint64_t s[3] = {0, 1121279001727, 1059312481445}; */
+
+ r = amdgpu_bo_cpu_map(fb_buf.handle, (void **)&fb_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ fb_ptr = (uint32_t*)fb_buf.ptr;
+ size = fb_ptr[6];
+ r = amdgpu_bo_cpu_unmap(fb_buf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_map(bs_buf.handle, (void **)&bs_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ bs_ptr = (uint8_t*)bs_buf.ptr;
+ r = verify_checksum(bs_ptr, size);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_unmap(bs_buf.handle);
+
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_vcn_ib_zero_count(int *len, int num)
+{
+ for (int i = 0; i < num; i++)
+ ib_cpu[(*len)++] = 0;
+}
+
+static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
+{
+ struct amdgpu_vcn_bo bs_buf, fb_buf, input_buf;
+ int len, r;
+ unsigned width = 160, height = 128, buf_size;
+ uint32_t *p_task_size = NULL;
+ uint32_t task_offset = 0, st_offset;
+ uint32_t *st_size = NULL;
+ uint32_t fw_maj = 1, fw_min = 9;
+
+ if (vcn_ip_version_major == 2) {
+ fw_maj = 1;
+ fw_min = 1;
+ } else if (vcn_ip_version_major == 3) {
+ fw_maj = 1;
+ fw_min = 0;
+ }
+ gSliceType = frame_type;
+ buf_size = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2;
+
+ num_resources = 0;
+ alloc_resource(&bs_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
+ alloc_resource(&fb_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
+ alloc_resource(&input_buf, buf_size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc_buf.handle;
+ resources[num_resources++] = cpb_buf.handle;
+ resources[num_resources++] = bs_buf.handle;
+ resources[num_resources++] = fb_buf.handle;
+ resources[num_resources++] = input_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+
+ r = amdgpu_bo_cpu_map(bs_buf.handle, (void**)&bs_buf.ptr);
+ memset(bs_buf.ptr, 0, 4096);
+ r = amdgpu_bo_cpu_unmap(bs_buf.handle);
+
+ r = amdgpu_bo_cpu_map(fb_buf.handle, (void**)&fb_buf.ptr);
+ memset(fb_buf.ptr, 0, 4096);
+ r = amdgpu_bo_cpu_unmap(fb_buf.handle);
+
+ r = amdgpu_bo_cpu_map(input_buf.handle, (void **)&input_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (int i = 0; i < ALIGN(height, 32) * 3 / 2; i++)
+ memcpy(input_buf.ptr + i * ALIGN(width, 256), frame + i * width, width);
+
+ r = amdgpu_bo_cpu_unmap(input_buf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ len = 0;
+
+ if (vcn_unified_ring)
+ amdgpu_cs_sq_head(ib_cpu, &len, true);
+
+ /* session info */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000001; /* RENCODE_IB_PARAM_SESSION_INFO */
+ ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0));
+ ib_cpu[len++] = enc_buf.addr >> 32;
+ ib_cpu[len++] = enc_buf.addr;
+ ib_cpu[len++] = 1; /* RENCODE_ENGINE_TYPE_ENCODE */;
+ *st_size = (len - st_offset) * 4;
+
+ /* task info */
+ task_offset = len;
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000002; /* RENCODE_IB_PARAM_TASK_INFO */
+ p_task_size = &ib_cpu[len++];
+ ib_cpu[len++] = enc_task_id++; /* task_id */
+ ib_cpu[len++] = 1; /* feedback */
+ *st_size = (len - st_offset) * 4;
+
+ if (frame_type == 2) {
+ /* sps */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x00000020; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1 */
+ else
+ ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU other vcn */
+ ib_cpu[len++] = 0x00000002; /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS */
+ ib_cpu[len++] = 0x00000011; /* sps len */
+ ib_cpu[len++] = 0x00000001; /* start code */
+ ib_cpu[len++] = 0x6764440b;
+ ib_cpu[len++] = 0xac54c284;
+ ib_cpu[len++] = 0x68078442;
+ ib_cpu[len++] = 0x37000000;
+ *st_size = (len - st_offset) * 4;
+
+ /* pps */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x00000020; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1*/
+ else
+ ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU other vcn*/
+ ib_cpu[len++] = 0x00000003; /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS */
+ ib_cpu[len++] = 0x00000008; /* pps len */
+ ib_cpu[len++] = 0x00000001; /* start code */
+ ib_cpu[len++] = 0x68ce3c80;
+ *st_size = (len - st_offset) * 4;
+ }
+
+ /* slice header */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_SLICE_HEADER vcn 1 */
+ else
+ ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_SLICE_HEADER other vcn */
+ if (frame_type == 2) {
+ ib_cpu[len++] = 0x65000000;
+ ib_cpu[len++] = 0x11040000;
+ } else {
+ ib_cpu[len++] = 0x41000000;
+ ib_cpu[len++] = 0x34210000;
+ }
+ ib_cpu[len++] = 0xe0000000;
+ amdgpu_cs_vcn_ib_zero_count(&len, 13);
+
+ ib_cpu[len++] = 0x00000001;
+ ib_cpu[len++] = 0x00000008;
+ ib_cpu[len++] = 0x00020000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000001;
+ ib_cpu[len++] = 0x00000015;
+ ib_cpu[len++] = 0x00020001;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000001;
+ ib_cpu[len++] = 0x00000003;
+ amdgpu_cs_vcn_ib_zero_count(&len, 22);
+ *st_size = (len - st_offset) * 4;
+
+ /* encode params */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_ENCODE_PARAMS vcn 1 */
+ else
+ ib_cpu[len++] = 0x0000000f; /* RENCODE_IB_PARAM_ENCODE_PARAMS other vcn */
+ ib_cpu[len++] = frame_type;
+ ib_cpu[len++] = 0x0001f000;
+ ib_cpu[len++] = input_buf.addr >> 32;
+ ib_cpu[len++] = input_buf.addr;
+ ib_cpu[len++] = (input_buf.addr + ALIGN(width, 256) * ALIGN(height, 32)) >> 32;
+ ib_cpu[len++] = input_buf.addr + ALIGN(width, 256) * ALIGN(height, 32);
+ ib_cpu[len++] = 0x00000100;
+ ib_cpu[len++] = 0x00000080;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0xffffffff;
+ ib_cpu[len++] = 0x00000000;
+ *st_size = (len - st_offset) * 4;
+
+ /* encode params h264 */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00200003; /* RENCODE_H264_IB_PARAM_ENCODE_PARAMS */
+ if (vcn_ip_version_major <= 2) {
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0xffffffff;
+ } else {
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0xffffffff;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0xffffffff;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000001;
+ }
+ *st_size = (len - st_offset) * 4;
+
+ /* encode context */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x0000000d; /* ENCODE_CONTEXT_BUFFER vcn 1 */
+ else
+ ib_cpu[len++] = 0x00000011; /* ENCODE_CONTEXT_BUFFER other vcn */
+ ib_cpu[len++] = cpb_buf.addr >> 32;
+ ib_cpu[len++] = cpb_buf.addr;
+ ib_cpu[len++] = 0x00000000; /* swizzle mode */
+ ib_cpu[len++] = 0x00000100; /* luma pitch */
+ ib_cpu[len++] = 0x00000100; /* chroma pitch */
+ ib_cpu[len++] = 0x00000002; /* no reconstructed picture */
+ ib_cpu[len++] = 0x00000000; /* reconstructed pic 1 luma offset */
+ ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32); /* pic1 chroma offset */
+ if(vcn_ip_version_major == 4)
+ amdgpu_cs_vcn_ib_zero_count(&len, 2);
+ ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2; /* pic2 luma offset */
+ ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 5 / 2; /* pic2 chroma offset */
+
+ amdgpu_cs_vcn_ib_zero_count(&len, 280);
+ *st_size = (len - st_offset) * 4;
+
+ /* bitstream buffer */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x0000000e; /* VIDEO_BITSTREAM_BUFFER vcn 1 */
+ else
+ ib_cpu[len++] = 0x00000012; /* VIDEO_BITSTREAM_BUFFER other vcn */
+
+ ib_cpu[len++] = 0x00000000; /* mode */
+ ib_cpu[len++] = bs_buf.addr >> 32;
+ ib_cpu[len++] = bs_buf.addr;
+ ib_cpu[len++] = 0x0001f000;
+ ib_cpu[len++] = 0x00000000;
+ *st_size = (len - st_offset) * 4;
+
+ /* feedback */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x00000010; /* FEEDBACK_BUFFER vcn 1 */
+ else
+ ib_cpu[len++] = 0x00000015; /* FEEDBACK_BUFFER vcn 2,3 */
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = fb_buf.addr >> 32;
+ ib_cpu[len++] = fb_buf.addr;
+ ib_cpu[len++] = 0x00000010;
+ ib_cpu[len++] = 0x00000028;
+ *st_size = (len - st_offset) * 4;
+
+ /* intra refresh */
+ st_offset = len;
+ st_size = &ib_cpu[len++];
+ if(vcn_ip_version_major == 1)
+ ib_cpu[len++] = 0x0000000c; /* INTRA_REFRESH vcn 1 */
+ else
+ ib_cpu[len++] = 0x00000010; /* INTRA_REFRESH vcn 2,3 */
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ *st_size = (len - st_offset) * 4;
+
+ if(vcn_ip_version_major != 1) {
+ /* Input Format */
+ st_offset = len;
+ st_size = &ib_cpu[len++];
+ ib_cpu[len++] = 0x0000000c;
+ ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_VOLUME_G22_BT709 */
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_BIT_DEPTH_8_BIT */
+ ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_PACKING_FORMAT_NV12 */
+ *st_size = (len - st_offset) * 4;
+
+ /* Output Format */
+ st_offset = len;
+ st_size = &ib_cpu[len++];
+ ib_cpu[len++] = 0x0000000d;
+ ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_VOLUME_G22_BT709 */
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_BIT_DEPTH_8_BIT */
+ *st_size = (len - st_offset) * 4;
+ }
+ /* op_speed */
+ st_offset = len;
+ st_size = &ib_cpu[len++];
+ ib_cpu[len++] = 0x01000006; /* SPEED_ENCODING_MODE */
+ *st_size = (len - st_offset) * 4;
+
+ /* op_enc */
+ st_offset = len;
+ st_size = &ib_cpu[len++];
+ ib_cpu[len++] = 0x01000003;
+ *st_size = (len - st_offset) * 4;
+
+ *p_task_size = (len - task_offset) * 4;
+
+ if (vcn_unified_ring)
+ amdgpu_cs_sq_ib_tail(ib_cpu + len);
+
+ r = submit(len, AMDGPU_HW_IP_VCN_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* check result */
+ check_result(fb_buf, bs_buf, frame_type);
+
+ free_resource(&fb_buf);
+ free_resource(&bs_buf);
+ free_resource(&input_buf);
+}
+
+static void amdgpu_cs_vcn_enc_encode(void)
+{
+ amdgpu_cs_vcn_enc_encode_frame(2); /* IDR frame */
+}
+
+static void amdgpu_cs_vcn_enc_destroy(void)
+{
+ int len = 0, r;
+ uint32_t *p_task_size = NULL;
+ uint32_t task_offset = 0, st_offset;
+ uint32_t *st_size = NULL;
+ uint32_t fw_maj = 1, fw_min = 9;
+
+ if (vcn_ip_version_major == 2) {
+ fw_maj = 1;
+ fw_min = 1;
+ } else if (vcn_ip_version_major == 3) {
+ fw_maj = 1;
+ fw_min = 0;
+ }
+
+ num_resources = 0;
+/* alloc_resource(&enc_buf, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT); */
+ resources[num_resources++] = enc_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ if (vcn_unified_ring)
+ amdgpu_cs_sq_head(ib_cpu, &len, true);
+
+ /* session info */
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000001; /* RENCODE_IB_PARAM_SESSION_INFO */
+ ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0));
+ ib_cpu[len++] = enc_buf.addr >> 32;
+ ib_cpu[len++] = enc_buf.addr;
+ ib_cpu[len++] = 1; /* RENCODE_ENGINE_TYPE_ENCODE; */
+ *st_size = (len - st_offset) * 4;
+
+ /* task info */
+ task_offset = len;
+ st_offset = len;
+ st_size = &ib_cpu[len++]; /* size */
+ ib_cpu[len++] = 0x00000002; /* RENCODE_IB_PARAM_TASK_INFO */
+ p_task_size = &ib_cpu[len++];
+ ib_cpu[len++] = enc_task_id++; /* task_id */
+ ib_cpu[len++] = 0; /* feedback */
+ *st_size = (len - st_offset) * 4;
+
+ /* op close */
+ st_offset = len;
+ st_size = &ib_cpu[len++];
+ ib_cpu[len++] = 0x01000002; /* RENCODE_IB_OP_CLOSE_SESSION */
+ *st_size = (len - st_offset) * 4;
+
+ *p_task_size = (len - task_offset) * 4;
+
+ if (vcn_unified_ring)
+ amdgpu_cs_sq_ib_tail(ib_cpu + len);
+
+ r = submit(len, AMDGPU_HW_IP_VCN_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&cpb_buf);
+ free_resource(&enc_buf);
+}
diff --git a/tests/amdgpu/vm_tests.c b/tests/amdgpu/vm_tests.c
new file mode 100644
index 0000000..b94999c
--- /dev/null
+++ b/tests/amdgpu/vm_tests.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_id;
+static uint32_t chip_id;
+static uint32_t chip_rev;
+
+static void amdgpu_vmid_reserve_test(void);
+static void amdgpu_vm_unaligned_map(void);
+static void amdgpu_vm_mapping_test(void);
+
+CU_BOOL suite_vm_tests_enable(void)
+{
+ CU_BOOL enable = CU_TRUE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ if (device_handle->info.family_id == AMDGPU_FAMILY_SI) {
+ printf("\n\nCurrently hangs the CP on this ASIC, VM suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_vm_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_vm_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo vm_tests[] = {
+ { "resere vmid test", amdgpu_vmid_reserve_test },
+ { "unaligned map", amdgpu_vm_unaligned_map },
+ { "vm mapping test", amdgpu_vm_mapping_test },
+ CU_TEST_INFO_NULL,
+};
+
+static void amdgpu_vmid_reserve_test(void)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired, flags;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ static uint32_t *ptr;
+ struct amdgpu_gpu_info gpu_info = {0};
+ unsigned gc_ip_type;
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ family_id = device_handle->info.family_id;
+ chip_id = device_handle->info.chip_external_rev;
+ chip_rev = device_handle->info.chip_rev;
+
+ gc_ip_type = (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) ?
+ AMDGPU_HW_IP_COMPUTE : AMDGPU_HW_IP_GFX;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ flags = 0;
+ r = amdgpu_vm_reserve_vmid(device_handle, flags);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+
+ for (i = 0; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = gc_ip_type;
+ ibs_request.ring = 0;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.resources = bo_list;
+ ibs_request.fence_info.handle = NULL;
+
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = gc_ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.ring = 0;
+ fence_status.fence = ibs_request.seq_no;
+
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,0, &expired);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
+ ib_result_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ flags = 0;
+ r = amdgpu_vm_unreserve_vmid(device_handle, flags);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_vm_unaligned_map(void)
+{
+ const uint64_t map_size = (4ULL << 30) - (2 << 12);
+ struct amdgpu_bo_alloc_request request = {};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle handle;
+ uint64_t vmc_addr;
+ int r;
+
+ request.alloc_size = 4ULL << 30;
+ request.phys_alignment = 4096;
+ request.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;
+ request.flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+
+ r = amdgpu_bo_alloc(device_handle, &request, &buf_handle);
+ /* Don't let the test fail if the device doesn't have enough VRAM */
+ if (r)
+ return;
+
+ r = amdgpu_va_range_alloc(device_handle, amdgpu_gpu_va_range_general,
+ 4ULL << 30, 1ULL << 30, 0, &vmc_addr,
+ &handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_va_alloc;
+
+ vmc_addr += 1 << 12;
+
+ r = amdgpu_bo_va_op(buf_handle, 0, map_size, vmc_addr, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_va_alloc;
+
+ amdgpu_bo_va_op(buf_handle, 0, map_size, vmc_addr, 0,
+ AMDGPU_VA_OP_UNMAP);
+
+error_va_alloc:
+ amdgpu_bo_free(buf_handle);
+}
+
+static void amdgpu_vm_mapping_test(void)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ struct drm_amdgpu_info_device dev_info;
+ const uint64_t size = 4096;
+ amdgpu_bo_handle buf;
+ uint64_t addr;
+ int r;
+
+ req.alloc_size = size;
+ req.phys_alignment = 0;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
+ req.flags = 0;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_query_info(device_handle, AMDGPU_INFO_DEV_INFO,
+ sizeof(dev_info), &dev_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ addr = dev_info.virtual_address_offset;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ addr = dev_info.virtual_address_max - size;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (dev_info.high_va_offset) {
+ addr = dev_info.high_va_offset;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ addr = dev_info.high_va_max - size;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ amdgpu_bo_free(buf);
+}