diff options
author | Will Deacon <will.deacon@arm.com> | 2012-09-21 09:53:13 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2012-11-09 06:47:05 -0500 |
commit | e64877dcf5fd05d81fa195785a738f3a729587a3 (patch) | |
tree | ec31d1ca85f3655f46e0ccbb4a7276797f53a506 /arch/arm/kernel | |
parent | 3d70f8c617a436c7146ecb81df2265b4626dfe89 (diff) |
ARM: hw_breakpoint: only clear OS lock when implemented on v7
The OS save and restore register are optional in debug architecture v7,
so check the status register before attempting to clear the OS lock.
Tested-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 281bf3301241..76a650a1a1d7 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -906,7 +906,7 @@ static struct undef_hook debug_reg_hook = { | |||
906 | static void reset_ctrl_regs(void *unused) | 906 | static 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 |
@@ -926,16 +926,23 @@ static void reset_ctrl_regs(void *unused) | |||
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 | asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (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 | asm volatile("mrc p14, 0, %0, c1, c1, 4" : "=r" (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 | asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (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,7 +954,7 @@ 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 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); |
@@ -957,6 +964,7 @@ static void reset_ctrl_regs(void *unused) | |||
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 | */ |
967 | clear_vcr: | ||
960 | asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); | 968 | asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); |
961 | isb(); | 969 | isb(); |
962 | 970 | ||