diff options
| -rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 54 |
1 files changed, 25 insertions, 29 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 56ed9a62013b..c9f3f0467570 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
| @@ -219,23 +219,6 @@ static int get_num_brps(void) | |||
| 219 | return brps; | 219 | return brps; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | int hw_breakpoint_slots(int type) | ||
| 223 | { | ||
| 224 | /* | ||
| 225 | * We can be called early, so don't rely on | ||
| 226 | * our static variables being initialised. | ||
| 227 | */ | ||
| 228 | switch (type) { | ||
| 229 | case TYPE_INST: | ||
| 230 | return get_num_brps(); | ||
| 231 | case TYPE_DATA: | ||
| 232 | return get_num_wrps(); | ||
| 233 | default: | ||
| 234 | pr_warning("unknown slot type: %d\n", type); | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | /* | 222 | /* |
| 240 | * In order to access the breakpoint/watchpoint control registers, | 223 | * In order to access the breakpoint/watchpoint control registers, |
| 241 | * we must be running in debug monitor mode. Unfortunately, we can | 224 | * we must be running in debug monitor mode. Unfortunately, we can |
| @@ -256,8 +239,12 @@ static int enable_monitor_mode(void) | |||
| 256 | goto out; | 239 | goto out; |
| 257 | } | 240 | } |
| 258 | 241 | ||
| 242 | /* If monitor mode is already enabled, just return. */ | ||
| 243 | if (dscr & ARM_DSCR_MDBGEN) | ||
| 244 | goto out; | ||
| 245 | |||
| 259 | /* Write to the corresponding DSCR. */ | 246 | /* Write to the corresponding DSCR. */ |
| 260 | switch (debug_arch) { | 247 | switch (get_debug_arch()) { |
| 261 | case ARM_DEBUG_ARCH_V6: | 248 | case ARM_DEBUG_ARCH_V6: |
| 262 | case ARM_DEBUG_ARCH_V6_1: | 249 | case ARM_DEBUG_ARCH_V6_1: |
| 263 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); | 250 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); |
| @@ -272,15 +259,30 @@ static int enable_monitor_mode(void) | |||
| 272 | 259 | ||
| 273 | /* Check that the write made it through. */ | 260 | /* Check that the write made it through. */ |
| 274 | ARM_DBG_READ(c1, 0, dscr); | 261 | ARM_DBG_READ(c1, 0, dscr); |
| 275 | if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN), | 262 | if (!(dscr & ARM_DSCR_MDBGEN)) |
| 276 | "failed to enable monitor mode.")) { | ||
| 277 | ret = -EPERM; | 263 | ret = -EPERM; |
| 278 | } | ||
| 279 | 264 | ||
| 280 | out: | 265 | out: |
| 281 | return ret; | 266 | return ret; |
| 282 | } | 267 | } |
| 283 | 268 | ||
| 269 | int hw_breakpoint_slots(int type) | ||
| 270 | { | ||
| 271 | /* | ||
| 272 | * We can be called early, so don't rely on | ||
| 273 | * our static variables being initialised. | ||
| 274 | */ | ||
| 275 | switch (type) { | ||
| 276 | case TYPE_INST: | ||
| 277 | return get_num_brps(); | ||
| 278 | case TYPE_DATA: | ||
| 279 | return get_num_wrps(); | ||
| 280 | default: | ||
| 281 | pr_warning("unknown slot type: %d\n", type); | ||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 284 | /* | 286 | /* |
| 285 | * Check if 8-bit byte-address select is available. | 287 | * Check if 8-bit byte-address select is available. |
| 286 | * This clobbers WRP 0. | 288 | * This clobbers WRP 0. |
| @@ -294,9 +296,6 @@ static u8 get_max_wp_len(void) | |||
| 294 | if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14) | 296 | if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14) |
| 295 | goto out; | 297 | goto out; |
| 296 | 298 | ||
| 297 | if (enable_monitor_mode()) | ||
| 298 | goto out; | ||
| 299 | |||
| 300 | memset(&ctrl, 0, sizeof(ctrl)); | 299 | memset(&ctrl, 0, sizeof(ctrl)); |
| 301 | ctrl.len = ARM_BREAKPOINT_LEN_8; | 300 | ctrl.len = ARM_BREAKPOINT_LEN_8; |
| 302 | ctrl_reg = encode_ctrl_reg(ctrl); | 301 | ctrl_reg = encode_ctrl_reg(ctrl); |
| @@ -879,15 +878,13 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { | |||
| 879 | 878 | ||
| 880 | static int __init arch_hw_breakpoint_init(void) | 879 | static int __init arch_hw_breakpoint_init(void) |
| 881 | { | 880 | { |
| 882 | int ret = 0; | ||
| 883 | u32 dscr; | 881 | u32 dscr; |
| 884 | 882 | ||
| 885 | debug_arch = get_debug_arch(); | 883 | debug_arch = get_debug_arch(); |
| 886 | 884 | ||
| 887 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { | 885 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { |
| 888 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); | 886 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); |
| 889 | ret = -ENODEV; | 887 | return 0; |
| 890 | goto out; | ||
| 891 | } | 888 | } |
| 892 | 889 | ||
| 893 | /* Determine how many BRPs/WRPs are available. */ | 890 | /* Determine how many BRPs/WRPs are available. */ |
| @@ -928,8 +925,7 @@ static int __init arch_hw_breakpoint_init(void) | |||
| 928 | 925 | ||
| 929 | /* Register hotplug notifier. */ | 926 | /* Register hotplug notifier. */ |
| 930 | register_cpu_notifier(&dbg_reset_nb); | 927 | register_cpu_notifier(&dbg_reset_nb); |
| 931 | out: | 928 | return 0; |
| 932 | return ret; | ||
| 933 | } | 929 | } |
| 934 | arch_initcall(arch_hw_breakpoint_init); | 930 | arch_initcall(arch_hw_breakpoint_init); |
| 935 | 931 | ||
