// SPDX-License-Identifier: GPL-2.0-only
/*
 * imr.c -- Intel Isolated Memory Region driver
 *
 * Copyright(c) 2013 Intel Corporation.
 * Copyright(c) 2015 Bryan O'Donoghue <pure.logic@nexus-software.ie>
 *
 * IMR registers define an isolated region of memory that can
 * be masked to prohibit certain system agents from accessing memory.
 * When a device behind a masked port performs an access - snooped or
 * not, an IMR may optionally prevent that transaction from changing
 * the state of memory or from getting correct data in response to the
 * operation.
 *
 * Write data will be dropped and reads will return 0xFFFFFFFF, the
 * system will reset and system BIOS will print out an error message to
 * inform the user that an IMR has been violated.
 *
 * This code is based on the Linux MTRR code and reference code from
 * Intel's Quark BSP EFI, Linux and grub code.
 *
 * See quark-x1000-datasheet.pdf for register definitions.
 * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/quark-x1000-datasheet.pdf
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <asm-generic/sections.h>
#include <asm/cpu_device_id.h>
#include <asm/imr.h>
#include <asm/iosf_mbi.h>
#include <asm/io.h>

#include <linux/debugfs.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/types.h>

struct imr_device {
	bool		init;
	struct mutex	lock;
	int		max_imr;
	int		reg_base;
};

static struct imr_device imr_dev;

/*
 * IMR read/write mask control registers.
 * See quark-x1000-datasheet.pdf sections 12.7.4.5 and 12.7.4.6 for
 * bit definitions.
 *
 * addr_hi
 * 31		Lock bit
 * 30:24	Reserved
 * 23:2		1 KiB aligned lo address
 * 1:0		Reserved
 *
 * addr_hi
 * 31:24	Reserved
 * 23:2		1 KiB aligned hi address
 * 1:0		Reserved
 */
#define IMR_LOCK	BIT(31)

struct imr_regs {
	u32 addr_lo;
	u32 addr_hi;
	u32 rmask;
	u32 wmask;
};

#define IMR_NUM_REGS	(sizeof(struct imr_regs)/sizeof(u32))
#define IMR_SHIFT	8
#define imr_to_phys(x)	((x) << IMR_SHIFT)
#define phys_to_imr(x)	((x) >> IMR_SHIFT)

/**
 * imr_is_enabled - true if an IMR is enabled false otherwise.
 *
 * Determines if an IMR is enabled based on address range and read/write
 * mask. An IMR set with an address range set to zero and a read/write
 * access mask set to all is considered to be disabled. An IMR in any
 * other state - for example set to zero but without read/write access
 * all is considered to be enabled. This definition of disabled is how
 * firmware switches off an IMR and is maintained in kernel for
 * consistency.
 *
 * @imr:	pointer to IMR descriptor.
 * @return:	true if IMR enabled false if disabled.
 */
static inline int imr_is_enabled(struct imr_regs *imr)
{
	return !(imr->rmask == IMR_READ_ACCESS_ALL &&
		 imr->wmask == IMR_WRITE_ACCESS_ALL &&
		 imr_to_phys(imr->addr_lo) == 0 &&
		 imr_to_phys(imr->addr_hi) == 0);
}

/**
 * imr_read - read an IMR at a given index.
 *
 * Requires caller to hold imr mutex.
 *
 * @idev:	pointer to imr_device structure.
 * @imr_id:	IMR entry to read.
 * @imr:	IMR structure representing address and access masks.
 * @return:	0 on success or error code passed from mbi_iosf on failure.
 */
static int imr_read(struct imr_device *idev, u32 imr_id, struct imr_regs *imr)
{
	u32 reg = imr_id * IMR_NUM_REGS + idev->reg_base;
	int ret;

	ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->addr_lo);
	if (ret)
		return ret;

	ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->addr_hi);
	if (ret)
		return ret;

	ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->rmask);
	if (ret)
		return ret;

	return iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->wmask);
}

/**
 * imr_write - write an IMR at a given index.
 *
 * Requires caller to hold imr mutex.
 * Note lock bits need to be written independently of address bits.
 *
 * @idev:	pointer to imr_device structure.
 * @imr_id:	IMR entry to write.
 * @imr:	IMR structure representing address and access masks.
 * @return:	0 on success or error code passed from mbi_iosf on failure.
 */
static int imr_write(struct imr_device *idev, u32 imr_id, struct imr_regs *imr)
{
	unsigned long flags;
	u32 reg = imr_id * IMR_NUM_REGS + idev->reg_base;
	int ret;

	local_irq_save(flags);

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_lo);
	if (ret)
		goto failed;

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_hi);
	if (ret)
		goto failed;

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->rmask);
	if (ret)
		goto failed;

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->wmask);
	if (ret)
		goto failed;

	local_irq_restore(flags);
	return 0;
failed:
	/*
	 * If writing to the IOSF failed then we're in an unknown state,
	 * likely a very bad state. An IMR in an invalid state will almost
	 * certainly lead to a memory access violation.
	 */
	local_irq_restore(flags);
	WARN(ret, "IOSF-MBI write fail range 0x%08x-0x%08x unreliable\n",
	     imr_to_phys(imr->addr_lo), imr_to_phys(imr->addr_hi) + IMR_MASK);

	return ret;
}

/**
 * imr_dbgfs_state_show - print state of IMR registers.
 *
 * @s:		pointer to seq_file for output.
 * @unused:	unused parameter.
 * @return:	0 on success or error code passed from mbi_iosf on failure.
 */
static int imr_dbgfs_state_show(struct seq_file *s, void *unused)
{
	phys_addr_t base;
	phys_addr_t end;
	int i;
	struct imr_device *idev = s->private;
	struct imr_regs imr;
	size_t size;
	int ret = -ENODEV;

	mutex_lock(&idev->lock);

	for (i = 0; i < idev->max_imr; i++) {

		ret = imr_read(idev, i, &imr);
		if (ret)
			break;

		/*
		 * Remember to add IMR_ALIGN bytes to size to indicate the
		 * inherent IMR_ALIGN size bytes contained in the masked away
		 * lower ten bits.
		 */
		if (imr_is_enabled(&imr)) {
			base = imr_to_phys(imr.addr_lo);
			end = imr_to_phys(imr.addr_hi) + IMR_MASK;
			size = end - base + 1;
		} else {
			base = 0;
			end = 0;
			size = 0;
		}
		seq_printf(s, "imr%02i: base=%pa, end=%pa, size=0x%08zx "
			   "rmask=0x%08x, wmask=0x%08x, %s, %s\n", i,
			   &base, &end, size, imr.rmask, imr.wmask,
			   imr_is_enabled(&imr) ? "enabled " : "disabled",
			   imr.addr_lo & IMR_LOCK ? "locked" : "unlocked");
	}

	mutex_unlock(&idev->lock);
	return ret;
}
DEFINE_SHOW_ATTRIBUTE(imr_dbgfs_state);

/**
 * imr_debugfs_register - register debugfs hooks.
 *
 * @idev:	pointer to imr_device structure.
 */
static void imr_debugfs_register(struct imr_device *idev)
{
	debugfs_create_file("imr_state", 0444, NULL, idev,
			    &imr_dbgfs_state_fops);
}

/**
 * imr_check_params - check passed address range IMR alignment and non-zero size
 *
 * @base:	base address of intended IMR.
 * @size:	size of intended IMR.
 * @return:	zero on valid range -EINVAL on unaligned base/size.
 */
static int imr_check_params(phys_addr_t base, size_t size)
{
	if ((base & IMR_MASK) || (size & IMR_MASK)) {
		pr_err("base %pa size 0x%08zx must align to 1KiB\n",
			&base, size);
		return -EINVAL;
	}
	if (size == 0)
		return -EINVAL;

	return 0;
}

/**
 * imr_raw_size - account for the IMR_ALIGN bytes that addr_hi appends.
 *
 * IMR addr_hi has a built in offset of plus IMR_ALIGN (0x400) bytes from the
 * value in the register. We need to subtract IMR_ALIGN bytes from input sizes
 * as a result.
 *
 * @size:	input size bytes.
 * @return:	reduced size.
 */
static inline size_t imr_raw_size(size_t size)
{
	return size - IMR_ALIGN;
}

/**
 * imr_address_overlap - detects an address overlap.
 *
 * @addr:	address to check against an existing IMR.
 * @imr:	imr being checked.
 * @return:	true for overlap false for no overlap.
 */
static inline int imr_address_overlap(phys_addr_t addr, struct imr_regs *imr)
{
	return addr >= imr_to_phys(imr->addr_lo) && addr <= imr_to_phys(imr->addr_hi);
}

/**
 * imr_add_range - add an Isolated Memory Region.
 *
 * @base:	physical base address of region aligned to 1KiB.
 * @size:	physical size of region in bytes must be aligned to 1KiB.
 * @read_mask:	read access mask.
 * @write_mask:	write access mask.
 * @return:	zero on success or negative value indicating error.
 */
int imr_add_range(phys_addr_t base, size_t size,
		  unsigned int rmask, unsigned int wmask)
{
	phys_addr_t end;
	unsigned int i;
	struct imr_device *idev = &imr_dev;
	struct imr_regs imr;
	size_t raw_size;
	int reg;
	int ret;

	if (WARN_ONCE(idev->init == false, "driver not initialized"))
		return -ENODEV;

	ret = imr_check_params(base, size);
	if (ret)
		return ret;

	/* Tweak the size value. */
	raw_size = imr_raw_size(size);
	end = base + raw_size;

	/*
	 * Check for reserved IMR value common to firmware, kernel and grub
	 * indicating a disabled IMR.
	 */
	imr.addr_lo = phys_to_imr(base);
	imr.addr_hi = phys_to_imr(end);
	imr.rmask = rmask;
	imr.wmask = wmask;
	if (!imr_is_enabled(&imr))
		return -ENOTSUPP;

	mutex_lock(&idev->lock);

	/*
	 * Find a free IMR while checking for an existing overlapping range.
	 * Note there's no restriction in silicon to prevent IMR overlaps.
	 * For the sake of simplicity and ease in defining/debugging an IMR
	 * memory map we exclude IMR overlaps.
	 */
	reg = -1;
	for (i = 0; i < idev->max_imr; i++) {
		ret = imr_read(idev, i, &imr);
		if (ret)
			goto failed;

		/* Find overlap @ base or end of requested range. */
		ret = -EINVAL;
		if (imr_is_enabled(&imr)) {
			if (imr_address_overlap(base, &imr))
				goto failed;
			if (imr_address_overlap(end, &imr))
				goto failed;
		} else {
			reg = i;
		}
	}

	/* Error out if we have no free IMR entries. */
	if (reg == -1) {
		ret = -ENOMEM;
		goto failed;
	}

	pr_debug("add %d phys %pa-%pa size %zx mask 0x%08x wmask 0x%08x\n",
		 reg, &base, &end, raw_size, rmask, wmask);

	/* Enable IMR at specified range and access mask. */
	imr.addr_lo = phys_to_imr(base);
	imr.addr_hi = phys_to_imr(end);
	imr.rmask = rmask;
	imr.wmask = wmask;

	ret = imr_write(idev, reg, &imr);
	if (ret < 0) {
		/*
		 * In the highly unlikely event iosf_mbi_write failed
		 * attempt to rollback the IMR setup skipping the trapping
		 * of further IOSF write failures.
		 */
		imr.addr_lo = 0;
		imr.addr_hi = 0;
		imr.rmask = IMR_READ_ACCESS_ALL;
		imr.wmask = IMR_WRITE_ACCESS_ALL;
		imr_write(idev, reg, &imr);
	}
failed:
	mutex_unlock(&idev->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(imr_add_range);

/**
 * __imr_remove_range - delete an Isolated Memory Region.
 *
 * This function allows you to delete an IMR by its index specified by reg or
 * by address range specified by base and size respectively. If you specify an
 * index on its own the base and size parameters are ignored.
 * imr_remove_range(0, base, size); delete IMR at index 0 base/size ignored.
 * imr_remove_range(-1, base, size); delete IMR from base to base+size.
 *
 * @reg:	imr index to remove.
 * @base:	physical base address of region aligned to 1 KiB.
 * @size:	physical size of region in bytes aligned to 1 KiB.
 * @return:	-EINVAL on invalid range or out or range id
 *		-ENODEV if reg is valid but no IMR exists or is locked
 *		0 on success.
 */
static int __imr_remove_range(int reg, phys_addr_t base, size_t size)
{
	phys_addr_t end;
	bool found = false;
	unsigned int i;
	struct imr_device *idev = &imr_dev;
	struct imr_regs imr;
	size_t raw_size;
	int ret = 0;

	if (WARN_ONCE(idev->init == false, "driver not initialized"))
		return -ENODEV;

	/*
	 * Validate address range if deleting by address, else we are
	 * deleting by index where base and size will be ignored.
	 */
	if (reg == -1) {
		ret = imr_check_params(base, size);
		if (ret)
			return ret;
	}

	/* Tweak the size value. */
	raw_size = imr_raw_size(size);
	end = base + raw_size;

	mutex_lock(&idev->lock);

	if (reg >= 0) {
		/* If a specific IMR is given try to use it. */
		ret = imr_read(idev, reg, &imr);
		if (ret)
			goto failed;

		if (!imr_is_enabled(&imr) || imr.addr_lo & IMR_LOCK) {
			ret = -ENODEV;
			goto failed;
		}
		found = true;
	} else {
		/* Search for match based on address range. */
		for (i = 0; i < idev->max_imr; i++) {
			ret = imr_read(idev, i, &imr);
			if (ret)
				goto failed;

			if (!imr_is_enabled(&imr) || imr.addr_lo & IMR_LOCK)
				continue;

			if ((imr_to_phys(imr.addr_lo) == base) &&
			    (imr_to_phys(imr.addr_hi) == end)) {
				found = true;
				reg = i;
				break;
			}
		}
	}

	if (!found) {
		ret = -ENODEV;
		goto failed;
	}

	pr_debug("remove %d phys %pa-%pa size %zx\n", reg, &base, &end, raw_size);

	/* Tear down the IMR. */
	imr.addr_lo = 0;
	imr.addr_hi = 0;
	imr.rmask = IMR_READ_ACCESS_ALL;
	imr.wmask = IMR_WRITE_ACCESS_ALL;

	ret = imr_write(idev, reg, &imr);

failed:
	mutex_unlock(&idev->lock);
	return ret;
}

/**
 * imr_remove_range - delete an Isolated Memory Region by address
 *
 * This function allows you to delete an IMR by an address range specified
 * by base and size respectively.
 * imr_remove_range(base, size); delete IMR from base to base+size.
 *
 * @base:	physical base address of region aligned to 1 KiB.
 * @size:	physical size of region in bytes aligned to 1 KiB.
 * @return:	-EINVAL on invalid range or out or range id
 *		-ENODEV if reg is valid but no IMR exists or is locked
 *		0 on success.
 */
int imr_remove_range(phys_addr_t base, size_t size)
{
	return __imr_remove_range(-1, base, size);
}
EXPORT_SYMBOL_GPL(imr_remove_range);

/**
 * imr_clear - delete an Isolated Memory Region by index
 *
 * This function allows you to delete an IMR by an address range specified
 * by the index of the IMR. Useful for initial sanitization of the IMR
 * address map.
 * imr_ge(base, size); delete IMR from base to base+size.
 *
 * @reg:	imr index to remove.
 * @return:	-EINVAL on invalid range or out or range id
 *		-ENODEV if reg is valid but no IMR exists or is locked
 *		0 on success.
 */
static inline int imr_clear(int reg)
{
	return __imr_remove_range(reg, 0, 0);
}

/**
 * imr_fixup_memmap - Tear down IMRs used during bootup.
 *
 * BIOS and Grub both setup IMRs around compressed kernel, initrd memory
 * that need to be removed before the kernel hands out one of the IMR
 * encased addresses to a downstream DMA agent such as the SD or Ethernet.
 * IMRs on Galileo are setup to immediately reset the system on violation.
 * As a result if you're running a root filesystem from SD - you'll need
 * the boot-time IMRs torn down or you'll find seemingly random resets when
 * using your filesystem.
 *
 * @idev:	pointer to imr_device structure.
 * @return:
 */
static void __init imr_fixup_memmap(struct imr_device *idev)
{
	phys_addr_t base = virt_to_phys(&_text);
	size_t size = virt_to_phys(&__end_rodata) - base;
	unsigned long start, end;
	int i;
	int ret;

	/* Tear down all existing unlocked IMRs. */
	for (i = 0; i < idev->max_imr; i++)
		imr_clear(i);

	start = (unsigned long)_text;
	end = (unsigned long)__end_rodata - 1;

	/*
	 * Setup an unlocked IMR around the physical extent of the kernel
	 * from the beginning of the .text section to the end of the
	 * .rodata section as one physically contiguous block.
	 *
	 * We don't round up @size since it is already PAGE_SIZE aligned.
	 * See vmlinux.lds.S for details.
	 */
	ret = imr_add_range(base, size, IMR_CPU, IMR_CPU);
	if (ret < 0) {
		pr_err("unable to setup IMR for kernel: %zu KiB (%lx - %lx)\n",
			size / 1024, start, end);
	} else {
		pr_info("protecting kernel .text - .rodata: %zu KiB (%lx - %lx)\n",
			size / 1024, start, end);
	}

}

static const struct x86_cpu_id imr_ids[] __initconst = {
	X86_MATCH_VENDOR_FAM_MODEL(INTEL, 5, INTEL_FAM5_QUARK_X1000, NULL),
	{}
};

/**
 * imr_init - entry point for IMR driver.
 *
 * return: -ENODEV for no IMR support 0 if good to go.
 */
static int __init imr_init(void)
{
	struct imr_device *idev = &imr_dev;

	if (!x86_match_cpu(imr_ids) || !iosf_mbi_available())
		return -ENODEV;

	idev->max_imr = QUARK_X1000_IMR_MAX;
	idev->reg_base = QUARK_X1000_IMR_REGBASE;
	idev->init = true;

	mutex_init(&idev->lock);
	imr_debugfs_register(idev);
	imr_fixup_memmap(idev);
	return 0;
}
device_initcall(imr_init);
