ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / 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
19         .data
20         .align  8
21 call_method:
22         .asciz  "call-method"
23         .align  8
24 itlb_load:
25         .asciz  "SUNW,itlb-load"
26         .align  8
27 dtlb_load:
28         .asciz  "SUNW,dtlb-load"
29
30         .text
31         .align          8
32         .globl          sparc64_cpu_startup, sparc64_cpu_startup_end
33 sparc64_cpu_startup:
34         flushw
35
36         BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_startup)
37         BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_startup)
38
39         ba,pt   %xcc, spitfire_startup
40          nop
41
42 cheetah_plus_startup:
43         /* Preserve OBP chosen DCU and DCR register settings.  */
44         ba,pt   %xcc, cheetah_generic_startup
45          nop
46
47 cheetah_startup:
48         mov     DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
49         wr      %g1, %asr18
50
51         sethi   %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
52         or      %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
53         sllx    %g5, 32, %g5
54         or      %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
55         stxa    %g5, [%g0] ASI_DCU_CONTROL_REG
56         membar  #Sync
57
58 cheetah_generic_startup:
59         mov     TSB_EXTENSION_P, %g3
60         stxa    %g0, [%g3] ASI_DMMU
61         stxa    %g0, [%g3] ASI_IMMU
62         membar  #Sync
63
64         mov     TSB_EXTENSION_S, %g3
65         stxa    %g0, [%g3] ASI_DMMU
66         membar  #Sync
67
68         mov     TSB_EXTENSION_N, %g3
69         stxa    %g0, [%g3] ASI_DMMU
70         stxa    %g0, [%g3] ASI_IMMU
71         membar  #Sync
72
73         /* Disable STICK_INT interrupts. */
74         sethi           %hi(0x80000000), %g5
75         sllx            %g5, 32, %g5
76         wr              %g5, %asr25
77
78         ba,pt           %xcc, startup_continue
79          nop
80
81 spitfire_startup:
82         mov             (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
83         stxa            %g1, [%g0] ASI_LSU_CONTROL
84         membar          #Sync
85
86 startup_continue:
87         wrpr            %g0, 15, %pil
88
89         sethi           %hi(0x80000000), %g2
90         sllx            %g2, 32, %g2
91         wr              %g2, 0, %tick_cmpr
92
93         /* Call OBP by hand to lock KERNBASE into i/d tlbs. */
94         mov             %o0, %l0
95
96         sethi           %hi(prom_entry_lock), %g2
97 1:      ldstub          [%g2 + %lo(prom_entry_lock)], %g1
98         brnz,pn         %g1, 1b
99          membar         #StoreLoad | #StoreStore
100
101         sethi           %hi(p1275buf), %g2
102         or              %g2, %lo(p1275buf), %g2
103         ldx             [%g2 + 0x10], %l2
104         mov             %sp, %l1
105         add             %l2, -(192 + 128), %sp
106         flushw
107
108         sethi           %hi(call_method), %g2
109         or              %g2, %lo(call_method), %g2
110         stx             %g2, [%sp + 2047 + 128 + 0x00]
111         mov             5, %g2
112         stx             %g2, [%sp + 2047 + 128 + 0x08]
113         mov             1, %g2
114         stx             %g2, [%sp + 2047 + 128 + 0x10]
115         sethi           %hi(itlb_load), %g2
116         or              %g2, %lo(itlb_load), %g2
117         stx             %g2, [%sp + 2047 + 128 + 0x18]
118         sethi           %hi(mmu_ihandle_cache), %g2
119         lduw            [%g2 + %lo(mmu_ihandle_cache)], %g2
120         stx             %g2, [%sp + 2047 + 128 + 0x20]
121         sethi           %hi(KERNBASE), %g2
122         stx             %g2, [%sp + 2047 + 128 + 0x28]
123         sethi           %hi(kern_locked_tte_data), %g2
124         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
125         stx             %g2, [%sp + 2047 + 128 + 0x30]
126
127         mov             15, %g2
128         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
129
130         mov             63, %g2
131 1:
132         stx             %g2, [%sp + 2047 + 128 + 0x38]
133         sethi           %hi(p1275buf), %g2
134         or              %g2, %lo(p1275buf), %g2
135         ldx             [%g2 + 0x08], %o1
136         call            %o1
137          add            %sp, (2047 + 128), %o0
138
139         sethi           %hi(call_method), %g2
140         or              %g2, %lo(call_method), %g2
141         stx             %g2, [%sp + 2047 + 128 + 0x00]
142         mov             5, %g2
143         stx             %g2, [%sp + 2047 + 128 + 0x08]
144         mov             1, %g2
145         stx             %g2, [%sp + 2047 + 128 + 0x10]
146         sethi           %hi(dtlb_load), %g2
147         or              %g2, %lo(dtlb_load), %g2
148         stx             %g2, [%sp + 2047 + 128 + 0x18]
149         sethi           %hi(mmu_ihandle_cache), %g2
150         lduw            [%g2 + %lo(mmu_ihandle_cache)], %g2
151         stx             %g2, [%sp + 2047 + 128 + 0x20]
152         sethi           %hi(KERNBASE), %g2
153         stx             %g2, [%sp + 2047 + 128 + 0x28]
154         sethi           %hi(kern_locked_tte_data), %g2
155         ldx             [%g2 + %lo(kern_locked_tte_data)], %g2
156         stx             %g2, [%sp + 2047 + 128 + 0x30]
157
158         mov             15, %g2
159         BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
160
161         mov             63, %g2
162 1:
163
164         stx             %g2, [%sp + 2047 + 128 + 0x38]
165         sethi           %hi(p1275buf), %g2
166         or              %g2, %lo(p1275buf), %g2
167         ldx             [%g2 + 0x08], %o1
168         call            %o1
169          add            %sp, (2047 + 128), %o0
170
171         sethi           %hi(prom_entry_lock), %g2
172         stb             %g0, [%g2 + %lo(prom_entry_lock)]
173         membar          #StoreStore | #StoreLoad
174
175         mov             %l1, %sp
176         flushw
177
178         mov             %l0, %o0
179
180         wrpr            %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
181         wr              %g0, 0, %fprs
182
183         /* XXX Buggy PROM... */
184         srl             %o0, 0, %o0
185         ldx             [%o0], %g6
186
187         wr              %g0, ASI_P, %asi
188
189         mov             PRIMARY_CONTEXT, %g7
190         stxa            %g0, [%g7] ASI_DMMU
191         membar          #Sync
192         mov             SECONDARY_CONTEXT, %g7
193         stxa            %g0, [%g7] ASI_DMMU
194         membar          #Sync
195
196         mov             1, %g5
197         sllx            %g5, THREAD_SHIFT, %g5
198         sub             %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
199         add             %g6, %g5, %sp
200         mov             0, %fp
201
202         wrpr            %g0, 0, %wstate
203         wrpr            %g0, 0, %tl
204
205         /* Setup the trap globals, then we can resurface. */
206         rdpr            %pstate, %o1
207         mov             %g6, %o2
208         wrpr            %o1, PSTATE_AG, %pstate
209         sethi           %hi(sparc64_ttable_tl0), %g5
210         wrpr            %g5, %tba
211         mov             %o2, %g6
212
213         wrpr            %o1, PSTATE_MG, %pstate
214 #define KERN_HIGHBITS           ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
215 #define KERN_LOWBITS            (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
216
217         mov             TSB_REG, %g1
218         stxa            %g0, [%g1] ASI_DMMU
219         membar          #Sync
220         mov             TLB_SFSR, %g1
221         sethi           %uhi(KERN_HIGHBITS), %g2
222         or              %g2, %ulo(KERN_HIGHBITS), %g2
223         sllx            %g2, 32, %g2
224         or              %g2, KERN_LOWBITS, %g2
225
226         BRANCH_IF_ANY_CHEETAH(g3,g7,9f)
227
228         ba,pt           %xcc, 1f
229          nop
230
231 9:
232         sethi           %uhi(VPTE_BASE_CHEETAH), %g3
233         or              %g3, %ulo(VPTE_BASE_CHEETAH), %g3
234         ba,pt           %xcc, 2f
235          sllx           %g3, 32, %g3
236 1:
237         sethi           %uhi(VPTE_BASE_SPITFIRE), %g3
238         or              %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
239         sllx            %g3, 32, %g3
240
241 2:
242         clr     %g7
243 #undef KERN_HIGHBITS
244 #undef KERN_LOWBITS
245
246         wrpr            %o1, 0x0, %pstate
247         ldx             [%g6 + TI_TASK], %g4
248
249         wrpr            %g0, 0, %wstate
250
251         call            init_irqwork_curcpu
252          nop
253
254         rdpr            %pstate, %o1
255         or              %o1, PSTATE_IE, %o1
256         wrpr            %o1, 0, %pstate
257
258         call            prom_set_trap_table
259          sethi          %hi(sparc64_ttable_tl0), %o0
260
261         call            smp_callin
262          nop
263         call            cpu_idle
264          mov            0, %o0
265         call            cpu_panic
266          nop
267 1:      b,a,pt          %xcc, 1b
268
269         .align          8
270 sparc64_cpu_startup_end: