* better
[mascara-docs.git] / i386 / linux-2.3.21 / arch / sparc64 / kernel / trampoline.S
blobfba910a55bdcb87925de17a015c1234fffd327ea
1 /* $Id: trampoline.S,v 1.10 1999/09/10 10:40:48 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 #include <linux/config.h>
9 #include <asm/head.h>
10 #include <asm/asi.h>
11 #include <asm/lsu.h>
12 #include <asm/pstate.h>
13 #include <asm/page.h>
14 #include <asm/pgtable.h>
15 #include <asm/spitfire.h>
16 #include <asm/asm_offsets.h>
18         .data
19         .align          8
20         .globl          smp_trampoline
21 smp_trampoline:         .skip   0x300
23         .text
24         .align          8
25         .globl          sparc64_cpu_startup, sparc64_cpu_startup_end
26 sparc64_cpu_startup:
27         flushw
28         mov     (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
29         stxa    %g1, [%g0] ASI_LSU_CONTROL
30         membar  #Sync
31         wrpr    %g0, (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE), %pstate
32         wr      %g0, 0, %fprs
33         wrpr    %g0, 15, %pil
35         sethi   %uhi(PAGE_OFFSET), %g4
36         sllx    %g4, 32, %g4
38         /* XXX Buggy PROM... */
39         srl     %o0, 0, %o0
40         ldx     [%o0], %g6
42         sethi   %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
43         sllx    %g5, 32, %g5
44         or      %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
46         sethi   %uhi(_PAGE_PADDR), %g3
47         or      %g3, %ulo(_PAGE_PADDR), %g3
48         sllx    %g3, 32, %g3
49         sethi   %hi(_PAGE_PADDR), %g7
50         or      %g7, %lo(_PAGE_PADDR), %g7
51         or      %g3, %g7, %g3
53         clr     %l0
54         set     0x1fff, %l2
55         rd      %pc, %l3
56         andn    %l3, %l2, %g2
57 1:      ldxa    [%l0] ASI_ITLB_TAG_READ, %g1
58         nop
59         nop
60         nop
61         andn    %g1, %l2, %g1
62         cmp     %g1, %g2
63         be,a,pn %xcc, 2f
64          ldxa   [%l0] ASI_ITLB_DATA_ACCESS, %g1
65         cmp     %l0, (63 << 3)
66         blu,pt  %xcc, 1b
67          add    %l0, (1 << 3), %l0
69 2:      nop
70         nop
71         nop
72         and     %g1, %g3, %g1
73         sub     %g1, %g2, %g1
74         or      %g5, %g1, %g5
75         clr     %l0
76         sethi   %hi(KERNBASE), %g3
77         sethi   %hi(KERNBASE<<1), %g7
78         mov     TLB_TAG_ACCESS, %l7
79 1:      ldxa    [%l0] ASI_ITLB_TAG_READ, %g1
80         nop
81         nop
82         nop
83         andn    %g1, %l2, %g1
84         cmp     %g1, %g3
85         blu,pn  %xcc, 2f
86          cmp    %g1, %g7
87         bgeu,pn %xcc, 2f
88          nop
89         stxa    %g0, [%l7] ASI_IMMU
90         stxa    %g0, [%l0] ASI_ITLB_DATA_ACCESS
91 2:      cmp     %l0, (63 << 3)
92         blu,pt  %xcc, 1b
93          add    %l0, (1 << 3), %l0
95         nop
96         nop
97         nop
98         clr     %l0
99 1:      ldxa    [%l0] ASI_DTLB_TAG_READ, %g1
100         nop
101         nop
102         nop
103         andn    %g1, %l2, %g1
104         cmp     %g1, %g3
105         blu,pn  %xcc, 2f
106          cmp    %g1, %g7
107         bgeu,pn %xcc, 2f
108          nop
109         stxa    %g0, [%l7] ASI_DMMU
110         stxa    %g0, [%l0] ASI_DTLB_DATA_ACCESS
111 2:      cmp     %l0, (63 << 3)
112         blu,pt  %xcc, 1b
113          add    %l0, (1 << 3), %l0
115         nop
116         nop
117         nop
118         sethi   %hi(KERNBASE), %g3
119         mov     (63 << 3), %g7
120         stxa    %g3, [%l7] ASI_DMMU
121         stxa    %g5, [%g7] ASI_DTLB_DATA_ACCESS
122         membar  #Sync
123         stxa    %g3, [%l7] ASI_IMMU
124         stxa    %g5, [%g7] ASI_ITLB_DATA_ACCESS
125         membar  #Sync
126         flush   %g3
127         membar  #Sync
128         b,pt    %xcc, 1f
129          nop
130 1:      set     bounce, %g2
131         jmpl    %g2 + %g0, %g0
132          nop
134 bounce:
135         wr      %g0, ASI_P, %asi
137         mov     PRIMARY_CONTEXT, %g7
138         stxa    %g0, [%g7] ASI_DMMU
139         membar  #Sync
140         mov     SECONDARY_CONTEXT, %g7
141         stxa    %g0, [%g7] ASI_DMMU
142         membar  #Sync
144         mov     TLB_TAG_ACCESS, %g2
145         stxa    %g3, [%g2] ASI_IMMU
146         stxa    %g3, [%g2] ASI_DMMU
148         mov     (63 << 3), %g7
149         ldxa    [%g7] ASI_ITLB_DATA_ACCESS, %g1
150         andn    %g1, (_PAGE_G), %g1
151         stxa    %g1, [%g7] ASI_ITLB_DATA_ACCESS
152         membar  #Sync
154         ldxa    [%g7] ASI_DTLB_DATA_ACCESS, %g1
155         andn    %g1, (_PAGE_G), %g1
156         stxa    %g1, [%g7] ASI_DTLB_DATA_ACCESS
157         membar  #Sync
159         flush   %g3
160         membar  #Sync
162         mov     1, %g5
163         sllx    %g5, (PAGE_SHIFT + 1), %g5
164         sub     %g5, (REGWIN_SZ + STACK_BIAS), %g5
165         add     %g6, %g5, %sp
166         mov     0, %fp
168         wrpr    %g0, 0, %wstate
169         wrpr    %g0, 0, %tl
171         /* Setup the trap globals, then we can resurface. */
172         rdpr    %pstate, %o1
173         mov     %g6, %o2
174         wrpr    %o1, (PSTATE_AG | PSTATE_IE), %pstate
175         sethi   %hi(sparc64_ttable_tl0), %g5
176         wrpr    %g5, %tba
177         mov     %o2, %g6
179         wrpr    %o1, (PSTATE_MG | PSTATE_IE), %pstate
180 #define KERN_HIGHBITS           ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
181 #define KERN_LOWBITS            (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
182 #ifdef THIS_IS_CHEETAH
183 #error Dave, make sure you took care of other issues in rest of sparc64 code...
184 #define VPTE_BASE               0xffe0000000000000
185 #else /* Spitfire/Blackbird */
186 #define VPTE_BASE               0xfffffffe00000000
187 #endif
188         mov     TSB_REG, %g1
189         stxa    %g0, [%g1] ASI_DMMU
190         membar  #Sync
191         mov     TLB_SFSR, %g1
192         sethi   %uhi(KERN_HIGHBITS), %g2
193         or      %g2, %ulo(KERN_HIGHBITS), %g2
194         sllx    %g2, 32, %g2
195         or      %g2, KERN_LOWBITS, %g2
196         sethi   %uhi(VPTE_BASE), %g3
197         or      %g3, %ulo(VPTE_BASE), %g3
198         sllx    %g3, 32, %g3
199         clr     %g7
200 #undef KERN_HIGHBITS
201 #undef KERN_LOWBITS
202 #undef VPTE_BASE
204         /* Setup interrupt globals, we are always SMP. */
205         wrpr    %o1, (PSTATE_IG | PSTATE_IE), %pstate
207         /* Get our UPA MID. */
208         lduw    [%o2 + AOFF_task_processor], %g1
209         sethi   %hi(cpu_data), %g5
210         or      %g5, %lo(cpu_data), %g5
212         /* In theory this is: &(cpu_data[this_upamid].irq_worklists[0]) */
213         sllx    %g1, 7, %g1
214         add     %g5, %g1, %g1
215         add     %g1, 64, %g1
217         wrpr    %g0, 0, %wstate
218         or      %o1, PSTATE_IE, %o1
219         wrpr    %o1, 0, %pstate
221         call    smp_callin
222          nop
223         call    cpu_idle
224          mov    0, %o0
225         call    cpu_panic
226          nop
227 1:      b,a,pt  %xcc, 1b
229         .align          8
230 sparc64_cpu_startup_end: