# from: @(#)Makefile 5.6.1.2 (Berkeley) 5/8/91
-# $Id: Makefile,v 1.7 1996/01/07 02:34:20 dm Exp $
+# $Id: Makefile,v 1.8 1996/04/18 21:32:46 deraadt Exp $
# not yet done: catman
.elif ${MACHINE} == "atari"
SUBDIR+=iteconfig
.elif ${MACHINE} == "hp300"
-SUBDIR+=grfinfo hilinfo
+SUBDIR+=grfinfo hilinfo config.old
.elif ${MACHINE} == "i386"
SUBDIR+=bad144
.elif ${MACHINE} == "pmax"
--- /dev/null
+# from: @(#)Makefile 5.12 (Berkeley) 1/16/91
+# $NetBSD: Makefile,v 1.11 1995/08/17 17:22:06 thorpej Exp $
+
+PROG= config.old
+BINDIR= /usr/sbin
+CFLAGS+=-I. -I${.CURDIR}
+SRCS= config.c main.c lang.c mkioconf.c mkmakefile.c mkglue.c mkheaders.c \
+ mkswapconf.c specfile.c
+MAN= config.old.8
+LDADD+= -ll
+DPADD+= ${LIBL}
+CLEANFILES+=y.tab.h lang.c config.c y.tab.c
+
+.include <bsd.prog.mk>
--- /dev/null
+/* $NetBSD: config.h,v 1.19 1995/08/17 17:22:08 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)config.h 5.14 (Berkeley) 7/1/91
+ */
+
+/*
+ * Config.
+ */
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NODEV ((dev_t)-1)
+
+struct name_expr {
+ int type;
+ char *name;
+ struct name_expr *next,*left,*right;
+};
+
+struct file_list {
+ struct file_list *f_next;
+ char *f_fn; /* the name */
+ u_char f_type; /* see below */
+ u_char f_flags; /* see below */
+ u_char f_was_driver; /* to handle un-included pseudo-drivers*/
+ u_char f_needs_count; /* to handle un-included pseudo-drivers*/
+ char *f_special; /* special make rule if present */
+ struct name_expr *f_needs;
+ struct name_expr *f_countname;
+ /*
+ * Random values:
+ * swap space parameters for swap areas
+ * root device, etc. for system specifications
+ */
+ union {
+ struct { /* when swap specification */
+ dev_t fuw_swapdev;
+ int fuw_swapsize;
+ } fuw;
+ struct { /* when system specification */
+ dev_t fus_rootdev;
+ dev_t fus_dumpdev;
+ } fus;
+ struct { /* when component dev specification */
+ dev_t fup_compdev;
+ int fup_compinfo;
+ } fup;
+ } fun;
+#define f_swapdev fun.fuw.fuw_swapdev
+#define f_swapsize fun.fuw.fuw_swapsize
+#define f_rootdev fun.fus.fus_rootdev
+#define f_dumpdev fun.fus.fus_dumpdev
+#define f_compdev fun.fup.fup_compdev
+#define f_compinfo fun.fup.fup_compinfo
+};
+
+/*
+ * Types.
+ */
+#define DRIVER 1
+#define NORMAL 2
+#define INVISIBLE 3
+#define PROFILING 4
+#define SYSTEMSPEC 5
+#define SWAPSPEC 6
+#define COMPDEVICE 7
+#define COMPSPEC 8
+
+/*
+ * Attributes (flags).
+ */
+#define CONFIGDEP 0x1
+#define DUPLICATE 0x2
+
+struct idlst {
+ char *id;
+ struct idlst *id_next;
+};
+
+struct device {
+ int d_type; /* CONTROLLER, DEVICE, bus adaptor */
+ struct device *d_conn; /* what it is connected to */
+ char *d_name; /* name of device (e.g. rk11) */
+ struct idlst *d_vec; /* interrupt vectors */
+ int d_pri; /* interrupt priority */
+ int d_addr; /* address of csr */
+ int d_unit; /* unit number */
+ int d_drive; /* drive number */
+ int d_slave; /* slave number */
+#define QUES -1 /* -1 means '?' */
+#define UNKNOWN -2 /* -2 means not set yet */
+ int d_dk; /* if init 1 set to number for iostat */
+ int d_flags; /* flags for device init */
+ char *d_port; /* io port base manifest constant */
+ int d_portn; /* io port base (if number not manifest) */
+ char *d_mask; /* interrupt mask */
+ int d_maddr; /* io memory base */
+ int d_msize; /* io memory size */
+ int d_drq; /* DMA request */
+ int d_irq; /* interrupt request */
+ int d_seq; /* sequential number */
+ struct device *d_next; /* Next one in list */
+};
+#define TO_NEXUS (struct device *)-1
+#define TO_VBA (struct device *)-2
+
+struct config {
+ char *c_dev;
+ char *s_sysname;
+};
+
+/*
+ * Config has a global notion of which machine type is
+ * being used. It uses the name of the machine in choosing
+ * files and directories. Thus if the name of the machine is ``vax'',
+ * it will build from ``Makefile.vax'' and use ``../vax/inline''
+ * in the makerules, etc.
+ */
+int machine;
+char *machinename;
+char *machinearch;
+#define MACHINE_VAX 1
+#define MACHINE_TAHOE 2
+#define MACHINE_HP300 3
+#define MACHINE_I386 4
+#define MACHINE_PC532 5
+#define MACHINE_PMAX 6
+#define MACHINE_AMIGA 7
+
+/*
+ * For each machine, a set of CPU's may be specified as supported.
+ * These and the options (below) are put in the C flags in the makefile.
+ */
+struct cputype {
+ char *cpu_name;
+ struct cputype *cpu_next;
+} *cputype;
+
+/*
+ * A set of options may also be specified which are like CPU types,
+ * but which may also specify values for the options.
+ * A separate set of options may be defined for make-style options.
+ */
+struct opt {
+ char *op_name;
+ char *op_value;
+ struct opt *op_next;
+} *opt, *mkopt;
+
+char *ident;
+char *ns();
+char *tc();
+char *qu();
+char *get_word();
+char *get_quoted_word();
+char *path();
+char *raisestr();
+
+int do_trace;
+
+#if MACHINE_VAX
+int seen_mba, seen_uba;
+#endif
+#if MACHINE_TAHOE
+int seen_vba;
+#endif
+#if MACHINE_I386
+int seen_isa;
+#endif
+
+struct device *connect();
+struct device *dtab;
+dev_t nametodev();
+char *devtoname();
+
+char errbuf[80];
+int yyline;
+
+struct file_list *ftab, *conf_list, **confp, *comp_list, **compp;
+
+int zone, hadtz;
+int dst;
+int profiling;
+int debugging;
+
+int maxusers;
+u_int loadaddress;
+int fatal_errors;
+
+#define eq(a,b) (!strcmp(a,b))
--- /dev/null
+.\" $NetBSD: config.old.8,v 1.9 1995/08/17 17:22:09 thorpej Exp $
+.\"
+.\" Copyright (c) 1980, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)config.8 6.5 (Berkeley) 3/16/91
+.\"
+.Dd March 16, 1991
+.Dt CONFIG.OLD 8
+.Os BSD 4
+.Sh NAME
+.Nm config.old
+.Nd build system configuration files
+.Sh SYNOPSIS
+.Nm config.old
+.Op Fl gkp
+.Ar SYSTEM_NAME
+.Sh DESCRIPTION
+.Pp
+.Nm config.old
+builds a set of system configuration files from the file
+.Ar SYSTEM_NAME
+which describes
+the system to configure.
+A second file
+tells
+.Nm config.old
+what files are needed to generate a system and
+can be augmented by configuration specific set of files
+that give alternate files for a specific machine.
+(see the
+.Sx FILES
+section below)
+.Pp
+Available option and operand:
+.Pp
+.Bl -tag -width SYSTEM_NAME
+.It Fl g
+If the
+.Fl g
+option is supplied,
+.Nm config.old
+will configure a system for debugging.
+.It Fl k
+If the
+.Fl k
+option is supplied,
+.Nm config.old
+will not fail immediately on detection of a configuration error.
+.It Fl p
+If the
+.Fl p
+option is supplied,
+.Nm config.old
+will configure a system for profiling; for example,
+.Xr kgmon 8
+and
+.Xr gprof 1 .
+
+.It Ar SYSTEM_NAME
+specifies the name of the system configuration file
+containing device specifications, configuration options
+and other system parameters for one system configuration.
+.El
+.Pp
+.Nm config.old
+should be run from the
+.Pa conf
+subdirectory of the system source (usually
+.Pa /sys/arch/ARCH/conf ) .
+.Nm Config.old
+assumes the directory
+.Pa ../compile/SYSTEM_NAME
+exists and places all output files there.
+The output of
+.Nm config.old
+consists of a number of files; for the
+.Tn i386 ,
+they are:
+.Pa ioconf.c ,
+a description
+of what I/O devices are attached to the system;
+.Pa vector.s ,
+a set of interrupt service routines for devices
+attached to the bus plus
+offsets into a structure used for counting per-device interrupts;
+.Pa Makefile ,
+used by
+.Xr make 1
+in building the system;
+header files,
+definitions of
+the number of various devices that will be compiled into the system;
+swap configuration files,
+definitions for
+the disk areas to be used for swapping, the root file system,
+argument processing, and system dumps.
+.Pp
+After running
+.Nm config.old ,
+it is necessary to run
+.Dq Li make depend
+in the directory where the new makefile
+was created.
+.Nm Config.old
+prints a reminder of this when it completes.
+.Pp
+If any other error messages are produced by
+.Nm config.old ,
+the problems in the configuration file should be corrected and
+.Nm config.old
+should be run again.
+Attempts to compile a system that had configuration errors
+are likely to fail.
+.Sh FILES
+.Bl -tag -width /sys/arch/i386/conf/Makefile.i386 -compact
+.It Pa /sys/arch/i386/conf/Makefile.i386
+generic makefile for the
+.Tn i386
+.It Pa /sys/conf/files.oldconf
+list of common files system is built from
+.It Pa /sys/arch/i386/conf/files.i386.oldconf
+list of
+.Tn i386
+specific files
+.It Pa /sys/arch/i386/conf/devices.i386.oldconf
+name to major device mapping file for the
+.Tn i386
+.It Pa /sys/arch/i386/conf/files.oldconf. Ns Em ERNIE
+list of files specific to
+.Em ERNIE
+system
+.El
+.Sh SEE ALSO
+The SYNOPSIS portion of each device in section 4.
+.Rs
+.%T "Building 4.3 BSD UNIX System with Config"
+.Re
+.Sh BUGS
+The line numbers reported in error messages are usually off by one.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.1 .
--- /dev/null
+%union {
+ char *str;
+ int val;
+ struct file_list *file;
+ struct idlst *lst;
+}
+
+%token AND
+%token ANY
+%token ARGS
+%token AT
+%token BIO
+%token COMMA
+%token CONFIG
+%token CONTROLLER
+%token CPU
+%token CSR
+%token DEVICE
+%token DISK
+%token DRIVE
+%token DRQ
+%token DST
+%token DUMPS
+%token EQUALS
+%token FLAGS
+%token HIGH
+%token HZ
+%token IDENT
+%token INTERLEAVE
+%token IOMEM
+%token IOSIZ
+%token IRQ
+%token MACHIN
+%token MAJOR
+%token MANUFACTURER
+%token MASTER
+%token MAXUSERS
+%token MINOR
+%token MINUS
+%token NET
+%token NEXUS
+%token ON
+%token OPTIONS
+%token MAKEOPTIONS
+%token PORT
+%token PRIORITY
+%token PRODUCT
+%token PSEUDO_DEVICE
+%token ROOT
+%token SEMICOLON
+%token SEQUENTIAL
+%token SIZE
+%token SLAVE
+%token SWAP
+%token TIMEZONE
+%token TTY
+%token TRACE
+%token VECTOR
+
+%token <str> ID
+%token <val> NUMBER
+%token <val> FPNUMBER
+
+%type <str> Save_id
+%type <str> Opt_value
+%type <str> Dev
+%type <lst> Id_list
+%type <val> optional_size
+%type <val> optional_sflag
+%type <str> device_name
+%type <val> major_minor
+%type <val> arg_device_spec
+%type <val> root_device_spec
+%type <val> dump_device_spec
+%type <file> swap_device_spec
+
+%{
+/* $NetBSD: config.y,v 1.18 1995/08/17 17:22:10 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)config.y 5.14 (Berkeley) 7/1/91
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include "config.h"
+#include "specfile.h"
+
+struct device cur;
+struct device *curp = 0;
+char *temp_id;
+char *val_id;
+
+%}
+%%
+Configuration:
+ Many_specs
+ = { verifysystemspecs(); }
+ ;
+
+Many_specs:
+ Many_specs Spec
+ |
+ /* lambda */
+ ;
+
+Spec:
+ Device_spec SEMICOLON
+ = { newdev(&cur); } |
+ Config_spec SEMICOLON
+ |
+ TRACE SEMICOLON
+ = { do_trace = !do_trace; } |
+ SEMICOLON
+ |
+ error SEMICOLON
+ ;
+
+Config_spec:
+ MACHIN Save_id
+ = {
+ if (!strcmp($2, "vax")) {
+ machine = MACHINE_VAX;
+ machinename = "vax";
+ machinearch = machinename;
+ } else if (!strcmp($2, "tahoe")) {
+ machine = MACHINE_TAHOE;
+ machinename = "tahoe";
+ machinearch = machinename;
+ } else if (!strcmp($2, "hp300")) {
+ machine = MACHINE_HP300;
+ machinename = "hp300";
+ machinearch = "m68k";
+ } else if (!strcmp($2, "i386")) {
+ machine = MACHINE_I386;
+ machinename = "i386";
+ machinearch = machinename;
+ } else if (!strcmp($2, "pc532")) {
+ machine = MACHINE_PC532;
+ machinename = "pc532";
+ machinearch = machinename;
+ } else if (!strcmp($2, "pmax")) {
+ machine = MACHINE_PMAX;
+ machinename = "pmax";
+ machinearch = machinename;
+ } else if (!strcmp($2, "amiga")) {
+ machine = MACHINE_AMIGA;
+ machinename = "amiga";
+ machinearch = "m68k";
+ } else
+ yyerror("Unknown machine type");
+ } |
+ CPU Save_id
+ = {
+ struct cputype *cp =
+ (struct cputype *)malloc(sizeof (struct cputype));
+ cp->cpu_name = ns($2);
+ cp->cpu_next = cputype;
+ cputype = cp;
+ free(temp_id);
+ } |
+ OPTIONS Opt_list
+ |
+ MAKEOPTIONS Mkopt_list
+ |
+ IDENT ID
+ = { ident = ns($2); } |
+ System_spec
+ |
+ HZ NUMBER
+ = { yyerror("HZ specification obsolete; delete"); } |
+ TIMEZONE NUMBER
+ = { zone = 60 * $2; check_tz(); } |
+ TIMEZONE NUMBER DST NUMBER
+ = { zone = 60 * $2; dst = $4; check_tz(); } |
+ TIMEZONE NUMBER DST
+ = { zone = 60 * $2; dst = 1; check_tz(); } |
+ TIMEZONE FPNUMBER
+ = { zone = $2; check_tz(); } |
+ TIMEZONE FPNUMBER DST NUMBER
+ = { zone = $2; dst = $4; check_tz(); } |
+ TIMEZONE FPNUMBER DST
+ = { zone = $2; dst = 1; check_tz(); } |
+ TIMEZONE MINUS NUMBER
+ = { zone = -60 * $3; check_tz(); } |
+ TIMEZONE MINUS NUMBER DST NUMBER
+ = { zone = -60 * $3; dst = $5; check_tz(); } |
+ TIMEZONE MINUS NUMBER DST
+ = { zone = -60 * $3; dst = 1; check_tz(); } |
+ TIMEZONE MINUS FPNUMBER
+ = { zone = -$3; check_tz(); } |
+ TIMEZONE MINUS FPNUMBER DST NUMBER
+ = { zone = -$3; dst = $5; check_tz(); } |
+ TIMEZONE MINUS FPNUMBER DST
+ = { zone = -$3; dst = 1; check_tz(); } |
+ MAXUSERS NUMBER
+ = { maxusers = $2; };
+
+System_spec:
+ System_id System_parameter_list
+ = { checksystemspec(*confp); }
+ ;
+
+System_id:
+ CONFIG Save_id
+ = { mkconf($2); }
+ ;
+
+System_parameter_list:
+ System_parameter_list System_parameter
+ | System_parameter
+ ;
+
+System_parameter:
+ addr_spec
+ | swap_spec
+ | root_spec
+ | dump_spec
+ | arg_spec
+ ;
+
+addr_spec:
+ AT NUMBER
+ = { loadaddress = $2; };
+ ;
+
+swap_spec:
+ SWAP optional_on swap_device_list
+ ;
+
+swap_device_list:
+ swap_device_list AND swap_device
+ | swap_device
+ ;
+
+swap_device:
+ swap_device_spec optional_size optional_sflag
+ = { mkswap(*confp, $1, $2, $3); }
+ ;
+
+swap_device_spec:
+ device_name
+ = {
+ struct file_list *fl = newswap();
+
+ if (eq($1, "generic") || eq($1, "nfs"))
+ fl->f_fn = $1;
+ else {
+ fl->f_swapdev = nametodev($1, 0, 'b');
+ fl->f_fn = devtoname(fl->f_swapdev);
+ }
+ $$ = fl;
+ }
+ | major_minor
+ = {
+ struct file_list *fl = newswap();
+
+ fl->f_swapdev = $1;
+ fl->f_fn = devtoname($1);
+ $$ = fl;
+ }
+ ;
+
+root_spec:
+ ROOT optional_on root_device_spec
+ = {
+ struct file_list *fl = *confp;
+
+ if (fl && fl->f_rootdev != NODEV)
+ yyerror("extraneous root device specification");
+ else
+ fl->f_rootdev = $3;
+ }
+ ;
+
+root_device_spec:
+ device_name
+ = { $$ = nametodev($1, 0, 'a'); }
+ | major_minor
+ ;
+
+dump_spec:
+ DUMPS optional_on dump_device_spec
+ = {
+ struct file_list *fl = *confp;
+
+ if (fl && fl->f_dumpdev != NODEV)
+ yyerror("extraneous dump device specification");
+ else
+ fl->f_dumpdev = $3;
+ }
+
+ ;
+
+dump_device_spec:
+ device_name
+ = { $$ = nametodev($1, 0, 'b'); }
+ | major_minor
+ ;
+
+arg_spec:
+ ARGS optional_on arg_device_spec
+ = { yyerror("arg device specification obsolete, ignored"); }
+ ;
+
+arg_device_spec:
+ device_name
+ = { $$ = nametodev($1, 0, 'b'); }
+ | major_minor
+ ;
+
+major_minor:
+ MAJOR NUMBER MINOR NUMBER
+ = { $$ = makedev($2, $4); }
+ ;
+
+optional_on:
+ ON
+ | /* empty */
+ ;
+
+optional_size:
+ SIZE NUMBER
+ = { $$ = $2; }
+ | /* empty */
+ = { $$ = 0; }
+ ;
+
+optional_sflag:
+ SEQUENTIAL
+ = { $$ = 2; }
+ | /* empty */
+ = { $$ = 0; }
+ ;
+
+device_name:
+ Save_id
+ = { $$ = $1; }
+ | Save_id NUMBER
+ = {
+ char buf[80];
+
+ (void) sprintf(buf, "%s%d", $1, $2);
+ $$ = ns(buf); free($1);
+ }
+ | Save_id NUMBER ID
+ = {
+ char buf[80];
+
+ (void) sprintf(buf, "%s%d%s", $1, $2, $3);
+ $$ = ns(buf); free($1);
+ }
+ ;
+
+Opt_list:
+ Opt_list COMMA Option
+ |
+ Option
+ ;
+
+Option:
+ Save_id
+ = {
+ struct opt *op = (struct opt *)malloc(sizeof (struct opt));
+ op->op_name = ns($1);
+ op->op_next = opt;
+ op->op_value = 0;
+ opt = op;
+ free(temp_id);
+ } |
+ Save_id EQUALS Opt_value
+ = {
+ struct opt *op = (struct opt *)malloc(sizeof (struct opt));
+ op->op_name = ns($1);
+ op->op_next = opt;
+ op->op_value = ns($3);
+ opt = op;
+ free(temp_id);
+ free(val_id);
+ } ;
+
+Opt_value:
+ ID
+ = { $$ = val_id = ns($1); } |
+ NUMBER
+ = {
+ char nb[16];
+ (void) sprintf(nb, "%d", $1);
+ $$ = val_id = ns(nb);
+ } ;
+
+
+Save_id:
+ ID
+ = { $$ = temp_id = ns($1); }
+ ;
+
+Mkopt_list:
+ Mkopt_list COMMA Mkoption
+ |
+ Mkoption
+ ;
+
+Mkoption:
+ Save_id EQUALS Opt_value
+ = {
+ struct opt *op = (struct opt *)malloc(sizeof (struct opt));
+ op->op_name = ns($1);
+ op->op_next = mkopt;
+ op->op_value = ns($3);
+ mkopt = op;
+ free(temp_id);
+ free(val_id);
+ } ;
+
+Dev:
+ ID
+ = { $$ = ns($1); }
+ ;
+
+Device_spec:
+ DEVICE Dev_name Dev_info Int_spec
+ = { cur.d_type = DEVICE; } |
+ MASTER Dev_name Dev_info Int_spec
+ = { cur.d_type = MASTER; } |
+ DISK Dev_name Dev_info Int_spec
+ = { cur.d_dk = 1; cur.d_type = DEVICE; } |
+ CONTROLLER Dev_name Dev_info Int_spec
+ = { cur.d_type = CONTROLLER; } |
+ PSEUDO_DEVICE Init_dev Dev
+ = {
+ cur.d_name = $3;
+ cur.d_type = PSEUDO_DEVICE;
+ } |
+ PSEUDO_DEVICE Init_dev Dev NUMBER
+ = {
+ cur.d_name = $3;
+ cur.d_type = PSEUDO_DEVICE;
+ cur.d_slave = $4;
+ };
+
+Dev_name:
+ Init_dev Dev NUMBER
+ = {
+ cur.d_name = $2;
+ if (eq($2, "mba"))
+ seen_mba = 1;
+ else if (eq($2, "uba"))
+ seen_uba = 1;
+ else if (eq($2, "vba"))
+ seen_vba = 1;
+ else if (eq($2, "isa"))
+ seen_isa = 1;
+ cur.d_unit = $3;
+ };
+
+Init_dev:
+ /* lambda */
+ = { init_dev(&cur); };
+
+Dev_info:
+ Con_info Info_list
+ |
+ /* lambda */
+ ;
+
+Con_info:
+ AT Dev NUMBER
+ = {
+ if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) {
+ (void) sprintf(errbuf,
+ "%s must be connected to a nexus", cur.d_name);
+ yyerror(errbuf);
+ }
+ cur.d_conn = connect($2, $3);
+ } |
+ AT NEXUS NUMBER
+ = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; } |
+ AT MANUFACTURER NUMBER PRODUCT NUMBER
+ = { check_manuf_prod (&cur, $3, $5); cur.d_conn = TO_NEXUS; } ;
+
+Info_list:
+ Info_list Info
+ |
+ /* lambda */
+ ;
+
+Info:
+ CSR NUMBER
+ = { cur.d_addr = $2; } |
+ DRIVE NUMBER
+ = { cur.d_drive = $2; } |
+ SLAVE NUMBER
+ = {
+ if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS &&
+ cur.d_conn->d_type == MASTER)
+ cur.d_slave = $2;
+ else
+ yyerror("can't specify slave--not to master");
+ } |
+ IRQ NUMBER
+ = { cur.d_irq = $2; } |
+ DRQ NUMBER
+ = { cur.d_drq = $2; } |
+ IOMEM NUMBER
+ = { cur.d_maddr = $2; } |
+ IOSIZ NUMBER
+ = { cur.d_msize = $2; } |
+ PORT device_name
+ = { cur.d_port = ns($2); } |
+ PORT NUMBER
+ = { cur.d_portn = $2; } |
+ TTY
+ = { cur.d_mask = "tty"; } |
+ BIO
+ = { cur.d_mask = "bio"; } |
+ NET
+ = { cur.d_mask = "net"; } |
+ HIGH
+ = { cur.d_mask = "high"; } |
+ FLAGS NUMBER
+ = { cur.d_flags = $2; };
+
+Int_spec:
+ VECTOR Id_list
+ = { cur.d_vec = $2; } |
+ PRIORITY NUMBER
+ = { cur.d_pri = $2; } |
+ /* lambda */
+ ;
+
+Id_list:
+ Save_id
+ = {
+ struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
+ a->id = $1; a->id_next = 0; $$ = a;
+ } |
+ Save_id Id_list =
+ {
+ struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
+ a->id = $1; a->id_next = $2; $$ = a;
+ };
+
+%%
+
+yyerror(s)
+ char *s;
+{
+
+ fprintf(stderr, "config.old: line %d: %s\n", yyline + 1, s);
+}
+
+/*
+ * return the passed string in a new space
+ */
+char *
+ns(str)
+ register char *str;
+{
+ register char *cp;
+
+ cp = malloc((unsigned)(strlen(str)+1));
+ (void) strcpy(cp, str);
+ return (cp);
+}
+
+/*
+ * add a device to the list of devices
+ */
+newdev(dp)
+ register struct device *dp;
+{
+ register struct device *np;
+
+ np = (struct device *) malloc(sizeof *np);
+ *np = *dp;
+ np->d_next = 0;
+ if (curp == 0)
+ dtab = np;
+ else
+ curp->d_next = np;
+ curp = np;
+}
+
+/*
+ * note that a configuration should be made
+ */
+mkconf(sysname)
+ char *sysname;
+{
+ register struct file_list *fl, **flp;
+ register struct name_expr *expr;
+
+ fl = (struct file_list *) malloc(sizeof *fl);
+ expr = (struct name_expr *) malloc(sizeof *expr);
+ fl->f_type = SYSTEMSPEC;
+ fl->f_needs = expr;
+ expr->type = T_IDENTIFIER;
+ expr->name = sysname;
+ fl->f_rootdev = NODEV;
+ fl->f_dumpdev = NODEV;
+ fl->f_fn = 0;
+ fl->f_next = 0;
+ for (flp = confp; *flp; flp = &(*flp)->f_next)
+ ;
+ *flp = fl;
+ confp = flp;
+}
+
+struct file_list *
+newflist(ftype)
+ u_char ftype;
+{
+ struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
+
+ fl->f_type = ftype;
+ fl->f_next = 0;
+ fl->f_swapdev = NODEV;
+ fl->f_swapsize = 0;
+ fl->f_needs = 0;
+ fl->f_fn = 0;
+ return (fl);
+}
+
+struct file_list *
+newswap()
+{
+ struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
+
+ fl->f_type = SWAPSPEC;
+ fl->f_next = 0;
+ fl->f_swapdev = NODEV;
+ fl->f_swapsize = 0;
+ fl->f_needs = 0;
+ fl->f_fn = 0;
+ return (fl);
+}
+
+/*
+ * Add a swap device to the system's configuration
+ */
+mkswap(system, fl, size)
+ struct file_list *system, *fl;
+ int size;
+{
+ register struct file_list **flp;
+ char name[80];
+
+ if (system == 0 || system->f_type != SYSTEMSPEC) {
+ yyerror("\"swap\" spec precedes \"config\" specification");
+ return;
+ }
+ if (size < 0) {
+ yyerror("illegal swap partition size");
+ return;
+ }
+ /*
+ * Append swap description to the end of the list.
+ */
+ flp = &system->f_next;
+ for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next)
+ ;
+ fl->f_next = *flp;
+ *flp = fl;
+ fl->f_swapsize = size;
+ /*
+ * If first swap device for this system,
+ * set up f_fn field to insure swap
+ * files are created with unique names.
+ */
+ if (system->f_fn)
+ return;
+ if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs"))
+ system->f_fn = ns(fl->f_fn);
+ else
+ system->f_fn = ns(system->f_needs->name);
+}
+
+mkcomp(dp)
+ register struct device *dp;
+{
+ register struct file_list *fl, **flp;
+ register struct name_expr *expr;
+ char buf[80];
+
+ fl = (struct file_list *) malloc(sizeof *fl);
+ expr = (struct name_expr *) malloc(sizeof *expr);
+
+ fl->f_needs = expr;
+ expr->type = T_DEVICE_DRIVER;
+
+ fl->f_type = COMPDEVICE;
+ fl->f_compinfo = dp->d_unit;
+ fl->f_fn = ns(dp->d_name);
+ (void) sprintf(buf, "%s%d", dp->d_name, dp->d_unit);
+ fl->f_needs->name = ns(buf);
+ fl->f_next = 0;
+ for (flp = compp; *flp; flp = &(*flp)->f_next)
+ ;
+ *flp = fl;
+ compp = flp;
+}
+
+addcomp(compdev, fl)
+ struct file_list *compdev, *fl;
+{
+ register struct file_list **flp;
+ char name[80];
+
+ if (compdev == 0 || compdev->f_type != COMPDEVICE) {
+ yyerror("component spec precedes device specification");
+ return;
+ }
+ /*
+ * Append description to the end of the list.
+ */
+ flp = &compdev->f_next;
+ for (; *flp && (*flp)->f_type == COMPSPEC; flp = &(*flp)->f_next)
+ ;
+ fl->f_next = *flp;
+ *flp = fl;
+}
+
+/*
+ * find the pointer to connect to the given device and number.
+ * returns 0 if no such device and prints an error message
+ */
+struct device *
+connect(dev, num)
+ register char *dev;
+ register int num;
+{
+ register struct device *dp;
+ struct device *huhcon();
+
+ if (num == QUES)
+ return (huhcon(dev));
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ if ((num != dp->d_unit) || !eq(dev, dp->d_name))
+ continue;
+ if (dp->d_type != CONTROLLER && dp->d_type != MASTER) {
+ (void) sprintf(errbuf,
+ "%s connected to non-controller", dev);
+ yyerror(errbuf);
+ return (0);
+ }
+ return (dp);
+ }
+ (void) sprintf(errbuf, "%s %d not defined", dev, num);
+ yyerror(errbuf);
+ return (0);
+}
+
+/*
+ * connect to an unspecific thing
+ */
+struct device *
+huhcon(dev)
+ register char *dev;
+{
+ register struct device *dp, *dcp;
+ struct device rdev;
+ int oldtype;
+
+ /*
+ * First make certain that there are some of these to wildcard on
+ */
+ for (dp = dtab; dp != 0; dp = dp->d_next)
+ if (eq(dp->d_name, dev))
+ break;
+ if (dp == 0) {
+ (void) sprintf(errbuf, "no %s's to wildcard", dev);
+ yyerror(errbuf);
+ return (0);
+ }
+ oldtype = dp->d_type;
+ dcp = dp->d_conn;
+ /*
+ * Now see if there is already a wildcard entry for this device
+ * (e.g. Search for a "uba ?")
+ */
+ for (; dp != 0; dp = dp->d_next)
+ if (eq(dev, dp->d_name) && dp->d_unit == -1)
+ break;
+ /*
+ * If there isn't, make one because everything needs to be connected
+ * to something.
+ */
+ if (dp == 0) {
+ dp = &rdev;
+ init_dev(dp);
+ dp->d_unit = QUES;
+ dp->d_name = ns(dev);
+ dp->d_type = oldtype;
+ newdev(dp);
+ dp = curp;
+ /*
+ * Connect it to the same thing that other similar things are
+ * connected to, but make sure it is a wildcard unit
+ * (e.g. up connected to sc ?, here we make connect sc? to a
+ * uba?). If other things like this are on the NEXUS or
+ * if they aren't connected to anything, then make the same
+ * connection, else call ourself to connect to another
+ * unspecific device.
+ */
+ if (dcp == TO_NEXUS || dcp == 0)
+ dp->d_conn = dcp;
+ else
+ dp->d_conn = connect(dcp->d_name, QUES);
+ }
+ return (dp);
+}
+
+init_dev(dp)
+ register struct device *dp;
+{
+
+ dp->d_name = "OHNO!!!";
+ dp->d_type = DEVICE;
+ dp->d_conn = 0;
+ dp->d_vec = 0;
+ dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0;
+ dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
+ dp->d_port = (char *)0;
+ dp->d_portn = 0;
+ dp->d_irq = -2;
+ dp->d_drq = -1;
+ dp->d_maddr = 0;
+ dp->d_msize = 0;
+ dp->d_mask = "null";
+}
+
+/*
+ * make certain that this is a reasonable type of thing to connect to a nexus
+ */
+check_nexus(dev, num)
+ register struct device *dev;
+ int num;
+{
+
+ switch (machine) {
+
+ case MACHINE_VAX:
+ if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") &&
+ !eq(dev->d_name, "bi"))
+ yyerror("only uba's, mba's, and bi's should be connected to the nexus");
+ if (num != QUES)
+ yyerror("can't give specific nexus numbers");
+ break;
+
+ case MACHINE_TAHOE:
+ if (!eq(dev->d_name, "vba"))
+ yyerror("only vba's should be connected to the nexus");
+ break;
+
+ case MACHINE_HP300:
+ if (num != QUES)
+ dev->d_addr = num;
+ break;
+
+ case MACHINE_I386:
+ if (!eq(dev->d_name, "isa"))
+ yyerror("only isa's should be connected to the nexus");
+ break;
+ }
+}
+
+/*
+ * build a nexus ID out of manufacturer and product code
+ */
+check_manuf_prod (dev, manuf, prod)
+ register struct device *dev;
+ int manuf, prod;
+{
+ /* need either both wildcard or none */
+ if ((manuf == QUES) != (prod == QUES))
+ yyerror ("manufacturer and product must either be both set or both wildcard.");
+
+ /* enough to check one now */
+ if (manuf != QUES)
+ dev->d_addr = ((manuf & 0xffff) << 16) | (prod & 0xffff);
+}
+
+/*
+ * Check the timezone to make certain it is sensible
+ */
+
+check_tz()
+{
+ if (abs(zone) > 12 * 60)
+ yyerror("timezone is unreasonable");
+ else
+ hadtz = 1;
+}
+
+/*
+ * Check system specification and apply defaulting
+ * rules on root, argument, dump, and swap devices.
+ */
+checksystemspec(fl)
+ register struct file_list *fl;
+{
+ char buf[BUFSIZ];
+ register struct file_list *swap;
+ int generic, nfs;
+
+ if (fl == 0 || fl->f_type != SYSTEMSPEC) {
+ yyerror("internal error, bad system specification");
+ exit(1);
+ }
+ swap = fl->f_next;
+ generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
+ nfs = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "nfs");
+ if (fl->f_rootdev == NODEV && !generic && !nfs) {
+ yyerror("no root device specified");
+ exit(1);
+ }
+ /*
+ * Default swap area to be in 'b' partition of root's
+ * device. If root specified to be other than on 'a'
+ * partition, give warning, something probably amiss.
+ */
+ if (swap == 0 || swap->f_type != SWAPSPEC) {
+ dev_t dev;
+
+ swap = newswap();
+ dev = fl->f_rootdev;
+ if (minor(dev) & 07) {
+ (void) sprintf(buf,
+"Warning, swap defaulted to 'b' partition with root on '%c' partition",
+ (minor(dev) & 07) + 'a');
+ yyerror(buf);
+ }
+ swap->f_swapdev =
+ makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a'));
+ swap->f_fn = devtoname(swap->f_swapdev);
+ mkswap(fl, swap, 0);
+ }
+ /*
+ * Make sure a generic swap isn't specified, along with
+ * other stuff (user must really be confused).
+ */
+ if (generic) {
+ if (fl->f_rootdev != NODEV)
+ yyerror("root device specified with generic swap");
+ if (fl->f_dumpdev != NODEV)
+ yyerror("dump device specified with generic swap");
+ return;
+ }
+ /*
+ * Default dump device and warn if place is not a
+ * swap area.
+ */
+ if (fl->f_dumpdev == NODEV)
+ fl->f_dumpdev = swap->f_swapdev;
+ if (fl->f_dumpdev != swap->f_swapdev) {
+ struct file_list *p = swap->f_next;
+
+ for (; p && p->f_type == SWAPSPEC; p = p->f_next)
+ if (fl->f_dumpdev == p->f_swapdev)
+ return;
+ (void) sprintf(buf,
+ "Warning: dump device is not a swap partition");
+ yyerror(buf);
+ }
+}
+
+/*
+ * Verify all devices specified in the system specification
+ * are present in the device specifications.
+ */
+verifysystemspecs()
+{
+ register struct file_list *fl;
+ dev_t checked[50], *verifyswap();
+ register dev_t *pchecked = checked;
+
+ for (fl = conf_list; fl; fl = fl->f_next) {
+ if (fl->f_type != SYSTEMSPEC)
+ continue;
+ if (!finddev(fl->f_rootdev))
+ deverror(fl->f_needs->name, "root");
+ *pchecked++ = fl->f_rootdev;
+ pchecked = verifyswap(fl->f_next, checked, pchecked);
+#define samedev(dev1, dev2) \
+ ((minor(dev1) &~ 07) != (minor(dev2) &~ 07))
+ if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) {
+ if (!finddev(fl->f_dumpdev))
+ deverror(fl->f_needs->name, "dump");
+ *pchecked++ = fl->f_dumpdev;
+ }
+ }
+}
+
+/*
+ * Do as above, but for swap devices.
+ */
+dev_t *
+verifyswap(fl, checked, pchecked)
+ register struct file_list *fl;
+ dev_t checked[];
+ register dev_t *pchecked;
+{
+
+ for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
+ if (eq(fl->f_fn, "generic") || eq(fl->f_fn,"nfs"))
+ continue;
+ if (alreadychecked(fl->f_swapdev, checked, pchecked))
+ continue;
+ if (!finddev(fl->f_swapdev))
+ fprintf(stderr,
+ "config.old: swap device %s not configured", fl->f_fn);
+ *pchecked++ = fl->f_swapdev;
+ }
+ return (pchecked);
+}
+
+/*
+ * Verify that components of a compound device have themselves been config'ed
+ */
+verifycomp(fl)
+ register struct file_list *fl;
+{
+ char *dname = fl->f_needs->name;
+
+ for (fl = fl->f_next; fl; fl = fl->f_next) {
+ if (fl->f_type != COMPSPEC || finddev(fl->f_compdev))
+ continue;
+ fprintf(stderr,
+ "config.old: %s: component device %s not configured\n",
+ dname, fl->f_needs->name);
+ }
+}
+
+/*
+ * Has a device already been checked
+ * for it's existence in the configuration?
+ */
+alreadychecked(dev, list, last)
+ dev_t dev, list[];
+ register dev_t *last;
+{
+ register dev_t *p;
+
+ for (p = list; p < last; p++)
+ if (samedev(*p, dev))
+ return (1);
+ return (0);
+}
+
+deverror(systemname, devtype)
+ char *systemname, *devtype;
+{
+
+ fprintf(stderr, "config.old: %s: %s device not configured\n",
+ systemname, devtype);
+}
+
+/*
+ * Look for the device in the list of
+ * configured hardware devices. Must
+ * take into account stuff wildcarded.
+ */
+/*ARGSUSED*/
+finddev(dev)
+ dev_t dev;
+{
+
+ /* punt on this right now */
+ return (1);
+}
--- /dev/null
+%{
+/* $NetBSD: lang.l,v 1.12 1995/08/17 17:22:11 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)lang.l 5.8 (Berkeley) 4/19/91
+ */
+
+#include <ctype.h>
+#include "y.tab.h"
+#include "config.h"
+
+#define tprintf if (do_trace) printf
+
+/*
+ * Key word table
+ */
+
+struct kt {
+ char *kt_name;
+ int kt_val;
+} key_words[] = {
+ { "and", AND },
+ { "args", ARGS },
+ { "at", AT },
+#if MACHINE_I386
+ { "bio", BIO },
+#endif MACHINE_I386
+ { "config", CONFIG },
+ { "controller", CONTROLLER },
+ { "cpu", CPU },
+ { "csr", CSR },
+ { "device", DEVICE },
+ { "disk", DISK },
+ { "drive", DRIVE },
+#if MACHINE_I386
+ { "drq", DRQ },
+#endif MACHINE_I386
+ { "dst", DST },
+ { "dumps", DUMPS },
+ { "flags", FLAGS },
+#if MACHINE_I386
+ { "high", HIGH },
+#endif MACHINE_I386
+ { "hz", HZ },
+ { "ident", IDENT },
+ { "interleave", INTERLEAVE },
+#if MACHINE_I386
+ { "iomem", IOMEM },
+ { "iosiz", IOSIZ },
+ { "irq", IRQ },
+#endif MACHINE_I386
+ { "machine", MACHIN },
+ { "major", MAJOR },
+ { "makeoptions", MAKEOPTIONS },
+#if MACHINE_AMIGA
+ { "manufacturer", MANUFACTURER },
+#endif
+ { "master", MASTER },
+ { "maxusers", MAXUSERS },
+ { "minor", MINOR },
+#if MACHINE_I386
+ { "net", NET },
+#endif MACHINE_I386
+ { "nexus", NEXUS },
+ { "on", ON },
+ { "options", OPTIONS },
+#if MACHINE_I386
+ { "port", PORT },
+#endif MACHINE_I386
+ { "priority", PRIORITY },
+#if MACHINE_AMIGA
+ { "product", PRODUCT },
+#endif
+ { "pseudo-device",PSEUDO_DEVICE },
+ { "root", ROOT },
+ { "sequential", SEQUENTIAL },
+#if MACHINE_HP300
+ { "scode", NEXUS },
+#endif
+ { "size", SIZE },
+ { "slave", SLAVE },
+ { "swap", SWAP },
+ { "tape", DEVICE },
+#if MACHINE_I386
+ { "tty", TTY },
+#endif MACHINE_I386
+ { "timezone", TIMEZONE },
+ { "trace", TRACE },
+ { "vector", VECTOR },
+ { 0, 0 },
+};
+%}
+WORD [A-Za-z_]([A-Za-z_0-9]+[A-Za-z_])*[-A-Za-z_]*
+%%
+{WORD} {
+ int i;
+
+ if ((i = kw_lookup(yytext)) == -1)
+ {
+ yylval.str = yytext;
+ tprintf("id(%s) ", yytext);
+ return ID;
+ }
+ tprintf("(%s) ", yytext);
+ return i;
+ }
+\"([^\"]|\\\")*\" {
+ yytext[strlen(yytext)-1] = '\0';
+ yylval.str = yytext + 1;
+ tprintf("QID: %s", yylval.str);
+ return ID;
+ }
+0[0-7]* {
+ yylval.val = octal(yytext);
+ tprintf("#O:%o ", yylval.val);
+ return NUMBER;
+ }
+0x[0-9a-fA-F]+ {
+ yylval.val = hex(yytext);
+ tprintf("#X:%x ", yylval.val);
+ return NUMBER;
+ }
+[1-9][0-9]* {
+ yylval.val = atoi(yytext);
+ tprintf("#D:%d ", yylval.val);
+ return NUMBER;
+ }
+[0-9]"."[0-9]* {
+ double atof();
+ yylval.val = (int) (60 * atof(yytext) + 0.5);
+ return FPNUMBER;
+ }
+"-" {
+ return MINUS;
+ }
+"?" {
+ yylval.val = -1;
+ tprintf("? ");
+ return NUMBER;
+ }
+\n/[ \t] {
+ yyline++;
+ tprintf("\n... ");
+ }
+\n {
+ yyline++;
+ tprintf("\n");
+ return SEMICOLON;
+ }
+#.* { /* Ignored (comment) */; }
+[ \t]* { /* Ignored (white space) */; }
+";" { return SEMICOLON; }
+"," { return COMMA; }
+"=" { return EQUALS; }
+"@" { return AT; }
+. { return yytext[0]; }
+
+%%
+/*
+ * kw_lookup
+ * Look up a string in the keyword table. Returns a -1 if the
+ * string is not a keyword otherwise it returns the keyword number
+ */
+
+kw_lookup(word)
+register char *word;
+{
+ register struct kt *kp;
+
+ for (kp = key_words; kp->kt_name != 0; kp++)
+ if (eq(word, kp->kt_name))
+ return kp->kt_val;
+ return -1;
+}
+
+/*
+ * Number conversion routines
+ */
+
+octal(str)
+char *str;
+{
+ int num;
+
+ (void) sscanf(str, "%o", &num);
+ return num;
+}
+
+hex(str)
+char *str;
+{
+ int num;
+
+ (void) sscanf(str+2, "%x", &num);
+ return num;
+}
--- /dev/null
+/* $NetBSD: main.c,v 1.13 1995/08/17 17:22:12 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)main.c 5.17 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: main.c,v 1.13 1995/08/17 17:22:12 thorpej Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "y.tab.h"
+#include "config.h"
+
+static char *PREFIX;
+
+/*
+ * Config builds a set of files for building a UNIX
+ * system given a description of the desired system.
+ */
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+
+ extern char *optarg;
+ extern int optind;
+ struct stat buf;
+ int ch;
+ char *p;
+
+ fatal_errors =1;
+ while ((ch = getopt(argc, argv, "gpk")) != EOF)
+ switch (ch) {
+ case 'g':
+ debugging++;
+ break;
+ case 'p':
+ profiling++;
+ break;
+ case 'k':
+ fatal_errors=0;
+ break;
+ case '?':
+ default:
+ goto usage;
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+usage: fputs("usage: config.old [-gkp] sysname\n", stderr);
+ exit(1);
+ }
+
+ if (freopen(PREFIX = *argv, "r", stdin) == NULL) {
+ perror(PREFIX);
+ exit(2);
+ }
+ if (stat(p = path((char *)NULL), &buf)) {
+ if (mkdir(p, 0777)) {
+ perror(p);
+ exit(2);
+ }
+ }
+ else if ((buf.st_mode & S_IFMT) != S_IFDIR) {
+ fprintf(stderr, "config.old: %s isn't a directory.\n", p);
+ exit(2);
+ }
+
+ loadaddress = -1;
+ dtab = NULL;
+ confp = &conf_list;
+ compp = &comp_list;
+ if (yyparse())
+ exit(3);
+ switch (machine) {
+
+ case MACHINE_VAX:
+ vax_ioconf(); /* Print ioconf.c */
+ ubglue(); /* Create ubglue.s */
+ break;
+
+ case MACHINE_TAHOE:
+ tahoe_ioconf();
+ vbglue();
+ break;
+
+ case MACHINE_HP300:
+ hp300_ioconf();
+ hpglue();
+ break;
+
+ case MACHINE_I386:
+ i386_ioconf(); /* Print ioconf.c */
+ i386_vector(); /* Create vector.s */
+ break;
+
+ case MACHINE_PC532:
+ pc532_ioconf(); /* Print ioconf.c */
+ break;
+
+ case MACHINE_PMAX:
+ pmax_ioconf();
+ break;
+
+ case MACHINE_AMIGA:
+ amiga_ioconf();
+ amigaglue();
+ break;
+
+ default:
+ printf("Specify machine type, e.g. ``machine vax''\n");
+ exit(1);
+ }
+ /*
+ * make symbolic links in compilation directory
+ * for "sys" (to make genassym.c work along with #include <sys/xxx>)
+ * and similarly for "machine".
+ */
+ {
+ char xxx[200];
+
+#ifndef NO_SYMLINK
+ (void) sprintf(xxx, "../../include");
+ (void) symlink(xxx, path("machine"));
+ (void) sprintf(xxx, "../../../%s/include", machinearch);
+ (void) symlink(xxx, path(machinearch));
+#else
+ sprintf (xxx, "/bin/rm -rf %s; /bin/cp -r ../include %s",
+ path("machine"), path("machine"));
+ system (xxx);
+ sprintf (xxx, "/bin/rm -rf %s; /bin/cp -r ../../%s/include %s",
+ path(machinearch), machinearch, path(machinearch));
+ system (xxx);
+#endif
+ }
+ makefile(); /* build Makefile */
+ headers(); /* make a lot of .h files */
+ swapconf(); /* swap config files */
+ printf("Don't forget to run \"make depend\"\n");
+ exit(0);
+}
+
+#define is_paren(x) ((x == '(') || (x == ')'))
+#define is_comment(x) (x == '#')
+/*
+ * get_word
+ * returns EOF on end of file
+ * NULL on end of line
+ * pointer to the word otherwise
+ */
+char *
+get_word(fp)
+ register FILE *fp;
+{
+ static char line[80];
+ register int ch;
+ register char *cp;
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch != ' ' && ch != '\t')
+ break;
+ if (ch == EOF)
+ return ((char *)EOF);
+ if (ch == '\n')
+ return (NULL);
+ if (is_paren(ch)) {
+ line[0] = ch;
+ line[1] = '\0';
+ return line;
+ }
+ if (is_comment(ch)) {
+ while ((ch = getc(fp)) != EOF)
+ if (ch == '\n')
+ break;
+ if (ch == EOF) return ((char *)EOF);
+ else return NULL;
+ }
+ cp = line;
+ *cp++ = ch;
+ while ((ch = getc(fp)) != EOF) {
+ if (isspace(ch) || is_paren(ch))
+ break;
+ *cp++ = ch;
+ }
+ *cp = 0;
+ if (ch == EOF)
+ return ((char *)EOF);
+ (void) ungetc(ch, fp);
+ return (line);
+}
+
+/*
+ * get_rword
+ * returns EOF on end of file
+ * NULL on end of line
+ * pointer to the word otherwise
+ */
+char *
+get_rword(fp)
+ register FILE *fp;
+{
+ static char line[80];
+ register int ch;
+ register char *cp;
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch != ' ' && ch != '\t')
+ break;
+ if (ch == EOF)
+ return ((char *)EOF);
+ if (ch == '\n')
+ return (NULL);
+ cp = line;
+ *cp++ = ch;
+ while ((ch = getc(fp)) != EOF) {
+ if (isspace(ch) || is_paren(ch))
+ break;
+ *cp++ = ch;
+ }
+ *cp = 0;
+ if (ch == EOF)
+ return ((char *)EOF);
+ (void) ungetc(ch, fp);
+ return (line);
+}
+/*
+ * get_quoted_word
+ * like get_word but will accept something in double or single quotes
+ * (to allow embedded spaces).
+ */
+char *
+get_quoted_word(fp)
+ register FILE *fp;
+{
+ static char line[256];
+ register int ch;
+ register char *cp;
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch != ' ' && ch != '\t')
+ break;
+ if (ch == EOF)
+ return ((char *)EOF);
+ if (ch == '\n')
+ return (NULL);
+ cp = line;
+ if (ch == '"' || ch == '\'') {
+ register int quote = ch;
+
+ while ((ch = getc(fp)) != EOF) {
+ if (ch == quote)
+ break;
+ if (ch == '\n') {
+ *cp = 0;
+ printf("config.old: missing quote reading `%s'\n",
+ line);
+ exit(2);
+ }
+ *cp++ = ch;
+ }
+ } else {
+ *cp++ = ch;
+ while ((ch = getc(fp)) != EOF) {
+ if (isspace(ch))
+ break;
+ *cp++ = ch;
+ }
+ if (ch != EOF)
+ (void) ungetc(ch, fp);
+ }
+ *cp = 0;
+ if (ch == EOF)
+ return ((char *)EOF);
+ return (line);
+}
+
+/*
+ * prepend the path to a filename
+ */
+char *
+path(file)
+ char *file;
+{
+ register char *cp;
+
+#define CDIR "../compile/"
+ cp = malloc((unsigned int)(sizeof(CDIR) + strlen(PREFIX) +
+ (file ? strlen(file) : 0) + 2));
+ (void) strcpy(cp, CDIR);
+ (void) strcat(cp, PREFIX);
+ if (file) {
+ (void) strcat(cp, "/");
+ (void) strcat(cp, file);
+ }
+ return (cp);
+}
--- /dev/null
+/* $NetBSD: mkglue.c,v 1.10 1995/08/17 17:22:14 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkglue.c 5.10 (Berkeley) 1/15/91";*/
+static char rcsid[] = "$NetBSD: mkglue.c,v 1.10 1995/08/17 17:22:14 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Make the bus adaptor interrupt glue files.
+ */
+#include <stdio.h>
+#include "config.h"
+#include "y.tab.h"
+#include <ctype.h>
+
+/*
+ * Create the UNIBUS interrupt vector glue file.
+ */
+ubglue()
+{
+ register FILE *fp, *gp;
+ register struct device *dp, *mp;
+
+ fp = fopen(path("ubglue.s"), "w");
+ if (fp == 0) {
+ perror(path("ubglue.s"));
+ exit(1);
+ }
+ gp = fopen(path("ubvec.s"), "w");
+ if (gp == 0) {
+ perror(path("ubvec.s"));
+ exit(1);
+ }
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp != 0 && mp != (struct device *)-1 &&
+ !eq(mp->d_name, "mba")) {
+ struct idlst *id, *id2;
+
+ for (id = dp->d_vec; id; id = id->id_next) {
+ for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+ if (id2 == id) {
+ dump_ubavec(fp, id->id,
+ dp->d_unit);
+ break;
+ }
+ if (!strcmp(id->id, id2->id))
+ break;
+ }
+ }
+ }
+ }
+ dump_std(fp, gp);
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp != 0 && mp != (struct device *)-1 &&
+ !eq(mp->d_name, "mba")) {
+ struct idlst *id, *id2;
+
+ for (id = dp->d_vec; id; id = id->id_next) {
+ for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+ if (id2 == id) {
+ dump_intname(fp, id->id,
+ dp->d_unit);
+ break;
+ }
+ if (!strcmp(id->id, id2->id))
+ break;
+ }
+ }
+ }
+ }
+ dump_ctrs(fp);
+ (void) fclose(fp);
+ (void) fclose(gp);
+}
+
+static int cntcnt = 0; /* number of interrupt counters allocated */
+
+/*
+ * Print a UNIBUS interrupt vector.
+ */
+dump_ubavec(fp, vector, number)
+ register FILE *fp;
+ char *vector;
+ int number;
+{
+ char nbuf[80];
+ register char *v = nbuf;
+
+ (void) sprintf(v, "%s%d", vector, number);
+ fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n",
+ v, v);
+ fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
+ if (strncmp(vector, "dzx", 3) == 0)
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number);
+ else if (strncmp(vector, "dpx", 3) == 0)
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number);
+ else if (strncmp(vector, "dpr", 3) == 0)
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number);
+ else {
+ if (strncmp(vector, "uur", 3) == 0) {
+ fprintf(fp, "#ifdef UUDMA\n");
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number);
+ fprintf(fp, "#endif\n");
+ }
+ fprintf(fp, "\tpushl\t$%d\n", number);
+ fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector);
+ fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n");
+ }
+}
+
+/*
+ * Create the VERSAbus interrupt vector glue file.
+ */
+vbglue()
+{
+ register FILE *fp, *gp;
+ register struct device *dp, *mp;
+
+ fp = fopen(path("vbglue.s"), "w");
+ if (fp == 0) {
+ perror(path("vbglue.s"));
+ exit(1);
+ }
+ gp = fopen(path("vbvec.s"), "w");
+ if (gp == 0) {
+ perror(path("vbvec.s"));
+ exit(1);
+ }
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ struct idlst *id, *id2;
+
+ mp = dp->d_conn;
+ if (mp == 0 || mp == (struct device *)-1 ||
+ eq(mp->d_name, "mba"))
+ continue;
+ for (id = dp->d_vec; id; id = id->id_next)
+ for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+ if (id == id2) {
+ dump_vbavec(fp, id->id, dp->d_unit);
+ break;
+ }
+ if (eq(id->id, id2->id))
+ break;
+ }
+ }
+ dump_std(fp, gp);
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp != 0 && mp != (struct device *)-1 &&
+ !eq(mp->d_name, "mba")) {
+ struct idlst *id, *id2;
+
+ for (id = dp->d_vec; id; id = id->id_next) {
+ for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+ if (id2 == id) {
+ dump_intname(fp, id->id,
+ dp->d_unit);
+ break;
+ }
+ if (eq(id->id, id2->id))
+ break;
+ }
+ }
+ }
+ }
+ dump_ctrs(fp);
+ (void) fclose(fp);
+ (void) fclose(gp);
+}
+
+/*
+ * Print a VERSAbus interrupt vector
+ */
+dump_vbavec(fp, vector, number)
+ register FILE *fp;
+ char *vector;
+ int number;
+{
+ char nbuf[80];
+ register char *v = nbuf;
+
+ (void) sprintf(v, "%s%d", vector, number);
+ fprintf(fp, "SCBVEC(%s):\n", v);
+ fprintf(fp, "\tCHECK_SFE(4)\n");
+ fprintf(fp, "\tSAVE_FPSTAT(4)\n");
+ fprintf(fp, "\tPUSHR\n");
+ fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
+ fprintf(fp, "\tpushl\t$%d\n", number);
+ fprintf(fp, "\tcallf\t$8,_%s\n", vector);
+ fprintf(fp, "\tincl\t_cnt+V_INTR\n");
+ fprintf(fp, "\tPOPR\n");
+ fprintf(fp, "\tREST_FPSTAT\n");
+ fprintf(fp, "\trei\n\n");
+}
+
+/*
+ * HP9000/300 interrupts are auto-vectored.
+ * Code is hardwired in locore.s
+ */
+hpglue() {}
+
+/*
+ * so are AMIGA interrupts
+ */
+amigaglue() {}
+
+static char *vaxinames[] = {
+ "clock", "cnr", "cnx", "tur", "tux",
+ "mba0", "mba1", "mba2", "mba3",
+ "uba0", "uba1", "uba2", "uba3"
+};
+static char *tahoeinames[] = {
+ "clock", "cnr", "cnx", "rmtr", "rmtx", "buserr",
+};
+static struct stdintrs {
+ char **si_names; /* list of standard interrupt names */
+ int si_n; /* number of such names */
+} stdintrs[] = {
+ { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) },
+ { tahoeinames, (sizeof (tahoeinames) / sizeof (tahoeinames[0])) }
+};
+/*
+ * Start the interrupt name table with the names
+ * of the standard vectors not directly associated
+ * with a bus. Also, dump the defines needed to
+ * reference the associated counters into a separate
+ * file which is prepended to locore.s.
+ */
+dump_std(fp, gp)
+ register FILE *fp, *gp;
+{
+ register struct stdintrs *si = &stdintrs[machine-1];
+ register char **cpp;
+ register int i;
+
+ fprintf(fp, "\n\t.globl\t_intrnames\n");
+ fprintf(fp, "\n\t.globl\t_eintrnames\n");
+ fprintf(fp, "\t.data\n");
+ fprintf(fp, "_intrnames:\n");
+ cpp = si->si_names;
+ for (i = 0; i < si->si_n; i++) {
+ register char *cp, *tp;
+ char buf[80];
+
+ cp = *cpp;
+ if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
+ cp += 3;
+ if (*cp == 'r')
+ cp++;
+ }
+ for (tp = buf; *cp; cp++)
+ if (islower(*cp))
+ *tp++ = toupper(*cp);
+ else
+ *tp++ = *cp;
+ *tp = '\0';
+ fprintf(gp, "#define\tI_%s\t%d\n", buf, i*sizeof (long));
+ fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp);
+ cpp++;
+ }
+}
+
+dump_intname(fp, vector, number)
+ register FILE *fp;
+ char *vector;
+ int number;
+{
+ register char *cp = vector;
+
+ fprintf(fp, "\t.asciz\t\"");
+ /*
+ * Skip any "int" or "intr" in the name.
+ */
+ while (*cp)
+ if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
+ cp += 3;
+ if (*cp == 'r')
+ cp++;
+ } else {
+ putc(*cp, fp);
+ cp++;
+ }
+ fprintf(fp, "%d\"\n", number);
+}
+
+/*
+ * Reserve space for the interrupt counters.
+ */
+dump_ctrs(fp)
+ register FILE *fp;
+{
+ struct stdintrs *si = &stdintrs[machine-1];
+
+ fprintf(fp, "_eintrnames:\n");
+ fprintf(fp, "\n\t.globl\t_intrcnt\n");
+ fprintf(fp, "\n\t.globl\t_eintrcnt\n");
+ fprintf(fp, "\t.align 2\n");
+ fprintf(fp, "_intrcnt:\n");
+ fprintf(fp, "\t.space\t4 * %d\n", si->si_n);
+ fprintf(fp, "_fltintrcnt:\n");
+ fprintf(fp, "\t.space\t4 * %d\n", cntcnt);
+ fprintf(fp, "_eintrcnt:\n\n");
+ fprintf(fp, "\t.text\n");
+}
+
+/*
+ * Create the ISA interrupt vector glue file.
+ */
+i386_vector() {
+ register FILE *fp, *gp;
+ register struct device *dp, *mp;
+ int count;
+
+ fp = fopen(path("vector.h"), "w");
+ if (fp == 0) {
+ perror(path("vector.h"));
+ exit(1);
+ }
+ fprintf(fp, "\
+/*\n\
+ * AT/386\n\
+ * Macros for interrupt vector routines\n\
+ * Generated by config program\n\
+ */\n\
+\n");
+
+ fprintf(fp, "\
+#define BUILD_VECTORS \\\n\
+ BUILD_VECTOR(clk, 0,0,0, _clockmask, _clockintr,1,1, al);\\\n");
+
+ count=1;
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp != 0 && /* mp != (struct device *)-1 &&*/
+ eq(mp->d_name, "isa")) {
+ struct idlst *id, *id2;
+
+ for (id = dp->d_vec; id; id = id->id_next) {
+ for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+ if (id2 == id) {
+ build_vector(fp, dp, id, count);
+ count++;
+ if (!strcmp(id->id, id2->id))
+ break;
+ }
+ }
+ }
+ }
+ }
+ fprintf(fp, "\n\n#define NR_REAL_INT_HANDLERS %d\n", count);
+ (void) fclose(fp);
+}
+
+build_vector(fp, dp, id, offset)
+ register FILE *fp;
+ register struct device *dp;
+ struct idlst *id;
+ int offset;
+{
+ fprintf(fp, "\tBUILD_%sVECTOR(%s%d, %d,%d,%d",
+ strcmp(dp->d_name, "sio") == 0 ? "FAST_" : "",
+ dp->d_name, dp->d_unit, dp->d_unit, dp->d_irq, offset);
+ if (eq(dp->d_mask, "null"))
+ fprintf(fp, ", _%s%dmask,", dp->d_name, dp->d_unit);
+ else
+ fprintf(fp, ", _%smask, ", dp->d_mask);
+ fprintf(fp, " _%s,%d,1", id->id, 1 + dp->d_irq / 8);
+ if (dp->d_irq < 8)
+ fprintf(fp, ", al");
+ else
+ fprintf(fp, "_AND_2, ah");
+ fprintf(fp, ");\\\n");
+}
--- /dev/null
+/* $NetBSD: mkheaders.c,v 1.7 1995/08/17 17:22:15 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkheaders.c 5.7 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: mkheaders.c,v 1.7 1995/08/17 17:22:15 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Make all the .h files for the optional entries
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "config.h"
+#include "y.tab.h"
+#include "specfile.h"
+
+headers()
+{
+ register struct file_list *fl;
+
+ for (fl = ftab; fl != 0; fl = fl->f_next)
+ if (fl->f_was_driver)
+ do_identifiers(fl->f_needs);
+ else if (fl->f_needs_count)
+ do_identifiers(fl->f_countname);
+}
+
+do_identifiers(expr)
+ register struct name_expr *expr;
+{
+
+ if (expr->left)
+ do_identifiers(expr->left);
+ if (expr->type == T_IDENTIFIER)
+ do_count(expr->name, expr->name, 1);
+ if (expr->right)
+ do_identifiers(expr->right);
+}
+
+/*
+ * count all the devices of a certain type and recurse to count
+ * whatever the device is connected to
+ */
+do_count(dev, hname, search)
+ register char *dev, *hname;
+ int search;
+{
+ register struct device *dp, *mp;
+ register int count;
+
+ for (count = 0,dp = dtab; dp != 0; dp = dp->d_next)
+ if (dp->d_unit != -1 && eq(dp->d_name, dev)) {
+ if (dp->d_type == PSEUDO_DEVICE) {
+ count =
+ dp->d_slave != UNKNOWN ? dp->d_slave : 1;
+ if (dp->d_flags)
+ dev = NULL;
+ break;
+ }
+ count++;
+ /*
+ * Allow holes in unit numbering,
+ * assumption is unit numbering starts
+ * at zero.
+ */
+ if (dp->d_unit + 1 > count)
+ count = dp->d_unit + 1;
+ if (search) {
+ mp = dp->d_conn;
+ if (mp != 0 && mp != TO_NEXUS &&
+ mp->d_conn != 0 && mp->d_conn != TO_NEXUS) {
+ do_count(mp->d_name, hname, 0);
+ search = 0;
+ }
+ }
+ }
+ do_header(dev, hname, count);
+}
+
+do_header(dev, hname, count)
+ char *dev, *hname;
+ int count;
+{
+ char *file, *name, *inw, *toheader(), *tomacro(), *get_rword();
+ struct file_list *fl, *fl_head;
+ FILE *inf, *outf;
+ int inc = 0, oldcount;
+
+ file = toheader(hname);
+ name = tomacro(dev?dev:hname) + (dev == NULL);
+ inf = fopen(file, "r");
+ oldcount = -1;
+ if (inf == 0) {
+ outf = fopen(file, "w");
+ if (outf == 0) {
+ perror(file);
+ exit(1);
+ }
+ if (dev || (!dev && count))
+ fprintf(outf, "#define %s %d\n", name, count);
+ (void) fclose(outf);
+ return;
+ }
+ fl_head = 0;
+ for (;;) {
+ char *cp;
+ if ((inw = get_rword(inf)) == 0 || inw == (char *)EOF)
+ break;
+ if ((inw = get_rword(inf)) == 0 || inw == (char *)EOF)
+ break;
+ inw = ns(inw);
+ cp = get_rword(inf);
+ if (cp == 0 || cp == (char *)EOF)
+ break;
+ inc = atoi(cp);
+ if (eq(inw, name)) {
+ oldcount = inc;
+ inc = count;
+ }
+ cp = get_rword(inf);
+ if (cp == (char *)EOF)
+ break;
+ fl = (struct file_list *) malloc(sizeof *fl);
+ bzero(fl, sizeof(*fl));
+ fl->f_fn = inw;
+ fl->f_type = inc;
+ fl->f_next = fl_head;
+ fl_head = fl;
+ }
+ (void) fclose(inf);
+/*DEBUG printf("%s: dev=%x, inc=%d, oldcount=%d count=%d\n",
+ file, dev, inc, oldcount, count); */
+ if (!dev && inc == 0 && oldcount == -1 && count == 0)
+ oldcount = 0;
+ else if (!dev && count == 0)
+ oldcount = -1;
+ if (count == oldcount) {
+ for (fl = fl_head; fl;) {
+ struct file_list *fln = fl->f_next;
+
+ free((char *)fl);
+ fl = fln;
+ }
+ return;
+ }
+ if (oldcount == -1) {
+ fl = (struct file_list *) malloc(sizeof *fl);
+ bzero(fl, sizeof(*fl));
+ fl->f_fn = name;
+ fl->f_type = count;
+ fl->f_next = fl_head;
+ fl_head = fl;
+ }
+ outf = fopen(file, "w");
+ if (outf == 0) {
+ perror(file);
+ exit(1);
+ }
+ for (fl = fl_head; fl;) {
+ struct file_list *fln = fl->f_next;
+
+ if (dev || (!dev && count))
+ fprintf(outf, "#define %s %u\n",
+ fl->f_fn, count ? fl->f_type : 0);
+ free((char *)fl);
+ fl = fln;
+ }
+ (void) fclose(outf);
+}
+
+/*
+ * convert a dev name to a .h file name
+ */
+char *
+toheader(dev)
+ char *dev;
+{
+ static char hbuf[80];
+
+ (void) strcpy(hbuf, path(dev));
+ (void) strcat(hbuf, ".h");
+ return (hbuf);
+}
+
+/*
+ * convert a dev name to a macro name
+ */
+char *tomacro(dev)
+ register char *dev;
+{
+ static char mbuf[20];
+ register char *cp;
+
+ cp = mbuf;
+ *cp++ = 'N';
+ while (*dev) {
+ if (islower(*dev))
+ *cp++ = toupper(*dev++);
+ else
+ *cp++ = *dev++;
+ }
+ *cp++ = 0;
+ return (mbuf);
+}
--- /dev/null
+/* $NetBSD: mkioconf.c,v 1.37 1995/08/17 17:22:17 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkioconf.c 5.18 (Berkeley) 5/10/91";*/
+static char rcsid[] = "$NetBSD: mkioconf.c,v 1.37 1995/08/17 17:22:17 thorpej Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "y.tab.h"
+#include "config.h"
+
+/*
+ * build the ioconf.c file
+ */
+char *qu();
+char *intv();
+
+static char *fakepdevs[] = {
+ "ether", /* XXX */
+ "log", /* XXX */
+ NULL,
+};
+
+pseudo_init(fp)
+ FILE *fp;
+{
+ struct device *dp;
+ char **s;
+ int ok, num;
+
+ fprintf(fp, "\n/* pseudo-devices */\n");
+ for (dp = dtab; dp; dp = dp->d_next) {
+ if (dp->d_type != PSEUDO_DEVICE)
+ continue;
+ for (ok = 1, s = fakepdevs; *s && ok; s++)
+ if (strcmp(dp->d_name, *s) == 0)
+ ok = 0;
+ if (ok == 0)
+ continue;
+ fprintf(fp, "extern void %sattach __P((int));\n",
+ dp->d_name);
+ }
+
+ fprintf(fp, "\nstruct pdevinit pdevinit[] = {\n");
+ for (dp = dtab; dp; dp = dp->d_next) {
+ if (dp->d_type != PSEUDO_DEVICE)
+ continue;
+ for (ok = 1, s = fakepdevs; *s && ok; s++)
+ if (strcmp(dp->d_name, *s) == 0)
+ ok = 0;
+ if (ok == 0)
+ continue;
+ num = dp->d_slave != UNKNOWN ? dp->d_slave : 0;
+ fprintf(fp, "\t{ %sattach, %d },\n",
+ dp->d_name, num);
+ }
+ fprintf(fp, "\t{ 0, 0 }\n};\n");
+}
+
+#if MACHINE_VAX
+vax_ioconf()
+{
+ register struct device *dp, *mp, *np;
+ register int uba_n, slave;
+ FILE *fp;
+
+ fp = fopen(path("ioconf.c"), "w");
+ if (fp == 0) {
+ perror(path("ioconf.c"));
+ exit(1);
+ }
+ fprintf(fp, "#include \"vax/include/pte.h\"\n");
+ fprintf(fp, "#include \"sys/param.h\"\n");
+ fprintf(fp, "#include \"sys/device.h\"\n");
+ fprintf(fp, "#include \"sys/buf.h\"\n");
+ fprintf(fp, "#include \"sys/map.h\"\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#include \"vax/mba/mbavar.h\"\n");
+ fprintf(fp, "#include \"vax/uba/ubavar.h\"\n\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#define C (caddr_t)\n\n");
+ /*
+ * First print the mba initialization structures
+ */
+ if (seen_mba) {
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || mp == TO_NEXUS ||
+ !eq(mp->d_name, "mba"))
+ continue;
+ fprintf(fp, "extern struct mba_driver %sdriver;\n",
+ dp->d_name);
+ }
+ fprintf(fp, "\nstruct mba_device mbdinit[] = {\n");
+ fprintf(fp, "\t/* Device, Unit, Mba, Drive, Dk */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES || mp == 0 ||
+ mp == TO_NEXUS || !eq(mp->d_name, "mba"))
+ continue;
+ if (dp->d_addr) {
+ printf("can't specify csr address on mba for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_vec != 0) {
+ printf("can't specify vector for %s%d on mba\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_drive == UNKNOWN) {
+ printf("drive not specified for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_slave != UNKNOWN) {
+ printf("can't specify slave number for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ fprintf(fp, "\t{ &%sdriver, %d, %s,",
+ dp->d_name, dp->d_unit, qu(mp->d_unit));
+ fprintf(fp, " %s, %d },\n",
+ qu(dp->d_drive), dp->d_dk);
+ }
+ fprintf(fp, "\t0\n};\n\n");
+ /*
+ * Print the mbsinit structure
+ * Driver Controller Unit Slave
+ */
+ fprintf(fp, "struct mba_slave mbsinit [] = {\n");
+ fprintf(fp, "\t/* Driver, Ctlr, Unit, Slave */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ /*
+ * All slaves are connected to something which
+ * is connected to the massbus.
+ */
+ if ((mp = dp->d_conn) == 0 || mp == TO_NEXUS)
+ continue;
+ np = mp->d_conn;
+ if (np == 0 || np == TO_NEXUS ||
+ !eq(np->d_name, "mba"))
+ continue;
+ fprintf(fp, "\t{ &%sdriver, %s",
+ mp->d_name, qu(mp->d_unit));
+ fprintf(fp, ", %2d, %s },\n",
+ dp->d_unit, qu(dp->d_slave));
+ }
+ fprintf(fp, "\t0\n};\n\n");
+ }
+ /*
+ * Now generate interrupt vectors for the unibus
+ */
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ if (dp->d_vec != 0) {
+ struct idlst *ip;
+ mp = dp->d_conn;
+ if (mp == 0 || mp == TO_NEXUS ||
+ (!eq(mp->d_name, "uba") && !eq(mp->d_name, "bi")))
+ continue;
+ fprintf(fp,
+ "extern struct uba_driver %sdriver;\n",
+ dp->d_name);
+ fprintf(fp, "extern ");
+ ip = dp->d_vec;
+ for (;;) {
+ fprintf(fp, "X%s%d()", ip->id, dp->d_unit);
+ ip = ip->id_next;
+ if (ip == 0)
+ break;
+ fprintf(fp, ", ");
+ }
+ fprintf(fp, ";\n");
+ fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name,
+ dp->d_unit);
+ ip = dp->d_vec;
+ for (;;) {
+ fprintf(fp, "X%s%d", ip->id, dp->d_unit);
+ ip = ip->id_next;
+ if (ip == 0)
+ break;
+ fprintf(fp, ", ");
+ }
+ fprintf(fp, ", 0 } ;\n");
+ }
+ }
+ fprintf(fp, "\nstruct uba_ctlr ubminit[] = {\n");
+ fprintf(fp, "/*\t driver,\tctlr,\tubanum,\talive,\tintr,\taddr */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 ||
+ !eq(mp->d_name, "uba"))
+ continue;
+ if (dp->d_vec == 0) {
+ printf("must specify vector for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_addr == 0) {
+ printf("must specify csr address for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("drives need their own entries; dont ");
+ printf("specify drive or slave for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_flags) {
+ printf("controllers (e.g. %s%d) ",
+ dp->d_name, dp->d_unit);
+ printf("don't have flags, only devices do\n");
+ continue;
+ }
+ fprintf(fp,
+ "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0%o },\n",
+ dp->d_name, dp->d_unit, qu(mp->d_unit),
+ dp->d_name, dp->d_unit, dp->d_addr);
+ }
+ fprintf(fp, "\t0\n};\n");
+ /* unibus devices */
+ fprintf(fp, "\nstruct uba_device ubdinit[] = {\n");
+ fprintf(fp,
+ "\t/* driver, unit, ctlr, ubanum, slave, intr, addr, dk, flags*/\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
+ mp == TO_NEXUS || mp->d_type == MASTER ||
+ eq(mp->d_name, "mba"))
+ continue;
+ np = mp->d_conn;
+ if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba"))
+ continue;
+ np = 0;
+ if (eq(mp->d_name, "uba")) {
+ if (dp->d_vec == 0) {
+ printf("must specify vector for device %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_addr == 0) {
+ printf("must specify csr for device %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("drives/slaves can be specified ");
+ printf("only for controllers, ");
+ printf("not for device %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ uba_n = mp->d_unit;
+ slave = QUES;
+ } else {
+ if ((np = mp->d_conn) == 0) {
+ printf("%s%d isn't connected to anything ",
+ mp->d_name, mp->d_unit);
+ printf(", so %s%d is unattached\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ uba_n = np->d_unit;
+ if (dp->d_drive == UNKNOWN) {
+ printf("must specify ``drive number'' ");
+ printf("for %s%d\n", dp->d_name, dp->d_unit);
+ continue;
+ }
+ /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */
+ /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
+ if (dp->d_slave != UNKNOWN) {
+ printf("slave numbers should be given only ");
+ printf("for massbus tapes, not for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_vec != 0) {
+ printf("interrupt vectors should not be ");
+ printf("given for drive %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_addr != 0) {
+ printf("csr addresses should be given only ");
+ printf("on controllers, not on %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ slave = dp->d_drive;
+ }
+ fprintf(fp, "\t{ &%sdriver, %2d, %s,",
+ eq(mp->d_name, "uba") ? dp->d_name : mp->d_name, dp->d_unit,
+ eq(mp->d_name, "uba") ? " -1" : qu(mp->d_unit));
+ fprintf(fp, " %s, %2d, %s, C 0%-6o, %d, 0x%x },\n",
+ qu(uba_n), slave, intv(dp), dp->d_addr, dp->d_dk,
+ dp->d_flags);
+ }
+ fprintf(fp, "\t0\n};\n");
+ pseudo_init(fp);
+ (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_TAHOE
+tahoe_ioconf()
+{
+ register struct device *dp, *mp, *np;
+ register int vba_n, slave;
+ FILE *fp;
+
+ fp = fopen(path("ioconf.c"), "w");
+ if (fp == 0) {
+ perror(path("ioconf.c"));
+ exit(1);
+ }
+ fprintf(fp, "#include \"sys/param.h\"\n");
+ fprintf(fp, "#include \"tahoe/include/pte.h\"\n");
+ fprintf(fp, "#include \"sys/device.h\"\n");
+ fprintf(fp, "#include \"sys/buf.h\"\n");
+ fprintf(fp, "#include \"sys/map.h\"\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#include \"tahoe/vba/vbavar.h\"\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#define C (caddr_t)\n\n");
+ /*
+ * Now generate interrupt vectors for the versabus
+ */
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || mp == TO_NEXUS || !eq(mp->d_name, "vba"))
+ continue;
+ if (dp->d_vec != 0) {
+ struct idlst *ip;
+ fprintf(fp,
+ "extern struct vba_driver %sdriver;\n",
+ dp->d_name);
+ fprintf(fp, "extern ");
+ ip = dp->d_vec;
+ for (;;) {
+ fprintf(fp, "X%s%d()", ip->id, dp->d_unit);
+ ip = ip->id_next;
+ if (ip == 0)
+ break;
+ fprintf(fp, ", ");
+ }
+ fprintf(fp, ";\n");
+ fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name,
+ dp->d_unit);
+ ip = dp->d_vec;
+ for (;;) {
+ fprintf(fp, "X%s%d", ip->id, dp->d_unit);
+ ip = ip->id_next;
+ if (ip == 0)
+ break;
+ fprintf(fp, ", ");
+ }
+ fprintf(fp, ", 0 } ;\n");
+ } else if (dp->d_type == DRIVER) /* devices w/o interrupts */
+ fprintf(fp,
+ "extern struct vba_driver %sdriver;\n",
+ dp->d_name);
+ }
+ fprintf(fp, "\nstruct vba_ctlr vbminit[] = {\n");
+ fprintf(fp, "/*\t driver,\tctlr,\tvbanum,\talive,\tintr,\taddr */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 ||
+ !eq(mp->d_name, "vba"))
+ continue;
+ if (dp->d_vec == 0) {
+ printf("must specify vector for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_addr == 0) {
+ printf("must specify csr address for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("drives need their own entries; dont ");
+ printf("specify drive or slave for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_flags) {
+ printf("controllers (e.g. %s%d) ",
+ dp->d_name, dp->d_unit);
+ printf("don't have flags, only devices do\n");
+ continue;
+ }
+ fprintf(fp,
+ "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0x%x },\n",
+ dp->d_name, dp->d_unit, qu(mp->d_unit),
+ dp->d_name, dp->d_unit, dp->d_addr);
+ }
+ fprintf(fp, "\t0\n};\n");
+ /* versabus devices */
+ fprintf(fp, "\nstruct vba_device vbdinit[] = {\n");
+ fprintf(fp,
+ "\t/* driver, unit, ctlr, vbanum, slave, intr, addr, dk, flags*/\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
+ mp == TO_NEXUS || mp->d_type == MASTER ||
+ eq(mp->d_name, "mba"))
+ continue;
+ np = mp->d_conn;
+ if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba"))
+ continue;
+ np = 0;
+ if (eq(mp->d_name, "vba")) {
+ if (dp->d_vec == 0)
+ printf(
+ "Warning, no interrupt vector specified for device %s%d\n",
+ dp->d_name, dp->d_unit);
+ if (dp->d_addr == 0) {
+ printf("must specify csr for device %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("drives/slaves can be specified ");
+ printf("only for controllers, ");
+ printf("not for device %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ vba_n = mp->d_unit;
+ slave = QUES;
+ } else {
+ if ((np = mp->d_conn) == 0) {
+ printf("%s%d isn't connected to anything ",
+ mp->d_name, mp->d_unit);
+ printf(", so %s%d is unattached\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ vba_n = np->d_unit;
+ if (dp->d_drive == UNKNOWN) {
+ printf("must specify ``drive number'' ");
+ printf("for %s%d\n", dp->d_name, dp->d_unit);
+ continue;
+ }
+ /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */
+ /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
+ if (dp->d_slave != UNKNOWN) {
+ printf("slave numbers should be given only ");
+ printf("for massbus tapes, not for %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_vec != 0) {
+ printf("interrupt vectors should not be ");
+ printf("given for drive %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ if (dp->d_addr != 0) {
+ printf("csr addresses should be given only ");
+ printf("on controllers, not on %s%d\n",
+ dp->d_name, dp->d_unit);
+ continue;
+ }
+ slave = dp->d_drive;
+ }
+ fprintf(fp, "\t{ &%sdriver, %2d, %s,",
+ eq(mp->d_name, "vba") ? dp->d_name : mp->d_name, dp->d_unit,
+ eq(mp->d_name, "vba") ? " -1" : qu(mp->d_unit));
+ fprintf(fp, " %s, %2d, %s, C 0x%-6x, %d, 0x%x },\n",
+ qu(vba_n), slave, intv(dp), dp->d_addr, dp->d_dk,
+ dp->d_flags);
+ }
+ fprintf(fp, "\t0\n};\n");
+ pseudo_init(fp);
+ (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_HP300
+hp300_ioconf()
+{
+ register struct device *dp, *mp, *np;
+ register int hpib, slave;
+ FILE *fp;
+ extern char *wnum();
+
+ fp = fopen(path("ioconf.c"), "w");
+ if (fp == 0) {
+ perror(path("ioconf.c"));
+ exit(1);
+ }
+ fprintf(fp, "#include \"sys/param.h\"\n");
+ fprintf(fp, "#include \"sys/device.h\"\n");
+ fprintf(fp, "#include \"sys/buf.h\"\n");
+ fprintf(fp, "#include \"sys/map.h\"\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#include \"hp300/dev/device.h\"\n\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#define C (caddr_t)\n");
+ fprintf(fp, "#define D (struct driver *)\n\n");
+ /*
+ * First print the hpib controller initialization structures
+ */
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES || mp == 0)
+ continue;
+ fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
+ }
+ fprintf(fp, "\nstruct hp_ctlr hp_cinit[] = {\n");
+ fprintf(fp, "/*\tdriver,\t\tunit,\talive,\taddr,\tflags */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES ||
+ dp->d_type != MASTER && dp->d_type != CONTROLLER)
+ continue;
+ if (mp != TO_NEXUS) {
+ printf("%s%s must be attached to an sc (nexus)\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("can't specify drive/slave for %s%s\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ fprintf(fp,
+ "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t0x%x },\n",
+ dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags);
+ }
+ fprintf(fp, "\t0\n};\n");
+ /* devices */
+ fprintf(fp, "\nstruct hp_device hp_dinit[] = {\n");
+ fprintf(fp,
+ "/*driver,\tcdriver,\tunit,\tctlr,\tslave,\taddr,\tdk,\tflags*/\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || dp->d_type != DEVICE || hpbadslave(mp, dp))
+ continue;
+ if (mp == TO_NEXUS) {
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("can't specify drive/slave for %s%s\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ slave = QUES;
+ hpib = QUES;
+ } else {
+ if (dp->d_addr != 0) {
+ printf("can't specify sc for device %s%s\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ if (mp->d_type == CONTROLLER) {
+ if (dp->d_drive == UNKNOWN) {
+ printf("must specify drive for %s%s\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ slave = dp->d_drive;
+ } else {
+ if (dp->d_slave == UNKNOWN) {
+ printf("must specify slave for %s%s\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ slave = dp->d_slave;
+ }
+ hpib = mp->d_unit;
+ }
+ fprintf(fp, "{ &%sdriver,\t", dp->d_name);
+ if (mp == TO_NEXUS)
+ fprintf(fp, "D 0x0,\t");
+ else
+ fprintf(fp, "&%sdriver,", mp->d_name);
+ fprintf(fp, "\t%d,\t%d,\t%d,\tC 0x%x,\t%d,\t0x%x },\n",
+ dp->d_unit, hpib, slave,
+ dp->d_addr, dp->d_dk, dp->d_flags);
+ }
+ fprintf(fp, "0\n};\n");
+ pseudo_init(fp);
+ (void) fclose(fp);
+}
+
+#define ishpibdev(n) (eq(n,"rd") || eq(n,"ct") || eq(n,"mt") || eq(n,"ppi"))
+#define isscsidev(n) (eq(n,"sd") || eq(n,"st"))
+
+hpbadslave(mp, dp)
+ register struct device *dp, *mp;
+{
+ extern char *wnum();
+
+ if (mp == TO_NEXUS && ishpibdev(dp->d_name) ||
+ mp != TO_NEXUS && eq(mp->d_name, "hpib") &&
+ !ishpibdev(dp->d_name)) {
+ printf("%s%s must be attached to an hpib\n",
+ dp->d_name, wnum(dp->d_unit));
+ return (1);
+ }
+ if (mp == TO_NEXUS && isscsidev(dp->d_name) ||
+ mp != TO_NEXUS && eq(mp->d_name, "scsi") &&
+ !isscsidev(dp->d_name)) {
+ printf("%s%s must be attached to a scsi\n",
+ dp->d_name, wnum(dp->d_unit));
+ return (1);
+ }
+ return (0);
+}
+
+char *
+ wnum(num)
+{
+
+ if (num == QUES || num == UNKNOWN)
+ return ("?");
+ (void) sprintf(errbuf, "%d", num);
+ return (errbuf);
+}
+#endif
+
+#if MACHINE_I386
+char *shandler();
+char *sirq();
+
+i386_ioconf()
+{
+ register struct device *dp, *mp, *np;
+ register int seq = 0;
+ FILE *fp;
+
+ fp = fopen(path("ioconf.c"), "w");
+ if (fp == 0) {
+ perror(path("ioconf.c"));
+ exit(1);
+ }
+ fprintf(fp, "/*\n");
+ fprintf(fp, " * ioconf.c \n");
+ fprintf(fp, " * Generated by config.old program\n");
+ fprintf(fp, " */\n\n");
+ fprintf(fp, "#include <sys/param.h>\n");
+ fprintf(fp, "#include <sys/device.h>\n");
+ fprintf(fp, "#include <sys/buf.h>\n");
+ fprintf(fp, "#include <machine/pte.h>\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#define C (caddr_t)\n");
+ fprintf(fp, "#define D &isa_devtab\n");
+ fprintf(fp, "\n");
+ /*
+ * First print the isa initialization structures
+ */
+ if (seen_isa) {
+
+ fprintf(fp, "/*\n");
+ fprintf(fp, " * ISA devices\n");
+ fprintf(fp, " */\n\n");
+ fprintf(fp, "#include <i386/isa/isa_device.h>\n");
+ fprintf(fp, "#include <i386/isa/isa.h>\n");
+ fprintf(fp, "#include <i386/isa/icu.h>\n\n");
+
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || mp == TO_NEXUS)
+ continue;
+ fprintf(fp, "extern struct cfdriver %7scd;\n",
+ dp->d_name);
+ if (dp->d_irq == 2) {
+ fprintf(stderr, "remapped irq 2 to irq 9, please update your config file\n");
+ dp->d_irq = 9;
+ }
+ }
+
+ fprintf(fp, "\nstruct isa_device isa_devtab[] = {\n");
+ fprintf(fp, "\
+/* driver iobase irq drq maddr msiz unit flags phys parent */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || mp == TO_NEXUS)
+ continue;
+ dp->d_seq = seq++;
+ }
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || mp == TO_NEXUS)
+ continue;
+ fprintf(fp, "{ &%7scd,", dp->d_name);
+ if (dp->d_port)
+ fprintf(fp, " %8s,", dp->d_port);
+ else
+ fprintf(fp, " 0x%04x,", dp->d_portn);
+ fprintf(fp, " %5s, %2d, C 0x%05x, %5d, %2d, 0x%04x, %3d",
+ sirq(dp->d_irq), dp->d_drq, dp->d_maddr, dp->d_msize,
+ dp->d_unit, dp->d_flags,
+ eq(mp->d_name, "isa") ? 0 :
+ dp->d_drive == UNKNOWN ? dp->d_slave : dp->d_drive);
+ if (eq(mp->d_name, "isa"))
+ fprintf(fp, ", NULL");
+ else
+ fprintf(fp, ", D[%2d]", mp->d_seq);
+ fprintf(fp, " },\n");
+ }
+ fprintf(fp, "0\n};\n");
+ }
+ pseudo_init(fp);
+ (void) fclose(fp);
+}
+
+/*
+ * XXX - there should be a general function to print devtabs instead of these
+ * little pieces of it.
+ */
+
+char *
+ sirq(int i)
+{
+ static char buf[20];
+
+#if 0
+ sprintf(buf, "%d", i);
+ return buf;
+#else
+ switch(i) {
+ case -2:
+ return "0";
+ case -1:
+ return "-1";
+ default:
+ sprintf(buf, "IRQ%d", i);
+ return buf;
+ }
+#endif
+}
+
+char *
+ shandler(dp)
+struct device *dp;
+{
+ static char buf[32+20];
+
+ if(dp->d_irq==-2)
+ return ("NULL");
+ sprintf(buf, "X%.32s%d", dp->d_name, dp->d_unit);
+ return buf;
+}
+#endif
+
+#if MACHINE_PC532
+pc532_ioconf()
+{
+ struct device *dp, *mp, *np;
+ int uba_n, slave;
+ FILE *fp;
+
+ fp = fopen(path("ioconf.c"), "w");
+ if (fp == 0) {
+ perror(path("ioconf.c"));
+ exit(1);
+ }
+ fprintf(fp, "/*\n");
+ fprintf(fp, " * ioconf.c \n");
+ fprintf(fp, " * Generated by config.old program\n");
+ fprintf(fp, " */\n\n");
+ fprintf(fp, "#include \"../../dev/device.h\"\n");
+ fprintf(fp, "#include <types.h>\n");
+ fprintf(fp, "#include <cdefs.h>\n");
+ fprintf(fp, "#include <device.h>\n");
+ fprintf(fp, "\n");
+
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES || mp == 0)
+ continue;
+ fprintf(fp, "extern struct pc532_driver %sdriver;\n", mp->d_name);
+ }
+
+ fprintf(fp, "\nstruct pc532_device pc532_devtab_bio[] = {\n");
+ fprintf(fp, "/* driver name unit drive flags alive */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || !eq(dp->d_mask, "bio"))
+ continue;
+ fprintf (fp, "{&%sdriver,\t\"%s\",\t%d,\t%d,\t%d,\t0},\n",
+ mp->d_name, dp->d_name, dp->d_unit, dp->d_drive, dp->d_flags);
+ }
+ fprintf(fp, "0\n};\n");
+
+ fprintf(fp, "\nstruct pc532_device pc532_devtab_tty[] = {\n");
+ fprintf(fp, "/* driver name unit scsiid flags alive */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || !eq(dp->d_mask, "tty"))
+ continue;
+ fprintf (fp, "{&%sdriver,\t\"%s\",\t%d,\t0,\t0,\t0},\n",
+ mp->d_name, dp->d_name, dp->d_unit);
+ }
+ fprintf(fp, "0\n};\n");
+
+ fprintf(fp, "\nstruct pc532_device pc532_devtab_net[] = {\n");
+ fprintf(fp, "/* driver unit scsiid alive */\n");
+ fprintf(fp, "0\n};\n");
+
+ pseudo_init(fp);
+ (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_PMAX
+pmax_ioconf()
+{
+ register struct device *dp, *mp;
+ FILE *fp;
+
+ fp = fopen(path("ioconf.c"), "w");
+ if (fp == 0) {
+ perror(path("ioconf.c"));
+ exit(1);
+ }
+ fprintf(fp, "/*\n");
+ fprintf(fp, " * ioconf.c \n");
+ fprintf(fp, " * Generated by config.old program\n");
+ fprintf(fp, " */\n\n");
+ fprintf(fp, "#include \"sys/param.h\"\n");
+ fprintf(fp, "#include \"sys/types.h\"\n");
+ fprintf(fp, "#include \"sys/device.h\"\n");
+ fprintf(fp, "#include \"sys/buf.h\"\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#include \"pmax/dev/device.h\"\n\n");
+ fprintf(fp, "#define C (char *)\n\n");
+
+ /* print controller initialization structures */
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ if (dp->d_type == PSEUDO_DEVICE)
+ continue;
+ fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
+ }
+ fprintf(fp, "\nstruct pmax_ctlr pmax_cinit[] = {\n");
+ fprintf(fp, "/*\tdriver,\t\tunit,\taddr,\t\tflags */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ if (dp->d_type != CONTROLLER && dp->d_type != MASTER)
+ continue;
+ if (dp->d_conn != TO_NEXUS) {
+ printf("%s%s must be attached to a nexus (internal bus)\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("can't specify drive/slave for %s%s\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ if (dp->d_unit == UNKNOWN || dp->d_unit == QUES)
+ dp->d_unit = 0;
+ fprintf(fp,
+ "\t{ &%sdriver,\t%d,\tC 0x%x,\t0x%x },\n",
+ dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags);
+ }
+ fprintf(fp, "\t0\n};\n");
+
+ /* print devices connected to other controllers */
+ fprintf(fp, "\nstruct scsi_device scsi_dinit[] = {\n");
+ fprintf(fp,
+ "/*driver,\tcdriver,\tunit,\tctlr,\tdrive,\tslave,\tdk,\tflags*/\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ if (dp->d_type == CONTROLLER || dp->d_type == MASTER ||
+ dp->d_type == PSEUDO_DEVICE)
+ continue;
+ mp = dp->d_conn;
+ if (mp == 0 ||
+ (!eq(mp->d_name, "asc") && !eq(mp->d_name, "sii"))) {
+ printf("%s%s: devices must be attached to a SCSI controller\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ if ((unsigned)dp->d_drive > 6) {
+ printf("%s%s: SCSI drive must be in the range 0..6\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ /* may want to allow QUES later */
+ if ((unsigned)dp->d_slave > 7) {
+ printf("%s%s: SCSI slave (LUN) must be in the range 0..7\n",
+ dp->d_name, wnum(dp->d_unit));
+ continue;
+ }
+ fprintf(fp, "{ &%sdriver,\t&%sdriver,", dp->d_name, mp->d_name);
+ fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t%d,\t0x%x },\n",
+ dp->d_unit, mp->d_unit, dp->d_drive, dp->d_slave,
+ dp->d_dk, dp->d_flags);
+ }
+ fprintf(fp, "0\n};\n");
+ pseudo_init(fp);
+ (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_AMIGA
+amiga_ioconf()
+{
+ register struct device *dp, *mp, *np;
+ register int controller, slave;
+ FILE *fp;
+ extern char *awnum();
+
+ fp = fopen(path("ioconf.c"), "w");
+ if (fp == 0) {
+ perror(path("ioconf.c"));
+ exit(1);
+ }
+ fprintf(fp, "#include \"sys/param.h\"\n");
+ fprintf(fp, "#include \"sys/buf.h\"\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#include \"arch/amiga/dev/device.h\"\n\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "#define C (caddr_t)\n");
+ fprintf(fp, "#define D (struct driver *)\n\n");
+ /*
+ * First print the controller initialization structures
+ */
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES || mp == 0)
+ continue;
+ fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
+ }
+ fprintf(fp, "\nstruct amiga_ctlr amiga_cinit[] = {\n");
+ fprintf(fp, "/*\tdriver,\t\tunit,\talive,\taddr,\tflags */\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (dp->d_unit == QUES ||
+ dp->d_type != MASTER && dp->d_type != CONTROLLER)
+ continue;
+ if (mp != TO_NEXUS) {
+ printf("%s%s must be attached to an controller\n",
+ dp->d_name, awnum(dp->d_unit));
+ continue;
+ }
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("can't specify drive/slave for %s%s\n",
+ dp->d_name, awnum(dp->d_unit));
+ continue;
+ }
+ fprintf(fp,
+ "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t0x%x },\n",
+ dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags);
+ }
+ fprintf(fp, "\t0\n};\n");
+/* devices */
+ fprintf(fp, "\nstruct amiga_device amiga_dinit[] = {\n");
+ fprintf(fp,
+ "/*driver,\tcdriver,\tunit,\tctlr,\tslave,\taddr,\tdk,\tflags*/\n");
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp == 0 || dp->d_type != DEVICE || amigabadslave(mp, dp))
+ continue;
+ if (mp == TO_NEXUS) {
+ if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+ printf("can't specify drive/slave for %s%s\n",
+ dp->d_name, awnum(dp->d_unit));
+ continue;
+ }
+ slave = QUES;
+ controller = QUES;
+ } else {
+ if (dp->d_addr != 0) {
+ printf("can't specify manufacturer/product for device %s%s\n",
+ dp->d_name, awnum(dp->d_unit));
+ continue;
+ }
+ if (mp->d_type == CONTROLLER) {
+ if (dp->d_drive == UNKNOWN) {
+ printf("must specify drive for %s%s\n",
+ dp->d_name, awnum(dp->d_unit));
+ continue;
+ }
+ slave = dp->d_drive;
+ } else {
+ if (dp->d_slave == UNKNOWN) {
+ printf("must specify slave for %s%s\n",
+ dp->d_name, awnum(dp->d_unit));
+ continue;
+ }
+ slave = dp->d_slave;
+ }
+ controller = mp->d_unit;
+ }
+ fprintf(fp, "{ &%sdriver,\t", dp->d_name);
+ if (mp == TO_NEXUS)
+ fprintf(fp, "D 0x0,\t");
+ else
+ fprintf(fp, "&%sdriver,", mp->d_name);
+ fprintf(fp, "\t%d,\t%d,\t%d,\tC 0x%x,\t%d,\t0x%x },\n",
+ dp->d_unit, controller, slave,
+ dp->d_addr, dp->d_dk, dp->d_flags);
+ }
+ fprintf(fp, "0\n};\n");
+ pseudo_init(fp);
+ (void) fclose(fp);
+}
+
+#define isscsidev(n) (eq(n,"sd") || eq(n,"st"))
+
+amigabadslave(mp, dp)
+ register struct device *dp, *mp;
+{
+ extern char *awnum();
+
+ if (mp == TO_NEXUS && isscsidev(dp->d_name) ||
+ mp != TO_NEXUS && eq(mp->d_name, "scsi") &&
+ !isscsidev(dp->d_name)) {
+ printf("%s%s must be attached to a scsi\n",
+ dp->d_name, awnum(dp->d_unit));
+ return (1);
+ }
+ return (0);
+}
+
+char *
+awnum(num)
+{
+
+ if (num == QUES || num == UNKNOWN)
+ return ("?");
+ (void) sprintf(errbuf, "%d", num);
+ return (errbuf);
+}
+#endif
+
+
+char *
+intv(dev)
+register struct device *dev;
+{
+ static char buf[20];
+
+ if (dev->d_vec == 0)
+ return (" 0");
+ (void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit);
+ return (buf);
+}
+
+char *
+qu(num)
+{
+ if (num == QUES)
+ return ("'?'");
+ if (num == UNKNOWN)
+ return (" -1");
+ (void) sprintf(errbuf, "%3d", num);
+ return (errbuf);
+}
--- /dev/null
+/* $NetBSD: mkmakefile.c,v 1.28 1995/08/17 17:22:18 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980,1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkmakefile.c 5.33 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: mkmakefile.c,v 1.28 1995/08/17 17:22:18 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Build the makefile for the system, from
+ * the information in the files files and the
+ * additional files for the machine being compiled to.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <machine/param.h>
+#include "y.tab.h"
+#include "config.h"
+
+#define next_word(fp, wd) \
+ { register char *word = get_word(fp); \
+ if (word == (char *)EOF) \
+ return; \
+ else \
+ wd = word; \
+ }
+#define next_quoted_word(fp, wd) \
+ { register char *word = get_quoted_word(fp); \
+ if (word == (char *)EOF) \
+ return; \
+ else \
+ wd = word; \
+ }
+
+static struct file_list *fcur;
+char *tail();
+
+/*
+ * Lookup a file, by name.
+ */
+struct file_list *
+fl_lookup(file)
+ register char *file;
+{
+ register struct file_list *fp;
+
+ for (fp = ftab ; fp != 0; fp = fp->f_next) {
+ if (eq(fp->f_fn, file))
+ return (fp);
+ }
+ return (0);
+}
+
+/*
+ * Lookup a file, by final component name.
+ */
+struct file_list *
+fltail_lookup(file)
+ register char *file;
+{
+ register struct file_list *fp;
+
+ for (fp = ftab ; fp != 0; fp = fp->f_next) {
+ if (eq(tail(fp->f_fn), tail(file)))
+ return (fp);
+ }
+ return (0);
+}
+
+/*
+ * Make a new file list entry
+ */
+struct file_list *
+new_fent()
+{
+ register struct file_list *fp;
+
+ fp = (struct file_list *) malloc(sizeof *fp);
+ bzero(fp, sizeof *fp);
+ if (fcur == 0)
+ fcur = ftab = fp;
+ else
+ fcur->f_next = fp;
+ fcur = fp;
+ return (fp);
+}
+
+static struct users {
+ int u_default;
+ int u_min;
+ int u_max;
+} users[] = {
+ { 24, 8, 1024 }, /* MACHINE_VAX */
+ { 4, 2, 128 }, /* MACHINE_TAHOE */
+ { 8, 2, 64 }, /* MACHINE_HP300 */
+ { 8, 2, 64 }, /* MACHINE_I386 */
+ { 8, 2, 64 }, /* MACHINE_PC532 */
+ { 8, 2, 64 }, /* MACHINE_PMAX */
+ { 8, 2, 64 }, /* MACHINE_AMIGA */
+};
+#define NUSERS (sizeof (users) / sizeof (users[0]))
+
+/*
+ * Build the makefile from the skeleton
+ */
+makefile()
+{
+ FILE *ifp, *ofp;
+ char line[BUFSIZ];
+ struct opt *op;
+ struct users *up;
+
+ read_files();
+ strcpy(line, "Makefile.");
+ (void) strcat(line, machinename);
+ ifp = fopen(line, "r");
+ if (ifp == 0) {
+ perror(line);
+ exit(1);
+ }
+ ofp = fopen(path("Makefile"), "w");
+ if (ofp == 0) {
+ perror(path("Makefile"));
+ exit(1);
+ }
+ fprintf(ofp, "KERN_IDENT=%s\n", raisestr(ident)); /* 29 Jun 92*/
+ fprintf(ofp, "IDENT=-D%s", raisestr(ident));
+ if (profiling)
+ fprintf(ofp, " -DGPROF");
+ if (cputype == 0) {
+ printf("cpu type must be specified\n");
+ exit(1);
+ }
+ { struct cputype *cp;
+ for (cp = cputype; cp; cp = cp->cpu_next)
+ fprintf(ofp, " -D%s", cp->cpu_name);
+ }
+ for (op = opt; op; op = op->op_next)
+ if (op->op_value)
+ fprintf(ofp, " -D%s=\"%s\"", op->op_name, op->op_value);
+ else
+ fprintf(ofp, " -D%s", op->op_name);
+ fprintf(ofp, "\n");
+ if (hadtz == 0)
+ printf("timezone not specified; gmt assumed\n");
+ if ((unsigned)machine > NUSERS) {
+ printf("maxusers config info isn't present, using vax\n");
+ up = &users[MACHINE_VAX-1];
+ } else
+ up = &users[machine-1];
+ if (maxusers == 0) {
+ printf("maxusers not specified; %d assumed\n", up->u_default);
+ maxusers = up->u_default;
+ } else if (maxusers < up->u_min) {
+ printf("minimum of %d maxusers assumed\n", up->u_min);
+ maxusers = up->u_min;
+ } else if (maxusers > up->u_max)
+ printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers);
+ fprintf(ofp, "PARAM=-DTIMEZONE=%d -DDST=%d -DMAXUSERS=%d\n",
+ zone, dst, maxusers);
+ if (loadaddress != -1) {
+ fprintf(ofp, "LOAD_ADDRESS=%X\n", loadaddress);
+ }
+ for (op = mkopt; op; op = op->op_next)
+ fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
+ if (debugging)
+ fprintf(ofp, "DEBUG=-g\n");
+ if (profiling)
+ fprintf(ofp, "PROF=-pg\n");
+ while (fgets(line, BUFSIZ, ifp) != 0) {
+ if (*line != '%') {
+ fprintf(ofp, "%s", line);
+ continue;
+ }
+ if (eq(line, "%OBJS\n"))
+ do_objs(ofp);
+ else if (eq(line, "%CFILES\n"))
+ do_cfiles(ofp);
+ else if (eq(line, "%RULES\n"))
+ do_rules(ofp);
+ else if (eq(line, "%LOAD\n"))
+ do_load(ofp);
+ else
+ fprintf(stderr,
+ "Unknown %% construct in generic makefile: %s",
+ line);
+ }
+ (void) fclose(ifp);
+ (void) fclose(ofp);
+}
+
+/*
+ * Read in the information about files used in making the system.
+ * Store it in the ftab linked list.
+ */
+read_files()
+{
+ register struct file_list *fl;
+ char fname[48];
+
+ ftab = 0;
+ (void) strcpy(fname, "../../../conf/files.oldconf");
+ read_file(fname,1,0);
+ (void) sprintf(fname, "files.%s.oldconf", machinename);
+ read_file(fname,1,0);
+ if (strcmp(machinearch, machinename)) {
+ (void) sprintf(fname, "../../%s/conf/files.%s.oldconf",
+ machinearch, machinearch);
+ read_file(fname,1,0);
+ }
+ (void) sprintf(fname, "files.%s.oldconf", raisestr(ident));
+ read_file(fname,0,1);
+ (void) strcpy(fname, "../../../conf/options.oldconf");
+ read_file(fname,0,0);
+ (void) sprintf(fname, "options.%s.oldconf", machinename);
+ read_file(fname,0,0);
+ if (strcmp(machinearch, machinename)) {
+ (void) sprintf(fname, "../../%s/conf/options.%s.oldconf",
+ machinearch, machinearch);
+ read_file(fname,0,0);
+ }
+ (void) sprintf(fname, "options.%s.oldconf", raisestr(ident));
+ read_file(fname,0,1);
+}
+
+opteq(cp, dp)
+ char *cp, *dp;
+{
+ char c, d;
+
+ for (; ; cp++, dp++) {
+ if (*cp != *dp) {
+ c = isupper(*cp) ? tolower(*cp) : *cp;
+ d = isupper(*dp) ? tolower(*dp) : *dp;
+ if (c != d)
+ return (0);
+ }
+ if (*cp == 0)
+ return (1);
+ }
+}
+
+do_objs(fp)
+ FILE *fp;
+{
+ register struct file_list *tp, *fl;
+ register int lpos, len;
+ register char *cp, och, *sp;
+ char swapname[32];
+
+ fprintf(fp, "OBJS=");
+ lpos = 6;
+ for (tp = ftab; tp != 0; tp = tp->f_next) {
+ if (tp->f_type == INVISIBLE)
+ continue;
+ if (tp->f_type == PROFILING && !profiling)
+ continue;
+ sp = tail(tp->f_fn);
+ for (fl = conf_list; fl; fl = fl->f_next) {
+ if (fl->f_type != SWAPSPEC)
+ continue;
+ (void) sprintf(swapname, "swap%s.c", fl->f_fn);
+ if (eq(sp, swapname))
+ goto cont;
+ }
+ cp = sp + (len = strlen(sp)) - 1;
+ och = *cp;
+ *cp = 'o';
+ if (len + lpos > 72) {
+ lpos = 8;
+ fprintf(fp, "\\\n\t");
+ }
+ fprintf(fp, "%s ", sp);
+ lpos += len + 1;
+ *cp = och;
+cont:
+ ;
+ }
+ if (lpos != 8)
+ putc('\n', fp);
+}
+
+do_cfiles(fp)
+ FILE *fp;
+{
+ register struct file_list *tp, *fl;
+ register int lpos, len;
+ char swapname[32];
+
+ fputs("CFILES=", fp);
+ lpos = 8;
+ for (tp = ftab; tp; tp = tp->f_next) {
+ if (tp->f_type == INVISIBLE)
+ continue;
+ if (tp->f_type == PROFILING && !profiling)
+ continue;
+ len = strlen(tp->f_fn);
+ if (tp->f_fn[len - 1] != 'c')
+ continue;
+ if ((len = 3 + len) + lpos > 72) {
+ lpos = 8;
+ fputs("\\\n\t", fp);
+ }
+ fprintf(fp, "$S/%s ", tp->f_fn);
+ lpos += len + 1;
+ }
+ for (fl = conf_list; fl; fl = fl->f_next)
+ if (fl->f_type == SYSTEMSPEC) {
+ (void) sprintf(swapname, "swap%s.c", fl->f_fn);
+ if ((len = 3 + strlen(swapname)) + lpos > 72) {
+ lpos = 8;
+ fputs("\\\n\t", fp);
+ }
+ if (eq(fl->f_fn, "generic"))
+ fprintf(fp, "$S/arch/%s/%s/%s ",
+ machinename, machinename, swapname);
+ else if (eq(fl->f_fn, "nfs"))
+ fprintf(fp, "$S/nfs/%s ", swapname);
+ else
+ fprintf(fp, "%s ", swapname);
+ lpos += len + 1;
+ }
+ if (lpos != 8)
+ putc('\n', fp);
+}
+
+char *
+tail(fn)
+ char *fn;
+{
+ register char *cp;
+
+ cp = rindex(fn, '/');
+ if (cp == 0)
+ return (fn);
+ return (cp+1);
+}
+
+/*
+ * Create the makerules for each file
+ * which is part of the system.
+ * Devices are processed with the special c2 option -i
+ * which avoids any problem areas with i/o addressing
+ * (e.g. for the VAX); assembler files are processed by as.
+ */
+do_rules(f)
+ FILE *f;
+{
+ register char *cp, *np, och, *tp;
+ register struct file_list *ftp;
+ char *special;
+
+ for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
+ if (ftp->f_type == INVISIBLE)
+ continue;
+ if (ftp->f_type == PROFILING && !profiling)
+ continue;
+ cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
+ och = *cp;
+ *cp = '\0';
+ if (och == 'o') {
+ fprintf(f, "%so:\n\t-cp $S/%so .\n\n", tail(np), np);
+ continue;
+ }
+ fprintf(f, "%so: $S/%s%c\n", tail(np), np, och);
+ tp = tail(np);
+ special = ftp->f_special;
+ if (special == 0) {
+ char *ftype;
+ static char cmd[128];
+
+ switch (ftp->f_type) {
+
+ case NORMAL:
+ ftype = "NORMAL";
+ break;
+
+ case DRIVER:
+ ftype = "DRIVER";
+ break;
+
+ case PROFILING:
+ ftype = "PROFILE";
+ break;
+
+ default:
+ printf("config.old: don't know rules for %s\n", np);
+ break;
+ }
+ (void)sprintf(cmd, "${%s_%c%s}", ftype, toupper(och),
+ ftp->f_flags & CONFIGDEP? "_C" : "");
+ special = cmd;
+ }
+ *cp = och;
+ fprintf(f, "\t%s\n\n", special);
+ }
+}
+
+/*
+ * Create the load strings
+ */
+do_load(f)
+ register FILE *f;
+{
+ register struct file_list *fl;
+ register int first;
+ struct file_list *do_systemspec();
+
+ for (first = 1, fl = conf_list; fl; first = 0)
+ fl = fl->f_type == SYSTEMSPEC ?
+ do_systemspec(f, fl, first) : fl->f_next;
+ fputs("all:", f);
+ for (fl = conf_list; fl; fl = fl->f_next)
+ if (fl->f_type == SYSTEMSPEC)
+ fprintf(f, " %s", fl->f_needs->name);
+ putc('\n', f);
+}
+
+struct file_list *
+do_systemspec(f, fl, first)
+ FILE *f;
+ register struct file_list *fl;
+ int first;
+{
+ fprintf(f, "SYSTEM_SWAP_DEP+= swap%s.o\n", fl->f_fn);
+ fprintf(f, "%s: ${SYSTEM_DEP} swap%s.o vers.o", fl->f_needs->name, fl->f_fn);
+ fprintf(f, "\n\t${SYSTEM_LD_HEAD}\n");
+ fprintf(f, "\t${SYSTEM_LD} swap%s.o\n", fl->f_fn);
+ fprintf(f, "\t${SYSTEM_LD_TAIL}\n\n");
+ do_swapspec(f, fl->f_fn);
+ for (fl = fl->f_next; fl && fl->f_type == SWAPSPEC; fl = fl->f_next)
+ ;
+ return (fl);
+}
+
+do_swapspec(f, name)
+ FILE *f;
+ register char *name;
+{
+
+ if (eq(name, "generic"))
+ fprintf(f, "swapgeneric.o: ../../%s/swapgeneric.c\n",
+ machinename);
+ else if (eq(name, "nfs"))
+ fprintf(f, "swapnfs.o: ../../../../nfs/swapnfs.c\n");
+ else
+ fprintf(f, "swap%s.o: swap%s.c\n", name, name);
+ fprintf(f, "\t${NORMAL_C}\n\n");
+}
+
+char *
+raisestr(str)
+ register char *str;
+{
+ register char *cp = str;
+
+ while (*str) {
+ if (islower(*str))
+ *str = toupper(*str);
+ str++;
+ }
+ return (cp);
+}
--- /dev/null
+/* $NetBSD: mkswapconf.c,v 1.11 1995/08/17 17:22:20 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkswapconf.c 5.10 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: mkswapconf.c,v 1.11 1995/08/17 17:22:20 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Build a swap configuration file.
+ */
+#include "config.h"
+
+#include <stdio.h>
+#include <ctype.h>
+
+swapconf()
+{
+ register struct file_list *fl;
+ struct file_list *do_swap();
+
+ fl = conf_list;
+ while (fl) {
+ if (fl->f_type != SYSTEMSPEC) {
+ fl = fl->f_next;
+ continue;
+ }
+ fl = do_swap(fl);
+ }
+}
+
+struct file_list *
+do_swap(fl)
+ register struct file_list *fl;
+{
+ FILE *fp;
+ char swapname[80];
+ register struct file_list *swap;
+ dev_t dev;
+
+ if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs")) {
+ fl = fl->f_next;
+ return (fl->f_next);
+ }
+ (void) sprintf(swapname, "swap%s.c", fl->f_fn);
+ fp = fopen(path(swapname), "w");
+ if (fp == 0) {
+ perror(path(swapname));
+ exit(1);
+ }
+ fprintf(fp, "#include \"sys/param.h\"\n");
+ fprintf(fp, "#include \"sys/conf.h\"\n");
+ fprintf(fp, "\n");
+ /*
+ * If there aren't any swap devices
+ * specified, just return, the error
+ * has already been noted.
+ */
+ swap = fl->f_next;
+ if (swap == 0 || swap->f_type != SWAPSPEC) {
+ (void) unlink(path(swapname));
+ fclose(fp);
+ return (swap);
+ }
+ fprintf(fp, "dev_t\trootdev = makedev(%d, %d);\n",
+ major(fl->f_rootdev), minor(fl->f_rootdev));
+ fprintf(fp, "dev_t\tdumpdev = makedev(%d, %d);\n",
+ major(fl->f_dumpdev), minor(fl->f_dumpdev));
+ fprintf(fp, "\n");
+ fprintf(fp, "struct\tswdevt swdevt[] = {\n");
+ do {
+ dev = swap->f_swapdev;
+ fprintf(fp, "\t{ makedev(%d, %d),\t0,\t%d },\t/* %s */\n",
+ major(dev), minor(dev), swap->f_swapsize, swap->f_fn);
+ swap = swap->f_next;
+ } while (swap && swap->f_type == SWAPSPEC);
+ fprintf(fp, "\t{ NODEV, 0, 0 }\n");
+ fprintf(fp, "};\n\n");
+ fprintf(fp, "extern int ffs_mountroot();\n");
+ fprintf(fp, "int (*mountroot)() = ffs_mountroot;\n");
+ fclose(fp);
+ return (swap);
+}
+
+static int devtablenotread = 1;
+static struct devdescription {
+ char *dev_name;
+ int dev_major;
+ struct devdescription *dev_next;
+} *devtable;
+
+/*
+ * Given a device name specification figure out:
+ * major device number
+ * partition
+ * device name
+ * unit number
+ * This is a hack, but the system still thinks in
+ * terms of major/minor instead of string names.
+ */
+dev_t
+nametodev(name, defunit, defpartition)
+ char *name;
+ int defunit;
+ char defpartition;
+{
+ char *cp, partition;
+ int unit;
+ register struct devdescription *dp;
+
+ cp = name;
+ if (cp == 0) {
+ fprintf(stderr, "config.old: internal error, nametodev\n");
+ exit(1);
+ }
+ while (*cp && !isdigit(*cp))
+ cp++;
+ unit = *cp ? atoi(cp) : defunit;
+ if (unit < 0 || unit > 31) {
+ fprintf(stderr,
+"config.old: %s: invalid device specification, unit out of range\n", name);
+ unit = defunit; /* carry on more checking */
+ }
+ if (*cp) {
+ *cp++ = '\0';
+ while (*cp && isdigit(*cp))
+ cp++;
+ }
+ partition = *cp ? *cp : defpartition;
+ if (partition < 'a' || partition > 'h') {
+ fprintf(stderr,
+"config.old: %c: invalid device specification, bad partition\n", *cp);
+ partition = defpartition; /* carry on */
+ }
+ if (devtablenotread)
+ initdevtable();
+ for (dp = devtable; dp; dp = dp->dev_next)
+ if (eq(name, dp->dev_name))
+ break;
+ if (dp == 0) {
+ fprintf(stderr, "config.old: %s: unknown device\n", name);
+ return (NODEV);
+ }
+ return (makedev(dp->dev_major, (unit << 3) + (partition - 'a')));
+}
+
+char *
+devtoname(dev)
+ dev_t dev;
+{
+ char buf[80];
+ register struct devdescription *dp;
+
+ if (devtablenotread)
+ initdevtable();
+ for (dp = devtable; dp; dp = dp->dev_next)
+ if (major(dev) == dp->dev_major)
+ break;
+ if (dp == 0)
+ dp = devtable;
+ (void) sprintf(buf, "%s%d%c", dp->dev_name,
+ minor(dev) >> 3, (minor(dev) & 07) + 'a');
+ return (ns(buf));
+}
+
+initdevtable()
+{
+ char linebuf[256];
+ char buf[BUFSIZ];
+ int maj;
+ register struct devdescription **dp = &devtable;
+ FILE *fp;
+
+ if (machinename==NULL) {
+ fprintf(stderr, "config.old: machine not specified\n");
+ exit(1);
+ }
+ (void) sprintf(buf, "../conf/devices.%s.oldconf", machinename);
+ fp = fopen(buf, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "config.old: ");
+ perror(buf);
+ exit(1);
+ }
+ while(fgets(linebuf,256,fp))
+ {
+ /*******************************\
+ * Allow a comment *
+ \*******************************/
+ if(linebuf[0] == '#') continue;
+
+ if (sscanf(linebuf, "%s\t%d\n", buf, &maj) == 2)
+ {
+ *dp = (struct devdescription *)malloc(sizeof (**dp));
+ (*dp)->dev_name = ns(buf);
+ (*dp)->dev_major = maj;
+ dp = &(*dp)->dev_next;
+ }
+ else
+ {
+ fprintf(stderr,"illegal line in devices file\n");
+ break;
+ }
+ }
+ *dp = 0;
+ fclose(fp);
+ devtablenotread = 0;
+}
--- /dev/null
+/* $NetBSD: mkubglue.c,v 1.3 1995/08/17 17:22:21 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkubglue.c 5.3 (Berkeley) 4/19/91";*/
+static char rcsid[] = "$NetBSD: mkubglue.c,v 1.3 1995/08/17 17:22:21 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Make the uba interrupt file ubglue.s
+ */
+#include <stdio.h>
+#include "config.h"
+#include "y.tab.h"
+
+ubglue()
+{
+ register FILE *fp;
+ register struct device *dp, *mp;
+
+ fp = fopen(path("ubglue.s"), "w");
+ if (fp == 0) {
+ perror(path("ubglue.s"));
+ exit(1);
+ }
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp != 0 && mp != (struct device *)-1 &&
+ !eq(mp->d_name, "mba")) {
+ struct idlst *id, *id2;
+
+ for (id = dp->d_vec; id; id = id->id_next) {
+ for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+ if (id2 == id) {
+ dump_vec(fp, id->id, dp->d_unit);
+ break;
+ }
+ if (!strcmp(id->id, id2->id))
+ break;
+ }
+ }
+ }
+ }
+ dump_std(fp);
+ for (dp = dtab; dp != 0; dp = dp->d_next) {
+ mp = dp->d_conn;
+ if (mp != 0 && mp != (struct device *)-1 &&
+ !eq(mp->d_name, "mba")) {
+ struct idlst *id, *id2;
+
+ for (id = dp->d_vec; id; id = id->id_next) {
+ for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+ if (id2 == id) {
+ dump_intname(fp, id->id,
+ dp->d_unit);
+ break;
+ }
+ if (!strcmp(id->id, id2->id))
+ break;
+ }
+ }
+ }
+ }
+ dump_ctrs(fp);
+ (void) fclose(fp);
+}
+
+static int cntcnt = 0; /* number of interrupt counters allocated */
+
+/*
+ * print an interrupt vector
+ */
+dump_vec(fp, vector, number)
+ register FILE *fp;
+ char *vector;
+ int number;
+{
+ char nbuf[80];
+ register char *v = nbuf;
+
+ (void) sprintf(v, "%s%d", vector, number);
+ fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n",
+ v, v);
+ fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
+ if (strncmp(vector, "dzx", 3) == 0)
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number);
+ else if (strncmp(vector, "dpx", 3) == 0)
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number);
+ else if (strncmp(vector, "dpr", 3) == 0)
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number);
+ else {
+ if (strncmp(vector, "uur", 3) == 0) {
+ fprintf(fp, "#ifdef UUDMA\n");
+ fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number);
+ fprintf(fp, "#endif\n");
+ }
+ fprintf(fp, "\tpushl\t$%d\n", number);
+ fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector);
+ fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n");
+ }
+}
+
+/*
+ * Start the interrupt name table with the names
+ * of the standard vectors not on the unibus.
+ * The number and order of these names should correspond
+ * with the definitions in scb.s.
+ */
+dump_std(fp)
+ register FILE *fp;
+{
+ fprintf(fp, "\n\t.globl\t_intrnames\n");
+ fprintf(fp, "\n\t.globl\t_eintrnames\n");
+ fprintf(fp, "\t.data\n");
+ fprintf(fp, "_intrnames:\n");
+ fprintf(fp, "\t.asciz\t\"clock\"\n");
+ fprintf(fp, "\t.asciz\t\"cnr\"\n");
+ fprintf(fp, "\t.asciz\t\"cnx\"\n");
+ fprintf(fp, "\t.asciz\t\"tur\"\n");
+ fprintf(fp, "\t.asciz\t\"tux\"\n");
+ fprintf(fp, "\t.asciz\t\"mba0\"\n");
+ fprintf(fp, "\t.asciz\t\"mba1\"\n");
+ fprintf(fp, "\t.asciz\t\"mba2\"\n");
+ fprintf(fp, "\t.asciz\t\"mba3\"\n");
+ fprintf(fp, "\t.asciz\t\"uba0\"\n");
+ fprintf(fp, "\t.asciz\t\"uba1\"\n");
+ fprintf(fp, "\t.asciz\t\"uba2\"\n");
+ fprintf(fp, "\t.asciz\t\"uba3\"\n");
+#define I_FIXED 13 /* number of names above */
+}
+
+dump_intname(fp, vector, number)
+ register FILE *fp;
+ char *vector;
+ int number;
+{
+ register char *cp = vector;
+
+ fprintf(fp, "\t.asciz\t\"");
+ /*
+ * Skip any "int" or "intr" in the name.
+ */
+ while (*cp)
+ if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
+ cp += 3;
+ if (*cp == 'r')
+ cp++;
+ } else {
+ putc(*cp, fp);
+ cp++;
+ }
+ fprintf(fp, "%d\"\n", number);
+}
+
+dump_ctrs(fp)
+ register FILE *fp;
+{
+ fprintf(fp, "_eintrnames:\n");
+ fprintf(fp, "\n\t.globl\t_intrcnt\n");
+ fprintf(fp, "\n\t.globl\t_eintrcnt\n");
+ fprintf(fp, "_intrcnt:\n", I_FIXED);
+ fprintf(fp, "\t.space\t4 * %d\n", I_FIXED);
+ fprintf(fp, "_fltintrcnt:\n", cntcnt);
+ fprintf(fp, "\t.space\t4 * %d\n", cntcnt);
+ fprintf(fp, "_eintrcnt:\n\n");
+ fprintf(fp, "\t.text\n");
+}
--- /dev/null
+/* $NetBSD: specfile.c,v 1.10 1995/08/17 17:22:22 thorpej Exp $ */
+
+#ifndef lint
+static char rcsid[] = "$NetBSD: specfile.c,v 1.10 1995/08/17 17:22:22 thorpej Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include "y.tab.h"
+#include "config.h"
+#include "specfile.h"
+
+#define is_paren(x) ((x == '(') || (x == ')'))
+struct file_keyword {
+ char *key;
+ int token;
+} file_kw_table[] = {
+ "compile-with", T_COMPILE_WITH,
+ "config-dependent", T_CONFIG_DEPENDENT,
+ "device-driver", T_DEVICE_DRIVER,
+ "optional", T_OPTIONAL,
+ "or", T_OR,
+ "not", T_NOT,
+ "requires", T_REQUIRES,
+ "standard", T_STANDARD,
+ "needs-count", T_NEEDS_COUNT,
+ };
+
+extern struct file_list *fltail_lookup(),*new_fent(),*fl_lookup();
+static char *current_file;
+static int current_line;
+static jmp_buf parse_problem;
+
+int file_tok(token)
+ char *token;
+{
+ int i, length;
+
+ if (is_paren(*token))
+ return (*token == '(' ? T_LEFTPAREN : T_RIGHTPAREN);
+ for (i =0; i <(sizeof(file_kw_table)/sizeof(file_kw_table[0])); i++) {
+ if (!strcmp(file_kw_table[i].key, token))
+ return file_kw_table[i].token;
+ }
+ length = strlen(token);
+ for (i = 0; i < length; i++) {
+ if (!isalnum(token[i]) && (token[i] != '_') &&
+ (token[i] != '-')) return -1;
+ }
+ return T_IDENTIFIER;
+}
+
+struct name_expr *
+alloc_name_expr(name)
+ char *name;
+{
+ struct name_expr *new;
+ int token,type;
+
+ type = 0;
+ token = file_tok(name);
+ switch (token) {
+ case T_OR:
+ case T_NOT:
+ case T_IDENTIFIER:
+ case T_LEFTPAREN:
+ case T_RIGHTPAREN:
+ type = token;
+ break;
+ default: return NULL;
+ }
+ new = malloc(sizeof(struct name_expr));
+ new->type = type;
+ if (type == T_IDENTIFIER) new->name = ns(name);
+ else new->name = NULL;
+ new->left = new->right = new->next = NULL;
+ return new;
+}
+
+void parse_err(char *emessage)
+{
+ fprintf(stderr, "%s:%d: %s\n", current_file, current_line, emessage);
+ if (!fatal_errors) longjmp(parse_problem,1);
+ exit(1);
+}
+
+delete_expr(expr)
+ struct name_expr *expr;
+{
+ if (expr->type == T_IDENTIFIER)
+ free(expr->name);
+ free(expr);
+}
+struct name_expr *yank_node(expr)
+ struct name_expr **expr;
+{
+ struct name_expr *node;
+
+ if (*expr == NULL) return NULL;
+ node = *expr;
+ *expr = (*expr)->next;
+ return node;
+}
+struct name_expr *yank_expr(expr)
+ struct name_expr **expr;
+{
+ struct name_expr *node,*tail, *subexpr,*next;
+
+ node = yank_node(expr);
+ if (node == NULL) return NULL;
+ if (node->type == T_LEFTPAREN)
+ for (tail = subexpr = NULL;;) {
+ next = yank_expr(expr);
+ if (!next) parse_err("missing ')'");
+ if (next->type == T_RIGHTPAREN) {
+ if (subexpr == NULL)
+ parse_err("empty inner expression i.e '()' ");
+ node->left = subexpr;
+ node->type = EXPR_GROUP;
+ break;
+ } else {
+ if (subexpr == NULL)
+ tail = subexpr = next;
+ else {
+ tail->next = next;
+ tail = next;
+ }
+ tail->next = NULL;
+ }
+ }
+ return(node);
+}
+
+struct name_expr *
+paren_squish(tree)
+ struct name_expr *tree;
+{
+ struct name_expr *result,*expr,*tail;
+
+ result = tail = NULL;
+
+ while ((expr = yank_expr(&tree)) != NULL) {
+ if (expr->type == T_RIGHTPAREN)
+ parse_err("unexpected ')'");
+ if (result == NULL) {
+ tail = result = expr;
+ }
+ else {
+ tail->next = expr;
+ tail = expr;
+ }
+ tail->next = NULL;
+ }
+ return(result);
+}
+
+struct name_expr *
+not_squish(tree)
+ struct name_expr *tree;
+{
+ struct name_expr *result,*next,*tail,*node;
+
+ tail = result = next = NULL;
+
+ while ((next = yank_node(&tree)) != NULL) {
+ if (next->type == EXPR_GROUP)
+ next->left = not_squish(next->left);
+ if (next->type == T_NOT) {
+ int notlevel = 1;
+
+ node = yank_node(&tree);
+ while (node->type == T_NOT) {
+ ++notlevel;
+ node = yank_node(&tree);
+ }
+ if (node == NULL)
+ parse_err("no expression following 'not'");
+ if (node->type == T_OR)
+ parse_err("nothing between 'not' and 'or'");
+ if (notlevel % 2 != 1)
+ next = node;
+ else
+ next->left = node;
+ }
+
+ /* add the node to our result plan */
+ if (result == NULL)
+ tail = result = next;
+ else {
+ tail->next = next;
+ tail = next;
+ }
+ tail->next = NULL;
+ }
+ return(result);
+}
+struct name_expr *
+or_squish(tree)
+ struct name_expr *tree;
+{
+ struct name_expr *next, *tail,*result;
+
+ tail = result = next = NULL;
+
+ while ((next = yank_node(&tree)) != NULL) {
+
+ if (next->type == EXPR_GROUP)
+ next->left = or_squish(next->left);
+
+ if (next->type == T_NOT)
+ next->left = or_squish(next->left);
+
+ if (next->type == T_OR) {
+ if (result == NULL)
+ parse_err("no expression before 'or'");
+ next->left = result;
+ next->right = or_squish(tree);
+ if (next->right == NULL)
+ parse_err("no expression after 'or'");
+ next->next = NULL;
+ return(next);
+ }
+
+ /* add the node to our result plan */
+ if (result == NULL)
+ tail = result = next;
+ else {
+ tail->next = next;
+ tail = next;
+ }
+ tail->next = NULL;
+ }
+ return(result);
+}
+
+struct name_expr *
+parse_name_expr(fp,seed, read_ahead)
+ FILE *fp;
+ char *seed, **read_ahead;
+{
+ struct name_expr *list, *tail,*new,*current;
+ char *str;
+
+
+ list = NULL;
+ *read_ahead = NULL;
+ if (seed) {
+ list = alloc_name_expr(seed);
+ if (list == NULL) {
+ *read_ahead = seed;
+ return NULL;
+ }
+ }
+ tail = list;
+ for (;;) {
+ str = get_word(fp);
+ if ((str == (char *)EOF) || str == NULL) {
+ *read_ahead = str;
+ break;
+ }
+ new = alloc_name_expr(str);
+ if (!new) {
+ *read_ahead = str;
+ break;
+ }
+ if (tail) tail->next = new;
+ else {
+ list = new;
+ }
+ tail = new;
+ }
+ list = paren_squish(list);
+ list = not_squish(list);
+ list = or_squish(list);
+ return list;
+}
+int is_simple(expr)
+ struct name_expr *expr;
+{
+ return expr && expr->type == T_IDENTIFIER;
+}
+
+int f_not(expr,explain)
+ struct name_expr *expr;
+ int explain;
+{
+ int result;
+
+ result = !depend_check(expr->left,explain);
+ return result;
+}
+int f_or(expr,explain)
+ struct name_expr *expr;
+ int explain;
+{
+ int result;
+
+ if (depend_check(expr->left,explain))
+ return 1;
+ if (depend_check(expr->right,explain))
+ return 1;
+ return 0;
+}
+int f_identifier(expr,explain)
+ struct name_expr *expr;
+ int explain;
+{
+ struct opt *op;
+ struct device *dp;
+ struct cputype *cp;
+
+ for (op = opt; op != 0; op = op->op_next)
+ if (opteq(op->op_name, expr->name)) return 1;
+ for (cp = cputype; cp != 0; cp = cp->cpu_next)
+ if (opteq(cp->cpu_name, expr->name)) return 1;
+ for (dp = dtab; dp != 0; dp = dp->d_next)
+ if (eq(dp->d_name, expr->name) &&
+ !(dp->d_type == PSEUDO_DEVICE && dp->d_flags && dp->d_slave == 0)) return 1;
+ return 0;
+}
+print_expr(expr)
+ struct name_expr *expr;
+{
+ struct name_expr *current;
+ for (current = expr; current != NULL; current= current->next) {
+ switch (current->type) {
+ case T_NOT:
+ fprintf (stderr, "not ");
+ print_expr(current->left);
+ break;
+ case T_OR:
+ print_expr(current->left);
+ fprintf (stderr, "or ");
+ print_expr(current->right);
+ break;
+ case EXPR_GROUP:
+ fprintf (stderr, "(");
+ print_expr(current->left);
+ fprintf (stderr, ")");
+ break;
+ case T_IDENTIFIER:
+ fprintf(stderr,"%s ", current->name);
+ break;
+ default:
+ parse_err("unknown expression type");
+ }
+ }
+}
+int depend_check(expr, explain)
+ struct name_expr *expr;
+ int explain;
+{
+ struct name_expr *current;
+ int result;
+
+ for (current= expr; current; current= current->next) {
+ switch(current->type) {
+ case T_NOT:
+ result = f_not(current,0);
+ break;
+ case T_OR:
+ result = f_or(current,0);
+ break;
+ case EXPR_GROUP:
+ result = depend_check(current->left, 0);
+ break;
+ case T_IDENTIFIER:
+ result = f_identifier(current,0);
+ break;
+ }
+ if (result) continue;
+ return 0;
+ }
+ return 1;
+}
+
+
+
+read_file(filename, fatal_on_open, override)
+ char *filename;
+ int fatal_on_open, override;
+{
+ FILE *fp;
+ size_t length;
+ char ebuf[1024];
+
+ fp = fopen(filename, "r");
+ if (!fp)
+ if (fatal_on_open) {
+ perror(filename);
+ exit(1);
+ }
+ else return;
+ current_line = 0;
+ current_file = filename;
+ for (;;) {
+ char *str, *kf_name, *read_ahead,*compile_with;
+ extern char *get_word(),*get_quoted_word();
+ int token,optional,driver,needs_count,config_depend,
+ is_dup,filetype,is_option;
+ struct name_expr *depends_on,*requires;
+ struct file_list *tp,*tmp, *fl,*pf;
+ enum {BEFORE_FILENAME,BEFORE_SPEC,BEFORE_DEPENDS,PAST_DEPENDS,
+ SPECIALS} parse_state;
+
+
+ if (setjmp(parse_problem)) {
+ while (1) {
+ str = get_word(fp);
+ if (!str || (str == (char *) EOF)) break;
+ }
+ if (!str) current_line++;
+ continue;
+ }
+ str = get_word(fp);
+ current_line++;
+ if (str == NULL) continue;
+ if (str == (char *) EOF) break;
+ if (*str == '#') {
+ fprintf(stderr, "shouldn't get here");
+ exit(1);
+ }
+ parse_state = BEFORE_FILENAME;
+ kf_name = read_ahead = compile_with = NULL;
+ optional= driver = config_depend = filetype = needs_count = 0;
+ depends_on = requires = NULL;
+ is_dup = 0;
+ is_option = 0;
+ while ((str != NULL) && (str != (char *)EOF)) {
+ switch (parse_state) {
+ case BEFORE_FILENAME: {
+ kf_name = ns(str);
+ if (strncmp(kf_name, "OPTIONS/", 8) == 0) {
+ kf_name = ns(index(kf_name, '/') + 1);
+ is_option++;
+ }
+ parse_state = BEFORE_SPEC;
+ break;
+ }
+ case BEFORE_SPEC: {
+ token = file_tok(str);
+ if ((token != T_OPTIONAL) && (token != T_STANDARD))
+ parse_err("unexpected token starts inclusion specification");
+ optional = (token == T_OPTIONAL);
+ parse_state = BEFORE_DEPENDS;
+ break;
+ }
+ case BEFORE_DEPENDS: {
+ depends_on = parse_name_expr(fp,str, &read_ahead);
+ str = read_ahead;
+ parse_state = PAST_DEPENDS;
+ continue;
+ break;
+ }
+ case PAST_DEPENDS:
+ case SPECIALS:
+ token = file_tok(str);
+ switch (token) {
+ case T_COMPILE_WITH: {
+ str = get_quoted_word(fp);
+ if ((str == 0) || (str == (char *) EOF))
+ parse_err("missing compile command string");
+ compile_with = ns(str);
+ }
+ case T_CONFIG_DEPENDENT: {
+ config_depend = 1;
+ break;
+ }
+ case T_DEVICE_DRIVER: {
+ driver = 1;
+ needs_count = 0;
+ break;
+ }
+ case T_REQUIRES: {
+ requires = parse_name_expr(fp,NULL, &read_ahead);
+ if (!requires)
+ parse_err("'requires' but no expression");
+ str = read_ahead;
+ continue;
+ break;
+ }
+ case T_NEEDS_COUNT: {
+ if (!driver) needs_count = 1;
+ break;
+ }
+ default:
+ parse_err("unexpected token");
+ }
+ break;
+ default:
+ parse_err("unknown state");
+ }
+ str = get_word(fp);
+ }
+ if (parse_state == BEFORE_SPEC)
+ parse_err("filename, but no specification");
+ if (is_option) {
+ struct device dev;
+ register struct opt *op;
+ struct opt *lop = 0;
+
+ /*
+ * Allocate a pseudo-device entry which we will insert into
+ * the device list below. The flags field is set non-zero to
+ * indicate an internal entry rather than one generated from
+ * the configuration file. The slave field is set to define
+ * the corresponding symbol as 0 should we fail to find the
+ * option in the option list.
+ */
+ init_dev(&dev);
+ dev.d_type = PSEUDO_DEVICE;
+ dev.d_name = ns(kf_name);
+ dev.d_slave = 0;
+ dev.d_flags++;
+ for (op=opt; op; lop=op, op=op->op_next) {
+ char *od = raisestr(ns(kf_name));
+
+ /*
+ * Found an option which matches the current device
+ * dependency identifier. Set the slave field to
+ * define the option in the header file.
+ */
+ if (strcmp(op->op_name, od) == 0) {
+ dev.d_slave = 1;
+ if (lop == 0)
+ opt = op->op_next;
+ else
+ lop->op_next = op->op_next;
+ free(op);
+ op = 0;
+ }
+ free(od);
+ if (op == 0)
+ break;
+ }
+ newdev(&dev);
+ needs_count = 0;
+ driver = 1;
+ filetype = INVISIBLE;
+ }
+ else {
+ if (!kf_name)
+ parse_err("no filename specified");
+ fl = fl_lookup(kf_name);
+ if (fl && !override) {
+ (void) sprintf(ebuf, "duplicate file name '%s'", kf_name);
+ parse_err(ebuf);
+ }
+ if ((pf = fl_lookup(kf_name)) &&
+ (pf->f_type != INVISIBLE || (pf->f_flags | DUPLICATE)))
+ is_dup = 1;
+ else
+ is_dup = 0;
+ if (override && ((tmp = fltail_lookup(kf_name)) != 0)) {
+ fprintf(stderr, "%s:%d: Local file %s overrides %s.\n",
+ current_file, current_line, kf_name, tmp->f_fn);
+ tmp->f_type = INVISIBLE;
+ }
+ if (!optional) {
+ if (driver)
+ parse_err("'standard' incompatible with 'device-driver'");
+ if (depends_on && !needs_count)
+ parse_err("'standard' can't have dependencies");
+ }
+ else if (!depends_on)
+ parse_err("'optional' requires dependency specification");
+ if (is_simple(depends_on) &&
+ eq("profiling-routine", depends_on->name)) filetype = PROFILING;
+ else if (!optional || depend_check(depends_on,0)) filetype = NORMAL;
+ else filetype = INVISIBLE;
+
+ if (filetype == NORMAL && requires && !depend_check(requires,0)) {
+ fprintf(stderr, "%s:%d: requirement expression failed: ",
+ current_file, current_line);
+ print_expr(requires);
+ fprintf(stderr, "\n");
+ parse_err("requirements not met");
+ }
+ }
+ tp = new_fent();
+ tp->f_fn = kf_name;
+ tp->f_type = filetype;
+ if (driver)
+ tp->f_needs = depends_on;
+ else
+ tp->f_needs = NULL;
+ if (needs_count)
+ tp->f_countname = depends_on;
+ else
+ tp->f_countname = NULL;
+ tp->f_was_driver = driver;
+ tp->f_needs_count = needs_count;
+ tp->f_special = compile_with;
+ tp->f_flags = 0;
+ tp->f_flags |= (config_depend ? CONFIGDEP : 0);
+ tp->f_flags |= (is_dup ? DUPLICATE : 0);
+ }
+ return;
+
+}
--- /dev/null
+/* $NetBSD: specfile.h,v 1.2 1995/08/17 17:22:23 thorpej Exp $ */
+
+#define T_OPTIONAL 1
+#define T_STANDARD 2
+#define T_COMPILE_WITH 3
+#define T_CONFIG_DEPENDENT 4
+#define T_DEVICE_DRIVER 5
+#define T_PROFILING_ROUTINE 6
+#define T_IDENTIFIER 7
+#define T_OR 8
+#define T_REQUIRES 9
+#define T_NOT 10
+#define EXPR_GROUP 11
+#define T_LEFTPAREN 12
+#define T_RIGHTPAREN 13
+#define T_NEEDS_COUNT 14