1d722e3fbSopenharmony_ci/* 2d722e3fbSopenharmony_ci * Copyright 2021 Advanced Micro Devices, Inc. 3d722e3fbSopenharmony_ci * 4d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 7d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10d722e3fbSopenharmony_ci * 11d722e3fbSopenharmony_ci * The above copyright notice and this permission notice shall be included in 12d722e3fbSopenharmony_ci * all copies or substantial portions of the Software. 13d722e3fbSopenharmony_ci * 14d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17d722e3fbSopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18d722e3fbSopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19d722e3fbSopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20d722e3fbSopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21d722e3fbSopenharmony_ci * 22d722e3fbSopenharmony_ci*/ 23d722e3fbSopenharmony_ci 24d722e3fbSopenharmony_ci#include <stdio.h> 25d722e3fbSopenharmony_ci#include <sys/types.h> 26d722e3fbSopenharmony_ci#include <sys/stat.h> 27d722e3fbSopenharmony_ci#include <fcntl.h> 28d722e3fbSopenharmony_ci#include <stdarg.h> 29d722e3fbSopenharmony_ci#include <string.h> 30d722e3fbSopenharmony_ci#include <errno.h> 31d722e3fbSopenharmony_ci#include <unistd.h> 32d722e3fbSopenharmony_ci#include <stdlib.h> 33d722e3fbSopenharmony_ci 34d722e3fbSopenharmony_ci#include "drm.h" 35d722e3fbSopenharmony_ci#include "xf86drmMode.h" 36d722e3fbSopenharmony_ci#include "xf86drm.h" 37d722e3fbSopenharmony_ci#include "amdgpu.h" 38d722e3fbSopenharmony_ci#include "amdgpu_drm.h" 39d722e3fbSopenharmony_ci#include "amdgpu_internal.h" 40d722e3fbSopenharmony_ci 41d722e3fbSopenharmony_ci#define MAX_CARDS_SUPPORTED 4 42d722e3fbSopenharmony_ci#define NUM_BUFFER_OBJECTS 1024 43d722e3fbSopenharmony_ci 44d722e3fbSopenharmony_ci#define SDMA_PACKET(op, sub_op, e) ((((e) & 0xFFFF) << 16) | \ 45d722e3fbSopenharmony_ci (((sub_op) & 0xFF) << 8) | \ 46d722e3fbSopenharmony_ci (((op) & 0xFF) << 0)) 47d722e3fbSopenharmony_ci 48d722e3fbSopenharmony_ci#define SDMA_OPCODE_COPY 1 49d722e3fbSopenharmony_ci# define SDMA_COPY_SUB_OPCODE_LINEAR 0 50d722e3fbSopenharmony_ci 51d722e3fbSopenharmony_ci 52d722e3fbSopenharmony_ci#define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \ 53d722e3fbSopenharmony_ci (((b) & 0x1) << 26) | \ 54d722e3fbSopenharmony_ci (((t) & 0x1) << 23) | \ 55d722e3fbSopenharmony_ci (((s) & 0x1) << 22) | \ 56d722e3fbSopenharmony_ci (((cnt) & 0xFFFFF) << 0)) 57d722e3fbSopenharmony_ci#define SDMA_OPCODE_COPY_SI 3 58d722e3fbSopenharmony_ci 59d722e3fbSopenharmony_ci 60d722e3fbSopenharmony_ci/** Help string for command line parameters */ 61d722e3fbSopenharmony_cistatic const char usage[] = 62d722e3fbSopenharmony_ci "Usage: %s [-?h] [-b v|g|vg size] " 63d722e3fbSopenharmony_ci "[-c from to size count]\n" 64d722e3fbSopenharmony_ci "where:\n" 65d722e3fbSopenharmony_ci " b - Allocate a BO in VRAM, GTT or VRAM|GTT of size bytes.\n" 66d722e3fbSopenharmony_ci " This flag can be used multiple times. The first bo will\n" 67d722e3fbSopenharmony_ci " have id `1`, then second id `2`, ...\n" 68d722e3fbSopenharmony_ci " c - Copy size bytes from BO (bo_id1) to BO (bo_id2), count times\n" 69d722e3fbSopenharmony_ci " h - Display this help\n" 70d722e3fbSopenharmony_ci "\n" 71d722e3fbSopenharmony_ci "Sizes can be postfixes with k, m or g for kilo, mega and gigabyte scaling\n"; 72d722e3fbSopenharmony_ci 73d722e3fbSopenharmony_ci/** Specified options strings for getopt */ 74d722e3fbSopenharmony_cistatic const char options[] = "?hb:c:"; 75d722e3fbSopenharmony_ci 76d722e3fbSopenharmony_ci/* Open AMD devices. 77d722e3fbSopenharmony_ci * Returns the fd of the first device it could open. 78d722e3fbSopenharmony_ci */ 79d722e3fbSopenharmony_cistatic int amdgpu_open_device(void) 80d722e3fbSopenharmony_ci{ 81d722e3fbSopenharmony_ci drmDevicePtr devices[MAX_CARDS_SUPPORTED]; 82d722e3fbSopenharmony_ci unsigned int i; 83d722e3fbSopenharmony_ci int drm_count; 84d722e3fbSopenharmony_ci 85d722e3fbSopenharmony_ci drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED); 86d722e3fbSopenharmony_ci if (drm_count < 0) { 87d722e3fbSopenharmony_ci fprintf(stderr, "drmGetDevices2() returned an error %d\n", 88d722e3fbSopenharmony_ci drm_count); 89d722e3fbSopenharmony_ci return drm_count; 90d722e3fbSopenharmony_ci } 91d722e3fbSopenharmony_ci 92d722e3fbSopenharmony_ci for (i = 0; i < drm_count; i++) { 93d722e3fbSopenharmony_ci drmVersionPtr version; 94d722e3fbSopenharmony_ci int fd; 95d722e3fbSopenharmony_ci 96d722e3fbSopenharmony_ci /* If this is not PCI device, skip*/ 97d722e3fbSopenharmony_ci if (devices[i]->bustype != DRM_BUS_PCI) 98d722e3fbSopenharmony_ci continue; 99d722e3fbSopenharmony_ci 100d722e3fbSopenharmony_ci /* If this is not AMD GPU vender ID, skip*/ 101d722e3fbSopenharmony_ci if (devices[i]->deviceinfo.pci->vendor_id != 0x1002) 102d722e3fbSopenharmony_ci continue; 103d722e3fbSopenharmony_ci 104d722e3fbSopenharmony_ci if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER)) 105d722e3fbSopenharmony_ci continue; 106d722e3fbSopenharmony_ci 107d722e3fbSopenharmony_ci fd = open(devices[i]->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC); 108d722e3fbSopenharmony_ci 109d722e3fbSopenharmony_ci /* This node is not available. */ 110d722e3fbSopenharmony_ci if (fd < 0) continue; 111d722e3fbSopenharmony_ci 112d722e3fbSopenharmony_ci version = drmGetVersion(fd); 113d722e3fbSopenharmony_ci if (!version) { 114d722e3fbSopenharmony_ci fprintf(stderr, 115d722e3fbSopenharmony_ci "Warning: Cannot get version for %s." 116d722e3fbSopenharmony_ci "Error is %s\n", 117d722e3fbSopenharmony_ci devices[i]->nodes[DRM_NODE_RENDER], 118d722e3fbSopenharmony_ci strerror(errno)); 119d722e3fbSopenharmony_ci close(fd); 120d722e3fbSopenharmony_ci continue; 121d722e3fbSopenharmony_ci } 122d722e3fbSopenharmony_ci 123d722e3fbSopenharmony_ci if (strcmp(version->name, "amdgpu")) { 124d722e3fbSopenharmony_ci /* This is not AMDGPU driver, skip.*/ 125d722e3fbSopenharmony_ci drmFreeVersion(version); 126d722e3fbSopenharmony_ci close(fd); 127d722e3fbSopenharmony_ci continue; 128d722e3fbSopenharmony_ci } 129d722e3fbSopenharmony_ci 130d722e3fbSopenharmony_ci drmFreeVersion(version); 131d722e3fbSopenharmony_ci drmFreeDevices(devices, drm_count); 132d722e3fbSopenharmony_ci return fd; 133d722e3fbSopenharmony_ci } 134d722e3fbSopenharmony_ci 135d722e3fbSopenharmony_ci return -1; 136d722e3fbSopenharmony_ci} 137d722e3fbSopenharmony_ci 138d722e3fbSopenharmony_ciamdgpu_device_handle device_handle; 139d722e3fbSopenharmony_ciamdgpu_context_handle context_handle; 140d722e3fbSopenharmony_ci 141d722e3fbSopenharmony_ciamdgpu_bo_handle resources[NUM_BUFFER_OBJECTS]; 142d722e3fbSopenharmony_ciuint64_t virtual[NUM_BUFFER_OBJECTS]; 143d722e3fbSopenharmony_ciunsigned int num_buffers; 144d722e3fbSopenharmony_ciuint32_t *pm4; 145d722e3fbSopenharmony_ci 146d722e3fbSopenharmony_ciint alloc_bo(uint32_t domain, uint64_t size) 147d722e3fbSopenharmony_ci{ 148d722e3fbSopenharmony_ci struct amdgpu_bo_alloc_request request = {}; 149d722e3fbSopenharmony_ci amdgpu_bo_handle bo; 150d722e3fbSopenharmony_ci amdgpu_va_handle va; 151d722e3fbSopenharmony_ci uint64_t addr; 152d722e3fbSopenharmony_ci int r; 153d722e3fbSopenharmony_ci 154d722e3fbSopenharmony_ci if (num_buffers >= NUM_BUFFER_OBJECTS) 155d722e3fbSopenharmony_ci return -ENOSPC; 156d722e3fbSopenharmony_ci 157d722e3fbSopenharmony_ci request.alloc_size = size; 158d722e3fbSopenharmony_ci request.phys_alignment = 0; 159d722e3fbSopenharmony_ci request.preferred_heap = domain; 160d722e3fbSopenharmony_ci request.flags = 0; 161d722e3fbSopenharmony_ci r = amdgpu_bo_alloc(device_handle, &request, &bo); 162d722e3fbSopenharmony_ci if (r) 163d722e3fbSopenharmony_ci return r; 164d722e3fbSopenharmony_ci 165d722e3fbSopenharmony_ci r = amdgpu_va_range_alloc(device_handle, amdgpu_gpu_va_range_general, 166d722e3fbSopenharmony_ci size, 0, 0, &addr, &va, 0); 167d722e3fbSopenharmony_ci if (r) 168d722e3fbSopenharmony_ci return r; 169d722e3fbSopenharmony_ci 170d722e3fbSopenharmony_ci r = amdgpu_bo_va_op_raw(device_handle, bo, 0, size, addr, 171d722e3fbSopenharmony_ci AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE | 172d722e3fbSopenharmony_ci AMDGPU_VM_PAGE_EXECUTABLE, AMDGPU_VA_OP_MAP); 173d722e3fbSopenharmony_ci if (r) 174d722e3fbSopenharmony_ci return r; 175d722e3fbSopenharmony_ci 176d722e3fbSopenharmony_ci resources[num_buffers] = bo; 177d722e3fbSopenharmony_ci virtual[num_buffers] = addr; 178d722e3fbSopenharmony_ci fprintf(stdout, "Allocated BO number %u at 0x%lx, domain 0x%x, size %lu\n", 179d722e3fbSopenharmony_ci num_buffers++, addr, domain, size); 180d722e3fbSopenharmony_ci return 0; 181d722e3fbSopenharmony_ci} 182d722e3fbSopenharmony_ci 183d722e3fbSopenharmony_ciint submit_ib(uint32_t from, uint32_t to, uint64_t size, uint32_t count) 184d722e3fbSopenharmony_ci{ 185d722e3fbSopenharmony_ci struct amdgpu_cs_request ibs_request; 186d722e3fbSopenharmony_ci struct amdgpu_cs_fence fence_status; 187d722e3fbSopenharmony_ci struct amdgpu_cs_ib_info ib_info; 188d722e3fbSopenharmony_ci uint64_t copied = size, delta; 189d722e3fbSopenharmony_ci struct timespec start, stop; 190d722e3fbSopenharmony_ci 191d722e3fbSopenharmony_ci uint64_t src = virtual[from]; 192d722e3fbSopenharmony_ci uint64_t dst = virtual[to]; 193d722e3fbSopenharmony_ci uint32_t expired; 194d722e3fbSopenharmony_ci int i, r; 195d722e3fbSopenharmony_ci 196d722e3fbSopenharmony_ci i = 0; 197d722e3fbSopenharmony_ci while (size) { 198d722e3fbSopenharmony_ci uint64_t bytes = size < 0x40000 ? size : 0x40000; 199d722e3fbSopenharmony_ci 200d722e3fbSopenharmony_ci if (device_handle->info.family_id == AMDGPU_FAMILY_SI) { 201d722e3fbSopenharmony_ci pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, 0, 0, 0, 202d722e3fbSopenharmony_ci bytes); 203d722e3fbSopenharmony_ci pm4[i++] = 0xffffffff & dst; 204d722e3fbSopenharmony_ci pm4[i++] = 0xffffffff & src; 205d722e3fbSopenharmony_ci pm4[i++] = (0xffffffff00000000 & dst) >> 32; 206d722e3fbSopenharmony_ci pm4[i++] = (0xffffffff00000000 & src) >> 32; 207d722e3fbSopenharmony_ci } else { 208d722e3fbSopenharmony_ci pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, 209d722e3fbSopenharmony_ci SDMA_COPY_SUB_OPCODE_LINEAR, 210d722e3fbSopenharmony_ci 0); 211d722e3fbSopenharmony_ci if ( device_handle->info.family_id >= AMDGPU_FAMILY_AI) 212d722e3fbSopenharmony_ci pm4[i++] = bytes - 1; 213d722e3fbSopenharmony_ci else 214d722e3fbSopenharmony_ci pm4[i++] = bytes; 215d722e3fbSopenharmony_ci pm4[i++] = 0; 216d722e3fbSopenharmony_ci pm4[i++] = 0xffffffff & src; 217d722e3fbSopenharmony_ci pm4[i++] = (0xffffffff00000000 & src) >> 32; 218d722e3fbSopenharmony_ci pm4[i++] = 0xffffffff & dst; 219d722e3fbSopenharmony_ci pm4[i++] = (0xffffffff00000000 & dst) >> 32; 220d722e3fbSopenharmony_ci } 221d722e3fbSopenharmony_ci 222d722e3fbSopenharmony_ci size -= bytes; 223d722e3fbSopenharmony_ci src += bytes; 224d722e3fbSopenharmony_ci dst += bytes; 225d722e3fbSopenharmony_ci } 226d722e3fbSopenharmony_ci 227d722e3fbSopenharmony_ci memset(&ib_info, 0, sizeof(ib_info)); 228d722e3fbSopenharmony_ci ib_info.ib_mc_address = virtual[0]; 229d722e3fbSopenharmony_ci ib_info.size = i; 230d722e3fbSopenharmony_ci 231d722e3fbSopenharmony_ci memset(&ibs_request, 0, sizeof(ibs_request)); 232d722e3fbSopenharmony_ci ibs_request.ip_type = AMDGPU_HW_IP_DMA; 233d722e3fbSopenharmony_ci ibs_request.ring = 0; 234d722e3fbSopenharmony_ci ibs_request.number_of_ibs = 1; 235d722e3fbSopenharmony_ci ibs_request.ibs = &ib_info; 236d722e3fbSopenharmony_ci ibs_request.fence_info.handle = NULL; 237d722e3fbSopenharmony_ci 238d722e3fbSopenharmony_ci r = clock_gettime(CLOCK_MONOTONIC, &start); 239d722e3fbSopenharmony_ci if (r) 240d722e3fbSopenharmony_ci return errno; 241d722e3fbSopenharmony_ci 242d722e3fbSopenharmony_ci r = amdgpu_bo_list_create(device_handle, num_buffers, resources, NULL, 243d722e3fbSopenharmony_ci &ibs_request.resources); 244d722e3fbSopenharmony_ci if (r) 245d722e3fbSopenharmony_ci return r; 246d722e3fbSopenharmony_ci 247d722e3fbSopenharmony_ci for (i = 0; i < count; ++i) { 248d722e3fbSopenharmony_ci r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); 249d722e3fbSopenharmony_ci if (r) 250d722e3fbSopenharmony_ci return r; 251d722e3fbSopenharmony_ci } 252d722e3fbSopenharmony_ci 253d722e3fbSopenharmony_ci r = amdgpu_bo_list_destroy(ibs_request.resources); 254d722e3fbSopenharmony_ci if (r) 255d722e3fbSopenharmony_ci return r; 256d722e3fbSopenharmony_ci 257d722e3fbSopenharmony_ci memset(&fence_status, 0, sizeof(fence_status)); 258d722e3fbSopenharmony_ci fence_status.ip_type = ibs_request.ip_type; 259d722e3fbSopenharmony_ci fence_status.ip_instance = 0; 260d722e3fbSopenharmony_ci fence_status.ring = ibs_request.ring; 261d722e3fbSopenharmony_ci fence_status.context = context_handle; 262d722e3fbSopenharmony_ci fence_status.fence = ibs_request.seq_no; 263d722e3fbSopenharmony_ci r = amdgpu_cs_query_fence_status(&fence_status, 264d722e3fbSopenharmony_ci AMDGPU_TIMEOUT_INFINITE, 265d722e3fbSopenharmony_ci 0, &expired); 266d722e3fbSopenharmony_ci if (r) 267d722e3fbSopenharmony_ci return r; 268d722e3fbSopenharmony_ci 269d722e3fbSopenharmony_ci r = clock_gettime(CLOCK_MONOTONIC, &stop); 270d722e3fbSopenharmony_ci if (r) 271d722e3fbSopenharmony_ci return errno; 272d722e3fbSopenharmony_ci 273d722e3fbSopenharmony_ci delta = stop.tv_nsec + stop.tv_sec * 1000000000UL; 274d722e3fbSopenharmony_ci delta -= start.tv_nsec + start.tv_sec * 1000000000UL; 275d722e3fbSopenharmony_ci 276d722e3fbSopenharmony_ci fprintf(stdout, "Submitted %u IBs to copy from %u(%lx) to %u(%lx) %lu bytes took %lu usec\n", 277d722e3fbSopenharmony_ci count, from, virtual[from], to, virtual[to], copied, delta / 1000); 278d722e3fbSopenharmony_ci return 0; 279d722e3fbSopenharmony_ci} 280d722e3fbSopenharmony_ci 281d722e3fbSopenharmony_civoid next_arg(int argc, char **argv, const char *msg) 282d722e3fbSopenharmony_ci{ 283d722e3fbSopenharmony_ci optarg = argv[optind++]; 284d722e3fbSopenharmony_ci if (optind > argc || optarg[0] == '-') { 285d722e3fbSopenharmony_ci fprintf(stderr, "%s\n", msg); 286d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 287d722e3fbSopenharmony_ci } 288d722e3fbSopenharmony_ci} 289d722e3fbSopenharmony_ci 290d722e3fbSopenharmony_ciuint64_t parse_size(void) 291d722e3fbSopenharmony_ci{ 292d722e3fbSopenharmony_ci uint64_t size; 293d722e3fbSopenharmony_ci char ext[2]; 294d722e3fbSopenharmony_ci 295d722e3fbSopenharmony_ci ext[0] = 0; 296d722e3fbSopenharmony_ci if (sscanf(optarg, "%li%1[kmgKMG]", &size, ext) < 1) { 297d722e3fbSopenharmony_ci fprintf(stderr, "Can't parse size arg: %s\n", optarg); 298d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 299d722e3fbSopenharmony_ci } 300d722e3fbSopenharmony_ci switch (ext[0]) { 301d722e3fbSopenharmony_ci case 'k': 302d722e3fbSopenharmony_ci case 'K': 303d722e3fbSopenharmony_ci size *= 1024; 304d722e3fbSopenharmony_ci break; 305d722e3fbSopenharmony_ci case 'm': 306d722e3fbSopenharmony_ci case 'M': 307d722e3fbSopenharmony_ci size *= 1024 * 1024; 308d722e3fbSopenharmony_ci break; 309d722e3fbSopenharmony_ci case 'g': 310d722e3fbSopenharmony_ci case 'G': 311d722e3fbSopenharmony_ci size *= 1024 * 1024 * 1024; 312d722e3fbSopenharmony_ci break; 313d722e3fbSopenharmony_ci default: 314d722e3fbSopenharmony_ci break; 315d722e3fbSopenharmony_ci } 316d722e3fbSopenharmony_ci return size; 317d722e3fbSopenharmony_ci} 318d722e3fbSopenharmony_ci 319d722e3fbSopenharmony_ciint main(int argc, char **argv) 320d722e3fbSopenharmony_ci{ 321d722e3fbSopenharmony_ci uint32_t major_version, minor_version; 322d722e3fbSopenharmony_ci uint32_t domain, from, to, count; 323d722e3fbSopenharmony_ci uint64_t size; 324d722e3fbSopenharmony_ci int fd, r, c; 325d722e3fbSopenharmony_ci 326d722e3fbSopenharmony_ci fd = amdgpu_open_device(); 327d722e3fbSopenharmony_ci if (fd < 0) { 328d722e3fbSopenharmony_ci perror("Cannot open AMDGPU device"); 329d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 330d722e3fbSopenharmony_ci } 331d722e3fbSopenharmony_ci 332d722e3fbSopenharmony_ci r = amdgpu_device_initialize(fd, &major_version, &minor_version, &device_handle); 333d722e3fbSopenharmony_ci if (r) { 334d722e3fbSopenharmony_ci fprintf(stderr, "amdgpu_device_initialize returned %d\n", r); 335d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 336d722e3fbSopenharmony_ci } 337d722e3fbSopenharmony_ci 338d722e3fbSopenharmony_ci r = amdgpu_cs_ctx_create(device_handle, &context_handle); 339d722e3fbSopenharmony_ci if (r) { 340d722e3fbSopenharmony_ci fprintf(stderr, "amdgpu_cs_ctx_create returned %d\n", r); 341d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 342d722e3fbSopenharmony_ci } 343d722e3fbSopenharmony_ci 344d722e3fbSopenharmony_ci if (argc == 1) { 345d722e3fbSopenharmony_ci fprintf(stderr, usage, argv[0]); 346d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 347d722e3fbSopenharmony_ci } 348d722e3fbSopenharmony_ci 349d722e3fbSopenharmony_ci r = alloc_bo(AMDGPU_GEM_DOMAIN_GTT, 2ULL * 1024 * 1024); 350d722e3fbSopenharmony_ci if (r) { 351d722e3fbSopenharmony_ci fprintf(stderr, "Buffer allocation failed with %d\n", r); 352d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 353d722e3fbSopenharmony_ci } 354d722e3fbSopenharmony_ci 355d722e3fbSopenharmony_ci r = amdgpu_bo_cpu_map(resources[0], (void **)&pm4); 356d722e3fbSopenharmony_ci if (r) { 357d722e3fbSopenharmony_ci fprintf(stderr, "Buffer mapping failed with %d\n", r); 358d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 359d722e3fbSopenharmony_ci } 360d722e3fbSopenharmony_ci 361d722e3fbSopenharmony_ci opterr = 0; 362d722e3fbSopenharmony_ci while ((c = getopt(argc, argv, options)) != -1) { 363d722e3fbSopenharmony_ci switch (c) { 364d722e3fbSopenharmony_ci case 'b': 365d722e3fbSopenharmony_ci if (!strcmp(optarg, "v")) 366d722e3fbSopenharmony_ci domain = AMDGPU_GEM_DOMAIN_VRAM; 367d722e3fbSopenharmony_ci else if (!strcmp(optarg, "g")) 368d722e3fbSopenharmony_ci domain = AMDGPU_GEM_DOMAIN_GTT; 369d722e3fbSopenharmony_ci else if (!strcmp(optarg, "vg")) 370d722e3fbSopenharmony_ci domain = AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT; 371d722e3fbSopenharmony_ci else { 372d722e3fbSopenharmony_ci fprintf(stderr, "Invalid domain: %s\n", optarg); 373d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 374d722e3fbSopenharmony_ci } 375d722e3fbSopenharmony_ci next_arg(argc, argv, "Missing buffer size"); 376d722e3fbSopenharmony_ci size = parse_size(); 377d722e3fbSopenharmony_ci if (size < getpagesize()) { 378d722e3fbSopenharmony_ci fprintf(stderr, "Buffer size to small %lu\n", size); 379d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 380d722e3fbSopenharmony_ci } 381d722e3fbSopenharmony_ci r = alloc_bo(domain, size); 382d722e3fbSopenharmony_ci if (r) { 383d722e3fbSopenharmony_ci fprintf(stderr, "Buffer allocation failed with %d\n", r); 384d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 385d722e3fbSopenharmony_ci } 386d722e3fbSopenharmony_ci break; 387d722e3fbSopenharmony_ci case 'c': 388d722e3fbSopenharmony_ci if (sscanf(optarg, "%u", &from) != 1) { 389d722e3fbSopenharmony_ci fprintf(stderr, "Can't parse from buffer: %s\n", optarg); 390d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 391d722e3fbSopenharmony_ci } 392d722e3fbSopenharmony_ci next_arg(argc, argv, "Missing to buffer"); 393d722e3fbSopenharmony_ci if (sscanf(optarg, "%u", &to) != 1) { 394d722e3fbSopenharmony_ci fprintf(stderr, "Can't parse to buffer: %s\n", optarg); 395d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 396d722e3fbSopenharmony_ci } 397d722e3fbSopenharmony_ci next_arg(argc, argv, "Missing size"); 398d722e3fbSopenharmony_ci size = parse_size(); 399d722e3fbSopenharmony_ci next_arg(argc, argv, "Missing count"); 400d722e3fbSopenharmony_ci count = parse_size(); 401d722e3fbSopenharmony_ci r = submit_ib(from, to, size, count); 402d722e3fbSopenharmony_ci if (r) { 403d722e3fbSopenharmony_ci fprintf(stderr, "IB submission failed with %d\n", r); 404d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 405d722e3fbSopenharmony_ci } 406d722e3fbSopenharmony_ci break; 407d722e3fbSopenharmony_ci case '?': 408d722e3fbSopenharmony_ci case 'h': 409d722e3fbSopenharmony_ci fprintf(stderr, usage, argv[0]); 410d722e3fbSopenharmony_ci exit(EXIT_SUCCESS); 411d722e3fbSopenharmony_ci default: 412d722e3fbSopenharmony_ci fprintf(stderr, usage, argv[0]); 413d722e3fbSopenharmony_ci exit(EXIT_FAILURE); 414d722e3fbSopenharmony_ci } 415d722e3fbSopenharmony_ci } 416d722e3fbSopenharmony_ci 417d722e3fbSopenharmony_ci return EXIT_SUCCESS; 418d722e3fbSopenharmony_ci} 419