// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license.  When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2022 Intel Corporation

#include <linux/firmware.h>
#include "sof-priv.h"
#include "sof-audio.h"
#include "ipc3-priv.h"
#include "ops.h"

static int ipc3_fw_ext_man_get_version(struct snd_sof_dev *sdev,
				       const struct sof_ext_man_elem_header *hdr)
{
	const struct sof_ext_man_fw_version *v =
		container_of(hdr, struct sof_ext_man_fw_version, hdr);

	memcpy(&sdev->fw_ready.version, &v->version, sizeof(v->version));
	sdev->fw_ready.flags = v->flags;

	/* log ABI versions and check FW compatibility */
	return sof_ipc3_validate_fw_version(sdev);
}

static int ipc3_fw_ext_man_get_windows(struct snd_sof_dev *sdev,
				       const struct sof_ext_man_elem_header *hdr)
{
	const struct sof_ext_man_window *w;

	w = container_of(hdr, struct sof_ext_man_window, hdr);

	return sof_ipc3_get_ext_windows(sdev, &w->ipc_window.ext_hdr);
}

static int ipc3_fw_ext_man_get_cc_info(struct snd_sof_dev *sdev,
				       const struct sof_ext_man_elem_header *hdr)
{
	const struct sof_ext_man_cc_version *cc;

	cc = container_of(hdr, struct sof_ext_man_cc_version, hdr);

	return sof_ipc3_get_cc_info(sdev, &cc->cc_version.ext_hdr);
}

static int ipc3_fw_ext_man_get_dbg_abi_info(struct snd_sof_dev *sdev,
					    const struct sof_ext_man_elem_header *hdr)
{
	const struct ext_man_dbg_abi *dbg_abi =
		container_of(hdr, struct ext_man_dbg_abi, hdr);

	if (sdev->first_boot)
		dev_dbg(sdev->dev,
			"Firmware: DBG_ABI %d:%d:%d\n",
			SOF_ABI_VERSION_MAJOR(dbg_abi->dbg_abi.abi_dbg_version),
			SOF_ABI_VERSION_MINOR(dbg_abi->dbg_abi.abi_dbg_version),
			SOF_ABI_VERSION_PATCH(dbg_abi->dbg_abi.abi_dbg_version));

	return 0;
}

static int ipc3_fw_ext_man_get_config_data(struct snd_sof_dev *sdev,
					   const struct sof_ext_man_elem_header *hdr)
{
	const struct sof_ext_man_config_data *config =
		container_of(hdr, struct sof_ext_man_config_data, hdr);
	const struct sof_config_elem *elem;
	int elems_counter;
	int elems_size;
	int ret = 0;
	int i;

	/* calculate elements counter */
	elems_size = config->hdr.size - sizeof(struct sof_ext_man_elem_header);
	elems_counter = elems_size / sizeof(struct sof_config_elem);

	dev_dbg(sdev->dev, "manifest can hold up to %d config elements\n", elems_counter);

	for (i = 0; i < elems_counter; ++i) {
		elem = &config->elems[i];
		dev_dbg(sdev->dev, "get index %d token %d val %d\n",
			i, elem->token, elem->value);
		switch (elem->token) {
		case SOF_EXT_MAN_CONFIG_EMPTY:
			/* unused memory space is zero filled - mapped to EMPTY elements */
			break;
		case SOF_EXT_MAN_CONFIG_IPC_MSG_SIZE:
			/* TODO: use ipc msg size from config data */
			break;
		case SOF_EXT_MAN_CONFIG_MEMORY_USAGE_SCAN:
			if (sdev->first_boot && elem->value)
				ret = snd_sof_dbg_memory_info_init(sdev);
			break;
		default:
			dev_info(sdev->dev,
				 "Unknown firmware configuration token %d value %d",
				 elem->token, elem->value);
			break;
		}
		if (ret < 0) {
			dev_err(sdev->dev,
				"%s: processing failed for token %d value %#x, %d\n",
				__func__, elem->token, elem->value, ret);
			return ret;
		}
	}

	return 0;
}

static ssize_t ipc3_fw_ext_man_size(struct snd_sof_dev *sdev, const struct firmware *fw)
{
	const struct sof_ext_man_header *head;

	head = (struct sof_ext_man_header *)fw->data;

	/*
	 * assert fw size is big enough to contain extended manifest header,
	 * it prevents from reading unallocated memory from `head` in following
	 * step.
	 */
	if (fw->size < sizeof(*head))
		return -EINVAL;

	/*
	 * When fw points to extended manifest,
	 * then first u32 must be equal SOF_EXT_MAN_MAGIC_NUMBER.
	 */
	if (head->magic == SOF_EXT_MAN_MAGIC_NUMBER)
		return head->full_size;

	/* otherwise given fw don't have an extended manifest */
	dev_dbg(sdev->dev, "Unexpected extended manifest magic number: %#x\n",
		head->magic);
	return 0;
}

static size_t sof_ipc3_fw_parse_ext_man(struct snd_sof_dev *sdev)
{
	const struct firmware *fw = sdev->basefw.fw;
	const struct sof_ext_man_elem_header *elem_hdr;
	const struct sof_ext_man_header *head;
	ssize_t ext_man_size;
	ssize_t remaining;
	uintptr_t iptr;
	int ret = 0;

	head = (struct sof_ext_man_header *)fw->data;
	remaining = head->full_size - head->header_size;
	if (remaining < 0 || remaining > sdev->basefw.fw->size)
		return -EINVAL;
	ext_man_size = ipc3_fw_ext_man_size(sdev, fw);

	/* Assert firmware starts with extended manifest */
	if (ext_man_size <= 0)
		return ext_man_size;

	/* incompatible version */
	if (SOF_EXT_MAN_VERSION_INCOMPATIBLE(SOF_EXT_MAN_VERSION,
					     head->header_version)) {
		dev_err(sdev->dev,
			"extended manifest version %#x differ from used %#x\n",
			head->header_version, SOF_EXT_MAN_VERSION);
		return -EINVAL;
	}

	/* get first extended manifest element header */
	iptr = (uintptr_t)fw->data + head->header_size;

	while (remaining > sizeof(*elem_hdr)) {
		elem_hdr = (struct sof_ext_man_elem_header *)iptr;

		dev_dbg(sdev->dev, "found sof_ext_man header type %d size %#x\n",
			elem_hdr->type, elem_hdr->size);

		if (elem_hdr->size < sizeof(*elem_hdr) ||
		    elem_hdr->size > remaining) {
			dev_err(sdev->dev,
				"invalid sof_ext_man header size, type %d size %#x\n",
				elem_hdr->type, elem_hdr->size);
			return -EINVAL;
		}

		/* process structure data */
		switch (elem_hdr->type) {
		case SOF_EXT_MAN_ELEM_FW_VERSION:
			ret = ipc3_fw_ext_man_get_version(sdev, elem_hdr);
			break;
		case SOF_EXT_MAN_ELEM_WINDOW:
			ret = ipc3_fw_ext_man_get_windows(sdev, elem_hdr);
			break;
		case SOF_EXT_MAN_ELEM_CC_VERSION:
			ret = ipc3_fw_ext_man_get_cc_info(sdev, elem_hdr);
			break;
		case SOF_EXT_MAN_ELEM_PROBE_INFO:
			dev_dbg(sdev->dev, "Probe info (not parsed)\n");
			break;
		case SOF_EXT_MAN_ELEM_DBG_ABI:
			ret = ipc3_fw_ext_man_get_dbg_abi_info(sdev, elem_hdr);
			break;
		case SOF_EXT_MAN_ELEM_CONFIG_DATA:
			ret = ipc3_fw_ext_man_get_config_data(sdev, elem_hdr);
			break;
		case SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA:
			ret = snd_sof_dsp_parse_platform_ext_manifest(sdev, elem_hdr);
			break;
		default:
			dev_info(sdev->dev,
				 "unknown sof_ext_man header type %d size %#x\n",
				 elem_hdr->type, elem_hdr->size);
			break;
		}

		if (ret < 0) {
			dev_err(sdev->dev,
				"failed to parse sof_ext_man header type %d size %#x\n",
				elem_hdr->type, elem_hdr->size);
			return ret;
		}

		remaining -= elem_hdr->size;
		iptr += elem_hdr->size;
	}

	if (remaining) {
		dev_err(sdev->dev, "error: sof_ext_man header is inconsistent\n");
		return -EINVAL;
	}

	return ext_man_size;
}

/* generic module parser for mmaped DSPs */
static int sof_ipc3_parse_module_memcpy(struct snd_sof_dev *sdev,
					struct snd_sof_mod_hdr *module)
{
	struct snd_sof_blk_hdr *block;
	int count, ret;
	u32 offset;
	size_t remaining;

	dev_dbg(sdev->dev, "new module size %#x blocks %#x type %#x\n",
		module->size, module->num_blocks, module->type);

	block = (struct snd_sof_blk_hdr *)((u8 *)module + sizeof(*module));

	/* module->size doesn't include header size */
	remaining = module->size;
	for (count = 0; count < module->num_blocks; count++) {
		/* check for wrap */
		if (remaining < sizeof(*block)) {
			dev_err(sdev->dev, "not enough data remaining\n");
			return -EINVAL;
		}

		/* minus header size of block */
		remaining -= sizeof(*block);

		if (block->size == 0) {
			dev_warn(sdev->dev,
				 "warning: block %d size zero\n", count);
			dev_warn(sdev->dev, " type %#x offset %#x\n",
				 block->type, block->offset);
			continue;
		}

		switch (block->type) {
		case SOF_FW_BLK_TYPE_RSRVD0:
		case SOF_FW_BLK_TYPE_ROM...SOF_FW_BLK_TYPE_RSRVD14:
			continue;	/* not handled atm */
		case SOF_FW_BLK_TYPE_IRAM:
		case SOF_FW_BLK_TYPE_DRAM:
		case SOF_FW_BLK_TYPE_SRAM:
			offset = block->offset;
			break;
		default:
			dev_err(sdev->dev, "%s: bad type %#x for block %#x\n",
				__func__, block->type, count);
			return -EINVAL;
		}

		dev_dbg(sdev->dev, "block %d type %#x size %#x ==>  offset %#x\n",
			count, block->type, block->size, offset);

		/* checking block->size to avoid unaligned access */
		if (block->size % sizeof(u32)) {
			dev_err(sdev->dev, "%s: invalid block size %#x\n",
				__func__, block->size);
			return -EINVAL;
		}
		ret = snd_sof_dsp_block_write(sdev, block->type, offset,
					      block + 1, block->size);
		if (ret < 0) {
			dev_err(sdev->dev, "%s: write to block type %#x failed\n",
				__func__, block->type);
			return ret;
		}

		if (remaining < block->size) {
			dev_err(sdev->dev, "%s: not enough data remaining\n", __func__);
			return -EINVAL;
		}

		/* minus body size of block */
		remaining -= block->size;
		/* next block */
		block = (struct snd_sof_blk_hdr *)((u8 *)block + sizeof(*block)
			+ block->size);
	}

	return 0;
}

static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev)
{
	u32 payload_offset = sdev->basefw.payload_offset;
	const struct firmware *fw = sdev->basefw.fw;
	struct snd_sof_fw_header *header;
	struct snd_sof_mod_hdr *module;
	int (*load_module)(struct snd_sof_dev *sof_dev, struct snd_sof_mod_hdr *hdr);
	size_t remaining;
	int ret, count;

	if (!fw)
		return -EINVAL;

	header = (struct snd_sof_fw_header *)(fw->data + payload_offset);
	load_module = sof_ops(sdev)->load_module;
	if (!load_module) {
		dev_dbg(sdev->dev, "Using generic module loading\n");
		load_module = sof_ipc3_parse_module_memcpy;
	} else {
		dev_dbg(sdev->dev, "Using custom module loading\n");
	}

	/* parse each module */
	module = (struct snd_sof_mod_hdr *)(fw->data + payload_offset + sizeof(*header));
	remaining = fw->size - sizeof(*header) - payload_offset;
	/* check for wrap */
	if (remaining > fw->size) {
		dev_err(sdev->dev, "%s: fw size smaller than header size\n", __func__);
		return -EINVAL;
	}

	for (count = 0; count < header->num_modules; count++) {
		/* check for wrap */
		if (remaining < sizeof(*module)) {
			dev_err(sdev->dev, "%s: not enough data for a module\n",
				__func__);
			return -EINVAL;
		}

		/* minus header size of module */
		remaining -= sizeof(*module);

		/* module */
		ret = load_module(sdev, module);
		if (ret < 0) {
			dev_err(sdev->dev, "%s: invalid module %d\n", __func__, count);
			return ret;
		}

		if (remaining < module->size) {
			dev_err(sdev->dev, "%s: not enough data remaining\n", __func__);
			return -EINVAL;
		}

		/* minus body size of module */
		remaining -=  module->size;
		module = (struct snd_sof_mod_hdr *)((u8 *)module +
			 sizeof(*module) + module->size);
	}

	return 0;
}

static int sof_ipc3_validate_firmware(struct snd_sof_dev *sdev)
{
	u32 payload_offset = sdev->basefw.payload_offset;
	const struct firmware *fw = sdev->basefw.fw;
	struct snd_sof_fw_header *header;
	size_t fw_size = fw->size - payload_offset;

	if (fw->size <= payload_offset) {
		dev_err(sdev->dev,
			"firmware size must be greater than firmware offset\n");
		return -EINVAL;
	}

	/* Read the header information from the data pointer */
	header = (struct snd_sof_fw_header *)(fw->data + payload_offset);

	/* verify FW sig */
	if (strncmp(header->sig, SND_SOF_FW_SIG, SND_SOF_FW_SIG_SIZE) != 0) {
		dev_err(sdev->dev, "invalid firmware signature\n");
		return -EINVAL;
	}

	/* check size is valid */
	if (fw_size != header->file_size + sizeof(*header)) {
		dev_err(sdev->dev,
			"invalid filesize mismatch got 0x%zx expected 0x%zx\n",
			fw_size, header->file_size + sizeof(*header));
		return -EINVAL;
	}

	dev_dbg(sdev->dev, "header size=0x%x modules=0x%x abi=0x%x size=%zu\n",
		header->file_size, header->num_modules,
		header->abi, sizeof(*header));

	return 0;
}

const struct sof_ipc_fw_loader_ops ipc3_loader_ops = {
	.validate = sof_ipc3_validate_firmware,
	.parse_ext_manifest = sof_ipc3_fw_parse_ext_man,
	.load_fw_to_dsp = sof_ipc3_load_fw_to_dsp,
};
