srt0.s revision 1.3 1 1.3 cdi /* $NetBSD: srt0.s,v 1.3 2006/01/27 18:31:12 cdi 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.1 mrg
67 1.1 mrg /*
68 1.1 mrg * Start by creating a stack for ourselves.
69 1.1 mrg */
70 1.1 mrg #ifdef _LP64
71 1.1 mrg /* 64-bit stack */
72 1.1 mrg btst 1, %sp
73 1.1 mrg set CC64FSZ, %g1 ! Frame Size (negative)
74 1.1 mrg bnz 1f
75 1.1 mrg set BIAS, %g2 ! Bias (negative)
76 1.1 mrg andn %sp, 0x0f, %sp ! 16 byte align, per ELF spec.
77 1.1 mrg add %g1, %g2, %g1 ! Frame + Bias
78 1.1 mrg 1:
79 1.1 mrg sub %sp, %g1, %g1
80 1.1 mrg save %g1, %g0, %sp
81 1.1 mrg #else
82 1.1 mrg /* 32-bit stack */
83 1.1 mrg btst 1, %sp
84 1.1 mrg set CC64FSZ, %g1 ! Frame Size (negative)
85 1.1 mrg bz 1f
86 1.1 mrg set BIAS, %g2
87 1.1 mrg sub %g1, %g2, %g1
88 1.1 mrg 1:
89 1.1 mrg sub %sp, %g1, %g1 ! This is so we properly sign-extend things
90 1.1 mrg andn %g1, 0x7, %g1
91 1.1 mrg save %g1, %g0, %sp
92 1.1 mrg #endif
93 1.3 cdi
94 1.1 mrg /*
95 1.1 mrg * Set the psr into a known state:
96 1.1 mrg * Set supervisor mode, interrupt level >= 13, traps enabled
97 1.1 mrg */
98 1.1 mrg wrpr %g0, 0, %pil ! So I lied
99 1.1 mrg wrpr %g0, PSTATE_PRIV+PSTATE_IE, %pstate
100 1.1 mrg
101 1.1 mrg clr %g4 ! Point %g4 to start of data segment
102 1.1 mrg ! only problem is that apparently the
103 1.1 mrg ! start of the data segment is 0
104 1.3 cdi
105 1.1 mrg /*
106 1.3 cdi * void
107 1.3 cdi * main(void *openfirmware)
108 1.1 mrg */
109 1.1 mrg call _C_LABEL(main)
110 1.3 cdi mov %i4, %o0
111 1.3 cdi call _C_LABEL(OF_exit)
112 1.1 mrg nop
113 1.1 mrg
114 1.1 mrg /*
115 1.1 mrg * void syncicache(void* start, int size)
116 1.1 mrg *
117 1.1 mrg * I$ flush. Really simple. Just flush over the whole range.
118 1.1 mrg */
119 1.1 mrg .align 8
120 1.1 mrg .globl _C_LABEL(syncicache)
121 1.1 mrg _C_LABEL(syncicache):
122 1.1 mrg dec 4, %o1
123 1.1 mrg flush %o0
124 1.1 mrg brgz,a,pt %o1, _C_LABEL(syncicache)
125 1.1 mrg inc 4, %o0
126 1.1 mrg retl
127 1.1 mrg nop
128 1.1 mrg
129 1.1 mrg /*
130 1.1 mrg * openfirmware(cell* param);
131 1.1 mrg *
132 1.1 mrg * OpenFirmware entry point
133 1.1 mrg *
134 1.1 mrg * If we're running in 32-bit mode we need to convert to a 64-bit stack
135 1.1 mrg * and 64-bit cells. The cells we'll allocate off the stack for simplicity.
136 1.1 mrg */
137 1.1 mrg .align 8
138 1.1 mrg .globl _C_LABEL(openfirmware)
139 1.1 mrg .proc 1
140 1.1 mrg FTYPE(openfirmware)
141 1.1 mrg _C_LABEL(openfirmware):
142 1.1 mrg andcc %sp, 1, %g0
143 1.1 mrg bz,pt %icc, 1f
144 1.1 mrg sethi %hi(_C_LABEL(romp)), %o1
145 1.1 mrg
146 1.3 cdi LDPTR [%o1+%lo(_C_LABEL(romp))], %o4 ! v9 stack, just load the addr and callit
147 1.1 mrg save %sp, -CC64FSZ, %sp
148 1.1 mrg mov %i0, %o0 ! Copy over our parameter
149 1.1 mrg mov %g1, %l1
150 1.1 mrg mov %g2, %l2
151 1.1 mrg mov %g3, %l3
152 1.1 mrg mov %g4, %l4
153 1.1 mrg mov %g5, %l5
154 1.1 mrg mov %g6, %l6
155 1.1 mrg mov %g7, %l7
156 1.1 mrg rdpr %pstate, %l0
157 1.1 mrg jmpl %i4, %o7
158 1.1 mrg wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate
159 1.1 mrg wrpr %l0, %g0, %pstate
160 1.1 mrg mov %l1, %g1
161 1.1 mrg mov %l2, %g2
162 1.1 mrg mov %l3, %g3
163 1.1 mrg mov %l4, %g4
164 1.1 mrg mov %l5, %g5
165 1.1 mrg mov %l6, %g6
166 1.1 mrg mov %l7, %g7
167 1.1 mrg ret
168 1.1 mrg restore %o0, %g0, %o0
169 1.1 mrg
170 1.1 mrg 1: ! v8 -- need to screw with stack & params
171 1.1 mrg save %sp, -CC64FSZ, %sp ! Get a new 64-bit stack frame
172 1.1 mrg add %sp, -BIAS, %sp
173 1.1 mrg sethi %hi(_C_LABEL(romp)), %o1
174 1.1 mrg rdpr %pstate, %l0
175 1.3 cdi LDPTR [%o1+%lo(_C_LABEL(romp))], %o1 ! Do the actual call
176 1.1 mrg srl %sp, 0, %sp
177 1.1 mrg mov %i0, %o0
178 1.1 mrg mov %g1, %l1
179 1.1 mrg mov %g2, %l2
180 1.1 mrg mov %g3, %l3
181 1.1 mrg mov %g4, %l4
182 1.1 mrg mov %g5, %l5
183 1.1 mrg mov %g6, %l6
184 1.1 mrg mov %g7, %l7
185 1.1 mrg jmpl %o1, %o7
186 1.1 mrg wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate ! Enable 64-bit addresses for the prom
187 1.1 mrg wrpr %l0, 0, %pstate
188 1.1 mrg mov %l1, %g1
189 1.1 mrg mov %l2, %g2
190 1.1 mrg mov %l3, %g3
191 1.1 mrg mov %l4, %g4
192 1.1 mrg mov %l5, %g5
193 1.1 mrg mov %l6, %g6
194 1.1 mrg mov %l7, %g7
195 1.1 mrg ret
196 1.1 mrg restore %o0, %g0, %o0
197 1.1 mrg
198 1.3 cdi /*
199 1.3 cdi * vaddr_t
200 1.3 cdi * itlb_va_to_pa(vaddr_t)
201 1.3 cdi *
202 1.3 cdi * Find out if there is a mapping in iTLB for a given virtual address,
203 1.3 cdi * return -1 if there is none.
204 1.3 cdi */
205 1.3 cdi .align 8
206 1.3 cdi .globl _C_LABEL(itlb_va_to_pa)
207 1.3 cdi _C_LABEL(itlb_va_to_pa):
208 1.3 cdi clr %o1
209 1.3 cdi 0: ldxa [%o1] ASI_IMMU_TLB_TAG, %o2
210 1.3 cdi cmp %o2, %o0
211 1.3 cdi bne,a %xcc, 1f
212 1.3 cdi nop
213 1.3 cdi /* return PA of matching entry */
214 1.3 cdi ldxa [%o1] ASI_IMMU_TLB_DATA, %o0
215 1.3 cdi sllx %o0, 23, %o0
216 1.3 cdi srlx %o0, PGSHIFT+23, %o0
217 1.3 cdi sllx %o0, PGSHIFT, %o0
218 1.3 cdi retl
219 1.3 cdi mov %o0, %o1
220 1.3 cdi 1: cmp %o1, 63<<3
221 1.3 cdi blu %xcc, 0b
222 1.3 cdi add %o1, 8, %o1
223 1.3 cdi clr %o0
224 1.3 cdi retl
225 1.3 cdi not %o0
226 1.3 cdi
227 1.3 cdi /*
228 1.3 cdi * vaddr_t
229 1.3 cdi * dtlb_va_to_pa(vaddr_t)
230 1.3 cdi *
231 1.3 cdi * Find out if there is a mapping in dTLB for a given virtual address,
232 1.3 cdi * return -1 if there is none.
233 1.3 cdi */
234 1.3 cdi .align 8
235 1.3 cdi .globl _C_LABEL(dtlb_va_to_pa)
236 1.3 cdi _C_LABEL(dtlb_va_to_pa):
237 1.3 cdi clr %o1
238 1.3 cdi 0: ldxa [%o1] ASI_DMMU_TLB_TAG, %o2
239 1.3 cdi cmp %o2, %o0
240 1.3 cdi bne,a %xcc, 1f
241 1.3 cdi nop
242 1.3 cdi /* return PA of matching entry */
243 1.3 cdi ldxa [%o1] ASI_DMMU_TLB_DATA, %o0
244 1.3 cdi sllx %o0, 23, %o0
245 1.3 cdi srlx %o0, PGSHIFT+23, %o0
246 1.3 cdi sllx %o0, PGSHIFT, %o0
247 1.3 cdi retl
248 1.3 cdi mov %o0, %o1
249 1.3 cdi 1: cmp %o1, 63<<3
250 1.3 cdi blu %xcc, 0b
251 1.3 cdi add %o1, 8, %o1
252 1.3 cdi clr %o0
253 1.3 cdi retl
254 1.3 cdi not %o0
255 1.3 cdi
256 1.3 cdi /*
257 1.3 cdi * void
258 1.3 cdi * itlb_enter(vaddr_t vpn, u_int32_t data_hi, u_int32_t data_lo)
259 1.3 cdi *
260 1.3 cdi * Insert new mapping into iTLB. Data tag is passed in two different
261 1.3 cdi * registers so that it works even with 32-bit compilers.
262 1.3 cdi */
263 1.3 cdi .align 8
264 1.3 cdi .globl _C_LABEL(itlb_enter)
265 1.3 cdi _C_LABEL(itlb_enter):
266 1.3 cdi sllx %o1, 32, %o1
267 1.3 cdi or %o1, %o2, %o1
268 1.3 cdi rdpr %pstate, %o4
269 1.3 cdi wrpr %o4, PSTATE_IE, %pstate
270 1.3 cdi mov TLB_TAG_ACCESS, %o3
271 1.3 cdi stxa %o0, [%o3] ASI_IMMU
272 1.3 cdi stxa %o1, [%g0] ASI_IMMU_DATA_IN
273 1.3 cdi membar #Sync
274 1.3 cdi retl
275 1.3 cdi wrpr %o4, 0, %pstate
276 1.3 cdi
277 1.3 cdi /*
278 1.3 cdi * void
279 1.3 cdi * dtlb_enter(vaddr_t vpn, u_int32_t data_hi, u_int32_t data_lo)
280 1.3 cdi *
281 1.3 cdi * Insert new mapping into dTLB. Data tag is passed in two different
282 1.3 cdi * registers so that it works even with 32-bit compilers.
283 1.3 cdi */
284 1.3 cdi .align 8
285 1.3 cdi .globl _C_LABEL(dtlb_enter)
286 1.3 cdi _C_LABEL(dtlb_enter):
287 1.3 cdi sllx %o1, 32, %o1
288 1.3 cdi or %o1, %o2, %o1
289 1.3 cdi rdpr %pstate, %o4
290 1.3 cdi wrpr %o4, PSTATE_IE, %pstate
291 1.3 cdi mov TLB_TAG_ACCESS, %o3
292 1.3 cdi stxa %o0, [%o3] ASI_DMMU
293 1.3 cdi stxa %o1, [%g0] ASI_DMMU_DATA_IN
294 1.3 cdi membar #Sync
295 1.3 cdi retl
296 1.3 cdi wrpr %o4, 0, %pstate
297 1.3 cdi
298 1.3 cdi /*
299 1.3 cdi * u_int
300 1.3 cdi * get_cpuid(void);
301 1.3 cdi *
302 1.3 cdi * Return UPA identifier for the CPU we're running on.
303 1.3 cdi */
304 1.3 cdi .align 8
305 1.3 cdi .globl _C_LABEL(get_cpuid)
306 1.3 cdi _C_LABEL(get_cpuid):
307 1.3 cdi UPA_GET_MID(%o0)
308 1.3 cdi retl
309 1.3 cdi nop
310 1.3 cdi
311 1.1 mrg #if 0
312 1.1 mrg .data
313 1.1 mrg .align 8
314 1.1 mrg bootstack:
315 1.1 mrg #define STACK_SIZE 0x14000
316 1.1 mrg .skip STACK_SIZE
317 1.1 mrg ebootstack: ! end (top) of boot stack
318 1.1 mrg #endif
319