Commit | Line | Data |
---|---|---|
8ae0e4b4 KM |
1 | /* |
2 | * Copyright (c) 1982 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
1c915156 | 6 | * @(#)boot.c 6.7 (Berkeley) %G% |
8ae0e4b4 | 7 | */ |
b7e60356 BJ |
8 | |
9 | #include "../h/param.h" | |
b7e60356 | 10 | #include "../h/inode.h" |
06254255 | 11 | #include "../h/fs.h" |
b7e60356 BJ |
12 | #include "../h/vm.h" |
13 | #include <a.out.h> | |
14 | #include "saio.h" | |
06254255 | 15 | #include "../h/reboot.h" |
b7e60356 | 16 | |
8da76047 BJ |
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 | /* Types in r10 specifying major device */ | |
24 | char devname[][2] = { | |
25 | 'h','p', /* 0 = hp */ | |
26 | 0,0, /* 1 = ht */ | |
27 | 'u','p', /* 2 = up */ | |
a0761322 | 28 | 'h','k', /* 3 = hk */ |
3486ee81 BJ |
29 | 0,0, /* 4 = sw */ |
30 | 0,0, /* 5 = tm */ | |
31 | 0,0, /* 6 = ts */ | |
32 | 0,0, /* 7 = mt */ | |
33 | 0,0, /* 8 = tu */ | |
34 | 'r','a', /* 9 = ra */ | |
1e549678 CL |
35 | 'u','t', /* 10 = ut */ |
36 | 'r','b', /* 11 = rb */ | |
c079fe19 SL |
37 | 0,0, /* 12 = uu */ |
38 | 0,0, /* 13 = rx */ | |
39 | 'r','l', /* 14 = rl */ | |
8da76047 BJ |
40 | }; |
41 | ||
5af1bd7a JB |
42 | /* |
43 | * constants for converting a "minor" device numbers to unit number | |
44 | * and partition number | |
45 | */ | |
46 | #define UNITSHIFT 16 | |
47 | #define UNITMASK 0x1ff | |
48 | #define PARTITIONMASK 0x7 | |
49 | #define PARTITIONSHIFT 3 | |
50 | ||
018dc60b MK |
51 | #define UNIX "vmunix" |
52 | char line[100]; | |
b7e60356 | 53 | |
a889f9b7 BJ |
54 | int retry = 0; |
55 | ||
b7e60356 BJ |
56 | main() |
57 | { | |
8da76047 | 58 | register howto, devtype; /* howto=r11, devtype=r10 */ |
a889f9b7 | 59 | int io; |
5af1bd7a | 60 | register type, part, unit; |
018dc60b | 61 | register char *cp; |
b7e60356 | 62 | |
610c6f01 BJ |
63 | #ifdef lint |
64 | howto = 0; devtype = 0; | |
65 | #endif | |
018dc60b | 66 | printf("\nBoot\n"); |
0bd37f37 | 67 | #ifdef JUSTASK |
aaa709c3 | 68 | howto = RB_ASKNAME|RB_SINGLE; |
0bd37f37 | 69 | #else |
5af1bd7a JB |
70 | type = devtype & 0xff; |
71 | unit = (int)((unsigned)devtype >> UNITSHIFT) & UNITMASK; | |
72 | part = unit & PARTITIONMASK; | |
73 | unit = unit >> PARTITIONSHIFT; | |
8da76047 | 74 | if ((howto&RB_ASKNAME)==0) { |
5af1bd7a JB |
75 | if (type >= 0 && type < sizeof(devname) / 2 |
76 | && devname[type][0]) { | |
018dc60b MK |
77 | cp = line; |
78 | *cp++ = devname[type][0]; | |
79 | *cp++ = devname[type][1]; | |
80 | *cp++ = '('; | |
81 | if (unit >= 10) | |
82 | *cp++ = unit / 10 + '0'; | |
83 | *cp++ = unit % 10 + '0'; | |
84 | *cp++ = ','; | |
85 | *cp++ = part + '0'; | |
86 | *cp++ = ')'; | |
87 | strcpy(cp, UNIX); | |
a0761322 | 88 | } else |
8da76047 | 89 | howto = RB_SINGLE|RB_ASKNAME; |
8da76047 | 90 | } |
0bd37f37 | 91 | #endif |
8da76047 BJ |
92 | for (;;) { |
93 | if (howto & RB_ASKNAME) { | |
94 | printf(": "); | |
95 | gets(line); | |
96 | } else | |
97 | printf(": %s\n", line); | |
98 | io = open(line, 0); | |
e559a17c | 99 | if (io >= 0) { |
1c915156 | 100 | loadpcs(); |
a889f9b7 | 101 | copyunix(howto, io); |
f834e141 MK |
102 | close(io); |
103 | howto = RB_SINGLE|RB_ASKNAME; | |
e559a17c | 104 | } |
8da76047 BJ |
105 | if (++retry > 2) |
106 | howto = RB_SINGLE|RB_ASKNAME; | |
107 | } | |
b7e60356 BJ |
108 | } |
109 | ||
a889f9b7 BJ |
110 | /*ARGSUSED*/ |
111 | copyunix(howto, io) | |
112 | register howto, io; | |
b7e60356 BJ |
113 | { |
114 | struct exec x; | |
115 | register int i; | |
116 | char *addr; | |
117 | ||
118 | i = read(io, (char *)&x, sizeof x); | |
06254255 KM |
119 | if (i != sizeof x || |
120 | (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) | |
b7e60356 BJ |
121 | _stop("Bad format\n"); |
122 | printf("%d", x.a_text); | |
b5d17f4d | 123 | if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) |
06254255 | 124 | goto shread; |
b7e60356 BJ |
125 | if (read(io, (char *)0, x.a_text) != x.a_text) |
126 | goto shread; | |
127 | addr = (char *)x.a_text; | |
06254255 KM |
128 | if (x.a_magic == 0413 || x.a_magic == 0410) |
129 | while ((int)addr & CLOFSET) | |
130 | *addr++ = 0; | |
b7e60356 BJ |
131 | printf("+%d", x.a_data); |
132 | if (read(io, addr, x.a_data) != x.a_data) | |
133 | goto shread; | |
134 | addr += x.a_data; | |
135 | printf("+%d", x.a_bss); | |
136 | x.a_bss += 128*512; /* slop */ | |
137 | for (i = 0; i < x.a_bss; i++) | |
138 | *addr++ = 0; | |
139 | x.a_entry &= 0x7fffffff; | |
140 | printf(" start 0x%x\n", x.a_entry); | |
141 | (*((int (*)()) x.a_entry))(); | |
f834e141 | 142 | return; |
b7e60356 BJ |
143 | shread: |
144 | _stop("Short read\n"); | |
145 | } | |
e559a17c | 146 | |
1c915156 | 147 | #ifndef SMALL |
e559a17c TF |
148 | /* 750 Patchable Control Store magic */ |
149 | ||
150 | #include "../vax/mtpr.h" | |
151 | #include "../vax/cpu.h" | |
152 | #define PCS_BITCNT 0x2000 /* number of patchbits */ | |
153 | #define PCS_MICRONUM 0x400 /* number of ucode locs */ | |
154 | #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ | |
155 | #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ | |
156 | #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ | |
157 | #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ | |
158 | ||
159 | loadpcs() | |
160 | { | |
161 | register int *ip; /* known to be r11 below */ | |
162 | register int i; /* known to be r10 below */ | |
163 | register int *jp; /* known to be r9 below */ | |
164 | register int j; | |
1c915156 | 165 | static int pcsdone = 0; |
e559a17c TF |
166 | union cpusid sid; |
167 | char pcs[100]; | |
5af1bd7a JB |
168 | char *closeparen; |
169 | char *index(); | |
e559a17c TF |
170 | |
171 | sid.cpusid = mfpr(SID); | |
1c915156 | 172 | if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95 || pcsdone) |
e559a17c TF |
173 | return; |
174 | printf("Updating 11/750 microcode: "); | |
5af1bd7a JB |
175 | strncpy(pcs, line, 99); |
176 | pcs[99] = 0; | |
177 | closeparen = index(pcs, ')'); | |
178 | if (closeparen) | |
179 | *(++closeparen) = 0; | |
180 | else | |
181 | return; | |
e559a17c TF |
182 | strcat(pcs, "pcs750.bin"); |
183 | i = open(pcs, 0); | |
184 | if (i < 0) | |
185 | return; | |
186 | /* | |
187 | * We ask for more than we need to be sure we get only what we expect. | |
188 | * After read: | |
189 | * locs 0 - 1023 packed patchbits | |
190 | * 1024 - 11264 packed microcode | |
191 | */ | |
192 | if (read(i, (char *)0, 23*512) != 22*512) { | |
193 | printf("Error reading %s\n", pcs); | |
194 | close(i); | |
195 | return; | |
196 | } | |
197 | close(i); | |
198 | ||
199 | /* | |
200 | * Enable patchbit loading and load the bits one at a time. | |
201 | */ | |
202 | *((int *)PCS_PATCHBIT) = 1; | |
203 | ip = (int *)PCS_PATCHADDR; | |
204 | jp = (int *)0; | |
205 | for (i=0; i < PCS_BITCNT; i++) { | |
206 | asm(" extzv r10,$1,(r9),(r11)+"); | |
207 | } | |
208 | *((int *)PCS_PATCHBIT) = 0; | |
209 | ||
210 | /* | |
211 | * Load PCS microcode 20 bits at a time. | |
212 | */ | |
213 | ip = (int *)PCS_PCSADDR; | |
214 | jp = (int *)1024; | |
215 | for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { | |
216 | asm(" extzv r10,$20,(r9),(r11)+"); | |
217 | } | |
218 | ||
219 | /* | |
220 | * Enable PCS. | |
221 | */ | |
222 | i = *jp; /* get 1st 20 bits of microcode again */ | |
223 | i &= 0xfffff; | |
224 | i |= PCS_ENABLE; /* reload these bits with PCS enable set */ | |
225 | *((int *)PCS_PCSADDR) = i; | |
226 | ||
227 | sid.cpusid = mfpr(SID); | |
228 | printf("new rev level=%d\n", sid.cpu750.cp_urev); | |
1c915156 | 229 | pcsdone = 1; |
e559a17c | 230 | } |
1c915156 | 231 | #endif SMALL |