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

Cache object: aea916d1b870115cb7498f518eeb4900


[ 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.