/*
 * Copyright © 2014 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 <limits.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#include "drmtest.h"
#include "igt_aux.h"
#include "igt_core.h"
#include "igt_gt.h"
#include "igt_sysfs.h"
#include "igt_debugfs.h"
#include "ioctl_wrappers.h"
#include "intel_reg.h"
#include "intel_chipset.h"

/**
 * SECTION:igt_gt
 * @short_description: GT support library
 * @title: GT
 * @include: igt.h
 *
 * This library provides various auxiliary helper functions to handle general
 * interactions with the GT like forcewake handling, injecting hangs or stopping
 * engines.
 */

static bool has_gpu_reset(int fd)
{
	static int once = -1;
	if (once < 0) {
		struct drm_i915_getparam gp;
		int val = 0;

		memset(&gp, 0, sizeof(gp));
		gp.param = 35; /* HAS_GPU_RESET */
		gp.value = &val;

		if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
			once = intel_gen(intel_get_drm_devid(fd)) >= 5;
		else
			once = val > 0;
	}
	return once;
}

static void eat_error_state(int dev)
{
	int dir;

	dir = igt_sysfs_open(dev, NULL);
	if (dir < 0)
		return;

	/* Any write to the error state clears it */
	igt_sysfs_set(dir, "error", "");
	close(dir);
}

/**
 * igt_require_hang_ring:
 * @fd: open i915 drm file descriptor
 * @ring: execbuf ring flag
 *
 * Convenience helper to check whether advanced hang injection is supported by
 * the kernel. Uses igt_skip to automatically skip the test/subtest if this
 * isn't the case.
 *
 * Note that we can't simply just call this from igt_hang_ring since some
 * tests want to exercise gpu wedging behavior. For which we intentionally
 * disable gpu reset support, but still want to inject a hang, see for example
 * tests/gem_eio.c Instead, we expect that the first invocation of
 * igt_require_hand_ring be from a vanilla context and use the has_gpu_reset()
 * determined then for all later instances. This allows us the convenience
 * of double checking when injecting hangs, whilst pushing the complexity
 * to the tests that are deliberating trying to break the box.
 *
 * This function is also controlled by the environment variables:
 *
 * IGT_HANG (boolean) - if false, skip all tests that try to inject a hang.
 * Default: true
 *
 * IGT_HANG_WITHOUT_RESET (boolean) - if true, allow the hang even if the
 * kernel does not support GPU recovery. The machine will be wedged afterwards
 * (and so require a reboot between testing), but it does allow limited testing
 * to be done under hang injection.
 * Default: false
 */
void igt_require_hang_ring(int fd, int ring)
{
	if (!igt_check_boolean_env_var("IGT_HANG", true))
		igt_skip("hang injection disabled by user");

	gem_require_ring(fd, ring);
	gem_context_require_bannable(fd);
	if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
		igt_require(has_gpu_reset(fd));
}

static unsigned context_get_ban(int fd, unsigned ctx)
{
	struct local_i915_gem_context_param param;

	param.param = LOCAL_CONTEXT_PARAM_BANNABLE;
	param.value = 0;
	param.size = 0;

	if (__gem_context_get_param(fd, &param) == -EINVAL) {
		igt_assert(param.value == 0);
		param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD;
		gem_context_get_param(fd, &param);
	}

	return param.value;
}

static void context_set_ban(int fd, unsigned ctx, unsigned ban)
{
	struct local_i915_gem_context_param param;

	memset(&param, 0, sizeof(param));
	param.context = ctx;
	param.value = ban;
	param.size = 0;
	param.param = LOCAL_CONTEXT_PARAM_BANNABLE;

	if(__gem_context_set_param(fd, &param) == -EINVAL) {
		igt_assert(param.value == ban);
		param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD;
		gem_context_set_param(fd, &param);
	}
}

igt_hang_t igt_allow_hang(int fd, unsigned ctx, unsigned flags)
{
	struct local_i915_gem_context_param param;
	unsigned ban;

	igt_assert(igt_sysfs_set_parameter
		   (fd, "reset", "%d", INT_MAX /* any reset method */));

	if (!igt_check_boolean_env_var("IGT_HANG", true))
		igt_skip("hang injection disabled by user");
	gem_context_require_bannable(fd);
	if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
		igt_require(has_gpu_reset(fd));

	param.context = ctx;
	param.size = 0;

	if ((flags & HANG_ALLOW_CAPTURE) == 0) {
		param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
		param.value = 1;
		/* Older kernels may not have NO_ERROR_CAPTURE, in which case
		 * we just eat the error state in post-hang (and hope we eat
		 * the right one).
		 */
		__gem_context_set_param(fd, &param);
	}

	ban = context_get_ban(fd, ctx);
	if ((flags & HANG_ALLOW_BAN) == 0)
		context_set_ban(fd, ctx, 0);

	return (struct igt_hang){ 0, ctx, ban, flags };
}

void igt_disallow_hang(int fd, igt_hang_t arg)
{
	struct local_i915_gem_context_param param;

	context_set_ban(fd, arg.ctx, arg.ban);

	if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
		param.context = arg.ctx;
		param.size = 0;
		param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
		param.value = 0;
		if (__gem_context_set_param(fd, &param))
			eat_error_state(fd);
	}
}

/**
 * igt_hang_ring_ctx:
 * @fd: open i915 drm file descriptor
 * @ctx: the contxt specifier
 * @ring: execbuf ring flag
 * @flags: set of flags to control execution
 *
 * This helper function injects a hanging batch associated with @ctx into @ring.
 * It returns a #igt_hang_t structure which must be passed to
 * igt_post_hang_ring() for hang post-processing (after the gpu hang
 * interaction has been tested.
 *
 * Returns:
 * Structure with helper internal state for igt_post_hang_ring().
 */
igt_hang_t igt_hang_ctx(int fd,
			uint32_t ctx,
			int ring,
			unsigned flags,
			uint64_t *offset)
{
	struct drm_i915_gem_relocation_entry reloc;
	struct drm_i915_gem_execbuffer2 execbuf;
	struct drm_i915_gem_exec_object2 exec;
	struct local_i915_gem_context_param param;
	uint32_t b[16];
	unsigned ban;
	unsigned len;

	igt_require_hang_ring(fd, ring);

	/* One day the kernel ABI will be fixed! */
	igt_require(ctx == 0 || ring == I915_EXEC_RENDER);

	param.context = ctx;
	param.size = 0;

	if ((flags & HANG_ALLOW_CAPTURE) == 0) {
		param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
		param.value = 1;
		/* Older kernels may not have NO_ERROR_CAPTURE, in which case
		 * we just eat the error state in post-hang (and hope we eat
		 * the right one).
		 */
		__gem_context_set_param(fd, &param);
	}

	ban = context_get_ban(fd, ctx);

	if ((flags & HANG_ALLOW_BAN) == 0)
		context_set_ban(fd, ctx, 0);

	memset(&reloc, 0, sizeof(reloc));
	memset(&exec, 0, sizeof(exec));
	memset(&execbuf, 0, sizeof(execbuf));

	exec.handle = gem_create(fd, 4096);
	exec.relocation_count = 1;
	exec.relocs_ptr = to_user_pointer(&reloc);

	memset(b, 0xc5, sizeof(b));

	len = 2;
	if (intel_gen(intel_get_drm_devid(fd)) >= 8)
		len++;
	b[0] = MI_BATCH_BUFFER_START | (len - 2);
	b[len] = MI_BATCH_BUFFER_END;
	b[len+1] = MI_NOOP;
	gem_write(fd, exec.handle, 0, b, sizeof(b));

	reloc.offset = sizeof(uint32_t);
	reloc.target_handle = exec.handle;
	reloc.read_domains = I915_GEM_DOMAIN_COMMAND;

	execbuf.buffers_ptr = to_user_pointer(&exec);
	execbuf.buffer_count = 1;
	execbuf.flags = ring;
	i915_execbuffer2_set_context_id(execbuf, ctx);
	gem_execbuf(fd, &execbuf);

	if (offset)
		*offset = exec.offset;

	return (igt_hang_t){ exec.handle, ctx, ban, flags };
}

/**
 * igt_hang_ring:
 * @fd: open i915 drm file descriptor
 * @ring: execbuf ring flag
 *
 * This helper function injects a hanging batch into @ring. It returns a
 * #igt_hang_t structure which must be passed to igt_post_hang_ring() for
 * hang post-processing (after the gpu hang interaction has been tested.
 *
 * Returns:
 * Structure with helper internal state for igt_post_hang_ring().
 */
igt_hang_t igt_hang_ring(int fd, int ring)
{
	return igt_hang_ctx(fd, 0, ring, 0, NULL);
}

/**
 * igt_post_hang_ring:
 * @fd: open i915 drm file descriptor
 * @arg: hang state from igt_hang_ring()
 *
 * This function does the necessary post-processing after a gpu hang injected
 * with igt_hang_ring().
 */
void igt_post_hang_ring(int fd, igt_hang_t arg)
{
	struct local_i915_gem_context_param param;

	if (arg.handle == 0)
		return;

	gem_set_domain(fd, arg.handle,
		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
	gem_close(fd, arg.handle);

	context_set_ban(fd, arg.ctx, arg.ban);

	if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
		param.context = arg.ctx;
		param.size = 0;
		param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
		param.value = 0;
		if (__gem_context_set_param(fd, &param))
			eat_error_state(fd);
	}
}

/**
 * igt_force_gpu_reset:
 *
 * forces a gpu reset using the i915_wedged debugfs interface. To be used to
 * recover from situations where the hangcheck didn't trigger and/or the gpu is
 * stuck, either because the test manually disabled gpu resets or because the
 * test hit an hangcheck bug
 */
void igt_force_gpu_reset(int drm_fd)
{
	int dir, wedged;

	igt_debug("Triggering GPU reset\n");

	dir = igt_debugfs_dir(drm_fd);

	igt_sysfs_set(dir, "i915_wedged", "-1");
	igt_sysfs_scanf(dir, "i915_wedged", "%d", &wedged);

	close(dir);

	igt_assert(!wedged);
}

/* GPU abusers */
static struct igt_helper_process hang_helper;
static void __attribute__((noreturn))
hang_helper_process(pid_t pid, int fd)
{
	while (1) {
		if (kill(pid, 0)) /* Parent has died, so must we. */
			exit(0);

		igt_post_hang_ring(fd,
				   igt_hang_ring(fd, I915_EXEC_DEFAULT));

		sleep(1);
	}
}

/**
 * igt_fork_hang_helper:
 *
 * Fork a child process using #igt_fork_helper to hang the default engine
 * of the GPU at regular intervals.
 *
 * This is useful to exercise slow running code (such as aperture placement)
 * which needs to be robust against a GPU reset.
 *
 * This function automatically skips when test requirements aren't met using
 * igt_skip().
 */
void igt_fork_hang_helper(void)
{
	int fd, gen;

	fd = drm_open_driver(DRIVER_INTEL);

	gen = intel_gen(intel_get_drm_devid(fd));
	igt_skip_on(gen < 5);

	igt_fork_helper(&hang_helper)
		hang_helper_process(getppid(), fd);

	close(fd);
}

/**
 * igt_stop_hang_helper:
 *
 * Stops the child process spawned with igt_fork_hang_helper().
 *
 * In tests with subtests this function can be called outside of failure
 * catching code blocks like #igt_fixture or #igt_subtest.
 */
void igt_stop_hang_helper(void)
{
	if (hang_helper.running)
		igt_stop_helper(&hang_helper);
}

/**
 * igt_open_forcewake_handle:
 *
 * This functions opens the debugfs forcewake file and so prevents the GT from
 * suspending. The reference is automatically dropped when the is closed.
 *
 * Returns:
 * The file descriptor of the forcewake handle or -1 if that didn't work out.
 */
int igt_open_forcewake_handle(int fd)
{
	if (getenv("IGT_NO_FORCEWAKE"))
		return -1;
	return igt_debugfs_open(fd, "i915_forcewake_user", O_WRONLY);
}

#if defined(__x86_64__) || defined(__i386__)
static unsigned int clflush_size;

int igt_setup_clflush(void)
{
	FILE *file;
	char *line = NULL;
	size_t size = 0;
	int first_stanza = 1;
	int has_clflush = 0;

	if (clflush_size)
		return 1;

	file = fopen("/proc/cpuinfo", "r");
	if (file == NULL)
		return 0;

	while (getline(&line, &size, file) != -1) {
		if (strncmp(line, "processor", 9) == 0) {
			if (!first_stanza)
				break;
			first_stanza = 0;
		}

		if (strncmp(line, "flags", 5) == 0) {
			if (strstr(line, "clflush"))
				has_clflush = 1;
		}

		if (strncmp(line, "clflush size", 12) == 0) {
			char *colon = strchr(line, ':');
			if (colon)
				clflush_size = atoi(colon + 1);
		}
	}
	free(line);
	fclose(file);

	return has_clflush && clflush_size;
}

__attribute__((target("sse2")))
void igt_clflush_range(void *addr, int size)
{
	char *p, *end;

	end = (char *)addr + size;
	p = (char *)((uintptr_t)addr & ~((uintptr_t)clflush_size - 1));

	__builtin_ia32_mfence();
	for (; p < end; p += clflush_size)
		__builtin_ia32_clflush(p);
	__builtin_ia32_clflush(end - 1); /* magic serialisation for byt+ */
	__builtin_ia32_mfence();
}
#else
int igt_setup_clflush(void)
{
	/* requires mfence + clflush, both SSE2 instructions */
	return 0;
}

void igt_clflush_range(void *addr, int size)
{
	fprintf(stderr, "igt_clflush_range() unsupported\n");
}
#endif

/**
 * intel_detect_and_clear_missed_irq:
 * @fd: open i915 drm file descriptor, used to quiesce the gpu
 *
 * This functions idles the GPU and then queries whether there has
 * been a missed interrupt reported by the driver. Afterwards it
 * clears the missed interrupt flag, in order to disable the timer
 * fallback for the next test.
 */
unsigned intel_detect_and_clear_missed_interrupts(int fd)
{
	unsigned missed;
	int dir;

	gem_quiescent_gpu(fd);

	dir = igt_debugfs_dir(fd);

	missed = 0;
	igt_assert(igt_sysfs_scanf(dir, "i915_ring_missed_irq", "%x", &missed) == 1);
	if (missed)
		igt_sysfs_set(dir, "i915_ring_missed_irq", "0");

	close(dir);

	errno = 0;
	return missed;
}

const struct intel_execution_engine intel_execution_engines[] = {
	{ "default", NULL, 0, 0 },
	{ "render", "rcs0", I915_EXEC_RENDER, 0 },
	{ "bsd", "vcs0", I915_EXEC_BSD, 0 },
	{ "bsd1", "vcs0", I915_EXEC_BSD, 1<<13 /*I915_EXEC_BSD_RING1*/ },
	{ "bsd2", "vcs1", I915_EXEC_BSD, 2<<13 /*I915_EXEC_BSD_RING2*/ },
	{ "blt", "bcs0", I915_EXEC_BLT, 0 },
	{ "vebox", "vecs0", I915_EXEC_VEBOX, 0 },
	{ NULL, 0, 0 }
};

bool gem_can_store_dword(int fd, unsigned int engine)
{
	uint16_t devid = intel_get_drm_devid(fd);
	const struct intel_device_info *info = intel_get_device_info(devid);
	const int gen = ffs(info->gen);

	if (gen <= 2) /* requires physical addresses */
		return false;

	if (gen == 6 && (engine & ~(3<<13)) == I915_EXEC_BSD)
		return false; /* kills the machine! */

	if (info->is_broadwater)
		return false; /* Not sure yet... */

	return true;
}
