Merge branch 'master'
[linux-2.6] / arch / sparc64 / kernel / trampoline.S
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  */
6
7 #include <asm/head.h>
8 #include <asm/asi.h>
9 #include <asm/lsu.h>
10 #include <asm/dcr.h>
11 #include <asm/dcu.h>
12 #include <asm/pstate.h>
13 #include <asm/page.h>
14 #include <asm/pgtable.h>
15 #include <asm/spitfire.h>
16 #include <asm/processor.h>
17 #include <asm/thread_info.h>
18 #include <asm/mmu.h>
19
20         .data
21         .align  8
22 call_method:
23         .asciz  "call-method"
24         .align  8
25 itlb_load:
26         .asciz  "SUNW,itlb-load"
27         .align  8
28 dtlb_load:
29         .asciz  "SUNW,dtlb-load"
30
31         .text
32         .align          8
33         .globl          sparc64_cpu_startup, sparc64_cpu_startup_end
34 sparc64_cpu_startup:
35         flushw
36
37         BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_startup)
38         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_startup)
39
40         ba,pt   %xcc, spitfire_startup
41          nop
42
43 cheetah_plus_startup:
44         /* Preserve OBP chosen DCU and DCR register settings.  */
45         ba,pt   %xcc, cheetah_generic_startup
46          nop
47
48 cheetah_startup:
49         mov     DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
50         wr      %g1, %asr18
51
52         sethi   %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
53         or      %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
54         sllx    %g5, 32, %g5
55         or      %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
56         stxa    %g5, [%g0] ASI_DCU_CONTROL_REG
57         membar  #Sync
58
59 cheetah_generic_startup:
60         mov     TSB_EXTENSION_P, %g3
61         stxa    %g0, [%g3] ASI_DMMU
62         stxa    %g0, [%g3] ASI_IMMU
63         membar  #Sync
64
65         mov     TSB_EXTENSION_S, %g3
66         stxa    %g0, [%g3] ASI_DMMU
67         membar  #Sync
68
69         mov     TSB_EXTENSION_N, %g3
70         stxa    %g0, [%g3] ASI_DMMU
71         stxa    %g0, [%g3] ASI_IMMU
72         membar  #Sync
73
74         /* Disable STICK_INT interrupts. */
75         sethi           %hi(0x80000000), %g5
76         sllx            %g5, 32, %g5
77         wr              %g5, %asr25
78
79         ba,pt           %xcc, startup_continue
80          nop
81
82 spitfire_startup:
83         mov             (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
84         stxa            %g1, [%g0] ASI_LSU_CONTROL
85         membar          #Sync
86
87 startup_continue:
88         wrpr            %g0, 15, %pil
89
90         sethi           %hi(0x80000000), %g2
91         sllx            %g2, 32, %g2
92         wr              %g2, 0, %tick_cmpr
93
94         /* Call OBP by hand to lock KERNBASE into i/d tlbs.
95          * We lock 2 consequetive entries if we are 'bigkernel'.
96          */
97         mov             %o0, %l0
98
99         sethi           %hi(prom_entry_lock), %g2
100 1:      ldstub          [%g2 + %lo(prom_entry_lock)], %g1
101         membar          #StoreLoad | #StoreStore
102         brnz,pn         %g1, 1b
103          nop
104
105         sethi           %hi(p1275buf), %g2
106         or              %g2, %lo(p1275buf), %g2
107         ldx             [%g2 + 0x10], %l2
108         mov             %sp, %l1
109         add             %l2, -(192 + 128), %sp
110         flushw
111
112         sethi           %hi(call_method), %g2
113         or              %g2, %lo(call_method), %g2
114         stx             %g2, [%sp + 2047 + 128 + 0x00]
115         mov             5, %g2
116         stx             %g2, [%sp + 2047 + 128 + 0x08]
117         mov             1, %g2
118         stx             %g2, [%sp + 2047 + 128 + 0x10]
119         sethi           %hi(itlb_load), %g2
120         or              %g2, %lo(itlb_load), %g2
121         stx             %g2, [%sp + 2047 + 128 + 0x18]
122         sethi           %hi(prom_mmu_ihandle_cache), %g2
123         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
124         stx             %g2, [%sp + 2047 + 128 + 0x20]
125         sethi           %hi(KERNBASE), %g2
126         stx             %g2, [%sp + 2047 + 128 + 0x28]
127         sethi           %hi(kern_locked_tte_data), %g2
128         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
129         stx             %g2, [%sp + 2047 + 128 + 0x30]
130
131         mov             15, %g2
132         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
133
134         mov             63, %g2
135 1:
136         stx             %g2, [%sp + 2047 + 128 + 0x38]
137         sethi           %hi(p1275buf), %g2
138         or              %g2, %lo(p1275buf), %g2
139         ldx             [%g2 + 0x08], %o1
140         call            %o1
141          add            %sp, (2047 + 128), %o0
142
143         sethi           %hi(bigkernel), %g2
144         lduw            [%g2 + %lo(bigkernel)], %g2
145         cmp             %g2, 0
146         be,pt           %icc, do_dtlb
147          nop
148
149         sethi           %hi(call_method), %g2
150         or              %g2, %lo(call_method), %g2
151         stx             %g2, [%sp + 2047 + 128 + 0x00]
152         mov             5, %g2
153         stx             %g2, [%sp + 2047 + 128 + 0x08]
154         mov             1, %g2
155         stx             %g2, [%sp + 2047 + 128 + 0x10]
156         sethi           %hi(itlb_load), %g2
157         or              %g2, %lo(itlb_load), %g2
158         stx             %g2, [%sp + 2047 + 128 + 0x18]
159         sethi           %hi(prom_mmu_ihandle_cache), %g2
160         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
161         stx             %g2, [%sp + 2047 + 128 + 0x20]
162         sethi           %hi(KERNBASE + 0x400000), %g2
163         stx             %g2, [%sp + 2047 + 128 + 0x28]
164         sethi           %hi(kern_locked_tte_data), %g2
165         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
166         sethi           %hi(0x400000), %g1
167         add             %g2, %g1, %g2
168         stx             %g2, [%sp + 2047 + 128 + 0x30]
169
170         mov             14, %g2
171         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
172
173         mov             62, %g2
174 1:
175         stx             %g2, [%sp + 2047 + 128 + 0x38]
176         sethi           %hi(p1275buf), %g2
177         or              %g2, %lo(p1275buf), %g2
178         ldx             [%g2 + 0x08], %o1
179         call            %o1
180          add            %sp, (2047 + 128), %o0
181
182 do_dtlb:
183         sethi           %hi(call_method), %g2
184         or              %g2, %lo(call_method), %g2
185         stx             %g2, [%sp + 2047 + 128 + 0x00]
186         mov             5, %g2
187         stx             %g2, [%sp + 2047 + 128 + 0x08]
188         mov             1, %g2
189         stx             %g2, [%sp + 2047 + 128 + 0x10]
190         sethi           %hi(dtlb_load), %g2
191         or              %g2, %lo(dtlb_load), %g2
192         stx             %g2, [%sp + 2047 + 128 + 0x18]
193         sethi           %hi(prom_mmu_ihandle_cache), %g2
194         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
195         stx             %g2, [%sp + 2047 + 128 + 0x20]
196         sethi           %hi(KERNBASE), %g2
197         stx             %g2, [%sp + 2047 + 128 + 0x28]
198         sethi           %hi(kern_locked_tte_data), %g2
199         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
200         stx             %g2, [%sp + 2047 + 128 + 0x30]
201
202         mov             15, %g2
203         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
204
205         mov             63, %g2
206 1:
207
208         stx             %g2, [%sp + 2047 + 128 + 0x38]
209         sethi           %hi(p1275buf), %g2
210         or              %g2, %lo(p1275buf), %g2
211         ldx             [%g2 + 0x08], %o1
212         call            %o1
213          add            %sp, (2047 + 128), %o0
214
215         sethi           %hi(bigkernel), %g2
216         lduw            [%g2 + %lo(bigkernel)], %g2
217         cmp             %g2, 0
218         be,pt           %icc, do_unlock
219          nop
220
221         sethi           %hi(call_method), %g2
222         or              %g2, %lo(call_method), %g2
223         stx             %g2, [%sp + 2047 + 128 + 0x00]
224         mov             5, %g2
225         stx             %g2, [%sp + 2047 + 128 + 0x08]
226         mov             1, %g2
227         stx             %g2, [%sp + 2047 + 128 + 0x10]
228         sethi           %hi(dtlb_load), %g2
229         or              %g2, %lo(dtlb_load), %g2
230         stx             %g2, [%sp + 2047 + 128 + 0x18]
231         sethi           %hi(prom_mmu_ihandle_cache), %g2
232         lduw            [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
233         stx             %g2, [%sp + 2047 + 128 + 0x20]
234         sethi           %hi(KERNBASE + 0x400000), %g2
235         stx             %g2, [%sp + 2047 + 128 + 0x28]
236         sethi           %hi(kern_locked_tte_data), %g2
237         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
238         sethi           %hi(0x400000), %g1
239         add             %g2, %g1, %g2
240         stx             %g2, [%sp + 2047 + 128 + 0x30]
241
242         mov             14, %g2
243         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
244
245         mov             62, %g2
246 1:
247
248         stx             %g2, [%sp + 2047 + 128 + 0x38]
249         sethi           %hi(p1275buf), %g2
250         or              %g2, %lo(p1275buf), %g2
251         ldx             [%g2 + 0x08], %o1
252         call            %o1
253          add            %sp, (2047 + 128), %o0
254
255 do_unlock:
256         sethi           %hi(prom_entry_lock), %g2
257         stb             %g0, [%g2 + %lo(prom_entry_lock)]
258         membar          #StoreStore | #StoreLoad
259
260         mov             %l1, %sp
261         flushw
262
263         mov             %l0, %o0
264
265         wrpr            %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
266         wr              %g0, 0, %fprs
267
268         /* XXX Buggy PROM... */
269         srl             %o0, 0, %o0
270         ldx             [%o0], %g6
271
272         wr              %g0, ASI_P, %asi
273
274         mov             PRIMARY_CONTEXT, %g7
275         stxa            %g0, [%g7] ASI_DMMU
276         membar          #Sync
277         mov             SECONDARY_CONTEXT, %g7
278         stxa            %g0, [%g7] ASI_DMMU
279         membar          #Sync
280
281         mov             1, %g5
282         sllx            %g5, THREAD_SHIFT, %g5
283         sub             %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
284         add             %g6, %g5, %sp
285         mov             0, %fp
286
287         wrpr            %g0, 0, %wstate
288         wrpr            %g0, 0, %tl
289
290         /* Setup the trap globals, then we can resurface. */
291         rdpr            %pstate, %o1
292         mov             %g6, %o2
293         wrpr            %o1, PSTATE_AG, %pstate
294         sethi           %hi(sparc64_ttable_tl0), %g5
295         wrpr            %g5, %tba
296         mov             %o2, %g6
297
298         wrpr            %o1, PSTATE_MG, %pstate
299 #define KERN_HIGHBITS           ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
300 #define KERN_LOWBITS            (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
301
302         mov             TSB_REG, %g1
303         stxa            %g0, [%g1] ASI_DMMU
304         membar          #Sync
305         mov             TLB_SFSR, %g1
306         sethi           %uhi(KERN_HIGHBITS), %g2
307         or              %g2, %ulo(KERN_HIGHBITS), %g2
308         sllx            %g2, 32, %g2
309         or              %g2, KERN_LOWBITS, %g2
310
311         BRANCH_IF_ANY_CHEETAH(g3,g7,9f)
312
313         ba,pt           %xcc, 1f
314          nop
315
316 9:
317         sethi           %uhi(VPTE_BASE_CHEETAH), %g3
318         or              %g3, %ulo(VPTE_BASE_CHEETAH), %g3
319         ba,pt           %xcc, 2f
320          sllx           %g3, 32, %g3
321 1:
322         sethi           %uhi(VPTE_BASE_SPITFIRE), %g3
323         or              %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
324         sllx            %g3, 32, %g3
325
326 2:
327         clr     %g7
328 #undef KERN_HIGHBITS
329 #undef KERN_LOWBITS
330
331         wrpr            %o1, 0x0, %pstate
332         ldx             [%g6 + TI_TASK], %g4
333
334         wrpr            %g0, 0, %wstate
335
336         call            init_irqwork_curcpu
337          nop
338
339         /* Start using proper page size encodings in ctx register.  */
340         sethi   %hi(sparc64_kern_pri_context), %g3
341         ldx     [%g3 + %lo(sparc64_kern_pri_context)], %g2
342         mov     PRIMARY_CONTEXT, %g1
343         stxa    %g2, [%g1] ASI_DMMU
344         membar  #Sync
345
346         rdpr            %pstate, %o1
347         or              %o1, PSTATE_IE, %o1
348         wrpr            %o1, 0, %pstate
349
350         call            prom_set_trap_table
351          sethi          %hi(sparc64_ttable_tl0), %o0
352
353         call            smp_callin
354          nop
355         call            cpu_idle
356          mov            0, %o0
357         call            cpu_panic
358          nop
359 1:      b,a,pt          %xcc, 1b
360
361         .align          8
362 sparc64_cpu_startup_end: