diff options
author | Will Deacon <will.deacon@arm.com> | 2011-02-25 14:20:42 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-02-26 08:35:51 -0500 |
commit | c09bae709182046ab104757115dfbd74a1ba1a15 (patch) | |
tree | 4abb05c23dd1846666c327d4ccb8aa3458b6f44a | |
parent | ba55d3db9bb59a52fe45dbc5d62776adbb289e54 (diff) |
ARM: 6768/1: hw_breakpoint: ensure debug logic is powered up on v7 cores
ARMv7 allows the debug core logic to be powered down and provides the
DBGPRSR register so that software can power-up and check the status of
the logic.
This patch ensures that the debug logic is powered up on ARMv7 cores
before we attempt to access the extended debug registers.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index d600bd350704..44b84fe6e1b0 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -836,9 +836,11 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
836 | /* | 836 | /* |
837 | * One-time initialisation. | 837 | * One-time initialisation. |
838 | */ | 838 | */ |
839 | static void reset_ctrl_regs(void *unused) | 839 | static void reset_ctrl_regs(void *info) |
840 | { | 840 | { |
841 | int i; | 841 | int i, cpu = smp_processor_id(); |
842 | u32 dbg_power; | ||
843 | cpumask_t *cpumask = info; | ||
842 | 844 | ||
843 | /* | 845 | /* |
844 | * v7 debug contains save and restore registers so that debug state | 846 | * v7 debug contains save and restore registers so that debug state |
@@ -850,6 +852,17 @@ static void reset_ctrl_regs(void *unused) | |||
850 | */ | 852 | */ |
851 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { | 853 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { |
852 | /* | 854 | /* |
855 | * Ensure sticky power-down is clear (i.e. debug logic is | ||
856 | * powered up). | ||
857 | */ | ||
858 | asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); | ||
859 | if ((dbg_power & 0x1) == 0) { | ||
860 | pr_warning("CPU %d debug is powered down!\n", cpu); | ||
861 | cpumask_or(cpumask, cpumask, cpumask_of(cpu)); | ||
862 | return; | ||
863 | } | ||
864 | |||
865 | /* | ||
853 | * Unconditionally clear the lock by writing a value | 866 | * Unconditionally clear the lock by writing a value |
854 | * other than 0xC5ACCE55 to the access register. | 867 | * other than 0xC5ACCE55 to the access register. |
855 | */ | 868 | */ |
@@ -887,6 +900,7 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { | |||
887 | static int __init arch_hw_breakpoint_init(void) | 900 | static int __init arch_hw_breakpoint_init(void) |
888 | { | 901 | { |
889 | u32 dscr; | 902 | u32 dscr; |
903 | cpumask_t cpumask = { CPU_BITS_NONE }; | ||
890 | 904 | ||
891 | debug_arch = get_debug_arch(); | 905 | debug_arch = get_debug_arch(); |
892 | 906 | ||
@@ -911,7 +925,13 @@ static int __init arch_hw_breakpoint_init(void) | |||
911 | * Reset the breakpoint resources. We assume that a halting | 925 | * Reset the breakpoint resources. We assume that a halting |
912 | * debugger will leave the world in a nice state for us. | 926 | * debugger will leave the world in a nice state for us. |
913 | */ | 927 | */ |
914 | on_each_cpu(reset_ctrl_regs, NULL, 1); | 928 | on_each_cpu(reset_ctrl_regs, &cpumask, 1); |
929 | if (!cpumask_empty(&cpumask)) { | ||
930 | core_num_brps = 0; | ||
931 | core_num_reserved_brps = 0; | ||
932 | core_num_wrps = 0; | ||
933 | return 0; | ||
934 | } | ||
915 | 935 | ||
916 | ARM_DBG_READ(c1, 0, dscr); | 936 | ARM_DBG_READ(c1, 0, dscr); |
917 | if (dscr & ARM_DSCR_HDBGEN) { | 937 | if (dscr & ARM_DSCR_HDBGEN) { |