// 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] = L" ";
	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(L"\r\nAborted\r\n");
			return EFI_ABORTED;
		default:
			break;
		}
		switch (key.unicode_char) {
		case 0x08: /* Backspace */
			if (pos) {
				buffer[pos--] = 0;
				print(L"\b \b");
			}
			break;
		case 0x0a: /* Linefeed */
		case 0x0d: /* Carriage return */
			print(L"\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(L"load          - show length and CRC32 of initial RAM disk\r\n");
	error(L"save <initrd> - save initial RAM disk to file\r\n");
	error(L"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(L"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(L"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(L"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(L"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(L"length: 0x");
	printx(initrd_size, 1);
	print(L"\r\n");

	ret = bs->calculate_crc32(initrd, initrd_size, &crc32);
	if (ret != EFI_SUCCESS) {
		error(L"Calculating CRC32 failed\r\n");
		return EFI_LOAD_ERROR;
	}
	print(L"crc32: 0x");
	printx(crc32, 8);
	print(L"\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(L"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(L"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(L"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(L"Overwrite existing file (y/n)? ");
		ret = efi_input_yn();
		print(L"\r\n");
		if (ret != EFI_SUCCESS) {
			root->close(root);
			error(L"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(L"Failed to write file\r\n");
		} else {
			print(filename);
			print(L" written\r\n");
		}
		file->close(file);
	} else {
		error(L"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(L"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(L"=> ");
		ret = efi_input(command, sizeof(command));
		if (ret == EFI_ABORTED)
			break;
		pos = skip_whitespace(command);
		if (starts_with(pos, L"exit"))
			break;
		else if (starts_with(pos, L"load"))
			do_load();
		else if (starts_with(pos, L"save "))
			do_save(pos + 5);
		else
			do_help();
	}

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