Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / arch / sparc64 / kernel / trampoline.S
blobb0674b3e46a36fa3c23fd2411a537ffcbd6ca4f1
1 /* $Id: trampoline.S,v 1.26 2002/02/09 19:49:30 davem Exp $
2  * trampoline.S: Jump start slave processors on sparc64.
3  *
4  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
5  */
7 <<<<<<< HEAD:arch/sparc64/kernel/trampoline.S
8 =======
9 #include <linux/init.h>
11 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/sparc64/kernel/trampoline.S
12 #include <asm/head.h>
13 #include <asm/asi.h>
14 #include <asm/lsu.h>
15 #include <asm/dcr.h>
16 #include <asm/dcu.h>
17 #include <asm/pstate.h>
18 #include <asm/page.h>
19 #include <asm/pgtable.h>
20 #include <asm/spitfire.h>
21 #include <asm/processor.h>
22 #include <asm/thread_info.h>
23 #include <asm/mmu.h>
24 #include <asm/hypervisor.h>
25 #include <asm/cpudata.h>
27         .data
28         .align  8
29 call_method:
30         .asciz  "call-method"
31         .align  8
32 itlb_load:
33         .asciz  "SUNW,itlb-load"
34         .align  8
35 dtlb_load:
36         .asciz  "SUNW,dtlb-load"
38         /* XXX __cpuinit this thing XXX */
39 #define TRAMP_STACK_SIZE        1024
40         .align  16
41 tramp_stack:
42         .skip   TRAMP_STACK_SIZE
44 <<<<<<< HEAD:arch/sparc64/kernel/trampoline.S
45         .text
46 =======
47         __CPUINIT
48 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/sparc64/kernel/trampoline.S
49         .align          8
50         .globl          sparc64_cpu_startup, sparc64_cpu_startup_end
51 sparc64_cpu_startup:
52         BRANCH_IF_SUN4V(g1, niagara_startup)
53         BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
54         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
56         ba,pt   %xcc, spitfire_startup
57          nop
59 cheetah_plus_startup:
60         /* Preserve OBP chosen DCU and DCR register settings.  */
61         ba,pt   %xcc, cheetah_generic_startup
62          nop
64 cheetah_startup:
65         mov     DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
66         wr      %g1, %asr18
68         sethi   %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
69         or      %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
70         sllx    %g5, 32, %g5
71         or      %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
72         stxa    %g5, [%g0] ASI_DCU_CONTROL_REG
73         membar  #Sync
74         /* fallthru */
76 cheetah_generic_startup:
77         mov     TSB_EXTENSION_P, %g3
78         stxa    %g0, [%g3] ASI_DMMU
79         stxa    %g0, [%g3] ASI_IMMU
80         membar  #Sync
82         mov     TSB_EXTENSION_S, %g3
83         stxa    %g0, [%g3] ASI_DMMU
84         membar  #Sync
86         mov     TSB_EXTENSION_N, %g3
87         stxa    %g0, [%g3] ASI_DMMU
88         stxa    %g0, [%g3] ASI_IMMU
89         membar  #Sync
90         /* fallthru */
92 niagara_startup:
93         /* Disable STICK_INT interrupts. */
94         sethi           %hi(0x80000000), %g5
95         sllx            %g5, 32, %g5
96         wr              %g5, %asr25
98         ba,pt           %xcc, startup_continue
99          nop
101 spitfire_startup:
102         mov             (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
103         stxa            %g1, [%g0] ASI_LSU_CONTROL
104         membar          #Sync
106 startup_continue:
107         mov             %o0, %l0
108         BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
110         sethi           %hi(0x80000000), %g2
111         sllx            %g2, 32, %g2
112         wr              %g2, 0, %tick_cmpr
114         /* Call OBP by hand to lock KERNBASE into i/d tlbs.
115          * We lock 2 consequetive entries if we are 'bigkernel'.
116          */
117         sethi           %hi(prom_entry_lock), %g2
118 1:      ldstub          [%g2 + %lo(prom_entry_lock)], %g1
119         membar          #StoreLoad | #StoreStore
120         brnz,pn         %g1, 1b
121          nop
123         sethi           %hi(p1275buf), %g2
124         or              %g2, %lo(p1275buf), %g2
125         ldx             [%g2 + 0x10], %l2
126         add             %l2, -(192 + 128), %sp
127         flushw
129         sethi           %hi(call_method), %g2
130         or              %g2, %lo(call_method), %g2
131         stx             %g2, [%sp + 2047 + 128 + 0x00]
132         mov             5, %g2
133         stx             %g2, [%sp + 2047 + 128 + 0x08]
134         mov             1, %g2
135         stx             %g2, [%sp + 2047 + 128 + 0x10]
136         sethi           %hi(itlb_load), %g2
137         or              %g2, %lo(itlb_load), %g2
138         stx             %g2, [%sp + 2047 + 128 + 0x18]
139         sethi           %hi(prom_mmu_ihandle_cache), %g2
140         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
141         stx             %g2, [%sp + 2047 + 128 + 0x20]
142         sethi           %hi(KERNBASE), %g2
143         stx             %g2, [%sp + 2047 + 128 + 0x28]
144         sethi           %hi(kern_locked_tte_data), %g2
145         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
146         stx             %g2, [%sp + 2047 + 128 + 0x30]
148         mov             15, %g2
149         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
151         mov             63, %g2
153         stx             %g2, [%sp + 2047 + 128 + 0x38]
154         sethi           %hi(p1275buf), %g2
155         or              %g2, %lo(p1275buf), %g2
156         ldx             [%g2 + 0x08], %o1
157         call            %o1
158          add            %sp, (2047 + 128), %o0
160         sethi           %hi(bigkernel), %g2
161         lduw            [%g2 + %lo(bigkernel)], %g2
162         brz,pt          %g2, do_dtlb
163          nop
165         sethi           %hi(call_method), %g2
166         or              %g2, %lo(call_method), %g2
167         stx             %g2, [%sp + 2047 + 128 + 0x00]
168         mov             5, %g2
169         stx             %g2, [%sp + 2047 + 128 + 0x08]
170         mov             1, %g2
171         stx             %g2, [%sp + 2047 + 128 + 0x10]
172         sethi           %hi(itlb_load), %g2
173         or              %g2, %lo(itlb_load), %g2
174         stx             %g2, [%sp + 2047 + 128 + 0x18]
175         sethi           %hi(prom_mmu_ihandle_cache), %g2
176         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
177         stx             %g2, [%sp + 2047 + 128 + 0x20]
178         sethi           %hi(KERNBASE + 0x400000), %g2
179         stx             %g2, [%sp + 2047 + 128 + 0x28]
180         sethi           %hi(kern_locked_tte_data), %g2
181         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
182         sethi           %hi(0x400000), %g1
183         add             %g2, %g1, %g2
184         stx             %g2, [%sp + 2047 + 128 + 0x30]
186         mov             14, %g2
187         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
189         mov             62, %g2
191         stx             %g2, [%sp + 2047 + 128 + 0x38]
192         sethi           %hi(p1275buf), %g2
193         or              %g2, %lo(p1275buf), %g2
194         ldx             [%g2 + 0x08], %o1
195         call            %o1
196          add            %sp, (2047 + 128), %o0
198 do_dtlb:
199         sethi           %hi(call_method), %g2
200         or              %g2, %lo(call_method), %g2
201         stx             %g2, [%sp + 2047 + 128 + 0x00]
202         mov             5, %g2
203         stx             %g2, [%sp + 2047 + 128 + 0x08]
204         mov             1, %g2
205         stx             %g2, [%sp + 2047 + 128 + 0x10]
206         sethi           %hi(dtlb_load), %g2
207         or              %g2, %lo(dtlb_load), %g2
208         stx             %g2, [%sp + 2047 + 128 + 0x18]
209         sethi           %hi(prom_mmu_ihandle_cache), %g2
210         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
211         stx             %g2, [%sp + 2047 + 128 + 0x20]
212         sethi           %hi(KERNBASE), %g2
213         stx             %g2, [%sp + 2047 + 128 + 0x28]
214         sethi           %hi(kern_locked_tte_data), %g2
215         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
216         stx             %g2, [%sp + 2047 + 128 + 0x30]
218         mov             15, %g2
219         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
221         mov             63, %g2
224         stx             %g2, [%sp + 2047 + 128 + 0x38]
225         sethi           %hi(p1275buf), %g2
226         or              %g2, %lo(p1275buf), %g2
227         ldx             [%g2 + 0x08], %o1
228         call            %o1
229          add            %sp, (2047 + 128), %o0
231         sethi           %hi(bigkernel), %g2
232         lduw            [%g2 + %lo(bigkernel)], %g2
233         brz,pt          %g2, do_unlock
234          nop
236         sethi           %hi(call_method), %g2
237         or              %g2, %lo(call_method), %g2
238         stx             %g2, [%sp + 2047 + 128 + 0x00]
239         mov             5, %g2
240         stx             %g2, [%sp + 2047 + 128 + 0x08]
241         mov             1, %g2
242         stx             %g2, [%sp + 2047 + 128 + 0x10]
243         sethi           %hi(dtlb_load), %g2
244         or              %g2, %lo(dtlb_load), %g2
245         stx             %g2, [%sp + 2047 + 128 + 0x18]
246         sethi           %hi(prom_mmu_ihandle_cache), %g2
247         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
248         stx             %g2, [%sp + 2047 + 128 + 0x20]
249         sethi           %hi(KERNBASE + 0x400000), %g2
250         stx             %g2, [%sp + 2047 + 128 + 0x28]
251         sethi           %hi(kern_locked_tte_data), %g2
252         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
253         sethi           %hi(0x400000), %g1
254         add             %g2, %g1, %g2
255         stx             %g2, [%sp + 2047 + 128 + 0x30]
257         mov             14, %g2
258         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
260         mov             62, %g2
263         stx             %g2, [%sp + 2047 + 128 + 0x38]
264         sethi           %hi(p1275buf), %g2
265         or              %g2, %lo(p1275buf), %g2
266         ldx             [%g2 + 0x08], %o1
267         call            %o1
268          add            %sp, (2047 + 128), %o0
270 do_unlock:
271         sethi           %hi(prom_entry_lock), %g2
272         stb             %g0, [%g2 + %lo(prom_entry_lock)]
273         membar          #StoreStore | #StoreLoad
275         ba,pt           %xcc, after_lock_tlb
276          nop
278 niagara_lock_tlb:
279         mov             HV_FAST_MMU_MAP_PERM_ADDR, %o5
280         sethi           %hi(KERNBASE), %o0
281         clr             %o1
282         sethi           %hi(kern_locked_tte_data), %o2
283         ldx             [%o2 + %lo(kern_locked_tte_data)], %o2
284         mov             HV_MMU_IMMU, %o3
285         ta              HV_FAST_TRAP
287         mov             HV_FAST_MMU_MAP_PERM_ADDR, %o5
288         sethi           %hi(KERNBASE), %o0
289         clr             %o1
290         sethi           %hi(kern_locked_tte_data), %o2
291         ldx             [%o2 + %lo(kern_locked_tte_data)], %o2
292         mov             HV_MMU_DMMU, %o3
293         ta              HV_FAST_TRAP
295         sethi           %hi(bigkernel), %g2
296         lduw            [%g2 + %lo(bigkernel)], %g2
297         brz,pt          %g2, after_lock_tlb
298          nop
300         mov             HV_FAST_MMU_MAP_PERM_ADDR, %o5
301         sethi           %hi(KERNBASE + 0x400000), %o0
302         clr             %o1
303         sethi           %hi(kern_locked_tte_data), %o2
304         ldx             [%o2 + %lo(kern_locked_tte_data)], %o2
305         sethi           %hi(0x400000), %o3
306         add             %o2, %o3, %o2
307         mov             HV_MMU_IMMU, %o3
308         ta              HV_FAST_TRAP
310         mov             HV_FAST_MMU_MAP_PERM_ADDR, %o5
311         sethi           %hi(KERNBASE + 0x400000), %o0
312         clr             %o1
313         sethi           %hi(kern_locked_tte_data), %o2
314         ldx             [%o2 + %lo(kern_locked_tte_data)], %o2
315         sethi           %hi(0x400000), %o3
316         add             %o2, %o3, %o2
317         mov             HV_MMU_DMMU, %o3
318         ta              HV_FAST_TRAP
320 after_lock_tlb:
321         wrpr            %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
322         wr              %g0, 0, %fprs
324         wr              %g0, ASI_P, %asi
326         mov             PRIMARY_CONTEXT, %g7
328 661:    stxa            %g0, [%g7] ASI_DMMU
329         .section        .sun4v_1insn_patch, "ax"
330         .word           661b
331         stxa            %g0, [%g7] ASI_MMU
332         .previous
334         membar          #Sync
335         mov             SECONDARY_CONTEXT, %g7
337 661:    stxa            %g0, [%g7] ASI_DMMU
338         .section        .sun4v_1insn_patch, "ax"
339         .word           661b
340         stxa            %g0, [%g7] ASI_MMU
341         .previous
343         membar          #Sync
345         /* Everything we do here, until we properly take over the
346          * trap table, must be done with extreme care.  We cannot
347          * make any references to %g6 (current thread pointer),
348          * %g4 (current task pointer), or %g5 (base of current cpu's
349          * per-cpu area) until we properly take over the trap table
350          * from the firmware and hypervisor.
351          *
352          * Get onto temporary stack which is in the locked kernel image.
353          */
354         sethi           %hi(tramp_stack), %g1
355         or              %g1, %lo(tramp_stack), %g1
356         add             %g1, TRAMP_STACK_SIZE, %g1
357         sub             %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
358         mov             0, %fp
360         /* Put garbage in these registers to trap any access to them.  */
361         set             0xdeadbeef, %g4
362         set             0xdeadbeef, %g5
363         set             0xdeadbeef, %g6
365         call            init_irqwork_curcpu
366          nop
368         sethi           %hi(tlb_type), %g3
369         lduw            [%g3 + %lo(tlb_type)], %g2
370         cmp             %g2, 3
371         bne,pt          %icc, 1f
372          nop
374         call            hard_smp_processor_id
375          nop
376         
377         call            sun4v_register_mondo_queues
378          nop
380 1:      call            init_cur_cpu_trap
381          ldx            [%l0], %o0
383         /* Start using proper page size encodings in ctx register.  */
384         sethi           %hi(sparc64_kern_pri_context), %g3
385         ldx             [%g3 + %lo(sparc64_kern_pri_context)], %g2
386         mov             PRIMARY_CONTEXT, %g1
388 661:    stxa            %g2, [%g1] ASI_DMMU
389         .section        .sun4v_1insn_patch, "ax"
390         .word           661b
391         stxa            %g2, [%g1] ASI_MMU
392         .previous
394         membar          #Sync
396         wrpr            %g0, 0, %wstate
398         /* As a hack, put &init_thread_union into %g6.
399          * prom_world() loads from here to restore the %asi
400          * register.
401          */
402         sethi           %hi(init_thread_union), %g6
403         or              %g6, %lo(init_thread_union), %g6
405         sethi           %hi(is_sun4v), %o0
406         lduw            [%o0 + %lo(is_sun4v)], %o0
407         brz,pt          %o0, 1f
408          nop
410         TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
411         add             %g2, TRAP_PER_CPU_FAULT_INFO, %g2
412         stxa            %g2, [%g0] ASI_SCRATCHPAD
414         /* Compute physical address:
415          *
416          * paddr = kern_base + (mmfsa_vaddr - KERNBASE)
417          */
418         sethi           %hi(KERNBASE), %g3
419         sub             %g2, %g3, %g2
420         sethi           %hi(kern_base), %g3
421         ldx             [%g3 + %lo(kern_base)], %g3
422         add             %g2, %g3, %o1
423         sethi           %hi(sparc64_ttable_tl0), %o0
425         set             prom_set_trap_table_name, %g2
426         stx             %g2, [%sp + 2047 + 128 + 0x00]
427         mov             2, %g2
428         stx             %g2, [%sp + 2047 + 128 + 0x08]
429         mov             0, %g2
430         stx             %g2, [%sp + 2047 + 128 + 0x10]
431         stx             %o0, [%sp + 2047 + 128 + 0x18]
432         stx             %o1, [%sp + 2047 + 128 + 0x20]
433         sethi           %hi(p1275buf), %g2
434         or              %g2, %lo(p1275buf), %g2
435         ldx             [%g2 + 0x08], %o1
436         call            %o1
437          add            %sp, (2047 + 128), %o0
439         ba,pt           %xcc, 2f
440          nop
442 1:      sethi           %hi(sparc64_ttable_tl0), %o0
443         set             prom_set_trap_table_name, %g2
444         stx             %g2, [%sp + 2047 + 128 + 0x00]
445         mov             1, %g2
446         stx             %g2, [%sp + 2047 + 128 + 0x08]
447         mov             0, %g2
448         stx             %g2, [%sp + 2047 + 128 + 0x10]
449         stx             %o0, [%sp + 2047 + 128 + 0x18]
450         sethi           %hi(p1275buf), %g2
451         or              %g2, %lo(p1275buf), %g2
452         ldx             [%g2 + 0x08], %o1
453         call            %o1
454          add            %sp, (2047 + 128), %o0
456 2:      ldx             [%l0], %g6
457         ldx             [%g6 + TI_TASK], %g4
459         mov             1, %g5
460         sllx            %g5, THREAD_SHIFT, %g5
461         sub             %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
462         add             %g6, %g5, %sp
463         mov             0, %fp
465         rdpr            %pstate, %o1
466         or              %o1, PSTATE_IE, %o1
467         wrpr            %o1, 0, %pstate
469         call            smp_callin
470          nop
471         call            cpu_idle
472          mov            0, %o0
473         call            cpu_panic
474          nop
475 1:      b,a,pt          %xcc, 1b
477         .align          8
478 sparc64_cpu_startup_end: