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