12 #include <linux/kernel.h>
14 #include <linux/bitops.h>
16 #include <linux/module.h>
18 #include <asm/mmu_context.h>
19 #include <asm/uaccess.h>
23 #define TRAPPED_PAGES_MAX 16
25 #ifdef CONFIG_HAS_IOPORT
29 #ifdef CONFIG_HAS_IOMEM
39 trapped_io_disable = 1;
42 __setup(
"noiotrap", trapped_io_setup);
55 if ((
unsigned long)tiop & (
PAGE_SIZE - 1))
65 if (hweight_long(
flags) != 1)
73 for (k = 0; k <
n; k++)
83 pr_info(
"trapped io 0x%08lx overrides %s 0x%08lx\n",
86 (
unsigned long)res->
start);
91 INIT_LIST_HEAD(&tiop->
list);
92 spin_lock_irq(&trapped_lock);
93 #ifdef CONFIG_HAS_IOPORT
97 #ifdef CONFIG_HAS_IOMEM
99 list_add(&tiop->
list, &trapped_mem);
101 spin_unlock_irq(&trapped_lock);
105 pr_warning(
"unable to install trapped io filter\n");
125 if (res->
start == offset) {
126 spin_unlock_irqrestore(&trapped_lock, flags);
130 len = resource_size(res);
134 spin_unlock_irqrestore(&trapped_lock, flags);
165 static unsigned long lookup_address(
struct trapped_io *tiop,
166 unsigned long address)
176 if (address < (vaddr + len))
183 static unsigned long long copy_word(
unsigned long src_addr,
int src_len,
184 unsigned long dst_addr,
int dst_len)
186 unsigned long long tmp = 0;
221 static unsigned long from_device(
void *
dst,
const void *
src,
unsigned long cnt)
224 unsigned long src_addr = (
unsigned long)src;
225 unsigned long long tmp;
227 pr_debug(
"trapped io read 0x%08lx (%ld)\n", src_addr, cnt);
228 tiop = lookup_tiop(src_addr);
231 src_addr = lookup_address(tiop, src_addr);
235 tmp = copy_word(src_addr,
236 max_t(
unsigned long, cnt,
238 (
unsigned long)dst, cnt);
240 pr_debug(
"trapped io read 0x%08lx -> 0x%08llx\n", src_addr, tmp);
244 static unsigned long to_device(
void *dst,
const void *src,
unsigned long cnt)
247 unsigned long dst_addr = (
unsigned long)dst;
248 unsigned long long tmp;
250 pr_debug(
"trapped io write 0x%08lx (%ld)\n", dst_addr, cnt);
251 tiop = lookup_tiop(dst_addr);
254 dst_addr = lookup_address(tiop, dst_addr);
258 tmp = copy_word((
unsigned long)src, cnt,
259 dst_addr,
max_t(
unsigned long, cnt,
262 pr_debug(
"trapped io write 0x%08lx -> 0x%08llx\n", dst_addr, tmp);
266 static struct mem_access trapped_io_access = {
277 if (trapped_io_disable)
279 if (!lookup_tiop(address))
287 sizeof(instruction))) {
293 &trapped_io_access, 1, address);