xref: /netbsd/sys/arch/x68k/stand/mboot/mboot.c (revision bf9ec67e)
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