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