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: }