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 */ 21a50445d7SPekka 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 #ifdef CONFIG_MMIOTRACE 38*9e57fb35SPekka Paalanen /* Called from ioremap.c */ 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); 42*9e57fb35SPekka Paalanen 43*9e57fb35SPekka Paalanen /* For anyone to insert markers. Remember trailing newline. */ 44*9e57fb35SPekka Paalanen extern int mmiotrace_printk(const char *fmt, ...) 45*9e57fb35SPekka Paalanen __attribute__ ((format (printf, 1, 2))); 46d61fc448SPekka Paalanen #else 47dee310d0SPekka Paalanen static inline void mmiotrace_ioremap(resource_size_t offset, 48dee310d0SPekka Paalanen unsigned long size, void __iomem *addr) 49d61fc448SPekka Paalanen { 50d61fc448SPekka Paalanen } 51dee310d0SPekka Paalanen 52d61fc448SPekka Paalanen static inline void mmiotrace_iounmap(volatile void __iomem *addr) 53d61fc448SPekka Paalanen { 54d61fc448SPekka Paalanen } 55*9e57fb35SPekka Paalanen 56*9e57fb35SPekka Paalanen static inline int mmiotrace_printk(const char *fmt, ...) 57*9e57fb35SPekka Paalanen __attribute__ ((format (printf, 1, 0))); 58*9e57fb35SPekka Paalanen 59*9e57fb35SPekka Paalanen static inline int mmiotrace_printk(const char *fmt, ...) 60*9e57fb35SPekka Paalanen { 61*9e57fb35SPekka Paalanen return 0; 62*9e57fb35SPekka Paalanen } 63*9e57fb35SPekka Paalanen #endif /* CONFIG_MMIOTRACE */ 64d61fc448SPekka Paalanen 65bd8ac686SPekka Paalanen enum mm_io_opcode { 66bd8ac686SPekka Paalanen MMIO_READ = 0x1, /* struct mmiotrace_rw */ 67bd8ac686SPekka Paalanen MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ 68bd8ac686SPekka Paalanen MMIO_PROBE = 0x3, /* struct mmiotrace_map */ 69bd8ac686SPekka Paalanen MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ 70bd8ac686SPekka Paalanen MMIO_MARKER = 0x5, /* raw char data */ 71bd8ac686SPekka Paalanen MMIO_UNKNOWN_OP = 0x6, /* struct mmiotrace_rw */ 72bd8ac686SPekka Paalanen }; 73bd8ac686SPekka Paalanen 74bd8ac686SPekka Paalanen struct mmiotrace_rw { 75dee310d0SPekka Paalanen resource_size_t phys; /* PCI address of register */ 76bd8ac686SPekka Paalanen unsigned long value; 77bd8ac686SPekka Paalanen unsigned long pc; /* optional program counter */ 78bd8ac686SPekka Paalanen int map_id; 79bd8ac686SPekka Paalanen unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */ 80bd8ac686SPekka Paalanen unsigned char width; /* size of register access in bytes */ 81bd8ac686SPekka Paalanen }; 82bd8ac686SPekka Paalanen 83bd8ac686SPekka Paalanen struct mmiotrace_map { 84dee310d0SPekka Paalanen resource_size_t phys; /* base address in PCI space */ 85bd8ac686SPekka Paalanen unsigned long virt; /* base virtual address */ 86bd8ac686SPekka Paalanen unsigned long len; /* mapping size */ 87bd8ac686SPekka Paalanen int map_id; 88bd8ac686SPekka Paalanen unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */ 89bd8ac686SPekka Paalanen }; 90bd8ac686SPekka Paalanen 91f984b51eSPekka Paalanen /* in kernel/trace/trace_mmiotrace.c */ 92f984b51eSPekka Paalanen extern void enable_mmiotrace(void); 93f984b51eSPekka Paalanen extern void disable_mmiotrace(void); 94bd8ac686SPekka Paalanen extern void mmio_trace_rw(struct mmiotrace_rw *rw); 95bd8ac686SPekka Paalanen extern void mmio_trace_mapping(struct mmiotrace_map *map); 96*9e57fb35SPekka Paalanen extern int mmio_trace_printk(const char *fmt, va_list args); 97f984b51eSPekka Paalanen 988b7d89d0SPekka Paalanen #endif /* MMIOTRACE_H */ 99