srt0.s revision 1.8 1 /* $NetBSD: srt0.s,v 1.8 2019/11/28 14:21:25 martin Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <machine/psl.h>
35 #include <machine/param.h>
36 #include <machine/frame.h>
37 #include <machine/asm.h>
38 #include <machine/ctlreg.h>
39
40
41 #ifdef _LP64
42 #define LDPTR ldx
43 #else
44 #define LDPTR lduw
45 #endif
46
47
48 .register %g2,#ignore
49 .register %g3,#ignore
50
51 /*
52 * Globals
53 */
54 .globl _esym
55 .data
56 _esym: .word 0 /* end of symbol table */
57
58 /*
59 * Startup entry
60 */
61 .text
62 .globl _start, _C_LABEL(kernel_text)
63 _C_LABEL(kernel_text) = _start
64 _start:
65 nop ! For some reason this is needed to fixup the text section
66 b 1f
67 nop
68 .zero 8192-(.-_start) /* hack for OpenBIOS, see port-sparc64/54719 */
69 1:
70 /*
71 * Start by creating a stack for ourselves.
72 */
73 #ifdef _LP64
74 /* 64-bit stack */
75 btst 1, %sp
76 set CC64FSZ, %g1 ! Frame Size (negative)
77 bnz 1f
78 set BIAS, %g2 ! Bias (negative)
79 andn %sp, 0x0f, %sp ! 16 byte align, per ELF spec.
80 add %g1, %g2, %g1 ! Frame + Bias
81 1:
82 sub %sp, %g1, %g1
83 save %g1, %g0, %sp
84 #else
85 /* 32-bit stack */
86 btst 1, %sp
87 set CC64FSZ, %g1 ! Frame Size (negative)
88 bz 1f
89 set BIAS, %g2
90 sub %g1, %g2, %g1
91 1:
92 sub %sp, %g1, %g1 ! This is so we properly sign-extend things
93 andn %g1, 0x7, %g1
94 save %g1, %g0, %sp
95 #endif
96
97 /*
98 * Set the psr into a known state:
99 * Set supervisor mode, interrupt level >= 13, traps enabled
100 */
101 wrpr %g0, 0, %pil ! So I lied
102 wrpr %g0, PSTATE_PRIV+PSTATE_IE, %pstate
103
104 clr %g4 ! Point %g4 to start of data segment
105 ! only problem is that apparently the
106 ! start of the data segment is 0
107
108 /*
109 * void
110 * main(void *openfirmware)
111 */
112 call _C_LABEL(main)
113 mov %i4, %o0
114 call _C_LABEL(OF_exit)
115 nop
116
117 /*
118 * void syncicache(void* start, int size)
119 *
120 * I$ flush. Really simple. Just flush over the whole range.
121 */
122 .align 8
123 .globl _C_LABEL(syncicache)
124 _C_LABEL(syncicache):
125 dec 4, %o1
126 flush %o0
127 brgz,a,pt %o1, _C_LABEL(syncicache)
128 inc 4, %o0
129 retl
130 nop
131
132 /*
133 * openfirmware(cell* param);
134 *
135 * OpenFirmware entry point
136 *
137 * If we're running in 32-bit mode we need to convert to a 64-bit stack
138 * and 64-bit cells. The cells we'll allocate off the stack for simplicity.
139 */
140 .align 8
141 .globl _C_LABEL(openfirmware)
142 FTYPE(openfirmware)
143 _C_LABEL(openfirmware):
144 andcc %sp, 1, %g0
145 bz,pt %icc, 1f
146 sethi %hi(_C_LABEL(romp)), %o1
147
148 LDPTR [%o1+%lo(_C_LABEL(romp))], %o4 ! v9 stack, just load the addr and callit
149 save %sp, -CC64FSZ, %sp
150 mov %i0, %o0 ! Copy over our parameter
151 mov %g1, %l1
152 mov %g2, %l2
153 mov %g3, %l3
154 mov %g4, %l4
155 mov %g5, %l5
156 mov %g6, %l6
157 mov %g7, %l7
158 rdpr %pstate, %l0
159 jmpl %i4, %o7
160 wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate
161 wrpr %l0, %g0, %pstate
162 mov %l1, %g1
163 mov %l2, %g2
164 mov %l3, %g3
165 mov %l4, %g4
166 mov %l5, %g5
167 mov %l6, %g6
168 mov %l7, %g7
169 ret
170 restore %o0, %g0, %o0
171
172 1: ! v8 -- need to screw with stack & params
173 save %sp, -CC64FSZ, %sp ! Get a new 64-bit stack frame
174 add %sp, -BIAS, %sp
175 sethi %hi(_C_LABEL(romp)), %o1
176 rdpr %pstate, %l0
177 LDPTR [%o1+%lo(_C_LABEL(romp))], %o1 ! Do the actual call
178 srl %sp, 0, %sp
179 mov %i0, %o0
180 mov %g1, %l1
181 mov %g2, %l2
182 mov %g3, %l3
183 mov %g4, %l4
184 mov %g5, %l5
185 mov %g6, %l6
186 mov %g7, %l7
187 jmpl %o1, %o7
188 wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate ! Enable 64-bit addresses for the prom
189 wrpr %l0, 0, %pstate
190 mov %l1, %g1
191 mov %l2, %g2
192 mov %l3, %g3
193 mov %l4, %g4
194 mov %l5, %g5
195 mov %l6, %g6
196 mov %l7, %g7
197 ret
198 restore %o0, %g0, %o0
199
200 /*
201 * vaddr_t
202 * itlb_va_to_pa(vaddr_t)
203 *
204 * Find out if there is a mapping in iTLB for a given virtual address,
205 * return -1 if there is none.
206 */
207 .align 8
208 .globl _C_LABEL(itlb_va_to_pa)
209 _C_LABEL(itlb_va_to_pa):
210 set _C_LABEL(itlb_slot_max), %o3
211 ld [%o3], %o3
212 dec %o3
213 sllx %o3, 3, %o3
214 clr %o1
215 0: ldxa [%o1] ASI_IMMU_TLB_TAG, %o2
216 cmp %o2, %o0
217 bne,a %xcc, 1f
218 nop
219 /* return PA of matching entry */
220 ldxa [%o1] ASI_IMMU_TLB_DATA, %o0
221 sllx %o0, 23, %o0
222 srlx %o0, PGSHIFT+23, %o0
223 sllx %o0, PGSHIFT, %o0
224 retl
225 mov %o0, %o1
226 1: cmp %o1, %o3
227 blu %xcc, 0b
228 add %o1, 8, %o1
229 clr %o0
230 retl
231 not %o0
232
233 /*
234 * vaddr_t
235 * dtlb_va_to_pa(vaddr_t)
236 *
237 * Find out if there is a mapping in dTLB for a given virtual address,
238 * return -1 if there is none.
239 */
240 .align 8
241 .globl _C_LABEL(dtlb_va_to_pa)
242 _C_LABEL(dtlb_va_to_pa):
243 set _C_LABEL(dtlb_slot_max), %o3
244 ld [%o3], %o3
245 dec %o3
246 sllx %o3, 3, %o3
247 clr %o1
248 0: ldxa [%o1] ASI_DMMU_TLB_TAG, %o2
249 cmp %o2, %o0
250 bne,a %xcc, 1f
251 nop
252 /* return PA of matching entry */
253 ldxa [%o1] ASI_DMMU_TLB_DATA, %o0
254 sllx %o0, 23, %o0
255 srlx %o0, PGSHIFT+23, %o0
256 sllx %o0, PGSHIFT, %o0
257 retl
258 mov %o0, %o1
259 1: cmp %o1, %o3
260 blu %xcc, 0b
261 add %o1, 8, %o1
262 clr %o0
263 retl
264 not %o0
265
266 /*
267 * void
268 * itlb_enter(vaddr_t vpn, uint32_t data_hi, uint32_t data_lo)
269 *
270 * Insert new mapping into iTLB. Data tag is passed in two different
271 * registers so that it works even with 32-bit compilers.
272 */
273 .align 8
274 .globl _C_LABEL(itlb_enter)
275 _C_LABEL(itlb_enter):
276 sllx %o1, 32, %o1
277 or %o1, %o2, %o1
278 rdpr %pstate, %o4
279 wrpr %o4, PSTATE_IE, %pstate
280 mov TLB_TAG_ACCESS, %o3
281 stxa %o0, [%o3] ASI_IMMU
282 stxa %o1, [%g0] ASI_IMMU_DATA_IN
283 membar #Sync
284 retl
285 wrpr %o4, 0, %pstate
286
287
288 /*
289 * void
290 * dtlb_replace(vaddr_t vpn, uint32_t data_hi, uint32_t data_lo)
291 *
292 * Replace mapping in dTLB. Data tag is passed in two different
293 * registers so that it works even with 32-bit compilers.
294 */
295 .align 8
296 .globl _C_LABEL(dtlb_replace)
297 _C_LABEL(dtlb_replace):
298 sllx %o1, 32, %o1
299 or %o1, %o2, %o1
300 rdpr %pstate, %o4
301 wrpr %o4, PSTATE_IE, %pstate
302 /* loop over dtlb entries */
303 clr %o5
304 0:
305 ldxa [%o5] ASI_DMMU_TLB_TAG, %o2
306 cmp %o2, %o0
307 bne,a %xcc, 1f
308 nop
309 /* found - modify entry */
310 mov TLB_TAG_ACCESS, %o2
311 stxa %o0, [%o2] ASI_DMMU
312 stxa %o1, [%o5] ASI_DMMU_TLB_DATA
313 membar #Sync
314 retl
315 wrpr %o4, 0, %pstate
316
317 /* advance to next tlb entry */
318 1: cmp %o5, 63<<3
319 blu %xcc, 0b
320 add %o5, 8, %o5
321 retl
322 nop
323
324 /*
325 * void
326 * dtlb_enter(vaddr_t vpn, uint32_t data_hi, uint32_t data_lo)
327 *
328 * Insert new mapping into dTLB. Data tag is passed in two different
329 * registers so that it works even with 32-bit compilers.
330 */
331 .align 8
332 .globl _C_LABEL(dtlb_enter)
333 _C_LABEL(dtlb_enter):
334 sllx %o1, 32, %o1
335 or %o1, %o2, %o1
336 rdpr %pstate, %o4
337 wrpr %o4, PSTATE_IE, %pstate
338 mov TLB_TAG_ACCESS, %o3
339 stxa %o0, [%o3] ASI_DMMU
340 stxa %o1, [%g0] ASI_DMMU_DATA_IN
341 membar #Sync
342 retl
343 wrpr %o4, 0, %pstate
344
345 /*
346 * u_int
347 * get_cpuid(void);
348 *
349 * Return UPA identifier for the CPU we're running on.
350 */
351 .align 8
352 .globl _C_LABEL(get_cpuid)
353 _C_LABEL(get_cpuid):
354 UPA_GET_MID(%o0)
355 retl
356 nop
357
358 #if 0
359 .data
360 .align 8
361 bootstack:
362 #define STACK_SIZE 0x14000
363 .skip STACK_SIZE
364 ebootstack: ! end (top) of boot stack
365 #endif
366