/* 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)
{
	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,
		void *args)
{
	uint8_t *dest;
	size_t memsz;
	struct cbfs_payload_segment *seg, segment;
	enum bootmem_type dest_type = *(enum bootmem_type *)args;

	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;
}

static void *selfprepare(struct prog *payload)
{
	void *data;
	data = rdev_mmap_full(prog_rdev(payload));
	return data;
}

static bool _selfload(struct prog *payload, checker_t f, void *args)
{
	uintptr_t entry = 0;
	struct cbfs_payload_segment *cbfssegs;
	void *data;

	data = selfprepare(payload);
	if (data == NULL)
		return false;

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

	if (f && f(cbfssegs, args))
		goto out;

	if (load_payload_segments(cbfssegs, &entry))
		goto out;

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

	rdev_munmap(prog_rdev(payload), data);

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

	return true;
out:
	rdev_munmap(prog_rdev(payload), data);
	return false;
}

bool selfload_check(struct prog *payload, enum bootmem_type dest_type)
{
	return _selfload(payload, check_payload_segments, &dest_type);
}

bool selfload(struct prog *payload)
{
	return _selfload(payload, NULL, 0);
}
