startit.s revision 1.4 1 /* $NetBSD: startit.s,v 1.4 1998/11/06 20:08:20 is Exp $ */
2
3 /*
4 * Copyright (c) 1996 Ignatios Souvatzis
5 * Copyright (c) 1994 Michael L. Hitch
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 Michael L. Hitch.
19 * 4. The name of the author 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 THE AUTHOR ``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 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 *
34 * From: $NetBSD: startit.s,v 1.4 1998/11/06 20:08:20 is Exp $
35 */
36
37 .set ABSEXECBASE,4
38
39 .text
40
41 .globl _startit
42 .globl _startit_end
43
44 _startit:
45 #if TESTONAMIGA
46 movew #0x999,0xdff180 | gray
47 #endif
48 #if TESTONDRACO
49 moveb #0,0x200003c8
50 moveb #31,0x200003c9
51 moveb #31,0x200003c9
52 moveb #31,0x200003c9
53 #endif
54 movel sp,a3
55 movel 4:w,a6
56 lea pc@(start_super:w),a5
57 jmp a6@(-0x1e) | supervisor-call
58
59 start_super:
60 #if TESTONAMIGA
61 movew #0x900,0xdff180 | dark red
62 #endif
63 movew #0x2700,sr
64
65 | the BSD kernel wants values into the following registers:
66 | a0: fastmem-start
67 | d0: fastmem-size
68 | d1: chipmem-size
69 | d3: Amiga specific flags
70 | d4: E clock frequency
71 | d5: AttnFlags (cpuid)
72 | d6: boot partition offset
73 | d7: boothowto
74 | a4: esym location
75 | a2: Inhibit sync flags
76 | All other registers zeroed for possible future requirements.
77
78 lea pc@(_startit:w),sp | make sure we have a good stack ***
79
80 movel a3@(4),a1 | loaded kernel
81 movel a3@(8),d2 | length of loaded kernel
82 | movel a3@(12),sp | entry point in stack pointer
83 movel a3@(12),a6 | entry point ***
84 movel a3@(16),a0 | fastmem-start
85 movel a3@(20),d0 | fastmem-size
86 movel a3@(24),d1 | chipmem-size
87 movel a3@(28),d7 | boothowto
88 movel a3@(32),a4 | esym
89 movel a3@(36),d5 | cpuid
90 movel a3@(40),d4 | E clock frequency
91 movel a3@(44),d3 | Amiga flags
92 movel a3@(48),a2 | Inhibit sync flags
93 movel a3@(52),d6 | boot partition offset
94
95 cmpb #0x7D,a3@(36) | is it DraCo?
96 movel a3@(56),a3 | Load to fastmem flag
97 jeq nott | yes, switch off MMU later
98
99 | no, it is an Amiga:
100
101 #if TESTONAMIGA
102 movew #0xf00,0xdff180 |red
103 #endif
104 #if TESTONDRACO
105 moveb #0,0x200003c8
106 moveb #63,0x200003c9
107 moveb #0,0x200003c9
108 moveb #0,0x200003c9
109 #endif
110
111 movew #(1<<9),0xdff096 | disable DMA on Amigas.
112
113 | ------ mmu off start -----
114
115 btst #3,d5 | AFB_68040,SysBase->AttnFlags
116 jeq not040
117
118 | Turn off 68040/060 MMU
119
120 subl a5,a5
121 .word 0x4e7b,0xd003 | movec a5,tc
122 .word 0x4e7b,0xd806 | movec a5,urp
123 .word 0x4e7b,0xd807 | movec a5,srp
124 .word 0x4e7b,0xd004 | movec a5,itt0
125 .word 0x4e7b,0xd005 | movec a5,itt1
126 .word 0x4e7b,0xd006 | movec a5,dtt0
127 .word 0x4e7b,0xd007 | movec a5,dtt1
128 jra nott
129
130 not040:
131 lea pc@(zero:w),a5
132 pmove a5@,tc | Turn off MMU
133 lea pc@(nullrp:w),a5
134 pmove a5@,crp | Turn off MMU some more
135 pmove a5@,srp | Really, really, turn off MMU
136
137 | Turn off 68030 TT registers
138
139 btst #2,d5 | AFB_68030,SysBase->AttnFlags
140 jeq nott | Skip TT registers if not 68030
141 lea pc@(zero:w),a5
142 .word 0xf015,0x0800 | pmove a5@,tt0 (gas only knows about 68851 ops..)
143 .word 0xf015,0x0c00 | pmove a5@,tt1 (gas only knows about 68851 ops..)
144
145 nott:
146 | ---- mmu off end ----
147 #if TESTONAMIGA
148 movew #0xf60,0xdff180 | orange
149 #endif
150 #if TESTONDRACO
151 moveb #0,0x200003c8
152 moveb #63,0x200003c9
153 moveb #24,0x200003c9
154 moveb #0,0x200003c9
155 #endif
156
157 | ---- switch off cache ----
158 btst #3,d5
159 jeq L3
160 .word 0xf4f8
161 L3: movl d2,sp@- | save d2
162 movql #0,d2 | switch off cache to ensure we use
163 movec d2,cacr | valid kernel data
164 movl sp@+,d2 | restore d2
165
166 | ---- copy kernel start ----
167
168 | removed Z flag
169 | tstl a3 | Can we load to fastmem?
170 | jeq L0 | No, leave destination at 0
171 movl a0,a3 | Move to start of fastmem chunk
172 addl a0,a6 | relocate kernel entry point
173
174 addl #3,d2
175 andl #0xfffffffc,d2 | round up.
176
177 | determine if the kernel need be copied upwards or downwards
178
179 cmpl a1,a3 | a3-a1
180 bcs above | source is above
181
182 movl a0,sp
183 addl d0,sp | move the stack to the end of segment
184
185 | copy from below upwards requires copying from end to start.
186
187 addl d2,a3 | one long word past
188 addl d2,a1 | one long word past
189
190 subl #4,sp | alloc space
191 movl a1,sp@- | save source
192 movl a3,sp@- | save destination
193
194 | copy copier to end of segment
195
196 movl sp,a3
197 subl #256,a3 | end of segment save our stack
198
199 lea pc@(_startit_end:w),a1
200 movl a0,sp@- | save segment start
201 lea pc@(below:w),a0
202
203 L0: movw a1@-,a3@-
204 cmpl a0,a1
205 bne L0
206 movl sp@,a0 | restore segment start
207 movl a3,sp@ | address of relocated below
208 addl #(ckend - below),a3
209 movl a3,sp@(12) | address of ckend for later
210 rts
211
212 below: movl sp@+,a3 | recover destination
213 movl sp@+,a1 | recover source
214
215 L1: movl a1@-,a3@- | copy kernel
216 subl #4,d2
217 bne L1
218
219 rts | jmps to relocated ckend
220
221 above: movl a1@+,a3@+
222 subl #4,d2
223 bne above
224
225 lea pc@(ckend:w),a1
226 movl a3,sp@-
227 pea pc@(_startit_end:w)
228 L2:
229 movl a1@+,a3@+
230 cmpl sp@,a1
231 bcs L2
232 addql #4,sp
233
234 #if TESTONAMIGA
235 movew #0xFF0,0xdff180 | yellow
236 #endif
237 #if TESTONDRACO
238 moveb #0,0x200003c8
239 moveb #63,0x200003c9
240 moveb #63,0x200003c9
241 moveb #0,0x200003c9
242 #endif
243
244 rts
245
246 | ---- copy kernel end ----
247
248 ckend:
249 #if TESTONAMIGA
250 movew #0x0ff,0xdff180 | petrol
251 #endif
252 #if TESTONDRACO
253 moveb #0,0x200003c8
254 moveb #0,0x200003c9
255 moveb #63,0x200003c9
256 moveb #63,0x200003c9
257 #endif
258
259 movl d5,d2
260 roll #8,d2
261 cmpb #0x7D,d2
262 jne noDraCo
263
264 | DraCo: switch off MMU now:
265
266 subl a5,a5
267 .word 0x4e7b,0xd003 | movec a5,tc
268 .word 0x4e7b,0xd806 | movec a5,urp
269 .word 0x4e7b,0xd807 | movec a5,srp
270 .word 0x4e7b,0xd004 | movec a5,itt0
271 .word 0x4e7b,0xd005 | movec a5,itt1
272 .word 0x4e7b,0xd006 | movec a5,dtt0
273 .word 0x4e7b,0xd007 | movec a5,dtt1
274
275 noDraCo:
276 moveq #0,d2 | zero out unused registers
277 movel d2,a1 | (might make future compatibility
278 movel d2,a3 | would have known contents)
279 movel d2,a5
280 movel a6,sp | entry point into stack pointer
281 movel d2,a6
282
283 #if TESTONAMIGA
284 movew #0x0F0,0xdff180 | green
285 #endif
286 #if TESTONDRACO
287 moveb #0,0x200003c8
288 moveb #0,0x200003c9
289 moveb #63,0x200003c9
290 moveb #0,0x200003c9
291 #endif
292
293 jmp sp@ | jump to kernel entry point
294
295
296 | A do-nothing MMU root pointer (includes the following long as well)
297
298 nullrp: .long 0x7fff0001
299 zero: .long 0
300
301 _startit_end:
302