// 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
 */

#define LOG_CATEGORY LOGC_EFI

#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));
	if (!hii)
		return NULL;

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