Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / amiga / stand / loadbsd / loadbsd.c
blobccd8fc6a094f5f04f6a4ddfdd6d08a1b682682da
1 /* $NetBSD: loadbsd.c,v 1.33 2005/12/24 22:45:34 perry Exp $ */
3 /*
4 * Copyright (c) 1994 Michael L. Hitch
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <err.h>
35 #include <exec/memory.h>
36 #include <exec/execbase.h>
37 #include <exec/resident.h>
38 #include <graphics/gfxbase.h>
39 #include <libraries/expansion.h>
40 #include <libraries/expansionbase.h>
41 #include <libraries/configregs.h>
42 #include <libraries/configvars.h>
43 #include <proto/expansion.h>
44 #include <proto/graphics.h>
45 #include <proto/exec.h>
46 #include <proto/dos.h>
48 /* Get definitions for boothowto */
49 #include "sys/reboot.h"
50 #include "inttypes.h"
51 #include "loadfile.h"
53 #undef AOUT_LDPGSZ
54 #define AOUT_LDPGSZ 8192
56 #undef sleep
57 #define sleep(n) if (!t_flag) (void)Delay(50*n)
60 * Version history:
61 * 1.x Kernel startup interface version check.
62 * 2.0 Added symbol table end address and symbol table support.
63 * 2.1 03/23/94 - Round up end of fastram segment.
64 * Check fastram segment size for minimum of 2M.
65 * Use largest segment of highest priority if -p option.
66 * Print out fastram size in KB if not a multiple of MB.
67 * 2.2 03/24/94 - Zero out all unused registers.
68 * Started version history comment.
69 * 2.3 04/26/94 - Added -D option to enter debugger on boot.
70 * 2.4 04/30/94 - Cpuid includes base machine type.
71 * Also check if CPU is capable of running NetBSD.
72 * 2.5 05/17/94 - Add check for "A3000 bonus".
73 * 2.6 06/05/94 - Added -c option to override machine type.
74 * 2.7 06/15/94 - Pass E clock frequency.
75 * 2.8 06/22/94 - Fix supervisor stack usage.
76 * 2.9 06/26/94 - Use PAL flag for E clock freq on pre 2.0 WB
77 * Added AGA enable parameter
78 * 2.10 12/22/94 - Use FindResident() & OpenResource() for machine
79 * type detection.
80 * Add -n flag & option for non-contiguous memory.
81 * 01/28/95 - Corrected -n on usage & help messages.
82 * 2.11 03/12/95 - Check kernel size against chip memory size.
83 * 2.12 11/11/95 - Add -I option to inhibit synchronous transfer
84 * 11/12/95 - New kernel startup interface version - to
85 * support loading kernel image to fastmem rather than chipmem.
86 * 2.13 04/15/96 - Direct load to fastmem.
87 * Add -Z flag to force chipmem load.
88 * Moved test mode exit to later - kernel image is created
89 * and startup interface version checked in test mode.
90 * Add -s flag for compatibility to bootblock loader.
91 * 05/02/96 - Add a maximum startup interface version level
92 * to allow future kernel compatibility.
93 * 2.14 06/26/96 is - Add first version of kludges needed to
94 * boot on DraCos. This can probably be done a bit more cleanly
95 * using TTRs, but it works for now.
96 * 2.15 07/28/96 is - Add first version of kludges needed to
97 * get FusionForty kickrom'd memory back. Hope this doesn't
98 * break anything else.
99 * 2.16 07/08/00 - Added bootverbose support.
100 * 01/15/03 - Plugged resource leaks.
101 * Fixed printf() statements.
102 * Ansified.
103 * 3.0 01/16/03 - ELF support through loadfile() interface.
105 static const char _version[] = "$VER: LoadBSD 3.0 (16.1.2003)";
108 * Kernel startup interface version
109 * 1: first version of loadbsd
110 * 2: needs esym location passed in a4
111 * 3: load kernel image into fastmem rather than chipmem
112 * MAX: highest version with backward compatibility.
114 #define KERNEL_STARTUP_VERSION 3
115 #define KERNEL_STARTUP_VERSION_MAX 9
117 #define DRACOREVISION (*(UBYTE *)0x02000009)
118 #define DRACOMMUMARGIN 0x200000
120 #define MAXMEMSEG 16
121 struct boot_memlist {
122 u_int m_nseg; /* num_mem; */
123 struct boot_memseg {
124 u_int ms_start;
125 u_int ms_size;
126 u_short ms_attrib;
127 short ms_pri;
128 } m_seg[MAXMEMSEG];
130 struct boot_memlist memlist;
131 struct boot_memlist *kmemlist;
133 void get_mem_config (void **, u_long *, u_long *);
134 void get_cpuid (void);
135 void get_eclock (void);
136 void get_AGA (void);
137 void usage (void);
138 void verbose_usage (void);
139 void startit (void *, u_long, u_long, void *, u_long, u_long, int, void *,
140 int, int, u_long, u_long, int);
141 extern u_long startit_sz;
143 extern char *optarg;
144 extern int optind;
146 struct ExpansionBase *ExpansionBase = NULL;
147 struct GfxBase *GfxBase = NULL;
149 int k_flag;
150 int p_flag;
151 int t_flag;
152 int reqmemsz;
153 int S_flag;
154 u_long I_flag;
155 int Z_flag;
156 u_long cpuid;
157 long eclock_freq;
158 long amiga_flags;
159 char *program_name;
160 u_char *kp;
161 u_long kpsz;
163 void
164 exit_func(void)
166 if (kp)
167 FreeMem(kp, kpsz);
168 if (ExpansionBase)
169 CloseLibrary((struct Library *)ExpansionBase);
170 if (GfxBase)
171 CloseLibrary((struct Library *)GfxBase);
175 main(int argc, char **argv)
177 struct ConfigDev *cd, *kcd;
178 u_long fmemsz, cmemsz, ksize, marks[MARK_MAX];
179 int boothowto, ncd, i, mem_ix, ch;
180 u_short kvers;
181 int *nkcd;
182 void *fmem;
183 char *esym;
184 void (*start_it) (void *, u_long, u_long, void *, u_long, u_long,
185 int, void *, int, int, u_long, u_long, int) = startit;
186 char *kernel_name;
188 atexit(exit_func);
190 program_name = argv[0];
191 boothowto = RB_SINGLE;
193 if (argc < 2)
194 usage();
196 if ((GfxBase = (void *)OpenLibrary(GRAPHICSNAME, 0)) == NULL)
197 err(20, "can't open graphics library");
198 if ((ExpansionBase=(void *)OpenLibrary(EXPANSIONNAME, 0)) == NULL)
199 err(20, "can't open expansion library");
201 while ((ch = getopt(argc, argv, "aAbc:DhI:km:n:qptsSvVZ")) != -1) {
202 switch (ch) {
203 case 'k':
204 k_flag = 1;
205 break;
206 case 'a':
207 boothowto &= ~(RB_SINGLE);
208 boothowto |= RB_AUTOBOOT;
209 break;
210 case 'b':
211 boothowto |= RB_ASKNAME;
212 break;
213 case 'p':
214 p_flag = 1;
215 break;
216 case 't':
217 t_flag = 1;
218 break;
219 case 'm':
220 reqmemsz = atoi(optarg) * 1024;
221 break;
222 case 's':
223 boothowto &= ~(RB_AUTOBOOT);
224 boothowto |= RB_SINGLE;
225 break;
226 case 'q':
227 boothowto |= AB_QUIET;
228 break;
229 case 'v':
230 boothowto |= AB_VERBOSE;
231 break;
232 case 'V':
233 fprintf(stderr,"%s\n",_version + 6);
234 break;
235 case 'S':
236 S_flag = 1;
237 break;
238 case 'D':
239 boothowto |= RB_KDB;
240 break;
241 case 'c':
242 cpuid = atoi(optarg) << 16;
243 break;
244 case 'A':
245 amiga_flags |= 1;
246 break;
247 case 'n':
248 i = atoi(optarg);
249 if (i >= 0 && i <= 3)
250 amiga_flags |= i << 1;
251 else
252 err(20, "-n option must be 0, 1, 2, or 3");
253 break;
254 case 'I':
255 I_flag = strtoul(optarg, NULL, 16);
256 break;
257 case 'Z':
258 Z_flag = 1;
259 break;
260 case 'h':
261 verbose_usage();
262 default:
263 usage();
266 argc -= optind;
267 argv += optind;
269 if (argc != 1)
270 usage();
272 kernel_name = argv[0];
274 for (cd = 0, ncd = 0; cd = FindConfigDev(cd, -1, -1); ncd++)
276 get_cpuid();
277 get_mem_config(&fmem, &fmemsz, &cmemsz);
278 get_eclock();
279 get_AGA();
282 * XXX Call loadfile with COUNT* options to get size
283 * XXX Allocate memory for kernel + additional data
284 * XXX Call loadfile with LOAD* options to load text/data/symbols
286 marks[MARK_START] = 0;
287 if (loadfile(kernel_name, marks,
288 COUNT_TEXT|COUNT_TEXTA|COUNT_DATA|COUNT_BSS|
289 (S_flag ? (COUNT_SYM|COUNT_HDR) : 0)) == -1) {
290 err(20, "unable to parse kernel image");
292 ksize = ((marks[MARK_END] + 3) & ~3)
293 + sizeof(*nkcd) + ncd * sizeof(*cd)
294 + sizeof(*nkcd) + memlist.m_nseg * sizeof(struct boot_memseg);
296 if (t_flag) {
297 for (i = 0; i < memlist.m_nseg; ++i) {
298 printf("mem segment %d: start=%08lx size=%08lx"
299 " attribute=%04lx pri=%d\n",
300 i + 1,
301 memlist.m_seg[i].ms_start,
302 memlist.m_seg[i].ms_size,
303 memlist.m_seg[i].ms_attrib,
304 memlist.m_seg[i].ms_pri);
306 printf("kernel size: %ld\n", ksize);
309 kpsz = ksize + 256 + startit_sz;
310 kp = (u_char *)AllocMem(kpsz, MEMF_FAST|MEMF_REVERSE);
311 if (kp == NULL)
312 err(20, "failed alloc %d", ksize);
314 marks[MARK_START] = (u_long)kp;
315 if (loadfile(kernel_name, marks,
316 LOAD_TEXT|LOAD_TEXTA|LOAD_DATA|LOAD_BSS|
317 (S_flag ? (LOAD_SYM|LOAD_HDR) : 0)) == -1) {
318 err(20, "unable to load kernel image");
320 marks[MARK_END] = (marks[MARK_END] + 3) & ~3;
322 if (k_flag) {
323 fmem += 4 * 1024 * 1024;
324 fmemsz -= 4 * 1024 * 1024;
326 if (reqmemsz && reqmemsz <= fmemsz)
327 fmemsz = reqmemsz;
329 if (boothowto & RB_AUTOBOOT)
330 printf("Autobooting...");
331 if (boothowto & RB_ASKNAME)
332 printf("Askboot...");
334 printf("Using %ld%c FASTMEM at 0x%lx, %ldM CHIPMEM\n",
335 (fmemsz & 0xfffff) ? fmemsz >> 10 : fmemsz >> 20,
336 (fmemsz & 0xfffff) ? 'K' : 'M', (u_long)fmem, cmemsz >> 20);
338 kvers = *(u_short *)(marks[MARK_ENTRY] - 2);
339 if (kvers == 0x4e73) kvers = 0;
340 if (kvers > KERNEL_STARTUP_VERSION_MAX)
341 err(20, "newer loadbsd required: %d\n", kvers);
342 if (kvers > KERNEL_STARTUP_VERSION) {
343 printf("****************************************************\n"
344 "*** Notice: this kernel has features which require\n"
345 "*** a newer version of loadbsd. To allow the use of\n"
346 "*** any newer features or capabilities, you should\n"
347 "*** update to a newer version of loadbsd\n"
348 "****************************************************\n");
349 sleep(3); /* even more time to see that message */
353 * give them a chance to read the information...
355 sleep(2);
357 nkcd = (int *)marks[MARK_END];
358 esym = 0;
360 * If symbols loaded and kernel can handle them, set esym to end.
362 if (marks[MARK_SYM] != marks[MARK_START]) {
363 if (kvers > 1) {
364 esym = (void *)(marks[MARK_END] - marks[MARK_START]);
366 else {
368 * suppress symbols
370 nkcd = (int *)marks[MARK_SYM];
374 *nkcd = ncd;
375 kcd = (struct ConfigDev *)(nkcd + 1);
376 while((cd = FindConfigDev(cd, -1, -1))) {
377 memcpy(kcd, cd, sizeof(*kcd));
378 if (((cpuid >> 24) == 0x7d) &&
379 ((u_long)kcd->cd_BoardAddr < 0x1000000)) {
380 if (t_flag)
381 printf("Transformed Z2 device from %08lx ", (u_long)kcd->cd_BoardAddr);
382 kcd->cd_BoardAddr += 0x3000000;
383 if (t_flag)
384 printf("to %08lx\n", (u_long)kcd->cd_BoardAddr);
386 ++kcd;
389 kmemlist = (struct boot_memlist *)kcd;
390 kmemlist->m_nseg = memlist.m_nseg;
391 for (mem_ix = 0; mem_ix < memlist.m_nseg; mem_ix++)
392 kmemlist->m_seg[mem_ix] = memlist.m_seg[mem_ix];
394 if (kvers > 2 && Z_flag == 0) {
396 * Kernel supports direct load to fastmem, and the -Z
397 * option was not specified. Copy startup code to end
398 * of kernel image and set start_it.
400 if ((void *)kp < fmem) {
401 printf("Kernel at %08lx, Fastmem used at %08lx\n",
402 (u_long)kp, (u_long)fmem);
403 err(20, "Can't copy upwards yet.\nDefragment your memory and try again OR try the -p OR try the -Z options.");
405 start_it = (void (*)())kp + ksize + 256;
406 memcpy(start_it, startit, startit_sz);
407 CacheClearU();
408 printf("*** Loading from %08lx to Fastmem %08lx ***\n",
409 (u_long)kp, (u_long)fmem);
410 sleep(2);
411 } else {
413 * Either the kernel doesn't suppport loading directly to
414 * fastmem or the -Z flag was given. Verify kernel image
415 * fits into chipmem.
417 if (ksize >= cmemsz) {
418 printf("Kernel size %ld exceeds Chip Memory of %ld\n",
419 ksize, cmemsz);
420 err(20, "Insufficient Chip Memory for kernel");
422 Z_flag = 1;
423 printf("*** Loading from %08lx to Chipmem ***\n", (u_long)kp);
427 * if test option set, done
429 if (t_flag) {
430 exit(0);
434 * XXX AGA startup - may need more
436 LoadView(NULL); /* Don't do this if AGA active? */
437 start_it(kp, ksize, marks[MARK_ENTRY] - marks[MARK_START], fmem, fmemsz, cmemsz,
438 boothowto, esym, cpuid, eclock_freq, amiga_flags, I_flag, Z_flag == 0);
439 /*NOTREACHED*/
442 void
443 get_mem_config(void **fmem, u_long *fmemsz, u_long *cmemsz)
445 struct MemHeader *mh, *nmh;
446 u_int nmem, eseg, segsz, seg, nseg, nsegsz;
447 char mempri;
449 nmem = 0;
450 mempri = -128;
451 *fmemsz = 0;
452 *cmemsz = 0;
455 * walk thru the exec memory list
457 Forbid();
458 for (mh = (void *) SysBase->MemList.lh_Head;
459 nmh = (void *) mh->mh_Node.ln_Succ; mh = nmh) {
461 nseg = (u_int)mh->mh_Lower;
462 nsegsz = (u_int)mh->mh_Upper - nseg;
464 segsz = nsegsz;
465 seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, 0L);
466 nsegsz -= segsz, nseg += segsz;
467 for (;segsz;
468 segsz = nsegsz,
469 seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, DMA_Continue),
470 nsegsz -= segsz, nseg += segsz, ++nmem) {
472 if (t_flag)
473 printf("Translated %08x sz %08x to %08x sz %08x\n",
474 nseg - segsz, nsegsz + segsz, seg, segsz);
476 eseg = seg + segsz;
478 if ((cpuid >> 24) == 0x7D) {
479 /* DraCo MMU table kludge */
481 segsz = ((segsz -1) | 0xfffff) + 1;
482 seg = eseg - segsz;
485 * Only use first SIMM to boot; we know it is VA==PA.
486 * Enter into table and continue. Yes,
487 * this is ugly.
489 if (seg != 0x40000000) {
490 memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
491 memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
492 memlist.m_seg[nmem].ms_size = segsz;
493 memlist.m_seg[nmem].ms_start = seg;
494 ++nmem;
495 continue;
498 memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
499 memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
500 memlist.m_seg[nmem].ms_size = DRACOMMUMARGIN;
501 memlist.m_seg[nmem].ms_start = seg;
503 ++nmem;
504 seg += DRACOMMUMARGIN;
505 segsz -= DRACOMMUMARGIN;
508 memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
509 memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
510 memlist.m_seg[nmem].ms_size = segsz;
511 memlist.m_seg[nmem].ms_start = seg;
513 if ((mh->mh_Attributes & (MEMF_CHIP|MEMF_FAST)) == MEMF_CHIP) {
515 * there should hardly be more than one entry for
516 * chip mem, but handle it the same nevertheless
517 * cmem always starts at 0, so include vector area
519 memlist.m_seg[nmem].ms_start = seg = 0;
521 * round to multiple of 512K
523 segsz = (segsz + 512 * 1024 - 1) & -(512 * 1024);
524 memlist.m_seg[nmem].ms_size = segsz;
525 if (segsz > *cmemsz)
526 *cmemsz = segsz;
527 continue;
530 * some heuristics..
532 seg &= -AOUT_LDPGSZ;
533 eseg = (eseg + AOUT_LDPGSZ - 1) & -AOUT_LDPGSZ;
536 * get the mem back stolen by incore kickstart on
537 * A3000 with V36 bootrom.
539 if (eseg == 0x07f80000)
540 eseg = 0x08000000;
543 * or by zkick on a A2000.
545 if (seg == 0x280000 &&
546 strcmp(mh->mh_Node.ln_Name, "zkick memory") == 0)
547 seg = 0x200000;
549 * or by Fusion Forty fastrom
551 if ((seg & ~(1024*1024-1)) == 0x11000000) {
553 * XXX we should test the name.
554 * Unfortunately, the memory is just called
555 * "32 bit memory" which isn't very specific.
557 seg = 0x11000000;
560 segsz = eseg - seg;
561 memlist.m_seg[nmem].ms_start = seg;
562 memlist.m_seg[nmem].ms_size = segsz;
564 * If this segment is smaller than 2M,
565 * don't use it to load the kernel
567 if (segsz < 2 * 1024 * 1024)
568 continue;
570 * if p_flag is set, select memory by priority
571 * instead of size
573 if ((!p_flag && segsz > *fmemsz) || (p_flag &&
574 mempri <= mh->mh_Node.ln_Pri && segsz > *fmemsz)) {
575 *fmemsz = segsz;
576 *fmem = (void *)seg;
577 mempri = mh->mh_Node.ln_Pri;
582 memlist.m_nseg = nmem;
583 Permit();
587 * Try to determine the machine ID by searching the resident module list
588 * for modules only present on specific machines. (Thanks, Bill!)
590 void
591 get_cpuid(void)
593 cpuid |= SysBase->AttnFlags; /* get FPU and CPU flags */
594 if ((cpuid & AFB_68020) == 0)
595 err(20, "CPU not supported");
596 if (cpuid & 0xffff0000) {
597 if ((cpuid >> 24) == 0x7D)
598 return;
600 switch (cpuid >> 16) {
601 case 500:
602 case 600:
603 case 1000:
604 case 1200:
605 case 2000:
606 case 3000:
607 case 4000:
608 return;
609 default:
610 printf("machine Amiga %ld is not recognized\n",
611 cpuid >> 16);
612 exit(1);
615 if (FindResident("A4000 Bonus") || FindResident("A4000 bonus")
616 || FindResident("A1000 Bonus"))
617 cpuid |= 4000 << 16;
618 else if (FindResident("A3000 Bonus") || FindResident("A3000 bonus"))
619 cpuid |= 3000 << 16;
620 else if (OpenResource("card.resource")) {
621 /* Test for AGA? */
622 cpuid |= 1200 << 16;
623 } else if (OpenResource("draco.resource")) {
624 cpuid |= (32000 | DRACOREVISION) << 16;
627 * Nothing found, it's probably an A2000 or A500
629 if ((cpuid >> 16) == 0)
630 cpuid |= 2000 << 16;
633 void
634 get_eclock(void)
636 /* Fix for 1.3 startups? */
637 if (SysBase->LibNode.lib_Version > 36)
638 eclock_freq = SysBase->ex_EClockFrequency;
639 else
640 eclock_freq = (GfxBase->DisplayFlags & PAL) ?
641 709379 : 715909;
644 void
645 get_AGA(void)
648 * Determine if an AGA mode is active
652 __asm("
653 .text
655 _startit:
656 movel sp,a3
657 movel 4:w,a6
658 lea pc@(start_super),a5
659 jmp a6@(-0x1e) | supervisor-call
661 start_super:
662 movew #0x2700,sr
664 | the BSD kernel wants values into the following registers:
665 | a0: fastmem-start
666 | d0: fastmem-size
667 | d1: chipmem-size
668 | d3: Amiga specific flags
669 | d4: E clock frequency
670 | d5: AttnFlags (cpuid)
671 | d7: boothowto
672 | a4: esym location
673 | a2: Inhibit sync flags
674 | All other registers zeroed for possible future requirements.
676 lea pc@(_startit),sp | make sure we have a good stack ***
678 movel a3@(4),a1 | loaded kernel
679 movel a3@(8),d2 | length of loaded kernel
680 | movel a3@(12),sp | entry point in stack pointer
681 movel a3@(12),a6 | push entry point ***
682 movel a3@(16),a0 | fastmem-start
683 movel a3@(20),d0 | fastmem-size
684 movel a3@(24),d1 | chipmem-size
685 movel a3@(28),d7 | boothowto
686 movel a3@(32),a4 | esym
687 movel a3@(36),d5 | cpuid
688 movel a3@(40),d4 | E clock frequency
689 movel a3@(44),d3 | Amiga flags
690 movel a3@(48),a2 | Inhibit sync flags
691 movel a3@(52),d6 | Load to fastmem flag
692 subl a5,a5 | target, load to 0
694 cmpb #0x7D,a3@(36) | is it DraCo?
695 beq nott | yes, switch off MMU later
697 | no, it is an Amiga:
699 | movew #0xf00,0xdff180 |red
700 | moveb #0,0x200003c8
701 | moveb #63,0x200003c9
702 | moveb #0,0x200003c9
703 | moveb #0,0x200003c9
705 movew #(1<<9),0xdff096 | disable DMA on Amigas.
707 | ------ mmu off start -----
709 btst #3,d5 | AFB_68040,SysBase->AttnFlags
710 beq not040
712 | Turn off 68040/060 MMU
714 subl a3,a3
715 .word 0x4e7b,0xb003 | movec a3,tc
716 .word 0x4e7b,0xb806 | movec a3,urp
717 .word 0x4e7b,0xb807 | movec a3,srp
718 .word 0x4e7b,0xb004 | movec a3,itt0
719 .word 0x4e7b,0xb005 | movec a3,itt1
720 .word 0x4e7b,0xb006 | movec a3,dtt0
721 .word 0x4e7b,0xb007 | movec a3,dtt1
722 bra nott
724 not040:
725 lea pc@(zero),a3
726 pmove a3@,tc | Turn off MMU
727 lea pc@(nullrp),a3
728 pmove a3@,crp | Turn off MMU some more
729 pmove a3@,srp | Really, really, turn off MMU
731 | Turn off 68030 TT registers
733 btst #2,d5 | AFB_68030,SysBase->AttnFlags
734 beq nott | Skip TT registers if not 68030
735 lea pc@(zero),a3
736 .word 0xf013,0x0800 | pmove a3@,tt0 (gas only knows about 68851 ops..)
737 .word 0xf013,0x0c00 | pmove a3@,tt1 (gas only knows about 68851 ops..)
739 nott:
740 | ---- mmu off end ----
741 | movew #0xf60,0xdff180 | orange
742 | moveb #0,0x200003c8
743 | moveb #63,0x200003c9
744 | moveb #24,0x200003c9
745 | moveb #0,0x200003c9
747 | ---- copy kernel start ----
749 tstl d6 | Can we load to fastmem?
750 beq L0 | No, leave destination at 0
751 movl a0,a5 | Move to start of fastmem chunk
752 addl a0,a6 | relocate kernel entry point
754 movl a1@+,a5@+
755 subl #4,d2
756 bcc L0
758 lea pc@(ckend),a1
759 movl a5,sp@-
760 movl #_startit_end - ckend,d2
762 movl a1@+,a5@+
763 subl #4,d2
764 bcc L2
766 btst #3,d5
767 jeq L1
768 .word 0xf4f8
770 movql #0,d2 | switch off cache to ensure we use
771 movec d2,cacr | valid kernel data
773 | movew #0xFF0,0xdff180 | yellow
774 | moveb #0,0x200003c8
775 | moveb #63,0x200003c9
776 | moveb #0,0x200003c9
777 | moveb #0,0x200003c9
780 | ---- copy kernel end ----
782 ckend:
783 | movew #0x0ff,0xdff180 | petrol
784 | moveb #0,0x200003c8
785 | moveb #0,0x200003c9
786 | moveb #63,0x200003c9
787 | moveb #63,0x200003c9
789 movl d5,d2
790 roll #8,d2
791 cmpb #0x7D,d2
792 jne noDraCo
794 | DraCo: switch off MMU now:
796 subl a3,a3
797 .word 0x4e7b,0xb003 | movec a3,tc
798 .word 0x4e7b,0xb806 | movec a3,urp
799 .word 0x4e7b,0xb807 | movec a3,srp
800 .word 0x4e7b,0xb004 | movec a3,itt0
801 .word 0x4e7b,0xb005 | movec a3,itt1
802 .word 0x4e7b,0xb006 | movec a3,dtt0
803 .word 0x4e7b,0xb007 | movec a3,dtt1
805 noDraCo:
806 moveq #0,d2 | zero out unused registers
807 moveq #0,d6 | (might make future compatibility
808 movel d6,a1 | would have known contents)
809 movel d6,a3
810 movel d6,a5
811 movel a6,sp | entry point into stack pointer
812 movel d6,a6
814 | movew #0x0F0,0xdff180 | green
815 | moveb #0,0x200003c8
816 | moveb #0,0x200003c9
817 | moveb #63,0x200003c9
818 | moveb #0,0x200003c9
820 jmp sp@ | jump to kernel entry point
822 | A do-nothing MMU root pointer (includes the following long as well)
824 nullrp: .long 0x7fff0001
825 zero: .long 0
827 _startit_end:
829 .data
830 _startit_sz: .long _startit_end-_startit
832 .text
835 void
836 usage(void)
838 fprintf(stderr, "usage: %s [-abhkpstADSVZ] [-c machine] [-m mem] [-n mode] [-I sync-inhibit] kernel\n",
839 program_name);
840 exit(1);
843 void
844 verbose_usage(void)
846 fprintf(stderr, "
847 NAME
848 \t%s - loads NetBSD from amiga dos.
849 SYNOPSIS
850 \t%s [-abhkpstADSVZ] [-c machine] [-m mem] [-n flags] [-I sync-inhibit] kernel
851 OPTIONS
852 \t-a Boot up to multiuser mode.
853 \t-A Use AGA display mode, if available.
854 \t-b Ask for which root device.
855 \t Its possible to have multiple roots and choose between them.
856 \t-c Set machine type. [e.g 3000; use 32000+N for DraCo rev. N]
857 \t-D Enter debugger
858 \t-h This help message.
859 \t-I Inhibit sync negotiation. Option value is bit-encoded targets.
860 \t-k Reserve the first 4M of fast mem [Some one else
861 \t is going to have to answer what that it is used for].
862 \t-m Tweak amount of available memory, for finding minimum amount
863 \t of memory required to run. Sets fastmem size to specified
864 \t size in Kbytes.
865 \t-n Enable multiple non-contiguous memory: value = 0 (disabled),
866 \t 1 (two segments), 2 (all avail segments), 3 (same as 2?).
867 \t-p Use highest priority fastmem segement instead of the largest
868 \t segment. The higher priority segment is usually faster
869 \t (i.e. 32 bit memory), but some people have smaller amounts
870 \t of 32 bit memory.
871 \t-q Boot up in quiet mode.
872 \t-s Boot up in singleuser mode (default).
873 \t-S Include kernel symbol table.
874 \t-t This is a *test* option. It prints out the memory
875 \t list information being passed to the kernel and also
876 \t exits without actually starting NetBSD.
877 \t-v Boot up in verbose mode.
878 \t-V Version of loadbsd program.
879 \t-Z Force kernel load to chipmem.
880 HISTORY
881 \tThis version supports Kernel version 720 +\n",
882 program_name, program_name);
883 exit(1);
886 static void
887 _Vdomessage(int doerrno, const char *fmt, va_list args)
889 fprintf(stderr, "%s: ", program_name);
890 if (fmt) {
891 vfprintf(stderr, fmt, args);
892 fprintf(stderr, ": ");
894 if (doerrno && errno < sys_nerr) {
895 fprintf(stderr, "%s", strerror(errno));
897 fprintf(stderr, "\n");
900 void
901 err(int eval, const char *fmt, ...)
903 va_list ap;
904 va_start(ap, fmt);
905 _Vdomessage(1, fmt, ap);
906 va_end(ap);
907 exit(eval);
910 #if 0
911 void
912 errx(int eval, const char *fmt, ...)
914 va_list ap;
915 va_start(ap, fmt);
916 _Vdomessage(0, fmt, ap);
917 va_end(ap);
918 exit(eval);
920 #endif
922 void
923 warn(const char *fmt, ...)
925 va_list ap;
926 va_start(ap, fmt);
927 _Vdomessage(1, fmt, ap);
928 va_end(ap);
931 #if 0
932 void
933 warnx(const char *fmt, ...)
935 va_list ap;
936 va_start(ap, fmt);
937 _Vdomessage(0, fmt, ap);
938 va_end(ap);
940 #endif