tests/intel/xe_sriov_flr: Add flr-twice subtest
[drm/igt-gpu-tools.git] / lib / igt_store.c
blob42ffdc5cdbe44a4786e2c0b8859f1295802cb2a2
1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Copyright © 2021 Intel Corporation
4 */
6 #include "i915/gem_create.h"
7 #include "igt_core.h"
8 #include "drmtest.h"
9 #include "igt_store.h"
10 #include "intel_chipset.h"
11 #include "intel_reg.h"
12 #include "ioctl_wrappers.h"
13 #include "lib/intel_allocator.h"
15 /**
16 * SECTION:igt_store_word
17 * @short_description: Library for writing a value to memory
18 * @title: StoreWord
19 * @include: igt.h
21 * A lot of igt testcases need some mechanism for writing a value to memory
22 * as a test that a batch buffer has executed.
24 * NB: Requires master for STORE_DWORD on gen4/5.
26 void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
27 const struct intel_execution_engine2 *e,
28 int fence, uint32_t target_handle,
29 uint64_t target_gpu_addr,
30 uint64_t store_offset, uint32_t store_value)
32 const int SCRATCH = 0;
33 const int BATCH = 1;
34 const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
35 struct drm_i915_gem_exec_object2 obj[2];
36 struct drm_i915_gem_relocation_entry reloc;
37 struct drm_i915_gem_execbuffer2 execbuf;
38 uint32_t batch[16];
39 uint64_t bb_offset, delta;
40 int i;
42 memset(&execbuf, 0, sizeof(execbuf));
43 execbuf.buffers_ptr = to_user_pointer(obj);
44 execbuf.buffer_count = ARRAY_SIZE(obj);
45 execbuf.flags = e->flags;
46 execbuf.rsvd1 = ctx->id;
47 if (fence != -1) {
48 execbuf.flags |= I915_EXEC_FENCE_IN;
49 execbuf.rsvd2 = fence;
51 if (gem_store_dword_needs_secure(fd))
52 execbuf.flags |= I915_EXEC_SECURE;
54 memset(obj, 0, sizeof(obj));
55 obj[SCRATCH].handle = target_handle;
57 obj[BATCH].handle = gem_create(fd, 4096);
58 obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
59 obj[BATCH].relocation_count = !ahnd ? 1 : 0;
60 bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
61 memset(&reloc, 0, sizeof(reloc));
63 i = 0;
64 delta = sizeof(uint32_t) * store_offset;
65 if (!ahnd) {
66 reloc.target_handle = obj[SCRATCH].handle;
67 reloc.presumed_offset = -1;
68 reloc.offset = sizeof(uint32_t) * (i + 1);
69 reloc.delta = lower_32_bits(delta);
70 igt_assert_eq(upper_32_bits(delta), 0);
71 reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
72 reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
73 } else {
74 obj[SCRATCH].offset = target_gpu_addr;
75 obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
76 obj[BATCH].offset = bb_offset;
77 obj[BATCH].flags |= EXEC_OBJECT_PINNED;
79 batch[i] = MI_STORE_DWORD_IMM_GEN4 | (gen < 6 ? 1 << 22 : 0);
80 if (gen >= 8) {
81 uint64_t addr = target_gpu_addr + delta;
82 batch[++i] = lower_32_bits(addr);
83 batch[++i] = upper_32_bits(addr);
84 } else if (gen >= 4) {
85 batch[++i] = 0;
86 batch[++i] = lower_32_bits(delta);
87 igt_assert_eq(upper_32_bits(delta), 0);
88 reloc.offset += sizeof(uint32_t);
89 } else {
90 batch[i]--;
91 batch[++i] = lower_32_bits(delta);
92 igt_assert_eq(upper_32_bits(delta), 0);
94 batch[++i] = store_value;
95 batch[++i] = MI_BATCH_BUFFER_END;
96 gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
97 gem_execbuf(fd, &execbuf);
98 gem_close(fd, obj[BATCH].handle);
99 put_offset(ahnd, obj[BATCH].handle);