Home | History | Annotate | Line # | Download | only in xxboot
      1  1.9    isaki /*	$NetBSD: bootmain.c,v 1.9 2024/01/07 07:58:34 isaki Exp $	*/
      2  1.1  minoura 
      3  1.1  minoura /*-
      4  1.1  minoura  * Copyright (c) 1993, 1994 Takumi Nakamura.
      5  1.1  minoura  * Copyright (c) 1999, 2000 Itoh Yasufumi.
      6  1.1  minoura  * Copyright (c) 2001 Minoura Makoto.
      7  1.1  minoura  *
      8  1.1  minoura  * Redistribution and use in source and binary forms, with or without
      9  1.1  minoura  * modification, are permitted provided that the following conditions
     10  1.1  minoura  * are met:
     11  1.1  minoura  * 1. Redistributions of source code must retain the above copyright
     12  1.1  minoura  *    notice, this list of conditions and the following disclaimer.
     13  1.1  minoura  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  minoura  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  minoura  *    documentation and/or other materials provided with the distribution.
     16  1.1  minoura  * 3. All advertising materials mentioning features or use of this software
     17  1.1  minoura  *    must display the following acknowledgement:
     18  1.1  minoura  *	This product includes software developed by Takumi Nakamura.
     19  1.1  minoura  * 4. Neither the name of the University nor the names of its contributors
     20  1.1  minoura  *    may be used to endorse or promote products derived from this software
     21  1.1  minoura  *    without specific prior written permission.
     22  1.1  minoura  *
     23  1.1  minoura  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  1.1  minoura  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.1  minoura  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.1  minoura  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  1.1  minoura  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.1  minoura  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.1  minoura  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.1  minoura  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.1  minoura  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.1  minoura  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.1  minoura  * SUCH DAMAGE.
     34  1.1  minoura  */
     35  1.1  minoura 
     36  1.1  minoura #include <sys/param.h>
     37  1.1  minoura #include <sys/types.h>
     38  1.1  minoura #include <machine/bootinfo.h>
     39  1.8    isaki #include <machine/disklabel.h>
     40  1.1  minoura #include <lib/libsa/stand.h>
     41  1.1  minoura #include <lib/libsa/loadfile.h>
     42  1.1  minoura 
     43  1.6    isaki #include "xxboot.h"
     44  1.1  minoura #include "libx68k.h"
     45  1.1  minoura #include "iocs.h"
     46  1.1  minoura #include "exec_image.h"
     47  1.1  minoura 
     48  1.2  tsutsui #define EXSCSI_BDID	((void *)0x00ea0001)
     49  1.1  minoura 
     50  1.2  tsutsui static int get_scsi_host_adapter(char *);
     51  1.8    isaki int get_scsi_part(void);
     52  1.2  tsutsui void bootmain(void) __attribute__ ((__noreturn__));
     53  1.1  minoura 
     54  1.8    isaki #if defined(XXBOOT_DEBUG)
     55  1.8    isaki /* Print 'x' as 'width' digit hex number */
     56  1.8    isaki void
     57  1.8    isaki print_hex(unsigned int x, int width)
     58  1.8    isaki {
     59  1.8    isaki 
     60  1.8    isaki 	if (width > 0) {
     61  1.8    isaki 		print_hex(x >> 4, width - 1);
     62  1.8    isaki 		x &= 0x0F;
     63  1.8    isaki 		if (x > 9)
     64  1.8    isaki 			x += 7;
     65  1.8    isaki 		IOCS_B_PUTC((unsigned int) '0' + x);
     66  1.8    isaki 	}
     67  1.8    isaki }
     68  1.8    isaki #endif
     69  1.8    isaki 
     70  1.1  minoura /*
     71  1.1  minoura  * Check the type of SCSI interface
     72  1.1  minoura  */
     73  1.1  minoura static int
     74  1.2  tsutsui get_scsi_host_adapter(char *devstr)
     75  1.1  minoura {
     76  1.2  tsutsui 	uint8_t *bootrom;
     77  1.1  minoura 	int ha;
     78  1.1  minoura 
     79  1.4  tsutsui #ifdef XXBOOT_DEBUG
     80  1.2  tsutsui 	*(uint32_t *)(devstr +  0) = '/' << 24 | 's' << 16 | 'p' << 8 | 'c';
     81  1.4  tsutsui #if defined(CDBOOT)
     82  1.2  tsutsui 	*(uint32_t *)(devstr +  4) = '@' << 24 | '0' << 16 | '/' << 8 | 'c';
     83  1.4  tsutsui #else
     84  1.4  tsutsui 	*(uint32_t *)(devstr +  4) = '@' << 24 | '0' << 16 | '/' << 8 | 's';
     85  1.4  tsutsui #endif
     86  1.2  tsutsui 	*(uint32_t *)(devstr +  8) = 'd' << 24 | '@' << 16 | '0' << 8 | ',';
     87  1.2  tsutsui 	*(uint32_t *)(devstr + 12) = '0' << 24 | ':' << 16 | 'a' << 8 | '\0';
     88  1.4  tsutsui #endif
     89  1.1  minoura 
     90  1.2  tsutsui 	bootrom = (uint8_t *)(BOOT_INFO & 0x00ffffe0);
     91  1.1  minoura 	/*
     92  1.1  minoura 	 * bootrom+0x24	"SCSIIN" ... Internal SCSI (spc@0)
     93  1.1  minoura 	 *		"SCSIEX" ... External SCSI (spc@1 or mha@0)
     94  1.1  minoura 	 */
     95  1.2  tsutsui 	if (*(uint16_t *)(bootrom + 0x24 + 4) == 0x494e) {	/* "IN" */
     96  1.1  minoura 		ha = (X68K_BOOT_SCSIIF_SPC << 4) | 0;
     97  1.1  minoura 	} else if (badbaddr(EXSCSI_BDID)) {
     98  1.1  minoura 		ha = (X68K_BOOT_SCSIIF_MHA << 4) | 0;
     99  1.4  tsutsui #ifdef XXBOOT_DEBUG
    100  1.8    isaki 		*(uint32_t *)devstr =
    101  1.8    isaki 		    ('/' << 24) | ('m' << 16) | ('h' << 8) | 'a';
    102  1.4  tsutsui #endif
    103  1.1  minoura 	} else {
    104  1.1  minoura 		ha = (X68K_BOOT_SCSIIF_SPC << 4) | 1;
    105  1.4  tsutsui #ifdef XXBOOT_DEBUG
    106  1.1  minoura 		devstr[5] = '1';
    107  1.4  tsutsui #endif
    108  1.1  minoura 	}
    109  1.1  minoura 
    110  1.1  minoura 	return ha;
    111  1.1  minoura }
    112  1.1  minoura 
    113  1.8    isaki #define PARTTBL_TOP	(4)	/* sector pos of part info in 512byte/sector */
    114  1.8    isaki #define NPART		(15)	/* total number of Human68k partitions */
    115  1.8    isaki #define MAXPART		(6)
    116  1.8    isaki int
    117  1.8    isaki get_scsi_part(void)
    118  1.8    isaki {
    119  1.8    isaki 	union {
    120  1.8    isaki 		char pad[1024];
    121  1.8    isaki 		struct {
    122  1.8    isaki 			uint32_t magic;		/* 0x5836384b ("X68k") */
    123  1.8    isaki 			uint32_t parttotal;	/* total block# -1 */
    124  1.8    isaki 			uint32_t diskblocks;
    125  1.8    isaki 			uint32_t diskblocks2;	/* backup? */
    126  1.8    isaki 			struct dos_partition parttbl[NPART];
    127  1.8    isaki 		} __packed;
    128  1.8    isaki 	} partbuf;
    129  1.8    isaki 	int i;
    130  1.8    isaki 	int part_top;
    131  1.8    isaki 
    132  1.8    isaki 	/*
    133  1.8    isaki 	 * Read partition table.
    134  1.8    isaki 	 * The actual partition table size we want to read is 256 bytes but
    135  1.8    isaki 	 * raw_read() for SCSI requires bytelen a multiple of sector size
    136  1.8    isaki 	 * (SCSI_CAP.blocksize).  Human68k supports sector size only 256,
    137  1.8    isaki 	 * 512 and 1024 so that we always use 1024 bytes fixed length buffer.
    138  1.8    isaki 	 */
    139  1.8    isaki 	raw_read(PARTTBL_TOP, SCSI_CAP.blocksize, &partbuf);
    140  1.8    isaki 
    141  1.8    isaki 	if (partbuf.magic != 0x5836384b/*"X68k"*/) {
    142  1.8    isaki 		BOOT_ERROR("Bad Human68k partition table");
    143  1.8    isaki 		/* NOTREACHED */
    144  1.8    isaki 	}
    145  1.8    isaki 
    146  1.8    isaki 	/*
    147  1.8    isaki 	 * SCSI_PARTTOP is top sector # of this partition in sector size
    148  1.8    isaki 	 * of this device (normally 512 bytes/sector).
    149  1.8    isaki 	 * part_top is top block # of this partition in 1024 bytes/block.
    150  1.8    isaki 	 * Human68k partition table uses 1024 bytes/block unit.
    151  1.8    isaki 	 */
    152  1.8    isaki 	part_top = SCSI_PARTTOP >> (2 - SCSI_BLKLEN);
    153  1.8    isaki 	for (i = 0; i < MAXPART; i++) {
    154  1.8    isaki 		if ((uint32_t)partbuf.parttbl[i].dp_start == part_top)
    155  1.8    isaki 			goto found;
    156  1.8    isaki 	}
    157  1.8    isaki 	BOOT_ERROR("Can't find this partition?");
    158  1.8    isaki 	/* NOTREACHED */
    159  1.8    isaki found:
    160  1.8    isaki 	/* bsd disklabel's c: means whole disk.  Skip it */
    161  1.8    isaki 	if (i >= 2)
    162  1.8    isaki 		i++;
    163  1.8    isaki 	return i;
    164  1.8    isaki }
    165  1.8    isaki 
    166  1.1  minoura void
    167  1.1  minoura bootmain(void)
    168  1.1  minoura {
    169  1.8    isaki 	int bootdev, fd;
    170  1.1  minoura 	char bootdevstr[16];
    171  1.1  minoura 	u_long marks[MARK_MAX];
    172  1.1  minoura 
    173  1.4  tsutsui 	IOCS_B_PRINT(bootprog_name);
    174  1.4  tsutsui 	IOCS_B_PRINT(" rev.");
    175  1.4  tsutsui 	IOCS_B_PRINT(bootprog_rev);
    176  1.4  tsutsui 	IOCS_B_PRINT("\r\n");
    177  1.1  minoura 
    178  1.8    isaki #if defined(XXBOOT_DEBUG)
    179  1.8    isaki 	/* Print the initial registers */
    180  1.8    isaki 	int i;
    181  1.8    isaki 	for (i = 0; i < __arraycount(startregs); i++) {
    182  1.8    isaki 		print_hex(startregs[i], 8);
    183  1.8    isaki 		IOCS_B_PRINT((i & 7) == 7 ? "\r\n" : " ");
    184  1.8    isaki 	}
    185  1.8    isaki 	IOCS_B_PRINT("BOOT_INFO ");
    186  1.8    isaki 	print_hex(BOOT_INFO, 8);
    187  1.8    isaki 	IOCS_B_PRINT("\r\n");
    188  1.4  tsutsui #endif
    189  1.4  tsutsui 
    190  1.4  tsutsui 	if (BINF_ISFD(&BOOT_INFO)) {
    191  1.4  tsutsui 		/* floppy */
    192  1.8    isaki 		int minor;
    193  1.8    isaki 		/* fdNa for 1024 bytes/sector, fdNc for 512 bytes/sector */
    194  1.8    isaki 		minor = (FDSEC.minsec.N == 3) ? 0 : 2;
    195  1.8    isaki 		bootdev = X68K_MAKEBOOTDEV(X68K_MAJOR_FD, BOOT_INFO & 3, minor);
    196  1.4  tsutsui #ifdef XXBOOT_DEBUG
    197  1.4  tsutsui 		*(uint32_t *)bootdevstr =
    198  1.5    isaki 		    ('f' << 24) | ('d' << 16) | ('@' << 8) |
    199  1.5    isaki 		    ('0' + (BOOT_INFO & 3));
    200  1.8    isaki 		bootdevstr[4] = 'a' + minor;
    201  1.8    isaki 		bootdevstr[5] = '\0';
    202  1.4  tsutsui #endif
    203  1.4  tsutsui 	} else {
    204  1.4  tsutsui 		/* SCSI */
    205  1.8    isaki 		int major, ha, part;
    206  1.8    isaki 		ha = get_scsi_host_adapter(bootdevstr);
    207  1.8    isaki 		part = 0;
    208  1.8    isaki #if defined(CDBOOT)
    209  1.8    isaki 		major = X68K_MAJOR_CD;
    210  1.4  tsutsui #else
    211  1.8    isaki 		major = X68K_MAJOR_SD;
    212  1.8    isaki 		if (SCSI_PARTTOP != 0)
    213  1.8    isaki 			part = get_scsi_part();
    214  1.8    isaki #endif
    215  1.8    isaki 		bootdev = X68K_MAKESCSIBOOTDEV(major, ha >> 4, ha & 15,
    216  1.8    isaki 		    SCSI_ID & 7, 0, part);
    217  1.8    isaki #ifdef XXBOOT_DEBUG
    218  1.8    isaki 		bootdevstr[10] = '0' + (SCSI_ID & 7);
    219  1.8    isaki 		bootdevstr[14] = 'a' + part;
    220  1.4  tsutsui #endif
    221  1.8    isaki 	}
    222  1.4  tsutsui 
    223  1.4  tsutsui #ifdef XXBOOT_DEBUG
    224  1.4  tsutsui 	IOCS_B_PRINT("boot device: ");
    225  1.4  tsutsui 	IOCS_B_PRINT(bootdevstr);
    226  1.1  minoura #endif
    227  1.4  tsutsui 	IOCS_B_PRINT("\r\n");
    228  1.1  minoura 
    229  1.1  minoura 	marks[MARK_START] = BOOT_TEXTADDR;
    230  1.8    isaki 
    231  1.8    isaki #if defined(XXBOOT_USTARFS)
    232  1.8    isaki 	/* ustarfs requires mangled filename... */
    233  1.8    isaki 	fd = loadfile("USTAR.volsize.4540", marks,
    234  1.8    isaki 	    LOAD_TEXT|LOAD_DATA|LOAD_BSS);
    235  1.8    isaki #else
    236  1.8    isaki 	/* XXX what is x68k/boot? */
    237  1.1  minoura 	fd = loadfile("x68k/boot", marks, LOAD_TEXT|LOAD_DATA|LOAD_BSS);
    238  1.1  minoura 	if (fd < 0)
    239  1.1  minoura 		fd = loadfile("boot", marks, LOAD_TEXT|LOAD_DATA|LOAD_BSS);
    240  1.8    isaki #endif
    241  1.1  minoura 	if (fd >= 0) {
    242  1.1  minoura 		close(fd);
    243  1.1  minoura 		exec_image(BOOT_TEXTADDR, /* image loaded at */
    244  1.1  minoura 			   BOOT_TEXTADDR, /* image executed at */
    245  1.1  minoura 			   BOOT_TEXTADDR, /* XXX: entry point */
    246  1.9    isaki 			   0,		  /* XXX: image size */
    247  1.9    isaki 			   bootdev, 0);   /* arguments */
    248  1.1  minoura 	}
    249  1.1  minoura 	IOCS_B_PRINT("can't load the secondary bootstrap.");
    250  1.1  minoura 	exit(0);
    251  1.1  minoura }
    252  1.1  minoura 
    253  1.1  minoura int
    254  1.1  minoura devopen(struct open_file *f, const char *fname, char **file)
    255  1.1  minoura {
    256  1.2  tsutsui 
    257  1.3  tsutsui 	*file = __UNCONST(fname);
    258  1.7    isaki 	return DEV_OPEN()(f);
    259  1.1  minoura }
    260