// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2020 Stefan Roese <sr@denx.de>
 */

#include <common.h>
#include <image.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <asm/sections.h>
#include <spl.h>

#include <lzma/LzmaTypes.h>
#include <lzma/LzmaDec.h>
#include <lzma/LzmaTools.h>

#define LZMA_LEN	(1 << 20)

static void spl_parse_legacy_validate(uintptr_t start, uintptr_t size)
{
	uintptr_t spl_start = (uintptr_t)_start;
	uintptr_t spl_end = (uintptr_t)&_image_binary_end;
	uintptr_t end = start + size;

	if ((start >= spl_start && start < spl_end) ||
	    (end > spl_start && end <= spl_end) ||
	    (start < spl_start && end >= spl_end) ||
	    (start > end && end > spl_start))
		panic("SPL: Image overlaps SPL\n");

	if (size > CONFIG_SYS_BOOTM_LEN)
		panic("SPL: Image too large\n");
}

int spl_parse_legacy_header(struct spl_image_info *spl_image,
			    const struct legacy_img_hdr *header)
{
	u32 header_size = sizeof(struct legacy_img_hdr);

	/* check uImage header CRC */
	if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK) &&
	    !image_check_hcrc(header)) {
		puts("SPL: Image header CRC check failed!\n");
		return -EINVAL;
	}

	if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) {
		/*
		 * On some system (e.g. powerpc), the load-address and
		 * entry-point is located at address 0. We can't load
		 * to 0-0x40. So skip header in this case.
		 */
		spl_image->load_addr = image_get_load(header);
		spl_image->entry_point = image_get_ep(header);
		spl_image->size = image_get_data_size(header);
	} else {
		spl_image->entry_point = image_get_ep(header);
		/* Load including the header */
		spl_image->load_addr = image_get_load(header) -
			header_size;
		spl_image->size = image_get_data_size(header) +
			header_size;
	}

#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
	/* store uImage data length and CRC to check later */
	spl_image->dcrc_data = image_get_load(header);
	spl_image->dcrc_length = image_get_data_size(header);
	spl_image->dcrc = image_get_dcrc(header);
#endif

	spl_image->os = image_get_os(header);
	spl_image->name = image_get_name(header);
	debug(SPL_TPL_PROMPT
	      "payload image: %32s load addr: 0x%lx size: %d\n",
	      spl_image->name, spl_image->load_addr, spl_image->size);

	spl_parse_legacy_validate(spl_image->load_addr, spl_image->size);
	spl_parse_legacy_validate(spl_image->entry_point, 0);

	return 0;
}

/*
 * This function is added explicitly to avoid code size increase, when
 * no compression method is enabled. The compiler will optimize the
 * following switch/case statement in spl_load_legacy_img() away due to
 * Dead Code Elimination.
 */
static inline int spl_image_get_comp(const struct legacy_img_hdr *hdr)
{
	if (IS_ENABLED(CONFIG_SPL_LZMA))
		return image_get_comp(hdr);

	return IH_COMP_NONE;
}

int spl_load_legacy_img(struct spl_image_info *spl_image,
			struct spl_boot_device *bootdev,
			struct spl_load_info *load, ulong offset,
			struct legacy_img_hdr *hdr)
{
	__maybe_unused SizeT lzma_len;
	__maybe_unused void *src;
	ulong dataptr;
	int ret;

	/*
	 * If the payload is compressed, the decompressed data should be
	 * directly write to its load address.
	 */
	if (spl_image_get_comp(hdr) != IH_COMP_NONE)
		spl_image->flags |= SPL_COPY_PAYLOAD_ONLY;

	ret = spl_parse_image_header(spl_image, bootdev, hdr);
	if (ret)
		return ret;

	/* Read image */
	switch (spl_image_get_comp(hdr)) {
	case IH_COMP_NONE:
		dataptr = offset;

		/*
		 * Image header will be skipped only if SPL_COPY_PAYLOAD_ONLY
		 * is set
		 */
		if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY)
			dataptr += sizeof(*hdr);

		load->read(load, dataptr, spl_image->size,
			   map_sysmem(spl_image->load_addr, spl_image->size));
		break;

	case IH_COMP_LZMA:
		lzma_len = LZMA_LEN;

		/* dataptr points to compressed payload  */
		dataptr = offset + sizeof(*hdr);

		debug("LZMA: Decompressing %08lx to %08lx\n",
		      dataptr, spl_image->load_addr);
		src = malloc(spl_image->size);
		if (!src) {
			printf("Unable to allocate %d bytes for LZMA\n",
			       spl_image->size);
			return -ENOMEM;
		}

		load->read(load, dataptr, spl_image->size, src);
		ret = lzmaBuffToBuffDecompress(map_sysmem(spl_image->load_addr,
							  spl_image->size),
					       &lzma_len, src, spl_image->size);
		if (ret) {
			printf("LZMA decompression error: %d\n", ret);
			return ret;
		}

		spl_image->size = lzma_len;
		break;

	default:
		debug("Compression method %s is not supported\n",
		      genimg_get_comp_short_name(image_get_comp(hdr)));
		return -EINVAL;
	}

	return 0;
}
