Home | History | Annotate | Line # | Download | only in loadbsd
loadbsd.c revision 1.14
      1   1.7  chopps /*
      2  1.12  chopps  * Copyright (c) 1994 Michael L. Hitch
      3  1.12  chopps  * All rights reserved.
      4  1.12  chopps  *
      5  1.12  chopps  * Redistribution and use in source and binary forms, with or without
      6  1.12  chopps  * modification, are permitted provided that the following conditions
      7  1.12  chopps  * are met:
      8  1.12  chopps  * 1. Redistributions of source code must retain the above copyright
      9  1.12  chopps  *    notice, this list of conditions and the following disclaimer.
     10  1.12  chopps  * 2. Redistributions in binary form must reproduce the above copyright
     11  1.12  chopps  *    notice, this list of conditions and the following disclaimer in the
     12  1.12  chopps  *    documentation and/or other materials provided with the distribution.
     13  1.12  chopps  * 3. All advertising materials mentioning features or use of this software
     14  1.12  chopps  *    must display the following acknowledgement:
     15  1.12  chopps  *      This product includes software developed by Michael L. Hitch.
     16  1.12  chopps  * 4. The name of the author may not be used to endorse or promote products
     17  1.12  chopps  *    derived from this software without specific prior written permission
     18  1.12  chopps  *
     19  1.12  chopps  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20  1.12  chopps  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21  1.12  chopps  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  1.12  chopps  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  1.12  chopps  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24  1.12  chopps  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  1.12  chopps  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  1.12  chopps  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  1.12  chopps  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  1.12  chopps  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  1.12  chopps  *
     30  1.14  chopps  *	$Id: loadbsd.c,v 1.14 1994/06/29 13:13:11 chopps Exp $
     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.10  chopps  *	1.x	Kernel parameter passing 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.9  chopps  */
     97  1.14  chopps static const char _version[] = "$VER: LoadBSD 2.9 (26.6.94)";
     98   1.9  chopps 
     99  1.12  chopps /*
    100  1.12  chopps  * Kernel parameter passing version
    101  1.12  chopps  *	1:	first version of loadbsd
    102  1.12  chopps  *	2:	needs esym location passed in a4
    103  1.12  chopps  */
    104  1.12  chopps #define KERNEL_PARAMETER_VERSION	2
    105  1.10  chopps 
    106  1.12  chopps #define MAXMEMSEG	16
    107  1.12  chopps struct boot_memlist {
    108  1.12  chopps 	u_int	m_nseg; /* num_mem; */
    109  1.12  chopps 	struct boot_memseg {
    110  1.12  chopps 		u_int	ms_start;
    111  1.12  chopps 		u_int	ms_size;
    112  1.12  chopps 		u_short	ms_attrib;
    113  1.12  chopps 		short	ms_pri;
    114  1.12  chopps 	} m_seg[MAXMEMSEG];
    115  1.12  chopps };
    116  1.12  chopps struct boot_memlist memlist;
    117  1.12  chopps struct boot_memlist *kmemlist;
    118  1.12  chopps 
    119  1.12  chopps 
    120  1.12  chopps void get_mem_config __P((void **, u_long *, u_long *));
    121  1.12  chopps void get_cpuid __P((void));
    122  1.12  chopps void get_eclock __P((void));
    123  1.14  chopps void get_AGA __P((void));
    124  1.12  chopps void usage __P((void));
    125  1.12  chopps void verbose_usage __P((void));
    126  1.12  chopps void Version __P((void));
    127   1.5      mw 
    128  1.12  chopps extern struct ExecBase *SysBase;
    129   1.5      mw extern char *optarg;
    130   1.5      mw extern int optind;
    131   1.5      mw 
    132  1.12  chopps int k_flag;
    133  1.12  chopps int p_flag;
    134  1.12  chopps int t_flag;
    135  1.12  chopps int reqmemsz;
    136  1.12  chopps int S_flag;
    137  1.12  chopps u_long cpuid;
    138  1.12  chopps long eclock_freq;
    139  1.14  chopps long AGA_mode;
    140  1.12  chopps char *program_name;
    141  1.12  chopps char *kname;
    142  1.12  chopps struct ExpansionBase *ExpansionBase;
    143  1.12  chopps struct GfxBase *GfxBase;
    144   1.6  chopps 
    145   1.1      mw 
    146  1.10  chopps int
    147  1.12  chopps main(argc, argv)
    148  1.12  chopps 	int argc;
    149  1.12  chopps 	char **argv;
    150   1.1      mw {
    151  1.12  chopps 	struct exec e;
    152  1.12  chopps 	struct ConfigDev *cd, *kcd;
    153  1.12  chopps 	u_long fmemsz, cmemsz;
    154  1.12  chopps 	int fd, boothowto, ksize, textsz, stringsz, ncd, i, mem_ix, ch;
    155  1.12  chopps 	u_short *kvers;
    156  1.12  chopps 	int *nkcd;
    157  1.12  chopps 	u_char *kp;
    158  1.12  chopps 	void *fmem;
    159  1.12  chopps 	char *esym;
    160  1.12  chopps 
    161  1.12  chopps 	program_name = argv[0];
    162  1.12  chopps 	boothowto = RB_SINGLE;
    163  1.12  chopps 
    164  1.12  chopps 	if (argc < 2)
    165  1.12  chopps 		usage();
    166  1.12  chopps 	if ((GfxBase = (void *)OpenLibrary(GRAPHICSNAME, 0)) == NULL)
    167  1.12  chopps 		err(20, "can't open graphics library");
    168  1.12  chopps 	if ((ExpansionBase=(void *)OpenLibrary(EXPANSIONNAME, 0)) == NULL)
    169  1.12  chopps 		err(20, "can't open expansion library");
    170  1.12  chopps 
    171  1.14  chopps 	while ((ch = getopt(argc, argv, "aAbc:Dhkm:ptSV")) != EOF) {
    172  1.12  chopps 		switch (ch) {
    173  1.12  chopps 		case 'k':
    174  1.12  chopps 			k_flag = 1;
    175  1.12  chopps 			break;
    176  1.12  chopps 		case 'a':
    177  1.12  chopps 			boothowto &= ~(RB_SINGLE);
    178  1.12  chopps 			boothowto |= RB_AUTOBOOT;
    179  1.12  chopps 			break;
    180  1.12  chopps 		case 'b':
    181  1.12  chopps 			boothowto |= RB_ASKNAME;
    182  1.12  chopps 			break;
    183  1.12  chopps 		case 'p':
    184  1.12  chopps 			p_flag = 1;
    185  1.12  chopps 			break;
    186  1.12  chopps 		case 't':
    187  1.12  chopps 			t_flag = 1;
    188  1.12  chopps 			break;
    189  1.12  chopps 		case 'm':
    190  1.12  chopps 			reqmemsz = atoi(optarg) * 1024;
    191  1.12  chopps 			break;
    192  1.12  chopps 		case 'V':
    193  1.12  chopps 			fprintf(stderr,"%s\n",_version + 6);
    194  1.12  chopps 			break;
    195  1.12  chopps 		case 'S':
    196  1.12  chopps 			S_flag = 1;
    197  1.12  chopps 			break;
    198  1.12  chopps 		case 'D':
    199  1.12  chopps 			boothowto |= RB_KDB;
    200  1.12  chopps 			break;
    201  1.12  chopps 		case 'c':
    202  1.12  chopps 			cpuid = atoi(optarg) << 16;
    203  1.12  chopps 			break;
    204  1.14  chopps 		case 'A':
    205  1.14  chopps 			AGA_mode = 1;
    206  1.14  chopps 			break;
    207  1.12  chopps 		case 'h':
    208  1.12  chopps 			verbose_usage();
    209  1.12  chopps 		default:
    210  1.12  chopps 			usage();
    211  1.12  chopps 		}
    212  1.12  chopps 	}
    213  1.12  chopps 	argc -= optind;
    214  1.12  chopps 	argv += optind;
    215  1.12  chopps 
    216  1.12  chopps 	if (argc != 1)
    217  1.12  chopps 		usage();
    218  1.12  chopps 	kname = argv[0];
    219  1.12  chopps 
    220  1.12  chopps 	if ((fd = open(kname, 0)) < 0)
    221  1.12  chopps 		err(20, "open");
    222  1.12  chopps 	if (read(fd, &e, sizeof(e)) != sizeof(e))
    223  1.12  chopps 		err(20, "reading exec");
    224  1.12  chopps 	if (e.a_magic != NMAGIC)
    225  1.12  chopps 		err(20, "unknown binary");
    226  1.12  chopps 
    227  1.12  chopps 	for (cd = 0, ncd = 0; cd = FindConfigDev(cd, -1, -1); ncd++)
    228  1.12  chopps 		;
    229  1.12  chopps 	get_mem_config(&fmem, &fmemsz, &cmemsz);
    230  1.12  chopps 	get_cpuid();
    231  1.12  chopps 	get_eclock();
    232  1.14  chopps 	get_AGA();
    233  1.12  chopps 
    234  1.12  chopps 	textsz = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ);
    235  1.12  chopps 	esym = NULL;
    236  1.12  chopps 	ksize = textsz + e.a_data + e.a_bss + ncd * sizeof(*cd)
    237  1.12  chopps 	    + 4 + memlist.m_nseg * sizeof(struct boot_memseg) + 4;
    238  1.12  chopps 
    239  1.12  chopps 	/*
    240  1.12  chopps 	 * get symbol table size & string size
    241  1.12  chopps 	 * (should check kernel version to see if it will handle it)
    242  1.12  chopps 	 */
    243  1.12  chopps 	if (S_flag && e.a_syms) {
    244  1.12  chopps 		if (lseek(fd, e.a_text + e.a_data + e.a_syms, SEEK_CUR) <= 0
    245  1.12  chopps 		    || read(fd, &stringsz, 4) != 4
    246  1.12  chopps 		    || lseek(fd, sizeof(e), SEEK_SET) < 0)
    247  1.12  chopps 			err(20, "lseek for symbols");
    248  1.12  chopps 		ksize += e.a_syms + 4 + stringsz;
    249  1.12  chopps 	}
    250  1.12  chopps 
    251  1.12  chopps 	kp = (u_char *)malloc(ksize);
    252  1.12  chopps 	if (t_flag) {
    253  1.12  chopps 		for (i = 0; i < memlist.m_nseg; ++i) {
    254  1.12  chopps 			printf("mem segment %d: start=%08lx size=%08lx"
    255  1.12  chopps 			    " attribute=%04lx pri=%d\n",
    256  1.12  chopps 			    i + 1, memlist.m_seg[i].ms_start,
    257  1.12  chopps 			    memlist.m_seg[i].ms_size,
    258  1.12  chopps 			    memlist.m_seg[i].ms_attrib,
    259  1.12  chopps 			    memlist.m_seg[i].ms_pri);
    260  1.10  chopps 		}
    261  1.12  chopps 	}
    262  1.12  chopps 	if (kp == NULL)
    263  1.12  chopps 		err(20, "failed malloc %d\n", ksize);
    264  1.12  chopps 
    265  1.12  chopps 	if (read(fd, kp, e.a_text) != e.a_text
    266  1.12  chopps 	    || read(fd, kp + textsz, e.a_data) != e.a_data)
    267  1.12  chopps 		err(20, "unable to read kernel image\n");
    268  1.12  chopps 
    269  1.12  chopps 	if (k_flag) {
    270  1.12  chopps 		fmem += 4 * 1024 * 1024;
    271  1.12  chopps 		fmemsz -= 4 * 1024 * 1024;
    272  1.12  chopps 	}
    273   1.1      mw 
    274  1.12  chopps 	if (reqmemsz && reqmemsz <= fmemsz)
    275  1.12  chopps 		fmemsz = reqmemsz;
    276  1.12  chopps 	if (boothowto & RB_AUTOBOOT)
    277  1.12  chopps 		printf("Autobooting...");
    278  1.12  chopps 	if (boothowto & RB_ASKNAME)
    279  1.12  chopps 		printf("Askboot...");
    280  1.12  chopps 
    281  1.12  chopps 	printf("Using %d%c FASTMEM at 0x%x, %dM CHIPMEM\n",
    282  1.12  chopps 	    (fmemsz & 0xfffff) ? fmemsz >> 10 : fmemsz >> 20,
    283  1.12  chopps 	    (fmemsz & 0xfffff) ? 'K' : 'M', fmem, cmemsz >> 20);
    284  1.12  chopps 	kvers = (u_short *)(kp + e.a_entry - 2);
    285  1.12  chopps 	if (*kvers > KERNEL_PARAMETER_VERSION && *kvers != 0x4e73)
    286  1.12  chopps 		err(20, "newer loadbsd required: %d\n", *kvers);
    287  1.12  chopps 	if ((cpuid & AFB_68020) == 0)
    288  1.12  chopps 		err(20, "cpu not supported");
    289  1.12  chopps 	/*
    290  1.12  chopps 	 * give them a chance to read the information...
    291  1.12  chopps 	 */
    292  1.12  chopps 	sleep(2);
    293  1.12  chopps 
    294  1.12  chopps 	bzero(kp + textsz + e.a_data, e.a_bss);
    295  1.12  chopps 	/*
    296  1.12  chopps 	 * If symbols wanted (and kernel can handle them),
    297  1.12  chopps 	 * load symbol table & strings and set esym to end.
    298  1.12  chopps 	 */
    299  1.12  chopps 	nkcd = (int *)(kp + textsz + e.a_data + e.a_bss);
    300  1.12  chopps 	if (*kvers != 0x4e73 && *kvers > 1 && S_flag && e.a_syms) {
    301  1.12  chopps 		*nkcd++ = e.a_syms;
    302  1.12  chopps 		read(fd, (char *)nkcd, e.a_syms);
    303  1.12  chopps 		nkcd = (int *)((char *)nkcd + e.a_syms);
    304  1.12  chopps 		read(fd, (char *)nkcd, stringsz);
    305  1.12  chopps 		    nkcd = (int*)((char *)nkcd + stringsz);
    306  1.12  chopps 		    esym = (char *)(textsz + e.a_data + e.a_bss
    307  1.12  chopps 		    + e.a_syms + 4 + stringsz);
    308  1.10  chopps 	}
    309  1.12  chopps 	*nkcd = ncd;
    310  1.12  chopps 
    311  1.12  chopps 	kcd = (struct ConfigDev *)(nkcd + 1);
    312  1.12  chopps 	while(cd = FindConfigDev(cd, -1, -1))
    313  1.12  chopps 		*kcd++ = *cd;
    314  1.12  chopps 
    315  1.12  chopps 	kmemlist = (struct boot_memlist *)kcd;
    316  1.12  chopps 	kmemlist->m_nseg = memlist.m_nseg;
    317  1.12  chopps 	for (mem_ix = 0; mem_ix < memlist.m_nseg; mem_ix++)
    318  1.12  chopps 		kmemlist->m_seg[mem_ix] = memlist.m_seg[mem_ix];
    319  1.12  chopps 	/*
    320  1.12  chopps 	 * if test option set, done
    321  1.12  chopps 	 */
    322  1.12  chopps 	if (t_flag)
    323  1.12  chopps 		exit(0);
    324  1.12  chopps 
    325  1.12  chopps 	/*
    326  1.12  chopps 	 * XXX AGA startup - may need more
    327  1.12  chopps 	 */
    328  1.14  chopps 	LoadView(NULL);		/* Don't do this if AGA_mode? */
    329  1.12  chopps 	startit(kp, ksize, e.a_entry, fmem, fmemsz, cmemsz, boothowto, esym,
    330  1.14  chopps 	    cpuid, eclock_freq, AGA_mode);
    331  1.12  chopps 	/*NOTREACHED*/
    332  1.12  chopps }
    333   1.1      mw 
    334   1.1      mw void
    335  1.12  chopps get_mem_config(fmem, fmemsz, cmemsz)
    336  1.12  chopps 	void **fmem;
    337  1.12  chopps 	u_long *fmemsz, *cmemsz;
    338   1.1      mw {
    339  1.12  chopps 	struct MemHeader *mh, *nmh;
    340  1.12  chopps 	u_int segsz, seg, eseg, nmem;
    341  1.12  chopps 	char mempri;
    342  1.12  chopps 
    343  1.12  chopps 	nmem = 0;
    344  1.12  chopps 	mempri = -128;
    345  1.12  chopps 	*fmemsz = 0;
    346  1.12  chopps 	*cmemsz = 0;
    347  1.12  chopps 
    348  1.12  chopps 	/*
    349  1.12  chopps 	 * walk thru the exec memory list
    350  1.12  chopps 	 */
    351  1.12  chopps 	Forbid();
    352  1.12  chopps 	for (mh  = (void *) SysBase->MemList.lh_Head;
    353  1.12  chopps 	    nmh = (void *) mh->mh_Node.ln_Succ; mh = nmh, nmem++) {
    354  1.12  chopps 		memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
    355  1.12  chopps 		memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
    356  1.12  chopps 		seg = (u_int)mh->mh_Lower;
    357  1.12  chopps 		eseg = (u_int)mh->mh_Upper;
    358  1.12  chopps 		segsz = eseg - seg;
    359  1.12  chopps 		memlist.m_seg[nmem].ms_size = segsz;
    360  1.12  chopps 		memlist.m_seg[nmem].ms_start = seg;
    361  1.12  chopps 
    362  1.12  chopps 		if (mh->mh_Attributes & MEMF_CHIP) {
    363  1.12  chopps 			/*
    364  1.12  chopps 			 * there should hardly be more than one entry for
    365  1.12  chopps 			 * chip mem, but handle it the same nevertheless
    366  1.12  chopps 			 * cmem always starts at 0, so include vector area
    367  1.12  chopps 			 */
    368  1.12  chopps 			memlist.m_seg[nmem].ms_start = seg = 0;
    369  1.12  chopps 			/*
    370  1.12  chopps 			 * round to multiple of 512K
    371  1.12  chopps 			 */
    372  1.12  chopps 			segsz = (segsz + 512 * 1024 - 1) & -(512 * 1024);
    373  1.12  chopps 			memlist.m_seg[nmem].ms_size = segsz;
    374  1.12  chopps 			if (segsz > *cmemsz)
    375  1.12  chopps 				*cmemsz = segsz;
    376  1.12  chopps 			continue;
    377  1.12  chopps 		}
    378  1.12  chopps 		/*
    379  1.12  chopps 		 * some heuristics..
    380  1.12  chopps 		 */
    381  1.12  chopps 		seg &= -__LDPGSZ;
    382  1.12  chopps 		eseg = (eseg + __LDPGSZ - 1) & -__LDPGSZ;
    383  1.12  chopps 
    384  1.12  chopps 		/*
    385  1.12  chopps 		 * get the mem back stolen by incore kickstart on
    386  1.12  chopps 		 * A3000 with V36 bootrom.
    387  1.12  chopps 		 */
    388  1.12  chopps 		if (eseg == 0x07f80000)
    389  1.12  chopps 			eseg = 0x08000000;
    390  1.12  chopps 
    391  1.12  chopps 		/*
    392  1.12  chopps 		 * or by zkick on a A2000.
    393  1.12  chopps 		 */
    394  1.12  chopps 		if (seg == 0x280000 &&
    395  1.12  chopps 		    strcmp(mh->mh_Node.ln_Name, "zkick memory") == 0)
    396  1.12  chopps 			seg = 0x200000;
    397  1.12  chopps 
    398  1.12  chopps 		segsz = eseg - seg;
    399  1.12  chopps 		memlist.m_seg[nmem].ms_start = seg;
    400  1.12  chopps 		memlist.m_seg[nmem].ms_size = segsz;
    401  1.12  chopps 		/*
    402  1.12  chopps 		 *  If this segment is smaller than 2M,
    403  1.12  chopps 		 *  don't use it to load the kernel
    404  1.12  chopps 		 */
    405  1.12  chopps 		if (segsz < 2 * 1024 * 1024)
    406  1.12  chopps 			continue;
    407  1.12  chopps 		/*
    408  1.12  chopps 		 * if p_flag is set, select memory by priority
    409  1.12  chopps 		 * instead of size
    410  1.12  chopps 		 */
    411  1.12  chopps 		if ((!p_flag && segsz > *fmemsz) || (p_flag &&
    412  1.12  chopps 		   mempri <= mh->mh_Node.ln_Pri && segsz > *fmemsz)) {
    413  1.12  chopps 			*fmemsz = segsz;
    414  1.12  chopps 			*fmem = (void *)seg;
    415  1.12  chopps 			mempri = mh->mh_Node.ln_Pri;
    416  1.12  chopps 		}
    417   1.1      mw 	}
    418  1.12  chopps 	memlist.m_nseg = nmem;
    419  1.12  chopps 	Permit();
    420   1.1      mw }
    421   1.1      mw 
    422  1.10  chopps /*
    423  1.10  chopps  * Try to determine the machine ID by searching the resident module list
    424  1.10  chopps  * for modules only present on specific machines.  (Thanks, Bill!)
    425  1.10  chopps  */
    426  1.10  chopps void
    427  1.12  chopps get_cpuid()
    428  1.10  chopps {
    429  1.10  chopps 	u_long *rl;
    430  1.10  chopps 	struct Resident *rm;
    431  1.10  chopps 
    432  1.11  chopps 	cpuid |= SysBase->AttnFlags;	/* get FPU and CPU flags */
    433  1.11  chopps 	if (cpuid & 0xffff0000) {
    434  1.11  chopps 		switch (cpuid >> 16) {
    435  1.11  chopps 		case 500:
    436  1.11  chopps 		case 600:
    437  1.11  chopps 		case 1000:
    438  1.11  chopps 		case 1200:
    439  1.11  chopps 		case 2000:
    440  1.11  chopps 		case 3000:
    441  1.11  chopps 		case 4000:
    442  1.11  chopps 			return;
    443  1.11  chopps 		default:
    444  1.12  chopps 			printf("machine Amiga %d is not recognized\n",
    445  1.11  chopps 			    cpuid >> 16);
    446  1.12  chopps 			exit(1);
    447  1.11  chopps 		}
    448  1.11  chopps 	}
    449  1.12  chopps 	rl = (u_long *)SysBase->ResModules;
    450  1.10  chopps 	if (rl == NULL)
    451  1.10  chopps 		return;
    452  1.10  chopps 
    453  1.10  chopps 	while (*rl) {
    454  1.10  chopps 		rm = (struct Resident *) *rl;
    455  1.12  chopps 		if (strcmp(rm->rt_Name, "A4000 Bonus") == 0 ||
    456  1.12  chopps 		    strcmp(rm->rt_Name, "A1000 Bonus") == 0) {
    457  1.10  chopps 			cpuid |= 4000 << 16;
    458  1.10  chopps 			break;
    459  1.10  chopps 		}
    460  1.12  chopps 		if (strcmp(rm->rt_Name, "A3000 bonus") == 0 ||
    461  1.12  chopps 		    strcmp(rm->rt_Name, "A3000 Bonus") == 0) {
    462  1.10  chopps 			cpuid |= 3000 << 16;
    463  1.10  chopps 			break;
    464  1.10  chopps 		}
    465  1.12  chopps 		if (strcmp(rm->rt_Name, "card.resource") == 0) {
    466  1.10  chopps 			cpuid |= 1200 << 16;	/* or A600 :-) */
    467  1.10  chopps 			break;
    468  1.10  chopps 		}
    469  1.10  chopps 		++rl;
    470  1.10  chopps 	}
    471  1.12  chopps 	/*
    472  1.12  chopps 	 * Nothing found, it's probably an A2000 or A500
    473  1.12  chopps 	 */
    474  1.12  chopps 	if (*rl == 0)
    475  1.10  chopps 		cpuid |= 2000 << 16;
    476  1.10  chopps }
    477   1.1      mw 
    478  1.12  chopps void
    479  1.12  chopps get_eclock()
    480  1.12  chopps {
    481  1.12  chopps 	/* Fix for 1.3 startups? */
    482  1.14  chopps 	if (SysBase->LibNode.lib_Version > 36)
    483  1.14  chopps 		eclock_freq = SysBase->ex_EClockFrequency;
    484  1.14  chopps 	else
    485  1.14  chopps 		eclock_freq = (GfxBase->DisplayFlags & PAL) ?
    486  1.14  chopps 		    709379 : 715909;
    487  1.14  chopps }
    488  1.14  chopps 
    489  1.14  chopps void
    490  1.14  chopps get_AGA()
    491  1.14  chopps {
    492  1.14  chopps 	/*
    493  1.14  chopps 	 * Determine if an AGA mode is active
    494  1.14  chopps 	 */
    495  1.12  chopps }
    496  1.12  chopps 
    497   1.1      mw 
    498  1.12  chopps asm("
    499   1.1      mw 	.set	ABSEXECBASE,4
    500   1.1      mw 
    501   1.1      mw 	.text
    502   1.1      mw 	.globl	_startit
    503   1.1      mw 
    504   1.1      mw _startit:
    505   1.1      mw 	movel	sp,a3
    506   1.1      mw 	movel	4:w,a6
    507   1.1      mw 	lea	pc@(start_super-.+2),a5
    508   1.1      mw 	jmp	a6@(-0x1e)		| supervisor-call
    509   1.1      mw 
    510   1.1      mw start_super:
    511   1.1      mw 	movew	#0x2700,sr
    512   1.1      mw 
    513   1.1      mw 	| the BSD kernel wants values into the following registers:
    514   1.1      mw 	| a0:  fastmem-start
    515   1.1      mw 	| d0:  fastmem-size
    516   1.1      mw 	| d1:  chipmem-size
    517  1.14  chopps 	| d3:  AGA mode enable
    518  1.12  chopps 	| d4:  E clock frequency
    519   1.5      mw 	| d5:  AttnFlags (cpuid)
    520   1.3      mw 	| d7:  boothowto
    521   1.8  chopps 	| a4:  esym location
    522  1.10  chopps 	| All other registers zeroed for possible future requirements.
    523   1.1      mw 
    524  1.14  chopps 	lea	pc@(_startit-.+2),sp	| make sure we have a good stack ***
    525   1.1      mw 	movel	a3@(4),a1		| loaded kernel
    526   1.1      mw 	movel	a3@(8),d2		| length of loaded kernel
    527  1.14  chopps |	movel	a3@(12),sp		| entry point in stack pointer
    528  1.14  chopps 	movel	a3@(12),sp@-		| push entry point		***
    529   1.1      mw 	movel	a3@(16),a0		| fastmem-start
    530   1.1      mw 	movel	a3@(20),d0		| fastmem-size
    531   1.1      mw 	movel	a3@(24),d1		| chipmem-size
    532   1.3      mw 	movel	a3@(28),d7		| boothowto
    533   1.8  chopps 	movel	a3@(32),a4		| esym
    534  1.10  chopps 	movel	a3@(36),d5		| cpuid
    535  1.12  chopps 	movel	a3@(40),d4		| E clock frequency
    536  1.14  chopps 	movel	a3@(44),d3		| AGA mode enable
    537   1.8  chopps 	subl	a5,a5			| target, load to 0
    538   1.1      mw 
    539   1.5      mw 	btst	#3,(ABSEXECBASE)@(0x129) | AFB_68040,SysBase->AttnFlags
    540   1.5      mw 	beq	not040
    541   1.5      mw 
    542   1.5      mw | Turn off 68040 MMU
    543   1.5      mw 
    544   1.8  chopps 	.word 0x4e7b,0xd003		| movec a5,tc
    545   1.8  chopps 	.word 0x4e7b,0xd806		| movec a5,urp
    546   1.8  chopps 	.word 0x4e7b,0xd807		| movec a5,srp
    547   1.8  chopps 	.word 0x4e7b,0xd004		| movec a5,itt0
    548   1.8  chopps 	.word 0x4e7b,0xd005		| movec a5,itt1
    549   1.8  chopps 	.word 0x4e7b,0xd006		| movec a5,dtt0
    550   1.8  chopps 	.word 0x4e7b,0xd007		| movec a5,dtt1
    551   1.5      mw 	bra	nott
    552   1.5      mw 
    553   1.5      mw not040:
    554   1.1      mw 	lea	pc@(zero-.+2),a3
    555   1.1      mw 	pmove	a3@,tc			| Turn off MMU
    556   1.1      mw 	lea	pc@(nullrp-.+2),a3
    557   1.1      mw 	pmove	a3@,crp			| Turn off MMU some more
    558   1.1      mw 	pmove	a3@,srp			| Really, really, turn off MMU
    559   1.1      mw 
    560   1.1      mw | Turn off 68030 TT registers
    561   1.1      mw 
    562   1.1      mw 	btst	#2,(ABSEXECBASE)@(0x129) | AFB_68030,SysBase->AttnFlags
    563   1.1      mw 	beq	nott			| Skip TT registers if not 68030
    564   1.1      mw 	lea	pc@(zero-.+2),a3
    565   1.1      mw 	.word 0xf013,0x0800		| pmove a3@,tt0 (gas only knows about 68851 ops..)
    566   1.1      mw 	.word 0xf013,0x0c00		| pmove a3@,tt1 (gas only knows about 68851 ops..)
    567   1.1      mw 
    568   1.1      mw nott:
    569   1.1      mw 
    570   1.1      mw 	movew	#(1<<9),0xdff096	| disable DMA
    571   1.1      mw 
    572   1.1      mw L0:
    573   1.8  chopps 	moveb	a1@+,a5@+
    574   1.1      mw 	subl	#1,d2
    575   1.1      mw 	bcc	L0
    576   1.1      mw 
    577   1.1      mw 
    578   1.9  chopps 	moveq	#0,d2			| zero out unused registers
    579  1.14  chopps 	moveq	#0,d6			| (might make future compatibility
    580  1.14  chopps 	movel	d6,a1			|  would have known contents)
    581   1.9  chopps 	movel	d6,a2
    582   1.9  chopps 	movel	d6,a3
    583   1.9  chopps 	movel	d6,a5
    584   1.9  chopps 	movel	d6,a6
    585  1.14  chopps |	jmp	sp@			| jump to kernel entry point
    586  1.14  chopps 	rts				| enter kernel at address on stack ***
    587   1.1      mw 
    588   1.1      mw 
    589   1.1      mw | A do-nothing MMU root pointer (includes the following long as well)
    590   1.1      mw 
    591   1.1      mw nullrp:	.long	0x7fff0001
    592   1.1      mw zero:	.long	0
    593   1.1      mw 
    594   1.1      mw 
    595   1.1      mw ");
    596   1.1      mw 
    597  1.12  chopps void
    598  1.12  chopps usage()
    599   1.6  chopps {
    600  1.14  chopps 	fprintf(stderr, "usage: %s [-abkptADSV] [-c machine] [-m mem] kernel\n",
    601  1.12  chopps 	    program_name);
    602  1.12  chopps 	exit(1);
    603   1.6  chopps }
    604   1.6  chopps 
    605  1.12  chopps 
    606  1.12  chopps void
    607  1.12  chopps verbose_usage()
    608  1.12  chopps {
    609  1.12  chopps 	fprintf(stderr, "
    610  1.12  chopps NAME
    611  1.12  chopps \t%s - loads NetBSD from amiga dos.
    612  1.12  chopps SYNOPSIS
    613  1.12  chopps \t%s [-abkptDSV] [-c machine] [-m mem] kernel
    614  1.12  chopps OPTIONS
    615  1.12  chopps \t-a  Boot up to multiuser mode.
    616  1.12  chopps \t-b  Ask for which root device.
    617  1.12  chopps \t    Its possible to have multiple roots and choose between them.
    618  1.12  chopps \t-c  Set machine type. [e.g 3000]
    619  1.12  chopps \t-k  Reserve the first 4M of fast mem [Some one else
    620  1.12  chopps \t    is going to have to answer what that it is used for].
    621  1.12  chopps \t-m  Tweak amount of available memory, for finding minimum amount
    622  1.12  chopps \t    of memory required to run. Sets fastmem size to specified
    623  1.12  chopps \t    size in Kbytes.
    624  1.12  chopps \t-p  Use highest priority fastmem segement instead of the largest
    625  1.12  chopps \t    segment. The higher priority segment is usually faster
    626  1.12  chopps \t    (i.e. 32 bit memory), but some people have smaller amounts
    627  1.12  chopps \t    of 32 bit memory.
    628  1.12  chopps \t-t  This is a *test* option.  It prints out the memory
    629  1.12  chopps \t    list information being passed to the kernel and also
    630  1.12  chopps \t    exits without actually starting NetBSD.
    631  1.12  chopps \t-S  Include kernel symbol table.
    632  1.12  chopps \t-D  Enter debugger
    633  1.14  chopps \t-A  Use AGA display mode, if available.
    634  1.12  chopps \t-V  Version of loadbsd program.
    635  1.12  chopps HISTORY
    636  1.12  chopps \tThis version supports Kernel version 720 +\n",
    637  1.12  chopps       program_name, program_name);
    638  1.12  chopps       exit(1);
    639  1.12  chopps }
    640  1.12  chopps 
    641  1.12  chopps 
    642  1.12  chopps void
    643  1.12  chopps _Vdomessage(doexit, eval, doerrno, fmt, args)
    644  1.12  chopps 	int doexit, doerrno, eval;
    645  1.12  chopps 	const char *fmt;
    646  1.12  chopps 	va_list args;
    647  1.12  chopps {
    648  1.12  chopps 	fprintf(stderr, "%s: ", program_name);
    649  1.12  chopps 	if (fmt) {
    650  1.12  chopps 		vfprintf(stderr, fmt, args);
    651  1.12  chopps 		fprintf(stderr, ": ");
    652  1.12  chopps 	}
    653  1.12  chopps 	if (doerrno && errno < sys_nerr) {
    654  1.12  chopps 		fprintf(stderr, "%s", strerror(errno));
    655  1.12  chopps 		if (errno == EINTR || errno == 0) {
    656  1.12  chopps 			int  sigs;
    657  1.12  chopps 			sigpending((sigset_t *)&sigs);
    658  1.12  chopps 			printf("%x\n", sigs);
    659  1.12  chopps 		}
    660  1.12  chopps 	}
    661  1.12  chopps 	fprintf(stderr, "\n");
    662  1.12  chopps 	if (doexit)
    663  1.12  chopps 		exit(eval);
    664  1.12  chopps }
    665  1.12  chopps 
    666  1.12  chopps void
    667  1.12  chopps err(int eval, const char *fmt, ...)
    668  1.12  chopps {
    669  1.12  chopps 	va_list ap;
    670  1.12  chopps 	va_start(ap, fmt);
    671  1.12  chopps 	_Vdomessage(1, eval, 1, fmt, ap);
    672  1.12  chopps 	/*NOTREACHED*/
    673  1.12  chopps }
    674  1.12  chopps 
    675  1.12  chopps void
    676  1.12  chopps errx(int eval, const char *fmt, ...)
    677  1.12  chopps {
    678  1.12  chopps 	va_list ap;
    679  1.12  chopps 	va_start(ap, fmt);
    680  1.12  chopps 	_Vdomessage(1, eval, 0, fmt, ap);
    681  1.12  chopps 	/*NOTREACHED*/
    682  1.12  chopps }
    683  1.12  chopps 
    684  1.12  chopps void
    685  1.12  chopps warn(const char *fmt, ...)
    686  1.12  chopps {
    687  1.12  chopps 	va_list ap;
    688  1.12  chopps 	va_start(ap, fmt);
    689  1.12  chopps 	_Vdomessage(0, 0, 1, fmt, ap);
    690  1.12  chopps 	va_end(ap);
    691  1.12  chopps }
    692  1.12  chopps 
    693  1.12  chopps void
    694  1.12  chopps warnx(const char *fmt, ...)
    695   1.6  chopps {
    696  1.12  chopps 	va_list ap;
    697  1.12  chopps 	va_start(ap, fmt);
    698  1.12  chopps 	_Vdomessage(0, 0, 0, fmt, ap);
    699  1.12  chopps 	va_end(ap);
    700   1.6  chopps }
    701