/*
 * cbfstool, CLI utility for creating rmodules
 *
 * Copyright (C) 2019 9elements Agency GmbH
 * Copyright (C) 2019 Facebook Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>

#include "common.h"
#include "cbfs_image.h"
#include "partitioned_file.h"
#include "fit.h"

/* Global variables */
partitioned_file_t *image_file;

static const char *optstring  = "H:j:f:r:d:t:n:s:cAaDvh?";
static struct option long_options[] = {
	{"file",           required_argument, 0, 'f' },
	{"region",         required_argument, 0, 'r' },
	{"add-cbfs-entry", no_argument,       0, 'a' },
	{"add-region",     no_argument,       0, 'A' },
	{"del-entry",      required_argument, 0, 'd' },
	{"clear-table",    no_argument,       0, 'c' },
	{"fit-type",       required_argument, 0, 't' },
	{"cbfs-filename",  required_argument, 0, 'n' },
	{"max-table-size", required_argument, 0, 's' },
	{"topswap-size",   required_argument, 0, 'j' },
	{"dump",           no_argument,       0, 'D' },
	{"verbose",        no_argument,       0, 'v' },
	{"help",           no_argument,       0, 'h' },
	{"header-offset",  required_argument, 0, 'H' },
	{NULL,             0,                 0,  0  }
};

static void usage(const char *name)
{
	printf(
		"ifittool: utility for modifying Intel Firmware Interface Table\n\n"
		"USAGE: %s [-h] [-H] [-v] [-D] [-c] <-f|--file name> <-s|--max-table-size size> <-r|--region fmap region> OPERATION\n"
		"\tOPERATION:\n"
		"\t\t-a|--add-entry        :   Add a CBFS file as new entry to FIT\n"
		"\t\t-A|--add-region       :   Add region as new entry to FIT (for microcodes)\n"
		"\t\t-d|--del-entry number :   Delete existing <number> entry\n"
		"\t\t-t|--fit-type         :   Type of new entry\n"
		"\t\t-n|--name             :   The CBFS filename or region to add to table\n"
		"\tOPTIONAL ARGUMENTS:\n"
		"\t\t-h|--help             :   Display this text\n"
		"\t\t-H|--header-offset    :   Do not search for header, use this offset\n"
		"\t\t-v|--verbose          :   Be verbose\n"
		"\t\t-D|--dump             :   Dump FIT table (at end of operation)\n"
		"\t\t-c|--clear-table      :   Remove all existing entries (do not update)\n"
		"\t\t-j|--topswap-size     :   Use second FIT table if non zero\n"
		"\tREQUIRED ARGUMENTS:\n"
		"\t\t-f|--file name        :   The file containing the CBFS\n"
		"\t\t-s|--max-table-size   :   The number of possible FIT entries in table\n"
		"\t\t-r|--region           :   The FMAP region to operate on\n"
	, name);
}

static int is_valid_topswap(size_t topswap_size)
{
	switch (topswap_size) {
	case (64 * KiB):
	case (128 * KiB):
	case (256 * KiB):
	case (512 * KiB):
	case (1 * MiB):
		break;
	default:
		ERROR("Invalid topswap_size %zd\n", topswap_size);
		ERROR("topswap can be 64K|128K|256K|512K|1M\n");
		return 0;
	}
	return 1;
}

/*
 * Converts between offsets from the start of the specified image region and
 * "top-aligned" offsets from the top of the entire boot media. See comment
 * below for convert_to_from_top_aligned() about forming addresses.
 */
static unsigned int convert_to_from_absolute_top_aligned(
		const struct buffer *region, unsigned int offset)
{
	assert(region);

	size_t image_size = partitioned_file_total_size(image_file);

	return image_size - region->offset - offset;
}

/*
 * Converts between offsets from the start of the specified image region and
 * "top-aligned" offsets from the top of the image region. Works in either
 * direction: pass in one type of offset and receive the other type.
 * N.B. A top-aligned offset is always a positive number, and should not be
 * confused with a top-aligned *address*, which is its arithmetic inverse. */
static unsigned int convert_to_from_top_aligned(const struct buffer *region,
						unsigned int offset)
{
	assert(region);

	/* Cover the situation where a negative base address is given by the
	 * user. Callers of this function negate it, so it'll be a positive
	 * number smaller than the region.
	 */
	if ((offset > 0) && (offset < region->size))
		return region->size - offset;

	return convert_to_from_absolute_top_aligned(region, offset);
}

/*
 * Get a pointer from an offset. This function assumes the ROM is located
 * in the host address space at [4G - romsize -> 4G). It also assume all
 * pointers have values within this address range.
 */
static inline uint32_t offset_to_ptr(fit_offset_converter_t helper,
				     const struct buffer *region, int offset)
{
	return -helper(region, offset);
}

enum fit_operation {
	NO_OP = 0,
	ADD_CBFS_OP,
	ADD_REGI_OP,
	ADD_ADDR_OP,
	DEL_OP
};

int main(int argc, char *argv[])
{
	int c;
	const char *input_file = NULL;
	const char *name = NULL;
	const char *region_name = NULL;
	enum fit_operation op = NO_OP;
	bool dump = false, clear_table = false;
	size_t max_table_size = 0;
	size_t table_entry = 0;
	uint32_t addr = 0;
	size_t topswap_size = 0;
	enum fit_type fit_type = 0;
	uint32_t headeroffset = ~0u;

	verbose = 0;

	if (argc < 4) {
		usage(argv[0]);
		return 1;
	}

	while (1) {
		int optindex = 0;
		char *suffix = NULL;

		c = getopt_long(argc, argv, optstring, long_options, &optindex);

		if (c == -1)
			break;

		switch (c) {
		case 'h':
			usage(argv[0]);
			return 1;
		case 'a':
			if (op != NO_OP) {
				ERROR("specified multiple actions at once\n");
				usage(argv[0]);
				return 1;
			}
			op = ADD_CBFS_OP;
			break;
		case 'A':
			if (op != NO_OP) {
				ERROR("specified multiple actions at once\n");
				usage(argv[0]);
				return 1;
			}
			op = ADD_REGI_OP;
			break;
		case 'x':
			if (op != NO_OP) {
				ERROR("specified multiple actions at once\n");
				usage(argv[0]);
				return 1;
			}
			op = ADD_ADDR_OP;
			addr = atoll(optarg);
			break;
		case 'c':
			clear_table = true;
			break;
		case 'd':
			if (op != NO_OP) {
				ERROR("specified multiple actions at once\n");
				usage(argv[0]);
				return 1;
			}
			op = DEL_OP;
			table_entry = atoi(optarg);
			break;
		case 'D':
			dump = true;
			break;
		case 'f':
			input_file = optarg;
			break;
		case 'H':
			headeroffset = strtoul(optarg, &suffix, 0);
			if (!*optarg || (suffix && *suffix)) {
				ERROR("Invalid header offset '%s'.\n", optarg);
				return 1;
			}
			break;
		case 'j':
			topswap_size = strtol(optarg, NULL, 0);
			if (!is_valid_topswap(topswap_size))
				return 1;
			break;
		case 'n':
			name = optarg;
			break;
		case 'r':
			region_name = optarg;
			break;
		case 's':
			max_table_size = atoi(optarg);
			break;
		case 't':
			fit_type = atoi(optarg);
			break;
		case 'v':
			verbose++;
			break;
		default:
			break;
		}
	}

	if (input_file == NULL) {
		ERROR("No input file given\n");
		usage(argv[0]);
		return 1;
	}

	if (op == ADD_CBFS_OP || op == ADD_REGI_OP) {
		if (fit_type == 0) {
			ERROR("Adding FIT entry, but no type given\n");
			usage(argv[0]);
			return 1;
		} else if (name == NULL) {
			ERROR("Adding FIT entry, but no name set\n");
			usage(argv[0]);
			return 1;
		} else if (max_table_size == 0) {
			ERROR("Maximum table size not given\n");
			usage(argv[0]);
			return 1;
		}
	}
	if (op == ADD_ADDR_OP) {
		if (fit_type == 0) {
			ERROR("Adding FIT entry, but no type given\n");
			usage(argv[0]);
			return 1;
		} else if (max_table_size == 0) {
			ERROR("Maximum table size not given\n");
			usage(argv[0]);
			return 1;
		}
	}

	if (!region_name) {
		ERROR("Region not given\n");
		usage(argv[0]);
		return 1;
	}

	image_file = partitioned_file_reopen(input_file,
					     op != NO_OP || clear_table);

	struct buffer image_region;

	if (!partitioned_file_read_region(&image_region, image_file,
					  region_name)) {
		partitioned_file_close(image_file);
		ERROR("The image will be left unmodified.\n");
		return 1;
	}

	struct buffer bootblock;
	// The bootblock is part of the CBFS on x86
	buffer_clone(&bootblock, &image_region);

	struct cbfs_image image;
	if (cbfs_image_from_buffer(&image, &image_region, headeroffset)) {
		partitioned_file_close(image_file);
		return 1;
	}

	struct fit_table *fit = fit_get_table(&bootblock,
					      convert_to_from_top_aligned,
					      topswap_size);
	if (!fit) {
		partitioned_file_close(image_file);
		ERROR("FIT not found.\n");
		return 1;
	}

	if (clear_table) {
		if (fit_clear_table(fit)) {
			partitioned_file_close(image_file);
			ERROR("Failed to clear table.\n");
			return 1;
		}
	}

	switch (op) {
	case ADD_REGI_OP:
	{
		struct buffer region;

		if (partitioned_file_read_region(&region, image_file, name)) {
			addr = -convert_to_from_top_aligned(&region, 0);
		} else {
			partitioned_file_close(image_file);
			return 1;
		}

		if (fit_add_entry(fit, addr, 0, fit_type, max_table_size)) {
			partitioned_file_close(image_file);
			ERROR("Adding type %u FIT entry\n", fit_type);
			return 1;
		}
		break;
	}
	case ADD_CBFS_OP:
	{
		if (fit_type == FIT_TYPE_MICROCODE) {
			if (fit_add_microcode_file(fit, &image, name,
						   convert_to_from_top_aligned,
						   max_table_size)) {
				return 1;
			}
		} else {
			uint32_t offset, len;
			struct cbfs_file *cbfs_file;

			cbfs_file = cbfs_get_entry(&image, name);
			if (!cbfs_file) {
				partitioned_file_close(image_file);
				ERROR("%s not found in CBFS.\n", name);
				return 1;
			}

			len = ntohl(cbfs_file->len);
			offset = offset_to_ptr(convert_to_from_top_aligned,
					&image.buffer,
					cbfs_get_entry_addr(&image, cbfs_file) +
					ntohl(cbfs_file->offset));


			if (fit_add_entry(fit, offset, len, fit_type,
					  max_table_size)) {
				partitioned_file_close(image_file);
				ERROR("Adding type %u FIT entry\n", fit_type);
				return 1;
			}
		}
		break;
	}
	case ADD_ADDR_OP:
	{
		if (fit_add_entry(fit, addr, 0, fit_type, max_table_size)) {
			partitioned_file_close(image_file);
			ERROR("Adding type %u FIT entry\n", fit_type);
			return 1;
		}
	}
	break;
	case DEL_OP:
	{
		if (fit_delete_entry(fit, table_entry)) {
			partitioned_file_close(image_file);
			ERROR("Deleting FIT entry %zu failed\n", table_entry);
			return 1;
		}
		break;
	}
	case NO_OP:
	default:
		break;
	}

	if (op != NO_OP || clear_table) {
		if (!partitioned_file_write_region(image_file, &bootblock)) {
			ERROR("Failed to write changes to disk.\n");
			partitioned_file_close(image_file);
			return 1;
		}
	}

	if (dump) {
		if (fit_dump(fit)) {
			partitioned_file_close(image_file);
			return 1;
		}
	}

	partitioned_file_close(image_file);

	return 0;
}
