Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * PowerPC BookIII S hardware breakpoint definitions
0004  *
0005  * Copyright 2010, IBM Corporation.
0006  * Author: K.Prasad <prasad@linux.vnet.ibm.com>
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; /* length of the target data symbol */
0019     u16     hw_len; /* length programmed in hw */
0020     u8      flags;
0021 };
0022 
0023 /* Note: Don't change the first 6 bits below as they are in the same order
0024  * as the dabr and dabrx.
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 /* bits that overlap with the bottom 3 bits of the dabr */
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 /* Minimum granularity */
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   /* CONFIG_HAVE_HW_BREAKPOINT */
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  /* CONFIG_HAVE_HW_BREAKPOINT */
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  /* __KERNEL__ */
0127 #endif  /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */