// SPDX-License-Identifier: GPL-2.0-only
/*
 * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/io.h>
#include <linux/mmiotrace.h>
#include <linux/security.h>

static unsigned long mmio_address;
module_param_hw(mmio_address, ulong, iomem, 0);
MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
				"(or 8 MB if read_far is non-zero).");

static unsigned long read_far = 0x400100;
module_param(read_far, ulong, 0);
MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
				"(default: 0x400100).");

static unsigned v16(unsigned i)
{
	return i * 12 + 7;
}

static unsigned v32(unsigned i)
{
	return i * 212371 + 13;
}

static void do_write_test(void __iomem *p)
{
	unsigned int i;
	pr_info("write test.\n");
	mmiotrace_printk("Write test.\n");

	for (i = 0; i < 256; i++)
		iowrite8(i, p + i);

	for (i = 1024; i < (5 * 1024); i += 2)
		iowrite16(v16(i), p + i);

	for (i = (5 * 1024); i < (16 * 1024); i += 4)
		iowrite32(v32(i), p + i);
}

static void do_read_test(void __iomem *p)
{
	unsigned int i;
	unsigned errs[3] = { 0 };
	pr_info("read test.\n");
	mmiotrace_printk("Read test.\n");

	for (i = 0; i < 256; i++)
		if (ioread8(p + i) != i)
			++errs[0];

	for (i = 1024; i < (5 * 1024); i += 2)
		if (ioread16(p + i) != v16(i))
			++errs[1];

	for (i = (5 * 1024); i < (16 * 1024); i += 4)
		if (ioread32(p + i) != v32(i))
			++errs[2];

	mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n",
						errs[0], errs[1], errs[2]);
}

static void do_read_far_test(void __iomem *p)
{
	pr_info("read far test.\n");
	mmiotrace_printk("Read far test.\n");

	ioread32(p + read_far);
}

static void do_test(unsigned long size)
{
	void __iomem *p = ioremap(mmio_address, size);
	if (!p) {
		pr_err("could not ioremap, aborting.\n");
		return;
	}
	mmiotrace_printk("ioremap returned %p.\n", p);
	do_write_test(p);
	do_read_test(p);
	if (read_far && read_far < size - 4)
		do_read_far_test(p);
	iounmap(p);
}

/*
 * Tests how mmiotrace behaves in face of multiple ioremap / iounmaps in
 * a short time. We had a bug in deferred freeing procedure which tried
 * to free this region multiple times (ioremap can reuse the same address
 * for many mappings).
 */
static void do_test_bulk_ioremapping(void)
{
	void __iomem *p;
	int i;

	for (i = 0; i < 10; ++i) {
		p = ioremap(mmio_address, PAGE_SIZE);
		if (p)
			iounmap(p);
	}

	/* Force freeing. If it will crash we will know why. */
	synchronize_rcu();
}

static int __init init(void)
{
	unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
	int ret = security_locked_down(LOCKDOWN_MMIOTRACE);

	if (ret)
		return ret;

	if (mmio_address == 0) {
		pr_err("you have to use the module argument mmio_address.\n");
		pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
		return -ENXIO;
	}

	pr_warn("WARNING: mapping %lu kB @ 0x%08lx in PCI address space, "
		"and writing 16 kB of rubbish in there.\n",
		size >> 10, mmio_address);
	do_test(size);
	do_test_bulk_ioremapping();
	pr_info("All done.\n");
	return 0;
}

static void __exit cleanup(void)
{
	pr_debug("unloaded.\n");
}

module_init(init);
module_exit(cleanup);
MODULE_LICENSE("GPL");
