0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
0010 #define _PPC_BOOK3S_64_HW_BREAKPOINT_H
0011
0012 #include <asm/cpu_has_feature.h>
0013
0014 #ifdef __KERNEL__
0015 struct arch_hw_breakpoint {
0016 unsigned long address;
0017 u16 type;
0018 u16 len;
0019 u16 hw_len;
0020 u8 flags;
0021 };
0022
0023
0024
0025
0026 #define HW_BRK_TYPE_READ 0x01
0027 #define HW_BRK_TYPE_WRITE 0x02
0028 #define HW_BRK_TYPE_TRANSLATE 0x04
0029 #define HW_BRK_TYPE_USER 0x08
0030 #define HW_BRK_TYPE_KERNEL 0x10
0031 #define HW_BRK_TYPE_HYP 0x20
0032 #define HW_BRK_TYPE_EXTRANEOUS_IRQ 0x80
0033
0034
0035 #define HW_BRK_TYPE_RDWR (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)
0036 #define HW_BRK_TYPE_DABR (HW_BRK_TYPE_RDWR | HW_BRK_TYPE_TRANSLATE)
0037 #define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
0038 HW_BRK_TYPE_HYP)
0039
0040 #define HW_BRK_FLAG_DISABLED 0x1
0041
0042
0043 #ifdef CONFIG_PPC_8xx
0044 #define HW_BREAKPOINT_SIZE 0x4
0045 #else
0046 #define HW_BREAKPOINT_SIZE 0x8
0047 #endif
0048 #define HW_BREAKPOINT_SIZE_QUADWORD 0x10
0049
0050 #define DABR_MAX_LEN 8
0051 #define DAWR_MAX_LEN 512
0052
0053 static inline int nr_wp_slots(void)
0054 {
0055 return cpu_has_feature(CPU_FTR_DAWR1) ? 2 : 1;
0056 }
0057
0058 bool wp_check_constraints(struct pt_regs *regs, ppc_inst_t instr,
0059 unsigned long ea, int type, int size,
0060 struct arch_hw_breakpoint *info);
0061
0062 void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
0063 int *type, int *size, unsigned long *ea);
0064
0065 #ifdef CONFIG_HAVE_HW_BREAKPOINT
0066 #include <linux/kdebug.h>
0067 #include <asm/reg.h>
0068 #include <asm/debug.h>
0069
0070 struct perf_event_attr;
0071 struct perf_event;
0072 struct pmu;
0073 struct perf_sample_data;
0074 struct task_struct;
0075
0076 extern int hw_breakpoint_slots(int type);
0077 extern int arch_bp_generic_fields(int type, int *gen_bp_type);
0078 extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
0079 extern int hw_breakpoint_arch_parse(struct perf_event *bp,
0080 const struct perf_event_attr *attr,
0081 struct arch_hw_breakpoint *hw);
0082 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
0083 unsigned long val, void *data);
0084 int arch_install_hw_breakpoint(struct perf_event *bp);
0085 void arch_uninstall_hw_breakpoint(struct perf_event *bp);
0086 void hw_breakpoint_pmu_read(struct perf_event *bp);
0087 extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
0088
0089 extern struct pmu perf_ops_bp;
0090 extern void ptrace_triggered(struct perf_event *bp,
0091 struct perf_sample_data *data, struct pt_regs *regs);
0092 static inline void hw_breakpoint_disable(void)
0093 {
0094 int i;
0095 struct arch_hw_breakpoint null_brk = {0};
0096
0097 if (!ppc_breakpoint_available())
0098 return;
0099
0100 for (i = 0; i < nr_wp_slots(); i++)
0101 __set_breakpoint(i, &null_brk);
0102 }
0103 extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
0104 int hw_breakpoint_handler(struct die_args *args);
0105
0106 #else
0107 static inline void hw_breakpoint_disable(void) { }
0108 static inline void thread_change_pc(struct task_struct *tsk,
0109 struct pt_regs *regs) { }
0110
0111 #endif
0112
0113
0114 #ifdef CONFIG_PPC_DAWR
0115 extern bool dawr_force_enable;
0116 static inline bool dawr_enabled(void)
0117 {
0118 return dawr_force_enable;
0119 }
0120 int set_dawr(int nr, struct arch_hw_breakpoint *brk);
0121 #else
0122 static inline bool dawr_enabled(void) { return false; }
0123 static inline int set_dawr(int nr, struct arch_hw_breakpoint *brk) { return -1; }
0124 #endif
0125
0126 #endif
0127 #endif