basic_tests.c revision 646f5411cf36413c903eb6db48b5e7febd893ec5
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#include <stdio.h>
24#include <stdlib.h>
25#include <unistd.h>
26
27#include "CUnit/Basic.h"
28
29#include "amdgpu_test.h"
30#include "amdgpu_drm.h"
31
32static  amdgpu_device_handle device_handle;
33static  uint32_t  major_version;
34static  uint32_t  minor_version;
35
36static void amdgpu_query_info_test(void);
37static void amdgpu_memory_alloc(void);
38static void amdgpu_command_submission_gfx(void);
39static void amdgpu_command_submission_compute(void);
40static void amdgpu_command_submission_sdma(void);
41static void amdgpu_userptr_test(void);
42
43CU_TestInfo basic_tests[] = {
44	{ "Query Info Test",  amdgpu_query_info_test },
45	{ "Memory alloc Test",  amdgpu_memory_alloc },
46	{ "Userptr Test",  amdgpu_userptr_test },
47	{ "Command submission Test (GFX)",  amdgpu_command_submission_gfx },
48	{ "Command submission Test (Compute)", amdgpu_command_submission_compute },
49	{ "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
50	CU_TEST_INFO_NULL,
51};
52#define BUFFER_SIZE (8 * 1024)
53#define SDMA_PKT_HEADER_op_offset 0
54#define SDMA_PKT_HEADER_op_mask   0x000000FF
55#define SDMA_PKT_HEADER_op_shift  0
56#define SDMA_PKT_HEADER_OP(x) (((x) & SDMA_PKT_HEADER_op_mask) << SDMA_PKT_HEADER_op_shift)
57#define SDMA_OPCODE_CONSTANT_FILL  11
58#       define SDMA_CONSTANT_FILL_EXTRA_SIZE(x)           ((x) << 14)
59	/* 0 = byte fill
60	 * 2 = DW fill
61	 */
62#define SDMA_PACKET(op, sub_op, e)	((((e) & 0xFFFF) << 16) |	\
63					(((sub_op) & 0xFF) << 8) |	\
64					(((op) & 0xFF) << 0))
65#define	SDMA_OPCODE_WRITE				  2
66#       define SDMA_WRITE_SUB_OPCODE_LINEAR               0
67#       define SDMA_WRTIE_SUB_OPCODE_TILED                1
68
69#define	SDMA_OPCODE_COPY				  1
70#       define SDMA_COPY_SUB_OPCODE_LINEAR                0
71
72int suite_basic_tests_init(void)
73{
74	int r;
75
76	r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
77				   &minor_version, &device_handle);
78
79	if (r == 0)
80		return CUE_SUCCESS;
81	else
82		return CUE_SINIT_FAILED;
83}
84
85int suite_basic_tests_clean(void)
86{
87	int r = amdgpu_device_deinitialize(device_handle);
88
89	if (r == 0)
90		return CUE_SUCCESS;
91	else
92		return CUE_SCLEAN_FAILED;
93}
94
95static void amdgpu_query_info_test(void)
96{
97	struct amdgpu_gpu_info gpu_info = {0};
98	uint32_t version, feature;
99	int r;
100
101	r = amdgpu_query_gpu_info(device_handle, &gpu_info);
102	CU_ASSERT_EQUAL(r, 0);
103
104	r = amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0,
105					  0, &version, &feature);
106	CU_ASSERT_EQUAL(r, 0);
107}
108
109static void amdgpu_memory_alloc(void)
110{
111	amdgpu_bo_handle bo;
112	uint64_t bo_mc;
113	int r;
114
115	/* Test visible VRAM */
116	bo = gpu_mem_alloc(device_handle,
117			4096, 4096,
118			AMDGPU_GEM_DOMAIN_VRAM,
119			AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
120			&bo_mc);
121
122	r = amdgpu_bo_free(bo);
123	CU_ASSERT_EQUAL(r, 0);
124
125	/* Test invisible VRAM */
126	bo = gpu_mem_alloc(device_handle,
127			4096, 4096,
128			AMDGPU_GEM_DOMAIN_VRAM,
129			AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
130			&bo_mc);
131
132	r = amdgpu_bo_free(bo);
133	CU_ASSERT_EQUAL(r, 0);
134
135	/* Test GART Cacheable */
136	bo = gpu_mem_alloc(device_handle,
137			4096, 4096,
138			AMDGPU_GEM_DOMAIN_GTT,
139			0,
140			&bo_mc);
141
142	r = amdgpu_bo_free(bo);
143	CU_ASSERT_EQUAL(r, 0);
144
145	/* Test GART USWC */
146	bo = gpu_mem_alloc(device_handle,
147			4096, 4096,
148			AMDGPU_GEM_DOMAIN_GTT,
149			AMDGPU_GEM_CREATE_CPU_GTT_USWC,
150			&bo_mc);
151
152	r = amdgpu_bo_free(bo);
153	CU_ASSERT_EQUAL(r, 0);
154}
155
156static void amdgpu_command_submission_gfx_separate_ibs(void)
157{
158	amdgpu_context_handle context_handle;
159	amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
160	void *ib_result_cpu, *ib_result_ce_cpu;
161	uint64_t ib_result_mc_address, ib_result_ce_mc_address;
162	struct amdgpu_cs_request ibs_request = {0};
163	struct amdgpu_cs_ib_info ib_info[2];
164	struct amdgpu_cs_query_fence fence_status = {0};
165	uint32_t *ptr;
166	uint32_t expired;
167	int r;
168
169	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
170	CU_ASSERT_EQUAL(r, 0);
171
172	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
173				    AMDGPU_GEM_DOMAIN_GTT, 0,
174				    &ib_result_handle, &ib_result_cpu,
175				    &ib_result_mc_address);
176	CU_ASSERT_EQUAL(r, 0);
177
178	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
179				    AMDGPU_GEM_DOMAIN_GTT, 0,
180				    &ib_result_ce_handle, &ib_result_ce_cpu,
181				    &ib_result_ce_mc_address);
182	CU_ASSERT_EQUAL(r, 0);
183
184	memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
185
186	/* IT_SET_CE_DE_COUNTERS */
187	ptr = ib_result_ce_cpu;
188	ptr[0] = 0xc0008900;
189	ptr[1] = 0;
190	ptr[2] = 0xc0008400;
191	ptr[3] = 1;
192	ib_info[0].bo_handle = ib_result_ce_handle;
193	ib_info[0].size = 4;
194	ib_info[0].flags = AMDGPU_IB_FLAG_CE;
195
196	/* IT_WAIT_ON_CE_COUNTER */
197	ptr = ib_result_cpu;
198	ptr[0] = 0xc0008600;
199	ptr[1] = 0x00000001;
200	ib_info[1].bo_handle = ib_result_handle;
201	ib_info[1].size = 2;
202
203	ibs_request.ip_type = AMDGPU_HW_IP_GFX;
204	ibs_request.number_of_ibs = 2;
205	ibs_request.ibs = ib_info;
206
207	r = amdgpu_cs_submit(context_handle, 0,
208			     &ibs_request, 1, &fence_status.fence);
209	CU_ASSERT_EQUAL(r, 0);
210
211	fence_status.context = context_handle;
212	fence_status.timeout_ns = AMDGPU_TIMEOUT_INFINITE;
213	fence_status.ip_type = AMDGPU_HW_IP_GFX;
214
215	r = amdgpu_cs_query_fence_status(&fence_status, &expired);
216	CU_ASSERT_EQUAL(r, 0);
217
218	r = amdgpu_bo_free(ib_result_handle);
219	CU_ASSERT_EQUAL(r, 0);
220
221	r = amdgpu_bo_free(ib_result_ce_handle);
222	CU_ASSERT_EQUAL(r, 0);
223
224	r = amdgpu_cs_ctx_free(context_handle);
225	CU_ASSERT_EQUAL(r, 0);
226}
227
228static void amdgpu_command_submission_gfx_shared_ib(void)
229{
230	amdgpu_context_handle context_handle;
231	amdgpu_bo_handle ib_result_handle;
232	void *ib_result_cpu;
233	uint64_t ib_result_mc_address;
234	struct amdgpu_cs_request ibs_request = {0};
235	struct amdgpu_cs_ib_info ib_info[2];
236	struct amdgpu_cs_query_fence fence_status = {0};
237	uint32_t *ptr;
238	uint32_t expired;
239	int r;
240
241	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
242	CU_ASSERT_EQUAL(r, 0);
243
244	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
245				    AMDGPU_GEM_DOMAIN_GTT, 0,
246				    &ib_result_handle, &ib_result_cpu,
247				    &ib_result_mc_address);
248	CU_ASSERT_EQUAL(r, 0);
249
250	memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
251
252	/* IT_SET_CE_DE_COUNTERS */
253	ptr = ib_result_cpu;
254	ptr[0] = 0xc0008900;
255	ptr[1] = 0;
256	ptr[2] = 0xc0008400;
257	ptr[3] = 1;
258	ib_info[0].bo_handle = ib_result_handle;
259	ib_info[0].size = 4;
260	ib_info[0].flags = AMDGPU_IB_FLAG_CE;
261
262	ptr = (uint32_t *)ib_result_cpu + 4;
263	ptr[0] = 0xc0008600;
264	ptr[1] = 0x00000001;
265	ib_info[1].bo_handle = ib_result_handle;
266	ib_info[1].size = 2;
267	ib_info[1].offset_dw = 4;
268
269	ibs_request.ip_type = AMDGPU_HW_IP_GFX;
270	ibs_request.number_of_ibs = 2;
271	ibs_request.ibs = ib_info;
272
273	r = amdgpu_cs_submit(context_handle, 0,
274			&ibs_request, 1, &fence_status.fence);
275	CU_ASSERT_EQUAL(r, 0);
276
277	fence_status.context = context_handle;
278	fence_status.timeout_ns = AMDGPU_TIMEOUT_INFINITE;
279	fence_status.ip_type = AMDGPU_HW_IP_GFX;
280
281	r = amdgpu_cs_query_fence_status(&fence_status, &expired);
282	CU_ASSERT_EQUAL(r, 0);
283
284	r = amdgpu_bo_free(ib_result_handle);
285	CU_ASSERT_EQUAL(r, 0);
286
287	r = amdgpu_cs_ctx_free(context_handle);
288	CU_ASSERT_EQUAL(r, 0);
289}
290
291static void amdgpu_command_submission_gfx(void)
292{
293	/* separate IB buffers for multi-IB submission */
294	amdgpu_command_submission_gfx_separate_ibs();
295	/* shared IB buffer for multi-IB submission */
296	amdgpu_command_submission_gfx_shared_ib();
297}
298
299static void amdgpu_command_submission_compute(void)
300{
301	amdgpu_context_handle context_handle;
302	amdgpu_bo_handle ib_result_handle;
303	void *ib_result_cpu;
304	uint64_t ib_result_mc_address;
305	struct amdgpu_cs_request ibs_request;
306	struct amdgpu_cs_ib_info ib_info;
307	struct amdgpu_cs_query_fence fence_status;
308	uint32_t *ptr;
309	uint32_t expired;
310	int i, r, instance;
311
312	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
313	CU_ASSERT_EQUAL(r, 0);
314
315	for (instance = 0; instance < 8; instance++) {
316		r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
317					    AMDGPU_GEM_DOMAIN_GTT, 0,
318					    &ib_result_handle, &ib_result_cpu,
319					    &ib_result_mc_address);
320		CU_ASSERT_EQUAL(r, 0);
321
322		ptr = ib_result_cpu;
323		for (i = 0; i < 16; ++i)
324			ptr[i] = 0xffff1000;
325
326		memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
327		ib_info.bo_handle = ib_result_handle;
328		ib_info.size = 16;
329
330		memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
331		ibs_request.ip_type = AMDGPU_HW_IP_COMPUTE;
332		ibs_request.ring = instance;
333		ibs_request.number_of_ibs = 1;
334		ibs_request.ibs = &ib_info;
335
336		memset(&fence_status, 0, sizeof(struct amdgpu_cs_query_fence));
337		r = amdgpu_cs_submit(context_handle, 0,
338				     &ibs_request, 1, &fence_status.fence);
339		CU_ASSERT_EQUAL(r, 0);
340
341		fence_status.context = context_handle;
342		fence_status.timeout_ns = AMDGPU_TIMEOUT_INFINITE;
343		fence_status.ip_type = AMDGPU_HW_IP_COMPUTE;
344		fence_status.ring = instance;
345
346		r = amdgpu_cs_query_fence_status(&fence_status, &expired);
347		CU_ASSERT_EQUAL(r, 0);
348
349		r = amdgpu_bo_free(ib_result_handle);
350		CU_ASSERT_EQUAL(r, 0);
351	}
352
353	r = amdgpu_cs_ctx_free(context_handle);
354	CU_ASSERT_EQUAL(r, 0);
355}
356
357/*
358 * caller need create/release:
359 * pm4_src, resources, ib_info, and ibs_request
360 * submit command stream described in ibs_request and wait for this IB accomplished
361 */
362static void amdgpu_sdma_test_exec_cs(amdgpu_context_handle context_handle,
363				 int instance, int pm4_dw, uint32_t *pm4_src,
364				 int res_cnt, amdgpu_bo_handle *resources,
365				 struct amdgpu_cs_ib_info *ib_info,
366				 struct amdgpu_cs_request *ibs_request)
367{
368	int r, i, j;
369	uint32_t expired;
370	uint32_t *ring_ptr;
371	amdgpu_bo_handle ib_result_handle;
372	void *ib_result_cpu;
373	uint64_t ib_result_mc_address;
374	struct amdgpu_cs_query_fence fence_status = {0};
375
376	/* prepare CS */
377	CU_ASSERT_NOT_EQUAL(pm4_src, NULL);
378	CU_ASSERT_NOT_EQUAL(resources, NULL);
379	CU_ASSERT_NOT_EQUAL(ib_info, NULL);
380	CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
381	CU_ASSERT_TRUE(pm4_dw <= 1024);
382
383	/* allocate IB */
384	r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
385				    AMDGPU_GEM_DOMAIN_GTT, 0,
386				    &ib_result_handle, &ib_result_cpu,
387				    &ib_result_mc_address);
388	CU_ASSERT_EQUAL(r, 0);
389
390	/* copy PM4 packet to ring from caller */
391	ring_ptr = ib_result_cpu;
392	memcpy(ring_ptr, pm4_src, pm4_dw * sizeof(*pm4_src));
393
394	ib_info->bo_handle = ib_result_handle;
395	ib_info->size = pm4_dw;
396
397	ibs_request->ip_type = AMDGPU_HW_IP_DMA;
398	ibs_request->ring = instance;
399	ibs_request->number_of_ibs = 1;
400	ibs_request->ibs = ib_info;
401
402	r = amdgpu_bo_list_create(device_handle, res_cnt, resources,
403				  NULL, &ibs_request->resources);
404	CU_ASSERT_EQUAL(r, 0);
405
406	CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
407
408	/* submit CS */
409	r = amdgpu_cs_submit(context_handle, 0,
410			 ibs_request, 1, &fence_status.fence);
411	CU_ASSERT_EQUAL(r, 0);
412
413	r = amdgpu_bo_list_destroy(ibs_request->resources);
414	CU_ASSERT_EQUAL(r, 0);
415
416	fence_status.ip_type = AMDGPU_HW_IP_DMA;
417	fence_status.ring = ibs_request->ring;
418	fence_status.context = context_handle;
419	fence_status.timeout_ns = AMDGPU_TIMEOUT_INFINITE;
420
421	/* wait for IB accomplished */
422	r = amdgpu_cs_query_fence_status(&fence_status, &expired);
423	CU_ASSERT_EQUAL(r, 0);
424	CU_ASSERT_EQUAL(expired, true);
425
426	r = amdgpu_bo_free(ib_result_handle);
427	CU_ASSERT_EQUAL(r, 0);
428}
429
430static void amdgpu_command_submission_sdma_write_linear(void)
431{
432	const int sdma_write_length = 128;
433	const int pm4_dw = 256;
434	amdgpu_context_handle context_handle;
435	amdgpu_bo_handle bo;
436	amdgpu_bo_handle *resources;
437	uint32_t *pm4;
438	struct amdgpu_cs_ib_info *ib_info;
439	struct amdgpu_cs_request *ibs_request;
440	uint64_t bo_mc;
441	volatile uint32_t *bo_cpu;
442	int i, j, r, loop;
443	uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
444
445	pm4 = calloc(pm4_dw, sizeof(*pm4));
446	CU_ASSERT_NOT_EQUAL(pm4, NULL);
447
448	ib_info = calloc(1, sizeof(*ib_info));
449	CU_ASSERT_NOT_EQUAL(ib_info, NULL);
450
451	ibs_request = calloc(1, sizeof(*ibs_request));
452	CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
453
454	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
455	CU_ASSERT_EQUAL(r, 0);
456
457	/* prepare resource */
458	resources = calloc(1, sizeof(amdgpu_bo_handle));
459	CU_ASSERT_NOT_EQUAL(resources, NULL);
460
461	loop = 0;
462	while(loop < 2) {
463		/* allocate UC bo for sDMA use */
464		bo = gpu_mem_alloc(device_handle,
465				sdma_write_length * sizeof(uint32_t),
466				4096, AMDGPU_GEM_DOMAIN_GTT,
467				gtt_flags[loop], &bo_mc);
468
469		CU_ASSERT_EQUAL(amdgpu_bo_cpu_map(bo, (void **)&bo_cpu), 0);
470		CU_ASSERT_NOT_EQUAL(bo_cpu, NULL);
471
472		/* clear bo */
473		memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t));
474
475
476		resources[0] = bo;
477
478		/* fullfill PM4: test DMA write-linear */
479		i = j = 0;
480		pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
481				SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
482		pm4[i++] = 0xffffffff & bo_mc;
483		pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
484		pm4[i++] = sdma_write_length;
485		while(j++ < sdma_write_length)
486			pm4[i++] = 0xdeadbeaf;
487
488		amdgpu_sdma_test_exec_cs(context_handle, 0,
489					i, pm4,
490					1, resources,
491					ib_info, ibs_request);
492
493		/* verify if SDMA test result meets with expected */
494		i = 0;
495		while(i < sdma_write_length) {
496			CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
497		}
498		amdgpu_bo_free(bo);
499		loop++;
500	}
501	/* clean resources */
502	free(resources);
503	free(ibs_request);
504	free(ib_info);
505	free(pm4);
506
507	/* end of test */
508	r = amdgpu_cs_ctx_free(context_handle);
509	CU_ASSERT_EQUAL(r, 0);
510}
511
512static void amdgpu_command_submission_sdma_const_fill(void)
513{
514	const int sdma_write_length = 1024 * 1024;
515	const int pm4_dw = 256;
516	amdgpu_context_handle context_handle;
517	amdgpu_bo_handle bo;
518	amdgpu_bo_handle *resources;
519	uint32_t *pm4;
520	struct amdgpu_cs_ib_info *ib_info;
521	struct amdgpu_cs_request *ibs_request;
522	uint64_t bo_mc;
523	volatile uint32_t *bo_cpu;
524	int i, j, r, loop;
525	uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
526
527	pm4 = calloc(pm4_dw, sizeof(*pm4));
528	CU_ASSERT_NOT_EQUAL(pm4, NULL);
529
530	ib_info = calloc(1, sizeof(*ib_info));
531	CU_ASSERT_NOT_EQUAL(ib_info, NULL);
532
533	ibs_request = calloc(1, sizeof(*ibs_request));
534	CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
535
536	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
537	CU_ASSERT_EQUAL(r, 0);
538
539	/* prepare resource */
540	resources = calloc(1, sizeof(amdgpu_bo_handle));
541	CU_ASSERT_NOT_EQUAL(resources, NULL);
542
543	loop = 0;
544	while(loop < 2) {
545		/* allocate UC bo for sDMA use */
546		bo = gpu_mem_alloc(device_handle,
547				sdma_write_length, 4096,
548				AMDGPU_GEM_DOMAIN_GTT,
549				gtt_flags[loop], &bo_mc);
550
551		CU_ASSERT_EQUAL(amdgpu_bo_cpu_map(bo, (void **)&bo_cpu), 0);
552		CU_ASSERT_NOT_EQUAL(bo_cpu, NULL);
553
554		/* clear bo */
555		memset((void*)bo_cpu, 0, sdma_write_length);
556
557		resources[0] = bo;
558
559		/* fullfill PM4: test DMA const fill */
560		i = j = 0;
561		pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0,
562				   SDMA_CONSTANT_FILL_EXTRA_SIZE(2));
563		pm4[i++] = 0xffffffff & bo_mc;
564		pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
565		pm4[i++] = 0xdeadbeaf;
566		pm4[i++] = sdma_write_length;
567
568		amdgpu_sdma_test_exec_cs(context_handle, 0,
569					i, pm4,
570					1, resources,
571					ib_info, ibs_request);
572
573		/* verify if SDMA test result meets with expected */
574		i = 0;
575		while(i < (sdma_write_length / 4)) {
576			CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
577		}
578		amdgpu_bo_free(bo);
579		loop++;
580	}
581	/* clean resources */
582	free(resources);
583	free(ibs_request);
584	free(ib_info);
585	free(pm4);
586
587	/* end of test */
588	r = amdgpu_cs_ctx_free(context_handle);
589	CU_ASSERT_EQUAL(r, 0);
590}
591
592static void amdgpu_command_submission_sdma_copy_linear(void)
593{
594	const int sdma_write_length = 1024;
595	const int pm4_dw = 256;
596	amdgpu_context_handle context_handle;
597	amdgpu_bo_handle bo1, bo2;
598	amdgpu_bo_handle *resources;
599	uint32_t *pm4;
600	struct amdgpu_cs_ib_info *ib_info;
601	struct amdgpu_cs_request *ibs_request;
602	uint64_t bo1_mc, bo2_mc;
603	volatile unsigned char *bo1_cpu, *bo2_cpu;
604	int i, j, r, loop1, loop2;
605	uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
606
607	pm4 = calloc(pm4_dw, sizeof(*pm4));
608	CU_ASSERT_NOT_EQUAL(pm4, NULL);
609
610	ib_info = calloc(1, sizeof(*ib_info));
611	CU_ASSERT_NOT_EQUAL(ib_info, NULL);
612
613	ibs_request = calloc(1, sizeof(*ibs_request));
614	CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
615
616	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
617	CU_ASSERT_EQUAL(r, 0);
618
619	/* prepare resource */
620	resources = calloc(2, sizeof(amdgpu_bo_handle));
621	CU_ASSERT_NOT_EQUAL(resources, NULL);
622
623	loop1 = loop2 = 0;
624	/* run 9 circle to test all mapping combination */
625	while(loop1 < 2) {
626		while(loop2 < 2) {
627			/* allocate UC bo1for sDMA use */
628			bo1 = gpu_mem_alloc(device_handle,
629					sdma_write_length, 4096,
630					AMDGPU_GEM_DOMAIN_GTT,
631					gtt_flags[loop1], &bo1_mc);
632
633			CU_ASSERT_EQUAL(amdgpu_bo_cpu_map(bo1, (void **)&bo1_cpu), 0);
634			CU_ASSERT_NOT_EQUAL(bo1_cpu, NULL);
635
636			/* set bo1 */
637			memset((void*)bo1_cpu, 0xaa, sdma_write_length);
638
639			/* allocate UC bo2 for sDMA use */
640			bo2 = gpu_mem_alloc(device_handle,
641					sdma_write_length, 4096,
642					AMDGPU_GEM_DOMAIN_GTT,
643					gtt_flags[loop2], &bo2_mc);
644
645			CU_ASSERT_EQUAL(amdgpu_bo_cpu_map(bo2, (void **)&bo2_cpu), 0);
646			CU_ASSERT_NOT_EQUAL(bo2_cpu, NULL);
647
648			/* clear bo2 */
649			memset((void*)bo2_cpu, 0, sdma_write_length);
650
651			resources[0] = bo1;
652			resources[1] = bo2;
653
654			/* fullfill PM4: test DMA copy linear */
655			i = j = 0;
656			pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
657			pm4[i++] = sdma_write_length;
658			pm4[i++] = 0;
659			pm4[i++] = 0xffffffff & bo1_mc;
660			pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
661			pm4[i++] = 0xffffffff & bo2_mc;
662			pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
663
664
665			amdgpu_sdma_test_exec_cs(context_handle, 0,
666						i, pm4,
667						2, resources,
668						ib_info, ibs_request);
669
670			/* verify if SDMA test result meets with expected */
671			i = 0;
672			while(i < sdma_write_length) {
673				CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa);
674			}
675			amdgpu_bo_free(bo1);
676			amdgpu_bo_free(bo2);
677			loop2++;
678		}
679		loop1++;
680	}
681	/* clean resources */
682	free(resources);
683	free(ibs_request);
684	free(ib_info);
685	free(pm4);
686
687	/* end of test */
688	r = amdgpu_cs_ctx_free(context_handle);
689	CU_ASSERT_EQUAL(r, 0);
690}
691
692static void amdgpu_command_submission_sdma(void)
693{
694	amdgpu_command_submission_sdma_write_linear();
695	amdgpu_command_submission_sdma_const_fill();
696	amdgpu_command_submission_sdma_copy_linear();
697}
698
699static void amdgpu_userptr_test(void)
700{
701	int i, r, j;
702	uint32_t *pm4 = NULL;
703	uint64_t bo_mc;
704	void *ptr = NULL;
705	int pm4_dw = 256;
706	int sdma_write_length = 4;
707	amdgpu_bo_handle handle;
708	amdgpu_context_handle context_handle;
709	struct amdgpu_cs_ib_info *ib_info;
710	struct amdgpu_cs_request *ibs_request;
711	struct amdgpu_bo_alloc_result res;
712
713	memset(&res, 0, sizeof(res));
714
715	pm4 = calloc(pm4_dw, sizeof(*pm4));
716	CU_ASSERT_NOT_EQUAL(pm4, NULL);
717
718	ib_info = calloc(1, sizeof(*ib_info));
719	CU_ASSERT_NOT_EQUAL(ib_info, NULL);
720
721	ibs_request = calloc(1, sizeof(*ibs_request));
722	CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
723
724	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
725	CU_ASSERT_EQUAL(r, 0);
726
727	posix_memalign(&ptr, sysconf(_SC_PAGE_SIZE), BUFFER_SIZE);
728	CU_ASSERT_NOT_EQUAL(ptr, NULL);
729	memset(ptr, 0, BUFFER_SIZE);
730
731	r = amdgpu_create_bo_from_user_mem(device_handle,
732					   ptr, BUFFER_SIZE, &res);
733	CU_ASSERT_EQUAL(r, 0);
734	bo_mc = res.virtual_mc_base_address;
735	handle = res.buf_handle;
736
737	j = i = 0;
738	pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
739			       SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
740	pm4[i++] = 0xffffffff & bo_mc;
741	pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
742	pm4[i++] = sdma_write_length;
743
744	while (j++ < sdma_write_length)
745		pm4[i++] = 0xdeadbeaf;
746
747	amdgpu_sdma_test_exec_cs(context_handle, 0,
748				 i, pm4,
749				 1, &handle,
750				 ib_info, ibs_request);
751	i = 0;
752	while (i < sdma_write_length) {
753		CU_ASSERT_EQUAL(((int*)ptr)[i++], 0xdeadbeaf);
754	}
755	free(ibs_request);
756	free(ib_info);
757	free(pm4);
758	r = amdgpu_bo_free(res.buf_handle);
759	CU_ASSERT_EQUAL(r, 0);
760	free(ptr);
761
762	r = amdgpu_cs_ctx_free(context_handle);
763	CU_ASSERT_EQUAL(r, 0);
764}
765