[igt-dev] [CI] tests/i915/gem_huc_copy: Enable a HuC copy test
Chris Wilson
chris at chris-wilson.co.uk
Fri Jun 5 19:45:40 UTC 2020
From: Sally Qi <feng.qi at intel.com>
This test case loads the HuC copy firmware to copy the content of
the source buffer to the destination buffer.
v2: (Tony Ye)
* Restructured some functions and files.
* Defined the copy buffer size as 4K explicitly as the HuC Copy kernel
always copy 4K bytes from src buffer to dst buffer.
v3: (Feng Qi, Antonio Argenziano, Tony Ye)
* Restructured some functions as igt requested, exclude libdrm function call.
* Remove huc function wrappers
* Random initialize source input buffer
v4: (Robert Fosha)
* Fix autotools build failure.
v5: (Feng Qi, Tony Ye)
* Released all bo buffer after huc copying.
* Restructured huc_copy() function.
v6: (Feng Qi)
* Fixed the function of huc enabling and status check
* Added huc_copy to fast feedback testlist
v7: (Tony Ye, Feng Qi, Robert Fosha, Chris Wilson, Michal Wajdeczko)
* Check error with HUC_STATUS ioctl instead of debugfs
v8: (Antonio Argenziano)
* Remove unnecessary variable.
* Add huc_load subtest.
* Move failure checks out of igt_fixture.
Signed-off-by: Feng Qi <feng.qi at intel.com>
Signed-off-by: Tony Ye <tony.ye at intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Acked-by: Antonio Argenziano <antonio.argenziano at intel.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
lib/Makefile.sources | 2 +
lib/huc_copy.c | 120 +++++++++++++++++++++
lib/huc_copy.h | 47 +++++++++
lib/intel_batchbuffer.c | 20 ++++
lib/intel_batchbuffer.h | 18 ++++
lib/meson.build | 1 +
tests/Makefile.sources | 3 +
tests/i915/gem_huc_copy.c | 144 ++++++++++++++++++++++++++
tests/intel-ci/fast-feedback.testlist | 2 +
tests/meson.build | 1 +
10 files changed, 358 insertions(+)
create mode 100644 lib/huc_copy.c
create mode 100644 lib/huc_copy.h
create mode 100644 tests/i915/gem_huc_copy.c
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index 09aedb403..e87a66ccb 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -88,6 +88,8 @@ lib_source_list = \
ioctl_wrappers.h \
media_fill.c \
media_fill.h \
+ huc_copy.c \
+ huc_copy.h \
media_spin.h \
media_spin.c \
gpgpu_fill.h \
diff --git a/lib/huc_copy.c b/lib/huc_copy.c
new file mode 100644
index 000000000..65033757c
--- /dev/null
+++ b/lib/huc_copy.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <i915_drm.h>
+#include "huc_copy.h"
+
+static unsigned int offset_in_page(void *addr)
+{
+ return (uintptr_t)addr & 4095;
+}
+
+static uint32_t *
+gen9_emit_huc_virtual_addr_state(uint32_t *cs,
+ struct drm_i915_gem_exec_object2 *src,
+ struct drm_i915_gem_exec_object2 *dst,
+ struct drm_i915_gem_relocation_entry *reloc_src,
+ struct drm_i915_gem_relocation_entry *reloc_dst)
+{
+ *cs++ = HUC_VIRTUAL_ADDR_STATE;
+
+ for (int j = 0; j < HUC_VIRTUAL_ADDR_REGION_NUM; j++) {
+ uint64_t addr = 0;
+
+ switch (j) {
+ case HUC_VIRTUAL_ADDR_REGION_SRC:
+ reloc_src->target_handle = src->handle;
+ reloc_src->presumed_offset = src->offset;
+ reloc_src->delta = 0;
+ reloc_dst->offset = offset_in_page(cs);
+ reloc_src->read_domains = 0;
+ reloc_src->write_domain = 0;
+
+ addr = reloc_src->presumed_offset;
+ break;
+
+ case HUC_VIRTUAL_ADDR_REGION_DST:
+ reloc_dst->target_handle = dst->handle;
+ reloc_dst->presumed_offset = dst->offset;
+ reloc_dst->delta = 0;
+ reloc_dst->offset = offset_in_page(cs);
+ reloc_dst->read_domains = 0;
+ reloc_dst->write_domain = I915_GEM_DOMAIN_RENDER;
+
+ addr = reloc_dst->presumed_offset;
+ break;
+
+ default:
+ break;
+ }
+
+ *cs++ = addr;
+ *cs++ = addr >> 32;
+ *cs++ = 0;
+ }
+
+ return cs;
+}
+
+void gen9_huc_copyfunc(int fd, struct drm_i915_gem_exec_object2 *obj)
+{
+ struct drm_i915_gem_relocation_entry reloc[2] = {};
+ struct drm_i915_gem_execbuffer2 execbuf = {
+ .buffers_ptr = to_user_pointer(obj),
+ .buffer_count = 3,
+ .flags = I915_EXEC_BSD | I915_EXEC_NO_RELOC,
+ };
+ uint32_t buf[64], *cs = buf;
+
+ /* load huc kernel */
+ *cs++ = HUC_IMEM_STATE;
+ *cs++ = 0;
+ *cs++ = 0;
+ *cs++ = 0;
+ *cs++ = 0x3;
+
+ *cs++ = MFX_WAIT;
+ *cs++ = MFX_WAIT;
+
+ *cs++ = HUC_PIPE_MODE_SELECT;
+ *cs++ = 0;
+ *cs++ = 0;
+
+ *cs++ = MFX_WAIT;
+
+ cs = gen9_emit_huc_virtual_addr_state(cs,
+ &obj[0], &obj[1],
+ &reloc[0], &reloc[1]);
+
+ *cs++ = HUC_START;
+ *cs++ = 1;
+
+ *cs++ = MI_BATCH_BUFFER_END;
+
+ gem_write(fd, obj[2].handle, 0, buf, sizeof(buf));
+ obj[2].relocation_count = 2;
+ obj[2].relocs_ptr = to_user_pointer(reloc);
+
+ gem_execbuf(fd, &execbuf);
+}
diff --git a/lib/huc_copy.h b/lib/huc_copy.h
new file mode 100644
index 000000000..f921cead7
--- /dev/null
+++ b/lib/huc_copy.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef HUC_COPY_H
+#define HUC_COPY_H
+
+#include <stdint.h>
+#include <string.h>
+#include "ioctl_wrappers.h"
+#include "intel_reg.h"
+
+#define PARALLEL_VIDEO_PIPE (0x3<<29)
+#define MFX_WAIT (PARALLEL_VIDEO_PIPE|(0x1<<27)|(0x1<<8))
+
+#define HUC_IMEM_STATE (PARALLEL_VIDEO_PIPE|(0x2<<27)|(0xb<<23)|(0x1<<16)|0x3)
+#define HUC_PIPE_MODE_SELECT (PARALLEL_VIDEO_PIPE|(0x2<<27)|(0xb<<23)|0x1)
+#define HUC_START (PARALLEL_VIDEO_PIPE|(0x2<<27)|(0xb<<23)|(0x21<<16))
+#define HUC_VIRTUAL_ADDR_STATE (PARALLEL_VIDEO_PIPE|(0x2<<27)|(0xb<<23)|(0x4<<16)|0x2f)
+
+#define HUC_VIRTUAL_ADDR_REGION_NUM 16
+#define HUC_VIRTUAL_ADDR_REGION_SRC 0
+#define HUC_VIRTUAL_ADDR_REGION_DST 14
+
+void gen9_huc_copyfunc(int fd, struct drm_i915_gem_exec_object2 *obj);
+
+#endif /* HUC_COPY_H */
diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
index 49f2d0fee..652d34b34 100644
--- a/lib/intel_batchbuffer.c
+++ b/lib/intel_batchbuffer.c
@@ -48,6 +48,7 @@
#include "igt_aux.h"
#include "igt_rand.h"
#include "i830_reg.h"
+#include "huc_copy.h"
#include <i915_drm.h>
@@ -1649,3 +1650,22 @@ uint64_t intel_bb_get_object_offset(struct intel_bb *ibb, uint32_t handle)
return (*found)->offset;
}
+
+/**
+ * igt_get_huc_copyfunc:
+ * @devid: pci device id
+ *
+ * Returns:
+ *
+ * The platform-specific huc copy function pointer for the device specified
+ * with @devid. Will return NULL when no media spin function is implemented.
+ */
+igt_huc_copyfunc_t igt_get_huc_copyfunc(int devid)
+{
+ igt_huc_copyfunc_t copy = NULL;
+
+ if (IS_GEN12(devid) || IS_GEN11(devid) || IS_GEN9(devid))
+ copy = gen9_huc_copyfunc;
+
+ return copy;
+}
diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h
index ae052c17b..553b3ad6f 100644
--- a/lib/intel_batchbuffer.h
+++ b/lib/intel_batchbuffer.h
@@ -525,4 +525,22 @@ void intel_bb_exec_with_context(struct intel_bb *ibb, uint32_t end_offset,
uint64_t intel_bb_get_object_offset(struct intel_bb *ibb, uint32_t handle);
+/**
+ * igt_huc_copyfunc_t:
+ * @fd: drm fd
+ * @obj: drm_i915_gem_exec_object2 buffer array
+ * obj[0] is source buffer
+ * obj[1] is destination buffer
+ * obj[2] is execution buffer
+ *
+ * This is the type of the per-platform huc copy functions.
+ *
+ * The huc copy function emits a batchbuffer to the VDBOX engine to
+ * invoke the HuC Copy kernel to copy 4K bytes from the source buffer
+ * to the destination buffer.
+ */
+typedef void (*igt_huc_copyfunc_t)(int fd,
+ struct drm_i915_gem_exec_object2 *obj);
+
+igt_huc_copyfunc_t igt_get_huc_copyfunc(int devid);
#endif
diff --git a/lib/meson.build b/lib/meson.build
index 99aee6ee1..4321820de 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -1,5 +1,6 @@
lib_sources = [
'drmtest.c',
+ 'huc_copy.c',
'i915/gem.c',
'i915/gem_context.c',
'i915/gem_engine_topology.c',
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index eaa6c0d04..d80c031e2 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -319,6 +319,9 @@ gem_media_fill_SOURCES = i915/gem_media_fill.c
TESTS_progs += gem_media_vme
gem_media_vme_SOURCES = i915/gem_media_vme.c
+TESTS_progs += gem_huc_copy
+gem_huc_copy_SOURCES = i915/gem_huc_copy.c
+
TESTS_progs += gem_mmap
gem_mmap_SOURCES = i915/gem_mmap.c
diff --git a/tests/i915/gem_huc_copy.c b/tests/i915/gem_huc_copy.c
new file mode 100644
index 000000000..2d3cb1f56
--- /dev/null
+++ b/tests/i915/gem_huc_copy.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include "igt.h"
+#include <stdbool.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include "drm.h"
+#include "i915/gem.h"
+
+IGT_TEST_DESCRIPTION("A very simple workload for the HuC.");
+
+#define HUC_COPY_DATA_DW 1024
+#define HUC_COPY_DATA_BUF_SIZE (HUC_COPY_DATA_DW * sizeof(uint32_t))
+
+static void
+compare_u32(uint32_t *src, uint32_t *dst, int len)
+{
+ for (int i = 0; i < len; i++)
+ igt_assert_f(src[i] == dst[i],
+ "Expected %08x, found %08x at %x.\n",
+ src[i], dst[i], 4 * i);
+}
+
+static int get_huc_status(int fd)
+{
+ int status = 0;
+ drm_i915_getparam_t gp = {
+ .param = I915_PARAM_HUC_STATUS,
+ .value = &status,
+ };
+
+ if (igt_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
+ return -errno;
+
+ errno = 0;
+ return status;
+}
+
+static void test_huc_load(int fd)
+{
+ int status = get_huc_status(fd);
+
+ igt_skip_on_f(status == -ENODEV,
+ "HuC is not present on this platform!\n");
+ igt_skip_on_f(status == -EOPNOTSUPP,
+ "HuC firmware is disabled!\n");
+ igt_fail_on_f(status < 0, "HuC firmware loading error: %i, %s\n",
+ -status, strerror(-status));
+ igt_fail_on_f(status == 0, "HuC firmware is not running!\n");
+}
+
+igt_main
+{
+ int i915 = -1;
+ igt_huc_copyfunc_t huc_copy;
+
+ igt_fixture {
+ uint32_t devid;
+
+ i915 = drm_open_driver(DRIVER_INTEL);
+ igt_require_gem(i915);
+
+ devid = intel_get_drm_devid(i915);
+ huc_copy = igt_get_huc_copyfunc(devid);
+ igt_require_f(huc_copy, "no huc_copy function\n");
+ }
+
+ igt_describe("Make sure that Huc has loaded"
+ "successfully if enabled and"
+ "present");
+
+ igt_subtest("huc-load")
+ test_huc_load(i915);
+
+ igt_describe("Make sure that Huc firmware works"
+ "by copying a char array using Huc"
+ "and verifying the copied result");
+
+ igt_subtest("huc-copy") {
+ struct drm_i915_gem_exec_object2 obj[3];
+ uint32_t inputs[HUC_COPY_DATA_DW];
+ uint32_t src[HUC_COPY_DATA_DW];
+ uint32_t dst[HUC_COPY_DATA_DW];
+
+ test_huc_load(i915);
+ /* Initialize src buffer randomly */
+ srand(time(NULL));
+ for (int i = 0; i < HUC_COPY_DATA_DW; i++)
+ inputs[i] = rand();
+
+ memset(obj, 0, sizeof(obj));
+ /* source buffer object for storing input */
+ obj[0].handle = gem_create(i915, HUC_COPY_DATA_BUF_SIZE);
+ /* destination buffer object to receive input */
+ obj[1].handle = gem_create(i915, HUC_COPY_DATA_BUF_SIZE);
+ /* execution buffer object */
+ obj[2].handle = gem_create(i915, 4096);
+
+ gem_write(i915, obj[0].handle, 0, inputs, sizeof(inputs));
+
+ huc_copy(i915, obj);
+
+ gem_read(i915, obj[0].handle, 0, src, sizeof(src));
+ gem_read(i915, obj[1].handle, 0, dst, sizeof(dst));
+
+ compare_u32(inputs, src, HUC_COPY_DATA_DW);
+ compare_u32(src, dst, HUC_COPY_DATA_DW);
+
+ gem_close(i915, obj[2].handle);
+ gem_close(i915, obj[1].handle);
+ gem_close(i915, obj[0].handle);
+ }
+
+ igt_fixture
+ close(i915);
+}
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index 04f6affcf..b23a884d4 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -28,6 +28,8 @@ igt at gem_flink_basic@bad-open
igt at gem_flink_basic@basic
igt at gem_flink_basic@double-flink
igt at gem_flink_basic@flink-lifetime
+igt at gem_huc_copy@huc_copy
+igt at gem_huc_copy@huc_load
igt at gem_linear_blits@basic
igt at gem_mmap@basic
igt at gem_mmap_gtt@basic
diff --git a/tests/meson.build b/tests/meson.build
index e69bdb7d0..5733d1e97 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -166,6 +166,7 @@ i915_progs = [
'gem_gtt_cpu_tlb',
'gem_gtt_hog',
'gem_gtt_speed',
+ 'gem_huc_copy',
'gem_linear_blits',
'gem_lut_handle',
'gem_madvise',
--
2.27.0
More information about the igt-dev
mailing list