loadbsd.c revision 1.11 1 1.7 chopps /*
2 1.11 chopps * $Id: loadbsd.c,v 1.11 1994/06/13 08:13:16 chopps Exp $
3 1.7 chopps */
4 1.7 chopps
5 1.1 mw #include <sys/types.h>
6 1.1 mw #include <a.out.h>
7 1.1 mw #include <stdio.h>
8 1.8 chopps #include <unistd.h>
9 1.1 mw
10 1.1 mw #include <exec/types.h>
11 1.1 mw #include <exec/execbase.h>
12 1.1 mw #include <exec/memory.h>
13 1.10 chopps #include <exec/resident.h>
14 1.1 mw #include <libraries/configregs.h>
15 1.1 mw #include <libraries/expansionbase.h>
16 1.5 mw #include <graphics/gfxbase.h>
17 1.1 mw
18 1.1 mw #include <inline/exec.h>
19 1.1 mw #include <inline/expansion.h>
20 1.5 mw #include <inline/graphics.h>
21 1.1 mw
22 1.3 mw /* Get definitions for boothowto */
23 1.3 mw #include "reboot.h"
24 1.3 mw
25 1.6 chopps static char usage[] =
26 1.6 chopps "
27 1.6 chopps NAME
28 1.6 chopps \t%s - loads NetBSD from amiga dos.
29 1.6 chopps SYNOPSIS
30 1.6 chopps \t%s some-vmunix [-a] [-b] [-k] [-m memory] [-p] [-t] [-V]
31 1.6 chopps OPTIONS
32 1.6 chopps \t-a Boot up to multiuser mode.
33 1.6 chopps \t-b Ask for which root device.
34 1.6 chopps \t Its possible to have multiple roots and choose between them.
35 1.6 chopps \t-k Reserve the first 4M of fast mem [Some one else
36 1.6 chopps \t is going to have to answer what that it is used for].
37 1.6 chopps \t-m Tweak amount of available memory, for finding minimum amount
38 1.6 chopps \t of memory required to run. Sets fastmem size to specified
39 1.6 chopps \t size in Kbytes.
40 1.6 chopps \t-p Use highest priority fastmem segement instead of the largest
41 1.6 chopps \t segment. The higher priority segment is usually faster
42 1.6 chopps \t (i.e. 32 bit memory), but some people have smaller amounts
43 1.6 chopps \t of 32 bit memory.
44 1.6 chopps \t-t This is a *test* option. It prints out the memory
45 1.6 chopps \t list information being passed to the kernel and also
46 1.6 chopps \t exits without actually starting NetBSD.
47 1.8 chopps \t-S Include kernel symbol table.
48 1.10 chopps \t-D Enter debugger
49 1.6 chopps \t-V Version of loadbsd program.
50 1.11 chopps \t-c Set machine type.
51 1.6 chopps HISTORY
52 1.6 chopps This version supports Kernel version 720 +
53 1.6 chopps ";
54 1.6 chopps
55 1.1 mw struct ExpansionBase *ExpansionBase;
56 1.5 mw struct GfxBase *GfxBase;
57 1.1 mw
58 1.1 mw #undef __LDPGSZ
59 1.1 mw #define __LDPGSZ 8192
60 1.1 mw
61 1.5 mw #define MAX_MEM_SEG 16
62 1.5 mw
63 1.6 chopps /*
64 1.6 chopps * Kernel parameter passing version
65 1.8 chopps * 1: first version of loadbsd
66 1.8 chopps * 2: needs esym location passed in a4
67 1.6 chopps */
68 1.8 chopps #define KERNEL_PARAMETER_VERSION 2
69 1.6 chopps
70 1.9 chopps /*
71 1.9 chopps * Version history:
72 1.10 chopps * 1.x Kernel parameter passing version check.
73 1.10 chopps * 2.0 Added symbol table end address and symbol table support.
74 1.10 chopps * 2.1 03/23/94 - Round up end of fastram segment.
75 1.10 chopps * Check fastram segment size for minimum of 2M.
76 1.10 chopps * Use largest segment of highest priority if -p option.
77 1.10 chopps * Print out fastram size in KB if not a multiple of MB.
78 1.10 chopps * 2.2 03/24/94 - Zero out all unused registers.
79 1.10 chopps * Started version history comment.
80 1.10 chopps * 2.3 04/26/94 - Added -D option to enter debugger on boot.
81 1.10 chopps * 2.4 04/30/94 - Cpuid includes base machine type.
82 1.10 chopps * Also check if CPU is capable of running NetBSD.
83 1.11 chopps * 2.5 05/17/94 - Add check for "A3000 bonus".
84 1.11 chopps * 2.6 06/05/94 - Added -c option to override machine type.
85 1.9 chopps */
86 1.9 chopps
87 1.5 mw struct MEM_LIST {
88 1.5 mw u_long num_mem;
89 1.5 mw struct MEM_SEG {
90 1.5 mw u_long mem_start;
91 1.5 mw u_long mem_size;
92 1.5 mw u_short mem_attrib;
93 1.5 mw short mem_prio;
94 1.5 mw } mem_seg[MAX_MEM_SEG];
95 1.5 mw } mem_list, *kmem_list;
96 1.5 mw
97 1.5 mw int k_opt;
98 1.5 mw int a_opt;
99 1.5 mw int b_opt;
100 1.5 mw int p_opt;
101 1.5 mw int t_opt;
102 1.6 chopps int m_opt;
103 1.8 chopps int S_opt;
104 1.10 chopps int D_opt;
105 1.10 chopps
106 1.10 chopps u_long cpuid;
107 1.5 mw
108 1.5 mw extern char *optarg;
109 1.5 mw extern int optind;
110 1.5 mw
111 1.1 mw void get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size);
112 1.10 chopps void get_cpuid (void);
113 1.6 chopps void Usage (char *program_name);
114 1.6 chopps void Version (void);
115 1.6 chopps
116 1.11 chopps static const char _version[] = "$VER: LoadBSD 2.6 (5.6.94)";
117 1.1 mw
118 1.10 chopps int
119 1.1 mw main (int argc, char *argv[])
120 1.1 mw {
121 1.1 mw struct exec e;
122 1.1 mw int fd;
123 1.3 mw int boothowto = RB_SINGLE;
124 1.1 mw
125 1.1 mw if (argc >= 2)
126 1.1 mw {
127 1.1 mw if ((fd = open (argv[1], 0)) >= 0)
128 1.10 chopps {
129 1.10 chopps if (read (fd, &e, sizeof (e)) == sizeof (e))
130 1.10 chopps {
131 1.10 chopps if (e.a_magic == NMAGIC)
132 1.10 chopps {
133 1.10 chopps u_char *kernel;
134 1.10 chopps int kernel_size;
135 1.1 mw int text_size;
136 1.1 mw struct ConfigDev *cd;
137 1.1 mw int num_cd;
138 1.5 mw void *fastmem_start;
139 1.5 mw u_long fastmem_size, chipmem_size;
140 1.5 mw int i;
141 1.6 chopps u_short *kern_vers;
142 1.8 chopps char *esym;
143 1.8 chopps int string_size;
144 1.10 chopps
145 1.5 mw GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0);
146 1.5 mw if (! GfxBase) /* not supposed to fail... */
147 1.5 mw abort();
148 1.1 mw ExpansionBase= (struct ExpansionBase *) OpenLibrary ("expansion.library", 0);
149 1.1 mw if (! ExpansionBase) /* not supposed to fail... */
150 1.1 mw abort();
151 1.5 mw optind = 2;
152 1.11 chopps while ((i = getopt (argc, argv, "kabptVm:SDc:")) != EOF)
153 1.5 mw switch (i) {
154 1.5 mw case 'k':
155 1.5 mw k_opt = 1;
156 1.5 mw break;
157 1.5 mw case 'a':
158 1.5 mw a_opt = 1;
159 1.5 mw break;
160 1.5 mw case 'b':
161 1.5 mw b_opt = 1;
162 1.5 mw break;
163 1.5 mw case 'p':
164 1.5 mw p_opt = 1;
165 1.5 mw break;
166 1.5 mw case 't':
167 1.5 mw t_opt = 1;
168 1.5 mw break;
169 1.6 chopps case 'm':
170 1.6 chopps m_opt = atoi (optarg) * 1024;
171 1.6 chopps break;
172 1.10 chopps case 'V':
173 1.10 chopps Version();
174 1.10 chopps break;
175 1.10 chopps case 'S':
176 1.10 chopps S_opt = 1;
177 1.10 chopps break;
178 1.10 chopps case 'D':
179 1.10 chopps D_opt = 1;
180 1.10 chopps break;
181 1.11 chopps case 'c':
182 1.11 chopps cpuid = atoi (optarg) << 16;
183 1.11 chopps break;
184 1.10 chopps default:
185 1.10 chopps Usage(argv[0]);
186 1.10 chopps fprintf(stderr,"Unrecognized option \n");
187 1.10 chopps exit(-1);
188 1.5 mw }
189 1.5 mw
190 1.1 mw for (cd = 0, num_cd = 0; cd = FindConfigDev (cd, -1, -1); num_cd++) ;
191 1.5 mw get_mem_config (&fastmem_start, &fastmem_size, &chipmem_size);
192 1.10 chopps get_cpuid ();
193 1.1 mw
194 1.1 mw text_size = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ);
195 1.8 chopps esym = NULL;
196 1.8 chopps kernel_size = text_size + e.a_data + e.a_bss
197 1.8 chopps + num_cd*sizeof(*cd) + 4
198 1.8 chopps + mem_list.num_mem*sizeof(struct MEM_SEG) + 4;
199 1.8 chopps /*
200 1.8 chopps * get symbol table size & string size
201 1.8 chopps * (should check kernel version to see if it will handle it)
202 1.8 chopps */
203 1.8 chopps if (S_opt && e.a_syms) {
204 1.8 chopps S_opt = 0; /* prepare for failure */
205 1.8 chopps if (lseek(fd, e.a_text + e.a_data + e.a_syms, SEEK_CUR) > 0) {
206 1.8 chopps if (read (fd, &string_size, 4) == 4) {
207 1.8 chopps if (lseek(fd, sizeof(e), SEEK_SET) < 0) {
208 1.8 chopps printf ("Error repositioning to text\n");
209 1.8 chopps exit(0); /* Give up! */
210 1.8 chopps }
211 1.8 chopps kernel_size += e.a_syms + 4 + string_size;
212 1.8 chopps S_opt = 1; /* sucess! Keep -S option */
213 1.8 chopps }
214 1.8 chopps }
215 1.10 chopps }
216 1.8 chopps
217 1.8 chopps kernel = (u_char *) malloc (kernel_size);
218 1.5 mw
219 1.5 mw if (t_opt)
220 1.5 mw for (i = 0; i < mem_list.num_mem; ++i) {
221 1.5 mw printf ("mem segment %d: start=%08lx size=%08lx attribute=%04lx pri=%d\n",
222 1.5 mw i + 1, mem_list.mem_seg[i].mem_start,
223 1.5 mw mem_list.mem_seg[i].mem_size,
224 1.5 mw mem_list.mem_seg[i].mem_attrib,
225 1.5 mw mem_list.mem_seg[i].mem_prio);
226 1.5 mw }
227 1.1 mw
228 1.10 chopps if (kernel)
229 1.10 chopps {
230 1.10 chopps if (read (fd, kernel, e.a_text) == e.a_text
231 1.1 mw && read (fd, kernel + text_size, e.a_data) == e.a_data)
232 1.1 mw {
233 1.1 mw int *knum_cd;
234 1.1 mw struct ConfigDev *kcd;
235 1.5 mw int mem_ix;
236 1.8 chopps
237 1.5 mw if (k_opt)
238 1.1 mw {
239 1.1 mw fastmem_start += 4*1024*1024;
240 1.1 mw fastmem_size -= 4*1024*1024;
241 1.1 mw }
242 1.6 chopps
243 1.6 chopps if (m_opt && m_opt <= fastmem_size)
244 1.6 chopps {
245 1.6 chopps fastmem_size = m_opt;
246 1.6 chopps }
247 1.10 chopps
248 1.5 mw if (a_opt)
249 1.3 mw {
250 1.3 mw printf("Autobooting...");
251 1.3 mw boothowto = RB_AUTOBOOT;
252 1.3 mw }
253 1.5 mw
254 1.5 mw if (b_opt)
255 1.5 mw {
256 1.5 mw printf("Askboot...");
257 1.5 mw boothowto |= RB_ASKNAME;
258 1.5 mw }
259 1.10 chopps
260 1.10 chopps if (D_opt)
261 1.10 chopps {
262 1.10 chopps boothowto |= RB_KDB;
263 1.10 chopps }
264 1.10 chopps
265 1.9 chopps printf ("Using %d%c FASTMEM at 0x%x, %dM CHIPMEM\n",
266 1.9 chopps (fastmem_size & 0xfffff) ? fastmem_size>>10 :
267 1.9 chopps fastmem_size>>20,
268 1.9 chopps (fastmem_size & 0xfffff) ? 'K' : 'M',
269 1.9 chopps fastmem_start, chipmem_size>>20);
270 1.6 chopps kern_vers = (u_short *) (kernel + e.a_entry - 2);
271 1.6 chopps if (*kern_vers > KERNEL_PARAMETER_VERSION &&
272 1.6 chopps *kern_vers != 0x4e73)
273 1.6 chopps {
274 1.6 chopps printf ("This kernel requires a newer version of loadbsd: %d\n", *kern_vers);
275 1.6 chopps exit (0);
276 1.6 chopps }
277 1.10 chopps if ((cpuid & AFB_68020) == 0)
278 1.10 chopps {
279 1.10 chopps printf ("Hmmm... You don't seem to have a CPU capable\n");
280 1.10 chopps printf (" of running NetBSD. You need a 68020\n");
281 1.10 chopps printf (" or better\n");
282 1.10 chopps exit (0);
283 1.10 chopps }
284 1.1 mw /* give them a chance to read the information... */
285 1.1 mw sleep(2);
286 1.1 mw
287 1.1 mw bzero (kernel + text_size + e.a_data, e.a_bss);
288 1.8 chopps /*
289 1.8 chopps * If symbols wanted (and kernel can handle them),
290 1.8 chopps * load symbol table & strings and set esym to end.
291 1.8 chopps */
292 1.1 mw knum_cd = (int *) (kernel + text_size + e.a_data + e.a_bss);
293 1.8 chopps if (*kern_vers != 0x4e73 && *kern_vers > 1 && S_opt && e.a_syms) {
294 1.8 chopps *knum_cd++ = e.a_syms;
295 1.8 chopps read(fd, (char *)knum_cd, e.a_syms);
296 1.8 chopps knum_cd = (int *)((char *)knum_cd + e.a_syms);
297 1.8 chopps read(fd, (char *)knum_cd, string_size);
298 1.8 chopps knum_cd = (int*)((char *)knum_cd + string_size);
299 1.8 chopps esym = (char *) (text_size + e.a_data + e.a_bss
300 1.8 chopps + e.a_syms + 4 + string_size);
301 1.8 chopps }
302 1.1 mw *knum_cd = num_cd;
303 1.5 mw for (kcd = (struct ConfigDev *) (knum_cd+1);
304 1.5 mw cd = FindConfigDev (cd, -1, -1);
305 1.6 chopps *kcd++ = *cd)
306 1.6 chopps ;
307 1.5 mw kmem_list = (struct MEM_LIST *)kcd;
308 1.5 mw kmem_list->num_mem = mem_list.num_mem;
309 1.5 mw for (mem_ix = 0; mem_ix < mem_list.num_mem; mem_ix++)
310 1.5 mw kmem_list->mem_seg[mem_ix] = mem_list.mem_seg[mem_ix];
311 1.8 chopps if (t_opt) /* if test option */
312 1.8 chopps exit (0); /* don't start kernel */
313 1.8 chopps /* AGA startup - may need more */
314 1.5 mw LoadView (NULL);
315 1.8 chopps startit (kernel, kernel_size,
316 1.1 mw e.a_entry, fastmem_start,
317 1.3 mw fastmem_size, chipmem_size,
318 1.10 chopps boothowto, esym, cpuid );
319 1.1 mw }
320 1.1 mw else
321 1.1 mw fprintf (stderr, "Executable corrupt!\n");
322 1.10 chopps }
323 1.10 chopps else
324 1.10 chopps fprintf (stderr, "Out of memory! (%d)\n", text_size + e.a_data + e.a_bss
325 1.5 mw + num_cd*sizeof(*cd) + 4
326 1.5 mw + mem_list.num_mem*sizeof(struct MEM_SEG) + 4);
327 1.10 chopps }
328 1.1 mw else
329 1.10 chopps fprintf (stderr, "Unsupported executable: %o\n", e.a_magic);
330 1.10 chopps }
331 1.10 chopps else
332 1.1 mw fprintf (stderr, "Can't read header of %s\n", argv[1]);
333 1.1 mw
334 1.1 mw close (fd);
335 1.10 chopps }
336 1.1 mw else
337 1.1 mw perror ("open");
338 1.1 mw }
339 1.1 mw else
340 1.6 chopps Usage(argv[0]);
341 1.6 chopps Version();
342 1.6 chopps }/* main() */
343 1.1 mw
344 1.1 mw void
345 1.1 mw get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size)
346 1.1 mw {
347 1.10 chopps extern struct ExecBase *SysBase;
348 1.1 mw struct MemHeader *mh, *nmh;
349 1.5 mw int num_mem = 0;
350 1.5 mw u_int seg_size;
351 1.5 mw u_int seg_start;
352 1.5 mw u_int seg_end;
353 1.9 chopps char mem_pri = -128;
354 1.10 chopps
355 1.1 mw *fastmem_size = 0;
356 1.1 mw *chipmem_size = 0;
357 1.10 chopps
358 1.1 mw /* walk thru the exec memory list */
359 1.1 mw Forbid ();
360 1.1 mw for (mh = (struct MemHeader *) SysBase->MemList.lh_Head;
361 1.1 mw nmh = (struct MemHeader *) mh->mh_Node.ln_Succ;
362 1.5 mw mh = nmh, num_mem++)
363 1.1 mw {
364 1.5 mw mem_list.mem_seg[num_mem].mem_attrib = mh->mh_Attributes;
365 1.5 mw mem_list.mem_seg[num_mem].mem_prio = mh->mh_Node.ln_Pri;
366 1.5 mw seg_start = (u_int)mh->mh_Lower;
367 1.5 mw seg_end = (u_int)mh->mh_Upper;
368 1.5 mw seg_size = seg_end - seg_start;
369 1.5 mw mem_list.mem_seg[num_mem].mem_size = seg_size;
370 1.5 mw mem_list.mem_seg[num_mem].mem_start = seg_start;
371 1.5 mw
372 1.1 mw if (mh->mh_Attributes & MEMF_CHIP)
373 1.10 chopps {
374 1.1 mw /* there should hardly be more than one entry for chip mem, but
375 1.1 mw handle it the same nevertheless */
376 1.5 mw /* chipmem always starts at 0, so include vector area */
377 1.6 chopps mem_list.mem_seg[num_mem].mem_start = seg_start = 0;
378 1.5 mw /* round to multiple of 512K */
379 1.5 mw seg_size = (seg_size + 512*1024 - 1) & -(512*1024);
380 1.5 mw mem_list.mem_seg[num_mem].mem_size = seg_size;
381 1.5 mw if (seg_size > *chipmem_size)
382 1.1 mw {
383 1.5 mw *chipmem_size = seg_size;
384 1.1 mw }
385 1.10 chopps }
386 1.1 mw else
387 1.1 mw {
388 1.5 mw /* some heuristics.. */
389 1.5 mw seg_start &= -__LDPGSZ;
390 1.9 chopps seg_end = (seg_end + __LDPGSZ - 1) & -__LDPGSZ;
391 1.5 mw /* get the mem back stolen by incore kickstart on A3000 with
392 1.5 mw V36 bootrom. */
393 1.5 mw if (seg_end == 0x07f80000)
394 1.5 mw seg_end = 0x08000000;
395 1.5 mw
396 1.5 mw /* or by zkick on a A2000. */
397 1.5 mw if (seg_start == 0x280000
398 1.5 mw && strcmp (mh->mh_Node.ln_Name, "zkick memory") == 0)
399 1.5 mw seg_start = 0x200000;
400 1.5 mw
401 1.5 mw seg_size = seg_end - seg_start;
402 1.5 mw mem_list.mem_seg[num_mem].mem_start = seg_start;
403 1.5 mw mem_list.mem_seg[num_mem].mem_size = seg_size;
404 1.9 chopps /*
405 1.9 chopps * If this segment is smaller than 2M,
406 1.9 chopps * don't use it to load the kernel
407 1.9 chopps */
408 1.9 chopps if (seg_size < 2 * 1024 * 1024)
409 1.9 chopps continue;
410 1.5 mw /* if p_opt is set, select memory by priority instead of size */
411 1.6 chopps if ((!p_opt && seg_size > *fastmem_size) ||
412 1.10 chopps (p_opt && mem_pri <= mh->mh_Node.ln_Pri && seg_size > *fastmem_size))
413 1.1 mw {
414 1.5 mw *fastmem_size = seg_size;
415 1.5 mw *fastmem_start = (void *)seg_start;
416 1.9 chopps mem_pri = mh->mh_Node.ln_Pri;
417 1.1 mw }
418 1.1 mw }
419 1.1 mw }
420 1.5 mw mem_list.num_mem = num_mem;
421 1.1 mw Permit();
422 1.1 mw }
423 1.1 mw
424 1.10 chopps /*
425 1.10 chopps * Try to determine the machine ID by searching the resident module list
426 1.10 chopps * for modules only present on specific machines. (Thanks, Bill!)
427 1.10 chopps */
428 1.1 mw
429 1.10 chopps void
430 1.10 chopps get_cpuid ()
431 1.10 chopps {
432 1.10 chopps extern struct ExecBase *SysBase;
433 1.10 chopps u_long *rl;
434 1.10 chopps struct Resident *rm;
435 1.10 chopps
436 1.11 chopps cpuid |= SysBase->AttnFlags; /* get FPU and CPU flags */
437 1.11 chopps if (cpuid & 0xffff0000) {
438 1.11 chopps switch (cpuid >> 16) {
439 1.11 chopps case 500:
440 1.11 chopps case 600:
441 1.11 chopps case 1000:
442 1.11 chopps case 1200:
443 1.11 chopps case 2000:
444 1.11 chopps case 3000:
445 1.11 chopps case 4000:
446 1.11 chopps return;
447 1.11 chopps default:
448 1.11 chopps printf ("Machine type Amiga %d is not valid\n",
449 1.11 chopps cpuid >> 16);
450 1.11 chopps exit (1);
451 1.11 chopps }
452 1.11 chopps }
453 1.10 chopps rl = (u_long *) SysBase->ResModules;
454 1.10 chopps if (rl == NULL)
455 1.10 chopps return;
456 1.10 chopps
457 1.10 chopps while (*rl) {
458 1.10 chopps rm = (struct Resident *) *rl;
459 1.10 chopps if (strcmp (rm->rt_Name, "A4000 Bonus") == 0 ||
460 1.10 chopps strcmp (rm->rt_Name, "A1000 Bonus") == 0) {
461 1.10 chopps cpuid |= 4000 << 16;
462 1.10 chopps break;
463 1.10 chopps }
464 1.11 chopps if (strcmp (rm->rt_Name, "A3000 bonus") == 0 ||
465 1.11 chopps strcmp (rm->rt_Name, "A3000 Bonus") == 0) {
466 1.10 chopps cpuid |= 3000 << 16;
467 1.10 chopps break;
468 1.10 chopps }
469 1.10 chopps if (strcmp (rm->rt_Name, "card.resource") == 0) {
470 1.10 chopps cpuid |= 1200 << 16; /* or A600 :-) */
471 1.10 chopps break;
472 1.10 chopps }
473 1.10 chopps ++rl;
474 1.10 chopps }
475 1.10 chopps if (*rl == 0) /* Nothing found, it's probably an A2000 or A500 */
476 1.10 chopps cpuid |= 2000 << 16;
477 1.10 chopps }
478 1.1 mw
479 1.1 mw
480 1.1 mw asm ("
481 1.1 mw .set ABSEXECBASE,4
482 1.1 mw
483 1.1 mw .text
484 1.1 mw .globl _startit
485 1.1 mw
486 1.1 mw _startit:
487 1.1 mw movel sp,a3
488 1.1 mw movel 4:w,a6
489 1.1 mw lea pc@(start_super-.+2),a5
490 1.1 mw jmp a6@(-0x1e) | supervisor-call
491 1.1 mw
492 1.1 mw start_super:
493 1.1 mw movew #0x2700,sr
494 1.1 mw
495 1.1 mw | the BSD kernel wants values into the following registers:
496 1.1 mw | a0: fastmem-start
497 1.1 mw | d0: fastmem-size
498 1.1 mw | d1: chipmem-size
499 1.5 mw | d5: AttnFlags (cpuid)
500 1.3 mw | d7: boothowto
501 1.8 chopps | a4: esym location
502 1.10 chopps | All other registers zeroed for possible future requirements.
503 1.1 mw
504 1.1 mw movel a3@(4),a1 | loaded kernel
505 1.1 mw movel a3@(8),d2 | length of loaded kernel
506 1.9 chopps movel a3@(12),sp@- | entry point [save on stack for rts]
507 1.1 mw movel a3@(16),a0 | fastmem-start
508 1.1 mw movel a3@(20),d0 | fastmem-size
509 1.1 mw movel a3@(24),d1 | chipmem-size
510 1.3 mw movel a3@(28),d7 | boothowto
511 1.8 chopps movel a3@(32),a4 | esym
512 1.10 chopps movel a3@(36),d5 | cpuid
513 1.8 chopps subl a5,a5 | target, load to 0
514 1.1 mw
515 1.5 mw btst #3,(ABSEXECBASE)@(0x129) | AFB_68040,SysBase->AttnFlags
516 1.5 mw beq not040
517 1.5 mw
518 1.5 mw | Turn off 68040 MMU
519 1.5 mw
520 1.8 chopps .word 0x4e7b,0xd003 | movec a5,tc
521 1.8 chopps .word 0x4e7b,0xd806 | movec a5,urp
522 1.8 chopps .word 0x4e7b,0xd807 | movec a5,srp
523 1.8 chopps .word 0x4e7b,0xd004 | movec a5,itt0
524 1.8 chopps .word 0x4e7b,0xd005 | movec a5,itt1
525 1.8 chopps .word 0x4e7b,0xd006 | movec a5,dtt0
526 1.8 chopps .word 0x4e7b,0xd007 | movec a5,dtt1
527 1.5 mw bra nott
528 1.5 mw
529 1.5 mw not040:
530 1.1 mw lea pc@(zero-.+2),a3
531 1.1 mw pmove a3@,tc | Turn off MMU
532 1.1 mw lea pc@(nullrp-.+2),a3
533 1.1 mw pmove a3@,crp | Turn off MMU some more
534 1.1 mw pmove a3@,srp | Really, really, turn off MMU
535 1.1 mw
536 1.1 mw | Turn off 68030 TT registers
537 1.1 mw
538 1.1 mw btst #2,(ABSEXECBASE)@(0x129) | AFB_68030,SysBase->AttnFlags
539 1.1 mw beq nott | Skip TT registers if not 68030
540 1.1 mw lea pc@(zero-.+2),a3
541 1.1 mw .word 0xf013,0x0800 | pmove a3@,tt0 (gas only knows about 68851 ops..)
542 1.1 mw .word 0xf013,0x0c00 | pmove a3@,tt1 (gas only knows about 68851 ops..)
543 1.1 mw
544 1.1 mw nott:
545 1.1 mw
546 1.1 mw movew #(1<<9),0xdff096 | disable DMA
547 1.1 mw
548 1.1 mw L0:
549 1.8 chopps moveb a1@+,a5@+
550 1.1 mw subl #1,d2
551 1.1 mw bcc L0
552 1.1 mw
553 1.1 mw
554 1.9 chopps moveq #0,d2 | zero out unused registers
555 1.9 chopps moveq #0,d3 | (might make future compatibility
556 1.9 chopps moveq #0,d4 | a little easier, since all registers
557 1.9 chopps moveq #0,d6 | would have known contents)
558 1.9 chopps movel d6,a1
559 1.9 chopps movel d6,a2
560 1.9 chopps movel d6,a3
561 1.9 chopps movel d6,a5
562 1.9 chopps movel d6,a6
563 1.9 chopps rts | return to kernel entry point
564 1.1 mw
565 1.1 mw
566 1.1 mw | A do-nothing MMU root pointer (includes the following long as well)
567 1.1 mw
568 1.1 mw nullrp: .long 0x7fff0001
569 1.1 mw zero: .long 0
570 1.1 mw
571 1.1 mw
572 1.1 mw ");
573 1.1 mw
574 1.6 chopps void Usage(char *program_name)
575 1.6 chopps {
576 1.6 chopps fprintf(stderr,usage,program_name,program_name);
577 1.6 chopps }
578 1.6 chopps
579 1.6 chopps void Version()
580 1.6 chopps {
581 1.6 chopps fprintf(stderr,"%s\n",_version + 6);
582 1.6 chopps }
583