Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.11 147 lines 3.9 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2022-2023 Loongson Technology Corporation Limited 4 */ 5#ifndef __ASM_HW_BREAKPOINT_H 6#define __ASM_HW_BREAKPOINT_H 7 8#include <asm/loongarch.h> 9 10#ifdef __KERNEL__ 11 12/* Breakpoint */ 13#define LOONGARCH_BREAKPOINT_EXECUTE (0 << 0) 14 15/* Watchpoints */ 16#define LOONGARCH_BREAKPOINT_LOAD (1 << 0) 17#define LOONGARCH_BREAKPOINT_STORE (1 << 1) 18 19struct arch_hw_breakpoint_ctrl { 20 u32 __reserved : 28, 21 len : 2, 22 type : 2; 23}; 24 25struct arch_hw_breakpoint { 26 u64 address; 27 u64 mask; 28 struct arch_hw_breakpoint_ctrl ctrl; 29}; 30 31/* Lengths */ 32#define LOONGARCH_BREAKPOINT_LEN_1 0b11 33#define LOONGARCH_BREAKPOINT_LEN_2 0b10 34#define LOONGARCH_BREAKPOINT_LEN_4 0b01 35#define LOONGARCH_BREAKPOINT_LEN_8 0b00 36 37/* 38 * Limits. 39 * Changing these will require modifications to the register accessors. 40 */ 41#define LOONGARCH_MAX_BRP 8 42#define LOONGARCH_MAX_WRP 8 43 44/* Virtual debug register bases. */ 45#define CSR_CFG_ADDR 0 46#define CSR_CFG_MASK (CSR_CFG_ADDR + LOONGARCH_MAX_BRP) 47#define CSR_CFG_CTRL (CSR_CFG_MASK + LOONGARCH_MAX_BRP) 48#define CSR_CFG_ASID (CSR_CFG_CTRL + LOONGARCH_MAX_WRP) 49 50/* Debug register names. */ 51#define LOONGARCH_CSR_NAME_ADDR ADDR 52#define LOONGARCH_CSR_NAME_MASK MASK 53#define LOONGARCH_CSR_NAME_CTRL CTRL 54#define LOONGARCH_CSR_NAME_ASID ASID 55 56/* Accessor macros for the debug registers. */ 57#define LOONGARCH_CSR_WATCH_READ(N, REG, T, VAL) \ 58do { \ 59 if (T == 0) \ 60 VAL = csr_read64(LOONGARCH_CSR_##IB##N##REG); \ 61 else \ 62 VAL = csr_read64(LOONGARCH_CSR_##DB##N##REG); \ 63} while (0) 64 65#define LOONGARCH_CSR_WATCH_WRITE(N, REG, T, VAL) \ 66do { \ 67 if (T == 0) \ 68 csr_write64(VAL, LOONGARCH_CSR_##IB##N##REG); \ 69 else \ 70 csr_write64(VAL, LOONGARCH_CSR_##DB##N##REG); \ 71} while (0) 72 73/* Exact number */ 74#define CSR_FWPC_NUM 0x3f 75#define CSR_MWPC_NUM 0x3f 76 77#define CTRL_PLV_ENABLE 0x1e 78#define CTRL_PLV0_ENABLE 0x02 79#define CTRL_PLV3_ENABLE 0x10 80 81#define MWPnCFG3_LoadEn 8 82#define MWPnCFG3_StoreEn 9 83 84#define MWPnCFG3_Type_mask 0x3 85#define MWPnCFG3_Size_mask 0x3 86 87static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) 88{ 89 return (ctrl.len << 10) | (ctrl.type << 8); 90} 91 92static inline void decode_ctrl_reg(u32 reg, struct arch_hw_breakpoint_ctrl *ctrl) 93{ 94 reg >>= 8; 95 ctrl->type = reg & MWPnCFG3_Type_mask; 96 reg >>= 2; 97 ctrl->len = reg & MWPnCFG3_Size_mask; 98} 99 100struct task_struct; 101struct notifier_block; 102struct perf_event; 103struct perf_event_attr; 104 105extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, 106 int *gen_len, int *gen_type); 107extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw); 108extern int hw_breakpoint_arch_parse(struct perf_event *bp, 109 const struct perf_event_attr *attr, 110 struct arch_hw_breakpoint *hw); 111extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, 112 unsigned long val, void *data); 113 114extern int arch_install_hw_breakpoint(struct perf_event *bp); 115extern void arch_uninstall_hw_breakpoint(struct perf_event *bp); 116extern int hw_breakpoint_slots(int type); 117extern void hw_breakpoint_pmu_read(struct perf_event *bp); 118 119void breakpoint_handler(struct pt_regs *regs); 120void watchpoint_handler(struct pt_regs *regs); 121 122#ifdef CONFIG_HAVE_HW_BREAKPOINT 123extern void ptrace_hw_copy_thread(struct task_struct *task); 124extern void hw_breakpoint_thread_switch(struct task_struct *next); 125#else 126static inline void ptrace_hw_copy_thread(struct task_struct *task) 127{ 128} 129static inline void hw_breakpoint_thread_switch(struct task_struct *next) 130{ 131} 132#endif 133 134/* Determine number of BRP registers available. */ 135static inline int get_num_brps(void) 136{ 137 return csr_read64(LOONGARCH_CSR_FWPC) & CSR_FWPC_NUM; 138} 139 140/* Determine number of WRP registers available. */ 141static inline int get_num_wrps(void) 142{ 143 return csr_read64(LOONGARCH_CSR_MWPC) & CSR_MWPC_NUM; 144} 145 146#endif /* __KERNEL__ */ 147#endif /* __ASM_BREAKPOINT_H */