aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-11-19 06:23:08 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-11-19 06:23:08 -0500
commitc71d4aa7e98f30d4011b44b168263abc72f676bd (patch)
tree3daa760c738a6e90f8af4b9ff163e608f10884e4
parent667832da846b5748e6c7b3139bbe015c7ea189f7 (diff)
parentf600b9fcd2bcb8ee0adb235f54ccdd93c729c442 (diff)
Merge branch 'hw-breakpoint' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into devel-stable
-rw-r--r--arch/arm/include/asm/cti.h20
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h8
-rw-r--r--arch/arm/kernel/hw_breakpoint.c154
3 files changed, 91 insertions, 91 deletions
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h
index a0ada3ea4358..f2e5cad3f306 100644
--- a/arch/arm/include/asm/cti.h
+++ b/arch/arm/include/asm/cti.h
@@ -146,15 +146,7 @@ static inline void cti_irq_ack(struct cti *cti)
146 */ 146 */
147static inline void cti_unlock(struct cti *cti) 147static inline void cti_unlock(struct cti *cti)
148{ 148{
149 void __iomem *base = cti->base; 149 __raw_writel(LOCKCODE, cti->base + LOCKACCESS);
150 unsigned long val;
151
152 val = __raw_readl(base + LOCKSTATUS);
153
154 if (val & 1) {
155 val = LOCKCODE;
156 __raw_writel(val, base + LOCKACCESS);
157 }
158} 150}
159 151
160/** 152/**
@@ -166,14 +158,6 @@ static inline void cti_unlock(struct cti *cti)
166 */ 158 */
167static inline void cti_lock(struct cti *cti) 159static inline void cti_lock(struct cti *cti)
168{ 160{
169 void __iomem *base = cti->base; 161 __raw_writel(~LOCKCODE, cti->base + LOCKACCESS);
170 unsigned long val;
171
172 val = __raw_readl(base + LOCKSTATUS);
173
174 if (!(val & 1)) {
175 val = ~LOCKCODE;
176 __raw_writel(val, base + LOCKACCESS);
177 }
178} 162}
179#endif 163#endif
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
index c190bc992f0e..01169dd723f1 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -98,12 +98,12 @@ static inline void decode_ctrl_reg(u32 reg,
98#define ARM_BASE_WCR 112 98#define ARM_BASE_WCR 112
99 99
100/* Accessor macros for the debug registers. */ 100/* Accessor macros for the debug registers. */
101#define ARM_DBG_READ(M, OP2, VAL) do {\ 101#define ARM_DBG_READ(N, M, OP2, VAL) do {\
102 asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\ 102 asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL));\
103} while (0) 103} while (0)
104 104
105#define ARM_DBG_WRITE(M, OP2, VAL) do {\ 105#define ARM_DBG_WRITE(N, M, OP2, VAL) do {\
106 asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\ 106 asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\
107} while (0) 107} while (0)
108 108
109struct notifier_block; 109struct notifier_block;
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 281bf3301241..5ff2e77782b1 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -52,14 +52,14 @@ static u8 debug_arch;
52/* Maximum supported watchpoint length. */ 52/* Maximum supported watchpoint length. */
53static u8 max_watchpoint_len; 53static u8 max_watchpoint_len;
54 54
55#define READ_WB_REG_CASE(OP2, M, VAL) \ 55#define READ_WB_REG_CASE(OP2, M, VAL) \
56 case ((OP2 << 4) + M): \ 56 case ((OP2 << 4) + M): \
57 ARM_DBG_READ(c ## M, OP2, VAL); \ 57 ARM_DBG_READ(c0, c ## M, OP2, VAL); \
58 break 58 break
59 59
60#define WRITE_WB_REG_CASE(OP2, M, VAL) \ 60#define WRITE_WB_REG_CASE(OP2, M, VAL) \
61 case ((OP2 << 4) + M): \ 61 case ((OP2 << 4) + M): \
62 ARM_DBG_WRITE(c ## M, OP2, VAL);\ 62 ARM_DBG_WRITE(c0, c ## M, OP2, VAL); \
63 break 63 break
64 64
65#define GEN_READ_WB_REG_CASES(OP2, VAL) \ 65#define GEN_READ_WB_REG_CASES(OP2, VAL) \
@@ -136,12 +136,12 @@ static u8 get_debug_arch(void)
136 136
137 /* Do we implement the extended CPUID interface? */ 137 /* Do we implement the extended CPUID interface? */
138 if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { 138 if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
139 pr_warning("CPUID feature registers not supported. " 139 pr_warn_once("CPUID feature registers not supported. "
140 "Assuming v6 debug is present.\n"); 140 "Assuming v6 debug is present.\n");
141 return ARM_DEBUG_ARCH_V6; 141 return ARM_DEBUG_ARCH_V6;
142 } 142 }
143 143
144 ARM_DBG_READ(c0, 0, didr); 144 ARM_DBG_READ(c0, c0, 0, didr);
145 return (didr >> 16) & 0xf; 145 return (didr >> 16) & 0xf;
146} 146}
147 147
@@ -169,7 +169,7 @@ static int debug_exception_updates_fsr(void)
169static int get_num_wrp_resources(void) 169static int get_num_wrp_resources(void)
170{ 170{
171 u32 didr; 171 u32 didr;
172 ARM_DBG_READ(c0, 0, didr); 172 ARM_DBG_READ(c0, c0, 0, didr);
173 return ((didr >> 28) & 0xf) + 1; 173 return ((didr >> 28) & 0xf) + 1;
174} 174}
175 175
@@ -177,7 +177,7 @@ static int get_num_wrp_resources(void)
177static int get_num_brp_resources(void) 177static int get_num_brp_resources(void)
178{ 178{
179 u32 didr; 179 u32 didr;
180 ARM_DBG_READ(c0, 0, didr); 180 ARM_DBG_READ(c0, c0, 0, didr);
181 return ((didr >> 24) & 0xf) + 1; 181 return ((didr >> 24) & 0xf) + 1;
182} 182}
183 183
@@ -228,19 +228,17 @@ static int get_num_brps(void)
228 * be put into halting debug mode at any time by an external debugger 228 * be put into halting debug mode at any time by an external debugger
229 * but there is nothing we can do to prevent that. 229 * but there is nothing we can do to prevent that.
230 */ 230 */
231static int enable_monitor_mode(void) 231static int monitor_mode_enabled(void)
232{ 232{
233 u32 dscr; 233 u32 dscr;
234 int ret = 0; 234 ARM_DBG_READ(c0, c1, 0, dscr);
235 235 return !!(dscr & ARM_DSCR_MDBGEN);
236 ARM_DBG_READ(c1, 0, dscr); 236}
237 237
238 /* Ensure that halting mode is disabled. */ 238static int enable_monitor_mode(void)
239 if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, 239{
240 "halting debug mode enabled. Unable to access hardware resources.\n")) { 240 u32 dscr;
241 ret = -EPERM; 241 ARM_DBG_READ(c0, c1, 0, dscr);
242 goto out;
243 }
244 242
245 /* If monitor mode is already enabled, just return. */ 243 /* If monitor mode is already enabled, just return. */
246 if (dscr & ARM_DSCR_MDBGEN) 244 if (dscr & ARM_DSCR_MDBGEN)
@@ -250,24 +248,27 @@ static int enable_monitor_mode(void)
250 switch (get_debug_arch()) { 248 switch (get_debug_arch()) {
251 case ARM_DEBUG_ARCH_V6: 249 case ARM_DEBUG_ARCH_V6:
252 case ARM_DEBUG_ARCH_V6_1: 250 case ARM_DEBUG_ARCH_V6_1:
253 ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); 251 ARM_DBG_WRITE(c0, c1, 0, (dscr | ARM_DSCR_MDBGEN));
254 break; 252 break;
255 case ARM_DEBUG_ARCH_V7_ECP14: 253 case ARM_DEBUG_ARCH_V7_ECP14:
256 case ARM_DEBUG_ARCH_V7_1: 254 case ARM_DEBUG_ARCH_V7_1:
257 ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); 255 ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN));
256 isb();
258 break; 257 break;
259 default: 258 default:
260 ret = -ENODEV; 259 return -ENODEV;
261 goto out;
262 } 260 }
263 261
264 /* Check that the write made it through. */ 262 /* Check that the write made it through. */
265 ARM_DBG_READ(c1, 0, dscr); 263 ARM_DBG_READ(c0, c1, 0, dscr);
266 if (!(dscr & ARM_DSCR_MDBGEN)) 264 if (!(dscr & ARM_DSCR_MDBGEN)) {
267 ret = -EPERM; 265 pr_warn_once("Failed to enable monitor mode on CPU %d.\n",
266 smp_processor_id());
267 return -EPERM;
268 }
268 269
269out: 270out:
270 return ret; 271 return 0;
271} 272}
272 273
273int hw_breakpoint_slots(int type) 274int hw_breakpoint_slots(int type)
@@ -328,14 +329,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
328{ 329{
329 struct arch_hw_breakpoint *info = counter_arch_bp(bp); 330 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
330 struct perf_event **slot, **slots; 331 struct perf_event **slot, **slots;
331 int i, max_slots, ctrl_base, val_base, ret = 0; 332 int i, max_slots, ctrl_base, val_base;
332 u32 addr, ctrl; 333 u32 addr, ctrl;
333 334
334 /* Ensure that we are in monitor mode and halting mode is disabled. */
335 ret = enable_monitor_mode();
336 if (ret)
337 goto out;
338
339 addr = info->address; 335 addr = info->address;
340 ctrl = encode_ctrl_reg(info->ctrl) | 0x1; 336 ctrl = encode_ctrl_reg(info->ctrl) | 0x1;
341 337
@@ -362,9 +358,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
362 } 358 }
363 } 359 }
364 360
365 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) { 361 if (i == max_slots) {
366 ret = -EBUSY; 362 pr_warning("Can't find any breakpoint slot\n");
367 goto out; 363 return -EBUSY;
368 } 364 }
369 365
370 /* Override the breakpoint data with the step data. */ 366 /* Override the breakpoint data with the step data. */
@@ -383,9 +379,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
383 379
384 /* Setup the control register. */ 380 /* Setup the control register. */
385 write_wb_reg(ctrl_base + i, ctrl); 381 write_wb_reg(ctrl_base + i, ctrl);
386 382 return 0;
387out:
388 return ret;
389} 383}
390 384
391void arch_uninstall_hw_breakpoint(struct perf_event *bp) 385void arch_uninstall_hw_breakpoint(struct perf_event *bp)
@@ -416,8 +410,10 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
416 } 410 }
417 } 411 }
418 412
419 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) 413 if (i == max_slots) {
414 pr_warning("Can't find any breakpoint slot\n");
420 return; 415 return;
416 }
421 417
422 /* Ensure that we disable the mismatch breakpoint. */ 418 /* Ensure that we disable the mismatch breakpoint. */
423 if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE && 419 if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE &&
@@ -596,6 +592,10 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
596 int ret = 0; 592 int ret = 0;
597 u32 offset, alignment_mask = 0x3; 593 u32 offset, alignment_mask = 0x3;
598 594
595 /* Ensure that we are in monitor debug mode. */
596 if (!monitor_mode_enabled())
597 return -ENODEV;
598
599 /* Build the arch_hw_breakpoint. */ 599 /* Build the arch_hw_breakpoint. */
600 ret = arch_build_bp_info(bp); 600 ret = arch_build_bp_info(bp);
601 if (ret) 601 if (ret)
@@ -858,7 +858,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
858 local_irq_enable(); 858 local_irq_enable();
859 859
860 /* We only handle watchpoints and hardware breakpoints. */ 860 /* We only handle watchpoints and hardware breakpoints. */
861 ARM_DBG_READ(c1, 0, dscr); 861 ARM_DBG_READ(c0, c1, 0, dscr);
862 862
863 /* Perform perf callbacks. */ 863 /* Perform perf callbacks. */
864 switch (ARM_DSCR_MOE(dscr)) { 864 switch (ARM_DSCR_MOE(dscr)) {
@@ -906,7 +906,7 @@ static struct undef_hook debug_reg_hook = {
906static void reset_ctrl_regs(void *unused) 906static void reset_ctrl_regs(void *unused)
907{ 907{
908 int i, raw_num_brps, err = 0, cpu = smp_processor_id(); 908 int i, raw_num_brps, err = 0, cpu = smp_processor_id();
909 u32 dbg_power; 909 u32 val;
910 910
911 /* 911 /*
912 * v7 debug contains save and restore registers so that debug state 912 * v7 debug contains save and restore registers so that debug state
@@ -919,23 +919,30 @@ static void reset_ctrl_regs(void *unused)
919 switch (debug_arch) { 919 switch (debug_arch) {
920 case ARM_DEBUG_ARCH_V6: 920 case ARM_DEBUG_ARCH_V6:
921 case ARM_DEBUG_ARCH_V6_1: 921 case ARM_DEBUG_ARCH_V6_1:
922 /* ARMv6 cores just need to reset the registers. */ 922 /* ARMv6 cores clear the registers out of reset. */
923 goto reset_regs; 923 goto out_mdbgen;
924 case ARM_DEBUG_ARCH_V7_ECP14: 924 case ARM_DEBUG_ARCH_V7_ECP14:
925 /* 925 /*
926 * Ensure sticky power-down is clear (i.e. debug logic is 926 * Ensure sticky power-down is clear (i.e. debug logic is
927 * powered up). 927 * powered up).
928 */ 928 */
929 asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); 929 ARM_DBG_READ(c1, c5, 4, val);
930 if ((dbg_power & 0x1) == 0) 930 if ((val & 0x1) == 0)
931 err = -EPERM; 931 err = -EPERM;
932
933 /*
934 * Check whether we implement OS save and restore.
935 */
936 ARM_DBG_READ(c1, c1, 4, val);
937 if ((val & 0x9) == 0)
938 goto clear_vcr;
932 break; 939 break;
933 case ARM_DEBUG_ARCH_V7_1: 940 case ARM_DEBUG_ARCH_V7_1:
934 /* 941 /*
935 * Ensure the OS double lock is clear. 942 * Ensure the OS double lock is clear.
936 */ 943 */
937 asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power)); 944 ARM_DBG_READ(c1, c3, 4, val);
938 if ((dbg_power & 0x1) == 1) 945 if ((val & 0x1) == 1)
939 err = -EPERM; 946 err = -EPERM;
940 break; 947 break;
941 } 948 }
@@ -947,24 +954,29 @@ static void reset_ctrl_regs(void *unused)
947 } 954 }
948 955
949 /* 956 /*
950 * Unconditionally clear the lock by writing a value 957 * Unconditionally clear the OS lock by writing a value
951 * other than 0xC5ACCE55 to the access register. 958 * other than 0xC5ACCE55 to the access register.
952 */ 959 */
953 asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); 960 ARM_DBG_WRITE(c1, c0, 4, 0);
954 isb(); 961 isb();
955 962
956 /* 963 /*
957 * Clear any configured vector-catch events before 964 * Clear any configured vector-catch events before
958 * enabling monitor mode. 965 * enabling monitor mode.
959 */ 966 */
960 asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); 967clear_vcr:
968 ARM_DBG_WRITE(c0, c7, 0, 0);
961 isb(); 969 isb();
962 970
963reset_regs: 971 if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
964 if (enable_monitor_mode()) 972 pr_warning("CPU %d failed to disable vector catch\n", cpu);
965 return; 973 return;
974 }
966 975
967 /* We must also reset any reserved registers. */ 976 /*
977 * The control/value register pairs are UNKNOWN out of reset so
978 * clear them to avoid spurious debug events.
979 */
968 raw_num_brps = get_num_brp_resources(); 980 raw_num_brps = get_num_brp_resources();
969 for (i = 0; i < raw_num_brps; ++i) { 981 for (i = 0; i < raw_num_brps; ++i) {
970 write_wb_reg(ARM_BASE_BCR + i, 0UL); 982 write_wb_reg(ARM_BASE_BCR + i, 0UL);
@@ -975,6 +987,19 @@ reset_regs:
975 write_wb_reg(ARM_BASE_WCR + i, 0UL); 987 write_wb_reg(ARM_BASE_WCR + i, 0UL);
976 write_wb_reg(ARM_BASE_WVR + i, 0UL); 988 write_wb_reg(ARM_BASE_WVR + i, 0UL);
977 } 989 }
990
991 if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
992 pr_warning("CPU %d failed to clear debug register pairs\n", cpu);
993 return;
994 }
995
996 /*
997 * Have a crack at enabling monitor mode. We don't actually need
998 * it yet, but reporting an error early is useful if it fails.
999 */
1000out_mdbgen:
1001 if (enable_monitor_mode())
1002 cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
978} 1003}
979 1004
980static int __cpuinit dbg_reset_notify(struct notifier_block *self, 1005static int __cpuinit dbg_reset_notify(struct notifier_block *self,
@@ -992,8 +1017,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
992 1017
993static int __init arch_hw_breakpoint_init(void) 1018static int __init arch_hw_breakpoint_init(void)
994{ 1019{
995 u32 dscr;
996
997 debug_arch = get_debug_arch(); 1020 debug_arch = get_debug_arch();
998 1021
999 if (!debug_arch_supported()) { 1022 if (!debug_arch_supported()) {
@@ -1028,17 +1051,10 @@ static int __init arch_hw_breakpoint_init(void)
1028 core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " : 1051 core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " :
1029 "", core_num_wrps); 1052 "", core_num_wrps);
1030 1053
1031 ARM_DBG_READ(c1, 0, dscr); 1054 /* Work out the maximum supported watchpoint length. */
1032 if (dscr & ARM_DSCR_HDBGEN) { 1055 max_watchpoint_len = get_max_wp_len();
1033 max_watchpoint_len = 4; 1056 pr_info("maximum watchpoint size is %u bytes.\n",
1034 pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n", 1057 max_watchpoint_len);
1035 max_watchpoint_len);
1036 } else {
1037 /* Work out the maximum supported watchpoint length. */
1038 max_watchpoint_len = get_max_wp_len();
1039 pr_info("maximum watchpoint size is %u bytes.\n",
1040 max_watchpoint_len);
1041 }
1042 1058
1043 /* Register debug fault handler. */ 1059 /* Register debug fault handler. */
1044 hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, 1060 hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,