aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2010-09-03 05:41:08 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-09-08 05:05:00 -0400
commitf81ef4a920c8e1af75adf9f15042c2daa49d3cb3 (patch)
tree48778ddf71477275bbe08c5e4394919061e27e12 /arch/arm/include
parent3a4b5dca53aecb16db9e007d782b2d1e757e941a (diff)
ARM: 6356/1: hw-breakpoint: add ARM backend for the hw-breakpoint framework
The hw-breakpoint framework in the kernel requires architecture-specific support in order to install, remove, validate and manage hardware breakpoints. This patch adds initial support for this framework to the ARM architecture, but restricts the number of watchpoints to a single resource to get around the fact that the Data Fault Address Register is unknown when a watchpoint debug exception is taken. On cores with v7 debug, the Kernel can handle breakpoint and watchpoint exceptions occuring from userspace. Older cores require clients to handle the exception themselves by registering an appropriate overflow handler or, in the case of ptrace, handling the raised SIGTRAP. The memory-mapped extended debug interface is unsupported due to its unreliability in real implementations. Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: S. Karthikeyan <informkarthik@gmail.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h123
1 files changed, 123 insertions, 0 deletions
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
new file mode 100644
index 000000000000..33048c700caa
--- /dev/null
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -0,0 +1,123 @@
1#ifndef _ARM_HW_BREAKPOINT_H
2#define _ARM_HW_BREAKPOINT_H
3
4#ifdef __KERNEL__
5struct arch_hw_breakpoint_ctrl {
6 u32 __reserved : 9,
7 mismatch : 1,
8 : 9,
9 len : 8,
10 type : 2,
11 privilege : 2,
12 enabled : 1;
13};
14
15struct arch_hw_breakpoint {
16 u32 address;
17 u32 trigger;
18 struct perf_event *suspended_wp;
19 struct arch_hw_breakpoint_ctrl ctrl;
20};
21
22static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
23{
24 return (ctrl.mismatch << 22) | (ctrl.len << 5) | (ctrl.type << 3) |
25 (ctrl.privilege << 1) | ctrl.enabled;
26}
27
28static inline void decode_ctrl_reg(u32 reg,
29 struct arch_hw_breakpoint_ctrl *ctrl)
30{
31 ctrl->enabled = reg & 0x1;
32 reg >>= 1;
33 ctrl->privilege = reg & 0x3;
34 reg >>= 2;
35 ctrl->type = reg & 0x3;
36 reg >>= 2;
37 ctrl->len = reg & 0xff;
38 reg >>= 17;
39 ctrl->mismatch = reg & 0x1;
40}
41
42/* Debug architecture numbers. */
43#define ARM_DEBUG_ARCH_RESERVED 0 /* In case of ptrace ABI updates. */
44#define ARM_DEBUG_ARCH_V6 1
45#define ARM_DEBUG_ARCH_V6_1 2
46#define ARM_DEBUG_ARCH_V7_ECP14 3
47#define ARM_DEBUG_ARCH_V7_MM 4
48
49/* Breakpoint */
50#define ARM_BREAKPOINT_EXECUTE 0
51
52/* Watchpoints */
53#define ARM_BREAKPOINT_LOAD 1
54#define ARM_BREAKPOINT_STORE 2
55
56/* Privilege Levels */
57#define ARM_BREAKPOINT_PRIV 1
58#define ARM_BREAKPOINT_USER 2
59
60/* Lengths */
61#define ARM_BREAKPOINT_LEN_1 0x1
62#define ARM_BREAKPOINT_LEN_2 0x3
63#define ARM_BREAKPOINT_LEN_4 0xf
64#define ARM_BREAKPOINT_LEN_8 0xff
65
66/* Limits */
67#define ARM_MAX_BRP 16
68#define ARM_MAX_WRP 16
69#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP)
70
71/* DSCR method of entry bits. */
72#define ARM_DSCR_MOE(x) ((x >> 2) & 0xf)
73#define ARM_ENTRY_BREAKPOINT 0x1
74#define ARM_ENTRY_ASYNC_WATCHPOINT 0x2
75#define ARM_ENTRY_SYNC_WATCHPOINT 0xa
76
77/* DSCR monitor/halting bits. */
78#define ARM_DSCR_HDBGEN (1 << 14)
79#define ARM_DSCR_MDBGEN (1 << 15)
80
81/* opcode2 numbers for the co-processor instructions. */
82#define ARM_OP2_BVR 4
83#define ARM_OP2_BCR 5
84#define ARM_OP2_WVR 6
85#define ARM_OP2_WCR 7
86
87/* Base register numbers for the debug registers. */
88#define ARM_BASE_BVR 64
89#define ARM_BASE_BCR 80
90#define ARM_BASE_WVR 96
91#define ARM_BASE_WCR 112
92
93/* Accessor macros for the debug registers. */
94#define ARM_DBG_READ(M, OP2, VAL) do {\
95 asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\
96} while (0)
97
98#define ARM_DBG_WRITE(M, OP2, VAL) do {\
99 asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\
100} while (0)
101
102struct notifier_block;
103struct perf_event;
104struct pmu;
105struct task_struct;
106
107extern struct pmu perf_ops_bp;
108extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
109 int *gen_len, int *gen_type);
110extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
111extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
112extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
113 unsigned long val, void *data);
114extern u8 arch_get_debug_arch(void);
115extern u8 arch_get_max_wp_len(void);
116
117int arch_install_hw_breakpoint(struct perf_event *bp);
118void arch_uninstall_hw_breakpoint(struct perf_event *bp);
119void hw_breakpoint_pmu_read(struct perf_event *bp);
120int hw_breakpoint_slots(int type);
121
122#endif /* __KERNEL__ */
123#endif /* _ARM_HW_BREAKPOINT_H */