// SPDX-License-Identifier: GPL-2.0+
/*
 * efi_selftest_register_notify
 *
 * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
 *
 * This unit test checks the following protocol services:
 * InstallProtocolInterface, UninstallProtocolInterface,
 * RegisterProtocolNotify, CreateEvent, CloseEvent.
 */

#include <efi_selftest.h>

/*
 * The test currently does not actually call the interface function.
 * So this is just a dummy structure.
 */
struct interface {
	void (EFIAPI * inc)(void);
};

struct context {
	void *registration_key;
	efi_uintn_t notify_count;
	efi_uintn_t handle_count;
	efi_handle_t *handles;
	efi_status_t ret;
};

static struct efi_boot_services *boottime;
static efi_guid_t guid1 =
	EFI_GUID(0x2e7ca819, 0x21d3, 0x0a3a,
		 0xf7, 0x91, 0x82, 0x1f, 0x7a, 0x83, 0x67, 0xaf);
static efi_guid_t guid2 =
	EFI_GUID(0xf909f2bb, 0x90a8, 0x0d77,
		 0x94, 0x0c, 0x3e, 0xa8, 0xea, 0x38, 0xd6, 0x6f);
static struct context context;
static struct efi_event *event;

/*
 * Notification function, increments the notification count if parameter
 * context is provided.
 *
 * @event	notified event
 * @context	pointer to the notification count
 */
static void EFIAPI notify(struct efi_event *event, void *context)
{
	struct context *cp = context;
	efi_uintn_t handle_count;
	efi_handle_t *handles;

	cp->notify_count++;

	for (;;) {
		cp->ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY,
							 NULL,
							 cp->registration_key,
							 &handle_count,
							 &handles);
		if (cp->ret != EFI_SUCCESS)
			break;
		cp->handle_count += handle_count;
		cp->handles = handles;
	}
}

/*
 * Setup unit test.
 *
 * @handle:	handle of the loaded image
 * @systable:	system table
 */
static int setup(const efi_handle_t img_handle,
		 const struct efi_system_table *systable)
{
	efi_status_t ret;

	boottime = systable->boottime;

	ret = boottime->create_event(EVT_NOTIFY_SIGNAL,
				     TPL_CALLBACK, notify, &context,
				     &event);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not create event\n");
		return EFI_ST_FAILURE;
	}

	ret = boottime->register_protocol_notify(&guid1, event,
						 &context.registration_key);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not register event\n");
		return EFI_ST_FAILURE;
	}

	return EFI_ST_SUCCESS;
}

/*
 * Tear down unit test.
 *
 */
static int teardown(void)
{
	efi_status_t ret;

	if (event) {
		ret = boottime->close_event(event);
		event = NULL;
		if (ret != EFI_SUCCESS) {
			efi_st_error("could not close event\n");
			return EFI_ST_FAILURE;
		}
	}

	return EFI_ST_SUCCESS;
}

/*
 * Execute unit test.
 *
 */
static int execute(void)
{
	efi_status_t ret;
	efi_handle_t handle1 = NULL, handle2 = NULL;
	struct interface *interface;
	struct interface interface1, interface2;

	ret = boottime->install_protocol_interface(&handle1, &guid1,
						   EFI_NATIVE_INTERFACE,
						   &interface1);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not install interface\n");
		return EFI_ST_FAILURE;
	}
	if (!context.notify_count) {
		efi_st_error("install was not notified\n");
		return EFI_ST_FAILURE;
	}
	if (context.notify_count > 1) {
		efi_st_error("install was notified too often\n");
		return EFI_ST_FAILURE;
	}
	if (context.handle_count != 1) {
		efi_st_error("LocateHandle failed\n");
		return EFI_ST_FAILURE;
	}
	interface = NULL;
	ret = boottime->open_protocol(handle1, &guid1, (void**)&interface,
				      NULL, NULL,
				      EFI_OPEN_PROTOCOL_GET_PROTOCOL);
	if (ret != EFI_SUCCESS) {
		efi_st_error("Cannot find installed protocol on handle\n");
		return EFI_ST_FAILURE;
	}
	if (interface != &interface1) {
		efi_st_error("Wrong interface after install\n");
		return EFI_ST_FAILURE;
	}
	ret = boottime->free_pool(context.handles);
	if (ret != EFI_SUCCESS) {
		efi_st_error("FreePool failed\n");
		return EFI_ST_FAILURE;
	}
	context.notify_count = 0;
	ret = boottime->install_protocol_interface(&handle1, &guid2,
						   EFI_NATIVE_INTERFACE,
						   &interface1);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not install interface\n");
		return EFI_ST_FAILURE;
	}
	if (context.notify_count) {
		efi_st_error("wrong protocol was notified\n");
		return EFI_ST_FAILURE;
	}
	context.notify_count = 0;
	ret = boottime->reinstall_protocol_interface(handle1, &guid1,
						     &interface1, &interface2);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not reinstall interface\n");
		return EFI_ST_FAILURE;
	}
	if (!context.notify_count) {
		efi_st_error("reinstall was not notified\n");
		return EFI_ST_FAILURE;
	}
	if (context.notify_count > 1) {
		efi_st_error("reinstall was notified too often\n");
		return EFI_ST_FAILURE;
	}
	if (context.handle_count != 2) {
		efi_st_error("LocateHandle failed\n");
		return EFI_ST_FAILURE;
	}
	ret = boottime->free_pool(context.handles);
	if (ret != EFI_SUCCESS) {
		efi_st_error("FreePool failed\n");
		return EFI_ST_FAILURE;
	}
	interface = NULL;
	ret = boottime->open_protocol(handle1, &guid1, (void**)&interface,
				      NULL, NULL,
				      EFI_OPEN_PROTOCOL_GET_PROTOCOL);
	if (ret != EFI_SUCCESS) {
		efi_st_error("Cannot find reinstalled protocol on handle\n");
		return EFI_ST_FAILURE;
	}
	if (interface != &interface2) {
		efi_st_error("Wrong interface after reinstall\n");
		return EFI_ST_FAILURE;
	}
	context.notify_count = 0;
	ret = boottime->install_protocol_interface(&handle2, &guid1,
						   EFI_NATIVE_INTERFACE,
						   &interface1);
	if (ret != EFI_SUCCESS) {
		efi_st_error("could not install interface\n");
		return EFI_ST_FAILURE;
	}
	if (!context.notify_count) {
		efi_st_error("install was not notified\n");
		return EFI_ST_FAILURE;
	}
	if (context.notify_count > 1) {
		efi_st_error("install was notified too often\n");
		return EFI_ST_FAILURE;
	}
	if (context.handle_count != 3) {
		efi_st_error("LocateHandle failed\n");
		return EFI_ST_FAILURE;
	}
	if (context.ret != EFI_NOT_FOUND) {
		efi_st_error("LocateHandle did not return EFI_NOT_FOUND\n");
		return EFI_ST_FAILURE;
	}
	ret = boottime->free_pool(context.handles);
	if (ret != EFI_SUCCESS) {
		efi_st_error("FreePool failed\n");
		return EFI_ST_FAILURE;
	}

	ret = boottime->uninstall_multiple_protocol_interfaces
			(handle1, &guid1, &interface2,
			 &guid2, &interface1, NULL);
	if (ret != EFI_SUCCESS) {
		efi_st_error("UninstallMultipleProtocolInterfaces failed\n");
		return EFI_ST_FAILURE;
	}
	ret = boottime->uninstall_multiple_protocol_interfaces
			(handle2, &guid1, &interface1, NULL);
	if (ret != EFI_SUCCESS) {
		efi_st_error("UninstallMultipleProtocolInterfaces failed\n");
		return EFI_ST_FAILURE;
	}

	return EFI_ST_SUCCESS;
}

EFI_UNIT_TEST(regprotnot) = {
	.name = "register protocol notify",
	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
	.setup = setup,
	.execute = execute,
	.teardown = teardown,
};
