xref: /openbsd-src/sys/arch/loongson/stand/boot/machdep.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: machdep.c,v 1.8 2014/07/13 09:26:08 jasper Exp $	*/
2 
3 /*
4  * Copyright (c) 2010 Miodrag Vallat.
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * Copyright (c) 1998-2004 Michael Shalayeff
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
35  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
41  * THE POSSIBILITY OF SUCH DAMAGE.
42  */
43 
44 #include <sys/param.h>
45 #include <lib/libkern/libkern.h>
46 #include "libsa.h"
47 #include <machine/cpu.h>
48 #include <machine/pmon.h>
49 #include <stand/boot/cmd.h>
50 
51 void	gdium_abort(void);
52 int	is_gdium;
53 int	boot_rd;
54 
55 extern int bootprompt;
56 
57 /*
58  * Console
59  */
60 
61 int
62 cnspeed(dev_t dev, int sp)
63 {
64 	return CONSPEED;
65 }
66 
67 char *
68 ttyname(int fd)
69 {
70 	return "pmon console";
71 }
72 
73 dev_t
74 ttydev(char *name)
75 {
76 	/* we do not support any other console than pmon */
77 	return NODEV;
78 }
79 
80 /*
81  * Configuration and device path aerobics
82  */
83 
84 /*
85  * Return the default boot device.
86  */
87 void
88 devboot(dev_t dev, char *path)
89 {
90 	const char *bootpath = NULL;
91 	size_t bootpathlen = 0;	/* gcc -Wall */
92 	const char *tmp;
93 	int i;
94 
95 	/*
96 	 * If we are booting the initrd image, things are easy...
97 	 */
98 
99 	if (dev != 0) {
100 		strlcpy(path, "rd0a", BOOTDEVLEN);
101 		return;
102 	}
103 
104 	/*
105 	 * First, try to figure where we have been loaded from; we'll assume
106 	 * the default device to load the kernel from is the same.
107 	 *
108 	 * We may have been loaded in three different ways:
109 	 * - automatic load from `al' environment variable (similar to a
110 	 *   `load' and `go' sequence).
111 	 * - manual `boot' command, with path on the commandline.
112 	 * - manual `load' and `go' commands, with no path on the commandline.
113 	 */
114 
115 	if (pmon_argc > 0) {
116 		tmp = (const char *)pmon_getarg(0);
117 		if (tmp[0] != 'g') {
118 			/* manual load */
119 			for (i = 1; i < pmon_argc; i++) {
120 				tmp = (const char *)pmon_getarg(i);
121 				if (tmp[0] != '-') {
122 					bootpath = tmp;
123 					break;
124 				}
125 			}
126 		} else {
127 			/* possible automatic load */
128 			bootpath = pmon_getenv("al");
129 		}
130 	}
131 
132 	/*
133 	 * If the bootblocks have been loaded from the network,
134 	 * use the default disk.
135 	 */
136 
137 	if (bootpath != NULL && strncmp(bootpath, "tftp://", 7) == 0)
138 		bootpath = NULL;
139 
140 	/*
141 	 * Now extract the device name from the bootpath.
142 	 */
143 
144 	if (bootpath != NULL) {
145 		tmp = strchr(bootpath, '@');
146 		if (tmp == NULL) {
147 			bootpath = NULL;
148 		} else {
149 			bootpath = tmp + 1;
150 			tmp = strchr(bootpath, '/');
151 			if (tmp == NULL) {
152 				bootpath = NULL;
153 			} else {
154 				bootpathlen = tmp - bootpath;
155 			}
156 		}
157 	}
158 
159 	if (bootpath != NULL && bootpathlen >= 3) {
160 		if (bootpathlen >= BOOTDEVLEN)
161 			bootpathlen = BOOTDEVLEN - 1;
162 		strncpy(path, bootpath, bootpathlen);
163 		path[bootpathlen] = '\0';
164 		/* only add a partition letter if there is none */
165 		if (bootpath[bootpathlen - 1] >= '0' &&
166 		    bootpath[bootpathlen - 1] <= '9')
167 			strlcat(path, "a", BOOTDEVLEN);
168 	} else {
169 		strlcpy(path, "wd0a", BOOTDEVLEN);
170 	}
171 }
172 
173 /*
174  * Ugly (lack of) clock routines
175  */
176 
177 time_t
178 getsecs()
179 {
180 	return 0;
181 }
182 
183 /*
184  * Initialization
185  */
186 
187 void
188 machdep()
189 {
190 	const char *envvar;
191 
192 	/*
193 	 * Since we can't have non-blocking input, we will try to
194 	 * autoload the kernel pointed to by the `bsd' environment
195 	 * variable, and fallback to interactive mode if the variable
196 	 * is empty or the load fails.
197 	 */
198 
199 	if (boot_rd == 0) {
200 		envvar = pmon_getenv("bsd");
201 		if (envvar != NULL) {
202 			bootprompt = 0;
203 			kernelfile = (char *)envvar;
204 		} else {
205 			if (is_gdium)
206 				gdium_abort();
207 		}
208 	}
209 }
210 
211 int
212 main()
213 {
214 	const char *envvar;
215 
216 	cninit();
217 
218 	/*
219 	 * Figure out whether we are running on a Gdium system, which
220 	 * has an horribly castrated PMON. If we do, the best we can do
221 	 * is boot an initrd image.
222 	 */
223 	envvar = pmon_getenv("Version");
224 	if (envvar != NULL && strncmp(envvar, "Gdium", 5) == 0)
225 		is_gdium = 1;
226 
227 	/*
228 	 * Check if we have a valid initrd loaded.
229 	 */
230 
231 	envvar = pmon_getenv("rd");
232 	if (envvar != NULL && *envvar != '\0')
233 		boot_rd = rd_isvalid();
234 
235 	if (boot_rd != 0)
236 		bootprompt = 0;
237 
238 	boot(boot_rd);
239 	return 0;
240 }
241 
242 void
243 gdium_abort()
244 {
245 	/* Here's a nickel, kid.  Get yourself a better firmware */
246 	printf("\n\nSorry, OpenBSD boot blocks do not work on Gdium, "
247 	    "because of dire firmware limitations.\n"
248 	    "Also, the firmware has reset the USB controller so you "
249 	    "will need to power cycle.\n"
250 	    "We would apologize for this inconvenience, but we have "
251 	    "no control about the firmware of your machine.\n\n");
252 	rd_invalidate();
253 	_rtt();
254 }
255