1b814d41fSIngo Molnar #ifndef _LINUX_MMIOTRACE_H 2b814d41fSIngo Molnar #define _LINUX_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 { 16b814d41fSIngo Molnar /* kmmio internal list: */ 17b814d41fSIngo Molnar struct list_head list; 18b814d41fSIngo Molnar /* start location of the probe point: */ 19b814d41fSIngo Molnar unsigned long addr; 20b814d41fSIngo Molnar /* length of the probe region: */ 21b814d41fSIngo Molnar unsigned long len; 22b814d41fSIngo Molnar /* Called before addr is executed: */ 23b814d41fSIngo Molnar kmmio_pre_handler_t pre_handler; 24b814d41fSIngo Molnar /* Called after addr is executed: */ 25b814d41fSIngo Molnar kmmio_post_handler_t post_handler; 26a50445d7SPekka Paalanen void *private; 270fd0e3daSPekka Paalanen }; 280fd0e3daSPekka Paalanen 290fd0e3daSPekka Paalanen extern unsigned int kmmio_count; 300fd0e3daSPekka Paalanen 310fd0e3daSPekka Paalanen extern int register_kmmio_probe(struct kmmio_probe *p); 320fd0e3daSPekka Paalanen extern void unregister_kmmio_probe(struct kmmio_probe *p); 330f9a623dSStuart Bennett extern int kmmio_init(void); 340f9a623dSStuart Bennett extern void kmmio_cleanup(void); 350fd0e3daSPekka Paalanen 36b814d41fSIngo Molnar #ifdef CONFIG_MMIOTRACE 37b814d41fSIngo Molnar /* kmmio is active by some kmmio_probes? */ 38b814d41fSIngo Molnar static inline int is_kmmio_active(void) 39b814d41fSIngo Molnar { 40b814d41fSIngo Molnar return kmmio_count; 41b814d41fSIngo Molnar } 42b814d41fSIngo Molnar 430fd0e3daSPekka Paalanen /* Called from page fault handler. */ 440fd0e3daSPekka Paalanen extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); 450fd0e3daSPekka Paalanen 469e57fb35SPekka Paalanen /* Called from ioremap.c */ 47dee310d0SPekka Paalanen extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, 48dee310d0SPekka Paalanen void __iomem *addr); 49d61fc448SPekka Paalanen extern void mmiotrace_iounmap(volatile void __iomem *addr); 509e57fb35SPekka Paalanen 519e57fb35SPekka Paalanen /* For anyone to insert markers. Remember trailing newline. */ 52b9075fa9SJoe Perches extern __printf(1, 2) int mmiotrace_printk(const char *fmt, ...); 53b814d41fSIngo Molnar #else /* !CONFIG_MMIOTRACE: */ 54b814d41fSIngo Molnar static inline int is_kmmio_active(void) 55b814d41fSIngo Molnar { 56b814d41fSIngo Molnar return 0; 57b814d41fSIngo Molnar } 58b814d41fSIngo Molnar 59b814d41fSIngo Molnar static inline int kmmio_handler(struct pt_regs *regs, unsigned long addr) 60b814d41fSIngo Molnar { 61b814d41fSIngo Molnar return 0; 62b814d41fSIngo Molnar } 63b814d41fSIngo Molnar 64dee310d0SPekka Paalanen static inline void mmiotrace_ioremap(resource_size_t offset, 65dee310d0SPekka Paalanen unsigned long size, void __iomem *addr) 66d61fc448SPekka Paalanen { 67d61fc448SPekka Paalanen } 68dee310d0SPekka Paalanen 69d61fc448SPekka Paalanen static inline void mmiotrace_iounmap(volatile void __iomem *addr) 70d61fc448SPekka Paalanen { 71d61fc448SPekka Paalanen } 729e57fb35SPekka Paalanen 73b9075fa9SJoe Perches static inline __printf(1, 2) int mmiotrace_printk(const char *fmt, ...) 749e57fb35SPekka Paalanen { 759e57fb35SPekka Paalanen return 0; 769e57fb35SPekka Paalanen } 779e57fb35SPekka Paalanen #endif /* CONFIG_MMIOTRACE */ 78d61fc448SPekka Paalanen 79bd8ac686SPekka Paalanen enum mm_io_opcode { 80bd8ac686SPekka Paalanen MMIO_READ = 0x1, /* struct mmiotrace_rw */ 81bd8ac686SPekka Paalanen MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ 82bd8ac686SPekka Paalanen MMIO_PROBE = 0x3, /* struct mmiotrace_map */ 83bd8ac686SPekka Paalanen MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ 8444274141SPekka Paalanen MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */ 85bd8ac686SPekka Paalanen }; 86bd8ac686SPekka Paalanen 87bd8ac686SPekka Paalanen struct mmiotrace_rw { 88dee310d0SPekka Paalanen resource_size_t phys; /* PCI address of register */ 89bd8ac686SPekka Paalanen unsigned long value; 90bd8ac686SPekka Paalanen unsigned long pc; /* optional program counter */ 91bd8ac686SPekka Paalanen int map_id; 92bd8ac686SPekka Paalanen unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */ 93bd8ac686SPekka Paalanen unsigned char width; /* size of register access in bytes */ 94bd8ac686SPekka Paalanen }; 95bd8ac686SPekka Paalanen 96bd8ac686SPekka Paalanen struct mmiotrace_map { 97dee310d0SPekka Paalanen resource_size_t phys; /* base address in PCI space */ 98bd8ac686SPekka Paalanen unsigned long virt; /* base virtual address */ 99bd8ac686SPekka Paalanen unsigned long len; /* mapping size */ 100bd8ac686SPekka Paalanen int map_id; 101bd8ac686SPekka Paalanen unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */ 102bd8ac686SPekka Paalanen }; 103bd8ac686SPekka Paalanen 104f984b51eSPekka Paalanen /* in kernel/trace/trace_mmiotrace.c */ 105f984b51eSPekka Paalanen extern void enable_mmiotrace(void); 106f984b51eSPekka Paalanen extern void disable_mmiotrace(void); 107bd8ac686SPekka Paalanen extern void mmio_trace_rw(struct mmiotrace_rw *rw); 108bd8ac686SPekka Paalanen extern void mmio_trace_mapping(struct mmiotrace_map *map); 109*8db14860SNicolas Iooss extern __printf(1, 0) int mmio_trace_printk(const char *fmt, va_list args); 110f984b51eSPekka Paalanen 111b814d41fSIngo Molnar #endif /* _LINUX_MMIOTRACE_H */ 112