// SPDX-License-Identifier: GPL-2.0-only
/*
 * Framework for parsing the firmware image configuration.
 *
 * Copyright (C) 2022 Google LLC
 */

#include <linux/device.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>

#include <gcip/gcip-image-config.h>

static int setup_iommu_mappings(struct gcip_image_config_parser *parser,
				struct gcip_image_config *config)
{
	int i, ret;
	dma_addr_t daddr;
	size_t size;
	phys_addr_t paddr;

	for (i = 0; i < config->num_iommu_mappings; i++) {
		daddr = config->iommu_mappings[i].virt_address;
		if (unlikely(!daddr)) {
			dev_warn(parser->dev, "Invalid config, device address is zero");
			ret = -EIO;
			goto err;
		}
		size = gcip_config_to_size(config->iommu_mappings[i].image_config_value);
		paddr = config->iommu_mappings[i].image_config_value & GCIP_IMG_CFG_ADDR_MASK;

		dev_dbg(parser->dev, "Image config adding IOMMU mapping: %pad -> %pap", &daddr,
			&paddr);

		if (unlikely(daddr + size <= daddr || paddr + size <= paddr)) {
			ret = -EOVERFLOW;
			goto err;
		}
		ret = parser->ops->map(parser->data, daddr, paddr, size,
				       GCIP_IMAGE_CONFIG_FLAGS_SECURE);
		if (ret) {
			dev_err(parser->dev,
				"Unable to Map: %d dma_addr: %pad phys_addr: %pap size: %#lx\n",
				ret, &daddr, &paddr, size);
			goto err;
		}
	}

	return 0;

err:
	while (i--) {
		daddr = config->iommu_mappings[i].virt_address;
		size = gcip_config_to_size(config->iommu_mappings[i].image_config_value);
		parser->ops->unmap(parser->data, daddr, size, GCIP_IMAGE_CONFIG_FLAGS_SECURE);
	}
	return ret;
}

static void clear_iommu_mappings(struct gcip_image_config_parser *parser,
				 struct gcip_image_config *config)
{
	dma_addr_t daddr;
	size_t size;
	int i;

	for (i = config->num_iommu_mappings - 1; i >= 0; i--) {
		daddr = config->iommu_mappings[i].virt_address;
		size = gcip_config_to_size(config->iommu_mappings[i].image_config_value);
		dev_dbg(parser->dev, "Image config removing IOMMU mapping: %pad size=%#lx", &daddr,
			size);
		parser->ops->unmap(parser->data, daddr, size, GCIP_IMAGE_CONFIG_FLAGS_SECURE);
	}
}

static int setup_ns_iommu_mappings(struct gcip_image_config_parser *parser,
				   struct gcip_image_config *config)
{
	dma_addr_t daddr;
	size_t size;
	int ret, i;
	phys_addr_t paddr = 0;

	for (i = 0; i < config->num_ns_iommu_mappings; i++) {
		daddr = config->ns_iommu_mappings[i] & GCIP_IMG_CFG_ADDR_MASK;
		if (unlikely(!daddr)) {
			dev_warn(parser->dev, "Invalid config, device address is zero");
			ret = -EIO;
			goto err;
		}
		size = gcip_ns_config_to_size(config->ns_iommu_mappings[i]);
		dev_dbg(parser->dev, "Image config adding NS IOMMU mapping: %pad -> %pap", &daddr,
			&paddr);
		if (unlikely(daddr + size <= daddr || paddr + size <= paddr)) {
			ret = -EOVERFLOW;
			goto err;
		}
		ret = parser->ops->map(parser->data, daddr, paddr, size, 0);
		if (ret)
			goto err;
		paddr += size;
	}

	return 0;

err:
	while (i--) {
		size = gcip_ns_config_to_size(config->ns_iommu_mappings[i]);
		daddr = config->ns_iommu_mappings[i] & GCIP_IMG_CFG_ADDR_MASK;
		parser->ops->unmap(parser->data, daddr, size, 0);
	}
	return ret;
}

static void clear_ns_iommu_mappings(struct gcip_image_config_parser *parser,
				    struct gcip_image_config *config)
{
	dma_addr_t daddr;
	size_t size;
	int i;

	for (i = config->num_ns_iommu_mappings - 1; i >= 0; i--) {
		size = gcip_ns_config_to_size(config->ns_iommu_mappings[i]);
		daddr = config->ns_iommu_mappings[i] & GCIP_IMG_CFG_ADDR_MASK;
		dev_dbg(parser->dev, "Image config removing NS IOMMU mapping: %pad size=%#lx",
			&daddr, size);
		parser->ops->unmap(parser->data, daddr, size, 0);
	}
}

static int map_image_config(struct gcip_image_config_parser *parser,
			    struct gcip_image_config *config)
{
	int ret = setup_ns_iommu_mappings(parser, config);

	if (ret)
		return ret;
	if (gcip_image_config_is_ns(config)) {
		ret = setup_iommu_mappings(parser, config);
		if (ret)
			clear_ns_iommu_mappings(parser, config);
	}
	return ret;
}

static void unmap_image_config(struct gcip_image_config_parser *parser,
			       struct gcip_image_config *config)
{
	if (gcip_image_config_is_ns(config))
		clear_iommu_mappings(parser, config);
	clear_ns_iommu_mappings(parser, config);
}

int gcip_image_config_parser_init(struct gcip_image_config_parser *parser,
				  const struct gcip_image_config_ops *ops, struct device *dev,
				  void *data)
{
	if (!ops->map || !ops->unmap) {
		dev_err(dev, "Missing mandatory operations for image config parser");
		return -EINVAL;
	}
	parser->dev = dev;
	parser->data = data;
	parser->ops = ops;
	memset(&parser->last_config, 0, sizeof(parser->last_config));
	parser->last_config_valid = false;
	return 0;
}

int gcip_image_config_parse(struct gcip_image_config_parser *parser,
			    struct gcip_image_config *config)
{
	int ret;

	if (!memcmp(config, &parser->last_config, sizeof(*config)))
		return 0;
	unmap_image_config(parser, &parser->last_config);
	ret = map_image_config(parser, config);
	if (ret) {
		dev_err(parser->dev, "Map image config failed: %d", ret);
		/*
		 * Weird case as the mappings in the last config were just removed - might happen
		 * if the IOMMU driver state is corrupted. We can't help to rescue it so let's
		 * simply log a message.
		 */
		if (unlikely(map_image_config(parser, &parser->last_config)))
			dev_err(parser->dev, "Failed to roll back the last image config");
		return ret;
	}
	memcpy(&parser->last_config, config, sizeof(parser->last_config));
	parser->last_config_valid = true;
	return 0;
}

void gcip_image_config_clear(struct gcip_image_config_parser *parser)
{
	unmap_image_config(parser, &parser->last_config);
	memset(&parser->last_config, 0, sizeof(parser->last_config));
	parser->last_config_valid = false;
}
