The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sqt/autoconf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.