# 2.11BSD#431 - /usr/src/sys/autoconfig/do_config.c

##### Functions

    auto_config       X
    clear_vec         X
    do_probe          X
    expect_intr       X
    grab              X
    init_lowcore      X
    intval            X
    prdev             X
    set_unused        X
    stuff             X

       1: /*
       2:  * Copyright (c) 1986 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  *
       6:  *	@(#)do_config.c	2.1 (2.11BSD GTE) 12/30/92
       7:  */
       8:
       9: /*
      10:  * Now with all our information, make a configuration
      11:  * Devices without both attach and probe routines will
      12:  * not be configured into the system
      13:  */
      14:
      15: #include <machine/psl.h>
      16: #include <machine/trap.h>
      17: #include <machine/autoconfig.h>
      18: #include <sys/types.h>
      19: #include <a.out.h>
      20: #include <errno.h>
      21: #include <stdio.h>
      22: #include "dtab.h"
      23: #include "ivec.h"
      24:
      25: extern  int kmem, verbose, debug, errno, complain;
      26: extern  NLIST   *bad_nl, *good_nl, *int_nl, *end_vector, *trap_nl, *sep_nl;
      27: extern  NLIST   *next_nl;
      28:
      29: grab(where)
      30: u_int   where;
      31: {
      32:     int var;
      33:
      34:     lseek(kmem,((long) where) & 0xffffL,0);
      35:     read(kmem,&var,sizeof(var));
      36:     if (debug)
      37:         printf("Grab %o = %o",where, var);
      38:     return(var);
      39: }
      40:
      41: stuff(var, where)
      42: unsigned int where;
      43: {
      44:     char s[20];
      45:
      46:     if (debug) {
      47:         printf("Stuff %o @ %o\n", var, where);
      48:         return;
      49:     }
      50:     lseek(kmem, ((long) where) & 0xffffL, 0);
      51:     if (write(kmem, &var, sizeof var) < sizeof var) {
      52:         sprintf(s, "stuff 0%o", where);
      53:         perror(s);
      54:     }
      55: }
      56:
      57: prdev(dp)
      58: DTAB    *dp;
      59: {
      60:     printf("%s ", dp->dt_name);
      61:     if (dp->dt_unit == -1)
      62:         putchar('?');
      63:     else
      64:         printf("%d", dp->dt_unit);
      65:     printf(" csr %o vector %o", dp->dt_addr, dp->dt_vector);
      66: }
      67:
      68: /*
      69:  * Go through the configuration table and probe all the devices.  Call
      70:  * attach for ones which exist.  Probe routines should return
      71:  *	ACP_NXDEV	No such device
      72:  *	ACP_IFINTR	Device exists if interrupts ok
      73:  *	ACP_EXISTS	Device exists
      74:  * All interrupt vectors are poked to either point to conf_goodvec or
      75:  * conf_badvec which change the value of conf_int.  Values of this
      76:  * variable are:
      77:  *	ACI_BADINTR	Device interrupted through wrong vector
      78:  *	ACI_NOINTR	Device didn't interrupt
      79:  *	ACI_GOODINTR	Interrupt ok
      80:  */
      81:
      82: auto_config()
      83: {
      84:     register DTAB   *dp;
      85:     int ret;
      86:
      87:     if (intval() != CONF_MAGIC) {
      88:         fputs(myname,stderr);
      89:         fputs(": namelist doesn't match running kernel.\n",stderr);
      90:         exit(AC_SETUP);
      91:     }
      92:
      93:     init_lowcore(bad_nl->n_value);
      94:
      95:     for (dp = devs; dp != NULL; dp = dp->dt_next) {
      96:         /*
      97: 		 * Make sure we have both a probe and attach routine
      98: 		 */
      99:         if (!((dp->dt_uprobe || (dp->dt_probe && dp->dt_probe->n_value))
     100:             && (dp->dt_attach && dp->dt_attach->n_value))) {
     101:             if (debug || verbose) {
     102:                 prdev(dp);
     103:                 puts(" skipped:  No autoconfig routines.");
     104:             }
     105:             continue;
     106:         }           /* Make sure the CSR is there */
     107:         errno = 0;
     108:         grab(dp->dt_addr);
     109:         if (errno) {
     110:             if (errno != EFAULT && errno != ENXIO)
     111:                 perror("Reading CSR");
     112:             if (debug || verbose) {
     113:                 prdev(dp);
     114:                 puts(" skipped:  No CSR.");
     115:             }
     116:             continue;
     117:         }           /* Ok, try a probe now */
     118:         if (expect_intr(dp)) {
     119:             if (complain) {
     120:                 prdev(dp);
     121:                 puts(" interrupt vector already in use.");
     122:             }
     123:             continue;
     124:         }
     125:         ret = do_probe(dp);
     126:         clear_vec(dp);
     127:         switch (ret) {
     128:             case ACP_NXDEV:
     129:                 if (debug || verbose) {
     130:                     prdev(dp);
     131:                     puts(" does not exist.");
     132:                 }
     133:                 break;
     134:             case ACP_IFINTR:
     135:                 switch (intval()) {
     136:                     case ACI_BADINTR:
     137:                         if (debug || verbose || complain) {
     138:                             prdev(dp);
     139:                             puts(" interrupt vector wrong.");
     140:                         }
     141:                         break;
     142:                     case ACI_NOINTR:
     143:                         if (complain) {
     144:                             prdev(dp);
     145:                             puts(" didn't interrupt.");
     146:                         }
     147:                         break;
     148:                     case ACI_GOODINTR:
     149:                         attach(dp);
     150:                         break;
     151:                     default:
     152:                         prdev(dp);
     153:                         printf(" bad interrupt value %d.\n", intval());
     154:                         break;
     155:                 }
     156:                 break;
     157:             case ACP_EXISTS:
     158:                 attach(dp);
     159:                 break;
     160:             default:
     161:                 prdev(dp);
     162:                 printf(" bad probe value %d.\n", ret);
     163:                 break;
     164:         }
     165:     }
     166:     set_unused();
     167: }
     168:
     169: /*
     170:  * Return the current value of the interrupt return flag.
     171:  * Initial value is the magic number
     172:  */
     173:
     174: static int conf_int = CONF_MAGIC;
     175:
     176: intval()
     177: {
     178:     if (debug)
     179:         return conf_int;
     180:     else
     181:         return grab(int_nl->n_value);
     182: }
     183:
     184: static int save_vec[9][2], save_p;
     185:
     186: /*
     187:  * Fill all interrupt vectors of this device with pointers to
     188:  * the good interrupt vector routine.  Also save values to
     189:  * later restore them.  Since we init_lowcore() everything to
     190:  * conf_badint, anything not equalling that indicates a vector
     191:  * which is already in use; unless the vector was initialized in l.s,
     192:  * this device should be skipped.
     193:  */
     194:
     195: expect_intr(dp)
     196: DTAB    *dp;
     197: {
     198:     HAND    *hp;
     199:     register int    addr = dp->dt_vector;
     200:
     201: /*
     202:  * A vector of 0 has special meaning for devices which support programmable
     203:  * (settable) vectors.  If a xxVec() entry point is present in the driver and
     204:  * /etc/dtab has a value of 0 for the vector then 'autoconfig' will allocate
     205:  * one by calling the kernel routine 'nextiv'.
     206:  *
     207:  * If multiple handlers are declared for a device (at present there are no
     208:  * progammable vector devices with more than 1 handler) the vector passed
     209:  * to the driver will be the lowest one (the first handle corresponds to
     210:  * the lowest vector).
     211: */
     212:     if (!addr) {
     213:         if (dp->dt_setvec == 0) {
     214:             prdev(dp);
     215:             printf(" vector = 0, %sVec undefined\n", dp->dt_name);
     216:             return(1);
     217:         }
     218: /*
     219:  * Now count the number of vectors needed.  This has the side effect of
     220:  * allocating the vectors even if an error occurs later.  At the end of
     221:  * the scan the last vector assigned will be the lowest one.  In order to
     222:  * assure adjacency of multiple vectors BR7 is used in the call to the
     223:  * kernel and it is assumed that at this point in the system's life
     224:  * nothing else is allocating vectors (the networking has already grabbed the
     225:  * ones it needs by the time autoconfig is run).
     226: */
     227:         for (hp = dp->dt_handlers; hp; hp = hp->s_next) {
     228:             addr = ucall(PSL_BR7, next_nl->n_value, 0, 0);
     229:             if (addr <= 0) {
     230:                 printf("'nextiv' error for %s\n",
     231:                     dp->dt_name);
     232:                 return(1);
     233:             }
     234:         }
     235: /*
     236:  * Now set the lowest vector allocated into the device entry for further
     237:  * processing.  From this point on the vector will behave just as if it
     238:  * had been read from /etc/dtab.
     239: */
     240:         dp->dt_vector = addr;
     241:     }
     242:
     243:     for (save_p = 0, hp = (HAND *)dp->dt_handlers;hp;hp = hp->s_next) {
     244:         save_vec[save_p][1] = grab(addr + sizeof(int));
     245:         if (((save_vec[save_p][0] = grab(addr)) != bad_nl->n_value)
     246:             && ((save_vec[save_p][0] != hp->s_nl->n_value)
     247:             || have_set(addr))) {
     248:             clear_vec(dp);
     249:             return 1;
     250:         }
     251:         save_p++;
     252:         write_vector(addr, good_nl->n_value, PSL_BR7);
     253:         addr += IVSIZE;
     254:     }
     255:     return 0;
     256: }
     257:
     258: clear_vec(dp)
     259: register DTAB   *dp;
     260: {
     261:     register int addr = dp->dt_vector, n;
     262:
     263:     for (n = 0; n < save_p; n++) {
     264:         write_vector(addr, save_vec[n][0], save_vec[n][1]);
     265:         addr += IVSIZE;
     266:     }
     267: }
     268:
     269: init_lowcore(val)
     270: {
     271:     int addr;
     272:
     273:     if (debug)
     274:         return;
     275:     for (addr = 0; addr < end_vector->n_value; addr += IVSIZE) {
     276:         if (grab(addr) || grab(addr + 2))
     277:             continue;
     278:         write_vector(addr, val, PSL_BR7);
     279:     }
     280: }
     281:
     282: do_probe(dp)
     283: register DTAB   *dp;
     284: {
     285:     int func;
     286:     int ret;
     287:
     288:     func = dp->dt_probe->n_value;
     289:     if (debug) {
     290:         char line[80];
     291:
     292:         if (func)
     293:             printf("ucall %o(PSL_BR0, %o, 0):", func, dp->dt_addr);
     294:         else
     295:             printf("probe %s:", dp->dt_name);
     296:         fputs(" return conf_int:",stdout);
     297:         gets(line);
     298:         sscanf(line, "%o%o", &ret, &conf_int);
     299:         return ret;
     300:     }
     301:     stuff(0, int_nl->n_value);  /* Clear conf_int */
     302:     /*
     303: 	 * use the kernel's probe routine if it exists,
     304: 	 * otherwise use our internal probe.  Pass it the first (lowest)
     305: 	 * vector assigned to the device.
     306: 	 */
     307:     if (func) {
     308:         errno = 0;
     309:         ret = ucall(PSL_BR0, func, dp->dt_addr, dp->dt_vector);
     310:         if (errno)
     311:             perror("ucall");
     312:         return(ret);
     313:     }
     314:     return((*(dp->dt_uprobe))(dp->dt_addr,  dp->dt_vector));
     315: }
     316:
     317: set_unused()
     318: {
     319:     int addr;
     320:
     321:     if (debug)
     322:         return;
     323:     if (sep_nl->n_value) {
     324:         /*
     325: 		 * On non-separate I/D kernel, attempt to set up catcher
     326: 		 * at 0 for both jumps and traps to 0.
     327: 		 * On traps, set PS for randomtrap, with the catcher at 0444.
     328: 		 * On jumps, branch to 0112, then to 050 (where there's space).
     329: 		 * The handler at 50 is already in place.
     330: 		 * The funny numbers are due to attempts to find vectors
     331: 		 * that are unlikely to be used, and the need for the value
     332: 		 * at 0 to serve as both a vector and an instruction
     333: 		 * (br 112 is octal 444).
     334: 		 */
     335:         if ((grab(0110) == bad_nl->n_value) && (grab(0112) == PSL_BR7)
     336:             && (grab(0444) == bad_nl->n_value) && (grab(0446) == PSL_BR7)) {
     337:             stuff(0444, 0);         /* br 0112 */
     338:             stuff(PSL_BR7 + T_ZEROTRAP, 2);
     339:             stuff(trap_nl->n_value, 0110);  /* trap; 756 (br7+14.)*/
     340:             stuff(0756, 0112);      /* br 050 */
     341:             stuff(0137, 0444);      /* jmp $*trap */
     342:             stuff(trap_nl->n_value, 0446);
     343:         }
     344:     }
     345:     for (addr = 0; addr < end_vector->n_value; addr += IVSIZE) {
     346:         if (grab(addr) != bad_nl->n_value)
     347:             continue;
     348:         write_vector(addr, trap_nl->n_value, PSL_BR7+T_RANDOMTRAP);
     349:     }
     350: }

#### Defined functions

auto_config defined in line 82; used 1 times

- in /usr/src/sys/autoconfig/main.c line 80

clear_vec defined in line 258; used 2 times

- in line 126, 248

do_probe defined in line 282; used 1 times

- in line 125

expect_intr defined in line 195; used 1 times

- in line 118

grab defined in line 29; used 22 times

- in line 108, 181, 244-245(2), 276(2), 335-336(4), 346
- in /usr/src/sys/autoconfig/cnauto.c line 17
- in /usr/src/sys/autoconfig/dhauto.c line 37
- in /usr/src/sys/autoconfig/dhuauto.c line 20
- in /usr/src/sys/autoconfig/dhvauto.c line 18-20(2)
- in /usr/src/sys/autoconfig/dzauto.c line 19
- in /usr/src/sys/autoconfig/lpauto.c line 27
- in /usr/src/sys/autoconfig/raauto.c line 25
- in /usr/src/sys/autoconfig/tmauto.c line 22
- in /usr/src/sys/autoconfig/tmsauto.c line 27
- in /usr/src/sys/autoconfig/tsauto.c line 33

init_lowcore defined in line 269; used 1 times

- in line 93

intval defined in line 176; used 3 times

- in line 87, 135, 153

prdev defined in line 57; used 14 times

- in line 102, 113, 120, 130, 138, 144, 152, 161, 214
- in /usr/src/sys/autoconfig/attach.c line 43, 52, 64, 77, 110

set_unused defined in line 317; used 1 times

- in line 166

stuff defined in line 41; used 49 times

- in line 301, 337-342(6)
- in /usr/src/sys/autoconfig/attach.c line 122-123(2)
- in /usr/src/sys/autoconfig/cnauto.c line 17
- in /usr/src/sys/autoconfig/dhauto.c line 21-29(6), 37-39(2)
- in /usr/src/sys/autoconfig/dhvauto.c line 22-24(2)
- in /usr/src/sys/autoconfig/dnauto.c line 10-12(2)
- in /usr/src/sys/autoconfig/drauto.c line 19-20(2)
- in /usr/src/sys/autoconfig/dzauto.c line 19-23(3)
- in /usr/src/sys/autoconfig/hkauto.c line 19-21(2)
- in /usr/src/sys/autoconfig/htauto.c line 25-33(4)
- in /usr/src/sys/autoconfig/lpauto.c line 27-29(2)
- in /usr/src/sys/autoconfig/rkauto.c line 19-21(2)
- in /usr/src/sys/autoconfig/rlauto.c line 20
- in /usr/src/sys/autoconfig/rxauto.c line 21-26(4)
- in /usr/src/sys/autoconfig/siauto.c line 19-22(3)
- in /usr/src/sys/autoconfig/tmauto.c line 20
- in /usr/src/sys/autoconfig/tsauto.c line 29
- in /usr/src/sys/autoconfig/xpauto.c line 25-27(2)

#### Defined variables

conf_int defined in line 174; used 2 times

- in line 179, 298

save_p defined in line 184; used 6 times

- in line 243-251(5), 263

save_vec defined in line 184; used 5 times

- in line 244-246(3), 264(2)

Last modified: 1994-01-15 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1285 |