mboot.c revision 1.3 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