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