18b7d89d0SPekka Paalanen #ifndef MMIOTRACE_H 28b7d89d0SPekka Paalanen #define MMIOTRACE_H 38b7d89d0SPekka Paalanen 4970e6fa0SPekka Paalanen #include <linux/types.h> 50fd0e3daSPekka Paalanen #include <linux/list.h> 60fd0e3daSPekka Paalanen 70fd0e3daSPekka Paalanen struct kmmio_probe; 80fd0e3daSPekka Paalanen struct pt_regs; 90fd0e3daSPekka Paalanen 100fd0e3daSPekka Paalanen typedef void (*kmmio_pre_handler_t)(struct kmmio_probe *, 110fd0e3daSPekka Paalanen struct pt_regs *, unsigned long addr); 120fd0e3daSPekka Paalanen typedef void (*kmmio_post_handler_t)(struct kmmio_probe *, 130fd0e3daSPekka Paalanen unsigned long condition, struct pt_regs *); 140fd0e3daSPekka Paalanen 150fd0e3daSPekka Paalanen struct kmmio_probe { 16d61fc448SPekka Paalanen struct list_head list; /* kmmio internal list */ 170fd0e3daSPekka Paalanen unsigned long addr; /* start location of the probe point */ 180fd0e3daSPekka Paalanen unsigned long len; /* length of the probe region */ 190fd0e3daSPekka Paalanen kmmio_pre_handler_t pre_handler; /* Called before addr is executed. */ 200fd0e3daSPekka Paalanen kmmio_post_handler_t post_handler; /* Called after addr is executed */ 21*a50445d7SPekka Paalanen void *private; 220fd0e3daSPekka Paalanen }; 230fd0e3daSPekka Paalanen 240fd0e3daSPekka Paalanen /* kmmio is active by some kmmio_probes? */ 250fd0e3daSPekka Paalanen static inline int is_kmmio_active(void) 260fd0e3daSPekka Paalanen { 270fd0e3daSPekka Paalanen extern unsigned int kmmio_count; 280fd0e3daSPekka Paalanen return kmmio_count; 290fd0e3daSPekka Paalanen } 300fd0e3daSPekka Paalanen 310fd0e3daSPekka Paalanen extern int register_kmmio_probe(struct kmmio_probe *p); 320fd0e3daSPekka Paalanen extern void unregister_kmmio_probe(struct kmmio_probe *p); 330fd0e3daSPekka Paalanen 340fd0e3daSPekka Paalanen /* Called from page fault handler. */ 350fd0e3daSPekka Paalanen extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); 360fd0e3daSPekka Paalanen 37d61fc448SPekka Paalanen /* Called from ioremap.c */ 38d61fc448SPekka Paalanen #ifdef CONFIG_MMIOTRACE 39dee310d0SPekka Paalanen extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, 40dee310d0SPekka Paalanen void __iomem *addr); 41d61fc448SPekka Paalanen extern void mmiotrace_iounmap(volatile void __iomem *addr); 42d61fc448SPekka Paalanen #else 43dee310d0SPekka Paalanen static inline void mmiotrace_ioremap(resource_size_t offset, 44dee310d0SPekka Paalanen unsigned long size, void __iomem *addr) 45d61fc448SPekka Paalanen { 46d61fc448SPekka Paalanen } 47dee310d0SPekka Paalanen 48d61fc448SPekka Paalanen static inline void mmiotrace_iounmap(volatile void __iomem *addr) 49d61fc448SPekka Paalanen { 50d61fc448SPekka Paalanen } 51d61fc448SPekka Paalanen #endif /* CONFIG_MMIOTRACE_HOOKS */ 52d61fc448SPekka Paalanen 53bd8ac686SPekka Paalanen enum mm_io_opcode { 54bd8ac686SPekka Paalanen MMIO_READ = 0x1, /* struct mmiotrace_rw */ 55bd8ac686SPekka Paalanen MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ 56bd8ac686SPekka Paalanen MMIO_PROBE = 0x3, /* struct mmiotrace_map */ 57bd8ac686SPekka Paalanen MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ 58bd8ac686SPekka Paalanen MMIO_MARKER = 0x5, /* raw char data */ 59bd8ac686SPekka Paalanen MMIO_UNKNOWN_OP = 0x6, /* struct mmiotrace_rw */ 60bd8ac686SPekka Paalanen }; 61bd8ac686SPekka Paalanen 62bd8ac686SPekka Paalanen struct mmiotrace_rw { 63dee310d0SPekka Paalanen resource_size_t phys; /* PCI address of register */ 64bd8ac686SPekka Paalanen unsigned long value; 65bd8ac686SPekka Paalanen unsigned long pc; /* optional program counter */ 66bd8ac686SPekka Paalanen int map_id; 67bd8ac686SPekka Paalanen unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */ 68bd8ac686SPekka Paalanen unsigned char width; /* size of register access in bytes */ 69bd8ac686SPekka Paalanen }; 70bd8ac686SPekka Paalanen 71bd8ac686SPekka Paalanen struct mmiotrace_map { 72dee310d0SPekka Paalanen resource_size_t phys; /* base address in PCI space */ 73bd8ac686SPekka Paalanen unsigned long virt; /* base virtual address */ 74bd8ac686SPekka Paalanen unsigned long len; /* mapping size */ 75bd8ac686SPekka Paalanen int map_id; 76bd8ac686SPekka Paalanen unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */ 77bd8ac686SPekka Paalanen }; 78bd8ac686SPekka Paalanen 79f984b51eSPekka Paalanen /* in kernel/trace/trace_mmiotrace.c */ 80f984b51eSPekka Paalanen extern void enable_mmiotrace(void); 81f984b51eSPekka Paalanen extern void disable_mmiotrace(void); 82bd8ac686SPekka Paalanen extern void mmio_trace_rw(struct mmiotrace_rw *rw); 83bd8ac686SPekka Paalanen extern void mmio_trace_mapping(struct mmiotrace_map *map); 84f984b51eSPekka Paalanen 858b7d89d0SPekka Paalanen #endif /* MMIOTRACE_H */ 86