1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)mkioconf.c 5.10 (Berkeley) 06/18/88"; 20 #endif /* not lint */ 21 22 #include <stdio.h> 23 #include "y.tab.h" 24 #include "config.h" 25 26 /* 27 * build the ioconf.c file 28 */ 29 char *qu(); 30 char *intv(); 31 32 #if MACHINE_VAX 33 vax_ioconf() 34 { 35 register struct device *dp, *mp, *np; 36 register int uba_n, slave; 37 FILE *fp; 38 39 fp = fopen(path("ioconf.c"), "w"); 40 if (fp == 0) { 41 perror(path("ioconf.c")); 42 exit(1); 43 } 44 fprintf(fp, "#include \"../machine/pte.h\"\n"); 45 fprintf(fp, "#include \"../h/param.h\"\n"); 46 fprintf(fp, "#include \"../h/buf.h\"\n"); 47 fprintf(fp, "#include \"../h/map.h\"\n"); 48 fprintf(fp, "#include \"../h/vm.h\"\n"); 49 fprintf(fp, "\n"); 50 fprintf(fp, "#include \"../vaxmba/mbavar.h\"\n"); 51 fprintf(fp, "#include \"../vaxuba/ubavar.h\"\n\n"); 52 fprintf(fp, "\n"); 53 fprintf(fp, "#define C (caddr_t)\n\n"); 54 /* 55 * First print the mba initialization structures 56 */ 57 if (seen_mba) { 58 for (dp = dtab; dp != 0; dp = dp->d_next) { 59 mp = dp->d_conn; 60 if (mp == 0 || mp == TO_NEXUS || 61 !eq(mp->d_name, "mba")) 62 continue; 63 fprintf(fp, "extern struct mba_driver %sdriver;\n", 64 dp->d_name); 65 } 66 fprintf(fp, "\nstruct mba_device mbdinit[] = {\n"); 67 fprintf(fp, "\t/* Device, Unit, Mba, Drive, Dk */\n"); 68 for (dp = dtab; dp != 0; dp = dp->d_next) { 69 mp = dp->d_conn; 70 if (dp->d_unit == QUES || mp == 0 || 71 mp == TO_NEXUS || !eq(mp->d_name, "mba")) 72 continue; 73 if (dp->d_addr) { 74 printf("can't specify csr address on mba for %s%d\n", 75 dp->d_name, dp->d_unit); 76 continue; 77 } 78 if (dp->d_vec != 0) { 79 printf("can't specify vector for %s%d on mba\n", 80 dp->d_name, dp->d_unit); 81 continue; 82 } 83 if (dp->d_drive == UNKNOWN) { 84 printf("drive not specified for %s%d\n", 85 dp->d_name, dp->d_unit); 86 continue; 87 } 88 if (dp->d_slave != UNKNOWN) { 89 printf("can't specify slave number for %s%d\n", 90 dp->d_name, dp->d_unit); 91 continue; 92 } 93 fprintf(fp, "\t{ &%sdriver, %d, %s,", 94 dp->d_name, dp->d_unit, qu(mp->d_unit)); 95 fprintf(fp, " %s, %d },\n", 96 qu(dp->d_drive), dp->d_dk); 97 } 98 fprintf(fp, "\t0\n};\n\n"); 99 /* 100 * Print the mbsinit structure 101 * Driver Controller Unit Slave 102 */ 103 fprintf(fp, "struct mba_slave mbsinit [] = {\n"); 104 fprintf(fp, "\t/* Driver, Ctlr, Unit, Slave */\n"); 105 for (dp = dtab; dp != 0; dp = dp->d_next) { 106 /* 107 * All slaves are connected to something which 108 * is connected to the massbus. 109 */ 110 if ((mp = dp->d_conn) == 0 || mp == TO_NEXUS) 111 continue; 112 np = mp->d_conn; 113 if (np == 0 || np == TO_NEXUS || 114 !eq(np->d_name, "mba")) 115 continue; 116 fprintf(fp, "\t{ &%sdriver, %s", 117 mp->d_name, qu(mp->d_unit)); 118 fprintf(fp, ", %2d, %s },\n", 119 dp->d_unit, qu(dp->d_slave)); 120 } 121 fprintf(fp, "\t0\n};\n\n"); 122 } 123 /* 124 * Now generate interrupt vectors for the unibus 125 */ 126 for (dp = dtab; dp != 0; dp = dp->d_next) { 127 if (dp->d_vec != 0) { 128 struct idlst *ip; 129 mp = dp->d_conn; 130 if (mp == 0 || mp == TO_NEXUS || 131 (!eq(mp->d_name, "uba") && !eq(mp->d_name, "bi"))) 132 continue; 133 fprintf(fp, 134 "extern struct uba_driver %sdriver;\n", 135 dp->d_name); 136 fprintf(fp, "extern "); 137 ip = dp->d_vec; 138 for (;;) { 139 fprintf(fp, "X%s%d()", ip->id, dp->d_unit); 140 ip = ip->id_next; 141 if (ip == 0) 142 break; 143 fprintf(fp, ", "); 144 } 145 fprintf(fp, ";\n"); 146 fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name, 147 dp->d_unit); 148 ip = dp->d_vec; 149 for (;;) { 150 fprintf(fp, "X%s%d", ip->id, dp->d_unit); 151 ip = ip->id_next; 152 if (ip == 0) 153 break; 154 fprintf(fp, ", "); 155 } 156 fprintf(fp, ", 0 } ;\n"); 157 } 158 } 159 fprintf(fp, "\nstruct uba_ctlr ubminit[] = {\n"); 160 fprintf(fp, "/*\t driver,\tctlr,\tubanum,\talive,\tintr,\taddr */\n"); 161 for (dp = dtab; dp != 0; dp = dp->d_next) { 162 mp = dp->d_conn; 163 if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || 164 !eq(mp->d_name, "uba")) 165 continue; 166 if (dp->d_vec == 0) { 167 printf("must specify vector for %s%d\n", 168 dp->d_name, dp->d_unit); 169 continue; 170 } 171 if (dp->d_addr == 0) { 172 printf("must specify csr address for %s%d\n", 173 dp->d_name, dp->d_unit); 174 continue; 175 } 176 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 177 printf("drives need their own entries; dont "); 178 printf("specify drive or slave for %s%d\n", 179 dp->d_name, dp->d_unit); 180 continue; 181 } 182 if (dp->d_flags) { 183 printf("controllers (e.g. %s%d) ", 184 dp->d_name, dp->d_unit); 185 printf("don't have flags, only devices do\n"); 186 continue; 187 } 188 fprintf(fp, 189 "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0%o },\n", 190 dp->d_name, dp->d_unit, qu(mp->d_unit), 191 dp->d_name, dp->d_unit, dp->d_addr); 192 } 193 fprintf(fp, "\t0\n};\n"); 194 /* unibus devices */ 195 fprintf(fp, "\nstruct uba_device ubdinit[] = {\n"); 196 fprintf(fp, 197 "\t/* driver, unit, ctlr, ubanum, slave, intr, addr, dk, flags*/\n"); 198 for (dp = dtab; dp != 0; dp = dp->d_next) { 199 mp = dp->d_conn; 200 if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || 201 mp == TO_NEXUS || mp->d_type == MASTER || 202 eq(mp->d_name, "mba")) 203 continue; 204 np = mp->d_conn; 205 if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba")) 206 continue; 207 np = 0; 208 if (eq(mp->d_name, "uba")) { 209 if (dp->d_vec == 0) { 210 printf("must specify vector for device %s%d\n", 211 dp->d_name, dp->d_unit); 212 continue; 213 } 214 if (dp->d_addr == 0) { 215 printf("must specify csr for device %s%d\n", 216 dp->d_name, dp->d_unit); 217 continue; 218 } 219 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 220 printf("drives/slaves can be specified "); 221 printf("only for controllers, "); 222 printf("not for device %s%d\n", 223 dp->d_name, dp->d_unit); 224 continue; 225 } 226 uba_n = mp->d_unit; 227 slave = QUES; 228 } else { 229 if ((np = mp->d_conn) == 0) { 230 printf("%s%d isn't connected to anything ", 231 mp->d_name, mp->d_unit); 232 printf(", so %s%d is unattached\n", 233 dp->d_name, dp->d_unit); 234 continue; 235 } 236 uba_n = np->d_unit; 237 if (dp->d_drive == UNKNOWN) { 238 printf("must specify ``drive number'' "); 239 printf("for %s%d\n", dp->d_name, dp->d_unit); 240 continue; 241 } 242 /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ 243 /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ 244 if (dp->d_slave != UNKNOWN) { 245 printf("slave numbers should be given only "); 246 printf("for massbus tapes, not for %s%d\n", 247 dp->d_name, dp->d_unit); 248 continue; 249 } 250 if (dp->d_vec != 0) { 251 printf("interrupt vectors should not be "); 252 printf("given for drive %s%d\n", 253 dp->d_name, dp->d_unit); 254 continue; 255 } 256 if (dp->d_addr != 0) { 257 printf("csr addresses should be given only "); 258 printf("on controllers, not on %s%d\n", 259 dp->d_name, dp->d_unit); 260 continue; 261 } 262 slave = dp->d_drive; 263 } 264 fprintf(fp, "\t{ &%sdriver, %2d, %s,", 265 eq(mp->d_name, "uba") ? dp->d_name : mp->d_name, dp->d_unit, 266 eq(mp->d_name, "uba") ? " -1" : qu(mp->d_unit)); 267 fprintf(fp, " %s, %2d, %s, C 0%-6o, %d, 0x%x },\n", 268 qu(uba_n), slave, intv(dp), dp->d_addr, dp->d_dk, 269 dp->d_flags); 270 } 271 fprintf(fp, "\t0\n};\n"); 272 (void) fclose(fp); 273 } 274 #endif 275 276 #if MACHINE_TAHOE 277 tahoe_ioconf() 278 { 279 register struct device *dp, *mp, *np; 280 register int vba_n, slave; 281 FILE *fp; 282 283 fp = fopen(path("ioconf.c"), "w"); 284 if (fp == 0) { 285 perror(path("ioconf.c")); 286 exit(1); 287 } 288 fprintf(fp, "#include \"../h/param.h\"\n"); 289 fprintf(fp, "#include \"../machine/pte.h\"\n"); 290 fprintf(fp, "#include \"../h/buf.h\"\n"); 291 fprintf(fp, "#include \"../h/map.h\"\n"); 292 fprintf(fp, "\n"); 293 fprintf(fp, "#include \"../tahoevba/vbavar.h\"\n"); 294 fprintf(fp, "\n"); 295 fprintf(fp, "#define C (caddr_t)\n\n"); 296 /* 297 * Now generate interrupt vectors for the versabus 298 */ 299 for (dp = dtab; dp != 0; dp = dp->d_next) { 300 mp = dp->d_conn; 301 if (mp == 0 || mp == TO_NEXUS || !eq(mp->d_name, "vba")) 302 continue; 303 if (dp->d_vec != 0) { 304 struct idlst *ip; 305 fprintf(fp, 306 "extern struct vba_driver %sdriver;\n", 307 dp->d_name); 308 fprintf(fp, "extern "); 309 ip = dp->d_vec; 310 for (;;) { 311 fprintf(fp, "X%s%d()", ip->id, dp->d_unit); 312 ip = ip->id_next; 313 if (ip == 0) 314 break; 315 fprintf(fp, ", "); 316 } 317 fprintf(fp, ";\n"); 318 fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name, 319 dp->d_unit); 320 ip = dp->d_vec; 321 for (;;) { 322 fprintf(fp, "X%s%d", ip->id, dp->d_unit); 323 ip = ip->id_next; 324 if (ip == 0) 325 break; 326 fprintf(fp, ", "); 327 } 328 fprintf(fp, ", 0 } ;\n"); 329 } else if (dp->d_type == DRIVER) /* devices w/o interrupts */ 330 fprintf(fp, 331 "extern struct vba_driver %sdriver;\n", 332 dp->d_name); 333 } 334 fprintf(fp, "\nstruct vba_ctlr vbminit[] = {\n"); 335 fprintf(fp, "/*\t driver,\tctlr,\tvbanum,\talive,\tintr,\taddr */\n"); 336 for (dp = dtab; dp != 0; dp = dp->d_next) { 337 mp = dp->d_conn; 338 if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || 339 !eq(mp->d_name, "vba")) 340 continue; 341 if (dp->d_vec == 0) { 342 printf("must specify vector for %s%d\n", 343 dp->d_name, dp->d_unit); 344 continue; 345 } 346 if (dp->d_addr == 0) { 347 printf("must specify csr address for %s%d\n", 348 dp->d_name, dp->d_unit); 349 continue; 350 } 351 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 352 printf("drives need their own entries; dont "); 353 printf("specify drive or slave for %s%d\n", 354 dp->d_name, dp->d_unit); 355 continue; 356 } 357 if (dp->d_flags) { 358 printf("controllers (e.g. %s%d) ", 359 dp->d_name, dp->d_unit); 360 printf("don't have flags, only devices do\n"); 361 continue; 362 } 363 fprintf(fp, 364 "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0x%x },\n", 365 dp->d_name, dp->d_unit, qu(mp->d_unit), 366 dp->d_name, dp->d_unit, dp->d_addr); 367 } 368 fprintf(fp, "\t0\n};\n"); 369 /* versabus devices */ 370 fprintf(fp, "\nstruct vba_device vbdinit[] = {\n"); 371 fprintf(fp, 372 "\t/* driver, unit, ctlr, vbanum, slave, intr, addr, dk, flags*/\n"); 373 for (dp = dtab; dp != 0; dp = dp->d_next) { 374 mp = dp->d_conn; 375 if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || 376 mp == TO_NEXUS || mp->d_type == MASTER || 377 eq(mp->d_name, "mba")) 378 continue; 379 np = mp->d_conn; 380 if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba")) 381 continue; 382 np = 0; 383 if (eq(mp->d_name, "vba")) { 384 if (dp->d_vec == 0) 385 printf( 386 "Warning, no interrupt vector specified for device %s%d\n", 387 dp->d_name, dp->d_unit); 388 if (dp->d_addr == 0) { 389 printf("must specify csr for device %s%d\n", 390 dp->d_name, dp->d_unit); 391 continue; 392 } 393 if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { 394 printf("drives/slaves can be specified "); 395 printf("only for controllers, "); 396 printf("not for device %s%d\n", 397 dp->d_name, dp->d_unit); 398 continue; 399 } 400 vba_n = mp->d_unit; 401 slave = QUES; 402 } else { 403 if ((np = mp->d_conn) == 0) { 404 printf("%s%d isn't connected to anything ", 405 mp->d_name, mp->d_unit); 406 printf(", so %s%d is unattached\n", 407 dp->d_name, dp->d_unit); 408 continue; 409 } 410 vba_n = np->d_unit; 411 if (dp->d_drive == UNKNOWN) { 412 printf("must specify ``drive number'' "); 413 printf("for %s%d\n", dp->d_name, dp->d_unit); 414 continue; 415 } 416 /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ 417 /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ 418 if (dp->d_slave != UNKNOWN) { 419 printf("slave numbers should be given only "); 420 printf("for massbus tapes, not for %s%d\n", 421 dp->d_name, dp->d_unit); 422 continue; 423 } 424 if (dp->d_vec != 0) { 425 printf("interrupt vectors should not be "); 426 printf("given for drive %s%d\n", 427 dp->d_name, dp->d_unit); 428 continue; 429 } 430 if (dp->d_addr != 0) { 431 printf("csr addresses should be given only "); 432 printf("on controllers, not on %s%d\n", 433 dp->d_name, dp->d_unit); 434 continue; 435 } 436 slave = dp->d_drive; 437 } 438 fprintf(fp, "\t{ &%sdriver, %2d, %s,", 439 eq(mp->d_name, "vba") ? dp->d_name : mp->d_name, dp->d_unit, 440 eq(mp->d_name, "vba") ? " -1" : qu(mp->d_unit)); 441 fprintf(fp, " %s, %2d, %s, C 0x%-6x, %d, 0x%x },\n", 442 qu(vba_n), slave, intv(dp), dp->d_addr, dp->d_dk, 443 dp->d_flags); 444 } 445 fprintf(fp, "\t0\n};\n"); 446 (void) fclose(fp); 447 } 448 #endif 449 450 char * 451 intv(dev) 452 register struct device *dev; 453 { 454 static char buf[20]; 455 456 if (dev->d_vec == 0) 457 return (" 0"); 458 (void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit); 459 return (buf); 460 } 461 462 char * 463 qu(num) 464 { 465 466 if (num == QUES) 467 return ("'?'"); 468 if (num == UNKNOWN) 469 return (" -1"); 470 (void) sprintf(errbuf, "%3d", num); 471 return (errbuf); 472 } 473