Commit | Line | Data |
---|---|---|
8ae0e4b4 | 1 | /* |
0880b18e | 2 | * Copyright (c) 1982, 1986 Regents of the University of California. |
8ae0e4b4 KM |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
39c71180 | 6 | * @(#)boot.c 7.6 (Berkeley) %G% |
8ae0e4b4 | 7 | */ |
b7e60356 | 8 | |
1cf5763d MK |
9 | #include "param.h" |
10 | #include "inode.h" | |
11 | #include "fs.h" | |
12 | #include "vm.h" | |
39c71180 MK |
13 | #include "reboot.h" |
14 | ||
b7e60356 BJ |
15 | #include <a.out.h> |
16 | #include "saio.h" | |
17 | ||
8da76047 BJ |
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 | ||
80c81fbf | 24 | #define UNIX "/vmunix" |
018dc60b | 25 | char line[100]; |
b7e60356 | 26 | |
a889f9b7 | 27 | int retry = 0; |
80c81fbf | 28 | extern unsigned opendev; |
a889f9b7 | 29 | |
b7e60356 BJ |
30 | main() |
31 | { | |
24a62d66 | 32 | register unsigned howto, devtype; /* howto=r11, devtype=r10 */ |
80c81fbf | 33 | int io, type; |
b7e60356 | 34 | |
610c6f01 BJ |
35 | #ifdef lint |
36 | howto = 0; devtype = 0; | |
37 | #endif | |
018dc60b | 38 | printf("\nBoot\n"); |
0bd37f37 | 39 | #ifdef JUSTASK |
aaa709c3 | 40 | howto = RB_ASKNAME|RB_SINGLE; |
0bd37f37 | 41 | #else |
24a62d66 | 42 | if ((howto & RB_ASKNAME) == 0) { |
80c81fbf | 43 | type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; |
39c71180 | 44 | if ((unsigned)type < ndevs && devsw[type].dv_name) |
80c81fbf MK |
45 | strcpy(line, UNIX); |
46 | else | |
1cf5763d | 47 | howto |= RB_SINGLE|RB_ASKNAME; |
8da76047 | 48 | } |
0bd37f37 | 49 | #endif |
8da76047 BJ |
50 | for (;;) { |
51 | if (howto & RB_ASKNAME) { | |
52 | printf(": "); | |
53 | gets(line); | |
80c81fbf MK |
54 | if (line[0] == 0) { |
55 | strcpy(line, UNIX); | |
56 | printf(": %s\n", line); | |
57 | } | |
8da76047 BJ |
58 | } else |
59 | printf(": %s\n", line); | |
60 | io = open(line, 0); | |
e559a17c | 61 | if (io >= 0) { |
39c71180 | 62 | #ifdef VAX750 |
1c915156 | 63 | loadpcs(); |
39c71180 | 64 | #endif |
80c81fbf | 65 | copyunix(howto, opendev, io); |
f834e141 | 66 | close(io); |
1cf5763d | 67 | howto |= RB_SINGLE|RB_ASKNAME; |
e559a17c | 68 | } |
8da76047 | 69 | if (++retry > 2) |
1cf5763d | 70 | howto |= RB_SINGLE|RB_ASKNAME; |
8da76047 | 71 | } |
b7e60356 BJ |
72 | } |
73 | ||
a889f9b7 | 74 | /*ARGSUSED*/ |
97b95718 MK |
75 | copyunix(howto, devtype, aio) |
76 | register howto, devtype; /* howto=r11, devtype=r10 */ | |
77 | int aio; | |
b7e60356 | 78 | { |
97b95718 | 79 | register int esym; /* must be r9 */ |
b7e60356 | 80 | struct exec x; |
97b95718 | 81 | register int io = aio, i; |
b7e60356 BJ |
82 | char *addr; |
83 | ||
84 | i = read(io, (char *)&x, sizeof x); | |
06254255 | 85 | if (i != sizeof x || |
1cf5763d MK |
86 | (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) { |
87 | printf("Bad format\n"); | |
88 | return; | |
89 | } | |
b7e60356 | 90 | printf("%d", x.a_text); |
b5d17f4d | 91 | if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) |
06254255 | 92 | goto shread; |
b7e60356 BJ |
93 | if (read(io, (char *)0, x.a_text) != x.a_text) |
94 | goto shread; | |
95 | addr = (char *)x.a_text; | |
06254255 KM |
96 | if (x.a_magic == 0413 || x.a_magic == 0410) |
97 | while ((int)addr & CLOFSET) | |
98 | *addr++ = 0; | |
b7e60356 BJ |
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); | |
b7e60356 BJ |
104 | for (i = 0; i < x.a_bss; i++) |
105 | *addr++ = 0; | |
1cf5763d MK |
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; | |
b7e60356 BJ |
127 | x.a_entry &= 0x7fffffff; |
128 | printf(" start 0x%x\n", x.a_entry); | |
129 | (*((int (*)()) x.a_entry))(); | |
f834e141 | 130 | return; |
b7e60356 | 131 | shread: |
1cf5763d MK |
132 | printf("Short read\n"); |
133 | return; | |
b7e60356 | 134 | } |
e559a17c | 135 | |
39c71180 | 136 | #ifdef VAX750 |
e559a17c TF |
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; | |
1c915156 | 154 | static int pcsdone = 0; |
e559a17c TF |
155 | union cpusid sid; |
156 | char pcs[100]; | |
c3fca454 | 157 | char *cp; |
e559a17c TF |
158 | |
159 | sid.cpusid = mfpr(SID); | |
1c915156 | 160 | if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95 || pcsdone) |
e559a17c TF |
161 | return; |
162 | printf("Updating 11/750 microcode: "); | |
c3fca454 MK |
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"); | |
e559a17c TF |
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); | |
1c915156 | 219 | pcsdone = 1; |
e559a17c | 220 | } |
39c71180 | 221 | #endif |