aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/common/Makefile2
-rw-r--r--arch/arm/common/mcpm_head.S41
-rw-r--r--arch/arm/kernel/asm-offsets.c1
3 files changed, 38 insertions, 6 deletions
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index b070671033ae..9ec273188ccb 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -11,4 +11,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
11obj-$(CONFIG_SHARP_SCOOP) += scoop.o 11obj-$(CONFIG_SHARP_SCOOP) += scoop.o
12obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o 12obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
13obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o 13obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
14obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o 14obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o vlock.o
diff --git a/arch/arm/common/mcpm_head.S b/arch/arm/common/mcpm_head.S
index 7d729bd72674..8178705c4b24 100644
--- a/arch/arm/common/mcpm_head.S
+++ b/arch/arm/common/mcpm_head.S
@@ -16,6 +16,8 @@
16#include <linux/linkage.h> 16#include <linux/linkage.h>
17#include <asm/mcpm.h> 17#include <asm/mcpm.h>
18 18
19#include "vlock.h"
20
19.if MCPM_SYNC_CLUSTER_CPUS 21.if MCPM_SYNC_CLUSTER_CPUS
20.error "cpus must be the first member of struct mcpm_sync_struct" 22.error "cpus must be the first member of struct mcpm_sync_struct"
21.endif 23.endif
@@ -69,10 +71,11 @@ ENTRY(mcpm_entry_point)
69 * position independent way. 71 * position independent way.
70 */ 72 */
71 adr r5, 3f 73 adr r5, 3f
72 ldmia r5, {r6, r7, r8} 74 ldmia r5, {r6, r7, r8, r11}
73 add r6, r5, r6 @ r6 = mcpm_entry_vectors 75 add r6, r5, r6 @ r6 = mcpm_entry_vectors
74 ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys 76 ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys
75 add r8, r5, r8 @ r8 = mcpm_sync 77 add r8, r5, r8 @ r8 = mcpm_sync
78 add r11, r5, r11 @ r11 = first_man_locks
76 79
77 mov r0, #MCPM_SYNC_CLUSTER_SIZE 80 mov r0, #MCPM_SYNC_CLUSTER_SIZE
78 mla r8, r0, r10, r8 @ r8 = sync cluster base 81 mla r8, r0, r10, r8 @ r8 = sync cluster base
@@ -86,13 +89,22 @@ ENTRY(mcpm_entry_point)
86 @ At this point, the cluster cannot unexpectedly enter the GOING_DOWN 89 @ At this point, the cluster cannot unexpectedly enter the GOING_DOWN
87 @ state, because there is at least one active CPU (this CPU). 90 @ state, because there is at least one active CPU (this CPU).
88 91
89 @ Note: the following is racy as another CPU might be testing 92 mov r0, #VLOCK_SIZE
90 @ the same flag at the same moment. That'll be fixed later. 93 mla r11, r0, r10, r11 @ r11 = cluster first man lock
94 mov r0, r11
95 mov r1, r9 @ cpu
96 bl vlock_trylock @ implies DMB
97
98 cmp r0, #0 @ failed to get the lock?
99 bne mcpm_setup_wait @ wait for cluster setup if so
100
91 ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] 101 ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
92 cmp r0, #CLUSTER_UP @ cluster already up? 102 cmp r0, #CLUSTER_UP @ cluster already up?
93 bne mcpm_setup @ if not, set up the cluster 103 bne mcpm_setup @ if not, set up the cluster
94 104
95 @ Otherwise, skip setup: 105 @ Otherwise, release the first man lock and skip setup:
106 mov r0, r11
107 bl vlock_unlock
96 b mcpm_setup_complete 108 b mcpm_setup_complete
97 109
98mcpm_setup: 110mcpm_setup:
@@ -142,6 +154,19 @@ mcpm_setup_leave:
142 dsb 154 dsb
143 sev 155 sev
144 156
157 mov r0, r11
158 bl vlock_unlock @ implies DMB
159 b mcpm_setup_complete
160
161 @ In the contended case, non-first men wait here for cluster setup
162 @ to complete:
163mcpm_setup_wait:
164 ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
165 cmp r0, #CLUSTER_UP
166 wfene
167 bne mcpm_setup_wait
168 dmb
169
145mcpm_setup_complete: 170mcpm_setup_complete:
146 @ If a platform-specific CPU setup hook is needed, it is 171 @ If a platform-specific CPU setup hook is needed, it is
147 @ called from here. 172 @ called from here.
@@ -173,11 +198,17 @@ mcpm_entry_gated:
1733: .word mcpm_entry_vectors - . 1983: .word mcpm_entry_vectors - .
174 .word mcpm_power_up_setup_phys - 3b 199 .word mcpm_power_up_setup_phys - 3b
175 .word mcpm_sync - 3b 200 .word mcpm_sync - 3b
201 .word first_man_locks - 3b
176 202
177ENDPROC(mcpm_entry_point) 203ENDPROC(mcpm_entry_point)
178 204
179 .bss 205 .bss
180 .align 5 206
207 .align CACHE_WRITEBACK_ORDER
208 .type first_man_locks, #object
209first_man_locks:
210 .space VLOCK_SIZE * MAX_NR_CLUSTERS
211 .align CACHE_WRITEBACK_ORDER
181 212
182 .type mcpm_entry_vectors, #object 213 .type mcpm_entry_vectors, #object
183ENTRY(mcpm_entry_vectors) 214ENTRY(mcpm_entry_vectors)
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 1bed82a0a9e0..3f088225e71c 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -150,6 +150,7 @@ int main(void)
150 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE); 150 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
151 DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE); 151 DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
152 BLANK(); 152 BLANK();
153 DEFINE(CACHE_WRITEBACK_ORDER, __CACHE_WRITEBACK_ORDER);
153 DEFINE(CACHE_WRITEBACK_GRANULE, __CACHE_WRITEBACK_GRANULE); 154 DEFINE(CACHE_WRITEBACK_GRANULE, __CACHE_WRITEBACK_GRANULE);
154 BLANK(); 155 BLANK();
155#ifdef CONFIG_KVM_ARM_HOST 156#ifdef CONFIG_KVM_ARM_HOST