aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/common/smpboot.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic/common/smpboot.S')
-rw-r--r--arch/mips/netlogic/common/smpboot.S157
1 files changed, 102 insertions, 55 deletions
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S
index c138b1a6dec3..a13355cc97eb 100644
--- a/arch/mips/netlogic/common/smpboot.S
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -54,28 +54,68 @@
54 XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \ 54 XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
55 SYS_CPU_NONCOHERENT_MODE * 4 55 SYS_CPU_NONCOHERENT_MODE * 4
56 56
57.macro __config_lsu 57#define XLP_AX_WORKAROUND /* enable Ax silicon workarounds */
58 li t0, LSU_DEFEATURE
59 mfcr t1, t0
60 58
61 lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */ 59/* Enable XLP features and workarounds in the LSU */
62 or t1, t1, t2 60.macro xlp_config_lsu
63 li t2, ~0xe /* S1RCM */ 61 li t0, LSU_DEFEATURE
62 mfcr t1, t0
63
64 lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */
65 or t1, t1, t2
66#ifdef XLP_AX_WORKAROUND
67 li t2, ~0xe /* S1RCM */
64 and t1, t1, t2 68 and t1, t1, t2
65 mtcr t1, t0 69#endif
70 mtcr t1, t0
66 71
67 li t0, SCHED_DEFEATURE 72#ifdef XLP_AX_WORKAROUND
68 lui t1, 0x0100 /* Experimental: Disable BRU accepting ALU ops */ 73 li t0, SCHED_DEFEATURE
69 mtcr t1, t0 74 lui t1, 0x0100 /* Disable BRU accepting ALU ops */
75 mtcr t1, t0
76#endif
77.endm
78
79/*
80 * This is the code that will be copied to the reset entry point for
81 * XLR and XLP. The XLP cores start here when they are woken up. This
82 * is also the NMI entry point.
83 */
84.macro xlp_flush_l1_dcache
85 li t0, LSU_DEBUG_DATA0
86 li t1, LSU_DEBUG_ADDR
87 li t2, 0 /* index */
88 li t3, 0x1000 /* loop count */
891:
90 sll v0, t2, 5
91 mtcr zero, t0
92 ori v1, v0, 0x3 /* way0 | write_enable | write_active */
93 mtcr v1, t1
942:
95 mfcr v1, t1
96 andi v1, 0x1 /* wait for write_active == 0 */
97 bnez v1, 2b
98 nop
99 mtcr zero, t0
100 ori v1, v0, 0x7 /* way1 | write_enable | write_active */
101 mtcr v1, t1
1023:
103 mfcr v1, t1
104 andi v1, 0x1 /* wait for write_active == 0 */
105 bnez v1, 3b
106 nop
107 addi t2, 1
108 bne t3, t2, 1b
109 nop
70.endm 110.endm
71 111
72/* 112/*
73 * The cores can come start when they are woken up. This is also the NMI 113 * The cores can come start when they are woken up. This is also the NMI
74 * entry, so check that first. 114 * entry, so check that first.
75 * 115 *
76 * The data corresponding to reset is stored at RESET_DATA_PHYS location, 116 * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
77 * this will have the thread mask (used when core is woken up) and the 117 * location, this will have the thread mask (used when core is woken up)
78 * current NMI handler in case we reached here for an NMI. 118 * and the current NMI handler in case we reached here for an NMI.
79 * 119 *
80 * When a core or thread is newly woken up, it loops in a 'wait'. When 120 * 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 121 * the CPU really needs waking up, we send an NMI to it, with the NMI
@@ -89,12 +129,12 @@
89FEXPORT(nlm_reset_entry) 129FEXPORT(nlm_reset_entry)
90 dmtc0 k0, $22, 6 130 dmtc0 k0, $22, 6
91 dmtc0 k1, $22, 7 131 dmtc0 k1, $22, 7
92 mfc0 k0, CP0_STATUS 132 mfc0 k0, CP0_STATUS
93 li k1, 0x80000 133 li k1, 0x80000
94 and k1, k0, k1 134 and k1, k0, k1
95 beqz k1, 1f /* go to real reset entry */ 135 beqz k1, 1f /* go to real reset entry */
96 nop 136 nop
97 li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */ 137 li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
98 ld k0, BOOT_NMI_HANDLER(k1) 138 ld k0, BOOT_NMI_HANDLER(k1)
99 jr k0 139 jr k0
100 nop 140 nop
@@ -114,21 +154,25 @@ FEXPORT(nlm_reset_entry)
114 li t2, SYS_CPU_COHERENT_BASE(0) 154 li t2, SYS_CPU_COHERENT_BASE(0)
115 add t2, t2, t3 /* t2 <- SYS offset for node */ 155 add t2, t2, t3 /* t2 <- SYS offset for node */
116 lw t1, 0(t2) 156 lw t1, 0(t2)
117 and t1, t1, t0 157 and t1, t1, t0
118 sw t1, 0(t2) 158 sw t1, 0(t2)
119 159
120 /* read back to ensure complete */ 160 /* read back to ensure complete */
121 lw t1, 0(t2) 161 lw t1, 0(t2)
122 sync 162 sync
123 163
124 /* Configure LSU on Non-0 Cores. */ 164 /* Configure LSU on Non-0 Cores. */
125 __config_lsu 165 xlp_config_lsu
166 /* FALL THROUGH */
126 167
127/* 168/*
128 * Wake up sibling threads from the initial thread in 169 * Wake up sibling threads from the initial thread in
129 * a core. 170 * a core.
130 */ 171 */
131EXPORT(nlm_boot_siblings) 172EXPORT(nlm_boot_siblings)
173 /* core L1D flush before enable threads */
174 xlp_flush_l1_dcache
175 /* Enable hw threads by writing to MAP_THREADMODE of the core */
132 li t0, CKSEG1ADDR(RESET_DATA_PHYS) 176 li t0, CKSEG1ADDR(RESET_DATA_PHYS)
133 lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */ 177 lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
134 li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE) 178 li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
@@ -139,31 +183,28 @@ EXPORT(nlm_boot_siblings)
139 /* 183 /*
140 * The new hardware thread starts at the next instruction 184 * The new hardware thread starts at the next instruction
141 * For all the cases other than core 0 thread 0, we will 185 * For all the cases other than core 0 thread 0, we will
142 * jump to the secondary wait function. 186 * jump to the secondary wait function.
143 */ 187 */
144 mfc0 v0, CP0_EBASE, 1 188 mfc0 v0, CP0_EBASE, 1
145 andi v0, 0x7f /* v0 <- node/core */ 189 andi v0, 0x7f /* v0 <- node/core */
146 190
147#if 1 191 /* Init MMU in the first thread after changing THREAD_MODE
148 /* A0 errata - Write MMU_SETUP after changing thread mode register. */ 192 * register (Ax Errata?)
193 */
149 andi v1, v0, 0x3 /* v1 <- thread id */ 194 andi v1, v0, 0x3 /* v1 <- thread id */
150 bnez v1, 2f 195 bnez v1, 2f
151 nop 196 nop
152 197
153 li t0, MMU_SETUP 198 li t0, MMU_SETUP
154 li t1, 0 199 li t1, 0
155 mtcr t1, t0 200 mtcr t1, t0
156 ehb 201 _ehb
157#endif
158 202
1592: beqz v0, 4f 2032: beqz v0, 4f /* boot cpu (cpuid == 0)? */
160 nop 204 nop
161 205
162 /* setup status reg */ 206 /* setup status reg */
163 mfc0 t1, CP0_STATUS 207 move t1, zero
164 li t0, ST0_BEV
165 or t1, t0
166 xor t1, t0
167#ifdef CONFIG_64BIT 208#ifdef CONFIG_64BIT
168 ori t1, ST0_KX 209 ori t1, ST0_KX
169#endif 210#endif
@@ -183,9 +224,9 @@ EXPORT(nlm_boot_siblings)
183 * For the boot CPU, we have to restore registers and 224 * For the boot CPU, we have to restore registers and
184 * return 225 * return
185 */ 226 */
1864: dmfc0 t0, $4, 2 /* restore SP from UserLocal */ 2274: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
187 li t1, 0xfadebeef 228 li t1, 0xfadebeef
188 dmtc0 t1, $4, 2 /* restore SP from UserLocal */ 229 dmtc0 t1, $4, 2 /* restore SP from UserLocal */
189 PTR_SUBU sp, t0, PT_SIZE 230 PTR_SUBU sp, t0, PT_SIZE
190 RESTORE_ALL 231 RESTORE_ALL
191 jr ra 232 jr ra
@@ -193,7 +234,7 @@ EXPORT(nlm_boot_siblings)
193EXPORT(nlm_reset_entry_end) 234EXPORT(nlm_reset_entry_end)
194 235
195FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ 236FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
196 __config_lsu 237 xlp_config_lsu
197 dmtc0 sp, $4, 2 /* SP saved in UserLocal */ 238 dmtc0 sp, $4, 2 /* SP saved in UserLocal */
198 SAVE_ALL 239 SAVE_ALL
199 sync 240 sync
@@ -210,6 +251,12 @@ FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
210 251
211 __CPUINIT 252 __CPUINIT
212NESTED(nlm_boot_secondary_cpus, 16, sp) 253NESTED(nlm_boot_secondary_cpus, 16, sp)
254 /* Initialize CP0 Status */
255 move t1, zero
256#ifdef CONFIG_64BIT
257 ori t1, ST0_KX
258#endif
259 mtc0 t1, CP0_STATUS
213 PTR_LA t1, nlm_next_sp 260 PTR_LA t1, nlm_next_sp
214 PTR_L sp, 0(t1) 261 PTR_L sp, 0(t1)
215 PTR_LA t1, nlm_next_gp 262 PTR_LA t1, nlm_next_gp
@@ -234,36 +281,36 @@ END(nlm_boot_secondary_cpus)
234 */ 281 */
235 __CPUINIT 282 __CPUINIT
236NESTED(nlm_rmiboot_preboot, 16, sp) 283NESTED(nlm_rmiboot_preboot, 16, sp)
237 mfc0 t0, $15, 1 # read ebase 284 mfc0 t0, $15, 1 /* read ebase */
238 andi t0, 0x1f # t0 has the processor_id() 285 andi t0, 0x1f /* t0 has the processor_id() */
239 andi t2, t0, 0x3 # thread no 286 andi t2, t0, 0x3 /* thread num */
240 sll t0, 2 # offset in cpu array 287 sll t0, 2 /* offset in cpu array */
241 288
242 PTR_LA t1, nlm_cpu_ready # mark CPU ready 289 PTR_LA t1, nlm_cpu_ready /* mark CPU ready */
243 PTR_ADDU t1, t0 290 PTR_ADDU t1, t0
244 li t3, 1 291 li t3, 1
245 sw t3, 0(t1) 292 sw t3, 0(t1)
246 293
247 bnez t2, 1f # skip thread programming 294 bnez t2, 1f /* skip thread programming */
248 nop # for non zero hw threads 295 nop /* for thread id != 0 */
249 296
250 /* 297 /*
251 * MMU setup only for first thread in core 298 * XLR MMU setup only for first thread in core
252 */ 299 */
253 li t0, 0x400 300 li t0, 0x400
254 mfcr t1, t0 301 mfcr t1, t0
255 li t2, 6 # XLR thread mode mask 302 li t2, 6 /* XLR thread mode mask */
256 nor t3, t2, zero 303 nor t3, t2, zero
257 and t2, t1, t2 # t2 - current thread mode 304 and t2, t1, t2 /* t2 - current thread mode */
258 li v0, CKSEG1ADDR(RESET_DATA_PHYS) 305 li v0, CKSEG1ADDR(RESET_DATA_PHYS)
259 lw v1, BOOT_THREAD_MODE(v0) # v1 - new thread mode 306 lw v1, BOOT_THREAD_MODE(v0) /* v1 - new thread mode */
260 sll v1, 1 307 sll v1, 1
261 beq v1, t2, 1f # same as request value 308 beq v1, t2, 1f /* same as request value */
262 nop # nothing to do */ 309 nop /* nothing to do */
263 310
264 and t2, t1, t3 # mask out old thread mode 311 and t2, t1, t3 /* mask out old thread mode */
265 or t1, t2, v1 # put in new value 312 or t1, t2, v1 /* put in new value */
266 mtcr t1, t0 # update core control 313 mtcr t1, t0 /* update core control */
267 314
2681: wait 3151: wait
269 j 1b 316 j 1b