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

#include <commonlib/bsd/compression.h>
#include <commonlib/endian.h>
#include <console/console.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <symbols.h>
#include <cbfs.h>
#include <lib.h>
#include <bootmem.h>
#include <program_loading.h>
#include <timestamp.h>
#include <cbmem.h>

/* The type syntax for C is essentially unparsable. -- Rob Pike */
typedef int (*checker_t)(struct cbfs_payload_segment *cbfssegs, void *args);

/* Decode a serialized cbfs payload segment
 * from memory into native endianness.
 */
static void cbfs_decode_payload_segment(struct cbfs_payload_segment *segment,
		const struct cbfs_payload_segment *src)
{
	segment->type        = read_be32(&src->type);
	segment->compression = read_be32(&src->compression);
	segment->offset      = read_be32(&src->offset);
	segment->load_addr   = read_be64(&src->load_addr);
	segment->len         = read_be32(&src->len);
	segment->mem_len     = read_be32(&src->mem_len);
}

static int segment_targets_type(void *dest, unsigned long memsz,
		enum bootmem_type dest_type)
{
	/* No bootmem to check in earlier stages, caller should not use
	   selfload_check(). */
	if (!ENV_RAMSTAGE) {
		printk(BIOS_ERR,
		       "Callers not supposed to call selfload_check() in romstage");
		return 0;
	}

	uintptr_t d = (uintptr_t) dest;
	if (bootmem_region_targets_type(d, memsz, dest_type))
		return 1;

	if (payload_arch_usable_ram_quirk(d, memsz))
		return 1;

	printk(BIOS_ERR, "SELF segment doesn't target RAM: %p, %lu bytes\n", dest, memsz);
	bootmem_dump_ranges();
	return 0;
}

static int load_one_segment(uint8_t *dest,
			    uint8_t *src,
			    size_t len,
			    size_t memsz,
			    uint32_t compression,
			    int flags)
{
	unsigned char *middle, *end;
	printk(BIOS_DEBUG, "Loading Segment: addr: %p memsz: 0x%016zx filesz: 0x%016zx\n",
	       dest, memsz, len);

	/* Compute the boundaries of the segment */
	end = dest + memsz;

	/* Copy data from the initial buffer */
	switch (compression) {
	case CBFS_COMPRESS_LZMA: {
		printk(BIOS_DEBUG, "using LZMA\n");
		timestamp_add_now(TS_START_ULZMA);
		len = ulzman(src, len, dest, memsz);
		timestamp_add_now(TS_END_ULZMA);
		if (!len) /* Decompression Error. */
			return 0;
		break;
	}
	case CBFS_COMPRESS_LZ4: {
		printk(BIOS_DEBUG, "using LZ4\n");
		timestamp_add_now(TS_START_ULZ4F);
		len = ulz4fn(src, len, dest, memsz);
		timestamp_add_now(TS_END_ULZ4F);
		if (!len) /* Decompression Error. */
			return 0;
		break;
	}
	case CBFS_COMPRESS_NONE: {
		printk(BIOS_DEBUG, "it's not compressed!\n");
		memcpy(dest, src, len);
		break;
	}
	default:
		printk(BIOS_INFO,  "CBFS:  Unknown compression type %d\n", compression);
		return 0;
	}
	/* Calculate middle after any changes to len. */
	middle = dest + len;
	printk(BIOS_SPEW, "[ 0x%08lx, %08lx, 0x%08lx) <- %08lx\n",
		(unsigned long)dest,
		(unsigned long)middle,
		(unsigned long)end,
		(unsigned long)src);

	/* Zero the extra bytes between middle & end */
	if (middle < end) {
		printk(BIOS_DEBUG,
			"Clearing Segment: addr: 0x%016lx memsz: 0x%016lx\n",
			(unsigned long)middle,
			(unsigned long)(end - middle));

		/* Zero the extra bytes */
		memset(middle, 0, end - middle);
	}

	/*
	 * Each architecture can perform additional operations
	 * on the loaded segment
	 */
	prog_segment_loaded((uintptr_t)dest, memsz, flags);

	return 1;
}

/* Note: this function is a bit dangerous so is not exported.
 * It assumes you're smart enough not to call it with the very
 * last segment, since it uses seg + 1 */
static int last_loadable_segment(struct cbfs_payload_segment *seg)
{
	return read_be32(&(seg + 1)->type) == PAYLOAD_SEGMENT_ENTRY;
}

static int check_payload_segments(struct cbfs_payload_segment *cbfssegs,
				  enum bootmem_type dest_type)
{
	uint8_t *dest;
	size_t memsz;
	struct cbfs_payload_segment *seg, segment;

	/* dest_type == INVALID means we're not supposed to check anything. */
	if (dest_type == BM_MEM_INVALID)
		return 0;

	for (seg = cbfssegs;; ++seg) {
		printk(BIOS_DEBUG, "Checking segment from ROM address %p\n", seg);
		cbfs_decode_payload_segment(&segment, seg);
		dest = (uint8_t *)(uintptr_t)segment.load_addr;
		memsz = segment.mem_len;
		if (segment.type == PAYLOAD_SEGMENT_ENTRY)
			break;
		if (!segment_targets_type(dest, memsz, dest_type))
			return -1;
	}
	return 0;
}

static int load_payload_segments(struct cbfs_payload_segment *cbfssegs, uintptr_t *entry)
{
	uint8_t *dest, *src;
	size_t filesz, memsz;
	uint32_t compression;
	struct cbfs_payload_segment *first_segment, *seg, segment;
	int flags = 0;

	for (first_segment = seg = cbfssegs;; ++seg) {
		printk(BIOS_DEBUG, "Loading segment from ROM address %p\n", seg);

		cbfs_decode_payload_segment(&segment, seg);
		dest = (uint8_t *)(uintptr_t)segment.load_addr;
		memsz = segment.mem_len;
		compression = segment.compression;
		filesz = segment.len;

		switch (segment.type) {
		case PAYLOAD_SEGMENT_CODE:
		case PAYLOAD_SEGMENT_DATA:
			printk(BIOS_DEBUG, "  %s (compression=%x)\n",
				segment.type == PAYLOAD_SEGMENT_CODE
				?  "code" : "data", segment.compression);
			src = ((uint8_t *)first_segment) + segment.offset;
			printk(BIOS_DEBUG,
				"  New segment dstaddr %p memsize 0x%zx srcaddr %p filesize 0x%zx\n",
			       dest, memsz, src, filesz);

			/* Clean up the values */
			if (filesz > memsz)  {
				filesz = memsz;
				printk(BIOS_DEBUG, "  cleaned up filesize 0x%zx\n", filesz);
			}
			break;

		case PAYLOAD_SEGMENT_BSS:
			printk(BIOS_DEBUG, "  BSS %p (%d byte)\n", (void *)
				(intptr_t)segment.load_addr, segment.mem_len);
			filesz = 0;
			src = ((uint8_t *)first_segment) + segment.offset;
			compression = CBFS_COMPRESS_NONE;
			break;

		case PAYLOAD_SEGMENT_ENTRY:
			printk(BIOS_DEBUG, "  Entry Point %p\n", (void *)
				(intptr_t)segment.load_addr);

			*entry = segment.load_addr;
			/* Per definition, a payload always has the entry point
			 * as last segment. Thus, we use the occurrence of the
			 * entry point as break condition for the loop.
			 */
			return 0;

		default:
			/* We found something that we don't know about. Throw
			 * hands into the sky and run away!
			 */
			printk(BIOS_EMERG, "Bad segment type %x\n", segment.type);
			return -1;
		}
		/* Note that the 'seg + 1' is safe as we only call this
		 * function on "not the last" * items, since entry
		 * is always last. */
		if (last_loadable_segment(seg))
			flags = SEG_FINAL;
		if (!load_one_segment(dest, src, filesz, memsz, compression, flags))
			return -1;
	}

	return 1;
}

__weak int payload_arch_usable_ram_quirk(uint64_t start, uint64_t size)
{
	return 0;
}

bool selfload_mapped(struct prog *payload, void *mapping,
		     enum bootmem_type dest_type)
{
	uintptr_t entry = 0;
	struct cbfs_payload_segment *cbfssegs;

	cbfssegs = &((struct cbfs_payload *)mapping)->segments;

	if (check_payload_segments(cbfssegs, dest_type))
		return false;

	if (load_payload_segments(cbfssegs, &entry))
		return false;

	printk(BIOS_SPEW, "Loaded segments\n");

	/* Pass cbtables to payload if architecture desires it. */
	prog_set_entry(payload, (void *)entry, cbmem_find(CBMEM_ID_CBTABLE));

	return true;
}

bool selfload_check(struct prog *payload, enum bootmem_type dest_type)
{
	if (prog_locate_hook(payload))
		return false;

	payload->cbfs_type = CBFS_TYPE_SELF;
	void *mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type);
	if (!mapping)
		return false;

	bool ret = selfload_mapped(payload, mapping, dest_type);

	cbfs_unmap(mapping);
	return ret;
}

bool selfload(struct prog *payload)
{
	return selfload_check(payload, BM_MEM_INVALID);
}
