1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039 |
- #!/bin/sh
- #
- # Kernel config script for OS/161.
- #
- # Usage: ./config conf-name
- #
- # WARNING! IF YOU JUST RUN "config" INSTEAD OF "./config" YOU WILL
- # PROBABLY GET THE HOST SYSTEM'S KERNEL CONFIG INSTEAD OF THIS ONE,
- # WHICH WILL CAUSE WEIRD THINGS TO HAPPEN. DON'T DO IT.
- #
- #
- # Recognized directives:
- #
- # file <filename> use source file
- # debug turn on debug info
- # defoption <sym> define an option
- # optfile <sym> <file> if option <sym> is enabled, use file <file>
- # optofffile <sym> <file> if option <sym> is disabled, use file <file>
- # defdevice <dev> <file> define a device
- # defattach <dev> <bus> <file>
- # define an attachment for a device to a bus
- # pseudoattach <dev> define a pseudo-attachment for a device
- #
- # options <sym> enable an option
- # device <dev> [at <bus>] enable a particular device [on a particular bus]
- #
- # include <filename> get additional directives from another file
- #
- # Filenames are relative to the top of the kernel tree.
- #
- # The comment character is '#'.
- #
- # The idea is that the first group of directives is used to set up a
- # static description of all possible configurations for each supported
- # architecture. Then a kernel config file uses the second group of
- # directives to specify a particular configuration. Then this script
- # is used to first check that the configuration is one of the possible
- # ones, and then to set up the compile directory, makefiles, and
- # associated material necessary to actually build that configuration.
- #
- # Further documentation is at the top of conf.kern.
- #
- #
- # Make sure we're in the right place.
- #
- if [ ! -d ../startup ]; then
- echo "$0: Run me from src/kern/conf"
- exit 1
- fi
- ########################################
- #
- # 1. Get configuration name and config file.
- #
- CONFNAME=$1
- if [ "x$CONFNAME" = x ]; then
- echo "Usage: $0 CONFIG-NAME"
- exit 1
- fi
- FOO=`echo $CONFNAME | tr -d 'a-zA-Z0-9_-'`
- if [ "x$FOO" != x ]; then
- echo "Illegal configuration name $CONFNAME"
- exit 1
- fi
- if [ ! -f $CONFNAME ]; then
- echo "$0: $CONFNAME not found"
- exit 1
- fi
- echo "Configuration $CONFNAME"
- COMPILEDIR="../compile/$CONFNAME"
- ########################################
- #
- # 2. Process includes.
- # Also strip comments.
- # Simultaneously, do a basic syntax check.
- #
- # For an introduction to awk, see
- # http://www.hcs.harvard.edu/~dholland/computers/awk.html
- #
- CONFTMP=.conftmp
- rm -f $CONFTMP
- echo "$CONFNAME" $CONFTMP | awk '
- BEGIN {
- #
- # Initialize list of directives and required numbers of words for each.
- #
- nfields["include"] = 2;
- nfields["file"] = 2;
- nfields["debug"] = 1;
- nfields["defoption"] = 2;
- nfields["optfile"] = 3;
- nfields["optofffile"] = 3;
- nfields["defdevice"] = 3;
- nfields["defattach"] = 4;
- nfields["pseudoattach"] = 2;
- nfields["options"] = 2;
- nfields["device"] = 4; # actually 2 or 4, handled specially
- #
- # Directives that can be made machine-dependent with "machine"
- # or "platform".
- #
- okmd["file"] = 1;
- okmd["optfile"] = 1;
- okmd["optofffile"] = 1;
- }
- function doinclude(file, lineno) {
- #
- # Include a file.
- #
- # lineno is a local.
- #
- # Read lines and hand them off recursively to processline().
- #
- lineno = 1;
- while (getline < file) {
- if (ERRNO) {
- printf "%s: %s\n", file, ERRNO;
- exit(1);
- }
- processline(file, lineno);
- lineno++;
- }
- }
- function processline(filename, lineno) {
- #
- # Handle a single config line.
- #
- # Strip comments.
- sub("#.*", "", $0);
- # Ignore blank lines.
- if (NF==0) return;
- direct = $1;
- foundfields = NF;
- if (direct == "machine" && NF > 2 && okmd[$3]) {
- # machine mips file ...
- direct = $3;
- foundfields -= 2;
- }
- else if (direct == "platform" && NF > 2 && okmd[$3]) {
- # platform sys161 file ...
- direct = $3;
- foundfields -= 2;
- }
- # Syntax check: reject unknown directives
- if (!nfields[direct]) {
- printf "%s: %d: Unknown directive %s\n", filename, lineno, direct;
- exit(1);
- }
- # Syntax check: require correct # of args.
- if (direct=="device") {
- # special case - device directive can have 2 or 4 words
- if ((NF!=2 && NF!=4) || (NF==4 && $3!="at")) {
- msg = sprintf("%s: Invalid arguments", direct);
- printf "%s: %d: %s\n", filename, lineno, msg;
- exit(1);
- }
- }
- else if (nfields[direct]!=foundfields) {
- printf "%s: %d: %s: Invalid arguments\n", filename, lineno, direct;
- exit(1);
- }
- # Now actually process the directives we need at this stage - which
- # is only "include". Handle includes.
- if (direct == "include") {
- doinclude("../" $2);
- }
- else {
- print >> outfile;
- }
- }
- #
- # Code called for lines input on stdin.
- # There is only one - the one generated above with echo, which
- # gives us the names of the input and output files to use.
- #
- {
- outfile = $2;
- doinclude($1);
- }
- ' || exit 1
- ########################################
- #
- # 3. Create compile dir.
- #
- if [ ! -d "$COMPILEDIR" ]; then
- mkdir $COMPILEDIR
- fi
- echo -n 'Generating files...'
- ########################################
- #
- # 4. Process device attachments into $CONFTMP.attach.
- # Also add device/attachment files to $CONFTMP.files.
- #
- rm -f $CONFTMP.files
- rm -f $CONFTMP.attach
- awk < $CONFTMP '
- #
- # Function to grab the "0" off "le0" or the "*" off "wd*".
- #
- function getunit(invalmsg, d, u, tmp) {
- u = d;
- sub("^[a-zA-Z_]*", "", u);
- if (u!="*") {
- tmp = u;
- sub("[0-9]*", "", tmp);
- if (tmp!="") {
- printf "\n%s: Invalid device/unit specification\n", invalmsg;
- exit(1);
- }
- }
- return u;
- }
- #
- # Function to grab the "le" off "le0" or the "wd" off "wd*".
- #
- function getbase(invalmsg, d, base) {
- base = d;
- sub("[\\*0-9]*$", "", base);
- if (!use[base]) {
- printf "\n%s: No such device\n", invalmsg;
- exit(1);
- }
- return base;
- }
- #
- # Routine invoked for "defdevice" directive lines.
- #
- $1=="defdevice" {
- dev = $2;
- file = $3;
- # Check for illegal characters in device name
- # (must be legal C symbol, and at this point must not have unit number)
- tmp = dev;
- sub("[a-zA-Z_]*", "", tmp);
- if (tmp!="") {
- printf "\ndefdevice %s: Illegal device name\n", dev;
- exit(1);
- }
- # Device must not have been already defined.
- if (use[dev]) {
- printf "\ndefdevice %s: %s already exists\n", dev, dev;
- exit(1);
- }
- # Note that it exists, but is not in use, and remember the
- # source file for later.
- use[dev] = "no";
- files[dev] = file;
- }
- #
- # Routine called for "defattach" directive lines.
- #
- $1=="defattach" {
- dev = $2;
- bus = $3;
- file = $4;
- # Even though we do not use basebus, busunit, or devunit,
- # call the routines to compute them, because they check the
- # syntax.
- devmsg = "defattach: device " dev;
- devunit = getunit(devmsg, dev);
- basedev = getbase(devmsg, dev);
- busmsg = "defattach: bus " bus;
- busunit = getunit(busmsg, bus);
- basebus = getbase(busmsg, bus);
- if (pseudo[basedev]) {
- printf "\n%s: Already declared pseudoattach\n", devmsg;
- exit(1);
- }
- # The attachment is the pair of bus and device.
- # We remember the specific names, including the unit numbers.
- # This is because "le* at sbus*" is different from "le0 at sbus0"
- # - the former allows le0 to be at sbus1, allows le1, etc.
- attachment = bus "." dev;
- attach[attachment] = "no";
- files[attachment] = file;
- # Remember that attachments are defined for this device. If
- # attachments are defined, when the device is turned on later
- # an attachment must be specified.
- attachable[basedev] = 1;
- }
- #
- # Routine called for "pseudoattach" directive lines.
- #
- $1=="pseudoattach" {
- dev = $2;
- devmsg = "pseudoattach: device " dev;
- devunit = getunit(devmsg, dev);
- basedev = getbase(devmsg, dev);
- if (attachable[basedev]) {
- printf "\n%s: Attachments already declared\n", devmsg;
- exit(1);
- }
- # Remember that this device is a pseudo-device.
- pseudo[basedev] = 1;
- }
- #
- # Helper function for the "device" code.
- #
- function tryattach(combo) {
- if (!attachok && attach[combo]) {
- # This attachment is defined. Note to compile it in, and report
- # success.
- attach[combo] = "yes";
- attachok = 1;
- }
- }
- #
- # Routine called for "device" directive lines.
- #
- $1=="device" {
- dev = $2;
- if (NF==4) {
- devmsg = "device: " dev " at " $4;
- }
- else {
- devmsg = "device: device " dev;
- }
- devunit = getunit(devmsg, dev);
- basedev = getbase(devmsg, dev);
- gendev = basedev "*";
- if (NF==4) {
- #
- # The longer form, with an attachment ("bus").
- #
- bus = $4;
- busmsg = "device: " dev " at " bus ": " bus;
- busunit = getunit(busmsg, bus);
- basebus = getbase(busmsg, bus);
- genbus = basebus "*";
- if (use[basebus]!="yes") {
- printf "\ndevice: bus %s: Bus device is not enabled\n", bus;
- exit(1);
- }
- # If the line was "le0 at sbus0", we try to attach it using
- # the following attachments:
- # First, the exact thing that was requested:
- # sbus0.le0 (le0 at sbus0)
- # Second, for any such device on that bus:
- # sbus*.le0 (le0 at sbus*)
- # Third, for that device on any such bus:
- # sbus0.le* (le* at sbus0)
- # Fourth, for any such device on any such bus:
- # sbus*.le* (le* at sbus*)
- #
- # If the line was "le* at sbus0", some of these will be
- # redundant, but that is ok.
- attachok = 0;
- tryattach(bus "." dev);
- tryattach(bus "." gendev);
- tryattach(genbus "." dev);
- tryattach(genbus "." gendev);
- if (!attachok) {
- # No matching attachment found.
- printf "\ndevice: %s at %s: Undefined attachment\n", dev, bus;
- exit(1);
- }
- devattach = sprintf("%s %s", basedev, devunit);
- baseattach = sprintf("%s %s", basebus, busunit);
- printf "attach %s at %s\n", devattach, baseattach >> attachfile;
- }
- else {
- # No bus specified to attach the device to (really, to find the
- # device attached on.) This is only legal if no attachments
- # at all were defined for the device, which is the case if the
- # device is in fact not attached to anything else (like the main
- # system bus, or a device like /dev/null that has no hardware.)
- # The opposite check to this is not required in the
- # preceding section because no attachment can be found if
- # attachable[basedev] is false.
- if (attachable[basedev]) {
- printf "\ndevice %s: attachment required\n", dev;
- exit(1);
- }
- if (pseudo[basedev]) {
- if (devunit=="*") {
- printf "\n%s: May not use wildcard units here\n", devmsg;
- exit(1);
- }
- printf "pseudo %s %s\n", basedev, devunit >> attachfile;
- }
- else {
- printf "noattach %s\n", basedev >> attachfile;
- }
- }
- use[basedev] = "yes";
- }
- #
- # Routine invoked when we have seen all the input.
- #
- END {
- # Print out the source filenames for the devices and attachments
- # we are using.
- for (dev in use) {
- if (use[dev]=="yes") {
- printf "* * %s\n", files[dev] >> filelistfile;
- }
- }
- for (att in attach) {
- if (attach[att]=="yes") {
- printf "* * %s\n", files[att] >> filelistfile;
- }
- }
- }
- ' "attachfile=$CONFTMP.attach" "filelistfile=$CONFTMP.files" || exit 1
- ########################################
- #
- # 5. Process options.
- #
- awk < $CONFTMP '
- #
- # Routine for a defoption line.
- #
- $1=="defoption" {
- opt = $2;
- options[opt] = "no";
- }
- #
- # Routine for an optfile line.
- #
- $1=="optfile" || (($1=="machine" || $1=="platform") && $3=="optfile") {
- if ($1 == "optfile") {
- opt = $2;
- file = $3;
- platform = "*";
- machine = "*";
- }
- else {
- if ($1=="machine") {
- platform = "*";
- machine = $2;
- }
- else {
- platform = $2;
- machine = "*";
- }
- opt = $4;
- file = $5;
- }
- if (!options[opt]) {
- printf "\noptfile %s %s: No such option %s\n", opt, file, opt;
- exit(1);
- }
- controllers[file] = opt;
- platforms[file] = platform;
- machines[file] = machine;
- }
- #
- # Routine for an optofffile line.
- #
- $1=="optofffile" || (($1=="machine" || $1=="platform") &&$3=="optofffile"){
- if ($1 == "optofffile") {
- opt = $2;
- file = $3;
- platform = "*";
- machine = "*";
- }
- else {
- if ($1=="machine") {
- platform = "*";
- machine = $2;
- }
- else {
- platform = $2;
- machine = "*";
- }
- opt = $4;
- file = $5;
- }
- if (!options[opt]) {
- printf "\noptofffile %s %s: No such option %s\n", opt, file, opt;
- exit(1);
- }
- offcontrollers[file] = opt;
- platforms[file] = platform;
- machines[file] = machine;
- }
- #
- # Routine for an options line.
- #
- $1=="options" {
- opt = $2;
- if (!options[$2]) {
- printf "\noptions %s: No such option\n", opt;
- exit(1);
- }
- options[$2] = "yes";
- }
- #
- # Routine invoked when we have seen everything.
- #
- END {
- #
- # First, add any files to the list of sources we are building.
- #
- for (file in controllers) {
- if (options[controllers[file]]=="yes") {
- line = sprintf("%s %s %s",
- platforms[file], machines[file], file);
- printf "%s\n", line >> filelistfile;
- }
- }
- for (file in offcontrollers) {
- if (options[offcontrollers[file]]=="no") {
- line = sprintf("%s %s %s",
- platforms[file], machines[file], file);
- printf "%s\n", line >> filelistfile;
- }
- }
- close(filelistfile);
- #
- # Now, generate the .h file for every option
- # (both the ones that are on and the ones that are off)
- #
- for (opt in options) {
- realfile = compiledir "/opt-" opt ".h";
- file = realfile ".new";
- sym = toupper(opt);
- printf "/* Automatically generated; do not edit */\n" > file;
- printf "#ifndef _OPT_%s_H_\n", sym >> file;
- printf "#define _OPT_%s_H_\n", sym >> file;
- val = options[opt]=="yes" ? 1 : 0;
- printf "#define OPT_%s %d\n", sym, val >> file;
- printf "#endif /* _OPT_%s_H_ */\n", sym >> file;
- close(file);
- }
- }
- ' "compiledir=$COMPILEDIR" "filelistfile=$CONFTMP.files" || exit 1
- # Avoid changing the actual headers if they aren't different, so as to
- # reduce unnecessary recompiles.
- (
- cd $COMPILEDIR
- for NF in opt-*.h.new; do
- OF=`echo $NF | sed 's/\.new$//'`
- if diff $OF $NF >/dev/null 2>&1; then
- rm -f $NF # unchanged
- else
- mv -f $NF $OF # it changed
- fi
- echo -n " $OF"
- done
- )
- ########################################
- #
- # 6. Add in the unconditional files.
- #
- awk < $CONFTMP '
- $1=="file" {
- printf "* * %s\n", $2 >> filelistfile;
- }
- $1=="machine" && $3=="file" {
- printf "* %s %s\n", $2, $4 >> filelistfile;
- }
- $1=="platform" && $3=="file" {
- printf "%s * %s\n", $2, $4 >> filelistfile;
- }
-
- ' "filelistfile=$CONFTMP.files" || exit 1
- #
- # autoconf.c (which we generate further down) is always compiled in but
- # is not in the list yet. Note that the path to it is where we are about
- # to put it: it lives in the build directory, because it's part of a
- # particular build.
- #
- echo "* * compile/$CONFNAME/autoconf.c" >> $CONFTMP.files
- ########################################
- #
- # 7. We now have the compile file list.
- # Generate files.mk.
- #
- #
- # Validate list first.
- #
- # We allow C++ files, because the makefile rules we generate are
- # sufficient to compile them. However, some low-level kernel hacking
- # will be needed to actually use C++ in OS/161.
- #
- awk < $CONFTMP.files '
- /\.cc$/ { next; }
- /\.cpp$/ { next; }
- /\.C$/ { next; }
- /\.c$/ { next; }
- #/\.l$/ { next; } # will require some makefile hacking to make work
- #/\.y$/ { next; } # will require some makefile hacking to make work
- /\.S$/ { next; }
- /\.o$/ { next; }
- {
- printf "\n%s: Unrecognized source file type\n", $1;
- exit(1);
- }
- ' || exit 1;
- #
- # Do it.
- # Generate a make rule for each file.
- #
- sort < $CONFTMP.files | awk '
- BEGIN {
- printf "# Automatically generated by config; do not edit\n";
- }
- {
- platform = $1;
- machine = $2;
- file = $3;
- # get basename
- basename = file;
- sub(".*/", "", basename);
- # get extension
- ext = basename;
- sub(".*\\.", "", ext);
- sub("\\.[^\\.]*$", "", basename);
- if (file ~ "^\\.\\./") {
- sub("^...", "", file);
- path = "$(TOP)/" file;
- }
- else {
- path = "$(KTOP)/" file;
- }
- #
- # For now a file cannot be both platform-dependent and
- # machine-dependent, so this sequence of tests is enough.
- #
- if (platform != "*") {
- printf "SRCS.PLATFORM.%s+=%s\n", platform, path;
- }
- else if (machine != "*") {
- printf "SRCS.MACHINE.%s+=%s\n", machine, path;
- }
- else {
- printf "SRCS+=%s\n", path;
- }
- }
- ' > $COMPILEDIR/files.mk
- rm -f $CONFTMP.files
- echo -n ' files.mk'
- ########################################
- #
- # 8. (reserved)
- #
- ########################################
- #
- # 9. Generate Makefile
- #
- (
- echo "# Automatically generated by config; do not edit."
- echo "#"
- echo
- echo '# Top of the kernel tree'
- echo 'KTOP=../..'
- echo '# Top of the whole tree'
- echo 'TOP=$(KTOP)/..'
- echo '# Debug vs. optimize'
- awk < $CONFTMP '
- # Default: optimize.
- BEGIN { debugflags="-O2"; }
- $1=="debug" {
- debugflags="-g";
- }
- END {
- printf "KDEBUG=%s\n", debugflags;
- }
- '
- echo '# Name of the kernel config file'
- echo "CONFNAME=$CONFNAME"
- echo
- echo '.include "$(TOP)/mk/os161.config.mk"'
- echo '.include "files.mk"'
- echo '.include "$(TOP)/mk/os161.kernel.mk"'
- ) > $COMPILEDIR/Makefile || exit 1
- echo -n ' Makefile'
- ########################################
- #
- # 10. (reserved)
- #
- ########################################
- #
- # 11. Process attachment list.
- # Generate autoconf.[ch].
- #
- ACHREAL=$COMPILEDIR/autoconf.h
- ACH=$COMPILEDIR/autoconf.h.new
- ACC=$COMPILEDIR/autoconf.c
- echo '/* Automatically generated; do not edit */' > $ACH
- echo '/* Automatically generated; do not edit */' > $ACC
- echo '#ifndef _AUTOCONF_H_' >> $ACH
- echo '#define _AUTOCONF_H_' >> $ACH
- #
- # first, declare struct foo_softc for all devices foo.
- #
- echo >> $ACH
- awk < $CONFTMP.attach '{ printf "struct %s_softc;\n", $2 }' >> $ACH
- #
- # second, declare the autoconf_foo functions for unattached devices.
- #
- # The autoconf_foo functions for attached devices are file-static
- # in autoconf.c.
- #
- echo >> $ACH
- awk < $CONFTMP.attach '$1=="noattach" { print $2 }' | sort -u | awk '
- {
- printf "void autoconf_%s(struct %s_softc *dev, int unit);\n", $1, $1;
- }
- ' >> $ACH
- #
- # third, declare the attach functions.
- #
- echo >> $ACH
- awk < $CONFTMP.attach '
- $1=="attach" {
- dev = $2;
- bus = $5;
- f = sprintf("struct %s_softc *attach_%s_to_%s", dev, dev, bus);
- printf "%s(int devunit, struct %s_softc *bus);\n", f, bus;
- }
- $1=="pseudo" {
- dev = $2;
- printf "struct %s_softc *pseudoattach_%s(int devunit);\n", dev, dev;
- }
- ' >> $ACH
- #
- # fourth, declare the config functions.
- #
- echo >> $ACH
- awk < $CONFTMP.attach '
- $1=="attach" {
- dev = $2;
- printf "int config_%s(struct %s_softc *dev, int unit);\n", dev, dev;
- }
- ' >> $ACH
- #
- # Declare pseudoconfig()
- #
- echo >> $ACH
- echo 'void pseudoconfig(void);' >> $ACH
- echo >> $ACH
- #
- # Done with the header file.
- #
- echo '#endif /* _AUTOCONF_H_ */' >> $ACH
- #
- # Avoid changing the actual autoconf.h if it's not different, so as to
- # reduce unnecessary recompiles.
- #
- if diff $ACHREAL $ACH >/dev/null 2>&1; then
- rm -f $ACH # unchanged
- else
- mv -f $ACH $ACHREAL # it changed
- fi
- echo -n ' autoconf.h'
- #
- # now, autoconf.c
- #
- echo '#include <types.h>' >> $ACC
- echo '#include <lib.h>' >> $ACC
- echo '#include "autoconf.h"' >> $ACC
- #
- # first, declare the static autoconf_foo functions and the nextunit_foo vars
- #
- echo >> $ACC
- awk < $CONFTMP.attach '$1=="attach" || $1=="pseudo" { print $2 }' | sort -u |\
- awk '
- {
- printf "static void autoconf_%s(struct %s_softc *, int);\n", $1, $1;
- }
- ' >> $ACC
- awk < $CONFTMP.attach '$1=="attach" { print $2 }' | sort -u | awk '
- {
- printf "static int nextunit_%s;\n", $1;
- }
- ' >> $ACC
- echo >> $ACC
- #
- # Now generate the tryattach_ functions.
- #
- awk < $CONFTMP.attach '
- $1=="attach" {
- dev = $2;
- bus = $5;
- printf "static\n";
- printf "int\n";
- printf "tryattach_%s_to_%s", dev, bus;
- printf "(int devunit, struct %s_softc *bus, int busunit)\n", bus;
- printf "{\n";
- printf "\tstruct %s_softc *dev;\n", dev;
- printf "\tint result;\n", dev;
- printf "\n";
- printf "\tdev = attach_%s_to_%s(devunit, bus);\n", dev, bus;
- printf "\tif (dev==NULL) {\n";
- printf "\t\treturn -1;\n";
- printf "\t}\n";
- printf "\tkprintf(\"%s%%d at %s%%d\", devunit, busunit);\n", dev, bus;
- printf "\tresult = config_%s(dev, devunit);\n", dev;
- printf "\tif (result != 0) {\n";
- printf "\t\tkprintf(\": %%s\\n\", strerror(result));\n";
- # Note: we leak the device softc instead of trying
- # to clean it up.
- printf "\t\t/* should really clean up dev */\n";
- printf "\t\treturn result;\n";
- printf "\t}\n";
- printf "\tkprintf(\"\\n\");\n";
- printf "\tnextunit_%s = devunit+1;\n", dev;
- printf "\tautoconf_%s(dev, devunit);\n", dev;
- printf "\treturn 0;\n";
- printf "}\n";
- printf "\n";
- }
- ' >> $ACC
- echo >> $ACC
- #
- # Now comes the tricky part, actually writing those autoconf
- # functions. We need one for every device. In each one, there needs
- # to be a probe section for each line in $CONFTMP.attach in which that
- # device appears on the *right hand* (bus) side.
- #
- awk < $CONFTMP.attach '
- BEGIN { nlines=0; npseudo=0; }
- $1=="attach" {
- devs[nlines] = $2;
- devunits[nlines] = $3;
- buses[nlines] = $5;
- busunits[nlines] = $6;
- alldevs[$2] = 1;
- nlines++;
- }
- $1=="noattach" {
- alldevs[$2] = 0;
- }
- $1=="pseudo" {
- alldevs[$2] = 0;
- pseudodevs[npseudo] = $2;
- pseudounits[npseudo] = $3;
- npseudo++;
- }
- function genprobe(dev, devunit, bus, busunit) {
- tryfunc = sprintf("tryattach_%s_to_%s", dev, bus);
-
- if (busunit!="*") {
- printf "\tif (busunit==%d) {\n", busunit;
- }
- else {
- printf "\t{\n";
- }
- if (devunit!="*") {
- printf "\t\tif (nextunit_%s <= %d) {\n", dev, devunit;
- printf "\t\t\t%s(%d, bus, busunit);\n", tryfunc, devunit;
- printf "\t\t}\n";
- }
- else {
- printf "\t\tint result, devunit=nextunit_%s;\n", dev;
- printf "\t\tdo {\n";
- printf "\t\t\tresult = %s(devunit, bus, busunit);\n", tryfunc;
- printf "\t\t\tdevunit++;\n";
- printf "\t\t} while (result==0);\n";
- }
- printf "\t}\n";
- }
- END {
- for (bus in alldevs) {
- softc = sprintf("struct %s_softc", bus);
- if (alldevs[bus]) printf "static\n";
- printf "void\n";
- printf "autoconf_%s(%s *bus, int busunit)\n", bus, softc;
- printf "{\n";
- printf "\t(void)bus; (void)busunit;\n";
- for (i=0; i<nlines; i++) {
- if (buses[i]==bus) {
- genprobe(devs[i], devunits[i], buses[i], busunits[i]);
- }
- }
- printf "}\n\n";
- }
- printf "void\n";
- printf "pseudoconfig(void)\n";
- printf "{\n";
- for (i=0; i<npseudo; i++) {
- dev = pseudodevs[i];
- unit = pseudounits[i];
- printf "\t{\n";
- printf "\t\tstruct %s_softc *s;\n", dev;
- printf "\t\t\n";
- printf "\t\ts = pseudoattach_%s(%s);\n", dev, unit;
- printf "\t\tif (s!=NULL) {\n";
- printf "\t\t\tkprintf(\"%s%d (virtual)\\n\");\n", dev, unit;
- printf "\t\t\tautoconf_%s(s, %s);\n", dev, unit;
- printf "\t\t}\n";
- printf "\t}\n";
- }
- printf "}\n\n";
- }
- ' >> $ACC
- echo -n ' autoconf.c'
- rm -f $CONFTMP $CONFTMP.attach
- ########################################
- #
- # Done.
- #
- echo
- echo "Configuration in ../compile/$CONFNAME done"
- echo "Remember to bmake depend"
|