// SPDX-License-Identifier:     GPL-2.0+
/*
 *  EFI Human Interface Infrastructure ... database and packages
 *
 *  Copyright (c) 2017 Leif Lindholm
 *  Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
 */

#include <common.h>
#include <efi_loader.h>
#include <malloc.h>
#include <asm/unaligned.h>

const efi_guid_t efi_guid_hii_database_protocol
		= EFI_HII_DATABASE_PROTOCOL_GUID;
const efi_guid_t efi_guid_hii_string_protocol = EFI_HII_STRING_PROTOCOL_GUID;

static LIST_HEAD(efi_package_lists);
static LIST_HEAD(efi_keyboard_layout_list);

struct efi_hii_packagelist {
	struct list_head link;
	// TODO should there be an associated efi_object?
	efi_handle_t driver_handle;
	u32 max_string_id;
	struct list_head string_tables;     /* list of efi_string_table */
	struct list_head guid_list;
	struct list_head keyboard_packages;

	/* we could also track fonts, images, etc */
};

static int efi_hii_packagelist_exists(efi_hii_handle_t package_list)
{
	struct efi_hii_packagelist *hii;
	int found = 0;

	list_for_each_entry(hii, &efi_package_lists, link) {
		if (hii == package_list) {
			found = 1;
			break;
		}
	}

	return found;
}

static u32 efi_hii_package_type(struct efi_hii_package_header *header)
{
	u32 fields;

	fields = get_unaligned_le32(&header->fields);

	return (fields >> __EFI_HII_PACKAGE_TYPE_SHIFT)
		& __EFI_HII_PACKAGE_TYPE_MASK;
}

static u32 efi_hii_package_len(struct efi_hii_package_header *header)
{
	u32 fields;

	fields = get_unaligned_le32(&header->fields);

	return (fields >> __EFI_HII_PACKAGE_LEN_SHIFT)
		& __EFI_HII_PACKAGE_LEN_MASK;
}

struct efi_string_info {
	efi_string_t string;
	/* we could also track font info, etc */
};

struct efi_string_table {
	struct list_head link;
	efi_string_id_t language_name;
	char *language;
	u32 nstrings;
	/*
	 * NOTE:
	 *  string id starts at 1 so value is stbl->strings[id-1],
	 *  and strings[] is a array of stbl->nstrings elements
	 */
	struct efi_string_info *strings;
};

struct efi_guid_data {
	struct list_head link;
	struct efi_hii_guid_package package;
};

struct efi_keyboard_layout_data {
	struct list_head link;		/* in package */
	struct list_head link_sys;	/* in global list */
	struct efi_hii_keyboard_layout keyboard_layout;
};

struct efi_keyboard_package_data {
	struct list_head link;		/* in package_list */
	struct list_head keyboard_layout_list;
};

static void free_strings_table(struct efi_string_table *stbl)
{
	int i;

	for (i = 0; i < stbl->nstrings; i++)
		free(stbl->strings[i].string);
	free(stbl->strings);
	free(stbl->language);
	free(stbl);
}

static void remove_strings_package(struct efi_hii_packagelist *hii)
{
	while (!list_empty(&hii->string_tables)) {
		struct efi_string_table *stbl;

		stbl = list_first_entry(&hii->string_tables,
					struct efi_string_table, link);
		list_del(&stbl->link);
		free_strings_table(stbl);
	}
}

static efi_status_t
add_strings_package(struct efi_hii_packagelist *hii,
		    struct efi_hii_strings_package *strings_package)
{
	struct efi_hii_string_block *block;
	void *end;
	u32 nstrings = 0, idx = 0;
	struct efi_string_table *stbl = NULL;
	efi_status_t ret;

	EFI_PRINT("header_size: %08x\n",
		  get_unaligned_le32(&strings_package->header_size));
	EFI_PRINT("string_info_offset: %08x\n",
		  get_unaligned_le32(&strings_package->string_info_offset));
	EFI_PRINT("language_name: %u\n",
		  get_unaligned_le16(&strings_package->language_name));
	EFI_PRINT("language: %s\n", strings_package->language);

	/* count # of string entries: */
	end = ((void *)strings_package)
			+ efi_hii_package_len(&strings_package->header);
	block = ((void *)strings_package)
		+ get_unaligned_le32(&strings_package->string_info_offset);

	while ((void *)block < end) {
		switch (block->block_type) {
		case EFI_HII_SIBT_STRING_UCS2: {
			struct efi_hii_sibt_string_ucs2_block *ucs2;

			ucs2 = (void *)block;
			nstrings++;
			block = efi_hii_sibt_string_ucs2_block_next(ucs2);
			break;
		}
		case EFI_HII_SIBT_END:
			block = end;
			break;
		default:
			EFI_PRINT("unknown HII string block type: %02x\n",
				  block->block_type);
			return EFI_INVALID_PARAMETER;
		}
	}

	stbl = calloc(sizeof(*stbl), 1);
	if (!stbl) {
		ret = EFI_OUT_OF_RESOURCES;
		goto error;
	}
	stbl->strings = calloc(sizeof(stbl->strings[0]), nstrings);
	if (!stbl->strings) {
		ret = EFI_OUT_OF_RESOURCES;
		goto error;
	}
	stbl->language_name =
			get_unaligned_le16(&strings_package->language_name);
	stbl->language = strdup((char *)strings_package->language);
	if (!stbl->language) {
		ret = EFI_OUT_OF_RESOURCES;
		goto error;
	}
	stbl->nstrings = nstrings;

	/* and now parse string entries and populate efi_string_table */
	block = ((void *)strings_package)
		+ get_unaligned_le32(&strings_package->string_info_offset);

	while ((void *)block < end) {
		switch (block->block_type) {
		case EFI_HII_SIBT_STRING_UCS2: {
			struct efi_hii_sibt_string_ucs2_block *ucs2;

			ucs2 = (void *)block;
			EFI_PRINT("%4u: \"%ls\"\n", idx + 1, ucs2->string_text);
			stbl->strings[idx].string =
				u16_strdup(ucs2->string_text);
			if (!stbl->strings[idx].string) {
				ret = EFI_OUT_OF_RESOURCES;
				goto error;
			}
			idx++;
			/* FIXME: accessing u16 * here */
			block = efi_hii_sibt_string_ucs2_block_next(ucs2);
			break;
		}
		case EFI_HII_SIBT_END:
			goto out;
		default:
			EFI_PRINT("unknown HII string block type: %02x\n",
				  block->block_type);
			ret = EFI_INVALID_PARAMETER;
			goto error;
		}
	}

out:
	list_add(&stbl->link, &hii->string_tables);
	if (hii->max_string_id < nstrings)
		hii->max_string_id = nstrings;

	return EFI_SUCCESS;

error:
	if (stbl) {
		free(stbl->language);
		while (idx > 0)
			free(stbl->strings[--idx].string);
		free(stbl->strings);
	}
	free(stbl);

	return ret;
}

static void remove_guid_package(struct efi_hii_packagelist *hii)
{
	struct efi_guid_data *data;

	while (!list_empty(&hii->guid_list)) {
		data = list_first_entry(&hii->guid_list,
					struct efi_guid_data, link);
		list_del(&data->link);
		free(data);
	}
}

static efi_status_t
add_guid_package(struct efi_hii_packagelist *hii,
		 struct efi_hii_guid_package *package)
{
	struct efi_guid_data *data;

	data = calloc(sizeof(*data), 1);
	if (!data)
		return EFI_OUT_OF_RESOURCES;

	/* TODO: we don't know any about data field */
	memcpy(&data->package, package, sizeof(*package));
	list_add_tail(&data->link, &hii->guid_list);

	return EFI_SUCCESS;
}

static void free_keyboard_layouts(struct efi_keyboard_package_data *package)
{
	struct efi_keyboard_layout_data *layout_data;

	while (!list_empty(&package->keyboard_layout_list)) {
		layout_data = list_first_entry(&package->keyboard_layout_list,
					       struct efi_keyboard_layout_data,
					       link);
		list_del(&layout_data->link);
		list_del(&layout_data->link_sys);
		free(layout_data);
	}
}

static void remove_keyboard_package(struct efi_hii_packagelist *hii)
{
	struct efi_keyboard_package_data *package;

	while (!list_empty(&hii->keyboard_packages)) {
		package = list_first_entry(&hii->keyboard_packages,
					   struct efi_keyboard_package_data,
					   link);
		free_keyboard_layouts(package);
		list_del(&package->link);
		free(package);
	}
}

static efi_status_t
add_keyboard_package(struct efi_hii_packagelist *hii,
		     struct efi_hii_keyboard_package *keyboard_package)
{
	struct efi_keyboard_package_data *package_data;
	struct efi_hii_keyboard_layout *layout;
	struct efi_keyboard_layout_data *layout_data;
	u16 layout_count, layout_length;
	int i;

	package_data = malloc(sizeof(*package_data));
	if (!package_data)
		return EFI_OUT_OF_RESOURCES;
	INIT_LIST_HEAD(&package_data->link);
	INIT_LIST_HEAD(&package_data->keyboard_layout_list);

	layout = &keyboard_package->layout[0];
	layout_count = get_unaligned_le16(&keyboard_package->layout_count);
	for (i = 0; i < layout_count; i++) {
		layout_length = get_unaligned_le16(&layout->layout_length);
		layout_data = malloc(sizeof(*layout_data) + layout_length);
		if (!layout_data)
			goto out;

		memcpy(&layout_data->keyboard_layout, layout, layout_length);
		list_add_tail(&layout_data->link,
			      &package_data->keyboard_layout_list);
		list_add_tail(&layout_data->link_sys,
			      &efi_keyboard_layout_list);

		layout += layout_length;
	}

	list_add_tail(&package_data->link, &hii->keyboard_packages);

	return EFI_SUCCESS;

out:
	free_keyboard_layouts(package_data);
	free(package_data);

	return EFI_OUT_OF_RESOURCES;
}

static struct efi_hii_packagelist *new_packagelist(void)
{
	struct efi_hii_packagelist *hii;

	hii = malloc(sizeof(*hii));
	list_add_tail(&hii->link, &efi_package_lists);
	hii->max_string_id = 0;
	INIT_LIST_HEAD(&hii->string_tables);
	INIT_LIST_HEAD(&hii->guid_list);
	INIT_LIST_HEAD(&hii->keyboard_packages);

	return hii;
}

static void free_packagelist(struct efi_hii_packagelist *hii)
{
	remove_strings_package(hii);
	remove_guid_package(hii);
	remove_keyboard_package(hii);

	list_del(&hii->link);
	free(hii);
}

static efi_status_t
add_packages(struct efi_hii_packagelist *hii,
	     const struct efi_hii_package_list_header *package_list)
{
	struct efi_hii_package_header *package;
	void *end;
	efi_status_t ret = EFI_SUCCESS;

	end = ((void *)package_list)
		+ get_unaligned_le32(&package_list->package_length);

	EFI_PRINT("package_list: %pUs (%u)\n", &package_list->package_list_guid,
		  get_unaligned_le32(&package_list->package_length));

	package = ((void *)package_list) + sizeof(*package_list);
	while ((void *)package < end) {
		EFI_PRINT("package=%p, package type=%x, length=%u\n", package,
			  efi_hii_package_type(package),
			  efi_hii_package_len(package));

		switch (efi_hii_package_type(package)) {
		case EFI_HII_PACKAGE_TYPE_GUID:
			ret = add_guid_package(hii,
				(struct efi_hii_guid_package *)package);
			break;
		case EFI_HII_PACKAGE_FORMS:
			EFI_PRINT("Form package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_STRINGS:
			ret = add_strings_package(hii,
				(struct efi_hii_strings_package *)package);
			break;
		case EFI_HII_PACKAGE_FONTS:
			EFI_PRINT("Font package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_IMAGES:
			EFI_PRINT("Image package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_SIMPLE_FONTS:
			EFI_PRINT("Simple font package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_DEVICE_PATH:
			EFI_PRINT("Device path package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
			ret = add_keyboard_package(hii,
				(struct efi_hii_keyboard_package *)package);
			break;
		case EFI_HII_PACKAGE_ANIMATIONS:
			EFI_PRINT("Animation package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_END:
			goto out;
		case EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN:
		case EFI_HII_PACKAGE_TYPE_SYSTEM_END:
		default:
			break;
		}

		if (ret != EFI_SUCCESS)
			return ret;

		package = (void *)package + efi_hii_package_len(package);
	}
out:
	// TODO in theory there is some notifications that should be sent..
	return EFI_SUCCESS;
}

/*
 * EFI_HII_DATABASE_PROTOCOL
 */

static efi_status_t EFIAPI
new_package_list(const struct efi_hii_database_protocol *this,
		 const struct efi_hii_package_list_header *package_list,
		 const efi_handle_t driver_handle,
		 efi_hii_handle_t *handle)
{
	struct efi_hii_packagelist *hii;
	efi_status_t ret;

	EFI_ENTRY("%p, %p, %p, %p", this, package_list, driver_handle, handle);

	if (!package_list || !handle)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	hii = new_packagelist();
	if (!hii)
		return EFI_EXIT(EFI_OUT_OF_RESOURCES);

	ret = add_packages(hii, package_list);
	if (ret != EFI_SUCCESS) {
		free_packagelist(hii);
		return EFI_EXIT(ret);
	}

	hii->driver_handle = driver_handle;
	*handle = hii;

	return EFI_EXIT(EFI_SUCCESS);
}

static efi_status_t EFIAPI
remove_package_list(const struct efi_hii_database_protocol *this,
		    efi_hii_handle_t handle)
{
	struct efi_hii_packagelist *hii = handle;

	EFI_ENTRY("%p, %p", this, handle);

	if (!handle || !efi_hii_packagelist_exists(handle))
		return EFI_EXIT(EFI_NOT_FOUND);

	free_packagelist(hii);

	return EFI_EXIT(EFI_SUCCESS);
}

static efi_status_t EFIAPI
update_package_list(const struct efi_hii_database_protocol *this,
		    efi_hii_handle_t handle,
		    const struct efi_hii_package_list_header *package_list)
{
	struct efi_hii_packagelist *hii = handle;
	struct efi_hii_package_header *package;
	void *end;
	efi_status_t ret = EFI_SUCCESS;

	EFI_ENTRY("%p, %p, %p", this, handle, package_list);

	if (!handle || !efi_hii_packagelist_exists(handle))
		return EFI_EXIT(EFI_NOT_FOUND);

	if (!package_list)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	EFI_PRINT("package_list: %pUs (%u)\n", &package_list->package_list_guid,
		  get_unaligned_le32(&package_list->package_length));

	package = ((void *)package_list) + sizeof(*package_list);
	end = ((void *)package_list)
		+ get_unaligned_le32(&package_list->package_length);

	while ((void *)package < end) {
		EFI_PRINT("package=%p, package type=%x, length=%u\n", package,
			  efi_hii_package_type(package),
			  efi_hii_package_len(package));

		switch (efi_hii_package_type(package)) {
		case EFI_HII_PACKAGE_TYPE_GUID:
			remove_guid_package(hii);
			break;
		case EFI_HII_PACKAGE_FORMS:
			EFI_PRINT("Form package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_STRINGS:
			remove_strings_package(hii);
			break;
		case EFI_HII_PACKAGE_FONTS:
			EFI_PRINT("Font package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_IMAGES:
			EFI_PRINT("Image package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_SIMPLE_FONTS:
			EFI_PRINT("Simple font package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_DEVICE_PATH:
			EFI_PRINT("Device path package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
			remove_keyboard_package(hii);
			break;
		case EFI_HII_PACKAGE_ANIMATIONS:
			EFI_PRINT("Animation package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_END:
			goto out;
		case EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN:
		case EFI_HII_PACKAGE_TYPE_SYSTEM_END:
		default:
			break;
		}

		/* TODO: already removed some packages */
		if (ret != EFI_SUCCESS)
			return EFI_EXIT(ret);

		package = ((void *)package)
			  + efi_hii_package_len(package);
	}
out:
	ret = add_packages(hii, package_list);

	return EFI_EXIT(ret);
}

static efi_status_t EFIAPI
list_package_lists(const struct efi_hii_database_protocol *this,
		   u8 package_type,
		   const efi_guid_t *package_guid,
		   efi_uintn_t *handle_buffer_length,
		   efi_hii_handle_t *handle)
{
	struct efi_hii_packagelist *hii =
				(struct efi_hii_packagelist *)handle;
	int package_cnt, package_max;
	efi_status_t ret = EFI_NOT_FOUND;

	EFI_ENTRY("%p, %u, %pUs, %p, %p", this, package_type, package_guid,
		  handle_buffer_length, handle);

	if (!handle_buffer_length ||
	    (*handle_buffer_length && !handle)) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	if ((package_type != EFI_HII_PACKAGE_TYPE_GUID && package_guid) ||
	    (package_type == EFI_HII_PACKAGE_TYPE_GUID && !package_guid)) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	EFI_PRINT("package type=%x, guid=%pUs, length=%zu\n", (int)package_type,
		  package_guid, *handle_buffer_length);

	package_cnt = 0;
	package_max = *handle_buffer_length / sizeof(*handle);
	list_for_each_entry(hii, &efi_package_lists, link) {
		switch (package_type) {
		case EFI_HII_PACKAGE_TYPE_ALL:
			break;
		case EFI_HII_PACKAGE_TYPE_GUID:
			if (!list_empty(&hii->guid_list))
				break;
			continue;
		case EFI_HII_PACKAGE_STRINGS:
			if (!list_empty(&hii->string_tables))
				break;
			continue;
		case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
			if (!list_empty(&hii->keyboard_packages))
				break;
			continue;
		default:
			continue;
		}

		package_cnt++;
		if (package_cnt <= package_max) {
			*handle++ = hii;
			ret = EFI_SUCCESS;
		} else {
			ret = EFI_BUFFER_TOO_SMALL;
		}
	}
	*handle_buffer_length = package_cnt * sizeof(*handle);
out:
	return EFI_EXIT(ret);
}

static efi_status_t EFIAPI
export_package_lists(const struct efi_hii_database_protocol *this,
		     efi_hii_handle_t handle,
		     efi_uintn_t *buffer_size,
		     struct efi_hii_package_list_header *buffer)
{
	EFI_ENTRY("%p, %p, %p, %p", this, handle, buffer_size, buffer);

	if (!buffer_size || !buffer)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	return EFI_EXIT(EFI_NOT_FOUND);
}

static efi_status_t EFIAPI
register_package_notify(const struct efi_hii_database_protocol *this,
			u8 package_type,
			const efi_guid_t *package_guid,
			const void *package_notify_fn,
			efi_uintn_t notify_type,
			efi_handle_t *notify_handle)
{
	EFI_ENTRY("%p, %u, %pUs, %p, %zu, %p", this, package_type,
		  package_guid, package_notify_fn, notify_type,
		  notify_handle);

	if (!notify_handle)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	if ((package_type != EFI_HII_PACKAGE_TYPE_GUID && package_guid) ||
	    (package_type == EFI_HII_PACKAGE_TYPE_GUID && !package_guid))
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}

static efi_status_t EFIAPI
unregister_package_notify(const struct efi_hii_database_protocol *this,
			  efi_handle_t notification_handle)
{
	EFI_ENTRY("%p, %p", this, notification_handle);

	return EFI_EXIT(EFI_NOT_FOUND);
}

static efi_status_t EFIAPI
find_keyboard_layouts(const struct efi_hii_database_protocol *this,
		      u16 *key_guid_buffer_length,
		      efi_guid_t *key_guid_buffer)
{
	struct efi_keyboard_layout_data *layout_data;
	int package_cnt, package_max;
	efi_status_t ret = EFI_SUCCESS;

	EFI_ENTRY("%p, %p, %p", this, key_guid_buffer_length, key_guid_buffer);

	if (!key_guid_buffer_length ||
	    (*key_guid_buffer_length && !key_guid_buffer))
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	package_cnt = 0;
	package_max = *key_guid_buffer_length / sizeof(*key_guid_buffer);
	list_for_each_entry(layout_data, &efi_keyboard_layout_list, link_sys) {
		package_cnt++;
		if (package_cnt <= package_max)
			memcpy(key_guid_buffer++,
			       &layout_data->keyboard_layout.guid,
			       sizeof(*key_guid_buffer));
		else
			ret = EFI_BUFFER_TOO_SMALL;
	}
	*key_guid_buffer_length = package_cnt * sizeof(*key_guid_buffer);

	return EFI_EXIT(ret);
}

static efi_status_t EFIAPI
get_keyboard_layout(const struct efi_hii_database_protocol *this,
		    efi_guid_t *key_guid,
		    u16 *keyboard_layout_length,
		    struct efi_hii_keyboard_layout *keyboard_layout)
{
	struct efi_keyboard_layout_data *layout_data;
	u16 layout_length;

	EFI_ENTRY("%p, %pUs, %p, %p", this, key_guid, keyboard_layout_length,
		  keyboard_layout);

	if (!keyboard_layout_length ||
	    (*keyboard_layout_length && !keyboard_layout))
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	/* TODO: no notion of current keyboard layout */
	if (!key_guid)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	list_for_each_entry(layout_data, &efi_keyboard_layout_list, link_sys) {
		if (!guidcmp(&layout_data->keyboard_layout.guid, key_guid))
			goto found;
	}

	return EFI_EXIT(EFI_NOT_FOUND);

found:
	layout_length =
		get_unaligned_le16(&layout_data->keyboard_layout.layout_length);
	if (*keyboard_layout_length < layout_length) {
		*keyboard_layout_length = layout_length;
		return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
	}

	memcpy(keyboard_layout, &layout_data->keyboard_layout, layout_length);

	return EFI_EXIT(EFI_SUCCESS);
}

static efi_status_t EFIAPI
set_keyboard_layout(const struct efi_hii_database_protocol *this,
		    efi_guid_t *key_guid)
{
	EFI_ENTRY("%p, %pUs", this, key_guid);

	return EFI_EXIT(EFI_NOT_FOUND);
}

static efi_status_t EFIAPI
get_package_list_handle(const struct efi_hii_database_protocol *this,
			efi_hii_handle_t package_list_handle,
			efi_handle_t *driver_handle)
{
	struct efi_hii_packagelist *hii;

	EFI_ENTRY("%p, %p, %p", this, package_list_handle, driver_handle);

	if (!driver_handle)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	list_for_each_entry(hii, &efi_package_lists, link) {
		if (hii == package_list_handle) {
			*driver_handle = hii->driver_handle;
			return EFI_EXIT(EFI_SUCCESS);
		}
	}

	return EFI_EXIT(EFI_NOT_FOUND);
}

const struct efi_hii_database_protocol efi_hii_database = {
	.new_package_list = new_package_list,
	.remove_package_list = remove_package_list,
	.update_package_list = update_package_list,
	.list_package_lists = list_package_lists,
	.export_package_lists = export_package_lists,
	.register_package_notify = register_package_notify,
	.unregister_package_notify = unregister_package_notify,
	.find_keyboard_layouts = find_keyboard_layouts,
	.get_keyboard_layout = get_keyboard_layout,
	.set_keyboard_layout = set_keyboard_layout,
	.get_package_list_handle = get_package_list_handle
};

/*
 * EFI_HII_STRING_PROTOCOL
 */

static bool language_match(char *language, char *languages)
{
	size_t n;

	n = strlen(language);
	/* match primary language? */
	if (!strncasecmp(language, languages, n) &&
	    (languages[n] == ';' || languages[n] == '\0'))
		return true;

	return false;
}

static efi_status_t EFIAPI
new_string(const struct efi_hii_string_protocol *this,
	   efi_hii_handle_t package_list,
	   efi_string_id_t *string_id,
	   const u8 *language,
	   const u16 *language_name,
	   const efi_string_t string,
	   const struct efi_font_info *string_font_info)
{
	struct efi_hii_packagelist *hii = package_list;
	struct efi_string_table *stbl;

	EFI_ENTRY("%p, %p, %p, \"%s\", %p, \"%ls\", %p", this, package_list,
		  string_id, language, language_name, string,
		  string_font_info);

	if (!package_list || !efi_hii_packagelist_exists(package_list))
		return EFI_EXIT(EFI_NOT_FOUND);

	if (!string_id || !language || !string)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	list_for_each_entry(stbl, &hii->string_tables, link) {
		if (language_match((char *)language, stbl->language)) {
			efi_string_id_t new_id;
			void *buf;
			efi_string_t str;

			new_id = ++hii->max_string_id;
			if (stbl->nstrings < new_id) {
				buf = realloc(stbl->strings,
					      sizeof(stbl->strings[0])
						* new_id);
				if (!buf)
					return EFI_EXIT(EFI_OUT_OF_RESOURCES);

				memset(&stbl->strings[stbl->nstrings], 0,
				       (new_id - stbl->nstrings)
					 * sizeof(stbl->strings[0]));
				stbl->strings = buf;
				stbl->nstrings = new_id;
			}

			str = u16_strdup(string);
			if (!str)
				return EFI_EXIT(EFI_OUT_OF_RESOURCES);

			stbl->strings[new_id - 1].string = str;
			*string_id = new_id;

			return EFI_EXIT(EFI_SUCCESS);
		}
	}

	return EFI_EXIT(EFI_NOT_FOUND);
}

static efi_status_t EFIAPI
get_string(const struct efi_hii_string_protocol *this,
	   const u8 *language,
	   efi_hii_handle_t package_list,
	   efi_string_id_t string_id,
	   efi_string_t string,
	   efi_uintn_t *string_size,
	   struct efi_font_info **string_font_info)
{
	struct efi_hii_packagelist *hii = package_list;
	struct efi_string_table *stbl;

	EFI_ENTRY("%p, \"%s\", %p, %u, %p, %p, %p", this, language,
		  package_list, string_id, string, string_size,
		  string_font_info);

	if (!package_list || !efi_hii_packagelist_exists(package_list))
		return EFI_EXIT(EFI_NOT_FOUND);

	list_for_each_entry(stbl, &hii->string_tables, link) {
		if (language_match((char *)language, stbl->language)) {
			efi_string_t str;
			size_t len;

			if (stbl->nstrings < string_id)
				return EFI_EXIT(EFI_NOT_FOUND);

			str = stbl->strings[string_id - 1].string;
			if (str) {
				len = u16_strsize(str);
				if (*string_size < len) {
					*string_size = len;

					return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
				}
				memcpy(string, str, len);
				*string_size = len;
			} else {
				return EFI_EXIT(EFI_NOT_FOUND);
			}

			return EFI_EXIT(EFI_SUCCESS);
		}
	}

	return EFI_EXIT(EFI_NOT_FOUND);
}

static efi_status_t EFIAPI
set_string(const struct efi_hii_string_protocol *this,
	   efi_hii_handle_t package_list,
	   efi_string_id_t string_id,
	   const u8 *language,
	   const efi_string_t string,
	   const struct efi_font_info *string_font_info)
{
	struct efi_hii_packagelist *hii = package_list;
	struct efi_string_table *stbl;

	EFI_ENTRY("%p, %p, %u, \"%s\", \"%ls\", %p", this, package_list,
		  string_id, language, string, string_font_info);

	if (!package_list || !efi_hii_packagelist_exists(package_list))
		return EFI_EXIT(EFI_NOT_FOUND);

	if (string_id > hii->max_string_id)
		return EFI_EXIT(EFI_NOT_FOUND);

	if (!string || !language)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	list_for_each_entry(stbl, &hii->string_tables, link) {
		if (language_match((char *)language, stbl->language)) {
			efi_string_t str;

			if (hii->max_string_id < string_id)
				return EFI_EXIT(EFI_NOT_FOUND);

			if (stbl->nstrings < string_id) {
				void *buf;

				buf = realloc(stbl->strings,
					      string_id
						* sizeof(stbl->strings[0]));
				if (!buf)
					return EFI_EXIT(EFI_OUT_OF_RESOURCES);

				memset(&stbl->strings[string_id - 1], 0,
				       (string_id - stbl->nstrings)
					 * sizeof(stbl->strings[0]));
				stbl->strings = buf;
			}

			str = u16_strdup(string);
			if (!str)
				return EFI_EXIT(EFI_OUT_OF_RESOURCES);

			free(stbl->strings[string_id - 1].string);
			stbl->strings[string_id - 1].string = str;

			return EFI_EXIT(EFI_SUCCESS);
		}
	}

	return EFI_EXIT(EFI_NOT_FOUND);
}

static efi_status_t EFIAPI
get_languages(const struct efi_hii_string_protocol *this,
	      efi_hii_handle_t package_list,
	      u8 *languages,
	      efi_uintn_t *languages_size)
{
	struct efi_hii_packagelist *hii = package_list;
	struct efi_string_table *stbl;
	size_t len = 0;
	char *p;

	EFI_ENTRY("%p, %p, %p, %p", this, package_list, languages,
		  languages_size);

	if (!package_list || !efi_hii_packagelist_exists(package_list))
		return EFI_EXIT(EFI_NOT_FOUND);

	if (!languages_size ||
	    (*languages_size && !languages))
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	/* figure out required size: */
	list_for_each_entry(stbl, &hii->string_tables, link) {
		len += strlen((char *)stbl->language) + 1;
	}

	if (*languages_size < len) {
		*languages_size = len;

		return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
	}

	p = (char *)languages;
	list_for_each_entry(stbl, &hii->string_tables, link) {
		if (p != (char *)languages)
			*p++ = ';';
		strcpy(p, stbl->language);
		p += strlen((char *)stbl->language);
	}
	*p = '\0';

	EFI_PRINT("languages: %s\n", languages);

	return EFI_EXIT(EFI_SUCCESS);
}

static efi_status_t EFIAPI
get_secondary_languages(const struct efi_hii_string_protocol *this,
			efi_hii_handle_t package_list,
			const u8 *primary_language,
			u8 *secondary_languages,
			efi_uintn_t *secondary_languages_size)
{
	struct efi_hii_packagelist *hii = package_list;
	struct efi_string_table *stbl;
	bool found = false;

	EFI_ENTRY("%p, %p, \"%s\", %p, %p", this, package_list,
		  primary_language, secondary_languages,
		  secondary_languages_size);

	if (!package_list || !efi_hii_packagelist_exists(package_list))
		return EFI_EXIT(EFI_NOT_FOUND);

	if (!secondary_languages_size ||
	    (*secondary_languages_size && !secondary_languages))
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	list_for_each_entry(stbl, &hii->string_tables, link) {
		if (language_match((char *)primary_language, stbl->language)) {
			found = true;
			break;
		}
	}
	if (!found)
		return EFI_EXIT(EFI_INVALID_LANGUAGE);

	/*
	 * TODO: What is secondary language?
	 * *secondary_languages = '\0';
	 * *secondary_languages_size = 0;
	 */

	return EFI_EXIT(EFI_NOT_FOUND);
}

const struct efi_hii_string_protocol efi_hii_string = {
	.new_string = new_string,
	.get_string = get_string,
	.set_string = set_string,
	.get_languages = get_languages,
	.get_secondary_languages = get_secondary_languages
};
