Merge branches 'topic/slob/cleanups', 'topic/slob/fixes', 'topic/slub/core', 'topic...
[linux-block.git] / arch / x86 / mm / testmmiotrace.c
CommitLineData
8b7d89d0 1/*
fab852aa 2 * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
8b7d89d0
PP
3 */
4#include <linux/module.h>
970e6fa0 5#include <linux/io.h>
9e57fb35 6#include <linux/mmiotrace.h>
8b7d89d0 7
8b7d89d0
PP
8#define MODULE_NAME "testmmiotrace"
9
10static unsigned long mmio_address;
11module_param(mmio_address, ulong, 0);
5ff93697
PP
12MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
13 "(or 8 MB if read_far is non-zero).");
14
15static unsigned long read_far = 0x400100;
16module_param(read_far, ulong, 0);
17MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
18 "(default: 0x400100).");
8b7d89d0 19
fab852aa
PP
20static unsigned v16(unsigned i)
21{
22 return i * 12 + 7;
23}
24
25static unsigned v32(unsigned i)
26{
27 return i * 212371 + 13;
28}
29
8b7d89d0
PP
30static void do_write_test(void __iomem *p)
31{
32 unsigned int i;
5ff93697 33 pr_info(MODULE_NAME ": write test.\n");
9e57fb35 34 mmiotrace_printk("Write test.\n");
fab852aa 35
8b7d89d0
PP
36 for (i = 0; i < 256; i++)
37 iowrite8(i, p + i);
fab852aa 38
8b7d89d0 39 for (i = 1024; i < (5 * 1024); i += 2)
fab852aa
PP
40 iowrite16(v16(i), p + i);
41
8b7d89d0 42 for (i = (5 * 1024); i < (16 * 1024); i += 4)
fab852aa 43 iowrite32(v32(i), p + i);
8b7d89d0
PP
44}
45
46static void do_read_test(void __iomem *p)
47{
48 unsigned int i;
fab852aa 49 unsigned errs[3] = { 0 };
5ff93697 50 pr_info(MODULE_NAME ": read test.\n");
9e57fb35 51 mmiotrace_printk("Read test.\n");
fab852aa 52
8b7d89d0 53 for (i = 0; i < 256; i++)
fab852aa
PP
54 if (ioread8(p + i) != i)
55 ++errs[0];
56
8b7d89d0 57 for (i = 1024; i < (5 * 1024); i += 2)
fab852aa
PP
58 if (ioread16(p + i) != v16(i))
59 ++errs[1];
60
8b7d89d0 61 for (i = (5 * 1024); i < (16 * 1024); i += 4)
fab852aa
PP
62 if (ioread32(p + i) != v32(i))
63 ++errs[2];
64
65 mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n",
66 errs[0], errs[1], errs[2]);
8b7d89d0
PP
67}
68
5ff93697
PP
69static void do_read_far_test(void __iomem *p)
70{
71 pr_info(MODULE_NAME ": read far test.\n");
72 mmiotrace_printk("Read far test.\n");
73
74 ioread32(p + read_far);
75}
76
77static void do_test(unsigned long size)
8b7d89d0 78{
5ff93697 79 void __iomem *p = ioremap_nocache(mmio_address, size);
8b7d89d0 80 if (!p) {
0fd0e3da 81 pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
8b7d89d0
PP
82 return;
83 }
9e57fb35 84 mmiotrace_printk("ioremap returned %p.\n", p);
8b7d89d0
PP
85 do_write_test(p);
86 do_read_test(p);
5ff93697
PP
87 if (read_far && read_far < size - 4)
88 do_read_far_test(p);
d61fc448 89 iounmap(p);
8b7d89d0
PP
90}
91
92static int __init init(void)
93{
5ff93697
PP
94 unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
95
8b7d89d0 96 if (mmio_address == 0) {
0fd0e3da
PP
97 pr_err(MODULE_NAME ": you have to use the module argument "
98 "mmio_address.\n");
99 pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS"
8b7d89d0
PP
100 " YOU REALLY KNOW WHAT YOU ARE DOING!\n");
101 return -ENXIO;
102 }
103
5ff93697
PP
104 pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
105 "address space, and writing 16 kB of rubbish in there.\n",
106 size >> 10, mmio_address);
107 do_test(size);
108 pr_info(MODULE_NAME ": All done.\n");
8b7d89d0
PP
109 return 0;
110}
111
112static void __exit cleanup(void)
113{
0fd0e3da 114 pr_debug(MODULE_NAME ": unloaded.\n");
8b7d89d0
PP
115}
116
117module_init(init);
118module_exit(cleanup);
119MODULE_LICENSE("GPL");