save r10 (boot device); use it to set rootdev and maybe swap, arg and dump devs
[unix-history] / usr / src / sys / vax / stand / boot.c
CommitLineData
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 */
24char 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"
52char line[100];
b7e60356 53
a889f9b7
BJ
54int retry = 0;
55
b7e60356
BJ
56main()
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*/
111copyunix(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
143shread:
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
159loadpcs()
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