xref: /openbsd-src/sys/arch/loongson/stand/boot/machdep.c (revision a4f11372d5ec16405c3947a49e9200b89358d82d)
1 /*	$OpenBSD: machdep.c,v 1.9 2023/02/23 19:48:22 miod 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  * Configuration and device path aerobics
59  */
60 
61 /*
62  * Return the default boot device.
63  */
64 void
devboot(dev_t dev,char * path)65 devboot(dev_t dev, char *path)
66 {
67 	const char *bootpath = NULL;
68 	size_t bootpathlen = 0;	/* gcc -Wall */
69 	const char *tmp;
70 	int i;
71 
72 	/*
73 	 * If we are booting the initrd image, things are easy...
74 	 */
75 
76 	if (dev != 0) {
77 		strlcpy(path, "rd0a", BOOTDEVLEN);
78 		return;
79 	}
80 
81 	/*
82 	 * First, try to figure where we have been loaded from; we'll assume
83 	 * the default device to load the kernel from is the same.
84 	 *
85 	 * We may have been loaded in three different ways:
86 	 * - automatic load from `al' environment variable (similar to a
87 	 *   `load' and `go' sequence).
88 	 * - manual `boot' command, with path on the commandline.
89 	 * - manual `load' and `go' commands, with no path on the commandline.
90 	 */
91 
92 	if (pmon_argc > 0) {
93 		tmp = (const char *)pmon_getarg(0);
94 		if (tmp[0] != 'g') {
95 			/* manual load */
96 			for (i = 1; i < pmon_argc; i++) {
97 				tmp = (const char *)pmon_getarg(i);
98 				if (tmp[0] != '-') {
99 					bootpath = tmp;
100 					break;
101 				}
102 			}
103 		} else {
104 			/* possible automatic load */
105 			bootpath = pmon_getenv("al");
106 		}
107 	}
108 
109 	/*
110 	 * If the bootblocks have been loaded from the network,
111 	 * use the default disk.
112 	 */
113 
114 	if (bootpath != NULL && strncmp(bootpath, "tftp://", 7) == 0)
115 		bootpath = NULL;
116 
117 	/*
118 	 * Now extract the device name from the bootpath.
119 	 */
120 
121 	if (bootpath != NULL) {
122 		tmp = strchr(bootpath, '@');
123 		if (tmp == NULL) {
124 			bootpath = NULL;
125 		} else {
126 			bootpath = tmp + 1;
127 			tmp = strchr(bootpath, '/');
128 			if (tmp == NULL) {
129 				bootpath = NULL;
130 			} else {
131 				bootpathlen = tmp - bootpath;
132 			}
133 		}
134 	}
135 
136 	if (bootpath != NULL && bootpathlen >= 3) {
137 		if (bootpathlen >= BOOTDEVLEN)
138 			bootpathlen = BOOTDEVLEN - 1;
139 		strncpy(path, bootpath, bootpathlen);
140 		path[bootpathlen] = '\0';
141 		/* only add a partition letter if there is none */
142 		if (bootpath[bootpathlen - 1] >= '0' &&
143 		    bootpath[bootpathlen - 1] <= '9')
144 			strlcat(path, "a", BOOTDEVLEN);
145 	} else {
146 		strlcpy(path, "wd0a", BOOTDEVLEN);
147 	}
148 }
149 
150 /*
151  * Ugly (lack of) clock routines
152  */
153 
154 time_t
getsecs()155 getsecs()
156 {
157 	return 0;
158 }
159 
160 /*
161  * Initialization
162  */
163 
164 void
machdep()165 machdep()
166 {
167 	const char *envvar;
168 
169 	/*
170 	 * Since we can't have non-blocking input, we will try to
171 	 * autoload the kernel pointed to by the `bsd' environment
172 	 * variable, and fallback to interactive mode if the variable
173 	 * is empty or the load fails.
174 	 */
175 
176 	if (boot_rd == 0) {
177 		envvar = pmon_getenv("bsd");
178 		if (envvar != NULL) {
179 			bootprompt = 0;
180 			kernelfile = (char *)envvar;
181 		} else {
182 			if (is_gdium)
183 				gdium_abort();
184 		}
185 	}
186 }
187 
188 int
main()189 main()
190 {
191 	const char *envvar;
192 
193 	cninit();
194 
195 	/*
196 	 * Figure out whether we are running on a Gdium system, which
197 	 * has an horribly castrated PMON. If we do, the best we can do
198 	 * is boot an initrd image.
199 	 */
200 	envvar = pmon_getenv("Version");
201 	if (envvar != NULL && strncmp(envvar, "Gdium", 5) == 0)
202 		is_gdium = 1;
203 
204 	/*
205 	 * Check if we have a valid initrd loaded.
206 	 */
207 
208 	envvar = pmon_getenv("rd");
209 	if (envvar != NULL && *envvar != '\0')
210 		boot_rd = rd_isvalid();
211 
212 	if (boot_rd != 0)
213 		bootprompt = 0;
214 
215 	boot(boot_rd);
216 	return 0;
217 }
218 
219 void
gdium_abort()220 gdium_abort()
221 {
222 	/* Here's a nickel, kid.  Get yourself a better firmware */
223 	printf("\n\nSorry, OpenBSD boot blocks do not work on Gdium, "
224 	    "because of dire firmware limitations.\n"
225 	    "Also, the firmware has reset the USB controller so you "
226 	    "will need to power cycle.\n"
227 	    "We would apologize for this inconvenience, but we have "
228 	    "no control about the firmware of your machine.\n\n");
229 	rd_invalidate();
230 	_rtt();
231 }
232