1*57491Storek /* 2*57491Storek * Copyright (c) 1992 The Regents of the University of California. 3*57491Storek * All rights reserved. 4*57491Storek * 5*57491Storek * This software was developed by the Computer Systems Engineering group 6*57491Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7*57491Storek * contributed to Berkeley. 8*57491Storek * 9*57491Storek * All advertising materials mentioning features or use of this software 10*57491Storek * must display the following acknowledgement: 11*57491Storek * This product includes software developed by the University of 12*57491Storek * California, Lawrence Berkeley Laboratories. 13*57491Storek * 14*57491Storek * %sccs.include.redist.c% 15*57491Storek * 16*57491Storek * @(#)mkioconf.c 5.1 (Berkeley) 01/12/93 17*57491Storek * 18*57491Storek * from: $Header: mkioconf.c,v 1.2 92/12/08 19:34:31 torek Exp $ 19*57491Storek */ 20*57491Storek 21*57491Storek #include <sys/param.h> 22*57491Storek #include <errno.h> 23*57491Storek #include <stdio.h> 24*57491Storek #include <stdlib.h> 25*57491Storek #include <string.h> 26*57491Storek #include "config.h" 27*57491Storek 28*57491Storek /* 29*57491Storek * Make ioconf.c. 30*57491Storek */ 31*57491Storek static int cforder __P((const void *, const void *)); 32*57491Storek static int emitcfdata __P((FILE *)); 33*57491Storek static int emitexterns __P((FILE *)); 34*57491Storek static int emithdr __P((FILE *)); 35*57491Storek static int emitloc __P((FILE *)); 36*57491Storek static int emitpseudo __P((FILE *)); 37*57491Storek static int emitpv __P((FILE *)); 38*57491Storek static int emitroots __P((FILE *)); 39*57491Storek static int emitvec __P((FILE *)); 40*57491Storek static char *vecname __P((char *, const char *, int)); 41*57491Storek 42*57491Storek static const char *s_i386; 43*57491Storek 44*57491Storek #define SEP(pos, max) (((u_int)(pos) % (max)) == 0 ? "\n\t" : " ") 45*57491Storek 46*57491Storek /* 47*57491Storek * NEWLINE can only be used in the emitXXX functions. 48*57491Storek * In most cases it can be subsumed into an fprintf. 49*57491Storek */ 50*57491Storek #define NEWLINE if (putc('\n', fp) < 0) return (1) 51*57491Storek 52*57491Storek int 53*57491Storek mkioconf() 54*57491Storek { 55*57491Storek register FILE *fp; 56*57491Storek register char *fname; 57*57491Storek int v; 58*57491Storek 59*57491Storek s_i386 = intern("i386"); 60*57491Storek 61*57491Storek fname = path("ioconf.c"); 62*57491Storek qsort(packed, npacked, sizeof *packed, cforder); 63*57491Storek if ((fp = fopen(fname, "w")) == NULL) { 64*57491Storek (void)fprintf(stderr, "config: cannot write %s: %s\n", 65*57491Storek fname, strerror(errno)); 66*57491Storek return (1); 67*57491Storek } 68*57491Storek v = emithdr(fp); 69*57491Storek if (v != 0 || emitvec(fp) || emitexterns(fp) || emitloc(fp) || 70*57491Storek emitpv(fp) || emitcfdata(fp) || emitroots(fp) || emitpseudo(fp)) { 71*57491Storek if (v >= 0) 72*57491Storek (void)fprintf(stderr, 73*57491Storek "config: error writing %s: %s\n", 74*57491Storek fname, strerror(errno)); 75*57491Storek (void)fclose(fp); 76*57491Storek /* (void)unlink(fname); */ 77*57491Storek free(fname); 78*57491Storek return (1); 79*57491Storek } 80*57491Storek (void)fclose(fp); 81*57491Storek free(fname); 82*57491Storek return (0); 83*57491Storek } 84*57491Storek 85*57491Storek static int 86*57491Storek cforder(a, b) 87*57491Storek const void *a, *b; 88*57491Storek { 89*57491Storek register int n1, n2; 90*57491Storek 91*57491Storek n1 = (*(struct devi **)a)->i_cfindex; 92*57491Storek n2 = (*(struct devi **)b)->i_cfindex; 93*57491Storek return (n1 - n2); 94*57491Storek } 95*57491Storek 96*57491Storek static int 97*57491Storek emithdr(ofp) 98*57491Storek register FILE *ofp; 99*57491Storek { 100*57491Storek register FILE *ifp; 101*57491Storek register int n; 102*57491Storek char ifn[200], buf[BUFSIZ]; 103*57491Storek 104*57491Storek if (fprintf(ofp, "\ 105*57491Storek /*\n\ 106*57491Storek * MACHINE GENERATED: DO NOT EDIT\n\ 107*57491Storek *\n\ 108*57491Storek * ioconf.c, from \"%s\"\n\ 109*57491Storek */\n\n", conffile) < 0) 110*57491Storek return (1); 111*57491Storek (void)sprintf(ifn, "ioconf.incl.%s", machine); 112*57491Storek if ((ifp = fopen(ifn, "r")) != NULL) { 113*57491Storek while ((n = fread(buf, 1, sizeof(buf), ifp)) > 0) 114*57491Storek if (fwrite(buf, 1, n, ofp) != n) 115*57491Storek return (1); 116*57491Storek if (ferror(ifp)) { 117*57491Storek (void)fprintf(stderr, "config: error reading %s: %s\n", 118*57491Storek ifn, strerror(errno)); 119*57491Storek (void)fclose(ifp); 120*57491Storek return (-1); 121*57491Storek } 122*57491Storek (void)fclose(ifp); 123*57491Storek } else { 124*57491Storek if (fputs("\ 125*57491Storek #include <sys/param.h>\n\ 126*57491Storek #include <sys/device.h>\n", ofp) < 0) 127*57491Storek return (1); 128*57491Storek } 129*57491Storek return (0); 130*57491Storek } 131*57491Storek 132*57491Storek static int 133*57491Storek emitexterns(fp) 134*57491Storek register FILE *fp; 135*57491Storek { 136*57491Storek register struct devbase *d; 137*57491Storek 138*57491Storek NEWLINE; 139*57491Storek for (d = allbases; d != NULL; d = d->d_next) { 140*57491Storek if (d->d_ihead == NULL) 141*57491Storek continue; 142*57491Storek if (fprintf(fp, "extern struct cfdriver %scd;\n", 143*57491Storek d->d_name) < 0) 144*57491Storek return (1); 145*57491Storek } 146*57491Storek NEWLINE; 147*57491Storek return (0); 148*57491Storek } 149*57491Storek 150*57491Storek static int 151*57491Storek emitloc(fp) 152*57491Storek register FILE *fp; 153*57491Storek { 154*57491Storek register int i; 155*57491Storek 156*57491Storek if (fprintf(fp, "\n/* locators */\n\ 157*57491Storek static int loc[%d] = {", locators.used) < 0) 158*57491Storek return (1); 159*57491Storek for (i = 0; i < locators.used; i++) 160*57491Storek if (fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]) < 0) 161*57491Storek return (1); 162*57491Storek return (fprintf(fp, "\n};\n") < 0); 163*57491Storek } 164*57491Storek 165*57491Storek /* 166*57491Storek * Emit global parents-vector. 167*57491Storek */ 168*57491Storek static int 169*57491Storek emitpv(fp) 170*57491Storek register FILE *fp; 171*57491Storek { 172*57491Storek register int i; 173*57491Storek 174*57491Storek if (fprintf(fp, "\n/* parent vectors */\n\ 175*57491Storek static short pv[%d] = {", parents.used) < 0) 176*57491Storek return (1); 177*57491Storek for (i = 0; i < parents.used; i++) 178*57491Storek if (fprintf(fp, "%s%d,", SEP(i, 16), parents.vec[i]) < 0) 179*57491Storek return (1); 180*57491Storek return (fprintf(fp, "\n};\n") < 0); 181*57491Storek } 182*57491Storek 183*57491Storek /* 184*57491Storek * Emit the cfdata array. 185*57491Storek */ 186*57491Storek static int 187*57491Storek emitcfdata(fp) 188*57491Storek register FILE *fp; 189*57491Storek { 190*57491Storek register struct devi **p, *i, **par; 191*57491Storek register int unit, v; 192*57491Storek register const char *vs, *state, *basename; 193*57491Storek register struct nvlist *nv; 194*57491Storek register struct attr *a; 195*57491Storek char *loc; 196*57491Storek char locbuf[20]; 197*57491Storek 198*57491Storek if (fprintf(fp, "\n\ 199*57491Storek #define NORM FSTATE_NOTFOUND\n\ 200*57491Storek #define STAR FSTATE_STAR\n\ 201*57491Storek \n\ 202*57491Storek struct cfdata cfdata[] = {\n\ 203*57491Storek \t/* driver unit state loc flags parents ivstubs */\n") < 0) 204*57491Storek return (1); 205*57491Storek for (p = packed; (i = *p) != NULL; p++) { 206*57491Storek /* the description */ 207*57491Storek if (fprintf(fp, "/*%3d: %s at ", i->i_cfindex, i->i_name) < 0) 208*57491Storek return (1); 209*57491Storek par = i->i_parents; 210*57491Storek for (v = 0; v < i->i_pvlen; v++) 211*57491Storek if (fprintf(fp, "%s%s", v == 0 ? "" : "|", 212*57491Storek i->i_parents[v]->i_name) < 0) 213*57491Storek return (1); 214*57491Storek if (v == 0 && fputs("root", fp) < 0) 215*57491Storek return (1); 216*57491Storek a = i->i_atattr; 217*57491Storek nv = a->a_locs; 218*57491Storek for (nv = a->a_locs, v = 0; nv != NULL; nv = nv->nv_next, v++) 219*57491Storek if (fprintf(fp, " %s %s", 220*57491Storek nv->nv_name, i->i_locs[v]) < 0) 221*57491Storek return (1); 222*57491Storek if (fputs(" */\n", fp) < 0) 223*57491Storek return (-1); 224*57491Storek 225*57491Storek /* then the actual defining line */ 226*57491Storek basename = i->i_base->d_name; 227*57491Storek if (i->i_unit == STAR) { 228*57491Storek unit = i->i_base->d_umax; 229*57491Storek state = "STAR"; 230*57491Storek } else { 231*57491Storek unit = i->i_unit; 232*57491Storek state = "NORM"; 233*57491Storek } 234*57491Storek if (i->i_ivoff < 0) { 235*57491Storek vs = ""; 236*57491Storek v = 0; 237*57491Storek } else { 238*57491Storek vs = "vec+"; 239*57491Storek v = i->i_ivoff; 240*57491Storek } 241*57491Storek if (i->i_locoff >= 0) { 242*57491Storek (void)sprintf(locbuf, "loc+%3d", i->i_locoff); 243*57491Storek loc = locbuf; 244*57491Storek } else 245*57491Storek loc = "loc"; 246*57491Storek if (fprintf(fp, "\ 247*57491Storek \t{&%scd,%s%2d, %s, %7s, %#6x, pv+%2d, %s%d},\n", 248*57491Storek basename, strlen(basename) < 3 ? "\t\t" : "\t", unit, 249*57491Storek state, loc, i->i_cfflags, i->i_pvoff, vs, v) < 0) 250*57491Storek return (1); 251*57491Storek } 252*57491Storek return (fputs("\t0\n};\n", fp) < 0); 253*57491Storek } 254*57491Storek 255*57491Storek /* 256*57491Storek * Emit the table of potential roots. 257*57491Storek */ 258*57491Storek static int 259*57491Storek emitroots(fp) 260*57491Storek register FILE *fp; 261*57491Storek { 262*57491Storek register struct devi **p, *i; 263*57491Storek 264*57491Storek if (fputs("\nshort cfroots[] = {\n", fp) < 0) 265*57491Storek return (1); 266*57491Storek for (p = packed; (i = *p) != NULL; p++) { 267*57491Storek if (i->i_at != NULL) 268*57491Storek continue; 269*57491Storek if (i->i_unit != 0 && 270*57491Storek (i->i_unit != STAR || i->i_base->d_umax != 0)) 271*57491Storek (void)fprintf(stderr, 272*57491Storek "config: warning: `%s at root' is not unit 0\n", 273*57491Storek i->i_name); 274*57491Storek if (fprintf(fp, "\t%2d /* %s */,\n", 275*57491Storek i->i_cfindex, i->i_name) < 0) 276*57491Storek return (1); 277*57491Storek } 278*57491Storek return (fputs("\t-1\n};\n", fp) < 0); 279*57491Storek } 280*57491Storek 281*57491Storek /* 282*57491Storek * Emit pseudo-device initialization. 283*57491Storek */ 284*57491Storek static int 285*57491Storek emitpseudo(fp) 286*57491Storek register FILE *fp; 287*57491Storek { 288*57491Storek register struct devi *i; 289*57491Storek register struct devbase *d; 290*57491Storek 291*57491Storek if (fputs("\n#ifdef notyet\n", fp) < 0) 292*57491Storek return (1); 293*57491Storek for (i = allpseudo; i != NULL; i = i->i_next) 294*57491Storek if (fprintf(fp, "extern void %sattach __P((int));\n", 295*57491Storek i->i_base->d_name) < 0) 296*57491Storek return (1); 297*57491Storek if (fputs("\nstruct pdevinit pdevinit[] = {\n", fp) < 0) 298*57491Storek return (1); 299*57491Storek for (i = allpseudo; i != NULL; i = i->i_next) { 300*57491Storek d = i->i_base; 301*57491Storek if (fprintf(fp, "\t{ %sattach, %d }\n", 302*57491Storek d->d_name, d->d_umax) < 0) 303*57491Storek return (1); 304*57491Storek } 305*57491Storek return (fputs("\t{ 0, 0 }\n};\n#endif\n", fp) < 0); 306*57491Storek } 307*57491Storek 308*57491Storek /* 309*57491Storek * Emit interrupt vector declarations, and calculate offsets. 310*57491Storek */ 311*57491Storek static int 312*57491Storek emitvec(fp) 313*57491Storek register FILE *fp; 314*57491Storek { 315*57491Storek register struct nvlist *head, *nv; 316*57491Storek register struct devi **p, *i; 317*57491Storek register int j, nvec, unit; 318*57491Storek char buf[200]; 319*57491Storek 320*57491Storek nvec = 0; 321*57491Storek for (p = packed; (i = *p) != NULL; p++) { 322*57491Storek if ((head = i->i_base->d_vectors) == NULL) 323*57491Storek continue; 324*57491Storek if ((unit = i->i_unit) == STAR) 325*57491Storek panic("emitvec unit==STAR"); 326*57491Storek if (nvec == 0) 327*57491Storek NEWLINE; 328*57491Storek for (j = 0, nv = head; nv != NULL; j++, nv = nv->nv_next) 329*57491Storek if (fprintf(fp, 330*57491Storek "/* IVEC %s %d */ extern void %s();\n", 331*57491Storek nv->nv_name, unit, 332*57491Storek vecname(buf, nv->nv_name, unit)) < 0) 333*57491Storek return (1); 334*57491Storek nvec += j + 1; 335*57491Storek } 336*57491Storek if (nvec == 0) 337*57491Storek return (0); 338*57491Storek if (fprintf(fp, "\nstatic void (*vec[%d]) __P((void)) = {", nvec) < 0) 339*57491Storek return (1); 340*57491Storek nvec = 0; 341*57491Storek for (p = packed; (i = *p) != NULL; p++) { 342*57491Storek if ((head = i->i_base->d_vectors) == NULL) 343*57491Storek continue; 344*57491Storek i->i_ivoff = nvec; 345*57491Storek unit = i->i_unit; 346*57491Storek for (nv = head; nv != NULL; nv = nv->nv_next) 347*57491Storek if (fprintf(fp, "%s%s,", 348*57491Storek SEP(nvec++, 4), 349*57491Storek vecname(buf, nv->nv_name, unit)) < 0) 350*57491Storek return (1); 351*57491Storek if (fprintf(fp, "%s0,", SEP(nvec++, 4)) < 0) 352*57491Storek return (1); 353*57491Storek } 354*57491Storek return (fputs("\n};\n", fp) < 0); 355*57491Storek } 356*57491Storek 357*57491Storek static char * 358*57491Storek vecname(buf, name, unit) 359*57491Storek char *buf; 360*57491Storek const char *name; 361*57491Storek int unit; 362*57491Storek { 363*57491Storek 364*57491Storek /* @#%* 386 uses a different name format */ 365*57491Storek if (machine == s_i386) { 366*57491Storek (void)sprintf(buf, "V%s%d", name, unit); 367*57491Storek return (buf); 368*57491Storek } 369*57491Storek (void)sprintf(buf, "X%s%d", name, unit); 370*57491Storek return (buf); 371*57491Storek } 372