aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorJayachandran C <jayachandranc@netlogicmicro.com>2011-11-15 19:21:29 -0500
committerRalf Baechle <ralf@linux-mips.org>2011-12-07 17:04:56 -0500
commit66d29985fab8207b1b2c03ac34a2c294c5b47a30 (patch)
treef73145e09c53606716266577eef5e14262129ed9 /arch/mips
parent8da24631e60438631112e6fdd198ef62416ff14a (diff)
MIPS: Netlogic: Merge some of XLR/XLP wakup code
Create a common NMI and reset handler in smpboot.S and use this for both XLR and XLP. In the earlier code, the woken up CPUs would busy wait until released, switch this to wakeup by NMI. The initial wakeup code or XLR and XLP are differ since they are started from different bootloaders (XLP from u-boot and XLR from netlogic bootloader). But in both platforms the woken up CPUs wait and are released by sending an NMI. Add support for starting XLR and XLP in 1/2/4 threads per core. Signed-off-by: Jayachandran C <jayachandranc@netlogicmicro.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2970/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/netlogic/common.h26
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/xlp.h7
-rw-r--r--arch/mips/include/asm/netlogic/xlr/xlr.h2
-rw-r--r--arch/mips/netlogic/common/Makefile2
-rw-r--r--arch/mips/netlogic/common/smp.c75
-rw-r--r--arch/mips/netlogic/common/smpboot.S (renamed from arch/mips/netlogic/xlp/smpboot.S)127
-rw-r--r--arch/mips/netlogic/xlp/Makefile2
-rw-r--r--arch/mips/netlogic/xlp/setup.c4
-rw-r--r--arch/mips/netlogic/xlp/wakeup.c93
-rw-r--r--arch/mips/netlogic/xlr/Makefile2
-rw-r--r--arch/mips/netlogic/xlr/setup.c7
-rw-r--r--arch/mips/netlogic/xlr/smpboot.S100
-rw-r--r--arch/mips/netlogic/xlr/wakeup.c17
13 files changed, 234 insertions, 230 deletions
diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h
index e5bdf8c529ff..fdd2f44c7b59 100644
--- a/arch/mips/include/asm/netlogic/common.h
+++ b/arch/mips/include/asm/netlogic/common.h
@@ -38,19 +38,39 @@
38/* 38/*
39 * Common SMP definitions 39 * Common SMP definitions
40 */ 40 */
41#define RESET_VEC_PHYS 0x1fc00000
42#define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10))
43#define BOOT_THREAD_MODE 0
44#define BOOT_NMI_LOCK 4
45#define BOOT_NMI_HANDLER 8
46
47#ifndef __ASSEMBLY__
41struct irq_desc; 48struct irq_desc;
42extern struct plat_smp_ops nlm_smp_ops; 49extern struct plat_smp_ops nlm_smp_ops;
43extern char nlm_reset_entry[], nlm_reset_entry_end[]; 50extern char nlm_reset_entry[], nlm_reset_entry_end[];
44void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc); 51void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
45void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc); 52void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
46void nlm_smp_irq_init(void); 53void nlm_smp_irq_init(void);
47void prom_pre_boot_secondary_cpus(void); 54void nlm_boot_secondary_cpus(void);
48int nlm_wakeup_secondary_cpus(u32 wakeup_mask); 55int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
49void nlm_boot_smp_nmi(void); 56void nlm_rmiboot_preboot(void);
57
58static inline void
59nlm_set_nmi_handler(void *handler)
60{
61 char *reset_data;
62
63 reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
64 *(int64_t *)(reset_data + BOOT_NMI_HANDLER) = (long)handler;
65}
50 66
51/* 67/*
52 * Misc. 68 * Misc.
53 */ 69 */
70unsigned int nlm_get_cpu_frequency(void);
71
54extern unsigned long nlm_common_ebase; 72extern unsigned long nlm_common_ebase;
55unsigned int nlm_get_cpu_frequency(void); 73extern int nlm_threads_per_core;
74extern uint32_t nlm_cpumask, nlm_coremask;
75#endif
56#endif /* _NETLOGIC_COMMON_H_ */ 76#endif /* _NETLOGIC_COMMON_H_ */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
index aae23f107412..1540588e396d 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
@@ -35,17 +35,14 @@
35#ifndef _NLM_HAL_XLP_H 35#ifndef _NLM_HAL_XLP_H
36#define _NLM_HAL_XLP_H 36#define _NLM_HAL_XLP_H
37 37
38#define RESET_VEC_PHYS 0x1fc00000
39#define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10))
40#define BOOT_THREAD_MODE 0
41
42#define PIC_UART_0_IRQ 17 38#define PIC_UART_0_IRQ 17
43#define PIC_UART_1_IRQ 18 39#define PIC_UART_1_IRQ 18
44 40
45#ifndef __ASSEMBLY__ 41#ifndef __ASSEMBLY__
46 42
47/* SMP support functions */ 43/* SMP support functions */
48void nlm_boot_core0_siblings(void); 44void xlp_boot_core0_siblings(void);
45void xlp_wakeup_secondary_cpus(void);
49 46
50void xlp_mmu_init(void); 47void xlp_mmu_init(void);
51void nlm_hal_init(void); 48void nlm_hal_init(void);
diff --git a/arch/mips/include/asm/netlogic/xlr/xlr.h b/arch/mips/include/asm/netlogic/xlr/xlr.h
index f4d3f7cb6d65..ff4a17b0bf78 100644
--- a/arch/mips/include/asm/netlogic/xlr/xlr.h
+++ b/arch/mips/include/asm/netlogic/xlr/xlr.h
@@ -40,6 +40,8 @@ struct uart_port;
40unsigned int nlm_xlr_uart_in(struct uart_port *, int); 40unsigned int nlm_xlr_uart_in(struct uart_port *, int);
41void nlm_xlr_uart_out(struct uart_port *, int, int); 41void nlm_xlr_uart_out(struct uart_port *, int, int);
42 42
43/* SMP helpers */
44void xlr_wakeup_secondary_cpus(void);
43 45
44/* XLS B silicon "Rook" */ 46/* XLS B silicon "Rook" */
45static inline unsigned int nlm_chip_is_xls_b(void) 47static inline unsigned int nlm_chip_is_xls_b(void)
diff --git a/arch/mips/netlogic/common/Makefile b/arch/mips/netlogic/common/Makefile
index d4215783c3e5..291372a086f5 100644
--- a/arch/mips/netlogic/common/Makefile
+++ b/arch/mips/netlogic/common/Makefile
@@ -1,3 +1,3 @@
1obj-y += irq.o time.o 1obj-y += irq.o time.o
2obj-$(CONFIG_SMP) += smp.o 2obj-$(CONFIG_SMP) += smp.o smpboot.o
3obj-$(CONFIG_EARLY_PRINTK) += earlycons.o 3obj-$(CONFIG_EARLY_PRINTK) += earlycons.o
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index c1960439f7e1..476c93ef3037 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -47,10 +47,12 @@
47 47
48#if defined(CONFIG_CPU_XLP) 48#if defined(CONFIG_CPU_XLP)
49#include <asm/netlogic/xlp-hal/iomap.h> 49#include <asm/netlogic/xlp-hal/iomap.h>
50#include <asm/netlogic/xlp-hal/xlp.h>
50#include <asm/netlogic/xlp-hal/pic.h> 51#include <asm/netlogic/xlp-hal/pic.h>
51#elif defined(CONFIG_CPU_XLR) 52#elif defined(CONFIG_CPU_XLR)
52#include <asm/netlogic/xlr/iomap.h> 53#include <asm/netlogic/xlr/iomap.h>
53#include <asm/netlogic/xlr/pic.h> 54#include <asm/netlogic/xlr/pic.h>
55#include <asm/netlogic/xlr/xlr.h>
54#else 56#else
55#error "Unknown CPU" 57#error "Unknown CPU"
56#endif 58#endif
@@ -125,10 +127,10 @@ void nlm_cpus_done(void)
125 * Boot all other cpus in the system, initialize them, and bring them into 127 * Boot all other cpus in the system, initialize them, and bring them into
126 * the boot function 128 * the boot function
127 */ 129 */
128int nlm_cpu_unblock[NR_CPUS];
129int nlm_cpu_ready[NR_CPUS]; 130int nlm_cpu_ready[NR_CPUS];
130unsigned long nlm_next_gp; 131unsigned long nlm_next_gp;
131unsigned long nlm_next_sp; 132unsigned long nlm_next_sp;
133
132cpumask_t phys_cpu_present_map; 134cpumask_t phys_cpu_present_map;
133 135
134void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) 136void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
@@ -142,7 +144,7 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
142 144
143 /* barrier */ 145 /* barrier */
144 __sync(); 146 __sync();
145 nlm_cpu_unblock[cpu] = 1; 147 nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1);
146} 148}
147 149
148void __init nlm_smp_setup(void) 150void __init nlm_smp_setup(void)
@@ -178,12 +180,81 @@ void __init nlm_smp_setup(void)
178 (unsigned long)cpu_possible_map.bits[0]); 180 (unsigned long)cpu_possible_map.bits[0]);
179 181
180 pr_info("Detected %i Slave CPU(s)\n", num_cpus); 182 pr_info("Detected %i Slave CPU(s)\n", num_cpus);
183 nlm_set_nmi_handler(nlm_boot_secondary_cpus);
181} 184}
182 185
183void nlm_prepare_cpus(unsigned int max_cpus) 186void nlm_prepare_cpus(unsigned int max_cpus)
184{ 187{
185} 188}
186 189
190static int nlm_parse_cpumask(u32 cpu_mask)
191{
192 uint32_t core0_thr_mask, core_thr_mask;
193 int threadmode, i;
194
195 core0_thr_mask = cpu_mask & 0xf;
196 switch (core0_thr_mask) {
197 case 1:
198 nlm_threads_per_core = 1;
199 threadmode = 0;
200 break;
201 case 3:
202 nlm_threads_per_core = 2;
203 threadmode = 2;
204 break;
205 case 0xf:
206 nlm_threads_per_core = 4;
207 threadmode = 3;
208 break;
209 default:
210 goto unsupp;
211 }
212
213 /* Verify other cores CPU masks */
214 nlm_coremask = 1;
215 nlm_cpumask = core0_thr_mask;
216 for (i = 1; i < 8; i++) {
217 core_thr_mask = (cpu_mask >> (i * 4)) & 0xf;
218 if (core_thr_mask) {
219 if (core_thr_mask != core0_thr_mask)
220 goto unsupp;
221 nlm_coremask |= 1 << i;
222 nlm_cpumask |= core0_thr_mask << (4 * i);
223 }
224 }
225 return threadmode;
226
227unsupp:
228 panic("Unsupported CPU mask %x\n", cpu_mask);
229 return 0;
230}
231
232int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
233{
234 unsigned long reset_vec;
235 char *reset_data;
236 int threadmode;
237
238 /* Update reset entry point with CPU init code */
239 reset_vec = CKSEG1ADDR(RESET_VEC_PHYS);
240 memcpy((void *)reset_vec, (void *)nlm_reset_entry,
241 (nlm_reset_entry_end - nlm_reset_entry));
242
243 /* verify the mask and setup core config variables */
244 threadmode = nlm_parse_cpumask(wakeup_mask);
245
246 /* Setup CPU init parameters */
247 reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
248 *(int *)(reset_data + BOOT_THREAD_MODE) = threadmode;
249
250#ifdef CONFIG_CPU_XLP
251 xlp_wakeup_secondary_cpus();
252#else
253 xlr_wakeup_secondary_cpus();
254#endif
255 return 0;
256}
257
187struct plat_smp_ops nlm_smp_ops = { 258struct plat_smp_ops nlm_smp_ops = {
188 .send_ipi_single = nlm_send_ipi_single, 259 .send_ipi_single = nlm_send_ipi_single,
189 .send_ipi_mask = nlm_send_ipi_mask, 260 .send_ipi_mask = nlm_send_ipi_mask,
diff --git a/arch/mips/netlogic/xlp/smpboot.S b/arch/mips/netlogic/common/smpboot.S
index 7dd323234d70..c138b1a6dec3 100644
--- a/arch/mips/netlogic/xlp/smpboot.S
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -42,6 +42,8 @@
42#include <asm/asmmacro.h> 42#include <asm/asmmacro.h>
43#include <asm/addrspace.h> 43#include <asm/addrspace.h>
44 44
45#include <asm/netlogic/common.h>
46
45#include <asm/netlogic/xlp-hal/iomap.h> 47#include <asm/netlogic/xlp-hal/iomap.h>
46#include <asm/netlogic/xlp-hal/xlp.h> 48#include <asm/netlogic/xlp-hal/xlp.h>
47#include <asm/netlogic/xlp-hal/sys.h> 49#include <asm/netlogic/xlp-hal/sys.h>
@@ -67,11 +69,37 @@
67 mtcr t1, t0 69 mtcr t1, t0
68.endm 70.endm
69 71
72/*
73 * The cores can come start when they are woken up. This is also the NMI
74 * entry, so check that first.
75 *
76 * The data corresponding to reset is stored at RESET_DATA_PHYS location,
77 * this will have the thread mask (used when core is woken up) and the
78 * current NMI handler in case we reached here for an NMI.
79 *
80 * When a core or thread is newly woken up, it loops in a 'wait'. When
81 * the CPU really needs waking up, we send an NMI to it, with the NMI
82 * handler set to prom_boot_secondary_cpus
83 */
84
70 .set noreorder 85 .set noreorder
86 .set noat
71 .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ 87 .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
72 88
73 __CPUINIT 89FEXPORT(nlm_reset_entry)
74EXPORT(nlm_reset_entry) 90 dmtc0 k0, $22, 6
91 dmtc0 k1, $22, 7
92 mfc0 k0, CP0_STATUS
93 li k1, 0x80000
94 and k1, k0, k1
95 beqz k1, 1f /* go to real reset entry */
96 nop
97 li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
98 ld k0, BOOT_NMI_HANDLER(k1)
99 jr k0
100 nop
101
1021: /* Entry point on core wakeup */
75 mfc0 t0, CP0_EBASE, 1 103 mfc0 t0, CP0_EBASE, 1
76 mfc0 t1, CP0_EBASE, 1 104 mfc0 t1, CP0_EBASE, 1
77 srl t1, 5 105 srl t1, 5
@@ -128,7 +156,7 @@ EXPORT(nlm_boot_siblings)
128 ehb 156 ehb
129#endif 157#endif
130 158
1312: beqz v0, 3f 1592: beqz v0, 4f
132 nop 160 nop
133 161
134 /* setup status reg */ 162 /* setup status reg */
@@ -140,17 +168,22 @@ EXPORT(nlm_boot_siblings)
140 ori t1, ST0_KX 168 ori t1, ST0_KX
141#endif 169#endif
142 mtc0 t1, CP0_STATUS 170 mtc0 t1, CP0_STATUS
143 171 /* mark CPU ready */
144 /* SETUP TLBs for a mapped kernel here */ 172 PTR_LA t1, nlm_cpu_ready
145 PTR_LA t0, prom_pre_boot_secondary_cpus 173 sll v1, v0, 2
146 jalr t0 174 PTR_ADDU t1, v1
175 li t2, 1
176 sw t2, 0(t1)
177 /* Wait until NMI hits */
1783: wait
179 j 3b
147 nop 180 nop
148 181
149 /* 182 /*
150 * For the boot CPU, we have to restore registers and 183 * For the boot CPU, we have to restore registers and
151 * return 184 * return
152 */ 185 */
1533: dmfc0 t0, $4, 2 /* restore SP from UserLocal */ 1864: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
154 li t1, 0xfadebeef 187 li t1, 0xfadebeef
155 dmtc0 t1, $4, 2 /* restore SP from UserLocal */ 188 dmtc0 t1, $4, 2 /* restore SP from UserLocal */
156 PTR_SUBU sp, t0, PT_SIZE 189 PTR_SUBU sp, t0, PT_SIZE
@@ -159,7 +192,7 @@ EXPORT(nlm_boot_siblings)
159 nop 192 nop
160EXPORT(nlm_reset_entry_end) 193EXPORT(nlm_reset_entry_end)
161 194
162EXPORT(nlm_boot_core0_siblings) /* "Master" (n0c0t0) cpu starts from here */ 195FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
163 __config_lsu 196 __config_lsu
164 dmtc0 sp, $4, 2 /* SP saved in UserLocal */ 197 dmtc0 sp, $4, 2 /* SP saved in UserLocal */
165 SAVE_ALL 198 SAVE_ALL
@@ -173,34 +206,11 @@ EXPORT(nlm_boot_core0_siblings) /* "Master" (n0c0t0) cpu starts from here */
173 /* call it */ 206 /* call it */
174 jr t2 207 jr t2
175 nop 208 nop
176 __FINIT 209 /* not reached */
177 210
178 __CPUINIT 211 __CPUINIT
179NESTED(prom_pre_boot_secondary_cpus, 16, sp) 212NESTED(nlm_boot_secondary_cpus, 16, sp)
180 .set mips64 213 PTR_LA t1, nlm_next_sp
181 mfc0 a0, CP0_EBASE, 1 /* read ebase */
182 andi a0, 0x3ff /* a0 has the processor_id() */
183 sll t0, a0, 2 /* offset in cpu array */
184
185 PTR_LA t1, nlm_cpu_ready /* mark CPU ready */
186 PTR_ADDU t1, t0
187 li t2, 1
188 sw t2, 0(t1)
189
190 PTR_LA t1, nlm_cpu_unblock
191 PTR_ADDU t1, t0
1921: lw t2, 0(t1) /* wait till unblocked */
193 bnez t2, 2f
194 nop
195 nop
196 nop
197 nop
198 nop
199 nop
200 j 1b
201 nop
202
2032: PTR_LA t1, nlm_next_sp
204 PTR_L sp, 0(t1) 214 PTR_L sp, 0(t1)
205 PTR_LA t1, nlm_next_gp 215 PTR_LA t1, nlm_next_gp
206 PTR_L gp, 0(t1) 216 PTR_L gp, 0(t1)
@@ -213,5 +223,50 @@ NESTED(prom_pre_boot_secondary_cpus, 16, sp)
213 PTR_LA t0, smp_bootstrap 223 PTR_LA t0, smp_bootstrap
214 jr t0 224 jr t0
215 nop 225 nop
216END(prom_pre_boot_secondary_cpus) 226END(nlm_boot_secondary_cpus)
227 __FINIT
228
229/*
230 * In case of RMIboot bootloader which is used on XLR boards, the CPUs
231 * be already woken up and waiting in bootloader code.
232 * This will get them out of the bootloader code and into linux. Needed
233 * because the bootloader area will be taken and initialized by linux.
234 */
235 __CPUINIT
236NESTED(nlm_rmiboot_preboot, 16, sp)
237 mfc0 t0, $15, 1 # read ebase
238 andi t0, 0x1f # t0 has the processor_id()
239 andi t2, t0, 0x3 # thread no
240 sll t0, 2 # offset in cpu array
241
242 PTR_LA t1, nlm_cpu_ready # mark CPU ready
243 PTR_ADDU t1, t0
244 li t3, 1
245 sw t3, 0(t1)
246
247 bnez t2, 1f # skip thread programming
248 nop # for non zero hw threads
249
250 /*
251 * MMU setup only for first thread in core
252 */
253 li t0, 0x400
254 mfcr t1, t0
255 li t2, 6 # XLR thread mode mask
256 nor t3, t2, zero
257 and t2, t1, t2 # t2 - current thread mode
258 li v0, CKSEG1ADDR(RESET_DATA_PHYS)
259 lw v1, BOOT_THREAD_MODE(v0) # v1 - new thread mode
260 sll v1, 1
261 beq v1, t2, 1f # same as request value
262 nop # nothing to do */
263
264 and t2, t1, t3 # mask out old thread mode
265 or t1, t2, v1 # put in new value
266 mtcr t1, t0 # update core control
267
2681: wait
269 j 1b
270 nop
271END(nlm_rmiboot_preboot)
217 __FINIT 272 __FINIT
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile
index 1940d1c946d0..b93ed83474ec 100644
--- a/arch/mips/netlogic/xlp/Makefile
+++ b/arch/mips/netlogic/xlp/Makefile
@@ -1,2 +1,2 @@
1obj-y += setup.o platform.o nlm_hal.o 1obj-y += setup.o platform.o nlm_hal.o
2obj-$(CONFIG_SMP) += smpboot.o wakeup.o 2obj-$(CONFIG_SMP) += wakeup.o
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index f40a0e73580f..acb677a1227c 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -51,6 +51,10 @@
51 51
52unsigned long nlm_common_ebase = 0x0; 52unsigned long nlm_common_ebase = 0x0;
53 53
54/* default to uniprocessor */
55uint32_t nlm_coremask = 1, nlm_cpumask = 1;
56int nlm_threads_per_core = 1;
57
54static void nlm_linux_exit(void) 58static void nlm_linux_exit(void)
55{ 59{
56 nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1); 60 nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1);
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c
index e081a778678e..44d923ff3846 100644
--- a/arch/mips/netlogic/xlp/wakeup.c
+++ b/arch/mips/netlogic/xlp/wakeup.c
@@ -51,18 +51,20 @@
51#include <asm/netlogic/xlp-hal/xlp.h> 51#include <asm/netlogic/xlp-hal/xlp.h>
52#include <asm/netlogic/xlp-hal/sys.h> 52#include <asm/netlogic/xlp-hal/sys.h>
53 53
54unsigned long secondary_entry; 54static void xlp_enable_secondary_cores(void)
55uint32_t nlm_coremask;
56unsigned int nlm_threads_per_core;
57unsigned int nlm_threadmode;
58
59static void nlm_enable_secondary_cores(unsigned int cores_bitmap)
60{ 55{
61 uint32_t core, value, coremask; 56 uint32_t core, value, coremask, syscoremask;
57 int count;
58
59 /* read cores in reset from SYS block */
60 syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
61
62 /* update user specified */
63 nlm_coremask = nlm_coremask & (syscoremask | 1);
62 64
63 for (core = 1; core < 8; core++) { 65 for (core = 1; core < 8; core++) {
64 coremask = 1 << core; 66 coremask = 1 << core;
65 if ((cores_bitmap & coremask) == 0) 67 if ((nlm_coremask & coremask) == 0)
66 continue; 68 continue;
67 69
68 /* Enable CPU clock */ 70 /* Enable CPU clock */
@@ -76,74 +78,25 @@ static void nlm_enable_secondary_cores(unsigned int cores_bitmap)
76 nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value); 78 nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value);
77 79
78 /* Poll for CPU to mark itself coherent */ 80 /* Poll for CPU to mark itself coherent */
81 count = 100000;
79 do { 82 do {
80 value = nlm_read_sys_reg(nlm_sys_base, 83 value = nlm_read_sys_reg(nlm_sys_base,
81 SYS_CPU_NONCOHERENT_MODE); 84 SYS_CPU_NONCOHERENT_MODE);
82 } while ((value & coremask) != 0); 85 } while ((value & coremask) != 0 && count-- > 0);
83 }
84}
85
86
87static void nlm_parse_cpumask(u32 cpu_mask)
88{
89 uint32_t core0_thr_mask, core_thr_mask;
90 int i;
91 86
92 core0_thr_mask = cpu_mask & 0xf; 87 if (count == 0)
93 switch (core0_thr_mask) { 88 pr_err("Failed to enable core %d\n", core);
94 case 1:
95 nlm_threads_per_core = 1;
96 nlm_threadmode = 0;
97 break;
98 case 3:
99 nlm_threads_per_core = 2;
100 nlm_threadmode = 2;
101 break;
102 case 0xf:
103 nlm_threads_per_core = 4;
104 nlm_threadmode = 3;
105 break;
106 default:
107 goto unsupp;
108 } 89 }
109
110 /* Verify other cores CPU masks */
111 nlm_coremask = 1;
112 for (i = 1; i < 8; i++) {
113 core_thr_mask = (cpu_mask >> (i * 4)) & 0xf;
114 if (core_thr_mask) {
115 if (core_thr_mask != core0_thr_mask)
116 goto unsupp;
117 nlm_coremask |= 1 << i;
118 }
119 }
120 return;
121
122unsupp:
123 panic("Unsupported CPU mask %x\n", cpu_mask);
124} 90}
125 91
126int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask) 92void xlp_wakeup_secondary_cpus(void)
127{ 93{
128 unsigned long reset_vec; 94 /*
129 unsigned int *reset_data; 95 * In case of u-boot, the secondaries are in reset
130 96 * first wakeup core 0 threads
131 /* Update reset entry point with CPU init code */ 97 */
132 reset_vec = CKSEG1ADDR(RESET_VEC_PHYS); 98 xlp_boot_core0_siblings();
133 memcpy((void *)reset_vec, (void *)nlm_reset_entry, 99
134 (nlm_reset_entry_end - nlm_reset_entry)); 100 /* now get other cores out of reset */
135 101 xlp_enable_secondary_cores();
136 /* verify the mask and setup core config variables */
137 nlm_parse_cpumask(wakeup_mask);
138
139 /* Setup CPU init parameters */
140 reset_data = (unsigned int *)CKSEG1ADDR(RESET_DATA_PHYS);
141 reset_data[BOOT_THREAD_MODE] = nlm_threadmode;
142
143 /* first wakeup core 0 siblings */
144 nlm_boot_core0_siblings();
145
146 /* enable the reset of the cores */
147 nlm_enable_secondary_cores(nlm_coremask);
148 return 0;
149} 102}
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile
index df245c604547..f01e4d7a0600 100644
--- a/arch/mips/netlogic/xlr/Makefile
+++ b/arch/mips/netlogic/xlr/Makefile
@@ -1,2 +1,2 @@
1obj-y += setup.o platform.o 1obj-y += setup.o platform.o
2obj-$(CONFIG_SMP) += smpboot.o wakeup.o 2obj-$(CONFIG_SMP) += wakeup.o
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
index 20c280ae7e99..c9d066dedc4e 100644
--- a/arch/mips/netlogic/xlr/setup.c
+++ b/arch/mips/netlogic/xlr/setup.c
@@ -52,9 +52,14 @@
52 52
53uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE; 53uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE;
54uint64_t nlm_pic_base; 54uint64_t nlm_pic_base;
55unsigned long nlm_common_ebase = 0x0;
56struct psb_info nlm_prom_info; 55struct psb_info nlm_prom_info;
57 56
57unsigned long nlm_common_ebase = 0x0;
58
59/* default to uniprocessor */
60uint32_t nlm_coremask = 1, nlm_cpumask = 1;
61int nlm_threads_per_core = 1;
62
58static void __init nlm_early_serial_setup(void) 63static void __init nlm_early_serial_setup(void)
59{ 64{
60 struct uart_port s; 65 struct uart_port s;
diff --git a/arch/mips/netlogic/xlr/smpboot.S b/arch/mips/netlogic/xlr/smpboot.S
deleted file mode 100644
index 7f1f6e6e295f..000000000000
--- a/arch/mips/netlogic/xlr/smpboot.S
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
3 * reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the NetLogic
9 * license below:
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <linux/init.h>
36
37#include <asm/asm.h>
38#include <asm/asm-offsets.h>
39#include <asm/regdef.h>
40#include <asm/mipsregs.h>
41
42/*
43 * Early code for secondary CPUs. This will get them out of the bootloader
44 * code and into linux. Needed because the bootloader area will be taken
45 * and initialized by linux.
46 */
47 __CPUINIT
48NESTED(prom_pre_boot_secondary_cpus, 16, sp)
49 .set mips64
50 mfc0 t0, $15, 1 # read ebase
51 andi t0, 0x1f # t0 has the processor_id()
52 sll t0, 2 # offset in cpu array
53
54 PTR_LA t1, nlm_cpu_ready # mark CPU ready
55 PTR_ADDU t1, t0
56 li t2, 1
57 sw t2, 0(t1)
58
59 PTR_LA t1, nlm_cpu_unblock
60 PTR_ADDU t1, t0
611: lw t2, 0(t1) # wait till unblocked
62 beqz t2, 1b
63 nop
64
65 PTR_LA t1, nlm_next_sp
66 PTR_L sp, 0(t1)
67 PTR_LA t1, nlm_next_gp
68 PTR_L gp, 0(t1)
69
70 PTR_LA t0, nlm_early_init_secondary
71 jalr t0
72 nop
73
74 PTR_LA t0, smp_bootstrap
75 jr t0
76 nop
77END(prom_pre_boot_secondary_cpus)
78
79/*
80 * NMI code, used for CPU wakeup, copied to reset entry
81 */
82EXPORT(nlm_reset_entry)
83 .set push
84 .set noat
85 .set mips64
86 .set noreorder
87
88 /* Clear the NMI and BEV bits */
89 MFC0 k0, CP0_STATUS
90 li k1, 0xffb7ffff
91 and k0, k0, k1
92 MTC0 k0, CP0_STATUS
93
94 PTR_LA k1, secondary_entry_point
95 PTR_L k0, 0(k1)
96 jr k0
97 nop
98 .set pop
99EXPORT(nlm_reset_entry_end)
100 __FINIT
diff --git a/arch/mips/netlogic/xlr/wakeup.c b/arch/mips/netlogic/xlr/wakeup.c
index 69143bb7f688..db5d987d4881 100644
--- a/arch/mips/netlogic/xlr/wakeup.c
+++ b/arch/mips/netlogic/xlr/wakeup.c
@@ -48,21 +48,18 @@
48#include <asm/netlogic/xlr/iomap.h> 48#include <asm/netlogic/xlr/iomap.h>
49#include <asm/netlogic/xlr/pic.h> 49#include <asm/netlogic/xlr/pic.h>
50 50
51unsigned long secondary_entry_point; 51int __cpuinit xlr_wakeup_secondary_cpus(void)
52
53int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
54{ 52{
55 unsigned int i, boot_cpu; 53 unsigned int i, boot_cpu;
56 void *reset_vec;
57 54
58 secondary_entry_point = (unsigned long)prom_pre_boot_secondary_cpus; 55 /*
59 reset_vec = (void *)CKSEG1ADDR(0x1fc00000); 56 * In case of RMI boot, hit with NMI to get the cores
60 memcpy(reset_vec, (void *)nlm_reset_entry, 57 * from bootloader to linux code.
61 (nlm_reset_entry_end - nlm_reset_entry)); 58 */
62 boot_cpu = hard_smp_processor_id(); 59 boot_cpu = hard_smp_processor_id();
63 60 nlm_set_nmi_handler(nlm_rmiboot_preboot);
64 for (i = 0; i < NR_CPUS; i++) { 61 for (i = 0; i < NR_CPUS; i++) {
65 if (i == boot_cpu || (wakeup_mask & (1u << i)) == 0) 62 if (i == boot_cpu || (nlm_cpumask & (1u << i)) == 0)
66 continue; 63 continue;
67 nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */ 64 nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */
68 } 65 }