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