xref: /csrg-svn/sys/vax/stand/boot.c (revision 33408)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)boot.c	7.6 (Berkeley) 01/28/88
7  */
8 
9 #include "param.h"
10 #include "inode.h"
11 #include "fs.h"
12 #include "vm.h"
13 #include "reboot.h"
14 
15 #include <a.out.h>
16 #include "saio.h"
17 
18 /*
19  * Boot program... arguments passed in r10 and r11 determine
20  * whether boot stops to ask for system name and which device
21  * boot comes from.
22  */
23 
24 #define	UNIX	"/vmunix"
25 char line[100];
26 
27 int	retry = 0;
28 extern	unsigned opendev;
29 
30 main()
31 {
32 	register unsigned howto, devtype;	/* howto=r11, devtype=r10 */
33 	int io, type;
34 
35 #ifdef lint
36 	howto = 0; devtype = 0;
37 #endif
38 	printf("\nBoot\n");
39 #ifdef JUSTASK
40 	howto = RB_ASKNAME|RB_SINGLE;
41 #else
42 	if ((howto & RB_ASKNAME) == 0) {
43 		type = (devtype >> B_TYPESHIFT) & B_TYPEMASK;
44 		if ((unsigned)type < ndevs && devsw[type].dv_name)
45 			strcpy(line, UNIX);
46 		else
47 			howto |= RB_SINGLE|RB_ASKNAME;
48 	}
49 #endif
50 	for (;;) {
51 		if (howto & RB_ASKNAME) {
52 			printf(": ");
53 			gets(line);
54 			if (line[0] == 0) {
55 				strcpy(line, UNIX);
56 				printf(": %s\n", line);
57 			}
58 		} else
59 			printf(": %s\n", line);
60 		io = open(line, 0);
61 		if (io >= 0) {
62 #ifdef VAX750
63 			loadpcs();
64 #endif
65 			copyunix(howto, opendev, io);
66 			close(io);
67 			howto |= RB_SINGLE|RB_ASKNAME;
68 		}
69 		if (++retry > 2)
70 			howto |= RB_SINGLE|RB_ASKNAME;
71 	}
72 }
73 
74 /*ARGSUSED*/
75 copyunix(howto, devtype, aio)
76 	register howto, devtype;	/* howto=r11, devtype=r10 */
77 	int aio;
78 {
79 	register int esym;		/* must be r9 */
80 	struct exec x;
81 	register int io = aio, i;
82 	char *addr;
83 
84 	i = read(io, (char *)&x, sizeof x);
85 	if (i != sizeof x ||
86 	    (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) {
87 		printf("Bad format\n");
88 		return;
89 	}
90 	printf("%d", x.a_text);
91 	if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1)
92 		goto shread;
93 	if (read(io, (char *)0, x.a_text) != x.a_text)
94 		goto shread;
95 	addr = (char *)x.a_text;
96 	if (x.a_magic == 0413 || x.a_magic == 0410)
97 		while ((int)addr & CLOFSET)
98 			*addr++ = 0;
99 	printf("+%d", x.a_data);
100 	if (read(io, addr, x.a_data) != x.a_data)
101 		goto shread;
102 	addr += x.a_data;
103 	printf("+%d", x.a_bss);
104 	for (i = 0; i < x.a_bss; i++)
105 		*addr++ = 0;
106 	if (howto & RB_KDB && x.a_syms) {
107 		*(int *)addr = x.a_syms;		/* symbol table size */
108 		addr += sizeof (int);
109 		printf("[+%d", x.a_syms);
110 		if (read(io, addr, x.a_syms) != x.a_syms)
111 			goto shread;
112 		addr += x.a_syms;
113 		if (read(io, addr, sizeof (int)) != sizeof (int))
114 			goto shread;
115 		i = *(int *)addr - sizeof (int);	/* string table size */
116 		addr += sizeof (int);
117 		printf("+%d]", i);
118 		if (read(io, addr, i) != i)
119 			goto shread;
120 		addr += i;
121 		esym = roundup((int)addr, sizeof (int));
122 		x.a_bss = 0;
123 	} else
124 		howto &= ~RB_KDB;
125 	for (i = 0; i < 128*512; i++)	/* slop */
126 		*addr++ = 0;
127 	x.a_entry &= 0x7fffffff;
128 	printf(" start 0x%x\n", x.a_entry);
129 	(*((int (*)()) x.a_entry))();
130 	return;
131 shread:
132 	printf("Short read\n");
133 	return;
134 }
135 
136 #ifdef VAX750
137 /* 750 Patchable Control Store magic */
138 
139 #include "../vax/mtpr.h"
140 #include "../vax/cpu.h"
141 #define	PCS_BITCNT	0x2000		/* number of patchbits */
142 #define	PCS_MICRONUM	0x400		/* number of ucode locs */
143 #define	PCS_PATCHADDR	0xf00000	/* start addr of patchbits */
144 #define	PCS_PCSADDR	(PCS_PATCHADDR+0x8000)	/* start addr of pcs */
145 #define	PCS_PATCHBIT	(PCS_PATCHADDR+0xc000)	/* patchbits enable reg */
146 #define	PCS_ENABLE	0xfff00000	/* enable bits for pcs */
147 
148 loadpcs()
149 {
150 	register int *ip;	/* known to be r11 below */
151 	register int i;		/* known to be r10 below */
152 	register int *jp;	/* known to be r9 below */
153 	register int j;
154 	static int pcsdone = 0;
155 	union cpusid sid;
156 	char pcs[100];
157 	char *cp;
158 
159 	sid.cpusid = mfpr(SID);
160 	if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95 || pcsdone)
161 		return;
162 	printf("Updating 11/750 microcode: ");
163 	for (cp = line; *cp; cp++)
164 		if (*cp == ')' || *cp == ':')
165 			break;
166 	if (*cp) {
167 		strncpy(pcs, line, 99);
168 		pcs[99] = 0;
169 		i = cp - line + 1;
170 	} else
171 		i = 0;
172 	strcpy(pcs + i, "pcs750.bin");
173 	i = open(pcs, 0);
174 	if (i < 0)
175 		return;
176 	/*
177 	 * We ask for more than we need to be sure we get only what we expect.
178 	 * After read:
179 	 *	locs 0 - 1023	packed patchbits
180 	 *	 1024 - 11264	packed microcode
181 	 */
182 	if (read(i, (char *)0, 23*512) != 22*512) {
183 		printf("Error reading %s\n", pcs);
184 		close(i);
185 		return;
186 	}
187 	close(i);
188 
189 	/*
190 	 * Enable patchbit loading and load the bits one at a time.
191 	 */
192 	*((int *)PCS_PATCHBIT) = 1;
193 	ip = (int *)PCS_PATCHADDR;
194 	jp = (int *)0;
195 	for (i=0; i < PCS_BITCNT; i++) {
196 		asm("	extzv	r10,$1,(r9),(r11)+");
197 	}
198 	*((int *)PCS_PATCHBIT) = 0;
199 
200 	/*
201 	 * Load PCS microcode 20 bits at a time.
202 	 */
203 	ip = (int *)PCS_PCSADDR;
204 	jp = (int *)1024;
205 	for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) {
206 		asm("	extzv	r10,$20,(r9),(r11)+");
207 	}
208 
209 	/*
210 	 * Enable PCS.
211 	 */
212 	i = *jp;		/* get 1st 20 bits of microcode again */
213 	i &= 0xfffff;
214 	i |= PCS_ENABLE;	/* reload these bits with PCS enable set */
215 	*((int *)PCS_PCSADDR) = i;
216 
217 	sid.cpusid = mfpr(SID);
218 	printf("new rev level=%d\n", sid.cpu750.cp_urev);
219 	pcsdone = 1;
220 }
221 #endif
222