aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/trampoline_64.S
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-12-03 06:11:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-04 12:17:21 -0500
commita88b5ba8bd8ac18aad65ee6c6a254e2e74876db3 (patch)
treeeb3d0ffaf53c3f7ec6083752c2097cecd1cb892a /arch/sparc/kernel/trampoline_64.S
parentd670bd4f803c8b646acd20f3ba21e65458293faf (diff)
sparc,sparc64: unify kernel/
o Move all files from sparc64/kernel/ to sparc/kernel - rename as appropriate o Update sparc/Makefile to the changes o Update sparc/kernel/Makefile to include the sparc64 files NOTE: This commit changes link order on sparc64! Link order had to change for either of sparc32 and sparc64. And assuming sparc64 see more testing than sparc32 change link order on sparc64 where issues will be caught faster. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/trampoline_64.S')
-rw-r--r--arch/sparc/kernel/trampoline_64.S417
1 files changed, 417 insertions, 0 deletions
diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S
new file mode 100644
index 000000000000..da1b781b5e65
--- /dev/null
+++ b/arch/sparc/kernel/trampoline_64.S
@@ -0,0 +1,417 @@
1/*
2 * trampoline.S: Jump start slave processors on sparc64.
3 *
4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#include <linux/init.h>
8
9#include <asm/head.h>
10#include <asm/asi.h>
11#include <asm/lsu.h>
12#include <asm/dcr.h>
13#include <asm/dcu.h>
14#include <asm/pstate.h>
15#include <asm/page.h>
16#include <asm/pgtable.h>
17#include <asm/spitfire.h>
18#include <asm/processor.h>
19#include <asm/thread_info.h>
20#include <asm/mmu.h>
21#include <asm/hypervisor.h>
22#include <asm/cpudata.h>
23
24 .data
25 .align 8
26call_method:
27 .asciz "call-method"
28 .align 8
29itlb_load:
30 .asciz "SUNW,itlb-load"
31 .align 8
32dtlb_load:
33 .asciz "SUNW,dtlb-load"
34
35 /* XXX __cpuinit this thing XXX */
36#define TRAMP_STACK_SIZE 1024
37 .align 16
38tramp_stack:
39 .skip TRAMP_STACK_SIZE
40
41 __CPUINIT
42 .align 8
43 .globl sparc64_cpu_startup, sparc64_cpu_startup_end
44sparc64_cpu_startup:
45 BRANCH_IF_SUN4V(g1, niagara_startup)
46 BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
47 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
48
49 ba,pt %xcc, spitfire_startup
50 nop
51
52cheetah_plus_startup:
53 /* Preserve OBP chosen DCU and DCR register settings. */
54 ba,pt %xcc, cheetah_generic_startup
55 nop
56
57cheetah_startup:
58 mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
59 wr %g1, %asr18
60
61 sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
62 or %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
63 sllx %g5, 32, %g5
64 or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
65 stxa %g5, [%g0] ASI_DCU_CONTROL_REG
66 membar #Sync
67 /* fallthru */
68
69cheetah_generic_startup:
70 mov TSB_EXTENSION_P, %g3
71 stxa %g0, [%g3] ASI_DMMU
72 stxa %g0, [%g3] ASI_IMMU
73 membar #Sync
74
75 mov TSB_EXTENSION_S, %g3
76 stxa %g0, [%g3] ASI_DMMU
77 membar #Sync
78
79 mov TSB_EXTENSION_N, %g3
80 stxa %g0, [%g3] ASI_DMMU
81 stxa %g0, [%g3] ASI_IMMU
82 membar #Sync
83 /* fallthru */
84
85niagara_startup:
86 /* Disable STICK_INT interrupts. */
87 sethi %hi(0x80000000), %g5
88 sllx %g5, 32, %g5
89 wr %g5, %asr25
90
91 ba,pt %xcc, startup_continue
92 nop
93
94spitfire_startup:
95 mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
96 stxa %g1, [%g0] ASI_LSU_CONTROL
97 membar #Sync
98
99startup_continue:
100 mov %o0, %l0
101 BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
102
103 sethi %hi(0x80000000), %g2
104 sllx %g2, 32, %g2
105 wr %g2, 0, %tick_cmpr
106
107 /* Call OBP by hand to lock KERNBASE into i/d tlbs.
108 * We lock 'num_kernel_image_mappings' consequetive entries.
109 */
110 sethi %hi(prom_entry_lock), %g2
1111: ldstub [%g2 + %lo(prom_entry_lock)], %g1
112 brnz,pn %g1, 1b
113 nop
114
115 sethi %hi(p1275buf), %g2
116 or %g2, %lo(p1275buf), %g2
117 ldx [%g2 + 0x10], %l2
118 add %l2, -(192 + 128), %sp
119 flushw
120
121 /* Setup the loop variables:
122 * %l3: VADDR base
123 * %l4: TTE base
124 * %l5: Loop iterator, iterates from 0 to 'num_kernel_image_mappings'
125 * %l6: Number of TTE entries to map
126 * %l7: Highest TTE entry number, we count down
127 */
128 sethi %hi(KERNBASE), %l3
129 sethi %hi(kern_locked_tte_data), %l4
130 ldx [%l4 + %lo(kern_locked_tte_data)], %l4
131 clr %l5
132 sethi %hi(num_kernel_image_mappings), %l6
133 lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
134 add %l6, 1, %l6
135
136 mov 15, %l7
137 BRANCH_IF_ANY_CHEETAH(g1,g5,2f)
138
139 mov 63, %l7
1402:
141
1423:
143 /* Lock into I-MMU */
144 sethi %hi(call_method), %g2
145 or %g2, %lo(call_method), %g2
146 stx %g2, [%sp + 2047 + 128 + 0x00]
147 mov 5, %g2
148 stx %g2, [%sp + 2047 + 128 + 0x08]
149 mov 1, %g2
150 stx %g2, [%sp + 2047 + 128 + 0x10]
151 sethi %hi(itlb_load), %g2
152 or %g2, %lo(itlb_load), %g2
153 stx %g2, [%sp + 2047 + 128 + 0x18]
154 sethi %hi(prom_mmu_ihandle_cache), %g2
155 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
156 stx %g2, [%sp + 2047 + 128 + 0x20]
157
158 /* Each TTE maps 4MB, convert index to offset. */
159 sllx %l5, 22, %g1
160
161 add %l3, %g1, %g2
162 stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR
163 add %l4, %g1, %g2
164 stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE
165
166 /* TTE index is highest minus loop index. */
167 sub %l7, %l5, %g2
168 stx %g2, [%sp + 2047 + 128 + 0x38]
169
170 sethi %hi(p1275buf), %g2
171 or %g2, %lo(p1275buf), %g2
172 ldx [%g2 + 0x08], %o1
173 call %o1
174 add %sp, (2047 + 128), %o0
175
176 /* Lock into D-MMU */
177 sethi %hi(call_method), %g2
178 or %g2, %lo(call_method), %g2
179 stx %g2, [%sp + 2047 + 128 + 0x00]
180 mov 5, %g2
181 stx %g2, [%sp + 2047 + 128 + 0x08]
182 mov 1, %g2
183 stx %g2, [%sp + 2047 + 128 + 0x10]
184 sethi %hi(dtlb_load), %g2
185 or %g2, %lo(dtlb_load), %g2
186 stx %g2, [%sp + 2047 + 128 + 0x18]
187 sethi %hi(prom_mmu_ihandle_cache), %g2
188 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
189 stx %g2, [%sp + 2047 + 128 + 0x20]
190
191 /* Each TTE maps 4MB, convert index to offset. */
192 sllx %l5, 22, %g1
193
194 add %l3, %g1, %g2
195 stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR
196 add %l4, %g1, %g2
197 stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE
198
199 /* TTE index is highest minus loop index. */
200 sub %l7, %l5, %g2
201 stx %g2, [%sp + 2047 + 128 + 0x38]
202
203 sethi %hi(p1275buf), %g2
204 or %g2, %lo(p1275buf), %g2
205 ldx [%g2 + 0x08], %o1
206 call %o1
207 add %sp, (2047 + 128), %o0
208
209 add %l5, 1, %l5
210 cmp %l5, %l6
211 bne,pt %xcc, 3b
212 nop
213
214 sethi %hi(prom_entry_lock), %g2
215 stb %g0, [%g2 + %lo(prom_entry_lock)]
216
217 ba,pt %xcc, after_lock_tlb
218 nop
219
220niagara_lock_tlb:
221 sethi %hi(KERNBASE), %l3
222 sethi %hi(kern_locked_tte_data), %l4
223 ldx [%l4 + %lo(kern_locked_tte_data)], %l4
224 clr %l5
225 sethi %hi(num_kernel_image_mappings), %l6
226 lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
227 add %l6, 1, %l6
228
2291:
230 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
231 sllx %l5, 22, %g2
232 add %l3, %g2, %o0
233 clr %o1
234 add %l4, %g2, %o2
235 mov HV_MMU_IMMU, %o3
236 ta HV_FAST_TRAP
237
238 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
239 sllx %l5, 22, %g2
240 add %l3, %g2, %o0
241 clr %o1
242 add %l4, %g2, %o2
243 mov HV_MMU_DMMU, %o3
244 ta HV_FAST_TRAP
245
246 add %l5, 1, %l5
247 cmp %l5, %l6
248 bne,pt %xcc, 1b
249 nop
250
251after_lock_tlb:
252 wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
253 wr %g0, 0, %fprs
254
255 wr %g0, ASI_P, %asi
256
257 mov PRIMARY_CONTEXT, %g7
258
259661: stxa %g0, [%g7] ASI_DMMU
260 .section .sun4v_1insn_patch, "ax"
261 .word 661b
262 stxa %g0, [%g7] ASI_MMU
263 .previous
264
265 membar #Sync
266 mov SECONDARY_CONTEXT, %g7
267
268661: stxa %g0, [%g7] ASI_DMMU
269 .section .sun4v_1insn_patch, "ax"
270 .word 661b
271 stxa %g0, [%g7] ASI_MMU
272 .previous
273
274 membar #Sync
275
276 /* Everything we do here, until we properly take over the
277 * trap table, must be done with extreme care. We cannot
278 * make any references to %g6 (current thread pointer),
279 * %g4 (current task pointer), or %g5 (base of current cpu's
280 * per-cpu area) until we properly take over the trap table
281 * from the firmware and hypervisor.
282 *
283 * Get onto temporary stack which is in the locked kernel image.
284 */
285 sethi %hi(tramp_stack), %g1
286 or %g1, %lo(tramp_stack), %g1
287 add %g1, TRAMP_STACK_SIZE, %g1
288 sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
289 mov 0, %fp
290
291 /* Put garbage in these registers to trap any access to them. */
292 set 0xdeadbeef, %g4
293 set 0xdeadbeef, %g5
294 set 0xdeadbeef, %g6
295
296 call init_irqwork_curcpu
297 nop
298
299 sethi %hi(tlb_type), %g3
300 lduw [%g3 + %lo(tlb_type)], %g2
301 cmp %g2, 3
302 bne,pt %icc, 1f
303 nop
304
305 call hard_smp_processor_id
306 nop
307
308 call sun4v_register_mondo_queues
309 nop
310
3111: call init_cur_cpu_trap
312 ldx [%l0], %o0
313
314 /* Start using proper page size encodings in ctx register. */
315 sethi %hi(sparc64_kern_pri_context), %g3
316 ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
317 mov PRIMARY_CONTEXT, %g1
318
319661: stxa %g2, [%g1] ASI_DMMU
320 .section .sun4v_1insn_patch, "ax"
321 .word 661b
322 stxa %g2, [%g1] ASI_MMU
323 .previous
324
325 membar #Sync
326
327 wrpr %g0, 0, %wstate
328
329 sethi %hi(prom_entry_lock), %g2
3301: ldstub [%g2 + %lo(prom_entry_lock)], %g1
331 brnz,pn %g1, 1b
332 nop
333
334 /* As a hack, put &init_thread_union into %g6.
335 * prom_world() loads from here to restore the %asi
336 * register.
337 */
338 sethi %hi(init_thread_union), %g6
339 or %g6, %lo(init_thread_union), %g6
340
341 sethi %hi(is_sun4v), %o0
342 lduw [%o0 + %lo(is_sun4v)], %o0
343 brz,pt %o0, 2f
344 nop
345
346 TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
347 add %g2, TRAP_PER_CPU_FAULT_INFO, %g2
348 stxa %g2, [%g0] ASI_SCRATCHPAD
349
350 /* Compute physical address:
351 *
352 * paddr = kern_base + (mmfsa_vaddr - KERNBASE)
353 */
354 sethi %hi(KERNBASE), %g3
355 sub %g2, %g3, %g2
356 sethi %hi(kern_base), %g3
357 ldx [%g3 + %lo(kern_base)], %g3
358 add %g2, %g3, %o1
359 sethi %hi(sparc64_ttable_tl0), %o0
360
361 set prom_set_trap_table_name, %g2
362 stx %g2, [%sp + 2047 + 128 + 0x00]
363 mov 2, %g2
364 stx %g2, [%sp + 2047 + 128 + 0x08]
365 mov 0, %g2
366 stx %g2, [%sp + 2047 + 128 + 0x10]
367 stx %o0, [%sp + 2047 + 128 + 0x18]
368 stx %o1, [%sp + 2047 + 128 + 0x20]
369 sethi %hi(p1275buf), %g2
370 or %g2, %lo(p1275buf), %g2
371 ldx [%g2 + 0x08], %o1
372 call %o1
373 add %sp, (2047 + 128), %o0
374
375 ba,pt %xcc, 3f
376 nop
377
3782: sethi %hi(sparc64_ttable_tl0), %o0
379 set prom_set_trap_table_name, %g2
380 stx %g2, [%sp + 2047 + 128 + 0x00]
381 mov 1, %g2
382 stx %g2, [%sp + 2047 + 128 + 0x08]
383 mov 0, %g2
384 stx %g2, [%sp + 2047 + 128 + 0x10]
385 stx %o0, [%sp + 2047 + 128 + 0x18]
386 sethi %hi(p1275buf), %g2
387 or %g2, %lo(p1275buf), %g2
388 ldx [%g2 + 0x08], %o1
389 call %o1
390 add %sp, (2047 + 128), %o0
391
3923: sethi %hi(prom_entry_lock), %g2
393 stb %g0, [%g2 + %lo(prom_entry_lock)]
394
395 ldx [%l0], %g6
396 ldx [%g6 + TI_TASK], %g4
397
398 mov 1, %g5
399 sllx %g5, THREAD_SHIFT, %g5
400 sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
401 add %g6, %g5, %sp
402 mov 0, %fp
403
404 rdpr %pstate, %o1
405 or %o1, PSTATE_IE, %o1
406 wrpr %o1, 0, %pstate
407
408 call smp_callin
409 nop
410 call cpu_idle
411 mov 0, %o0
412 call cpu_panic
413 nop
4141: b,a,pt %xcc, 1b
415
416 .align 8
417sparc64_cpu_startup_end: