Home | History | Annotate | Line # | Download | only in mboot
mboot.c revision 1.1
      1 /*	$NetBSD: mboot.c,v 1.1 1999/07/04 04:38:54 minoura Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Minoura Makoto.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the NetBSD
     21  *	Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include <sys/types.h>
     40 #include <machine/disklabel.h>
     41 
     42 struct iocs_readcap {
     43 	unsigned long	block;
     44 	unsigned long	size;
     45 };
     46 static inline int
     47 IOCS_BITSNS (int row)
     48 {
     49 	register unsigned int reg_d0 __asm ("d0");
     50 
     51 	__asm __volatile ("movel %1,d1\n\t"
     52 			  "movel #0x04,%0\n\t"
     53 			  "trap #15"
     54 			  : "=d" (reg_d0)
     55 			  : "ri" ((int) row)
     56 			  : "d1");
     57 
     58 	return reg_d0;
     59 }
     60 static inline void
     61 IOCS_B_PRINT (const char *str)
     62 {
     63 	__asm __volatile ("moval %0,a1\n\t"
     64 			  "movel #0x21,d0\n\t"
     65 			  "trap #15\n\t"
     66 			  :
     67 			  : "a" ((int) str)
     68 			  : "a1", "d0");
     69 	return;
     70 }
     71 static inline int
     72 IOCS_S_READCAP (int id, struct iocs_readcap *cap)
     73 {
     74 	register int reg_d0 __asm ("d0");
     75 
     76 	__asm __volatile ("moveml d4,sp@-\n\t"
     77 			  "movel %2,d4\n\t"
     78 			  "moval %3,a1\n\t"
     79 			  "movel #0x25,d1\n\t"
     80 			  "movel #0xf5,d0\n\t"
     81 			  "trap #15\n\t"
     82 			  "moveml sp@+,d4"
     83 			  : "=d" (reg_d0), "=m" (*cap)
     84 			  : "ri" (id), "g" ((int) cap)
     85 			  : "d1", "a1");
     86 
     87 	return reg_d0;
     88 }
     89 static inline int
     90 IOCS_S_READEXT (int pos, int blk, int id, int size, void *buf)
     91 {
     92 	register int reg_d0 __asm ("d0");
     93 
     94 	__asm __volatile ("moveml d3-d5,sp@-\n\t"
     95 			  "movel %2,d2\n\t"
     96 			  "movel %3,d3\n\t"
     97 			  "movel %4,d4\n\t"
     98 			  "movel %5,d5\n\t"
     99 			  "moval %6,a1\n\t"
    100 			  "movel #0x26,d1\n\t"
    101 			  "movel #0xf5,d0\n\t"
    102 			  "trap #15\n\t"
    103 			  "moveml sp@+,d3-d5"
    104 			  : "=d" (reg_d0), "=m" (*(char*) buf)
    105 			  : "ri" (pos), "ri" (blk), "ri" (id), "ri" (size), "g" ((int) buf)
    106 			  : "d1", "d2", "a1");
    107 
    108 	return reg_d0;
    109 }
    110 
    111 #define PART_BOOTABLE	0
    112 #define PART_UNUSED	1
    113 #define PART_INUSE	2
    114 
    115 
    116 
    117 int
    118 bootmain(scsiid)
    119 	int scsiid;
    120 {
    121 	struct iocs_readcap cap;
    122 	int size;
    123 
    124 	if (IOCS_BITSNS(0) & 1)	/* ESC key */
    125 		return 0;
    126 
    127 	if (IOCS_S_READCAP(scsiid, &cap) < 0) {
    128 		IOCS_B_PRINT("Error in reading.\r\n");
    129 		return 0;
    130 	}
    131 	size = cap.size >> 9;
    132 
    133 	{
    134 		long *label = (void*) 0x3000;
    135 		if (IOCS_S_READEXT(0, 1, scsiid, size, label) < 0) {
    136 			IOCS_B_PRINT("Error in reading.\r\n");
    137 			return 0;
    138 		}
    139 		if (label[0] != 0x58363853 ||
    140 		    label[1] != 0x43534931) {
    141 			IOCS_B_PRINT("Invalid disk.\r\n");
    142 			return 0;
    143 		}
    144 	}
    145 
    146 	{
    147 		struct cpu_disklabel *label = (void*) 0x3000;
    148 		int i, firstinuse=-1;
    149 
    150 		if (IOCS_S_READEXT(2<<(2-size), size?2:1, scsiid, size, label) < 0) {
    151 			IOCS_B_PRINT("Error in reading.\r\n");
    152 			return 0;
    153 		}
    154 		if (*((long*) &label->dosparts[0].dp_typname) != 0x5836384b) {
    155 			IOCS_B_PRINT("Invalid disk.\r\n");
    156 			return 0;
    157 		}
    158 
    159 		for (i = 1; i < NDOSPART; i++) {
    160 			if (label->dosparts[i].dp_flag == PART_BOOTABLE)
    161 				break;
    162 			else if (label->dosparts[i].dp_flag == PART_INUSE)
    163 				firstinuse = i;
    164 		}
    165 		if (i >= NDOSPART && firstinuse >= 0)
    166 			i = firstinuse;
    167 		if (i < NDOSPART) {
    168 			unsigned int start = label->dosparts[i].dp_start;
    169 			if (IOCS_S_READEXT(start << (2-size),
    170 					   8>>size,
    171 					   scsiid,
    172 					   size,
    173 					   (void*) 0x2400) < 0) {
    174 				IOCS_B_PRINT ("Error in reading.\r\n");
    175 				return 0;
    176 			}
    177 			if (*((char*) 0x2400) != 0x60) {
    178 				IOCS_B_PRINT("Invalid disk.\r\n");
    179 				return 0;
    180 			}
    181 			asm volatile ("movl %0,d4\n\t"
    182 				      "movl %1,d2\n\t"
    183 				      "jsr 0x2400"
    184 				      :
    185 				      : "g" (scsiid), "g"(start)
    186 				      : "d4");
    187 			return 0;
    188 		}
    189 		IOCS_B_PRINT ("No bootable partition.\r\n");
    190 		return 0;
    191 	}
    192 
    193 	return 0;
    194 }
    195