FreeBSD/Linux Kernel Cross Reference
sys/sqt/autoconf.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1991 Carnegie Mellon University
4 * Copyright (c) 1991 Sequent Computer Systems
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation.
12 *
13 * CARNEGIE MELLON AND SEQUENT COMPUTER SYSTEMS ALLOW FREE USE OF
14 * THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON AND
15 * SEQUENT COMPUTER SYSTEMS DISCLAIM ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
27 */
28
29 /*
30 * HISTORY
31 * $Log: autoconf.c,v $
32 * Revision 2.4 93/11/17 18:45:48 dbg
33 * Moved machine_slot to kern/machine.h.
34 * [93/11/03 dbg]
35 *
36 * Revision 2.3 91/07/31 17:59:27 dbg
37 * Changed copyright.
38 * [91/07/31 dbg]
39 *
40 * Revision 2.2 91/05/08 12:52:16 dbg
41 * Adapted for pure Mach kernel. No conditionals. Removed ns32000
42 * and KXX support.
43 * [91/04/26 14:47:41 dbg]
44 *
45 */
46
47 #ifndef lint
48 static char rcsid[] = "$Header: autoconf.c,v 2.4 93/11/17 18:45:48 dbg Exp $";
49 #endif
50
51 /*
52 * autoconf.c
53 * Auto-configuration.
54 */
55
56 /*
57 * Revision 1.2 89/07/20 18:05:40 kak
58 * moved balance includes
59 *
60 * Revision 1.1 89/07/05 13:15:26 kak
61 * Initial revision
62 *
63 * Revision 2.26 88/11/10 08:25:49 djg
64 * bak242
65 *
66 * Revision 2.25 88/03/18 11:54:24 dilip
67 * moved init of dmmin, dmmax, zdmap to vm_drum.c. Also, drop maxdmap
68 * init, call init_dmap() instead.
69 *
70 */
71
72 #include <sys/reboot.h>
73
74 #include <kern/assert.h>
75 #include <kern/cpu_number.h>
76 #include <kern/machine.h>
77
78 #include <sqt/vm_defs.h>
79
80 #include <sqt/intctl.h>
81 #include <sqt/ioconf.h>
82 #include <sqt/mutex.h>
83
84 #include <sqt/SGSproc.h>
85 #include <sqt/cfg.h>
86 #include <sqt/slic.h>
87 #include <sqt/slicreg.h>
88 #include <sqt/clkarb.h>
89 #include <sqt/clock.h>
90 #include <sqt/engine.h>
91
92 /*
93 * Address of configuration table set by PROM loader.
94 */
95 struct config_desc *va_CD_LOC;
96
97 unsigned Nengine; /* # processors */
98 struct engine *engine; /* base of engine array */
99 struct engine *engine_Nengine; /* end of engine array */
100 int NFPA = 0; /* # processors with FPA's */
101 int mono_P_slic = -1; /* no mono_P drivers == -1 */
102 short fp_lights; /* Front panel lights */
103 u_char cons_scsi = 0; /* 26 */ /* console SCSI's SLIC id */
104 extern int cpurate; /* used for delays */
105
106 int boothowto; /* boot flags */
107 unsigned sys_clock_rate; /* # Mega Hz system runs at */
108
109 struct bin_header int_bin_table[SLICBINS]; /* Interrupt Bin Table */
110 int bin_alloc[SLICBINS]; /* for allocating vectors */
111
112 /*
113 * slic_to_config[] maps SLIC number to configuration information about
114 * that SLIC.
115 */
116
117 struct ctlr_desc *slic_to_config[MAX_NUM_SLIC];
118
119 /*
120 * slic_to_cpu maps SLIC number to logical processor id
121 */
122
123 char slic_to_cpu[MAX_NUM_SLIC];
124
125 /*
126 * sec0eaddr encodes a system unique 24-bit number. Name is historic.
127 * This value is the low-order 24-bits of the ether address on SCED[0] for
128 * a B8k; on a B21k it's the system-ID value from the backplane (readable thru
129 * the CADM). After system is up and /etc/init has the magic system ID number,
130 * sec0eaddr holds the number of users the system can legally support.
131 */
132
133 unsigned sec0eaddr = -1; /* system ID number */
134
135 extern char * calloc();
136 int strayint();
137
138
139 /*
140 * configure()
141 * Scan the HW configuration information, do probes, etc,
142 * all in the name of determining what's out there.
143 */
144
145 configure()
146 {
147 register struct ctlr_desc *cd;
148 register struct cntlrs *b8k;
149
150 /*
151 * Force io to this slic
152 */
153 mono_P_slic = va_slic->sl_procid;
154
155 /*
156 * Determine boot flags and system clock rate.
157 */
158
159 boothowto = va_CD_LOC->c_boot_flag;
160 sys_clock_rate = va_CD_LOC->c_clock_rate;
161
162 /*
163 * Build slic to config information map.
164 */
165
166 for (cd = PHYSTOKV(va_CD_LOC->c_ctlrs, struct ctlr_desc *);
167 cd < PHYSTOKV(va_CD_LOC->c_end_ctlrs, struct ctlr_desc *);
168 cd++)
169 slic_to_config[cd->cd_slic] = cd;
170
171 /*
172 * Do configuration/allocation of basic system components.
173 */
174
175 conf_console();
176 conf_clkarb();
177 conf_proc();
178 conf_mem();
179
180 for (b8k = b8k_cntlrs; b8k->conf_b8k != NULL; b8k++)
181 (*b8k->conf_b8k)();
182
183 /*
184 * Allocate interrupt table, set up pseudo devices, and
185 * probe IO controllers (includes MBAd's, SCED's, ZDC's, etc).
186 */
187
188 conf_intr();
189 conf_pseudo();
190
191 for (b8k = b8k_cntlrs; b8k->conf_b8k != NULL; b8k++)
192 (*b8k->probe_b8k_devs)();
193 setconf();
194 }
195
196 /*
197 * conf_console()
198 * Determine Console SCSI card for putchar()'s and "boot" console device.
199 */
200
201 conf_console()
202 {
203 register struct ctlr_desc *cd;
204
205 cd = PHYSTOKV(va_CD_LOC->c_cons, struct ctlr_desc *);
206 cons_scsi = cd->cd_slic;
207 }
208
209 /*
210 * conf_clkarb()
211 * Determine if clock arbiter is present. If present,
212 * set flag for front panel lights. And determine bus priority
213 * for slots 16-20. If all are processors then set priority to low
214 * otherwise set high (default).
215 */
216
217 conf_clkarb()
218 {
219 register struct ctlr_toc *toc =
220 PHYSTOKV(&va_CD_LOC->c_toc[SLB_CLKARBBOARD], struct ctlr_toc *);
221 register struct ctlr_desc *cd;
222 extern int light_show;
223
224 if (toc->ct_count == 0) {
225 return;
226 }
227
228 /*
229 * We're a B21k ==> set up to use front-panel LED's and get system ID
230 * from clock-arbiter board.
231 */
232
233 cd = PHYSTOKV(&va_CD_LOC->c_ctlrs[toc->ct_start],
234 struct ctlr_desc *); /* clkarb ctlr_desc */
235
236 fp_lights = 1; /* use front panel LEDs */
237 if (light_show > 1)
238 fp_lights = -1; /* use front-panel and processor LEDs */
239 FP_IO_ONLINE; /* ASSUME all drives online */
240
241 sec0eaddr = cd->cd_ca_sysid & 0x00FFFFFF;
242
243 }
244
245 /*
246 * conf_proc()
247 * Configure processors.
248 *
249 * Allocate engine table for all possible processors, but only remember
250 * alive and configured processors.
251 *
252 * We only fill out the slic addresses in the engine structures;
253 * sysinit() fills out the rest.
254 *
255 * We also set `Nengine' here to the # of desired processors.
256 */
257
258 conf_proc()
259 {
260 extern int lcpuspeed; /* configured value */
261 register struct ctlr_toc *toc;
262 register struct ctlr_desc *cd;
263 register struct engine *eng;
264 register int i;
265
266 /*
267 * Get table of contents pointer for processor board.
268 */
269
270 toc = PHYSTOKV(&va_CD_LOC->c_toc[SLB_SGSPROCBOARD],
271 struct ctlr_toc *); /* SGS processors */
272
273 engine = (struct engine *)
274 calloc((int)toc->ct_count * sizeof(struct engine));
275
276 printf("%d processors; slic", toc->ct_count);
277
278 cd = PHYSTOKV(&va_CD_LOC->c_ctlrs[toc->ct_start], struct ctlr_desc *);
279 for (i = 0; i < toc->ct_count; i++, cd++) {
280 printf(" %d", cd->cd_slic);
281 if (cd->cd_diag_flag & (CFG_FAIL|CFG_DECONF))
282 continue;
283 eng = &engine[Nengine];
284 eng->e_diag_flag = cd->cd_diag_flag;
285 eng->e_slicaddr = cd->cd_slic;
286 eng->e_cpu_speed = cd->cd_p_speed;
287
288 slic_to_cpu[cd->cd_slic] = Nengine;
289
290 machine_slot[Nengine].is_cpu = TRUE;
291 machine_slot[Nengine].cpu_type = CPU_TYPE_I386;
292 machine_slot[Nengine].cpu_subtype = CPU_SUBTYPE_SYMMETRY;
293 machine_slot[Nengine].running = FALSE;
294
295 /*
296 * Set the engine rate and find the slowest proccesor
297 * if not set assume minimum.
298 * Note: cpurate is recalulated to be in MIPS at the
299 * end of this routine.
300 */
301 if (eng->e_cpu_speed == 0 )
302 eng->e_cpu_speed = cpurate;
303 if (eng->e_cpu_speed < cpurate)
304 cpurate = eng->e_cpu_speed;
305 #ifdef E_FPU387
306 /*
307 * Set E_FPU387 and E_FPA in e_flags as appropriate.
308 * Bump NFPA for those available processors that have FPA's.
309 * Only set E_FPA if there is an FPA and it passed diagnostics.
310 */
311 if (cd->cd_p_fp & SLP_387)
312 eng->e_flags |= E_FPU387;
313 if (cd->cd_p_fp & SLP_FPA) {
314 if ((cd->cd_diag_flag & CFG_SP_FPA) == 0) {
315 eng->e_flags |= E_FPA;
316 ++NFPA;
317 }
318 }
319 #endif E_FPU387
320 Nengine++;
321
322 }
323 engine_Nengine = &engine[Nengine];
324 printf(".\n");
325
326 if (Nengine < toc->ct_count) {
327 printf("Not using processors: slic");
328 cd = PHYSTOKV(&va_CD_LOC->c_ctlrs[toc->ct_start],
329 struct ctlr_desc *);
330 for (i = 0; i < toc->ct_count; i++, cd++) {
331 if (cd->cd_diag_flag & (CFG_FAIL|CFG_DECONF))
332 printf(" %d", cd->cd_slic);
333 }
334 printf(".\n");
335 }
336 /*
337 * compute cpurate for delay loops. The value should
338 * correspond to the "mips" rating for the processor
339 * at its running rate.
340 * cd_p_speed: is an actual boards running rate
341 * e_cpu_speed: is the number of mips if
342 * sys_clock_rate = 100
343 * cpurate is only used for probe routines running on the
344 * "boot" processor.
345 */
346 cpurate = (lcpuspeed * cpurate) / 100;
347 }
348
349 /*
350 * conf_intr()
351 * Allocate and initialize interrupt vector table.
352 *
353 * Sysinit() already set up master HW vector table.
354 * Don't allocate anything for bin[0] (SW -- doesn't use this table).
355 */
356
357 conf_intr()
358 {
359 register int i;
360 register int vec;
361 extern todclock(); /* tod clock handler */
362 extern hardclock();
363
364 /*
365 * Add in local clock, tod clock to appropriate bins.
366 */
367
368 ivecres(LCLKBIN, 1);
369 ivecres(TODCLKBIN, 1);
370
371 /*
372 * Allocate int_bin_table, init all entries to point at strayint().
373 */
374
375 for (i = 1; i < SLICBINS; i++) {
376 if (bin_intr[i] == 0)
377 continue;
378 assert(bin_intr[i] <= MSGSPERBIN);
379 int_bin_table[i].bh_size = bin_intr[i];
380 int_bin_table[i].bh_hdlrtab =
381 (int(**)())calloc(bin_intr[i]*sizeof(int (*)()));
382 for (vec = 0; vec < int_bin_table[i].bh_size; vec++)
383 ivecinit(i, vec, strayint);
384 }
385
386 /*
387 * Set up vectors for local clock and tod clock.
388 * Must do LCLKBIN first, to insure it gets vector 0.
389 */
390
391 ivecinit(LCLKBIN, ivecall(LCLKBIN), hardclock);
392 ivecinit(TODCLKBIN, ivecall(TODCLKBIN), todclock);
393 }
394
395 /*
396 * conf_pseudo()
397 * Call the boot procedures of pseudo-devices.
398 */
399
400 conf_pseudo()
401 {
402 register struct pseudo_dev *pd;
403
404 printf("Pseudo devices:");
405 for (pd = pseudo_dev; pd->pd_name; pd++) {
406 printf(" %d %s", pd->pd_flags, pd->pd_name);
407 (*pd->pd_boot)(pd->pd_flags);
408 }
409 printf(".\n");
410 }
411
412 /*
413 * ivecall()
414 * Allocate a vector from a given bin.
415 *
416 * Insures sequential values returned per bin.
417 */
418
419 u_char
420 ivecall(bin)
421 u_char bin;
422 {
423 if (bin_alloc[bin] >= int_bin_table[bin].bh_size) {
424 printf("Too many vectors in bin %d.\n", bin);
425 panic("ivecall");
426 /*NOTREACHED*/
427 }
428 return(bin_alloc[bin]++);
429 }
430
431 /*
432 * strayint()
433 * Stray interrupt catcher.
434 *
435 * Doesn't report bin #; instead reports current value of SLIC local
436 * mask which allows inference of interrupting bin.
437 */
438
439 strayint(vec)
440 int vec; /* vector number within bin */
441 {
442 printf("Stray intr, vector %d ipl 0x%x.\n", vec, va_slic->sl_lmask);
443 }
444
445 /*
446 * bogusint()
447 * Called from locore.s when bad vector number presented
448 * from SLIC.
449 */
450
451 bogusint(bin, vec)
452 unsigned bin;
453 unsigned vec;
454 {
455 printf("Bogus interrupt vector %d on bin %d.\n", vec, bin);
456 }
Cache object: 78cfa121828d685c4ad790a18ffae41b
|