1 /* SPDX-License-Identifier: MIT */
3 * Copyright © 2021 Intel Corporation
6 #include "i915/gem_create.h"
10 #include "intel_chipset.h"
11 #include "intel_reg.h"
12 #include "ioctl_wrappers.h"
13 #include "lib/intel_allocator.h"
16 * SECTION:igt_store_word
17 * @short_description: Library for writing a value to memory
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;
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
;
39 uint64_t bb_offset
, delta
;
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
;
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
));
64 delta
= sizeof(uint32_t) * store_offset
;
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
;
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);
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) {
86 batch
[++i
] = lower_32_bits(delta
);
87 igt_assert_eq(upper_32_bits(delta
), 0);
88 reloc
.offset
+= sizeof(uint32_t);
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
);