xref: /netbsd-src/sys/arch/vax/boot/boot/boot.c (revision 89c5a767f8fc7a4633b2d409966e2becbb98ff92)
1 /*	$NetBSD: boot.c,v 1.4 1999/10/23 14:42:22 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 Xmain()
79 {
80 	int io, type, sluttid, askname, filindex = 0;
81 	int j, senast = 0, nu;
82 
83 	io=0;
84 	autoconf();
85 
86 	askname = howto & RB_ASKNAME;
87 	printf("\n\r>> NetBSD/vax boot [%s %s] <<\n", __DATE__, __TIME__);
88 	printf(">> Press any key to abort autoboot  ");
89 	sluttid = getsecs() + 5;
90 	for (;;) {
91 		nu = sluttid - getsecs();
92 		if (senast != nu)
93 			printf("%c%d", 8, nu);
94 		if (nu <= 0)
95 			break;
96 		senast = nu;
97 		if ((j = (testkey() & 0177))) {
98 			if (j != 10 && j != 13) {
99 				printf("\nPress '?' for help");
100 				askname = 1;
101 			}
102 			break;
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 		printf("> ");
127 		gets(line);
128 
129 		c = line;
130 		while (*c == ' ')
131 			c++;
132 
133 		if (c[0] == 0)
134 			continue;
135 
136 		if ((d = index(c, ' ')))
137 			*d++ = 0;
138 
139 		while (v->namn) {
140 			if (strcmp(v->namn, c) == 0)
141 				break;
142 			v++;
143 		}
144 		if (v->namn)
145 			(*v->func)(d);
146 		else
147 			printf("Unknown command: %s\n", c);
148 
149 	}
150 }
151 
152 void
153 halt()
154 {
155 	asm("halt");
156 }
157 
158 void
159 boot(arg)
160 	char *arg;
161 {
162 	char *fn = "netbsd";
163 
164 	if (arg) {
165 		while (*arg == ' ')
166 			arg++;
167 
168 		if (*arg != '-') {
169 			fn = arg;
170 			if ((arg = index(arg, ' '))) {
171 				*arg++ = 0;
172 				while (*arg == ' ')
173 					arg++;
174 			} else
175 				goto load;
176 		}
177 		if (*arg != '-') {
178 fail:			printf("usage: boot [filename] [-asd]\n");
179 			return;
180 		}
181 
182 		while (*++arg) {
183 			if (*arg == 'a')
184 				howto |= RB_ASKNAME;
185 			else if (*arg == 'd')
186 				howto |= RB_KDB;
187 			else if (*arg == 's')
188 				howto |= RB_SINGLE;
189 			else
190 				goto fail;
191 		}
192 	}
193 load:	exec(fn, 0, 0);
194 	printf("Boot failed: %s\n", strerror(errno));
195 }
196 
197 /* 750 Patchable Control Store magic */
198 
199 #include "../include/mtpr.h"
200 #include "../include/cpu.h"
201 #include "../include/sid.h"
202 #define	PCS_BITCNT	0x2000		/* number of patchbits */
203 #define	PCS_MICRONUM	0x400		/* number of ucode locs */
204 #define	PCS_PATCHADDR	0xf00000	/* start addr of patchbits */
205 #define	PCS_PCSADDR	(PCS_PATCHADDR+0x8000)	/* start addr of pcs */
206 #define	PCS_PATCHBIT	(PCS_PATCHADDR+0xc000)	/* patchbits enable reg */
207 #define	PCS_ENABLE	0xfff00000	/* enable bits for pcs */
208 
209 #define	extzv(one, two, three,four)	\
210 ({			\
211 	asm __volatile (" extzv %0,%3,(%1),(%2)+"	\
212 			:			\
213 			: "g"(one),"g"(two),"g"(three),"g"(four));	\
214 })
215 
216 
217 loadpcs()
218 {
219 	static int pcsdone = 0;
220 	int mid = mfpr(PR_SID);
221 	int i, j, *ip, *jp;
222 	char pcs[100];
223 	char *cp;
224 
225 	if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone)
226 		return;
227 	printf("Updating 11/750 microcode: ");
228 	for (cp = line; *cp; cp++)
229 		if (*cp == ')' || *cp == ':')
230 			break;
231 	if (*cp) {
232 		bcopy(line, pcs, 99);
233 		pcs[99] = 0;
234 		i = cp - line + 1;
235 	} else
236 		i = 0;
237 	strcpy(pcs + i, "pcs750.bin");
238 	i = open(pcs, 0);
239 	if (i < 0) {
240 		printf("bad luck - missing pcs750.bin :-(\n");
241 		return;
242 	}
243 	/*
244 	 * We ask for more than we need to be sure we get only what we expect.
245 	 * After read:
246 	 *	locs 0 - 1023	packed patchbits
247 	 *	 1024 - 11264	packed microcode
248 	 */
249 	if (read(i, (char *)0, 23*512) != 22*512) {
250 		printf("Error reading %s\n", pcs);
251 		close(i);
252 		return;
253 	}
254 	close(i);
255 
256 	/*
257 	 * Enable patchbit loading and load the bits one at a time.
258 	 */
259 	*((int *)PCS_PATCHBIT) = 1;
260 	ip = (int *)PCS_PATCHADDR;
261 	jp = (int *)0;
262 	for (i=0; i < PCS_BITCNT; i++) {
263 		extzv(i,jp,ip,1);
264 	}
265 	*((int *)PCS_PATCHBIT) = 0;
266 
267 	/*
268 	 * Load PCS microcode 20 bits at a time.
269 	 */
270 	ip = (int *)PCS_PCSADDR;
271 	jp = (int *)1024;
272 	for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) {
273 		extzv(i,jp,ip,20);
274 	}
275 
276 	/*
277 	 * Enable PCS.
278 	 */
279 	i = *jp;		/* get 1st 20 bits of microcode again */
280 	i &= 0xfffff;
281 	i |= PCS_ENABLE;	/* reload these bits with PCS enable set */
282 	*((int *)PCS_PCSADDR) = i;
283 
284 	mid = mfpr(PR_SID);
285 	printf("new rev level=%d\n", V750UCODE(mid));
286 	pcsdone = 1;
287 }
288 
289 void
290 usage()
291 {
292 	struct vals *v = &val[0];
293 
294 	printf("Commands:\n");
295 	while (v->namn) {
296 		printf("%s\t%s\n", v->namn, v->info);
297 		v++;
298 	}
299 }
300