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

	debug("header_size: %08x\n",
	      get_unaligned_le32(&strings_package->header_size));
	debug("string_info_offset: %08x\n",
	      get_unaligned_le32(&strings_package->string_info_offset));
	debug("language_name: %u\n",
	      get_unaligned_le16(&strings_package->language_name));
	debug("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:
			debug("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;
			debug("%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:
			debug("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);
		if (idx > 0)
			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));
	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);

	debug("package_list: %pUl (%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) {
		debug("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:
			printf("\tForm 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:
			printf("\tFont package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_IMAGES:
			printf("\tImage package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_SIMPLE_FONTS:
			printf("\tSimple font package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_DEVICE_PATH:
			printf("\tDevice 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:
			printf("\tAnimation 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;
	list_add_tail(&hii->link, &efi_package_lists);
	*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);

	debug("package_list: %pUl (%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) {
		debug("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:
			printf("\tForm package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_STRINGS:
			remove_strings_package(hii);
			break;
		case EFI_HII_PACKAGE_FONTS:
			printf("\tFont package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_IMAGES:
			printf("\tImage package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_SIMPLE_FONTS:
			printf("\tSimple font package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			break;
		case EFI_HII_PACKAGE_DEVICE_PATH:
			printf("\tDevice 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:
			printf("\tAnimation 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_SUCCESS;

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

	if (!handle_buffer_length ||
	    (*handle_buffer_length && !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);

	debug("package type=%x, guid=%pUl, length=%lu\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_FORMS:
			printf("\tForm package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			continue;
		case EFI_HII_PACKAGE_STRINGS:
			if (!list_empty(&hii->string_tables))
				break;
			continue;
		case EFI_HII_PACKAGE_FONTS:
			printf("\tFont package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			continue;
		case EFI_HII_PACKAGE_IMAGES:
			printf("\tImage package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			continue;
		case EFI_HII_PACKAGE_SIMPLE_FONTS:
			printf("\tSimple font package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			continue;
		case EFI_HII_PACKAGE_DEVICE_PATH:
			printf("\tDevice path package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			continue;
		case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
			if (!list_empty(&hii->keyboard_packages))
				break;
			continue;
		case EFI_HII_PACKAGE_ANIMATIONS:
			printf("\tAnimation package not supported\n");
			ret = EFI_INVALID_PARAMETER;
			continue;
		case EFI_HII_PACKAGE_END:
		case EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN:
		case EFI_HII_PACKAGE_TYPE_SYSTEM_END:
		default:
			continue;
		}

		package_cnt++;
		if (package_cnt <= package_max)
			*handle++ = hii;
		else
			ret = EFI_BUFFER_TOO_SMALL;
	}
	*handle_buffer_length = package_cnt * sizeof(*handle);

	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, %pUl, %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, %pUl, %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, %pUl", 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_strlen(str) + 1) * sizeof(u16);
				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';

	debug("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
};
