1 /* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include <string.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 #include <string.h> 29 #include <ctype.h> 30 #include <fcntl.h> 31 #include <errno.h> 32 #include <signal.h> 33 #include <time.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <sys/ioctl.h> 37 #include <sys/time.h> 38 #include <stdarg.h> 39 #include <stdint.h> 40 #ifdef __linux__ 41 #include <linux/limits.h> 42 #elif __FreeBSD__ 43 /* SPECNAMELEN in FreeBSD is defined here: */ 44 #include <sys/param.h> 45 #endif 46 #ifdef MAJOR_IN_MKDEV 47 #include <sys/mkdev.h> 48 #endif 49 #ifdef MAJOR_IN_SYSMACROS 50 #include <sys/sysmacros.h> 51 #endif 52 53 #include "drm.h" 54 #include "xf86drmMode.h" 55 #include "xf86drm.h" 56 57 #include "CUnit/Basic.h" 58 59 #include "amdgpu_test.h" 60 #include "amdgpu_internal.h" 61 62 /* Test suite names */ 63 #define BASIC_TESTS_STR "Basic Tests" 64 #define BO_TESTS_STR "BO Tests" 65 #define CS_TESTS_STR "CS Tests" 66 #define VCE_TESTS_STR "VCE Tests" 67 #define VCN_TESTS_STR "VCN Tests" 68 #define JPEG_TESTS_STR "JPEG Tests" 69 #define UVD_ENC_TESTS_STR "UVD ENC Tests" 70 #define DEADLOCK_TESTS_STR "Deadlock Tests" 71 #define VM_TESTS_STR "VM Tests" 72 #define RAS_TESTS_STR "RAS Tests" 73 #define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests" 74 #define SECURITY_TESTS_STR "Security Tests" 75 #define HOTUNPLUG_TESTS_STR "Hotunplug Tests" 76 #define CP_DMA_TESTS_STR "CP DMA Tests" 77 78 /** 79 * Open handles for amdgpu devices 80 * 81 */ 82 int drm_amdgpu[MAX_CARDS_SUPPORTED]; 83 84 /** Open render node to test */ 85 int open_render_node = 0; /* By default run most tests on primary node */ 86 87 /** The table of all known test suites to run */ 88 static CU_SuiteInfo suites[] = { 89 { 90 .pName = BASIC_TESTS_STR, 91 .pInitFunc = suite_basic_tests_init, 92 .pCleanupFunc = suite_basic_tests_clean, 93 .pTests = basic_tests, 94 }, 95 { 96 .pName = BO_TESTS_STR, 97 .pInitFunc = suite_bo_tests_init, 98 .pCleanupFunc = suite_bo_tests_clean, 99 .pTests = bo_tests, 100 }, 101 { 102 .pName = CS_TESTS_STR, 103 .pInitFunc = suite_cs_tests_init, 104 .pCleanupFunc = suite_cs_tests_clean, 105 .pTests = cs_tests, 106 }, 107 { 108 .pName = VCE_TESTS_STR, 109 .pInitFunc = suite_vce_tests_init, 110 .pCleanupFunc = suite_vce_tests_clean, 111 .pTests = vce_tests, 112 }, 113 { 114 .pName = VCN_TESTS_STR, 115 .pInitFunc = suite_vcn_tests_init, 116 .pCleanupFunc = suite_vcn_tests_clean, 117 .pTests = vcn_tests, 118 }, 119 { 120 .pName = JPEG_TESTS_STR, 121 .pInitFunc = suite_jpeg_tests_init, 122 .pCleanupFunc = suite_jpeg_tests_clean, 123 .pTests = jpeg_tests, 124 }, 125 { 126 .pName = UVD_ENC_TESTS_STR, 127 .pInitFunc = suite_uvd_enc_tests_init, 128 .pCleanupFunc = suite_uvd_enc_tests_clean, 129 .pTests = uvd_enc_tests, 130 }, 131 { 132 .pName = DEADLOCK_TESTS_STR, 133 .pInitFunc = suite_deadlock_tests_init, 134 .pCleanupFunc = suite_deadlock_tests_clean, 135 .pTests = deadlock_tests, 136 }, 137 { 138 .pName = VM_TESTS_STR, 139 .pInitFunc = suite_vm_tests_init, 140 .pCleanupFunc = suite_vm_tests_clean, 141 .pTests = vm_tests, 142 }, 143 { 144 .pName = RAS_TESTS_STR, 145 .pInitFunc = suite_ras_tests_init, 146 .pCleanupFunc = suite_ras_tests_clean, 147 .pTests = ras_tests, 148 }, 149 { 150 .pName = SYNCOBJ_TIMELINE_TESTS_STR, 151 .pInitFunc = suite_syncobj_timeline_tests_init, 152 .pCleanupFunc = suite_syncobj_timeline_tests_clean, 153 .pTests = syncobj_timeline_tests, 154 }, 155 { 156 .pName = SECURITY_TESTS_STR, 157 .pInitFunc = suite_security_tests_init, 158 .pCleanupFunc = suite_security_tests_clean, 159 .pTests = security_tests, 160 }, 161 { 162 .pName = HOTUNPLUG_TESTS_STR, 163 .pInitFunc = suite_hotunplug_tests_init, 164 .pCleanupFunc = suite_hotunplug_tests_clean, 165 .pTests = hotunplug_tests, 166 }, 167 { 168 .pName = CP_DMA_TESTS_STR, 169 .pInitFunc = suite_cp_dma_tests_init, 170 .pCleanupFunc = suite_cp_dma_tests_clean, 171 .pTests = cp_dma_tests, 172 }, 173 174 CU_SUITE_INFO_NULL, 175 }; 176 177 typedef CU_BOOL (*active__stat_func)(void); 178 179 typedef struct Suites_Active_Status { 180 char* pName; 181 active__stat_func pActive; 182 }Suites_Active_Status; 183 184 static CU_BOOL always_active() 185 { 186 return CU_TRUE; 187 } 188 189 static Suites_Active_Status suites_active_stat[] = { 190 { 191 .pName = BASIC_TESTS_STR, 192 .pActive = suite_basic_tests_enable, 193 }, 194 { 195 .pName = BO_TESTS_STR, 196 .pActive = always_active, 197 }, 198 { 199 .pName = CS_TESTS_STR, 200 .pActive = suite_cs_tests_enable, 201 }, 202 { 203 .pName = VCE_TESTS_STR, 204 .pActive = suite_vce_tests_enable, 205 }, 206 { 207 .pName = VCN_TESTS_STR, 208 .pActive = suite_vcn_tests_enable, 209 }, 210 { 211 .pName = JPEG_TESTS_STR, 212 .pActive = suite_jpeg_tests_enable, 213 }, 214 { 215 .pName = UVD_ENC_TESTS_STR, 216 .pActive = suite_uvd_enc_tests_enable, 217 }, 218 { 219 .pName = DEADLOCK_TESTS_STR, 220 .pActive = suite_deadlock_tests_enable, 221 }, 222 { 223 .pName = VM_TESTS_STR, 224 .pActive = suite_vm_tests_enable, 225 }, 226 { 227 .pName = RAS_TESTS_STR, 228 .pActive = suite_ras_tests_enable, 229 }, 230 { 231 .pName = SYNCOBJ_TIMELINE_TESTS_STR, 232 .pActive = suite_syncobj_timeline_tests_enable, 233 }, 234 { 235 .pName = SECURITY_TESTS_STR, 236 .pActive = suite_security_tests_enable, 237 }, 238 { 239 .pName = HOTUNPLUG_TESTS_STR, 240 .pActive = suite_hotunplug_tests_enable, 241 }, 242 { 243 .pName = CP_DMA_TESTS_STR, 244 .pActive = suite_cp_dma_tests_enable, 245 }, 246 }; 247 248 249 /* 250 * Display information about all suites and their tests 251 * 252 * NOTE: Must be run after registry is initialized and suites registered. 253 */ 254 static void display_test_suites(void) 255 { 256 int iSuite; 257 int iTest; 258 CU_pSuite pSuite = NULL; 259 CU_pTest pTest = NULL; 260 261 printf("%5s: %2s: %8s: %s\n", "What", "ID", "Status", "Name"); 262 263 for (iSuite = 0; suites[iSuite].pName != NULL; iSuite++) { 264 265 pSuite = CU_get_suite_by_index((unsigned int) iSuite + 1, 266 CU_get_registry()); 267 268 if (!pSuite) { 269 fprintf(stderr, "Invalid suite id : %d\n", iSuite + 1); 270 continue; 271 } 272 273 printf("Suite: %2d: %8s: %s\n", 274 iSuite + 1, 275 pSuite->fActive ? "ENABLED" : "DISABLED", 276 suites[iSuite].pName); 277 278 if (!pSuite->fActive) 279 continue; 280 281 for (iTest = 0; suites[iSuite].pTests[iTest].pName != NULL; 282 iTest++) { 283 pTest = CU_get_test_by_index((unsigned int) iTest + 1, 284 pSuite); 285 if (!pTest) { 286 fprintf(stderr, "Invalid test id : %d\n", iTest + 1); 287 continue; 288 } 289 printf(" Test: %2d: %8s: %s\n", 290 iTest + 1, 291 pSuite->fActive && pTest->fActive ? "ENABLED" : "DISABLED", 292 suites[iSuite].pTests[iTest].pName); 293 } 294 } 295 } 296 297 /** Help string for command line parameters */ 298 static const char usage[] = 299 "Usage: %s [-hlpr] [-s <suite id>] [-e <s>[.<t>] [-e ...]] [-t <test id>] [-f] " 300 "[-b <pci_bus_id>] [-d <pci_device_id>]\n" 301 "Where,\n" 302 " -b Specify device's PCI bus id to run tests\n" 303 " -d Specify device's PCI device id to run tests (optional)\n" 304 " -e <s>[.<t>] Disable test <t> of suite <s>. If only <s> is given, then disable\n" 305 " the whole suite. Can be specified more than once on the command line\n" 306 " to disable multiple tests or suites.\n" 307 " -f Force executing inactive suite or test\n" 308 " -h Display this help\n" 309 " -l Display all test suites and their tests\n" 310 " -p Display information of AMDGPU devices in system\n" 311 " -r Run the tests on render node\n" 312 " -s <s> Enable only test suite <s>\n" 313 " -t <t> Enable only test <t> of test suite <s>\n"; 314 /** Specified options strings for getopt */ 315 static const char options[] = "hlrps:t:e:b:d:f"; 316 317 /* Open AMD devices. 318 * Return the number of AMD device opened. 319 */ 320 static int amdgpu_open_devices(int open_render_node) 321 { 322 drmDevicePtr devices[MAX_CARDS_SUPPORTED]; 323 int i; 324 int drm_node; 325 int amd_index = 0; 326 int drm_count; 327 int fd; 328 drmVersionPtr version; 329 330 for (i = 0; i < MAX_CARDS_SUPPORTED; i++) { 331 drm_amdgpu[i] = -1; 332 } 333 334 drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED); 335 336 if (drm_count < 0) { 337 fprintf(stderr, 338 "drmGetDevices2() returned an error %d\n", 339 drm_count); 340 return 0; 341 } 342 343 for (i = 0; i < drm_count; i++) { 344 /* If this is not PCI device, skip*/ 345 if (devices[i]->bustype != DRM_BUS_PCI) 346 continue; 347 348 /* If this is not AMD GPU vender ID, skip*/ 349 if (devices[i]->deviceinfo.pci->vendor_id != 0x1002) 350 continue; 351 352 if (open_render_node) 353 drm_node = DRM_NODE_RENDER; 354 else 355 drm_node = DRM_NODE_PRIMARY; 356 357 fd = -1; 358 if (devices[i]->available_nodes & 1 << drm_node) 359 fd = open( 360 devices[i]->nodes[drm_node], 361 O_RDWR | O_CLOEXEC); 362 363 /* This node is not available. */ 364 if (fd < 0) continue; 365 366 version = drmGetVersion(fd); 367 if (!version) { 368 fprintf(stderr, 369 "Warning: Cannot get version for %s." 370 "Error is %s\n", 371 devices[i]->nodes[drm_node], 372 strerror(errno)); 373 close(fd); 374 continue; 375 } 376 377 if (strcmp(version->name, "amdgpu")) { 378 /* This is not AMDGPU driver, skip.*/ 379 drmFreeVersion(version); 380 close(fd); 381 continue; 382 } 383 384 drmFreeVersion(version); 385 386 drm_amdgpu[amd_index] = fd; 387 amd_index++; 388 } 389 390 drmFreeDevices(devices, drm_count); 391 return amd_index; 392 } 393 394 /* Close AMD devices. 395 */ 396 void amdgpu_close_devices() 397 { 398 int i; 399 for (i = 0; i < MAX_CARDS_SUPPORTED; i++) 400 if (drm_amdgpu[i] >=0) { 401 close(drm_amdgpu[i]); 402 } 403 } 404 405 /* Print AMD devices information */ 406 static void amdgpu_print_devices() 407 { 408 int i; 409 drmDevicePtr device; 410 411 /* Open the first AMD device to print driver information. */ 412 if (drm_amdgpu[0] >=0) { 413 /* Display AMD driver version information.*/ 414 drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]); 415 416 if (retval == NULL) { 417 perror("Cannot get version for AMDGPU device"); 418 return; 419 } 420 421 printf("Driver name: %s, Date: %s, Description: %s.\n", 422 retval->name, retval->date, retval->desc); 423 drmFreeVersion(retval); 424 } 425 426 /* Display information of AMD devices */ 427 printf("Devices:\n"); 428 for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++) 429 if (drmGetDevice2(drm_amdgpu[i], 430 DRM_DEVICE_GET_PCI_REVISION, 431 &device) == 0) { 432 if (device->bustype == DRM_BUS_PCI) { 433 printf("PCI "); 434 printf(" domain:%04x", 435 device->businfo.pci->domain); 436 printf(" bus:%02x", 437 device->businfo.pci->bus); 438 printf(" device:%02x", 439 device->businfo.pci->dev); 440 printf(" function:%01x", 441 device->businfo.pci->func); 442 printf(" vendor_id:%04x", 443 device->deviceinfo.pci->vendor_id); 444 printf(" device_id:%04x", 445 device->deviceinfo.pci->device_id); 446 printf(" subvendor_id:%04x", 447 device->deviceinfo.pci->subvendor_id); 448 printf(" subdevice_id:%04x", 449 device->deviceinfo.pci->subdevice_id); 450 printf(" revision_id:%02x", 451 device->deviceinfo.pci->revision_id); 452 printf("\n"); 453 } 454 drmFreeDevice(&device); 455 } 456 } 457 458 /* Find a match AMD device in PCI bus 459 * Return the index of the device or -1 if not found 460 */ 461 static int amdgpu_find_device(uint8_t bus, uint16_t dev) 462 { 463 int i; 464 drmDevicePtr device; 465 466 for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) { 467 if (drmGetDevice2(drm_amdgpu[i], 468 DRM_DEVICE_GET_PCI_REVISION, 469 &device) == 0) { 470 if (device->bustype == DRM_BUS_PCI) 471 if ((bus == 0xFF || device->businfo.pci->bus == bus) && 472 device->deviceinfo.pci->device_id == dev) { 473 drmFreeDevice(&device); 474 return i; 475 } 476 477 drmFreeDevice(&device); 478 } 479 } 480 481 return -1; 482 } 483 484 static void amdgpu_disable_suites() 485 { 486 amdgpu_device_handle device_handle; 487 uint32_t major_version, minor_version, family_id; 488 drmDevicePtr devices[MAX_CARDS_SUPPORTED]; 489 int i, drm_count; 490 int size = sizeof(suites_active_stat) / sizeof(suites_active_stat[0]); 491 492 if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, 493 &minor_version, &device_handle)) 494 return; 495 496 family_id = device_handle->info.family_id; 497 498 if (amdgpu_device_deinitialize(device_handle)) 499 return; 500 501 drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED); 502 503 /* Set active status for suites based on their policies */ 504 for (i = 0; i < size; ++i) 505 if (amdgpu_set_suite_active(suites_active_stat[i].pName, 506 suites_active_stat[i].pActive())) 507 fprintf(stderr, "suite deactivation failed - %s\n", CU_get_error_msg()); 508 509 /* Explicitly disable specific tests due to known bugs or preferences */ 510 /* 511 * BUG: Compute ring stalls and never recovers when the address is 512 * written after the command already submitted 513 */ 514 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 515 "compute ring block test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 516 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 517 518 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 519 "sdma ring block test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 520 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 521 522 /* This test was ran on GFX9 only */ 523 //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 524 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 525 "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 526 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 527 528 /* This test was ran on GFX9 only */ 529 //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 530 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 531 "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE)) 532 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 533 534 /* This test was ran on GFX9 only */ 535 //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 536 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 537 "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 538 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 539 540 /* This test was ran on GFX9 only */ 541 //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 542 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 543 "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE)) 544 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 545 546 //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 547 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 548 "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 549 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 550 551 /* This test was ran on GFX9 only */ 552 //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 553 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 554 "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 555 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 556 557 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 558 "sdma ring corrupted header test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 559 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 560 561 if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, 562 "sdma ring slow linear copy test (set amdgpu.lockup_timeout=50)", CU_FALSE)) 563 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 564 565 if (amdgpu_set_test_active(BASIC_TESTS_STR, "bo eviction Test", CU_FALSE)) 566 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 567 568 /* This test was ran on GFX8 and GFX9 only */ 569 if (family_id < AMDGPU_FAMILY_VI || family_id > AMDGPU_FAMILY_RV) 570 if (amdgpu_set_test_active(BASIC_TESTS_STR, "Sync dependency Test", CU_FALSE)) 571 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 572 573 /* This test was ran on GFX9 only */ 574 if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) { 575 if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (GFX)", CU_FALSE)) 576 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 577 if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (Compute)", CU_FALSE)) 578 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 579 } 580 581 /* This test was ran on GFX9 only */ 582 if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 583 if (amdgpu_set_test_active(BASIC_TESTS_STR, "Draw Test", CU_FALSE)) 584 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 585 586 /* This test was ran on GFX9 only */ 587 //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) 588 if (amdgpu_set_test_active(BASIC_TESTS_STR, "GPU reset Test", CU_FALSE)) 589 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 590 591 /* You need at least 2 devices for this */ 592 if (drm_count < 2) 593 if (amdgpu_set_test_active(HOTUNPLUG_TESTS_STR, "Unplug with exported fence", CU_FALSE)) 594 fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); 595 } 596 597 int test_device_index; 598 599 int amdgpu_open_device_on_test_index(int render_node) 600 { 601 int i; 602 603 if (amdgpu_open_devices(open_render_node) <= 0) { 604 perror("Cannot open AMDGPU device"); 605 return -1; 606 } 607 608 if (test_device_index >= 0) { 609 /* Most tests run on device of drm_amdgpu[0]. 610 * Swap the chosen device to drm_amdgpu[0]. 611 */ 612 i = drm_amdgpu[0]; 613 drm_amdgpu[0] = drm_amdgpu[test_device_index]; 614 drm_amdgpu[test_device_index] = i; 615 } 616 617 return 0; 618 619 620 } 621 622 623 static bool amdgpu_node_is_drm(int maj, int min) 624 { 625 #ifdef __linux__ 626 char path[64]; 627 struct stat sbuf; 628 629 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm", 630 maj, min); 631 return stat(path, &sbuf) == 0; 632 #elif defined(__FreeBSD__) 633 char name[SPECNAMELEN]; 634 635 if (!devname_r(makedev(maj, min), S_IFCHR, name, sizeof(name))) 636 return 0; 637 /* Handle drm/ and dri/ as both are present in different FreeBSD version 638 * FreeBSD on amd64/i386/powerpc external kernel modules create node in 639 * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates 640 * only device nodes in /dev/dri/ */ 641 return (!strncmp(name, "drm/", 4) || !strncmp(name, "dri/", 4)); 642 #else 643 return maj == DRM_MAJOR; 644 #endif 645 } 646 647 char *amdgpu_get_device_from_fd(int fd) 648 { 649 #ifdef __linux__ 650 struct stat sbuf; 651 char path[PATH_MAX + 1]; 652 unsigned int maj, min; 653 654 if (fstat(fd, &sbuf)) 655 return NULL; 656 657 maj = major(sbuf.st_rdev); 658 min = minor(sbuf.st_rdev); 659 660 if (!amdgpu_node_is_drm(maj, min) || !S_ISCHR(sbuf.st_mode)) 661 return NULL; 662 663 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 664 return strdup(path); 665 #else 666 return NULL; 667 #endif 668 } 669 670 #ifndef ARRAY_SIZE 671 #define ARRAY_SIZE(_A) (sizeof(_A)/sizeof(_A[0])) 672 #endif 673 674 static void amdgpu_test_disable(long suite, long test) 675 { 676 const char *suite_name; 677 678 if (suite < 1) 679 return; 680 681 /* The array is 0-based, so subract 1. */ 682 suite--; 683 if (suite >= ARRAY_SIZE(suites) - 1) 684 return; 685 686 suite_name = suites[suite].pName; 687 if (test < 1) { 688 fprintf(stderr, "Deactivating suite %s\n", suite_name); 689 amdgpu_set_suite_active(suite_name, CU_FALSE); 690 } else { 691 int ii; 692 693 /* The array is 0-based so subtract 1. */ 694 test--; 695 for (ii = 0; suites[suite].pTests[ii].pName; ii++) { 696 if (ii == test) { 697 fprintf(stderr, "Deactivating %s:%s\n", 698 suite_name, 699 suites[suite].pTests[ii].pName); 700 amdgpu_set_test_active(suite_name, 701 suites[suite].pTests[ii].pName, 702 CU_FALSE); 703 break; 704 } 705 } 706 707 if (suites[suite].pTests[ii].pName == NULL) 708 fprintf(stderr, "No such suite.test %ld.%ld\n", suite, test); 709 } 710 } 711 712 /* The main() function for setting up and running the tests. 713 * Returns a CUE_SUCCESS on successful running, another 714 * CUnit error code on failure. 715 */ 716 int main(int argc, char **argv) 717 { 718 int c; /* Character received from getopt */ 719 int i = 0; 720 int suite_id = -1; /* By default run everything */ 721 int test_id = -1; /* By default run all tests in the suite */ 722 int pci_bus_id = -1; /* By default PC bus ID is not specified */ 723 int pci_device_id = 0; /* By default PC device ID is zero */ 724 int display_devices = 0;/* By default not to display devices' info */ 725 CU_pSuite pSuite = NULL; 726 CU_pTest pTest = NULL; 727 int display_list = 0; 728 int force_run = 0; 729 730 /* Parse command line string. 731 * Process various command line options as early as possible. 732 */ 733 opterr = 0; /* Do not print error messages from getopt */ 734 while ((c = getopt(argc, argv, options)) != -1) { 735 switch (c) { 736 case 'h': 737 fprintf(stderr, usage, argv[0]); 738 exit(EXIT_SUCCESS); 739 } 740 } 741 742 for (i = 0; i < MAX_CARDS_SUPPORTED; i++) 743 drm_amdgpu[i] = -1; 744 745 if (amdgpu_open_devices(open_render_node) <= 0) { 746 perror("Cannot open AMDGPU device"); 747 exit(EXIT_FAILURE); 748 } 749 750 if (drm_amdgpu[0] < 0) { 751 perror("Cannot open AMDGPU device"); 752 exit(EXIT_FAILURE); 753 } 754 755 /* Parse command line string */ 756 opterr = 0; /* Do not print error messages from getopt */ 757 optind = 1; 758 while ((c = getopt(argc, argv, options)) != -1) { 759 switch (c) { 760 case 'p': 761 display_devices = 1; 762 break; 763 } 764 } 765 766 if (display_devices) { 767 amdgpu_print_devices(); 768 amdgpu_close_devices(); 769 exit(EXIT_SUCCESS); 770 } 771 772 /* Parse command line string */ 773 opterr = 0; /* Do not print error messages from getopt */ 774 optind = 1; 775 while ((c = getopt(argc, argv, options)) != -1) { 776 switch (c) { 777 case 'b': 778 pci_bus_id = atoi(optarg); 779 break; 780 case 'd': 781 sscanf(optarg, "%x", &pci_device_id); 782 break; 783 } 784 } 785 786 if (pci_bus_id > 0 || pci_device_id) { 787 /* A device was specified to run the test */ 788 test_device_index = amdgpu_find_device(pci_bus_id, 789 pci_device_id); 790 791 if (test_device_index >= 0) { 792 /* Most tests run on device of drm_amdgpu[0]. 793 * Swap the chosen device to drm_amdgpu[0]. 794 */ 795 i = drm_amdgpu[0]; 796 drm_amdgpu[0] = drm_amdgpu[test_device_index]; 797 drm_amdgpu[test_device_index] = i; 798 } else { 799 fprintf(stderr, 800 "The specified GPU device does not exist.\n"); 801 exit(EXIT_FAILURE); 802 } 803 } 804 805 /* Initialize test suites to run */ 806 807 /* initialize the CUnit test registry */ 808 if (CUE_SUCCESS != CU_initialize_registry()) { 809 amdgpu_close_devices(); 810 return CU_get_error(); 811 } 812 813 /* Register suites. */ 814 if (CU_register_suites(suites) != CUE_SUCCESS) { 815 fprintf(stderr, "suite registration failed - %s\n", 816 CU_get_error_msg()); 817 CU_cleanup_registry(); 818 amdgpu_close_devices(); 819 exit(EXIT_FAILURE); 820 } 821 822 /* Run tests using the CUnit Basic interface */ 823 CU_basic_set_mode(CU_BRM_VERBOSE); 824 825 /* Disable suites and individual tests based on misc. conditions */ 826 amdgpu_disable_suites(); 827 828 /* Parse command line string */ 829 opterr = 0; /* Do not print error messages from getopt */ 830 optind = 1; 831 while ((c = getopt(argc, argv, options)) != -1) { 832 switch (c) { 833 case 'l': 834 display_list = 1; 835 break; 836 } 837 } 838 839 if (display_list) { 840 display_test_suites(); 841 goto end; 842 } 843 844 /* Parse command line string */ 845 opterr = 0; /* Do not print error messages from getopt */ 846 optind = 1; 847 while ((c = getopt(argc, argv, options)) != -1) { 848 long esuite = -1; 849 long etest = -1; 850 char *endp; 851 switch (c) { 852 case 's': 853 suite_id = atoi(optarg); 854 break; 855 case 't': 856 test_id = atoi(optarg); 857 break; 858 case 'r': 859 open_render_node = 1; 860 break; 861 case 'f': 862 force_run = 1; 863 break; 864 case 'e': 865 esuite = strtol(optarg, &endp, 0); 866 if (endp == optarg) { 867 fprintf(stderr, "No digits given for -e argument\n"); 868 goto end; 869 } else if (endp && *endp == '.' && esuite > 0) { 870 char *tt = endp + 1; 871 etest = strtol(tt, &endp, 0); 872 if (endp == tt) { 873 fprintf(stderr, "No digits given for test in -e s.t argument\n"); 874 goto end; 875 } else if (endp && *endp != '\0') { 876 fprintf(stderr, "Bad input given for test in -e s.t argument\n"); 877 goto end; 878 } else if (etest < 1) { 879 fprintf(stderr, "Test in -e s.t argument cannot be smaller than 1\n"); 880 goto end; 881 } 882 } else if (endp && *endp != '\0') { 883 fprintf(stderr, "Bad input given for suite for -e s argument\n"); 884 goto end; 885 } else if (esuite < 1) { 886 fprintf(stderr, "Suite in -e s argument cannot be smaller than 1\n"); 887 goto end; 888 } 889 amdgpu_test_disable(esuite, etest); 890 break; 891 case 'h': 892 case 'p': 893 case 'b': 894 case 'd': 895 case 'l': 896 /* Those have been processed earlier. 897 */ 898 break; 899 case '?': 900 default: 901 fprintf(stderr, "Unknown command line option '%c'. Try -h.\n", 902 c == '?' ? optopt : c); 903 goto end; 904 } 905 } 906 907 if (suite_id != -1) { /* If user specify particular suite? */ 908 pSuite = CU_get_suite_by_index((unsigned int) suite_id, 909 CU_get_registry()); 910 911 if (pSuite) { 912 913 if (force_run) 914 CU_set_suite_active(pSuite, CU_TRUE); 915 916 if (test_id != -1) { /* If user specify test id */ 917 pTest = CU_get_test_by_index( 918 (unsigned int) test_id, 919 pSuite); 920 if (pTest) { 921 if (force_run) 922 CU_set_test_active(pTest, CU_TRUE); 923 924 CU_basic_run_test(pSuite, pTest); 925 } 926 else { 927 fprintf(stderr, "Invalid test id: %d\n", 928 test_id); 929 CU_cleanup_registry(); 930 amdgpu_close_devices(); 931 exit(EXIT_FAILURE); 932 } 933 } else 934 CU_basic_run_suite(pSuite); 935 } else { 936 fprintf(stderr, "Invalid suite id : %d\n", 937 suite_id); 938 CU_cleanup_registry(); 939 amdgpu_close_devices(); 940 exit(EXIT_FAILURE); 941 } 942 } else 943 CU_basic_run_tests(); 944 945 end: 946 CU_cleanup_registry(); 947 amdgpu_close_devices(); 948 return CU_get_error(); 949 } 950