boot.c revision 1.2 1 /* $NetBSD: boot.c,v 1.2 1999/04/01 20:40:07 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 <a.out.h>
44
45 #include "vaxstand.h"
46
47 /*
48 * Boot program... arguments passed in r10 and r11 determine
49 * whether boot stops to ask for system name and which device
50 * boot comes from.
51 */
52
53 char line[100];
54 int devtype, bootdev, howto, debug;
55 extern unsigned opendev;
56 extern unsigned *bootregs;
57
58 void usage(), boot();
59
60 struct vals {
61 char *namn;
62 void (*func)();
63 char *info;
64 } val[] = {
65 {"?", usage, "Show this help menu"},
66 {"help", usage, "Same as '?'"},
67 {"boot", exec, "load and execute file"},
68 {0, 0},
69 };
70
71 char *filer[] = {
72 "netbsd",
73 "netbsd.gz",
74 "netbsd.old",
75 "gennetbsd",
76 0,
77 };
78
79 Xmain()
80 {
81 int io, type, sluttid, askname, filindex = 0;
82 volatile int i, j;
83
84 io=0;
85 autoconf();
86
87 askname = howto & RB_ASKNAME;
88 printf("\n\r>> NetBSD/vax boot [%s %s] <<\n", __DATE__, __TIME__);
89 printf(">> Press any key to abort autoboot ");
90 sluttid = getsecs() + 5;
91 for (;;) {
92 printf("%c%d", 8, sluttid - getsecs());
93 if (sluttid <= getsecs())
94 break;
95 if ((j = (testkey() & 0177))) {
96 if (j != 10 && j != 13) {
97 printf("\nPress '?' for help");
98 askname = 1;
99 }
100 break;
101 }
102 for (i = 10000;i; i--)/* Don't read the timer chip too often */
103 ;
104 }
105 printf("\n");
106
107 /* First try to autoboot */
108 if (askname == 0) {
109 type = (devtype >> B_TYPESHIFT) & B_TYPEMASK;
110 if ((unsigned)type < ndevs && devsw[type].dv_name)
111 while (filer[filindex]) {
112 errno = 0;
113 printf("> boot %s\n", filer[filindex]);
114 exec(filer[filindex++], 0, 0);
115 printf("boot failed: %s\n", strerror(errno));
116 if (testkey())
117 break;
118 }
119 }
120
121 /* If any key pressed, go to conversational boot */
122 for (;;) {
123 struct vals *v = &val[0];
124 char *c, *d;
125
126 start: printf("> ");
127 gets(line);
128 if (line[0] == 0)
129 continue;
130
131 if ((c = index(line, ' '))) {
132 *c++ = 0;
133 while (*c == ' ')
134 c++;
135 }
136
137 /* If *c != '-' then it is a filename */
138 if (c) {
139 if (*c == '-') {
140 d = c;
141 c = filer[0];
142 } else {
143 d = index(c, ' ');
144 if (d) {
145 *d++ = 0;
146 if (*d != '-')
147 goto fail;
148 }
149 }
150
151 while (*++d) {
152 if (*d == 'a')
153 howto |= RB_ASKNAME;
154 else if (*d == 'd')
155 howto |= RB_KDB;
156 else if (*d == 's')
157 howto |= RB_SINGLE;
158 #ifdef notyet
159 else if (*d == 'r')
160 rawread++;
161 #endif
162 else {
163 fail: printf("usage: boot [filename] [-asd]\n");
164 goto start;
165 }
166 }
167 } else
168 c = filer[0];
169 while (v->namn) {
170 if (strcmp(v->namn, line) == 0)
171 break;
172 v++;
173 }
174 errno = 0;
175 if (v->namn)
176 (*v->func)(c, 0, 0);
177 else
178 printf("Unknown command: %s %s\n", line, (c ? c : ""));
179 if (errno)
180 printf("Command failed: %s\n", strerror(errno));
181 }
182 }
183
184 /* 750 Patchable Control Store magic */
185
186 #include "../include/mtpr.h"
187 #include "../include/cpu.h"
188 #include "../include/sid.h"
189 #define PCS_BITCNT 0x2000 /* number of patchbits */
190 #define PCS_MICRONUM 0x400 /* number of ucode locs */
191 #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */
192 #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */
193 #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */
194 #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */
195
196 #define extzv(one, two, three,four) \
197 ({ \
198 asm __volatile (" extzv %0,%3,(%1),(%2)+" \
199 : \
200 : "g"(one),"g"(two),"g"(three),"g"(four)); \
201 })
202
203
204 loadpcs()
205 {
206 static int pcsdone = 0;
207 int mid = mfpr(PR_SID);
208 int i, j, *ip, *jp;
209 char pcs[100];
210 char *cp;
211
212 if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone)
213 return;
214 printf("Updating 11/750 microcode: ");
215 for (cp = line; *cp; cp++)
216 if (*cp == ')' || *cp == ':')
217 break;
218 if (*cp) {
219 bcopy(line, pcs, 99);
220 pcs[99] = 0;
221 i = cp - line + 1;
222 } else
223 i = 0;
224 strcpy(pcs + i, "pcs750.bin");
225 i = open(pcs, 0);
226 if (i < 0) {
227 printf("bad luck - missing pcs750.bin :-(\n");
228 return;
229 }
230 /*
231 * We ask for more than we need to be sure we get only what we expect.
232 * After read:
233 * locs 0 - 1023 packed patchbits
234 * 1024 - 11264 packed microcode
235 */
236 if (read(i, (char *)0, 23*512) != 22*512) {
237 printf("Error reading %s\n", pcs);
238 close(i);
239 return;
240 }
241 close(i);
242
243 /*
244 * Enable patchbit loading and load the bits one at a time.
245 */
246 *((int *)PCS_PATCHBIT) = 1;
247 ip = (int *)PCS_PATCHADDR;
248 jp = (int *)0;
249 for (i=0; i < PCS_BITCNT; i++) {
250 extzv(i,jp,ip,1);
251 }
252 *((int *)PCS_PATCHBIT) = 0;
253
254 /*
255 * Load PCS microcode 20 bits at a time.
256 */
257 ip = (int *)PCS_PCSADDR;
258 jp = (int *)1024;
259 for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) {
260 extzv(i,jp,ip,20);
261 }
262
263 /*
264 * Enable PCS.
265 */
266 i = *jp; /* get 1st 20 bits of microcode again */
267 i &= 0xfffff;
268 i |= PCS_ENABLE; /* reload these bits with PCS enable set */
269 *((int *)PCS_PCSADDR) = i;
270
271 mid = mfpr(PR_SID);
272 printf("new rev level=%d\n", V750UCODE(mid));
273 pcsdone = 1;
274 }
275
276 void
277 usage()
278 {
279 struct vals *v = &val[0];
280
281 printf("Commands:\n");
282 while (v->namn) {
283 printf("%s\t%s\n", v->namn, v->info);
284 v++;
285 }
286 }
287