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