boot.c revision 1.5 1 /* $NetBSD: boot.c,v 1.5 2000/04/22 20:29:59 ragge Exp $ */
2 /*-
3 * Copyright (c) 1982, 1986 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)boot.c 7.15 (Berkeley) 5/4/91
35 */
36
37 #include "sys/param.h"
38 #include "sys/reboot.h"
39 #include "lib/libsa/stand.h"
40
41 #define V750UCODE(x) ((x>>8)&255)
42
43 #include "vaxstand.h"
44
45 /*
46 * Boot program... arguments passed in r10 and r11 determine
47 * whether boot stops to ask for system name and which device
48 * boot comes from.
49 */
50
51 char line[100];
52 int devtype, bootdev, howto, debug;
53 extern unsigned opendev;
54 extern unsigned *bootregs;
55
56 void usage(), boot(), halt();
57
58 struct vals {
59 char *namn;
60 void (*func)();
61 char *info;
62 } val[] = {
63 {"?", usage, "Show this help menu"},
64 {"help", usage, "Same as '?'"},
65 {"boot", boot, "Load and execute file"},
66 {"halt", halt, "Halts the system"},
67 {0, 0},
68 };
69
70 char *filer[] = {
71 "netbsd",
72 "netbsd.gz",
73 "netbsd.old",
74 "gennetbsd",
75 0,
76 };
77
78 int jbuf[10];
79 int sluttid, senast, skip;
80
81 Xmain()
82 {
83 int io, type, askname, filindex = 0;
84 int j, nu;
85
86 io = 0;
87 skip = 1;
88 autoconf();
89
90 askname = howto & RB_ASKNAME;
91 printf("\n\r>> NetBSD/vax boot [%s %s] <<\n", __DATE__, __TIME__);
92 printf(">> Press any key to abort autoboot ");
93 sluttid = getsecs() + 5;
94 senast = 0;
95 skip = 0;
96 setjmp(jbuf);
97 for (;;) {
98 nu = sluttid - getsecs();
99 if (senast != nu)
100 printf("%c%d", 8, nu);
101 if (nu <= 0)
102 break;
103 senast = nu;
104 if ((j = (testkey() & 0177))) {
105 skip = 1;
106 if (j != 10 && j != 13) {
107 printf("\nPress '?' for help");
108 askname = 1;
109 }
110 break;
111 }
112 }
113 skip = 1;
114 printf("\n");
115
116 /* First try to autoboot */
117 if (askname == 0) {
118 type = (devtype >> B_TYPESHIFT) & B_TYPEMASK;
119 if ((unsigned)type < ndevs && devsw[type].dv_name)
120 while (filer[filindex]) {
121 errno = 0;
122 printf("> boot %s\n", filer[filindex]);
123 exec(filer[filindex++], 0, 0);
124 printf("boot failed: %s\n", strerror(errno));
125 if (testkey())
126 break;
127 }
128 }
129
130 /* If any key pressed, go to conversational boot */
131 for (;;) {
132 struct vals *v = &val[0];
133 char *c, *d;
134
135 printf("> ");
136 gets(line);
137
138 c = line;
139 while (*c == ' ')
140 c++;
141
142 if (c[0] == 0)
143 continue;
144
145 if ((d = index(c, ' ')))
146 *d++ = 0;
147
148 while (v->namn) {
149 if (strcmp(v->namn, c) == 0)
150 break;
151 v++;
152 }
153 if (v->namn)
154 (*v->func)(d);
155 else
156 printf("Unknown command: %s\n", c);
157
158 }
159 }
160
161 void
162 halt()
163 {
164 asm("halt");
165 }
166
167 void
168 boot(arg)
169 char *arg;
170 {
171 char *fn = "netbsd";
172
173 if (arg) {
174 while (*arg == ' ')
175 arg++;
176
177 if (*arg != '-') {
178 fn = arg;
179 if ((arg = index(arg, ' '))) {
180 *arg++ = 0;
181 while (*arg == ' ')
182 arg++;
183 } else
184 goto load;
185 }
186 if (*arg != '-') {
187 fail: printf("usage: boot [filename] [-asd]\n");
188 return;
189 }
190
191 while (*++arg) {
192 if (*arg == 'a')
193 howto |= RB_ASKNAME;
194 else if (*arg == 'd')
195 howto |= RB_KDB;
196 else if (*arg == 's')
197 howto |= RB_SINGLE;
198 else
199 goto fail;
200 }
201 }
202 load: exec(fn, 0, 0);
203 printf("Boot failed: %s\n", strerror(errno));
204 }
205
206 /* 750 Patchable Control Store magic */
207
208 #include "../include/mtpr.h"
209 #include "../include/cpu.h"
210 #include "../include/sid.h"
211 #define PCS_BITCNT 0x2000 /* number of patchbits */
212 #define PCS_MICRONUM 0x400 /* number of ucode locs */
213 #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */
214 #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */
215 #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */
216 #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */
217
218 #define extzv(one, two, three,four) \
219 ({ \
220 asm __volatile (" extzv %0,%3,(%1),(%2)+" \
221 : \
222 : "g"(one),"g"(two),"g"(three),"g"(four)); \
223 })
224
225
226 loadpcs()
227 {
228 static int pcsdone = 0;
229 int mid = mfpr(PR_SID);
230 int i, j, *ip, *jp;
231 char pcs[100];
232 char *cp;
233
234 if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone)
235 return;
236 printf("Updating 11/750 microcode: ");
237 for (cp = line; *cp; cp++)
238 if (*cp == ')' || *cp == ':')
239 break;
240 if (*cp) {
241 bcopy(line, pcs, 99);
242 pcs[99] = 0;
243 i = cp - line + 1;
244 } else
245 i = 0;
246 strcpy(pcs + i, "pcs750.bin");
247 i = open(pcs, 0);
248 if (i < 0) {
249 printf("bad luck - missing pcs750.bin :-(\n");
250 return;
251 }
252 /*
253 * We ask for more than we need to be sure we get only what we expect.
254 * After read:
255 * locs 0 - 1023 packed patchbits
256 * 1024 - 11264 packed microcode
257 */
258 if (read(i, (char *)0, 23*512) != 22*512) {
259 printf("Error reading %s\n", pcs);
260 close(i);
261 return;
262 }
263 close(i);
264
265 /*
266 * Enable patchbit loading and load the bits one at a time.
267 */
268 *((int *)PCS_PATCHBIT) = 1;
269 ip = (int *)PCS_PATCHADDR;
270 jp = (int *)0;
271 for (i=0; i < PCS_BITCNT; i++) {
272 extzv(i,jp,ip,1);
273 }
274 *((int *)PCS_PATCHBIT) = 0;
275
276 /*
277 * Load PCS microcode 20 bits at a time.
278 */
279 ip = (int *)PCS_PCSADDR;
280 jp = (int *)1024;
281 for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) {
282 extzv(i,jp,ip,20);
283 }
284
285 /*
286 * Enable PCS.
287 */
288 i = *jp; /* get 1st 20 bits of microcode again */
289 i &= 0xfffff;
290 i |= PCS_ENABLE; /* reload these bits with PCS enable set */
291 *((int *)PCS_PCSADDR) = i;
292
293 mid = mfpr(PR_SID);
294 printf("new rev level=%d\n", V750UCODE(mid));
295 pcsdone = 1;
296 }
297
298 void
299 usage()
300 {
301 struct vals *v = &val[0];
302
303 printf("Commands:\n");
304 while (v->namn) {
305 printf("%s\t%s\n", v->namn, v->info);
306 v++;
307 }
308 }
309