aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/common
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic/common')
-rw-r--r--arch/mips/netlogic/common/Makefile2
-rw-r--r--arch/mips/netlogic/common/irq.c7
-rw-r--r--arch/mips/netlogic/common/nlm-dma.c107
-rw-r--r--arch/mips/netlogic/common/reset.S230
-rw-r--r--arch/mips/netlogic/common/smp.c18
-rw-r--r--arch/mips/netlogic/common/smpboot.S194
6 files changed, 353 insertions, 205 deletions
diff --git a/arch/mips/netlogic/common/Makefile b/arch/mips/netlogic/common/Makefile
index 291372a086f5..362739d62b1d 100644
--- a/arch/mips/netlogic/common/Makefile
+++ b/arch/mips/netlogic/common/Makefile
@@ -1,3 +1,5 @@
1obj-y += irq.o time.o 1obj-y += irq.o time.o
2obj-y += nlm-dma.o
3obj-y += reset.o
2obj-$(CONFIG_SMP) += smp.o smpboot.o 4obj-$(CONFIG_SMP) += smp.o smpboot.o
3obj-$(CONFIG_EARLY_PRINTK) += earlycons.o 5obj-$(CONFIG_EARLY_PRINTK) += earlycons.o
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
index 9f84c60bf535..73facb2b33bb 100644
--- a/arch/mips/netlogic/common/irq.c
+++ b/arch/mips/netlogic/common/irq.c
@@ -253,13 +253,12 @@ asmlinkage void plat_irq_dispatch(void)
253 253
254 node = nlm_nodeid(); 254 node = nlm_nodeid();
255 eirr = read_c0_eirr_and_eimr(); 255 eirr = read_c0_eirr_and_eimr();
256 256 if (eirr == 0)
257 i = __ilog2_u64(eirr);
258 if (i == -1)
259 return; 257 return;
260 258
259 i = __ffs64(eirr);
261 /* per-CPU IRQs don't need translation */ 260 /* per-CPU IRQs don't need translation */
262 if (eirr & PERCPU_IRQ_MASK) { 261 if (i < PIC_IRQ_BASE) {
263 do_IRQ(i); 262 do_IRQ(i);
264 return; 263 return;
265 } 264 }
diff --git a/arch/mips/netlogic/common/nlm-dma.c b/arch/mips/netlogic/common/nlm-dma.c
new file mode 100644
index 000000000000..f3d4ae87abc7
--- /dev/null
+++ b/arch/mips/netlogic/common/nlm-dma.c
@@ -0,0 +1,107 @@
1/*
2* Copyright (C) 2003-2013 Broadcom Corporation
3* All Rights 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 Broadcom
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 BROADCOM ``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 BROADCOM 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#include <linux/dma-mapping.h>
35#include <linux/scatterlist.h>
36#include <linux/bootmem.h>
37#include <linux/export.h>
38#include <linux/swiotlb.h>
39#include <linux/types.h>
40#include <linux/init.h>
41#include <linux/mm.h>
42
43#include <asm/bootinfo.h>
44
45static char *nlm_swiotlb;
46
47static void *nlm_dma_alloc_coherent(struct device *dev, size_t size,
48 dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
49{
50 void *ret;
51
52 if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
53 return ret;
54
55 /* ignore region specifiers */
56 gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
57
58#ifdef CONFIG_ZONE_DMA32
59 if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
60 gfp |= __GFP_DMA32;
61#endif
62
63 /* Don't invoke OOM killer */
64 gfp |= __GFP_NORETRY;
65
66 return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
67}
68
69static void nlm_dma_free_coherent(struct device *dev, size_t size,
70 void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs)
71{
72 int order = get_order(size);
73
74 if (dma_release_from_coherent(dev, order, vaddr))
75 return;
76
77 swiotlb_free_coherent(dev, size, vaddr, dma_handle);
78}
79
80struct dma_map_ops nlm_swiotlb_dma_ops = {
81 .alloc = nlm_dma_alloc_coherent,
82 .free = nlm_dma_free_coherent,
83 .map_page = swiotlb_map_page,
84 .unmap_page = swiotlb_unmap_page,
85 .map_sg = swiotlb_map_sg_attrs,
86 .unmap_sg = swiotlb_unmap_sg_attrs,
87 .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
88 .sync_single_for_device = swiotlb_sync_single_for_device,
89 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
90 .sync_sg_for_device = swiotlb_sync_sg_for_device,
91 .mapping_error = swiotlb_dma_mapping_error,
92 .dma_supported = swiotlb_dma_supported
93};
94
95void __init plat_swiotlb_setup(void)
96{
97 size_t swiotlbsize;
98 unsigned long swiotlb_nslabs;
99
100 swiotlbsize = 1 << 20; /* 1 MB for now */
101 swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
102 swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
103 swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
104
105 nlm_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
106 swiotlb_init_with_tbl(nlm_swiotlb, swiotlb_nslabs, 1);
107}
diff --git a/arch/mips/netlogic/common/reset.S b/arch/mips/netlogic/common/reset.S
new file mode 100644
index 000000000000..adb18288a6c0
--- /dev/null
+++ b/arch/mips/netlogic/common/reset.S
@@ -0,0 +1,230 @@
1/*
2 * Copyright 2003-2013 Broadcom Corporation.
3 * All Rights 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 Broadcom
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 BROADCOM ``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 BROADCOM 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#include <asm/stackframe.h>
42#include <asm/asmmacro.h>
43#include <asm/addrspace.h>
44
45#include <asm/netlogic/common.h>
46
47#include <asm/netlogic/xlp-hal/iomap.h>
48#include <asm/netlogic/xlp-hal/xlp.h>
49#include <asm/netlogic/xlp-hal/sys.h>
50#include <asm/netlogic/xlp-hal/cpucontrol.h>
51
52#define CP0_EBASE $15
53#define SYS_CPU_COHERENT_BASE(node) CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
54 XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
55 SYS_CPU_NONCOHERENT_MODE * 4
56
57/* Enable XLP features and workarounds in the LSU */
58.macro xlp_config_lsu
59 li t0, LSU_DEFEATURE
60 mfcr t1, t0
61
62 lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */
63 or t1, t1, t2
64 mtcr t1, t0
65
66 li t0, ICU_DEFEATURE
67 mfcr t1, t0
68 ori t1, 0x1000 /* Enable Icache partitioning */
69 mtcr t1, t0
70
71 li t0, SCHED_DEFEATURE
72 lui t1, 0x0100 /* Disable BRU accepting ALU ops */
73 mtcr t1, t0
74.endm
75
76/*
77 * Low level flush for L1D cache on XLP, the normal cache ops does
78 * not do the complete and correct cache flush.
79 */
80.macro xlp_flush_l1_dcache
81 li t0, LSU_DEBUG_DATA0
82 li t1, LSU_DEBUG_ADDR
83 li t2, 0 /* index */
84 li t3, 0x1000 /* loop count */
851:
86 sll v0, t2, 5
87 mtcr zero, t0
88 ori v1, v0, 0x3 /* way0 | write_enable | write_active */
89 mtcr v1, t1
902:
91 mfcr v1, t1
92 andi v1, 0x1 /* wait for write_active == 0 */
93 bnez v1, 2b
94 nop
95 mtcr zero, t0
96 ori v1, v0, 0x7 /* way1 | write_enable | write_active */
97 mtcr v1, t1
983:
99 mfcr v1, t1
100 andi v1, 0x1 /* wait for write_active == 0 */
101 bnez v1, 3b
102 nop
103 addi t2, 1
104 bne t3, t2, 1b
105 nop
106.endm
107
108/*
109 * nlm_reset_entry will be copied to the reset entry point for
110 * XLR and XLP. The XLP cores start here when they are woken up. This
111 * is also the NMI entry point.
112 *
113 * We use scratch reg 6/7 to save k0/k1 and check for NMI first.
114 *
115 * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
116 * location, this will have the thread mask (used when core is woken up)
117 * and the current NMI handler in case we reached here for an NMI.
118 *
119 * When a core or thread is newly woken up, it marks itself ready and
120 * loops in a 'wait'. When the CPU really needs waking up, we send an NMI
121 * IPI to it, with the NMI handler set to prom_boot_secondary_cpus
122 */
123 .set noreorder
124 .set noat
125 .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
126
127FEXPORT(nlm_reset_entry)
128 dmtc0 k0, $22, 6
129 dmtc0 k1, $22, 7
130 mfc0 k0, CP0_STATUS
131 li k1, 0x80000
132 and k1, k0, k1
133 beqz k1, 1f /* go to real reset entry */
134 nop
135 li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
136 ld k0, BOOT_NMI_HANDLER(k1)
137 jr k0
138 nop
139
1401: /* Entry point on core wakeup */
141 mfc0 t0, CP0_EBASE, 1
142 mfc0 t1, CP0_EBASE, 1
143 srl t1, 5
144 andi t1, 0x3 /* t1 <- node */
145 li t2, 0x40000
146 mul t3, t2, t1 /* t3 = node * 0x40000 */
147 srl t0, t0, 2
148 and t0, t0, 0x7 /* t0 <- core */
149 li t1, 0x1
150 sll t0, t1, t0
151 nor t0, t0, zero /* t0 <- ~(1 << core) */
152 li t2, SYS_CPU_COHERENT_BASE(0)
153 add t2, t2, t3 /* t2 <- SYS offset for node */
154 lw t1, 0(t2)
155 and t1, t1, t0
156 sw t1, 0(t2)
157
158 /* read back to ensure complete */
159 lw t1, 0(t2)
160 sync
161
162 /* Configure LSU on Non-0 Cores. */
163 xlp_config_lsu
164 /* FALL THROUGH */
165
166/*
167 * Wake up sibling threads from the initial thread in
168 * a core.
169 */
170EXPORT(nlm_boot_siblings)
171 /* core L1D flush before enable threads */
172 xlp_flush_l1_dcache
173 /* Enable hw threads by writing to MAP_THREADMODE of the core */
174 li t0, CKSEG1ADDR(RESET_DATA_PHYS)
175 lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
176 li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
177 mfcr t2, t0
178 or t2, t2, t1
179 mtcr t2, t0
180
181 /*
182 * The new hardware thread starts at the next instruction
183 * For all the cases other than core 0 thread 0, we will
184 * jump to the secondary wait function.
185 */
186 mfc0 v0, CP0_EBASE, 1
187 andi v0, 0x3ff /* v0 <- node/core */
188
189 beqz v0, 4f /* boot cpu (cpuid == 0)? */
190 nop
191
192 /* setup status reg */
193 move t1, zero
194#ifdef CONFIG_64BIT
195 ori t1, ST0_KX
196#endif
197 mtc0 t1, CP0_STATUS
198
199 /* mark CPU ready, careful here, previous mtcr trashed registers */
200 li t3, CKSEG1ADDR(RESET_DATA_PHYS)
201 ADDIU t1, t3, BOOT_CPU_READY
202 sll v1, v0, 2
203 PTR_ADDU t1, v1
204 li t2, 1
205 sw t2, 0(t1)
206 /* Wait until NMI hits */
2073: wait
208 b 3b
209 nop
210
211 /*
212 * For the boot CPU, we have to restore registers and
213 * return
214 */
2154: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
216 li t1, 0xfadebeef
217 dmtc0 t1, $4, 2 /* restore SP from UserLocal */
218 PTR_SUBU sp, t0, PT_SIZE
219 RESTORE_ALL
220 jr ra
221 nop
222EXPORT(nlm_reset_entry_end)
223
224LEAF(nlm_init_boot_cpu)
225#ifdef CONFIG_CPU_XLP
226 xlp_config_lsu
227#endif
228 jr ra
229 nop
230END(nlm_init_boot_cpu)
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index ffba52489bef..885d293b61da 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -145,7 +145,6 @@ void nlm_cpus_done(void)
145 * Boot all other cpus in the system, initialize them, and bring them into 145 * Boot all other cpus in the system, initialize them, and bring them into
146 * the boot function 146 * the boot function
147 */ 147 */
148int nlm_cpu_ready[NR_CPUS];
149unsigned long nlm_next_gp; 148unsigned long nlm_next_gp;
150unsigned long nlm_next_sp; 149unsigned long nlm_next_sp;
151static cpumask_t phys_cpu_present_mask; 150static cpumask_t phys_cpu_present_mask;
@@ -168,6 +167,7 @@ void __init nlm_smp_setup(void)
168{ 167{
169 unsigned int boot_cpu; 168 unsigned int boot_cpu;
170 int num_cpus, i, ncore; 169 int num_cpus, i, ncore;
170 volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
171 char buf[64]; 171 char buf[64];
172 172
173 boot_cpu = hard_smp_processor_id(); 173 boot_cpu = hard_smp_processor_id();
@@ -181,10 +181,10 @@ void __init nlm_smp_setup(void)
181 num_cpus = 1; 181 num_cpus = 1;
182 for (i = 0; i < NR_CPUS; i++) { 182 for (i = 0; i < NR_CPUS; i++) {
183 /* 183 /*
184 * nlm_cpu_ready array is not set for the boot_cpu, 184 * cpu_ready array is not set for the boot_cpu,
185 * it is only set for ASPs (see smpboot.S) 185 * it is only set for ASPs (see smpboot.S)
186 */ 186 */
187 if (nlm_cpu_ready[i]) { 187 if (cpu_ready[i]) {
188 cpumask_set_cpu(i, &phys_cpu_present_mask); 188 cpumask_set_cpu(i, &phys_cpu_present_mask);
189 __cpu_number_map[i] = num_cpus; 189 __cpu_number_map[i] = num_cpus;
190 __cpu_logical_map[num_cpus] = i; 190 __cpu_logical_map[num_cpus] = i;
@@ -254,21 +254,15 @@ unsupp:
254 254
255int __cpuinit nlm_wakeup_secondary_cpus(void) 255int __cpuinit nlm_wakeup_secondary_cpus(void)
256{ 256{
257 unsigned long reset_vec; 257 u32 *reset_data;
258 char *reset_data;
259 int threadmode; 258 int threadmode;
260 259
261 /* Update reset entry point with CPU init code */
262 reset_vec = CKSEG1ADDR(RESET_VEC_PHYS);
263 memcpy((void *)reset_vec, (void *)nlm_reset_entry,
264 (nlm_reset_entry_end - nlm_reset_entry));
265
266 /* verify the mask and setup core config variables */ 260 /* verify the mask and setup core config variables */
267 threadmode = nlm_parse_cpumask(&nlm_cpumask); 261 threadmode = nlm_parse_cpumask(&nlm_cpumask);
268 262
269 /* Setup CPU init parameters */ 263 /* Setup CPU init parameters */
270 reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS); 264 reset_data = nlm_get_boot_data(BOOT_THREAD_MODE);
271 *(int *)(reset_data + BOOT_THREAD_MODE) = threadmode; 265 *reset_data = threadmode;
272 266
273#ifdef CONFIG_CPU_XLP 267#ifdef CONFIG_CPU_XLP
274 xlp_wakeup_secondary_cpus(); 268 xlp_wakeup_secondary_cpus();
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S
index 026517488584..528c46c5a170 100644
--- a/arch/mips/netlogic/common/smpboot.S
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -50,197 +50,12 @@
50#include <asm/netlogic/xlp-hal/cpucontrol.h> 50#include <asm/netlogic/xlp-hal/cpucontrol.h>
51 51
52#define CP0_EBASE $15 52#define CP0_EBASE $15
53#define SYS_CPU_COHERENT_BASE(node) CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
54 XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
55 SYS_CPU_NONCOHERENT_MODE * 4
56
57#define XLP_AX_WORKAROUND /* enable Ax silicon workarounds */
58
59/* Enable XLP features and workarounds in the LSU */
60.macro xlp_config_lsu
61 li t0, LSU_DEFEATURE
62 mfcr t1, t0
63
64 lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */
65 or t1, t1, t2
66#ifdef XLP_AX_WORKAROUND
67 li t2, ~0xe /* S1RCM */
68 and t1, t1, t2
69#endif
70 mtcr t1, t0
71
72 li t0, ICU_DEFEATURE
73 mfcr t1, t0
74 ori t1, 0x1000 /* Enable Icache partitioning */
75 mtcr t1, t0
76
77
78#ifdef XLP_AX_WORKAROUND
79 li t0, SCHED_DEFEATURE
80 lui t1, 0x0100 /* Disable BRU accepting ALU ops */
81 mtcr t1, t0
82#endif
83.endm
84
85/*
86 * This is the code that will be copied to the reset entry point for
87 * XLR and XLP. The XLP cores start here when they are woken up. This
88 * is also the NMI entry point.
89 */
90.macro xlp_flush_l1_dcache
91 li t0, LSU_DEBUG_DATA0
92 li t1, LSU_DEBUG_ADDR
93 li t2, 0 /* index */
94 li t3, 0x1000 /* loop count */
951:
96 sll v0, t2, 5
97 mtcr zero, t0
98 ori v1, v0, 0x3 /* way0 | write_enable | write_active */
99 mtcr v1, t1
1002:
101 mfcr v1, t1
102 andi v1, 0x1 /* wait for write_active == 0 */
103 bnez v1, 2b
104 nop
105 mtcr zero, t0
106 ori v1, v0, 0x7 /* way1 | write_enable | write_active */
107 mtcr v1, t1
1083:
109 mfcr v1, t1
110 andi v1, 0x1 /* wait for write_active == 0 */
111 bnez v1, 3b
112 nop
113 addi t2, 1
114 bne t3, t2, 1b
115 nop
116.endm
117
118/*
119 * The cores can come start when they are woken up. This is also the NMI
120 * entry, so check that first.
121 *
122 * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
123 * location, this will have the thread mask (used when core is woken up)
124 * and the current NMI handler in case we reached here for an NMI.
125 *
126 * When a core or thread is newly woken up, it loops in a 'wait'. When
127 * the CPU really needs waking up, we send an NMI to it, with the NMI
128 * handler set to prom_boot_secondary_cpus
129 */
130 53
131 .set noreorder 54 .set noreorder
132 .set noat 55 .set noat
133 .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ 56 .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
134
135FEXPORT(nlm_reset_entry)
136 dmtc0 k0, $22, 6
137 dmtc0 k1, $22, 7
138 mfc0 k0, CP0_STATUS
139 li k1, 0x80000
140 and k1, k0, k1
141 beqz k1, 1f /* go to real reset entry */
142 nop
143 li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
144 ld k0, BOOT_NMI_HANDLER(k1)
145 jr k0
146 nop
147
1481: /* Entry point on core wakeup */
149 mfc0 t0, CP0_EBASE, 1
150 mfc0 t1, CP0_EBASE, 1
151 srl t1, 5
152 andi t1, 0x3 /* t1 <- node */
153 li t2, 0x40000
154 mul t3, t2, t1 /* t3 = node * 0x40000 */
155 srl t0, t0, 2
156 and t0, t0, 0x7 /* t0 <- core */
157 li t1, 0x1
158 sll t0, t1, t0
159 nor t0, t0, zero /* t0 <- ~(1 << core) */
160 li t2, SYS_CPU_COHERENT_BASE(0)
161 add t2, t2, t3 /* t2 <- SYS offset for node */
162 lw t1, 0(t2)
163 and t1, t1, t0
164 sw t1, 0(t2)
165
166 /* read back to ensure complete */
167 lw t1, 0(t2)
168 sync
169
170 /* Configure LSU on Non-0 Cores. */
171 xlp_config_lsu
172 /* FALL THROUGH */
173
174/*
175 * Wake up sibling threads from the initial thread in
176 * a core.
177 */
178EXPORT(nlm_boot_siblings)
179 /* core L1D flush before enable threads */
180 xlp_flush_l1_dcache
181 /* Enable hw threads by writing to MAP_THREADMODE of the core */
182 li t0, CKSEG1ADDR(RESET_DATA_PHYS)
183 lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
184 li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
185 mfcr t2, t0
186 or t2, t2, t1
187 mtcr t2, t0
188
189 /*
190 * The new hardware thread starts at the next instruction
191 * For all the cases other than core 0 thread 0, we will
192 * jump to the secondary wait function.
193 */
194 mfc0 v0, CP0_EBASE, 1
195 andi v0, 0x3ff /* v0 <- node/core */
196
197 /* Init MMU in the first thread after changing THREAD_MODE
198 * register (Ax Errata?)
199 */
200 andi v1, v0, 0x3 /* v1 <- thread id */
201 bnez v1, 2f
202 nop
203
204 li t0, MMU_SETUP
205 li t1, 0
206 mtcr t1, t0
207 _ehb
208
2092: beqz v0, 4f /* boot cpu (cpuid == 0)? */
210 nop
211
212 /* setup status reg */
213 move t1, zero
214#ifdef CONFIG_64BIT
215 ori t1, ST0_KX
216#endif
217 mtc0 t1, CP0_STATUS
218 /* mark CPU ready */
219 PTR_LA t1, nlm_cpu_ready
220 sll v1, v0, 2
221 PTR_ADDU t1, v1
222 li t2, 1
223 sw t2, 0(t1)
224 /* Wait until NMI hits */
2253: wait
226 j 3b
227 nop
228
229 /*
230 * For the boot CPU, we have to restore registers and
231 * return
232 */
2334: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
234 li t1, 0xfadebeef
235 dmtc0 t1, $4, 2 /* restore SP from UserLocal */
236 PTR_SUBU sp, t0, PT_SIZE
237 RESTORE_ALL
238 jr ra
239 nop
240EXPORT(nlm_reset_entry_end)
241 57
242FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ 58FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
243 xlp_config_lsu
244 dmtc0 sp, $4, 2 /* SP saved in UserLocal */ 59 dmtc0 sp, $4, 2 /* SP saved in UserLocal */
245 SAVE_ALL 60 SAVE_ALL
246 sync 61 sync
@@ -294,8 +109,9 @@ NESTED(nlm_rmiboot_preboot, 16, sp)
294 andi t2, t0, 0x3 /* thread num */ 109 andi t2, t0, 0x3 /* thread num */
295 sll t0, 2 /* offset in cpu array */ 110 sll t0, 2 /* offset in cpu array */
296 111
297 PTR_LA t1, nlm_cpu_ready /* mark CPU ready */ 112 li t3, CKSEG1ADDR(RESET_DATA_PHYS)
298 PTR_ADDU t1, t0 113 ADDIU t1, t3, BOOT_CPU_READY
114 ADDU t1, t0
299 li t3, 1 115 li t3, 1
300 sw t3, 0(t1) 116 sw t3, 0(t1)
301 117
@@ -321,7 +137,7 @@ NESTED(nlm_rmiboot_preboot, 16, sp)
321 mtcr t1, t0 /* update core control */ 137 mtcr t1, t0 /* update core control */
322 138
3231: wait 1391: wait
324 j 1b 140 b 1b
325 nop 141 nop
326END(nlm_rmiboot_preboot) 142END(nlm_rmiboot_preboot)
327 __FINIT 143 __FINIT