| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 
|---|
| 2 | #ifndef _LINUX_MMIOTRACE_H | 
|---|
| 3 | #define _LINUX_MMIOTRACE_H | 
|---|
| 4 |  | 
|---|
| 5 | #include <linux/types.h> | 
|---|
| 6 | #include <linux/list.h> | 
|---|
| 7 |  | 
|---|
| 8 | struct kmmio_probe; | 
|---|
| 9 | struct pt_regs; | 
|---|
| 10 |  | 
|---|
| 11 | typedef void (*kmmio_pre_handler_t)(struct kmmio_probe *, | 
|---|
| 12 | struct pt_regs *, unsigned long addr); | 
|---|
| 13 | typedef void (*kmmio_post_handler_t)(struct kmmio_probe *, | 
|---|
| 14 | unsigned long condition, struct pt_regs *); | 
|---|
| 15 |  | 
|---|
| 16 | struct kmmio_probe { | 
|---|
| 17 | /* kmmio internal list: */ | 
|---|
| 18 | struct list_head	list; | 
|---|
| 19 | /* start location of the probe point: */ | 
|---|
| 20 | unsigned long		addr; | 
|---|
| 21 | /* length of the probe region: */ | 
|---|
| 22 | unsigned long		len; | 
|---|
| 23 | /* Called before addr is executed: */ | 
|---|
| 24 | kmmio_pre_handler_t	pre_handler; | 
|---|
| 25 | /* Called after addr is executed: */ | 
|---|
| 26 | kmmio_post_handler_t	post_handler; | 
|---|
| 27 | void			*private; | 
|---|
| 28 | }; | 
|---|
| 29 |  | 
|---|
| 30 | extern unsigned int kmmio_count; | 
|---|
| 31 |  | 
|---|
| 32 | extern int register_kmmio_probe(struct kmmio_probe *p); | 
|---|
| 33 | extern void unregister_kmmio_probe(struct kmmio_probe *p); | 
|---|
| 34 | extern int kmmio_init(void); | 
|---|
| 35 | extern void kmmio_cleanup(void); | 
|---|
| 36 |  | 
|---|
| 37 | #ifdef CONFIG_MMIOTRACE | 
|---|
| 38 | /* kmmio is active by some kmmio_probes? */ | 
|---|
| 39 | static inline int is_kmmio_active(void) | 
|---|
| 40 | { | 
|---|
| 41 | return kmmio_count; | 
|---|
| 42 | } | 
|---|
| 43 |  | 
|---|
| 44 | /* Called from page fault handler. */ | 
|---|
| 45 | extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); | 
|---|
| 46 |  | 
|---|
| 47 | /* Called from ioremap.c */ | 
|---|
| 48 | extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, | 
|---|
| 49 | void __iomem *addr); | 
|---|
| 50 | extern void mmiotrace_iounmap(volatile void __iomem *addr); | 
|---|
| 51 |  | 
|---|
| 52 | /* For anyone to insert markers. Remember trailing newline. */ | 
|---|
| 53 | extern __printf(1, 2) int mmiotrace_printk(const char *fmt, ...); | 
|---|
| 54 | #else /* !CONFIG_MMIOTRACE: */ | 
|---|
| 55 | static inline int is_kmmio_active(void) | 
|---|
| 56 | { | 
|---|
| 57 | return 0; | 
|---|
| 58 | } | 
|---|
| 59 |  | 
|---|
| 60 | static inline int kmmio_handler(struct pt_regs *regs, unsigned long addr) | 
|---|
| 61 | { | 
|---|
| 62 | return 0; | 
|---|
| 63 | } | 
|---|
| 64 |  | 
|---|
| 65 | static inline void mmiotrace_ioremap(resource_size_t offset, | 
|---|
| 66 | unsigned long size, void __iomem *addr) | 
|---|
| 67 | { | 
|---|
| 68 | } | 
|---|
| 69 |  | 
|---|
| 70 | static inline void mmiotrace_iounmap(volatile void __iomem *addr) | 
|---|
| 71 | { | 
|---|
| 72 | } | 
|---|
| 73 |  | 
|---|
| 74 | static inline __printf(1, 2) int mmiotrace_printk(const char *fmt, ...) | 
|---|
| 75 | { | 
|---|
| 76 | return 0; | 
|---|
| 77 | } | 
|---|
| 78 | #endif /* CONFIG_MMIOTRACE */ | 
|---|
| 79 |  | 
|---|
| 80 | enum mm_io_opcode { | 
|---|
| 81 | MMIO_READ	= 0x1,	/* struct mmiotrace_rw */ | 
|---|
| 82 | MMIO_WRITE	= 0x2,	/* struct mmiotrace_rw */ | 
|---|
| 83 | MMIO_PROBE	= 0x3,	/* struct mmiotrace_map */ | 
|---|
| 84 | MMIO_UNPROBE	= 0x4,	/* struct mmiotrace_map */ | 
|---|
| 85 | MMIO_UNKNOWN_OP = 0x5,	/* struct mmiotrace_rw */ | 
|---|
| 86 | }; | 
|---|
| 87 |  | 
|---|
| 88 | struct mmiotrace_rw { | 
|---|
| 89 | resource_size_t	phys;	/* PCI address of register */ | 
|---|
| 90 | unsigned long	value; | 
|---|
| 91 | unsigned long	pc;	/* optional program counter */ | 
|---|
| 92 | int		map_id; | 
|---|
| 93 | unsigned char	opcode;	/* one of MMIO_{READ,WRITE,UNKNOWN_OP} */ | 
|---|
| 94 | unsigned char	width;	/* size of register access in bytes */ | 
|---|
| 95 | }; | 
|---|
| 96 |  | 
|---|
| 97 | struct mmiotrace_map { | 
|---|
| 98 | resource_size_t	phys;	/* base address in PCI space */ | 
|---|
| 99 | unsigned long	virt;	/* base virtual address */ | 
|---|
| 100 | unsigned long	len;	/* mapping size */ | 
|---|
| 101 | int		map_id; | 
|---|
| 102 | unsigned char	opcode;	/* MMIO_PROBE or MMIO_UNPROBE */ | 
|---|
| 103 | }; | 
|---|
| 104 |  | 
|---|
| 105 | /* in kernel/trace/trace_mmiotrace.c */ | 
|---|
| 106 | extern void enable_mmiotrace(void); | 
|---|
| 107 | extern void disable_mmiotrace(void); | 
|---|
| 108 | extern void mmio_trace_rw(struct mmiotrace_rw *rw); | 
|---|
| 109 | extern void mmio_trace_mapping(struct mmiotrace_map *map); | 
|---|
| 110 | extern __printf(1, 0) int mmio_trace_printk(const char *fmt, va_list args); | 
|---|
| 111 |  | 
|---|
| 112 | #endif /* _LINUX_MMIOTRACE_H */ | 
|---|
| 113 |  | 
|---|