aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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 }