1: /*
   2:  * Now with all our information, make a configuration
   3:  * Devices without both attach and probe routines will
   4:  * not be configured into the system
   5:  */
   6: 
   7: #include    <stdio.h>
   8: #include    <a.out.h>
   9: #include    <sys/autoconfig.h>
  10: #include    <sys/trap.h>
  11: #include    <errno.h>
  12: #include    <sys/psw.h>
  13: #include    "dtab.h"
  14: #include    "ivec.h"
  15: 
  16: extern int kmem, verbose, debug, errno, complain;
  17: extern struct nlist *bad_nl, *good_nl, *int_nl, *end_vector, *trap_nl, *sep_nl;
  18: 
  19: grab(where)
  20: unsigned int where;
  21: {
  22:     int var;
  23: 
  24:     if (debug) {
  25:         char line[80];
  26: 
  27:         printf("Grab %o =", where);
  28:         gets(line);
  29:         return otoi(line);
  30:     }
  31:     lseek(kmem, ((long) where) & 0xffffL, 0);
  32:     read(kmem, &var, sizeof var);
  33:     return var;
  34: }
  35: 
  36: stuff(var, where)
  37: unsigned int where;
  38: {
  39:     char s[20];
  40: 
  41:     if (debug) {
  42:         printf("Stuff %o @ %o\n", var, where);
  43:         return;
  44:     }
  45:     lseek(kmem, ((long) where) & 0xffffL, 0);
  46:     if (write(kmem, &var, sizeof var) < sizeof var) {
  47:         sprintf(s, "stuff 0%o", where);
  48:         perror(s);
  49:     }
  50: }
  51: 
  52: prdev(dp)
  53: struct dtab_s *dp;
  54: {
  55:     printf("%s ", dp->dt_name);
  56:     if (dp->dt_unit == -1)
  57:         printf("?");
  58:     else
  59:         printf("%d", dp->dt_unit);
  60:     printf(" csr %o vector %o", dp->dt_addr, dp->dt_vector);
  61: }
  62: 
  63: /*
  64:  * Go through the configuration table and probe all the devices.  Call
  65:  * attach for ones which exist.  Probe routines should return
  66:  *	ACP_NXDEV	No such device
  67:  *	ACP_IFINTR	Device exists if interrupts ok
  68:  *	ACP_EXISTS	Device exists
  69:  * All interrupt vectors are poked to either point to conf_goodvec or
  70:  * conf_badvec which change the value of conf_int.  Values of this
  71:  * variable are:
  72:  *	ACI_BADINTR	Device interrupted through wrong vector
  73:  *	ACI_NOINTR	Device didn't interrupt
  74:  *	ACI_GOODINTR	Interrupt ok
  75:  */
  76: 
  77: auto_config()
  78: {
  79:     register struct dtab_s *dp;
  80:     int ret;
  81: 
  82:     if (intval() != CONF_MAGIC) {
  83:         fprintf(stderr, "Namelist doesn't match running kernel\n");
  84:         exit(AC_SETUP);
  85:     }
  86: 
  87:     init_lowcore(bad_nl->n_value);
  88: 
  89:     for (dp = devs; dp != NULL; dp = dp->dt_next) {
  90: 
  91:         /* Make sure we have both a probe and attach routine */
  92:         if (!((dp->dt_uprobe || (dp->dt_probe && dp->dt_probe->n_value))
  93:             && (dp->dt_attach && dp->dt_attach->n_value))) {
  94:             if (debug || verbose) {
  95:                 prdev(dp);
  96:                 printf(" skipped:  No autoconfig routines\n");
  97:             }
  98:             continue;
  99:         }
 100: 
 101:         /* Make sure the CSR is there */
 102:         errno = 0;
 103:         grab(dp->dt_addr);
 104:         if (errno) {
 105:             if (errno != EFAULT && errno != ENXIO)
 106:                 perror("Reading CSR");
 107:             if (debug || verbose) {
 108:                 prdev(dp);
 109:                 printf(" skipped:  No CSR\n");
 110:             }
 111:             detach(dp);
 112:             continue;
 113:         }
 114: 
 115:         /* Ok, try a probe now */
 116:         if (expect_intr(dp)) {
 117:             if (complain) {
 118:                 prdev(dp);
 119:                 printf(" interrupt vector already in use\n");
 120:             }
 121:             detach(dp);
 122:             continue;
 123:         }
 124:         ret = do_probe(dp, dp->dt_addr);
 125:         clear_vec(dp);
 126:         switch (ret) {
 127:             case ACP_NXDEV:
 128:                 if (debug || verbose) {
 129:                     prdev(dp);
 130:                     printf(" does not exist\n");
 131:                 }
 132:                 detach(dp);
 133:                 break;
 134:             case ACP_IFINTR:
 135:                 switch (intval()) {
 136:                     case ACI_BADINTR:
 137:                         if (debug || verbose || complain) {
 138:                             prdev(dp);
 139:                             printf(" interrupt vector wrong\n");
 140:                         }
 141:                         detach(dp);
 142:                         break;
 143:                     case ACI_NOINTR:
 144:                         if (complain) {
 145:                             prdev(dp);
 146:                             printf(" didn't interrupt\n");
 147:                         }
 148:                         detach(dp);
 149:                         break;
 150:                     case ACI_GOODINTR:
 151:                         attach(dp);
 152:                         break;
 153:                     default:
 154:                         prdev(dp);
 155:                         printf(" bad interrupt value %d\n", intval());
 156:                         break;
 157:                 }
 158:                 break;
 159: 
 160:             case ACP_EXISTS:
 161:                 attach(dp);
 162:                 break;
 163: 
 164:             default:
 165:                 prdev(dp);
 166:                 printf(" bad probe value %d\n", ret);
 167:                 break;
 168:         }
 169:     }
 170:     set_unused();
 171: }
 172: 
 173: /*
 174:  * Return the current value of the interrupt return flag.
 175:  * Initial value is the magic number
 176:  */
 177: 
 178: static int conf_int = CONF_MAGIC;
 179: 
 180: intval()
 181: {
 182:     if (debug)
 183:         return conf_int;
 184:     else
 185:         return grab(int_nl->n_value);
 186: }
 187: 
 188: static int save_vec[9][2], save_p;
 189: 
 190: /*
 191:  * Fill all interrupt vectors of this device with pointers to
 192:  * the good interrupt vector routine.  Also save values to
 193:  * later restore them.  Since we init_lowcore() everything to
 194:  * conf_badint, anything not equalling that indicates a vector
 195:  * which is already in use; unless the vector was initialized in l.s,
 196:  * this device should be skipped.
 197:  */
 198: 
 199: expect_intr(dp)
 200: struct dtab_s *dp;
 201: {
 202:     struct handler_s *hp;
 203:     int addr;
 204: 
 205:     addr = dp->dt_vector;
 206:     for (save_p = 0, hp = dp->dt_handlers; hp != NULL; hp = hp->s_next) {
 207:         save_vec[save_p][1] = grab(addr + sizeof(int));
 208:         if (((save_vec[save_p][0] = grab(addr)) != bad_nl->n_value)
 209:             && ((save_vec[save_p][0] != hp->s_nl->n_value)
 210:             || have_set(addr))) {
 211:             clear_vec(dp);
 212:             return 1;
 213:         }
 214:         save_p ++;
 215:         write_vector(addr, good_nl->n_value, PS_BR7);
 216:         addr += IVSIZE;
 217:     }
 218:     return 0;
 219: }
 220: 
 221: clear_vec(dp)
 222: register struct dtab_s *dp;
 223: {
 224:     register int addr = dp->dt_vector, n;
 225: 
 226:     for (n = 0; n < save_p; n++) {
 227:         write_vector(addr, save_vec[n][0], save_vec[n][1]);
 228:         addr += IVSIZE;
 229:     }
 230: }
 231: 
 232: init_lowcore(val)
 233: {
 234:     int addr;
 235: 
 236:     if (debug)
 237:         return;
 238:     for (addr = 0; addr < end_vector->n_value; addr += IVSIZE) {
 239:         if (grab(addr) || grab(addr + 2))
 240:             continue;
 241:         write_vector(addr, val, PS_BR7);
 242:     }
 243: }
 244: 
 245: do_probe(dp, a1)
 246: register struct dtab_s *dp;
 247: int a1;
 248: {
 249:     int func;
 250:     int ret;
 251: 
 252:     func = dp->dt_probe->n_value;
 253:     if (debug) {
 254:         char line[80];
 255: 
 256:         if (func)
 257:             printf("ucall %o(PS_BR0, %o, 0):", func, a1);
 258:         else
 259:             printf("probe %s:", dp->dt_name);
 260:         printf(" return conf_int:");
 261:         gets(line);
 262:         sscanf(line, "%o%o", &ret, &conf_int);
 263:         return ret;
 264:     }
 265:     stuff(0, int_nl->n_value);  /* Clear conf_int */
 266:     /*
 267: 	 * use the kernel's probe routine if it exists,
 268: 	 * otherwise use our internal probe.
 269: 	 */
 270:     if (func) {
 271:         errno = 0;
 272:         ret = ucall(PS_BR0, func, a1, 0);
 273:         if (errno)
 274:             perror("ucall");
 275:         return(ret);
 276:     }
 277:     return((*(dp->dt_uprobe))(a1));
 278: }
 279: 
 280: set_unused()
 281: {
 282:     int addr;
 283: 
 284:     if (debug)
 285:         return;
 286:     if (sep_nl->n_value) {
 287:         /*
 288: 		 * On non-separate I/D kernel, attempt to set up catcher
 289: 		 * at 0 for both jumps and traps to 0.
 290: 		 * On traps, set PS for randomtrap, with the catcher at 0444.
 291: 		 * On jumps, branch to 0112, then to 050 (where there's space).
 292: 		 * The handler at 50 is already in place.
 293: 		 * The funny numbers are due to attempts to find vectors
 294: 		 * that are unlikely to be used, and the need for the value
 295: 		 * at 0 to serve as both a vector and an instruction
 296: 		 * (br 112 is octal 444).
 297: 		 */
 298:         if ((grab(0110) == bad_nl->n_value) && (grab(0112) == PS_BR7)
 299:             && (grab(0444) == bad_nl->n_value) && (grab(0446) == PS_BR7)) {
 300:             stuff(0444, 0);         /* br 0112 */
 301:             stuff(PS_BR7 + ZEROTRAP, 2);
 302:             stuff(trap_nl->n_value, 0110);  /* trap; 756 (br7+14.)*/
 303:             stuff(0756, 0112);      /* br 050 */
 304:             stuff(0137, 0444);      /* jmp $*trap */
 305:             stuff(trap_nl->n_value, 0446);
 306:         }
 307:     }
 308:     for (addr = 0; addr < end_vector->n_value; addr += IVSIZE) {
 309:         if (grab(addr) != bad_nl->n_value)
 310:             continue;
 311:         write_vector(addr, trap_nl->n_value, PS_BR7+RANDOMTRAP);
 312:     }
 313: }

Defined functions

auto_config defined in line 77; used 1 times
clear_vec defined in line 221; used 2 times
do_probe defined in line 245; used 1 times
expect_intr defined in line 199; used 1 times
grab defined in line 19; used 18 times
init_lowcore defined in line 232; used 1 times
  • in line 87
intval defined in line 180; used 3 times
prdev defined in line 52; used 14 times
set_unused defined in line 280; used 1 times
stuff defined in line 36; used 47 times

Defined variables

conf_int defined in line 178; used 2 times
save_p defined in line 188; used 6 times
save_vec defined in line 188; used 5 times
Last modified: 1983-10-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1369
Valid CSS Valid XHTML 1.0 Strict