Commit 32f8759b authored by Sally Qi's avatar Sally Qi Committed by Antonio Argenziano

tests/i915/gem_huc_copy: Enable a HuC copy test

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.
 * get_huc_status() returns errno and then status as a parameter

v9: (Antonio Argenziano)
 * Remove huc_load subtest - to be added later.

v10:
 * Rebase
 * Remove huc_load subtest from fast-feedback.testlist.
Signed-off-by: default avatarFeng Qi <feng.qi@intel.com>
Signed-off-by: default avatarTony Ye <tony.ye@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Antonio Argenziano's avatarAntonio Argenziano <antonio.argenziano@intel.com>
parent 21f8204e
Pipeline #177383 passed with stages
in 13 minutes and 50 seconds
...@@ -90,6 +90,8 @@ lib_source_list = \ ...@@ -90,6 +90,8 @@ lib_source_list = \
ioctl_wrappers.h \ ioctl_wrappers.h \
media_fill.c \ media_fill.c \
media_fill.h \ media_fill.h \
huc_copy.c \
huc_copy.h \
media_spin.h \ media_spin.h \
media_spin.c \ media_spin.c \
gpgpu_fill.h \ gpgpu_fill.h \
......
/*
* 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 void
gen9_emit_huc_virtual_addr_state(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,
uint32_t *buf,
int *i)
{
buf[(*i)++] = HUC_VIRTUAL_ADDR_STATE;
for (int j = 0; j < HUC_VIRTUAL_ADDR_REGION_NUM; j++) {
if (j == HUC_VIRTUAL_ADDR_REGION_SRC) {
buf[(*i)++] = src->offset;
reloc_src->target_handle = src->handle;
reloc_src->delta = 0;
reloc_src->offset = (*i - 1) * sizeof(buf[0]);
reloc_src->read_domains = 0;
reloc_src->write_domain = 0;
} else if (j == HUC_VIRTUAL_ADDR_REGION_DST) {
buf[(*i)++] = dst->offset;
reloc_dst->target_handle = dst->handle;
reloc_dst->delta = 0;
reloc_dst->offset = (*i - 1) * sizeof(buf[0]);
reloc_dst->read_domains = 0;
reloc_dst->write_domain = I915_GEM_DOMAIN_RENDER;
} else {
buf[(*i)++] = 0;
}
buf[(*i)++] = 0;
buf[(*i)++] = 0;
}
}
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;
int i = 0;
uint32_t buf[63];
/* load huc kernel */
buf[i++] = HUC_IMEM_STATE;
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = 0x3;
buf[i++] = MFX_WAIT;
buf[i++] = MFX_WAIT;
buf[i++] = HUC_PIPE_MODE_SELECT;
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = MFX_WAIT;
memset(reloc, 0, sizeof(reloc));
gen9_emit_huc_virtual_addr_state(&obj[0], &obj[1], &reloc[0], &reloc[1], buf, &i);
buf[i++] = HUC_START;
buf[i++] = 1;
buf[i++] = 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);
memset(&execbuf, 0, sizeof(execbuf));
execbuf.buffers_ptr = to_user_pointer(obj);
execbuf.buffer_count = 3;
execbuf.flags = I915_EXEC_BSD;
gem_execbuf(fd, &execbuf);
}
/*
* 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 */
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "igt_aux.h" #include "igt_aux.h"
#include "igt_rand.h" #include "igt_rand.h"
#include "i830_reg.h" #include "i830_reg.h"
#include "huc_copy.h"
#include <i915_drm.h> #include <i915_drm.h>
...@@ -2125,3 +2126,22 @@ void intel_bb_blt_copy(struct intel_bb *ibb, ...@@ -2125,3 +2126,22 @@ void intel_bb_blt_copy(struct intel_bb *ibb,
intel_bb_emit_bbe(ibb); intel_bb_emit_bbe(ibb);
intel_bb_flush_blit(ibb); intel_bb_flush_blit(ibb);
} }
/**
* 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;
}
...@@ -601,4 +601,23 @@ void intel_bb_blt_copy(struct intel_bb *ibb, ...@@ -601,4 +601,23 @@ void intel_bb_blt_copy(struct intel_bb *ibb,
struct intel_buf *dst, struct intel_buf *dst,
int dst_x1, int dst_y1, int dst_pitch, int dst_x1, int dst_y1, int dst_pitch,
int width, int height, int bpp); int width, int height, int bpp);
/**
* 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 #endif
lib_sources = [ lib_sources = [
'drmtest.c', 'drmtest.c',
'huc_copy.c',
'i915/gem.c', 'i915/gem.c',
'i915/gem_context.c', 'i915/gem_context.c',
'i915/gem_engine_topology.c', 'i915/gem_engine_topology.c',
......
...@@ -323,6 +323,9 @@ gem_media_fill_SOURCES = i915/gem_media_fill.c ...@@ -323,6 +323,9 @@ gem_media_fill_SOURCES = i915/gem_media_fill.c
TESTS_progs += gem_media_vme TESTS_progs += gem_media_vme
gem_media_vme_SOURCES = i915/gem_media_vme.c 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 TESTS_progs += gem_mmap
gem_mmap_SOURCES = i915/gem_mmap.c gem_mmap_SOURCES = i915/gem_mmap.c
......
/*
* 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_BUF_SIZE 4096
static void
compare_huc_copy_result(int drm_fd, uint32_t src_handle, uint32_t dst_handle)
{
char src_output[HUC_COPY_DATA_BUF_SIZE];
char dst_output[HUC_COPY_DATA_BUF_SIZE];
gem_read(drm_fd, src_handle, 0, src_output, HUC_COPY_DATA_BUF_SIZE);
gem_read(drm_fd, dst_handle, 0, dst_output, HUC_COPY_DATA_BUF_SIZE);
for (int i = 0; i < HUC_COPY_DATA_BUF_SIZE; i++)
igt_assert_f(src_output[i] == dst_output[i],
"Exepected %c, found %c at %4d.\n",
src_output[i], dst_output[i], i);
}
static int get_huc_status(int fd, int *status)
{
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 errno;
}
static void test_huc_load(int fd)
{
int err;
int status = 0;
err = get_huc_status(fd, &status);
igt_skip_on_f(err == -ENODEV,
"HuC is not present on this platform!\n");
igt_skip_on_f(err == -EOPNOTSUPP,
"HuC firmware is disabled!\n");
igt_fail_on_f(err < 0, "HuC firmware loading error: %i, %s\n",
-err, strerror(-err));
igt_fail_on_f(status == 0, "HuC firmware is not running!\n");
}
igt_main
{
int drm_fd = -1;
uint32_t devid;
igt_huc_copyfunc_t huc_copy;
igt_fixture {
drm_fd = drm_open_driver(DRIVER_INTEL);
igt_require_gem(drm_fd);
devid = intel_get_drm_devid(drm_fd);
huc_copy = igt_get_huc_copyfunc(devid);
igt_require_f(huc_copy, "no huc_copy function\n");
}
igt_describe("Make sure that Huc firmware works"
"by copying a char array using Huc"
"and verifying the copied result");
igt_subtest("huc-copy") {
char inputs[HUC_COPY_DATA_BUF_SIZE];
struct drm_i915_gem_exec_object2 obj[3];
test_huc_load(drm_fd);
/* Initialize src buffer randomly */
srand(time(NULL));
for (int i = 0; i < HUC_COPY_DATA_BUF_SIZE; i++)
inputs[i] = (char) (rand() % 256);
memset(obj, 0, sizeof(obj));
/* source buffer object for storing input */
obj[0].handle = gem_create(drm_fd, HUC_COPY_DATA_BUF_SIZE);
/* destination buffer object to receive input */
obj[1].handle = gem_create(drm_fd, HUC_COPY_DATA_BUF_SIZE);
/* execution buffer object */
obj[2].handle = gem_create(drm_fd, 4096);
gem_write(drm_fd, obj[0].handle, 0, inputs, HUC_COPY_DATA_BUF_SIZE);
huc_copy(drm_fd, obj);
compare_huc_copy_result(drm_fd, obj[0].handle, obj[1].handle);
gem_close(drm_fd, obj[0].handle);
gem_close(drm_fd, obj[1].handle);
gem_close(drm_fd, obj[2].handle);
}
igt_fixture
close(drm_fd);
}
...@@ -28,6 +28,7 @@ igt@gem_flink_basic@bad-open ...@@ -28,6 +28,7 @@ igt@gem_flink_basic@bad-open
igt@gem_flink_basic@basic igt@gem_flink_basic@basic
igt@gem_flink_basic@double-flink igt@gem_flink_basic@double-flink
igt@gem_flink_basic@flink-lifetime igt@gem_flink_basic@flink-lifetime
igt@gem_huc_copy@huc_copy
igt@gem_linear_blits@basic igt@gem_linear_blits@basic
igt@gem_mmap@basic igt@gem_mmap@basic
igt@gem_mmap_gtt@basic igt@gem_mmap_gtt@basic
......
...@@ -166,6 +166,7 @@ i915_progs = [ ...@@ -166,6 +166,7 @@ i915_progs = [
'gem_gtt_cpu_tlb', 'gem_gtt_cpu_tlb',
'gem_gtt_hog', 'gem_gtt_hog',
'gem_gtt_speed', 'gem_gtt_speed',
'gem_huc_copy',
'gem_linear_blits', 'gem_linear_blits',
'gem_lut_handle', 'gem_lut_handle',
'gem_madvise', 'gem_madvise',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment