Home | History | Annotate | Line # | Download | only in loadbsd
loadbsd.c revision 1.26
      1  1.26   aymeric /*	$NetBSD: loadbsd.c,v 1.26 2000/10/30 14:40:33 aymeric Exp $	*/
      2  1.15       cgd 
      3   1.7    chopps /*
      4  1.12    chopps  * Copyright (c) 1994 Michael L. Hitch
      5  1.12    chopps  * All rights reserved.
      6  1.12    chopps  *
      7  1.12    chopps  * Redistribution and use in source and binary forms, with or without
      8  1.12    chopps  * modification, are permitted provided that the following conditions
      9  1.12    chopps  * are met:
     10  1.12    chopps  * 1. Redistributions of source code must retain the above copyright
     11  1.12    chopps  *    notice, this list of conditions and the following disclaimer.
     12  1.12    chopps  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.12    chopps  *    notice, this list of conditions and the following disclaimer in the
     14  1.12    chopps  *    documentation and/or other materials provided with the distribution.
     15  1.12    chopps  * 3. All advertising materials mentioning features or use of this software
     16  1.12    chopps  *    must display the following acknowledgement:
     17  1.12    chopps  *      This product includes software developed by Michael L. Hitch.
     18  1.12    chopps  * 4. The name of the author may not be used to endorse or promote products
     19  1.12    chopps  *    derived from this software without specific prior written permission
     20  1.12    chopps  *
     21  1.12    chopps  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  1.12    chopps  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  1.12    chopps  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  1.12    chopps  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  1.12    chopps  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  1.12    chopps  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  1.12    chopps  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  1.12    chopps  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  1.12    chopps  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  1.12    chopps  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31   1.7    chopps  */
     32   1.7    chopps 
     33   1.1        mw #include <sys/types.h>
     34   1.1        mw #include <a.out.h>
     35   1.1        mw #include <stdio.h>
     36   1.8    chopps #include <unistd.h>
     37  1.12    chopps #include <errno.h>
     38  1.12    chopps #include <stdarg.h>
     39  1.12    chopps #include <signal.h>
     40  1.12    chopps #ifdef __NetBSD__
     41  1.12    chopps #include <err.h>
     42  1.12    chopps #endif
     43   1.1        mw #include <exec/types.h>
     44   1.1        mw #include <exec/execbase.h>
     45   1.1        mw #include <exec/memory.h>
     46  1.10    chopps #include <exec/resident.h>
     47  1.12    chopps #include <graphics/gfxbase.h>
     48   1.1        mw #include <libraries/configregs.h>
     49  1.12    chopps #include <libraries/configvars.h>
     50  1.12    chopps #include <libraries/expansion.h>
     51   1.1        mw #include <libraries/expansionbase.h>
     52   1.1        mw 
     53   1.1        mw #include <inline/exec.h>
     54   1.1        mw #include <inline/expansion.h>
     55   1.5        mw #include <inline/graphics.h>
     56   1.1        mw 
     57   1.3        mw /* Get definitions for boothowto */
     58   1.3        mw #include "reboot.h"
     59   1.3        mw 
     60   1.1        mw #undef __LDPGSZ
     61   1.1        mw #define __LDPGSZ 8192
     62   1.1        mw 
     63  1.12    chopps #ifndef __NetBSD__
     64  1.12    chopps #ifndef __P
     65  1.12    chopps #ifdef __STDC__
     66  1.12    chopps #define __P(x) x
     67  1.12    chopps #else
     68  1.12    chopps #define __P(x)
     69  1.12    chopps #endif
     70  1.12    chopps #endif
     71  1.12    chopps void err __P((int, const char *, ...));
     72  1.12    chopps void errx __P((int, const char *, ...));
     73  1.12    chopps void warn __P((const char *, ...));
     74  1.12    chopps void warnx __P((const char *, ...));
     75  1.12    chopps #endif
     76   1.6    chopps 
     77   1.9    chopps /*
     78   1.9    chopps  *	Version history:
     79  1.19    mhitch  *	1.x	Kernel startup interface version check.
     80  1.10    chopps  *	2.0	Added symbol table end address and symbol table support.
     81  1.10    chopps  *	2.1	03/23/94 - Round up end of fastram segment.
     82  1.10    chopps  *		Check fastram segment size for minimum of 2M.
     83  1.10    chopps  *		Use largest segment of highest priority if -p option.
     84  1.10    chopps  *		Print out fastram size in KB if not a multiple of MB.
     85  1.10    chopps  *	2.2	03/24/94 - Zero out all unused registers.
     86  1.10    chopps  *		Started version history comment.
     87  1.10    chopps  *	2.3	04/26/94 - Added -D option to enter debugger on boot.
     88  1.10    chopps  *	2.4	04/30/94 - Cpuid includes base machine type.
     89  1.10    chopps  *		Also check if CPU is capable of running NetBSD.
     90  1.11    chopps  *	2.5	05/17/94 - Add check for "A3000 bonus".
     91  1.11    chopps  *	2.6	06/05/94 - Added -c option to override machine type.
     92  1.12    chopps  *	2.7	06/15/94 - Pass E clock frequency.
     93  1.13    chopps  *	2.8	06/22/94 - Fix supervisor stack usage.
     94  1.14    chopps  *	2.9	06/26/94 - Use PAL flag for E clock freq on pre 2.0 WB
     95  1.14    chopps  *		Added AGA enable parameter
     96  1.16    chopps  *	2.10	12/22/94 - Use FindResident() & OpenResource() for machine
     97  1.16    chopps  *		type detection.
     98  1.16    chopps  *		Add -n flag & option for non-contiguous memory.
     99  1.16    chopps  *		01/28/95 - Corrected -n on usage & help messages.
    100  1.17       jtc  *	2.11	03/12/95 - Check kernel size against chip memory size.
    101  1.17       jtc  *	2.12	11/11/95 - Add -I option to inhibit synchronous transfer
    102  1.19    mhitch  *		11/12/95 - New kernel startup interface version - to
    103  1.19    mhitch  *		support loading kernel image to fastmem rather than chipmem.
    104  1.19    mhitch  *	2.13	04/15/96 - Direct load to fastmem.
    105  1.19    mhitch  *		Add -Z flag to force chipmem load.
    106  1.19    mhitch  *		Moved test mode exit to later - kernel image is created
    107  1.19    mhitch  *		and startup interface version checked in test mode.
    108  1.19    mhitch  *		Add -s flag for compatibility to bootblock loader.
    109  1.19    mhitch  *		05/02/96 - Add a maximum startup interface version level
    110  1.20        is  *		to allow future kernel compatibility.
    111  1.20        is  *	2.14	06/26/96 is - Add first version of kludges needed to
    112  1.20        is  *		boot on DraCos. This can probably be done a bit more cleanly
    113  1.20        is  *		using TTRs, but it works for now.
    114  1.21        is  *	2.15	07/28/96 is - Add first version of kludges needed to
    115  1.21        is  *		get FusionForty kickrom'd memory back. Hope this doesn't
    116  1.21        is  *		break anything else.
    117  1.25  jdolecek  *	2.16	07/08/00 - added bootverbose support
    118   1.9    chopps  */
    119  1.25  jdolecek static const char _version[] = "$VER: LoadBSD 2.16 (19.9.2000)";
    120   1.9    chopps 
    121  1.12    chopps /*
    122  1.19    mhitch  * Kernel startup interface version
    123  1.12    chopps  *	1:	first version of loadbsd
    124  1.12    chopps  *	2:	needs esym location passed in a4
    125  1.19    mhitch  *	3:	load kernel image into fastmem rather than chipmem
    126  1.19    mhitch  *	MAX:	highest version with backward compatibility.
    127  1.12    chopps  */
    128  1.19    mhitch #define KERNEL_STARTUP_VERSION	3
    129  1.19    mhitch #define	KERNEL_STARTUP_VERSION_MAX	9
    130  1.10    chopps 
    131  1.20        is #define DRACOREVISION (*(UBYTE *)0x02000009)
    132  1.20        is #define DRACOMMUMARGIN 0x200000
    133  1.20        is 
    134  1.12    chopps #define MAXMEMSEG	16
    135  1.12    chopps struct boot_memlist {
    136  1.12    chopps 	u_int	m_nseg; /* num_mem; */
    137  1.12    chopps 	struct boot_memseg {
    138  1.12    chopps 		u_int	ms_start;
    139  1.12    chopps 		u_int	ms_size;
    140  1.12    chopps 		u_short	ms_attrib;
    141  1.12    chopps 		short	ms_pri;
    142  1.12    chopps 	} m_seg[MAXMEMSEG];
    143  1.12    chopps };
    144  1.12    chopps struct boot_memlist memlist;
    145  1.12    chopps struct boot_memlist *kmemlist;
    146  1.12    chopps 
    147  1.12    chopps 
    148  1.12    chopps void get_mem_config __P((void **, u_long *, u_long *));
    149  1.12    chopps void get_cpuid __P((void));
    150  1.12    chopps void get_eclock __P((void));
    151  1.14    chopps void get_AGA __P((void));
    152  1.12    chopps void usage __P((void));
    153  1.12    chopps void verbose_usage __P((void));
    154  1.12    chopps void Version __P((void));
    155  1.19    mhitch void startit __P((void *, u_long, u_long, void *, u_long, u_long, int, void *,
    156  1.19    mhitch 		int, int, u_long, u_long, int));
    157  1.19    mhitch void startit_end __P((void));
    158   1.5        mw 
    159  1.12    chopps extern struct ExecBase *SysBase;
    160   1.5        mw extern char *optarg;
    161   1.5        mw extern int optind;
    162   1.5        mw 
    163  1.12    chopps int k_flag;
    164  1.12    chopps int p_flag;
    165  1.12    chopps int t_flag;
    166  1.12    chopps int reqmemsz;
    167  1.12    chopps int S_flag;
    168  1.17       jtc u_long I_flag;
    169  1.19    mhitch int Z_flag;
    170  1.12    chopps u_long cpuid;
    171  1.12    chopps long eclock_freq;
    172  1.16    chopps long amiga_flags;
    173  1.12    chopps char *program_name;
    174  1.12    chopps char *kname;
    175  1.12    chopps struct ExpansionBase *ExpansionBase;
    176  1.12    chopps struct GfxBase *GfxBase;
    177  1.20        is u_char *kp;
    178  1.20        is int ksize;
    179   1.1        mw 
    180  1.10    chopps int
    181  1.12    chopps main(argc, argv)
    182  1.12    chopps 	int argc;
    183  1.12    chopps 	char **argv;
    184   1.1        mw {
    185  1.12    chopps 	struct exec e;
    186  1.12    chopps 	struct ConfigDev *cd, *kcd;
    187  1.12    chopps 	u_long fmemsz, cmemsz;
    188  1.20        is 	int fd, boothowto, textsz, stringsz, ncd, i, mem_ix, ch;
    189  1.12    chopps 	u_short *kvers;
    190  1.12    chopps 	int *nkcd;
    191  1.12    chopps 	void *fmem;
    192  1.12    chopps 	char *esym;
    193  1.19    mhitch 	void (*start_it) __P((void *, u_long, u_long, void *, u_long, u_long,
    194  1.19    mhitch 	     int, void *, int, int, u_long, u_long, int)) = startit;
    195  1.12    chopps 
    196  1.12    chopps 	program_name = argv[0];
    197  1.12    chopps 	boothowto = RB_SINGLE;
    198  1.12    chopps 
    199  1.12    chopps 	if (argc < 2)
    200  1.12    chopps 		usage();
    201  1.12    chopps 	if ((GfxBase = (void *)OpenLibrary(GRAPHICSNAME, 0)) == NULL)
    202  1.12    chopps 		err(20, "can't open graphics library");
    203  1.12    chopps 	if ((ExpansionBase=(void *)OpenLibrary(EXPANSIONNAME, 0)) == NULL)
    204  1.12    chopps 		err(20, "can't open expansion library");
    205  1.12    chopps 
    206  1.25  jdolecek 	while ((ch = getopt(argc, argv, "aAbc:DhI:km:n:qptsSvVZ")) != -1) {
    207  1.12    chopps 		switch (ch) {
    208  1.12    chopps 		case 'k':
    209  1.12    chopps 			k_flag = 1;
    210  1.12    chopps 			break;
    211  1.12    chopps 		case 'a':
    212  1.12    chopps 			boothowto &= ~(RB_SINGLE);
    213  1.12    chopps 			boothowto |= RB_AUTOBOOT;
    214  1.12    chopps 			break;
    215  1.12    chopps 		case 'b':
    216  1.12    chopps 			boothowto |= RB_ASKNAME;
    217  1.12    chopps 			break;
    218  1.12    chopps 		case 'p':
    219  1.12    chopps 			p_flag = 1;
    220  1.12    chopps 			break;
    221  1.12    chopps 		case 't':
    222  1.12    chopps 			t_flag = 1;
    223  1.12    chopps 			break;
    224  1.12    chopps 		case 'm':
    225  1.12    chopps 			reqmemsz = atoi(optarg) * 1024;
    226  1.12    chopps 			break;
    227  1.19    mhitch 		case 's':
    228  1.19    mhitch 			boothowto &= ~(RB_AUTOBOOT);
    229  1.19    mhitch 			boothowto |= RB_SINGLE;
    230  1.19    mhitch 			break;
    231  1.25  jdolecek 		case 'q':
    232  1.25  jdolecek 			boothowto |= AB_QUIET;
    233  1.26   aymeric 			break;
    234  1.25  jdolecek 		case 'v':
    235  1.25  jdolecek 			boothowto |= AB_VERBOSE;
    236  1.25  jdolecek 			break;
    237  1.12    chopps 		case 'V':
    238  1.12    chopps 			fprintf(stderr,"%s\n",_version + 6);
    239  1.12    chopps 			break;
    240  1.12    chopps 		case 'S':
    241  1.12    chopps 			S_flag = 1;
    242  1.12    chopps 			break;
    243  1.12    chopps 		case 'D':
    244  1.12    chopps 			boothowto |= RB_KDB;
    245  1.12    chopps 			break;
    246  1.12    chopps 		case 'c':
    247  1.12    chopps 			cpuid = atoi(optarg) << 16;
    248  1.12    chopps 			break;
    249  1.14    chopps 		case 'A':
    250  1.16    chopps 			amiga_flags |= 1;
    251  1.16    chopps 			break;
    252  1.16    chopps 		case 'n':
    253  1.16    chopps 			i = atoi(optarg);
    254  1.16    chopps 			if (i >= 0 && i <= 3)
    255  1.16    chopps 				amiga_flags |= i << 1;
    256  1.16    chopps 			else
    257  1.16    chopps 				err(20, "-n option must be 0, 1, 2, or 3");
    258  1.14    chopps 			break;
    259  1.17       jtc 		case 'I':
    260  1.17       jtc 			I_flag = strtoul(optarg, NULL, 16);
    261  1.17       jtc 			break;
    262  1.19    mhitch 		case 'Z':
    263  1.19    mhitch 			Z_flag = 1;
    264  1.19    mhitch 			break;
    265  1.12    chopps 		case 'h':
    266  1.12    chopps 			verbose_usage();
    267  1.12    chopps 		default:
    268  1.12    chopps 			usage();
    269  1.12    chopps 		}
    270  1.12    chopps 	}
    271  1.12    chopps 	argc -= optind;
    272  1.12    chopps 	argv += optind;
    273  1.12    chopps 
    274  1.12    chopps 	if (argc != 1)
    275  1.12    chopps 		usage();
    276  1.12    chopps 	kname = argv[0];
    277  1.12    chopps 
    278  1.12    chopps 	if ((fd = open(kname, 0)) < 0)
    279  1.12    chopps 		err(20, "open");
    280  1.12    chopps 	if (read(fd, &e, sizeof(e)) != sizeof(e))
    281  1.12    chopps 		err(20, "reading exec");
    282  1.12    chopps 	if (e.a_magic != NMAGIC)
    283  1.12    chopps 		err(20, "unknown binary");
    284  1.12    chopps 
    285  1.12    chopps 	for (cd = 0, ncd = 0; cd = FindConfigDev(cd, -1, -1); ncd++)
    286  1.12    chopps 		;
    287  1.20        is 	get_cpuid();
    288  1.12    chopps 	get_mem_config(&fmem, &fmemsz, &cmemsz);
    289  1.12    chopps 	get_eclock();
    290  1.14    chopps 	get_AGA();
    291  1.12    chopps 
    292  1.12    chopps 	textsz = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ);
    293  1.12    chopps 	esym = NULL;
    294  1.12    chopps 	ksize = textsz + e.a_data + e.a_bss + ncd * sizeof(*cd)
    295  1.12    chopps 	    + 4 + memlist.m_nseg * sizeof(struct boot_memseg) + 4;
    296  1.12    chopps 
    297  1.12    chopps 	/*
    298  1.12    chopps 	 * get symbol table size & string size
    299  1.12    chopps 	 * (should check kernel version to see if it will handle it)
    300  1.12    chopps 	 */
    301  1.12    chopps 	if (S_flag && e.a_syms) {
    302  1.12    chopps 		if (lseek(fd, e.a_text + e.a_data + e.a_syms, SEEK_CUR) <= 0
    303  1.12    chopps 		    || read(fd, &stringsz, 4) != 4
    304  1.12    chopps 		    || lseek(fd, sizeof(e), SEEK_SET) < 0)
    305  1.12    chopps 			err(20, "lseek for symbols");
    306  1.19    mhitch 		ksize += e.a_syms + 4 + ((stringsz + 3) & ~3);
    307  1.12    chopps 	}
    308  1.12    chopps 
    309  1.20        is 	kp = (u_char *)AllocMem(ksize + ((char *)startit_end - (char *)startit) + 256,
    310  1.20        is 	    MEMF_FAST|MEMF_REVERSE);
    311  1.12    chopps 	if (t_flag) {
    312  1.12    chopps 		for (i = 0; i < memlist.m_nseg; ++i) {
    313  1.12    chopps 			printf("mem segment %d: start=%08lx size=%08lx"
    314  1.12    chopps 			    " attribute=%04lx pri=%d\n",
    315  1.12    chopps 			    i + 1, memlist.m_seg[i].ms_start,
    316  1.12    chopps 			    memlist.m_seg[i].ms_size,
    317  1.12    chopps 			    memlist.m_seg[i].ms_attrib,
    318  1.12    chopps 			    memlist.m_seg[i].ms_pri);
    319  1.10    chopps 		}
    320  1.17       jtc 		printf("kernel size: %d\n", ksize);
    321  1.12    chopps 	}
    322  1.12    chopps 	if (kp == NULL)
    323  1.12    chopps 		err(20, "failed malloc %d\n", ksize);
    324  1.12    chopps 
    325  1.12    chopps 	if (read(fd, kp, e.a_text) != e.a_text
    326  1.12    chopps 	    || read(fd, kp + textsz, e.a_data) != e.a_data)
    327  1.12    chopps 		err(20, "unable to read kernel image\n");
    328  1.12    chopps 
    329  1.12    chopps 	if (k_flag) {
    330  1.12    chopps 		fmem += 4 * 1024 * 1024;
    331  1.12    chopps 		fmemsz -= 4 * 1024 * 1024;
    332  1.12    chopps 	}
    333   1.1        mw 
    334  1.12    chopps 	if (reqmemsz && reqmemsz <= fmemsz)
    335  1.12    chopps 		fmemsz = reqmemsz;
    336  1.12    chopps 	if (boothowto & RB_AUTOBOOT)
    337  1.12    chopps 		printf("Autobooting...");
    338  1.12    chopps 	if (boothowto & RB_ASKNAME)
    339  1.12    chopps 		printf("Askboot...");
    340  1.12    chopps 
    341  1.12    chopps 	printf("Using %d%c FASTMEM at 0x%x, %dM CHIPMEM\n",
    342  1.12    chopps 	    (fmemsz & 0xfffff) ? fmemsz >> 10 : fmemsz >> 20,
    343  1.12    chopps 	    (fmemsz & 0xfffff) ? 'K' : 'M', fmem, cmemsz >> 20);
    344  1.12    chopps 	kvers = (u_short *)(kp + e.a_entry - 2);
    345  1.19    mhitch 	if (*kvers > KERNEL_STARTUP_VERSION_MAX && *kvers != 0x4e73)
    346  1.12    chopps 		err(20, "newer loadbsd required: %d\n", *kvers);
    347  1.19    mhitch 	if (*kvers > KERNEL_STARTUP_VERSION) {
    348  1.17       jtc 		printf("****************************************************\n");
    349  1.17       jtc 		printf("*** Notice:  this kernel has features which require\n");
    350  1.17       jtc 		printf("*** a newer version of loadbsd.  To allow the use of\n");
    351  1.17       jtc 		printf("*** any newer features or capabilities, you should\n");
    352  1.19    mhitch 		printf("*** update to a newer version of loadbsd\n");
    353  1.17       jtc 		printf("****************************************************\n");
    354  1.17       jtc 		sleep(3);	/* even more time to see that message */
    355  1.17       jtc 	}
    356  1.12    chopps 	if ((cpuid & AFB_68020) == 0)
    357  1.12    chopps 		err(20, "cpu not supported");
    358  1.12    chopps 	/*
    359  1.12    chopps 	 * give them a chance to read the information...
    360  1.12    chopps 	 */
    361  1.12    chopps 	sleep(2);
    362  1.12    chopps 
    363  1.12    chopps 	bzero(kp + textsz + e.a_data, e.a_bss);
    364  1.12    chopps 	/*
    365  1.12    chopps 	 * If symbols wanted (and kernel can handle them),
    366  1.12    chopps 	 * load symbol table & strings and set esym to end.
    367  1.12    chopps 	 */
    368  1.12    chopps 	nkcd = (int *)(kp + textsz + e.a_data + e.a_bss);
    369  1.12    chopps 	if (*kvers != 0x4e73 && *kvers > 1 && S_flag && e.a_syms) {
    370  1.12    chopps 		*nkcd++ = e.a_syms;
    371  1.12    chopps 		read(fd, (char *)nkcd, e.a_syms);
    372  1.12    chopps 		nkcd = (int *)((char *)nkcd + e.a_syms);
    373  1.12    chopps 		read(fd, (char *)nkcd, stringsz);
    374  1.19    mhitch 		    nkcd = (int*)((char *)nkcd + ((stringsz + 3) & ~3));
    375  1.12    chopps 		    esym = (char *)(textsz + e.a_data + e.a_bss
    376  1.19    mhitch 		    + e.a_syms + 4 + ((stringsz + 3) & ~3));
    377  1.10    chopps 	}
    378  1.12    chopps 	*nkcd = ncd;
    379  1.12    chopps 
    380  1.12    chopps 	kcd = (struct ConfigDev *)(nkcd + 1);
    381  1.20        is 	while(cd = FindConfigDev(cd, -1, -1)) {
    382  1.20        is 		*kcd = *cd;
    383  1.20        is 		if (((cpuid >> 24) == 0x7d) &&
    384  1.20        is 		    ((u_long)kcd->cd_BoardAddr < 0x1000000)) {
    385  1.20        is 			if (t_flag)
    386  1.20        is 				printf("Transformed Z2 device from %08lx ",
    387  1.20        is 				    kcd->cd_BoardAddr);
    388  1.20        is 			kcd->cd_BoardAddr += 0x3000000;
    389  1.20        is 
    390  1.20        is 			if (t_flag)
    391  1.20        is 				printf("to %08lx\n", kcd->cd_BoardAddr);
    392  1.20        is 		}
    393  1.20        is 		++kcd;
    394  1.20        is 	}
    395  1.12    chopps 
    396  1.12    chopps 	kmemlist = (struct boot_memlist *)kcd;
    397  1.12    chopps 	kmemlist->m_nseg = memlist.m_nseg;
    398  1.12    chopps 	for (mem_ix = 0; mem_ix < memlist.m_nseg; mem_ix++)
    399  1.12    chopps 		kmemlist->m_seg[mem_ix] = memlist.m_seg[mem_ix];
    400  1.19    mhitch 
    401  1.19    mhitch 	if (*kvers > 2 && Z_flag == 0) {
    402  1.19    mhitch 		/*
    403  1.19    mhitch 		 * Kernel supports direct load to fastmem, and the -Z
    404  1.19    mhitch 		 * option was not specified.  Copy startup code to end
    405  1.19    mhitch 		 * of kernel image and set start_it.
    406  1.19    mhitch 		 */
    407  1.20        is 		if ((void *)kp < fmem) {
    408  1.20        is 			printf("Kernel at %08lx, Fastmem used at %08lx\n",
    409  1.20        is 			    kp, fmem);
    410  1.22        is 			errx(20, "Can't copy upwards yet.\nDefragment your memory and try again OR try the -p OR try the -Z options.");
    411  1.20        is 		}
    412  1.19    mhitch 		memcpy(kp + ksize + 256, (char *)startit,
    413  1.19    mhitch 		    (char *)startit_end - (char *)startit);
    414  1.19    mhitch 		CacheClearU();
    415  1.19    mhitch 		start_it = (void (*)())kp + ksize + 256;
    416  1.19    mhitch 		printf("*** Loading from %08lx to Fastmem %08lx ***\n",
    417  1.19    mhitch 		    kp, fmem);
    418  1.19    mhitch 		sleep(2);
    419  1.19    mhitch 	} else {
    420  1.19    mhitch 		/*
    421  1.19    mhitch 		 * Either the kernel doesn't suppport loading directly to
    422  1.19    mhitch 		 * fastmem or the -Z flag was given.  Verify kernel image
    423  1.19    mhitch 		 * fits into chipmem.
    424  1.19    mhitch 		 */
    425  1.19    mhitch 		if (ksize >= cmemsz) {
    426  1.19    mhitch 			printf("Kernel size %d exceeds Chip Memory of %d\n",
    427  1.19    mhitch 			    ksize, cmemsz);
    428  1.19    mhitch 			err(20, "Insufficient Chip Memory for kernel");
    429  1.19    mhitch 		}
    430  1.19    mhitch 		Z_flag = 1;
    431  1.24        is 		printf("*** Loading from %08lx to Chipmem ***\n", kp);
    432  1.19    mhitch 	}
    433  1.19    mhitch 
    434  1.12    chopps 	/*
    435  1.12    chopps 	 * if test option set, done
    436  1.12    chopps 	 */
    437  1.20        is 	if (t_flag) {
    438  1.20        is 		if (kp)
    439  1.20        is 			FreeMem(kp, ksize + ((char *)startit_end
    440  1.20        is 			    - (char *)startit) + 256);
    441  1.12    chopps 		exit(0);
    442  1.20        is 	}
    443  1.12    chopps 
    444  1.12    chopps 	/*
    445  1.12    chopps 	 * XXX AGA startup - may need more
    446  1.12    chopps 	 */
    447  1.16    chopps 	LoadView(NULL);		/* Don't do this if AGA active? */
    448  1.19    mhitch 	start_it(kp, ksize, e.a_entry, fmem, fmemsz, cmemsz, boothowto, esym,
    449  1.19    mhitch 	    cpuid, eclock_freq, amiga_flags, I_flag, Z_flag == 0);
    450  1.12    chopps 	/*NOTREACHED*/
    451  1.12    chopps }
    452   1.1        mw 
    453   1.1        mw void
    454  1.12    chopps get_mem_config(fmem, fmemsz, cmemsz)
    455  1.12    chopps 	void **fmem;
    456  1.12    chopps 	u_long *fmemsz, *cmemsz;
    457   1.1        mw {
    458  1.12    chopps 	struct MemHeader *mh, *nmh;
    459  1.20        is 	u_int segsz, seg, eseg, nmem, nseg, nsegsz;
    460  1.20        is 	u_int tseg, tsegsz;
    461  1.12    chopps 	char mempri;
    462  1.12    chopps 
    463  1.12    chopps 	nmem = 0;
    464  1.12    chopps 	mempri = -128;
    465  1.12    chopps 	*fmemsz = 0;
    466  1.12    chopps 	*cmemsz = 0;
    467  1.12    chopps 
    468  1.12    chopps 	/*
    469  1.12    chopps 	 * walk thru the exec memory list
    470  1.12    chopps 	 */
    471  1.12    chopps 	Forbid();
    472  1.20        is 	for (mh  = (void *) SysBase->MemList.lh_Head;
    473  1.20        is 	    nmh = (void *) mh->mh_Node.ln_Succ; mh = nmh) {
    474  1.20        is 
    475  1.20        is 		nseg = (u_int)mh->mh_Lower;
    476  1.20        is 		nsegsz = (u_int)mh->mh_Upper - nseg;
    477  1.20        is 
    478  1.20        is 		segsz = nsegsz;
    479  1.20        is 		seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, 0L);
    480  1.20        is 		nsegsz -= segsz, nseg += segsz;
    481  1.20        is 		for (;segsz;
    482  1.20        is 		    segsz = nsegsz,
    483  1.20        is 		    seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, DMA_Continue),
    484  1.20        is 		    nsegsz -= segsz, nseg += segsz, ++nmem) {
    485  1.20        is 
    486  1.20        is 			if (t_flag)
    487  1.20        is 				printf("Translated %08x sz %08x to %08x sz %08x\n",
    488  1.20        is 				    nseg - segsz, nsegsz + segsz, seg, segsz);
    489  1.20        is 
    490  1.20        is 			eseg = seg + segsz;
    491  1.20        is 
    492  1.20        is 
    493  1.20        is 			if ((cpuid >> 24) == 0x7D) {
    494  1.20        is 				/* DraCo MMU table kludge */
    495  1.20        is 
    496  1.20        is 				segsz = ((segsz -1) | 0xfffff) + 1;
    497  1.20        is 				seg = eseg - segsz;
    498  1.20        is 
    499  1.20        is 				/*
    500  1.20        is 				 * Only use first SIMM to boot; we know it is VA==PA.
    501  1.20        is 				 * Enter into table and continue. Yes,
    502  1.20        is 				 * this is ugly.
    503  1.20        is 				 */
    504  1.20        is 				if (seg != 0x40000000) {
    505  1.20        is 					memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
    506  1.20        is 					memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
    507  1.20        is 					memlist.m_seg[nmem].ms_size = segsz;
    508  1.20        is 					memlist.m_seg[nmem].ms_start = seg;
    509  1.20        is 					++nmem;
    510  1.20        is 					continue;
    511  1.20        is 				}
    512  1.20        is 
    513  1.20        is 				memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
    514  1.20        is 				memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
    515  1.20        is 				memlist.m_seg[nmem].ms_size = DRACOMMUMARGIN;
    516  1.20        is 				memlist.m_seg[nmem].ms_start = seg;
    517  1.20        is 
    518  1.20        is 				++nmem;
    519  1.20        is 				seg += DRACOMMUMARGIN;
    520  1.20        is 				segsz -= DRACOMMUMARGIN;
    521  1.20        is 			}
    522  1.12    chopps 
    523  1.20        is 			memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
    524  1.20        is 			memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
    525  1.20        is 			memlist.m_seg[nmem].ms_size = segsz;
    526  1.20        is 			memlist.m_seg[nmem].ms_start = seg;
    527  1.20        is 
    528  1.20        is 			if ((mh->mh_Attributes & (MEMF_CHIP|MEMF_FAST)) == MEMF_CHIP) {
    529  1.20        is 				/*
    530  1.20        is 				 * there should hardly be more than one entry for
    531  1.20        is 				 * chip mem, but handle it the same nevertheless
    532  1.20        is 				 * cmem always starts at 0, so include vector area
    533  1.20        is 				 */
    534  1.20        is 				memlist.m_seg[nmem].ms_start = seg = 0;
    535  1.20        is 				/*
    536  1.20        is 				 * round to multiple of 512K
    537  1.20        is 				 */
    538  1.20        is 				segsz = (segsz + 512 * 1024 - 1) & -(512 * 1024);
    539  1.20        is 				memlist.m_seg[nmem].ms_size = segsz;
    540  1.20        is 				if (segsz > *cmemsz)
    541  1.20        is 					*cmemsz = segsz;
    542  1.20        is 				continue;
    543  1.20        is 			}
    544  1.12    chopps 			/*
    545  1.20        is 			 * some heuristics..
    546  1.12    chopps 			 */
    547  1.20        is 			seg &= -__LDPGSZ;
    548  1.20        is 			eseg = (eseg + __LDPGSZ - 1) & -__LDPGSZ;
    549  1.20        is 
    550  1.12    chopps 			/*
    551  1.20        is 			 * get the mem back stolen by incore kickstart on
    552  1.20        is 			 * A3000 with V36 bootrom.
    553  1.12    chopps 			 */
    554  1.20        is 			if (eseg == 0x07f80000)
    555  1.20        is 				eseg = 0x08000000;
    556  1.20        is 
    557  1.20        is 			/*
    558  1.20        is 			 * or by zkick on a A2000.
    559  1.20        is 			 */
    560  1.20        is 			if (seg == 0x280000 &&
    561  1.20        is 			    strcmp(mh->mh_Node.ln_Name, "zkick memory") == 0)
    562  1.20        is 				seg = 0x200000;
    563  1.21        is 			/*
    564  1.21        is 			 * or by Fusion Forty fastrom
    565  1.21        is 			 */
    566  1.21        is 			if ((seg & ~(1024*1024-1)) == 0x11000000) {
    567  1.21        is 				/*
    568  1.21        is 				 * XXX we should test the name.
    569  1.21        is 				 * Unfortunately, the memory is just called
    570  1.21        is 				 * "32 bit memory" which isn't very specific.
    571  1.21        is 				 */
    572  1.21        is 				seg = 0x11000000;
    573  1.21        is 			}
    574  1.20        is 
    575  1.20        is 			segsz = eseg - seg;
    576  1.20        is 			memlist.m_seg[nmem].ms_start = seg;
    577  1.12    chopps 			memlist.m_seg[nmem].ms_size = segsz;
    578  1.20        is 			/*
    579  1.20        is 			 *  If this segment is smaller than 2M,
    580  1.20        is 			 *  don't use it to load the kernel
    581  1.20        is 			 */
    582  1.20        is 			if (segsz < 2 * 1024 * 1024)
    583  1.20        is 				continue;
    584  1.20        is 			/*
    585  1.20        is 			 * if p_flag is set, select memory by priority
    586  1.20        is 			 * instead of size
    587  1.20        is 			 */
    588  1.20        is 			if ((!p_flag && segsz > *fmemsz) || (p_flag &&
    589  1.20        is 			   mempri <= mh->mh_Node.ln_Pri && segsz > *fmemsz)) {
    590  1.20        is 				*fmemsz = segsz;
    591  1.20        is 				*fmem = (void *)seg;
    592  1.20        is 				mempri = mh->mh_Node.ln_Pri;
    593  1.20        is 			}
    594  1.12    chopps 
    595  1.12    chopps 		}
    596   1.1        mw 	}
    597  1.12    chopps 	memlist.m_nseg = nmem;
    598  1.12    chopps 	Permit();
    599   1.1        mw }
    600   1.1        mw 
    601  1.10    chopps /*
    602  1.10    chopps  * Try to determine the machine ID by searching the resident module list
    603  1.10    chopps  * for modules only present on specific machines.  (Thanks, Bill!)
    604  1.10    chopps  */
    605  1.10    chopps void
    606  1.12    chopps get_cpuid()
    607  1.10    chopps {
    608  1.10    chopps 	u_long *rl;
    609  1.10    chopps 	struct Resident *rm;
    610  1.16    chopps 	struct Node *rn;		/* Resource node entry */
    611  1.10    chopps 
    612  1.11    chopps 	cpuid |= SysBase->AttnFlags;	/* get FPU and CPU flags */
    613  1.11    chopps 	if (cpuid & 0xffff0000) {
    614  1.24        is 		if ((cpuid >> 24) == 0x7D)
    615  1.20        is 			return;
    616  1.20        is 
    617  1.11    chopps 		switch (cpuid >> 16) {
    618  1.11    chopps 		case 500:
    619  1.11    chopps 		case 600:
    620  1.11    chopps 		case 1000:
    621  1.11    chopps 		case 1200:
    622  1.11    chopps 		case 2000:
    623  1.11    chopps 		case 3000:
    624  1.11    chopps 		case 4000:
    625  1.11    chopps 			return;
    626  1.11    chopps 		default:
    627  1.12    chopps 			printf("machine Amiga %d is not recognized\n",
    628  1.11    chopps 			    cpuid >> 16);
    629  1.12    chopps 			exit(1);
    630  1.11    chopps 		}
    631  1.11    chopps 	}
    632  1.18    chopps 	if (FindResident("A4000 Bonus") || FindResident("A4000 bonus")
    633  1.18    chopps 	    || FindResident("A1000 Bonus"))
    634  1.16    chopps 		cpuid |= 4000 << 16;
    635  1.16    chopps 	else if (FindResident("A3000 Bonus") || FindResident("A3000 bonus"))
    636  1.16    chopps 		cpuid |= 3000 << 16;
    637  1.16    chopps 	else if (OpenResource("card.resource")) {
    638  1.16    chopps 		/* Test for AGA? */
    639  1.16    chopps 		cpuid |= 1200 << 16;
    640  1.20        is 	} else if (OpenResource("draco.resource")) {
    641  1.20        is 		cpuid |= (32000 | DRACOREVISION) << 16;
    642  1.10    chopps 	}
    643  1.12    chopps 	/*
    644  1.12    chopps 	 * Nothing found, it's probably an A2000 or A500
    645  1.12    chopps 	 */
    646  1.16    chopps 	if ((cpuid >> 16) == 0)
    647  1.10    chopps 		cpuid |= 2000 << 16;
    648  1.10    chopps }
    649   1.1        mw 
    650  1.12    chopps void
    651  1.12    chopps get_eclock()
    652  1.12    chopps {
    653  1.12    chopps 	/* Fix for 1.3 startups? */
    654  1.14    chopps 	if (SysBase->LibNode.lib_Version > 36)
    655  1.14    chopps 		eclock_freq = SysBase->ex_EClockFrequency;
    656  1.14    chopps 	else
    657  1.14    chopps 		eclock_freq = (GfxBase->DisplayFlags & PAL) ?
    658  1.14    chopps 		    709379 : 715909;
    659  1.14    chopps }
    660  1.14    chopps 
    661  1.14    chopps void
    662  1.14    chopps get_AGA()
    663  1.14    chopps {
    664  1.14    chopps 	/*
    665  1.14    chopps 	 * Determine if an AGA mode is active
    666  1.14    chopps 	 */
    667  1.12    chopps }
    668  1.12    chopps 
    669   1.1        mw 
    670  1.12    chopps asm("
    671   1.1        mw 	.set	ABSEXECBASE,4
    672   1.1        mw 
    673   1.1        mw 	.text
    674   1.1        mw 	.globl	_startit
    675   1.1        mw 
    676   1.1        mw _startit:
    677   1.1        mw 	movel	sp,a3
    678   1.1        mw 	movel	4:w,a6
    679  1.20        is 	lea	pc@(start_super),a5
    680   1.1        mw 	jmp	a6@(-0x1e)		| supervisor-call
    681   1.1        mw 
    682   1.1        mw start_super:
    683   1.1        mw 	movew	#0x2700,sr
    684   1.1        mw 
    685   1.1        mw 	| the BSD kernel wants values into the following registers:
    686   1.1        mw 	| a0:  fastmem-start
    687   1.1        mw 	| d0:  fastmem-size
    688   1.1        mw 	| d1:  chipmem-size
    689  1.16    chopps 	| d3:  Amiga specific flags
    690  1.12    chopps 	| d4:  E clock frequency
    691   1.5        mw 	| d5:  AttnFlags (cpuid)
    692   1.3        mw 	| d7:  boothowto
    693   1.8    chopps 	| a4:  esym location
    694  1.17       jtc 	| a2:  Inhibit sync flags
    695  1.10    chopps 	| All other registers zeroed for possible future requirements.
    696   1.1        mw 
    697  1.20        is 	lea	pc@(_startit),sp	| make sure we have a good stack ***
    698  1.20        is 
    699   1.1        mw 	movel	a3@(4),a1		| loaded kernel
    700   1.1        mw 	movel	a3@(8),d2		| length of loaded kernel
    701  1.14    chopps |	movel	a3@(12),sp		| entry point in stack pointer
    702  1.20        is 	movel	a3@(12),a6		| push entry point		***
    703   1.1        mw 	movel	a3@(16),a0		| fastmem-start
    704   1.1        mw 	movel	a3@(20),d0		| fastmem-size
    705   1.1        mw 	movel	a3@(24),d1		| chipmem-size
    706   1.3        mw 	movel	a3@(28),d7		| boothowto
    707   1.8    chopps 	movel	a3@(32),a4		| esym
    708  1.10    chopps 	movel	a3@(36),d5		| cpuid
    709  1.12    chopps 	movel	a3@(40),d4		| E clock frequency
    710  1.16    chopps 	movel	a3@(44),d3		| Amiga flags
    711  1.17       jtc 	movel	a3@(48),a2		| Inhibit sync flags
    712  1.19    mhitch 	movel	a3@(52),d6		| Load to fastmem flag
    713   1.8    chopps 	subl	a5,a5			| target, load to 0
    714   1.1        mw 
    715  1.20        is 	cmpb	#0x7D,a3@(36)		| is it DraCo?
    716  1.20        is 	beq	nott			| yes, switch off MMU later
    717  1.20        is 
    718  1.20        is 					| no, it is an Amiga:
    719  1.20        is 
    720  1.20        is |	movew	#0xf00,0xdff180		|red
    721  1.20        is |	moveb	#0,0x200003c8
    722  1.20        is |	moveb	#63,0x200003c9
    723  1.20        is |	moveb	#0,0x200003c9
    724  1.20        is |	moveb	#0,0x200003c9
    725  1.20        is 
    726  1.20        is 	movew	#(1<<9),0xdff096	| disable DMA on Amigas.
    727  1.20        is 
    728  1.20        is | ------ mmu off start -----
    729  1.20        is 
    730  1.20        is 	btst	#3,d5			| AFB_68040,SysBase->AttnFlags
    731   1.5        mw 	beq	not040
    732   1.5        mw 
    733  1.20        is | Turn off 68040/060 MMU
    734   1.5        mw 
    735  1.20        is 	subl	a3,a3
    736  1.20        is 	.word 0x4e7b,0xb003		| movec a3,tc
    737  1.20        is 	.word 0x4e7b,0xb806		| movec a3,urp
    738  1.20        is 	.word 0x4e7b,0xb807		| movec a3,srp
    739  1.20        is 	.word 0x4e7b,0xb004		| movec a3,itt0
    740  1.20        is 	.word 0x4e7b,0xb005		| movec a3,itt1
    741  1.20        is 	.word 0x4e7b,0xb006		| movec a3,dtt0
    742  1.20        is 	.word 0x4e7b,0xb007		| movec a3,dtt1
    743   1.5        mw 	bra	nott
    744   1.5        mw 
    745   1.5        mw not040:
    746  1.20        is 	lea	pc@(zero),a3
    747   1.1        mw 	pmove	a3@,tc			| Turn off MMU
    748  1.20        is 	lea	pc@(nullrp),a3
    749   1.1        mw 	pmove	a3@,crp			| Turn off MMU some more
    750   1.1        mw 	pmove	a3@,srp			| Really, really, turn off MMU
    751   1.1        mw 
    752   1.1        mw | Turn off 68030 TT registers
    753   1.1        mw 
    754  1.20        is 	btst	#2,d5			| AFB_68030,SysBase->AttnFlags
    755   1.1        mw 	beq	nott			| Skip TT registers if not 68030
    756  1.20        is 	lea	pc@(zero),a3
    757   1.1        mw 	.word 0xf013,0x0800		| pmove a3@,tt0 (gas only knows about 68851 ops..)
    758   1.1        mw 	.word 0xf013,0x0c00		| pmove a3@,tt1 (gas only knows about 68851 ops..)
    759   1.1        mw 
    760   1.1        mw nott:
    761  1.20        is | ---- mmu off end ----
    762  1.20        is |	movew	#0xf60,0xdff180		| orange
    763  1.20        is |	moveb	#0,0x200003c8
    764  1.20        is |	moveb	#63,0x200003c9
    765  1.20        is |	moveb	#24,0x200003c9
    766  1.20        is |	moveb	#0,0x200003c9
    767   1.1        mw 
    768  1.20        is | ---- copy kernel start ----
    769   1.1        mw 
    770  1.19    mhitch 	tstl	d6			| Can we load to fastmem?
    771  1.19    mhitch 	beq	L0			| No, leave destination at 0
    772  1.19    mhitch 	movl	a0,a5			| Move to start of fastmem chunk
    773  1.20        is 	addl	a0,a6			| relocate kernel entry point
    774   1.1        mw L0:
    775  1.19    mhitch 	movl	a1@+,a5@+
    776  1.19    mhitch 	subl	#4,d2
    777   1.1        mw 	bcc	L0
    778   1.1        mw 
    779  1.20        is 	lea	pc@(ckend:w),a1
    780  1.20        is 	movl	a5,sp@-
    781  1.20        is 	movl	#_startit_end - ckend,d2
    782  1.20        is L2:
    783  1.20        is 	movl	a1@+,a5@+
    784  1.20        is 	subl	#4,d2
    785  1.20        is 	bcc	L2
    786  1.20        is 
    787  1.20        is 	btst	#3,d5
    788  1.20        is 	jeq	L1
    789  1.20        is 	.word	0xf4f8
    790  1.20        is L1:	movql	#0,d2			| switch off cache to ensure we use
    791  1.20        is 	movec	d2,cacr			| valid kernel data
    792  1.20        is 
    793  1.20        is |	movew	#0xFF0,0xdff180		| yellow
    794  1.20        is |	moveb	#0,0x200003c8
    795  1.20        is |	moveb	#63,0x200003c9
    796  1.20        is |	moveb	#0,0x200003c9
    797  1.20        is |	moveb	#0,0x200003c9
    798  1.20        is 	rts
    799  1.20        is 
    800  1.21        is | ---- copy kernel end ----
    801  1.20        is 
    802  1.20        is ckend:
    803  1.20        is |	movew	#0x0ff,0xdff180		| petrol
    804  1.20        is |	moveb	#0,0x200003c8
    805  1.20        is |	moveb	#0,0x200003c9
    806  1.20        is |	moveb	#63,0x200003c9
    807  1.20        is |	moveb	#63,0x200003c9
    808  1.20        is 
    809  1.20        is 	movl	d5,d2
    810  1.20        is 	roll	#8,d2
    811  1.20        is 	cmpb	#0x7D,d2
    812  1.20        is 	jne	noDraCo
    813  1.20        is 
    814  1.20        is | DraCo: switch off MMU now:
    815  1.20        is 
    816  1.20        is 	subl	a3,a3
    817  1.20        is 	.word 0x4e7b,0xb003		| movec a3,tc
    818  1.20        is 	.word 0x4e7b,0xb806		| movec a3,urp
    819  1.20        is 	.word 0x4e7b,0xb807		| movec a3,srp
    820  1.20        is 	.word 0x4e7b,0xb004		| movec a3,itt0
    821  1.20        is 	.word 0x4e7b,0xb005		| movec a3,itt1
    822  1.20        is 	.word 0x4e7b,0xb006		| movec a3,dtt0
    823  1.20        is 	.word 0x4e7b,0xb007		| movec a3,dtt1
    824  1.20        is 
    825  1.20        is noDraCo:
    826   1.9    chopps 	moveq	#0,d2			| zero out unused registers
    827  1.14    chopps 	moveq	#0,d6			| (might make future compatibility
    828  1.14    chopps 	movel	d6,a1			|  would have known contents)
    829   1.9    chopps 	movel	d6,a3
    830   1.9    chopps 	movel	d6,a5
    831  1.20        is 	movel	a6,sp			| entry point into stack pointer
    832   1.9    chopps 	movel	d6,a6
    833  1.20        is 
    834  1.20        is |	movew	#0x0F0,0xdff180		| green
    835  1.20        is |	moveb	#0,0x200003c8
    836  1.20        is |	moveb	#0,0x200003c9
    837  1.20        is |	moveb	#63,0x200003c9
    838  1.20        is |	moveb	#0,0x200003c9
    839  1.20        is 
    840  1.20        is 	jmp	sp@			| jump to kernel entry point
    841   1.1        mw 
    842   1.1        mw 
    843   1.1        mw | A do-nothing MMU root pointer (includes the following long as well)
    844   1.1        mw 
    845   1.1        mw nullrp:	.long	0x7fff0001
    846   1.1        mw zero:	.long	0
    847   1.1        mw 
    848  1.19    mhitch _startit_end:
    849   1.1        mw 
    850   1.1        mw ");
    851   1.1        mw 
    852  1.12    chopps void
    853  1.12    chopps usage()
    854   1.6    chopps {
    855  1.19    mhitch 	fprintf(stderr, "usage: %s [-abhkpstADSVZ] [-c machine] [-m mem] [-n mode] [-I sync-inhibit] kernel\n",
    856  1.12    chopps 	    program_name);
    857  1.12    chopps 	exit(1);
    858   1.6    chopps }
    859   1.6    chopps 
    860  1.12    chopps 
    861  1.12    chopps void
    862  1.12    chopps verbose_usage()
    863  1.12    chopps {
    864  1.12    chopps 	fprintf(stderr, "
    865  1.12    chopps NAME
    866  1.12    chopps \t%s - loads NetBSD from amiga dos.
    867  1.12    chopps SYNOPSIS
    868  1.19    mhitch \t%s [-abhkpstADSVZ] [-c machine] [-m mem] [-n flags] [-I sync-inhibit] kernel
    869  1.12    chopps OPTIONS
    870  1.12    chopps \t-a  Boot up to multiuser mode.
    871  1.17       jtc \t-A  Use AGA display mode, if available.
    872  1.12    chopps \t-b  Ask for which root device.
    873  1.12    chopps \t    Its possible to have multiple roots and choose between them.
    874  1.20        is \t-c  Set machine type. [e.g 3000; use 32000+N for DraCo rev. N]
    875  1.17       jtc \t-D  Enter debugger
    876  1.16    chopps \t-h  This help message.
    877  1.17       jtc \t-I  Inhibit sync negotiation. Option value is bit-encoded targets.
    878  1.12    chopps \t-k  Reserve the first 4M of fast mem [Some one else
    879  1.12    chopps \t    is going to have to answer what that it is used for].
    880  1.12    chopps \t-m  Tweak amount of available memory, for finding minimum amount
    881  1.12    chopps \t    of memory required to run. Sets fastmem size to specified
    882  1.12    chopps \t    size in Kbytes.
    883  1.16    chopps \t-n  Enable multiple non-contiguous memory: value = 0 (disabled),
    884  1.16    chopps \t    1 (two segments), 2 (all avail segments), 3 (same as 2?).
    885  1.12    chopps \t-p  Use highest priority fastmem segement instead of the largest
    886  1.12    chopps \t    segment. The higher priority segment is usually faster
    887  1.12    chopps \t    (i.e. 32 bit memory), but some people have smaller amounts
    888  1.12    chopps \t    of 32 bit memory.
    889  1.25  jdolecek \t-q  Boot up in quiet mode.
    890  1.19    mhitch \t-s  Boot up in singleuser mode (default).
    891  1.17       jtc \t-S  Include kernel symbol table.
    892  1.12    chopps \t-t  This is a *test* option.  It prints out the memory
    893  1.12    chopps \t    list information being passed to the kernel and also
    894  1.12    chopps \t    exits without actually starting NetBSD.
    895  1.25  jdolecek \t-v  Boot up in verbose mode.
    896  1.12    chopps \t-V  Version of loadbsd program.
    897  1.19    mhitch \t-Z  Force kernel load to chipmem.
    898  1.12    chopps HISTORY
    899  1.12    chopps \tThis version supports Kernel version 720 +\n",
    900  1.12    chopps       program_name, program_name);
    901  1.12    chopps       exit(1);
    902  1.12    chopps }
    903  1.12    chopps 
    904  1.12    chopps 
    905  1.12    chopps void
    906  1.12    chopps _Vdomessage(doexit, eval, doerrno, fmt, args)
    907  1.12    chopps 	int doexit, doerrno, eval;
    908  1.12    chopps 	const char *fmt;
    909  1.12    chopps 	va_list args;
    910  1.12    chopps {
    911  1.12    chopps 	fprintf(stderr, "%s: ", program_name);
    912  1.12    chopps 	if (fmt) {
    913  1.12    chopps 		vfprintf(stderr, fmt, args);
    914  1.12    chopps 		fprintf(stderr, ": ");
    915  1.12    chopps 	}
    916  1.12    chopps 	if (doerrno && errno < sys_nerr) {
    917  1.12    chopps 		fprintf(stderr, "%s", strerror(errno));
    918  1.20        is #if 0
    919  1.12    chopps 		if (errno == EINTR || errno == 0) {
    920  1.12    chopps 			int  sigs;
    921  1.12    chopps 			sigpending((sigset_t *)&sigs);
    922  1.12    chopps 			printf("%x\n", sigs);
    923  1.12    chopps 		}
    924  1.20        is #endif
    925  1.12    chopps 	}
    926  1.12    chopps 	fprintf(stderr, "\n");
    927  1.20        is 	if (doexit) {
    928  1.20        is 		if (kp)
    929  1.20        is 			FreeMem(kp, ksize + ((char *)startit_end
    930  1.20        is 			    - (char *)startit) + 256);
    931  1.12    chopps 		exit(eval);
    932  1.20        is 	}
    933  1.12    chopps }
    934  1.12    chopps 
    935  1.12    chopps void
    936  1.12    chopps err(int eval, const char *fmt, ...)
    937  1.12    chopps {
    938  1.12    chopps 	va_list ap;
    939  1.12    chopps 	va_start(ap, fmt);
    940  1.12    chopps 	_Vdomessage(1, eval, 1, fmt, ap);
    941  1.12    chopps 	/*NOTREACHED*/
    942  1.12    chopps }
    943  1.12    chopps 
    944  1.12    chopps void
    945  1.12    chopps errx(int eval, const char *fmt, ...)
    946  1.12    chopps {
    947  1.12    chopps 	va_list ap;
    948  1.12    chopps 	va_start(ap, fmt);
    949  1.12    chopps 	_Vdomessage(1, eval, 0, fmt, ap);
    950  1.12    chopps 	/*NOTREACHED*/
    951  1.12    chopps }
    952  1.12    chopps 
    953  1.12    chopps void
    954  1.12    chopps warn(const char *fmt, ...)
    955  1.12    chopps {
    956  1.12    chopps 	va_list ap;
    957  1.12    chopps 	va_start(ap, fmt);
    958  1.12    chopps 	_Vdomessage(0, 0, 1, fmt, ap);
    959  1.12    chopps 	va_end(ap);
    960  1.12    chopps }
    961  1.12    chopps 
    962  1.12    chopps void
    963  1.12    chopps warnx(const char *fmt, ...)
    964   1.6    chopps {
    965  1.12    chopps 	va_list ap;
    966  1.12    chopps 	va_start(ap, fmt);
    967  1.12    chopps 	_Vdomessage(0, 0, 0, fmt, ap);
    968  1.12    chopps 	va_end(ap);
    969  1.20        is }
    970  1.20        is 
    971  1.20        is 
    972  1.20        is u_int
    973  1.20        is sleep(u_int n)
    974  1.20        is {
    975  1.20        is 	(void)TimeDelay(0L, n, 0L);
    976   1.6    chopps }
    977  1.21        is 
    978  1.21        is 
    979