diff options
Diffstat (limited to 'tests/amdgpu')
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, >t_info); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, >t_max[0]); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, >t_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, ¤t_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); +} |