// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
 *
 * initrddump.efi saves the initial RAM disk provided via the
 * EFI_LOAD_FILE2_PROTOCOL.
 */

#include <common.h>
#include <efi_api.h>
#include <efi_load_initrd.h>

#define BUFFER_SIZE 64
#define ESC 0x17

#define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)

static struct efi_system_table *systable;
static struct efi_boot_services *bs;
static struct efi_simple_text_output_protocol *cerr;
static struct efi_simple_text_output_protocol *cout;
static struct efi_simple_text_input_protocol *cin;
static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
static const efi_guid_t guid_simple_file_system_protocol =
					EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
static const efi_guid_t load_file2_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
static efi_handle_t handle;

/*
 * Device path defined by Linux to identify the handle providing the
 * EFI_LOAD_FILE2_PROTOCOL used for loading the initial ramdisk.
 */
static const struct efi_initrd_dp initrd_dp = {
	.vendor = {
		{
		   DEVICE_PATH_TYPE_MEDIA_DEVICE,
		   DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
		   sizeof(initrd_dp.vendor),
		},
		EFI_INITRD_MEDIA_GUID,
	},
	.end = {
		DEVICE_PATH_TYPE_END,
		DEVICE_PATH_SUB_TYPE_END,
		sizeof(initrd_dp.end),
	}
};

/**
 * print() - print string
 *
 * @string:	text
 */
static void print(u16 *string)
{
	cout->output_string(cout, string);
}

/**
 * error() - print error string
 *
 * @string:	error text
 */
static void error(u16 *string)
{
	cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK);
	print(string);
	cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
}

/*
 * printx() - print hexadecimal number
 *
 * @val:	value to print;
 * @prec:	minimum number of digits to print
 */
static void printx(u64 val, u32 prec)
{
	int i;
	u16 c;
	u16 buf[16];
	u16 *pos = buf;

	for (i = 2 * sizeof(val) - 1; i >= 0; --i) {
		c = (val >> (4 * i)) & 0x0f;
		if (c || pos != buf || !i || i < prec) {
			c += '0';
			if (c > '9')
				c += 'a' - '9' - 1;
			*pos++ = c;
		}
	}
	*pos = 0;
	print(buf);
}

/**
 * efi_input_yn() - get answer to yes/no question
 *
 * Return:
 * y or Y
 *     EFI_SUCCESS
 * n or N
 *     EFI_ACCESS_DENIED
 * ESC
 *     EFI_ABORTED
 */
static efi_status_t efi_input_yn(void)
{
	struct efi_input_key key = {0};
	efi_uintn_t index;
	efi_status_t ret;

	/* Drain the console input */
	ret = cin->reset(cin, true);
	for (;;) {
		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
		if (ret != EFI_SUCCESS)
			continue;
		ret = cin->read_key_stroke(cin, &key);
		if (ret != EFI_SUCCESS)
			continue;
		switch (key.scan_code) {
		case 0x17: /* Escape */
			return EFI_ABORTED;
		default:
			break;
		}
		/* Convert to lower case */
		switch (key.unicode_char | 0x20) {
		case 'y':
			return EFI_SUCCESS;
		case 'n':
			return EFI_ACCESS_DENIED;
		default:
			break;
		}
	}
}

/**
 * efi_input() - read string from console
 *
 * @buffer:		input buffer
 * @buffer_size:	buffer size
 * Return:		status code
 */
static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
{
	struct efi_input_key key = {0};
	efi_uintn_t index;
	efi_uintn_t pos = 0;
	u16 outbuf[2] = u" ";
	efi_status_t ret;

	/* Drain the console input */
	ret = cin->reset(cin, true);
	*buffer = 0;
	for (;;) {
		ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
		if (ret != EFI_SUCCESS)
			continue;
		ret = cin->read_key_stroke(cin, &key);
		if (ret != EFI_SUCCESS)
			continue;
		switch (key.scan_code) {
		case 0x17: /* Escape */
			print(u"\r\nAborted\r\n");
			return EFI_ABORTED;
		default:
			break;
		}
		switch (key.unicode_char) {
		case 0x08: /* Backspace */
			if (pos) {
				buffer[pos--] = 0;
				print(u"\b \b");
			}
			break;
		case 0x0a: /* Linefeed */
		case 0x0d: /* Carriage return */
			print(u"\r\n");
			return EFI_SUCCESS;
		default:
			break;
		}
		/* Ignore surrogate codes */
		if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
			continue;
		if (key.unicode_char >= 0x20 &&
		    pos < buffer_size - 1) {
			*outbuf = key.unicode_char;
			buffer[pos++] = key.unicode_char;
			buffer[pos] = 0;
			print(outbuf);
		}
	}
}

/**
 * skip_whitespace() - skip over leading whitespace
 *
 * @pos:	UTF-16 string
 * Return:	pointer to first non-whitespace
 */
static u16 *skip_whitespace(u16 *pos)
{
	for (; *pos && *pos <= 0x20; ++pos)
		;
	return pos;
}

/**
 * starts_with() - check if @string starts with @keyword
 *
 * @string:	string to search for keyword
 * @keyword:	keyword to be searched
 * Return:	true fi @string starts with the keyword
 */
static bool starts_with(u16 *string, u16 *keyword)
{
	for (; *keyword; ++string, ++keyword) {
		if (*string != *keyword)
			return false;
	}
	return true;
}

/**
 * do_help() - print help
 */
static void do_help(void)
{
	error(u"load          - show length and CRC32 of initial RAM disk\r\n");
	error(u"save <initrd> - save initial RAM disk to file\r\n");
	error(u"exit          - exit the shell\r\n");
}

/**
 * get_initrd() - read initial RAM disk via EFI_LOAD_FILE2_PROTOCOL
 *
 * @initrd:		on return buffer with initial RAM disk
 * @initrd_size:	size of initial RAM disk
 * Return:		status code
 */
static efi_status_t get_initrd(void **initrd, efi_uintn_t *initrd_size)
{
	struct efi_device_path *dp = (struct efi_device_path *)&initrd_dp;
	struct efi_load_file_protocol *load_file2_prot;
	u64 buffer;
	efi_handle_t handle;
	efi_status_t ret;

	*initrd = NULL;
	*initrd_size = 0;
	ret = bs->locate_device_path(&load_file2_guid, &dp, &handle);
	if (ret != EFI_SUCCESS) {
		error(u"Load File2 protocol not found\r\n");
		return ret;
	}
	ret = bs->handle_protocol(handle, &load_file2_guid,
				 (void **)&load_file2_prot);
	ret = load_file2_prot->load_file(load_file2_prot, dp, false,
					 initrd_size, NULL);
	if (ret != EFI_BUFFER_TOO_SMALL) {
		error(u"Load File2 protocol does not provide file length\r\n");
		return EFI_LOAD_ERROR;
	}
	ret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA,
				 efi_size_in_pages(*initrd_size), &buffer);
	if (ret != EFI_SUCCESS) {
		error(u"Out of memory\r\n");
		return ret;
	}
	*initrd = (void *)(uintptr_t)buffer;
	ret = load_file2_prot->load_file(load_file2_prot, dp, false,
					 initrd_size, *initrd);
	if (ret != EFI_SUCCESS) {
		error(u"Load File2 protocol failed to provide file\r\n");
		bs->free_pages(buffer, efi_size_in_pages(*initrd_size));
		return EFI_LOAD_ERROR;
	}
	return ret;
}

/**
 * do_load() - load initial RAM disk and display CRC32 and length
 *
 * @filename:	file name
 * Return:	status code
 */
static efi_status_t do_load(void)
{
	void *initrd;
	efi_uintn_t initrd_size;
	u32 crc32;
	efi_uintn_t ret;

	ret =  get_initrd(&initrd, &initrd_size);
	if (ret != EFI_SUCCESS)
		return ret;
	print(u"length: 0x");
	printx(initrd_size, 1);
	print(u"\r\n");

	ret = bs->calculate_crc32(initrd, initrd_size, &crc32);
	if (ret != EFI_SUCCESS) {
		error(u"Calculating CRC32 failed\r\n");
		return EFI_LOAD_ERROR;
	}
	print(u"crc32: 0x");
	printx(crc32, 8);
	print(u"\r\n");

	return EFI_SUCCESS;
}

/**
 * do_save() - save initial RAM disk
 *
 * @filename:	file name
 * Return:	status code
 */
static efi_status_t do_save(u16 *filename)
{
	struct efi_loaded_image *loaded_image;
	struct efi_simple_file_system_protocol *file_system;
	struct efi_file_handle *root, *file;
	void *initrd;
	efi_uintn_t initrd_size;
	efi_uintn_t ret;

	ret = get_initrd(&initrd, &initrd_size);
	if (ret != EFI_SUCCESS)
		return ret;

	filename = skip_whitespace(filename);

	ret = bs->open_protocol(handle, &loaded_image_guid,
				(void **)&loaded_image, NULL, NULL,
				EFI_OPEN_PROTOCOL_GET_PROTOCOL);
	if (ret != EFI_SUCCESS) {
		error(u"Loaded image protocol not found\r\n");
		goto out;
	}

	/* Open the simple file system protocol */
	ret = bs->open_protocol(loaded_image->device_handle,
				&guid_simple_file_system_protocol,
				(void **)&file_system, NULL, NULL,
				EFI_OPEN_PROTOCOL_GET_PROTOCOL);
	if (ret != EFI_SUCCESS) {
		error(u"Failed to open simple file system protocol\r\n");
		goto out;
	}

	/* Open volume */
	ret = file_system->open_volume(file_system, &root);
	if (ret != EFI_SUCCESS) {
		error(u"Failed to open volume\r\n");
		goto out;
	}
	/* Check if file already exists */
	ret = root->open(root, &file, filename, EFI_FILE_MODE_READ, 0);
	if (ret == EFI_SUCCESS) {
		file->close(file);
		print(u"Overwrite existing file (y/n)? ");
		ret = efi_input_yn();
		print(u"\r\n");
		if (ret != EFI_SUCCESS) {
			root->close(root);
			error(u"Aborted by user\r\n");
			goto out;
		}
	}

	/* Create file */
	ret = root->open(root, &file, filename,
			 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
			 EFI_FILE_MODE_CREATE, EFI_FILE_ARCHIVE);
	if (ret == EFI_SUCCESS) {
		/* Write file */
		ret = file->write(file, &initrd_size, initrd);
		if (ret != EFI_SUCCESS) {
			error(u"Failed to write file\r\n");
		} else {
			print(filename);
			print(u" written\r\n");
		}
		file->close(file);
	} else {
		error(u"Failed to open file\r\n");
	}
	root->close(root);

out:
	if (initrd)
		bs->free_pages((uintptr_t)initrd,
			       efi_size_in_pages(initrd_size));
	return ret;
}

/**
 * efi_main() - entry point of the EFI application.
 *
 * @handle:	handle of the loaded image
 * @systab:	system table
 * Return:	status code
 */
efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
			     struct efi_system_table *systab)
{
	handle = image_handle;
	systable = systab;
	cerr = systable->std_err;
	cout = systable->con_out;
	cin = systable->con_in;
	bs = systable->boottime;

	cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
	cout->clear_screen(cout);
	cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK);
	print(u"INITRD Dump\r\n========\r\n\r\n");
	cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);

	for (;;) {
		u16 command[BUFFER_SIZE];
		u16 *pos;
		efi_uintn_t ret;

		print(u"=> ");
		ret = efi_input(command, sizeof(command));
		if (ret == EFI_ABORTED)
			break;
		pos = skip_whitespace(command);
		if (starts_with(pos, u"exit"))
			break;
		else if (starts_with(pos, u"load"))
			do_load();
		else if (starts_with(pos, u"save "))
			do_save(pos + 5);
		else
			do_help();
	}

	cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
	cout->clear_screen(cout);
	return EFI_SUCCESS;
}
