root/arch/arm64/include/asm/hw_breakpoint.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. encode_ctrl_reg
  2. decode_ctrl_reg
  3. hw_breakpoint_thread_switch
  4. ptrace_hw_copy_thread
  5. get_num_brps
  6. get_num_wrps

   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * Copyright (C) 2012 ARM Ltd.
   4  */
   5 #ifndef __ASM_HW_BREAKPOINT_H
   6 #define __ASM_HW_BREAKPOINT_H
   7 
   8 #include <asm/cputype.h>
   9 #include <asm/cpufeature.h>
  10 #include <asm/sysreg.h>
  11 #include <asm/virt.h>
  12 
  13 struct arch_hw_breakpoint_ctrl {
  14         u32 __reserved  : 19,
  15         len             : 8,
  16         type            : 2,
  17         privilege       : 2,
  18         enabled         : 1;
  19 };
  20 
  21 struct arch_hw_breakpoint {
  22         u64 address;
  23         u64 trigger;
  24         struct arch_hw_breakpoint_ctrl ctrl;
  25 };
  26 
  27 /* Privilege Levels */
  28 #define AARCH64_BREAKPOINT_EL1  1
  29 #define AARCH64_BREAKPOINT_EL0  2
  30 
  31 #define DBG_HMC_HYP             (1 << 13)
  32 
  33 static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
  34 {
  35         u32 val = (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
  36                 ctrl.enabled;
  37 
  38         if (is_kernel_in_hyp_mode() && ctrl.privilege == AARCH64_BREAKPOINT_EL1)
  39                 val |= DBG_HMC_HYP;
  40 
  41         return val;
  42 }
  43 
  44 static inline void decode_ctrl_reg(u32 reg,
  45                                    struct arch_hw_breakpoint_ctrl *ctrl)
  46 {
  47         ctrl->enabled   = reg & 0x1;
  48         reg >>= 1;
  49         ctrl->privilege = reg & 0x3;
  50         reg >>= 2;
  51         ctrl->type      = reg & 0x3;
  52         reg >>= 2;
  53         ctrl->len       = reg & 0xff;
  54 }
  55 
  56 /* Breakpoint */
  57 #define ARM_BREAKPOINT_EXECUTE  0
  58 
  59 /* Watchpoints */
  60 #define ARM_BREAKPOINT_LOAD     1
  61 #define ARM_BREAKPOINT_STORE    2
  62 #define AARCH64_ESR_ACCESS_MASK (1 << 6)
  63 
  64 /* Lengths */
  65 #define ARM_BREAKPOINT_LEN_1    0x1
  66 #define ARM_BREAKPOINT_LEN_2    0x3
  67 #define ARM_BREAKPOINT_LEN_3    0x7
  68 #define ARM_BREAKPOINT_LEN_4    0xf
  69 #define ARM_BREAKPOINT_LEN_5    0x1f
  70 #define ARM_BREAKPOINT_LEN_6    0x3f
  71 #define ARM_BREAKPOINT_LEN_7    0x7f
  72 #define ARM_BREAKPOINT_LEN_8    0xff
  73 
  74 /* Kernel stepping */
  75 #define ARM_KERNEL_STEP_NONE    0
  76 #define ARM_KERNEL_STEP_ACTIVE  1
  77 #define ARM_KERNEL_STEP_SUSPEND 2
  78 
  79 /*
  80  * Limits.
  81  * Changing these will require modifications to the register accessors.
  82  */
  83 #define ARM_MAX_BRP             16
  84 #define ARM_MAX_WRP             16
  85 
  86 /* Virtual debug register bases. */
  87 #define AARCH64_DBG_REG_BVR     0
  88 #define AARCH64_DBG_REG_BCR     (AARCH64_DBG_REG_BVR + ARM_MAX_BRP)
  89 #define AARCH64_DBG_REG_WVR     (AARCH64_DBG_REG_BCR + ARM_MAX_BRP)
  90 #define AARCH64_DBG_REG_WCR     (AARCH64_DBG_REG_WVR + ARM_MAX_WRP)
  91 
  92 /* Debug register names. */
  93 #define AARCH64_DBG_REG_NAME_BVR        bvr
  94 #define AARCH64_DBG_REG_NAME_BCR        bcr
  95 #define AARCH64_DBG_REG_NAME_WVR        wvr
  96 #define AARCH64_DBG_REG_NAME_WCR        wcr
  97 
  98 /* Accessor macros for the debug registers. */
  99 #define AARCH64_DBG_READ(N, REG, VAL) do {\
 100         VAL = read_sysreg(dbg##REG##N##_el1);\
 101 } while (0)
 102 
 103 #define AARCH64_DBG_WRITE(N, REG, VAL) do {\
 104         write_sysreg(VAL, dbg##REG##N##_el1);\
 105 } while (0)
 106 
 107 struct task_struct;
 108 struct notifier_block;
 109 struct perf_event_attr;
 110 struct perf_event;
 111 struct pmu;
 112 
 113 extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
 114                                   int *gen_len, int *gen_type, int *offset);
 115 extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 116 extern int hw_breakpoint_arch_parse(struct perf_event *bp,
 117                                     const struct perf_event_attr *attr,
 118                                     struct arch_hw_breakpoint *hw);
 119 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
 120                                            unsigned long val, void *data);
 121 
 122 extern int arch_install_hw_breakpoint(struct perf_event *bp);
 123 extern void arch_uninstall_hw_breakpoint(struct perf_event *bp);
 124 extern void hw_breakpoint_pmu_read(struct perf_event *bp);
 125 extern int hw_breakpoint_slots(int type);
 126 
 127 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 128 extern void hw_breakpoint_thread_switch(struct task_struct *next);
 129 extern void ptrace_hw_copy_thread(struct task_struct *task);
 130 #else
 131 static inline void hw_breakpoint_thread_switch(struct task_struct *next)
 132 {
 133 }
 134 static inline void ptrace_hw_copy_thread(struct task_struct *task)
 135 {
 136 }
 137 #endif
 138 
 139 /* Determine number of BRP registers available. */
 140 static inline int get_num_brps(void)
 141 {
 142         u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
 143         return 1 +
 144                 cpuid_feature_extract_unsigned_field(dfr0,
 145                                                 ID_AA64DFR0_BRPS_SHIFT);
 146 }
 147 
 148 /* Determine number of WRP registers available. */
 149 static inline int get_num_wrps(void)
 150 {
 151         u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
 152         return 1 +
 153                 cpuid_feature_extract_unsigned_field(dfr0,
 154                                                 ID_AA64DFR0_WRPS_SHIFT);
 155 }
 156 
 157 #endif  /* __ASM_BREAKPOINT_H */

/* [<][>][^][v][top][bottom][index][help] */