xref: /linux/include/linux/mmiotrace.h (revision 0fd0e3da4557c479b820b9a4a7afa25b4637ddf2)
18b7d89d0SPekka Paalanen #ifndef MMIOTRACE_H
28b7d89d0SPekka Paalanen #define MMIOTRACE_H
38b7d89d0SPekka Paalanen 
48b7d89d0SPekka Paalanen #include <asm/types.h>
58b7d89d0SPekka Paalanen 
6*0fd0e3daSPekka Paalanen #ifdef __KERNEL__
7*0fd0e3daSPekka Paalanen 
8*0fd0e3daSPekka Paalanen #include <linux/list.h>
9*0fd0e3daSPekka Paalanen 
10*0fd0e3daSPekka Paalanen struct kmmio_probe;
11*0fd0e3daSPekka Paalanen struct pt_regs;
12*0fd0e3daSPekka Paalanen 
13*0fd0e3daSPekka Paalanen typedef void (*kmmio_pre_handler_t)(struct kmmio_probe *,
14*0fd0e3daSPekka Paalanen 				struct pt_regs *, unsigned long addr);
15*0fd0e3daSPekka Paalanen typedef void (*kmmio_post_handler_t)(struct kmmio_probe *,
16*0fd0e3daSPekka Paalanen 				unsigned long condition, struct pt_regs *);
17*0fd0e3daSPekka Paalanen 
18*0fd0e3daSPekka Paalanen struct kmmio_probe {
19*0fd0e3daSPekka Paalanen 	struct list_head list;
20*0fd0e3daSPekka Paalanen 	unsigned long addr; /* start location of the probe point */
21*0fd0e3daSPekka Paalanen 	unsigned long len; /* length of the probe region */
22*0fd0e3daSPekka Paalanen 	kmmio_pre_handler_t pre_handler; /* Called before addr is executed. */
23*0fd0e3daSPekka Paalanen 	kmmio_post_handler_t post_handler; /* Called after addr is executed */
24*0fd0e3daSPekka Paalanen };
25*0fd0e3daSPekka Paalanen 
26*0fd0e3daSPekka Paalanen /* kmmio is active by some kmmio_probes? */
27*0fd0e3daSPekka Paalanen static inline int is_kmmio_active(void)
28*0fd0e3daSPekka Paalanen {
29*0fd0e3daSPekka Paalanen 	extern unsigned int kmmio_count;
30*0fd0e3daSPekka Paalanen 	return kmmio_count;
31*0fd0e3daSPekka Paalanen }
32*0fd0e3daSPekka Paalanen 
33*0fd0e3daSPekka Paalanen extern void reference_kmmio(void);
34*0fd0e3daSPekka Paalanen extern void unreference_kmmio(void);
35*0fd0e3daSPekka Paalanen extern int register_kmmio_probe(struct kmmio_probe *p);
36*0fd0e3daSPekka Paalanen extern void unregister_kmmio_probe(struct kmmio_probe *p);
37*0fd0e3daSPekka Paalanen 
38*0fd0e3daSPekka Paalanen /* Called from page fault handler. */
39*0fd0e3daSPekka Paalanen extern int kmmio_handler(struct pt_regs *regs, unsigned long addr);
40*0fd0e3daSPekka Paalanen 
41*0fd0e3daSPekka Paalanen #endif /* __KERNEL__ */
42*0fd0e3daSPekka Paalanen 
43*0fd0e3daSPekka Paalanen 
4463ffa3e4SPekka Paalanen /*
4563ffa3e4SPekka Paalanen  * If you change anything here, you must bump MMIO_VERSION.
4663ffa3e4SPekka Paalanen  * This is the relay data format for user space.
4763ffa3e4SPekka Paalanen  */
488b7d89d0SPekka Paalanen #define MMIO_VERSION 0x04
498b7d89d0SPekka Paalanen 
508b7d89d0SPekka Paalanen /* mm_io_header.type */
518b7d89d0SPekka Paalanen #define MMIO_OPCODE_MASK 0xff
528b7d89d0SPekka Paalanen #define MMIO_OPCODE_SHIFT 0
538b7d89d0SPekka Paalanen #define MMIO_WIDTH_MASK 0xff00
548b7d89d0SPekka Paalanen #define MMIO_WIDTH_SHIFT 8
558b7d89d0SPekka Paalanen #define MMIO_MAGIC (0x6f000000 | (MMIO_VERSION<<16))
568b7d89d0SPekka Paalanen #define MMIO_MAGIC_MASK 0xffff0000
578b7d89d0SPekka Paalanen 
588b7d89d0SPekka Paalanen enum mm_io_opcode {          /* payload type: */
598b7d89d0SPekka Paalanen 	MMIO_READ = 0x1,     /* struct mm_io_rw */
608b7d89d0SPekka Paalanen 	MMIO_WRITE = 0x2,    /* struct mm_io_rw */
618b7d89d0SPekka Paalanen 	MMIO_PROBE = 0x3,    /* struct mm_io_map */
628b7d89d0SPekka Paalanen 	MMIO_UNPROBE = 0x4,  /* struct mm_io_map */
638b7d89d0SPekka Paalanen 	MMIO_MARKER = 0x5,   /* raw char data */
648b7d89d0SPekka Paalanen 	MMIO_UNKNOWN_OP = 0x6, /* struct mm_io_rw */
658b7d89d0SPekka Paalanen };
668b7d89d0SPekka Paalanen 
678b7d89d0SPekka Paalanen struct mm_io_header {
6863ffa3e4SPekka Paalanen 	__u32 type;     /* see MMIO_* macros above */
698b7d89d0SPekka Paalanen 	__u32 sec;      /* timestamp */
708b7d89d0SPekka Paalanen 	__u32 nsec;
718b7d89d0SPekka Paalanen 	__u32 pid;      /* PID of the process, or 0 for kernel core */
728b7d89d0SPekka Paalanen 	__u16 data_len; /* length of the following payload */
738b7d89d0SPekka Paalanen };
748b7d89d0SPekka Paalanen 
758b7d89d0SPekka Paalanen struct mm_io_rw {
768b7d89d0SPekka Paalanen 	__u64 address; /* virtual address of register */
778b7d89d0SPekka Paalanen 	__u64 value;
788b7d89d0SPekka Paalanen 	__u64 pc;      /* optional program counter */
798b7d89d0SPekka Paalanen };
808b7d89d0SPekka Paalanen 
818b7d89d0SPekka Paalanen struct mm_io_map {
828b7d89d0SPekka Paalanen 	__u64 phys;  /* base address in PCI space */
838b7d89d0SPekka Paalanen 	__u64 addr;  /* base virtual address */
848b7d89d0SPekka Paalanen 	__u64 len;   /* mapping size */
858b7d89d0SPekka Paalanen 	__u64 pc;    /* optional program counter */
868b7d89d0SPekka Paalanen };
878b7d89d0SPekka Paalanen 
888b7d89d0SPekka Paalanen 
898b7d89d0SPekka Paalanen /*
908b7d89d0SPekka Paalanen  * These structures are used to allow a single relay_write()
918b7d89d0SPekka Paalanen  * call to write a full packet.
928b7d89d0SPekka Paalanen  */
938b7d89d0SPekka Paalanen 
948b7d89d0SPekka Paalanen struct mm_io_header_rw {
958b7d89d0SPekka Paalanen 	struct mm_io_header header;
968b7d89d0SPekka Paalanen 	struct mm_io_rw rw;
978b7d89d0SPekka Paalanen } __attribute__((packed));
988b7d89d0SPekka Paalanen 
998b7d89d0SPekka Paalanen struct mm_io_header_map {
1008b7d89d0SPekka Paalanen 	struct mm_io_header header;
1018b7d89d0SPekka Paalanen 	struct mm_io_map map;
1028b7d89d0SPekka Paalanen } __attribute__((packed));
1038b7d89d0SPekka Paalanen 
1048b7d89d0SPekka Paalanen #endif /* MMIOTRACE_H */
105