// SPDX-License-Identifier: GPL-2.0+
/*
 * efi_selftest_watchdog
 *
 * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
 *
 * The 'watchdog timer' unit test checks that the watchdog timer
 * will not cause a system restart during the timeout period after
 * a timer reset.
 *
 * The 'watchdog reboot' unit test checks that the watchdog timer
 * actually reboots the system after a timeout. The test is only
 * executed on explicit request. Use the following commands:
 *
 *	setenv efi_selftest watchdog reboot
 *	bootefi selftest
 */

#include <efi_selftest.h>

/*
 * This is the communication structure for the notification function.
 */
struct notify_context {
	/* Status code returned when resetting watchdog */
	efi_status_t status;
	/* Number of invocations of the notification function */
	unsigned int timer_ticks;
};

static struct efi_event *event_notify;
static struct efi_event *event_wait;
static struct efi_boot_services *boottime;
static struct notify_context notification_context;
static bool watchdog_reset;

/*
 * Notification function, increments the notification count if parameter
 * context is provided.
 *
 * @event	notified event
 * @context	pointer to the timeout
 */
static void EFIAPI notify(struct efi_event *event, void *context)
{
	struct notify_context *notify_context = context;
	efi_status_t ret = EFI_SUCCESS;

	if (!notify_context)
		return;

	/* Reset watchdog timer to one second */
	ret = boottime->set_watchdog_timer(1, 0, 0, NULL);
	if (ret != EFI_SUCCESS)
		notify_context->status = ret;
	/* Count number of calls */
	notify_context->timer_ticks++;
}

/*
 * Setup unit test.
 *
 * Create two timer events.
 * One with EVT_NOTIFY_SIGNAL, the other with EVT_NOTIFY_WAIT.
 *
 * @handle:	handle of the loaded image
 * @systable:	system table
 * @return:	EFI_ST_SUCCESS for success
 */
static int setup(const efi_handle_t handle,
		 const struct efi_system_table *systable)
{
	efi_status_t ret;

	boottime = systable->boottime;

	notification_context.status = EFI_SUCCESS;
	notification_context.timer_ticks = 0;
	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
				     TPL_CALLBACK, notify,
				     (void *)&notification_context,
				     &event_notify);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not create event\n");
		return EFI_ST_FAILURE;
	}
	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT,
				     TPL_CALLBACK, notify, NULL, &event_wait);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not create event\n");
		return EFI_ST_FAILURE;
	}
	return EFI_ST_SUCCESS;
}

/*
 * Execute the test resetting the watchdog in a timely manner. No reboot occurs.
 *
 * @handle:	handle of the loaded image
 * @systable:	system table
 * @return:	EFI_ST_SUCCESS for success
 */
static int setup_timer(const efi_handle_t handle,
		       const struct efi_system_table *systable)
{
	watchdog_reset = true;
	return setup(handle, systable);
}

/*
 * Execute the test without resetting the watchdog. A system reboot occurs.
 *
 * @handle:	handle of the loaded image
 * @systable:	system table
 * @return:	EFI_ST_SUCCESS for success
 */
static int setup_reboot(const efi_handle_t handle,
			const struct efi_system_table *systable)
{
	watchdog_reset = false;
	return setup(handle, systable);
}

/*
 * Tear down unit test.
 *
 * Close the events created in setup.
 *
 * @return:	EFI_ST_SUCCESS for success
 */
static int teardown(void)
{
	efi_status_t ret;

	/* Set the watchdog timer to the five minute default value */
	ret = boottime->set_watchdog_timer(300, 0, 0, NULL);
	if (ret != EFI_SUCCESS) {
		efi_st_error("Setting watchdog timer failed\n");
		return EFI_ST_FAILURE;
	}
	if (event_notify) {
		ret = boottime->close_event(event_notify);
		event_notify = NULL;
		if (ret != EFI_SUCCESS) {
			efi_st_error("Could not close event\n");
			return EFI_ST_FAILURE;
		}
	}
	if (event_wait) {
		ret = boottime->close_event(event_wait);
		event_wait = NULL;
		if (ret != EFI_SUCCESS) {
			efi_st_error("Could not close event\n");
			return EFI_ST_FAILURE;
		}
	}
	return EFI_ST_SUCCESS;
}

/*
 * Execute unit test.
 *
 * Run a 600 ms periodic timer that resets the watchdog to one second
 * on every timer tick.
 *
 * Run a 1350 ms single shot timer and check that the 600ms timer has
 * been called 2 times.
 *
 * @return:	EFI_ST_SUCCESS for success
 */
static int execute(void)
{
	size_t index;
	efi_status_t ret;

	/* Set the watchdog timeout to one second */
	ret = boottime->set_watchdog_timer(1, 0, 0, NULL);
	if (ret != EFI_SUCCESS) {
		efi_st_error("Setting watchdog timer failed\n");
		return EFI_ST_FAILURE;
	}
	if (watchdog_reset) {
		/* Set 600 ms timer */
		ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC,
					  6000000);
		if (ret != EFI_SUCCESS) {
			efi_st_error("Could not set timer\n");
			return EFI_ST_FAILURE;
		}
	}
	/* Set 1350 ms timer */
	ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 13500000);
	if (ret != EFI_SUCCESS) {
		efi_st_error("Could not set timer\n");
		return EFI_ST_FAILURE;
	}

	ret = boottime->wait_for_event(1, &event_wait, &index);
	if (ret != EFI_SUCCESS) {
		efi_st_error("Could not wait for event\n");
		return EFI_ST_FAILURE;
	}
	if (notification_context.status != EFI_SUCCESS) {
		efi_st_error("Setting watchdog timer failed\n");
		return EFI_ST_FAILURE;
	}
	if (notification_context.timer_ticks != 2) {
		efi_st_error("The timer was called %u times, expected 2.\n",
			     notification_context.timer_ticks);
		return EFI_ST_FAILURE;
	}
	return EFI_ST_SUCCESS;
}

EFI_UNIT_TEST(watchdog1) = {
	.name = "watchdog timer",
	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
	.setup = setup_timer,
	.execute = execute,
	.teardown = teardown,
};

EFI_UNIT_TEST(watchdog2) = {
	.name = "watchdog reboot",
	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
	.setup = setup_reboot,
	.execute = execute,
	.teardown = teardown,
	.on_request = true,
};
