1b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar#ifndef _LINUX_MMIOTRACE_H
2b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar#define _LINUX_MMIOTRACE_H
38b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen
4970e6fa03885f32cc43e42cb08c73a5f54cd8bd9Pekka Paalanen#include <linux/types.h>
50fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen#include <linux/list.h>
60fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen
70fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanenstruct kmmio_probe;
80fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanenstruct pt_regs;
90fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen
100fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanentypedef void (*kmmio_pre_handler_t)(struct kmmio_probe *,
110fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen				struct pt_regs *, unsigned long addr);
120fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanentypedef void (*kmmio_post_handler_t)(struct kmmio_probe *,
130fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen				unsigned long condition, struct pt_regs *);
140fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen
150fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanenstruct kmmio_probe {
16b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	/* kmmio internal list: */
17b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	struct list_head	list;
18b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	/* start location of the probe point: */
19b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned long		addr;
20b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	/* length of the probe region: */
21b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned long		len;
22b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	/* Called before addr is executed: */
23b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	kmmio_pre_handler_t	pre_handler;
24b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	/* Called after addr is executed: */
25b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	kmmio_post_handler_t	post_handler;
26b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	void			*private;
270fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen};
280fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen
29b814d41f0987c7648d7ed07471258101c95c026bIngo Molnarextern unsigned int kmmio_count;
30b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar
31b814d41f0987c7648d7ed07471258101c95c026bIngo Molnarextern int register_kmmio_probe(struct kmmio_probe *p);
32b814d41f0987c7648d7ed07471258101c95c026bIngo Molnarextern void unregister_kmmio_probe(struct kmmio_probe *p);
330f9a623dd6c9b5b4dd00c232f29525bfc7a8ecf2Stuart Bennettextern int kmmio_init(void);
340f9a623dd6c9b5b4dd00c232f29525bfc7a8ecf2Stuart Bennettextern void kmmio_cleanup(void);
35b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar
36b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar#ifdef CONFIG_MMIOTRACE
370fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen/* kmmio is active by some kmmio_probes? */
380fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanenstatic inline int is_kmmio_active(void)
390fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen{
400fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen	return kmmio_count;
410fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen}
420fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen
430fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen/* Called from page fault handler. */
440fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanenextern int kmmio_handler(struct pt_regs *regs, unsigned long addr);
450fd0e3da4557c479b820b9a4a7afa25b4637ddf2Pekka Paalanen
469e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen/* Called from ioremap.c */
47dee310d0adf41019aca476052ac3085ff286d9bePekka Paalanenextern void mmiotrace_ioremap(resource_size_t offset, unsigned long size,
48dee310d0adf41019aca476052ac3085ff286d9bePekka Paalanen							void __iomem *addr);
49d61fc44853f46fb002228b18aa5f30db21fcd4acPekka Paalanenextern void mmiotrace_iounmap(volatile void __iomem *addr);
509e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen
519e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen/* For anyone to insert markers. Remember trailing newline. */
52b9075fa968a0a4347aef35e235e2995c0e57ddddJoe Perchesextern __printf(1, 2) int mmiotrace_printk(const char *fmt, ...);
53b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar#else /* !CONFIG_MMIOTRACE: */
54b814d41f0987c7648d7ed07471258101c95c026bIngo Molnarstatic inline int is_kmmio_active(void)
55b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar{
56b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	return 0;
57b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar}
58b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar
59b814d41f0987c7648d7ed07471258101c95c026bIngo Molnarstatic inline int kmmio_handler(struct pt_regs *regs, unsigned long addr)
60b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar{
61b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	return 0;
62b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar}
63b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar
64dee310d0adf41019aca476052ac3085ff286d9bePekka Paalanenstatic inline void mmiotrace_ioremap(resource_size_t offset,
65dee310d0adf41019aca476052ac3085ff286d9bePekka Paalanen					unsigned long size, void __iomem *addr)
66d61fc44853f46fb002228b18aa5f30db21fcd4acPekka Paalanen{
67d61fc44853f46fb002228b18aa5f30db21fcd4acPekka Paalanen}
68dee310d0adf41019aca476052ac3085ff286d9bePekka Paalanen
69d61fc44853f46fb002228b18aa5f30db21fcd4acPekka Paalanenstatic inline void mmiotrace_iounmap(volatile void __iomem *addr)
70d61fc44853f46fb002228b18aa5f30db21fcd4acPekka Paalanen{
71d61fc44853f46fb002228b18aa5f30db21fcd4acPekka Paalanen}
729e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen
73b9075fa968a0a4347aef35e235e2995c0e57ddddJoe Perchesstatic inline __printf(1, 2) int mmiotrace_printk(const char *fmt, ...)
749e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen{
759e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen	return 0;
769e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen}
779e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanen#endif /* CONFIG_MMIOTRACE */
78d61fc44853f46fb002228b18aa5f30db21fcd4acPekka Paalanen
79bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanenenum mm_io_opcode {
80b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	MMIO_READ	= 0x1,	/* struct mmiotrace_rw */
81b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	MMIO_WRITE	= 0x2,	/* struct mmiotrace_rw */
82b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	MMIO_PROBE	= 0x3,	/* struct mmiotrace_map */
83b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	MMIO_UNPROBE	= 0x4,	/* struct mmiotrace_map */
84b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	MMIO_UNKNOWN_OP = 0x5,	/* struct mmiotrace_rw */
858b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen};
868b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen
87bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanenstruct mmiotrace_rw {
88b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	resource_size_t	phys;	/* PCI address of register */
89b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned long	value;
90b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned long	pc;	/* optional program counter */
91b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	int		map_id;
92b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned char	opcode;	/* one of MMIO_{READ,WRITE,UNKNOWN_OP} */
93b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned char	width;	/* size of register access in bytes */
948b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen};
958b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen
96bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanenstruct mmiotrace_map {
97b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	resource_size_t	phys;	/* base address in PCI space */
98b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned long	virt;	/* base virtual address */
99b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned long	len;	/* mapping size */
100b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	int		map_id;
101b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar	unsigned char	opcode;	/* MMIO_PROBE or MMIO_UNPROBE */
1028b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen};
1038b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen
104bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanen/* in kernel/trace/trace_mmiotrace.c */
105bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanenextern void enable_mmiotrace(void);
106bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanenextern void disable_mmiotrace(void);
107bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanenextern void mmio_trace_rw(struct mmiotrace_rw *rw);
108bd8ac686c73c7e925fcfe0b02dc4e7b947127864Pekka Paalanenextern void mmio_trace_mapping(struct mmiotrace_map *map);
1099e57fb35d711331a9b1410c5c56ebeb3733428a0Pekka Paalanenextern int mmio_trace_printk(const char *fmt, va_list args);
1108b7d89d02ef3c6a7c73d6596f28cea7632850af4Pekka Paalanen
111b814d41f0987c7648d7ed07471258101c95c026bIngo Molnar#endif /* _LINUX_MMIOTRACE_H */
112