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
always_active()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 */
display_test_suites(void)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 */
amdgpu_open_devices(int open_render_node)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 */
amdgpu_close_devices()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 */
amdgpu_print_devices()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 */
amdgpu_find_device(uint8_t bus,uint16_t dev)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
amdgpu_disable_suites()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
amdgpu_open_device_on_test_index(int render_node)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
amdgpu_node_is_drm(int maj,int min)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
amdgpu_get_device_from_fd(int fd)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
amdgpu_test_disable(long suite,long test)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 */
main(int argc,char ** argv)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