| 1 | /* |
| 2 | * Copyright (c) 1992 The Regents of the University of California. |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * This software was developed by the Computer Systems Engineering group |
| 6 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and |
| 7 | * contributed to Berkeley. |
| 8 | * |
| 9 | * All advertising materials mentioning features or use of this software |
| 10 | * must display the following acknowledgement: |
| 11 | * This product includes software developed by the University of |
| 12 | * California, Lawrence Berkeley Laboratories. |
| 13 | * |
| 14 | * %sccs.include.redist.c% |
| 15 | * |
| 16 | * @(#)config.h 5.2 (Berkeley) %G% |
| 17 | */ |
| 18 | |
| 19 | /* |
| 20 | * Name/value lists. Values can be strings or pointers and/or can carry |
| 21 | * integers. The names can be NULL, resulting in simple value lists. |
| 22 | */ |
| 23 | struct nvlist { |
| 24 | struct nvlist *nv_next; |
| 25 | const char *nv_name; |
| 26 | union { |
| 27 | const char *un_str; |
| 28 | void *un_ptr; |
| 29 | } nv_un; |
| 30 | #define nv_str nv_un.un_str |
| 31 | #define nv_ptr nv_un.un_ptr |
| 32 | int nv_int; |
| 33 | }; |
| 34 | |
| 35 | /* |
| 36 | * Kernel configurations. |
| 37 | */ |
| 38 | struct config { |
| 39 | struct config *cf_next; /* linked list */ |
| 40 | const char *cf_name; /* "vmunix" */ |
| 41 | int cf_lineno; /* source line */ |
| 42 | struct nvlist *cf_root; /* "root on ra0a" */ |
| 43 | struct nvlist *cf_swap; /* "swap on ra0b and ra1b" */ |
| 44 | struct nvlist *cf_dump; /* "dumps on ra0b" */ |
| 45 | }; |
| 46 | |
| 47 | /* |
| 48 | * Attributes. These come in two flavors: "plain" and "interface". |
| 49 | * Plain attributes (e.g., "ether") simply serve to pull in files. |
| 50 | * Interface attributes (e.g., "scsi") carry three lists: locators, |
| 51 | * child devices, and references. The locators are those things |
| 52 | * that must be specified in order to configure a device instance |
| 53 | * using this attribute (e.g., "tg0 at scsi0"). The a_devs field |
| 54 | * lists child devices that can connect here (e.g., "tg"s), while |
| 55 | * the a_refs are parents that carry the attribute (e.g., actual |
| 56 | * SCSI host adapter drivers such as the SPARC "esp"). |
| 57 | */ |
| 58 | struct attr { |
| 59 | const char *a_name; /* name of this attribute */ |
| 60 | int a_iattr; /* true => allows children */ |
| 61 | struct nvlist *a_locs; /* locators required */ |
| 62 | int a_loclen; /* length of above list */ |
| 63 | struct nvlist *a_devs; /* children */ |
| 64 | struct nvlist *a_refs; /* parents */ |
| 65 | }; |
| 66 | |
| 67 | /* |
| 68 | * The "base" part of a device ("uba", "sd"; but not "uba2" or |
| 69 | * "sd0"). It may be found "at" one or more attributes, including |
| 70 | * "at root" (this is represented by a NULL attribute). |
| 71 | * |
| 72 | * Each device may also export attributes. If any provide an output |
| 73 | * interface (e.g., "esp" provides "scsi"), other devices (e.g., |
| 74 | * "tg"s) can be found at instances of this one (e.g., "esp"s). |
| 75 | * Such a connection must provide locators as specified by that |
| 76 | * interface attribute (e.g., "target"). |
| 77 | * |
| 78 | * Each base carries a list of instances (via d_ihead). Note that this |
| 79 | * list "skips over" aliases; those must be found through the instances |
| 80 | * themselves. |
| 81 | */ |
| 82 | struct devbase { |
| 83 | const char *d_name; /* e.g., "sd" */ |
| 84 | struct devbase *d_next; /* linked list */ |
| 85 | int d_isdef; /* set once properly defined */ |
| 86 | int d_ispseudo; /* is a pseudo-device */ |
| 87 | int d_major; /* used for "root on sd0", e.g. */ |
| 88 | struct nvlist *d_atlist; /* e.g., "at tg" (attr list) */ |
| 89 | struct nvlist *d_vectors; /* interrupt vectors, if any */ |
| 90 | struct nvlist *d_attrs; /* attributes, if any */ |
| 91 | struct devi *d_ihead; /* first instance, if any */ |
| 92 | struct devi **d_ipp; /* used for tacking on more instances */ |
| 93 | int d_umax; /* highest unit number + 1 */ |
| 94 | }; |
| 95 | |
| 96 | /* |
| 97 | * An "instance" of a device. The same instance may be listed more |
| 98 | * than once, e.g., "xx0 at isa? port FOO" + "xx0 at isa? port BAR". |
| 99 | * |
| 100 | * After everything has been read in and verified, the devi's are |
| 101 | * "packed" to collect all the information needed to generate ioconf.c. |
| 102 | * In particular, we try to collapse multiple aliases into a single entry. |
| 103 | * We then assign each "primary" (non-collapsed) instance a cfdata index. |
| 104 | * Note that there may still be aliases among these. |
| 105 | */ |
| 106 | struct devi { |
| 107 | /* created while parsing config file */ |
| 108 | const char *i_name; /* e.g., "sd0" */ |
| 109 | int i_unit; /* unit from name, e.g., 0 */ |
| 110 | struct devbase *i_base;/* e.g., pointer to "sd" base */ |
| 111 | struct devi *i_next; /* list of all instances */ |
| 112 | struct devi *i_bsame; /* list on same base */ |
| 113 | struct devi *i_alias; /* other aliases of this instance */ |
| 114 | const char *i_at; /* where this is "at" (NULL if at root) */ |
| 115 | struct attr *i_atattr; /* attr that allowed attach */ |
| 116 | struct devbase *i_atdev;/* dev if "at <devname><unit>", else NULL */ |
| 117 | const char **i_locs; /* locators (as given by i_atattr) */ |
| 118 | int i_atunit; /* unit from "at" */ |
| 119 | int i_cfflags; /* flags from config line */ |
| 120 | int i_lineno; /* line # in config, for later errors */ |
| 121 | |
| 122 | /* created during packing or ioconf.c generation */ |
| 123 | /* i_loclen via i_atattr->a_loclen */ |
| 124 | short i_collapsed; /* set => this alias no longer needed */ |
| 125 | short i_cfindex; /* our index in cfdata */ |
| 126 | short i_pvlen; /* number of parents */ |
| 127 | short i_pvoff; /* offset in parents.vec */ |
| 128 | short i_locoff; /* offset in locators.vec */ |
| 129 | short i_ivoff; /* offset in interrupt vectors, if any */ |
| 130 | struct devi **i_parents;/* the parents themselves */ |
| 131 | |
| 132 | }; |
| 133 | /* special units */ |
| 134 | #define STAR (-1) /* unit number for, e.g., "sd*" */ |
| 135 | #define WILD (-2) /* unit number for, e.g., "sd?" */ |
| 136 | |
| 137 | /* |
| 138 | * Files. Each file is either standard (always included) or optional, |
| 139 | * depending on whether it has names on which to *be* optional. |
| 140 | */ |
| 141 | struct files { |
| 142 | struct files *fi_next; /* linked list */ |
| 143 | const char *fi_srcfile; /* the name of the "files" file that got us */ |
| 144 | u_short fi_srcline; /* and the line number */ |
| 145 | u_char fi_flags; /* as below */ |
| 146 | char fi_lastc; /* last char from path */ |
| 147 | const char *fi_path; /* full file path */ |
| 148 | const char *fi_tail; /* name, i.e., rindex(fi_path, '/') + 1 */ |
| 149 | const char *fi_base; /* tail minus ".c" (or whatever) */ |
| 150 | struct nvlist *fi_opt; /* optional on ... */ |
| 151 | const char *fi_mkrule; /* special make rule, if any */ |
| 152 | }; |
| 153 | |
| 154 | /* flags */ |
| 155 | #define FI_SEL 0x01 /* selected */ |
| 156 | #define FI_CONFIGDEP 0x02 /* config-dependent */ |
| 157 | #define FI_DRIVER 0x04 /* device-driver */ |
| 158 | #define FI_NEEDSCOUNT 0x08 /* needs-count */ |
| 159 | #define FI_NEEDSFLAG 0x10 /* needs-flag */ |
| 160 | #define FI_HIDDEN 0x20 /* obscured by other(s), base names overlap */ |
| 161 | |
| 162 | /* |
| 163 | * Hash tables look up name=value pairs. The pointer value of the name |
| 164 | * is assumed to be constant forever; this can be arranged by interning |
| 165 | * the name. (This is fairly convenient since our lexer does this for |
| 166 | * all identifier-like strings---it has to save them anyway, lest yacc's |
| 167 | * look-ahead wipe out the current one.) |
| 168 | */ |
| 169 | struct hashtab; |
| 170 | |
| 171 | const char *conffile; /* source file, e.g., "GENERIC.sparc" */ |
| 172 | const char *confdirbase; /* basename of compile directory, usu. same */ |
| 173 | const char *machine; /* machine type, e.g., "sparc" */ |
| 174 | int errors; /* counts calls to error() */ |
| 175 | int minmaxusers; /* minimum "maxusers" parameter */ |
| 176 | int defmaxusers; /* default "maxusers" parameter */ |
| 177 | int maxmaxusers; /* default "maxusers" parameter */ |
| 178 | int maxusers; /* configuration's "maxusers" parameter */ |
| 179 | struct nvlist *options; /* options */ |
| 180 | struct nvlist *mkoptions; /* makeoptions */ |
| 181 | struct hashtab *devbasetab; /* devbase lookup */ |
| 182 | struct hashtab *selecttab; /* selects things that are "optional foo" */ |
| 183 | struct hashtab *needcnttab; /* retains names marked "needs-count" */ |
| 184 | |
| 185 | struct devbase *allbases; /* list of all devbase structures */ |
| 186 | struct config *allcf; /* list of configured kernels */ |
| 187 | struct devi *alldevi; /* list of all instances */ |
| 188 | struct devi *allpseudo; /* list of all pseudo-devices */ |
| 189 | int ndevi; /* number of devi's (before packing) */ |
| 190 | int npseudo; /* number of pseudo's */ |
| 191 | |
| 192 | struct files *allfiles; /* list of all kernel source files */ |
| 193 | |
| 194 | struct devi **packed; /* arrayified table for packed devi's */ |
| 195 | int npacked; /* size of packed table, <= ndevi */ |
| 196 | |
| 197 | struct { /* pv[] table for config */ |
| 198 | short *vec; |
| 199 | int used; |
| 200 | } parents; |
| 201 | struct { /* loc[] table for config */ |
| 202 | const char **vec; |
| 203 | int used; |
| 204 | } locators; |
| 205 | |
| 206 | /* files.c */ |
| 207 | void initfiles __P((void)); |
| 208 | void checkfiles __P((void)); |
| 209 | int fixfiles __P((void)); /* finalize */ |
| 210 | void addfile __P((const char *, struct nvlist *, int, const char *)); |
| 211 | |
| 212 | /* hash.c */ |
| 213 | struct hashtab *ht_new __P((void)); |
| 214 | int ht_insrep __P((struct hashtab *, const char *, void *, int)); |
| 215 | #define ht_insert(ht, nam, val) ht_insrep(ht, nam, val, 0) |
| 216 | #define ht_replace(ht, nam, val) ht_insrep(ht, nam, val, 1) |
| 217 | void *ht_lookup __P((struct hashtab *, const char *)); |
| 218 | void initintern __P((void)); |
| 219 | const char *intern __P((const char *)); |
| 220 | |
| 221 | /* main.c */ |
| 222 | void addoption __P((const char *name, const char *value)); |
| 223 | void addmkoption __P((const char *name, const char *value)); |
| 224 | |
| 225 | /* mkheaders.c */ |
| 226 | int mkheaders __P((void)); |
| 227 | |
| 228 | /* mkioconf.c */ |
| 229 | int mkioconf __P((void)); |
| 230 | |
| 231 | /* mkmakefile.c */ |
| 232 | int mkmakefile __P((void)); |
| 233 | |
| 234 | /* mkswap.c */ |
| 235 | int mkswap __P((void)); |
| 236 | |
| 237 | /* pack.c */ |
| 238 | void pack __P((void)); |
| 239 | |
| 240 | /* scan.l */ |
| 241 | int currentline __P((void)); |
| 242 | |
| 243 | /* sem.c, other than for yacc actions */ |
| 244 | void initsem __P((void)); |
| 245 | |
| 246 | /* util.c */ |
| 247 | void *emalloc __P((size_t)); |
| 248 | void *erealloc __P((void *, size_t)); |
| 249 | char *path __P((const char *)); |
| 250 | void error __P((const char *, ...)); /* immediate errs */ |
| 251 | void xerror __P((const char *, int, const char *, ...)); /* delayed errs */ |
| 252 | __dead void panic __P((const char *, ...)); |
| 253 | struct nvlist *newnv __P((const char *, const char *, void *, int)); |
| 254 | void nvfree __P((struct nvlist *)); |
| 255 | void nvfreel __P((struct nvlist *)); |