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