0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007
0008 #include <linux/module.h>
0009 #include <linux/io.h>
0010 #include <linux/mmiotrace.h>
0011 #include <linux/security.h>
0012
0013 static unsigned long mmio_address;
0014 module_param_hw(mmio_address, ulong, iomem, 0);
0015 MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
0016 "(or 8 MB if read_far is non-zero).");
0017
0018 static unsigned long read_far = 0x400100;
0019 module_param(read_far, ulong, 0);
0020 MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
0021 "(default: 0x400100).");
0022
0023 static unsigned v16(unsigned i)
0024 {
0025 return i * 12 + 7;
0026 }
0027
0028 static unsigned v32(unsigned i)
0029 {
0030 return i * 212371 + 13;
0031 }
0032
0033 static void do_write_test(void __iomem *p)
0034 {
0035 unsigned int i;
0036 pr_info("write test.\n");
0037 mmiotrace_printk("Write test.\n");
0038
0039 for (i = 0; i < 256; i++)
0040 iowrite8(i, p + i);
0041
0042 for (i = 1024; i < (5 * 1024); i += 2)
0043 iowrite16(v16(i), p + i);
0044
0045 for (i = (5 * 1024); i < (16 * 1024); i += 4)
0046 iowrite32(v32(i), p + i);
0047 }
0048
0049 static void do_read_test(void __iomem *p)
0050 {
0051 unsigned int i;
0052 unsigned errs[3] = { 0 };
0053 pr_info("read test.\n");
0054 mmiotrace_printk("Read test.\n");
0055
0056 for (i = 0; i < 256; i++)
0057 if (ioread8(p + i) != i)
0058 ++errs[0];
0059
0060 for (i = 1024; i < (5 * 1024); i += 2)
0061 if (ioread16(p + i) != v16(i))
0062 ++errs[1];
0063
0064 for (i = (5 * 1024); i < (16 * 1024); i += 4)
0065 if (ioread32(p + i) != v32(i))
0066 ++errs[2];
0067
0068 mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n",
0069 errs[0], errs[1], errs[2]);
0070 }
0071
0072 static void do_read_far_test(void __iomem *p)
0073 {
0074 pr_info("read far test.\n");
0075 mmiotrace_printk("Read far test.\n");
0076
0077 ioread32(p + read_far);
0078 }
0079
0080 static void do_test(unsigned long size)
0081 {
0082 void __iomem *p = ioremap(mmio_address, size);
0083 if (!p) {
0084 pr_err("could not ioremap, aborting.\n");
0085 return;
0086 }
0087 mmiotrace_printk("ioremap returned %p.\n", p);
0088 do_write_test(p);
0089 do_read_test(p);
0090 if (read_far && read_far < size - 4)
0091 do_read_far_test(p);
0092 iounmap(p);
0093 }
0094
0095
0096
0097
0098
0099
0100
0101 static void do_test_bulk_ioremapping(void)
0102 {
0103 void __iomem *p;
0104 int i;
0105
0106 for (i = 0; i < 10; ++i) {
0107 p = ioremap(mmio_address, PAGE_SIZE);
0108 if (p)
0109 iounmap(p);
0110 }
0111
0112
0113 synchronize_rcu();
0114 }
0115
0116 static int __init init(void)
0117 {
0118 unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
0119 int ret = security_locked_down(LOCKDOWN_MMIOTRACE);
0120
0121 if (ret)
0122 return ret;
0123
0124 if (mmio_address == 0) {
0125 pr_err("you have to use the module argument mmio_address.\n");
0126 pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
0127 return -ENXIO;
0128 }
0129
0130 pr_warn("WARNING: mapping %lu kB @ 0x%08lx in PCI address space, "
0131 "and writing 16 kB of rubbish in there.\n",
0132 size >> 10, mmio_address);
0133 do_test(size);
0134 do_test_bulk_ioremapping();
0135 pr_info("All done.\n");
0136 return 0;
0137 }
0138
0139 static void __exit cleanup(void)
0140 {
0141 pr_debug("unloaded.\n");
0142 }
0143
0144 module_init(init);
0145 module_exit(cleanup);
0146 MODULE_LICENSE("GPL");