diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-01-23 17:42:36 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-01-23 17:42:36 -0500 |
commit | 13cea1069f65c120c8b5d44ea09903aad41ad715 (patch) | |
tree | 745315397702b63bd023974c7ebf439dec6ccce4 | |
parent | 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (diff) | |
parent | 9a6eb310eaa5336b89a27a0bbb78da4bba35f6f1 (diff) |
Merge branch 'for-rmk/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.h | 10 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/coresight.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/hw_breakpoint.h | 3 | ||||
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 61 |
4 files changed, 62 insertions, 18 deletions
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h index f2e5cad3f306..2381199acb7d 100644 --- a/arch/arm/include/asm/cti.h +++ b/arch/arm/include/asm/cti.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __ASMARM_CTI_H | 2 | #define __ASMARM_CTI_H |
3 | 3 | ||
4 | #include <asm/io.h> | 4 | #include <asm/io.h> |
5 | #include <asm/hardware/coresight.h> | ||
5 | 6 | ||
6 | /* The registers' definition is from section 3.2 of | 7 | /* The registers' definition is from section 3.2 of |
7 | * Embedded Cross Trigger Revision: r0p0 | 8 | * Embedded Cross Trigger Revision: r0p0 |
@@ -35,11 +36,6 @@ | |||
35 | #define LOCKACCESS 0xFB0 | 36 | #define LOCKACCESS 0xFB0 |
36 | #define LOCKSTATUS 0xFB4 | 37 | #define LOCKSTATUS 0xFB4 |
37 | 38 | ||
38 | /* write this value to LOCKACCESS will unlock the module, and | ||
39 | * other value will lock the module | ||
40 | */ | ||
41 | #define LOCKCODE 0xC5ACCE55 | ||
42 | |||
43 | /** | 39 | /** |
44 | * struct cti - cross trigger interface struct | 40 | * struct cti - cross trigger interface struct |
45 | * @base: mapped virtual address for the cti base | 41 | * @base: mapped virtual address for the cti base |
@@ -146,7 +142,7 @@ static inline void cti_irq_ack(struct cti *cti) | |||
146 | */ | 142 | */ |
147 | static inline void cti_unlock(struct cti *cti) | 143 | static inline void cti_unlock(struct cti *cti) |
148 | { | 144 | { |
149 | __raw_writel(LOCKCODE, cti->base + LOCKACCESS); | 145 | __raw_writel(CS_LAR_KEY, cti->base + LOCKACCESS); |
150 | } | 146 | } |
151 | 147 | ||
152 | /** | 148 | /** |
@@ -158,6 +154,6 @@ static inline void cti_unlock(struct cti *cti) | |||
158 | */ | 154 | */ |
159 | static inline void cti_lock(struct cti *cti) | 155 | static inline void cti_lock(struct cti *cti) |
160 | { | 156 | { |
161 | __raw_writel(~LOCKCODE, cti->base + LOCKACCESS); | 157 | __raw_writel(~CS_LAR_KEY, cti->base + LOCKACCESS); |
162 | } | 158 | } |
163 | #endif | 159 | #endif |
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h index 7ecd793b8f5a..0cf7a6b842ff 100644 --- a/arch/arm/include/asm/hardware/coresight.h +++ b/arch/arm/include/asm/hardware/coresight.h | |||
@@ -36,7 +36,7 @@ | |||
36 | /* CoreSight Component Registers */ | 36 | /* CoreSight Component Registers */ |
37 | #define CSCR_CLASS 0xff4 | 37 | #define CSCR_CLASS 0xff4 |
38 | 38 | ||
39 | #define UNLOCK_MAGIC 0xc5acce55 | 39 | #define CS_LAR_KEY 0xc5acce55 |
40 | 40 | ||
41 | /* ETM control register, "ETM Architecture", 3.3.1 */ | 41 | /* ETM control register, "ETM Architecture", 3.3.1 */ |
42 | #define ETMR_CTRL 0 | 42 | #define ETMR_CTRL 0 |
@@ -147,11 +147,11 @@ | |||
147 | 147 | ||
148 | #define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0) | 148 | #define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0) |
149 | #define etm_unlock(t) \ | 149 | #define etm_unlock(t) \ |
150 | do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) | 150 | do { etm_writel((t), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0) |
151 | 151 | ||
152 | #define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0) | 152 | #define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0) |
153 | #define etb_unlock(t) \ | 153 | #define etb_unlock(t) \ |
154 | do { etb_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) | 154 | do { etb_writel((t), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0) |
155 | 155 | ||
156 | #endif /* __ASM_HARDWARE_CORESIGHT_H */ | 156 | #endif /* __ASM_HARDWARE_CORESIGHT_H */ |
157 | 157 | ||
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index 01169dd723f1..eef55ea9ef00 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h | |||
@@ -85,6 +85,9 @@ static inline void decode_ctrl_reg(u32 reg, | |||
85 | #define ARM_DSCR_HDBGEN (1 << 14) | 85 | #define ARM_DSCR_HDBGEN (1 << 14) |
86 | #define ARM_DSCR_MDBGEN (1 << 15) | 86 | #define ARM_DSCR_MDBGEN (1 << 15) |
87 | 87 | ||
88 | /* OSLSR os lock model bits */ | ||
89 | #define ARM_OSLSR_OSLM0 (1 << 0) | ||
90 | |||
88 | /* opcode2 numbers for the co-processor instructions. */ | 91 | /* opcode2 numbers for the co-processor instructions. */ |
89 | #define ARM_OP2_BVR 4 | 92 | #define ARM_OP2_BVR 4 |
90 | #define ARM_OP2_BCR 5 | 93 | #define ARM_OP2_BCR 5 |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 5ff2e77782b1..5eae53e7a2e1 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/perf_event.h> | 28 | #include <linux/perf_event.h> |
29 | #include <linux/hw_breakpoint.h> | 29 | #include <linux/hw_breakpoint.h> |
30 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
31 | #include <linux/cpu_pm.h> | ||
31 | 32 | ||
32 | #include <asm/cacheflush.h> | 33 | #include <asm/cacheflush.h> |
33 | #include <asm/cputype.h> | 34 | #include <asm/cputype.h> |
@@ -35,6 +36,7 @@ | |||
35 | #include <asm/hw_breakpoint.h> | 36 | #include <asm/hw_breakpoint.h> |
36 | #include <asm/kdebug.h> | 37 | #include <asm/kdebug.h> |
37 | #include <asm/traps.h> | 38 | #include <asm/traps.h> |
39 | #include <asm/hardware/coresight.h> | ||
38 | 40 | ||
39 | /* Breakpoint currently in use for each BRP. */ | 41 | /* Breakpoint currently in use for each BRP. */ |
40 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]); | 42 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]); |
@@ -49,6 +51,9 @@ static int core_num_wrps; | |||
49 | /* Debug architecture version. */ | 51 | /* Debug architecture version. */ |
50 | static u8 debug_arch; | 52 | static u8 debug_arch; |
51 | 53 | ||
54 | /* Does debug architecture support OS Save and Restore? */ | ||
55 | static bool has_ossr; | ||
56 | |||
52 | /* Maximum supported watchpoint length. */ | 57 | /* Maximum supported watchpoint length. */ |
53 | static u8 max_watchpoint_len; | 58 | static u8 max_watchpoint_len; |
54 | 59 | ||
@@ -903,6 +908,23 @@ static struct undef_hook debug_reg_hook = { | |||
903 | .fn = debug_reg_trap, | 908 | .fn = debug_reg_trap, |
904 | }; | 909 | }; |
905 | 910 | ||
911 | /* Does this core support OS Save and Restore? */ | ||
912 | static bool core_has_os_save_restore(void) | ||
913 | { | ||
914 | u32 oslsr; | ||
915 | |||
916 | switch (get_debug_arch()) { | ||
917 | case ARM_DEBUG_ARCH_V7_1: | ||
918 | return true; | ||
919 | case ARM_DEBUG_ARCH_V7_ECP14: | ||
920 | ARM_DBG_READ(c1, c1, 4, oslsr); | ||
921 | if (oslsr & ARM_OSLSR_OSLM0) | ||
922 | return true; | ||
923 | default: | ||
924 | return false; | ||
925 | } | ||
926 | } | ||
927 | |||
906 | static void reset_ctrl_regs(void *unused) | 928 | static void reset_ctrl_regs(void *unused) |
907 | { | 929 | { |
908 | int i, raw_num_brps, err = 0, cpu = smp_processor_id(); | 930 | int i, raw_num_brps, err = 0, cpu = smp_processor_id(); |
@@ -930,11 +952,7 @@ static void reset_ctrl_regs(void *unused) | |||
930 | if ((val & 0x1) == 0) | 952 | if ((val & 0x1) == 0) |
931 | err = -EPERM; | 953 | err = -EPERM; |
932 | 954 | ||
933 | /* | 955 | if (!has_ossr) |
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; | 956 | goto clear_vcr; |
939 | break; | 957 | break; |
940 | case ARM_DEBUG_ARCH_V7_1: | 958 | case ARM_DEBUG_ARCH_V7_1: |
@@ -955,9 +973,9 @@ static void reset_ctrl_regs(void *unused) | |||
955 | 973 | ||
956 | /* | 974 | /* |
957 | * Unconditionally clear the OS lock by writing a value | 975 | * Unconditionally clear the OS lock by writing a value |
958 | * other than 0xC5ACCE55 to the access register. | 976 | * other than CS_LAR_KEY to the access register. |
959 | */ | 977 | */ |
960 | ARM_DBG_WRITE(c1, c0, 4, 0); | 978 | ARM_DBG_WRITE(c1, c0, 4, ~CS_LAR_KEY); |
961 | isb(); | 979 | isb(); |
962 | 980 | ||
963 | /* | 981 | /* |
@@ -1015,6 +1033,30 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { | |||
1015 | .notifier_call = dbg_reset_notify, | 1033 | .notifier_call = dbg_reset_notify, |
1016 | }; | 1034 | }; |
1017 | 1035 | ||
1036 | #ifdef CONFIG_CPU_PM | ||
1037 | static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action, | ||
1038 | void *v) | ||
1039 | { | ||
1040 | if (action == CPU_PM_EXIT) | ||
1041 | reset_ctrl_regs(NULL); | ||
1042 | |||
1043 | return NOTIFY_OK; | ||
1044 | } | ||
1045 | |||
1046 | static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = { | ||
1047 | .notifier_call = dbg_cpu_pm_notify, | ||
1048 | }; | ||
1049 | |||
1050 | static void __init pm_init(void) | ||
1051 | { | ||
1052 | cpu_pm_register_notifier(&dbg_cpu_pm_nb); | ||
1053 | } | ||
1054 | #else | ||
1055 | static inline void pm_init(void) | ||
1056 | { | ||
1057 | } | ||
1058 | #endif | ||
1059 | |||
1018 | static int __init arch_hw_breakpoint_init(void) | 1060 | static int __init arch_hw_breakpoint_init(void) |
1019 | { | 1061 | { |
1020 | debug_arch = get_debug_arch(); | 1062 | debug_arch = get_debug_arch(); |
@@ -1024,6 +1066,8 @@ static int __init arch_hw_breakpoint_init(void) | |||
1024 | return 0; | 1066 | return 0; |
1025 | } | 1067 | } |
1026 | 1068 | ||
1069 | has_ossr = core_has_os_save_restore(); | ||
1070 | |||
1027 | /* Determine how many BRPs/WRPs are available. */ | 1071 | /* Determine how many BRPs/WRPs are available. */ |
1028 | core_num_brps = get_num_brps(); | 1072 | core_num_brps = get_num_brps(); |
1029 | core_num_wrps = get_num_wrps(); | 1073 | core_num_wrps = get_num_wrps(); |
@@ -1062,8 +1106,9 @@ static int __init arch_hw_breakpoint_init(void) | |||
1062 | hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, | 1106 | hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, |
1063 | TRAP_HWBKPT, "breakpoint debug exception"); | 1107 | TRAP_HWBKPT, "breakpoint debug exception"); |
1064 | 1108 | ||
1065 | /* Register hotplug notifier. */ | 1109 | /* Register hotplug and PM notifiers. */ |
1066 | register_cpu_notifier(&dbg_reset_nb); | 1110 | register_cpu_notifier(&dbg_reset_nb); |
1111 | pm_init(); | ||
1067 | return 0; | 1112 | return 0; |
1068 | } | 1113 | } |
1069 | arch_initcall(arch_hw_breakpoint_init); | 1114 | arch_initcall(arch_hw_breakpoint_init); |