// SPDX-License-Identifier: MIT
/*
 * Copyright © 2020 Intel Corporation
 */

#include "i915_selftest.h"

#include "gt/intel_engine_pm.h"
#include "selftests/igt_flush_test.h"

static u64 read_reloc(const u32 *map, int x, const u64 mask)
{
	u64 reloc;

	memcpy(&reloc, &map[x], sizeof(reloc));
	return reloc & mask;
}

static int __igt_gpu_reloc(struct i915_execbuffer *eb,
			   struct drm_i915_gem_object *obj)
{
	const unsigned int offsets[] = { 8, 3, 0 };
	const u64 mask =
		GENMASK_ULL(eb->reloc_cache.use_64bit_reloc ? 63 : 31, 0);
	const u32 *map = page_mask_bits(obj->mm.mapping);
	struct i915_request *rq;
	struct i915_vma *vma;
	int err;
	int i;

	vma = i915_vma_instance(obj, eb->context->vm, NULL);
	if (IS_ERR(vma))
		return PTR_ERR(vma);

	err = i915_vma_pin(vma, 0, 0, PIN_USER | PIN_HIGH);
	if (err)
		return err;

	/* 8-Byte aligned */
	err = __reloc_entry_gpu(eb, vma, offsets[0] * sizeof(u32), 0);
	if (err)
		goto unpin_vma;

	/* !8-Byte aligned */
	err = __reloc_entry_gpu(eb, vma, offsets[1] * sizeof(u32), 1);
	if (err)
		goto unpin_vma;

	/* Skip to the end of the cmd page */
	i = PAGE_SIZE / sizeof(u32) - RELOC_TAIL - 1;
	i -= eb->reloc_cache.rq_size;
	memset32(eb->reloc_cache.rq_cmd + eb->reloc_cache.rq_size,
		 MI_NOOP, i);
	eb->reloc_cache.rq_size += i;

	/* Force batch chaining */
	err = __reloc_entry_gpu(eb, vma, offsets[2] * sizeof(u32), 2);
	if (err)
		goto unpin_vma;

	GEM_BUG_ON(!eb->reloc_cache.rq);
	rq = i915_request_get(eb->reloc_cache.rq);
	err = reloc_gpu_flush(&eb->reloc_cache);
	if (err)
		goto put_rq;
	GEM_BUG_ON(eb->reloc_cache.rq);

	err = i915_gem_object_wait(obj, I915_WAIT_INTERRUPTIBLE, HZ / 2);
	if (err) {
		intel_gt_set_wedged(eb->engine->gt);
		goto put_rq;
	}

	if (!i915_request_completed(rq)) {
		pr_err("%s: did not wait for relocations!\n", eb->engine->name);
		err = -EINVAL;
		goto put_rq;
	}

	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
		u64 reloc = read_reloc(map, offsets[i], mask);

		if (reloc != i) {
			pr_err("%s[%d]: map[%d] %llx != %x\n",
			       eb->engine->name, i, offsets[i], reloc, i);
			err = -EINVAL;
		}
	}
	if (err)
		igt_hexdump(map, 4096);

put_rq:
	i915_request_put(rq);
unpin_vma:
	i915_vma_unpin(vma);
	return err;
}

static int igt_gpu_reloc(void *arg)
{
	struct i915_execbuffer eb;
	struct drm_i915_gem_object *scratch;
	int err = 0;
	u32 *map;

	eb.i915 = arg;

	scratch = i915_gem_object_create_internal(eb.i915, 4096);
	if (IS_ERR(scratch))
		return PTR_ERR(scratch);

	map = i915_gem_object_pin_map(scratch, I915_MAP_WC);
	if (IS_ERR(map)) {
		err = PTR_ERR(map);
		goto err_scratch;
	}

	for_each_uabi_engine(eb.engine, eb.i915) {
		reloc_cache_init(&eb.reloc_cache, eb.i915);
		memset(map, POISON_INUSE, 4096);

		intel_engine_pm_get(eb.engine);
		eb.context = intel_context_create(eb.engine);
		if (IS_ERR(eb.context)) {
			err = PTR_ERR(eb.context);
			goto err_pm;
		}

		err = intel_context_pin(eb.context);
		if (err)
			goto err_put;

		err = __igt_gpu_reloc(&eb, scratch);

		intel_context_unpin(eb.context);
err_put:
		intel_context_put(eb.context);
err_pm:
		intel_engine_pm_put(eb.engine);
		if (err)
			break;
	}

	if (igt_flush_test(eb.i915))
		err = -EIO;

err_scratch:
	i915_gem_object_put(scratch);
	return err;
}

int i915_gem_execbuffer_live_selftests(struct drm_i915_private *i915)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(igt_gpu_reloc),
	};

	if (intel_gt_is_wedged(&i915->gt))
		return 0;

	return i915_live_subtests(tests, i915);
}
