// 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);

	if (!key_guid)
		return EFI_EXIT(EFI_INVALID_PARAMETER);

	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_INVALID_PARAMETER);
}

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
};
