diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/Kconfig | 1 | ||||
-rw-r--r-- | arch/blackfin/include/asm/smp.h | 7 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 37 | ||||
-rw-r--r-- | arch/blackfin/kernel/vmlinux.lds.S | 1 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/secondary.S | 7 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/smp.c | 9 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cache.S | 20 | ||||
-rw-r--r-- | arch/blackfin/mach-common/smp.c | 4 |
8 files changed, 74 insertions, 12 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 0f34ec58bac3..c4cda6f52b61 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -850,7 +850,6 @@ config CPLB_SWITCH_TAB_L1 | |||
850 | config ICACHE_FLUSH_L1 | 850 | config ICACHE_FLUSH_L1 |
851 | bool "Locate icache flush funcs in L1 Inst Memory" | 851 | bool "Locate icache flush funcs in L1 Inst Memory" |
852 | default y | 852 | default y |
853 | depends on !SMP | ||
854 | help | 853 | help |
855 | If enabled, the Blackfin icache flushing functions are linked | 854 | If enabled, the Blackfin icache flushing functions are linked |
856 | into L1 instruction memory. | 855 | into L1 instruction memory. |
diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h index 9dd487375247..af6c0aa79bae 100644 --- a/arch/blackfin/include/asm/smp.h +++ b/arch/blackfin/include/asm/smp.h | |||
@@ -17,7 +17,12 @@ | |||
17 | 17 | ||
18 | #define raw_smp_processor_id() blackfin_core_id() | 18 | #define raw_smp_processor_id() blackfin_core_id() |
19 | 19 | ||
20 | extern char coreb_trampoline_start, coreb_trampoline_end; | 20 | extern void bfin_relocate_coreb_l1_mem(void); |
21 | |||
22 | #if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1) | ||
23 | asmlinkage void blackfin_icache_flush_range_l1(unsigned long *ptr); | ||
24 | extern unsigned long blackfin_iflush_l1_entry[NR_CPUS]; | ||
25 | #endif | ||
21 | 26 | ||
22 | struct corelock_slot { | 27 | struct corelock_slot { |
23 | int lock; | 28 | int lock; |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index ac71dc15cbdb..805c6132c779 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -215,11 +215,48 @@ void __init bfin_relocate_l1_mem(void) | |||
215 | 215 | ||
216 | early_dma_memcpy_done(); | 216 | early_dma_memcpy_done(); |
217 | 217 | ||
218 | #if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1) | ||
219 | blackfin_iflush_l1_entry[0] = (unsigned long)blackfin_icache_flush_range_l1; | ||
220 | #endif | ||
221 | |||
218 | /* if necessary, copy L2 text/data to L2 SRAM */ | 222 | /* if necessary, copy L2 text/data to L2 SRAM */ |
219 | if (L2_LENGTH && l2_len) | 223 | if (L2_LENGTH && l2_len) |
220 | memcpy(_stext_l2, _l2_lma, l2_len); | 224 | memcpy(_stext_l2, _l2_lma, l2_len); |
221 | } | 225 | } |
222 | 226 | ||
227 | #ifdef CONFIG_SMP | ||
228 | void __init bfin_relocate_coreb_l1_mem(void) | ||
229 | { | ||
230 | unsigned long text_l1_len = (unsigned long)_text_l1_len; | ||
231 | unsigned long data_l1_len = (unsigned long)_data_l1_len; | ||
232 | unsigned long data_b_l1_len = (unsigned long)_data_b_l1_len; | ||
233 | |||
234 | blackfin_dma_early_init(); | ||
235 | |||
236 | /* if necessary, copy L1 text to L1 instruction SRAM */ | ||
237 | if (L1_CODE_LENGTH && text_l1_len) | ||
238 | early_dma_memcpy((void *)COREB_L1_CODE_START, _text_l1_lma, | ||
239 | text_l1_len); | ||
240 | |||
241 | /* if necessary, copy L1 data to L1 data bank A SRAM */ | ||
242 | if (L1_DATA_A_LENGTH && data_l1_len) | ||
243 | early_dma_memcpy((void *)COREB_L1_DATA_A_START, _data_l1_lma, | ||
244 | data_l1_len); | ||
245 | |||
246 | /* if necessary, copy L1 data B to L1 data bank B SRAM */ | ||
247 | if (L1_DATA_B_LENGTH && data_b_l1_len) | ||
248 | early_dma_memcpy((void *)COREB_L1_DATA_B_START, _data_b_l1_lma, | ||
249 | data_b_l1_len); | ||
250 | |||
251 | early_dma_memcpy_done(); | ||
252 | |||
253 | #ifdef CONFIG_ICACHE_FLUSH_L1 | ||
254 | blackfin_iflush_l1_entry[1] = (unsigned long)blackfin_icache_flush_range_l1 - | ||
255 | (unsigned long)_stext_l1 + COREB_L1_CODE_START; | ||
256 | #endif | ||
257 | } | ||
258 | #endif | ||
259 | |||
223 | #ifdef CONFIG_ROMKERNEL | 260 | #ifdef CONFIG_ROMKERNEL |
224 | void __init bfin_relocate_xip_data(void) | 261 | void __init bfin_relocate_xip_data(void) |
225 | { | 262 | { |
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index f5fd234e5773..854fa49f1c3e 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S | |||
@@ -176,6 +176,7 @@ SECTIONS | |||
176 | { | 176 | { |
177 | . = ALIGN(4); | 177 | . = ALIGN(4); |
178 | __stext_l1 = .; | 178 | __stext_l1 = .; |
179 | *(.l1.text.head) | ||
179 | *(.l1.text) | 180 | *(.l1.text) |
180 | #ifdef CONFIG_SCHEDULE_L1 | 181 | #ifdef CONFIG_SCHEDULE_L1 |
181 | SCHED_TEXT | 182 | SCHED_TEXT |
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S index 148e50764555..4c462838f4e1 100644 --- a/arch/blackfin/mach-bf561/secondary.S +++ b/arch/blackfin/mach-bf561/secondary.S | |||
@@ -13,7 +13,11 @@ | |||
13 | #include <asm/asm-offsets.h> | 13 | #include <asm/asm-offsets.h> |
14 | #include <asm/trace.h> | 14 | #include <asm/trace.h> |
15 | 15 | ||
16 | __INIT | 16 | /* |
17 | * This code must come first as CoreB is hardcoded (in hardware) | ||
18 | * to start at the beginning of its L1 instruction memory. | ||
19 | */ | ||
20 | .section .l1.text.head | ||
17 | 21 | ||
18 | /* Lay the initial stack into the L1 scratch area of Core B */ | 22 | /* Lay the initial stack into the L1 scratch area of Core B */ |
19 | #define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) | 23 | #define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) |
@@ -160,7 +164,6 @@ ENTRY(_coreb_trampoline_start) | |||
160 | .LWAIT_HERE: | 164 | .LWAIT_HERE: |
161 | jump .LWAIT_HERE; | 165 | jump .LWAIT_HERE; |
162 | ENDPROC(_coreb_trampoline_start) | 166 | ENDPROC(_coreb_trampoline_start) |
163 | ENTRY(_coreb_trampoline_end) | ||
164 | 167 | ||
165 | #ifdef CONFIG_HOTPLUG_CPU | 168 | #ifdef CONFIG_HOTPLUG_CPU |
166 | .section ".text" | 169 | .section ".text" |
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c index 1074a7ef81c7..82b94e137886 100644 --- a/arch/blackfin/mach-bf561/smp.c +++ b/arch/blackfin/mach-bf561/smp.c | |||
@@ -30,18 +30,11 @@ void __init platform_init_cpus(void) | |||
30 | 30 | ||
31 | void __init platform_prepare_cpus(unsigned int max_cpus) | 31 | void __init platform_prepare_cpus(unsigned int max_cpus) |
32 | { | 32 | { |
33 | int len; | 33 | bfin_relocate_coreb_l1_mem(); |
34 | |||
35 | len = &coreb_trampoline_end - &coreb_trampoline_start + 1; | ||
36 | BUG_ON(len > L1_CODE_LENGTH); | ||
37 | |||
38 | dma_memcpy((void *)COREB_L1_CODE_START, &coreb_trampoline_start, len); | ||
39 | 34 | ||
40 | /* Both cores ought to be present on a bf561! */ | 35 | /* Both cores ought to be present on a bf561! */ |
41 | cpu_set(0, cpu_present_map); /* CoreA */ | 36 | cpu_set(0, cpu_present_map); /* CoreA */ |
42 | cpu_set(1, cpu_present_map); /* CoreB */ | 37 | cpu_set(1, cpu_present_map); /* CoreB */ |
43 | |||
44 | printk(KERN_INFO "CoreB bootstrap code to SRAM %p via DMA.\n", (void *)COREB_L1_CODE_START); | ||
45 | } | 38 | } |
46 | 39 | ||
47 | int __init setup_profiling_timer(unsigned int multiplier) /* not supported */ | 40 | int __init setup_profiling_timer(unsigned int multiplier) /* not supported */ |
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S index 85aadeb76658..9f4dd35bfd74 100644 --- a/arch/blackfin/mach-common/cache.S +++ b/arch/blackfin/mach-common/cache.S | |||
@@ -69,10 +69,30 @@ | |||
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | /* Invalidate all instruction cache lines assocoiated with this memory area */ | 71 | /* Invalidate all instruction cache lines assocoiated with this memory area */ |
72 | #ifdef CONFIG_SMP | ||
73 | # define _blackfin_icache_flush_range _blackfin_icache_flush_range_l1 | ||
74 | #endif | ||
72 | ENTRY(_blackfin_icache_flush_range) | 75 | ENTRY(_blackfin_icache_flush_range) |
73 | do_flush IFLUSH | 76 | do_flush IFLUSH |
74 | ENDPROC(_blackfin_icache_flush_range) | 77 | ENDPROC(_blackfin_icache_flush_range) |
75 | 78 | ||
79 | #ifdef CONFIG_SMP | ||
80 | .text | ||
81 | # undef _blackfin_icache_flush_range | ||
82 | ENTRY(_blackfin_icache_flush_range) | ||
83 | p0.L = LO(DSPID); | ||
84 | p0.H = HI(DSPID); | ||
85 | r3 = [p0]; | ||
86 | r3 = r3.b (z); | ||
87 | p2 = r3; | ||
88 | p0.L = _blackfin_iflush_l1_entry; | ||
89 | p0.H = _blackfin_iflush_l1_entry; | ||
90 | p0 = p0 + (p2 << 2); | ||
91 | p1 = [p0]; | ||
92 | jump (p1); | ||
93 | ENDPROC(_blackfin_icache_flush_range) | ||
94 | #endif | ||
95 | |||
76 | #ifdef CONFIG_DCACHE_FLUSH_L1 | 96 | #ifdef CONFIG_DCACHE_FLUSH_L1 |
77 | .section .l1.text | 97 | .section .l1.text |
78 | #else | 98 | #else |
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 5f7617d66905..6e17a265c4d3 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
@@ -40,6 +40,10 @@ | |||
40 | */ | 40 | */ |
41 | struct corelock_slot corelock __attribute__ ((__section__(".l2.bss"))); | 41 | struct corelock_slot corelock __attribute__ ((__section__(".l2.bss"))); |
42 | 42 | ||
43 | #ifdef CONFIG_ICACHE_FLUSH_L1 | ||
44 | unsigned long blackfin_iflush_l1_entry[NR_CPUS]; | ||
45 | #endif | ||
46 | |||
43 | void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb, | 47 | void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb, |
44 | *init_saved_seqstat_coreb, *init_saved_icplb_fault_addr_coreb, | 48 | *init_saved_seqstat_coreb, *init_saved_icplb_fault_addr_coreb, |
45 | *init_saved_dcplb_fault_addr_coreb; | 49 | *init_saved_dcplb_fault_addr_coreb; |