Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_MMIOTRACE_H
0003 #define _LINUX_MMIOTRACE_H
0004 
0005 #include <linux/types.h>
0006 #include <linux/list.h>
0007 
0008 struct kmmio_probe;
0009 struct pt_regs;
0010 
0011 typedef void (*kmmio_pre_handler_t)(struct kmmio_probe *,
0012                 struct pt_regs *, unsigned long addr);
0013 typedef void (*kmmio_post_handler_t)(struct kmmio_probe *,
0014                 unsigned long condition, struct pt_regs *);
0015 
0016 struct kmmio_probe {
0017     /* kmmio internal list: */
0018     struct list_head    list;
0019     /* start location of the probe point: */
0020     unsigned long       addr;
0021     /* length of the probe region: */
0022     unsigned long       len;
0023     /* Called before addr is executed: */
0024     kmmio_pre_handler_t pre_handler;
0025     /* Called after addr is executed: */
0026     kmmio_post_handler_t    post_handler;
0027     void            *private;
0028 };
0029 
0030 extern unsigned int kmmio_count;
0031 
0032 extern int register_kmmio_probe(struct kmmio_probe *p);
0033 extern void unregister_kmmio_probe(struct kmmio_probe *p);
0034 extern int kmmio_init(void);
0035 extern void kmmio_cleanup(void);
0036 
0037 #ifdef CONFIG_MMIOTRACE
0038 /* kmmio is active by some kmmio_probes? */
0039 static inline int is_kmmio_active(void)
0040 {
0041     return kmmio_count;
0042 }
0043 
0044 /* Called from page fault handler. */
0045 extern int kmmio_handler(struct pt_regs *regs, unsigned long addr);
0046 
0047 /* Called from ioremap.c */
0048 extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size,
0049                             void __iomem *addr);
0050 extern void mmiotrace_iounmap(volatile void __iomem *addr);
0051 
0052 /* For anyone to insert markers. Remember trailing newline. */
0053 extern __printf(1, 2) int mmiotrace_printk(const char *fmt, ...);
0054 #else /* !CONFIG_MMIOTRACE: */
0055 static inline int is_kmmio_active(void)
0056 {
0057     return 0;
0058 }
0059 
0060 static inline int kmmio_handler(struct pt_regs *regs, unsigned long addr)
0061 {
0062     return 0;
0063 }
0064 
0065 static inline void mmiotrace_ioremap(resource_size_t offset,
0066                     unsigned long size, void __iomem *addr)
0067 {
0068 }
0069 
0070 static inline void mmiotrace_iounmap(volatile void __iomem *addr)
0071 {
0072 }
0073 
0074 static inline __printf(1, 2) int mmiotrace_printk(const char *fmt, ...)
0075 {
0076     return 0;
0077 }
0078 #endif /* CONFIG_MMIOTRACE */
0079 
0080 enum mm_io_opcode {
0081     MMIO_READ   = 0x1,  /* struct mmiotrace_rw */
0082     MMIO_WRITE  = 0x2,  /* struct mmiotrace_rw */
0083     MMIO_PROBE  = 0x3,  /* struct mmiotrace_map */
0084     MMIO_UNPROBE    = 0x4,  /* struct mmiotrace_map */
0085     MMIO_UNKNOWN_OP = 0x5,  /* struct mmiotrace_rw */
0086 };
0087 
0088 struct mmiotrace_rw {
0089     resource_size_t phys;   /* PCI address of register */
0090     unsigned long   value;
0091     unsigned long   pc; /* optional program counter */
0092     int     map_id;
0093     unsigned char   opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */
0094     unsigned char   width;  /* size of register access in bytes */
0095 };
0096 
0097 struct mmiotrace_map {
0098     resource_size_t phys;   /* base address in PCI space */
0099     unsigned long   virt;   /* base virtual address */
0100     unsigned long   len;    /* mapping size */
0101     int     map_id;
0102     unsigned char   opcode; /* MMIO_PROBE or MMIO_UNPROBE */
0103 };
0104 
0105 /* in kernel/trace/trace_mmiotrace.c */
0106 extern void enable_mmiotrace(void);
0107 extern void disable_mmiotrace(void);
0108 extern void mmio_trace_rw(struct mmiotrace_rw *rw);
0109 extern void mmio_trace_mapping(struct mmiotrace_map *map);
0110 extern __printf(1, 0) int mmio_trace_printk(const char *fmt, va_list args);
0111 
0112 #endif /* _LINUX_MMIOTRACE_H */