Commit | Line | Data |
---|---|---|
dea92547 KM |
1 | /* |
2 | * Copyright (c) 1988 University of Utah. | |
3 | * Copyright (c) 1992 The Regents of the University of California. | |
4 | * All rights reserved. | |
5 | * | |
6 | * This code is derived from software contributed to Berkeley by | |
7 | * the Systems Programming Group of the University of Utah Computer | |
8 | * Science Department and Ralph Campbell. | |
9 | * | |
10 | * %sccs.include.redist.c% | |
11 | * | |
12 | * from: Utah $Hdr: autoconf.c 1.31 91/01/21$ | |
13 | * | |
38a01dbe | 14 | * @(#)autoconf.c 7.5 (Berkeley) %G% |
dea92547 KM |
15 | */ |
16 | ||
17 | /* | |
18 | * Setup the system to run on the current machine. | |
19 | * | |
20 | * Configure() is called at boot time. Available | |
21 | * devices are determined (from possibilities mentioned in ioconf.c), | |
22 | * and the drivers are initialized. | |
23 | */ | |
24 | ||
38a01dbe KB |
25 | #include <sys/param.h> |
26 | #include <sys/systm.h> | |
27 | #include <sys/map.h> | |
28 | #include <sys/buf.h> | |
29 | #include <sys/dkstat.h> | |
30 | #include <sys/conf.h> | |
31 | #include <sys/dmap.h> | |
32 | #include <sys/reboot.h> | |
dea92547 | 33 | |
38a01dbe KB |
34 | #include <machine/cpu.h> |
35 | #include <pmax/dev/device.h> | |
dea92547 KM |
36 | |
37 | /* | |
38 | * The following several variables are related to | |
39 | * the configuration process, and are used in initializing | |
40 | * the machine. | |
41 | */ | |
42 | int cold = 1; /* if 1, still working on cold-start */ | |
43 | int dkn; /* number of iostat dk numbers assigned so far */ | |
44 | int cpuspeed = 30; /* approx # instr per usec. */ | |
45 | ||
46 | /* | |
47 | * Determine mass storage and memory configuration for a machine. | |
48 | * Get cpu type, and then switch out to machine specific procedures | |
49 | * which will probe adaptors to see what is out there. | |
50 | */ | |
51 | configure() | |
52 | { | |
53 | register struct pmax_ctlr *cp; | |
54 | register struct scsi_device *dp; | |
55 | register struct driver *drp; | |
646ba44c RC |
56 | #ifdef DS5000 |
57 | register int i; | |
58 | #endif | |
dea92547 KM |
59 | |
60 | /* print what type of CPU and FPU we have */ | |
61 | switch (cpu.cpu.cp_imp) { | |
62 | case MIPS_R2000: | |
63 | printf("cpu0 (MIPS R2000 revision %d.%d)\n", | |
64 | cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); | |
65 | break; | |
66 | ||
646ba44c RC |
67 | case MIPS_R3000: |
68 | printf("cpu0 (MIPS R3000 revision %d.%d)\n", | |
69 | cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); | |
70 | break; | |
71 | ||
72 | case MIPS_R4000: | |
73 | printf("cpu0 (MIPS R4000 revision %d.%d)\n", | |
74 | cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); | |
75 | break; | |
76 | ||
dea92547 KM |
77 | default: |
78 | printf("cpu0 (implementation %d revision %d.%d)\n", | |
79 | cpu.cpu.cp_imp, cpu.cpu.cp_majrev, cpu.cpu.cp_minrev); | |
80 | } | |
81 | switch (fpu.cpu.cp_imp) { | |
82 | case MIPS_R2010: | |
83 | printf("fpu0 (MIPS R2010 revision %d.%d)\n", | |
84 | fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); | |
85 | break; | |
86 | ||
646ba44c RC |
87 | case MIPS_R3010: |
88 | printf("fpu0 (MIPS R3010 revision %d.%d)\n", | |
89 | fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); | |
90 | break; | |
91 | ||
92 | case MIPS_R4010: | |
93 | printf("fpu0 (MIPS R4010 revision %d.%d)\n", | |
94 | fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); | |
95 | break; | |
96 | ||
dea92547 KM |
97 | default: |
98 | printf("fpu0 (implementation %d revision %d.%d)\n", | |
99 | fpu.cpu.cp_imp, fpu.cpu.cp_majrev, fpu.cpu.cp_minrev); | |
100 | } | |
101 | printf("data cache size %dK inst cache size %dK\n", | |
102 | machDataCacheSize >> 10, machInstCacheSize >> 10); | |
103 | ||
104 | /* probe and initialize controllers */ | |
105 | for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { | |
646ba44c | 106 | #ifdef DS3100 |
dea92547 KM |
107 | if (!(*drp->d_init)(cp)) |
108 | continue; | |
646ba44c RC |
109 | #endif |
110 | #ifdef DS5000 | |
111 | /* | |
112 | * If the device is still in an unknown slot, | |
113 | * then it was not found by tc_find_all_options(). | |
114 | */ | |
115 | if (cp->pmax_addr == (char *)QUES) | |
116 | continue; | |
117 | if (!(*drp->d_init)(cp)) | |
118 | continue; | |
119 | if (drp->d_intr && (i = cp->pmax_pri) >= 0) { | |
120 | if (intr_tab[i].func) | |
121 | printf("%s: slot %d already in use\n", | |
122 | drp->d_name, i); | |
123 | intr_tab[i].func = drp->d_intr; | |
124 | intr_tab[i].unit = cp->pmax_unit; | |
125 | tc_enable_interrupt(i, 1); | |
126 | } | |
127 | #endif | |
dea92547 KM |
128 | |
129 | cp->pmax_alive = 1; | |
130 | ||
131 | /* probe and initialize devices connected to controller */ | |
132 | for (dp = scsi_dinit; drp = dp->sd_driver; dp++) { | |
133 | /* might want to get fancier later */ | |
134 | if (dp->sd_cdriver != cp->pmax_driver || | |
135 | dp->sd_ctlr != cp->pmax_unit) | |
136 | continue; /* not connected */ | |
137 | if (!(*drp->d_init)(dp)) | |
138 | continue; | |
139 | dp->sd_alive = 1; | |
140 | /* if device is a disk, assign number for statistics */ | |
141 | if (dp->sd_dk && dkn < DK_NDRIVE) | |
142 | dp->sd_dk = dkn++; | |
143 | else | |
144 | dp->sd_dk = -1; | |
145 | } | |
146 | } | |
147 | ||
6f5de829 | 148 | #ifdef GENERIC |
dea92547 KM |
149 | if ((boothowto & RB_ASKNAME) == 0) |
150 | setroot(); | |
151 | setconf(); | |
152 | #else | |
153 | setroot(); | |
154 | #endif | |
155 | swapconf(); | |
156 | cold = 0; | |
157 | } | |
158 | ||
159 | /* | |
160 | * Configure swap space and related parameters. | |
161 | */ | |
162 | swapconf() | |
163 | { | |
164 | register struct swdevt *swp; | |
165 | register int nblks; | |
166 | ||
167 | for (swp = swdevt; swp->sw_dev; swp++) | |
168 | if (bdevsw[major(swp->sw_dev)].d_psize) { | |
169 | nblks = | |
170 | (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); | |
171 | if (nblks != -1 && | |
172 | (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) | |
173 | swp->sw_nblks = nblks; | |
174 | } | |
175 | dumpconf(); | |
176 | } | |
177 | ||
178 | #define DOSWAP /* Change swdevt and dumpdev too */ | |
179 | u_long bootdev; /* should be dev_t, but not until 32 bits */ | |
180 | ||
181 | static char devname[][2] = { | |
182 | 'r','z', /* 0 = rz */ | |
183 | }; | |
184 | ||
185 | #define PARTITIONMASK 0x7 | |
186 | #define PARTITIONSHIFT 3 | |
187 | ||
188 | /* | |
189 | * Attempt to find the device from which we were booted. | |
190 | * If we can do so, and not instructed not to do so, | |
191 | * change rootdev to correspond to the load device. | |
192 | */ | |
193 | setroot() | |
194 | { | |
195 | register struct scsi_device *dp; | |
196 | int majdev, mindev, unit, part, controller; | |
197 | dev_t temp, orootdev; | |
198 | struct swdevt *swp; | |
199 | ||
200 | if (boothowto & RB_DFLTROOT || | |
201 | (bootdev & B_MAGICMASK) != B_DEVMAGIC) | |
202 | return; | |
203 | majdev = B_TYPE(bootdev); | |
204 | if (majdev >= sizeof(devname) / sizeof(devname[0])) | |
205 | return; | |
206 | controller = B_CONTROLLER(bootdev); | |
207 | part = B_PARTITION(bootdev); | |
208 | unit = B_UNIT(bootdev); | |
209 | ||
210 | for (dp = scsi_dinit; ; dp++) { | |
211 | if (dp->sd_driver == 0) | |
212 | return; | |
213 | if (dp->sd_alive && dp->sd_drive == unit && | |
214 | dp->sd_ctlr == controller && | |
215 | dp->sd_driver->d_name[0] == devname[majdev][0] && | |
216 | dp->sd_driver->d_name[1] == devname[majdev][1]) { | |
217 | mindev = dp->sd_unit; | |
218 | break; | |
219 | } | |
220 | } | |
221 | /* | |
222 | * Form a new rootdev | |
223 | */ | |
224 | mindev = (mindev << PARTITIONSHIFT) + part; | |
225 | orootdev = rootdev; | |
226 | rootdev = makedev(majdev, mindev); | |
227 | /* | |
228 | * If the original rootdev is the same as the one | |
229 | * just calculated, don't need to adjust the swap configuration. | |
230 | */ | |
231 | if (rootdev == orootdev) | |
232 | return; | |
233 | ||
234 | printf("Changing root device to %c%c%d%c\n", | |
235 | devname[majdev][0], devname[majdev][1], | |
236 | mindev >> PARTITIONSHIFT, part + 'a'); | |
237 | ||
238 | #ifdef DOSWAP | |
239 | mindev &= ~PARTITIONMASK; | |
240 | for (swp = swdevt; swp->sw_dev; swp++) { | |
241 | if (majdev == major(swp->sw_dev) && | |
242 | mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { | |
243 | temp = swdevt[0].sw_dev; | |
244 | swdevt[0].sw_dev = swp->sw_dev; | |
245 | swp->sw_dev = temp; | |
246 | break; | |
247 | } | |
248 | } | |
249 | if (swp->sw_dev == 0) | |
250 | return; | |
251 | ||
252 | /* | |
253 | * If dumpdev was the same as the old primary swap | |
254 | * device, move it to the new primary swap device. | |
255 | */ | |
256 | if (temp == dumpdev) | |
257 | dumpdev = swdevt[0].sw_dev; | |
258 | #endif | |
259 | } | |
260 | ||
261 | /* | |
262 | * Look at the string 'cp' and decode the boot device. | |
263 | */ | |
264 | void | |
265 | makebootdev(cp) | |
266 | register char *cp; | |
267 | { | |
268 | int majdev, unit, part, ctrl; | |
269 | ||
270 | for (majdev = 0; majdev < sizeof(devname)/sizeof(devname[0]); majdev++) | |
271 | if (cp[0] == devname[majdev][0] && | |
272 | cp[1] == devname[majdev][1] && | |
273 | cp[2] == '(') | |
274 | goto fndmaj; | |
275 | defdev: | |
276 | bootdev = B_DEVMAGIC; | |
277 | return; | |
278 | ||
279 | fndmaj: | |
280 | for (ctrl = 0, cp += 3; *cp >= '0' && *cp <= '9'; ) | |
281 | ctrl = ctrl * 10 + *cp++ - '0'; | |
282 | if (*cp == ',') | |
283 | cp++; | |
284 | for (unit = 0; *cp >= '0' && *cp <= '9'; ) | |
285 | unit = unit * 10 + *cp++ - '0'; | |
286 | if (*cp == ',') | |
287 | cp++; | |
288 | for (part = 0; *cp >= '0' && *cp <= '9'; ) | |
289 | part = part * 10 + *cp++ - '0'; | |
290 | if (*cp != ')') | |
291 | goto defdev; | |
b8767ed1 | 292 | bootdev = MAKEBOOTDEV(majdev, 0, ctrl, unit, part); |
dea92547 | 293 | } |