diff options
author | Will Deacon <will.deacon@arm.com> | 2011-07-22 13:27:37 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2011-08-31 05:42:47 -0400 |
commit | b5d5b8f98641edac6641af9e19e933083ade603b (patch) | |
tree | e68c07f25ddd2e90160abb2d8696eac046cc2e93 /arch/arm | |
parent | 90e93648c41bd29a72f6ec55ce27a23c209eab8c (diff) |
ARM: hw_breakpoint: add initial Cortex-A15 (debug v7.1) support
This patch adds initial support for Cortex-A15 (debug architecture v7.1)
to the hw_breakpoint ARM backend.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/hw_breakpoint.h | 1 | ||||
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 55 |
2 files changed, 37 insertions, 19 deletions
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index f389b2704d82..0ac141a87616 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h | |||
@@ -50,6 +50,7 @@ static inline void decode_ctrl_reg(u32 reg, | |||
50 | #define ARM_DEBUG_ARCH_V6_1 2 | 50 | #define ARM_DEBUG_ARCH_V6_1 2 |
51 | #define ARM_DEBUG_ARCH_V7_ECP14 3 | 51 | #define ARM_DEBUG_ARCH_V7_ECP14 3 |
52 | #define ARM_DEBUG_ARCH_V7_MM 4 | 52 | #define ARM_DEBUG_ARCH_V7_MM 4 |
53 | #define ARM_DEBUG_ARCH_V7_1 5 | ||
53 | 54 | ||
54 | /* Breakpoint */ | 55 | /* Breakpoint */ |
55 | #define ARM_BREAKPOINT_EXECUTE 0 | 56 | #define ARM_BREAKPOINT_EXECUTE 0 |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index a927ca1f5566..b6ddbfaae52c 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -154,7 +154,10 @@ u8 arch_get_debug_arch(void) | |||
154 | static int debug_arch_supported(void) | 154 | static int debug_arch_supported(void) |
155 | { | 155 | { |
156 | u8 arch = get_debug_arch(); | 156 | u8 arch = get_debug_arch(); |
157 | return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14; | 157 | |
158 | /* We don't support the memory-mapped interface. */ | ||
159 | return (arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14) || | ||
160 | arch >= ARM_DEBUG_ARCH_V7_1; | ||
158 | } | 161 | } |
159 | 162 | ||
160 | /* Determine number of BRP register available. */ | 163 | /* Determine number of BRP register available. */ |
@@ -255,6 +258,7 @@ static int enable_monitor_mode(void) | |||
255 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); | 258 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); |
256 | break; | 259 | break; |
257 | case ARM_DEBUG_ARCH_V7_ECP14: | 260 | case ARM_DEBUG_ARCH_V7_ECP14: |
261 | case ARM_DEBUG_ARCH_V7_1: | ||
258 | ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); | 262 | ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); |
259 | break; | 263 | break; |
260 | default: | 264 | default: |
@@ -836,7 +840,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
836 | */ | 840 | */ |
837 | static void reset_ctrl_regs(void *info) | 841 | static void reset_ctrl_regs(void *info) |
838 | { | 842 | { |
839 | int i, cpu = smp_processor_id(); | 843 | int i, err = 0, cpu = smp_processor_id(); |
840 | u32 dbg_power; | 844 | u32 dbg_power; |
841 | cpumask_t *cpumask = info; | 845 | cpumask_t *cpumask = info; |
842 | 846 | ||
@@ -848,33 +852,46 @@ static void reset_ctrl_regs(void *info) | |||
848 | * Access Register to avoid taking undefined instruction exceptions | 852 | * Access Register to avoid taking undefined instruction exceptions |
849 | * later on. | 853 | * later on. |
850 | */ | 854 | */ |
851 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { | 855 | switch (debug_arch) { |
856 | case ARM_DEBUG_ARCH_V7_ECP14: | ||
852 | /* | 857 | /* |
853 | * Ensure sticky power-down is clear (i.e. debug logic is | 858 | * Ensure sticky power-down is clear (i.e. debug logic is |
854 | * powered up). | 859 | * powered up). |
855 | */ | 860 | */ |
856 | asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); | 861 | asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); |
857 | if ((dbg_power & 0x1) == 0) { | 862 | if ((dbg_power & 0x1) == 0) |
858 | pr_warning("CPU %d debug is powered down!\n", cpu); | 863 | err = -EPERM; |
859 | cpumask_or(cpumask, cpumask, cpumask_of(cpu)); | 864 | break; |
860 | return; | 865 | case ARM_DEBUG_ARCH_V7_1: |
861 | } | ||
862 | |||
863 | /* | 866 | /* |
864 | * Unconditionally clear the lock by writing a value | 867 | * Ensure the OS double lock is clear. |
865 | * other than 0xC5ACCE55 to the access register. | ||
866 | */ | 868 | */ |
867 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); | 869 | asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power)); |
868 | isb(); | 870 | if ((dbg_power & 0x1) == 1) |
871 | err = -EPERM; | ||
872 | break; | ||
873 | } | ||
869 | 874 | ||
870 | /* | 875 | if (err) { |
871 | * Clear any configured vector-catch events before | 876 | pr_warning("CPU %d debug is powered down!\n", cpu); |
872 | * enabling monitor mode. | 877 | cpumask_or(cpumask, cpumask, cpumask_of(cpu)); |
873 | */ | 878 | return; |
874 | asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); | ||
875 | isb(); | ||
876 | } | 879 | } |
877 | 880 | ||
881 | /* | ||
882 | * Unconditionally clear the lock by writing a value | ||
883 | * other than 0xC5ACCE55 to the access register. | ||
884 | */ | ||
885 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); | ||
886 | isb(); | ||
887 | |||
888 | /* | ||
889 | * Clear any configured vector-catch events before | ||
890 | * enabling monitor mode. | ||
891 | */ | ||
892 | asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); | ||
893 | isb(); | ||
894 | |||
878 | if (enable_monitor_mode()) | 895 | if (enable_monitor_mode()) |
879 | return; | 896 | return; |
880 | 897 | ||