diff --git a/sys/pic32/devcfg.c b/sys/pic32/devcfg.c deleted file mode 100644 index 5418445..0000000 --- a/sys/pic32/devcfg.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Chip configuration. - */ -#include "machine/pic32mx.h" - -PIC32_DEVCFG ( - 0| DC0_DEBUG | DC0_ICE, - - 0| DC1_FNOSC | DC1_SOSC | DC1_IESO | DC1_POSCMOD | - DC1_OSCIOFNC | DC1_PBDIV | DC1_CKM | DC1_CKS | - DC1_WDTPS | DC1_WDTEN, - - 0| DC2_PLLIDIV | DC2_PLLMUL | DC2_UPLLIDIV | DC2_UPLL | - DC2_PLLODIV, - - 0| DEVCFG3_USERID(DC3_USERID) | DC3_SRS | DC3_MII | - DC3_ETH | DC3_CAN | DC3_USBID | DC3_VBUSON -); - - diff --git a/sys/pic32/drivers.mk b/sys/pic32/drivers.mk deleted file mode 100644 index 7729900..0000000 --- a/sys/pic32/drivers.mk +++ /dev/null @@ -1,43 +0,0 @@ -ifeq ($(DRIVER_GPIO),yes) - KERNOBJ += gpio.o - DEFS += -DGPIO_ENABLED -endif - -ifeq ($(DRIVER_POWER),yes) - KERNOBJ += power_control.o - POWER_LED_PORT ?= TRISG - POWER_LED_PIN ?= 14 - POWER_SWITCH_PORT ?= TRISE - POWER_SWITCH_PIN ?= 9 - POWER_CONTROL_PORT ?= TRISE - POWER_CONTROL_PIN ?= 9 - DEFS += -DPOWER_ENABLED -DPOWER_LED_PORT=$(POWER_LED_PORT) -DPOWER_LED_PIN=$(POWER_LED_PIN) - DEFS += -DPOWER_SWITCH_PORT=$(POWER_SWITCH_PORT) -DPOWER_SWITCH_PIN=$(POWER_SWITCH_PIN) - DEFS += -DPOWER_CONTROL_PORT=$(POWER_CONTROL_PORT) -DPOWER_CONTROL_PIN=$(POWER_CONTROL_PIN) -endif - -ifeq ($(DRIVER_ADC),yes) - KERNOBJ += adc.o - DEFS += -DADC_ENABLED -endif - -ifeq ($(DRIVER_SPI),yes) - KERNOBJ += spi.o - DEFS += -DSPI_ENABLED -endif - -ifeq ($(DRIVER_GLCD),yes) - KERNOBJ += glcd.o - DEFS += -DGLCD_ENABLED -endif - -ifeq ($(DRIVER_PWM),yes) - KERNOBJ += pwm.o - DEFS += -DPWM_ENABLED -endif - -ifeq ($(DRIVER_SDRAMP),yes) - NEEDS_FEATURE_KERNEL_EXECUTABLE_RAM = yes - KERNOBJ += sdram.o rd_sdramp.o - DEFS += -DSDRAMP_ENABLED -endif diff --git a/sys/pic32/retroone/Makefile b/sys/pic32/retroone/Makefile index 6933f26..c08ebdd 100644 --- a/sys/pic32/retroone/Makefile +++ b/sys/pic32/retroone/Makefile @@ -14,7 +14,7 @@ DEFS += -DGLOBAL_DEBUG # CPU frequency 80 MHz. DEFS += -DCPU_KHZ=80000 -DEFS += -DBUS_KHZ=80000 +DEFS += -DBUS_KHZ=80000 -DBUS_DIV=1 # # Basic pic32mx795f512l chip with internal oscillator @@ -32,28 +32,6 @@ DEFS += -DLED_KERNEL_PORT=TRISB -DLED_KERNEL_PIN=8 DEFS += -DLED_TTY_PORT=TRISB -DLED_TTY_PIN=9 DEFS += -DLED_AUX_PORT=TRISA -DLED_AUX_PIN=9 -# Include or exclude drivers - -# General Purpose I/O -DRIVER_GPIO = yes - -# Basic ADC interface -DRIVER_ADC = yes - -# Power control (power LED, and soft power-off by button) -# requires supported PSU (ATX) -DRIVER_POWER = no - -DRIVER_GLCD = yes -DRIVER_PWM = yes - -POWER_LED_PORT = TRISG -POWER_LED_PIN = 12 -POWER_SWITCH_PORT = TRISG -POWER_SWITCH_PIN = 0 -POWER_CONTROL_PORT = TRISE -POWER_CONTROL_PIN = 9 - DEPFLAGS = -MT $@ -MD -MP -MF .deps/$*.dep CFLAGS = -O $(DEFS) $(DEPFLAGS) ASFLAGS = $(DEFS) $(DEPFLAGS) @@ -97,8 +75,21 @@ KERNOBJ += vers.o devcfg.o # Include any local specific configuration overrides -include Makefile.local -# This makefile does the work including the right files and options for the drivers -include ../drivers.mk +# GPIO driver +KERNOBJ += gpio.o +DEFS += -DGPIO_ENABLED + +# ADC driver +KERNOBJ += adc.o +DEFS += -DADC_ENABLED + +# GLCD driver +KERNOBJ += glcd.o +DEFS += -DGLCD_ENABLED + +# PWM driver +KERNOBJ += pwm.o +DEFS += -DPWM_ENABLED all: .deps sys machine unix.elf $(SIZE) unix.elf diff --git a/sys/pic32/retroone/README b/sys/pic32/retroone/README new file mode 100644 index 0000000..c648880 --- /dev/null +++ b/sys/pic32/retroone/README @@ -0,0 +1,2 @@ +This directory contains an example of RetroBSD kernel build +using plain Makefile (no configsys or kconfig tools). diff --git a/sys/pic32/diag/Makefile b/tools/diag/Makefile similarity index 85% rename from sys/pic32/diag/Makefile rename to tools/diag/Makefile index ff2b8d6..0744184 100644 --- a/sys/pic32/diag/Makefile +++ b/tools/diag/Makefile @@ -12,7 +12,7 @@ DEFS += -I. -I$(H) -DKERNEL -DPIC32MX7 # CPU frequency 80 MHz. DEFS += -DCPU_KHZ=80000 -DEFS += -DBUS_KHZ=80000 +DEFS += -DBUS_KHZ=80000 -DBUS_DIV=1 # # Ethernet/USB Starter Kit with I/O Expansion board @@ -54,27 +54,6 @@ DEFS += -DLED_DISK_PORT=TRISE -DLED_DISK_PIN=1 -DLED_DISK_INVERT DEFS += -DLED_KERNEL_PORT=TRISE -DLED_KERNEL_PIN=2 -DLED_KERNEL_INVERT DEFS += -DLED_TTY_PORT=TRISE -DLED_TTY_PIN=3 -DLED_TTY_INVERT -# -# Include or exclude drivers -# - -# General Purpose I/O -DRIVER_GPIO = no - -# Basic ADC interface -DRIVER_ADC = no - -# Power control (power LED, and soft power-off by button) -# requires supported PSU (ATX) -DRIVER_POWER = no - -POWER_LED_PORT = TRISG -POWER_LED_PIN = 12 -POWER_SWITCH_PORT = TRISG -POWER_SWITCH_PIN = 0 -POWER_CONTROL_PORT = TRISE -POWER_CONTROL_PIN = 9 - DEPFLAGS = -MT $@ -MD -MP -MF .deps/$*.dep CFLAGS = -O $(DEFS) $(DEPFLAGS) ASFLAGS = $(DEFS) $(DEPFLAGS) @@ -101,9 +80,6 @@ KERNOBJ += rdisk.o rd_sd.o spi_bus.o # Include any local specific configuration overrides -include Makefile.local -# This makefile does the work including the right files and options for the drivers -include ../drivers.mk - all: .deps sys machine diag.elf $(SIZE) diag.elf diff --git a/sys/pic32/diag/main.c b/tools/diag/main.c similarity index 100% rename from sys/pic32/diag/main.c rename to tools/diag/main.c diff --git a/tools/kconfig/.gitignore b/tools/kconfig/.gitignore new file mode 100644 index 0000000..393baec --- /dev/null +++ b/tools/kconfig/.gitignore @@ -0,0 +1,2 @@ +y.tab.h +kconfig diff --git a/tools/kconfig/Makefile b/tools/kconfig/Makefile new file mode 100644 index 0000000..57f981f --- /dev/null +++ b/tools/kconfig/Makefile @@ -0,0 +1,27 @@ +CC = gcc -g +CFLAGS = -O -Wall -Werror +YACC = byacc -d +DESTDIR = /usr/local +OBJS = config.o main.o lang.o mkioconf.o mkmakefile.o mkheaders.o \ + mkswapconf.o +PROG = kconfig + +all: $(PROG) $(PROG).0 + +install: $(PROG) + install -s $(PROG) ${DESTDIR}/bin/$(PROG) + +$(PROG).0: $(PROG).8 + nroff -man $< > $@ + +clean: + rm -rf *~ *.o *.lst *.dis $(PROG) $(PROG).0 $(PROG).dSYM y.tab.[ch] lang.c config.c + +$(PROG): $(OBJS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +main.o: main.c y.tab.h config.h +mkheaders.o: mkheaders.c config.h y.tab.h +mkioconf.o: mkioconf.c y.tab.h config.h +mkmakefile.o: mkmakefile.c y.tab.h config.h +mkswapconf.o: mkswapconf.c config.h diff --git a/tools/kconfig/Makefile-bsd b/tools/kconfig/Makefile-bsd new file mode 100644 index 0000000..fa710fa --- /dev/null +++ b/tools/kconfig/Makefile-bsd @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= config +CFLAGS+=-I. -I${.CURDIR} +SRCS= config.c main.c lang.c mkioconf.c mkmakefile.c mkglue.c mkheaders.c \ + mkswapconf.c +MAN8= config.0 +DPADD= ${LIBL} +LDADD= -ll +CLEANFILES+=y.tab.h lang.c config.c y.tab.c config.0 + +.include diff --git a/tools/kconfig/Makefile.kconf b/tools/kconfig/Makefile.kconf new file mode 100644 index 0000000..3b587c4 --- /dev/null +++ b/tools/kconfig/Makefile.kconf @@ -0,0 +1,149 @@ +# +# Makefile for 4.4 BSD, pic32 target +# +# This makefile is constructed from a machine description: +# config machineid +# Most changes should be made in the machine description +# /sys/conf/``machineid'' +# after which you should do +# config machineid +# Machine generic makefile changes should be made in +# /sys/conf/Makefile.``machinetype'' +# after which config should be rerun for all machines of that type. +# +# N.B.: NO DEPENDENCIES ON FOLLOWING FLAGS ARE VISIBLE TO MAKEFILE +# IF YOU CHANGE THE DEFINITION OF ANY OF THESE RECOMPILE EVERYTHING +# +# -DTRACE compile in kernel tracing hooks +# -DQUOTA compile in file system quotas +# +# DEBUG is set to -g by config if debugging is requested (config -g). +# PROF is set to -pg by config if profiling is requested (config -p). + +.if exists(${MIPS_GCC_ROOT}/bin/mips-sde-elf-gcc) +MIPS_GCC_PREFIX ?= ${MIPS_GCC_ROOT}/bin/mips-sde-elf- +.endif +.if exists(${MIPS_GCC_ROOT}/bin/mips-elf-gcc) +MIPS_GCC_PREFIX ?= ${MIPS_GCC_ROOT}/bin/mips-elf- +.endif + +AS= ${MIPS_GCC_PREFIX}as ${DEBUG} -mips32r2 -EL +CC= ${MIPS_GCC_PREFIX}gcc ${DEBUG} -mips32r2 -EL -msoft-float -nostdinc -fno-builtin -Werror -Wall +CPP= ${MIPS_GCC_PREFIX}cpp +LD= ${MIPS_GCC_PREFIX}gcc -mips32r2 -EL +LDFLAGS= -nostdlib -T $A/${LDSCRIPT} -Wl,-Map=vmunix.map +SIZE= ${MIPS_GCC_PREFIX}size +OBJCOPY= ${MIPS_GCC_PREFIX}objcopy +OBJDUMP= ${MIPS_GCC_PREFIX}objdump + +.if exists(${MIPS_GCC_ROOT}/bin/mips-elf-gcc) +LDFLAGS+= -Wl,--oformat=elf32-littlemips +.endif + +# source tree is located via $S relative to the compilation directory +S= ../.. +A= $S/mips + +COPTS= -I. -I$S ${IDENT} -DKERNEL +CFLAGS= -O ${COPTS} + +# compile rules: rules are named ${TYPE}_${SUFFIX}${CONFIG_DEP} +# where TYPE is NORMAL, DRIVER, or PROFILE}; SUFFIX is the file suffix, +# capitalized (e.g. C for a .c file), and CONFIG_DEP is _C if the file +# is marked as config-dependent. + +NORMAL_C= ${CC} -c ${CFLAGS} ${PROF} $< +NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $< + +DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $< +DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $< + +PROFILE_C= ${CC} -p -c ${COPTS} $< + +NORMAL_S= ${CPP} ${COPTS} $< | ${AS} -o $@ +NORMAL_S_C= ${CPP} ${COPTS} ${PARAM} $< | ${AS} -o $@ + +%OBJS + +%CFILES + +# load lines for config "xxx" will be emitted as: +# xxx: ${SYSTEM_DEP} swapxxx.o +# ${SYSTEM_LD_HEAD} +# ${SYSTEM_LD} swapxxx.o +# ${SYSTEM_LD_TAIL} +SYSTEM_OBJ= locore.o ${OBJS} param.o ioconf.o vnode_if.o +SYSTEM_DEP= Makefile ${SYSTEM_OBJ} $S/libkern/libkern.a +SYSTEM_LD_HEAD= sh $S/conf/newvers.sh; ${CC} $(CFLAGS) -c vers.c; rm -f $@ +SYSTEM_LD= -@echo ${LD} ${LDFLAGS} '$${SYSTEM_OBJ}' vers.o -L$S/libkern -lkern -o vmunix.elf; \ + ${LD} ${LDFLAGS} ${SYSTEM_OBJ} vers.o -L$S/libkern -lkern -o vmunix.elf +SYSTEM_LD_TAIL= ${SIZE} vmunix.elf; \ + $(OBJCOPY) -O ihex --change-addresses=0x80000000 $@ vmunix.hex; \ + $(OBJDUMP) -d -S vmunix.elf > vmunix.dis + +%LOAD + +$S/libkern/libkern.a: + cd $S/libkern && ${MAKE} all + +clean: + rm -f eddep *vmunix.elf vmunix.gdb tags *.o locore.i [a-z]*.s \ + Errs errs linterrs makelinks + +lint: /tmp param.c + @lint -hbxn -DGENERIC -Dvolatile= ${COPTS} ${PARAM} -UKGDB \ + $A/pic32/Locore.c ${CFILES} $A/pic32/swapgeneric.c \ + ioconf.c param.c + +symbols.sort: $A/pic32/symbols.raw + grep -v '^#' $A/pic32/symbols.raw \ + | sed 's/^ //' | sort -u > symbols.sort + +locore.o: $A/pic32/locore.s $A/include/machAsmDefs.h \ + $A/include/machConst.h $A/include/reg.h $A/include/assym.h + ${CPP} ${COPTS} ${PARAM} -DLOCORE $A/pic32/locore.s | \ + ${AS} -o locore.o + +# the following is necessary because autoconf.o depends on #if GENERIC +autoconf.o: Makefile + +# the following are necessary because the files depend on the types of +# cpu's included in the system configuration +clock.o machdep.o autoconf.o conf.o: Makefile + +# depend on network configuration +uipc_proto.o vfs_conf.o: Makefile + +machine: + ln -s $A/include $@ + +depend: machine param.c vnode_if.h + mkdep ${COPTS} ${CFILES} ioconf.c param.c + +links: + egrep '#if' ${CFILES} | sed -f $S/conf/defines | \ + sed -e 's/:.*//' -e 's/\.c/.o/' | sort -u > dontlink + echo ${CFILES} | tr -s ' ' '\12' | sed 's/\.c/.o/' | \ + sort -u | comm -23 - dontlink | \ + sed 's,../.*/\(.*.o\),rm -f \1;ln -s ../GENERIC/\1 \1,' > makelinks + sh makelinks && rm -f dontlink + +tags: + @echo "see $S/kern/Makefile for tags" + +ioconf.o: ioconf.c + ${CC} -c ${CFLAGS} ioconf.c + +param.c: $S/conf/param.c + rm -f param.c + cp $S/conf/param.c . + +param.o: param.c Makefile + ${CC} -c ${CFLAGS} ${PARAM} param.c + +vnode_if.c: $S/kern/vnode_if.sh $S/kern/vnode_if.src + sh $S/kern/vnode_if.sh $S/kern/vnode_if.src +vnode_if.h: $S/kern/vnode_if.sh $S/kern/vnode_if.src + sh $S/kern/vnode_if.sh $S/kern/vnode_if.src + +%RULES diff --git a/tools/kconfig/config.h b/tools/kconfig/config.h new file mode 100644 index 0000000..c08ff50 --- /dev/null +++ b/tools/kconfig/config.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 1980, 1993 + * 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. + * + * @(#)config.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Config. + */ +#include +#include +#include +#include + +#define NODEV ((dev_t)-1) + +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 */ + char *f_special; /* special make rule if present */ + char *f_needs; + /* + * 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; + int fuw_swapflag; + } 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_swapflag fun.fuw.fuw_swapflag +#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 + +/* + * Attributes (flags). + */ +#define CONFIGDEP 1 + +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 */ + struct device *d_next; /* Next one in list */ +}; + +struct config { + char *c_dev; + char *s_sysname; +}; + +/* + * Config has a global notion of which machine type is + * being used. + */ +int machine; +char *machinename; +#define MACHINE_PIC32 1 + +/* + * 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 *ldscript; + +int do_trace; + +struct device *dtab; + +char errbuf[80]; +int yyline; + +struct file_list *ftab, *conf_list, **confp, *comp_list, **compp; + +int zone, hadtz; +int dst; +int hz; +int profiling; +int debugging; + +int maxusers; + +#define eq(a,b) (!strcmp(a,b)) + +char *get_word(FILE *); +char *get_quoted_word(FILE *); +char *raise(char *); +dev_t nametodev(char *, int); +char *devtoname(dev_t); +void init_dev(struct device *); +int yyparse(void); +void pic32_ioconf(void); +void makefile(void); +void headers(void); +void swapconf(void); diff --git a/tools/kconfig/config.y b/tools/kconfig/config.y new file mode 100644 index 0000000..e72f9c2 --- /dev/null +++ b/tools/kconfig/config.y @@ -0,0 +1,939 @@ +%union { + char *str; + int val; + struct file_list *file; + struct idlst *lst; +} + +%token AND +%token ANY +%token AT +%token COMMA +%token CONFIG +%token CONTROLLER +%token CPU +%token CSR +%token DEVICE +%token DISK +%token DRIVE +%token DST +%token DUMPS +%token EQUALS +%token FLAGS +%token HZ +%token IDENT +%token LDSCRIPT +%token MACHINE +%token MAJOR +%token MASTER +%token MAXUSERS +%token MINOR +%token MINUS +%token ON +%token OPTIONS +%token MAKEOPTIONS +%token PRIORITY +%token PSEUDO_DEVICE +%token ROOT +%token SEMICOLON +%token SEQUENTIAL +%token SIZE +%token SLAVE +%token SWAP +%token TIMEZONE +%token TRACE +%token VECTOR + +%token ID +%token NUMBER +%token FPNUMBER + +%type Save_id +%type Opt_value +%type Dev +%type Id_list +%type optional_size +%type optional_sflag +%type device_name +%type major_minor +%type root_device_spec +%type dump_device_spec +%type swap_device_spec + +%{ + +/* + * Copyright (c) 1988, 1993 + * 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. + * + * @(#)config.y 8.1 (Berkeley) 6/6/93 + */ + +#include "config.h" +#include +#include + +struct device cur; +struct device *curp = 0; +char *temp_id; +char *val_id; + +int yylex(void); +int finddev(dev_t dev); +void deverror(char *systemname, char *devtype); +int alreadychecked(dev_t dev, dev_t list[], dev_t *last); + +%} +%% +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: + MACHINE Save_id + = { + if (strcmp($2, "pic32") == 0) { + machine = MACHINE_PIC32; + machinename = "pic32"; + } else + yyerror("Unknown machine type"); + } + | + CPU Save_id + = { + struct cputype *cp = + (struct cputype *)malloc(sizeof (struct cputype)); + cp->cpu_name = strdup($2); + cp->cpu_next = cputype; + cputype = cp; + free(temp_id); + } + | + OPTIONS Opt_list + | + MAKEOPTIONS Mkopt_list + | + IDENT ID + = { ident = strdup($2); } + | + LDSCRIPT ID + = { ldscript = strdup($2); } + | + System_spec + | + HZ NUMBER + = { hz = $2; } + | + 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: + swap_spec + | + root_spec + | + dump_spec + ; + +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 = newflist(SWAPSPEC); + + if (eq($1, "generic")) + fl->f_fn = $1; + else { + fl->f_swapdev = nametodev($1, 0); + fl->f_fn = devtoname(fl->f_swapdev); + } + $$ = fl; + } + | + major_minor + = { + struct file_list *fl = newflist(SWAPSPEC); + + 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); } + | + 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); } + | + 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); + $$ = strdup(buf); + free($1); + } + | + Save_id NUMBER ID + = { + char buf[80]; + + (void) sprintf(buf, "%s%d%s", $1, $2, $3); + $$ = strdup(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 = strdup($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 = strdup($1); + op->op_next = opt; + op->op_value = strdup($3); + opt = op; + free(temp_id); + free(val_id); + } + ; + +Opt_value: + ID + = { $$ = val_id = strdup($1); } + | + NUMBER + = { + char nb[16]; + (void) sprintf(nb, "%d", $1); + $$ = val_id = strdup(nb); + } + ; + +Save_id: + ID + = { $$ = temp_id = strdup($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 = strdup($1); + op->op_next = mkopt; + op->op_value = strdup($3); + mkopt = op; + free(temp_id); + free(val_id); + } + ; + +Dev: + ID + = { $$ = strdup($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; + cur.d_unit = $3; + } + ; + +Init_dev: + /* lambda */ + = { init_dev(&cur); } + ; + +Dev_info: + Con_info Info_list + | + Info_list + | + /* lambda */ + ; + +Con_info: + AT Dev NUMBER + = { cur.d_conn = connect($2, $3); } + ; + +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->d_type == MASTER) + cur.d_slave = $2; + else + yyerror("can't specify slave--not to master"); + } + | + 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; + } + ; +%% + +void yyerror(s) + char *s; +{ + fprintf(stderr, "config: line %d: %s\n", yyline + 1, s); +} + +/* + * add a device to the list of devices + */ +void 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 + */ +void mkconf(sysname) + char *sysname; +{ + register struct file_list *fl, **flp; + + fl = (struct file_list *) malloc(sizeof *fl); + fl->f_type = SYSTEMSPEC; + fl->f_needs = 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); +} + +/* + * Add a swap device to the system's configuration + */ +void mkswap(system, fl, size, flag) + struct file_list *system, *fl; + int size, flag; +{ + register struct file_list **flp; + + 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; + fl->f_swapflag = flag; + + /* + * 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")) + system->f_fn = strdup(fl->f_fn); + else + system->f_fn = strdup(system->f_needs); +} + +/* + * 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 = strdup(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 + * aren't connected to anything, then make the same + * connection, else call ourself to connect to another + * unspecific device. + */ + if (dcp == 0) + dp->d_conn = dcp; + else + dp->d_conn = connect(dcp->d_name, QUES); + } + return (dp); +} + +void 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_flags = dp->d_dk = 0; + dp->d_pri = -1; + dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN; + dp->d_port = (char *)0; + dp->d_portn = 0; + dp->d_irq = -1; + 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 + */ +void check_nexus(dev, num) + register struct device *dev; + int num; +{ + switch (machine) { + + case MACHINE_PIC32: + break; + } +} + +/* + * Check the timezone to make certain it is sensible + */ +void 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. + */ +void checksystemspec(fl) + register struct file_list *fl; +{ + char buf[BUFSIZ]; + register struct file_list *swap; + int generic; + + 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"); + if (fl->f_rootdev == NODEV && !generic) { + 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 = newflist(SWAPSPEC); + dev = fl->f_rootdev; + if (minor(dev) & 07) { + 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' + 1)); + swap->f_fn = devtoname(swap->f_swapdev); + mkswap(fl, swap, 0, 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. + */ +void 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, "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, "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")) + continue; + if (alreadychecked(fl->f_swapdev, checked, pchecked)) + continue; + if (!finddev(fl->f_swapdev)) + fprintf(stderr, + "config: swap device %s not configured", fl->f_fn); + *pchecked++ = fl->f_swapdev; + } + return (pchecked); +} + +/* + * Has a device already been checked + * for it's existence in the configuration? + */ +int 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); +} + +void deverror(systemname, devtype) + char *systemname, *devtype; +{ + + fprintf(stderr, "config: %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*/ +int finddev(dev) + dev_t dev; +{ + /* punt on this right now */ + return (1); +} diff --git a/tools/kconfig/devices.kconf b/tools/kconfig/devices.kconf new file mode 100644 index 0000000..20f486e --- /dev/null +++ b/tools/kconfig/devices.kconf @@ -0,0 +1 @@ +sd 0 diff --git a/tools/kconfig/files.kconf b/tools/kconfig/files.kconf new file mode 100644 index 0000000..42db771 --- /dev/null +++ b/tools/kconfig/files.kconf @@ -0,0 +1,179 @@ +isofs/cd9660/cd9660_bmap.c optional cd9660 +isofs/cd9660/cd9660_lookup.c optional cd9660 +isofs/cd9660/cd9660_node.c optional cd9660 +isofs/cd9660/cd9660_rrip.c optional cd9660 +isofs/cd9660/cd9660_util.c optional cd9660 +isofs/cd9660/cd9660_vfsops.c optional cd9660 +isofs/cd9660/cd9660_vnops.c optional cd9660 +kern/init_main.c standard +kern/init_sysent.c standard +kern/kern_acct.c standard +kern/kern_clock.c standard +kern/kern_descrip.c standard +kern/kern_exec.c standard +kern/kern_exit.c standard +kern/kern_fork.c standard +kern/kern_ktrace.c standard +kern/kern_malloc.c standard +kern/kern_physio.c standard +kern/kern_proc.c standard +kern/kern_prot.c standard +kern/kern_resource.c standard +kern/kern_sig.c standard +kern/kern_subr.c standard +kern/kern_synch.c standard +kern/kern_sysctl.c standard +kern/kern_time.c standard +kern/kern_xxx.c standard +kern/kern_lock.c standard +kern/subr_log.c standard +kern/subr_prf.c standard +kern/subr_prof.c standard +kern/subr_rmap.c standard +kern/subr_xxx.c standard +kern/sys_generic.c standard +kern/sys_process.c standard +kern/sys_socket.c standard +kern/sysv_shm.c optional sysvshm +kern/tty.c standard +kern/tty_compat.c standard +kern/tty_conf.c standard +kern/tty_pty.c optional pty +kern/tty_subr.c standard +kern/tty_tb.c optional tb +kern/tty_tty.c standard +kern/uipc_domain.c standard +kern/uipc_mbuf.c standard +kern/uipc_proto.c standard +kern/uipc_socket.c standard +kern/uipc_socket2.c standard +kern/uipc_syscalls.c standard +kern/uipc_usrreq.c standard +kern/vfs_bio.c standard +kern/vfs_cache.c standard +kern/vfs_cluster.c standard +kern/vfs_conf.c standard +kern/vfs_init.c standard +kern/vfs_lookup.c standard +kern/vfs_subr.c standard +kern/vfs_syscalls.c standard +kern/vfs_vnops.c standard +miscfs/deadfs/dead_vnops.c standard +miscfs/fdesc/fdesc_vfsops.c optional fdesc +miscfs/fdesc/fdesc_vnops.c optional fdesc +miscfs/fifofs/fifo_vnops.c optional fifo +miscfs/kernfs/kernfs_vfsops.c optional kernfs +miscfs/kernfs/kernfs_vnops.c optional kernfs +miscfs/nullfs/null_subr.c optional nullfs +miscfs/nullfs/null_vfsops.c optional nullfs +miscfs/nullfs/null_vnops.c optional nullfs +miscfs/portal/portal_vfsops.c optional portal +miscfs/portal/portal_vnops.c optional portal +miscfs/procfs/procfs_subr.c optional procfs +miscfs/procfs/procfs_vnops.c optional procfs +miscfs/procfs/procfs_vfsops.c optional procfs +miscfs/procfs/procfs_note.c optional procfs +miscfs/procfs/procfs_mem.c optional procfs +miscfs/procfs/procfs_ctl.c optional procfs +miscfs/procfs/procfs_status.c optional procfs +miscfs/procfs/procfs_regs.c optional procfs +miscfs/procfs/procfs_fpregs.c optional procfs +miscfs/specfs/spec_vnops.c standard +miscfs/umapfs/umap_subr.c optional umapfs +miscfs/umapfs/umap_vfsops.c optional umapfs +miscfs/umapfs/umap_vnops.c optional umapfs +miscfs/union/union_subr.c optional union +miscfs/union/union_vfsops.c optional union +miscfs/union/union_vnops.c optional union +net/bpf.c optional bpfilter +net/bpf_filter.c optional bpfilter +net/if.c standard +net/if_ethersubr.c optional ether +net/if_loop.c optional loop +net/if_sl.c optional sl +net/radix.c standard +net/raw_cb.c standard +net/raw_usrreq.c standard +net/route.c standard +net/rtsock.c standard +net/slcompress.c optional sl +netinet/if_ether.c optional ether +netinet/igmp.c optional inet +netinet/in.c optional inet +netinet/in_pcb.c optional inet +netinet/in_proto.c optional inet +netinet/ip_icmp.c optional inet +netinet/ip_input.c optional inet +netinet/ip_mroute.c optional inet mrouting +netinet/ip_output.c optional inet +netinet/raw_ip.c optional inet +netinet/tcp_debug.c optional inet +netinet/tcp_input.c optional inet +netinet/tcp_output.c optional inet +netinet/tcp_subr.c optional inet +netinet/tcp_timer.c optional inet +netinet/tcp_usrreq.c optional inet +netinet/udp_usrreq.c optional inet +nfs/nfs_bio.c optional nfs +nfs/nfs_node.c optional nfs +nfs/nfs_nqlease.c optional nfs +nfs/nfs_serv.c optional nfs +nfs/nfs_socket.c optional nfs +nfs/nfs_srvcache.c optional nfs +nfs/nfs_subs.c optional nfs +nfs/nfs_syscalls.c optional nfs +nfs/nfs_vfsops.c optional nfs +nfs/nfs_vnops.c optional nfs +ufs/ffs/ffs_alloc.c optional ffs +ufs/ffs/ffs_alloc.c optional mfs +ufs/ffs/ffs_balloc.c optional ffs +ufs/ffs/ffs_balloc.c optional mfs +ufs/ffs/ffs_inode.c optional ffs +ufs/ffs/ffs_inode.c optional mfs +ufs/ffs/ffs_subr.c optional ffs +ufs/ffs/ffs_subr.c optional mfs +ufs/ffs/ffs_tables.c optional ffs +ufs/ffs/ffs_tables.c optional mfs +ufs/ffs/ffs_vfsops.c optional ffs +ufs/ffs/ffs_vfsops.c optional mfs +ufs/ffs/ffs_vnops.c optional ffs +ufs/ffs/ffs_vnops.c optional mfs +ufs/lfs/lfs_alloc.c optional lfs +ufs/lfs/lfs_bio.c optional lfs +ufs/lfs/lfs_balloc.c optional lfs +ufs/lfs/lfs_cksum.c optional lfs +ufs/lfs/lfs_debug.c optional lfs +ufs/lfs/lfs_inode.c optional lfs +ufs/lfs/lfs_segment.c optional lfs +ufs/lfs/lfs_subr.c optional lfs +ufs/lfs/lfs_syscalls.c optional lfs +ufs/lfs/lfs_vfsops.c optional lfs +ufs/lfs/lfs_vnops.c optional lfs +ufs/mfs/mfs_vfsops.c optional mfs +ufs/mfs/mfs_vnops.c optional mfs +ufs/ufs/ufs_bmap.c standard +ufs/ufs/ufs_disksubr.c standard +ufs/ufs/ufs_ihash.c standard +ufs/ufs/ufs_inode.c standard +ufs/ufs/ufs_lockf.c standard +ufs/ufs/ufs_lookup.c standard +ufs/ufs/ufs_quota.c standard +ufs/ufs/ufs_vfsops.c standard +ufs/ufs/ufs_vnops.c standard +vm/device_pager.c optional devpager +vm/swap_pager.c optional swappager +vm/vm_fault.c standard +vm/vm_glue.c standard +vm/vm_init.c standard +vm/vm_kern.c standard +vm/vm_map.c standard +vm/vm_meter.c standard +vm/vm_mmap.c standard +vm/vm_object.c standard +vm/vm_page.c standard +vm/vm_pageout.c standard +vm/vm_pager.c standard +vm/vm_swap.c standard +vm/vm_unix.c standard +vm/vm_user.c standard +vm/vnode_pager.c optional vnodepager diff --git a/tools/kconfig/kconfig.8 b/tools/kconfig/kconfig.8 new file mode 100644 index 0000000..cb9f9c4 --- /dev/null +++ b/tools/kconfig/kconfig.8 @@ -0,0 +1,102 @@ +.Dd June 1, 2015 +.Dt CONFIG 8 +.Os RetroBSD +.Sh NAME +.Nm kconfig +.Nd build kernel configuration files +.Sh SYNOPSIS +.Nm kconfig +.Op Fl p +.Ar system_name +.Sh DESCRIPTION +.Pp +.Nm Kconfig +builds a set of kernel configuration files from the file +.Ar SYSTEM_NAME +which describes the kernel to configure. +A second file tells +.Nm kconfig +what files are needed to generate a kernel 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 p +If the +.Fl p +option is supplied, +.Nm kconfig +will configure a kernel for profiling; for example, +.Xr kgmon 8 +and +.Xr gprof 1 . +.It Ar SYSTEM_NAME +specifies the name of the kernel configuration file +containing device specifications, configuration options +and other system parameters for one kernel configuration. +.El +.Pp +.Nm Kconfig +should be run from the machine and board specific +subdirectory of the system source (like +.Pa sys/pic32/max32 ) . +.Nm Kconfig +places all output files in the current directory. +The output of +.Nm kconfig +consists of a number of files: +.Pa ioconf.c , +a description +of what I/O devices are attached to the system; +.Pa Makefile , +used by +.Xr make 1 +in building the kernel; +header files, definitions of +the number of various devices that will be compiled into the kernel; +swap configuration files, definitions for +the disk areas to be used for swapping, the root file system, +argument processing, and kernel dumps. +.Pp +After running +.Nm kconfig , +it is necessary to run +.Dq Li make depend +in the directory where the new makefile +was created (current directory). +.Nm Kconfig +prints a reminder of this when it completes. +.Pp +If any other error messages are produced by +.Nm kconfig , +the problems in the configuration file should be corrected and +.Nm kconfig +should be run again. +Attempts to compile a kernel that had configuration errors +are likely to fail. +.Sh FILES +.Bl -tag -width ../Makefile.kconf -compact +.It Pa ../Makefile.kconf +generic makefile for the platform +.It Pa ../files.kconf +list of files kernel is built from +.It Pa ../devices.kconf +name to major device mapping file +.El +.Sh SEE ALSO +The SYNOPSIS portion of each device in section 4. +.Rs +.%T "Building RetroBSD Kernel with kconfig" +.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 . diff --git a/tools/kconfig/lang.l b/tools/kconfig/lang.l new file mode 100644 index 0000000..08e5bd2 --- /dev/null +++ b/tools/kconfig/lang.l @@ -0,0 +1,171 @@ +%option noinput +%option nounput +%option noyywrap +%{ +/*- + * Copyright (c) 1980, 1993 + * 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. + * + * @(#)lang.l 8.1 (Berkeley) 6/6/93 + */ +#include +#include "y.tab.h" +#include "config.h" + +#define tprintf if (do_trace) printf + +/* + * Key word table + */ +struct kt { + char *kt_name; + int kt_val; +}; + +static struct kt key_words[] = { + { "and", AND }, + { "at", AT }, + { "config", CONFIG }, + { "controller", CONTROLLER }, + { "cpu", CPU }, + { "csr", CSR }, + { "device", DEVICE }, + { "disk", DISK }, + { "drive", DRIVE }, + { "dst", DST }, + { "dumps", DUMPS }, + { "flags", FLAGS }, + { "hz", HZ }, + { "ident", IDENT }, + { "ldscript", LDSCRIPT }, + { "machine", MACHINE }, + { "major", MAJOR }, + { "makeoptions", MAKEOPTIONS }, + { "master", MASTER }, + { "maxusers", MAXUSERS }, + { "minor", MINOR }, + { "on", ON }, + { "options", OPTIONS }, + { "priority", PRIORITY }, + { "pseudo-device", PSEUDO_DEVICE }, + { "root", ROOT }, + { "sequential", SEQUENTIAL }, + { "size", SIZE }, + { "slave", SLAVE }, + { "swap", SWAP }, + { "tape", DEVICE }, + { "timezone", TIMEZONE }, + { "trace", TRACE }, + { "vector", VECTOR }, + { 0, 0 }, +}; + +/* + * Look up a string in the keyword table. Returns a -1 if the + * string is not a keyword otherwise it returns the keyword number + */ +static int +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; +} +%} +WORD [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; + return ID; + } +0[0-7]* { + yylval.val = strtoul(yytext, 0, 8); + tprintf("#O:%o ", yylval.val); + return NUMBER; + } +0x[0-9a-fA-F]+ { + yylval.val = strtoul(yytext, 0, 16); + 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]; } + +%% diff --git a/tools/kconfig/main.c b/tools/kconfig/main.c new file mode 100644 index 0000000..ee5d6c5 --- /dev/null +++ b/tools/kconfig/main.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 1980, 1993 + * 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. + */ +#include +#include +#include +#include +#include +#include "y.tab.h" +#include "config.h" + +/* + * Config builds a set of files for building a UNIX + * system given a description of the desired system. + */ +int main(argc, argv) + int argc; + char **argv; +{ + int ch; + + while ((ch = getopt(argc, argv, "gp")) != EOF) + switch (ch) { + case 'g': + debugging++; + break; + case 'p': + profiling++; + break; + case '?': + default: + goto usage; + } + argc -= optind; + argv += optind; + + if (argc != 1) { +usage: fputs("usage: kconfig [-gp] sysname\n", stderr); + exit(1); + } + + if (! freopen(*argv, "r", stdin)) { + perror(*argv); + exit(2); + } + + dtab = NULL; + confp = &conf_list; + compp = &comp_list; + if (yyparse()) + exit(3); + + switch (machine) { + + case MACHINE_PIC32: + pic32_ioconf(); + break; + + default: + printf("Specify machine type, e.g. ``machine pic32''\n"); + exit(1); + } + 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); +} + +/* + * 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); + cp = line; + *cp++ = ch; + while ((ch = getc(fp)) != EOF) { + if (isspace(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: 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); +} diff --git a/tools/kconfig/max32/Config b/tools/kconfig/max32/Config new file mode 100644 index 0000000..7a8656d --- /dev/null +++ b/tools/kconfig/max32/Config @@ -0,0 +1,74 @@ +# +# chipKIT Max32 board +# +# To build the kernel, use: +# cd sys/pic32/max32 +# kconfig MAX32 +# make clean depend +# make depend +# make +# +machine "pic32" + +cpu "PIC32MX" +ident CHIPKIT-MAX + +# Linker script +ldscript "pic32/bootloader-max32.ld" + +# Need to set locally +timezone 8 dst +maxusers 2 + +# Standard system options +options "CPU_KHZ=80000" # Oscillator frequency of CPU core +options "HZ=100" # Frequency of clock interrupt + +# Root filesystem at /dev/sd0a, swap at /dev/sd0b +config unix root on sd0a + swap on sd0b + dumps on sd0b + +# UART ports +device uart1 flags 0x614f # pins rx=RD14, tx=RD15 - logical 39/40 +device uart4 flags 0x6268 # pins rx=RF2, tx=RF8 - serial-to-USB converter + +# Use UART4 as console +options "CONS_MAJOR=17" # UART device +options "CONS_MINOR=3" # UART4 - chipKIT WiFire board + +# SPI ports +controller spi2 flags 0x2a34 # pins sdi=RB10, sdo=RC4 - SD card + +# microSD card +disk sd0 at spi2 drive 0 flags 0x33 # select pin RC3 +options "SD_LED=0x7f" # LED4 is G15 + +# General purpose I/O ports +# Flags define a mask of available pins +# The following pins excluded: +# D14, D15 - uart1 +# F2, F8 - uart4 +# C1, D1, F1, - spi1 +# D11, F0, G6 - spi2, LED1 +# B10, B14, C3, C4 - spi3, SD card +# A15, D9, D10, F4, F5, G0, G1 - spi4, Wi-Fi +# B12 - 1/11 of input voltage +# B13 - potentiometer +#device gpio0 flags 0x46ff # port A +#device gpio1 flags 0x8bff # port B +#device gpio2 flags 0xf004 # port C +#device gpio3 flags 0x303d # port D +#device gpio4 flags 0x03ff # port E +#device gpio5 flags 0x3008 # port F +#device gpio6 flags 0xf380 # port G + +#device adc +#device pwm +#device skel + +# Buttons +options "BUTTON1=0x15" # button 1 at pin RA5 +options "BUTTON2=0x14" # button 2 at pin RA4 + +#pseudo-device pty 4 # pseudo ptys diff --git a/tools/kconfig/mkheaders.c b/tools/kconfig/mkheaders.c new file mode 100644 index 0000000..76eec47 --- /dev/null +++ b/tools/kconfig/mkheaders.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 1980, 1993 + * 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. + */ + +/* + * Make all the .h files for the optional entries + */ +#include +#include "config.h" +#include "y.tab.h" + +void do_header(dev, hname, count) + char *dev, *hname; + int count; +{ + char *file, *name, *inw, *toheader(), *tomacro(); + struct file_list *fl, *fl_head, *tflp; + FILE *inf, *outf; + int inc, oldcount; + + file = toheader(hname); + name = tomacro(dev); + inf = fopen(file, "r"); + oldcount = -1; + if (inf == 0) { + outf = fopen(file, "w"); + if (outf == 0) { + perror(file); + exit(1); + } + fprintf(outf, "#define %s %d\n", name, count); + (void) fclose(outf); + return; + } + fl_head = NULL; + for (;;) { + char *cp; + if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) + break; + if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) + break; + inw = strdup(inw); + cp = get_word(inf); + if (cp == 0 || cp == (char *)EOF) + break; + inc = atoi(cp); + if (eq(inw, name)) { + oldcount = inc; + inc = count; + } + cp = get_word(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); + if (count == oldcount) { + for (fl = fl_head; fl != NULL; fl = tflp) { + tflp = fl->f_next; + free(fl); + } + 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 != NULL; fl = tflp) { + fprintf(outf, + "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0); + tflp = fl->f_next; + free(fl); + } + (void) fclose(outf); +} + +/* + * count all the devices of a certain type and recurse to count + * whatever the device is connected to + */ +void do_count(dev, hname, search) + register char *dev, *hname; + int search; +{ + register struct device *dp, *mp; + register int count, hicount; + + /* + * After this loop, "count" will be the actual number of units, + * and "hicount" will be the highest unit declared. do_header() + * must use this higher of these values. + */ + for (hicount = 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; + break; + } + count++; + /* + * Allow holes in unit numbering, + * assumption is unit numbering starts + * at zero. + */ + if (dp->d_unit + 1 > hicount) + hicount = dp->d_unit + 1; + if (search) { + mp = dp->d_conn; + if (mp != 0 && mp->d_conn != 0) { + do_count(mp->d_name, hname, 0); + search = 0; + } + } + } + do_header(dev, hname, count > hicount ? count : hicount); +} + +void headers() +{ + register struct file_list *fl; + + for (fl = ftab; fl != 0; fl = fl->f_next) + if (fl->f_needs != 0) + do_count(fl->f_needs, fl->f_needs, 1); +} + +/* + * convert a dev name to a .h file name + */ +char * +toheader(dev) + char *dev; +{ + static char hbuf[80]; + + (void) strcpy(hbuf, 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) + *cp++ = islower(*dev) ? toupper(*dev++) : *dev++; + *cp++ = 0; + return (mbuf); +} diff --git a/tools/kconfig/mkioconf.c b/tools/kconfig/mkioconf.c new file mode 100644 index 0000000..c01ec62 --- /dev/null +++ b/tools/kconfig/mkioconf.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 1980, 1993 + * 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. + */ +#include "y.tab.h" +#include "config.h" + +/* + * build the ioconf.c file + */ +static void +pseudo_ioconf(fp) + register FILE *fp; +{ + register struct device *dp; + + for (dp = dtab; dp != NULL; dp = dp->d_next) + if (dp->d_type == PSEUDO_DEVICE) + fprintf(fp, "extern void %sattach __P((int));\n", + dp->d_name); + + fprintf(fp, "\nstruct conf_pdev conf_pdinit[] = {\n"); + for (dp = dtab; dp != NULL; dp = dp->d_next) + if (dp->d_type == PSEUDO_DEVICE) + fprintf(fp, " { %sattach, %d },\n", dp->d_name, + dp->d_slave > 0 ? dp->d_slave : 1); + + fprintf(fp, " { 0, 0 }\n};\n"); +} + +static char * +wnum(num) +{ + if (num == QUES || num == UNKNOWN) + return ("?"); + sprintf(errbuf, "%d", num); + return (errbuf); +} + +#if MACHINE_PIC32 +void pic32_ioconf() +{ + register struct device *dp, *mp; + FILE *fp; + + fp = fopen("ioconf.c", "w"); + if (fp == 0) { + perror("ioconf.c"); + exit(1); + } + fprintf(fp, "#include \"sys/types.h\"\n"); + fprintf(fp, "#include \"sys/time.h\"\n"); + fprintf(fp, "#include \"mips/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 conf_ctlr conf_cinit[] = {\n"); + fprintf(fp, " /* driver,\t\tunit,\taddr,\t\tpri,\tflags */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + if (dp->d_type != CONTROLLER && dp->d_type != MASTER) + 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, + " { &%sdriver,\t%d,\tC 0x%08x,\t%d,\t0x%x },\n", + dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri, + dp->d_flags); + } + fprintf(fp, " { 0 }\n};\n"); + + /* print devices connected to other controllers */ + fprintf(fp, "\nstruct conf_device conf_dinit[] = {\n"); + fprintf(fp, + " /* driver,\t\tctlr driver,\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; + fprintf(fp, " { &%sdriver,\t", dp->d_name); + if (mp) { + fprintf(fp, "&%sdriver,\t%d,\t%d,\t", + mp->d_name, dp->d_unit, mp->d_unit); + } else { + fprintf(fp, "0,\t\t%d,\t0,\t", + dp->d_unit); + } + fprintf(fp, "%d,\t%d,\t%d,\t0x%x },\n", + dp->d_drive, dp->d_slave, dp->d_dk, dp->d_flags); + } + fprintf(fp, " { 0 }\n};\n"); + pseudo_ioconf(fp); + fclose(fp); +} +#endif diff --git a/tools/kconfig/mkmakefile.c b/tools/kconfig/mkmakefile.c new file mode 100644 index 0000000..88538e4 --- /dev/null +++ b/tools/kconfig/mkmakefile.c @@ -0,0 +1,604 @@ +/* + * Copyright (c) 1993, 19801990 + * 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. + */ + +/* + * Build the makefile for the system, from + * the information in the files files and the + * additional files for the machine being compiled to. + */ +#include +#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[] = { + { 2, 1, 16 }, /* MACHINE_PIC32 */ +}; +#define NUSERS (sizeof (users) / sizeof (users[0])) + +int 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); + } +} + +/* + * Read in the information about files used in making the system. + * Store it in the ftab linked list. + */ +void read_files() +{ + FILE *fp; + register struct file_list *tp, *pf; + register struct device *dp; + struct device *save_dp = 0; + register struct opt *op; + char *wd, *this, *needs, *special; + char fname[32]; + int nreqs, first = 1, configdep, isdup, std, filetype; + + ftab = 0; + (void) strcpy(fname, "../files.kconf"); + fp = fopen(fname, "r"); + if (fp == 0) { + perror(fname); + exit(1); + } +next: + /* + * filename [ standard | optional ] [ config-dependent ] + * [ dev* | profiling-routine ] [ device-driver] + * [ compile-with "compile rule" ] + */ + wd = get_word(fp); + if (wd == (char *)EOF) { + (void) fclose(fp); + if (first == 1) { + (void) sprintf(fname, "files.%s", raise(ident)); + first++; + fp = fopen(fname, "r"); + if (fp != 0) + goto next; + } + return; + } + if (wd == 0) + goto next; + this = strdup(wd); + next_word(fp, wd); + if (wd == 0) { + printf("%s: No type for %s.\n", + fname, this); + exit(1); + } + if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags)) + isdup = 1; + else + isdup = 0; + tp = 0; + if (first == 3 && (tp = fltail_lookup(this)) != 0) + printf("%s: Local file %s overrides %s.\n", + fname, this, tp->f_fn); + nreqs = 0; + special = 0; + configdep = 0; + needs = 0; + std = 0; + filetype = NORMAL; + if (eq(wd, "standard")) + std = 1; + else if (!eq(wd, "optional")) { + printf("%s: %s must be optional or standard\n", fname, this); + exit(1); + } +nextparam: + next_word(fp, wd); + if (wd == 0) + goto doneparam; + if (eq(wd, "config-dependent")) { + configdep++; + goto nextparam; + } + if (eq(wd, "compile-with")) { + next_quoted_word(fp, wd); + if (wd == 0) { + printf("%s: missing compile command string.\n", + fname); + exit(1); + } + special = strdup(wd); + goto nextparam; + } + nreqs++; + if (eq(wd, "device-driver")) { + filetype = DRIVER; + goto nextparam; + } + if (eq(wd, "profiling-routine")) { + filetype = PROFILING; + goto nextparam; + } + if (needs == 0 && nreqs == 1) + needs = strdup(wd); + if (isdup) + goto invis; + for (dp = dtab; dp != 0; save_dp = dp, dp = dp->d_next) + if (eq(dp->d_name, wd)) { + if (std && dp->d_type == PSEUDO_DEVICE && + dp->d_slave <= 0) + dp->d_slave = 1; + goto nextparam; + } + if (std) { + dp = (struct device *) malloc(sizeof *dp); + init_dev(dp); + dp->d_name = strdup(wd); + dp->d_type = PSEUDO_DEVICE; + dp->d_slave = 1; + if (save_dp) + save_dp->d_next = dp; + goto nextparam; + } + for (op = opt; op != 0; op = op->op_next) + if (op->op_value == 0 && opteq(op->op_name, wd)) { + if (nreqs == 1) { + free(needs); + needs = 0; + } + goto nextparam; + } +invis: + while ((wd = get_word(fp)) != 0) + ; + if (tp == 0) + tp = new_fent(); + tp->f_fn = this; + tp->f_type = INVISIBLE; + tp->f_needs = needs; + tp->f_flags = isdup; + tp->f_special = special; + goto next; + +doneparam: + if (std == 0 && nreqs == 0) { + printf("%s: what is %s optional on?\n", + fname, this); + exit(1); + } + + if (wd) { + printf("%s: syntax error describing %s\n", + fname, this); + exit(1); + } + if (filetype == PROFILING && profiling == 0) + goto next; + if (tp == 0) + tp = new_fent(); + tp->f_fn = this; + tp->f_type = filetype; + tp->f_flags = 0; + if (configdep) + tp->f_flags |= CONFIGDEP; + tp->f_needs = needs; + tp->f_special = special; + if (pf && pf->f_type == INVISIBLE) + pf->f_flags = 1; /* mark as duplicate */ + goto next; +} + +void 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; + 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); +} + +void 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) { + 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, "$A/%s/%s ", + machinename, swapname); + else + fprintf(fp, "%s ", swapname); + lpos += len + 1; + } + if (lpos != 8) + putc('\n', fp); +} + +/* + * Create the makerules for each file + * which is part of the system. + */ +void do_rules(f) + FILE *f; +{ + register char *cp, *np, och; + register struct file_list *ftp; + char *special; + + for (ftp = ftab; ftp != 0; ftp = ftp->f_next) { + if (ftp->f_type == INVISIBLE) + 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); + 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: + if (!profiling) + continue; + ftype = "PROFILE"; + break; + + default: + printf("config: 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 + */ +void 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.elf", fl->f_needs); + putc('\n', f); +} + +/* + * Build the makefile from the skeleton + */ +void makefile() +{ + FILE *ifp, *ofp; + char line[BUFSIZ]; + struct opt *op; + struct users *up; + + read_files(); + strcpy(line, "../Makefile.kconf"); + //(void) strcat(line, machinename); + ifp = fopen(line, "r"); + if (ifp == 0) { + perror(line); + exit(1); + } + ofp = fopen("Makefile", "w"); + if (ofp == 0) { + perror("Makefile"); + exit(1); + } + fprintf(ofp, "IDENT=-D%s", raise(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 (ldscript) + fprintf(ofp, "LDSCRIPT=\"%s\"\n", ldscript); + if (hadtz == 0) + printf("timezone not specified; gmt assumed\n"); + if ((unsigned)machine > NUSERS) { + printf("maxusers config info isn't present, using pic32\n"); + up = &users[MACHINE_PIC32-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", + zone, dst, maxusers); + if (hz > 0) + fprintf(ofp, " -DHZ=%d", hz); + fprintf(ofp, "\n"); + 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); +} + +char * +tail(fn) + char *fn; +{ + register char *cp; + + cp = rindex(fn, '/'); + if (cp == 0) + return (fn); + return (cp+1); +} + +void do_swapspec(f, name) + FILE *f; + register char *name; +{ + + if (!eq(name, "generic")) + fprintf(f, "swap%s.o: swap%s.c\n", name, name); + else + fprintf(f, "swapgeneric.o: $A/%s/swapgeneric.c\n", + machinename); + fprintf(f, "\t${NORMAL_C}\n\n"); +} + +struct file_list * +do_systemspec(f, fl, first) + FILE *f; + register struct file_list *fl; + int first; +{ + + fprintf(f, "%s.elf: ${SYSTEM_DEP} swap%s.o", fl->f_needs, fl->f_fn); + // Don't use newvers target. + // A preferred way is to run newvers.sh from SYSTEM_LD_HEAD macro. + //if (first) + // fprintf(f, " newvers"); + 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 = fl->f_next) + if (fl->f_type != SWAPSPEC) + break; + return (fl); +} + +char * +raise(str) + register char *str; +{ + register char *cp = str; + + while (*str) { + if (islower(*str)) + *str = toupper(*str); + str++; + } + return (cp); +} diff --git a/tools/kconfig/mkswapconf.c b/tools/kconfig/mkswapconf.c new file mode 100644 index 0000000..e680528 --- /dev/null +++ b/tools/kconfig/mkswapconf.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 1980, 1993 + * 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. + */ + +/* + * Build a swap configuration file. + */ +#include "config.h" + +#include +#include + +void 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")) { + fl = fl->f_next; + return (fl->f_next); + } + (void) sprintf(swapname, "swap%s.c", fl->f_fn); + fp = fopen(swapname, "w"); + if (fp == 0) { + perror(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(swapname); + fclose(fp); + return (swap); + } + fprintf(fp, "dev_t\trootdev = makedev(%d, %d);\t/* %s */\n", + major(fl->f_rootdev), minor(fl->f_rootdev), + devtoname(fl->f_rootdev)); + fprintf(fp, "dev_t\tdumpdev = makedev(%d, %d);\t/* %s */\n", + major(fl->f_dumpdev), minor(fl->f_dumpdev), + devtoname(fl->f_dumpdev)); + fprintf(fp, "\n"); + fprintf(fp, "struct\tswdevt swdevt[] = {\n"); + do { + dev = swap->f_swapdev; + fprintf(fp, "\t{ makedev(%d, %d), %d, %d },\t/* %s */\n", + major(dev), minor(dev), swap->f_swapflag, + 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"); + fclose(fp); + return (swap); +} + +static int devtablenotread = 1; + +static struct devdescription { + char *dev_name; + int dev_major; + struct devdescription *dev_next; +} *devtable; + +void initdevtable() +{ + char buf[BUFSIZ]; + int maj; + register struct devdescription **dp = &devtable; + FILE *fp; + + (void) sprintf(buf, "../devices.kconf"); + fp = fopen(buf, "r"); + if (fp == NULL) { + fprintf(stderr, "config: can't open %s\n", buf); + exit(1); + } + while (fscanf(fp, "%s\t%d\n", buf, &maj) == 2) { + *dp = (struct devdescription *)malloc(sizeof (**dp)); + (*dp)->dev_name = strdup(buf); + (*dp)->dev_major = maj; + dp = &(*dp)->dev_next; + } + *dp = 0; + fclose(fp); + devtablenotread = 0; +} + +/* + * 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) + char *name; + int defunit; +{ + char *cp, partition; + int unit; + register struct devdescription *dp; + + cp = name; + if (cp == 0) { + fprintf(stderr, "config: internal error, nametodev\n"); + exit(1); + } + while (*cp && !isdigit(*cp)) + cp++; + unit = *cp ? atoi(cp) : defunit; + if (unit < 0 || unit > 31) { + fprintf(stderr, + "config: %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 : '`'; + if (partition < '`' || partition > 'd') { + fprintf(stderr, + "config: %c: invalid device specification, bad partition\n", *cp); + partition = 'a'; /* 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: %s: unknown device\n", name); + return (NODEV); + } + return (makedev(dp->dev_major, (unit << 3) + (partition - '`'))); +} + +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; + + if (minor(dev) == 0) + sprintf(buf, "%s%d", dp->dev_name, minor(dev) >> 3); + else + sprintf(buf, "%s%d%c", dp->dev_name, minor(dev) >> 3, + (minor(dev) & 07) + 'a' - 1); + return strdup(buf); +}