/* SPDX-License-Identifier: GPL-2.0-only */

#include <cbfs.h>
#include <commonlib/bsd/compression.h>
#include <console/console.h>
#include <bootmem.h>
#include <cbmem.h>
#include <device/resource.h>
#include <stdlib.h>
#include <commonlib/region.h>
#include <fit.h>
#include <program_loading.h>
#include <timestamp.h>
#include <string.h>
#include <lib.h>
#include <boardid.h>

/* Pack the device_tree and place it at given position. */
static void pack_fdt(struct region *fdt, struct device_tree *dt)
{
	printk(BIOS_INFO, "FIT: Flattening FDT to %p\n",
	       (void *)fdt->offset);

	dt_flatten(dt, (void *)fdt->offset);
	prog_segment_loaded(fdt->offset, fdt->size, 0);
}

/**
 * Extract a node to given regions.
 * Returns true on error, false on success.
 */
static bool extract(struct region *region, struct fit_image_node *node)
{
	void *dst = (void *)region->offset;
	const char *comp_name;
	size_t true_size = 0;

	if (node->size == 0) {
		printk(BIOS_ERR, "ERROR: The %s size is 0\n", node->name);
		return true;
	}

	switch (node->compression) {
	case CBFS_COMPRESS_NONE:
		comp_name = "Relocating uncompressed";
		break;
	case CBFS_COMPRESS_LZMA:
		comp_name = "Decompressing LZMA";
		break;
	case CBFS_COMPRESS_LZ4:
		comp_name = "Decompressing LZ4";
		break;
	default:
		printk(BIOS_ERR, "ERROR: Unsupported compression\n");
		return true;
	}

	printk(BIOS_INFO, "FIT: %s %s to %p\n", comp_name, node->name, dst);

	switch (node->compression) {
	case CBFS_COMPRESS_NONE:
		memcpy(dst, node->data, node->size);
		true_size = node->size;
		break;
	case CBFS_COMPRESS_LZMA:
		timestamp_add_now(TS_START_ULZMA);
		true_size = ulzman(node->data, node->size, dst, region->size);
		timestamp_add_now(TS_END_ULZMA);
		break;
	case CBFS_COMPRESS_LZ4:
		timestamp_add_now(TS_START_ULZ4F);
		true_size = ulz4fn(node->data, node->size, dst, region->size);
		timestamp_add_now(TS_END_ULZ4F);
		break;
	default:
		return true;
	}

	if (!true_size) {
		printk(BIOS_ERR, "ERROR: %s decompression failed!\n",
		       comp_name);
		return true;
	}

	return false;
}

static struct device_tree *unpack_fdt(struct fit_image_node *image_node)
{
	void *data = image_node->data;

	if (image_node->compression != CBFS_COMPRESS_NONE) {
		/* TODO: This is an ugly heuristic for how much the size will
		   expand on decompression, fix once FIT images support storing
		   the real uncompressed size. */
		struct region r = { .offset = 0, .size = image_node->size * 5 };
		data = malloc(r.size);
		r.offset = (uintptr_t)data;
		if (!data || extract(&r, image_node))
			return NULL;
	}

	return fdt_unflatten(data);
}

/**
 * Add coreboot tables, CBMEM information and optional board specific strapping
 * IDs to the device tree loaded via FIT.
 */
static void add_cb_fdt_data(struct device_tree *tree)
{
	u32 addr_cells = 1, size_cells = 1;
	u64 reg_addrs[2], reg_sizes[2];
	void *baseptr = NULL;
	size_t size = 0;

	static const char *firmware_path[] = {"firmware", NULL};
	struct device_tree_node *firmware_node = dt_find_node(tree->root,
		firmware_path, &addr_cells, &size_cells, 1);

	/* Need to add 'ranges' to the intermediate node to make 'reg' work. */
	dt_add_bin_prop(firmware_node, "ranges", NULL, 0);

	static const char *coreboot_path[] = {"coreboot", NULL};
	struct device_tree_node *coreboot_node = dt_find_node(firmware_node,
		coreboot_path, &addr_cells, &size_cells, 1);

	dt_add_string_prop(coreboot_node, "compatible", "coreboot");

	/* Fetch CB tables from cbmem */
	void *cbtable = cbmem_find(CBMEM_ID_CBTABLE);
	if (!cbtable) {
		printk(BIOS_WARNING, "FIT: No coreboot table found!\n");
		return;
	}

	/* First 'reg' address range is the coreboot table. */
	const struct lb_header *header = cbtable;
	reg_addrs[0] = (uintptr_t)header;
	reg_sizes[0] = header->header_bytes + header->table_bytes;

	/* Second is the CBMEM area (which usually includes the coreboot
	table). */
	cbmem_get_region(&baseptr, &size);
	if (!baseptr || size == 0) {
		printk(BIOS_WARNING, "FIT: CBMEM pointer/size not found!\n");
		return;
	}

	reg_addrs[1] = (uintptr_t)baseptr;
	reg_sizes[1] = size;

	dt_add_reg_prop(coreboot_node, reg_addrs, reg_sizes, 2, addr_cells,
			size_cells);

	/* Expose board ID, SKU ID, and RAM code to payload.*/
	if (board_id() != UNDEFINED_STRAPPING_ID)
		dt_add_u32_prop(coreboot_node, "board-id", board_id());

	if (sku_id() != UNDEFINED_STRAPPING_ID)
		dt_add_u32_prop(coreboot_node, "sku-id", sku_id());

	if (ram_code() != UNDEFINED_STRAPPING_ID)
		dt_add_u32_prop(coreboot_node, "ram-code", ram_code());
}

/*
 * Parse the uImage FIT, choose a configuration and extract images.
 */
void fit_payload(struct prog *payload, void *data)
{
	struct device_tree *dt = NULL;
	struct region kernel = {0}, fdt = {0}, initrd = {0};

	printk(BIOS_INFO, "FIT: Examine payload %s\n", payload->name);

	struct fit_config_node *config = fit_load(data);

	if (!config) {
		printk(BIOS_ERR, "ERROR: Could not load FIT\n");
		return;
	}

	dt = unpack_fdt(config->fdt);
	if (!dt) {
		printk(BIOS_ERR, "ERROR: Failed to unflatten the FDT.\n");
		return;
	}

	struct fit_overlay_chain *chain;
	list_for_each(chain, config->overlays, list_node) {
		struct device_tree *overlay = unpack_fdt(chain->overlay);
		if (!overlay || dt_apply_overlay(dt, overlay)) {
			printk(BIOS_ERR, "ERROR: Failed to apply overlay %s!\n",
			       chain->overlay->name);
		}
	}

	dt_apply_fixups(dt);

	/* Insert coreboot specific information */
	add_cb_fdt_data(dt);

	/* Update device_tree */
#if defined(CONFIG_LINUX_COMMAND_LINE)
	fit_update_chosen(dt, (char *)CONFIG_LINUX_COMMAND_LINE);
#endif
	fit_update_memory(dt);

	/* Collect infos for fit_payload_arch */
	kernel.size = config->kernel->size;
	fdt.size = dt_flat_size(dt);
	initrd.size = config->ramdisk ? config->ramdisk->size : 0;

	/* Invoke arch specific payload placement and fixups */
	if (!fit_payload_arch(payload, config, &kernel, &fdt, &initrd)) {
		printk(BIOS_ERR, "ERROR: Failed to find free memory region\n");
		bootmem_dump_ranges();
		return;
	}

	/* Update ramdisk location in FDT */
	if (config->ramdisk)
		fit_add_ramdisk(dt, (void *)initrd.offset, initrd.size);

	/* Repack FDT for handoff to kernel */
	pack_fdt(&fdt, dt);

	if (config->ramdisk &&
	    extract(&initrd, config->ramdisk)) {
		printk(BIOS_ERR, "ERROR: Failed to extract initrd\n");
		prog_set_entry(payload, NULL, NULL);
		return;
	}

	timestamp_add_now(TS_KERNEL_DECOMPRESSION);

	if (extract(&kernel, config->kernel)) {
		printk(BIOS_ERR, "ERROR: Failed to extract kernel\n");
		prog_set_entry(payload, NULL, NULL);
		return;
	}

	timestamp_add_now(TS_START_KERNEL);
}
