1 /* $NetBSD: mboot.c,v 1.3 2001/06/12 16:57:28 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_READ (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 static inline int 112 IOCS_S_READEXT (int pos, int blk, int id, int size, void *buf) 113 { 114 register int reg_d0 __asm ("%d0"); 115 116 __asm __volatile ("moveml %%d3-%%d5,%%sp@-\n\t" 117 "movel %2,%%d2\n\t" 118 "movel %3,%%d3\n\t" 119 "movel %4,%%d4\n\t" 120 "movel %5,%%d5\n\t" 121 "moval %6,%%a1\n\t" 122 "movel #0x26,%%d1\n\t" 123 "movel #0xf5,%%d0\n\t" 124 "trap #15\n\t" 125 "moveml %%sp@+,%%d3-%%d5" 126 : "=d" (reg_d0), "=m" (*(char*) buf) 127 : "ri" (pos), "ri" (blk), "ri" (id), "ri" (size), "g" ((int) buf) 128 : "%d1", "%d2", "%a1"); 129 130 return reg_d0; 131 } 132 133 #define PART_BOOTABLE 0 134 #define PART_UNUSED 1 135 #define PART_INUSE 2 136 137 138 139 int 140 bootmain(scsiid) 141 int scsiid; 142 { 143 struct iocs_readcap cap; 144 int size; 145 146 if (IOCS_BITSNS(0) & 1) /* ESC key */ 147 return 0; 148 149 if (IOCS_S_READCAP(scsiid, &cap) < 0) { 150 IOCS_B_PRINT("Error in reading.\r\n"); 151 return 0; 152 } 153 size = cap.size >> 9; 154 155 { 156 long *label = (void*) 0x3000; 157 if (IOCS_S_READ(0, 1, scsiid, size, label) < 0) { 158 IOCS_B_PRINT("Error in reading.\r\n"); 159 return 0; 160 } 161 if (label[0] != 0x58363853 || 162 label[1] != 0x43534931) { 163 IOCS_B_PRINT("Invalid disk.\r\n"); 164 return 0; 165 } 166 } 167 168 { 169 struct cpu_disklabel *label = (void*) 0x3000; 170 int i, firstinuse=-1; 171 172 if (IOCS_S_READ(2<<(2-size), size?2:1, scsiid, size, label) < 0) { 173 IOCS_B_PRINT("Error in reading.\r\n"); 174 return 0; 175 } 176 if (*((long*) &label->dosparts[0].dp_typname) != 0x5836384b) { 177 IOCS_B_PRINT("Invalid disk.\r\n"); 178 return 0; 179 } 180 181 for (i = 1; i < NDOSPART; i++) { 182 if (label->dosparts[i].dp_flag == PART_BOOTABLE) 183 break; 184 else if (label->dosparts[i].dp_flag == PART_INUSE) 185 firstinuse = i; 186 } 187 if (i >= NDOSPART && firstinuse >= 0) 188 i = firstinuse; 189 if (i < NDOSPART) { 190 unsigned int start = label->dosparts[i].dp_start; 191 unsigned int start1 = start << (2-size); 192 int r; 193 if ((start1 & 0x1fffff) == 0x1fffff) 194 r = IOCS_S_READ(start1, 195 8>>size, 196 scsiid, 197 size, 198 (void*) 0x2400); 199 else 200 r = IOCS_S_READEXT(start1, 201 8>>size, 202 scsiid, 203 size, 204 (void*) 0x2400); 205 if (r < 0) { 206 IOCS_B_PRINT ("Error in reading.\r\n"); 207 return 0; 208 } 209 if (*((char*) 0x2400) != 0x60) { 210 IOCS_B_PRINT("Invalid disk.\r\n"); 211 return 0; 212 } 213 asm volatile ("movl %0,%%d4\n\t" 214 "movl %1,%%d2\n\t" 215 "jsr 0x2400" 216 : 217 : "g" (scsiid), "g"(start) 218 : "d4"); 219 return 0; 220 } 221 IOCS_B_PRINT ("No bootable partition.\r\n"); 222 return 0; 223 } 224 225 return 0; 226 } 227