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

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

static struct i915_vma *create_wally(struct intel_engine_cs *engine)
{
	struct drm_i915_gem_object *obj;
	struct i915_vma *vma;
	u32 *cs;
	int err;

	obj = i915_gem_object_create_internal(engine->i915, 4096);
	if (IS_ERR(obj))
		return ERR_CAST(obj);

	vma = i915_vma_instance(obj, engine->gt->vm, NULL);
	if (IS_ERR(vma)) {
		i915_gem_object_put(obj);
		return vma;
	}

	err = i915_vma_pin(vma, 0, 0, PIN_USER | PIN_HIGH);
	if (err) {
		i915_gem_object_put(obj);
		return ERR_PTR(err);
	}

	err = i915_vma_sync(vma);
	if (err) {
		i915_gem_object_put(obj);
		return ERR_PTR(err);
	}

	cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
	if (IS_ERR(cs)) {
		i915_gem_object_put(obj);
		return ERR_CAST(cs);
	}

	if (GRAPHICS_VER(engine->i915) >= 6) {
		*cs++ = MI_STORE_DWORD_IMM_GEN4;
		*cs++ = 0;
	} else if (GRAPHICS_VER(engine->i915) >= 4) {
		*cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
		*cs++ = 0;
	} else {
		*cs++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
	}
	*cs++ = i915_vma_offset(vma) + 4000;
	*cs++ = STACK_MAGIC;

	*cs++ = MI_BATCH_BUFFER_END;

	i915_gem_object_flush_map(obj);
	i915_gem_object_unpin_map(obj);

	vma->private = intel_context_create(engine); /* dummy residuals */
	if (IS_ERR(vma->private)) {
		vma = ERR_CAST(vma->private);
		i915_gem_object_put(obj);
	}

	return vma;
}

static int context_sync(struct intel_context *ce)
{
	struct i915_request *rq;
	int err = 0;

	rq = intel_context_create_request(ce);
	if (IS_ERR(rq))
		return PTR_ERR(rq);

	i915_request_get(rq);
	i915_request_add(rq);

	if (i915_request_wait(rq, 0, HZ / 5) < 0)
		err = -ETIME;
	i915_request_put(rq);

	return err;
}

static int new_context_sync(struct intel_engine_cs *engine)
{
	struct intel_context *ce;
	int err;

	ce = intel_context_create(engine);
	if (IS_ERR(ce))
		return PTR_ERR(ce);

	err = context_sync(ce);
	intel_context_put(ce);

	return err;
}

static int mixed_contexts_sync(struct intel_engine_cs *engine, u32 *result)
{
	int pass;
	int err;

	for (pass = 0; pass < 2; pass++) {
		WRITE_ONCE(*result, 0);
		err = context_sync(engine->kernel_context);
		if (err || READ_ONCE(*result)) {
			if (!err) {
				pr_err("pass[%d] wa_bb emitted for the kernel context\n",
				       pass);
				err = -EINVAL;
			}
			return err;
		}

		WRITE_ONCE(*result, 0);
		err = new_context_sync(engine);
		if (READ_ONCE(*result) != STACK_MAGIC) {
			if (!err) {
				pr_err("pass[%d] wa_bb *NOT* emitted after the kernel context\n",
				       pass);
				err = -EINVAL;
			}
			return err;
		}

		WRITE_ONCE(*result, 0);
		err = new_context_sync(engine);
		if (READ_ONCE(*result) != STACK_MAGIC) {
			if (!err) {
				pr_err("pass[%d] wa_bb *NOT* emitted for the user context switch\n",
				       pass);
				err = -EINVAL;
			}
			return err;
		}
	}

	return 0;
}

static int double_context_sync_00(struct intel_engine_cs *engine, u32 *result)
{
	struct intel_context *ce;
	int err, i;

	ce = intel_context_create(engine);
	if (IS_ERR(ce))
		return PTR_ERR(ce);

	for (i = 0; i < 2; i++) {
		WRITE_ONCE(*result, 0);
		err = context_sync(ce);
		if (err)
			break;
	}
	intel_context_put(ce);
	if (err)
		return err;

	if (READ_ONCE(*result)) {
		pr_err("wa_bb emitted between the same user context\n");
		return -EINVAL;
	}

	return 0;
}

static int kernel_context_sync_00(struct intel_engine_cs *engine, u32 *result)
{
	struct intel_context *ce;
	int err, i;

	ce = intel_context_create(engine);
	if (IS_ERR(ce))
		return PTR_ERR(ce);

	for (i = 0; i < 2; i++) {
		WRITE_ONCE(*result, 0);
		err = context_sync(ce);
		if (err)
			break;

		err = context_sync(engine->kernel_context);
		if (err)
			break;
	}
	intel_context_put(ce);
	if (err)
		return err;

	if (READ_ONCE(*result)) {
		pr_err("wa_bb emitted between the same user context [with intervening kernel]\n");
		return -EINVAL;
	}

	return 0;
}

static int __live_ctx_switch_wa(struct intel_engine_cs *engine)
{
	struct i915_vma *bb;
	u32 *result;
	int err;

	bb = create_wally(engine);
	if (IS_ERR(bb))
		return PTR_ERR(bb);

	result = i915_gem_object_pin_map_unlocked(bb->obj, I915_MAP_WC);
	if (IS_ERR(result)) {
		intel_context_put(bb->private);
		i915_vma_unpin_and_release(&bb, 0);
		return PTR_ERR(result);
	}
	result += 1000;

	engine->wa_ctx.vma = bb;

	err = mixed_contexts_sync(engine, result);
	if (err)
		goto out;

	err = double_context_sync_00(engine, result);
	if (err)
		goto out;

	err = kernel_context_sync_00(engine, result);
	if (err)
		goto out;

out:
	intel_context_put(engine->wa_ctx.vma->private);
	i915_vma_unpin_and_release(&engine->wa_ctx.vma, I915_VMA_RELEASE_MAP);
	return err;
}

static int live_ctx_switch_wa(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;

	/*
	 * Exercise the inter-context wa batch.
	 *
	 * Between each user context we run a wa batch, and since it may
	 * have implications for user visible state, we have to check that
	 * we do actually execute it.
	 *
	 * The trick we use is to replace the normal wa batch with a custom
	 * one that writes to a marker within it, and we can then look for
	 * that marker to confirm if the batch was run when we expect it,
	 * and equally important it was wasn't run when we don't!
	 */

	for_each_engine(engine, gt, id) {
		struct i915_vma *saved_wa;
		int err;

		if (!intel_engine_can_store_dword(engine))
			continue;

		if (IS_GRAPHICS_VER(gt->i915, 4, 5))
			continue; /* MI_STORE_DWORD is privileged! */

		saved_wa = fetch_and_zero(&engine->wa_ctx.vma);

		intel_engine_pm_get(engine);
		err = __live_ctx_switch_wa(engine);
		intel_engine_pm_put(engine);
		if (igt_flush_test(gt->i915))
			err = -EIO;

		engine->wa_ctx.vma = saved_wa;
		if (err)
			return err;
	}

	return 0;
}

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

	if (to_gt(i915)->submission_method > INTEL_SUBMISSION_RING)
		return 0;

	return intel_gt_live_subtests(tests, to_gt(i915));
}
