xref: /OK3568_Linux_fs/kernel/arch/arm64/include/asm/debug-monitors.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2012 ARM Ltd.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun #ifndef __ASM_DEBUG_MONITORS_H
6*4882a593Smuzhiyun #define __ASM_DEBUG_MONITORS_H
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/errno.h>
9*4882a593Smuzhiyun #include <linux/types.h>
10*4882a593Smuzhiyun #include <asm/brk-imm.h>
11*4882a593Smuzhiyun #include <asm/esr.h>
12*4882a593Smuzhiyun #include <asm/insn.h>
13*4882a593Smuzhiyun #include <asm/ptrace.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /* Low-level stepping controls. */
16*4882a593Smuzhiyun #define DBG_MDSCR_SS		(1 << 0)
17*4882a593Smuzhiyun #define DBG_SPSR_SS		(1 << 21)
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* MDSCR_EL1 enabling bits */
20*4882a593Smuzhiyun #define DBG_MDSCR_KDE		(1 << 13)
21*4882a593Smuzhiyun #define DBG_MDSCR_MDE		(1 << 15)
22*4882a593Smuzhiyun #define DBG_MDSCR_MASK		~(DBG_MDSCR_KDE | DBG_MDSCR_MDE)
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define	DBG_ESR_EVT(x)		(((x) >> 27) & 0x7)
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /* AArch64 */
27*4882a593Smuzhiyun #define DBG_ESR_EVT_HWBP	0x0
28*4882a593Smuzhiyun #define DBG_ESR_EVT_HWSS	0x1
29*4882a593Smuzhiyun #define DBG_ESR_EVT_HWWP	0x2
30*4882a593Smuzhiyun #define DBG_ESR_EVT_BRK		0x6
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /*
33*4882a593Smuzhiyun  * Break point instruction encoding
34*4882a593Smuzhiyun  */
35*4882a593Smuzhiyun #define BREAK_INSTR_SIZE		AARCH64_INSN_SIZE
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /*
38*4882a593Smuzhiyun  * BRK instruction encoding
39*4882a593Smuzhiyun  * The #imm16 value should be placed at bits[20:5] within BRK ins
40*4882a593Smuzhiyun  */
41*4882a593Smuzhiyun #define AARCH64_BREAK_MON	0xd4200000
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /*
44*4882a593Smuzhiyun  * BRK instruction for provoking a fault on purpose
45*4882a593Smuzhiyun  * Unlike kgdb, #imm16 value with unallocated handler is used for faulting.
46*4882a593Smuzhiyun  */
47*4882a593Smuzhiyun #define AARCH64_BREAK_FAULT	(AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5))
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define AARCH64_BREAK_KGDB_DYN_DBG	\
50*4882a593Smuzhiyun 	(AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5))
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #define CACHE_FLUSH_IS_SAFE		1
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* kprobes BRK opcodes with ESR encoding  */
55*4882a593Smuzhiyun #define BRK64_OPCODE_KPROBES	(AARCH64_BREAK_MON | (KPROBES_BRK_IMM << 5))
56*4882a593Smuzhiyun #define BRK64_OPCODE_KPROBES_SS	(AARCH64_BREAK_MON | (KPROBES_BRK_SS_IMM << 5))
57*4882a593Smuzhiyun /* uprobes BRK opcodes with ESR encoding  */
58*4882a593Smuzhiyun #define BRK64_OPCODE_UPROBES	(AARCH64_BREAK_MON | (UPROBES_BRK_IMM << 5))
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /* AArch32 */
61*4882a593Smuzhiyun #define DBG_ESR_EVT_BKPT	0x4
62*4882a593Smuzhiyun #define DBG_ESR_EVT_VECC	0x5
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define AARCH32_BREAK_ARM	0x07f001f0
65*4882a593Smuzhiyun #define AARCH32_BREAK_THUMB	0xde01
66*4882a593Smuzhiyun #define AARCH32_BREAK_THUMB2_LO	0xf7f0
67*4882a593Smuzhiyun #define AARCH32_BREAK_THUMB2_HI	0xa000
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun #ifndef __ASSEMBLY__
70*4882a593Smuzhiyun struct task_struct;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun #define DBG_ARCH_ID_RESERVED	0	/* In case of ptrace ABI updates. */
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun #define DBG_HOOK_HANDLED	0
75*4882a593Smuzhiyun #define DBG_HOOK_ERROR		1
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun struct step_hook {
78*4882a593Smuzhiyun 	struct list_head node;
79*4882a593Smuzhiyun 	int (*fn)(struct pt_regs *regs, unsigned int esr);
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun void register_user_step_hook(struct step_hook *hook);
83*4882a593Smuzhiyun void unregister_user_step_hook(struct step_hook *hook);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun void register_kernel_step_hook(struct step_hook *hook);
86*4882a593Smuzhiyun void unregister_kernel_step_hook(struct step_hook *hook);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun struct break_hook {
89*4882a593Smuzhiyun 	struct list_head node;
90*4882a593Smuzhiyun 	int (*fn)(struct pt_regs *regs, unsigned int esr);
91*4882a593Smuzhiyun 	u16 imm;
92*4882a593Smuzhiyun 	u16 mask; /* These bits are ignored when comparing with imm */
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun void register_user_break_hook(struct break_hook *hook);
96*4882a593Smuzhiyun void unregister_user_break_hook(struct break_hook *hook);
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun void register_kernel_break_hook(struct break_hook *hook);
99*4882a593Smuzhiyun void unregister_kernel_break_hook(struct break_hook *hook);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun u8 debug_monitors_arch(void);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun enum dbg_active_el {
104*4882a593Smuzhiyun 	DBG_ACTIVE_EL0 = 0,
105*4882a593Smuzhiyun 	DBG_ACTIVE_EL1,
106*4882a593Smuzhiyun };
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun void enable_debug_monitors(enum dbg_active_el el);
109*4882a593Smuzhiyun void disable_debug_monitors(enum dbg_active_el el);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun void user_rewind_single_step(struct task_struct *task);
112*4882a593Smuzhiyun void user_fastforward_single_step(struct task_struct *task);
113*4882a593Smuzhiyun void user_regs_reset_single_step(struct user_pt_regs *regs,
114*4882a593Smuzhiyun 				 struct task_struct *task);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun void kernel_enable_single_step(struct pt_regs *regs);
117*4882a593Smuzhiyun void kernel_disable_single_step(void);
118*4882a593Smuzhiyun int kernel_active_single_step(void);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun #ifdef CONFIG_HAVE_HW_BREAKPOINT
121*4882a593Smuzhiyun int reinstall_suspended_bps(struct pt_regs *regs);
122*4882a593Smuzhiyun #else
reinstall_suspended_bps(struct pt_regs * regs)123*4882a593Smuzhiyun static inline int reinstall_suspended_bps(struct pt_regs *regs)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	return -ENODEV;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun #endif
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun int aarch32_break_handler(struct pt_regs *regs);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun void debug_traps_init(void);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #endif	/* __ASSEMBLY */
134*4882a593Smuzhiyun #endif	/* __ASM_DEBUG_MONITORS_H */
135