diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
commit | 1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch) | |
tree | 4495d23e7b54ab5700e3839081e797c1eafe0db9 /setup | |
download | oss4-1058def8e7827e56ce4a70afb4aeacb5dc44148f.tar.gz |
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'setup')
147 files changed, 21196 insertions, 0 deletions
diff --git a/setup/.nomake b/setup/.nomake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/setup/.nomake diff --git a/setup/BeOS/build.sh b/setup/BeOS/build.sh new file mode 100644 index 0000000..045a599 --- /dev/null +++ b/setup/BeOS/build.sh @@ -0,0 +1,230 @@ +#!/bin/sh + +. ./.directories + +#BEOS_SYSTEM=beos/system +# to install as user addons +BEOS_SYSTEM=home/config + +DRVPREFIX=oss_ + +rm -rf prototype + +mkdir prototype +#mkdir prototype/etc +#echo "OSSLIBDIR=$OSSLIBDIR" > prototype/etc/oss.conf + +TXT2MAN=$SRCDIR/setup/txt2man + +if gawk '' 2>/dev/null +then + # No gawk installed. Use the simple txt2man program instead of + # the fully featured shell script which depends on gawk. + + rm -f txt2man + + cc -o txt2man $SRCDIR/setup/txt2man.c + + if test -f txt2man + then + TXT2MAN=./txt2man + fi +fi + +mkdir -p prototype/$BEOS_SYSTEM/add-ons/media +mkdir -p prototype/$BEOS_SYSTEM/add-ons/kernel/media +#hack for now +#mkdir -p prototype/$BEOS_SYSTEM/add-ons/kernel/media/oss +mkdir -p prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/bin +mkdir -p prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/dev/audio/multi +mkdir -p prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/dev/audio/oss +#hack for now +mkdir -p prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/dev/oss +ln -s ../../bin/${DRVPREFIX}loader prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/dev/oss/ +ln -s ../bin/${DRVPREFIX}loader prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/dev/ +#hack: install bins for now +mkdir -p prototype/home/config/bin +mkdir -p prototype/home/config/settings/kernel/drivers +mkdir -p prototype/home/Desktop + +#cp $SRCDIR/include/soundcard.h prototype/usr/include/sys + +#cp .version prototype/$OSSLIBDIR/version.dat + +#cp -R $SRCDIR/include/* prototype/$OSSLIBDIR/include/sys/ +#cp $SRCDIR/kernel/framework/include/midiparser.h prototype/$OSSLIBDIR/include/ + +(cd target/bin; rm -f ossrecord; ln -s ossplay ossrecord) +cp -f target/bin/* prototype/home/config/bin +cp -f target/sbin/* prototype/home/config/bin + +#cp -R $SRCDIR/oss/* prototype/$OSSLIBDIR + +# generate driver_settings file from the .params on stdin. +function gensettings () { + awk 'BEGIN { print "# Open Sound System configuration file" ; print "" } +/^int/ { split($2, option, "[=;]") } +/^ \*\// { print "#" option[1] " " option[2] ; print "" } +/^ \* / { print "# " substr($0, 4) }' +} + + +# set version info and mime type on a binary +function setvermime () { + local longver="`cat .version`" + local shortver="${longver%% *}" + local appver="${shortver:0:1} ${shortver:2:1} 0 b ${shortver##*[a-z]}" + #local lic="`cat .license`" + local copyright="`echo -n -e '\302\251'` 2007 4Front" + setversion "$1" -app $appver -short $shortver -long "$longver $copyright" + mimeset -f "$1" +} + +#ld -r -o prototype/$OSSLIBDIR/modules/osscore/Driver.o target/objects/*.o $SRCDIR/setup/SCO_SV/*.o $FPSUPPORT + +#core=prototype/$BEOS_SYSTEM/add-ons/kernel/media/oss/${DRVPREFIX}core +#must match internal module name... +core=prototype/$BEOS_SYSTEM/add-ons/kernel/media/oss +#gcc -o $drv target/objects/*.o -nostdlib /boot/develop/lib/x86/_KERNEL_ || exit 1 + +# no midi yet +rm target/modules/oss_midiloop.o + +# try to build all in a single bin for now... +# driver_beos.o shouldn' be in, oh well... +# R5 has symbols like __ucmpdi2 but not Haiku, so use libgcc +gcc -o $core target/objects/*.o target/modules/*.o -nostdlib -lgcc /boot/develop/lib/x86/_KERNEL_ || exit 1 +setvermime $core + +# except the loader driver... +# using the same bin works in BeOS but not in Haiku. +drv=prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/bin/${DRVPREFIX}loader +gcc -o $drv target/objects/driver_beos.o -nostdlib /boot/develop/lib/x86/_KERNEL_ || exit 1 +setvermime $drv + +rm -f devlist.txt + +# generate driver settings +settingspath=prototype/home/config/settings/kernel/drivers +gensettings < kernel/framework/ac97/.params > $settingspath/oss_core +gensettings < kernel/drv/osscore/.params >> $settingspath/oss_core +for n in target/modules/*.o +do + N=`basename $n .o` + test -e kernel/drv/$N/.params && gensettings < kernel/drv/$N/.params > $settingspath/$N + echo Check devices for $N + grep "^$N[ ]" ./devices.list >> devlist.txt +done + +#echo "Copying media node addon, make sure it's up to date! (cd lib/opensound.media_addon && make)" +#cp ../oss-*-gpl/lib/opensound.media_addon/obj.x86/opensound.media_addon prototype/$BEOS_SYSTEM/add-ons/media/ +#copyattr -d ../oss-*-gpl/lib/opensound.media_addon/OpenSound_README.txt prototype/home/Desktop/ +echo "make sure the opensound media addon is installed and up to date!" +echo "(cd lib/opensound.media_addon && make)" +echo "The addon is distributed as part of Haiku (www.haiku-os.org) source" + +#grep '^int' $SRCDIR/kernel/framework/osscore/options.c > prototype/$OSSLIBDIR/modules/osscore/Space.c + +#sed 's/.* //' < devlist.txt|sort|uniq >$SRCDIR/devlists/OSR6 +if test -d kernel/nonfree +then + cp devlist.txt $SRCDIR/devlists/BeOS +fi + +exit 0 +########## + +for n in target/modules/*.o +do + N=`basename $n .o` + #mkdir prototype/$OSSLIBDIR/modules/$N + #cp target/build/$N/* prototype/$OSSLIBDIR/modules/$N + #ld -r -o prototype/$OSSLIBDIR/modules/$N/Driver.o $n + + #drv=prototype/$BEOS_SYSTEM/add-ons/kernel/drivers/bin/${DRVPREFIX}$N + #gcc -o $drv $n -nostdlib /boot/develop/lib/x86/_KERNEL_ || exit 1 + #longver="`cat .version`" + #shortver="${longver%% *}" + #appver="${shortver:0:1} ${shortver:0:1} 0 b ${shortver##*[a-z]}" + #lic="`cat .license`" + #copyright="`echo -n -e '\302\251'` 2007 4Front" + #setversion $drv -app $appver -short $shortver -long "$longver $copyright $lic" + #mimeset -f $drv + +# Now copy the man pages +# if test -f $SRCDIR/kernel/drv/$N/$N.man +# then +# sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf/:g" < $SRCDIR/kernel/drv/$N/$N.man > /tmp/ossman.tmp +# $TXT2MAN -t "$N" -v "Devices" -s 7d /tmp/ossman.tmp > prototype/usr/man/man7/$N.7 +# fi + +# if test -f $SRCDIR/kernel/nonfree/drv/$N/$N.man +# then +# sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf/:g" < $SRCDIR/kernel/nonfree/drv/$N/$N.man > /tmp/ossman.tmp +# $TXT2MAN -t "$N" -v "Devices" -s 7d /tmp/ossman.tmp > prototype/usr/man/man7/$N.7 +# fi + +done + +#cp devlist.txt prototype/$OSSLIBDIR/etc/devices.list + + + + + + + + + + + + + + +# Generate Man pages for commands +#for i in target/bin/* +#do +#CMD=`basename $i` +#$TXT2MAN -t "$CMD" -v "User Commands" -s 1 cmd/$CMD/$CMD.man > prototype/usr/man/man1/$CMD.1 +#echo done $CMD +#done + +#for i in target/sbin/* +#do +# CMD=`basename $i` +# if test -f cmd/$CMD/$CMD.man +# then +# $TXT2MAN -t "$CMD" -v "System Administration Commands" -s 8 cmd/$CMD/$CMD.man > prototype/usr/man/man8/$CMD.8 +# echo done $CMD +# fi +#done + +#rm -f prototype/usr/man/man8/ossdetect.8 +#$TXT2MAN -t "ossdetect" -v "User Commands" -s 8 os_cmd/SCO_SV/ossdetect/ossdetect.man > prototype/usr/man/man8/ossdetect.8 +#echo done ossdetect + +## Licensing stuff +#if test -f $SRCDIR/4front-private/osslic.c +#then +# cc -o prototype/usr/sbin/osslic -Isetup -Ikernel/nonfree/include -Ikernel/framework/include -Iinclude -Ikernel/OS/SCO_SV -I$SRCDIR $SRCDIR/4front-private/osslic.c +# strip prototype/usr/sbin/osslic +# +# prototype/usr/sbin/osslic -q -u -3prototype/$OSSLIBDIR/modules/osscore/Driver.o +# +#fi + +#if test -f 4front-private/ossupdate.c +#then +# # ossupdate +# cc -I. 4front-private/ossupdate.c -s -o prototype/usr/sbin/ossupdate -lsocket -lbind +#fi + +sh $SRCDIR/setup/build_common.sh $SRCDIR $OSSLIBDIR + +#chmod 700 prototype/usr/sbin/* +#chmod 755 prototype/usr/bin/* + +#cp setup/SCO_SV/S89oss prototype/$OSSLIBDIR/etc +#chmod 744 prototype/$OSSLIBDIR/etc/S89oss + +exit 0 diff --git a/setup/BeOS/make.local b/setup/BeOS/make.local new file mode 100644 index 0000000..ca403e9 --- /dev/null +++ b/setup/BeOS/make.local @@ -0,0 +1,10 @@ +build: kernel/framework/include/buildid.h all + sh build.sh + +copy: build + cp -R prototype/* /boot/ + +package: build + sh setup/BeOS/mkpkg.sh + +install: copy diff --git a/setup/BeOS/mkpkg.sh b/setup/BeOS/mkpkg.sh new file mode 100644 index 0000000..bd4c74c --- /dev/null +++ b/setup/BeOS/mkpkg.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +VERSION=`sh showversion.sh` +RELEASE=`cat buildid.dat` +OSSNAME=oss-beos +PKGNAME=$OSSNAME-$VERSION-$RELEASE + +echo building $PKGNAME.zip +(cd prototype; zip -ry9 ../$PKGNAME.zip *) + +#if test -f 4front-private/export_package.sh +#then +# sh 4front-private/export_package.sh $PKGNAME.zip . `sh showversion.sh` /tmp `uname -i`-26 +#fi + +exit 0 diff --git a/setup/FreeBSD/build.sh b/setup/FreeBSD/build.sh new file mode 100644 index 0000000..595d77e --- /dev/null +++ b/setup/FreeBSD/build.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +. ./.directories + +if which gawk >/dev/null +then + TXT2MAN=$SRCDIR/setup/txt2man +else + echo "No gawk found. Using lesser replacement" >&2 + cc -o txt2man origdir/setup/txt2man.c + TXT2MAN=./txt2man +fi + +rm -rf prototype + +mkdir prototype +mkdir prototype/etc +mkdir prototype/etc/rc.d +mkdir prototype/usr +mkdir prototype/usr/bin +mkdir prototype/usr/sbin +mkdir -p prototype/$OSSLIBDIR +mkdir prototype/$OSSLIBDIR/etc +mkdir prototype/$OSSLIBDIR/lib +mkdir prototype/$OSSLIBDIR/include +mkdir prototype/$OSSLIBDIR/include/internals +mkdir prototype/$OSSLIBDIR/include/sys +mkdir prototype/$OSSLIBDIR/modules +mkdir prototype/$OSSLIBDIR/objects +mkdir prototype/usr/share +mkdir prototype/usr/share/man +mkdir prototype/usr/share/man/man1 +mkdir prototype/usr/share/man/man7 +mkdir prototype/usr/share/man/man8 +mkdir prototype/$OSSLIBDIR/conf + +echo "OSSLIBDIR=$OSSLIBDIR" > prototype/etc/oss.conf + +# Regenerating the config file templates +rm -f /tmp/confgen +if ! cc -o /tmp/confgen ./setup/FreeBSD/confgen.c +then + echo Building confgen failed + exit 1 +fi + +if ! /tmp/confgen prototype/$OSSLIBDIR/conf $OSSLIBDIR/conf kernel/drv/* kernel/nonfree/drv/* +then + echo Running confgen failed + exit 1 +fi + +rm -f /tmp/confgen + +cp -r $SRCDIR/setup/FreeBSD/oss/* prototype/$OSSLIBDIR/ +cp $SRCDIR/kernel/OS/FreeBSD/wrapper/bsddefs.h prototype/$OSSLIBDIR/build/ + +cp $SRCDIR/include/*.h prototype/$OSSLIBDIR/include/sys/ +cp $SRCDIR/lib/libOSSlib/midiparser.h prototype/$OSSLIBDIR/include/ +cp kernel/framework/include/timestamp.h kernel/framework/include/local_config.h $SRCDIR/kernel/framework/include/*_core.h $SRCDIR/kernel/framework/include/ossddk/*.h prototype/$OSSLIBDIR/include/internals +cp kernel/framework/include/ossddk/oss_limits.h prototype/$OSSLIBDIR/include/internals + +ld -r -o prototype/$OSSLIBDIR/build/osscore.lib target/objects/*.o + +rm -f devlist.txt + +for n in target/modules/*.o +do + N=`basename $n .o` +echo Check devices for $N + grep "^$N[ ]" ./devices.list >> devlist.txt +done + +(cd target/bin; rm -f ossrecord; ln -s ossplay ossrecord) +cp target/modules/*.o prototype/$OSSLIBDIR/objects +cp target/build/*.c prototype/$OSSLIBDIR/build/ +cp target/bin/* prototype/usr/bin/ +cp target/sbin/* prototype/usr/sbin/ +cp $SRCDIR/setup/FreeBSD/sbin/* prototype/usr/sbin/ +cp $SRCDIR/setup/FreeBSD/etc/rc.d/oss prototype/etc/rc.d +cp lib/libOSSlib/libOSSlib.so prototype/$OSSLIBDIR/lib + +cp devlist.txt prototype/$OSSLIBDIR/etc/devices.list + +if test -d kernel/nonfree +then + rm -f $SRCDIR/devlists/FreeBSD + cp devlist.txt $SRCDIR/devlists/FreeBSD +fi + +# Generate Man pages for commands +for i in target/bin/* +do +CMD=`basename $i` +$TXT2MAN -t "$CMD" -v "User Commands" -s 1 cmd/$CMD/$CMD.man | gzip -9 > prototype/usr/share/man/man1/$CMD.1.gz +echo done $CMD +done + +for i in target/sbin/* +do + CMD=`basename $i` + if test -f cmd/$CMD/$CMD.man + then + $TXT2MAN -t "$CMD" -v "System Administration Commands" -s 8 cmd/$CMD/$CMD.man | gzip -9 > prototype/usr/share/man/man8/$CMD.8.gz + echo done $CMD + fi +done + +for i in $SRCDIR/misc/man1m/*.man +do + N=`basename $i .man` + $TXT2MAN -t "$CMD" -v "OSS System Administration Commands" -s 1 $i | gzip -9 > prototype/usr/share/man/man1/$N.1.gz +done + +$TXT2MAN -t "ossdetect" -v "User Commands" -s 8 os_cmd/FreeBSD/ossdetect/ossdetect.man | gzip -9 > prototype/usr/share/man/man8/ossdetect.8.gz +echo done ossdetect + +for n in target/modules/*.o +do + N=`basename $n .o` + ld -r -o prototype/$OSSLIBDIR/$MODULES/$N.o $n + echo Check devices for $N + grep "^$N[ ]" ./devices.list >> devlist.txt + + rm -f /tmp/ossman.txt + + if test -f $SRCDIR/kernel/drv/$N/$N.man + then + sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/drv/$N/$N.man > /tmp/ossman.txt + $TXT2MAN -t "$CMD" -v "OSS Devices" -s 7 /tmp/ossman.txt|gzip -9 > prototype/usr/share/man/man7/$N.7.gz + else + if test -f $SRCDIR/kernel/nonfree/drv/$N/$N.man + then + sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/nonfree/drv/$N/$N.man > /tmp/ossman.txt + $TXT2MAN -t "$CMD" -v "OSS Devices" -s 7 $SRCDIR/kernel/nonfree/drv/$N/$N.man|gzip -9 > prototype/usr/share/man/man7/$N.7.gz + fi + fi +done + +sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/drv/osscore/osscore.man > /tmp/ossman.txt +$TXT2MAN -t "osscore" -v "OSS Devices" -s 7 /tmp/ossman.txt|gzip -9 > prototype/usr/share/man/man7/osscore.7.gz +rm -f /tmp/ossman.txt + +cp .version prototype/$OSSLIBDIR/version.dat + +# Licensing stuff +if test -f $SRCDIR/4front-private/osslic.c +then + cc -o prototype/usr/sbin/osslic -Isetup -Ikernel/nonfree/include -Ikernel/framework/include -Iinclude -Ikernel/OS/FreeBSD -I$SRCDIR $SRCDIR/4front-private/osslic.c + strip prototype/usr/sbin/osslic + + BITS=3 # Default to 32 bit ELF format + if test "`uname -m` " = "amd64 " + then + BITS=6 # Use 64 bit ELF format + fi + + prototype/usr/sbin/osslic -q -u -$BITS./prototype/$OSSLIBDIR/build/osscore.lib + +fi + +if test -f 4front-private/ossupdate.c +then + #ossupdate + cc -I. 4front-private/ossupdate.c -s -o prototype/usr/sbin/ossupdate +fi + +sh $SRCDIR/setup/build_common.sh $SRCDIR $OSSLIBDIR + +chmod 700 prototype/usr/sbin/* +chmod 755 prototype/usr/bin/* +chmod 700 prototype/$OSSLIBDIR + +(cd prototype;ls usr/sbin/* usr/bin/* etc/* usr/share/man/man*/*) > prototype/$OSSLIBDIR/sysfiles.list + +exit 0 diff --git a/setup/FreeBSD/confgen.c b/setup/FreeBSD/confgen.c new file mode 100644 index 0000000..d94157b --- /dev/null +++ b/setup/FreeBSD/confgen.c @@ -0,0 +1,188 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <libgen.h> +#include <sys/stat.h> + +char *targetdir = ""; +char *confpath = ""; + +static int +copy_parms (FILE * f, FILE * conf) +{ + char line[1024], *s; + char var[256] = "", comment[64 * 1024] = ""; + int i; + int ok = 0; + + while (fgets (line, sizeof (line), f) != NULL) + { + for (i = 0; i < strlen (line); i++) + if (line[i] == '\n') + line[i] = 0; + + s = line; + + while (*s == ' ' || *s == '\t') + s++; + if (strncmp (s, "int ", 4) == 0) + { + if (*var != 0) + { + fprintf (conf, "%s\n", comment); + if (*var != 0) + fprintf (conf, "#%s\n#\n", var); + *var = 0; + *comment = 0; + } + s += 4; + + for (i = 0; i < strlen (line); i++) + if (line[i] == ';') + line[i] = 0; + ok = 1; + strcpy (var, s); + continue; + } + + + s = line; + + while (*s == ' ' || *s == '\t' || *s == '/' || *s == '*') + s++; + + if (*comment != 0) + strcat (comment, "\n"); + strcat (comment, "# "); + strcat (comment, s); + } + + if (*var != 0) + { + fprintf (conf, "%s\n", comment); + fprintf (conf, "#%s\n", var); + } + + return ok; +} + +static void +scan_dir (const char *srcdir, const char *modnam) +{ + char confname[256], tmp[256], line[1024]; + char module[256], *p; + FILE *conf; + FILE *f; + int i; + struct stat st; + + int check_platform = 0; + int platform_ok = 0; + int ok = 0; + + strcpy (module, modnam); + p = module; + while (*p) + { + if (*p == '.') + *p = 0; + else + p++; + } + + if (stat (srcdir, &st) == -1) + return; + + if (!S_ISDIR (st.st_mode)) /* Not a directory? */ + return; + + sprintf (tmp, "%s/.nomake", srcdir); + if (stat (tmp, &st) != -1) /* File exists */ + return; /* Skip this one */ + + sprintf (tmp, "%s/.config", srcdir); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + char *s; + for (i = 0; i < strlen (line); i++) + if (line[i] == '\n') + line[i] = 0; + + s = line; + while (*s && *s != '=') + s++; + if (*s == '=') + *s++ = 0; + + if (strcmp (line, "OS") == 0 || strcmp (line, "targetos") == 0) + { + check_platform = 1; + if (strcmp (s, "Linux") == 0) + platform_ok = 1; + continue; + } + } + fclose (f); + } + + if (check_platform && !platform_ok && strcmp (modnam, "osscore")) + { + return; + } +#if 0 + /* copy the man pages */ + sprintf (syscmd, "sed 's:CONFIGFILEPATH:%s:g' < %s/%s.man > /tmp/ossman.man", + confpath, srcdir, module); + printf ("%s\n", syscmd); + unlink ("/tmp/ossman.man"); + system (syscmd); + + sprintf (syscmd, + "./origdir/setup/txt2man -t \"%s\" -v \"Devices\" -s 7 /tmp/ossman.man > prototype/usr/man/man7/%s.7", + module, module); + printf ("%s\n", syscmd); + system (syscmd); +#endif + + sprintf (confname, "%s/%s.conf", targetdir, module); + sprintf (tmp, "%s/.params", srcdir); + if ((f = fopen (tmp, "r")) != NULL) + { + if ((conf = fopen (confname, "w")) == NULL) + { + perror (confname); + exit (-1); + } + fprintf (conf, "# Open Sound System configuration file\n"); + fprintf (conf, + "# Remove the '#' in front of the option(s) you like to set.\n#\n"); + ok = copy_parms (f, conf); + fclose (f); +// fprintf(conf, "#\n"); + fclose (conf); + if (!ok) + unlink (confname); + } +} + +int +main (int argc, char *argv[]) +{ + int i; + + if (argc < 3) + exit (-1); + + targetdir = argv[1]; + confpath = argv[2]; + + for (i = 3; i < argc; i++) + { + scan_dir (argv[i], basename (argv[i])); + } + + exit (0); +} diff --git a/setup/FreeBSD/etc/rc.d/oss b/setup/FreeBSD/etc/rc.d/oss new file mode 100644 index 0000000..6b532e5 --- /dev/null +++ b/setup/FreeBSD/etc/rc.d/oss @@ -0,0 +1,58 @@ +#!/bin/sh - +# +# Copyright (c) 2006, 4Front Technologies. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +# +# + +# PROVIDE: oss +# REQUIRE: cleanvar +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="oss" +stop_cmd="oss_stop" +start_cmd="oss_start" + +# +# Start Open Sound System +# +oss_start() +{ + echo "Starting Open Sound System" + /usr/sbin/soundon +} + +# +# Stop Open Sound System +# +oss_stop() +{ + echo "Stopping Open Sound System" + /usr/sbin/soundoff +} + +load_rc_config $name +run_rc_command "$1" diff --git a/setup/FreeBSD/make.local b/setup/FreeBSD/make.local new file mode 100644 index 0000000..2cd68f8 --- /dev/null +++ b/setup/FreeBSD/make.local @@ -0,0 +1,11 @@ +build: kernel/framework/include/buildid.h all + sh build.sh + +copy: build + cp -R prototype/* / + +package: build + sh setup/FreeBSD/mkpkg.sh + +install: copy + cd ${OSSLIBDIR}/build && sh install.sh diff --git a/setup/FreeBSD/mkpkg.sh b/setup/FreeBSD/mkpkg.sh new file mode 100644 index 0000000..d7908bf --- /dev/null +++ b/setup/FreeBSD/mkpkg.sh @@ -0,0 +1,18 @@ +#!/bin/sh +VERSION=`sh showversion.sh` +BUILDID=`cat buildid.dat` +TOPDIR=`pwd` +SETUPDIR=$TOPDIR/setup/FreeBSD +PROTODIR=$TOPDIR/prototype +KERNELVERS=`uname -m` +BSDVER=`uname -r | cut -s -d'.' -f1` +PKGNAME=oss-freebsd$BSDVER-$VERSION-$BUILDID-$KERNELVERS + +(cd $PROTODIR; find . -type f -print > $SETUPDIR/pkg-plist) + +(cd /; pkg_create -c $SETUPDIR/pkg-comment -d $SETUPDIR/pkg-descr -I $SETUPDIR/pkg-postinstall -k $SETUPDIR/pkg-preremove -K $SETUPDIR/pkg-postremove -f $SETUPDIR/pkg-plist -p / -S $PROTODIR -v $TOPDIR/$PKGNAME.tbz) + +if test -f 4front-private/export_package.sh +then + sh 4front-private/export_package.sh $PKGNAME.tbz . `sh showversion.sh` /tmp `uname -m` +fi diff --git a/setup/FreeBSD/oss/build/Makefile.osscore b/setup/FreeBSD/oss/build/Makefile.osscore new file mode 100644 index 0000000..e1f428b --- /dev/null +++ b/setup/FreeBSD/oss/build/Makefile.osscore @@ -0,0 +1,7 @@ +SRCS=osscore.c +KMOD=osscore +OBJS += osscore_mainline.o +SRCS += device_if.h bus_if.h pci_if.h + +.include <bsd.kmod.mk> + diff --git a/setup/FreeBSD/oss/build/Makefile.tmpl b/setup/FreeBSD/oss/build/Makefile.tmpl new file mode 100644 index 0000000..1653841 --- /dev/null +++ b/setup/FreeBSD/oss/build/Makefile.tmpl @@ -0,0 +1,8 @@ +SRCS=MODNAME.c +KMOD=MODNAME +OBJS += MODNAME_mainline.o +SRCS += device_if.h bus_if.h pci_if.h +CFLAGS += -I../include/internals + +.include <bsd.kmod.mk> + diff --git a/setup/FreeBSD/oss/build/bsdpci.inc b/setup/FreeBSD/oss/build/bsdpci.inc new file mode 100644 index 0000000..5cb0b55 --- /dev/null +++ b/setup/FreeBSD/oss/build/bsdpci.inc @@ -0,0 +1,153 @@ +/* + * Purpose: Wrapper functions for PCI drivers under FreeBSD + */ +/* + * Copyright (C) 4Front Technologies 2005-2007. Released under BSD license. + */ +#include <dev/pci/pcivar.h> /* For pci_get macros! */ +#include <dev/pci/pcireg.h> + +/* PCI Support Functions */ + +static oss_device_t *device_list[16]; +static device_t bsd_devices[16]; +static int ndevs = 0; + +/* + * Compare the device ID of this device against the IDs that this driver + * supports. If there is a match, set the description and return success. + */ +static int +osspci_probe (device_t dev) +{ +#ifdef DEVTYPE_PCI + int i, ok = 0; + int vendor, device, class; + oss_device_t *osdev; + + for (i = 0; i < ndevs; i++) + if (dev == bsd_devices[i]) /* Already detected */ + { + return ENXIO; + } + + if (ndevs >= 16) + { + printf (DRIVER_NICK ": Too many instances\n"); + return ENXIO; + } + + vendor = pci_get_vendor (dev); + device = pci_get_device (dev); + class = pci_get_class (dev); +// printf("PCI dev %08lx c=%x, v=%04x, d=%04x\n", (unsigned long)dev, class, vendor, device); + + if (class != 4) /* Not a multimedia device */ + return ENXIO; + + for (i = 0; id_table[i].vendor != 0; i++) + if (vendor == id_table[i].vendor && device == id_table[i].device) /* Match */ + { + ok = 1; + break; + } + + if (!ok) + { + return (ENXIO); + } + + if ((osdev = + osdev_create (dev, DRIVER_TYPE, ndevs, DRIVER_NICK, NULL)) == NULL) + { + return ENOMEM; + } + if (!DRIVER_ATTACH (osdev)) + return EIO; + + bsd_devices[ndevs] = dev; + device_list[ndevs++] = osdev; +#endif + return (BUS_PROBE_DEFAULT); +} + +/* Attach function is only called if the probe is successful */ + +static int +osspci_attach (device_t dev) +{ + return 0; +} + +/* Detach device. */ + +static int +osspci_detach (device_t dev) +{ + oss_device_t *osdev; + int i; + + for (i = 0; i < ndevs; i++) + { + osdev = device_list[i]; + if (osdev->dip == dev) + { + if (device_get_state(dev) == DS_BUSY) + device_unbusy(dev); + if (!DRIVER_DETACH (osdev)) + { + printf (DRIVER_NICK ": Unloading busy device\n"); + return EBUSY; + } + osdev_delete (osdev); + } + } + + return (0); +} + +/* Called during system shutdown after sync. */ + +static int +osspci_shutdown (device_t dev) +{ + + printf ("Mypci shutdown!\n"); + return (0); +} + +/* + * Device suspend routine. + */ +static int +osspci_suspend (device_t dev) +{ + + printf ("Mypci suspend!\n"); + return (0); +} + +/* + * Device resume routine. + */ +static int +osspci_resume (device_t dev) +{ + + printf ("Mypci resume!\n"); + return (0); +} + +static device_method_t osspci_methods[] = { + /* Device interface */ + DEVMETHOD (device_probe, osspci_probe), + DEVMETHOD (device_attach, osspci_attach), + DEVMETHOD (device_detach, osspci_detach), + DEVMETHOD (device_shutdown, osspci_shutdown), + DEVMETHOD (device_suspend, osspci_suspend), + DEVMETHOD (device_resume, osspci_resume), + + {0, 0} +}; + +static devclass_t osspci_devclass; diff --git a/setup/FreeBSD/oss/build/bsdvirtual.inc b/setup/FreeBSD/oss/build/bsdvirtual.inc new file mode 100644 index 0000000..cb5190e --- /dev/null +++ b/setup/FreeBSD/oss/build/bsdvirtual.inc @@ -0,0 +1,83 @@ +/* + * Purpose: Wrapper functions for virtual drivers under FreeBSD + */ +/* + * Copyright (C) 4Front Technologies 2005-2007. Released under BSD license. + */ +static int ndevs = 0; +oss_device_t *device_list[16]; + +static int +module_attach (void) +{ + oss_device_t *osdev; + + if ((osdev = + osdev_create (NULL, DRIVER_TYPE, ndevs, DRIVER_NICK, NULL)) == NULL) + { + return ENOMEM; + } + if (!DRIVER_ATTACH (osdev)) + return EIO; + device_list[ndevs++] = osdev; + + return 0; +} + +static int +module_detach (void) +{ + oss_device_t *osdev; + int i; + + for (i = 0; i < ndevs; i++) + { + osdev = device_list[i]; + + if (osdev->dip != NULL && device_get_state(osdev->dip) == DS_BUSY) + device_unbusy(osdev->dip); + if (!DRIVER_DETACH (osdev)) + { + printf (DRIVER_NICK ": Unloading busy device\n"); + return EBUSY; + } + osdev_delete (osdev); + } + + return 0; +} + +/* + * Load handler that deals with the loading and unloading of a KLD. + */ + +static int +ossmodule_loader (struct module *m, int what, void *arg) +{ + int err = 0; + + switch (what) + { + case MOD_LOAD: /* kldload */ + return module_attach (); + break; + case MOD_UNLOAD: + return module_detach (); + break; + default: + err = EINVAL; + break; + } + return (err); +} + +/* Declare this module to the rest of the kernel */ + +static moduledata_t ossmodule_mod = { + "ossmodule", + ossmodule_loader, + NULL +}; + +DECLARE_MODULE (ossmodule, ossmodule_mod, SI_SUB_KLD, SI_ORDER_ANY); +MODULE_VERSION (ossmodule, 4); diff --git a/setup/FreeBSD/oss/build/devid.h b/setup/FreeBSD/oss/build/devid.h new file mode 100644 index 0000000..8d6a5c7 --- /dev/null +++ b/setup/FreeBSD/oss/build/devid.h @@ -0,0 +1,5 @@ + +typedef struct +{ + unsigned short vendor, device; +} device_id_t; diff --git a/setup/FreeBSD/oss/build/install.sh b/setup/FreeBSD/oss/build/install.sh new file mode 100644 index 0000000..872d43f --- /dev/null +++ b/setup/FreeBSD/oss/build/install.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +rm -f osscore_mainline.o +ln -s osscore.lib osscore_mainline.o + +rm -f Makefile +ln -s Makefile.osscore Makefile + +echo Compiling module osscore + +if ! make > compile.list 2>&1 +then + echo Compiling osscore module failed + cat compile.list + exit 1 +fi + +if ! test -d ../modules +then + mkdir ../modules +fi + +if ! test -d ../logs +then + mkdir ../logs +fi + +mv osscore.ko ../modules/ +make clean > /dev/null 2>&1 + +for n in ../objects/*.o +do + N=`basename $n .o` + + rm -f $N"_mainline.o" + ln -s $n $N"_mainline.o" + + rm -f Makefile + sed "s/MODNAME/$N/g" < Makefile.tmpl > Makefile + + echo Compiling module $N + + if ! make > compile.list 2>&1 + then + echo Compiling module $N failed + cat compile.list + exit 2 + fi + + mv $N.ko* ../modules/ + make clean > /dev/null 2>&1 + rm -f Makefile +done + +if ! test -f $OSSLIBDIR/etc/installed_drivers +then + echo "-----------------------------" + /usr/sbin/ossdetect -v + echo "-----------------------------" + echo "" +fi + +if test ! -f $OSSLIBDIR/etc/userdefs +then + echo "autosave_mixer yes" > $OSSLIBDIR/etc/userdefs +fi + +exit 0 diff --git a/setup/FreeBSD/oss/build/module.inc b/setup/FreeBSD/oss/build/module.inc new file mode 100644 index 0000000..8ed73e9 --- /dev/null +++ b/setup/FreeBSD/oss/build/module.inc @@ -0,0 +1,89 @@ +/* + * Purpose: Generic OSS driver module interface for FreeBSD + * + * This file is included by the driver modules when they are compiled + * in the target system. In this way this code can be changed for non-srandard + * kernels. Compiling this file in the target file makes it also possible + * to distribute single OSS binary package that works under as many + * FreeBSD versions as possible. + */ +/* + * Copyright (C) 4Front Technologies 2005-2007. Released under BSD license. + */ + +#include <machine/stdarg.h> +#include <sys/param.h> /* defines used in kernel.h */ +#include <sys/module.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/kernel.h> /* types used in module initialization */ +#include <sys/conf.h> /* cdevsw struct */ +#include <sys/uio.h> /* uio struct */ +#include <sys/malloc.h> + +#include <sys/bus.h> /* structs, prototypes for pci bus stuff */ +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> + +#include <timestamp.h> +#include <oss_exports.h> +#include "bsddefs.h" + +void +cmn_err (int level, char *s, ...) +{ + char tmp[1024], *a[6]; + va_list ap; + int i, n = 0; + + va_start (ap, s); + + for (i = 0; i < strlen (s); i++) + if (s[i] == '%') + n++; + + for (i = 0; i < n && i < 6; i++) + a[i] = va_arg (ap, char *); + + for (i = n; i < 6; i++) + a[i] = NULL; + + strcpy (tmp, DRIVER_NICK ": "); + sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5], NULL, + NULL, NULL, NULL); + if (level == CE_PANIC) + panic (tmp); + printf ("%s", tmp); +#if 0 + /* This may cause a crash under SMP */ + if (sound_started) + store_msg (tmp); +#endif + + va_end (ap); +} + +extern int DRIVER_ATTACH (oss_device_t * osdev); +extern int DRIVER_DETACH (oss_device_t * osdev); + +#ifdef DEVTYPE_VMIX +#define TYPE_OK +#include "bsdvirtual.inc" +#endif + +#ifdef DEVTYPE_PCI +#define TYPE_OK +#include "bsdpci.inc" +#endif + +#ifdef DEVTYPE_VIRTUAL +#define TYPE_OK +#include "bsdvirtual.inc" +#endif + +#ifndef TYPE_OK +#error Unrecognized driver type +#endif + +MODULE_DEPEND (DRIVER_NAME, osscore, 4, 4, 4); diff --git a/setup/FreeBSD/oss/build/osscore.c b/setup/FreeBSD/oss/build/osscore.c new file mode 100644 index 0000000..5264118 --- /dev/null +++ b/setup/FreeBSD/oss/build/osscore.c @@ -0,0 +1,559 @@ +/* + * Purpose: OSS core functions that need to be compiled in the target system + * + * Some parts of the FreeBSD operating system interface of OSS are sensitive + * to changes in internal structures of FreeBSD. For this reason these + * files have to be compiled in the target system when OSS is installed. + * In this way the same OSS binary package can be used with several FreeBSD + * versions. + */ +#include <machine/stdarg.h> +#include <sys/param.h> /* defines used in kernel.h */ +#include <sys/module.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/kernel.h> /* types used in module initialization */ +#include <sys/conf.h> /* cdevsw struct */ +#include <sys/uio.h> /* uio struct */ +#include <sys/malloc.h> + +#include <sys/bus.h> /* structs, prototypes for pci bus stuff */ +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/param.h> /* defines used in kernel.h */ +#include <dev/pci/pcivar.h> /* For pci_get macros! */ +#include <dev/pci/pcireg.h> +#include <machine/intr_machdep.h> + +#include <vm/vm.h> +#include <vm/pmap.h> +#include <sys/proc.h> + +typedef struct _oss_device_t oss_device_t; +#include "bsddefs.h" + +/* The PCIBIOS_* defines must match oss_pci.h */ +#define PCIBIOS_SUCCESSFUL 0x00 +#define PCIBIOS_FAILED -1 + +extern int soundcard_attach (void); +extern int soundcard_detach (void); + +void * +memset (void *t, int val, int l) +{ + char *c = t; + while (l-- > 0) + *c++ = val; + + return t; +} + +void +cmn_err (int level, char *s, ...) +{ + char tmp[1024], *a[6]; + va_list ap; + int i, n = 0; + + va_start (ap, s); + + for (i = 0; i < strlen (s); i++) + if (s[i] == '%') + n++; + + for (i = 0; i < n && i < 6; i++) + a[i] = va_arg (ap, char *); + + for (i = n; i < 6; i++) + a[i] = NULL; + + strcpy (tmp, "osscore: "); + sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5], NULL, + NULL, NULL, NULL); + if (level == CE_PANIC) + panic (tmp); + printf ("%s", tmp); +#if 0 + /* This may cause a crash under SMP */ + if (sound_started) + store_msg (tmp); +#endif + + va_end (ap); +} + +void +oss_udelay (unsigned long t) +{ + DELAY (t); +} + +typedef struct +{ + int irq; + oss_device_t *osdev; + oss_tophalf_handler_t top; + oss_bottomhalf_handler_t bottom; + struct resource *irqres; + int irqid; + void *cookie; +} osscore_intr_t; + +#define MAX_INTRS 32 + +static osscore_intr_t intrs[MAX_INTRS] = { {0} }; +static int nintrs = 0; + +static void +ossintr (void *arg) +{ + osscore_intr_t *intr = arg; + int serviced = 0; + + if (intr->top) + serviced = intr->top (intr->osdev); + if (intr->bottom) + intr->bottom (intr->osdev); + oss_inc_intrcount (intr->osdev, serviced); +} + +int +oss_register_interrupts (oss_device_t * osdev, int intrnum, + oss_tophalf_handler_t top, + oss_bottomhalf_handler_t bottom) +{ + + osscore_intr_t *intr; + char name[32]; + + if (nintrs >= MAX_INTRS) + { + cmn_err (CE_CONT, + "oss_register_interrupts: Too many interrupt handlers\n"); + return -ENOMEM; + } + + intr = &intrs[nintrs]; + + intr->irq = 0; + intr->osdev = osdev; + intr->top = top; + intr->bottom = bottom; + + sprintf (name, "%s%d", osdev->nick, osdev->instance); + + intr->irqid = 0; + intr->irqres = bus_alloc_resource (osdev->dip, SYS_RES_IRQ, &(intr->irqid), + 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); + if (intr->irqres == NULL) + { + cmn_err (CE_CONT, + "oss_register_interrupts: bus_alloc_resource failed.\n"); + return -EIO; + } + + intr->irq = bus_setup_intr (osdev->dip, intr->irqres, + INTR_TYPE_AV | INTR_MPSAFE, +#if __FreeBSD_version >= 700031 + NULL, +#endif + ossintr, intr, &(intr->cookie)); + + nintrs++; + + return 0; +} + +void +oss_unregister_interrupts (oss_device_t * osdev) +{ + int i; + + for (i = 0; i < nintrs; i++) + if (intrs[i].osdev == osdev) + { + osscore_intr_t *intr; + + intr = &intrs[i]; + bus_teardown_intr (osdev->dip, intr->irqres, intr->cookie); + bus_release_resource (osdev->dip, SYS_RES_IRQ, intr->irqid, + intr->irqres); + } +} + +/* + * PCI config space access + */ +char * +oss_pci_read_devpath (dev_info_t * dip) +{ + return "Unknown PCI path"; // TODO +} + +int +pci_read_config_byte (oss_device_t * osdev, offset_t where, + unsigned char *val) +{ + *val = pci_read_config (osdev->dip, where, 1); + return PCIBIOS_SUCCESSFUL; +} + +int +pci_read_config_irq (oss_device_t * osdev, offset_t where, unsigned char *val) +{ + *val = pci_read_config (osdev->dip, where, 1); + return PCIBIOS_SUCCESSFUL; +} + +int +pci_read_config_word (oss_device_t * osdev, offset_t where, + unsigned short *val) +{ + *val = pci_read_config (osdev->dip, where, 2); + return PCIBIOS_SUCCESSFUL; +} + +int +pci_read_config_dword (oss_device_t * osdev, offset_t where, + unsigned int *val) +{ + *val = pci_read_config (osdev->dip, where, 4); + return PCIBIOS_SUCCESSFUL; +} + +int +pci_write_config_byte (oss_device_t * osdev, offset_t where, + unsigned char val) +{ + pci_write_config (osdev->dip, where, val, 1); + return PCIBIOS_FAILED; +} + +int +pci_write_config_word (oss_device_t * osdev, offset_t where, + unsigned short val) +{ + pci_write_config (osdev->dip, where, val, 2); + return PCIBIOS_FAILED; +} + +int +pci_write_config_dword (oss_device_t * osdev, offset_t where, + unsigned int val) +{ + pci_write_config (osdev->dip, where, val, 4); + return PCIBIOS_FAILED; +} + +void * +oss_contig_malloc (unsigned long buffsize, unsigned long memlimit, + oss_native_word * phaddr) +{ + char *tmpbuf; + *phaddr = 0; + + tmpbuf = + (char *) contigmalloc (buffsize, M_DEVBUF, M_WAITOK, 0ul, memlimit, + PAGE_SIZE, 0ul); + if (tmpbuf == NULL) + { + cmn_err (CE_CONT, "OSS: Unable to allocate %lu bytes for a DMA buffer\n", + buffsize); + cmn_err (CE_CONT, "run soundoff and run soundon again.\n"); + return NULL; + } + *phaddr = vtophys (tmpbuf); + return tmpbuf; +} + +void +oss_contig_free (void *p, unsigned long sz) +{ + if (p) + contigfree (p, sz, M_DEVBUF); +} + +/* + * Load handler that deals with the loading and unloading of a KLD. + */ + +static int +osscore_loader (struct module *m, int what, void *arg) +{ + int err = 0; + + switch (what) + { + case MOD_LOAD: /* kldload */ + return soundcard_attach (); + break; + case MOD_UNLOAD: + return soundcard_detach (); + break; + default: + err = EINVAL; + break; + } + return (err); +} + +/* Declare this module to the rest of the kernel */ + +static moduledata_t osscore_mod = { + "osscore", + osscore_loader, + NULL +}; + +#define _FP_SAVE(envbuf) asm ("fnsave %0":"=m" (*envbuf)); +#define _FP_RESTORE(envbuf) asm ("frstor %0":"=m" (*envbuf)); + +/* SSE/SSE2 compatible macros */ +#define FX_SAVE(envbuf) asm ("fxsave %0":"=m" (*envbuf)); +#define FX_RESTORE(envbuf) asm ("fxrstor %0":"=m" (*envbuf)); + +static int old_arch = 0; /* No SSE/SSE2 instructions */ + +#define asm __asm__ + +#if defined(__amd64__) +#define AMD64 +#endif + +static inline void +cpuid (int op, int *eax, int *ebx, int *ecx, int *edx) +{ +__asm__ ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx):"0" (op), "c" + (0)); +} + +#ifdef AMD64 +# define local_save_flags(x) asm volatile("pushfq ; popq %0":"=g" (x):) +# define local_restore_flags(x) asm volatile("pushq %0 ; popfq"::"g" (x):"memory", "cc") +#else +# define local_save_flags(x) asm volatile("pushfl ; popl %0":"=g" (x):) +# define local_restore_flags(x) asm volatile("pushl %0 ; popfl"::"g" (x):"memory", "cc") +#endif + +static inline unsigned long +read_cr0 (void) +{ + unsigned long cr0; +#ifdef AMD64 +asm ("movq %%cr0,%0":"=r" (cr0)); +#else +asm ("movl %%cr0,%0":"=r" (cr0)); +#endif + return cr0; +} + +static inline void +write_cr0 (unsigned long val) +{ +#ifdef AMD64 + asm ("movq %0,%%cr0"::"r" (val)); +#else + asm ("movl %0,%%cr0"::"r" (val)); +#endif +} + +static inline unsigned long +read_cr4 (void) +{ + unsigned long cr4; +#ifdef AMD64 +asm ("movq %%cr4,%0":"=r" (cr4)); +#else +asm ("movl %%cr4,%0":"=r" (cr4)); +#endif + return cr4; +} + +static inline void +write_cr4 (unsigned long val) +{ +#ifdef AMD64 + asm ("movq %0,%%cr4"::"r" (val)); +#else + asm ("movl %0,%%cr4"::"r" (val)); +#endif +} + +static inline unsigned long long +read_mxcsr (void) +{ + unsigned long long mxcsr; +asm ("stmxcsr %0":"=m" (mxcsr)); + return mxcsr; +} + +static inline void +write_mxcsr (unsigned long long val) +{ + asm ("ldmxcsr %0"::"m" (val)); +} + +int +oss_fp_check (void) +{ + int eax, ebx, ecx, edx; +#define FLAGS_ID (1<<21) + + oss_native_word flags_reg; + + local_save_flags (flags_reg); + flags_reg &= ~FLAGS_ID; + local_restore_flags (flags_reg); + + local_save_flags (flags_reg); + if (flags_reg & FLAGS_ID) + return 0; + + flags_reg |= FLAGS_ID; + local_restore_flags (flags_reg); + + local_save_flags (flags_reg); + if (!(flags_reg & FLAGS_ID)) + return 0; + +#define OSS_CPUID_FXSR (1<<24) +#define OSS_CPUID_SSE (1<<25) +#define OSS_CPUID_SSE2 (1<<26) + + cpuid (1, &eax, &ebx, &ecx, &edx); + + if (!(edx & OSS_CPUID_FXSR)) + return 0; + + /* + * Older machines require different FP handling than the latest ones. Use the SSE + * instruction set as an indicator. + */ + if (!(edx & OSS_CPUID_SSE)) + old_arch = 1; + + return 1; +} + +void +oss_fp_save (short *envbuf, unsigned int flags[]) +{ + flags[0] = read_cr0 (); + write_cr0 (flags[0] & ~0x0e); /* Clear CR0.TS/MP/EM */ + + if (old_arch) + { + _FP_SAVE (envbuf); + } + else + { + flags[1] = read_cr4 (); + write_cr4 (flags[1] | 0x600); /* Set OSFXSR & OSXMMEXCEPT */ + FX_SAVE (envbuf); + asm ("fninit"); + asm ("fwait"); + write_mxcsr (0x1f80); + } + flags[2] = read_cr0 (); +} + +void +oss_fp_restore (short *envbuf, unsigned int flags[]) +{ + asm ("fwait"); + if (old_arch) + { + _FP_RESTORE (envbuf); + } + else + { + FX_RESTORE (envbuf); + write_cr4 (flags[1]); /* Restore cr4 */ + } + write_cr0 (flags[0]); /* Restore cr0 */ +} + +#ifdef VDEV_SUPPORT +static void +oss_file_free_private (void *v) +{ + free (v, M_DEVBUF); +} + +int +oss_file_get_private (void **v) +{ + int error; + + error = devfs_get_cdevpriv (v); + if (error) + { + cmn_err (CE_CONT, "Couldn't retrieve private data from file handle!\n"); + return error; + } + return 0; +} + +int +oss_file_set_private (struct thread *t, void *v, size_t l) +{ + int error; + void * p; + + p = malloc (l, M_DEVBUF, M_WAITOK); + if (p == NULL) + { + cmn_err (CE_CONT, "Couldn't allocate memory!\n"); + return -1; + } + memcpy (p, v, l); + error = devfs_set_cdevpriv (p, oss_file_free_private); + if (error) + { + cmn_err (CE_CONT, "Couldn't attach private data to file handle!\n"); + oss_file_free_private (p); + return error; + } + return 0; +} +#endif + +int +oss_get_uid(void) +{ + return curthread->td_ucred->cr_uid; +} + +extern int max_intrate; +extern int detect_trace; +extern int src_quality; +extern int flat_device_model; +extern int vmix_disabled; +extern int vmix_loopdevs; +extern int vmix_no_autoattach; +extern int ac97_amplifier; +extern int ac97_recselect; +extern int cooked_enable; +extern int dma_buffsize; +extern int excl_policy; +extern int mixer_muted; +TUNABLE_INT("osscore.max_intrate", &max_intrate); +TUNABLE_INT("osscore.detect_trace", &detect_trace); +TUNABLE_INT("osscore.src_quality", &src_quality); +TUNABLE_INT("osscore.flat_device_model", &flat_device_model); +TUNABLE_INT("osscore.vmix_disabled", &vmix_disabled); +TUNABLE_INT("osscore.vmix_loopdevs", &vmix_loopdevs); +TUNABLE_INT("osscore.vmix_no_autoattach", &vmix_no_autoattach); +TUNABLE_INT("osscore.ac97_amplifier", &ac97_amplifier); +TUNABLE_INT("osscore.ac97_recselect", &ac97_recselect); +TUNABLE_INT("osscore.cooked_enable", &cooked_enable); +TUNABLE_INT("osscore.dma_buffsize", &dma_buffsize); +TUNABLE_INT("osscore.excl_policy", &excl_policy); +TUNABLE_INT("osscore.mixer_muted", &mixer_muted); + +DECLARE_MODULE (osscore, osscore_mod, SI_SUB_KLD, SI_ORDER_ANY); +MODULE_VERSION (osscore, 4); diff --git a/setup/FreeBSD/oss/soundon.user b/setup/FreeBSD/oss/soundon.user new file mode 100644 index 0000000..da31b6d --- /dev/null +++ b/setup/FreeBSD/oss/soundon.user @@ -0,0 +1,7 @@ +#!/bin/sh +# +# This script can be used to run programs every time OSS is started. +# By default, this script is disabled, and contains no commands. +# To enable, add executable permissions to this file, and edit below +# commands to be run. +exit 0 diff --git a/setup/FreeBSD/pkg-comment b/setup/FreeBSD/pkg-comment new file mode 100644 index 0000000..d2bd0e3 --- /dev/null +++ b/setup/FreeBSD/pkg-comment @@ -0,0 +1 @@ +Open Sound System for FreeBSD diff --git a/setup/FreeBSD/pkg-descr b/setup/FreeBSD/pkg-descr new file mode 100644 index 0000000..d56fdaa --- /dev/null +++ b/setup/FreeBSD/pkg-descr @@ -0,0 +1,4 @@ +Open Sound System for FreeBSD is a audio subsystem that provides a cross +platform audio and MIDI API with device drivers for most consumer and +professional PCI and USB audio devices. Additional information about +Open Sound System is available at http://www.opensound.com diff --git a/setup/FreeBSD/pkg-message b/setup/FreeBSD/pkg-message new file mode 100644 index 0000000..00aefe4 --- /dev/null +++ b/setup/FreeBSD/pkg-message @@ -0,0 +1,87 @@ + + SOFTWARE LICENSE AGREEMENT + -------------------------- + +PLEASE CAREFULLY READ THE FOLLOWING TERMS AND CONDITIONS BEFORE +INSTALLING THE SOFTWARE. INSTALLING THE SOFTWARE INDICATES THAT YOU HAVE +ACCEPTED THESE TERMS AND CONDITIONS. + +4Front Technologies provides this program and licenses its use to you, the +licensee, pursuant to the following terms. You assume responsibility for the +selection of the program to achieve your intended results. Further, you are +responsible for the installation, use and results obtained from this program. + +LICENSE +You, the licensee, have the non-exclusive right to use the hardware, software +and its documentation. You may only use the software on a single computer at +one time. You may not distribute copies of the software or documentation to +others nor are you licensed to sell or lend it to others.You may copy the +program for "backup" purposes only. You agree to replicate the copyright note +shown below on any such copies. + +If you violate the terms and conditions set forth, eg, sharing your licenses +with a third party or illegally trading OSS licenses, your license will be +terminated without any refund and we will report any fraud to the SPA. We +appreciate your cooperation in this matter. + +COPYRIGHT +THE PROGRAM IS COPYRIGHTED AND EXCEPT AS PERMITTED BY THIS AGREEMENT, YOU +MAY NOT DUPLICATE THE PROGRAM OR DISCLOSE IT TO ANY OTHER PARTY. IF YOU +TRANSFER POSSESSION OF THIS PROGRAM TO ANOTHER PARTY, YOUR LICENSE IS +AUTOMATICALLY TERMNIATED. + +TERM +This license agreement is effective until terminated. You may terminate it +voluntarily at any time. Voluntary termination by you must be accompanied by +the full destruction of the licensed copies thereof. Should you fail to comply +with the terms and conditions, your license will be automatically terminated +by 4Front Technologies. + +SUPPORT +4Front Technologies will provide free technical support for the software for +a period of 1 year from the date of purchase. After the expiration of this +period, you may choose to renew the support by signing a Technical Support +Contract with 4Front Technologies. + +GENERAL WARRANTY +THE SOFTWARE DISTRIBUTED AND LICENSED "AS-IS". ALL WARRANTIES, EITHER EXPRESSED +OR IMPLIED, ARE DISCLAIMED AS TO THE SOFTWARE'S QUALITY, PERFORMANCE OR FITNESS +FOR ANY PARTICULAR PURPOSE. THE LICENSEE BEARS THE ENTIRE RISK RELATING TO THE +QUALITY, PERFORMANCE AND FITNESS OF THE SOFTWARE. + +LIABILITY +IN NO EVENT SHALL 4FRONT TECHNOLOGIES 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. OUR SOLE OBLIGATION TO +YOU SHALL BE THE REPAIR OR REPLACEMENT OF A NON-CONFORMING PROGRAM IN THE +SOFTWARE. + +MISCELLANEOUS + +(1) This Agreement shall be governed by State of California law. + +(2) U.S. GOVERNMENT RESTRICTED RIGHTS. Use, duplication or disclosure by + the Government is subject to restrictions set forth in subparagraphs + (a) through (d) of the Commercial Computer-Restricted Rights clause at + DFAR 52.227-19 when applicable, or in subparagraph (c)(1)(ii) of the + Rights in Technical Data and Computer Software clause at DFARS + 252.227-7013, or at 252.211-7015. + +(3) U.S. GOVERNMENT EXPORT RESTRICTIONS. None of the Software or underlying + information or technology may be downloaded or otherwise exported or + reexported to any country to which the U.S. has embargoed goods. + Manufacturer is 4Front Technologies. + +______________________________________________________________________________ + +4Front Technologies, Inc. +9826 Beverlywood Street +Los Angeles, CA 90064 +U.S.A. + +Tel: (+01) 310-202-8530 WWW: http://www.opensound.com +Fax: (+01) 310-202-0496 E-mail: info@opensound.com diff --git a/setup/FreeBSD/pkg-postinstall b/setup/FreeBSD/pkg-postinstall new file mode 100644 index 0000000..de2c03a --- /dev/null +++ b/setup/FreeBSD/pkg-postinstall @@ -0,0 +1,18 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +cd $OSSLIBDIR/build +echo "Build Open Sound System for FreeBSD-`uname -m` `uname -r`" +sh install.sh + +chmod 744 /etc/rc.d/oss + +echo "Starting Open Sound System" +rm -f /dev/dsp; ln -s /dev/dsp0 /dev/dsp +/usr/sbin/soundoff > /dev/null 2>&1 +/usr/sbin/soundon diff --git a/setup/FreeBSD/pkg-postremove b/setup/FreeBSD/pkg-postremove new file mode 100644 index 0000000..4d6d028 --- /dev/null +++ b/setup/FreeBSD/pkg-postremove @@ -0,0 +1,10 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +rm -rf $OSSLIBDIR +rm -f /dev/dsp* /dev/audio* /dev/mixer* /dev/midi* /dev/sndstat /dev/sequencer /dev/music diff --git a/setup/FreeBSD/pkg-preremove b/setup/FreeBSD/pkg-preremove new file mode 100644 index 0000000..c02f38b --- /dev/null +++ b/setup/FreeBSD/pkg-preremove @@ -0,0 +1,10 @@ +#!/bin/sh + +echo "Killing all active audio applications" + +/usr/sbin/fuser -k /dev/mixer* /dev/dsp* /dev/audio* /dev/sequencer /dev/music /dev/midi* > /dev/null 2>&1 + +sleep 2 + +/usr/sbin/soundoff +exit 0 diff --git a/setup/FreeBSD/sbin/soundoff b/setup/FreeBSD/sbin/soundoff new file mode 100755 index 0000000..7cb4962 --- /dev/null +++ b/setup/FreeBSD/sbin/soundoff @@ -0,0 +1,60 @@ +#!/bin/sh + +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +if ! /sbin/kldstat | grep -q osscore.ko +then + echo OSS not loaded. + exit 0 +fi + +if ! test -f $OSSLIBDIR/etc/installed_drivers +then + echo $OSSLIBDIR/etc/installed_drivers is missing. + exit 1 +fi + +# Save mixer settings automatically if requested +if test -f $OSSLIBDIR/etc/userdefs && grep -q "autosave_mixer yes" $OSSLIBDIR/etc/userdefs +then + /usr/sbin/savemixer +fi + +# Save legacy devices +/usr/sbin/ossdevlinks -N + +PROGRAMS="`fstat /dev/mixer* /dev/dsp* /dev/midi* /dev/oss/*/* 2>/dev/null | sed '1 D'`" + +if test "$PROGRAMS " != " " +then + echo + echo Some applications are still using OSS - cannot unload + echo + + fstat /dev/mixer* /dev/dsp* /dev/midi* /dev/oss/*/* 2>/dev/null + + echo + echo Please stop these applications and run soundoff again + exit 2 +fi + +for n in `cat $OSSLIBDIR/etc/installed_drivers | sed 's/#.*//'` +do + /sbin/kldunload $n > /dev/null 2>&1 +done + +/sbin/kldunload osscore + +if ! /sbin/kldstat | grep -q osscore.ko # OSS gone? +then + exit 0 +fi + +echo Cannot unload the OSS driver modules + +exit 0 diff --git a/setup/FreeBSD/sbin/soundon b/setup/FreeBSD/sbin/soundon new file mode 100755 index 0000000..091b2dc --- /dev/null +++ b/setup/FreeBSD/sbin/soundon @@ -0,0 +1,122 @@ +#!/bin/sh + +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +LOG=/var/log/soundon.log +echo "Open Sound System starting" `date` > $LOG +echo "OSS version: " `cat $OSSLIBDIR/version.dat` >> $LOG 2>&1 +echo "Kernel version: " `uname -a` >> $LOG + +if ! test -f $OSSLIBDIR/etc/installed_drivers +then + echo No $OSSLIBDIR/etc/installed_drivers >> $LOG + echo No $OSSLIBDIR/etc/installed_drivers + echo Please run ossdetect to create it. + exit 1 +fi + +if ! test -f $OSSLIBDIR/modules/osscore.ko +then + echo No $OSSLIBDIR/modules/osscore.ko module >> $LOG + echo No $OSSLIBDIR/modules/osscore.ko module + exit 2 +fi + +if test -f $OSSLIBDIR/etc/license.asc +then + /usr/sbin/ossdetect -l >> $LOG +fi + +OPTIONS= +if test -f $OSSLIBDIR/conf/osscore.conf +then + OPTIONS=`grep -v -h '^#' $OSSLIBDIR/conf/osscore.conf | sed 's/[ ]//g'` + if test "$OPTIONS " != " " + then + echo $OPTIONS | xargs -I % kenv osscore.% + fi +fi + +if ! /sbin/kldload $OSSLIBDIR/modules/osscore.ko +then + echo Loading the osscore module failed + echo Loading the osscore module failed >> $LOG + dmesg >> $LOG + exit 4 +fi + +for n in `cat $OSSLIBDIR/etc/installed_drivers | sed 's/#.*//'` +do + OPTIONS= + if test -f $OSSLIBDIR/conf/$n.conf + then + OPTIONS=`grep -v -h '^#' $OSSLIBDIR/conf/$n.conf | sed 's/[ ]//g'` + if test "$OPTIONS " != " " + then + echo $OPTIONS | xargs -I % kenv $n.% + fi + fi + + if ! /sbin/kldload $OSSLIBDIR/modules/$n.ko + then + echo Loading module $n failed '-' ignored >> $LOG + echo Loading module $n failed '-' ignored + fi +done + +echo "+++ ossinfo -v3 +++" >> $LOG +/usr/bin/ossinfo -v3 >> $LOG 2>&1 +echo "+++ /dev/sndstat +++" >> $LOG +cat /dev/sndstat >> $LOG 2>&1 +echo "+++ dmesg +++" >> $LOG +dmesg >> $LOG +echo "+++ pciconf +++" >> $LOG +/usr/sbin/pciconf -l -v >> $LOG 2>&1 +echo "+++ OSS devices +++" >> $LOG + +# Restore the previous legacy device links +if test -f $OSSLIBDIR/etc/legacy_devices +then + sh $OSSLIBDIR/etc/legacy_devices >> $LOG 2>&1 +fi + +/usr/sbin/ossdevlinks -v >> $LOG 2>&1 + +ls -l /dev/dsp* /dev/sndstat /dev/mixer* /dev/oss/*/* >> $LOG 2>&1 + +/usr/sbin/savemixer -L -v >> $LOG 2>&1 + +if test -x $OSSLIBDIR/soundon.user +then + echo Running $OSSLIBDIR/soundon.user >> $LOG + $OSSLIBDIR/soundon.user >> $LOG 2>&1 +fi + +if test "`ossinfo -g|grep TRIAL` " != " " +then + echo + echo "************************************************************" + echo "* NOTE! You are using trial version of Open Sound System *" + echo "************************************************************" + echo + + sleep 1 +fi + +if test "`ossinfo -g|grep EXPIRED` " != " " +then + echo + echo "****************************************************************" + echo "* NOTE! Your Open Sound System evaluation license has expired *" + echo "****************************************************************" + echo + + sleep 15 +fi + +exit 0 diff --git a/setup/Linux/arm/Makefile.osscore.arm b/setup/Linux/arm/Makefile.osscore.arm new file mode 100644 index 0000000..ffe2d3f --- /dev/null +++ b/setup/Linux/arm/Makefile.osscore.arm @@ -0,0 +1,17 @@ + +ifneq ($(KERNELRELEASE),) + + obj-m := osscore.o + +else + + PWD := $(shell pwd) +endif + +default: + @echo "static const char __oss_compile_vermagic[];" > ubuntu_version_hack.inc + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +clean: + rm -f *.o *.ko *.mod.c *.mod.o .*.cmd core core.* x y z + rm -rf .tmp_versions diff --git a/setup/Linux/arm/Makefile.tmpl.arm b/setup/Linux/arm/Makefile.tmpl.arm new file mode 100644 index 0000000..a8f0df2 --- /dev/null +++ b/setup/Linux/arm/Makefile.tmpl.arm @@ -0,0 +1,21 @@ +include /etc/oss.conf + +EXTRA_CFLAGS += -I${OSSLIBDIR}/include/internals -I${OSSLIBDIR}/include/sys + +ifneq ($(KERNELRELEASE),) + + obj-m := MODNAME.o + +else + + #KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +endif + +clean: + @rm -f *.o *.ko *.mod.c *.mod.o .*.cmd core core.* x y z + @rm -rf .tmp_versions diff --git a/setup/Linux/arm/bpabi.S b/setup/Linux/arm/bpabi.S new file mode 100644 index 0000000..1f08346 --- /dev/null +++ b/setup/Linux/arm/bpabi.S @@ -0,0 +1,119 @@ +/* Miscellaneous BPABI functions. + + Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC. + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combine + executable.) + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#ifdef __ARMEB__ +#define xxh r0 +#define xxl r1 +#define yyh r2 +#define yyl r3 +#else +#define xxh r1 +#define xxl r0 +#define yyh r3 +#define yyl r2 +#endif + +#ifdef L_aeabi_lcmp + +ARM_FUNC_START aeabi_lcmp + cmp xxh, yyh + do_it lt + movlt r0, #-1 + do_it gt + movgt r0, #1 + do_it ne + RETc(ne) + subs r0, xxl, yyl + do_it lo + movlo r0, #-1 + do_it hi + movhi r0, #1 + RET + FUNC_END aeabi_lcmp + +#endif /* L_aeabi_lcmp */ + +#ifdef L_aeabi_ulcmp + +ARM_FUNC_START aeabi_ulcmp + cmp xxh, yyh + do_it lo + movlo r0, #-1 + do_it hi + movhi r0, #1 + do_it ne + RETc(ne) + cmp xxl, yyl + do_it lo + movlo r0, #-1 + do_it hi + movhi r0, #1 + do_it eq + moveq r0, #0 + RET + FUNC_END aeabi_ulcmp + +#endif /* L_aeabi_ulcmp */ + +#ifdef L_aeabi_ldivmod + +ARM_FUNC_START aeabi_ldivmod + sub sp, sp, #8 +#if defined(__thumb2__) + mov ip, sp + push {ip, lr} +#else + do_push {sp, lr} +#endif + bl SYM(__gnu_ldivmod_helper) __PLT__ + ldr lr, [sp, #4] + add sp, sp, #8 + do_pop {r2, r3} + RET + +#endif /* L_aeabi_ldivmod */ + +#ifdef L_aeabi_uldivmod + +ARM_FUNC_START aeabi_uldivmod + sub sp, sp, #8 +#if defined(__thumb2__) + mov ip, sp + push {ip, lr} +#else + do_push {sp, lr} +#endif + bl SYM(__gnu_uldivmod_helper) __PLT__ + ldr lr, [sp, #4] + add sp, sp, #8 + do_pop {r2, r3} + RET + +#endif /* L_aeabi_divmod */ + diff --git a/setup/Linux/arm/bpabi.c b/setup/Linux/arm/bpabi.c new file mode 100644 index 0000000..7ff8e2a --- /dev/null +++ b/setup/Linux/arm/bpabi.c @@ -0,0 +1,375 @@ +/* Miscellaneous BPABI functions. + + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC. + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combine + executable.) + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +extern long long __divdi3 (long long, long long); +extern unsigned long long __udivdi3 (unsigned long long, + unsigned long long); +extern long long __gnu_ldivmod_helper (long long, long long, long long *); +extern unsigned long long __gnu_uldivmod_helper (unsigned long long, + unsigned long long, + unsigned long long *); +#define UQItype unsigned char +#define DWtype long long +#define UDItype unsigned long long +#define Wtype int +#define USItype unsigned int + +#include "longlong.h" + +const UQItype __clz_tab[256] = +{ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 +}; + +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rI" ((USItype) (bl)) __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rI" ((USItype) (bl)) __CLOBBER_CC) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm\n" \ + " mov %2, %5, lsr #16\n" \ + " mov %0, %6, lsr #16\n" \ + " bic %3, %5, %2, lsl #16\n" \ + " bic %4, %6, %0, lsl #16\n" \ + " mul %1, %3, %4\n" \ + " mul %4, %2, %4\n" \ + " mul %3, %0, %3\n" \ + " mul %0, %2, %0\n" \ + " adds %3, %4, %3\n" \ + " addcs %0, %0, #65536\n" \ + " adds %1, %1, %3, lsl #16\n" \ + " adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)) __CLOBBER_CC );} +#define UMUL_TIME 20 +#define UDIV_TIME 100 + +#if 1 /* Big endian */ + struct DWstruct {Wtype high, low;}; +#else + struct DWstruct {Wtype low, high;}; +#endif + +/* We need this union to unpack/pack DImode values, since we don't have + any arithmetic yet. Incoming DImode parameters are stored into the + `ll' field, and the unpacked result is read from the struct `s'. */ + +typedef union +{ + struct DWstruct s; + DWtype ll; +} DWunion; + +UDWtype +__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) +{ + const DWunion nn = {.ll = n}; + const DWunion dd = {.ll = d}; + DWunion rr; + UWtype d0, d1, n0, n1, n2; + UWtype q0, q1; + UWtype b, bm; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + +#if !UDIV_NEEDS_NORMALIZATION + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + udiv_qrnnd (q1, n1, 0, n1, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0. */ + } + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = 0; + *rp = rr.ll; + } + } + +#else /* UDIV_NEEDS_NORMALIZATION */ + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + + This special case is necessary, not an optimization. + (Shifts counts of W_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } +#endif /* UDIV_NEEDS_NORMALIZATION */ + + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + UWtype m1, m0; + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + const DWunion ww = {{.low = q0, .high = q1}}; + return ww.ll; +} + +UDWtype +__udivdi3 (UDWtype n, UDWtype d) +{ + return __udivmoddi4 (n, d, (UDWtype *) 0); +} + +long long +__divdi3 (DWtype u, DWtype v) +{ + Wtype c = 0; + DWunion uu = {.ll = u}; + DWunion vv = {.ll = v}; + DWtype w; + + if (uu.s.high < 0) + c = ~c, + uu.ll = -uu.ll; + if (vv.s.high < 0) + c = ~c, + vv.ll = -vv.ll; + + w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); + if (c) + w = -w; + + return w; +} + +long long +__gnu_ldivmod_helper (long long a, + long long b, + long long *remainder) +{ + long long quotient; + + quotient = __divdi3 (a, b); + *remainder = a - b * quotient; + return quotient; +} + +unsigned long long +__gnu_uldivmod_helper (unsigned long long a, + unsigned long long b, + unsigned long long *remainder) +{ + unsigned long long quotient; + + quotient = __udivdi3 (a, b); + *remainder = a - b * quotient; + return quotient; +} diff --git a/setup/Linux/arm/bpabi.h b/setup/Linux/arm/bpabi.h new file mode 100644 index 0000000..a67f649 --- /dev/null +++ b/setup/Linux/arm/bpabi.h @@ -0,0 +1,125 @@ +/* Configuration file for ARM BPABI targets. + Copyright (C) 2004, 2005, 2007 + Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +/* Use the AAPCS ABI by default. */ +#define ARM_DEFAULT_ABI ARM_ABI_AAPCS + +/* Assume that AAPCS ABIs should adhere to the full BPABI. */ +#define TARGET_BPABI (TARGET_AAPCS_BASED) + +/* BPABI targets use EABI frame unwinding tables. */ +#define TARGET_UNWIND_INFO 1 + +/* Section 4.1 of the AAPCS requires the use of VFP format. */ +#undef FPUTYPE_DEFAULT +#define FPUTYPE_DEFAULT FPUTYPE_VFP + +/* TARGET_BIG_ENDIAN_DEFAULT is set in + config.gcc for big endian configurations. */ +#if TARGET_BIG_ENDIAN_DEFAULT +#define TARGET_ENDIAN_DEFAULT MASK_BIG_END +#else +#define TARGET_ENDIAN_DEFAULT 0 +#endif + +/* EABI targets should enable interworking by default. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_INTERWORK | TARGET_ENDIAN_DEFAULT) + +/* The ARM BPABI functions return a boolean; they use no special + calling convention. */ +#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) TARGET_BPABI + +/* The BPABI integer comparison routines return { -1, 0, 1 }. */ +#define TARGET_LIB_INT_CMP_BIASED !TARGET_BPABI + +/* Tell the assembler to build BPABI binaries. */ +#undef SUBTARGET_EXTRA_ASM_SPEC +#define SUBTARGET_EXTRA_ASM_SPEC "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=4}" + +/* The generic link spec in elf.h does not support shared libraries. */ +#undef LINK_SPEC +#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} " \ + "%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} " \ + "-X" + +#if defined (__thumb__) +#define RENAME_LIBRARY_SET ".thumb_set" +#else +#define RENAME_LIBRARY_SET ".set" +#endif + +/* Make __aeabi_AEABI_NAME an alias for __GCC_NAME. */ +#define RENAME_LIBRARY(GCC_NAME, AEABI_NAME) \ + __asm__ (".globl\t__aeabi_" #AEABI_NAME "\n" \ + RENAME_LIBRARY_SET "\t__aeabi_" #AEABI_NAME \ + ", __" #GCC_NAME "\n"); + +/* Give some libgcc functions an additional __aeabi name. */ +#ifdef L_muldi3 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, lmul) +#endif +#ifdef L_muldi3 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, lmul) +#endif +#ifdef L_fixdfdi +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz) +#endif +#ifdef L_fixunsdfdi +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz) +#endif +#ifdef L_fixsfdi +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz) +#endif +#ifdef L_fixunssfdi +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz) +#endif +#ifdef L_floatdidf +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, l2d) +#endif +#ifdef L_floatdisf +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, l2f) +#endif + +/* The BPABI requires that we always use an out-of-line implementation + of RTTI comparison, even if the target supports weak symbols, + because the same object file might be used on a target that does + not support merging symbols across DLL boundaries. This macro is + broken out separately so that it can be used within + TARGET_OS_CPP_BUILTINS in configuration files for systems based on + the BPABI. */ +#define TARGET_BPABI_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("__GXX_TYPEINFO_EQUALITY_INLINE=0"); \ + } \ + while (false) + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + TARGET_BPABI_CPP_BUILTINS() + +/* The BPABI specifies the use of .{init,fini}_array. Therefore, we + do not want GCC to put anything into the .{init,fini} sections. */ +#undef INIT_SECTION_ASM_OP +#undef FINI_SECTION_ASM_OP +#define INIT_ARRAY_SECTION_ASM_OP ARM_EABI_CTORS_SECTION_OP +#define FINI_ARRAY_SECTION_ASM_OP ARM_EABI_DTORS_SECTION_OP diff --git a/setup/Linux/arm/lib1funcs.asm b/setup/Linux/arm/lib1funcs.asm new file mode 100644 index 0000000..e2c2201 --- /dev/null +++ b/setup/Linux/arm/lib1funcs.asm @@ -0,0 +1,1393 @@ +@ libgcc routines for ARM cpu. +@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) + +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005, 2007 + Free Software Foundation, Inc. + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +This file is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* An executable stack is *not* required for these functions. */ +#if defined(__ELF__) && defined(__linux__) +.section .note.GNU-stack,"",%progbits +.previous +#endif + +/* ------------------------------------------------------------------------ */ + +/* We need to know what prefix to add to function names. */ + +#ifndef __USER_LABEL_PREFIX__ +#error __USER_LABEL_PREFIX__ not defined +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +#ifdef __ELF__ +#ifdef __thumb__ +#define __PLT__ /* Not supported in Thumb assembler (for now). */ +#elif defined __vxworks && !defined __PIC__ +#define __PLT__ /* Not supported by the kernel loader. */ +#else +#define __PLT__ (PLT) +#endif +#define TYPE(x) .type SYM(x),function +#define SIZE(x) .size SYM(x), . - SYM(x) +#define LSYM(x) .x +#else +#define __PLT__ +#define TYPE(x) +#define SIZE(x) +#define LSYM(x) x +#endif + +/* Function end macros. Variants for interworking. */ + +#if defined(__ARM_ARCH_2__) +# define __ARM_ARCH__ 2 +#endif + +#if defined(__ARM_ARCH_3__) +# define __ARM_ARCH__ 3 +#endif + +#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \ + || defined(__ARM_ARCH_4T__) +/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with + long multiply instructions. That includes v3M. */ +# define __ARM_ARCH__ 4 +#endif + +#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +# define __ARM_ARCH__ 5 +#endif + +#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) +# define __ARM_ARCH__ 6 +#endif + +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) +# define __ARM_ARCH__ 7 +#endif + +#ifndef __ARM_ARCH__ +#error Unable to determine architecture. +#endif + +/* How to return from a function call depends on the architecture variant. */ + +#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__) + +# define RET bx lr +# define RETc(x) bx##x lr + +/* Special precautions for interworking on armv4t. */ +# if (__ARM_ARCH__ == 4) + +/* Always use bx, not ldr pc. */ +# if (defined(__thumb__) || defined(__THUMB_INTERWORK__)) +# define __INTERWORKING__ +# endif /* __THUMB__ || __THUMB_INTERWORK__ */ + +/* Include thumb stub before arm mode code. */ +# if defined(__thumb__) && !defined(__THUMB_INTERWORK__) +# define __INTERWORKING_STUBS__ +# endif /* __thumb__ && !__THUMB_INTERWORK__ */ + +#endif /* __ARM_ARCH == 4 */ + +#else + +# define RET mov pc, lr +# define RETc(x) mov##x pc, lr + +#endif + +.macro cfi_pop advance, reg, cfa_offset +#ifdef __ELF__ + .pushsection .debug_frame + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte \advance + .byte (0xc0 | \reg) /* DW_CFA_restore */ + .byte 0xe /* DW_CFA_def_cfa_offset */ + .uleb128 \cfa_offset + .popsection +#endif +.endm +.macro cfi_push advance, reg, offset, cfa_offset +#ifdef __ELF__ + .pushsection .debug_frame + .byte 0x4 /* DW_CFA_advance_loc4 */ + .4byte \advance + .byte (0x80 | \reg) /* DW_CFA_offset */ + .uleb128 (\offset / -4) + .byte 0xe /* DW_CFA_def_cfa_offset */ + .uleb128 \cfa_offset + .popsection +#endif +.endm +.macro cfi_start start_label, end_label +#ifdef __ELF__ + .pushsection .debug_frame +LSYM(Lstart_frame): + .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE +LSYM(Lstart_cie): + .4byte 0xffffffff @ CIE Identifier Tag + .byte 0x1 @ CIE Version + .ascii "\0" @ CIE Augmentation + .uleb128 0x1 @ CIE Code Alignment Factor + .sleb128 -4 @ CIE Data Alignment Factor + .byte 0xe @ CIE RA Column + .byte 0xc @ DW_CFA_def_cfa + .uleb128 0xd + .uleb128 0x0 + + .align 2 +LSYM(Lend_cie): + .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length +LSYM(Lstart_fde): + .4byte LSYM(Lstart_frame) @ FDE CIE offset + .4byte \start_label @ FDE initial location + .4byte \end_label-\start_label @ FDE address range + .popsection +#endif +.endm +.macro cfi_end end_label +#ifdef __ELF__ + .pushsection .debug_frame + .align 2 +LSYM(Lend_fde): + .popsection +\end_label: +#endif +.endm + +/* Don't pass dirn, it's there just to get token pasting right. */ + +.macro RETLDM regs=, cond=, unwind=, dirn=ia +#if defined (__INTERWORKING__) + .ifc "\regs","" + ldr\cond lr, [sp], #8 + .else +# if defined(__thumb2__) + pop\cond {\regs, lr} +# else + ldm\cond\dirn sp!, {\regs, lr} +# endif + .endif + .ifnc "\unwind", "" + /* Mark LR as restored. */ +97: cfi_pop 97b - \unwind, 0xe, 0x0 + .endif + bx\cond lr +#else + /* Caller is responsible for providing IT instruction. */ + .ifc "\regs","" + ldr\cond pc, [sp], #8 + .else +# if defined(__thumb2__) + pop\cond {\regs, pc} +# else + ldm\cond\dirn sp!, {\regs, pc} +# endif + .endif +#endif +.endm + +/* The Unified assembly syntax allows the same code to be assembled for both + ARM and Thumb-2. However this is only supported by recent gas, so define + a set of macros to allow ARM code on older assemblers. */ +#if defined(__thumb2__) +.macro do_it cond, suffix="" + it\suffix \cond +.endm +.macro shift1 op, arg0, arg1, arg2 + \op \arg0, \arg1, \arg2 +.endm +#define do_push push +#define do_pop pop +#define COND(op1, op2, cond) op1 ## op2 ## cond +/* Perform an arithmetic operation with a variable shift operand. This + requires two instructions and a scratch register on Thumb-2. */ +.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp + \shiftop \tmp, \src2, \shiftreg + \name \dest, \src1, \tmp +.endm +#else +.macro do_it cond, suffix="" +.endm +.macro shift1 op, arg0, arg1, arg2 + mov \arg0, \arg1, \op \arg2 +.endm +#define do_push stmfd sp!, +#define do_pop ldmfd sp!, +#define COND(op1, op2, cond) op1 ## cond ## op2 +.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp + \name \dest, \src1, \src2, \shiftop \shiftreg +.endm +#endif + +.macro ARM_LDIV0 name + str lr, [sp, #-8]! +98: cfi_push 98b - __\name, 0xe, -0x8, 0x8 + bl SYM (__div0) __PLT__ + mov r0, #0 @ About as wrong as it could be. + RETLDM unwind=98b +.endm + + +.macro THUMB_LDIV0 name + push { r1, lr } +98: cfi_push 98b - __\name, 0xe, -0x4, 0x8 + bl SYM (__div0) + mov r0, #0 @ About as wrong as it could be. +#if defined (__INTERWORKING__) + pop { r1, r2 } + bx r2 +#else + pop { r1, pc } +#endif +.endm + +.macro FUNC_END name + SIZE (__\name) +.endm + +.macro DIV_FUNC_END name + cfi_start __\name, LSYM(Lend_div0) +LSYM(Ldiv0): +#ifdef __thumb__ + THUMB_LDIV0 \name +#else + ARM_LDIV0 \name +#endif + cfi_end LSYM(Lend_div0) + FUNC_END \name +.endm + +.macro THUMB_FUNC_START name + .globl SYM (\name) + TYPE (\name) + .thumb_func +SYM (\name): +.endm + +/* Function start macros. Variants for ARM and Thumb. */ + +#ifdef __thumb__ +#define THUMB_FUNC .thumb_func +#define THUMB_CODE .force_thumb +# if defined(__thumb2__) +#define THUMB_SYNTAX .syntax divided +# else +#define THUMB_SYNTAX +# endif +#else +#define THUMB_FUNC +#define THUMB_CODE +#define THUMB_SYNTAX +#endif + +.macro FUNC_START name + .text + .globl SYM (__\name) + TYPE (__\name) + .align 0 + THUMB_CODE + THUMB_FUNC + THUMB_SYNTAX +SYM (__\name): +.endm + +/* Special function that will always be coded in ARM assembly, even if + in Thumb-only compilation. */ + +#if defined(__thumb2__) + +/* For Thumb-2 we build everything in thumb mode. */ +.macro ARM_FUNC_START name + FUNC_START \name + .syntax unified +.endm +#define EQUIV .thumb_set +.macro ARM_CALL name + bl __\name +.endm + +#elif defined(__INTERWORKING_STUBS__) + +.macro ARM_FUNC_START name + FUNC_START \name + bx pc + nop + .arm +/* A hook to tell gdb that we've switched to ARM mode. Also used to call + directly from other local arm routines. */ +_L__\name: +.endm +#define EQUIV .thumb_set +/* Branch directly to a function declared with ARM_FUNC_START. + Must be called in arm mode. */ +.macro ARM_CALL name + bl _L__\name +.endm + +#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */ + +.macro ARM_FUNC_START name + .text + .globl SYM (__\name) + TYPE (__\name) + .align 0 + .arm +SYM (__\name): +.endm +#define EQUIV .set +.macro ARM_CALL name + bl __\name +.endm + +#endif + +.macro FUNC_ALIAS new old + .globl SYM (__\new) +#if defined (__thumb__) + .thumb_set SYM (__\new), SYM (__\old) +#else + .set SYM (__\new), SYM (__\old) +#endif +.endm + +.macro ARM_FUNC_ALIAS new old + .globl SYM (__\new) + EQUIV SYM (__\new), SYM (__\old) +#if defined(__INTERWORKING_STUBS__) + .set SYM (_L__\new), SYM (_L__\old) +#endif +.endm + +#ifdef __thumb__ +/* Register aliases. */ + +work .req r4 @ XXXX is this safe ? +dividend .req r0 +divisor .req r1 +overdone .req r2 +result .req r2 +curbit .req r3 +#endif +#if 0 +ip .req r12 +sp .req r13 +lr .req r14 +pc .req r15 +#endif + +/* ------------------------------------------------------------------------ */ +/* Bodies of the division and modulo routines. */ +/* ------------------------------------------------------------------------ */ +.macro ARM_DIV_BODY dividend, divisor, result, curbit + +#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__) + + clz \curbit, \dividend + clz \result, \divisor + sub \curbit, \result, \curbit + rsbs \curbit, \curbit, #31 + addne \curbit, \curbit, \curbit, lsl #1 + mov \result, #0 + addne pc, pc, \curbit, lsl #2 + nop + .set shift, 32 + .rept 32 + .set shift, shift - 1 + cmp \dividend, \divisor, lsl #shift + adc \result, \result, \result + subcs \dividend, \dividend, \divisor, lsl #shift + .endr + +#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ +#if __ARM_ARCH__ >= 5 + + clz \curbit, \divisor + clz \result, \dividend + sub \result, \curbit, \result + mov \curbit, #1 + mov \divisor, \divisor, lsl \result + mov \curbit, \curbit, lsl \result + mov \result, #0 + +#else /* __ARM_ARCH__ < 5 */ + + @ Initially shift the divisor left 3 bits if possible, + @ set curbit accordingly. This allows for curbit to be located + @ at the left end of each 4-bit nibbles in the division loop + @ to save one loop in most cases. + tst \divisor, #0xe0000000 + moveq \divisor, \divisor, lsl #3 + moveq \curbit, #8 + movne \curbit, #1 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + movlo \curbit, \curbit, lsl #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + movlo \curbit, \curbit, lsl #1 + blo 1b + + mov \result, #0 + +#endif /* __ARM_ARCH__ < 5 */ + + @ Division loop +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + orrhs \result, \result, \curbit + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + orrhs \result, \result, \curbit, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + orrhs \result, \result, \curbit, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + orrhs \result, \result, \curbit, lsr #3 + cmp \dividend, #0 @ Early termination? + movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? + movne \divisor, \divisor, lsr #4 + bne 1b + +#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ + +.endm +/* ------------------------------------------------------------------------ */ +.macro ARM_DIV2_ORDER divisor, order + +#if __ARM_ARCH__ >= 5 + + clz \order, \divisor + rsb \order, \order, #31 + +#else + + cmp \divisor, #(1 << 16) + movhs \divisor, \divisor, lsr #16 + movhs \order, #16 + movlo \order, #0 + + cmp \divisor, #(1 << 8) + movhs \divisor, \divisor, lsr #8 + addhs \order, \order, #8 + + cmp \divisor, #(1 << 4) + movhs \divisor, \divisor, lsr #4 + addhs \order, \order, #4 + + cmp \divisor, #(1 << 2) + addhi \order, \order, #3 + addls \order, \order, \divisor, lsr #1 + +#endif + +.endm +/* ------------------------------------------------------------------------ */ +.macro ARM_MOD_BODY dividend, divisor, order, spare + +#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__) + + clz \order, \divisor + clz \spare, \dividend + sub \order, \order, \spare + rsbs \order, \order, #31 + addne pc, pc, \order, lsl #3 + nop + .set shift, 32 + .rept 32 + .set shift, shift - 1 + cmp \dividend, \divisor, lsl #shift + subcs \dividend, \dividend, \divisor, lsl #shift + .endr + +#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ +#if __ARM_ARCH__ >= 5 + + clz \order, \divisor + clz \spare, \dividend + sub \order, \order, \spare + mov \divisor, \divisor, lsl \order + +#else /* __ARM_ARCH__ < 5 */ + + mov \order, #0 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + addlo \order, \order, #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + addlo \order, \order, #1 + blo 1b + +#endif /* __ARM_ARCH__ < 5 */ + + @ Perform all needed substractions to keep only the reminder. + @ Do comparisons in batch of 4 first. + subs \order, \order, #3 @ yes, 3 is intended here + blt 2f + +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + cmp \dividend, #1 + mov \divisor, \divisor, lsr #4 + subges \order, \order, #4 + bge 1b + + tst \order, #3 + teqne \dividend, #0 + beq 5f + + @ Either 1, 2 or 3 comparison/substractions are left. +2: cmn \order, #2 + blt 4f + beq 3f + cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +3: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +4: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor +5: + +#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ + +.endm +/* ------------------------------------------------------------------------ */ +.macro THUMB_DIV_MOD_BODY modulo + @ Load the constant 0x10000000 into our work register. + mov work, #1 + lsl work, #28 +LSYM(Loop1): + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. + cmp divisor, work + bhs LSYM(Lbignum) + cmp divisor, dividend + bhs LSYM(Lbignum) + lsl divisor, #4 + lsl curbit, #4 + b LSYM(Loop1) +LSYM(Lbignum): + @ Set work to 0x80000000 + lsl work, #3 +LSYM(Loop2): + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. + cmp divisor, work + bhs LSYM(Loop3) + cmp divisor, dividend + bhs LSYM(Loop3) + lsl divisor, #1 + lsl curbit, #1 + b LSYM(Loop2) +LSYM(Loop3): + @ Test for possible subtractions ... + .if \modulo + @ ... On the final pass, this may subtract too much from the dividend, + @ so keep track of which subtractions are done, we can fix them up + @ afterwards. + mov overdone, #0 + cmp dividend, divisor + blo LSYM(Lover1) + sub dividend, dividend, divisor +LSYM(Lover1): + lsr work, divisor, #1 + cmp dividend, work + blo LSYM(Lover2) + sub dividend, dividend, work + mov ip, curbit + mov work, #1 + ror curbit, work + orr overdone, curbit + mov curbit, ip +LSYM(Lover2): + lsr work, divisor, #2 + cmp dividend, work + blo LSYM(Lover3) + sub dividend, dividend, work + mov ip, curbit + mov work, #2 + ror curbit, work + orr overdone, curbit + mov curbit, ip +LSYM(Lover3): + lsr work, divisor, #3 + cmp dividend, work + blo LSYM(Lover4) + sub dividend, dividend, work + mov ip, curbit + mov work, #3 + ror curbit, work + orr overdone, curbit + mov curbit, ip +LSYM(Lover4): + mov ip, curbit + .else + @ ... and note which bits are done in the result. On the final pass, + @ this may subtract too much from the dividend, but the result will be ok, + @ since the "bit" will have been shifted out at the bottom. + cmp dividend, divisor + blo LSYM(Lover1) + sub dividend, dividend, divisor + orr result, result, curbit +LSYM(Lover1): + lsr work, divisor, #1 + cmp dividend, work + blo LSYM(Lover2) + sub dividend, dividend, work + lsr work, curbit, #1 + orr result, work +LSYM(Lover2): + lsr work, divisor, #2 + cmp dividend, work + blo LSYM(Lover3) + sub dividend, dividend, work + lsr work, curbit, #2 + orr result, work +LSYM(Lover3): + lsr work, divisor, #3 + cmp dividend, work + blo LSYM(Lover4) + sub dividend, dividend, work + lsr work, curbit, #3 + orr result, work +LSYM(Lover4): + .endif + + cmp dividend, #0 @ Early termination? + beq LSYM(Lover5) + lsr curbit, #4 @ No, any more bits to do? + beq LSYM(Lover5) + lsr divisor, #4 + b LSYM(Loop3) +LSYM(Lover5): + .if \modulo + @ Any subtractions that we should not have done will be recorded in + @ the top three bits of "overdone". Exactly which were not needed + @ are governed by the position of the bit, stored in ip. + mov work, #0xe + lsl work, #28 + and overdone, work + beq LSYM(Lgot_result) + + @ If we terminated early, because dividend became zero, then the + @ bit in ip will not be in the bottom nibble, and we should not + @ perform the additions below. We must test for this though + @ (rather relying upon the TSTs to prevent the additions) since + @ the bit in ip could be in the top two bits which might then match + @ with one of the smaller RORs. + mov curbit, ip + mov work, #0x7 + tst curbit, work + beq LSYM(Lgot_result) + + mov curbit, ip + mov work, #3 + ror curbit, work + tst overdone, curbit + beq LSYM(Lover6) + lsr work, divisor, #3 + add dividend, work +LSYM(Lover6): + mov curbit, ip + mov work, #2 + ror curbit, work + tst overdone, curbit + beq LSYM(Lover7) + lsr work, divisor, #2 + add dividend, work +LSYM(Lover7): + mov curbit, ip + mov work, #1 + ror curbit, work + tst overdone, curbit + beq LSYM(Lgot_result) + lsr work, divisor, #1 + add dividend, work + .endif +LSYM(Lgot_result): +.endm +/* ------------------------------------------------------------------------ */ +/* Start of the Real Functions */ +/* ------------------------------------------------------------------------ */ +#ifdef L_udivsi3 + + FUNC_START udivsi3 + FUNC_ALIAS aeabi_uidiv udivsi3 + +#ifdef __thumb__ + + cmp divisor, #0 + beq LSYM(Ldiv0) + mov curbit, #1 + mov result, #0 + + push { work } + cmp dividend, divisor + blo LSYM(Lgot_result) + + THUMB_DIV_MOD_BODY 0 + + mov r0, result + pop { work } + RET + +#else /* ARM version. */ + + subs r2, r1, #1 + RETc(eq) + bcc LSYM(Ldiv0) + cmp r0, r1 + bls 11f + tst r1, r2 + beq 12f + + ARM_DIV_BODY r0, r1, r2, r3 + + mov r0, r2 + RET + +11: moveq r0, #1 + movne r0, #0 + RET + +12: ARM_DIV2_ORDER r1, r2 + + mov r0, r0, lsr r2 + RET + +#endif /* ARM version */ + + DIV_FUNC_END udivsi3 + +FUNC_START aeabi_uidivmod +#ifdef __thumb__ + push {r0, r1, lr} + bl SYM(__udivsi3) + POP {r1, r2, r3} + mul r2, r0 + sub r1, r1, r2 + bx r3 +#else + stmfd sp!, { r0, r1, lr } + bl SYM(__udivsi3) + ldmfd sp!, { r1, r2, lr } + mul r3, r2, r0 + sub r1, r1, r3 + RET +#endif + FUNC_END aeabi_uidivmod + +#endif /* L_udivsi3 */ +/* ------------------------------------------------------------------------ */ +#ifdef L_umodsi3 + + FUNC_START umodsi3 + +#ifdef __thumb__ + + cmp divisor, #0 + beq LSYM(Ldiv0) + mov curbit, #1 + cmp dividend, divisor + bhs LSYM(Lover10) + RET + +LSYM(Lover10): + push { work } + + THUMB_DIV_MOD_BODY 1 + + pop { work } + RET + +#else /* ARM version. */ + + subs r2, r1, #1 @ compare divisor with 1 + bcc LSYM(Ldiv0) + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + RETc(ls) + + ARM_MOD_BODY r0, r1, r2, r3 + + RET + +#endif /* ARM version. */ + + DIV_FUNC_END umodsi3 + +#endif /* L_umodsi3 */ +/* ------------------------------------------------------------------------ */ +#ifdef L_divsi3 + + FUNC_START divsi3 + FUNC_ALIAS aeabi_idiv divsi3 + +#ifdef __thumb__ + cmp divisor, #0 + beq LSYM(Ldiv0) + + push { work } + mov work, dividend + eor work, divisor @ Save the sign of the result. + mov ip, work + mov curbit, #1 + mov result, #0 + cmp divisor, #0 + bpl LSYM(Lover10) + neg divisor, divisor @ Loops below use unsigned. +LSYM(Lover10): + cmp dividend, #0 + bpl LSYM(Lover11) + neg dividend, dividend +LSYM(Lover11): + cmp dividend, divisor + blo LSYM(Lgot_result) + + THUMB_DIV_MOD_BODY 0 + + mov r0, result + mov work, ip + cmp work, #0 + bpl LSYM(Lover12) + neg r0, r0 +LSYM(Lover12): + pop { work } + RET + +#else /* ARM version. */ + + cmp r1, #0 + eor ip, r0, r1 @ save the sign of the result. + beq LSYM(Ldiv0) + rsbmi r1, r1, #0 @ loops below use unsigned. + subs r2, r1, #1 @ division by 1 or -1 ? + beq 10f + movs r3, r0 + rsbmi r3, r0, #0 @ positive dividend value + cmp r3, r1 + bls 11f + tst r1, r2 @ divisor is power of 2 ? + beq 12f + + ARM_DIV_BODY r3, r1, r0, r2 + + cmp ip, #0 + rsbmi r0, r0, #0 + RET + +10: teq ip, r0 @ same sign ? + rsbmi r0, r0, #0 + RET + +11: movlo r0, #0 + moveq r0, ip, asr #31 + orreq r0, r0, #1 + RET + +12: ARM_DIV2_ORDER r1, r2 + + cmp ip, #0 + mov r0, r3, lsr r2 + rsbmi r0, r0, #0 + RET + +#endif /* ARM version */ + + DIV_FUNC_END divsi3 + +FUNC_START aeabi_idivmod +#ifdef __thumb__ + push {r0, r1, lr} + bl SYM(__divsi3) + POP {r1, r2, r3} + mul r2, r0 + sub r1, r1, r2 + bx r3 +#else + stmfd sp!, { r0, r1, lr } + bl SYM(__divsi3) + ldmfd sp!, { r1, r2, lr } + mul r3, r2, r0 + sub r1, r1, r3 + RET +#endif + FUNC_END aeabi_idivmod + +#endif /* L_divsi3 */ +/* ------------------------------------------------------------------------ */ +#ifdef L_modsi3 + + FUNC_START modsi3 + +#ifdef __thumb__ + + mov curbit, #1 + cmp divisor, #0 + beq LSYM(Ldiv0) + bpl LSYM(Lover10) + neg divisor, divisor @ Loops below use unsigned. +LSYM(Lover10): + push { work } + @ Need to save the sign of the dividend, unfortunately, we need + @ work later on. Must do this after saving the original value of + @ the work register, because we will pop this value off first. + push { dividend } + cmp dividend, #0 + bpl LSYM(Lover11) + neg dividend, dividend +LSYM(Lover11): + cmp dividend, divisor + blo LSYM(Lgot_result) + + THUMB_DIV_MOD_BODY 1 + + pop { work } + cmp work, #0 + bpl LSYM(Lover12) + neg dividend, dividend +LSYM(Lover12): + pop { work } + RET + +#else /* ARM version. */ + + cmp r1, #0 + beq LSYM(Ldiv0) + rsbmi r1, r1, #0 @ loops below use unsigned. + movs ip, r0 @ preserve sign of dividend + rsbmi r0, r0, #0 @ if negative make positive + subs r2, r1, #1 @ compare divisor with 1 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + bls 10f + + ARM_MOD_BODY r0, r1, r2, r3 + +10: cmp ip, #0 + rsbmi r0, r0, #0 + RET + +#endif /* ARM version */ + + DIV_FUNC_END modsi3 + +#endif /* L_modsi3 */ +/* ------------------------------------------------------------------------ */ +#ifdef L_dvmd_tls + + FUNC_START div0 + FUNC_ALIAS aeabi_idiv0 div0 + FUNC_ALIAS aeabi_ldiv0 div0 + + RET + + FUNC_END aeabi_ldiv0 + FUNC_END aeabi_idiv0 + FUNC_END div0 + +#endif /* L_divmodsi_tools */ +/* ------------------------------------------------------------------------ */ +#ifdef L_dvmd_lnx +@ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls + +/* Constant taken from <asm/signal.h>. */ +#define SIGFPE 8 + + ARM_FUNC_START div0 + + do_push {r1, lr} + mov r0, #SIGFPE + bl SYM(raise) __PLT__ + RETLDM r1 + + FUNC_END div0 + +#endif /* L_dvmd_lnx */ +/* ------------------------------------------------------------------------ */ +/* Dword shift operations. */ +/* All the following Dword shift variants rely on the fact that + shft xxx, Reg + is in fact done as + shft xxx, (Reg & 255) + so for Reg value in (32...63) and (-1...-31) we will get zero (in the + case of logical shifts) or the sign (for asr). */ + +#ifdef __ARMEB__ +#define al r1 +#define ah r0 +#else +#define al r0 +#define ah r1 +#endif + +/* Prevent __aeabi double-word shifts from being produced on SymbianOS. */ +#ifndef __symbian__ + +#ifdef L_lshrdi3 + + FUNC_START lshrdi3 + FUNC_ALIAS aeabi_llsr lshrdi3 + +#ifdef __thumb__ + lsr al, r2 + mov r3, ah + lsr ah, r2 + mov ip, r3 + sub r2, #32 + lsr r3, r2 + orr al, r3 + neg r2, r2 + mov r3, ip + lsl r3, r2 + orr al, r3 + RET +#else + subs r3, r2, #32 + rsb ip, r2, #32 + movmi al, al, lsr r2 + movpl al, ah, lsr r3 + orrmi al, al, ah, lsl ip + mov ah, ah, lsr r2 + RET +#endif + FUNC_END aeabi_llsr + FUNC_END lshrdi3 + +#endif + +#ifdef L_ashrdi3 + + FUNC_START ashrdi3 + FUNC_ALIAS aeabi_lasr ashrdi3 + +#ifdef __thumb__ + lsr al, r2 + mov r3, ah + asr ah, r2 + sub r2, #32 + @ If r2 is negative at this point the following step would OR + @ the sign bit into all of AL. That's not what we want... + bmi 1f + mov ip, r3 + asr r3, r2 + orr al, r3 + mov r3, ip +1: + neg r2, r2 + lsl r3, r2 + orr al, r3 + RET +#else + subs r3, r2, #32 + rsb ip, r2, #32 + movmi al, al, lsr r2 + movpl al, ah, asr r3 + orrmi al, al, ah, lsl ip + mov ah, ah, asr r2 + RET +#endif + + FUNC_END aeabi_lasr + FUNC_END ashrdi3 + +#endif + +#ifdef L_ashldi3 + + FUNC_START ashldi3 + FUNC_ALIAS aeabi_llsl ashldi3 + +#ifdef __thumb__ + lsl ah, r2 + mov r3, al + lsl al, r2 + mov ip, r3 + sub r2, #32 + lsl r3, r2 + orr ah, r3 + neg r2, r2 + mov r3, ip + lsr r3, r2 + orr ah, r3 + RET +#else + subs r3, r2, #32 + rsb ip, r2, #32 + movmi ah, ah, lsl r2 + movpl ah, al, lsl r3 + orrmi ah, ah, al, lsr ip + mov al, al, lsl r2 + RET +#endif + FUNC_END aeabi_llsl + FUNC_END ashldi3 + +#endif + +#endif /* __symbian__ */ + +/* ------------------------------------------------------------------------ */ +/* These next two sections are here despite the fact that they contain Thumb + assembler because their presence allows interworked code to be linked even + when the GCC library is this one. */ + +/* Do not build the interworking functions when the target architecture does + not support Thumb instructions. (This can be a multilib option). */ +#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\ + || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \ + || __ARM_ARCH__ >= 6 + +#if defined L_call_via_rX + +/* These labels & instructions are used by the Arm/Thumb interworking code. + The address of function to be called is loaded into a register and then + one of these labels is called via a BL instruction. This puts the + return address into the link register with the bottom bit set, and the + code here switches to the correct mode before executing the function. */ + + .text + .align 0 + .force_thumb + +.macro call_via register + THUMB_FUNC_START _call_via_\register + + bx \register + nop + + SIZE (_call_via_\register) +.endm + + call_via r0 + call_via r1 + call_via r2 + call_via r3 + call_via r4 + call_via r5 + call_via r6 + call_via r7 + call_via r8 + call_via r9 + call_via sl + call_via fp + call_via ip + call_via sp + call_via lr + +#endif /* L_call_via_rX */ + +/* Don't bother with the old interworking routines for Thumb-2. */ +/* ??? Maybe only omit these on v7m. */ +#ifndef __thumb2__ + +#if defined L_interwork_call_via_rX + +/* These labels & instructions are used by the Arm/Thumb interworking code, + when the target address is in an unknown instruction set. The address + of function to be called is loaded into a register and then one of these + labels is called via a BL instruction. This puts the return address + into the link register with the bottom bit set, and the code here + switches to the correct mode before executing the function. Unfortunately + the target code cannot be relied upon to return via a BX instruction, so + instead we have to store the resturn address on the stack and allow the + called function to return here instead. Upon return we recover the real + return address and use a BX to get back to Thumb mode. + + There are three variations of this code. The first, + _interwork_call_via_rN(), will push the return address onto the + stack and pop it in _arm_return(). It should only be used if all + arguments are passed in registers. + + The second, _interwork_r7_call_via_rN(), instead stores the return + address at [r7, #-4]. It is the caller's responsibility to ensure + that this address is valid and contains no useful data. + + The third, _interwork_r11_call_via_rN(), works in the same way but + uses r11 instead of r7. It is useful if the caller does not really + need a frame pointer. */ + + .text + .align 0 + + .code 32 + .globl _arm_return +LSYM(Lstart_arm_return): + cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return) + cfi_push 0, 0xe, -0x8, 0x8 + nop @ This nop is for the benefit of debuggers, so that + @ backtraces will use the correct unwind information. +_arm_return: + RETLDM unwind=LSYM(Lstart_arm_return) + cfi_end LSYM(Lend_arm_return) + + .globl _arm_return_r7 +_arm_return_r7: + ldr lr, [r7, #-4] + bx lr + + .globl _arm_return_r11 +_arm_return_r11: + ldr lr, [r11, #-4] + bx lr + +.macro interwork_with_frame frame, register, name, return + .code 16 + + THUMB_FUNC_START \name + + bx pc + nop + + .code 32 + tst \register, #1 + streq lr, [\frame, #-4] + adreq lr, _arm_return_\frame + bx \register + + SIZE (\name) +.endm + +.macro interwork register + .code 16 + + THUMB_FUNC_START _interwork_call_via_\register + + bx pc + nop + + .code 32 + .globl LSYM(Lchange_\register) +LSYM(Lchange_\register): + tst \register, #1 + streq lr, [sp, #-8]! + adreq lr, _arm_return + bx \register + + SIZE (_interwork_call_via_\register) + + interwork_with_frame r7,\register,_interwork_r7_call_via_\register + interwork_with_frame r11,\register,_interwork_r11_call_via_\register +.endm + + interwork r0 + interwork r1 + interwork r2 + interwork r3 + interwork r4 + interwork r5 + interwork r6 + interwork r7 + interwork r8 + interwork r9 + interwork sl + interwork fp + interwork ip + interwork sp + + /* The LR case has to be handled a little differently... */ + .code 16 + + THUMB_FUNC_START _interwork_call_via_lr + + bx pc + nop + + .code 32 + .globl .Lchange_lr +.Lchange_lr: + tst lr, #1 + stmeqdb r13!, {lr, pc} + mov ip, lr + adreq lr, _arm_return + bx ip + + SIZE (_interwork_call_via_lr) + +#endif /* L_interwork_call_via_rX */ +#endif /* !__thumb2__ */ +#endif /* Arch supports thumb. */ + +#ifndef __symbian__ +//#include "ieee754-df.S" +//#include "ieee754-sf.S" +#include "bpabi.S" +#endif /* __symbian__ */ diff --git a/setup/Linux/arm/longlong.h b/setup/Linux/arm/longlong.h new file mode 100644 index 0000000..a2f4e56 --- /dev/null +++ b/setup/Linux/arm/longlong.h @@ -0,0 +1,1465 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 + Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* You have to define the following before including this file: + + UWtype -- An unsigned type, default type for operations (typically a "word") + UHWtype -- An unsigned type, at least half the size of UWtype. + UDWtype -- An unsigned type, at least twice as large a UWtype + W_TYPE_SIZE -- size in bits of UWtype + + UQItype -- Unsigned 8 bit type. + SItype, USItype -- Signed and unsigned 32 bit types. + DItype, UDItype -- Signed and unsigned 64 bit types. + + On a 32 bit machine UWtype should typically be USItype; + on a 64 bit machine, UWtype should typically be UDItype. */ + +#define __BITS4 (W_TYPE_SIZE / 4) +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) + +#ifndef W_TYPE_SIZE +#define W_TYPE_SIZE 32 +#define UWtype USItype +#define UHWtype USItype +#define UDWtype UDItype +#endif + +extern const UQItype __clz_tab[256]; + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two + UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype + word product in HIGH_PROD and LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a + UDWtype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a UDWtype, composed by the UWtype integers + HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient + in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less + than DENOMINATOR for correct operation. If, in addition, the most + significant bit of DENOMINATOR must be 1, then the pre-processor symbol + UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The quotient + is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from the + msb to the first nonzero bit in the UWtype X. This is the number of + steps X needs to be shifted left to set the msb. Undefined for X == 0, + unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. + + 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts + from the least significant end. + + 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two UWtype integers, composed by + HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 + respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow + (i.e. carry out) is not stored anywhere, and is lost. + + 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, + high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, + composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and + LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE + and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +/* The CPUs come in alphabetical order below. + + Please add support for more CPUs here, or improve the current support + for the CPUs below! + (E.g. WE32100, IBM360.) */ + +#if defined (__GNUC__) && !defined (NO_ASM) + +/* We sometimes need to clobber "cc" with gcc2, but that would not be + understood by gcc1. Use cpp to avoid major code duplication. */ +#if __GNUC__ < 2 +#define __CLOBBER_CC +#define __AND_CLOBBER_CC +#else /* __GNUC__ >= 2 */ +#define __CLOBBER_CC : "cc" +#define __AND_CLOBBER_CC , "cc" +#endif /* __GNUC__ < 2 */ + +#if defined (__alpha) && W_TYPE_SIZE == 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + (ph) = __builtin_alpha_umulh (__m0, __m1); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 46 +#ifndef LONGLONG_STANDALONE +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { UDItype __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ + } while (0) +extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); +#define UDIV_TIME 220 +#endif /* LONGLONG_STANDALONE */ +#ifdef __alpha_cix__ +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) +#define COUNT_LEADING_ZEROS_0 64 +#else +#define count_leading_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __t = __builtin_alpha_cmpbge (0, __xr); \ + __a = __clz_tab[__t ^ 0xff] - 1; \ + __t = __builtin_alpha_extbl (__xr, __a); \ + (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ + } while (0) +#define count_trailing_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __t = __builtin_alpha_cmpbge (0, __xr); \ + __t = ~__t & -~__t; \ + __a = ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + __t = __builtin_alpha_extbl (__xr, __a); \ + __a <<= 3; \ + __t &= -__t; \ + __a += ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + (COUNT) = __a; \ + } while (0) +#endif /* __alpha_cix__ */ +#endif /* __alpha */ + +#if defined (__arc__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +/* Call libgcc routine. */ +#define umul_ppmm(w1, w0, u, v) \ +do { \ + DWunion __w; \ + __w.ll = __umulsidi3 (u, v); \ + w1 = __w.s.high; \ + w0 = __w.s.low; \ +} while (0) +#define __umulsidi3 __umulsidi3 +UDItype __umulsidi3 (USItype, USItype); +#endif + +#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rI" ((USItype) (bl)) __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rI" ((USItype) (bl)) __CLOBBER_CC) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm\n" \ + " mov %2, %5, lsr #16\n" \ + " mov %0, %6, lsr #16\n" \ + " bic %3, %5, %2, lsl #16\n" \ + " bic %4, %6, %0, lsl #16\n" \ + " mul %1, %3, %4\n" \ + " mul %4, %2, %4\n" \ + " mul %3, %0, %3\n" \ + " mul %0, %2, %0\n" \ + " adds %3, %4, %3\n" \ + " addcs %0, %0, #65536\n" \ + " adds %1, %1, %3, lsl #16\n" \ + " adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)) __CLOBBER_CC );} +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#if defined (__CRIS__) && __CRIS_arch_version >= 3 +#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +#if __CRIS_arch_version >= 8 +#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +#endif +#endif /* __CRIS__ */ + +#if defined (__hppa) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "%rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#if defined (_PA_RISC1_1) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + union \ + { \ + UDItype __f; \ + struct {USItype __w1, __w0;} __w1w0; \ + } __t; \ + __asm__ ("xmpyu %1,%2,%0" \ + : "=x" (__t.__f) \ + : "x" ((USItype) (u)), \ + "x" ((USItype) (v))); \ + (w1) = __t.__w1w0.__w1; \ + (w0) = __t.__w1w0.__w0; \ + } while (0) +#define UMUL_TIME 8 +#else +#define UMUL_TIME 30 +#endif +#define UDIV_TIME 40 +#define count_leading_zeros(count, x) \ + do { \ + USItype __tmp; \ + __asm__ ( \ + "ldi 1,%0\n" \ +" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ +" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ +" ldo 16(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ +" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ +" ldo 8(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ +" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ +" ldo 4(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ +" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ +" ldo 2(%0),%0 ; Yes. Perform add.\n" \ +" extru %1,30,1,%1 ; Extract bit 1.\n" \ +" sub %0,%1,%0 ; Subtract it.\n" \ + : "=r" (count), "=r" (__tmp) : "1" (x)); \ + } while (0) +#endif + +#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 +#define smul_ppmm(xh, xl, m0, m1) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __x; \ + __asm__ ("lr %N0,%1\n\tmr %0,%2" \ + : "=&r" (__x.__ll) \ + : "r" (m0), "r" (m1)); \ + (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __x; \ + __x.__i.__h = n1; __x.__i.__l = n0; \ + __asm__ ("dr %0,%2" \ + : "=r" (__x.__ll) \ + : "0" (__x.__ll), "r" (d)); \ + (q) = __x.__i.__l; (r) = __x.__i.__h; \ + } while (0) +#endif + +#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mul{l} %3" \ + : "=a" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "rm" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, dv) \ + __asm__ ("div{l} %4" \ + : "=a" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "rm" ((USItype) (dv))) +#define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) +#define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* 80x86 */ + +#if (defined (__x86_64__) || defined (__i386__)) && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}" \ + : "=r" ((UDItype) (sh)), \ + "=&r" ((UDItype) (sl)) \ + : "%0" ((UDItype) (ah)), \ + "rme" ((UDItype) (bh)), \ + "%1" ((UDItype) (al)), \ + "rme" ((UDItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}" \ + : "=r" ((UDItype) (sh)), \ + "=&r" ((UDItype) (sl)) \ + : "0" ((UDItype) (ah)), \ + "rme" ((UDItype) (bh)), \ + "1" ((UDItype) (al)), \ + "rme" ((UDItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mul{q} %3" \ + : "=a" ((UDItype) (w0)), \ + "=d" ((UDItype) (w1)) \ + : "%0" ((UDItype) (u)), \ + "rm" ((UDItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, dv) \ + __asm__ ("div{q} %4" \ + : "=a" ((UDItype) (q)), \ + "=d" ((UDItype) (r)) \ + : "0" ((UDItype) (n0)), \ + "1" ((UDItype) (n1)), \ + "rm" ((UDItype) (dv))) +#define count_leading_zeros(count, x) ((count) = __builtin_clzl (x)) +#define count_trailing_zeros(count, x) ((count) = __builtin_ctzl (x)) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* x86_64 */ + +#if defined (__i960__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__xx.__ll) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__w) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + __w; }) +#endif /* __i960__ */ + +#if defined (__M32R__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#endif /* __M32R__ */ + +#if defined (__mc68000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) + +/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r. */ +#if (defined (__mc68020__) && !defined (__mc68060__)) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "dmi" ((USItype) (v))) +#define UMUL_TIME 45 +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divu%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) +#define UDIV_TIME 90 +#define sdiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divs%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) + +#elif defined (__mcoldfire__) /* not mc68020 */ + +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm\n" \ + " move%.l %2,%/d0\n" \ + " move%.l %3,%/d1\n" \ + " move%.l %/d0,%/d2\n" \ + " swap %/d0\n" \ + " move%.l %/d1,%/d3\n" \ + " swap %/d1\n" \ + " move%.w %/d2,%/d4\n" \ + " mulu %/d3,%/d4\n" \ + " mulu %/d1,%/d2\n" \ + " mulu %/d0,%/d3\n" \ + " mulu %/d0,%/d1\n" \ + " move%.l %/d4,%/d0\n" \ + " clr%.w %/d0\n" \ + " swap %/d0\n" \ + " add%.l %/d0,%/d2\n" \ + " add%.l %/d3,%/d2\n" \ + " jcc 1f\n" \ + " add%.l %#65536,%/d1\n" \ + "1: swap %/d2\n" \ + " moveq %#0,%/d0\n" \ + " move%.w %/d2,%/d0\n" \ + " move%.w %/d4,%/d2\n" \ + " move%.l %/d2,%1\n" \ + " add%.l %/d1,%/d0\n" \ + " move%.l %/d0,%0" \ + : "=g" ((USItype) (xh)), \ + "=g" ((USItype) (xl)) \ + : "g" ((USItype) (a)), \ + "g" ((USItype) (b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 +#else /* not ColdFire */ +/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm\n" \ + " move%.l %2,%/d0\n" \ + " move%.l %3,%/d1\n" \ + " move%.l %/d0,%/d2\n" \ + " swap %/d0\n" \ + " move%.l %/d1,%/d3\n" \ + " swap %/d1\n" \ + " move%.w %/d2,%/d4\n" \ + " mulu %/d3,%/d4\n" \ + " mulu %/d1,%/d2\n" \ + " mulu %/d0,%/d3\n" \ + " mulu %/d0,%/d1\n" \ + " move%.l %/d4,%/d0\n" \ + " eor%.w %/d0,%/d0\n" \ + " swap %/d0\n" \ + " add%.l %/d0,%/d2\n" \ + " add%.l %/d3,%/d2\n" \ + " jcc 1f\n" \ + " add%.l %#65536,%/d1\n" \ + "1: swap %/d2\n" \ + " moveq %#0,%/d0\n" \ + " move%.w %/d2,%/d0\n" \ + " move%.w %/d4,%/d2\n" \ + " move%.l %/d2,%1\n" \ + " add%.l %/d1,%/d0\n" \ + " move%.l %/d0,%0" \ + : "=g" ((USItype) (xh)), \ + "=g" ((USItype) (xl)) \ + : "g" ((USItype) (a)), \ + "g" ((USItype) (b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 + +#endif /* not mc68020 */ + +/* The '020, '030, '040 and '060 have bitfield insns. + cpu32 disguises as a 68020, but lacks them. */ +#if defined (__mc68020__) && !defined (__mcpu32__) +#define count_leading_zeros(count, x) \ + __asm__ ("bfffo %1{%b2:%b2},%0" \ + : "=d" ((USItype) (count)) \ + : "od" ((USItype) (x)), "n" (0)) +/* Some ColdFire architectures have a ff1 instruction supported via + __builtin_clz. */ +#elif defined (__mcfisaaplus__) || defined (__mcfisac__) +#define count_leading_zeros(count,x) ((count) = __builtin_clz (x)) +#define COUNT_LEADING_ZEROS_0 32 +#endif +#endif /* mc68000 */ + +#if defined (__m88000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("ff1 %0,%1" \ + : "=r" (__cbtmp) \ + : "r" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define COUNT_LEADING_ZEROS_0 63 /* sic */ +#if defined (__mc88110__) +#define umul_ppmm(wh, wl, u, v) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mulu.d %0,%1,%2" \ + : "=r" (__xx.__ll) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))); \ + (wh) = __xx.__i.__h; \ + (wl) = __xx.__i.__l; \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __q; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("divu.d %0,%1,%2" \ + : "=r" (__q) \ + : "r" (__xx.__ll), \ + "r" ((USItype) (d))); \ + (r) = (n0) - __q * (d); (q) = __q; }) +#define UMUL_TIME 5 +#define UDIV_TIME 25 +#else +#define UMUL_TIME 17 +#define UDIV_TIME 150 +#endif /* __mc88110__ */ +#endif /* __m88000__ */ + +#if defined (__mips__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("multu %2,%3" \ + : "=l" ((USItype) (w0)), \ + "=h" ((USItype) (w1)) \ + : "d" ((USItype) (u)), \ + "d" ((USItype) (v))) +#define UMUL_TIME 10 +#define UDIV_TIME 100 + +#if (__mips == 32 || __mips == 64) && ! __mips16 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +#define COUNT_LEADING_ZEROS_0 32 +#endif +#endif /* __mips__ */ + +#if defined (__ns32000__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("meid %2,%0" \ + : "=g" (__xx.__ll) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("meid %2,%0" \ + : "=g" (__w) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + __w; }) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("deid %2,%0" \ + : "=g" (__xx.__ll) \ + : "0" (__xx.__ll), \ + "g" ((USItype) (d))); \ + (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) +#define count_trailing_zeros(count,x) \ + do { \ + __asm__ ("ffsd %2,%0" \ + : "=r" ((USItype) (count)) \ + : "0" ((USItype) 0), \ + "r" ((USItype) (x))); \ + } while (0) +#endif /* __ns32000__ */ + +/* FIXME: We should test _IBMR2 here when we add assembly support for the + system vendor compilers. + FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good + enough, since that hits ARM and m68k too. */ +#if (defined (_ARCH_PPC) /* AIX */ \ + || defined (_ARCH_PWR) /* AIX */ \ + || defined (_ARCH_COM) /* AIX */ \ + || defined (__powerpc__) /* gcc */ \ + || defined (__POWERPC__) /* BEOS */ \ + || defined (__ppc__) /* Darwin */ \ + || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ + || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ + && CPU_FAMILY == PPC) \ + ) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 32 +#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ + || defined (__ppc__) \ + || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ + || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ + && CPU_FAMILY == PPC) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + SItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 +#define UDIV_TIME 120 +#elif defined (_ARCH_PWR) +#define UMUL_TIME 8 +#define smul_ppmm(xh, xl, m0, m1) \ + __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) +#define SMUL_TIME 4 +#define sdiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) +#define UDIV_TIME 100 +#endif +#endif /* 32-bit POWER architecture variants. */ + +/* We should test _IBMR2 here when we add assembly support for the system + vendor compilers. */ +#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + DItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 /* ??? */ +#define UDIV_TIME 120 /* ??? */ +#endif /* 64-bit PowerPC. */ + +#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("a %1,%5\n\tae %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("s %1,%5\n\tse %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ( \ + "s r2,r2\n" \ +" mts r10,%2\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" cas %0,r2,r0\n" \ +" mfs r10,%1" \ + : "=r" ((USItype) (ph)), \ + "=r" ((USItype) (pl)) \ + : "%r" (__m0), \ + "r" (__m1) \ + : "r2"); \ + (ph) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 20 +#define UDIV_TIME 200 +#define count_leading_zeros(count, x) \ + do { \ + if ((x) >= 0x10000) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x) >> 16)); \ + else \ + { \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + (count) += 16; \ + } \ + } while (0) +#endif + +#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32 +#ifndef __sh1__ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ( \ + "dmulu.l %2,%3\n\tsts%M1 macl,%1\n\tsts%M0 mach,%0" \ + : "=r<" ((USItype)(w1)), \ + "=r<" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v)) \ + : "macl", "mach") +#define UMUL_TIME 5 +#endif + +/* This is the same algorithm as __udiv_qrnnd_c. */ +#define UDIV_NEEDS_NORMALIZATION 1 + +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { \ + extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ + __attribute__ ((visibility ("hidden"))); \ + /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ + __asm__ ( \ + "mov%M4 %4,r5\n" \ +" swap.w %3,r4\n" \ +" swap.w r5,r6\n" \ +" jsr @%5\n" \ +" shll16 r6\n" \ +" swap.w r4,r4\n" \ +" jsr @%5\n" \ +" swap.w r1,%0\n" \ +" or r1,%0" \ + : "=r" (q), "=&z" (r) \ + : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ + : "r1", "r2", "r4", "r5", "r6", "pr"); \ + } while (0) + +#define UDIV_TIME 80 + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("clrt;subc %5,%1; subc %4,%0" \ + : "=r" (sh), "=r" (sl) \ + : "0" (ah), "1" (al), "r" (bh), "r" (bl)) + +#endif /* __sh__ */ + +#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 +#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) +#define count_leading_zeros(count, x) \ + do \ + { \ + UDItype x_ = (USItype)(x); \ + SItype c_; \ + \ + __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ + (count) = c_ - 31; \ + } \ + while (0) +#define COUNT_LEADING_ZEROS_0 32 +#endif + +#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ + && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#if defined (__sparc_v8__) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__n1)), \ + "r" ((USItype) (__n0)), \ + "r" ((USItype) (__d))) +#else +#if defined (__sparclite__) +/* This has hardware multiply but not divide. It also has two additional + instructions scan (ffs from high bit) and divscc. */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ +" tst %%g0\n" \ +" divscc %3,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%0\n" \ +" rd %%y,%1\n" \ +" bl,a 1f\n" \ +" add %1,%4,%1\n" \ +"1: ! End of inline udiv_qrnnd" \ + : "=r" ((USItype) (q)), \ + "=r" ((USItype) (r)) \ + : "r" ((USItype) (n1)), \ + "r" ((USItype) (n0)), \ + "rI" ((USItype) (d)) \ + : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME 37 +#define count_leading_zeros(count, x) \ + do { \ + __asm__ ("scan %1,1,%0" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + } while (0) +/* Early sparclites return 63 for an argument of 0, but they warn that future + implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 + undefined. */ +#else +/* SPARC without integer multiplication and divide instructions. + (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("! Inlined umul_ppmm\n" \ +" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ +" sra %3,31,%%o5 ! Don't move this insn\n" \ +" and %2,%%o5,%%o5 ! Don't move this insn\n" \ +" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,0,%%g1\n" \ +" add %%g1,%%o5,%0\n" \ +" rd %%y,%1" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "%rI" ((USItype) (u)), \ + "r" ((USItype) (v)) \ + : "g1", "o5" __AND_CLOBBER_CC) +#define UMUL_TIME 39 /* 39 instructions */ +/* It's quite necessary to add this much assembler for the sparc. + The default udiv_qrnnd (in C) is more than 10 times slower! */ +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" mov 32,%%g1\n" \ +" subcc %1,%2,%%g0\n" \ +"1: bcs 5f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +" addx %1,%1,%1 ! so this can't give carry\n" \ +" subcc %%g1,1,%%g1\n" \ +"2: bne 1b\n" \ +" subcc %1,%2,%%g0\n" \ +" bcs 3f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" b 3f\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +"4: sub %1,%2,%1\n" \ +"5: addxcc %1,%1,%1\n" \ +" bcc 2b\n" \ +" subcc %%g1,1,%%g1\n" \ +"! Got carry from n. Subtract next step to cancel this carry.\n" \ +" bne 4b\n" \ +" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ +" sub %1,%2,%1\n" \ +"3: xnor %0,0,%0\n" \ +" ! End of inline udiv_qrnnd" \ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__d)), \ + "1" ((USItype) (__n1)), \ + "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ +#endif /* __sparclite__ */ +#endif /* __sparc_v8__ */ +#endif /* sparc32 */ + +#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ + && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\t" \ + "add %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "add %0, 1, %0\n" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "%rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "%rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\t" \ + "sub %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "sub %0, 1, %0\n\t" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define umul_ppmm(wh, wl, u, v) \ + do { \ + UDItype tmp1, tmp2, tmp3, tmp4; \ + __asm__ __volatile__ ( \ + "srl %7,0,%3\n\t" \ + "mulx %3,%6,%1\n\t" \ + "srlx %6,32,%2\n\t" \ + "mulx %2,%3,%4\n\t" \ + "sllx %4,32,%5\n\t" \ + "srl %6,0,%3\n\t" \ + "sub %1,%5,%5\n\t" \ + "srlx %5,32,%5\n\t" \ + "addcc %4,%5,%4\n\t" \ + "srlx %7,32,%5\n\t" \ + "mulx %3,%5,%3\n\t" \ + "mulx %2,%5,%5\n\t" \ + "sethi %%hi(0x80000000),%2\n\t" \ + "addcc %4,%3,%4\n\t" \ + "srlx %4,32,%4\n\t" \ + "add %2,%2,%2\n\t" \ + "movcc %%xcc,%%g0,%2\n\t" \ + "addcc %5,%4,%5\n\t" \ + "sllx %3,32,%3\n\t" \ + "add %1,%3,%1\n\t" \ + "add %5,%2,%0" \ + : "=r" ((UDItype)(wh)), \ + "=&r" ((UDItype)(wl)), \ + "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ + : "r" ((UDItype)(u)), \ + "r" ((UDItype)(v)) \ + __CLOBBER_CC); \ + } while (0) +#define UMUL_TIME 96 +#define UDIV_TIME 230 +#endif /* sparc64 */ + +#if defined (__vax__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union { \ + UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("emul %1,%2,$0,%0" \ + : "=r" (__xx.__ll) \ + : "g" (__m0), \ + "g" (__m1)); \ + (xh) = __xx.__i.__h; \ + (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("ediv %3,%2,%0,%1" \ + : "=g" (q), "=g" (r) \ + : "g" (__xx.__ll), "g" (d)); \ + } while (0) +#endif /* __vax__ */ + +#if defined (__xtensa__) && W_TYPE_SIZE == 32 +/* This code is not Xtensa-configuration-specific, so rely on the compiler + to expand builtin functions depending on what configuration features + are available. This avoids library calls when the operation can be + performed in-line. */ +#define umul_ppmm(w1, w0, u, v) \ + do { \ + DWunion __w; \ + __w.ll = __builtin_umulsidi3 (u, v); \ + w1 = __w.s.high; \ + w0 = __w.s.low; \ + } while (0) +#define __umulsidi3(u, v) __builtin_umulsidi3 (u, v) +#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +#endif /* __xtensa__ */ + +#if defined (__z8000__) && W_TYPE_SIZE == 16 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "%0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "%1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {long int __ll; \ + struct {unsigned int __h, __l;} __i; \ + } __xx; \ + unsigned int __m0 = (m0), __m1 = (m1); \ + __asm__ ("mult %S0,%H3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "rQR" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((signed int) __m0 >> 15) & __m1) \ + + (((signed int) __m1 >> 15) & __m0)); \ + } while (0) +#endif /* __z8000__ */ + +#endif /* __GNUC__ */ + +/* If this machine has no inline assembler, use C macros. */ + +#if !defined (add_ssaaaa) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (sub_ddmmss) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) +#endif + +/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of + smul_ppmm. */ +#if !defined (umul_ppmm) && defined (smul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __w1; \ + UWtype __xm0 = (u), __xm1 = (v); \ + smul_ppmm (__w1, w0, __xm0, __xm1); \ + (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ + + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ + } while (0) +#endif + +/* If we still don't have umul_ppmm, define it using plain C. */ +#if !defined (umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __x0, __x1, __x2, __x3; \ + UHWtype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (UWtype) __ul * __vl; \ + __x1 = (UWtype) __ul * __vh; \ + __x2 = (UWtype) __uh * __vl; \ + __x3 = (UWtype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) +#endif + +#if !defined (__umulsidi3) +#define __umulsidi3(u, v) \ + ({DWunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +/* Define this unconditionally, so it can be used for debugging. */ +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0; \ + UWtype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (UWtype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (UWtype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (UWtype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through + __udiv_w_sdiv (defined in libgcc or elsewhere). */ +#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) +#define udiv_qrnnd(q, r, nh, nl, d) \ + do { \ + USItype __r; \ + (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ + (r) = __r; \ + } while (0) +#endif + +/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +#if !defined (udiv_qrnnd) +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c +#endif + +#if !defined (count_leading_zeros) +#define count_leading_zeros(count, x) \ + do { \ + UWtype __xr = (x); \ + UWtype __a; \ + \ + if (W_TYPE_SIZE <= 32) \ + { \ + __a = __xr < ((UWtype)1<<2*__BITS4) \ + ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ + : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ + } \ + else \ + { \ + for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) +#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif + +#if !defined (count_trailing_zeros) +/* Define count_trailing_zeros using count_leading_zeros. The latter might be + defined in asm, but if it is not, the C version above is good enough. */ +#define count_trailing_zeros(count, x) \ + do { \ + UWtype __ctz_x = (x); \ + UWtype __ctz_c; \ + count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ + (count) = W_TYPE_SIZE - 1 - __ctz_c; \ + } while (0) +#endif + +#ifndef UDIV_NEEDS_NORMALIZATION +#define UDIV_NEEDS_NORMALIZATION 0 +#endif diff --git a/setup/Linux/build.sh b/setup/Linux/build.sh new file mode 100644 index 0000000..e889bfe --- /dev/null +++ b/setup/Linux/build.sh @@ -0,0 +1,240 @@ +#!/bin/sh + +. ./.directories + +if gawk '' >/dev/null +then + TXT2MAN=$SRCDIR/setup/txt2man +else + echo "No gawk found. Using lesser replacement" >&2 + cc -o txt2man origdir/setup/txt2man.c + TXT2MAN=./txt2man +fi + +[ -z "$LD" ] && LD=ld + +rm -rf prototype + +mkdir prototype +mkdir prototype/etc +echo "OSSLIBDIR=$OSSLIBDIR" > prototype/etc/oss.conf +mkdir prototype/usr +mkdir prototype/usr/bin +mkdir prototype/usr/share +mkdir prototype/usr/share/man +mkdir prototype/usr/share/man/man1 +mkdir prototype/usr/share/man/man7 +mkdir prototype/usr/share/man/man8 +mkdir prototype/usr/sbin +mkdir -p prototype/$OSSLIBDIR +mkdir prototype/$OSSLIBDIR/etc +mkdir prototype/$OSSLIBDIR/save +mkdir prototype/$OSSLIBDIR/conf.tmpl +mkdir prototype/$OSSLIBDIR/lib +mkdir prototype/$OSSLIBDIR/modules.regparm +mkdir prototype/$OSSLIBDIR/modules.noregparm +mkdir prototype/$OSSLIBDIR/objects.regparm +mkdir prototype/$OSSLIBDIR/objects.noregparm +mkdir prototype/$OSSLIBDIR/include +mkdir prototype/$OSSLIBDIR/include/sys +mkdir prototype/$OSSLIBDIR/include/internals +mkdir prototype/$OSSLIBDIR/build + +chmod 700 prototype/$OSSLIBDIR/modules.* +chmod 700 prototype/$OSSLIBDIR/objects.* +chmod 700 prototype/$OSSLIBDIR/build +chmod 700 prototype/$OSSLIBDIR/save + +if test -f regparm && test "`cat regparm` " = "1 " +then + MODULES=modules.regparm + OBJECTS=objects.regparm +else + MODULES=modules.noregparm + OBJECTS=objects.noregparm +fi + +cp .version prototype/$OSSLIBDIR/version.dat + +if test "`uname -m` " != "arm " +then + if ! test -f regparm + then + echo Error: ./regparm is missing + exit 1 + fi + cp regparm prototype/$OSSLIBDIR/build +fi + +# Regenerating the config file templates +rm -f /tmp/confgen +if ! cc -o /tmp/confgen ./setup/Linux/confgen.c +then + echo Building confgen failed + exit 1 +fi + +if ! /tmp/confgen prototype/$OSSLIBDIR/conf.tmpl $OSSLIBDIR/conf kernel/drv/* kernel/nonfree/drv/* +then + echo Running confgen failed + exit 1 +fi + +rm -f /tmp/confgen + +cp $SRCDIR/include/*.h prototype/$OSSLIBDIR/include/sys/ +cp $SRCDIR/kernel/framework/include/midiparser.h prototype/$OSSLIBDIR/include/ +cp -f $SRCDIR/kernel/OS/Linux/wrapper/wrap.h prototype/$OSSLIBDIR/build/ +cp -f $SRCDIR/kernel/framework/include/udi.h prototype/$OSSLIBDIR/build/ +cp -a $SRCDIR/kernel/framework/include/*_core.h kernel/framework/include/local_config.h prototype/$OSSLIBDIR/include/internals +cp $SRCDIR/kernel/framework/include/ossddk/*.h prototype/$OSSLIBDIR/include/internals +cp kernel/framework/include/timestamp.h prototype/$OSSLIBDIR/include/internals +cp kernel/framework/include/ossddk/oss_limits.h prototype/$OSSLIBDIR/include/internals + +cat > prototype/$OSSLIBDIR/include/internals/WARNING.txt << EOF +Caution: All header files included in this directory are there only because + some parts of OSS may need to be re-compiled. It is not safe to use + these files for any purposes because they will change between OSS + versions/builds. +EOF + +(cd target/bin; rm -f ossrecord; ln -s ossplay ossrecord) +cp -f target/build/* prototype/$OSSLIBDIR/build/ +cp -f target/bin/* prototype/usr/bin +cp -f target/sbin/* prototype/usr/sbin + +cp -a $SRCDIR/setup/Linux/oss/* prototype/$OSSLIBDIR/ +cp -a $SRCDIR/setup/Linux/sbin prototype/usr/ +chmod +x prototype/$OSSLIBDIR/scripts/* + +if ! $LD -r -o prototype/$OSSLIBDIR/$OBJECTS/osscore.o target/objects/*.o +then + echo Linking osscore failed! + exit 1 +fi + +rm -f devlist.txt devices.list + +for n in `find kernel/ -name .devices` +do + cat $n >> devices.list +done + +for n in target/modules/*.o +do + N=`basename $n .o` + $LD -r -o prototype/$OSSLIBDIR/$MODULES/$N.o $n + echo Check devices for $N + grep "^$N[ ]" ./devices.list >> devlist.txt + + rm -f /tmp/ossman.txt + + if test -f $SRCDIR/kernel/drv/$N/$N.man + then + sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/drv/$N/$N.man > /tmp/ossman.txt + $TXT2MAN -t "$CMD" -v "OSS Devices" -s 7 /tmp/ossman.txt | gzip -9 > prototype/usr/share/man/man7/$N.7.gz + else + if test -f $SRCDIR/kernel/nonfree/drv/$N/$N.man + then + sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/nonfree/drv/$N/$N.man > /tmp/ossman.txt + $TXT2MAN -t "$CMD" -v "OSS Devices" -s 7 $SRCDIR/kernel/nonfree/drv/$N/$N.man | gzip -9 > prototype/usr/share/man/man7/$N.7.gz + fi + fi +done + +sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/drv/osscore/osscore.man > /tmp/ossman.txt +$TXT2MAN -t "osscore" -v "OSS Devices" -s 7 /tmp/ossman.txt | gzip -9 > prototype/usr/share/man/man7/osscore.7.gz +rm -f /tmp/ossman.txt + +# Link the optional NOREGPARM modules +if test -d noregparm +then + $LD -r -o prototype/$OSSLIBDIR/objects.noregparm/osscore.o noregparm/target/objects/*.o + + for n in noregparm/target/modules/*.o + do + N=`basename $n .o` + $LD -r -o prototype/$OSSLIBDIR/modules.noregparm/$N.o $n + done +fi + +for n in $SRCDIR/misc/man7/*.man +do + N=`basename $n .man` + + $TXT2MAN -t "$CMD" -v "OSS Devices" -s 7 $n | gzip -9 > prototype/usr/share/man/man7/$N.7.gz +done + +for n in $SRCDIR/misc/man1m/*.man +do + N=`basename $n .man` + $TXT2MAN -t "$CMD" -v "OSS System Administration Commands" -s 1 $n | gzip -9 > prototype/usr/share/man/man1/$N.1.gz +done + +if ! cp lib/libOSSlib/libOSSlib.so lib/libsalsa/.libs/libsalsa.so.2.0.0 prototype/$OSSLIBDIR/lib +then + echo Warning: No libsalsa library compiled +fi + +cp target/lib/* prototype/$OSSLIBDIR/lib + +cp devlist.txt prototype/$OSSLIBDIR/etc/devices.list + +if test -d kernel/nonfree +then + cp devlist.txt $SRCDIR/devlists/Linux +fi + +# Generate Man pages for commands +for i in target/bin/* +do +CMD=`basename $i` +$TXT2MAN -t "$CMD" -v "OSS User Commands" -s 1 cmd/$CMD/$CMD.man | gzip -9 > prototype/usr/share/man/man1/$CMD.1.gz +echo done $CMD +done + +for i in target/sbin/* +do + CMD=`basename $i` + if test -f cmd/$CMD/$CMD.man + then + $TXT2MAN -t "$CMD" -v "OSS System Administration Commands" -s 8 cmd/$CMD/$CMD.man | gzip -9 > prototype/usr/share/man/man8/$CMD.8.gz + echo done $CMD + fi +done + +$TXT2MAN -t "ossdetect" -v "User Commands" -s 8 os_cmd/Linux/ossdetect/ossdetect.man | gzip -9 > prototype/usr/share/man/man8/ossdetect.8.gz +echo done ossdetect + +cp -f $SRCDIR/oss/lib/flashsupport.c prototype/$OSSLIBDIR/lib + +# Licensing stuff +if test -f 4front-private/osslic.c +then + cc -o prototype/usr/sbin/osslic -Isetup -Ikernel/nonfree/include -Ikernel/framework/include -Iinclude -Ikernel/OS/Linux -I$SRCDIR $SRCDIR/4front-private/osslic.c + strip prototype/usr/sbin/osslic + + BITS=3 # Default to 32 bit ELF format + if test "`uname -m` " = "x86_64 " + then + BITS=6 # Use 64 bit ELF format + fi + prototype/usr/sbin/osslic -q -u -$BITS./prototype/$OSSLIBDIR/objects.regparm/osscore.o + prototype/usr/sbin/osslic -q -u -$BITS./prototype/$OSSLIBDIR/objects.noregparm/osscore.o + +fi + +if test -f 4front-private/ossupdate.c +then + #ossupdate + cc -I. 4front-private/ossupdate.c -s -o prototype/usr/sbin/ossupdate +fi + +sh $SRCDIR/setup/build_common.sh $SRCDIR $OSSLIBDIR + +chmod 700 prototype/usr/sbin/* +chmod 755 prototype/usr/bin/* + +(cd prototype;ls usr/sbin/* usr/bin/* etc/* usr/share/man/man*/*) > prototype/$OSSLIBDIR/sysfiles.list + +exit 0 diff --git a/setup/Linux/build_arm.sh b/setup/Linux/build_arm.sh new file mode 100644 index 0000000..7031ec5 --- /dev/null +++ b/setup/Linux/build_arm.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +# build script for ARM Linux (Nokia's Maemo plattform) + +. ./.directories + +KERNELDIR=~/maemo_kernel/kernel-source-diablo-2.6.21/kernel-source + +rm -rf prototype + +mkdir prototype +mkdir prototype/etc +echo "OSSLIBDIR=$OSSLIBDIR" > prototype/etc/oss.conf +mkdir prototype/usr +mkdir prototype/usr/bin +mkdir prototype/usr/sbin +mkdir -p prototype/$OSSLIBDIR +mkdir prototype/$OSSLIBDIR/etc +mkdir prototype/$OSSLIBDIR/conf.tmpl +mkdir prototype/$OSSLIBDIR/lib +mkdir prototype/$OSSLIBDIR/modules + +cp target/bin/* prototype/usr/bin +cp target/sbin/* prototype/usr/sbin +cp target/lib/* prototype/$OSSLIBDIR/lib + +# Compile the 64 bit div/mod functions required by gcc +rm -f bpabi.s bpabi_s.o bpabi_c.o bpabi.o +cc -c origdir/setup/Linux/arm/bpabi.c -o bpabi_c.o + +for n in L_udivsi3 L_idivsi3 L_divsi3 L_aeabi_ldivmod L_aeabi_uldivmod L_dvmd_lnx +do +# Strip position independent code (PLT) from the asm sources before compile +cpp -static -D$n origdir/setup/Linux/arm/lib1funcs.asm | sed 's/..PLT.//g' > $n.s +as -o $n.o $n.s +done + +ld -r -o bpabi.o L*.o bpabi_c.o +rm -f L*.s L*.o bpabi_c.o + +#build osscore + +rm -rf tmp_build +mkdir tmp_build + +cp origdir/setup/Linux/arm/Makefile.osscore.arm tmp_build/Makefile +cp origdir/setup/Linux/oss/build/osscore.c tmp_build/osscore.c + +cp ./kernel/framework/include/*.h tmp_build/ +cp ./kernel/OS/Linux/wrapper/wrap.h tmp_build/ +cp ./setup/Linux/oss/build/ossdip.h tmp_build/ +cp ./include/soundcard.h tmp_build/ +cp ./kernel/framework/include/ossddk/oss_exports.h tmp_build/ + +if ! (cd tmp_build && make KERNELDIR=$KERNELDIR) > build.log 2>&1 +then + cat build.log + echo + echo Building osscore module failed + exit 1 +fi + +ld -r tmp_build/osscore.ko target/objects/*.o -o prototype/usr/lib/oss/modules/osscore.ko + +if test -f tmp_build/Module.symvers +then + #Take generated symbol information and add it to module.inc + echo "static const struct modversion_info ____versions[]" > tmp_build/osscore_symbols.inc + echo " __attribute__((used))" >> tmp_build/osscore_symbols.inc + echo "__attribute__((section(\"__versions\"))) = {" >> tmp_build/osscore_symbols.inc + sed -e "s:^:{:" -e "s:\t:, \":" -e "s:\t\(.\)*:\"},:" < tmp_build/Module.symvers >> tmp_build/osscore_symbols.inc + echo "};" >> tmp_build/osscore_symbols.inc +else + echo > tmp_build/osscore_symbols.inc +fi + +cp origdir/setup/Linux/oss/build/*.inc tmp_build/ + +for n in target/modules/*.o +do + N=`basename $n .o` + + cp target/build/$N.c tmp_build/$N.c + + sed "s/MODNAME/$N/" < origdir/setup/Linux/arm/Makefile.tmpl.arm > tmp_build/Makefile + if ! (cd tmp_build && make KERNELDIR=$KERNELDIR) > build.log 2>&1 + then + cat build.log + echo + echo Building $N module failed + exit 1 + fi + ld -r tmp_build/$N.ko bpabi.o target/modules/$N.o -o prototype/usr/lib/oss/modules/$N.ko +done + +exit 0 diff --git a/setup/Linux/confgen.c b/setup/Linux/confgen.c new file mode 100644 index 0000000..53662f2 --- /dev/null +++ b/setup/Linux/confgen.c @@ -0,0 +1,188 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <libgen.h> +#include <sys/stat.h> + +char *targetdir = ""; +char *confpath = ""; + +static int +copy_parms (FILE * f, FILE * conf) +{ + char line[1024], *s; + char var[256] = "", comment[64 * 1024] = ""; + int i; + int ok = 0; + + while (fgets (line, sizeof (line), f) != NULL) + { + for (i = 0; i < strlen (line); i++) + if (line[i] == '\n') + line[i] = 0; + + s = line; + + while (*s == ' ' || *s == '\t') + s++; + if (strncmp (s, "int ", 4) == 0) + { + if (*var != 0) + { + fprintf (conf, "%s\n", comment); + if (*var != 0) + fprintf (conf, "#%s\n#\n", var); + *var = 0; + *comment = 0; + } + s += 4; + + for (i = 0; i < strlen (line); i++) + if (line[i] == ';') + line[i] = 0; + ok = 1; + strcpy (var, s); + continue; + } + + + s = line; + + while (*s == ' ' || *s == '\t' || *s == '/' || *s == '*') + s++; + + if (*comment != 0) + strcat (comment, "\n"); + strcat (comment, "# "); + strcat (comment, s); + } + + if (*var != 0) + { + fprintf (conf, "%s\n", comment); + fprintf (conf, "#%s\n", var); + } + + return ok; +} + +static void +scan_dir (const char *srcdir, const char *modnam) +{ + char confname[256], tmp[256], line[1024]; + char module[256], *p; + FILE *conf; + FILE *f; + int i; + struct stat st; + + int check_platform = 0; + int platform_ok = 0; + int ok = 0; + + strcpy (module, modnam); + p = module; + while (*p) + { + if (*p == '.') + *p = 0; + else + p++; + } + + if (stat (srcdir, &st) == -1) + return; + + if (!S_ISDIR (st.st_mode)) /* Not a directory? */ + return; + + sprintf (tmp, "%s/.nomake", srcdir); + if (stat (tmp, &st) != -1) /* File exists */ + return; /* Skip this one */ + + sprintf (tmp, "%s/.config", srcdir); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line), f) != NULL) + { + char *s; + for (i = 0; i < strlen (line); i++) + if (line[i] == '\n') + line[i] = 0; + + s = line; + while (*s && *s != '=') + s++; + if (*s == '=') + *s++ = 0; + + if (strcmp (line, "OS") == 0 || strcmp (line, "targetos") == 0) + { + check_platform = 1; + if (strcmp (s, "Linux") == 0) + platform_ok = 1; + continue; + } + } + fclose (f); + } + + if (check_platform && !platform_ok && strcmp (modnam, "osscore")) + { + return; + } +#if 0 + /* copy the man pages */ + sprintf (syscmd, "sed 's:CONFIGFILEPATH:%s:g' < %s/%s.man > /tmp/ossman.man", + confpath, srcdir, module); + printf ("%s\n", syscmd); + unlink ("/tmp/ossman.man"); + system (syscmd); + + sprintf (syscmd, + "./origdir/setup/txt2man -t \"%s\" -v \"Devices\" -s 7 /tmp/ossman.man > prototype/usr/man/man7/%s.7", + module, module); + printf ("%s\n", syscmd); + system (syscmd); +#endif + + sprintf (confname, "%s/%s.conf", targetdir, module); + sprintf (tmp, "%s/.params", srcdir); + if ((f = fopen (tmp, "r")) != NULL) + { + if ((conf = fopen (confname, "w")) == NULL) + { + perror (confname); + exit (-1); + } + fprintf (conf, "# Open Sound System configuration file\n"); + fprintf (conf, + "# Remove the '#' in front of the option(s) you like to set.\n#\n"); + ok = copy_parms (f, conf); + fclose (f); +// fprintf(conf, "#\n"); + fclose (conf); + if (!ok) + unlink (confname); + } +} + +int +main (int argc, char *argv[]) +{ + int i; + + if (argc < 3) + exit (-1); + + targetdir = argv[1]; + confpath = argv[2]; + + for (i = 3; i < argc; i++) + { + scan_dir (argv[i], basename (argv[i])); + } + + exit (0); +} diff --git a/setup/Linux/copyright b/setup/Linux/copyright new file mode 100644 index 0000000..3ec1b2e --- /dev/null +++ b/setup/Linux/copyright @@ -0,0 +1,25 @@ +Upstream sources are at: + http://www.opensound.com + +Authors: + 4Front Technologies ( http://www.4front-tech.com ) + +Copyright: + Copyright (C) 2006-2008 Hannu Savolainen and Dev Mazumdar. + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian GNU/Linux systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. diff --git a/setup/Linux/installoss.sh b/setup/Linux/installoss.sh new file mode 100644 index 0000000..5109fca --- /dev/null +++ b/setup/Linux/installoss.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +if test "$USER " != "root " +then + echo "You must be super-user or logged in as root to install OSS" + exit 1 +fi + +if test "$1 " != " " +then + OSSLIBDIR="$1" +else + OSSLIBDIR="/usr/lib/oss" +fi + +echo "Installing Open Sound System `cat "./$OSSLIBDIR/version.dat"`...." +echo "Copying files from ./etc and ./usr into /..." +tar -cpf - etc usr |(cd /; tar -xpf -) +echo "Running /usr/lib/oss/build/install script...." +if ! sh "/$OSSLIBDIR/build/install.sh" +then + echo + echo "ERROR: install.sh script failed" + exit 0 +fi +echo "OSS installation complete..." +echo +echo "Run /usr/sbin/soundon to start the drivers" +echo "Run /usr/bin/osstest to test the audio" +echo "Run /usr/bin/ossinfo to display status" diff --git a/setup/Linux/linsetup.sh b/setup/Linux/linsetup.sh new file mode 100644 index 0000000..dc34289 --- /dev/null +++ b/setup/Linux/linsetup.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +if test "$CONFIGURE " != "YES " +then + echo + echo Error: Wrong usage + echo + echo You must run `dirname $0`/configure instead of $0 + exit 1 +fi + +if test "`ls .` " != " " +then + echo Error: Current directory must be empty + exit 1 +fi + +if test "`uname -m` " = "arm " +then +# ARM doesn't have regparm support + + echo Setting up for ARM architecture + sh $SRCDIR/setup/setupdir.sh + exit 0 +fi + +# Setup directory for REGPARM + +unset NO_REGPARM +export USE_REGPARM=1 + +echo Setting up full REGPARM compiling environment + +echo "SUBDIRS+=noregparm" > .makefile +sh $SRCDIR/setup/setupdir.sh + +# Setup for NOREGPARM + +mkdir noregparm + +unset USE_REGPARM +export NO_REGPARM=1 + +echo > .nocopy +echo Setting up kernel-only NOREGPARM compiling environment +(cd noregparm;sh $SRCDIR/setup/setupdir.sh -K) +rm -f .nocopy + +# Make sure both versions share the same timestamp.h file. +cp -f kernel/framework/include/timestamp.h noregparm/kernel/framework/include/timestamp.h + +exit 0 diff --git a/setup/Linux/make.local b/setup/Linux/make.local new file mode 100644 index 0000000..ad9ac7f --- /dev/null +++ b/setup/Linux/make.local @@ -0,0 +1,21 @@ +build: kernel/framework/include/buildid.h all + sh build.sh + +copy: build + #rm -f ${OSSLIBDIR}/modules/*.o + (cd prototype; find -L . -type d | xargs -i{} mkdir -p ${DESTDIR}/{}) + (cd prototype; find -L . -type f | xargs -i{} cp {} ${DESTDIR}/{}) + +package: build + sh setup/Linux/mkpkg.sh + +tarball: build + sh setup/Linux/mktarball.sh + +deb: build + sh setup/Linux/mkdeb.sh + +install: copy + cd ${OSSLIBDIR}/build && sh install.sh + sync + soundoff && sync && soundon && echo "OSS has started OK" diff --git a/setup/Linux/md5.sh b/setup/Linux/md5.sh new file mode 100644 index 0000000..533c12e --- /dev/null +++ b/setup/Linux/md5.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +i=$2 +i=${i#.} + +# Create the MD5 sums file using the program we have found earlier +case "$1" in + MD5SUM) + md5sum ".$i" + ;; + MD5) + x=`md5 ".$i" | awk "{ for (y=1;y<=NF;y++) if ((length(\\$y) == 32) && (\\$y !~ /[\/]/)) {print \\$y; break} }"`; echo "$x $i" + ;; + DIGEST) + x=`digest -a md5 ".$i"`; echo "$x $i" + ;; + OPENSSL) + x=`openssl md5 $i | awk "{ for (y=1;y<=NF;y++) if ((length(\\$y) == 32) && (\\$y !~ /[\/]/)) {print \\$y; break} }"`; echo "$x $i" + ;; +esac diff --git a/setup/Linux/menu.ex b/setup/Linux/menu.ex new file mode 100644 index 0000000..854671b --- /dev/null +++ b/setup/Linux/menu.ex @@ -0,0 +1,4 @@ +?package(oss-linux):needs="X11" \ + section="Apps/Sound" \ + title="ossxmix" \ + command="/usr/bin/ossxmix" diff --git a/setup/Linux/mkdeb.sh b/setup/Linux/mkdeb.sh new file mode 100644 index 0000000..8330ae2 --- /dev/null +++ b/setup/Linux/mkdeb.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +. ./.directories + +VERSION=`sh showversion.sh` +VERSION=${VERSION#v} +RELEASE=`cat buildid.dat` +OSSNAME="oss-linux" + +# Chosing the right architecture +if test `uname -m` = "x86_64"; then ARCH=amd64 +else ARCH=`uname -m|sed 's/^i[3-9]86/i386/'` +fi + +DEBNAME=${OSSNAME}-${VERSION}-${RELEASE}_${ARCH} + +# Checking for known MD5 hashing programs +if type md5sum > /dev/null 2>&1; then MD5=MD5SUM +elif type openssl > /dev/null 2>&1; then MD5=OPENSSL +elif type md5 > /dev/null 2>&1; then MD5=MD5 +elif type digest > /dev/null 2>&1; then MD5=DIGEST +else echo "There has been no MD5 creation utily found. deb archive creation will be aborted." && exit 1 +fi + +echo building $DEBNAME.deb + + +mkdir control 2>/dev/null +echo "2.0" > debian-binary +cat > control/control << END +Package: $OSSNAME +Version: ${VERSION}-${RELEASE} +Section: sound +Priority: optional +Architecture: $ARCH +Installed-Size: `du -ks prototype | awk '{print $1}'` +Build-Depends: build-essential sed gawk libtool libgtk2.0-dev +Depends: binutils, gcc, libc6, libgtk2.0-0, sed (>= 1.0.0) +Conflicts: libflashsupport +Provides: oss +Suggests: libsdl1.2debian-oss | libsdl1.2debian-all, libesd0, libwine-oss, libsox-fmt-oss, mpg123, gstreamer0.10-plugins-bad (>= 0.10.7), libasound2-plugins +Maintainer: 4Front Technologies <support@opensound.com> +Description: Open Sound System (http://www.opensound.com) + OSS provides libraries and necessary drivers for practically all sound + cards on the market including PnP and many PCI ones which enable you + to play sound files, compose music, use MIDI (only included in the + testing releases) and adjust your sound card using various user space + programs. +END + +# Copying the menu and copyright file to the right place, taking care that the md5sums generation will take place AFTER this step +mkdir -p prototype/usr/share/menu prototype/usr/share/doc/oss-linux +cp setup/Linux/menu.ex prototype/usr/share/menu/ossxmix +cp setup/Linux/copyright prototype/usr/share/doc/oss-linux/ + + +# Create the MD5 sums file using the program we have found earlier +(cd prototype; find . -type f -exec sh ../setup/Linux/md5.sh "$MD5" "{}" \; > ../control/md5sums) + +(cd prototype; find . -type f -print | sed 's/^.//g' | egrep "^/etc/" > ../control/conffiles) + + +# Removing older builds +rm -rf /tmp/prototype $DEBNAME.deb + + +cp -pRf prototype /tmp +cp setup/Linux/preinst setup/Linux/postinst setup/Linux/prerm setup/Linux/postrm control/ +if test -e prototype/$OSSLIBDIR/lib/libsalsa.so* +then + cp setup/Linux/shlibs control/ +fi + + +# Correcting file and directory permissions required by lintian +chmod 0755 control/control + +# Building control and data archives +(cd control; tar c * | gzip -9 > ../control.tar.gz) +(cd /tmp/prototype; tar c ./* | gzip -9 > data.tar.gz) +mv /tmp/prototype/data.tar.gz . + + +# Creating the actual archive +ar r $DEBNAME.deb debian-binary control.tar.gz data.tar.gz + + +# Cleanup +rm -rf /tmp/prototype control control.tar.gz data.tar.gz debian-binary + + +if test -f 4front-private/export_package.sh +then + sh 4front-private/export_package.sh $OSSNAME*.deb . `sh showversion.sh` /tmp `uname -i`-26 +fi diff --git a/setup/Linux/mkpkg.sh b/setup/Linux/mkpkg.sh new file mode 100644 index 0000000..4ccfe90 --- /dev/null +++ b/setup/Linux/mkpkg.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +. ./.directories + +VERSION=`sh showversion.sh` +RELEASE=`cat buildid.dat` +ARCH=`uname -i` +OSSNAME=oss-linux + +RPMNAME=$OSSNAME-$VERSION +PKGNAME=$OSSNAME-$VERSION-$RELEASE.$ARCH +echo building $RPMNAME.rpm + +rm -rf spec $RPMNAME +mkdir $RPMNAME +echo "Version: " $VERSION > spec +echo "Release: " $RELEASE >> spec +echo "Name: " $OSSNAME >> spec +cat setup/Linux/spec.tmpl | sed "s:OSSLIBDIR:\"$OSSLIBDIR\":g" >> spec +echo "%files" >> spec +(cd prototype; find . -type f -print | sed 's/^.//g' > /tmp/filelist) +cat /tmp/filelist >> spec +rm -rf /tmp/prototype +cp -af prototype /tmp +tar zcvf /tmp/oss $RPMNAME +rpmbuild -bb --define "_sourcedir /tmp" --define "_rpmdir ./" --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm' spec +# Cleanup +rm -rf /tmp/oss /tmp/filelist $RPMNAME spec + +if test -f 4front-private/export_package.sh +then + sh 4front-private/export_package.sh $PKGNAME.rpm . `sh showversion.sh` /tmp `uname -i`-26 +fi diff --git a/setup/Linux/mktarball.sh b/setup/Linux/mktarball.sh new file mode 100644 index 0000000..4610a4b --- /dev/null +++ b/setup/Linux/mktarball.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +. ./.directories + +VERSION=`sh showversion.sh` +RELEASE=`cat buildid.dat` +OSSNAME=oss-linux +PKGNAME=$OSSNAME-$VERSION-$RELEASE-`uname -m` + +echo building $PKGNAME.tar.bz2 +#cp ./setup/Linux/installoss.sh prototype +cp ./setup/Linux/removeoss.sh prototype/$OSSLIBDIR/scripts +(cd prototype; find . -type f -print) > prototype/$OSSLIBDIR/MANIFEST +(cd prototype; tar cfj /tmp/$PKGNAME.tar.bz2 . ) +mv /tmp/$PKGNAME.tar.bz2 . + +if test -f 4front-private/export_package.sh +then + sh 4front-private/export_package.sh $PKGNAME.tar.bz2 . `sh showversion.sh` /tmp `uname -m`-26 +fi + +exit 0 diff --git a/setup/Linux/oss/build/Makefile.osscore b/setup/Linux/oss/build/Makefile.osscore new file mode 100644 index 0000000..30d0287 --- /dev/null +++ b/setup/Linux/oss/build/Makefile.osscore @@ -0,0 +1,32 @@ +include /etc/oss.conf + +EXTRA_CFLAGS += -I${OSSLIBDIR}/include/internals -I${OSSLIBDIR}/include/sys + +ifneq ($(KERNELRELEASE),) + + obj-m := osscore.o + +else + + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) +endif + +default: + @echo "static const char __oss_compile_vermagic[]" > ubuntu_version_hack.inc +#The kernel build system saves kernel version (obtained via "utsrelease.h") +#used during compile in a "vermagic" symbol. soundon compares this with +#current version of running kernel to know when to relink modules. +#Some Ubuntu kernels have 'uname -r' output different from "utsrelease.h" +#contents, so we save the previous uname as a fallback check. +# https://bugs.launchpad.net/ubuntu/+source/linux/+bug/247055 + @echo "__attribute__((used))" >> ubuntu_version_hack.inc + @echo "__attribute__((section(\".modinfo\")))" >> ubuntu_version_hack.inc + @echo "= \"$(shell /usr/sbin/ossvermagic -z -s)\";" >> ubuntu_version_hack.inc + + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + @rm -f ubuntu_version_hack.inc + +clean: + rm -f *.o *.ko *.mod.c *.mod.o .*.cmd core core.* x y z ubuntu_version_hack.inc + rm -rf .tmp_versions diff --git a/setup/Linux/oss/build/Makefile.tmpl b/setup/Linux/oss/build/Makefile.tmpl new file mode 100644 index 0000000..fd331c1 --- /dev/null +++ b/setup/Linux/oss/build/Makefile.tmpl @@ -0,0 +1,21 @@ +include /etc/oss.conf + +EXTRA_CFLAGS += -I${OSSLIBDIR}/include/internals -I${OSSLIBDIR}/include/sys + +ifneq ($(KERNELRELEASE),) + + obj-m := MODNAME.o + +else + + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +endif + +clean: + @rm -f *.o *.ko *.mod.c *.mod.o .*.cmd core core.* x y z + @rm -rf .tmp_versions diff --git a/setup/Linux/oss/build/install.sh b/setup/Linux/oss/build/install.sh new file mode 100644 index 0000000..13fdbc2 --- /dev/null +++ b/setup/Linux/oss/build/install.sh @@ -0,0 +1,347 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss + echo "OSSLIBDIR=/usr/lib/oss" > /etc/oss.conf +fi + +[ -z "$LD" ] && LD=ld + +cd $OSSLIBDIR/build + +rm -f $OSSLIBDIR/.cuckoo_installed + +# Check if we should use REGPARM or non-REGPARM modules +if /usr/sbin/ossvermagic -r || /sbin/modinfo ext3|grep -q REGPARM +then + REGPARM=REGPARM + rm -rf $OSSLIBDIR/objects + ln -s $OSSLIBDIR/objects.regparm $OSSLIBDIR/objects + rm -rf $OSSLIBDIR/modules + ln -s $OSSLIBDIR/modules.regparm $OSSLIBDIR/modules +else + REGPARM=NOREGPARM + rm -rf $OSSLIBDIR/objects + ln -s $OSSLIBDIR/objects.noregparm $OSSLIBDIR/objects + rm -rf $OSSLIBDIR/modules + ln -s $OSSLIBDIR/modules.noregparm $OSSLIBDIR/modules +fi + +UNAME=`uname -r` + +if test -f /lib/modules/$UNAME/kernel/oss/vmix.ko || test -f /lib/modules/$UNAME/kernel/oss/ich.ko +then +# Older versions of OSS modules exist under /lib/modules. This indicates that +# previous version of OSS has not been properly uninstalled. Run osdetect +# again to fix rthe situation + + /usr/sbin/soundoff > /dev/null 2>&1 + /usr/sbin/ossdetect +fi + +# Remove previous OSS modules from the system +rm -rf /lib/modules/$UNAME/kernel/oss + +if test -f /usr/lib/oss/build/ich.c +then + # Older v4.0 modules found. Remove them + (cd /usr/lib/oss/build ; rm -f ali5455.c allegro.c als300.c als4000.c apci97.c atiaudio.c audigyls.c audioloop.c audiopci.c cmi8788.c cmpci.c cs4280.c cs4281.c digi32.c digi96.c emu10k1x.c envy24.c envy24ht.c fm801.c geode.c hdaudio.c hdsp.c ich.c imux.c maestro.c neomagic.c ossusb.c riptide.c s3vibes.c sblive.c sbxfi.c softoss.c solo.c sonorus.c trident.c via8233.c via97.c vmix.c vortex.c ymf7xx.c) + echo + echo + echo Error: Older OSS version seems to be installed in your system. + echo Please remove previous /usr/lib/oss directory and the install OSS v4.x again. + soundoff + exit 127 +fi + +if ! test -f $OSSLIBDIR/objects/osscore.o +then + echo Error: OSS core module for $REGPARM kernel is not available in $OSSLIBDIR/objects + exit 1 +fi + +echo +echo OSS build environment set up for $REGPARM kernels + +KERNELDIR=/lib/modules/$UNAME/build +UBUNTUPACKAGES="" + +OK=1 +echo + +if test "`which gcc 2>/dev/null` " = " " +then + echo " gcc" + UBUNTUPACKAGES="$UBUNTUPACKAGES gcc" + OK=0 +fi + +if test "`which make 2>/dev/null` " = " " +then + echo " make" + UBUNTUPACKAGES="$UBUNTUPACKAGES make" + OK=0 +fi + +if test "`which ld 2>/dev/null` " = " " +then + echo " binutils" + UBUNTUPACKAGES="$UBUNTUPACKAGES binutils" + OK=0 +fi + +if ! test -f /usr/include/stdio.h +then + echo " C library headers (glibc-devel or build-essential)" + OK=0 + UBUNTUPACKAGES="$UBUNTUPACKAGES build-essentials" +fi + +if test "$OK " = "0 " +then + echo + echo 'Error: The above Linux package(s) seem to be missing from your system.' + echo ' Please install them and then try to install OSS again.' + echo + echo Please refer to the documentation of your Linux distribution if you + echo have problems with installing the packages. + echo + + if grep -q Ubuntu /etc/issue # Ubuntu? + then + echo You can use the following commands to download and install all + echo required packages: + echo + + for n in $UBUNTUPACKAGES + do + echo " apt-get install $n" + done + + exit 1 + fi + + exit 1 +fi + + +if ! test -f $KERNELDIR/Makefile && ! test -f /lib/modules/$UNAME/sources/Makefile +then + echo + echo 'Warning: Cannot locate the Linux kernel development package for' + echo ' Linux kernel version ' $UNAME + echo ' Please install the kernel development package if linking the' + echo ' OSS modules fails.' + echo + echo The kernel development package may be called kernel-devel, kernel-smp-devel, + echo kernel-sources, kernel-headers or something like that. Please refer + echo to the documentation of your Linux distribution if there are any + echo difficulties in installing the kernel/driver development environment. + echo + + if grep -q 'Fedora Core release' /etc/issue + then + if uname -v|grep -q SMP + then + echo Assuming that you are using Fedora Core 5 or later + echo "the right kernel source package (RPM) is probably called" + echo kernel-smp-devel. + else + echo Assuming that you are using Fedora Core 5 or later + echo "the right kernel source package (RPM) is probably called" + echo kernel-devel. + fi + else + echo For your Linux distribution the right kernel source package + echo might be kernel-source. + fi + echo + + if grep -q Ubuntu /etc/issue || grep -q Debian /etc/issue # Ubuntu or Debian? + then + echo Under Ubuntu you may need to prepare the kernel environment + echo after downloading the kernel sources using + echo + echo " sudo apt-get install linux-headers-$UNAME" + echo " cd /usr/src/linux-headers-$UNAME/" +# echo " sudo make prepare" +# echo " sudo make prepare scripts" + echo + fi +fi + +if ! test -d /lib/modules/$UNAME +then + echo Error: Kernel directory /lib/modules/$UNAME does not exist + exit 1 +fi + +cp -f ../objects/osscore.o osscore_mainline.o + +rm -f Makefile +ln -s Makefile.osscore Makefile + +echo Building module osscore + +if ! make KERNELDIR=$KERNELDIR> build.list 2>&1 +then + echo Failed to compile OSS + cat build.list + exit 2 +fi + +if ! test -d /lib/modules/$UNAME/kernel/oss +then + mkdir /lib/modules/$UNAME/kernel/oss +fi + +if ! test -d /lib/modules/$UNAME/kernel/oss +then + echo OSS module directory /lib/modules/$UNAME/kernel/oss does not exist. + exit 3 +fi + +if ! $LD -r osscore.ko osscore_mainline.o -o /lib/modules/$UNAME/kernel/oss/osscore.ko +then + echo Linking the osscore module failed + exit 5 +fi + +if test -f Module.symvers +then + #Take generated symbol information and add it to module.inc + echo "static const struct modversion_info ____versions[]" > osscore_symbols.inc + echo " __attribute__((used))" >> osscore_symbols.inc + echo "__attribute__((section(\"__versions\"))) = {" >> osscore_symbols.inc + sed -e "s:^:{:" -e "s:\t:, \":" -e "s:\t\(.\)*:\"},:" < Module.symvers >> osscore_symbols.inc + echo "};" >> osscore_symbols.inc +else + echo > osscore_symbols.inc +fi + +#depmod -a + +for n in ../modules/*.o +do + N=`basename $n .o` + echo Building module $N + + rm -f $N_mainline.o Makefile + + sed "s/MODNAME/$N/" < Makefile.tmpl > Makefile + ln -s $n $N_mainline.o + + if ! make KERNELDIR=$KERNELDIR > build.list 2>&1 + then + echo Compiling module $N failed + cat build.list + exit 4 + fi + + if ! $LD -r $N.ko $N_mainline.o -o /lib/modules/$UNAME/kernel/oss/$N.ko + then + echo Linking $N module failed + exit 6 + fi + + rm -f $N_mainline.o + make clean +done + +rm -f Makefile + +echo "depmod -a" +depmod -a + +# Copy config files for any new driver modules + +if ! test -d $OSSLIBDIR/conf +then + mkdir $OSSLIBDIR/conf +fi + +if test -d $OSSLIBDIR/conf.tmpl +then + for n in $OSSLIBDIR/conf.tmpl/*.conf + do + N=`basename $n` + + if ! test -f $OSSLIBDIR/conf/$N + then + cp -f $n $OSSLIBDIR/conf/ + fi + done + rm -rf $OSSLIBDIR/conf.tmpl +fi + +if ! test -f $OSSLIBDIR/etc/installed_drivers +then + echo "-----------------------------" + /usr/sbin/ossdetect -v + echo "-----------------------------" + echo +fi + +if ! test -d /etc/init.d +then + mkdir /etc/init.d +fi + +rm -f /etc/init.d/oss /etc/rc.d/rc3.d/S89oss /etc/rc3.d/S89oss +cp -f $OSSLIBDIR/etc/S89oss /etc/init.d/oss + +chmod 744 /etc/init.d/oss + +if test -x /sbin/chkconfig +then + /sbin/chkconfig oss on > /dev/null 2>&1 +else + if test -x /usr/sbin/update-rc.d + then + /usr/sbin/update-rc.d oss defaults > /dev/null 2>&1 + else + if test -d etc/rc.d/rc3.d + then + rm -f /etc/rc.d/rc3.d/S89oss + ln -s /etc/init.d/oss /etc/rc.d/rc3.d/S89oss + else + if test -d /etc/rc3.d + then + rm -f /etc/rc3.d/S89oss + ln -s /etc/init.d/oss /etc/rc3.d/S89oss + fi + fi + fi +fi + +# Install ALSA interface module (Cuckoo) +#(cd $OSSLIBDIR/cuckoo && make clean) > /dev/null 2>&1 +#if (cd $OSSLIBDIR/cuckoo && make install) > /var/log/cuckoo.log 2>&1 +#then +# touch $OSSLIBDIR/.cuckoo_installed +#fi +#(cd $OSSLIBDIR/cuckoo && make clean) > /dev/null 2>&1 + +# Remove bogus char major 14 device files left from earlier OSS versions. + +rm -f `ls -l -d /dev/*|grep ^c|grep ' 14, '|sed 's/.* //'` + +# Recompile libflashsupport.so if possible. Otherwise use the precompiled +# version. +(cd $OSSLIBDIR/lib;cc -m64 -shared -fPIC -O2 -Wall -Werror flashsupport.c -o $OSSLIBDIR/lib/libflashsupport_64.so) > /dev/null 2>&1 +(cd $OSSLIBDIR/lib;cc -m32 -shared -fPIC -O2 -Wall -Werror flashsupport.c -o $OSSLIBDIR/lib/libflashsupport_32.so) > /dev/null 2>&1 + +if test ! -f $OSSLIBDIR/etc/userdefs +then + echo "autosave_mixer yes" > $OSSLIBDIR/etc/userdefs +fi + +# Hal 0.5.0+ hotplug +mkdir -p /usr/lib/hal/scripts +ln -sf $OSSLIBDIR/scripts/oss_usb-create-devices /usr/lib/hal/scripts/ +mkdir -p /usr/share/hal/fdi/policy/20thirdparty/ +ln -sf $OSSLIBDIR/scripts/90-oss_usb-create-device.fdi /usr/share/hal/fdi/policy/20thirdparty/ + +exit 0 diff --git a/setup/Linux/oss/build/module.inc b/setup/Linux/oss/build/module.inc new file mode 100644 index 0000000..4e34003 --- /dev/null +++ b/setup/Linux/oss/build/module.inc @@ -0,0 +1,245 @@ +/* + * Purpose: Template for OSS modules under Linux + * + * This file is included by the low level driver modules when they are + * compiled in the target system. In this way this file can be modified + * for non-standard kernels by the customer. Compiling in the target is + * necessary because the driver/module framework of Linux cannot support + * binary drivers. Another reason is that the kbuild mechanism used to build + * kernel modules under Linux is not compatible with the way how the source + * code of OSS is organized. + */ +/* + * Copyright (C) 4Front Technologies 2005-2007. Released under GPL2 license. + */ +#define strcpy dummy_strcpy +#include <linux/version.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include "timestamp.h" +#include "oss_exports.h" +#include "wrap.h" +#include "ossddk.h" +#include "ossdip.h" +#undef strcpy +#define strcpy oss_strcpy +#undef strlen +#define strlen oss_strlen + +static int module_major = 0; +static int instance = 0; + +MODULE_LICENSE ("GPL v2"); +MODULE_DESCRIPTION ("Open Sound System '" DRIVER_PURPOSE "' driver module"); +MODULE_AUTHOR ("4Front Technologies (support@opensound.com)"); + +extern int DRIVER_ATTACH (oss_device_t * osdev); +extern int DRIVER_DETACH (oss_device_t * osdev); + +#if DRIVER_TYPE==DRV_PCI +#define DRIVER_TYPE_OK + +#include "pci_wrapper.inc" + +// MODULE_DEVICE_TABLE(pci, id_table); +static struct pci_driver osspci_driver = { + .name = DRIVER_NICK, + .id_table = id_table, + .probe = osspci_probe, + .remove = osspci_remove +}; + +static int __init +pcidrv_init (void) +{ + int err; + + if ((err = pci_register_driver (&osspci_driver)) < 0) + return err; + oss_register_module (THIS_MODULE); + return 0; +} + +static void __exit +pcidrv_exit (void) +{ + if (module_major > 0) + { + oss_unregister_chrdev (module_major, DRIVER_NICK); + } + pci_unregister_driver (&osspci_driver); + oss_unregister_module (THIS_MODULE); +} + +module_init (pcidrv_init); +module_exit (pcidrv_exit); +#endif /* PCI driver */ + +#if DRIVER_TYPE==DRV_VIRTUAL || DRIVER_TYPE==DRV_VMIX +#define DRIVER_TYPE_OK +static oss_device_t *osdev = NULL; + +static int +virtualdrv_init (void) +{ + static int instance = 0, maj; + + if ((osdev = + osdev_create (NULL, DRIVER_TYPE, instance++, DRIVER_NICK, + NULL)) == NULL) + { + return -ENOMEM; + } + osdev_set_owner (osdev, THIS_MODULE); + maj = oss_request_major (osdev, 0, DRIVER_NICK); + osdev_set_major (osdev, maj); + if (!DRIVER_ATTACH (osdev)) + return -EIO; + oss_register_module (THIS_MODULE); + oss_audio_delayed_attach (); + return 0; +} + +static void +virtualdrv_exit (void) +{ + + if (!DRIVER_DETACH (osdev)) + printk (KERN_ALERT DRIVER_NICK ": Unloading busy device\n"); + osdev_delete (osdev); + oss_unregister_module (THIS_MODULE); +} + +module_init (virtualdrv_init); +module_exit (virtualdrv_exit); +#endif /* Virtual driver */ + +#if DRIVER_TYPE==DRV_USB +#define DRIVER_TYPE_OK +oss_device_t *osdev = NULL; +static int usb_major = 0; + +#include "usb_wrapper.inc" + +static int +usbdrv_init (void) +{ + int res; + + if (udi_usb_installed) + return 0; + if ((osdev = + osdev_create (NULL, DRV_VIRTUAL, instance++, DRIVER_NICK, + NULL)) == NULL) + { + return -ENOMEM; + } + osdev_set_owner (osdev, THIS_MODULE); + usb_major = oss_request_major (osdev, 0, DRIVER_NICK); + if (usb_major < 0) + { + oss_cmn_err (CE_WARN, "Failed to allocate USB major (%d)\n", usb_major); + return -EIO; + } + osdev_set_major (osdev, usb_major); + oss_register_device (osdev, "USB audio core services"); + if (!DRIVER_ATTACH (osdev)) + return -EIO; + oss_register_module (THIS_MODULE); + oss_audio_delayed_attach (); + + udi_usb_installed = 1; + + if ((res = usb_register (&oss_usb)) < 0) + { + printk ("oss: usb_register failed, err=%d\n", res); + drv = NULL; + return -ENXIO; + } + return 0; +} + +static void +usbdrv_exit (void) +{ + if (!udi_usb_installed) + return; + if (!DRIVER_DETACH (osdev)) + printk (KERN_ALERT DRIVER_NICK ": Unloading busy device\n"); + usb_deregister (&oss_usb); + udi_usb_installed = 0; + known_devices = NULL; + osdev_delete (osdev); + osdev = NULL; + oss_unregister_module (THIS_MODULE); +} + +module_init (usbdrv_init); +module_exit (usbdrv_exit); +#endif /* USB driver */ + +#ifndef DRIVER_TYPE_OK +#error Unrecognized driver type +#endif + +char * +strcpy (char *s1, const char *s2) +{ + char *s = s1; + + while (*s2) + *s1++ = *s2++; + *s1 = 0; + return s; +} + +void +oss_cmn_err (int level, const char *s, ...) +{ + char tmp[1024], *a[6]; + va_list ap; + int i, n = 0; + + va_start (ap, s); + + for (i = 0; i < strlen (s); i++) + if (s[i] == '%') + n++; + + for (i = 0; i < n && i < 6; i++) + { + a[i] = va_arg (ap, char *); + } + + for (i = n; i < 6; i++) + a[i] = NULL; + + if (level == CE_CONT) + { + sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL, + NULL, NULL, NULL); + printk ("%s", tmp); + } + else + { + strcpy (tmp, DRIVER_NICK ": "); + + sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5], + NULL, NULL, NULL, NULL); + if (level == CE_PANIC) + panic (tmp); + printk (KERN_ALERT "%s", tmp); + } +#if 0 + /* This may cause a crash under SMP */ + if (sound_started) + store_msg (tmp); +#endif + + va_end (ap); +} + +#include "osscore_symbols.inc" diff --git a/setup/Linux/oss/build/osscore.c b/setup/Linux/oss/build/osscore.c new file mode 100644 index 0000000..1a029b4 --- /dev/null +++ b/setup/Linux/oss/build/osscore.c @@ -0,0 +1,2214 @@ +/* + * Purpose: Linux kernel version specific wrapper routines. + * + * This file will be shipped in source format and compiled in the target + * (customer) system. In this way minor changes between Linux versions + * can be fixed by the customer. + */ + +/* + * Copyright (C) 4Front Technologies 2005-2009. Released under GPL2 license. + */ +//#include <linux/config.h> +typedef int *ioctl_arg; +#include <linux/init.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <stdarg.h> +#include <linux/vmalloc.h> +#include "timestamp.h" +#include "local_config.h" +#include "oss_exports.h" +#include "wrap.h" +#include "ossdip.h" +#include <linux/version.h> +#include <linux/fs.h> +#include <linux/poll.h> +#include <linux/time.h> +#include <linux/proc_fs.h> +#include <linux/spinlock.h> +#include <linux/pci.h> +#include <linux/irq.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#undef strlen +#undef strcpy +#define strlen oss_strlen +#define strcpy oss_strcpy + +typedef struct _smap_t dmap_t; + +#include "soundcard.h" +#include "audio_core.h" +#include "mixer_core.h" +#include "ubuntu_version_hack.inc" + +MODULE_LICENSE ("GPL v2"); +MODULE_DESCRIPTION ("Open Sound System core services"); +MODULE_AUTHOR ("4Front Technologies (support@opensound.com)"); + +struct _oss_mutex_t +{ + /* Caution! This definition must match cuckoo.h */ + spinlock_t lock; + int filler; /* Make sure this structure doesn't become zero length */ +}; + +static oss_device_t *core_osdev = NULL; +/* + * Minor device list + */ +#define MAX_MINOR 256 +typedef struct +{ + int major, minor; + char name[32]; +} oss_minor_t; + +static oss_minor_t minors[MAX_MINOR]; +static int nminors = 0; + +/* + * Sleep flags. Make sure these definitions match oss_config.h. + */ +#define WK_NONE 0x00 +#define WK_WAKEUP 0x01 +#define WK_TIMEOUT 0x02 +#define WK_SIGNAL 0x04 +#define WK_SLEEP 0x08 +#define WK_SELECT 0x10 + +time_t +oss_get_time (void) +{ +#if 1 + return get_seconds (); +#else + return xtime.tv_sec; +#endif +} + +void *oss_memset (void *t, int val, size_t l); + +void * +oss_kmem_alloc (size_t size) +{ + void *ptr; + if ((ptr = vmalloc (size)) == NULL) + { + oss_cmn_err (CE_WARN, "vmalloc(%d) failed\n", size); + return NULL; + } + memset (ptr, 0, size); + return ptr; +} + +void +oss_kmem_free (void *addr) +{ + vfree (addr); +} + +/* oss_pmalloc() moved to os_linux.c */ + +extern oss_native_word +oss_virt_to_bus (void *addr) +{ + return virt_to_bus (addr); +} + +void * +oss_memcpy (void *t_, const void *f_, size_t l) +{ + unsigned char *t = t_; + unsigned const char *f = f_; + int i; + + for (i = 0; i < l; i++) + *t++ = *f++; + + return t; +} + +void * +oss_memset (void *t, int val, size_t l) +{ + char *c = t; + while (l-- > 0) + *c++ = val; + + return t; +} + +int +oss_strcmp (const char *s1, const char *s2) +{ + while (*s1 && *s2) + { + if (*s1 != *s2) + return *s1 - *s2; + s1++; + s2++; + } + + return *s1 - *s2; +} + +int +oss_strncmp (const char *s1, const char *s2, size_t len) +{ + while (*s1 && *s2 && len--) + { + if (*s1 != *s2) + return *s1 - *s2; + s1++; + s2++; + } + + return *s1 - *s2; +} + +char * +oss_strcpy (char *s1, const char *s2) +{ + char *s = s1; + + while (*s2) + *s1++ = *s2++; + *s1 = '\0'; + return s; +} + +size_t +oss_strlen (const char *s) +{ + int i; + + for (i = 0; s[i]; i++); + + return i; +} + +char * +oss_strncpy (char *s1, const char *s2, size_t l) +{ + char *s = s1; + int n = 0; + + while (*s2) + { + if (n++ >= l) + return s; + + *s1++ = *s2++; + } + *s1 = '\0'; + return s; +} + +int oss_hz = HZ; +extern int max_intrate; +extern int detect_trace; +extern int src_quality; +extern int flat_device_model; +extern int vmix_disabled; +extern int vmix_no_autoattach; +extern int vmix_loopdevs; +extern int ac97_amplifier; +extern int ac97_recselect; +extern int cooked_enable; +extern int dma_buffsize; +extern int excl_policy; +extern int mixer_muted; + +module_param (oss_hz, int, S_IRUGO); +module_param (max_intrate, int, S_IRUGO); +module_param (detect_trace, int, S_IRUGO); +module_param (src_quality, int, S_IRUGO); +module_param (flat_device_model, int, S_IRUGO); +module_param (vmix_disabled, int, S_IRUGO); +module_param (vmix_no_autoattach, int, S_IRUGO); +module_param (vmix_loopdevs, int, S_IRUGO); +module_param (ac97_amplifier, int, S_IRUGO); +module_param (ac97_recselect, int, S_IRUGO); +module_param (cooked_enable, int, S_IRUGO); +module_param (dma_buffsize, int, S_IRUGO); +module_param (excl_policy, int, S_IRUGO); +module_param (mixer_muted, int, S_IRUGO); + +static struct proc_dir_entry *oss_proc_root = NULL; +static struct proc_dir_entry *oss_proc_devfiles = NULL; + +static ssize_t +oss_read_devfiles (struct file *file, char __user * buf, size_t count, + loff_t * ppos) +{ + static char tmp[8192]; + char *s; + static int eof = 0; + int i; + + if (eof) + { + eof = 0; + return 0; + } + + *tmp = 0; + s = tmp; + + for (i = 0; i < nminors; i++) + { + if (strlen (tmp) > sizeof (tmp) - 20) + { + printk (KERN_ALERT "osscore: Procfs buffer too small\n"); + return -ENOMEM; + } + + s += sprintf (s, "%s %d %d\n", + minors[i].name, minors[i].major, minors[i].minor); + } + + if (copy_to_user (buf, (void *) tmp, strlen (tmp))) + return -EFAULT; + + eof = 1; + return strlen (tmp); +} + +static struct file_operations oss_proc_operations = { + .read = oss_read_devfiles, +}; + +static void +init_proc_fs (void) +{ + if ((oss_proc_root = + create_proc_entry ("opensound", 0700 | S_IFDIR, NULL)) == NULL) + { + oss_cmn_err (CE_CONT, "Cannot create /proc/opensound\n"); + return; + } + + if ((oss_proc_devfiles = + create_proc_entry ("devfiles", 0600, oss_proc_root)) == NULL) + { + oss_cmn_err (CE_CONT, "Cannot create /proc/opensound/devfiles\n"); + return; + } + + oss_proc_devfiles->proc_fops = &oss_proc_operations; +} + +static void +uninit_proc_fs (void) +{ + if (oss_proc_root) + { + if (oss_proc_devfiles) + remove_proc_entry ("devfiles", oss_proc_root); + remove_proc_entry ("opensound", NULL); + } +} + +static int +osscore_init (void) +{ + if ((core_osdev = + osdev_create (NULL, DRV_UNKNOWN, 0, "osscore", NULL)) == NULL) + { + oss_cmn_err (CE_WARN, "Failed to allocate OSDEV structure\n"); + return -ENOMEM; + } + + osdev_set_owner (core_osdev, THIS_MODULE); + + init_proc_fs (); + + return oss_init_osscore (core_osdev); +} + +static void +osscore_exit (void) +{ + uninit_proc_fs (); + oss_uninit_osscore (core_osdev); +} + +void +oss_udelay (unsigned long d) +{ + udelay (d); +} + +oss_mutex_t +oss_mutex_init (void) +{ + oss_mutex_t mutex; + + if ((mutex = vmalloc (sizeof (*mutex))) == NULL) + { + oss_cmn_err (CE_WARN, "vmalloc(%d) failed (mutex)\n", sizeof (*mutex)); + return NULL; + } + + spin_lock_init (&(mutex->lock)); + + return mutex; +} + +void +oss_mutex_cleanup (oss_mutex_t mutex) +{ + vfree (mutex); +} + +void +oss_spin_lock_irqsave (oss_mutex_t mutex, oss_native_word * flags) +{ + unsigned long flag; + if (mutex == NULL) + return; + spin_lock_irqsave (&mutex->lock, flag); + *flags = flag; +} + +void +oss_spin_unlock_irqrestore (oss_mutex_t mutex, oss_native_word flags) +{ + if (mutex == NULL) + return; + spin_unlock_irqrestore (&mutex->lock, flags); +} + +void +oss_spin_lock (oss_mutex_t mutex) +{ + if (mutex == NULL) + return; + spin_lock (&mutex->lock); +} + +void +oss_spin_unlock (oss_mutex_t mutex) +{ + if (mutex == NULL) + return; + spin_unlock (&mutex->lock); +} + +void * +oss_map_pci_mem (oss_device_t * osdev, int size, unsigned long offset) +{ +#ifdef __arm__ + return (void*)offset; +#else + return ioremap (offset, size); +#endif +} + +void +oss_unmap_pci_mem (void *addr) +{ +#ifndef __arm__ + iounmap (addr); +#endif +} + +unsigned long long +oss_get_jiffies (void) +{ + return jiffies_64; +} + +char * +oss_get_procname (void) +{ + return current->comm; +} + +int +oss_get_pid (void) +{ + return current->pid; +} + +int +oss_get_uid (void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + return current->cred->uid; +#else + return current->uid; +#endif +} + +typedef struct tmout_desc +{ + volatile int active; + int timestamp; + void (*func) (void *); + void *arg; + + struct timer_list timer; +} tmout_desc_t; + +static volatile int next_id = 0; +#define MAX_TMOUTS 128 + +tmout_desc_t tmouts[MAX_TMOUTS] = { {0} }; + +int timeout_random = 0x12123400; + +void +oss_timer_callback (unsigned long id) +{ + tmout_desc_t *tmout; + int ix; + void *arg; + + timeout_random++; + + ix = id & 0xff; + if (ix < 0 || ix >= MAX_TMOUTS) + return; + tmout = &tmouts[ix]; + + if (tmout->timestamp != id) /* Expired timer */ + return; + + if (!tmout->active) + return; + + arg = tmout->arg; + tmout->active = 0; + tmout->timestamp = 0; + + tmout->func (arg); +} + +timeout_id_t +oss_timeout (void (*func) (void *), void *arg, unsigned long long ticks) +{ + tmout_desc_t *tmout = NULL; + int id, n; + + timeout_random++; + + n = 0; + id = -1; + + while (id == -1 && n < MAX_TMOUTS) + { + if (!tmouts[next_id].active) + { + tmouts[next_id].active = 1; + id = next_id++; + tmout = &tmouts[id]; + break; + } + + next_id = (next_id + 1) % MAX_TMOUTS; + } + + if (id == -1) /* No timer slots available */ + { + oss_cmn_err (CE_WARN, "Timeout table full\n"); + return 0; + } + + tmout->func = func; + tmout->arg = arg; + tmout->timestamp = id | (timeout_random & ~0xff); + + init_timer (&tmout->timer); + tmout->timer.expires = jiffies + ticks; + tmout->timer.data = id | (timeout_random & ~0xff); + tmout->timer.function = oss_timer_callback; + add_timer (&tmout->timer); + + return id | (timeout_random & ~0xff); +} + +void +oss_untimeout (timeout_id_t id) +{ + tmout_desc_t *tmout; + int ix; + + ix = id & 0xff; + if (ix < 0 || ix >= MAX_TMOUTS) + return; + + timeout_random++; + tmout = &tmouts[ix]; + + if (tmout->timestamp != id) /* Expired timer */ + return; + if (tmout->active) + del_timer (&tmout->timer); + tmout->active = 0; + tmout->timestamp = 0; +} + +int +oss_uiomove (void *addr, size_t nbytes, enum uio_rw rwflag, uio_t * uio) +{ +/* + * NOTE! Returns 0 upon success and EFAULT on failure (instead of -EFAULT + * (for Solaris/BSD compatibilityi)). + */ + + int c; + char *address = addr; + + if (rwflag != uio->rw) + { + oss_cmn_err (CE_WARN, "uiomove: Bad direction\n"); + return EFAULT; + } + + if (uio->resid < nbytes) + { + oss_cmn_err (CE_WARN, "uiomove: Bad count %d (%d)\n", nbytes, + uio->resid); + return EFAULT; + } + + if (uio->kernel_space) + return EFAULT; + + switch (rwflag) + { + case UIO_READ: + c = nbytes; + if (c > 10) + c = 0; + + if ((c = copy_to_user (uio->ptr, address, nbytes) != 0)) + { + uio->resid -= nbytes; + oss_cmn_err (CE_CONT, "copy_to_user(%d) failed (%d)\n", nbytes, c); + return EFAULT; + } + break; + + case UIO_WRITE: + if (copy_from_user (address, uio->ptr, nbytes) != 0) + { + oss_cmn_err (CE_CONT, "copy_from_user failed\n"); + uio->resid -= nbytes; + return EFAULT; + } + break; + } + + uio->resid -= nbytes; + uio->ptr += nbytes; + + return 0; +} + +int +oss_create_uio (uio_t * uio, char *buf, size_t count, uio_rw_t rw, + int is_kernel) +{ + memset (uio, 0, sizeof (*uio)); + + if (is_kernel) + { + oss_cmn_err (CE_CONT, + "oss_create_uio: Kernel space buffers not supported\n"); + return -EIO; + } + + uio->ptr = buf; + uio->resid = count; + uio->kernel_space = is_kernel; + uio->rw = rw; + + return 0; +} + +void +oss_cmn_err (int level, const char *s, ...) +{ + char tmp[1024], *a[6]; + va_list ap; + int i, n = 0; + + va_start (ap, s); + + for (i = 0; i < strlen (s); i++) + if (s[i] == '%') + n++; + + for (i = 0; i < n && i < 6; i++) + a[i] = va_arg (ap, char *); + + for (i = n; i < 6; i++) + a[i] = NULL; + + if (level == CE_CONT) + { + sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL, + NULL, NULL, NULL); + printk ("%s", tmp); + } + else + { + strcpy (tmp, "osscore: "); + sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5], + NULL, NULL, NULL, NULL); + if (level == CE_PANIC) + panic (tmp); + + printk (KERN_ALERT "%s", tmp); + } +#if 0 + /* This may cause a crash under SMP */ + if (sound_started) + store_msg (tmp); +#endif + + va_end (ap); +} + +/* + * Sleep/wakeup + */ + +struct oss_wait_queue +{ + volatile int flags; + wait_queue_head_t wq; +}; + +struct oss_wait_queue * +oss_create_wait_queue (oss_device_t * osdev, const char *name) +{ + struct oss_wait_queue *wq; + + if ((wq = vmalloc (sizeof (*wq))) == NULL) + { + oss_cmn_err (CE_WARN, "vmalloc(%d) failed (wq)\n", sizeof (*wq)); + return NULL; + } + init_waitqueue_head (&wq->wq); + + return wq; +} + +void +oss_reset_wait_queue (struct oss_wait_queue *wq) +{ + wq->flags = 0; +} + +void +oss_remove_wait_queue (struct oss_wait_queue *wq) +{ + vfree (wq); +} + +int +oss_sleep (struct oss_wait_queue *wq, oss_mutex_t * mutex, int ticks, + oss_native_word * flags, unsigned int *status) +{ + int result = 0; + *status = 0; + + if (wq == NULL) + return 0; + + wq->flags = 0; + oss_spin_unlock_irqrestore (*mutex, *flags); + + if (ticks <= 0) + result = wait_event_interruptible (wq->wq, (wq->flags & WK_WAKEUP)); + else + result = + wait_event_interruptible_timeout (wq->wq, (wq->flags & WK_WAKEUP), + ticks); + + oss_spin_lock_irqsave (*mutex, flags); + + if (result < 0) /* Signal received */ + { + *status |= WK_SIGNAL; + return 1; + } + + if (!(wq->flags & WK_WAKEUP)) /* Timeout */ + { + return 0; + } + + return 1; +} + +int +oss_register_poll (struct oss_wait_queue *wq, oss_mutex_t * mutex, + oss_native_word * flags, oss_poll_event_t * ev) +{ + oss_spin_unlock_irqrestore (*mutex, *flags); + poll_wait ((struct file *) ev->file, &wq->wq, + (struct poll_table_struct *) ev->wait); + oss_spin_lock_irqsave (*mutex, flags); + return 0; +} + +void +oss_wakeup (struct oss_wait_queue *wq, oss_mutex_t * mutex, + oss_native_word * flags, short events) +{ + if (wq == NULL) + return; + + wq->flags |= WK_WAKEUP; + oss_spin_unlock_irqrestore (*mutex, *flags); + wake_up (&wq->wq); + oss_spin_lock_irqsave (*mutex, flags); +} + +void +oss_reserve_pages (oss_native_word start_addr, oss_native_word end_addr) +{ + struct page *page, *lastpage; + + lastpage = virt_to_page (end_addr); + + for (page = virt_to_page (start_addr); page <= lastpage; page++) + set_bit (PG_reserved, &page->flags); +} + +void +oss_unreserve_pages (oss_native_word start_addr, oss_native_word end_addr) +{ + struct page *page, *lastpage; + + lastpage = virt_to_page (end_addr); + + for (page = virt_to_page (start_addr); page <= lastpage; page++) + clear_bit (PG_reserved, &page->flags); +} + +void * +oss_contig_malloc (oss_device_t * osdev, int buffsize, oss_uint64_t memlimit, + oss_native_word * phaddr) +{ + char *start_addr, *end_addr; + int sz, size; + int flags = 0; + + *phaddr = 0; + +#ifdef GFP_DMA32 + if (memlimit < 0x0000000100000000LL) + flags |= GFP_DMA32; +#endif + + if (memlimit < 0x00000000ffffffffLL) + flags |= GFP_DMA; + + start_addr = NULL; + + for (sz = 0, size = PAGE_SIZE; size < buffsize; sz++, size <<= 1); + + if (buffsize != (PAGE_SIZE * (1 << sz))) + { +#if 0 + printk + ("Contig_malloc: Invalid size %d != %ld\n", buffsize, + PAGE_SIZE * (1 << sz)); +#endif + } + + start_addr = (char *) __get_free_pages (GFP_KERNEL | flags, sz); + + if (start_addr == NULL) + { + cmn_err (CE_NOTE, "Failed to allocate memory buffer of %d bytes\n", + buffsize); + return NULL; + } + else + { + /* make some checks */ + end_addr = start_addr + buffsize - 1; + + oss_reserve_pages ((oss_native_word) start_addr, + (oss_native_word) end_addr); + } + + *phaddr = virt_to_bus (start_addr); + return start_addr; +} + +void +oss_contig_free (oss_device_t * osdev, void *p, int buffsize) +{ + int sz, size; + caddr_t start_addr, end_addr; + + if (p == NULL) + return; + + for (sz = 0, size = PAGE_SIZE; size < buffsize; sz++, size <<= 1); + + start_addr = p; + end_addr = p + buffsize - 1; + + oss_unreserve_pages ((oss_native_word) start_addr, + (oss_native_word) end_addr); + free_pages ((unsigned long) p, sz); +} + +/* + * These typedefs must match definition of struct file_operations. + * (See notes in routine oss_register_chrdev). + */ +typedef ssize_t (*read_t) (struct file *, char *, size_t, loff_t *); +typedef ssize_t (*write_t) (struct file *, const char *, size_t, loff_t *); +typedef unsigned int (*poll_t) (struct file *, poll_table *); +typedef poll_table select_table; + +typedef int (*readdir_t) (struct inode *, struct file *, void *, filldir_t); +typedef int (*ioctl_t) (struct inode *, struct file *, unsigned int, + unsigned long); +typedef long (*new_ioctl_t) (struct file *, unsigned int, unsigned long); +typedef int (*mmap_t) (struct file *, struct vm_area_struct *); +typedef int (*open_t) (struct inode *, struct file *); + +typedef int (*release_t) (struct inode *, struct file *); +typedef int (*fasync_t) (int, struct file *, int); +typedef int (*fsync_t) (struct inode *, struct file *); + +static loff_t +oss_no_llseek (struct file *file, loff_t offset, int orig) +{ + return -EINVAL; +} + +static int +oss_no_fsync (struct file *f, struct dentry *d, int datasync) +{ + return -EINVAL; +} + +static int +oss_no_fasync (int x, struct file *f, int m) +{ + return -EINVAL; +} + +/* + * Wrappers for installing and uninstalling character and block devices. + * + * The oss_file_operation_handle structure differs from kernel's + * file_operations structure in parameters of the driver entry points. + * Kernel inode, file, wait_struct, vm_are_struct etc. typed arguments + * are replaced by wrapper handles. + */ + +static struct file_operations * +alloc_fop (oss_device_t * osdev, struct oss_file_operation_handle *op) +{ +/* + * This routine performs initialization of kernel file_operations structure + * from oss_file_operation_handle structure. Each procedure pointer is copied + * to a temporary variable before doing the actual assignment. This + * prevents unnecessary warnings while it still enables compatibility + * warnings. + * + * Any warning given by this routine may indicate that kernel fs + * call interface has changed significantly (added parameters to the routines). + * In this case definition routine in oss_file_operation_handle must be updated + * and WRAPPER_VERSION must be incremented. + */ + + struct file_operations *fop; + + poll_t tmp_poll = (poll_t) op->poll; + read_t tmp_read = (read_t) op->read; + write_t tmp_write = (write_t) op->write; + /* readdir_t tmp_readdir = (readdir_t)op->readdir; */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35) + ioctl_t tmp_ioctl = (ioctl_t) op->ioctl; +#endif + mmap_t tmp_mmap = (mmap_t) op->mmap; + open_t tmp_open = (open_t) op->open; + release_t tmp_release = (release_t) op->release; + new_ioctl_t tmp_unlocked_ioctl = (new_ioctl_t) op->unlocked_ioctl; + new_ioctl_t tmp_compat_ioctl = (new_ioctl_t) op->compat_ioctl; + + fop = (struct file_operations *) + oss_kmem_alloc (sizeof (struct file_operations)); + + memset ((char *) fop, 0, sizeof (struct file_operations)); + +/* + * Now the assignment + */ + fop->llseek = oss_no_llseek; + fop->read = tmp_read; + fop->write = tmp_write; + fop->readdir = NULL; /* tmp_readdir; */ + fop->poll = tmp_poll; +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35) + fop->ioctl = tmp_ioctl; +#endif + fop->mmap = tmp_mmap; + fop->open = tmp_open; + fop->release = tmp_release; + fop->fsync = oss_no_fsync; + fop->fasync = oss_no_fasync; + fop->lock = NULL; + fop->flush = NULL; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + fop->owner = osdev_get_owner (osdev); +#endif +#ifdef HAVE_UNLOCKED_IOCTL + fop->unlocked_ioctl = tmp_unlocked_ioctl; +#endif +#ifdef HAVE_COMPAT_IOCTL + fop->compat_ioctl = tmp_compat_ioctl; +#endif + + return fop; +} + +int +oss_register_chrdev (oss_device_t * osdev, unsigned int major, + const char *name, struct oss_file_operation_handle *op) +{ + int maj; + maj = register_chrdev (major, name, alloc_fop (osdev, op)); + + return maj; +} + +void +oss_register_minor (int major, int minor, char *name) +{ + if (nminors >= MAX_MINOR) + { + oss_cmn_err (CE_WARN, "Too many device files\n"); + return; + } + + minors[nminors].major = major; + minors[nminors].minor = minor; + strcpy (minors[nminors].name, name); + nminors++; +} + +int +oss_unregister_chrdev (unsigned int major, const char *name) +{ + unregister_chrdev (major, name); + return 0; +} + +int +oss_inode_get_minor (oss_inode_handle_t * inode) +{ + return MINOR (((struct inode *) inode)->i_rdev); +} + +int +oss_file_get_flags (oss_file_handle_t * file) +{ + return ((struct file *) file)->f_flags; +} + +void * +oss_file_get_private (oss_file_handle_t * file) +{ + return ((struct file *) file)->private_data; +} + +void +oss_file_set_private (oss_file_handle_t * file, void *v) +{ + ((struct file *) file)->private_data = v; +} + +int +oss_vma_get_flags (oss_vm_area_handle_t * vma) +{ + return ((struct vm_area_struct *) vma)->vm_flags; +} + +int +oss_do_mmap (oss_vm_area_handle_t * v, oss_native_word dmabuf_phys, + int bytes_in_use) +{ + struct vm_area_struct *vma = (struct vm_area_struct *) v; + int res, size; + + if (vma->vm_pgoff != 0) + { + oss_cmn_err (CE_WARN, "mmap() offset must be 0.\n"); + return -EINVAL; + } + + size = vma->vm_end - vma->vm_start; + + if (size != bytes_in_use) + { + oss_cmn_err (CE_WARN, "mmap() size = %ld. Should be %d\n", + size, bytes_in_use); + return -EBUSY; + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) + res = io_remap_page_range (vma, vma->vm_start, + dmabuf_phys, size, vma->vm_page_prot); + +#else + res = io_remap_pfn_range (vma, vma->vm_start, + dmabuf_phys >> PAGE_SHIFT, + size, vma->vm_page_prot); +#endif + + if (res) + { + oss_cmn_err (CE_WARN, "io_remap_pfn_range returned %d\n", res); + return -EAGAIN; + } + + return 0; +} + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); + +typedef int word_type __attribute__ ((mode (__word__))); + +/* DIstructs are pairs of SItype values in the order determined by + little/big ENDIAN. */ + +#if defined(__i386__) || defined(__x86_64__) +struct DIstruct +{ + SItype low, high; +}; +#endif + + +#ifndef __arm__ +/* We need this union to unpack/pack DImode values, since we don't have + any arithmetic yet. Incoming DImode parameters are stored into the + `ll' field, and the unpacked result is read from the struct `s'. */ + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + + +/* From gcc/longlong.h */ + +#ifndef SI_TYPE_SIZE +#define SI_TYPE_SIZE 32 +#endif + +#define __BITS4 (SI_TYPE_SIZE / 4) +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) + +#if defined(__i386__) || defined(__x86_64__) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl %5,%1\n" \ + "sbbl %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mull %3" \ + : "=a" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "rm" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divl %4" \ + : "=a" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "rm" ((USItype) (d))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("bsrl %1,%0" \ + : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#endif /* __i386__ */ + +/* If this machine has no inline assembler, use C macros. */ + +/* Define this unconditionally, so it can be used for debugging. */ +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + USItype __d1, __d0, __q1, __q0; \ + USItype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (USItype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (USItype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (USItype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +#if !defined (udiv_qrnnd) +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c +#endif + +/* End of gcc/longlong.h */ + + +static inline DItype +__negdi2 (DItype u) +{ + DIunion w; + DIunion uu; + + uu.ll = u; + + w.s.low = -uu.s.low; + w.s.high = -uu.s.high - ((USItype) w.s.low > 0); + + return w.ll; +} + +static inline UDItype +__udivmoddi4 (UDItype n, UDItype d, UDItype * rp) +{ + DIunion ww; + DIunion nn, dd; + DIunion rr; + USItype d0, d1, n0, n1, n2; + USItype q0, q1; + USItype b, bm; + + nn.ll = n; + dd.ll = d; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + +#ifndef UDIV_NEEDS_NORMALIZATION + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + udiv_qrnnd (q1, n1, 0, n1, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0. */ + } + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = 0; + *rp = rr.ll; + } + } + +#else /* UDIV_NEEDS_NORMALIZATION */ + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + + This special case is necessary, not an optimization. + (Shifts counts of SI_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = SI_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } +#endif /* UDIV_NEEDS_NORMALIZATION */ + + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + USItype m1, m0; + /* Normalize. */ + + b = SI_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + ww.s.low = q0; + ww.s.high = q1; + return ww.ll; +} + +DItype +__divdi3 (DItype u, DItype v) +{ + word_type c = 0; + DIunion uu, vv; + DItype w; + + uu.ll = u; + vv.ll = v; + + if (uu.s.high < 0) + c = ~c, uu.ll = __negdi2 (uu.ll); + if (vv.s.high < 0) + c = ~c, vv.ll = __negdi2 (vv.ll); + + w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0); + if (c) + w = __negdi2 (w); + + return w; +} + + +DItype +__moddi3 (DItype u, DItype v) +{ + word_type c = 0; + DIunion uu, vv; + DItype w; + + uu.ll = u; + vv.ll = v; + + if (uu.s.high < 0) + c = ~c, uu.ll = __negdi2 (uu.ll); + if (vv.s.high < 0) + vv.ll = __negdi2 (vv.ll); + + (void) __udivmoddi4 (uu.ll, vv.ll, (UDItype *) & w); + if (c) + w = __negdi2 (w); + + return w; +} + + +UDItype +__umoddi3 (UDItype u, UDItype v) +{ + UDItype w; + + (void) __udivmoddi4 (u, v, (UDItype *) & w); + + return w; +} + + +UDItype +__udivdi3 (UDItype n, UDItype d) +{ + return __udivmoddi4 (n, d, (UDItype *) 0); +} +#endif + +#ifdef __arm__ +void +raise(void) +{ + oss_cmn_err (CE_PANIC, "raise() got called\n"); +} + +#endif + +dev_info_t * +oss_create_pcidip (struct pci_dev * pcidev) +{ + dev_info_t *dip; + + if ((dip = oss_pmalloc (sizeof (*dip))) == NULL) + return NULL; + + memset (dip, 0, sizeof (*dip)); + dip->pcidev = pcidev; + + return dip; +} + +int +osscore_pci_read_config_byte (dev_info_t * dip, unsigned int where, + unsigned char *val) +{ + return pci_read_config_byte (dip->pcidev, where, val); +} + +int +osscore_pci_read_config_irq (dev_info_t * dip, unsigned int where, + unsigned char *val) +{ + *val = dip->pcidev->irq; + return 0; // PCIBIOS_SUCCESSFUL +} + +int +osscore_pci_read_config_word (dev_info_t * dip, unsigned int where, + unsigned short *val) +{ + if (dip == NULL) + { + oss_cmn_err (CE_CONT, "osscore_pci_read_config_word: dip==NULL\n"); + return -1; + } + return pci_read_config_word (dip->pcidev, where, val); +} + +int +osscore_pci_read_config_dword (dev_info_t * dip, unsigned int where, + unsigned int *val) +{ + return pci_read_config_dword (dip->pcidev, where, val); +} + +int +osscore_pci_write_config_byte (dev_info_t * dip, unsigned int where, + unsigned char val) +{ + return pci_write_config_byte (dip->pcidev, where, val); +} + +int +osscore_pci_write_config_word (dev_info_t * dip, unsigned int where, + unsigned short val) +{ + return pci_write_config_word (dip->pcidev, where, val); +} + +int +osscore_pci_write_config_dword (dev_info_t * dip, unsigned int where, + unsigned int val) +{ + return pci_write_config_dword (dip->pcidev, where, val); +} + +int +osscore_pci_enable_msi (dev_info_t * dip) +{ + pci_enable_msi (dip->pcidev); + return (dip->pcidev->irq); +} + +/* These definitions must match with oss_config.h */ +typedef int (*oss_tophalf_handler_t) (struct _oss_device_t * osdev); +typedef void (*oss_bottomhalf_handler_t) (struct _oss_device_t * osdev); + +typedef struct +{ + int irq; + oss_device_t *osdev; + oss_tophalf_handler_t top; + oss_bottomhalf_handler_t bottom; +} osscore_intr_t; + +#define MAX_INTRS 32 + +static osscore_intr_t intrs[MAX_INTRS] = { {0} }; +static int nintrs = 0; + +static irqreturn_t +osscore_intr (int irq, void *arg) +{ + int serviced; + osscore_intr_t *intr = arg; + + if (intr->osdev == NULL || intr->top == NULL) /* Removed interrupt */ + return 0; + + serviced = intr->top (intr->osdev); + oss_inc_intrcount (intr->osdev, serviced); + if (serviced) + { + if (intr->bottom != NULL) + intr->bottom (intr->osdev); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +extern int oss_pci_read_config_irq (oss_device_t * osdev, unsigned long where, + unsigned char *val); + +char * +oss_pci_read_devpath (dev_info_t * dip) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) + return dev_name(&dip->pcidev->dev); +#else + return dip->pcidev->dev.bus_id; +#endif +} + +int +oss_register_interrupts (oss_device_t * osdev, int irqnum, + oss_tophalf_handler_t top, + oss_bottomhalf_handler_t bottom) +{ + + unsigned char pci_irq_line; + osscore_intr_t *intr; + char *name; + int err; + + if (nintrs >= MAX_INTRS) + { + oss_cmn_err (CE_CONT, + "oss_register_interrupts: Too many interrupt handlers\n"); + return -ENOMEM; + } + + intr = &intrs[nintrs]; + + if (oss_pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line) > 0) + return -EIO; + + intr->irq = pci_irq_line; + intr->osdev = osdev; + intr->top = top; + intr->bottom = bottom; + + name = osdev_get_nick (osdev); +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + + if ((err = + request_irq (pci_irq_line, osscore_intr, IRQF_SHARED, name, intr)) < 0) + { + oss_cmn_err (CE_CONT, "request_irq(%d) failed, err=%d\n", pci_irq_line, + err); + return err; + } + + nintrs++; + + return 0; +} + +void +oss_unregister_interrupts (oss_device_t * osdev) +{ + int i; + + for (i = 0; i < nintrs; i++) + if (intrs[i].osdev == osdev) + { + free_irq (intrs[i].irq, &intrs[i]); + intrs[i].osdev = NULL; + intrs[i].top = NULL; + intrs[i].bottom = NULL; + } +} + +int +oss_copy_to_user (void *to, const void *from, unsigned long n) +{ + return copy_to_user (to, from, n); +} + +int +oss_copy_from_user (void *to, const void *from, unsigned long n) +{ + return copy_from_user (to, from, n); +} + +static int refcount = 0; + +typedef struct +{ + struct module *module; + int active; +} oss_module_t; + +#define OSS_MAX_MODULES 50 + +static oss_module_t oss_modules[OSS_MAX_MODULES]; +static int num_oss_modules = 0; + +void +oss_inc_refcounts (void) +{ + int i; + refcount++; + for (i = 0; i < num_oss_modules; i++) + if (oss_modules[i].active) + { + if (!try_module_get (oss_modules[i].module)) + oss_cmn_err (CE_WARN, "try_module_get() failed\n"); + } +} + +void +oss_dec_refcounts (void) +{ + int i; + refcount--; + for (i = 0; i < num_oss_modules; i++) + if (oss_modules[i].active) + { + module_put (oss_modules[i].module); + } +} + +void +oss_register_module (struct module *mod) +{ + int i, n = -1; + + for (i = 0; i < num_oss_modules; i++) + if (!oss_modules[i].active) + { + n = i; + break; + } + + if (n == -1) + { + if (num_oss_modules >= OSS_MAX_MODULES) + { + printk (KERN_ALERT "Too many OSS modules\n"); + return; + } + + n = num_oss_modules++; + } + + oss_modules[n].module = mod; + oss_modules[n].active = 1; +} + +void +oss_unregister_module (struct module *mod) +{ + int i; + + for (i = 0; i < num_oss_modules; i++) + if (oss_modules[i].active && oss_modules[i].module == mod) + { + oss_modules[i].active = 0; + oss_modules[i].module = NULL; + return; + } +} + +module_init (osscore_init); +module_exit (osscore_exit); + +#ifdef CONFIG_OSS_VMIX_FLOAT + +#define FP_SAVE(envbuf) asm ("fnsave %0":"=m" (*envbuf)); +#define FP_RESTORE(envbuf) asm ("frstor %0":"=m" (*envbuf)); + +/* SSE/SSE2 compatible macros */ +#define FX_SAVE(envbuf) asm ("fxsave %0":"=m" (*envbuf)); +#define FX_RESTORE(envbuf) asm ("fxrstor %0":"=m" (*envbuf)); + +static int old_arch = 0; /* No SSE/SSE2 instructions */ + +#if 0 +static inline unsigned long +read_cr0 (void) +{ + unsigned long cr0; + asm volatile ("movq %%cr0,%0":"=r" (cr0)); + return cr0; +} + +static inline void +write_cr0 (unsigned long val) +{ + asm volatile ("movq %0,%%cr0"::"r" (val)); +} + +static inline unsigned long +read_cr4 (void) +{ + unsigned long cr4; + asm volatile ("movq %%cr4,%0":"=r" (cr4)); + return cr4; +} + +static inline void +write_cr4 (unsigned long val) +{ + asm volatile ("movq %0,%%cr4"::"r" (val)); +} +#endif + +static inline unsigned long long +read_mxcsr (void) +{ + unsigned long long mxcsr; + asm volatile ("stmxcsr %0":"=m" (mxcsr)); + return mxcsr; +} + +static inline void +write_mxcsr (unsigned long long val) +{ + asm volatile ("ldmxcsr %0"::"m" (val)); +} + +int +oss_fp_check (void) +{ + int eax, ebx, ecx, edx; +#define FLAGS_ID (1<<21) + + oss_native_word flags_reg; + + local_save_flags (flags_reg); + flags_reg &= ~FLAGS_ID; + local_irq_restore (flags_reg); + + local_save_flags (flags_reg); + if (flags_reg & FLAGS_ID) + return 0; + + flags_reg |= FLAGS_ID; + local_irq_restore (flags_reg); + + local_save_flags (flags_reg); + if (!(flags_reg & FLAGS_ID)) + return 0; + +#define CPUID_FXSR (1<<24) +#define CPUID_SSE (1<<25) +#define CPUID_SSE2 (1<<26) + + cpuid (1, &eax, &ebx, &ecx, &edx); + + if (!(edx & CPUID_FXSR)) + return -1; + + /* + * Older machines require different FP handling than the latest ones. Use the SSE + * instruction set as an indicator. + */ + if (!(edx & CPUID_SSE)) + old_arch = 1; + + return 1; +} + +void +oss_fp_save (short *envbuf, unsigned int flags[]) +{ + flags[0] = read_cr0 (); + write_cr0 (flags[0] & ~0x0e); /* Clear CR0.TS/MP/EM */ + + if (old_arch) + { + FP_SAVE (envbuf); + } + else + { + flags[1] = read_cr4 (); + write_cr4 (flags[1] | 0x600); /* Set OSFXSR & OSXMMEXCEPT */ + FX_SAVE (envbuf); + asm ("fninit"); + asm ("fwait"); + write_mxcsr (0x1f80); + } + flags[2] = read_cr0 (); +} + +void +oss_fp_restore (short *envbuf, unsigned int flags[]) +{ + asm ("fwait"); + if (old_arch) + { + FP_RESTORE (envbuf); + } + else + { + FX_RESTORE (envbuf); + write_cr4 (flags[1]); /* Restore cr4 */ + } + write_cr0 (flags[0]); /* Restore cr0 */ +} +#endif + +#if 0 +void +__stack_chk_fail (void) +{ + panic ("__stack_chk_fail\n"); +} +#endif + +/* + * Exported symbols + */ + +#define EXPORT_FUNC(name) extern void name(void);EXPORT_SYMBOL(name); +#define EXPORT_DATA(name) extern int name;EXPORT_SYMBOL(name); + +/* EXPORT_SYMBOL (__stack_chk_fail); */ + +#ifdef CONFIG_OSS_VMIX_FLOAT +EXPORT_SYMBOL (oss_fp_check); +EXPORT_SYMBOL (oss_fp_save); +EXPORT_SYMBOL (oss_fp_restore); +#endif + +EXPORT_SYMBOL (oss_register_chrdev); +EXPORT_SYMBOL (oss_unregister_chrdev); +EXPORT_SYMBOL (oss_reserve_pages); +EXPORT_SYMBOL (oss_unreserve_pages); +EXPORT_FUNC (ac97_install); +EXPORT_FUNC (ac97_install_full); +EXPORT_FUNC (ac97_playrate); +EXPORT_FUNC (ac97_recrate); +EXPORT_FUNC (ac97_varrate); +EXPORT_FUNC (ac97_override_control); +EXPORT_FUNC (ac97_init_ext); +EXPORT_FUNC (ac97_mixer_set); +EXPORT_FUNC (ac97_spdif_setup); +EXPORT_FUNC (ac97_spdifout_ctl); +EXPORT_FUNC (ac97_remove_control); +EXPORT_SYMBOL (ac97_amplifier); +EXPORT_FUNC (ac97_disable_spdif); +EXPORT_FUNC (ac97_enable_spdif); +EXPORT_FUNC (ac97_mixext_ctl); +EXPORT_FUNC (ac97_spdifin_ctl); +EXPORT_FUNC (oss_pci_byteswap); +EXPORT_SYMBOL (mixer_ext_truncate); +EXPORT_SYMBOL (mixer_ext_rebuild_all); +EXPORT_FUNC (remux_install); +EXPORT_SYMBOL (oss_strlen); +EXPORT_SYMBOL (oss_strcmp); +EXPORT_FUNC (oss_install_mididev); +EXPORT_DATA (detect_trace); +EXPORT_SYMBOL (dmap_get_qhead); +EXPORT_SYMBOL (dmap_get_qtail); +EXPORT_FUNC (oss_alloc_dmabuf); +EXPORT_SYMBOL (oss_contig_free); +EXPORT_SYMBOL (oss_contig_malloc); +EXPORT_FUNC (oss_disable_device); +EXPORT_FUNC (oss_free_dmabuf); +EXPORT_SYMBOL (oss_map_pci_mem); +EXPORT_SYMBOL (oss_install_audiodev); +EXPORT_SYMBOL (oss_install_audiodev_with_devname); +EXPORT_FUNC (oss_audio_set_error); +EXPORT_SYMBOL (load_mixer_volumes); +EXPORT_SYMBOL (oss_unmap_pci_mem); +EXPORT_SYMBOL (oss_memset); +EXPORT_SYMBOL (oss_mutex_cleanup); +EXPORT_SYMBOL (oss_mutex_init); +EXPORT_SYMBOL (oss_register_device); +EXPORT_SYMBOL (oss_register_interrupts); +EXPORT_SYMBOL (oss_inc_intrcount); +EXPORT_SYMBOL (oss_spin_lock); +EXPORT_SYMBOL (oss_spin_lock_irqsave); +EXPORT_SYMBOL (oss_spin_unlock); +EXPORT_SYMBOL (oss_spin_unlock_irqrestore); +EXPORT_SYMBOL (oss_udelay); +EXPORT_FUNC (oss_unregister_device); +EXPORT_SYMBOL (oss_unregister_interrupts); +EXPORT_SYMBOL (oss_virt_to_bus); +EXPORT_FUNC (oss_pci_read_config_byte); +EXPORT_FUNC (oss_pci_read_config_word); +EXPORT_FUNC (oss_pci_read_config_dword); +EXPORT_FUNC (oss_pci_write_config_byte); +EXPORT_FUNC (oss_pci_write_config_word); +EXPORT_FUNC (oss_pci_write_config_dword); +EXPORT_FUNC (oss_pci_enable_msi); +EXPORT_SYMBOL (oss_pci_read_config_irq); +EXPORT_SYMBOL (oss_pci_read_devpath); +EXPORT_SYMBOL (oss_get_jiffies); +EXPORT_SYMBOL (mixer_find_ext); +EXPORT_SYMBOL (oss_install_mixer); +EXPORT_SYMBOL (oss_strcpy); +EXPORT_SYMBOL (oss_kmem_free); +#ifndef __arm__ +EXPORT_FUNC (uart401_init); +EXPORT_FUNC (uart401_disable); +EXPORT_FUNC (uart401_irq); +#endif +EXPORT_SYMBOL (mixer_ext_set_init_fn); +EXPORT_SYMBOL (mixer_ext_set_vmix_init_fn); +#ifdef CONFIG_OSS_VMIX +EXPORT_FUNC (vmix_attach_audiodev); +EXPORT_FUNC (vmix_detach_audiodev); +EXPORT_FUNC (vmix_change_devnames); +#endif +EXPORT_SYMBOL (mixer_ext_set_strings); +EXPORT_SYMBOL (mixer_ext_create_group); +EXPORT_SYMBOL (mixer_ext_create_group_flags); +EXPORT_SYMBOL (mixer_ext_create_control); +EXPORT_SYMBOL (oss_strncpy); +EXPORT_SYMBOL (oss_memcpy); +EXPORT_SYMBOL (oss_kmem_alloc); +EXPORT_DATA (oss_hz); +EXPORT_FUNC (oss_spdif_open); +EXPORT_FUNC (oss_spdif_ioctl); +EXPORT_FUNC (oss_spdif_install); +EXPORT_FUNC (oss_spdif_uninstall); +EXPORT_FUNC (oss_spdif_close); +EXPORT_FUNC (oss_spdif_mix_init); +EXPORT_FUNC (oss_spdif_setrate); +EXPORT_FUNC (create_new_card); +EXPORT_FUNC (oss_audio_ioctl); +EXPORT_FUNC (oss_audio_open_engine); +EXPORT_FUNC (oss_audio_release); +EXPORT_FUNC (oss_audio_set_rate); +EXPORT_SYMBOL (oss_uiomove); +EXPORT_SYMBOL (oss_get_pid); +EXPORT_SYMBOL (oss_get_uid); +EXPORT_SYMBOL (oss_get_procname); +EXPORT_SYMBOL (mix_cvt); +EXPORT_FUNC (oss_audio_set_format); +EXPORT_FUNC (oss_audio_set_channels); +EXPORT_FUNC (midiparser_create); +EXPORT_FUNC (midiparser_input); +EXPORT_FUNC (midiparser_unalloc); +EXPORT_FUNC (mixer_ext_create_device); +EXPORT_SYMBOL (mixer_ext_recrw); +EXPORT_SYMBOL (mixer_ext_rw); +EXPORT_SYMBOL (mixer_ext_set_enum); +EXPORT_SYMBOL (mixer_ext_set_description); +EXPORT_SYMBOL (osdev_create); +EXPORT_FUNC (osdev_clone); +EXPORT_SYMBOL (osdev_delete); +EXPORT_FUNC (oss_audio_chpoll); +EXPORT_FUNC (oss_audio_delayed_attach); +EXPORT_FUNC (oss_audio_read); +EXPORT_FUNC (oss_audio_write); +EXPORT_SYMBOL (oss_create_wait_queue); +EXPORT_SYMBOL (oss_remove_wait_queue); +EXPORT_SYMBOL (oss_reset_wait_queue); +EXPORT_SYMBOL (oss_sleep); +EXPORT_SYMBOL (oss_strncmp); +EXPORT_SYMBOL (oss_timeout); +EXPORT_SYMBOL (oss_untimeout); +EXPORT_SYMBOL (oss_wakeup); +#if 0 +EXPORT_FUNC (ossddk_ac97_install); +EXPORT_FUNC (ossddk_ac97_is_varrate); +EXPORT_FUNC (ossddk_ac97_remove); +EXPORT_FUNC (ossddk_ac97_set_ext_init); +EXPORT_FUNC (ossddk_ac97_set_playrate); +EXPORT_FUNC (ossddk_ac97_set_recrate); +EXPORT_FUNC (ossddk_adev_get_devc); +EXPORT_FUNC (ossddk_adev_get_dmapin); +EXPORT_FUNC (ossddk_adev_get_dmapout); +EXPORT_FUNC (ossddk_adev_get_flags); +EXPORT_FUNC (ossddk_adev_get_label); +EXPORT_FUNC (ossddk_adev_get_portc); +EXPORT_FUNC (ossddk_adev_get_portc_play); +EXPORT_FUNC (ossddk_adev_get_portc_record); +EXPORT_FUNC (ossddk_adev_get_songname); +EXPORT_FUNC (ossddk_adev_set_buflimits); +EXPORT_FUNC (ossddk_adev_set_caps); +EXPORT_FUNC (ossddk_adev_set_channels); +EXPORT_FUNC (ossddk_adev_set_devc); +EXPORT_FUNC (ossddk_adev_set_enable_flag); +EXPORT_FUNC (ossddk_adev_set_flags); +EXPORT_FUNC (ossddk_adev_set_formats); +EXPORT_FUNC (ossddk_adev_set_label); +EXPORT_FUNC (ossddk_adev_set_magic); +EXPORT_FUNC (ossddk_adev_set_mixer); +EXPORT_FUNC (ossddk_adev_set_portc); +EXPORT_FUNC (ossddk_adev_set_portc_play); +EXPORT_FUNC (ossddk_adev_set_portc_record); +EXPORT_FUNC (ossddk_adev_set_portnum); +EXPORT_FUNC (ossddk_adev_set_rates); +EXPORT_FUNC (ossddk_adev_set_ratesource); +EXPORT_FUNC (ossddk_adev_set_songname); +EXPORT_FUNC (ossddk_adev_set_unloaded_flag); +EXPORT_FUNC (ossddk_audio_inputintr); +EXPORT_FUNC (ossddk_audio_outputintr); +EXPORT_FUNC (ossddk_disable_device); +EXPORT_FUNC (ossddk_dmap_get_buffsize); +EXPORT_FUNC (ossddk_dmap_get_buffused); +EXPORT_FUNC (ossddk_dmap_get_dmabuf); +EXPORT_FUNC (ossddk_dmap_get_fragsize); +EXPORT_FUNC (ossddk_dmap_get_numfrags); +EXPORT_FUNC (ossddk_dmap_get_phys); +EXPORT_FUNC (ossddk_dmap_get_private); +EXPORT_FUNC (ossddk_dmap_get_qhead); +EXPORT_FUNC (ossddk_dmap_get_qtail); +EXPORT_FUNC (ossddk_dmap_set_buffsize); +EXPORT_FUNC (ossddk_dmap_set_callback); +EXPORT_FUNC (ossddk_dmap_set_dmabuf); +EXPORT_FUNC (ossddk_dmap_set_fragsize); +EXPORT_FUNC (ossddk_dmap_set_numfrags); +EXPORT_FUNC (ossddk_dmap_set_phys); +EXPORT_FUNC (ossddk_dmap_set_playerror); +EXPORT_FUNC (ossddk_dmap_set_private); +EXPORT_FUNC (ossddk_dmap_set_recerror); +EXPORT_FUNC (ossddk_install_audiodev); +EXPORT_FUNC (ossddk_install_mixer); +EXPORT_FUNC (ossddk_mixer_create_control); +EXPORT_FUNC (ossddk_mixer_create_group); +EXPORT_FUNC (ossddk_mixer_get_devc); +EXPORT_FUNC (ossddk_mixer_set_strings); +EXPORT_FUNC (ossddk_mixer_touch); +EXPORT_FUNC (ossddk_mixer_truncate); +EXPORT_FUNC (ossddk_osdev_get_devc); +EXPORT_FUNC (ossddk_register_device); +EXPORT_FUNC (ossddk_unregister_device); +#endif +EXPORT_SYMBOL (osdev_set_major); +EXPORT_SYMBOL (osdev_set_owner); +EXPORT_SYMBOL (osdev_get_owner); +EXPORT_SYMBOL (oss_create_pcidip); +EXPORT_SYMBOL (touch_mixer); +EXPORT_SYMBOL (oss_mixer_ext); +EXPORT_SYMBOL (oss_request_major); +EXPORT_SYMBOL (audio_engines); +EXPORT_DATA (midi_devs); +EXPORT_SYMBOL (mixer_devs); +EXPORT_SYMBOL (mixer_devs_p); +EXPORT_DATA (num_audio_engines); +EXPORT_DATA (num_mididevs); +EXPORT_SYMBOL (num_mixers); +EXPORT_DATA (oss_timing_mutex); +EXPORT_DATA (oss_num_cards); +EXPORT_FUNC (oss_do_timing); +EXPORT_FUNC (oss_do_timing2); +EXPORT_FUNC (oss_timing_enter); +EXPORT_FUNC (oss_timing_leave); +#ifndef __arm__ +EXPORT_SYMBOL (__udivdi3); +EXPORT_SYMBOL (__umoddi3); +EXPORT_SYMBOL (__divdi3); +#else +EXPORT_SYMBOL (raise); +#endif +EXPORT_SYMBOL (oss_copy_from_user); +EXPORT_SYMBOL (oss_copy_to_user); +EXPORT_SYMBOL (osdev_set_irqparms); +EXPORT_SYMBOL (osdev_get_irqparms); +EXPORT_SYMBOL (osdev_get_nick); +EXPORT_SYMBOL (osdev_get_instance); +EXPORT_SYMBOL (oss_inc_refcounts); +EXPORT_SYMBOL (oss_dec_refcounts); +EXPORT_SYMBOL (oss_register_module); +EXPORT_SYMBOL (oss_unregister_module); +EXPORT_SYMBOL (oss_audio_reset); +EXPORT_SYMBOL (oss_audio_start_syncgroup); +EXPORT_SYMBOL (oss_encode_enum); +EXPORT_SYMBOL (dmap_get_qlen); +EXPORT_SYMBOL (num_audio_devfiles); +EXPORT_SYMBOL (oss_audio_inc_byte_counter); +EXPORT_SYMBOL (oss_audio_register_client); +EXPORT_SYMBOL (audio_devfiles); +EXPORT_FUNC (oss_get_cardinfo); +EXPORT_SYMBOL (oss_pmalloc); +EXPORT_SYMBOL (oss_add_audio_devlist); +EXPORT_FUNC (oss_memblk_malloc); +EXPORT_FUNC (oss_memblk_free); +EXPORT_FUNC (oss_memblk_unalloc); +EXPORT_DATA (oss_global_memblk); +EXPORT_FUNC (oss_get_procinfo); +EXPORT_DATA (mixer_muted); + +#ifdef CONFIG_OSS_MIDI +EXPORT_FUNC (oss_midi_ioctl); +EXPORT_FUNC (oss_midi_copy_timer); +#endif diff --git a/setup/Linux/oss/build/ossdip.h b/setup/Linux/oss/build/ossdip.h new file mode 100644 index 0000000..811e70a --- /dev/null +++ b/setup/Linux/oss/build/ossdip.h @@ -0,0 +1,10 @@ +/* + * Purpose: Definition of the _dev_info_t structure for Linux + */ +#ifndef OSSDIP_H +#define OSSDIP_H +struct _dev_info_t +{ + struct pci_dev *pcidev; +}; +#endif diff --git a/setup/Linux/oss/build/pci_wrapper.inc b/setup/Linux/oss/build/pci_wrapper.inc new file mode 100644 index 0000000..e08ec3a --- /dev/null +++ b/setup/Linux/oss/build/pci_wrapper.inc @@ -0,0 +1,93 @@ +/* + * Purpose: PCI wrapper routines for Linux + * + * This source file contains probe and remove routines for PCI devices. + * This code will be compiled in the target system. + */ +/* + * Copyright (C) 4Front Technologies 2005-2007. Released under GPL2 license. + */ +typedef struct +{ + struct pci_dev *pcidev; + oss_device_t *osdev; +} dev_map_t; + +#define MAX_INSTANCE 10 +static dev_map_t dev_map[MAX_INSTANCE]; +static int n_devmap = 0; + +static int __devinit +osspci_probe (struct pci_dev *pcidev, const struct pci_device_id *pciid) +{ + oss_device_t *osdev; + dev_info_t *dip; + + if (n_devmap >= MAX_INSTANCE) + { + printk (KERN_ALERT "oss: Too many instances of " DRIVER_NICK); + return -ENOMEM; + } + + if ((dip = oss_create_pcidip (pcidev)) == NULL) + return -ENOMEM; + + if ((osdev = + osdev_create (dip, DRIVER_TYPE, instance++, DRIVER_NICK, + NULL)) == NULL) + { + return -ENOMEM; + } + + osdev_set_owner (osdev, THIS_MODULE); + + if (module_major == 0) + module_major = oss_request_major (osdev, 0, DRIVER_NICK); + if (module_major <= 0) + { + printk (KERN_ALERT "Failed to allocate major device for " DRIVER_NICK); + return -EIO; + + } + osdev_set_major (osdev, module_major); + + pci_enable_device (pcidev); + if (!DRIVER_ATTACH (osdev)) + { + pci_disable_device (pcidev); + return -EIO; + } + + dev_map[n_devmap].pcidev = pcidev; + dev_map[n_devmap++].osdev = osdev; + oss_audio_delayed_attach (); + + return 0; +} + +static void __devexit +osspci_remove (struct pci_dev *pcidev) +{ + int i; + oss_device_t *osdev; + + for (i = 0; i < n_devmap; i++) + if (dev_map[i].pcidev == pcidev) + { + osdev = dev_map[i].osdev; + if (!DRIVER_DETACH (osdev)) + printk (KERN_ALERT DRIVER_NICK ": Unloading busy device\n"); + pci_disable_device (dev_map[i].pcidev); + osdev_delete (osdev); + + return; + } + + printk (KERN_ALERT DRIVER_NICK ": Can't find the PCI device to detach\n"); +} + +void +oss_pcie_init (oss_device_t * osdev, int flags) +{ + /* TODO: Do we need to do something here? */ +} diff --git a/setup/Linux/oss/build/usb_wrapper.inc b/setup/Linux/oss/build/usb_wrapper.inc new file mode 100644 index 0000000..ee199a7 --- /dev/null +++ b/setup/Linux/oss/build/usb_wrapper.inc @@ -0,0 +1,730 @@ +/* + * Purpose: Low level USB wrapper routines for Linux (2.6.x and later) + * + * This file contains the Linux specific USB support routines defined in udi.h + */ +/* + * Copyright (C) 4Front Technologies 2005-2007. Released under GPL2 license. + */ +#include "udi.h" + +#undef IO_DEBUG +static const udi_usb_devinfo *known_devices = NULL; + +#define MAX_DEVICE_SLOTS 20 + +int udi_usb_trace = 0; + +static udi_usb_driver *drv = NULL; +extern void *oss_pmalloc (size_t sz); + +struct udi_usb_devc +{ + struct usb_device *usb_dev; + const struct usb_device_id *id; + const udi_usb_devinfo *udi_usb_dev; + char *devpath; + + int enabled; + + int vendor, product, class, subclass; + struct usb_interface *iface; + int iface_number; + char *dev_name; + char *altsetting_labels; + int default_altsetting; + unsigned int altsetting_mask; + udi_usb_driver *drv; + void *client_devc; + int num_altsettings; + int usb_version; + struct usb_host_interface *altsetting; + +}; + +struct _udi_endpoint_handle_t +{ + unsigned char desc[32]; +}; + +#define MAX_DEVC 32 + +static udi_usb_devc usb_devc_list[MAX_DEVC] = { {0} }; +static int ndevs = 0; + +udi_endpoint_handle_t * +udi_open_endpoint (udi_usb_devc * usbdev, void *ep_descr) +{ + return (udi_endpoint_handle_t *) ep_descr; +} + +void +udi_close_endpoint (udi_endpoint_handle_t * eph) +{ + // NOP +} + +int +udi_endpoint_get_num (udi_endpoint_handle_t * eph) +{ + return eph->desc[2] /* & 0x7f */; +} + +#if 1 +static void +dump_configs (struct usb_device *dev) +{ + int c; + + printk ("#configs %d\n", dev->descriptor.bNumConfigurations); + + for (c = 0; c < dev->descriptor.bNumConfigurations; c++) + { + int i, j, k; + struct usb_host_config *config = &dev->config[c]; + + printk ("\tConfig #%d - #interfaces=%d\n", c, + config->desc.bNumInterfaces); + + for (j = 0; j < config->desc.bNumInterfaces; j++) + { + struct usb_interface *ifp = config->interface[j]; + printk ("\t\tInterface #%d - altsettings=%d\n", j, + ifp->num_altsetting); + + for (k = 0; k < ifp->num_altsetting; k++) + { + struct usb_host_interface *alt = &ifp->altsetting[k]; + unsigned char *buf = alt->extra; + + printk ("\t\t\tAlt setting #%d:\n", k); + + for (i = 0; i < alt->extralen; i++) + { + if (!(i % 8)) + { + if (i) + printk ("\n"); + printk ("\t\t\t%04x: ", i); + } + printk ("%02x ", buf[i]); + } + + printk ("\n"); + } + } + } +} +#endif + +static int +udi_attach_usbdev (struct usb_device *dev, + oss_device_t * osdev, + char *devpath, + struct usb_interface *iface, + const struct usb_device_id *id, + const udi_usb_devinfo * udi_usb_dev) +{ + int cfg_num, ep; + + udi_usb_devc *devc = &usb_devc_list[ndevs]; + struct usb_host_interface *alts; + + if (ndevs >= MAX_DEVC) + { + printk ("OSS: Too many USB audio/midi devices\n"); + return -ENODEV; + } + + if (udi_usb_trace > 1) + printk ("OSS: Attaching USB device %x:%x/%d, class=%x:%x, name=%s\n", + dev->descriptor.idVendor, dev->descriptor.idProduct, + iface->altsetting[0].desc.bInterfaceNumber, + iface->altsetting[0].desc.bInterfaceClass, + iface->altsetting[0].desc.bInterfaceSubClass, udi_usb_dev->name); + + devc->usb_dev = dev; + devc->id = id; + devc->udi_usb_dev = udi_usb_dev; + + devc->vendor = dev->descriptor.idVendor; + devc->product = dev->descriptor.idProduct; + devc->usb_version = dev->descriptor.bcdUSB >> 8; + devc->class = iface->altsetting[0].desc.bInterfaceClass; + devc->subclass = iface->altsetting[0].desc.bInterfaceSubClass; + devc->iface_number = iface->altsetting[0].desc.bInterfaceNumber; + devc->iface = iface; + devc->dev_name = udi_usb_dev->name; + devc->devpath = devpath; + devc->num_altsettings = iface->num_altsetting; + devc->altsetting = iface->altsetting; + + alts = &iface->altsetting[devc->num_altsettings - 1]; + ep = 0; + + if (alts->desc.bNumEndpoints > 1) + ep = 1; + + if (udi_usb_trace > 2) + { + int i; + + for (i = 0; i < alts->desc.bNumEndpoints; i++) + { + printk ("Endpoint: %02x\n", + alts->endpoint[i].desc.bEndpointAddress); + } + } + + cfg_num = 0; + + devc->enabled = 1; + devc->drv = drv; + + if (udi_usb_trace > 2) + dump_configs (dev); + + if ((devc->client_devc = drv->attach (devc, osdev)) == NULL) + { + return -EIO; + } + + ndevs++; + + usb_set_intfdata (iface, devc); + return 0; +} + +static char *prev_devices[32] = { NULL }; +static int nprev_devices = 0; + +static int +udi_usb_probe (struct usb_interface *iface, const struct usb_device_id *id) +{ + int i; + static int ncalls = 0; + oss_device_t *osdev = NULL; + dev_info_t *dip = NULL; // TODO + + char nick[32]; + int inst = 0; + + struct usb_device *dev = interface_to_usbdev (iface); + + if (ncalls++ > 100) + return -EIO; + + sprintf (nick, "usb%04x%04x-", dev->descriptor.idVendor, + dev->descriptor.idProduct); + +/* + * Find out how many instances of this device (ID) are already attached. + */ + + for (i = 0; i < nprev_devices; i++) + { + if (strcmp (nick, prev_devices[i]) == 0) + { + inst++; + } + } + + prev_devices[nprev_devices] = oss_pmalloc (strlen (nick) + 1); + strcpy (prev_devices[nprev_devices], nick); + if (nprev_devices < 32) + nprev_devices++; + + if ((osdev = osdev_create (dip, DRV_USB, inst, nick, NULL)) == NULL) + { + return -ENOMEM; + } + osdev_set_owner (osdev, THIS_MODULE); + osdev_set_major (osdev, usb_major); + + i = 0; + if (udi_usb_trace > 1) + printk ("\n\nProbing dev=%s id=%x:%x/%d\n", dev->devpath, + dev->descriptor.idVendor, + dev->descriptor.idProduct, + iface->altsetting[0].desc.bInterfaceNumber); + + while (i >= 0 && known_devices[i].vendor >= 0) + { + if (dev->descriptor.idVendor == known_devices[i].vendor && + dev->descriptor.idProduct == known_devices[i].product) + { + int ret; + const udi_usb_devinfo *d = &known_devices[i]; + ret = udi_attach_usbdev (dev, osdev, dev->devpath, iface, id, d); + return ret; + } + else + i++; + } + +/* Try the "generic" device */ + { + int ret; + const udi_usb_devinfo *d = &known_devices[i]; + ret = udi_attach_usbdev (dev, osdev, dev->devpath, iface, id, d); + return ret; + } + + return -ENODEV; +} + +static void +udi_usb_disconnect (struct usb_interface *iface) +{ + udi_usb_devc *devc = usb_get_intfdata (iface); + //struct usb_device *dev = interface_to_usbdev (iface); + + if (devc == (udi_usb_devc *) - 1) + return; + + if (!devc->enabled) + return; + + if (udi_usb_trace > 0) + printk ("OSS: Disconnect USB device %x:%x %s\n", devc->vendor, + devc->product, devc->udi_usb_dev->name); + devc->drv->disconnect (devc->client_devc); + devc->enabled = 0; +} + +static struct usb_driver oss_usb = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +owner:THIS_MODULE, +#endif +name:"oss_usb", +probe:udi_usb_probe, +disconnect:udi_usb_disconnect, +id_table:udi_usb_table +}; + +static int udi_usb_installed = 0; + +int +udi_attach_usbdriver (oss_device_t * osdev, const udi_usb_devinfo * devlist, + udi_usb_driver * driver) +{ + drv = driver; + known_devices = devlist; + return 1; +} + +void +udi_unload_usbdriver (oss_device_t * osdev) +{ +} + +/* + * Device access routines + */ + +int +udi_usbdev_get_class (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->class; +} + +int +udi_usbdev_get_subclass (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->subclass; +} + +int +udi_usbdev_get_vendor (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->vendor; +} + +int +udi_usbdev_get_product (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->product; +} + +int +udi_usbdev_get_inum (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->iface_number; +} + +int +udi_usbdev_set_interface (udi_usb_devc * usbdev, int inum, int altset) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return usb_set_interface (devc->usb_dev, inum, altset); +} + +unsigned char * +udi_usbdev_get_endpoint (udi_usb_devc * usbdev, int altsetting, int n, + int *len) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + int num_endpoints; + struct usb_device *dev; + struct usb_host_interface *alts; + struct usb_interface *iface; + + dev = devc->usb_dev; + iface = devc->iface; + + if (altsetting >= devc->num_altsettings) + return NULL; + + alts = &iface->altsetting[altsetting]; + + num_endpoints = alts->desc.bNumEndpoints; + + if (n >= num_endpoints) + return NULL; + + *len = alts->endpoint[n].desc.bLength; + return (unsigned char *) &alts->endpoint[n].desc; +} + +int +udi_usbdev_get_num_altsettings (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->num_altsettings; +} + +int +udi_usbdev_get_usb_version (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->usb_version; +} + +unsigned char * +udi_usbdev_get_altsetting (udi_usb_devc * usbdev, int n, int *size) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + struct usb_host_interface *alt; + + if (n < 0 || n >= devc->num_altsettings) + { + /* printk("udi usb: Bad altsetting %d (%d)\n", n, n >= devc->num_altsettings); */ + return NULL; + } + + alt = &devc->altsetting[n]; + + *size = alt->extralen; + return alt->extra; +} + +char * +udi_usbdev_get_name (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->dev_name == NULL ? "Unknown" : devc->dev_name; +} + + +char * +udi_usbdev_get_altsetting_labels (udi_usb_devc * usbdev, int if_num, int *default_alt, unsigned int *mask) +{ + int i; + + *default_alt=1; + *mask=0xffffffff; + + if (usbdev->udi_usb_dev == NULL) /* No device definitions available */ + { + return NULL; + } + + for (i=0;usbdev->udi_usb_dev->altsettings[i].altsetting_labels!=NULL;i++) + if (i==if_num) + { + *default_alt = usbdev->udi_usb_dev->altsettings[i].default_altsetting; + *mask = usbdev->udi_usb_dev->altsettings[i].altsetting_mask; + if (*mask==0) + *mask=0xffffffff; + return usbdev->udi_usb_dev->altsettings[i].altsetting_labels; + } + + return NULL; /* Not found */ +} + +char * +udi_usbdev_get_string (udi_usb_devc * usbdev, int ix) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + static char str[100]; + int err; + + if (ix == 0) + return NULL; + + if ((err = usb_string (devc->usb_dev, ix, str, sizeof (str) - 1)) != 0) + { + return NULL; + } + + return str; +} + +char * +udi_usbdev_get_devpath (udi_usb_devc * usbdev) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + return devc->devpath; +} + +int +udi_usb_snd_control_msg (udi_usb_devc * usbdev, unsigned int endpoint, + unsigned char rq, + unsigned char rqtype, + unsigned short value, + unsigned short index, + void *buf, int len, int timeout) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + int err; + + if (!devc->enabled) + return -EPIPE; + + if (timeout < 0) + timeout = 0; + +#ifdef IO_DEBUG + printk ("Snd %x (%x) rq=%x, rt=%x, v=%x, ix=%x, l=%d %02x %02x\n", + devc->usb_dev, + usb_sndctrlpipe (devc->usb_dev, endpoint), + rq, rqtype, value, index, len, b[0], b[1]); +#endif + err = usb_control_msg (devc->usb_dev, + usb_sndctrlpipe (devc->usb_dev, endpoint), + rq, rqtype, value, index, buf, len, timeout); +#ifdef IO_DEBUG + if (err < 0) + printk ("Usb write error %d\n", err); +#endif + + return err; +} + +int +udi_usb_rcv_control_msg (udi_usb_devc * usbdev, unsigned int endpoint, + unsigned char rq, + unsigned char rqtype, + unsigned short value, + unsigned short index, + void *buf, int len, int timeout) +{ + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + int err; + + if (!devc->enabled) + return -EPIPE; + + if (timeout < 0) + timeout = 0; + +#ifdef IO_DEBUG + printk ("Rcv %x (%x) rq=%x, rt=%x, v=%x, ix=%x, l=%d\n", + devc->usb_dev, + (unsigned int) usb_rcvctrlpipe (devc->usb_dev, endpoint), + rq, rqtype | USB_DIR_IN, value, index, len); +#endif + err = usb_control_msg (devc->usb_dev, + (unsigned int) usb_rcvctrlpipe (devc->usb_dev, + endpoint), rq, + rqtype | USB_DIR_IN, value, index, buf, len, + timeout); +#ifdef IO_DEBUG + if (err < 0) + printk ("Usb read error %d\n", err); + else + printk ("Got %02x %02x\n", b[0], b[1]); +#endif + + return err; +} + +/* Request stuff */ + +struct udi_usb_request +{ + struct urb *urb; + udi_usb_complete_func_t callback; + void *callback_arg; + int active; + void *data; +}; + +udi_usb_request_t + * udi_usb_alloc_request (udi_usb_devc * usbdev, udi_endpoint_handle_t * eph, + int nframes, int xfer_type) +{ + udi_usb_request_t *rq; + udi_usb_devc *devc = (udi_usb_devc *) usbdev; + + if ((rq = kmalloc (sizeof (*rq), GFP_KERNEL)) == NULL) + { + printk ("udi_usb_alloc_request: Out of memory\n"); + return NULL; + } + + memset (rq, 0, sizeof (*rq)); + + if ((rq->urb = usb_alloc_urb (nframes, 0)) == NULL) + { + kfree (rq); + printk ("udi_usb_alloc_request: Failed to allocate URB\n"); + return NULL; + } + + rq->urb->dev = devc->usb_dev; + rq->urb->number_of_packets = nframes; + rq->active = 0; + + return rq; +} + +void +udi_usb_free_request (udi_usb_request_t * request) +{ + if (request == NULL) + return; + + udi_usb_cancel_request (request); + + usb_free_urb (request->urb); + kfree (request); +} + +unsigned char * +udi_usb_request_actdata (udi_usb_request_t * request) +{ + return request->data; +} + +static void +complete_func (struct urb *urb) +{ + udi_usb_request_t *request = urb->context; + + request->active = 0; + request->callback (request, request->callback_arg); +} + +int +udi_usb_submit_request (udi_usb_request_t * request, + udi_usb_complete_func_t callback, void *callback_arg, + udi_endpoint_handle_t * eph, int xfer_type, + void *data, int data_len) +{ + struct urb *urb; + struct usb_device *d; + int i, err; + int endpoint = eph->desc[2] & 0x7f; + + if (request == NULL) + return -EINVAL; + + urb = request->urb; + d = urb->dev; + request->callback = callback; + request->callback_arg = callback_arg; + request->data = data; + urb->complete = (usb_complete_t) complete_func; + urb->context = request; + urb->transfer_buffer = data; + + for (i = 0; i < urb->number_of_packets; i++) + { + urb->iso_frame_desc[i].status = 0; + urb->iso_frame_desc[i].length = data_len; + urb->iso_frame_desc[i].offset = i * data_len; + } + + urb->transfer_buffer_length = urb->actual_length = data_len; + + switch (xfer_type) + { + case UDI_USBXFER_ISO_WRITE: + urb->pipe = usb_sndisocpipe (urb->dev, endpoint); + urb->transfer_flags = URB_ISO_ASAP; + urb->interval = 1; + break; + + case UDI_USBXFER_ISO_READ: + urb->pipe = usb_rcvisocpipe (urb->dev, endpoint); + urb->transfer_flags = URB_ISO_ASAP; + urb->interval = 1; + break; + + case UDI_USBXFER_BULK_READ: + usb_fill_bulk_urb (urb, d, usb_rcvbulkpipe (d, endpoint), + data, data_len, + (usb_complete_t) complete_func, request); + break; + + case UDI_USBXFER_INTR_READ: + usb_fill_int_urb (urb, d, usb_rcvintpipe (d, endpoint), + data, data_len, + (usb_complete_t) complete_func, request, 8); + break; + + case UDI_USBXFER_BULK_WRITE: + usb_fill_bulk_urb (urb, d, usb_sndbulkpipe (d, endpoint), + data, data_len, + (usb_complete_t) complete_func, request); + break; + + default: + printk ("udi usb: Bad xfer type %d\n", xfer_type); + return -EINVAL; + } + +#ifdef SLAB_ATOMIC + if ((err = usb_submit_urb (request->urb, SLAB_ATOMIC)) >= 0) + request->active = 1; +#else + /* + * Linux 2.6.20 and later don't have SLAB_ATOMIC + */ + if ((err = usb_submit_urb (request->urb, GFP_ATOMIC)) >= 0) + request->active = 1; +#endif + return err; +} + +int +udi_usb_request_actlen (udi_usb_request_t * request) +{ + return request->urb->actual_length; +} + +void +udi_usb_cancel_request (udi_usb_request_t * request) +{ + if (request == NULL || !request->active) + return; + + usb_kill_urb (request->urb); + +} diff --git a/setup/Linux/oss/cuckoo/Makefile b/setup/Linux/oss/cuckoo/Makefile new file mode 100644 index 0000000..da9013b --- /dev/null +++ b/setup/Linux/oss/cuckoo/Makefile @@ -0,0 +1,23 @@ +ccflags-y += -I/usr/lib/oss + +ifneq ($(KERNELRELEASE),) + + obj-m := cuckoo.o cuckoo_pcm.o cuckoo_mixer.o + +else + + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +endif + +install: default + cp *.ko /lib/modules/`uname -r`/kernel/oss + depmod -a + +clean: + rm -f *.o *.ko *.mod.c *.mod.o .*.cmd core core.* x y z + rm -rf .tmp_versions Modules.symvers diff --git a/setup/Linux/oss/cuckoo/checksum.h b/setup/Linux/oss/cuckoo/checksum.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/setup/Linux/oss/cuckoo/checksum.h diff --git a/setup/Linux/oss/cuckoo/cuckoo.c b/setup/Linux/oss/cuckoo/cuckoo.c new file mode 100644 index 0000000..b7a04a6 --- /dev/null +++ b/setup/Linux/oss/cuckoo/cuckoo.c @@ -0,0 +1,251 @@ +/* + * This software module makes it possible to use Open Sound System for Linux + * (the _professional_ version) as a low level driver source for ALSA. + * + * Copyright (C) 2004-2009 Hannu Savolainen (hannu@opensound.com). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +/* + * !!!!!!!!!!!!!!!!!!!! Important !!!!!!!!!!!!!!!!!! + * + * If this file doesn't compile, you must not try to resolve the problem + * without perfect understanding of internals of Linux kernel, ALSA and + * Open Sound System. + * + * Instead you need to check that you are using the version of this file + * that matches the versions of ALSA, OSS and Linux you are currently using. + */ + +#ifndef KBUILD_MODNAME +#define KBUILD_MODNAME cuckoo +#endif + +#include "cuckoo.h" + +#include "./checksum.h" + +#ifdef VERMAGIC_STRING +static const char vermagic[] = VERMAGIC_STRING; +#endif + +MODULE_AUTHOR ("Hannu Savolainen <hannu@opensound.com>"); +MODULE_LICENSE ("GPL v2"); +//MODULE_CLASSES("{sound}"); +MODULE_DESCRIPTION ("OSS low level driver interface for ALSA"); + +#define CUCKOO_MAXCARD SNDRV_CARDS +static int index[CUCKOO_MAXCARD] = SNDRV_DEFAULT_IDX; +static char *id[CUCKOO_MAXCARD] = SNDRV_DEFAULT_STR; +static int enable[CUCKOO_MAXCARD] = SNDRV_DEFAULT_ENABLE_PNP; + +static int +snd_cuckoo_free (cuckoo_t * chip) +{ + // TODO + return 0; +} + +static int +snd_cuckoo_dev_free (snd_device_t * device) +{ + cuckoo_t *cuckoo = (cuckoo_t *) device->device_data; + return snd_cuckoo_free (cuckoo); +} + +static int +snd_cuckoo_create (snd_card_t * card, int osscard, cuckoo_t ** rchip) +{ + cuckoo_t *chip; + int err; + + static snd_device_ops_t ops = { + .dev_free = snd_cuckoo_dev_free + }; + + *rchip = NULL; + + if ((chip = (cuckoo_t *) kmalloc (sizeof (cuckoo_t), GFP_KERNEL)) == NULL) + return -ENOMEM; + + chip->card = card; + chip->osscard = osscard; + chip->ncapture = chip->nplay = chip->npcm = 0; + + if ((err = snd_device_new (card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) + { + snd_cuckoo_free (chip); + return err; + } + + *rchip = chip; + return 0; +} + +static snd_card_t *cards[SNDRV_CARDS]; +static int ncards = 0; + +int +init_module (void) +{ + int err; + int dev, cardno; + char tmp[100]; + int pass; + +#if 0 + // TODO + if ((err = udi_connect (WRAPPER_VERSION)) < 0) + return err; + + if (strcmp (oss_checksum, cuckoo_checksum) != 0) + { + printk + ("cuckoo: Error OSS incompatibility problem. Please recompile.\n"); + return -EIO; + } +#endif + + for (pass = 0; pass < 2; pass++) + { + cardno = -1; + + for (dev = 0; dev < num_audio_engines; dev++) + { + adev_p adev = audio_engines[dev]; + cuckoo_t *chip; + snd_card_t *card = NULL; + + if (pass == 0) + { + // Ignore non-virtual devices + if (!(adev->flags & ADEV_VIRTUAL)) + continue; + } + else + { + // Ignore virtual devices + if ((adev->flags & ADEV_VIRTUAL)) + continue; + } + + if (adev->card_number < 0) + { + printk ("cuckoo: Ignored audio device %d - %s\n", dev, + adev->name); + continue; + } + + if (adev->card_number != cardno) + { + oss_card_info cd; + + cardno = adev->card_number; + + if (oss_get_cardinfo (cardno, &cd) < 0) + { + printk ("oss_get_cardinfo(%d) failed\n", cardno); + continue; + } + + // printk("Card %d: %s/%s\n", cardno, cd.shortname, cd.longname); + printk ("Card %d: %s/%s\n", cardno, cd.shortname, cd.longname); + + if (ncards >= CUCKOO_MAXCARD) + { + printk + ("Cuckoo: Too many audio devices (%d), only %d supported. by ALSA.\n", + num_audio_engines, CUCKOO_MAXCARD); + return -EIO; + } + + if (!enable[ncards]) + { + printk ("cuckoo: Device was not enabled (yet)\n"); + return -EIO; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) + if ((card = + snd_card_new (index[ncards], id[ncards], THIS_MODULE, + 0)) == NULL) +#else + if ( + snd_card_create (index[ncards], id[ncards], THIS_MODULE, + 0, &card) != 0) +#endif + { + printk ("cuckoo: Can't create a card instance\n"); + return -EIO; + } + + if ((err = snd_cuckoo_create (card, cardno, &chip)) < 0) + { + printk ("cuckoo: Couldn't create a chip instance (%d)\n", + err); + snd_card_free (card); + return err; + } + +#define oss_version_string "v4.x" // TODO + sprintf (tmp, "OSS %s", oss_version_string); + strlcpy (card->driver, tmp); + strlcpy (card->shortname, cd.shortname); + strlcpy (card->longname, cd.longname); + + if ((err = install_pcm_instances (chip, cardno)) < 0) + return err; + + if ((err = install_mixer_instances (chip, cardno)) < 0) + return err; + + // if ((err=install_midiport_instances(chip, cardno))<0) + // return err; + + if ((err = snd_card_register (card)) < 0) + { + printk ("cuckoo: Couldn't register card(%s) err=%d\n", + card->shortname, err); + continue; // TODO: Should handle this in more intelligent way + + snd_card_free (card); + return err; + } + + cards[ncards++] = card; + } + } + } + + return 0; +} + +void +cleanup_module (void) +{ + int i; + + for (i = 0; i < ncards; i++) + snd_card_free (cards[i]); +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5)) +#undef unix +struct module __this_module + __attribute__ ((section (".gnu.linkonce.this_module"))) = +{ + .name = __stringify (KBUILD_MODNAME),.init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module +#endif +}; +#endif diff --git a/setup/Linux/oss/cuckoo/cuckoo.h b/setup/Linux/oss/cuckoo/cuckoo.h new file mode 100644 index 0000000..3df2966 --- /dev/null +++ b/setup/Linux/oss/cuckoo/cuckoo.h @@ -0,0 +1,171 @@ +/* + * This software module makes it possible to use Open Ssund System for Linux + * (the _professional_ version) as a low level driver source for ALSA. + * + * Copyright (C) 2004-2006 Hannu Savolainen (hannu@voimakentta.net). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#define _KERNEL + +/* + * !!!!!!!!!!!!!!!!!!!! Important !!!!!!!!!!!!!!!!!! + * + * If this file doesn't compile, you must not try to resolve the problem + * without perfect understanding of internals of Linux kernel, ALSA and + * Open Sound System. + * + * Instead you need to check that you are using the version of this file + * that matches the versions of ALSA, OSS and Linux you are currently using. + */ + +#define _KERNEL +#include "../include/sys/soundcard.h" + +#include <linux/version.h> + +#define _LOOSE_KERNEL_NAMES + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) +#include <linux/config.h> +#else +#include <linux/autoconf.h> +#endif + +#if !defined(__SMP__) && defined(CONFIG_SMP) +#define __SMP__ +#endif +#include <linux/module.h> + +#include <stdarg.h> + +extern int oss_get_cardinfo (int cardnum, oss_card_info * ci); /* from oss_config.h */ + +#include <linux/param.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/fcntl.h> +#include <linux/sched.h> +#include <linux/timer.h> +#include <linux/tty.h> +#include <linux/mm.h> +#include <linux/ctype.h> +#include <linux/delay.h> +#include <linux/vmalloc.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <linux/pci.h> +#include <linux/apm_bios.h> +#include <asm/segment.h> +#include <asm/uaccess.h> +#include <linux/poll.h> + +#include <asm/system.h> +#include <asm/dma.h> +#include <linux/wait.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/ioport.h> +//#include <asm/mach-default/irq_vectors.h> +#include <linux/interrupt.h> +#include <linux/pm.h> + +struct _oss_mutex_t +{ + /* Caution! This definition must match Linux/osscore.c */ + spinlock_t lock; +}; + +#define audio_devs dummy_audio_devs + +#include "../include/internals/oss_exports.h" +#include "../build/wrap.h" +#include "../include/internals/ossddk.h" + +typedef struct oss_wait_queue oss_wait_queue_t; /* This must match oss_config.h */ + +#include "../include/internals/ossddk.h" + +//#include <sound/driver.h> +#include <sound/core.h> +#include <sound/control.h> +#include <sound/pcm.h> + +#include "../build/osscore_symbols.inc" + +#define SNDRV_GET_ID +#include <sound/initval.h> + +typedef caddr_t ioctl_arg; +typedef char snd_rw_buf; + +typedef int sound_os_info; + +#define WR_BUF_CONST const + +#include "../include/internals/audio_core.h" +#include "../include/internals/mixer_core.h" + +typedef struct _snd_cuckoo cuckoo_t, chip_t; + +typedef struct +{ + adev_p adev; +} cuckoo_pcm_t; + +#define MAX_OSSPCM 24 // Max # of PCM devices/card instance + +#if 1 +// Older ALSA versions used to define these... +typedef struct snd_card snd_card_t; +typedef struct snd_pcm snd_pcm_t; +typedef struct snd_rawmidi snd_rawmidi_t; +typedef struct snd_rawmidi_substream snd_rawmidi_substream_t; +typedef struct snd_rawmidi_ops snd_rawmidi_ops_t; +typedef struct snd_kcontrol snd_kcontrol_t; +typedef struct snd_kcontrol_new snd_kcontrol_new_t; +typedef struct snd_ctl_elem_info snd_ctl_elem_info_t; +typedef struct snd_ctl_elem_value snd_ctl_elem_value_t; +typedef struct snd_pcm_substream snd_pcm_substream_t; +typedef struct snd_pcm_hardware snd_pcm_hardware_t; +typedef struct snd_pcm_runtime snd_pcm_runtime_t; +typedef struct snd_pcm_hw_params snd_pcm_hw_params_t; +typedef struct snd_pcm_ops snd_pcm_ops_t; +typedef struct snd_device snd_device_t; +typedef struct snd_device_ops snd_device_ops_t; +#endif + +struct _snd_cuckoo +{ + snd_card_t *card; + snd_pcm_t *pcm[MAX_OSSPCM]; + adev_p play_adev[MAX_OSSPCM], capture_adev[MAX_OSSPCM]; + int osscard; + int nplay, ncapture, npcm; +}; + +#define cuckoo_t_magic 0xaabbccdd +#define chip__tmagic cuckoo_t_magic + +//#define OPEN_READ PCM_ENABLE_INPUT +//#define OPEN_WRITE PCM_ENABLE_OUTPUT + +extern int install_mixer_instances (cuckoo_t * chip, int cardno); +extern int install_midiport_instances (cuckoo_t * chip, int cardno); +extern int install_pcm_instances (cuckoo_t * chip, int cardno); + +// Disable locking for now +#define udi_spin_lock_irqsave(a, b) *(b)=0 +#define udi_spin_unlock_irqrestore(a, b) + +#define strlcpy(a, b) {strncpy(a, b, sizeof(a)-1);a[sizeof(a)-1]=0;} diff --git a/setup/Linux/oss/cuckoo/cuckoo_midi.c b/setup/Linux/oss/cuckoo/cuckoo_midi.c new file mode 100644 index 0000000..949379b --- /dev/null +++ b/setup/Linux/oss/cuckoo/cuckoo_midi.c @@ -0,0 +1,310 @@ +/* + * This software module makes it possible to use Open Sound System for Linux + * (the _professional_ version) as a low level driver source for ALSA. + * + * Copyright (C) 2004 Hannu Savolainen (hannu@voimakentta.net). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +/* + * !!!!!!!!!!!!!!!!!!!! Important !!!!!!!!!!!!!!!!!! + * + * If this file doesn't compile, you must not try to resolve the problem + * without perfect understanding of internals of Linux kernel, ALSA and + * Open Sound System. + * + * Instead you need to check that you are using the version of this file + * that matches the versions of ALSA, OSS and Linux you are currently using. + */ + +#include "cuckoo.h" +#include <sound/rawmidi.h> +#include <midi_core.h> + +static snd_rawmidi_t *rmidis[256] = { NULL }; + +static int +cuckoo_uart_input_open (snd_rawmidi_substream_t * substream) +{ +#if 0 + mpu401_t *mpu; + int err; + + mpu = + snd_magic_cast (mpu401_t, substream->rmidi->private_data, return -ENXIO); + if (mpu->open_input && (err = mpu->open_input (mpu)) < 0) + return err; + if (!test_bit (MPU401_MODE_BIT_OUTPUT, &mpu->mode)) + { + cuckoo_uart_cmd (mpu, MPU401_RESET, 1); + cuckoo_uart_cmd (mpu, MPU401_ENTER_UART, 1); + } + mpu->substream_input = substream; + atomic_set (&mpu->rx_loop, 1); + set_bit (MPU401_MODE_BIT_INPUT, &mpu->mode); +#endif + return 0; +} + +static int +cuckoo_uart_output_open (snd_rawmidi_substream_t * substream) +{ + int dev; + + dev = (int) substream->rmidi->private_data; + + printk ("Output open %d\n", dev); + + return -EIO; +#if 0 + mpu401_t *mpu; + int err; + if (mpu->open_output && (err = mpu->open_output (mpu)) < 0) + return err; + if (!test_bit (MPU401_MODE_BIT_INPUT, &mpu->mode)) + { + cuckoo_uart_cmd (mpu, MPU401_RESET, 1); + cuckoo_uart_cmd (mpu, MPU401_ENTER_UART, 1); + } + mpu->substream_output = substream; + atomic_set (&mpu->tx_loop, 1); + set_bit (MPU401_MODE_BIT_OUTPUT, &mpu->mode); +#endif + return 0; +} + +static int +cuckoo_uart_input_close (snd_rawmidi_substream_t * substream) +{ +#if 0 + mpu401_t *mpu; + + mpu = + snd_magic_cast (mpu401_t, substream->rmidi->private_data, return -ENXIO); + clear_bit (MPU401_MODE_BIT_INPUT, &mpu->mode); + mpu->substream_input = NULL; + if (!test_bit (MPU401_MODE_BIT_OUTPUT, &mpu->mode)) + cuckoo_uart_cmd (mpu, MPU401_RESET, 0); + if (mpu->close_input) + mpu->close_input (mpu); +#endif + return 0; +} + +static int +cuckoo_uart_output_close (snd_rawmidi_substream_t * substream) +{ +#if 0 + mpu401_t *mpu; + + mpu = + snd_magic_cast (mpu401_t, substream->rmidi->private_data, return -ENXIO); + clear_bit (MPU401_MODE_BIT_OUTPUT, &mpu->mode); + mpu->substream_output = NULL; + if (!test_bit (MPU401_MODE_BIT_INPUT, &mpu->mode)) + cuckoo_uart_cmd (mpu, MPU401_RESET, 0); + if (mpu->close_output) + mpu->close_output (mpu); +#endif + return 0; +} + +static void +cuckoo_uart_input_trigger (snd_rawmidi_substream_t * substream, int up) +{ +#if 0 + unsigned long flags; + mpu401_t *mpu; + int max = 64; + + mpu = snd_magic_cast (mpu401_t, substream->rmidi->private_data, return); + if (up) + { + if (!test_and_set_bit (MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) + { + /* first time - flush FIFO */ + while (max-- > 0) + mpu->read (mpu, MPU401D (mpu)); + if (mpu->irq < 0) + cuckoo_uart_add_timer (mpu, 1); + } + + /* read data in advance */ + /* prevent double enter via rawmidi->event callback */ + if (atomic_dec_and_test (&mpu->rx_loop)) + { + local_irq_save (flags); + if (spin_trylock (&mpu->input_lock)) + { + cuckoo_uart_input_read (mpu); + spin_unlock (&mpu->input_lock); + } + local_irq_restore (flags); + } + atomic_inc (&mpu->rx_loop); + } + else + { + if (mpu->irq < 0) + cuckoo_uart_remove_timer (mpu, 1); + clear_bit (MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); + } +#endif +} + +#if 0 +static void +cuckoo_uart_input_read (void *mpu) +{ + int max = 128; + unsigned char byte; + + while (max-- > 0) + { + if (cuckoo_input_avail (mpu)) + { + byte = mpu->read (mpu, MPU401D (mpu)); + if (test_bit (MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) + snd_rawmidi_receive (mpu->substream_input, &byte, 1); + } + else + { + break; /* input not available */ + } + } +} +#endif + +#if 0 +static void +cuckoo_uart_output_write (void *mpu) +{ + unsigned char byte; + int max = 256, timeout; + + do + { + if (snd_rawmidi_transmit_peek (mpu->substream_output, &byte, 1) == 1) + { + for (timeout = 100; timeout > 0; timeout--) + { + if (cuckoo_output_ready (mpu)) + { + mpu->write (mpu, byte, MPU401D (mpu)); + snd_rawmidi_transmit_ack (mpu->substream_output, 1); + break; + } + } + if (timeout == 0) + break; /* Tx FIFO full - try again later */ + } + else + { + cuckoo_uart_remove_timer (mpu, 0); + break; /* no other data - leave the tx loop */ + } + } + while (--max > 0); +} +#endif + +static void +cuckoo_uart_output_trigger (snd_rawmidi_substream_t * substream, int up) +{ + int dev; + + dev = (int) substream->rmidi->private_data; + printk ("Output trigger %d\n", dev); +#if 0 + if (up) + { + set_bit (MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); + + /* try to add the timer at each output trigger, + * since the output timer might have been removed in + * cuckoo_uart_output_write(). + */ + cuckoo_uart_add_timer (mpu, 0); + + /* output pending data */ + /* prevent double enter via rawmidi->event callback */ + if (atomic_dec_and_test (&mpu->tx_loop)) + { + local_irq_save (flags); + if (spin_trylock (&mpu->output_lock)) + { + cuckoo_uart_output_write (mpu); + spin_unlock (&mpu->output_lock); + } + local_irq_restore (flags); + } + atomic_inc (&mpu->tx_loop); + } + else + { + cuckoo_uart_remove_timer (mpu, 0); + clear_bit (MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); + } +#endif +} + +static snd_rawmidi_ops_t cuckoo_uart_output = { + .open = cuckoo_uart_output_open, + .close = cuckoo_uart_output_close, + .trigger = cuckoo_uart_output_trigger, +}; + +static snd_rawmidi_ops_t cuckoo_uart_input = { + .open = cuckoo_uart_input_open, + .close = cuckoo_uart_input_close, + .trigger = cuckoo_uart_input_trigger, +}; + +extern mididev_p *midi_devs; + +int +install_midiport_instances (cuckoo_t * chip, int cardno) +{ + int dev, devix = 0; + + for (dev = 0; dev < num_mididevs; dev++) + if (midi_devs[dev]->card_number == cardno) + { + mididev_p mididev = midi_devs[dev]; + snd_rawmidi_t *rmidi; + int err; + +//printk("Midi device %s\n", mididev->info.name); + + if ((err = snd_rawmidi_new (chip->card, mididev->name, devix, + 1, 1, &rmidi)) < 0) + { + printk ("cuckoo: Failed to register rawmidi device, err=%d\n", + err); + return 0; + } + + rmidi->private_data = (void *) dev; + strcpy (rmidi->name, mididev->name); + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | + SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; + snd_rawmidi_set_ops (rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &cuckoo_uart_output); + snd_rawmidi_set_ops (rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &cuckoo_uart_input); + + devix++; + rmidis[dev] = rmidi; + } // dev + + return 0; +} diff --git a/setup/Linux/oss/cuckoo/cuckoo_mixer.c b/setup/Linux/oss/cuckoo/cuckoo_mixer.c new file mode 100644 index 0000000..6d2bb6d --- /dev/null +++ b/setup/Linux/oss/cuckoo/cuckoo_mixer.c @@ -0,0 +1,389 @@ +/* + * This software module makes it possible to use Open Sound System for Linux + * (the _professional_ version) as a low level driver source for ALSA. + * + * Copyright (C) 2004 Hannu Savolainen (hannu@voimakentta.net). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +/* + * !!!!!!!!!!!!!!!!!!!! Important !!!!!!!!!!!!!!!!!! + * + * If this file doesn't compile, you must not try to resolve the problem + * without perfect understanding of internals of Linux kernel, ALSA and + * Open Sound System. + * + * Instead you need to check that you are using the version of this file + * that matches the versions of ALSA, OSS and Linux you are currently using. + */ + +#include "cuckoo.h" + +MODULE_AUTHOR ("Hannu Savolainen <hannu@opensound.com>"); +MODULE_LICENSE ("GPL v2"); +MODULE_DESCRIPTION ("OSS mixer low level driver interface for ALSA"); + +typedef struct +{ + char *name, *data; +} enum_entry_t; + +#if 0 +static void +downshift (char *s) +{ + while (*s) + { + if (*s >= 'A' && *s <= 'Z') + *s += 32; + s++; + } +} +#endif + +static int +get_mixer_info (snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) +{ + oss_mixext ext; + int dev, ix; + + dev = ext.dev = kcontrol->private_value >> 16; + ix = ext.ctrl = kcontrol->private_value & 0xffff;; + + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO, (caddr_t) & ext); + + switch (ext.type) + { + case MIXT_STEREOSLIDER: + case MIXT_STEREOVU: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = ext.minvalue; + uinfo->value.integer.max = ext.maxvalue; + break; + + case MIXT_MONOSLIDER: + case MIXT_MONOVU: + case MIXT_SLIDER: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = ext.minvalue; + uinfo->value.integer.max = ext.maxvalue; + break; + + case MIXT_ONOFF: + case MIXT_MUTE: + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + break; + + case MIXT_ENUM: + { + static const char *texts[] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", + "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", + "30", "31", "32" + }; + oss_mixer_enuminfo enumdef; + uinfo->value.enumerated.items = ext.maxvalue; + + if (uinfo->value.enumerated.item < 0) + uinfo->value.enumerated.item = 0; + if (uinfo->value.enumerated.item >= ext.maxvalue) + uinfo->value.enumerated.item = ext.maxvalue - 1; + if (uinfo->value.enumerated.item > 31) + uinfo->value.enumerated.item = 31; + strcpy (uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + + enumdef.dev = ext.dev; + enumdef.ctrl = ext.ctrl; + if (oss_mixer_ext + (dev, OSS_DEV_MIXER, SNDCTL_MIX_ENUMINFO, + (caddr_t) & enumdef) >= 0) + { + char *text; + + text = + &enumdef.strings[enumdef. + strindex[uinfo->value.enumerated.item]]; + strcpy (uinfo->value.enumerated.name, text); + } + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = ext.maxvalue; + } + break; + + default: + printk ("cuckoo: mixer_info(%d/%d) - unknown type %d\n", dev, ix, + ext.type); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = ext.minvalue; + uinfo->value.integer.max = ext.maxvalue; + return 0; + } + + return 0; +} + +static int +mixer_get (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + oss_mixext ext; + oss_mixer_value val; + int dev, ix, err; + + dev = ext.dev = kcontrol->private_value >> 16; + ix = ext.ctrl = kcontrol->private_value & 0xffff;; + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO, + (caddr_t) & ext)) < 0) + return err; + + val.dev = dev; + val.ctrl = ix; + val.timestamp = ext.timestamp; + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_READ, + (caddr_t) & val)) < 0) + return err; + + switch (ext.type) + { + case MIXT_STEREOVU: + case MIXT_STEREOSLIDER: + ucontrol->value.integer.value[0] = val.value & 0xff; // Left + ucontrol->value.integer.value[1] = (val.value >> 8) & 0xff; // Right + break; + + case MIXT_MONOSLIDER: + case MIXT_MONOVU: + case MIXT_SLIDER: + ucontrol->value.integer.value[0] = val.value & 0xff; + break; + + case MIXT_ONOFF: + case MIXT_MUTE: + ucontrol->value.integer.value[0] = !!val.value; + break; + + case MIXT_ENUM: + ucontrol->value.integer.value[0] = val.value; + break; + + default: + printk ("cuckoo: mixer_get(%d/%d) - unknown type %d\n", dev, ix, + ext.type); + ucontrol->value.integer.value[0] = val.value & 0xff; + return 0; + } + + return 0; +} + +static int +mixer_put (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + oss_mixext ext; + oss_mixer_value val; + int dev, ix, err; + + dev = ext.dev = kcontrol->private_value >> 16; + ix = ext.ctrl = kcontrol->private_value & 0xffff;; + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO, + (caddr_t) & ext)) < 0) + return err; + + val.dev = dev; + val.ctrl = ix; + val.timestamp = ext.timestamp; + + switch (ext.type) + { + case MIXT_STEREOSLIDER: + val.value = ucontrol->value.integer.value[0] | // Left + ucontrol->value.integer.value[1] << 8; // Right + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE, + (caddr_t) & val)) < 0) + return err; + break; + + case MIXT_MONOSLIDER: + case MIXT_SLIDER: + val.value = ucontrol->value.integer.value[0]; + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE, + (caddr_t) & val)) < 0) + return err; + break; + + case MIXT_ONOFF: + case MIXT_MUTE: + val.value = !!ucontrol->value.integer.value[0]; + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE, + (caddr_t) & val)) < 0) + return err; + break; + + case MIXT_ENUM: + val.value = ucontrol->value.integer.value[0]; + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE, + (caddr_t) & val)) < 0) + return err; + break; + + case MIXT_MONOVU: + case MIXT_STEREOVU: + return -EPERM; + + default: + printk ("cuckoo: mixer_put(%d/%d) - unknown type %d\n", dev, ix, + ext.type); + val.value = ucontrol->value.integer.value[0]; + if ((err = + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE, + (caddr_t) & val)) < 0) + return err; + } + + return 0; +} + +static void +add_control (cuckoo_t * chip, int dev, int ix, oss_mixext * ext, char *name) +{ + int i, ok, err = 0; + snd_kcontrol_new_t my_control; + +// Upshift the name if it's an single part one + + ok = 0; + for (i = 0; i < strlen (name); i++) + if (name[i] == '.') + ok = 1; + if (!ok) + for (i = 0; i < strlen (name); i++) + if (name[i] >= 'a' && name[i] <= 'z') + name[i] -= 32; + +// Add the control + + memset (&my_control, 0, sizeof (my_control)); + + my_control.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + my_control.name = name; + my_control.index = 0; + my_control.access = 0; + + if (ext->flags & MIXF_READABLE) + my_control.access |= SNDRV_CTL_ELEM_ACCESS_READ; + if (ext->flags & MIXF_WRITEABLE) + my_control.access |= SNDRV_CTL_ELEM_ACCESS_WRITE; + if ((ext->flags & 0x3) == MIXF_READABLE) /* Read only */ + my_control.access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE; + + my_control.private_value = (dev << 16) | ix; + my_control.info = get_mixer_info; + my_control.get = mixer_get; + my_control.put = mixer_put; + + switch (ext->type) + { + case MIXT_ENUM: + case MIXT_ONOFF: + case MIXT_MUTE: + case MIXT_STEREOSLIDER: + case MIXT_SLIDER: + case MIXT_MONOSLIDER: + case MIXT_MONOVU: + case MIXT_STEREOVU: + if ((err = + snd_ctl_add (chip->card, snd_ctl_new1 (&my_control, chip))) < 0) + { + printk ("cuckoo: snd_ctl_add(%s) failed, err=%d\n", ext->extname, + err); + return; + } + break; + } +} + +int +install_mixer_instances (cuckoo_t * chip, int cardno) +{ + int dev; + mixer_operations_t **cuckoo_mixer_devs = mixer_devs_p; + + for (dev = 0; dev < num_mixers; dev++) + if (cuckoo_mixer_devs[dev]->card_number == cardno) + { + int nrext, i, sz; + + touch_mixer (dev); + + nrext = dev; + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_NREXT, + (ioctl_arg) & nrext); + + if (nrext == 0) + continue; + + sz = nrext * (sizeof (char *) + 32); // 32 characters / name (average) + + for (i = 0; i < nrext; i++) + { + oss_mixext ext; + int parent = 0; + oss_mixext_root *root = NULL; + + ext.dev = dev; + ext.ctrl = i; + oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_EXTINFO, + (caddr_t) & ext); + + switch (ext.type) + { + case MIXT_DEVROOT: + root = (oss_mixext_root *) & ext.data; + break; + + case MIXT_GROUP: + parent = ext.parent; + break; + + case MIXT_MARKER: + break; + + default: + add_control (chip, dev, i, &ext, ext.extname); + break; + } // Switch + + } // i + + + } // dev + + return 0; +} + +EXPORT_SYMBOL (install_mixer_instances); diff --git a/setup/Linux/oss/cuckoo/cuckoo_pcm.c b/setup/Linux/oss/cuckoo/cuckoo_pcm.c new file mode 100644 index 0000000..2ae08b5 --- /dev/null +++ b/setup/Linux/oss/cuckoo/cuckoo_pcm.c @@ -0,0 +1,810 @@ +/* + * This software module makes it possible to use Open Sound System for Linux + * (the _professional_ version) as a low level driver source for ALSA. + * + * Copyright (C) 2004 Hannu Savolainen (hannu@voimakentta.net). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +/* + * !!!!!!!!!!!!!!!!!!!! Important !!!!!!!!!!!!!!!!!! + * + * If this file doesn't compile, you must not try to resolve the problem + * without perfect understanding of internals of Linux kernel, ALSA and + * Open Sound System. + * + * Instead you need to check that you are using the version of this file + * that matches the versions of ALSA, OSS and Linux you are currently using. + */ + +#include "cuckoo.h" + +MODULE_AUTHOR ("Hannu Savolainen <hannu@opensound.com>"); +MODULE_LICENSE ("GPL v2"); +MODULE_DESCRIPTION ("OSS PCM low level driver interface for ALSA"); + +static snd_pcm_substream_t *cuckoo_playsubstream[256] = { NULL }; +static snd_pcm_substream_t *cuckoo_capturesubstream[256] = { NULL }; + +static snd_pcm_hardware_t snd_cuckoo_playback = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 4000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (64 * 1024), + .period_bytes_min = 64, + .period_bytes_max = (32 * 1024), + .periods_min = 2, + .periods_max = 1024, + .fifo_size = 0, +}; + +static snd_pcm_hardware_t snd_cuckoo_capture = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 4000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (128 * 1024), + .period_bytes_min = 64, + .period_bytes_max = (64 * 1024), + .periods_min = 2, + .periods_max = 1024, + .fifo_size = 0, +}; + +static void +cuckoo_outputintr (int dev, int notify_only) +{ + snd_pcm_substream_t *substream; + adev_t *adev; + dmap_t *dmap; + oss_native_word flags; + + if (dev < 0 || dev > 255) + return; + + adev = audio_devfiles[dev]; + dmap = adev->dmap_out; + + dmap->fragment_counter = (dmap->fragment_counter + 1) % dmap->nfrags; + + substream = cuckoo_playsubstream[dev]; + if (substream == NULL) + return; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + snd_pcm_period_elapsed (substream); + udi_spin_unlock_irqrestore (&adev->mutex, flags); +} + +static void +cuckoo_inputintr (int dev, int intr_flags) +{ + snd_pcm_substream_t *substream; + adev_t *adev; + dmap_t *dmap; + oss_native_word flags; + + if (dev < 0 || dev > 255) + return; + + adev = audio_devfiles[dev]; + dmap = adev->dmap_in; + + dmap->fragment_counter = (dmap->fragment_counter + 1) % dmap->nfrags; + + substream = cuckoo_capturesubstream[dev]; + if (substream == NULL) + return; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + snd_pcm_period_elapsed (substream); + udi_spin_unlock_irqrestore (&adev->mutex, flags); +} + +static void +copy_hw_caps (snd_pcm_runtime_t * runtime, adev_t * adev, int dir) +{ + u64 fmts = 0; + int i; + unsigned int fmtmask; + + if (dir == OPEN_WRITE) + { + fmtmask = adev->oformat_mask; + } + else + { + fmtmask = adev->iformat_mask; + } + + for (i = 0; i < 32; i++) + switch (fmtmask & (1 << i)) + { + case AFMT_MU_LAW: + fmts |= SNDRV_PCM_FMTBIT_MU_LAW; + break; + case AFMT_A_LAW: + fmts |= SNDRV_PCM_FMTBIT_A_LAW; + break; + case AFMT_IMA_ADPCM: + fmts |= SNDRV_PCM_FMTBIT_IMA_ADPCM; + break; + case AFMT_U8: + fmts |= SNDRV_PCM_FMTBIT_U8; + break; + case AFMT_S8: + fmts |= SNDRV_PCM_FMTBIT_S8; + break; + case AFMT_S16_LE: + fmts |= SNDRV_PCM_FMTBIT_S16_LE; + break; + case AFMT_S16_BE: + fmts |= SNDRV_PCM_FMTBIT_S16_BE; + break; + case AFMT_S24_LE: + fmts |= SNDRV_PCM_FMTBIT_S24_LE; + break; + case AFMT_S24_BE: + fmts |= SNDRV_PCM_FMTBIT_S24_BE; + break; + case AFMT_S32_LE: + fmts |= SNDRV_PCM_FMTBIT_S32_LE; + break; + case AFMT_S32_BE: + fmts |= SNDRV_PCM_FMTBIT_S32_BE; + break; + case AFMT_MPEG: + fmts |= SNDRV_PCM_FMTBIT_MPEG; + break; + case AFMT_FLOAT: + fmts |= SNDRV_PCM_FMTBIT_FLOAT_LE; + break; + case AFMT_SPDIF_RAW: + fmts |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE; + break; + } + + runtime->hw.formats = fmts; + + if (adev->min_block > 0) + runtime->hw.period_bytes_min = adev->min_block; + if (adev->max_block > 0) + runtime->hw.period_bytes_max = adev->max_block; + + if (adev->flags & ADEV_NOMMAP) + runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID); + + if (adev->max_rate > adev->min_rate) + { + runtime->hw.rate_min = adev->min_rate; + runtime->hw.rate_max = adev->max_rate; + } + + if (!(adev->caps & DSP_CAP_FREERATE)) + runtime->hw.rates &= + ~(SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000); +} + +static int +snd_cuckoo_playback_open (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + int err; + adev_t *adev; + oss_native_word flags; + struct fileinfo tmp_finfo; + + if (snum < 0 || snum >= chip->npcm) + { + printk ("cuckoo: Playback open - bad substream index %d\n", snum); + return -EIO; + } + + adev = chip->play_adev[snum]; + printk ("cuckoo_playback_open(%d=%s)\n", adev->engine_num, adev->name); + + cuckoo_playsubstream[adev->engine_num] = substream; + + if (adev->dmap_out == NULL || adev->dmap_out->dmabuf == NULL) + { + printk ("cuckoo: dev %d - no buffer available\n", adev->engine_num); + return -ENOMEM; + } + + if (adev->open_mode != 0) + { + udi_spin_unlock_irqrestore (&adev->mutex, flags); + return -EBUSY; + } + + tmp_finfo.mode = OPEN_WRITE; + tmp_finfo.acc_flags = 0; + if ((err = + oss_audio_open_engine (adev->engine_num, OSS_DEV_DSP, + &tmp_finfo, 1, OF_SMALLBUF, + NULL)) < 0) + { + return err; + } + + udi_spin_lock_irqsave (&adev->mutex, &flags); + adev->open_mode = OPEN_WRITE; + runtime->hw = snd_cuckoo_playback; + copy_hw_caps (runtime, adev, OPEN_WRITE); + snd_pcm_set_sync (substream); + adev->pid = current->pid; + strncpy (adev->cmd, current->comm, sizeof (adev->cmd) - 1); + adev->cmd[sizeof (adev->cmd) - 1] = 0; + adev->outputintr = cuckoo_outputintr; + udi_spin_unlock_irqrestore (&adev->mutex, flags); + + return 0; +} + +static int +snd_cuckoo_capture_open (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + int err; + adev_t *adev; + oss_native_word flags; + struct fileinfo tmp_finfo; + + if (snum < 0 || snum >= chip->npcm) + { + printk ("cuckoo: Capture open - bad substream index %d\n", snum); + return -EIO; + } + + adev = chip->capture_adev[snum]; + + cuckoo_capturesubstream[adev->engine_num] = substream; + + if (adev->dmap_in == NULL || adev->dmap_in->dmabuf == NULL) + { + printk ("cuckoo: dev %d - no buffer available\n", adev->engine_num); + return -ENOMEM; + } + + if (adev->open_mode != 0) + { + udi_spin_unlock_irqrestore (&adev->mutex, flags); + return -EBUSY; + } + + tmp_finfo.mode = OPEN_READ; + tmp_finfo.acc_flags = 0; + if ((err = + oss_audio_open_engine (adev->engine_num, OSS_DEV_DSP, + &tmp_finfo, 1, OF_SMALLBUF, + NULL)) < 0) + { + return err; + } + + udi_spin_lock_irqsave (&adev->mutex, &flags); + adev->open_mode = OPEN_READ; + runtime->hw = snd_cuckoo_capture; + copy_hw_caps (runtime, adev, OPEN_READ); + snd_pcm_set_sync (substream); + adev->pid = current->pid; + strncpy (adev->cmd, current->comm, sizeof (adev->cmd) - 1); + adev->cmd[sizeof (adev->cmd) - 1] = 0; + adev->inputintr = cuckoo_inputintr; + udi_spin_unlock_irqrestore (&adev->mutex, flags); + + return 0; +} + +static int +snd_cuckoo_playback_close (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + int snum = substream->number; + adev_t *adev; + oss_native_word flags; + struct fileinfo tmp_finfo; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->play_adev[snum]; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + cuckoo_playsubstream[adev->engine_num] = NULL; + udi_spin_unlock_irqrestore (&adev->mutex, flags); + + tmp_finfo.mode = OPEN_WRITE; + tmp_finfo.acc_flags = 0; + oss_audio_release (adev->engine_num, &tmp_finfo); + + return 0; +} + +static int +snd_cuckoo_capture_close (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + int snum = substream->number; + adev_t *adev; + oss_native_word flags; + struct fileinfo tmp_finfo; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->capture_adev[snum]; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + cuckoo_capturesubstream[adev->engine_num] = NULL; + udi_spin_unlock_irqrestore (&adev->mutex, flags); + + tmp_finfo.mode = OPEN_READ; + tmp_finfo.acc_flags = 0; + oss_audio_release (adev->engine_num, &tmp_finfo); + + return 0; +} + +static int +snd_cuckoo_playback_hw_params (snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + adev_t *adev; + dmap_t *dmap; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->play_adev[snum]; + dmap = adev->dmap_out; + + if (dmap->dmabuf == NULL) + return -ENOMEM; + + runtime->dma_area = dmap->dmabuf; + runtime->dma_addr = dmap->dmabuf_phys; + runtime->dma_bytes = dmap->buffsize; + memset (dmap->dmabuf, 0, dmap->buffsize); + + return 0; +} + +static int +snd_cuckoo_capture_hw_params (snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + adev_t *adev; + dmap_t *dmap; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->capture_adev[snum]; + dmap = adev->dmap_in; + + if (dmap->dmabuf == NULL) + return -ENOMEM; + + runtime->dma_area = dmap->dmabuf; + runtime->dma_addr = dmap->dmabuf_phys; + runtime->dma_bytes = dmap->buffsize; + memset (dmap->dmabuf, 0, dmap->buffsize); + + return 0; +} + +static int +snd_cuckoo_hw_free (snd_pcm_substream_t * substream) +{ + snd_pcm_runtime_t *runtime = substream->runtime; + + runtime->dma_area = NULL; + runtime->dma_addr = 0; + runtime->dma_bytes = 0; + + return 0; +} + +static int +snd_cuckoo_playback_prepare (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number, err; + adev_t *adev; + oss_native_word flags; + dmap_t *dmap; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->play_adev[snum]; + dmap = adev->dmap_out; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + + adev->d->adrv_set_format (adev->engine_num, + snd_pcm_format_width (runtime->format)); + runtime->channels = + adev->d->adrv_set_channels (adev->engine_num, runtime->channels); + runtime->rate = adev->d->adrv_set_rate (adev->engine_num, runtime->rate); + adev->user_parms.rate = adev->user_parms.rate = runtime->rate; + + dmap->bytes_in_use = snd_pcm_lib_buffer_bytes (substream); + dmap->fragment_size = snd_pcm_lib_period_bytes (substream); + +#if 1 + { + int f, s;; + + f = dmap->fragment_size / 4; + if (f < 128) + f = dmap->fragment_size / 2; + if (f < 128) + f = dmap->fragment_size; + + s = dmap->bytes_in_use; + while (s > f) + s /= 2; + + dmap->fragment_size = s; + } +#endif + + if (adev->max_block > 0 && dmap->fragment_size > adev->max_block) + dmap->fragment_size = adev->max_block; + if (adev->min_block > 0 && dmap->fragment_size < adev->min_block) + dmap->fragment_size = adev->min_block; + if (dmap->fragment_size < 8) + dmap->fragment_size = 8; + dmap->nfrags = dmap->bytes_in_use / dmap->fragment_size; + + err = + adev->d->adrv_prepare_for_output (adev->engine_num, dmap->fragment_size, + dmap->nfrags); + cuckoo_playsubstream[adev->engine_num] = substream; + udi_spin_unlock_irqrestore (&adev->mutex, flags); + return err; +} + +static int +snd_cuckoo_capture_prepare (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number, err; + adev_t *adev; + oss_native_word flags; + dmap_t *dmap; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->capture_adev[snum]; + dmap = adev->dmap_in; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + + adev->d->adrv_set_format (adev->engine_num, + snd_pcm_format_width (runtime->format)); + adev->d->adrv_set_channels (adev->engine_num, runtime->channels); + adev->d->adrv_set_rate (adev->engine_num, runtime->rate); + + dmap->bytes_in_use = snd_pcm_lib_buffer_bytes (substream); + dmap->fragment_size = snd_pcm_lib_period_bytes (substream); + +#if 1 + { + int f, s;; + + f = dmap->fragment_size / 4; + if (f < 128) + f = dmap->fragment_size / 2; + if (f < 128) + f = dmap->fragment_size; + + s = dmap->bytes_in_use; + while (s > f) + s /= 2; + + dmap->fragment_size = s; + } +#endif + + if (adev->max_block > 0 && dmap->fragment_size > adev->max_block) + dmap->fragment_size = adev->max_block; + if (adev->min_block > 0 && dmap->fragment_size < adev->min_block) + dmap->fragment_size = adev->min_block; + if (dmap->fragment_size < 8) + dmap->fragment_size = 8; + dmap->nfrags = dmap->bytes_in_use / dmap->fragment_size; + + err = + adev->d->adrv_prepare_for_input (adev->engine_num, dmap->fragment_size, + dmap->nfrags); + cuckoo_capturesubstream[adev->engine_num] = substream; + udi_spin_unlock_irqrestore (&adev->mutex, flags); + return err; +} + +static int +snd_cuckoo_playback_trigger (snd_pcm_substream_t * substream, int cmd) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + //snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + adev_t *adev; + oss_native_word flags; + dmap_t *dmap; + int err = 0; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->play_adev[snum]; + dmap = adev->dmap_out; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + + switch (cmd) + { + case SNDRV_PCM_TRIGGER_START: + adev->d->adrv_output_block (adev->engine_num, dmap->dmabuf_phys, + dmap->bytes_in_use, dmap->fragment_size, 0); + adev->d->adrv_trigger (adev->engine_num, PCM_ENABLE_OUTPUT); + break; + + case SNDRV_PCM_TRIGGER_STOP: + adev->d->adrv_trigger (adev->engine_num, 0); + break; + + default: + printk ("cuckoo: Bad trigger cmd %x\n", cmd); + err = -EIO; + goto fail; + } + +fail: + udi_spin_unlock_irqrestore (&adev->mutex, flags); + return err; +} + +static int +snd_cuckoo_capture_trigger (snd_pcm_substream_t * substream, int cmd) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + //snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + adev_t *adev; + oss_native_word flags; + dmap_t *dmap; + int err = 0; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->capture_adev[snum]; + dmap = adev->dmap_in; + + udi_spin_lock_irqsave (&adev->mutex, &flags); + + switch (cmd) + { + case SNDRV_PCM_TRIGGER_START: + adev->d->adrv_start_input (adev->engine_num, dmap->dmabuf_phys, + dmap->bytes_in_use, dmap->fragment_size, 0); + adev->d->adrv_trigger (adev->engine_num, PCM_ENABLE_INPUT); + break; + + case SNDRV_PCM_TRIGGER_STOP: + adev->d->adrv_trigger (adev->engine_num, 0); + break; + + default: + printk ("cuckoo: Bad trigger cmd %x\n", cmd); + err = -EIO; + goto fail; + } + +fail: + udi_spin_unlock_irqrestore (&adev->mutex, flags); + return err; +} + +static snd_pcm_uframes_t +snd_cuckoo_playback_pointer (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + //snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + adev_t *adev; + dmap_t *dmap; + int pos; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->play_adev[snum]; + dmap = adev->dmap_out; + + if (adev->d->adrv_get_output_pointer != NULL) + pos = + adev->d->adrv_get_output_pointer (adev->engine_num, dmap, PCM_ENABLE_OUTPUT); + else + { + pos = dmap->fragment_counter * dmap->fragment_size; + } + pos = bytes_to_frames (substream->runtime, pos); + + return pos; +} + +static snd_pcm_uframes_t +snd_cuckoo_capture_pointer (snd_pcm_substream_t * substream) +{ + cuckoo_t *chip = snd_pcm_substream_chip (substream); + //snd_pcm_runtime_t *runtime = substream->runtime; + int snum = substream->number; + adev_t *adev; + dmap_t *dmap; + int pos; + + if (snum < 0 || snum >= chip->npcm) + return -ENXIO; + + adev = chip->capture_adev[snum]; + dmap = adev->dmap_in; + + if (adev->d->adrv_get_input_pointer != NULL) + pos = + adev->d->adrv_get_input_pointer (adev->engine_num, dmap, PCM_ENABLE_INPUT); + else + { + pos = dmap->fragment_counter * dmap->fragment_size; + } + pos = bytes_to_frames (substream->runtime, pos); + + return pos; +} + +static snd_pcm_ops_t snd_cuckoo_playback_ops = { + .open = snd_cuckoo_playback_open, + .close = snd_cuckoo_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_cuckoo_playback_hw_params, + .hw_free = snd_cuckoo_hw_free, + .prepare = snd_cuckoo_playback_prepare, + .trigger = snd_cuckoo_playback_trigger, + .pointer = snd_cuckoo_playback_pointer, +}; + +static snd_pcm_ops_t snd_cuckoo_capture_ops = { + .open = snd_cuckoo_capture_open, + .close = snd_cuckoo_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_cuckoo_capture_hw_params, + .hw_free = snd_cuckoo_hw_free, + .prepare = snd_cuckoo_capture_prepare, + .trigger = snd_cuckoo_capture_trigger, + .pointer = snd_cuckoo_capture_pointer, +}; + +int +install_pcm_instances (cuckoo_t * chip, int cardno) +{ + int dev, err, ok = 0; + int ninputs = 0, noutputs = 0; + + for (dev = 0; dev < num_audio_devfiles; dev++) + if (audio_devfiles[dev]->card_number == cardno) + { + adev_t *adev = audio_devfiles[dev]; + adev_t *nextdev = audio_devfiles[dev + 1]; + snd_pcm_t *pcm; + + ninputs = noutputs = 0; + + ok = 0; +/* Special handling for shadow devices */ + if (dev < num_audio_devfiles - 1 && (adev->flags & ADEV_DUPLEX)) + if ((nextdev->flags & ADEV_DUPLEX) + && (nextdev->flags & ADEV_SHADOW)) + ok = 1; + +// Devices with one recording engine and multiple playback ones + if (dev < num_audio_devfiles - 1 && (adev->flags & ADEV_DUPLEX)) + if (adev->card_number == nextdev->card_number) + if ((nextdev->flags & ADEV_NOINPUT)) + ok = 1; + + if (ok) // Device needs special handling + { + if ((err = + snd_pcm_new (chip->card, "OSS/Linux", chip->npcm, 1, 1, + &pcm)) < 0) + { + printk ("cuckoo: snd_pcm_new failed - error %d\n", err); + return err; + } + + pcm->private_data = chip; + chip->pcm[chip->npcm++] = pcm; + strlcpy (pcm->name, adev->name); + + chip->capture_adev[chip->ncapture++] = nextdev; + snd_pcm_set_ops (pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_cuckoo_capture_ops); + + chip->play_adev[chip->nplay++] = adev; + snd_pcm_set_ops (pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_cuckoo_playback_ops); + + dev++; + continue; + } + + if (!(adev->flags & ADEV_NOINPUT)) + ninputs = 1; + if (!(adev->flags & ADEV_NOOUTPUT)) + noutputs = 1; + + if ((err = + snd_pcm_new (chip->card, "OSS/Linux", chip->npcm, noutputs, + ninputs, &pcm)) < 0) + { + printk ("cuckoo: snd_pcm_new failed - error %d\n", err); + return err; + } + + pcm->private_data = chip; + chip->pcm[chip->npcm++] = pcm; + strlcpy (pcm->name, adev->name); + + if (noutputs > 0) + { + chip->play_adev[chip->nplay++] = adev; + snd_pcm_set_ops (pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_cuckoo_playback_ops); + } + + if (ninputs > 0) + { + chip->capture_adev[chip->ncapture++] = adev; + snd_pcm_set_ops (pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_cuckoo_capture_ops); + } + } + + return 0; +} + +EXPORT_SYMBOL (install_pcm_instances); diff --git a/setup/Linux/oss/etc/S89oss b/setup/Linux/oss/etc/S89oss new file mode 100755 index 0000000..5a1cdcd --- /dev/null +++ b/setup/Linux/oss/etc/S89oss @@ -0,0 +1,80 @@ +#!/bin/bash +# +# /etc/rc.d/init.d/oss +# +# Starts the OSS sound driver +# +# chkconfig: 2345 80 20 +# description: Open Sound System for Linux (OSS/Linux) is a \ +# commercial quality sound driver distributed by 4Front Technologies \ +# (http://www.opensound.com). + +### BEGIN INIT INFO +# Provides: oss +# Required-Start: $local_fs $remote_fs +# Should-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start OSS +### END INIT INFO + +# Source function library. +if test -f /lib/lsb/init-functions +then +. /lib/lsb/init-functions +fi + +if test -f /etc/rc.d/init.d/functions +then +. /etc/rc.d/init.d/functions +fi + +# Add oss configuration. +. /etc/oss.conf + +RETVAL=0 + +# +# See how we were called. +# +case "$1" in + start) + # Check if OSS is already running + echo -n 'Starting Open Sound System: ' + if ! test -f /usr/sbin/soundon + then + exit 0 + fi + + if test -f $OSSLIBDIR/starting + then + ls -l $OSSLIBDIR/starting + echo Previous start of OSS crashed the system + echo Please resolve the situation and remove file + echo \"$OSSLIBDIR/starting\". Then start OSS by + echo running soundon + exit 0 + fi + + if ! /usr/sbin/soundon + then + echo Starting OSS failed + fi + rm -f $OSSLIBDIR/starting + ;; + stop) + echo -n 'Stopping Open Sound System: ' + + /usr/sbin/savemixer + exit 0 + ;; + restart) + $0 stop + /usr/sbin/soundoff + $0 start + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 +esac diff --git a/setup/Linux/oss/scripts/90-oss_usb-create-device.fdi b/setup/Linux/oss/scripts/90-oss_usb-create-device.fdi new file mode 100644 index 0000000..28744f9 --- /dev/null +++ b/setup/Linux/oss/scripts/90-oss_usb-create-device.fdi @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<deviceinfo version="0.2"> + <device> + <match key="info.linux.driver" string="oss_usb"> + <append key="info.callouts.add" type="strlist">oss_usb-create-devices</append> + </match> + </device> +</deviceinfo> diff --git a/setup/Linux/oss/scripts/killprocs.sh b/setup/Linux/oss/scripts/killprocs.sh new file mode 100755 index 0000000..ce8d26d --- /dev/null +++ b/setup/Linux/oss/scripts/killprocs.sh @@ -0,0 +1,17 @@ +#!/bin/sh +PROCS="`fuser /dev/mixer* /dev/dsp* /dev/audio* /dev/sequencer /dev/music /dev/midi* 2>/dev/null`" + +if test "$PROCS " = " " +then + exit 0 +fi + +for pid in $PROCS +do + #ps ax|grep "^ *$pid " + echo killing $pid + kill $pid +done + +sleep 2 +exit 0 diff --git a/setup/Linux/oss/scripts/oss_usb-create-devices b/setup/Linux/oss/scripts/oss_usb-create-devices new file mode 100644 index 0000000..a6de13c --- /dev/null +++ b/setup/Linux/oss/scripts/oss_usb-create-devices @@ -0,0 +1,4 @@ +#!/bin/sh + +/usr/sbin/ossdetect -d +/usr/sbin/ossdevlinks diff --git a/setup/Linux/oss/scripts/remove_drv.sh b/setup/Linux/oss/scripts/remove_drv.sh new file mode 100644 index 0000000..55cc1b4 --- /dev/null +++ b/setup/Linux/oss/scripts/remove_drv.sh @@ -0,0 +1,164 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +# This script wipes out the previously installed sound drivers +# from the system. + +# Backup all kernel sound drivers (ALSA) and remove the kernel/sound +# directory from the system. Untar the backup package to return ALSA +# back in business. + +if test -x /sbin/chkconfig +then + /sbin/chkconfig alsasound off > /dev/null 2>&1 +elif test -x /usr/sbin/update-rc.d +then + /usr/sbin/update-rc.d -f alsa-utils remove > /dev/null 2>&1 +elif test -x /usr/sbin/alsa +then + /usr/sbin/alsa force-unload > /dev/null 2>&1 +fi + +if test -d /lib/modules/`uname -r`/kernel/sound +then + if ! test -f /lib/modules/`uname -r`/sound-preoss.tar.bz2 + then + (cd /lib/modules/`uname -r`; tar cfj /lib/modules/`uname -r`/sound-preoss.tar.bz2 kernel/sound) + fi + + rm -rf /lib/modules/`uname -r`/kernel/sound + depmod -a +fi + +# Kill all applications using ALSA or OSS/Free devices + +# We have to use ugly replacement of fuser since this command got broken +# in some Linux recent distributions. + +KILL=0 + +for n in /proc/[0-9]* +do + PID=`basename $n` + if test "`ls -l $n/fd/* 2>/dev/null|grep /dev/snd` " != " " + then + KILL=1 + fi + + if test "`ls -l $n/fd/* 2>/dev/null|grep /dev/mixer` " != " " + then + KILL=1 + fi +done + +if ! test -d $OSSLIBDIR/save +then + mkdir $OSSLIBDIR/save +fi + +if test "$KILL " = "1 " +then +echo killing + rm -f /dev/mixer.old + mv /dev/mixer /dev/mixer.old 2>/dev/null + #if test -d /dev/snd + #then + #(cd /;tar cfj $OSSLIBDIR/save/alsadevs.tar.bz2 dev/snd) + #fi + + #mv /dev/snd /dev/snd.osssave + #fuser -k -s /dev/mixer.old /dev/snd.osssave/* +fi + +# Remove all loaded ALSA modules +SOUNDDEVS= + +if test -f /dev/mixer.old +then + SOUNDDEVS="$SOUNDDEVS /dev/mixer.old" +fi + +if test -d /dev/snd.osssave +then + SOUNDDEVS="$SOUNDDEVS /dev/snd.osssave/*" +fi + +for timeout in 0 1 2 3 4 5 6 7 8 9 10 11 +do + if test "`cat /proc/modules|grep ^snd_|sed 's/ .*//'` " = " " + then + break + fi + + if test $timeout -gt 10 + then + echo Cannot unload the ALSA modules. Apparently there is some + echo application keeping them busy. + echo Please reboot your system and try to start OSS again. + ps ax + lsmod + cat /proc/devices + cat /proc/interrupts + exit 1 + fi + + if test "$SOUNDDEVS " != " " + then + fuser -s -9 $SOUNDDEVS + else + echo Cannot find any processes using the conflicting sound driver + fi + + for n in `cat /proc/modules|grep ^snd_|sed 's/ .*//'` + do + rmmod $n + #rmmod $n >/dev/null 2>&1 + done + + sleep 1 +done + +rmmod snd > /dev/null 2>&1 + +# Remove soundcore +rmmod soundcore > /dev/null 2>&1 + +rm -f /dev/mixer.old + +if cat /proc/devices|grep -q '^ *14 ' +then + + echo There still appears to be another sound driver hanging around + + lsmod + cat /proc/devices|grep '^ *14 ' + cat /proc/interrupts + + exit 1 +fi + +for n in /dev/sndstat /dev/mixer* /dev/dsp* /dev/midi* /dev/sequencer /dev/music +do + if readlink $n >/dev/null 2>&1 + then # Symbolic link + if readlink $n | grep -q asound + then # Link to ALSA devices + rm -f $n + fi + fi +done + +# Disable automatic startup of ALSA during system bootup + +if test "`ls /etc/rc.d/rc*/*alsasound*` " != " " > /dev/null 2>&1 +then + (cd /;tar cfj $OSSLIBDIR/save/alsarc/tar.bz2 etc/rc.d/rc*/*alsasound*) + rm -f /etc/rc.d/rc*/*alsasound* +fi > /dev/null 2>&1 + +exit 0 diff --git a/setup/Linux/oss/scripts/restore_drv.sh b/setup/Linux/oss/scripts/restore_drv.sh new file mode 100644 index 0000000..9046d04 --- /dev/null +++ b/setup/Linux/oss/scripts/restore_drv.sh @@ -0,0 +1,63 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +/usr/sbin/soundoff + +rm -rf /lib/modules/`uname -r`/kernel/oss + +if test -x /sbin/chkconfig +then /sbin/chkconfig oss off > /dev/null 2>&1 +else + if test -x /sbin/update-rc.d + then /usr/sbin/update-rc.d -f oss remove > /dev/null 2>&1 + fi +fi + +rm -f /etc/init.d/oss + +if ! test -d /lib/modules/`uname -r`/kernel/sound +then + if test -f /lib/modules/`uname -r`/sound-preoss.tar.bz2 + then + (cd /lib/modules/`uname -r`; tar xfj sound-preoss.tar.bz2) + /sbin/depmod -a + fi +fi + +rm -f /lib/modules/`uname -r`/sound-preoss.tar.bz2 + +if test -f $OSSLIBDIR/sysfiles.list +then + rm -f `cat $OSSLIBDIR/sysfiles.list` +fi + +if test -f $OSSLIBDIR/save/alsadevs.tar.bz2 +then + (cd /;tar xfj $OSSLIBDIR/save/alsadevs.tar.bz2) +fi + +if test -f $OSSLIBDIR/save/alsarc/tar.bz2 +then + (cd /;tar xfj $OSSLIBDIR/save/alsarc/tar.bz2) +fi + +rm -f /dev/dsp* /dev/midi* /dev/mixer* /dev/sndstat + +/sbin/ldconfig + +if test -x /sbin/chkconfig +then + /sbin/chkconfig alsasound on > /dev/null 2>&1 +else + if test -x /usr/sbin/update-rc.d + then + /usr/sbin/update-rc.d alsa-utils defaults > /dev/null 2>&1 + fi +fi + +exit 0 diff --git a/setup/Linux/oss/scripts/setup-alsa.sh b/setup/Linux/oss/scripts/setup-alsa.sh new file mode 100644 index 0000000..fdcf4ff --- /dev/null +++ b/setup/Linux/oss/scripts/setup-alsa.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +# This script will restgore selected ALSA modules that were earlier removed by +# remove_drv.sh + +if test -d /proc/asound +then +# ALSA is already loaded + exit 0 +fi + +if ! test -f /lib/modules/`uname -r`/sound-preoss.tar.bz2 +then + echo ALSA backup archive /lib/modules/`uname -r`/sound-preoss.tar.bz2 not found. Cannot continue. + exit 1 +fi + +RESTORE=kernel/sound/soundcore.ko + +for n in snd snd-pcm snd-timer snd-page-alloc +do + RESTORE="$RESTORE kernel/sound/core/$n.ko kernel/sound/acore/$n.ko" +done + +(cd /lib/modules/`uname -r` && tar xvfj sound-preoss.tar.bz2 $RESTORE) + +if test -d /dev/snd.save && ! test -d /dev/snd +then + mv /dev/snd.save /dev/snd +fi + +exit 0 diff --git a/setup/Linux/oss/scripts/showprocs.sh b/setup/Linux/oss/scripts/showprocs.sh new file mode 100755 index 0000000..827bb33 --- /dev/null +++ b/setup/Linux/oss/scripts/showprocs.sh @@ -0,0 +1,28 @@ +#!/bin/sh +PROCS="`fuser /dev/mixer* /dev/dsp* /dev/audio* /dev/sequencer /dev/music /dev/midi*|sed 's/.* //'|sort|uniq`" + +if test "$PROCS " = " " +then + exit 0 +fi + +if test "$1 " != "-q " +then +echo $PROCS +echo +echo "NOTICE!" +echo "=======" +echo +echo There are some programs still using OSS devices. You may need to stop them +echo manually: +echo +fi + +for pid in $PROCS +do + ps ax|grep "^ *$pid " +done + +echo + +exit 0 diff --git a/setup/Linux/oss/soundon.user b/setup/Linux/oss/soundon.user new file mode 100644 index 0000000..da31b6d --- /dev/null +++ b/setup/Linux/oss/soundon.user @@ -0,0 +1,7 @@ +#!/bin/sh +# +# This script can be used to run programs every time OSS is started. +# By default, this script is disabled, and contains no commands. +# To enable, add executable permissions to this file, and edit below +# commands to be run. +exit 0 diff --git a/setup/Linux/postinst b/setup/Linux/postinst new file mode 100644 index 0000000..f1ccbf3 --- /dev/null +++ b/setup/Linux/postinst @@ -0,0 +1,15 @@ +#!/bin/sh +OSSLIBDIR=/usr/lib/oss +if [ -e /tmp/OSS_UPGRADE ]; then rm /tmp/OSS_UPGRADE; fi +if [ -e /etc/oss.conf ]; then . /etc/oss.conf; else echo "OSSLIBDIR=/usr/lib/oss" > /etc/oss.conf; fi +echo "Building OSS Modules for Linux-`uname -p` `uname -r`" +cd "$OSSLIBDIR"/build +sh install.sh +if [ -x /usr/bin/update-menus ]; then /usr/bin/update-menus; fi +echo "Forcing re-detection of installed soundcards" +ossdetect +echo "Starting Open Sound System" +sync +/usr/sbin/soundoff >> /dev/null 2>&1 +sync +/usr/sbin/soundon || exit 0 diff --git a/setup/Linux/postrm b/setup/Linux/postrm new file mode 100644 index 0000000..620f8e2 --- /dev/null +++ b/setup/Linux/postrm @@ -0,0 +1,6 @@ +#!/bin/sh +OSSLIBDIR=/usr/lib/oss +if [ -e /etc/oss.conf ]; then . /etc/oss.conf; fi +if [ -e /tmp/OSS_UPGRADE ]; then echo "Upgrading OSS - will not purge $OSSLIBDIR."; else rm -rf "$OSSLIBDIR"/*; fi +rm -f /usr/lib/libflashsupport.so +if [ -x /usr/bin/update-menus ]; then /usr/bin/update-menus; fi diff --git a/setup/Linux/preinst b/setup/Linux/preinst new file mode 100644 index 0000000..ae93962 --- /dev/null +++ b/setup/Linux/preinst @@ -0,0 +1,6 @@ +#!/bin/sh +if [ -x /etc/init.d/alsa-utils ]; then /etc/init.d/alsa-utils stop || true; fi +if [ -x /usr/sbin/alsa ]; then /usr/sbin/alsa force-unload || true; fi +if [ -x /etc/init.d/alsa ]; then /etc/init.d/alsa force-unload || true; fi +touch /tmp/OSS_UPGRADE +exit 0 diff --git a/setup/Linux/prerm b/setup/Linux/prerm new file mode 100644 index 0000000..67fdf0c --- /dev/null +++ b/setup/Linux/prerm @@ -0,0 +1,4 @@ +#!/bin/sh +OSSLIBDIR=/usr/lib/oss +if [ -e /etc/oss.conf ]; then . /etc/oss.conf; fi +sh "$OSSLIBDIR"/scripts/restore_drv.sh || true diff --git a/setup/Linux/removeoss.sh b/setup/Linux/removeoss.sh new file mode 100644 index 0000000..0e9d992 --- /dev/null +++ b/setup/Linux/removeoss.sh @@ -0,0 +1,31 @@ +#!/bin/sh +if test `whoami` != "root" +then + echo "You must be super-user or logged in as root to uninstall OSS..." + exit 0 +fi + +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +echo "Uninstalling OSS...." +echo "Running soundoff...." +/usr/sbin/soundoff +echo "Restoring previously install sound drivers..." +sh "$OSSLIBDIR"/scripts/restore_drv.sh +echo "Removing OSS Files in MANIFEST" +cd / +for i in `cat "$OSSLIBDIR"/MANIFEST` +do +# echo "Removing file $i" +rm -f $i +done + +echo "Removing $OSSLIBDIR directory" +rm -rf "$OSSLIBDIR" + +echo "OSS Uninstalled. However you may need to reboot the system." diff --git a/setup/Linux/sbin/soundoff b/setup/Linux/sbin/soundoff new file mode 100755 index 0000000..16ff69c --- /dev/null +++ b/setup/Linux/sbin/soundoff @@ -0,0 +1,69 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +if ! test -f /proc/opensound/devfiles +then + echo OSS not loaded. + exit 0 +fi + +if ! test -f $OSSLIBDIR/etc/installed_drivers +then + echo $OSSLIBDIR/etc/installed_drivers is missing. + exit 1 +fi + + +# Save mixer settings automatically if requested +if test -f $OSSLIBDIR/etc/userdefs && grep -q "autosave_mixer yes" $OSSLIBDIR/etc/userdefs +then + /usr/sbin/savemixer +fi + +# Save legacy devices +/usr/sbin/ossdevlinks -N + +PROGRAMS="`fuser /dev/mixer* /dev/dsp* /dev/midi* /dev/oss/*/* 2>/dev/null`" + +if test "$PROGRAMS " != " " +then + echo + echo Some applications are still using OSS - cannot unload + echo + + for n in $PROGRAMS + do + if test -f /proc/$n/cmdline + then + echo $n `cat /proc/$n/cmdline | sed 's/\x00/ /g'` + else + echo $n Unknown + fi + done + + echo + echo Please stop these applications and run soundoff again + exit 2 +fi + +for i in 1 2 3 +do + for n in `egrep "^osscore" /proc/modules 2>/dev/null | cut -d ' ' -f 4 | sed 's/,/ /g'` `cat $OSSLIBDIR/etc/installed_drivers | sed 's/#.*//'` osscore + do + /sbin/modprobe -r $n > /dev/null 2>&1 + done +done + +if ! test -f /proc/opensound/devfiles # OSS gone? +then + exit 0 +fi + +echo Cannot unload the OSS driver modules + +exit 3 diff --git a/setup/Linux/sbin/soundon b/setup/Linux/sbin/soundon new file mode 100755 index 0000000..e868fd6 --- /dev/null +++ b/setup/Linux/sbin/soundon @@ -0,0 +1,351 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +if ! test -d /proc +then + echo soundon script requires procfs to be mounted at /proc! + exit 200 +fi + +if test -f /proc/opensound/devfiles +then + echo OSS is already loaded. + exit 0 +fi + +if test -f $OSSLIBDIR/starting +then + echo Previous start of OSS crashed the system + echo Please resolve the situation and remove file + echo \"$OSSLIBDIR/starting\". Then start OSS by + echo running soundon again. + exit 1 +fi + +NOTIFY=0 + +LOG=/var/log/soundon.log +echo "Open Sound System starting" `date` > $LOG +echo "OSS version: " `cat $OSSLIBDIR/version.dat` >> $LOG 2>&1 +KERNEL_VERSION=`uname -r` +echo "Kernel version: " $KERNEL_VERSION >> $LOG +KERNEL_VERMAGIC=`/usr/sbin/ossvermagic -z -s` +echo "Kernel vermagic: " $KERNEL_VERMAGIC >> $LOG 2>&1 + +if ! test -f $OSSLIBDIR/etc/installed_drivers +then + echo No $OSSLIBDIR/etc/installed_drivers - running ossdetect >> $LOG + /usr/sbin/ossdetect -v >> $LOG +fi + +if ! test -f $OSSLIBDIR/etc/installed_drivers +then + echo Still no $OSSLIBDIR/etc/installed_drivers - cannot continue >> $LOG + echo No $OSSLIBDIR/etc/installed_drivers - cannot continue + exit 10 +fi + +UBUNTU_OVERRIDE= +POS_UBUNTU_OVERRIDE= +if test -f /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko +then +# Verify that vermagic of OSS matches the kernel vermagic + + OSS_VERMAGIC=`/usr/sbin/ossvermagic -z -q /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko` + + if ! test "$OSS_VERMAGIC " = "$KERNEL_VERMAGIC " + then + OSS_ORIG_VERMAGIC="$OSS_VERMAGIC" + OSS_VERMAGIC=`/usr/sbin/ossvermagic -z -u -q /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko` + POS_UBUNTU_OVERRIDE=1 + fi + + if ! test "$OSS_VERMAGIC " = "$KERNEL_VERMAGIC " + then + echo "Old vermagic: " $OSS_VERMAGIC >> $LOG + rm -rf /lib/modules/$KERNEL_VERSION/kernel/oss + echo Previous OSS modules were for a different kernel version - removed + echo Previous OSS modules were for a different kernel version - removed >> $LOG + elif test "$POS_UBUNTU_OVERRIDE " = "1 " + then + echo "Vermagic backup check activated for Ubuntu. Backup vermagic: $OSS_VERMAGIC. OSS stored vermagic $OSS_ORIG_VERMAGIC" >> $LOG + UBUNTU_OVERRIDE="-u" + fi +fi + +if ! test -f /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko +then + NOTIFY=1 + echo Relinking OSS kernel modules for \"$KERNEL_VERMAGIC\" + echo This may take few moments - please stand by... + echo Relinking OSS kernel modules for $KERNEL_VERMAGIC >> $LOG + + rm -f /var/log/relink.log + if ! (cd $OSSLIBDIR/build && sh install.sh > /var/log/relink.log 2>&1) + then + cat /var/log/relink.log >> $LOG 2>&1 + cat /var/log/relink.log + echo + echo Relinking the OSS kernel modules failed + rm -f /var/log/relink.log + exit 20 + fi + + cat /var/log/relink.log >> $LOG 2>&1 + echo Relinking OSS kernel modules finished + rm -f /var/log/relink.log +fi + +if ! test -f /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko +then + echo + echo No /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko module >> $LOG + echo No /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko module in the system + exit 30 +fi + +OSS_VERMAGIC=`/usr/sbin/ossvermagic -z $UBUNTU_OVERRIDE -q /lib/modules/$KERNEL_VERSION/kernel/oss/osscore.ko` +echo "OSS vermagic: " $OSS_VERMAGIC >> $LOG + +if ! test "$OSS_VERMAGIC " = "$KERNEL_VERMAGIC " +then + echo OSS driver modules do not match the current kernel >> $LOG + echo + echo Error: OSS driver modules do not match the current kernel + echo + echo "Kernel vermagic: " $KERNEL_VERMAGIC + echo "OSS vermagic: " $OSS_VERMAGIC + echo + echo The most likely reason is that the kernel development package + echo installed in the system is wrong. Please refer to the documentation + echo of your Linux distribution for more info about setting up the + echo kernel/driver development environment properly. + echo + exit 40 +fi + +if test -f $OSSLIBDIR/etc/license.asc +then + /usr/sbin/ossdetect -l >> $LOG +fi + +if test -d /proc/asound || grep -q '^ *14 ' < /proc/devices +then + if ! sh $OSSLIBDIR/scripts/remove_drv.sh>> $LOG + then + echo Failed to disable conflicting sound drivers >> $LOG + echo Failed to disable conflicting sound drivers + echo Reboot and try running soundon again + echo + echo Also check that you have not compiled sound support statically + echo into the kernel. + exit 50 + fi +fi + +echo >> $LOG +echo '*** Loading OSS kernel modules ***' >> $LOG +echo >> $LOG + +touch $OSSLIBDIR/starting +sync + +OPTIONS= +if test -f $OSSLIBDIR/conf/osscore.conf +then + OPTIONS="`grep -v -h '^#' $OSSLIBDIR/conf/osscore.conf|sed 's/[ \t]//g'`" +fi + +if ! /sbin/modprobe osscore $OPTIONS +then + echo Loading the osscore module failed + echo Loading the osscore module failed >> $LOG + dmesg >> $LOG + exit 60 +fi + +echo "osscore module loaded OK" >> $LOG + +for n in `cat $OSSLIBDIR/etc/installed_drivers | sed 's/#.*//'` +do + OPTIONS= + + if test -f $OSSLIBDIR/conf/$n.conf + then + OPTIONS="`grep -v -h '^#' $OSSLIBDIR/conf/$n.conf|sed 's/[ \t]//g'`" + fi + + if ! /sbin/modprobe $n $OPTIONS + then + echo Loading module $n failed '-' ignored >> $LOG + echo Loading module $n failed '-' ignored + else + echo $n module loaded OK >> $LOG + fi +done +echo >> $LOG +echo '*** Finished loading OSS kernel modules ***' >> $LOG +echo >> $LOG + +if ! test -f /proc/opensound/devfiles +then + echo OSS Core module refused to start >> $LOG + echo OSS Core module refused to start + dmesg >> $LOG + exit 70 +fi + +/usr/sbin/ossdetect -d >> $LOG 2>&1 + +# Restore the legacy device links. This is necessary because in some +# Linux distributions they get lost when the system is booted. +if test -f $OSSLIBDIR/etc/legacy_devices +then + sh $OSSLIBDIR/etc/legacy_devices >> $LOG 2>&1 +fi + +/usr/sbin/ossdevlinks -v >> $LOG 2>&1 + +echo "+++ ossinfo -v3 +++" >> $LOG +ossinfo -v3 >> $LOG 2>&1 +echo "+++ /dev/sndstat +++" >> $LOG +cat /dev/sndstat >> $LOG 2>&1 +echo "+++ dmesg +++" >> $LOG +dmesg >> $LOG +echo "+++ lspci +++" >> $LOG +lspci -vnn >> $LOG 2>&1 +echo "+++ /proc/interrupts +++" >> $LOG +cat /proc/interrupts >> $LOG 2>&1 +echo "+++ /proc/cpuinfo +++" >> $LOG +cat /proc/cpuinfo >> $LOG 2>&1 +echo "+++ /proc/opensound/devfiles +++" >> $LOG +cat /proc/opensound/devfiles >> $LOG 2>&1 +ls -l /dev/dsp* /dev/mixer* /dev/midi* /dev/oss/*/* >> $LOG 2>&1 + +echo >> $LOG +/usr/sbin/savemixer -L -v >> $LOG 2>&1 + +# Setup ALSA emulation + +if test -f $OSSLIBDIR/.cuckoo_installed +then +# Use kernel based ALSA compatibility + + if ! test -f /lib/modules/$KERNEL_VERSION/kernel/sound/core/snd.ko + then + sh $OSSLIBDIR/scripts/setup-alsa.sh >> $LOG 2>&1 + depmod -a + fi + + echo "*** Setting up ALSA compatibility ****" >> $LOG + modprobe cuckoo >> $LOG 2>&1 + head -10 /proc/asound/version >> $LOG 2>&1 + lsmod|grep snd >> $LOG + echo "**************************************" >> $LOG +elif test -f $OSSLIBDIR/.libsalsa_installed +then +# Use library based ALSA compatibility + + if test -f $OSSLIBDIR/lib/libsalsa.so.2.0.0 + then + if test "`uname -m` " = "x86_64 " + then + ln -sf $OSSLIBDIR/lib/libsalsa.so.2.0.0 /usr/lib64/libasound.so.2 + #ln -sf $OSSLIBDIR/lib/libOSSlib.so /usr/lib64 + else + if test -s /lib/libasound.so.2 + then + ln -sf $OSSLIBDIR/lib/libsalsa.so.2.0.0 /lib/libasound.so.2 + #ln -sf $OSSLIBDIR/lib/libOSSlib.so /lib + fi + + if test -s /usr/lib/libasound.so.2 + then + ln -sf $OSSLIBDIR/lib/libsalsa.so.2.0.0 /usr/lib/libasound.so.2 + #ln -sf $OSSLIBDIR/lib/libOSSlib.so /usr/lib + fi + fi + fi +fi + +# Setup libOSSlib.so +if test -f $OSSLIBDIR/lib/libOSSlib.so +then + if test "`uname -m` " = "x86_64 " + then + ln -sf $OSSLIBDIR/lib/libOSSlib.so /usr/lib64 + ln -sf $OSSLIBDIR/lib/libossmix.so /usr/lib64 + else + if test -s /lib/libasound.so.2 + then + ln -sf $OSSLIBDIR/lib/libOSSlib.so /lib + ln -sf $OSSLIBDIR/lib/libossmix.so /lib + fi + + if test -s /usr/lib/libasound.so.2 + then + ln -sf $OSSLIBDIR/lib/libOSSlib.so /usr/lib + ln -sf $OSSLIBDIR/lib/libossmix.so /usr/lib + fi + fi +fi + +# Setup Flash 9 audio support plugin for OSS + +if test -d /usr/lib64 && test -f $OSSLIBDIR/lib/libflashsupport_64.so +then + ln -sf $OSSLIBDIR/lib/libflashsupport_64.so /usr/lib64/libflashsupport.so +fi + +if test -d /usr/lib32 && test -f $OSSLIBDIR/lib/libflashsupport_32.so +then + ln -sf $OSSLIBDIR/lib/libflashsupport_32.so /usr/lib32/libflashsupport.so +fi + +if ! test -f /usr/lib/libflashsupport.so && test -f $OSSLIBDIR/lib/libflashsupport_32.so +then + ln -sf $OSSLIBDIR/lib/libflashsupport_32.so /usr/lib/libflashsupport.so +fi + +if test -x $OSSLIBDIR/soundon.user +then + echo Running $OSSLIBDIR/soundon.user >> $LOG + $OSSLIBDIR/soundon.user >> $LOG 2>&1 +fi + +if test "`ossinfo -g|grep TRIAL` " != " " +then + echo + echo "************************************************************" + echo "* NOTE! You are using trial version of Open Sound System *" + echo "************************************************************" + echo + + sleep 1 +fi + +if test "`ossinfo -g|grep EXPIRED` " != " " +then + echo + echo "****************************************************************" + echo "* NOTE! Your Open Sound System evaluation license has expired *" + echo "****************************************************************" + echo + + sleep 15 +fi + +if test "$NOTIFY " = "1 " +then + echo + echo OSS started OK +fi + +rm -f $OSSLIBDIR/starting + +exit 0 diff --git a/setup/Linux/shlibs b/setup/Linux/shlibs new file mode 100644 index 0000000..95e6d37 --- /dev/null +++ b/setup/Linux/shlibs @@ -0,0 +1 @@ +libsalsa 2 oss-linux diff --git a/setup/Linux/spec.tmpl b/setup/Linux/spec.tmpl new file mode 100644 index 0000000..2861496 --- /dev/null +++ b/setup/Linux/spec.tmpl @@ -0,0 +1,39 @@ +Summary: Open Sound System sound drivers for Linux +License: Open Sound System +Group: System/sound +Source: oss +URL: http://www.opensound.com +Distribution: Open Sound System +Vendor: 4Front Technologies +Packager: 4Front Technologies +BuildRoot: /tmp/prototype +Requires: gcc, make +%if 0%{?suse_version} +Requires: kernel-default-devel +%else +Requires: kernel-devel +%endif + +%description +Open Sound System for Linux (OSS/Linux) is a commercial quality sound driver +distributed by 4Front Technologies (http://www.opensound.com). OSS provides +support for practically all sound cards on the market including PnP and +many PCI ones. Installation and configuration is higly automated and easy to +perform. To obtain technical support and additional features, you will need to +order a license key from http://www.opensound.com/order.html +%prep +%setup +%pre +%post +echo "Building OSS Modules for Linux-`uname -p` `uname -r`" +cd OSSLIBDIR/build +sh install.sh +echo "Starting Open Sound System" +/usr/sbin/soundoff >> /dev/null 2>&1 +/usr/sbin/soundon +exit 0 +%preun +sh OSSLIBDIR/scripts/restore_drv.sh +%postun +rm -rf OSSLIBDIR/* +rm -f /usr/lib/libflashsupport.so diff --git a/setup/SCO_SV/README.txt b/setup/SCO_SV/README.txt new file mode 100644 index 0000000..6a5de1d --- /dev/null +++ b/setup/SCO_SV/README.txt @@ -0,0 +1,64 @@ +Build instructions for UW7/OSR6 combined oss package. + +A. Build the UW7 version. + + 1. On the UW7 machine, create a directory for the builds (we'll use + $HOME/oss for our examples). + + 2. Copy this included tarball into that directory. + + 3. Install the txt2man-1.4.8.tar.gz as root: + # cd /tmp + # gunzip -c $HOME/oss/txt2man-1.4.8.tar.gz | tar xvf - + # cd txt2man-1.4.8 + # make install + + 4. Make sure there is a gawk installed in /usr/local/bin. If the + GNUgawk package is already installed, you can just create a + symbolic link to it: + # ln -s /usr/gnu/bin/gawk /usr/local/bin/gawk + + 5. Unwind the oss source into the build directory: + $ cd $HOME/oss + $ bunzip2 -c /tmp/oss-4.0-177-061108-src.tar.bz2 | tar xvf - + This should give you a oss-4.0 directory. + + 6. Create a directory for the UW7 specific build and do the build and + package: + $ mkdir $HOME/oss/oss-4.0-uw7.BUILD + $ cd $HOME/oss/oss-4.0-uw7.BUILD + $ $HOME/oss/oss-4.0/configure + $ make + $ make package + +B. Build an OSR6 version. + + 1. On the OSR6 machine, create a directory for the builds (we'll use + $HOME/oss for our examples). + + 2. Copy this included tarball into that directory. + + 3. Unwind the oss source into the build directory: + $ cd $HOME/oss + $ bunzip2 -c /tmp/oss-4.0-177-061108-src.tar.bz2 | tar xvf - + This should give you a oss-4.0 directory. + + 6. Create a directory for the OSR6 specific build and do the build and + package: + $ mkdir $HOME/oss/oss-4.0-osr6.BUILD + $ cd $HOME/oss/oss-4.0-osr6.BUILD + $ $HOME/oss/oss-4.0/configure + $ make + $ make package + +C. Create the combined package. + + 1. Copy the entire oss-4.0-osr6.BUILD directory onto the UW7 machine, + and put it in the $HOME/oss directory. You should now have both a + oss-4.0-uw7.BUILD and a oss-4.0-osr6.BUILD directory in $HOME/oss. + + 2. Run the mkoss.sh script to build the product. + $ cd $HOME/oss + $ ./mkoss.sh + + 3. The pkgadd'able data stream is $HOME/oss/oss-4.0-comb/*.pkg. diff --git a/setup/SCO_SV/S89oss b/setup/SCO_SV/S89oss new file mode 100644 index 0000000..1cfb472 --- /dev/null +++ b/setup/SCO_SV/S89oss @@ -0,0 +1,46 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +########## +# +# The first argument tells what to do. +########## + +state=$1 + +case $state in + +'start') + # Signal the osscore module to forceload all the low level + # drivers (in the right order). + + if test -f $OSSLIBDIR/starting + then + echo Previous start failed. Remove $OSSLIBDIR/starting + echo and run soundon manually to start OSS. + exit 1 + fi + + echo "Starting Open Sound System" + /usr/sbin/soundoff > /dev/null 2>&1 + /usr/sbin/soundon + rm -f $OSSLIBDIR/starting + exit 0 + ;; +'stop') + # Save mixer settings automatically if requested + if test -f $OSSLIBDIR/etc/userdefs && grep -q "autosave_mixer yes" $OSSLIBDIR/etc/userdefs + then + /usr/sbin/savemixer + fi + exit 0 + ;; +esac + +exit 1 + diff --git a/setup/SCO_SV/build.sh b/setup/SCO_SV/build.sh new file mode 100644 index 0000000..27d4471 --- /dev/null +++ b/setup/SCO_SV/build.sh @@ -0,0 +1,172 @@ +#!/bin/sh + +. ./.directories + +rm -rf prototype + +mkdir prototype +mkdir prototype/etc +echo "OSSLIBDIR=$OSSLIBDIR" > prototype/etc/oss.conf + +TXT2MAN=$SRCDIR/setup/txt2man + +if test ! -f /usr/local/bin/gawk +then + # No gawk installed. Use the simple txt2man program instead of + # the fully featured shell script which depends on gawk. + + rm -f txt2man + + cc -o txt2man $SRCDIR/setup/txt2man.c + + if test -f txt2man + then + TXT2MAN=./txt2man + fi +fi + +mkdir prototype/usr +mkdir prototype/usr/lib +mkdir prototype/usr/bin +mkdir prototype/usr/man +mkdir prototype/usr/man/man1 +mkdir prototype/usr/man/man7 +mkdir prototype/usr/man/man8 +mkdir prototype/usr/sbin +mkdir prototype/$OSSLIBDIR +mkdir prototype/$OSSLIBDIR/etc +echo "autosave_mixer yes" > prototype/$OSSLIBDIR/etc/userdefs +mkdir prototype/$OSSLIBDIR/lib +mkdir prototype/$OSSLIBDIR/logs +mkdir prototype/$OSSLIBDIR/modules +mkdir prototype/$OSSLIBDIR/modules/osscore +mkdir prototype/$OSSLIBDIR/include +mkdir prototype/$OSSLIBDIR/include/sys +mkdir prototype/$OSSLIBDIR/conf +mkdir prototype/usr/include +mkdir prototype/usr/include/sys + +chmod 700 prototype/$OSSLIBDIR/modules + +cp $SRCDIR/include/soundcard.h prototype/usr/include/sys + +cp .version prototype/$OSSLIBDIR/version.dat + +cp -R $SRCDIR/include/* prototype/$OSSLIBDIR/include/sys/ +cp $SRCDIR/kernel/framework/include/midiparser.h prototype/$OSSLIBDIR/include/ + +(cd target/bin; rm -f ossrecord; ln -s ossplay ossrecord) +cp -f target/bin/* prototype/usr/bin +cp -f target/sbin/* prototype/usr/sbin +cp -f $SRCDIR/setup/SCO_SV/sbin/* prototype/usr/sbin +cp -R $SRCDIR/setup/SCO_SV/oss prototype/usr/lib + +FPSUPPORT= + +if test -f $SRCDIR/setup/SCO_SV/fpsupport.s && as $SRCDIR/setup/SCO_SV/fpsupport.s +then + FPSUPPORT=fpsupport.o +fi + +ld -r -o prototype/$OSSLIBDIR/modules/osscore/Driver.o target/objects/*.o $SRCDIR/setup/SCO_SV/*.o $FPSUPPORT + +grep '^int' $SRCDIR/kernel/framework/osscore/oss_core_options.c > prototype/$OSSLIBDIR/modules/osscore/Space.c + +rm -f devlist.txt + +for n in target/modules/*.o +do + N=`basename $n .o` + mkdir prototype/$OSSLIBDIR/modules/$N + cp target/build/$N/* prototype/$OSSLIBDIR/modules/$N + ld -r -o prototype/$OSSLIBDIR/modules/$N/Driver.o $n + +# Now copy the man pages + if test -f $SRCDIR/kernel/drv/$N/$N.man + then + sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/drv/$N/$N.man > /tmp/ossman.tmp + $TXT2MAN -t "$N" -v "Devices" -s 7d /tmp/ossman.tmp > prototype/usr/man/man7/$N.7 + fi + + if test -f $SRCDIR/kernel/nonfree/drv/$N/$N.man + then + sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/nonfree/drv/$N/$N.man > /tmp/ossman.tmp + $TXT2MAN -t "$N" -v "Devices" -s 7d /tmp/ossman.tmp > prototype/usr/man/man7/$N.7 + fi + +echo Check devices for $N + grep "^$N[ ]" ./devices.list >> devlist.txt +done + +sed "s:CONFIGFILEPATH:$OSSLIBDIR/conf:g" < $SRCDIR/kernel/drv/osscore/osscore.man > /tmp/ossman.tmp +$TXT2MAN -t "osscore" -v "Devices" -s 7 /tmp/ossman.tmp > prototype/usr/man/man7/osscore.7 +rm -f /tmp/ossman.tmp + +#if cp lib/libOSSlib/libOSSlib.a prototype/$OSSLIBDIR/lib +#then +# ok=1 +#else +# exit 1 +#fi + +cp devlist.txt prototype/$OSSLIBDIR/etc/devices.list + +if test -d kernel/nonfree +then + sed 's/.* //' < devlist.txt|sort|uniq >$SRCDIR/devlists/OSR6 + #cp devlist.txt $SRCDIR/devlists/SCO +fi + +# Generate Man pages for commands +for i in target/bin/* +do +CMD=`basename $i` +$TXT2MAN -t "$CMD" -v "User Commands" -s 1 cmd/$CMD/$CMD.man > prototype/usr/man/man1/$CMD.1 +echo done $CMD +done + +for i in target/sbin/* +do + CMD=`basename $i` + if test -f cmd/$CMD/$CMD.man + then + $TXT2MAN -t "$CMD" -v "System Administration Commands" -s 8 cmd/$CMD/$CMD.man > prototype/usr/man/man8/$CMD.8 + echo done $CMD + fi +done + +for i in $SRCDIR/misc/man1m/*.man +do + N=`basename $i .man` + $SRCDIR/setup/txt2man -t "$CMD" -v "OSS System Administration Commands" -s 1 $i > prototype/usr/man/man1/$N.1 +done + +rm -f prototype/usr/man/man8/ossdetect.8 +$TXT2MAN -t "ossdetect" -v "User Commands" -s 8 os_cmd/SCO_SV/ossdetect/ossdetect.man > prototype/usr/man/man8/ossdetect.8 +echo done ossdetect + +# Licensing stuff +if test -f $SRCDIR/4front-private/osslic.c +then + cc -o prototype/usr/sbin/osslic -Isetup -Ikernel/nonfree/include -Ikernel/framework/include -Iinclude -Ikernel/OS/SCO_SV -I$SRCDIR $SRCDIR/4front-private/osslic.c + strip prototype/usr/sbin/osslic + + prototype/usr/sbin/osslic -q -u -3prototype/$OSSLIBDIR/modules/osscore/Driver.o + +fi + +if test -f 4front-private/ossupdate.c +then + # ossupdate + cc -I. 4front-private/ossupdate.c -s -o prototype/usr/sbin/ossupdate -lsocket -lnsl +fi + +sh $SRCDIR/setup/build_common.sh $SRCDIR $OSSLIBDIR + +chmod 700 prototype/usr/sbin/* +chmod 755 prototype/usr/bin/* + +cp setup/SCO_SV/S89oss prototype/$OSSLIBDIR/etc +chmod 744 prototype/$OSSLIBDIR/etc/S89oss + +exit 0 diff --git a/setup/SCO_SV/combpkg/depend b/setup/SCO_SV/combpkg/depend new file mode 100644 index 0000000..f3a47b4 --- /dev/null +++ b/setup/SCO_SV/combpkg/depend @@ -0,0 +1,2 @@ +# using depend in packages. +X audio Audio Subsystem diff --git a/setup/SCO_SV/combpkg/mkpkg.sh b/setup/SCO_SV/combpkg/mkpkg.sh new file mode 100755 index 0000000..2e4cb21 --- /dev/null +++ b/setup/SCO_SV/combpkg/mkpkg.sh @@ -0,0 +1,78 @@ +#!/bin/sh +if test "`uname -s`" = "UnixWare" +then + OS=unixware +else + OS=osr6 +fi +# Force both OS versions +OS=unixware_osr6 + +ARCH=i386 + +PKG=oss + +VERSION=`cat ./.version` +BUILDID=`cat ./buildid.dat` +PKGVERSION=$VERSION-$BUILDID +PKGFILE=$PKG-$OS-$PKGVERSION-$ARCH.pkg +TOPDIR=`pwd` +# Setup the scripts +echo "CLASSES=none drvcfg" > ./setup/pkginfo +echo "BASEDIR=/" >> ./setup/pkginfo +echo "PKG=$PKG" >> ./setup/pkginfo +echo "NAME=Open Sound System" >> ./setup/pkginfo +echo "VERSION=$PKGVERSION" >> ./setup/pkginfo +echo "CATEGORY=driver" >> ./setup/pkginfo +echo "DESC=Open Sound System for SCO $OS" >> ./setup/pkginfo +echo "ARCH=$ARCH" >> ./setup/pkginfo +echo "VENDOR=4Front Technologies" >> ./setup/pkginfo +echo "HOTLINE=+1 (310) 202 8530" >> ./setup/pkginfo +echo "EMAIL=support@opensound.com" >> ./setup/pkginfo + +echo "i pkginfo=./setup/pkginfo" > /tmp/$$ +if test -f .date +then + # Open Source Version + echo "i copyright=./Copying" >>/tmp/$$ +else + # Retail version + echo "i copyright=./setup/SCO_EULA" >>/tmp/$$ +fi +echo "i depend=./setup/pkgdepend" >> /tmp/$$ +echo "i postinstall=./setup/postinstall" >> /tmp/$$ +echo "i preremove=./setup/preremove" >> /tmp/$$ +echo "i postremove=./setup/postremove" >> /tmp/$$ +echo "i request=./setup/request" >> /tmp/$$ +echo "i i.drvcfg=./setup/i.drvcfg" >> /tmp/$$ +echo "i r.drvcfg=./setup/r.drvcfg" >> /tmp/$$ + +# now get a list of all the files and directories +(cd prototype; find . -type f -print |pkgproto >> /tmp/$$) +(cd prototype; find . -type l -print |pkgproto >> /tmp/$$) +(cd prototype; find usr/lib/oss -type d -print | pkgproto >> /tmp/$$) +# Change the owner/group for the files +OLDOG="`id -un` `id -gn`" +cp /tmp/$$ /tmp/$$.o +cat /tmp/$$.o | sed -e "s/${OLDOG}/root sys/g" > /tmp/$$ + +# For some files, change the file type of .conf files to editable and set +# class to drvcfg. For architecture specific files, just set the class. +EXCEPTIONLIST='Space.c|userdefs|.uw7|.osr6' +/bin/grep -v -E -e $EXCEPTIONLIST /tmp/$$ > proto +EXCEPTIONLIST='Space.c|userdefs|.uw7$|.osr6$' +/bin/grep -E -e $EXCEPTIONLIST /tmp/$$ |sed -e 's/f none/e drvcfg/g' >> proto +EXCEPTIONLIST='.uw7' +/bin/grep -E -e $EXCEPTIONLIST /tmp/$$ |sed -e 's/f none/f uw7/g' >> proto +EXCEPTIONLIST='.osr6' +/bin/grep -E -e $EXCEPTIONLIST /tmp/$$ |sed -e 's/f none/f osr6/g' >> proto + +# Remove the temp file. +echo "removing /tmp/$$"; rm -f /tmp/$$ + +#now create the package. +pkgmk -o -d /tmp -r $TOPDIR/prototype -a $ARCH -f proto +echo package file is $PKGFILE +pkgtrans -s /tmp $PKGFILE $PKG +echo package file is $PKGFILE +mv /tmp/$PKGFILE $TOPDIR diff --git a/setup/SCO_SV/combpkg/postinstall b/setup/SCO_SV/combpkg/postinstall new file mode 100644 index 0000000..c49de2e --- /dev/null +++ b/setup/SCO_SV/combpkg/postinstall @@ -0,0 +1,82 @@ +#!/bin/sh + +# Place the uw/osr6 specific files into place +if [ -n "`echo $CLASSES | grep osr6`" ]; then + PRFX="osr6" +else + PRFX="uw7" +fi +while read file +do + removef oss ${file}.${PRFX} + mv ${file}.${PRFX} ${file} + installf -c none oss ${file} f +done <<!EOF + /usr/bin/ossxmix +!EOF +removef -f oss +installf -f oss + +. /etc/oss.conf + +echo "Setting up Open Sound System....please wait" + +#first remove the SCO ich driver from the system +/etc/conf/bin/idinstall -d ich > /dev/null 2>&1 + +#Remove orphaned files left from earlier OSS installations +rm -f /dev/sequencer /dev/music +rm -f /dev/*_mixer[0-9]* +rm -f /dev/*_midi[0-9]* +rm -f /dev/*_dsp[0-9]* +rm -f /dev/dsp* +rm -f /dev/mixer* +rm -f /dev/midi* +rm -f /etc/rc3.d/S99oss + +# Unload previous modules +for n in `ls $OSSLIBDIR/modules|grep -v osscore` +do + modadmin -U $n > /dev/null 2>&1 +done + +modadmin -U osscore > /dev/null 2>&1 + +# Remove previous OSS startup files +rm -f /etc/rc3.d/S99oss /etc/init.d/oss + +# (re)install osscore + +rm -f $OSSLIBDIR/modules/*/install.log + +cd $OSSLIBDIR/modules/osscore + +cd $OSSLIBDIR/build && sh install.sh + +if test ! -f $OSSLIBDIR/etc/userdefs +then + echo "autosave_mixer yes" > $OSSLIBDIR/etc/userdefs +fi + +/usr/sbin/soundon + +installf -f oss + +echo "Adding OSS startup scripts to /etc/rc2.d and /etc/init.d" +rm -f /etc/rc2.d/S89oss /etc/init.d/oss + +cp $OSSLIBDIR/etc/S89oss /etc/init.d/oss +chmod 744 /etc/init.d/oss + +ln -s /etc/init.d/oss /etc/rc2.d/S89oss +echo "" +echo "" +echo "" +echo "" +echo Thank you for installing Open Sound System +echo You can run the osstest command to test audio playback in your system. +echo +echo It may be necessary to reboot the system before all devices get properly +echo detected by the system. + +exit 0 diff --git a/setup/SCO_SV/combpkg/request b/setup/SCO_SV/combpkg/request new file mode 100644 index 0000000..005313a --- /dev/null +++ b/setup/SCO_SV/combpkg/request @@ -0,0 +1,21 @@ +#!/bin/sh + + +uver=`uname -v` +if [ "$uver" = 7.1.4 ] ; then + CLASSES="$CLASSES uw7" +else + if [ $uver = "6.0.0" ] ; then + CLASSES="$CLASSES osr6" + else + echo "invalid CLASS" + exit 2 + fi +fi + +# and so to any other packaging scripts +cat >$1 <<! +CLASSES='$CLASSES' +! + +exit 0 diff --git a/setup/SCO_SV/fpsupport.s b/setup/SCO_SV/fpsupport.s new file mode 100644 index 0000000..c2328c4 --- /dev/null +++ b/setup/SCO_SV/fpsupport.s @@ -0,0 +1,107 @@ + .file "fpsupport_i86pc.c" + .text +.globl oss_fp_check + .type oss_fp_check, @function +oss_fp_check: + pushl %ebp + movl %esp, %ebp + pushl %ebx +/APP + pushfl ; popl %edx +/NO_APP + andl $-2097153, %edx +/APP + pushl %edx ; popfl + pushfl ; popl %eax +/NO_APP + movl %eax, %ecx + orl $-1, %edx + andl $2097152, %ecx + jne .L1 + orl $2097152, %eax +/APP + pushl %eax ; popfl + pushfl ; popl %eax +/NO_APP + movl $-2, %edx + testl $2097152, %eax + je .L1 + movl $1, %eax +/APP + cpuid +/NO_APP + andl $16777216, %edx + cmpl $1, %edx + sbbl %ecx, %ecx + andl $-4, %ecx + leal 1(%ecx), %edx +.L1: + movl %edx, %eax + popl %ebx + popl %ebp + ret + .size oss_fp_check, .-oss_fp_check +.globl oss_fp_save + .type oss_fp_save, @function +oss_fp_save: + pushl %ebp + movl %esp, %ebp + pushl %eax + pushl %eax + movl 12(%ebp), %ecx +/APP + movl %cr0,%eax +/NO_APP + movl %eax, (%ecx) +/APP + movl %cr4,%edx +/NO_APP + movl %edx, 4(%ecx) + andl $-15, %eax +/APP + movl %eax,%cr0 +/NO_APP + orb $6, %dh +/APP + movl %edx,%cr4 +/NO_APP + movl 8(%ebp), %edx +/APP + fxsave (%edx) + fninit + fwait +/NO_APP + movl $8064, -8(%ebp) + movl $0, -4(%ebp) +/APP + ldmxcsr -8(%ebp) + movl %cr0,%edx +/NO_APP + movl %edx, 8(%ecx) + leave + ret + .size oss_fp_save, .-oss_fp_save +.globl oss_fp_restore + .type oss_fp_restore, @function +oss_fp_restore: + pushl %ebp + movl %esp, %ebp + movl 12(%ebp), %edx +/APP + fwait +/NO_APP + movl 8(%ebp), %ecx +/APP + fxrstor (%ecx) +/NO_APP + movl (%edx), %ecx +/APP + movl %ecx,%cr0 +/NO_APP + movl 4(%edx), %ecx +/APP + movl %ecx,%cr4 +/NO_APP + popl %ebp + ret + .size oss_fp_restore, .-oss_fp_restore diff --git a/setup/SCO_SV/i.drvcfg b/setup/SCO_SV/i.drvcfg new file mode 100644 index 0000000..f93f876 --- /dev/null +++ b/setup/SCO_SV/i.drvcfg @@ -0,0 +1,12 @@ +#!/bin/sh +# +# Copyright (c) 2005-2006 4Front Technologies +# + +while read src dest +do + if [ ! -f $dest ] ; then + cp $src $dest + fi +done +exit 0 diff --git a/setup/SCO_SV/llasgmul.o b/setup/SCO_SV/llasgmul.o Binary files differnew file mode 100644 index 0000000..68af379 --- /dev/null +++ b/setup/SCO_SV/llasgmul.o diff --git a/setup/SCO_SV/lldivrem.o b/setup/SCO_SV/lldivrem.o Binary files differnew file mode 100644 index 0000000..9cf7d20 --- /dev/null +++ b/setup/SCO_SV/lldivrem.o diff --git a/setup/SCO_SV/llmul.o b/setup/SCO_SV/llmul.o Binary files differnew file mode 100644 index 0000000..d7a8218 --- /dev/null +++ b/setup/SCO_SV/llmul.o diff --git a/setup/SCO_SV/make.local b/setup/SCO_SV/make.local new file mode 100644 index 0000000..eedb911 --- /dev/null +++ b/setup/SCO_SV/make.local @@ -0,0 +1,15 @@ +build: kernel/framework/include/buildid.h all + sh build.sh + +copy: build + cp -R prototype/* / + +package: build + sh setup/SCO_SV/mkpkg.sh + +tarball: build + sh setup/SCO_SV/mktarball.sh + +install: copy + cd ${OSSLIBDIR}/build && sh install.sh + sync && soundoff && sync && soundon && echo "OSS has started OK" diff --git a/setup/SCO_SV/mkoss.sh b/setup/SCO_SV/mkoss.sh new file mode 100755 index 0000000..63adcb1 --- /dev/null +++ b/setup/SCO_SV/mkoss.sh @@ -0,0 +1,96 @@ +#!/usr/bin/ksh + +BASEDIR=`pwd` +PKGDIR=$BASEDIR/combpkg +UW7DIR=$BASEDIR/oss-4.0-uw7.BUILD +OSR6DIR=$BASEDIR/oss-4.0-osr6.BUILD +COMBDIR=$BASEDIR/oss-4.0-comb +ARCHFILES="/usr/bin/ossxmix" +SETUPDIR=$COMBDIR/setup + +# We must do this on a UW7 machine to redo the manual pages properly +if [ "`uname -s`" != "UnixWare" ]; then + echo "Error: the combined build must be done on a UnixWare 7 machine!" + exit 1 +fi + +# Make sure we have the built directories in place +if [ ! -d $UW7DIR ]; then + echo "Error: you must have a build $UW7DIR directory installed!" + exit 1 +fi +if [ ! -d $OSR6DIR ]; then + echo "Error: you must have a build $OSR6DIR directory installed!" + exit 1 +fi + +# +# Recreate the combined directory +# +rm -rf $COMBDIR +mkdir $COMBDIR + +# Copy the OSR6 files +cd $OSR6DIR +find prototype | cpio -pdumvL $COMBDIR + +# Rename OSR6/copy UW7 files which are OS dependent +for file in $ARCHFILES +do + mv $COMBDIR/prototype/$file $COMBDIR/prototype/$file.osr6 + cp $UW7DIR/prototype/$file $COMBDIR/prototype/$file.uw7 +done + +# Use the UW7 manual pages, which have the right format +rm -rf $COMBDIR/prototype/usr/man/* +cp -r $UW7DIR/prototype/usr/man/* $COMBDIR/prototype/usr/man + +# Recreate the manual pages as plain installable text files +MANPATH=$COMBDIR/prototype/usr/man; export MANPATH +cd $MANPATH +find * -print | while read file +do + mfile=${file#man[1-9]/} + if [ "$file" != "$mfile" ]; then + mfile=${mfile%\.[1-9]} + man $mfile - > /dev/null + else + # Rename the directory the correct way + sect=${file#man} + mv $MANPATH/$file $MANPATH/man.$sect + fi +done +rm -rf $MANPATH/man.[0-9] + +# Copy the packaging files +rm -rf $SETUPDIR +mkdir $SETUPDIR +while read file +do + cp $OSR6DIR/setup/SCO_SV/$file $SETUPDIR +done <<!EOF + mkpkg.sh + S89oss + SCO_EULA + i.drvcfg + pkgdepend + pkginfo + postinstall + postremove + preremove + r.drvcfg +!EOF + +# Copy the new/modified packaging files +cd $PKGDIR +find * -print | cpio -pdumvL $SETUPDIR + +# Create a version file +grep "define OSS_VERSION_ID" $OSR6DIR/kernel/framework/include/oss_version.h|sed 's/.*_ID "/v/'|sed 's/"//' > $COMBDIR/.version + +# Copy the buildid file +cp $OSR6DIR/buildid.dat $COMBDIR + +# Run the mkpkg.sh to create the final package +cd $COMBDIR +./setup/mkpkg.sh diff --git a/setup/SCO_SV/mkpkg.sh b/setup/SCO_SV/mkpkg.sh new file mode 100644 index 0000000..86d2c2a --- /dev/null +++ b/setup/SCO_SV/mkpkg.sh @@ -0,0 +1,76 @@ +#!/bin/sh +if test "`uname -s`" = "UnixWare" +then + OS=unixware +else + OS=osr6 +fi + +ARCH=i386 + +PKG=oss + +VERSION=`sh showversion.sh` +BUILDID=`cat ./buildid.dat` +PKGVERSION=$VERSION-$BUILDID +PKGFILE=$PKG-$OS-$PKGVERSION-$ARCH.pkg +TOPDIR=`pwd` +# Setup the scripts +echo "CLASSES=none drvcfg" > ./setup/SCO_SV/pkginfo +echo "BASEDIR=/" >> ./setup/SCO_SV/pkginfo +echo "PKG=$PKG" >> ./setup/SCO_SV/pkginfo +echo "NAME=Open Sound System" >> ./setup/SCO_SV/pkginfo +echo "VERSION=$PKGVERSION" >> ./setup/SCO_SV/pkginfo +echo "CATEGORY=driver" >> ./setup/SCO_SV/pkginfo +echo "DESC=Open Sound System for SCO $OS" >> ./setup/SCO_SV/pkginfo +echo "ARCH=$ARCH" >> ./setup/SCO_SV/pkginfo +echo "VENDOR=4Front Technologies" >> ./setup/SCO_SV/pkginfo +echo "HOTLINE=+1 (310) 202 8530" >> ./setup/SCO_SV/pkginfo +echo "EMAIL=support@opensound.com" >> ./setup/SCO_SV/pkginfo + +echo "i pkginfo=./setup/SCO_SV/pkginfo" > /tmp/$$ +if test -f .date +then + # Open source version + echo "i copyright=./COPYING" >>/tmp/$$ +else + # Retail version + echo "i copyright=./EULA" >>/tmp/$$ +fi +echo "i depend=./setup/SCO_SV/pkgdepend" >> /tmp/$$ +echo "i postinstall=./setup/SCO_SV/postinstall" >> /tmp/$$ +echo "i preremove=./setup/SCO_SV/preremove" >> /tmp/$$ +echo "i postremove=./setup/SCO_SV/postremove" >> /tmp/$$ +echo "i i.drvcfg=./setup/SCO_SV/i.drvcfg" >> /tmp/$$ +echo "i r.drvcfg=./setup/SCO_SV/r.drvcfg" >> /tmp/$$ + +# now get a list of all the files and directories +(cd prototype; find . -type f -print |pkgproto >> /tmp/$$) +(cd prototype; find . -type l -print |pkgproto >> /tmp/$$) +(cd prototype; find usr/lib/oss -type d -print | pkgproto >> /tmp/$$) + +# now change the file type of .conf files to editable and set class to drvcfg +EXCEPTIONLIST='Space.c|userdefs' + +/bin/grep -v -E -e $EXCEPTIONLIST /tmp/$$ > proto +/bin/grep -E -e $EXCEPTIONLIST /tmp/$$ |sed -e 's/f none/e drvcfg/g' >> proto + +# Remove the temp file. +echo "removing /tmp/$$"; rm -f /tmp/$$ + +#now create the package. +pkgmk -o -d /tmp -r $TOPDIR/prototype -a $ARCH -f proto +echo package file is $PKGFILE +pkgtrans -s /tmp $PKGFILE $PKG +echo package file is $PKGFILE +mv /tmp/$PKGFILE $TOPDIR + +if test -f 4front-private/export_package.sh +then + if sh 4front-private/export_package.sh $PKGFILE . `sh showversion.sh` /tmp `uname -m` + then + exit 0 + else + exit 1 + fi +fi diff --git a/setup/SCO_SV/mktarball.sh b/setup/SCO_SV/mktarball.sh new file mode 100644 index 0000000..63e81ab --- /dev/null +++ b/setup/SCO_SV/mktarball.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +. ./.directories + +VERSION=`sh showversion.sh` +RELEASE=`cat buildid.dat` +if test "`uname -s` " = "UnixWare " +then + OSSNAME=oss-unixware +else + OSSNAME=oss-osr6 +fi + +PKGNAME=$OSSNAME-$VERSION-$RELEASE-`uname -m` + +echo building $PKGNAME.tar.Z +cp ./setup/SCO_SV/removeoss.sh prototype/$OSSLIBDIR/scripts +(cd prototype; find . -type f -print) > prototype/$OSSLIBDIR/MANIFEST +(cd prototype; tar cf - . ) | compress > $PKGNAME.tar.Z + +if test -f 4front-private/export_package.sh +then + sh 4front-private/export_package.sh $PKGNAME.tar.Z . `sh showversion.sh` /tmp `uname -m` +fi + +exit 0 diff --git a/setup/SCO_SV/oss/build/install.sh b/setup/SCO_SV/oss/build/install.sh new file mode 100755 index 0000000..3239575 --- /dev/null +++ b/setup/SCO_SV/oss/build/install.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +. /etc/oss.conf + +if test "$CONFDIR " = " " +then + CONFDIR=/etc/conf +fi + +# Remove the non-oss ICH driver before doing anything else +/etc/conf/bin/idinstall -R $CONFDIR -d ich > /dev/null 2>&1 + +# Unload previous modules +for n in `ls $OSSLIBDIR/modules|egrep -v "osscore|oss_imux"` +do + modadmin -U $n > /dev/null 2>&1 +done + +for MOD in osscore oss_imux +do + modadmin -U $MOD > /dev/null 2>&1 +done + +# (re)install osscore and oss_imux + +rm -f $OSSLIBDIR/modules/*/install.log + +for MOD in osscore oss_imux +do + cd $OSSLIBDIR/modules/$MOD + + if test ! -f Space.c + then + cp $OSSLIBDIR/space.inst/$MOD Space.c + fi + + rm -f install.log + + if /etc/conf/bin/idinstall -k -P oss -R $CONFDIR -M $MOD >> install.log 2>&1 + then + if /etc/conf/bin/idbuild -M $MOD >> install.log 2>&1 + then + echo OSS module $MOD installed OK + echo OSS module $MOD installed OK >> install.log + else + cat install.log + echo Building $MOD module failed + echo Building $MOD module failed >> install.log + exit 1 + fi + else + cat install.log + echo Failed to idinstall $MOD + echo Failed to idinstall $MOD >> install.log + exit 1 + fi + + (cd $OSSLIBDIR/conf && rm -f $MOD.conf && ln -sf ../modules/$MOD/Space.c $MOD.conf) + + installf oss $CONFDIR/sdevice.d/$MOD +done + + +# Only install the drivers we have a resmgr match for +OSSTMPFILE=/tmp/ossdetect.$$ +CDIR=`pwd` +cd $OSSLIBDIR/modules +/sbin/resmgr -p BRDID > $OSSTMPFILE +for file in */Drvmap +do + DRVR=`dirname $file` + grep "^|" $file | cut -d \| -f3 | while read BRDID + do + if [ -n "$BRDID" ]; then + while read RMBRDID + do + if [ "$BRDID" = "$RMBRDID" ]; then + echo "$DRVR" + fi + done < $OSSTMPFILE + fi + done +done | sort -u | while read DRVR +do + cd $OSSLIBDIR/modules/$DRVR + + if test ! -f Space.c + then + cp $OSSLIBDIR/../space.inst/$n Space.c + fi + + rm -f install.log + +# /etc/conf/bin/idinstall -R $CONFDIR -d $DRVR > /dev/null 2>&1 + + if /etc/conf/bin/idinstall -k -P oss -R $CONFDIR -M $DRVR >> install.log 2>&1 + then + if /etc/conf/bin/idbuild -M $DRVR >> install.log 2>&1 + then + echo OSS module $DRVR installed OK + echo OSS module $DRVR installed OK >> install.log + else + cat install.log + echo Building $DRVR module failed + echo Building $DRVR module failed >> install.log + exit 1 + fi + else + cat install.log + echo Failed to idinstall $DRVR + echo Failed to idinstall $DRVR >> install.log + exit 1 + fi + installf oss $CONFDIR/sdevice.d/$DRVR + + (cd $OSSLIBDIR/conf && rm -f $DRVR.conf && \ + ln -sf ../modules/$DRVR/Space.c $DRVR.conf) +done + +rm -f $OSSTMPFILE + +cd $CDIR + +if test -f /bin/dcu +then + /bin/dcu -S +else + /sbin/dcu -S +fi + +if test ! -f $OSSLIBDIR/etc/installed_drivers +then +echo "----------------------------------------------" + /usr/sbin/ossdetect -v +echo "----------------------------------------------" +fi +echo OSS modules installed OK diff --git a/setup/SCO_SV/oss/modules/osscore/Drvmap b/setup/SCO_SV/oss/modules/osscore/Drvmap new file mode 100644 index 0000000..498646c --- /dev/null +++ b/setup/SCO_SV/oss/modules/osscore/Drvmap @@ -0,0 +1,2 @@ +osscore|Y|N|Sound Boards|Open Sound System +|||OSS framework module diff --git a/setup/SCO_SV/oss/modules/osscore/Master b/setup/SCO_SV/oss/modules/osscore/Master new file mode 100644 index 0000000..51a7805 --- /dev/null +++ b/setup/SCO_SV/oss/modules/osscore/Master @@ -0,0 +1,4 @@ +$version 2 +$contact 4Front Technologies (http://www.opensound.com) +$interface ddi 8mp +osscore - R diff --git a/setup/SCO_SV/oss/modules/osscore/Node b/setup/SCO_SV/oss/modules/osscore/Node new file mode 100644 index 0000000..b450408 --- /dev/null +++ b/setup/SCO_SV/oss/modules/osscore/Node @@ -0,0 +1,2 @@ +$maxchan 0 +osscore osscore%i c 0 0 0 0600 diff --git a/setup/SCO_SV/oss/modules/osscore/System b/setup/SCO_SV/oss/modules/osscore/System new file mode 100644 index 0000000..2bdb086 --- /dev/null +++ b/setup/SCO_SV/oss/modules/osscore/System @@ -0,0 +1,4 @@ +* Don't edit this file manually! This information will be ignored. +* +$version 2 +osscore Y 0 5 4 0 0 0 0 0 -1 diff --git a/setup/SCO_SV/pkgdepend b/setup/SCO_SV/pkgdepend new file mode 100644 index 0000000..f3a47b4 --- /dev/null +++ b/setup/SCO_SV/pkgdepend @@ -0,0 +1,2 @@ +# using depend in packages. +X audio Audio Subsystem diff --git a/setup/SCO_SV/postinstall b/setup/SCO_SV/postinstall new file mode 100644 index 0000000..df07988 --- /dev/null +++ b/setup/SCO_SV/postinstall @@ -0,0 +1,63 @@ +#!/bin/sh + +. /etc/oss.conf + +echo "Setting up Open Sound System....please wait" + +#first remove the SCO ich driver from the system +/etc/conf/bin/idinstall -d ich > /dev/null 2>&1 + +#Remove oprhaned files left from earlier OSS installations +rm -f /dev/sequencer /dev/music +rm -f /dev/*_mixer[0-9]* +rm -f /dev/*_midi[0-9]* +rm -f /dev/*_dsp[0-9]* +rm -f /dev/dsp* +rm -f /dev/mixer* +rm -f /dev/midi* +rm -f /etc/rc3.d/S99oss + +# Unload previous modules +for n in `ls $OSSLIBDIR/modules|grep -v osscore` +do + modadmin -U $n > /dev/null 2>&1 +done + +modadmin -U osscore > /dev/null 2>&1 + +# Remove previous OSS startup files +rm -f /etc/rc3.d/S99oss /etc/init.d/oss + +# (re)install osscore + +rm -f $OSSLIBDIR/modules/*/install.log + +cd $OSSLIBDIR/modules/osscore + +cd $OSSLIBDIR/build && sh install.sh + +if test ! -f $OSSLIBDIR/etc/userdefs +then + echo "autosave_mixer yes" > $OSSLIBDIR/etc/userdefs +fi + +/usr/sbin/soundon + +echo "Adding OSS startup scripts to /etc/rc2.d and /etc/init.d" +rm -f /etc/rc2.d/S89oss /etc/init.d/oss + +cp $OSSLIBDIR/etc/S89oss /etc/init.d/oss +chmod 744 /etc/init.d/oss + +ln -s /etc/init.d/oss /etc/rc2.d/S89oss +echo "" +echo "" +echo "" +echo "" +echo Thank you for installing Open Sound System +echo You can run the osstest command to test audio playback in your system. +echo +echo It may be necessary to reboot the system before all devices get properly +echo detected by the system. + +exit 0 diff --git a/setup/SCO_SV/postremove b/setup/SCO_SV/postremove new file mode 100644 index 0000000..e5aa2ba --- /dev/null +++ b/setup/SCO_SV/postremove @@ -0,0 +1,17 @@ +#!/bin/sh +# Remove the device instances from /dev +for i in `cat /tmp/installed_drivers` +do +rm -f /dev/$i[0-9]* +done +rm -f /tmp/installed_drivers + +# Remove the device files +rm -f /dev/dsp /dev/dsp_* /dev/midi /dev/mixer +rm -f /dev/dsp[0-9]* /dev/dsp_* +rm -f /dev/mixer[0-9]* +rm -f /dev/midi[0-9][0-9]* +rm -f /dev/sndstat +rm -f /etc/rc2.d/S89oss /etc/init.d/oss +rm -rf /dev/oss +exit 0 diff --git a/setup/SCO_SV/preremove b/setup/SCO_SV/preremove new file mode 100644 index 0000000..1f37d98 --- /dev/null +++ b/setup/SCO_SV/preremove @@ -0,0 +1,15 @@ +#!/bin/sh +. /etc/oss.conf + +/usr/sbin/soundoff +cp -f $OSSLIBDIR/etc/installed_drivers /tmp/installed_drivers +(cd $OSSLIBDIR;rm -rf etc/installed_drivers etc/legacy_devices logs conf) + +# Remove the drivers - preremove will copy installed_drivers to /tmp +for n in `ls $OSSLIBDIR/modules` +do + if [ -d /etc/conf/pack.d/$n ]; then + /etc/conf/bin/idinstall -P oss -d $n > /dev/null 2>&1 + rm -f $OSSLIBDIR/modules/$n/install.log + fi +done diff --git a/setup/SCO_SV/r.drvcfg b/setup/SCO_SV/r.drvcfg new file mode 100644 index 0000000..00004b2 --- /dev/null +++ b/setup/SCO_SV/r.drvcfg @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (c) 2005 by 4Front Technologies +# All rights reserved. +# +# + +if test "`uname -s`" = "UnixWare" +then +PKGCHK=/usr/sbin/pkgchk +else +PKGCHK=/bin/pkgchk +fi + +while read src +do + if [ -f $src ] + then + if $PKGCHK -p $src + then + rm -f $src + else + echo "not removing $src" + fi + fi +done +exit 0 diff --git a/setup/SCO_SV/removeoss.sh b/setup/SCO_SV/removeoss.sh new file mode 100644 index 0000000..ad5eb98 --- /dev/null +++ b/setup/SCO_SV/removeoss.sh @@ -0,0 +1,36 @@ +#!/bin/bash +if test `whoami` != "root" +then + echo "You must be super-user or logged in as root to uninstall OSS..." + exit 0 +fi + +echo "Uninstalling OSS...." +echo "Running soundoff...." +/usr/sbin/soundoff + +echo Uninstalling OSS modules +cp -f $OSSLIBDIR/etc/installed_drivers /tmp/installed_drivers +(cd $OSSLIBDIR;rm -rf etc/installed_drivers etc/legacy_devices logs conf) + +# Remove the drivers - preremove will copy installed_drivers to /tmp +for n in `ls $OSSLIBDIR/modules` +do + if [ -d /etc/conf/pack.d/$n ]; then + /etc/conf/bin/idinstall -P oss -d $n > /dev/null 2>&1 + rm -f $OSSLIBDIR/modules/$n/install.log + fi +done + +echo "Removing OSS Files in MANIFEST" +cd / +for i in `cat /usr/lib/oss/MANIFEST` +do +# echo "Removing file $i" +rm -f $i +done + +echo "Removing /usr/lib/oss directory" +rm -rf /usr/lib/oss + +echo "OSS Uninstalled. However you may need reboot the system." diff --git a/setup/SCO_SV/sbin/soundoff b/setup/SCO_SV/sbin/soundoff new file mode 100755 index 0000000..2196ab6 --- /dev/null +++ b/setup/SCO_SV/sbin/soundoff @@ -0,0 +1,41 @@ +#!/bin/sh + +. /etc/oss.conf + +if /sbin/modadmin -Q osscore >> /dev/null 2>&1 +then + OK=1 +else + echo OSS not loaded. + exit 0 +fi + +if test ! -f $OSSLIBDIR/etc/installed_drivers +then + echo $OSSLIBDIR/etc/installed_drivers is missing. + exit 1 +fi + +# Save mixer settings automatically if requested +if test -f $OSSLIBDIR/etc/userdefs && /usr/bin/grep -q "autosave_mixer yes" $OSSLIBDIR/etc/userdefs +then + /usr/sbin/savemixer +fi + +for n in `cat $OSSLIBDIR/etc/installed_drivers | sed 's/#.*//'` +do + /sbin/modadmin -U $n > /dev/null 2>&1 +done + +/sbin/modadmin -U osscore > /dev/null 2>&1 + +if /sbin/modadmin -Q osscore >> /dev/null 2>&1 +then + OK=1 +else + exit 0 +fi + +echo Cannot unload the OSS driver modules + +exit 0 diff --git a/setup/SCO_SV/sbin/soundon b/setup/SCO_SV/sbin/soundon new file mode 100755 index 0000000..923c953 --- /dev/null +++ b/setup/SCO_SV/sbin/soundon @@ -0,0 +1,133 @@ +#!/bin/sh + +. /etc/oss.conf + +if test -f $OSSLIBDIR/starting +then + echo Previous start of OSS crashed the system + echo Please resolve the situation and remove file + echo \"$OSSLIBDIR/starting\". Then start OSS by + echo running soundon again. + exit 1 +fi + +if /sbin/modadmin -Q osscore >> /dev/null 2>&1 +then + echo Open Sound System is already running + exit 0 +fi + +LOG=$OSSLIBDIR/logs/soundon.log + +touch $OSSLIBDIR/starting +sync + +echo "Open Sound System starting" `date` > $LOG +echo "OSS version: " `cat $OSSLIBDIR/version.dat` >> $LOG 2>&1 +echo "Kernel version: " `uname -a` >> $LOG + +if test ! -f $OSSLIBDIR/etc/installed_drivers +then + echo No $OSSLIBDIR/etc/installed_drivers >> $LOG + echo No $OSSLIBDIR/etc/installed_drivers + echo Please run ossdetect to create it. + exit 1 +fi + +if test ! -f /etc/conf/mod.d/osscore +then + echo No $OSSLIBDIR/modules/osscore module >> $LOG + echo No $OSSLIBDIR/modules/osscore module + exit 2 +fi + +if test -f $OSSLIBDIR/etc/license.asc +then + /usr/sbin/ossdetect -l >> $LOG +fi + +if /sbin/modadmin -l osscore >> $LOG 2>&1 +then + OK=1 +else + echo Loading the osscore module failed + echo Loading the osscore module failed >> $LOG + + echo "+++ Kernel messages +++" >> $LOG + # This may look fatal but in fact it's not. The panic command + # of the crash utility just prints the panic buffer (latest kernel messages). + echo panic|/usr/sbin/crash >> $LOG + + exit 4 +fi + +for n in `cat $OSSLIBDIR/etc/installed_drivers | sed 's/#.*//'` +do + if /sbin/modadmin -l $n >> $LOG 2>&1 + then + OK=1 + else + echo Loading module $n failed '-' ignored >> $LOG + echo Loading module $n failed '-' ignored + fi +done + +echo "+++ Kernel messages +++" >> $LOG +# This may look fatal but in fact it's not. The panic command +# of the crash utility just prints the panic buffer (latest kernel messages). +echo panic|/usr/sbin/crash >> $LOG + +/usr/sbin/ossdetect -d >> $LOG 2>&1 + +# Restore the previous legacy device links +if test -f $OSSLIBDIR/etc/legacy_devices +then + sh $OSSLIBDIR/etc/legacy_devices >> $LOG 2>&1 +fi + +/usr/sbin/ossdevlinks -v >> $LOG 2>&1 + +echo "+++ ossinfo -v3 +++" >> $LOG +ossinfo -v3 >> $LOG 2>&1 + +echo "+++ /dev/sndstat +++" >> $LOG +cat /dev/sndstat >> $LOG 2>&1 + +echo "+++ pciconf +++" >> $LOG +echo pcilong|/usr/sbin/ndcfg -q >> $LOG 2>&1 +echo "+++ OSS devices +++" >> $LOG +ls -l /dev/*dsp* /dev/*_pcm* /dev/*mixer* /dev/*_mix* /dev/*midi* /dev/*_mid* >> $LOG 2>&1 + +/usr/sbin/savemixer -L >> $LOG 2>&1 + +if test -x $OSSLIBDIR/soundon.user +then + echo Running $OSSLIBDIR/soundon.user >> $LOG + $OSSLIBDIR/soundon.user >> $LOG 2>&1 +fi + +if test "`ossinfo -g|grep TRIAL` " != " " +then + echo + echo "************************************************************" + echo "* NOTE! You are using trial version of Open Sound System *" + echo "************************************************************" + echo + + sleep 1 +fi + +if test "`ossinfo -g|grep EXPIRED` " != " " +then + echo + echo "****************************************************************" + echo "* NOTE! Your Open Sound System evaluation license has expired *" + echo "****************************************************************" + echo + + sleep 15 +fi + +rm -f $OSSLIBDIR/starting + +exit 0 diff --git a/setup/SunOS/.changelog b/setup/SunOS/.changelog new file mode 100644 index 0000000..4cd902c --- /dev/null +++ b/setup/SunOS/.changelog @@ -0,0 +1 @@ +010814 by Dev Mazumdar: Added forceload.conf in build.sh so that USB driver loads. diff --git a/setup/SunOS/S89oss b/setup/SunOS/S89oss new file mode 100644 index 0000000..eaff504 --- /dev/null +++ b/setup/SunOS/S89oss @@ -0,0 +1,37 @@ +#!/bin/sh +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +########## +# +# The first argument tells what to do. +########## + +state=$1 + +if test -f /etc/oss.conf +then +. /etc/oss.conf +else + OSSLIBDIR=$OSSLIBDIR +fi + +case $state in + +'start') + soundoff + soundon + exit 0 + ;; +'stop') + /usr/sbin/savemixer > /dev/null 2>&1 + exit 0 + ;; +esac + +exit 1 + diff --git a/setup/SunOS/__xtol-i86pc-i386.s b/setup/SunOS/__xtol-i86pc-i386.s new file mode 100644 index 0000000..eebc94a --- /dev/null +++ b/setup/SunOS/__xtol-i86pc-i386.s @@ -0,0 +1,24 @@ +.file "__xtol-i86pc-i386.s" +.text +.globl __xtol + .type __xtol, @function +__xtol: + subl $0x8,%esp + fnstcw 0x2(%esp) + movw 0x2(%esp),%ax + movw %ax,%cx + andw $0xc00,%cx + orw $0xc00,%ax + movw %ax,0x0(%esp) + fldcw 0x0(%esp) + fistpl 0x4(%esp) + fstcw 0x0(%esp) + movw 0x0(%esp),%ax + andw $0xf3ff,%ax + orw %cx,%ax + movw %ax,0x0(%esp) + fldcw 0x0(%esp) + movl 0x4(%esp),%eax + addl $0x8,%esp + ret + .size __xtol, .-__xtol diff --git a/setup/SunOS/build.sh b/setup/SunOS/build.sh new file mode 100644 index 0000000..881ffa3 --- /dev/null +++ b/setup/SunOS/build.sh @@ -0,0 +1,291 @@ + +. ./.directories + +OSSLIBDIR=/usr/lib/oss + +if test "`which gawk|grep 'no gawk in '` " = " " 2>/dev/null +then + TXT2MAN=$SRCDIR/setup/txt2man +else + cc -o txt2man origdir/setup/txt2man.c + TXT2MAN=./txt2man +fi + +if test "`uname -p`" = "sparc" +then + KERNEL32=sparc + KERNEL64=sparcv9 + MACH=sun4u +else + case `uname -r` in + "5.8") + KERNEL32=i386 + KERNEL64=NULL + ;; + "5.9") + KERNEL32=i386 + KERNEL64=NULL + ;; + *) + KERNEL32=i386 + KERNEL64=amd64 + ;; + esac + MACH=i86pc +fi + +if test "`uname -r`" = "5.9" || test "`uname -r`" = "5.8" +then + AMSRC=amsrc1 + OSFLAGS=-DSOL9 +else + AMSRC=amsrc2 +fi + +# Re-create the prototype directory +rm -rf prototype + +mkdir prototype +mkdir prototype/kernel +mkdir prototype/kernel/drv +mkdir prototype/kernel/drv/$KERNEL64 +mkdir prototype/kernel/misc +mkdir prototype/kernel/misc/$KERNEL64 + +mkdir prototype/etc +mkdir prototype/etc/oss +mkdir prototype/etc/init.d +mkdir prototype/usr +mkdir prototype/usr/bin +mkdir prototype/usr/sbin +mkdir prototype/usr/man +mkdir prototype/usr/man/man1 +mkdir prototype/usr/man/man1m +mkdir prototype/usr/man/man7d +mkdir prototype/usr/include +mkdir prototype/usr/include/sys +mkdir prototype/usr/include/oss +mkdir prototype/usr/lib +mkdir prototype/usr/lib/oss + +cat > prototype/usr/lib/oss/README <<EOF +This directory is not used any more. Configuration files for OSS are +located under /etc/oss. The soundon.log file is located in +/var/log/soundon.log. +EOF + +cp $KERNEL32/.version prototype/etc/oss/version.dat + +# Copy the files to their right place + +cp $SRCDIR/include/soundcard.h prototype/usr/include/sys +cp $SRCDIR/include/oss_userdev_exports.h prototype/usr/include/oss +(cd $KERNEL32/target/bin; rm -f ossrecord; ln -s ossplay ossrecord) +cp $KERNEL32/target/bin/* prototype/usr/bin +cp $KERNEL32/target/sbin/* prototype/usr/sbin +cp $KERNEL32/setup/SunOS/sbin/* prototype/usr/sbin +cp origdir/setup/SunOS/S89oss prototype/etc/init.d/oss +chmod 500 prototype/usr/sbin/* +echo "autosave_mixer yes" > prototype/etc/oss/userdefs +#echo "usbif,class1" > prototype/etc/oss/forceload.conf +rm -f devlist.txt + +# Create the driver modules (for 64 bit) + +if test "`ls $KERNEL64/target/modules/*.o 2>/dev/null` " != " " +then + # osscommon + if ld -64 -dy -r -Nmisc/usba -o prototype/kernel/misc/$KERNEL64/osscommon $KERNEL64/target/objects/*.o + then + $TXT2MAN -v "OSS Devices" -s 7 $KERNEL64/kernel/drv/osscore/osscore.man > prototype/usr/man/man7d/osscore.7d + else + exit 1 + fi + + rm -f fpsupport.o + + # Man pages + for n in $SRCDIR/misc/man7/*.man + do + N=`basename $n .man` + $TXT2MAN -t "$CMD" -v "OSS Devices" -s 7 $n > prototype/usr/man/man7d/$N.7d + done + + for n in $SRCDIR/misc/man1m/*.man + do + N=`basename $n .man` + $TXT2MAN -t "$CMD" -v "OSS System Administration Commands" -s 1 $n > prototype/usr/man/man1m/$N.1m + done + + # Other modules for 64bit kernel + for n in $KERNEL64/target/modules/*.o + do + N=`basename $n .o` + if ld -64 -dy -r -Nmisc/osscommon -o prototype/kernel/drv/$KERNEL64/$N $n + then + OK=1 + else + exit 1 + fi + + if test $KERNEL64 = "sparcv9" + then + grep "^$N[ ]" $KERNEL64/devices.list >> devlist.txt + fi + done + + # USB Module + if test -f $KERNEL64/target/modules/oss_usb.o + then + if ld -64 -dy -r -Nmisc/osscommon -Nmisc/usba -o prototype/kernel/drv/$KERNEL64/oss_usb $KERNEL64/target/modules/oss_usb.o + then + OK=1 + else + exit 1 + fi + fi + + # SADA compatibility module + if test -r $KERNEL64/target/modules/oss_sadasupport.o + then + if ld -64 -dy -r -Nmisc/osscommon -Nmisc/$AMSRC -Nmisc/audiosup -Nmisc/mixer -o prototype/kernel/drv/$KERNEL64/oss_sadasupport $KERNEL64/target/modules/oss_sadasupport.o + then + OK=1 + else + exit 1 + fi + else + OK=1 + fi +fi # 64 bit modules done + +# Handle 32 bit modules + +if test "`ls $KERNEL32/target/modules/*.o 2>/dev/null` " != " " +then + + # osscommon + + if ld -dy -r -Nmisc/usba -o prototype/kernel/misc/osscommon $KERNEL32/target/objects/*.o + then + $TXT2MAN -v "OSS Devices" -s 7 $KERNEL32/kernel/drv/osscore/osscore.man > prototype/usr/man/man7d/osscore.7d + else + exit 1 + fi + + rm -f fpsupport.o __xtol.o + + # Other modules for 32bit kernel + for n in $KERNEL32/target/modules/*.o + do + N=`basename $n .o` + if ld -dy -r -Nmisc/osscommon -o prototype/kernel/drv/$N $n + then + OK=1 + else + exit 1 + fi + grep "^$N[ ]" $KERNEL32/devices.list >> devlist.txt + done + + # USB Modules + if test -f $KERNEL32/target/modules/oss_usb.o + then + if ld -dy -r -Nmisc/osscommon -Nmisc/usba -o prototype/kernel/drv/oss_usb $KERNEL32/target/modules/oss_usb.o + then + OK=1 + else + exit 1 + fi + fi + + # SADA Compatibility + if test -r $KERNEL32/target/modules/oss_sadasupport.o + then + if ld -dy -r -Nmisc/osscommon -Nmisc/$AMSRC -Nmisc/audiosup -Nmisc/mixer -o prototype/kernel/drv/oss_sadasupport $KERNEL32/target/modules/oss_sadasupport.o + then + OK=1 + else + exit 1 + fi + else + OK=1 + fi + +fi # 32 bit modules done + +if test "$KERNEL64 " = "sparcv9 " +then + # Drop SB Live! from the list of supported devices for Sparc + rm -f tmplist + mv devlist.txt tmplist + grep -v "Sound Blaster Live" < tmplist|sort|uniq >devlist.txt + rm -f tmplist +fi + +cp devlist.txt prototype/etc/oss/devices.list + +if test -d $KERNEL32/kernel/nonfree +then + cp -f devlist.txt $KERNEL32/origdir/devlists/Solaris-`uname -p` +fi + +# Generate the config files +rm -f confgen +cc -o confgen -DTXT2MAN=\"$TXT2MAN\" $OSFLAGS $KERNEL32/setup/SunOS/confgen.c + +./confgen prototype/kernel/drv \\/kernel\\/drv $KERNEL32/kernel/drv/* $KERNEL32/kernel/nonfree/drv/* $KERNEL32/kernel/framework/* +rm -f confgen + +# Generate Man pages for user commands +for i in $KERNEL32/target/bin/* +do + CMD=`basename $i` + $TXT2MAN -t "$CMD" -v "OSS User Commands" -s 1 $KERNEL32/cmd/$CMD/$CMD.man > prototype/usr/man/man1/$CMD.1 + echo done $CMD +done + +# Generate Man pages for system commands +for i in $KERNEL32/target/sbin/* +do + CMD=`basename $i` + if test -f $KERNEL32/cmd/$CMD/$CMD.man + then + $TXT2MAN -t "$CMD" -v "OSS System Administration Commands" -s 1m $KERNEL32/cmd/$CMD/$CMD.man > prototype/usr/man/man1m/$CMD.1m + echo done $CMD + fi +done + +# Generate pages for Maintenance Commands +rm -f prototype/usr/man/man1m/ossdetect.1m +$TXT2MAN -t "ossdetect" -v "OSS User Commands" -s 1m $KERNEL32/os_cmd/SunOS/ossdetect/ossdetect.man > prototype/usr/man/man1m/ossdetect.1m +echo done ossdetect + +# Licensing stuff +if test -f $KERNEL32/4front-private/osslic.c +then + cc $OSFLAGS -o prototype/usr/sbin/osslic -I$KERNEL32/setup -I$KERNEL32/kernel/nonfree/include -I$KERNEL32/kernel/framework/include -I$KERNEL32/include -I$KERNEL32/kernel/OS/SunOS $KERNEL32/4front-private/osslic.c + strip prototype/usr/sbin/osslic + + if test -f prototype/kernel/misc/osscommon + then + prototype/usr/sbin/osslic -q -u -3prototype/kernel/misc/osscommon + fi + + if test -f prototype/kernel/misc/$KERNEL64/osscommon + then + prototype/usr/sbin/osslic -q -u -6prototype/kernel/misc/$KERNEL64/osscommon + fi +fi + +if test -f $KERNEL32/4front-private/ossupdate.c +then + # ossupdate + cc -I$KERNEL32 $KERNEL32/4front-private/ossupdate.c -s -o prototype/usr/sbin/ossupdate -lsocket -lnsl +fi + +sh $SRCDIR/setup/build_common.sh $SRCDIR $OSSLIBDIR + +rm -f $OSSLIBDIR/oss/ + +exit 0 diff --git a/setup/SunOS/confgen.c b/setup/SunOS/confgen.c new file mode 100644 index 0000000..61ac776 --- /dev/null +++ b/setup/SunOS/confgen.c @@ -0,0 +1,221 @@ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <libgen.h> +#include <sys/stat.h> + +char *targetdir = ""; +char *confpath = ""; + +static void +copy_parms (FILE * f, FILE * conf) +{ + char line[1024], *s, *p; + char var[256] = "", comment[64 * 1024] = ""; + int i; + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + for (i = 0; i < strlen (line); i++) + if (line[i] == '\n') + line[i] = 0; + + s = line; + + while (*s == ' ' || *s == '\t') + s++; + if (strncmp (s, "int ", 4) == 0) + { + if (*var != 0) + { + fprintf (conf, "%s\n", comment); + if (*var != 0) + fprintf (conf, "%s\n", var); + *var = 0; + *comment = 0; + } + s += 4; + + for (i = 0; i < strlen (line); i++) + if (line[i] == ';') + line[i] = 0; + strcpy (var, s); + continue; + } + + + s = line; + + while (*s == ' ' || *s == '\t' || *s == '/' || *s == '*') + s++; + + strcat (comment, "\n# "); + strcat (comment, s); + } + + if (*var != 0) + { + fprintf (conf, "%s\n", comment); + fprintf (conf, "%s\n", var); + } +} + +static void +scan_dir (char *srcdir, char *module) +{ + char confname[256], tmp[256], line[1024], syscmd[255]; + FILE *conf; + FILE *f; + int i; + struct stat st; + + int is_pci = 1; + int check_platform = 0; + int platform_ok = 0; + + if (stat (srcdir, &st) == -1) + { + // perror("stat"); + // fprintf(stderr, "confgen: Cannot access %s\n", srcdir); + return; + } + + if (!S_ISDIR (st.st_mode)) /* Not a directory? */ + { + // fprintf(stderr, "confgen: %s is not a directory\n", srcdir); + return; + } + + sprintf (tmp, "%s/.nomake", srcdir); + if (stat (tmp, &st) != -1) /* File exists */ + return; /* Skip this one */ + + sprintf (tmp, "%s/.config", srcdir); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + char *s; + for (i = 0; i < strlen (line); i++) + if (line[i] == '\n') + line[i] = 0; + + s = line; + while (*s && *s != '=') + s++; + if (*s == '=') + *s++ = 0; + + if (strcmp (line, "bus") == 0) + { + if (strcmp (s, "PCI") != 0) + is_pci = 0; + continue; + } + + if (strcmp (line, "platform") == 0) + { + check_platform = 1; +#ifdef sparc + if (strcmp (s, "sparc") == 0) + platform_ok = 1; +#endif + +#ifdef i386 + if (strcmp (s, "i86pc") == 0) + platform_ok = 1; +#endif + continue; + } + } + fclose (f); + } +#if 0 + else + perror (tmp); +#endif + + if (check_platform && !platform_ok) + { + return; + } + + /* generate the man pages */ + + sprintf (tmp, "%s/%s.man", srcdir, module); + if (stat (tmp, &st) != 0) /* Man File doesn't exist */ + goto no_manual; /* Skip this one */ + + sprintf (syscmd, "sed 's/CONFIGFILEPATH/%s/' < %s/%s.man > /tmp/ossman.man", + confpath, srcdir, module); + //printf ("%s\n", syscmd); + unlink ("/tmp/ossman.man"); + system (syscmd); + + sprintf (syscmd, + TXT2MAN + " -t \"%s\" -v \"Devices\" -s 7d /tmp/ossman.man > prototype/usr/man/man7d/%s.7d", + module, module); + //printf ("%s\n", syscmd); + system (syscmd); + +no_manual: + sprintf (confname, "%s/%s.conf", targetdir, module); + + if ((conf = fopen (confname, "w")) == NULL) + { + perror (confname); + exit (-1); + } + + fprintf (conf, "# Open Sound System configuration file\n"); + + if (is_pci) + fprintf (conf, + "# Please consult the documentation before changing\n# interrupt-priorities\ninterrupt-priorities=9 "); + else + fprintf (conf, "name=\"%s\" parent=\"pseudo\" instance=0 ", module); + + fprintf (conf, "ddi-no-autodetach=1 ddi-forceattach=1 \n"); + + sprintf (tmp, "%s/.params", srcdir); + if ((f = fopen (tmp, "r")) != NULL) + { + copy_parms (f, conf); + fclose (f); + } + + fprintf (conf, ";\n"); + fclose (conf); +} + +int +main (int argc, char *argv[]) +{ + int i; + + if (argc < 3) + exit (-1); + + targetdir = argv[1]; + confpath = argv[2]; + + for (i = 3; i < argc; i++) + { + scan_dir (argv[i], basename (argv[i])); + } + + exit (0); +} diff --git a/setup/SunOS/i.drvcfg b/setup/SunOS/i.drvcfg new file mode 100644 index 0000000..05dfcf0 --- /dev/null +++ b/setup/SunOS/i.drvcfg @@ -0,0 +1,12 @@ +#!/bin/sh +# +# Copyright (c) 2005 4Fronte Technologies +# + +while read src dest +do + if [ ! -f $dest ] ; then + mv $src $dest + fi +done +exit 0 diff --git a/setup/SunOS/mkpkg.sh b/setup/SunOS/mkpkg.sh new file mode 100644 index 0000000..5c43694 --- /dev/null +++ b/setup/SunOS/mkpkg.sh @@ -0,0 +1,83 @@ +#!/usr/bin/bash +case `uname -r` in + "5.6") OS=solaris6 + REL=6 + ;; + "5.7") OS=solaris7 + REL=7 + ;; + "5.8") OS=solaris8 + REL=8 + ;; + "5.9") OS=solaris9 + REL=9 + ;; + *) OS=solaris + REL=10 + ;; +esac + +ARCH=`uname -p` +PKG=oss +VERSION=`sh $ARCH/showversion.sh` +BUILDID=`cat $ARCH/buildid.dat` +PKGVERSION=$VERSION-$BUILDID +PKGFILE=$PKG-$OS-$PKGVERSION-$ARCH.pkg +# Setup the scripts +echo "CLASSES=none drvcfg" > $ARCH/setup/SunOS/pkginfo +echo "BASEDIR=/" >> $ARCH/setup/SunOS/pkginfo +echo "TZ=PST" >> $ARCH/setup/SunOS/pkginfo +echo "PKG=$PKG" >> $ARCH/setup/SunOS/pkginfo +echo "PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin" >> $ARCH/setup/SunOS/pkginfo +echo "NAME=Open Sound System" >> $ARCH/setup/SunOS/pkginfo +echo "VERSION=$PKGVERSION" >> $ARCH/setup/SunOS/pkginfo +echo "CATEGORY=driver" >> $ARCH/setup/SunOS/pkginfo +echo "DESC=Open Sound System for Solaris $ARCH" >> $ARCH/setup/SunOS/pkginfo +echo "ARCH=$ARCH" >> $ARCH/setup/SunOS/pkginfo +echo "VENDOR=4Front Technologies" >> $ARCH/setup/SunOS/pkginfo +echo "HOTLINE=+1 (310) 202 8530" >> $ARCH/setup/SunOS/pkginfo +echo "EMAIL=support@opensound.com" >> $ARCH/setup/SunOS/pkginfo +echo "VSTOCK=" >> $ARCH/setup/SunOS/pkginfo +echo "PSTAMP=" >> $ARCH/setup/SunOS/pkginfo +echo "PKGINST=oss" >> $ARCH/setup/SunOS/pkginfo +echo "PKGSAV=/var/sadm/pkg/OSS/save" >> $ARCH/setup/SunOS/pkginfo +echo "INSTDATE=" >> $ARCH/setup/SunOS/pkginfo + +echo "i pkginfo=$ARCH/setup/SunOS/pkginfo" > /tmp/$$ +if test -f $ARCH/.date +then + # Open source version + echo "i copyright=$ARCH/COPYING" >> /tmp/$$ +else + # Retail version + echo "i copyright=$ARCH/EULA" >> /tmp/$$ +fi +echo "i postinstall=$ARCH/setup/SunOS/postinstall" >> /tmp/$$ +echo "i preremove=$ARCH/setup/SunOS/preremove" >>/tmp/$$ +echo "i postremove=$ARCH/setup/SunOS/postremove" >>/tmp/$$ +echo "i i.drvcfg=$ARCH/setup/SunOS/i.drvcfg" >>/tmp/$$ +echo "i r.drvcfg=$ARCH/setup/SunOS/r.drvcfg" >>/tmp/$$ + +# now get a list of all the files and directories +(cd prototype; find . -type f -print |pkgproto >> /tmp/$$) +(cd prototype; find . -type l -print |pkgproto >> /tmp/$$) + +# now change the file type of .conf files to editable and set class to drvcfg +EXCEPTIONLIST='.conf|userdefs' + +/usr/xpg4/bin/grep -v -E -e $EXCEPTIONLIST /tmp/$$ > proto +/usr/xpg4/bin/grep -E -e $EXCEPTIONLIST /tmp/$$ |sed -e 's/f none/e drvcfg/g' >> proto + +# Remove the temp file. +echo "removing /tmp/$$"; rm -f /tmp/$$ + +#now create the package. +pkgmk -o -d /tmp -r prototype -a $ARCH -f proto +touch $PKGFILE +pkgtrans -s /tmp $PKGFILE $PKG +echo package file is $PKGFILE + +if test -f $ARCH/4front-private/export_package.sh +then + sh $ARCH/4front-private/export_package.sh $PKGFILE $ARCH `sh $ARCH/showversion.sh` /tmp $ARCH-$REL +fi diff --git a/setup/SunOS/oss.xml b/setup/SunOS/oss.xml new file mode 100755 index 0000000..c8cafee --- /dev/null +++ b/setup/SunOS/oss.xml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> +<service_bundle type='manifest' name='opensoundsvc'> +<service + name='system/opensound' + type='service' + version='1'> + + <create_default_instance enabled='false' /> + <single_instance/> + + <!-- No idea what sysconfig is good for, but it's in all examples --> + <dependency + name='sysconfig' + grouping='require_all' + restart_on='none' + type='service'> + <service_fmri value='svc:/milestone/sysconfig' /> + </dependency> + + <!-- Require local filesystems to be present --> + <dependency + name='fslocal' + grouping='require_all' + restart_on='none' + type='service'> + <service_fmri value='svc:/system/filesystem/local:default' /> + </dependency> + + <exec_method + type='method' + name='start' + exec='/lib/svc/method/svc-oss start' + timeout_seconds='60'> + </exec_method> + + <exec_method + type='method' + name='stop' + exec='/lib/svc/method/svc-oss stop' + timeout_seconds='60'> + </exec_method> + + <!-- soundon and ossdevlinks exit, so it's a transient service --> + <property_group name='startd' type='framework'> + <propval name='duration' type='astring' value='transient' /> + </property_group> + + <stability value='Evolving' /> + <template> + <common_name> + <loctext xml:lang='C'>Open Sound System control service</loctext> + </common_name> + </template> +</service> + +</service_bundle> diff --git a/setup/SunOS/oss/scripts/install.sh b/setup/SunOS/oss/scripts/install.sh new file mode 100644 index 0000000..91ebbe6 --- /dev/null +++ b/setup/SunOS/oss/scripts/install.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +echo "Setting up Open Sound System....please wait" + +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +rm -f /etc/rc3.d/S80ossinstall # Remove temporary installer + +# Remove previous sound drivers and make a backup of the removed +# /etc/driver_aliases lines. +rem_drv oss > /dev/null 2>&1 # OSS 3.99.x and earlier +rem_drv ossaudios > /dev/null 2>&1 # Old name for sadasupport + +for n in audiocs audioens audiots audio1575 audiovia823x audiohd audio810 audioixp usb_ac usb_as +do + # Copy the /etc/driver_aliases entries for the SADA drivers to a backup + # file so that the drivers could be restored later. + grep "^$n " /etc/driver_aliases >> /usr/lib/oss/etc/driver_aliases.removed + + rem_drv $n > /dev/null 2>&1 # Remove the driver +done + +# Make sure the driver aliases collection doesn't contain duplicate lines +sort /usr/lib/oss/etc/driver_aliases.removed|uniq > /usr/lib/oss/etc/driver_aliases.bak +mv /usr/lib/oss/etc/driver_aliases.bak /usr/lib/oss/etc/driver_aliases.removed +rm -f /usr/lib/oss/etc/driver_aliases.bak + +# Remove previous OSS and SADA devices +rm -f /dev/sound/* +rm -f /dev/audio* +rm -f /dev/dsp* +rm -f /dev/mixer* +rm -f /dev/midi* +rm -f /dev/sndstat +rm -f /dev/sequencer +rm -f /dev/music + +sync + +rm -f /tmp/osspkg.tmp +grep -v type=oss_ /etc/devlink.tab > /tmp/osspkg.tmp +cat /tmp/osspkg.tmp > /etc/devlink.tab +cat >> /etc/devlink.tab <<EOF +type=oss_sysdev \M0 +type=oss_audio oss/\M1/\M2 +EOF + +if test ! -f $OSSLIBDIR/etc/userdefs +then + echo "autosave_mixer yes" > $OSSLIBDIR/etc/userdefs +fi + +if /usr/xpg4/bin/grep -q 'install_imux yes' $OSSLIBDIR/etc/userdefs +then + # Install the imux driver + /usr/sbin/ossdetect -i +else + /usr/sbin/ossdetect +fi + +/usr/sbin/devlinks +/usr/sbin/ossdevlinks + +# Symlink the config files to $OSSLIBDIR/conf +#cd $OSSLIBDIR/conf +#ARCH=`uname -m` +#for n in `grep -l 'Open Sound System configuration file' /kernel/drv/*.conf` +#do +# ln -s $n . +#done + +#echo "" +#echo "Adding OSS startup scripts to /etc/rc3.d and /etc/init.d" +#rm -f /etc/rc3.d/S89oss /etc/rc3.d/S99oss /etc/init.d/oss + +#cp $OSSLIBDIR/etc/S89oss /etc/init.d/oss +#chmod 744 /etc/init.d/oss + +#ln -s ../init.d/oss /etc/rc3.d/S89oss +#ln -s ../init.d/oss /etc/rc3.d/K89oss + +echo "" +echo "" +echo "" +echo Open Sound System installation complete +echo "" +echo You can use the osstest command to test audio playback in your system. +echo "" +echo It may be necessary to reboot the system before all devices get properly +echo detected by the system. + +exit 0 diff --git a/setup/SunOS/postinstall b/setup/SunOS/postinstall new file mode 100644 index 0000000..94e02d4 --- /dev/null +++ b/setup/SunOS/postinstall @@ -0,0 +1,101 @@ +#!/bin/bash + +echo "Setting up Open Sound System....please wait" + +rm -f ${PKG_INSTALL_ROOT}/etc/rc3.d/S80ossinstall # Remove temporary installer + +# Remove previous sound drivers and make a backup of the removed +# /etc/driver_aliases lines. +rem_drv oss > /dev/null 2>&1 # OSS 3.99.x and earlier +rem_drv ossaudios > /dev/null 2>&1 # Old name for sadasupport + +for n in `ls /kernel/drv|grep audio|grep -v .conf` usb_ac usb_as +do + echo Removing old driver $n + # Copy the /etc/driver_aliases entries for the SADA drivers to a backup + # file so that the drivers could be restored later. + grep "^$n " ${PKG_INSTALL_ROOT}/etc/driver_aliases >> ${PKG_INSTALL_ROOT}/etc/oss/driver_aliases.removed + + rem_drv $n > /dev/null 2>&1 # Remove the driver +done + +# Make sure the driver aliases collection doesn't contain duplicate lines +sort ${PKG_INSTALL_ROOT}/etc/oss/driver_aliases.removed|uniq > ${PKG_INSTALL_ROOT}/etc/oss/driver_aliases.bak +mv ${PKG_INSTALL_ROOT}/etc/oss/driver_aliases.bak ${PKG_INSTALL_ROOT}/etc/oss/driver_aliases.removed +rm -f ${PKG_INSTALL_ROOT}/etc/oss/driver_aliases.bak + +# Remove previous OSS and SADA devices +rm -f ${PKG_INSTALL_ROOT}/dev/sound/* +rm -f ${PKG_INSTALL_ROOT}/dev/audio* +rm -f ${PKG_INSTALL_ROOT}/dev/dsp* +rm -f ${PKG_INSTALL_ROOT}/dev/mixer* +rm -f ${PKG_INSTALL_ROOT}/dev/midi* +rm -f ${PKG_INSTALL_ROOT}/dev/sndstat +rm -f ${PKG_INSTALL_ROOT}/dev/sequencer +rm -f ${PKG_INSTALL_ROOT}/dev/music + +(cd ${PKG_INSTALL_ROOT}/etc/rc3.d;ln -s ../init.d/oss S89oss) + +sync + +rm -f ${PKG_INSTALL_ROOT}/tmp/osspkg.tmp +grep -v type=oss_ ${PKG_INSTALL_ROOT}/etc/devlink.tab > ${PKG_INSTALL_ROOT}/tmp/osspkg.tmp +cat ${PKG_INSTALL_ROOT}/tmp/osspkg.tmp > ${PKG_INSTALL_ROOT}/etc/devlink.tab +cat >> ${PKG_INSTALL_ROOT}/etc/devlink.tab <<EOF +type=oss_sysdev \M0 +type=oss_audio oss/\M1/\M2 +EOF + +if test ! -f ${PKG_INSTALL_ROOT}/etc/oss/userdefs +then + echo "autosave_mixer yes" > ${PKG_INSTALL_ROOT}/etc/oss/userdefs +fi + +if ${PKG_INSTALL_ROOT}/usr/xpg4/bin/grep -q 'install_imux yes' $OSSLIBDIR/etc/oss/userdefs +then + # Install the imux driver + ${PKG_INSTALL_ROOT}/usr/sbin/ossdetect -i +else + ${PKG_INSTALL_ROOT}/usr/sbin/ossdetect +fi + +${PKG_INSTALL_ROOT}/usr/sbin/devlinks +${PKG_INSTALL_ROOT}/usr/sbin/ossdevlinks + +if test "`ossinfo -g|grep TRIAL` " != " " +then + echo + echo + echo + echo "************************************************************" + echo "* NOTE! You are using trial version of Open Sound System *" + echo "************************************************************" + echo + + sleep 10 +fi + +if test "`ossinfo -g|grep EXPIRED` " != " " +then + echo + echo + echo + echo "****************************************************************" + echo "* NOTE! Your Open Sound System evaluation license has expired *" + echo "****************************************************************" + echo + + sleep 15 +fi + +echo "" +echo "" +echo "" +echo Open Sound System installation complete +echo "" +echo You can use the osstest command to test audio playback in your system. +echo "" +echo It may be necessary to reboot the system before all devices get properly +echo detected by the system. + +exit 0 diff --git a/setup/SunOS/postremove b/setup/SunOS/postremove new file mode 100644 index 0000000..0d4ed19 --- /dev/null +++ b/setup/SunOS/postremove @@ -0,0 +1,66 @@ +#! /bin/sh + +PATH="/usr/bin:/usr/sbin:${PATH}" +export PATH + +ISA_TYPE_I386="i386" +ISA_TYPE_SPARC="sparc" +ISA_TYPE="$ARCH" + +if test -f ${PKG_INSTALL_ROOT}/tmp/installed_drivers +then + for i in `cat ${PKG_INSTALL_ROOT}/tmp/installed_drivers | sed 's/ .*//'` + do + rem_drv $i + done +fi +rm -f ${PKG_INSTALL_ROOT}/tmp/installed_drivers + +# +# Unload the osscommon misc/module +# +MODULEID=`/usr/sbin/modinfo|grep " osscommon "|sed "s/^ *//"|sed "s/ .*//"` +if test " $MODULEID" != " " +then + /usr/sbin/modunload -i $MODULEID +fi + +# Remove the device files +rm -f ${PKG_INSTALL_ROOT}/dev/dsp* +rm -f ${PKG_INSTALL_ROOT}/dev/mixer* +rm -f ${PKG_INSTALL_ROOT}/dev/midi* +rm -rf ${PKG_INSTALL_ROOT}/dev/oss +rm -f ${PKG_INSTALL_ROOT}/dev/sndstat +rm -f ${PKG_INSTALL_ROOT}/dev/sequencer +rm -f ${PKG_INSTALL_ROOT}/dev/music +rm -f ${PKG_INSTALL_ROOT}/dev/sound/* +rm -f ${PKG_INSTALL_ROOT}/dev/audio +rm -f ${PKG_INSTALL_ROOT}/dev/audioctl +rm -f ${PKG_INSTALL_ROOT}/etc/rc3.d/S89oss ${PKG_INSTALL_ROOT}/etc/rc3.d/K89oss ${PKG_INSTALL_ROOT}/etc/rc3.d/S99oss ${PKG_INSTALL_ROOT}/etc/init.d/oss + +# Remove OSS related entries from /etc/devlink.tab +rm -f ${PKG_INSTALL_ROOT}/tmp/osspkg.tmp +grep -v type=oss_ ${PKG_INSTALL_ROOT}/etc/devlink.tab > ${PKG_INSTALL_ROOT}/tmp/osspkg.tmp +cat ${PKG_INSTALL_ROOT}/tmp/osspkg.tmp > ${PKG_INSTALL_ROOT}/etc/devlink.tab + +if [ "${ISA_TYPE}" = "${ISA_TYPE_I386}" ]; then + # Restore SADA drivers + for PKG in SUNWaudd SUNWvia823x SUNWaudiohd SUNWad810 SUNWadixp SUNWusb + do + echo $PKG + sh ${PKG_INSTALL_ROOT}/var/sadm/pkg/$PKG/save/pspool/$PKG/install/postinstall + done +elif [ "${ISA_TYPE}" = "${ISA_TYPE_SPARC}" ]; then + # Restore SADA drivers + for PKG in SUNWaudd + do + echo $PKG + sh ${PKG_INSTALL_ROOT}/var/sadm/pkg/$PKG/save/pspool/$PKG/install/postinstall + done +fi + +# finally remove /etc/oss directory. + +rm -rf /etc/oss + +exit 0 diff --git a/setup/SunOS/preremove b/setup/SunOS/preremove new file mode 100644 index 0000000..d46a306 --- /dev/null +++ b/setup/SunOS/preremove @@ -0,0 +1,5 @@ +#!/bin/sh + +cp -f ${PKG_INSTALL_ROOT}/etc/oss/installed_drivers ${PKG_INSTALL_ROOT}/tmp/installed_drivers + +rm -f ${PKG_INSTALL_ROOT}/usr/sfw/lib/libflashsupport.so diff --git a/setup/SunOS/r.drvcfg b/setup/SunOS/r.drvcfg new file mode 100644 index 0000000..713ef60 --- /dev/null +++ b/setup/SunOS/r.drvcfg @@ -0,0 +1,20 @@ +#!/bin/sh +# +# Copyright (c) 2005 by 4Front Technologies +# All rights reserved. +# +# + +while read src +do + if [ -f $src ] + then + if /usr/sbin/pkgchk -p $src + then + rm -f $src + else + echo "not removing $src" + fi + fi +done +exit 0 diff --git a/setup/SunOS/sbin/soundoff b/setup/SunOS/sbin/soundoff new file mode 100755 index 0000000..432b65c --- /dev/null +++ b/setup/SunOS/sbin/soundoff @@ -0,0 +1,72 @@ +#!/bin/sh + +LOG=/var/log/soundoff.log +rm -f $LOG + +if test "`/usr/sbin/modinfo|grep OSS` " = " " +then + exit 0 +fi + +PIDLIST="`fuser /dev/mixer* /dev/dsp* /dev/midi* /dev/oss/*/* 2>/dev/null`" + +if test ! "$PIDLIST " = " " +then + echo + echo 'Error: OSS devices are in use by the following application(s)' + echo + + for n in $PIDLIST + do + ps -p $n |grep -v PID + done + + echo + echo Please terminate these applications and try soundoff again + echo + exit 1 +fi + +# Save mixer settings automatically +/usr/sbin/savemixer + +echo Modules to be unloaded >> $LOG +/usr/sbin/modinfo|grep OSS >> $LOG + +# Perform three iterations since certain drivers may depend on each other + +if test -f /etc/oss/installed_drivers +then + for i in 1 2 3 4 5 + do + for n in `cat /etc/oss/installed_drivers | sed 's/ .*//'` + do + N=`modinfo|grep " $n "|sed 's/^ //'|sed 's/ .*//'` + if test "$N " != " " + then + echo Unload $n/$N>> $LOG + /usr/sbin/modunload -i $N >> $LOG 2>&1 + fi + done + done +fi + +#remove the osscore module that isn't listed in installed_drivers +N=`modinfo|grep " osscore "|sed 's/^ //'|sed 's/ .*//'` +echo Unload osscore >> $LOG +/usr/sbin/modunload -i $N >> $LOG 2>&1 + +#remove the osscommon module that isn't listed in installed_drivers +N=`modinfo|grep " osscommon "|sed 's/^ //'|sed 's/ .*//'` +echo Unload osscommon >> $LOG +/usr/sbin/modunload -i $N >> $LOG 2>&1 + +if test "`/usr/sbin/modinfo|grep OSS` " = " " +then + exit 0 +fi + +echo Modules left >> $LOG +/usr/sbin/modinfo|grep OSS >> $LOG + +exit 0 diff --git a/setup/SunOS/sbin/soundon b/setup/SunOS/sbin/soundon new file mode 100755 index 0000000..79b7ca2 --- /dev/null +++ b/setup/SunOS/sbin/soundon @@ -0,0 +1,161 @@ +#!/bin/sh + +case `/usr/bin/isainfo -k` in + +i386) + DRVPATH=/kernel/drv/ + ;; + +amd64) + DRVPATH=/kernel/drv/amd64/ + ;; + +sparcv9) + DRVPATH=/kernel/drv/sparcv9/ + ;; + +*) + echo Unknown architecture in soundon `isainfo -k` +esac + +if test "`modinfo|grep OSS` " != " " +then + echo One or more OSS modules already loaded + modinfo|grep OSS + exit 1 +fi + +LOG=/var/log/soundon.log + +rm -f /dev/sndstat # Just in case Boomer is installed in the system + +echo "Open Sound System starting" `date` > $LOG +echo "OSS version: " `cat /etc/oss/version.dat` >> $LOG 2>&1 +echo Solaris version: `uname -a` >> $LOG +echo CPU: `isainfo -k` >> $LOG + +if test "`/usr/sbin/modinfo|grep OSS` " != " " +then + echo Warning: Some of the OSS modules were already loaded >> $LOG + /usr/sbin/modinfo|grep OSS >> $LOG +fi + +if test -f /etc/oss/license.asc +then + /usr/sbin/ossdetect -l >> $LOG +fi + +# Load osscore since it's not listed in installed_drivers file +/usr/sbin/modload $DRVPATH/osscore >> $LOG 2>&1 +/usr/sbin/modinfo|grep " osscore " >> $LOG + +if test -f /etc/oss/installed_drivers +then + + echo "Loading driver modules" >> $LOG + for n in `cat /etc/oss/installed_drivers | sed 's/ .*//'` + do + /usr/sbin/modload $DRVPATH/$n >> $LOG 2>&1 + /usr/sbin/modinfo|grep " $n " >> $LOG + /usr/sbin/devfsadm -i $n + done +else + echo /etc/oss/installed_drivers not found. >> $LOG + echo /etc/oss/installed_drivers not found. + exit 1 +fi + +sleep 5 +echo "=========" >> $LOG +find /devices -name *_mix* > /dev/null +find /devices -name *_pcm* > /dev/null +find /devices -name *_mid* > /dev/null +/usr/sbin/devlinks + +# Restore the legacy device links. +if test -f /etc/oss/legacy_devices +then + sh /etc/oss/legacy_devices >> $LOG 2>&1 +fi + +echo "=========" >> $LOG +/usr/sbin/ossdevlinks -v >> $LOG 2>&1 +ls -l /dev/*dsp* /dev/*_pcm* /dev/*mixer* /dev/*_mix* /dev/*midi* /dev/*_mid* >> $LOG 2>&1 +echo "=========" >> $LOG +echo "OSS configuration" >> $LOG +/usr/bin/ossinfo -v3 >> $LOG 2>&1 +echo "=========" >> $LOG +cat /dev/sndstat >> $LOG + +if test -f /etc/oss/mixer.save || test -f /etc/oss/dspdevs.map || test -f /etc/oss/applist.conf +then + /usr/sbin/savemixer -L +fi + +echo "=========" >> $LOG +dmesg >> $LOG + +if grep "This OSS version has expired" /dev/sndstat > /dev/null +then +rm -f /tmp/ossmsg +cat > /tmp/ossmsg << EOM +From: "Open Sound System" <root> +To: <root> +Subject: Your Open Sound System copy has expired + +The unregistered version of Open Sound System installed in your system +has expired. To continue using Open Sound System you need to upgrade to the +latest OSS version which is available from http://www.opensound.com/download.cgi + +Alternatively ou can purchase the official OSS version from +http://www.opensound.com/order.html . The registered version does not +have any time limits. + +Best regards, + +Open Sound System Sales +sales@opensound.com + +EOM + +echo +echo +echo '********** IMPORTANT! *************' +echo +cat /tmp/ossmsg + +mail root < /tmp/ossmsg + +rm -f /tmp/ossmsg + +fi + +if test -x /etc/oss/soundon.user +then + echo Running /etc/oss/soundon.user >> $LOG + /etc/oss/soundon.user >> $LOG 2>&1 +fi + +if test "`ossinfo -g|grep TRIAL` " != " " +then + echo + echo "************************************************************" + echo "* NOTE! You are using trial version of Open Sound System *" + echo "************************************************************" + echo + + sleep 1 +fi + +if test "`ossinfo -g|grep EXPIRED` " != " " +then + echo + echo "****************************************************************" + echo "* NOTE! Your Open Sound System evaluation license has expired *" + echo "****************************************************************" + echo + + sleep 15 +fi + +exit 0 diff --git a/setup/SunOS/solsetup.sh b/setup/SunOS/solsetup.sh new file mode 100644 index 0000000..732c18a --- /dev/null +++ b/setup/SunOS/solsetup.sh @@ -0,0 +1,182 @@ +#!/bin/sh + +if test "$CONFIGURE " != "YES " +then + echo + echo Error: Wrong usage + echo + echo You must run `dirname $0`/configure instead of $0 + exit 1 +fi + +if test "`ls .` " != " " +then + echo Error: Current directory must be empty + exit 1 +fi + +if test "`uname -p`" = "sparc" +then +KERNEL32=sparc +KERNEL64=sparcv9 +KERNEL32FLAGS=-U +KERNEL64FLAGS=-K +else +if test "`uname -r`" = "5.9" +then +KERNEL32=i386 +KERNEL64=NULL +KERNEL32FLAGS= +KERNEL64FLAGS= +else +KERNEL32=i386 +KERNEL64=amd64 +KERNEL32FLAGS= +KERNEL64FLAGS=-K +fi +fi + +ln -s $SRCDIR/setup/SunOS/build.sh build.sh +ln -s $SRCDIR origdir +ln -s $SRCDIR/misc/samples/ddksample . +echo SRCDIR=$SRCDIR>.directories +echo > .nocopy + +# Check if SADA headers are present in the system. + +if test -f /usr/include/sys/audiovar.h +then + HAVE_SADA=1 + export HAVE_SADA +else + echo + echo Warning! oss_sadasupport cannot be compiled in systems that have + echo Boomer installed. + echo +fi + +# Make the 32bit kernel drivers +mkdir $KERNEL32 +echo "cd $KERNEL32;sh $SRCDIR/setup/setupdir.sh -A$KERNEL32 $KERNEL32FLAGS" +(cd $KERNEL32;sh $SRCDIR/setup/setupdir.sh -A$KERNEL32 $KERNEL32FLAGS) + +# If KERNEL64 is specified then do both 32 and 64bit +if test "$KERNEL64" != "NULL" +then + mkdir $KERNEL64 + echo "cd $KERNEL64;sh $SRCDIR/setup/setupdir.sh -A$KERNEL64 $KERNEL64FLAGS" + (cd $KERNEL64;sh $SRCDIR/setup/setupdir.sh -A$KERNEL64 $KERNEL64FLAGS) + + # Make sure both 32 and 64 bit versions share the same timestamp.h file. + cp $KERNEL32/kernel/framework/include/timestamp.h $KERNEL64/kernel/framework/include/timestamp.h + + cat > Makefile <<THE_END_IS_NEAR +# Autogenerated file - do not edit + +all: $KERNEL32/kernel/framework/include/buildid.h subdirs build + +install: all + rm -f prototype/kernel/drv/*.conf + cp -R prototype/* / + sync + soundoff + sync + soundon + sync + +subdirs: + cd $KERNEL32;make + cd $KERNEL64;make + +build: + sh build.sh + +copy: all + rm -f prototype/kernel/drv/*.conf + cp -R prototype/* / + +package: all + sh $KERNEL32/setup/SunOS/mkpkg.sh + +clean: + cd $KERNEL32;make clean + cd $KERNEL64;make clean + rm -f *.pkg + rm -rf prototype + +config: + cd $KERNEL32;make config CONFIG_FLAGS=-A$KERNEL32 + cd $KERNEL64;make config CONFIG_FLAGS="-A$KERNEL64 -K" + +THE_END_IS_NEAR + +else # Do just the 32bit kernel + +cat > Makefile <<THE_END_IS_NEAR +# Autogenerated file - do not edit + +all: $KERNEL32/kernel/framework/include/buildid.h subdirs build + +install: all + rm -f prototype/kernel/drv/*.conf + cp -R prototype/* / + sync + soundoff + sync + soundon + sync + +subdirs: + cd $KERNEL32;make + +build: + sh build.sh + +copy: all + rm -f prototype/kernel/drv/*.conf + cp -R prototype/* / + +package: all + sh $KERNEL32/setup/SunOS/mkpkg.sh + +clean: + cd $KERNEL32;make clean + rm -f *.pkg + rm -rf prototype + +config: + cd $KERNEL32;make config CONFIG_FLAGS=-A$KERNEL32 + +THE_END_IS_NEAR +fi + +rm -f .nocopy + +# +# Check if some mandatory Solaris packages have been installed +# +MISSING="" +for n in SUNWgcc SUNWaudh SUNWusbu +do + if pkginfo -q $n + then + OK=1 + else + MISSING="$MISSING $n" + fi +done + +if test "$MISSING " != " " +then + echo + echo Some required Solaris packages may be missing. You can install them + echo by doing: + echo + + for n in $MISSING + do + echo pkg install $n + done +fi + +exit 0 diff --git a/setup/SunOS/svc-oss.htm b/setup/SunOS/svc-oss.htm new file mode 100755 index 0000000..d45a124 --- /dev/null +++ b/setup/SunOS/svc-oss.htm @@ -0,0 +1,55 @@ +#!/sbin/sh +# + +. /lib/svc/share/smf_include.sh + +# Generic runtime checks +OSS_SERVICE=`echo $SMF_FMRI | sed 's/.*:\(.*\)/\1/'` + +if [ -z "$SMF_FMRI" ]; then + echo "Open Sound System service can only be started/stopped via the SMF framework" + exit $SMF_EXIT_ERR_NOSMF +fi + +if [ -z "$OSS_SERVICE" ]; then + echo "Unable to parse service name from SMF FRMI $SMF_FRMI" + exit $SMF_EXIT_ERR_NOSMF +fi + +# +# Original script, refactored +# + +if test -f /etc/oss.conf +then + . /etc/oss.conf +else + OSSLIBDIR=/usr/lib/oss +fi + +oss_start() { + /usr/sbin/soundon > /dev/null 2>&1 + # Somehow this is required overhere to prevent skipping + /usr/sbin/ossdevlinks +} + +oss_stop() { + # Save mixer settings automatically if requested + if test -f $OSSLIBDIR/etc/userdefs && /usr/xpg4/bin/grep -q "autosave_mixer yes" $OSSLIBDIR/etc/userdefs + then + /usr/sbin/savemixer + fi +} + +case $1 in +'start') + oss_start + ;; +'stop') + oss_stop + ;; +*) + echo "Usage: $0 { start | stop }" + exit 1 + ;; +esac diff --git a/setup/VxWorks/build.sh b/setup/VxWorks/build.sh new file mode 100644 index 0000000..aa8d11b --- /dev/null +++ b/setup/VxWorks/build.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +rm -rf prototype +mkdir prototype +mkdir prototype/oss-install + +if test "$LD " = " " +then + LD=ar +fi + +$LD -r -o prototype/oss-install/osscore.o target/objects/*.o + +cp target/modules/*.o prototype/oss-install/ + +if test "$AR " = " " +then + AR=ar +fi + +$AR rc prototype/oss-install/liboss.a prototype/oss-install/*.o + +exit 0 diff --git a/setup/VxWorks/make.local b/setup/VxWorks/make.local new file mode 100644 index 0000000..3eac1d3 --- /dev/null +++ b/setup/VxWorks/make.local @@ -0,0 +1,5 @@ +build: kernel/framework/include/buildid.h all + LD=$(LD) AR=$(AR) sh build.sh + +package: build + sh setup/VxWorks/mkpkg.sh diff --git a/setup/build_common.sh b/setup/build_common.sh new file mode 100644 index 0000000..78d3acd --- /dev/null +++ b/setup/build_common.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +SRCDIR=$1 +OSSLIBDIR=$2 + +if test ! -d $SRCDIR +then + echo Bad SRCDIR parameter + exit 1 +fi + +if test ! -d prototype +then + echo Bad prototype directory + exit 1 +fi + +# Copy common files to the prototype tree +cp -pRf $SRCDIR/oss/* prototype/$OSSLIBDIR/ +rm -f prototype/$OSSLIBDIR/oss/.nomake + +#cp $SRCDIR/lib/libossmix/libossmix.h prototype/usr/lib/oss/include + +chmod 700 prototype/usr/sbin/* + +exit 0 diff --git a/setup/dirsetup.c b/setup/dirsetup.c new file mode 100644 index 0000000..38bcd2b --- /dev/null +++ b/setup/dirsetup.c @@ -0,0 +1,224 @@ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <time.h> + +#if PATH_MAX == -1 +#undef PATH_MAX +#endif +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +char *srcdir = NULL, *blddir = NULL; +int verbose = 0, copy_files = 0; +struct stat bld_stat, src_stat; + +static void +copy_file (char *sname, char *tname, char *pname, int native_make) +{ + char *p; + int in_fd, out_fd, l; + + unsigned char buf[4096]; + + if (strcmp (pname, ".depend") == 0) + return; + + if (!native_make) + if (strncmp (pname, "Makefile", 8) == 0) + return; + + if (strlen (pname) > 6) + { + p = pname + strlen (pname) - 6; /* Seek to the _cfg.[c-h] suffix */ + if (strcmp (p, "_cfg.c") == 0) + return; + if (strcmp (p, "_cfg.h") == 0) + return; + } + + if (!copy_files) + { + symlink (sname, tname); + return; + } + + if ((in_fd=open(sname, O_RDONLY, 0))==-1) + { + perror(sname); + exit(-1); + } + + if ((out_fd=creat(tname, 0644))==-1) + { + perror(tname); + exit(-1); + } + + while ((l=read(in_fd, buf, sizeof(buf)))>0) + { + if (write(out_fd, buf, l)!=l) + { + perror(tname); + exit(-1); + } + } + + if (l==-1) + { + perror(sname); + exit(-1); + } + + close(in_fd); + close(out_fd); +} + +static void +copy_tree (char *fromdir, char *tgtdir, int native_make) +{ + DIR *dir; + struct dirent *de; + struct stat st; + + if (tgtdir != NULL) + { + mkdir (tgtdir, 0700); + } + + if ((dir = opendir (fromdir)) == NULL) + { + fprintf (stderr, "Bad source directory %s\n", fromdir); + return; + } + + while ((de = readdir (dir)) != NULL) + { + char sname[PATH_MAX+20], tname[PATH_MAX+20]; + + sprintf (sname, "%s/%s", fromdir, de->d_name); + if (tgtdir != NULL) + sprintf (tname, "%s/%s", tgtdir, de->d_name); + else + sprintf (tname, "%s", de->d_name); + + if (stat (sname, &st) == -1) + { + perror (sname); + exit (-1); + } + + if ((st.st_dev == bld_stat.st_dev) && (st.st_ino == bld_stat.st_ino)) continue; + if ((st.st_dev == src_stat.st_dev) && (st.st_ino == src_stat.st_ino)) continue; + + if (S_ISDIR (st.st_mode)) + { + if (de->d_name[0] != '.') + { + char tmp[PATH_MAX+20]; + int is_native = 0; + struct stat st2; + + sprintf (tmp, "%s/.nativemake", sname); + if (stat (tmp, &st2) != -1) + is_native = 1; + + sprintf (tmp, "%s/.nocopy", sname); + if (stat (tmp, &st2) == -1) + copy_tree (sname, tname, is_native); + } + } + else + { + copy_file (sname, tname, de->d_name, native_make); + } + } + + closedir (dir); +} + +int +main (int argc, char *argv[]) +{ + int i; + FILE *f; + + time_t t; + struct tm *tm; + + if (argc < 3) + { + fprintf (stderr, "%s: Bad usage\n", argv[0]); + exit (-1); + } + + srcdir = argv[1]; + blddir = argv[2]; + + if (stat (blddir, &bld_stat) == -1) + { + perror (blddir); + exit (-1); + } + + if (stat (srcdir, &src_stat) == -1) + { + perror (srcdir); + exit (-1); + } + + for (i = 3; i < argc; i++) + { + if (strcmp (argv[i], "-v") == 0) + { + verbose++; + continue; + } + + if (strcmp (argv[i], "-c") == 0) + { + copy_files = 1; + continue; + } + } + + f = fopen (".nocopy", "w"); + fclose (f); + copy_tree (srcdir, NULL, 0); + +#if 0 + if ((f = fopen ("timestamp.h", "w")) == NULL) + { + perror ("timestamp.h"); + exit (-1); + } + + time (&t); + tm = gmtime (&t); + fprintf (f, "#define OSS_COMPILE_DATE \"%04d%02d%02d%02d%02d\"\n", + tm->tm_year + 1900, + tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); + + fclose (f); +#endif + + exit (0); +} diff --git a/setup/elflib.inc b/setup/elflib.inc new file mode 100644 index 0000000..0611c7d --- /dev/null +++ b/setup/elflib.inc @@ -0,0 +1,440 @@ +/* + * These routines are used to change the contects of various structures + * stored inside the modules + */ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +#if !defined(ELF64) && !defined(ELF32) +# if defined(sparc) || defined(__x86_64__) +# define ELF64 +# else +#error here +# define ELF32 +# endif +#endif + +#undef Elf_Ehdr +#undef Elf_Shdr +#undef Elf_Sym + +#ifdef ELF32 +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym + +static int +valid_elf_file (Elf_Ehdr * hdr) +{ + if (hdr->e_ident[0] != 0x7f) + return 0; + if (hdr->e_ident[1] != 'E') + return 0; + if (hdr->e_ident[2] != 'L') + return 0; + if (hdr->e_ident[3] != 'F') + return 0; + if (hdr->e_ident[EI_CLASS] != ELFCLASS32) + { + fprintf (stderr, "EI_CLASS=%x\n", hdr->e_ident[EI_CLASS]); + return 0; + } +/* Check for x86 (LSB) and PPC (MSB) data format */ + if ((hdr->e_ident[EI_DATA] != ELFDATA2LSB) && + (hdr->e_ident[EI_DATA] != ELFDATA2MSB)) + { + fprintf (stderr, "EI_DATA=%x\n", hdr->e_ident[EI_DATA]); + return 0; + } + if (hdr->e_ident[EI_VERSION] != EV_CURRENT) + { + fprintf (stderr, "EI_VERSION=%x (%x)\n", hdr->e_ident[EI_VERSION], + EV_CURRENT); + return 0; + } + if (hdr->e_type != ET_REL && hdr->e_type != ET_DYN) + { + fprintf (stderr, "e_type=%x\n", hdr->e_type); + return 0; + } +/* Check for x86 and PPC machine type */ + if ((hdr->e_machine != EM_386) && (hdr->e_machine != EM_PPC) + && (hdr->e_machine != EM_SPARC)) + { + fprintf (stderr, "e_machine=%x\n", hdr->e_machine); + return 0; + } + + if (hdr->e_version != EV_CURRENT) + { + fprintf (stderr, "e_version=%x (%x)\n", hdr->e_version, EV_CURRENT); + return 0; + } + if (hdr->e_ehsize != sizeof (*hdr)) + { + fprintf (stderr, "e_ehsize=%x (%x)\n", hdr->e_ehsize, sizeof (*hdr)); + return 0; + } + + return 1; +} +#else +/* Elf64 */ +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define locate_symbol locate_symbol64 + +#define elf_read_datasym elf_read_datasym64 +#define valid_elf_file valid_elf_file64 + +static int +valid_elf_file (Elf64_Ehdr * hdr) +{ + if (hdr->e_ident[0] != 0x7f) + return 0; + if (hdr->e_ident[1] != 'E') + return 0; + if (hdr->e_ident[2] != 'L') + return 0; + if (hdr->e_ident[3] != 'F') + return 0; + if (hdr->e_ident[EI_CLASS] != ELFCLASS64) + return 0; + if (hdr->e_ident[EI_VERSION] != EV_CURRENT) + return 0; + if (hdr->e_type != ET_REL) + return 0; +#ifdef sparc +/* Check for Sparc machine type */ + if ((hdr->e_machine != EM_SPARCV9)) + { + fprintf (stderr, "e_machine=%x\n", hdr->e_machine); + return 0; + } +#else +/* Check for AMD64 (LSB) data format */ + if (hdr->e_ident[EI_DATA] != ELFDATA2LSB) + return 0; +/* Check for x86 and PPC machine type */ +#ifndef EM_X86_64 +#define EM_X86_64 0 /* Dummy */ +#endif + if ((hdr->e_machine != EM_ALPHA) && (hdr->e_machine != EM_X86_64)) + return 0; +#endif + if (hdr->e_version != EV_CURRENT) + return 0; + if (hdr->e_ehsize != sizeof (*hdr)) + return 0; + + return 1; +} +#endif + +#ifdef NEEDS_LOCATE_SYMBOL +static char * +locate_symbol (char *buffer, int len, char *symname) +{ + Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer; + Elf_Shdr *shdr; + Elf_Sym *sym = NULL; + char *strtab = NULL, *ptr; + int symsize = 0; + int i; + + shdr = (Elf_Shdr *) & buffer[ehdr->e_shoff]; + + for (i = 0; i < ehdr->e_shnum; i++) + { + + switch (shdr[i].sh_type) + { + case SHT_SYMTAB: + sym = (Elf_Sym *) & buffer[shdr[i].sh_offset]; + symsize = shdr[i].sh_size / shdr[i].sh_entsize; + break; + + case SHT_STRTAB: +#ifndef SECOND_STRTAB + if (strtab != NULL) + break; +#endif + strtab = &buffer[shdr[i].sh_offset]; + break; + } + } + + if (sym == NULL || strtab == NULL) + { + fprintf (stderr, "Missing ELF symbol information\n"); + return NULL; + } + + for (i = 0; i < symsize; i++) + { + char *name = &strtab[sym[i].st_name]; + + if (strcmp (name, symname) == 0) + { + ptr = buffer + (sym[i].st_value + shdr[sym[i].st_shndx].sh_offset); + return ptr; + } + } + return NULL; +} +#endif + +int +elf_read_datasym (char *buffer, int blen, Elf_Sym * sym, int addr, + char *buf, int count) +{ + Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer; + Elf_Shdr *shdr; + int i; + + shdr = (Elf_Shdr *) & buffer[ehdr->e_shoff]; + + i = sym->st_shndx; + memcpy (buf, &buffer[shdr[i].sh_offset + addr], count); + + return 1; +} + +#ifdef PATCH_MODULE +static int +PATCH_MODULE (char *fname) +{ + int fd; + int l, n; + char *lic; + + oss_license_t *oss_license; + + char elf_file[1024 * 1024]; + +/* + * Some security checks to prevent running osslic by + * mistake. That would wipe out the license information. + */ + + if (!ok) + { + printf ("Incorrect osslic usage\n"); + return 0; + } + + if (fname == NULL) + return 0; + + if ((fd = open (fname, O_RDWR, 0)) == -1) + { + perror (fname); + return 0; + } + + if ((l = read (fd, elf_file, sizeof (elf_file))) < 1 + || l == sizeof (elf_file)) + { + perror (fname); + fprintf (stderr, "Bad ELF file %s\n", fname); + return 0; + } + + if (!valid_elf_file ((Elf_Ehdr *) elf_file)) + { + fprintf (stderr, "OSS elflib: Invalid ELF file %s\n", fname); + return 0; + } + + if ((lic = locate_symbol (elf_file, l, "oss_license")) == NULL) + { + fprintf (stderr, "File error\n"); + close (fd); + return 0; + } + + oss_license = (oss_license_t *) lic; + + oss_license->license_type = license_type; + strcpy (oss_license->person, person); + strcpy (oss_license->organization, organization); + strcpy (oss_license->options_string, options_string); + strcpy (oss_license->serial, serial); + oss_license->exp_year = exp_year; + oss_license->exp_month = exp_mon; + + if (lseek (fd, 0L, SEEK_SET) == -1) + { + perror (fname); + fprintf (stderr, "Bad seek\n"); + return 0; + } + + if ((n = write (fd, elf_file, l)) != l) + { + perror (fname); + fprintf (stderr, "Writing ELF file %s failed\n", fname); + return 0; + } + + close (fd); + return 1; +} +#endif + +#ifdef ELF_LOAD_SYMTAB + +typedef struct +{ + char name[64]; + unsigned long addr; +} oss_symbol_t; + +#define MAX_MODULES 100 +static oss_symbol_t module_table[MAX_MODULES]; +static int n_module_table = 0; + +typedef void (*elf_callback_t) (char *buffer, int blen, Elf_Sym * sym, + char *name, int addr); +static int +list_symbols (char *buffer, int len, char *prefix, elf_callback_t callback) +{ + Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer; + Elf_Shdr *shdr; + Elf_Sym *sym = NULL; + char *strtab = NULL; + int symsize = 0; + int i; + int shstrndx = -1; + int found = 0; + + shdr = (Elf_Shdr *) & buffer[ehdr->e_shoff]; + shstrndx = ehdr->e_shstrndx; + + if (elf_verbose > 1) + printf ("e_shstrndx=%d\n", shstrndx); + + for (i = 0; i < ehdr->e_shnum; i++) + { + switch (shdr[i].sh_type) + { + case SHT_SYMTAB: + sym = (Elf_Sym *) & buffer[shdr[i].sh_offset]; + symsize = shdr[i].sh_size / shdr[i].sh_entsize; + if (elf_verbose > 1) +#ifdef ELF32 + printf ("ELF symtab at 0x%x\n", shdr[i].sh_offset); +#else + printf ("ELF symtab at 0x%lx\n", shdr[i].sh_offset); +#endif + break; + + case SHT_STRTAB: + if (i == shstrndx) /* Ignore section header symbol table */ + break; + strtab = &buffer[shdr[i].sh_offset]; + if (elf_verbose > 1) +#ifdef ELF32 + printf ("ELF strtab at 0x%x (%d) \n", shdr[i].sh_offset, i); +#else + printf ("ELF strtab at 0x%lx (%d) \n", shdr[i].sh_offset, i); +#endif + break; + } + } + + if (sym == NULL || strtab == NULL) + { + fprintf (stderr, "Missing ELF symbol information\n"); + return 0; + } + + for (i = 0; i < symsize; i++) + { + char *name = &strtab[sym[i].st_name]; + + if (elf_verbose > 2) + printf ("Sym %d '%s'\n", sym[i].st_name, name); + + if (strncmp (name, prefix, strlen (prefix)) == 0) + { + oss_symbol_t *m; + + if (callback != NULL) + { + found = 1; + callback (buffer, len, &sym[i], name, sym[i].st_value); + continue; + } + + m = &module_table[n_module_table++]; + strcpy (m->name, name); + m->addr = sym[i].st_value; + } + } + return found; +} + +int +ELF_LOAD_SYMTAB (char *filename, char *prefix, elf_callback_t callback) +{ + char buffer[4 * 1024 * 1024]; + int fd, len; + Elf_Ehdr *hdr = (Elf_Ehdr *) buffer; + + if ((fd = open (filename, O_RDONLY, 0)) == -1) + { + perror (filename); + return 0; + } + + if ((len = read (fd, buffer, sizeof (buffer))) <= 0) + { + perror (filename); + close (fd); + return 0; + } + + if (len >= sizeof (buffer)) + { + fprintf (stderr, "%s is too large\n", filename); + close (fd); + return 0; + } + + if (len < sizeof (*hdr)) + { + fprintf (stderr, "%s is too short (%d)\n", filename, len); + close (fd); + return 0; + } + + if (!valid_elf_file (hdr)) + { + fprintf (stderr, "%s is not a valid ELF object\n", filename); + close (fd); + return 0; + } + + if (!(list_symbols (buffer, len, prefix, callback))) + { + if (elf_verbose > 1) + fprintf(stderr, "%s does not contain %s symbol\n", filename, prefix); + close (fd); + return 0; + } + + close (fd); + return 1; +} +#endif diff --git a/setup/fpsupport_i86pc.c b/setup/fpsupport_i86pc.c new file mode 100644 index 0000000..3979d01 --- /dev/null +++ b/setup/fpsupport_i86pc.c @@ -0,0 +1,236 @@ +#ifndef lint +/* + * Floating point support routines for x86 and x86_64 + * + * Copyright (C) 4Front Technologies 2006. Released under GPLv2/CDDL. + * + * Must be compiled to .asm with gcc -S -O6. + */ +#define BLOCK_INTERRUPTS + +#define FP_SAVE(envbuf) asm ("fnsave %0":"=m" (*envbuf)); +#define FP_RESTORE(envbuf) asm ("frstor %0":"=m" (*envbuf)); + +/* SSE/SSE2 compatible macros */ +#define FX_SAVE(envbuf) asm ("fxsave %0":"=m" (*envbuf)); +#define FX_RESTORE(envbuf) asm ("fxrstor %0":"=m" (*envbuf)); + +#if defined(amd64) || defined(__x86_64__) +#define ARCH64 +#endif + +static int old_arch = 0; /* No SSE/SSE2 instructions */ + +/* + * Generic CPUID function + * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx + * resulting in stale register contents being returned. + */ +static inline void +cpuid (int op, int *eax, int *ebx, int *ecx, int *edx) +{ +__asm__ ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx):"0" (op), "c" + (0)); +} + +#ifdef ARCH64 +# define local_save_flags(x) asm volatile("pushfq ; popq %0":"=g" (x):) +# define local_restore_flags(x) asm volatile("pushq %0 ; popfq"::"g" (x):"memory", "cc") +#else +# define local_save_flags(x) asm volatile("pushfl ; popl %0":"=g" (x):) +# define local_restore_flags(x) asm volatile("pushl %0 ; popfl"::"g" (x):"memory", "cc") +#endif + +static inline unsigned long +read_cr0 (void) +{ + unsigned long cr0; +#ifdef ARCH64 + asm volatile ("movq %%cr0,%0":"=r" (cr0)); +#else + asm volatile ("movl %%cr0,%0":"=r" (cr0)); +#endif + return cr0; +} + +static inline void +write_cr0 (unsigned long val) +{ +#ifdef ARCH64 + asm volatile ("movq %0,%%cr0"::"r" (val)); +#else + asm volatile ("movl %0,%%cr0"::"r" (val)); +#endif +} + +static inline unsigned long +read_cr4 (void) +{ + unsigned long cr4; +#ifdef ARCH64 + asm volatile ("movq %%cr4,%0":"=r" (cr4)); +#else + asm volatile ("movl %%cr4,%0":"=r" (cr4)); +#endif + return cr4; +} + +static inline void +write_cr4 (unsigned long val) +{ +#ifdef ARCH64 + asm volatile ("movq %0,%%cr4"::"r" (val)); +#else + asm volatile ("movl %0,%%cr4"::"r" (val)); +#endif +} + +static inline unsigned long long +read_mxcsr (void) +{ + unsigned long long mxcsr; + asm volatile ("stmxcsr %0":"=m" (mxcsr)); + return mxcsr; +} + +static inline void +write_mxcsr (unsigned long long val) +{ + asm volatile ("ldmxcsr %0"::"m" (val)); +} + +int +oss_fp_check (void) +{ +/* + * oss_fp_check returns 1 if the CPU architecture supports floating point + * in kernel space. Otherwise 0 will be returned. + */ + int eax, ebx, ecx, edx; +#define FLAGS_ID (1<<21) + +#ifdef ARCH64 + unsigned long long flags_reg; +#else + unsigned long flags_reg; +#endif + +/* + * First probe if the CPU supports CPUID by checking if the ID bit + * can be changed. + */ + + local_save_flags (flags_reg); + flags_reg &= ~FLAGS_ID; /* Clear */ + local_restore_flags (flags_reg); + + local_save_flags (flags_reg); + if (flags_reg & FLAGS_ID) + return -1; + + flags_reg |= FLAGS_ID; /* Set */ + local_restore_flags (flags_reg); + + local_save_flags (flags_reg); + if (!(flags_reg & FLAGS_ID)) + return -2; + +/* + * Now we know that the CPU supports CPUID. Ensure that FXSAVE and FXRSTOR + * are supported. + */ +#define CPUID_FXSR (1<<24) +#define CPUID_SSE (1<<25) +#define CPUID_SSE2 (1<<26) + + cpuid (1, &eax, &ebx, &ecx, &edx); + + if (!(edx & CPUID_FXSR)) + return -3; /* No */ + + /* + * Older machines require different FP handling. Use the SSE + * instruction set as an indicator. + */ + if (!(edx & CPUID_SSE)) + old_arch = 1; /* No */ + + return 1; +} + +#define local_irq_disable() asm volatile("cli": : :"memory") + +void +oss_fp_save (short *envbuf, unsigned int flags[]) +{ +/* + * oss_fp_save saves the floating point environment (registers) and + * enables floating point operations if necessary. + */ + +#ifdef BLOCK_INTERRUPTS +# ifdef ARCH64 + unsigned long long flags_reg; +# else + unsigned long flags_reg; +# endif + local_save_flags (flags_reg); + flags[3] = flags_reg; + local_irq_disable (); +#endif + + /* + * Prepare the FP related control register bits to disable all kind of + * FP related exceptions. + */ + flags[0] = read_cr0 (); + write_cr0 (flags[0] & ~0x0e); /* Clear CR0.TS/EM/MP */ + + /* + * Save FPU/SSE/XMM registers and init the hardware. + */ + if (old_arch) + { + FP_SAVE (envbuf); + } + else + { + flags[1] = read_cr4 (); + write_cr4 (flags[1] | 0x600); /* Set OSFXSR & OSXMMEXCEPT */ + FX_SAVE (envbuf); + asm ("fninit"); + asm ("fwait"); + write_mxcsr (0x1f80); + } + flags[2] = read_cr0 (); +} + +void +oss_fp_restore (short *envbuf, unsigned int flags[]) +{ +/* + * oss_fp_restore reverses any changes made by oss_fp_save and restores + * the floating point environment (registers) back to the original state. + */ + asm ("fwait"); + if (old_arch) + { + FP_RESTORE (envbuf); + } + else + { + FX_RESTORE (envbuf); + write_cr4 (flags[1]); /* Restore cr4 */ + } + write_cr0 (flags[0]); /* Restore cr0 */ +#ifdef BLOCK_INTERRUPTS + local_restore_flags (flags[3]); +#endif +} +#else +int +oss_fp_check (void) +{ + return 0; +} +#endif diff --git a/setup/gen_driver_beos.inc b/setup/gen_driver_beos.inc new file mode 100644 index 0000000..b85f11f --- /dev/null +++ b/setup/gen_driver_beos.inc @@ -0,0 +1,183 @@ +static void +generate_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir) +{ + + /* BeOS version */ +//XXX:WRITEME + + FILE *f, *src; + char tmp[256], line[256], *p, *s; + int i, n = 0; + char *options[MAXOPTS]; + int nopts = 0; + + sprintf (tmp, "%s/%s", dirname, cfg_name); + + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + +/* + * Handle driver specific configuration options + */ + sprintf (tmp, "%s/.params", dirname); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + fprintf (src, "%s\n", line); + if (strncmp (line, "int ", 4) == 0) + { + char *s = line + 4, *p = s; + + while (*p && *p != '=' && *p != ';') + p++; + *p = 0; + if (nopts >= MAXOPTS) + { + fprintf (stderr, "Too many options for driver '%s' (%d)\n", + name, nopts); + exit (-1); + } + + options[nopts++] = strdup (s); + } + } + + fclose (f); + } + + fprintf (src, "\n"); + fprintf (src, "#include \"%s\"\n", cfg_header); + fprintf (src, "\n"); + + if ((f = fopen ("devices.list", "r")) == NULL) + { + perror ("devices.list"); + exit (-1); + } + + if (strcmp (conf->bus, "PCI") == 0) + { + fprintf (src, "static struct {\n"); + fprintf (src, "\tbool subsystem;\n"); + fprintf (src, "\tuint32 vendor, product;\n"); + fprintf (src, "} id_table[] = {\n"); + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + int vendor, product; + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strncmp (s, "pci", 3) == 0 || strncmp (s, "pcs", 3) == 0) + { + const char *sub = (strncmp (s, "pcs", 3) == 0) ? "true" : "false"; + if (sscanf (s + 3, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad PCI id %s\n", s); + } + + fprintf (src, "\t{%s,\t0x%x,\t0x%x},\n", sub, vendor, product); + } + + } + + fprintf (src, "\t{0}\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + } + + fclose (f); + + +/* + * Create the driver specific option list + */ + fprintf (src, "static oss_option_map_t local_driver_options[] =\n"); + fprintf (src, "{\n"); + for (i = 0; i < nopts; i++) + fprintf (src, "\t{\"%s\", &%s},\n", options[i], options[i]); + fprintf (src, "\t{NULL, NULL}\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + + fprintf (src, "#include \"%s/%s/module.inc\"\n", topdir, this_os); + + if (n == 0) + { + fprintf (stderr, + "Warning: No device entries (devices.list) for driver %s\n", + name); + } + + fclose (src); + + /* config header */ + + sprintf (tmp, "%s/%s", dirname, cfg_header); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + /* nudge all symbols to function pointers */ + fprintf (src, "#define BUILDING_DRIVER\n"); + + fprintf (src, "#include <oss_config.h>\n"); + fprintf (src, "\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_PURPOSE\t\"%s\"\n", conf->purpose); + fprintf (src, "#define DRIVER_STR_INFO\t%s_str_info\n", name); + fprintf (src, "#define DRIVER_PROBE\t%s_probe\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + + fprintf (src, "#define DRIVER_MODULE_OBJECT\tgModule_%s\n", name); + fprintf (src, "\n"); + + fprintf (src, "extern int DRIVER_PROBE(void);\n"); + fprintf (src, "extern int DRIVER_ATTACH(oss_device_t *ossdev);\n"); + fprintf (src, "extern int DRIVER_DETACH(oss_device_t *ossdev);\n"); + + fclose (src); + +} diff --git a/setup/gen_driver_freebsd.inc b/setup/gen_driver_freebsd.inc new file mode 100644 index 0000000..be5fa0e --- /dev/null +++ b/setup/gen_driver_freebsd.inc @@ -0,0 +1,280 @@ +static void +generate_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir) +{ + /* FreeBSD version */ + + FILE *f, *src; + char tmp[256], line[256], *p, *s; + int i, n = 0; + char *options[MAXOPTS]; + char *option_desc[MAXOPTS]; + char desc[65536]; + int nopts = 0; + + sprintf (tmp, "target/build/%s.c", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + fprintf (src, "#include \"devid.h\"\n\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_PURPOSE\t\"%s\"\n", conf->purpose); + fprintf (src, "#define DRIVER_STR_INFO\t%s_str_info\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + fprintf (src, "#define DEVTYPE_%s\n", conf->bus); + fprintf (src, "\n"); + +/* + * Handle driver specific configuration options + */ + *desc = 0; + sprintf (tmp, "%s/.params", dirname); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + fprintf (src, "%s\n", line); + if (strncmp (line, "int ", 4) == 0) + { + char *s = line + 4, *p = s; + + while (*p && *p != '=' && *p != ';' && *p != ' ') + p++; + *p = 0; + if (nopts >= MAXOPTS) + { + fprintf (stderr, "Too many options for driver '%s' (%d)\n", + name, nopts); + exit (-1); + } + + if (nopts != 0 && *desc != 0) + option_desc[nopts - 1] = strdup (desc); + option_desc[nopts] = 0; + options[nopts++] = strdup (s); + *desc = 0; + } + else + { + char *s = line, *p; + char tmp[4096]; + while (*s == ' ' || *s == '/' || *s == '*') + s++; + + p = tmp; + + while (*s) + { + if (*s == '"') + *p++ = '\\'; + + *p++ = *s++;; + } + *p = 0; + + p = desc + strlen (desc); + sprintf (p, "\n\"%s\\n\"", tmp); + } + } + + fclose (f); + } + + if (nopts > 0 && *desc != 0) + option_desc[nopts - 1] = strdup (desc); + + if ((f = fopen ("devices.list", "r")) == NULL) + { + perror ("devices.list"); + exit (-1); + } + + if (strcmp (conf->bus, "PCI") == 0) + { + fprintf (src, "static device_id_t id_table[] = {\n"); + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + int vendor, product; + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strncmp (s, "pci", 3) == 0) + { + if (sscanf (s + 3, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad PCI id %s\n", s); + } + + fprintf (src, "\t{0x%x,\t0x%x},\n", vendor, product); + } + + } + + fclose (f); + + fprintf (src, "\t{0}\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + } + +#if 0 + if (strcmp (conf->bus, "USB") == 0) + { + fprintf (src, "#include <linux/mod_devicetable.h>\n\n"); + fprintf (src, "#define strcpy dummy_strcpy\n"); + fprintf (src, "#include <linux/usb.h>\n"); + fprintf (src, "#undef strcpy\n"); + fprintf (src, "static struct usb_device_id udi_usb_table[] = {\n"); + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + int vendor, product; + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (s, "usbif,class1") == 0) + continue; + + if (strncmp (s, "usbi", 4) == 0) + { + if (sscanf (s + 4, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad USB id %s\n", s); + } + + fprintf (src, + "\t{.match_flags=USB_DEVICE_ID_MATCH_DEVICE,\t.idVendor=0x%x,\t.idProduct=0x%x},\n", + vendor, product); + continue; + } + + if (strncmp (s, "usb", 3) == 0) + { + if (sscanf (s + 3, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad USB id %s\n", s); + } + + fprintf (src, + "\t{.match_flags=USB_DEVICE_ID_MATCH_DEVICE,\t.idVendor=0x%x,\t.idProduct=0x%x},\n", + vendor, product); + continue; + } + + + } + + fclose (f); + + fprintf (src, "\t{match_flags:USB_DEVICE_ID_MATCH_INT_CLASS,\n"); + fprintf (src, "\tbInterfaceClass: USB_CLASS_AUDIO},\n"); + fprintf (src, "\t{0}\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + } +#endif /* USB */ + + fprintf (src, "#include \"module.inc\"\n"); + fprintf (src, "\n"); + + if (strcmp (conf->bus, "PCI") == 0) + { + fprintf (src, + "DEFINE_CLASS_0(%s, osspci_driver, osspci_methods, sizeof(struct _oss_device_t));\n", + name); + fprintf (src, + "DRIVER_MODULE(%s, pci, osspci_driver, osspci_devclass, 0, 0);\n", + name); + } + + for (i = 0; i < nopts; i++) + { + fprintf (src, "TUNABLE_INT(\"%s.%s\", &%s);\n", name, options[i], options[i]); +#if 0 + if (option_desc[i] != NULL) + fprintf (src, "MODULE_PARM_DESC(%s, %s);\n", options[i], + option_desc[i]); +#endif + } + fprintf (src, "\n"); + + fclose (src); + + sprintf (tmp, "%s/%s", dirname, cfg_header); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + fprintf (src, "#include <oss_config.h>\n"); + fprintf (src, "\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_STR_INFO\t%s_str_info\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + fprintf (src, "\n"); + + fprintf (src, "extern int DRIVER_ATTACH(oss_device_t *ossdev);\n"); + fprintf (src, "extern int DRIVER_DETACH(oss_device_t *ossdev);\n"); + + fclose (src); +} diff --git a/setup/gen_driver_linux.inc b/setup/gen_driver_linux.inc new file mode 100644 index 0000000..aa8c1b7 --- /dev/null +++ b/setup/gen_driver_linux.inc @@ -0,0 +1,270 @@ +static void +generate_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir) +{ + /* Linux version */ + + FILE *f, *src; + char tmp[256], line[256], *p, *s; + int i, n = 0; + char *options[MAXOPTS]; + char *option_desc[MAXOPTS]; + char desc[65536]; + int nopts = 0; + + sprintf (tmp, "target/build/%s.c", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_PURPOSE\t\"%s\"\n", conf->purpose); + fprintf (src, "#define DRIVER_STR_INFO\t%s_str_info\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + fprintf (src, "\n"); + +/* + * Handle driver specific configuration options + */ + *desc = 0; + sprintf (tmp, "%s/.params", dirname); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + fprintf (src, "%s\n", line); + if (strncmp (line, "int ", 4) == 0) + { + char *s = line + 4, *p = s; + + while (*p && *p != '=' && *p != ';') + p++; + *p = 0; + if (nopts >= MAXOPTS) + { + fprintf (stderr, "Too many options for driver '%s' (%d)\n", + name, nopts); + exit (-1); + } + + if (nopts != 0 && *desc != 0) + option_desc[nopts - 1] = strdup (desc); + option_desc[nopts] = 0; + options[nopts++] = strdup (s); + *desc = 0; + } + else + { + char *s = line, *p; + char tmp[4096]; + while (*s == ' ' || *s == '/' || *s == '*') + s++; + + p = tmp; + + while (*s) + { + if (*s == '"') + *p++ = '\\'; + + *p++ = *s++;; + } + *p = 0; + + p = desc + strlen (desc); + sprintf (p, "\n\"%s\\n\"", tmp); + } + } + + fclose (f); + } + + if (nopts > 0 && *desc != 0) + option_desc[nopts - 1] = strdup (desc); + + if ((f = fopen ("devices.list", "r")) == NULL) + { + perror ("devices.list"); + exit (-1); + } + + if (strcmp (conf->bus, "PCI") == 0) + { + fprintf (src, "#include <linux/mod_devicetable.h>\n\n"); + fprintf (src, "#include <linux/pci_ids.h>\n\n"); + fprintf (src, "static struct pci_device_id id_table[] = {\n"); + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + int vendor, product; + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strncmp (s, "pci", 3) == 0) + { + if (sscanf (s + 3, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad PCI id %s\n", s); + } + + fprintf (src, + "\t{.vendor=0x%x,\t.device=0x%x,\t.subvendor=PCI_ANY_ID,\t.subdevice=PCI_ANY_ID,\t.class=PCI_CLASS_MULTIMEDIA_AUDIO},\n", + vendor, product); + } + + } + + fclose (f); + + fprintf (src, "\t{0}\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + } + + if (strcmp (conf->bus, "USB") == 0) + { + fprintf (src, "#include <linux/mod_devicetable.h>\n\n"); + fprintf (src, "#undef strcpy\n"); + fprintf (src, "#define strcpy dummy_strcpy\n"); + fprintf (src, "#include <linux/usb.h>\n"); + fprintf (src, "#undef strcpy\n"); + fprintf (src, "static struct usb_device_id udi_usb_table[] = {\n"); + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + int vendor, product; + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (s, "usbif,class1") == 0) + continue; + + if (strncmp (s, "usbi", 4) == 0) + { + if (sscanf (s + 4, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad USB id %s\n", s); + } + + fprintf (src, + "\t{.match_flags=USB_DEVICE_ID_MATCH_DEVICE,\t.idVendor=0x%x,\t.idProduct=0x%x},\n", + vendor, product); + continue; + } + + if (strncmp (s, "usb", 3) == 0) + { + if (sscanf (s + 3, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad USB id %s\n", s); + } + + fprintf (src, + "\t{.match_flags=USB_DEVICE_ID_MATCH_DEVICE,\t.idVendor=0x%x,\t.idProduct=0x%x},\n", + vendor, product); + continue; + } + + + } + + fclose (f); + + fprintf (src, "\t{match_flags:USB_DEVICE_ID_MATCH_INT_CLASS,\n"); + fprintf (src, "\tbInterfaceClass: USB_CLASS_AUDIO},\n"); + fprintf (src, "\t{0}\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + } + + fprintf (src, "#include \"module.inc\"\n"); + fprintf (src, "\n"); + + for (i = 0; i < nopts; i++) + { + fprintf (src, "module_param(%s, int, S_IRUGO);\n", options[i]); + if (option_desc[i] != NULL) + fprintf (src, "MODULE_PARM_DESC(%s, %s);\n", options[i], + option_desc[i]); + } + fprintf (src, "\n"); + fprintf (src, "\n"); + + fclose (src); + + sprintf (tmp, "%s/%s", dirname, cfg_header); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + fprintf (src, "#include <oss_config.h>\n"); + fprintf (src, "\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_STR_INFO\t%s_str_info\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + fprintf (src, "\n"); + + fprintf (src, "extern int DRIVER_ATTACH(oss_device_t *ossdev);\n"); + fprintf (src, "extern int DRIVER_DETACH(oss_device_t *ossdev);\n"); + + fclose (src); +} diff --git a/setup/gen_driver_sco.inc b/setup/gen_driver_sco.inc new file mode 100644 index 0000000..279178e --- /dev/null +++ b/setup/gen_driver_sco.inc @@ -0,0 +1,260 @@ +static void +generate_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir) +{ + + /* SCO DDI8 version */ + + + FILE *f, *src; + char tmp[256], line[256], *p, *s; + int i, n = 0; + int is_pseudo = 0; + + if (strcmp (conf->bus, "VIRTUAL") == 0) + is_pseudo = 1; + + sprintf (tmp, "%s/%s", dirname, cfg_name); + + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + fprintf (src, "#include \"%s\"\n", cfg_header); + fprintf (src, "\n"); + + fprintf (src, "#include \"%s/%s/module.inc\"\n", topdir, this_os); + + fclose (src); + + sprintf (tmp, "%s/%s", dirname, cfg_header); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + fprintf (src, "#include <oss_config.h>\n"); + fprintf (src, "\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_PURPOSE\t\"%s\"\n", conf->purpose); + fprintf (src, "#define DRIVER_STR_INFO\t%s_str_info\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + fprintf (src, "\n"); + + fprintf (src, "extern int DRIVER_ATTACH(oss_device_t *ossdev);\n"); + fprintf (src, "extern int DRIVER_DETACH(oss_device_t *ossdev);\n"); + + fclose (src); +/* + * Generate SCO DDI8 specific config files + */ + sprintf (tmp, "target/build/%s", name); + if (mkdir (tmp, 0755) == -1) + { + perror (tmp); + fprintf (stderr, "Cannot make module target directory\n"); + exit (-1); + } + +/* + * Master file + */ + sprintf (tmp, "target/build/%s/Master", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + fprintf (src, "$version 2\n"); + fprintf (src, "$contact 4Front Technologies (http://www.opensound.com)\n"); + fprintf (src, "$interface ddi 8mp\n"); + fprintf (src, "$depend osscore\n"); + + if (is_pseudo) + fprintf (src, "%s - R\n", name); + else + fprintf (src, "%s - h\n", name); + fclose (src); + +/* + * System file + */ + sprintf (tmp, "target/build/%s/System", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + fprintf (src, + "* Don't edit this file manually! This information will be ignored.\n"); + fprintf (src, "*\n"); + fprintf (src, "$version 2\n"); + if (is_pseudo) + fprintf (src, + "%s Y 0 5 0 0 0 0 0 0 -1\n", + name); + else + fprintf (src, + "%s Y 0 5 4 0 0 0 0 0 -1\n", + name); + fclose (src); + +/* + * Node file + */ + sprintf (tmp, "target/build/%s/Node", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + fprintf (src, "$maxchan 255\n"); + fprintf (src, "%s %s%%i c 0 0 0 0600\n", name, + name); + fclose (src); + +/* + * Drvmap file + */ + sprintf (tmp, "target/build/%s/Drvmap", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + fprintf (src, "%s|Y|N|Sound Boards|OSS %s module\n", name, name); + + if (strcmp (conf->bus, "VIRTUAL") == 0) + { + fprintf (src, "|||OSS %s pseudo device\n", name); + } + + if (strcmp (conf->bus, "PCI") == 0) + { + + if ((f = fopen ("devices.list", "r")) == NULL) + { + perror ("devices.list"); + exit (-1); + } + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + int vendor, product; + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strncmp (s, "pci", 3) == 0) + { + if (sscanf (s + 3, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad PCI id %s\n", s); + } + + fprintf (src, "|PCI|0x%04X%04X|%s\n", vendor, product, p); + } + + } + + fclose (f); + } + fclose (src); + +#if 0 +/* + * config.h file + */ + sprintf (tmp, "target/build/%s/config.h", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + fclose (src); +#endif + +/* + * Space.c file + */ + sprintf (tmp, "target/build/%s/Space.c", name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * NOTICE!\n"); + fprintf (src, " *\n"); + + fprintf (src, + " * You need to re-install OSS modules after modifying this file.\n"); + fprintf (src, " * You need to do the following:\n"); + fprintf (src, " *\n"); + fprintf (src, " * \tcd /usr/lib/oss/build\n"); + fprintf (src, " * \tsh install.sh\n"); + fprintf (src, " *\n"); + fprintf (src, " * Each option is documented in the comments below them.\n"); + fprintf (src, " */\n\n"); + +/* + * Handle driver specific configuration options + */ + sprintf (tmp, "%s/.params", dirname); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + fprintf (src, "%s\n", line); + if (strncmp (line, "int ", 4) == 0) + { + char *s = line + 4, *p = s; + + while (*p && *p != '=' && *p != ';') + p++; + *p = 0; + } + } + + fclose (f); + } + + fprintf (src, "\n"); + fclose (src); +} diff --git a/setup/gen_driver_solaris.inc b/setup/gen_driver_solaris.inc new file mode 100644 index 0000000..f0ba96b --- /dev/null +++ b/setup/gen_driver_solaris.inc @@ -0,0 +1,174 @@ +static void +generate_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir) +{ + + /* Solaris version */ + + + FILE *f, *src; + char tmp[256], line[256], *p, *s; + int i, n = 0; + char *options[MAXOPTS]; + int nopts = 0; + + sprintf (tmp, "%s/%s", dirname, cfg_name); + + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + +/* + * Handle driver specific configuration options + */ + sprintf (tmp, "%s/.params", dirname); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + fprintf (src, "%s\n", line); + if (strncmp (line, "int ", 4) == 0) + { + char *s = line + 4, *p = s; + + while (*p && *p != '=' && *p != ';') + p++; + *p = 0; + if (nopts >= MAXOPTS) + { + fprintf (stderr, "Too many options for driver '%s' (%d)\n", + name, nopts); + exit (-1); + } + + options[nopts++] = strdup (s); + } + } + + fclose (f); + } + + fprintf (src, "\n"); + fprintf (src, "#include \"%s\"\n", cfg_header); + fprintf (src, "\n"); + +#if 0 + /* Not needed for Solaris */ + fprintf (src, "oss_device_table_t %s_devid_list[]=\n", name); + fprintf (src, "{\n"); + + if ((f = fopen ("devices.list", "r")) == NULL) + { + perror ("devices.list"); + exit (-1); + } + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + fprintf (src, "\t{\"%s\", \"%s\"},\n", s, p); + } + + fclose (f); + + fprintf (src, "\t{NULL}\n"); + fprintf (src, "};\n"); +#endif + +/* + * Create the driver specific option list + */ + fprintf (src, "oss_option_map_t local_driver_options[] =\n"); + fprintf (src, "{\n"); + for (i = 0; i < nopts; i++) + fprintf (src, "\t{\"%s\", &%s},\n", options[i], options[i]); + fprintf (src, "\t{NULL, NULL}\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + + fprintf (src, "#include \"%s/%s/module.inc\"\n", topdir, this_os); + +#if 0 + if (n == 0) + { + fprintf (stderr, + "Warning: No device entries (devices.list) for driver %s\n", + name); + } +#endif + + fclose (src); + + sprintf (tmp, "%s/%s", dirname, cfg_header); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + fprintf (src, "#include <oss_config.h>\n"); + fprintf (src, "\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_PURPOSE\t\"%s\"\n", conf->purpose); + fprintf (src, "#define DRIVER_STR_INFO\t%s_str_info\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + + if (conf->power_manage) + { + fprintf (src, "#define DRIVER_POWER\t%s_power\n", name); + fprintf (src, "#define OSS_POWER_MANAGE\n"); + } + + if (conf->suspend_resume) + { + fprintf (src, "#define DRIVER_SUSPEND\t%s_suspend\n", name); + fprintf (src, "#define DRIVER_RESUME\t%s_resume\n", name); + fprintf (src, "#define OSS_SUSPEND_RESUME\n"); + } + + fprintf (src, "\n"); + + fprintf (src, "extern int DRIVER_ATTACH(oss_device_t *ossdev);\n"); + fprintf (src, "extern int DRIVER_DETACH(oss_device_t *ossdev);\n"); + fprintf (src, "extern int DRIVER_POWER(oss_device_t *ossdev, int component, int level);\n"); + + fclose (src); +} diff --git a/setup/ossvers.c b/setup/ossvers.c new file mode 100644 index 0000000..a688b2a --- /dev/null +++ b/setup/ossvers.c @@ -0,0 +1,21 @@ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +#include <stdio.h> +#include <oss_version.h> + +int +main (void) +{ + printf (OSS_VERSION_STRING "\n"); + return 0; +} diff --git a/setup/setupdir.sh b/setup/setupdir.sh new file mode 100644 index 0000000..9bb9f37 --- /dev/null +++ b/setup/setupdir.sh @@ -0,0 +1,316 @@ +#!/bin/sh -e + +if test "$CONFIGURE " != "YES " +then + echo + echo Error: Wrong usage + echo + echo You must run `dirname $0`/configure instead of $0 + exit 1 +fi + +[ -z "$CC" ] && CC=cc + +echo srcdir=$SRCDIR + +BLDDIR=`pwd` +OS=`uname -s` + +if test "$TARGETOS " != " " +then + OS=$TARGETOS +fi + +# Use the same source directories for SCO UnixWare and SCO OSR +if test "$OS " = "UnixWare " +then + OS=SCO_SV +fi + +# Use the same source directories for Haiku and BeOS +if test "$OS " = "Haiku " +then + OS=BeOS +fi + +# Use Linux24 as the OS name for Linux 2.4.x +if test "$OS " = "Linux " +then + if test "`uname -r|sed 's/2.//'|sed 's/\..*//'` " = "4 " + then + OS=Linux24 + fi +fi + +# pkg-config seems to crash in some systems so disable core dumps +ulimit -c 0 >/dev/null 2>&1 + +if pkg-config gtk+-2.0 --cflags > /dev/null 2>&1 +then + HAVE_GTK=y + GTK2=1 + export HAVE_GTK GTK2 +else + if gtk-config --cflags > /dev/null 2>&1 + then + HAVE_GTK=y + GTK1=1 + export HAVE_GTK GTK1 + fi +fi + +if test "`ls .` " != " " && test "`ls .` " != ".makefile " +then + echo Error: Current directory must be empty + exit 1 +fi + +if test -f $SRCDIR/setup/setupdir.sh +then + echo Source directory is $SRCDIR + echo Build directory is $BLDDIR +else + echo Error: Invalid source directory $SRCDIR + exit 2 +fi + +# Copy the ".devices" files for all drivers to devices.list +cat `find $SRCDIR/kernel/drv -name .devices`|grep -v '^#' > devices.list + +if test -d $SRCDIR/kernel/nonfree/drv +then + cat `find $SRCDIR/kernel/nonfree/drv -name .devices`|grep -v '^#' >> devices.list +fi + +echo BLDDIR=$BLDDIR > .directories +echo SRCDIR=$SRCDIR >> .directories +echo OSSLIBDIR=$OSSLIBDIR >> .directories + +$CC $LDFLAGS -o dirsetup $SRCDIR/setup/dirsetup.c + +# Make sure the latest soundcard.h version is installed in the system +#rm /usr/include/sys/soundcard.h +#cp $SRCDIR/include/soundcard.h /usr/include/sys/soundcard.h + +if ./dirsetup "$SRCDIR" "$BLDDIR" $* $COPY_OPTIONS +then + echo Build tree created OK +else + echo Cannot create the build tree + rm -f dirsetup + exit 3 +fi + +rm -f dirsetup + +if test "$CLOSED_SOURCE " != "YES " +then + rm -rf kernel/nonfree 4front-private +fi + +if test "$ONLY_DRVS " != " " +then + cd kernel/drv + for drv in * + do + if echo $ONLY_DRVS | grep ",$drv" >/dev/null + then + : + else + touch "$drv"/.nomake + fi + done + cd ../.. + + if test "$CLOSED_SOURCE " = "YES " + then + cd kernel/nonfree/drv + for drv in * + do + if echo $ONLY_DRVS | grep ",$drv" >/dev/null + then + : + else + touch "$drv"/.nomake + fi + done + cd ../../../ + fi +fi + +DTARGETOS= +if ! test -z $TARGETOS +then + DTARGETOS="-D$TARGETOS" +fi + +$CC $LDFLAGS -D`uname -s` $DTARGETOS -o srcconf $SRCDIR/setup/srcconf.c + +if ./srcconf $* +then + echo Source configuration OK +else + echo Source configuration failed +fi + +if test "$CLOSED_SOURCE " != "YES " && test -d $SRCDIR/.hg +then + HGID=`(cd $SRCDIR && hg tip|grep changeset) 2>/dev/null` + + if test "$HGID " != " " + then + echo '#define' OSS_HG_INFO \"$HGID, \" \\ >> kernel/framework/include/local_config.h + + HGID=`(cd $SRCDIR && hg tip|grep tag) 2>/dev/null` + echo ' ' \"$HGID, \" \\ >> kernel/framework/include/local_config.h + + HGID=`(cd $SRCDIR && hg tip|grep date) 2>/dev/null` + echo ' ' \"$HGID, \" \\ >> kernel/framework/include/local_config.h + + HGID=`(cd $SRCDIR && hg tip|grep summary) 2>/dev/null` + echo ' ' \"$HGID\" >> kernel/framework/include/local_config.h + fi + +fi + +if test ! "$OSS_CONFIG_OPTIONS " = " " && test ! "$OSS_CONFIG_OPTIONS " = "--include-closed-source " +then + echo '#define OSS_CONFIG_OPTIONS '\"$OSS_CONFIG_OPTIONS\" >> kernel/framework/include/local_config.h +fi + +if test ! -d target +then + mkdir target +fi + +mkdir target/bin +mkdir target/lib +mkdir target/sbin +mkdir target/modules +mkdir target/objects +mkdir target/tmpobjects + +touch .depend + +if date -u +%Y%m%d%H%M > build.id.new 2>/dev/null +then + rm -f build.id + mv build.id.new build.id + echo "#define OSS_COMPILE_DATE \""`cat build.id`"\"" >> kernel/framework/include/timestamp.h + echo "#define osdev_create osdev_create_`cat build.id`" >> kernel/framework/include/timestamp.h + echo + echo Build ID will become `cat build.id` +else + echo Failed to create the build timestamp + exit 254 +fi + +if test "$CLOSED_SOURCE " = "YES " +then + echo "#define LICENSED_VERSION" >> kernel/framework/include/local_config.h +fi + +if test -f $SRCDIR/buildid.dat +then + echo '#define 'OSS_BUILD_ID \"`cat $SRCDIR/buildid.dat`\" > kernel/framework/include/buildid.h +else + echo $SRCDIR/buildid.dat is missing + exit 10 +fi + +if test ! -d kernel/nonfree || test -f $SRCDIR/kernel/nonfree/.nomake +then + echo '#define __OPENOSS__' >> kernel/framework/include/buildid.h + if test -f $SRCDIR/.license + then + echo '#define OSS_LICENSE "'`cat $SRCDIR/.license`'"' >> kernel/framework/include/buildid.h + else + echo '#define OSS_LICENSE "OSS_HG"' >> kernel/framework/include/buildid.h + fi +fi + +if test "$uOSS " = "1 " +then + echo '#define uOSS' >> kernel/framework/include/buildid.h +fi + +if test "$USE_REGPARM " = "1 " +then + echo "1" > ./regparm +fi + +if test "$NO_REGPARM " = "1 " +then + echo "0" > ./regparm +fi + +# Setup the link to the right os.h file for this operating system. +(cd kernel/framework/include;ln -s ../../../kernel/OS/$OS/os_*.h os.h) + +$CC $LDFLAGS -o ossvers -I./kernel/framework/include setup/ossvers.c +./ossvers > .version +rm ./ossvers + +ln -s $SRCDIR origdir + +if test -f setup/$OS/build_`uname -m`.sh +then + ln -s setup/$OS/build_`uname -m`.sh build.sh +else + if test -f setup/$OS/build.sh + then + ln -s setup/$OS/build.sh build.sh + fi +fi + +if test -f setup/$OS/make.local +then + if test -f Makefile.php + then + echo >> Makefile.php + echo include setup/$OS/make.local >> Makefile.php + else + echo >> Makefile + echo include setup/$OS/make.local >> Makefile + fi +fi +PHPMAKE=phpmake + +if test ! -d phpmake && test -d ../phpmake +then + PHPMAKE=../phpmake +fi + +if test -f Makefile.php && test -d $PHPMAKE +then + echo Running phpmake for all subdirectories - please wait + + if test "$PHPMAKE_LIBPATH " = " " + then + PHPMAKE_LIBPATH="`pwd`/$PHPMAKE/" + + export PHPMAKE_LIBPATH + echo PHPMAKE_LIBPATH not set - assuming $PHPMAKE_LIBPATH + fi + + if test "$PHPMAKE_PROJECT " = " " + then + echo PHPMAKE_PROJECT not set - cannot continue + exit 1 + fi + + phpmake + + (cd targetos && phpmake) + + make kernel/framework/include/ossddk/oss_limits.h # Generate this file from PHh +else + ln -s oss_limits.PHh kernel/framework/include/ossddk/oss_limits.h +fi + +make dep + +echo Directory preparation complete. +echo Build ID will be `cat $SRCDIR/buildid.dat` + +exit 0 diff --git a/setup/srcconf.c b/setup/srcconf.c new file mode 100644 index 0000000..0d37a16 --- /dev/null +++ b/setup/srcconf.c @@ -0,0 +1,1583 @@ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/stat.h> +#include <sys/utsname.h> +#include <errno.h> + +#define MAX_SUBDIRS 64 +#define MAX_OBJECTS 64 +#define MAX_INCLUDES 32 +#define MAXOPTS 64 + +static char *vmix_mode="FIXEDPOINT"; +static char *config_midi="ENABLED"; // Actually this depends on the configure script + +static int exact_architectures=0; /* 1=Compile only drivers that have matching arch given in their .config file. */ + +static int config_phpmake=0; + +typedef struct +{ + char project_name[64]; + char os_name[64]; + int mode; +#define MD_UNDEF 0 +#define MD_USERLAND 1 +#define MD_SBIN 2 +#define MD_KERNEL 3 +#define MD_KERNEL_ 4 +#define MD_MODULE_ 5 +#define MD_MODULE 6 +#define MD_SHLIB 7 + char cflags[256]; + char ldflags[256]; + char OSflags[256]; + int license; +#define LIC_FREE 0 +#define LIC_RESTRICTED 1 + char bus[16]; + char endianess[16]; + char ccomp[256]; + char cplusplus[256]; + char system[32], arch[32], platform[32]; + + unsigned int flags; +#define F_USEARCH 0x00000001 + + + int check_os, os_ok, os_bad; + int check_cpu, cpu_ok, cpu_bad; + int check_endian, endian_ok; + int check_platform, platform_ok; + + int power_manage; /* Supports device power management (under Solaris) */ + int suspend_resume; /* Supports suspend/resume (under Solaris) */ + + char *purpose; +} conf_t; + +#define DEFAULT_CC "cc" + +static conf_t conf = { + "Open Sound System", + "Solaris", + MD_USERLAND, + "", /* cflags */ + "", /* ldflags */ + "", /* OSflags */ + LIC_FREE, + "PCI", /* bus */ + "LITTLE", /* Endianess */ + DEFAULT_CC, /* c compiler */ + "c++" /* cplusplus */ +}; + +static char this_os[64] = "kernel/OS/SunOS"; +static int kernelonly = 0; +static int useronly = 0; +static int do_warning_checks=1; + +static char *shlib_cflags = "-shared -fPIC"; +static char *shlib_ldflags = "-shared -fPIC"; + +static char *extra_libraries = ""; + +char *hostcc; +char *targetcc; + +static int nincludes = 0; +static char *includes[MAX_INCLUDES]; +static int do_cleanup = 0; + +static char arch[32] = ""; + +static void +generate_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir); + +typedef void +(*generate_driver_t) (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir); + +generate_driver_t driver_gen = generate_driver; + +#ifdef linux +#include "srcconf_vxworks.inc" +#include "srcconf_linux.inc" +#endif + +#ifdef __FreeBSD__ +#include "srcconf_freebsd.inc" +#endif + +#ifdef sun +#include "srcconf_vxworks.inc" +#include "srcconf_solaris.inc" +#endif + +#if defined(__BEOS__) || defined(__HAIKU__) +#include "srcconf_beos.inc" +#endif + +static int +parse_config (FILE * f, conf_t * conf, char *comment) +{ + char line[256], *p, *parms; + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + if (*line == '#') /* Comment line */ + continue; + + parms = p = line; + while (*parms && *parms != '=') + parms++; + + if (*parms == '=') + *parms++ = 0; + +#if defined(__BEOS__) || defined(__HAIKU__) + if (strcmp (parms, "-lm") == 0) + { + parms = ""; + } +#endif + + if (strcmp (parms, "$GTKCFLAGS") == 0) + { + parms = ""; + if (getenv ("GTK1") != NULL) + parms = "`gtk-config --cflags` -DGTK1_ONLY"; + else + if (getenv ("GTK2") != NULL) + parms = "`pkg-config gtk+-2.0 --cflags`"; + } + + if (strcmp (parms, "$GTKLDFLAGS") == 0) + { + parms = ""; + if (getenv ("GTK1") != NULL) + parms = "`gtk-config --libs`"; + else + if (getenv ("GTK2") != NULL) + parms = "`pkg-config gtk+-2.0 --libs`"; + } + + if (strcmp (parms, "$DLOPENLDFLAGS") == 0) + { + parms = ""; +#ifndef __FreeBSD__ + if (getenv ("OGG_SUPPORT") != NULL) + parms = "-ldl"; +#endif + } + + if (strcmp (parms, "$OGGDEFINE") == 0) + { + parms = ""; + if (getenv ("OGG_SUPPORT") != NULL) + parms = "-DOGG_SUPPORT"; + } + + if (strcmp (line, "project") == 0) + { + strcpy (conf->project_name, parms); + continue; + } + + if (strcmp (line, "cflags") == 0) + { + strcpy (conf->cflags, parms); + continue; + } + + if (strcmp (line, "ldflags") == 0) + { + strcpy (conf->ldflags, parms); + continue; + } + + if (strcmp (line, "osflags") == 0) + { + if (*conf->OSflags) + strcat (conf->OSflags, " "); + strcat (conf->OSflags, parms); + continue; + } + + if (strcmp (line, "bus") == 0) + { + strcpy (conf->bus, parms); + continue; + } + + if (strcmp (line, "OS") == 0) + { + strcpy (conf->os_name, parms); + continue; + } + + if (strcmp (line, "mode") == 0) + { + if (strcmp (parms, "user") == 0) + { + conf->mode = MD_USERLAND; + continue; + } + + if (strcmp (parms, "sbin") == 0) + { + conf->mode = MD_SBIN; + continue; + } + + if (strcmp (parms, "shlib") == 0) + { + conf->mode = MD_SHLIB; + continue; + } + + if (strcmp (parms, "kernel") == 0) + { + conf->mode = MD_KERNEL; + continue; + } + + if (strcmp (parms, "undefined") == 0) + { + conf->mode = MD_UNDEF; + continue; + } + + if (strcmp (parms, "kernelmode") == 0) + { + conf->mode = MD_KERNEL_; + continue; + } + + if (strcmp (parms, "module") == 0) + { + conf->mode = MD_MODULE_; + continue; + } + + fprintf (stderr, "Bad mode %s\n", parms); + exit (-1); + } + + if (strcmp (line, "license") == 0) + { + if (strcmp (parms, "free") == 0) + conf->license = LIC_FREE; + if (strcmp (parms, "restricted") == 0) + conf->license = LIC_RESTRICTED; + continue; + } + + if (strcmp (line, "depends") == 0) + { + char tmp[64]; + sprintf (tmp, "HAVE_%s", parms); + if (getenv (tmp) == NULL) + { + printf + ("Directory depends on the %s package which is not available\n", + parms); + + return 0; + } + continue; + } + + if (strcmp (line, "configcheck") == 0) + { + if (strcmp (parms, "VMIX") == 0) + { + if (strcmp(vmix_mode, "DISABLED")==0) + { + printf + ("Directory depends on the VMIX subsystem which is not enabled\n"); + + return 0; + } + continue; + } + + if (strcmp (parms, "MIDI") == 0) // Skip if MIDI is disabled + { + if (strcmp(config_midi, "DISABLED")==0) + { + printf + ("Directory depends on the MIDI subsystem which is not enabled\n"); + + return 0; + } + continue; + } + + if (strcmp (parms, "NO_MIDI") == 0) // Skip if MIDI is enabled + { + if (strcmp(config_midi, "DISABLED")!=0) + { + // printf ("Directory not compatible with MIDI subsystem (which is enabled)\n"); + + return 0; + } + continue; + } + + fprintf (stderr, "Unknown configcheck parameter '%s'\n", parms); + exit(-1); + } + + if (strcmp (line, "targetos") == 0) + { + conf->check_os = 1; + if (strcmp (conf->system, parms) == 0) + conf->os_ok = 1; + continue; + } + + if (strcmp (line, "forgetos") == 0) + { + if (strcmp (conf->system, parms) == 0) + conf->os_bad = 1; + continue; + } + + if (strcmp (line, "targetcpu") == 0) + { + conf->check_cpu = 1; + if (strcmp (parms, "any") == 0) + conf->cpu_ok = 1; + else + if (strcmp (conf->arch, parms) == 0) + conf->cpu_ok = 1; + continue; + } + + if (strcmp (line, "forgetcpu") == 0) + { + if (strcmp (conf->arch, parms) == 0) + conf->cpu_bad = 1; + continue; + } + + if (strcmp (line, "endian") == 0) + { + conf->check_endian = 1; + if (strcmp (conf->endianess, parms) == 0) + conf->endian_ok = 1; + continue; + } + + if (strcmp (line, "platform") == 0) + { + conf->check_platform = 1; + if (strcmp (conf->platform, parms) == 0) + conf->platform_ok = 1; + continue; + } + + if (strcmp (line, "pm_support") == 0) + { + conf->power_manage=1; + } + + if (strcmp (line, "suspend_resume") == 0) + { + conf->suspend_resume=1; + } + + if (strcmp (line, "force_endian") == 0) + { + if (strcmp (parms, "BIG") == 0) + { + strcpy (conf->endianess, "BIG"); + } + else + if (strcmp (parms, "LITTLE") == 0) + { + strcpy (conf->endianess, "LITTLE"); + } + else + if (strcmp (parms, "UNKNOWN") == 0) + { + strcpy (conf->endianess, "UNKNOWN"); + } + } + + printf ("\t %s\n", line); + printf ("\t ^\n"); + printf ("\t*** Unknown parameter ***\n"); + } + + if (conf->os_bad) + { + return 0; + } + + if (conf->check_os && !conf->os_ok) + { + return 0; + } + + if (conf->cpu_bad) + { + return 0; + } + + if (conf->check_cpu && !conf->cpu_ok) + { + return 0; + } + + if (conf->check_endian && !conf->endian_ok) + { + return 0; + } + + if (conf->check_platform && !conf->platform_ok) + { + return 0; + } + +/* + * Under some CPU architectures we should compile only the driver modules + * that have proper targetcpu line in their .config file. It doesn't make any + * sense to compile PCI drivers for architectures that don't have any PCI bus. + */ + if (conf->mode == MD_MODULE && exact_architectures && !conf->check_cpu) + { + printf ("Ignoring %s - No CPU specified\n", comment); + return 0; + } + + return 1; +} + +#if defined(linux) +#include "gen_driver_linux.inc" +#endif + +#if defined(__FreeBSD__) +#include "gen_driver_freebsd.inc" +#endif + +#if defined(sun) +#include "gen_driver_solaris.inc" +#endif + +#if defined(__SCO_VERSION__) +#include "gen_driver_sco.inc" +#endif + +#if defined(__BEOS__) || defined(__HAIKU__) +#include "gen_driver_beos.inc" +#endif + +static int +is_cplusplus (char *fname) +{ + while (*fname && *fname != '.') + fname++; + + if (strcmp (fname, ".cpp") == 0) + return 1; + if (strcmp (fname, ".C") == 0) + return 1; + + return 0; +} + +static int +cmpstringp (const void *p1, const void *p2) +{ + /* The arguments to this function are "pointers to + * pointers to char", but strcmp() arguments are "pointers + * to char", hence the following cast plus dereference + */ + + /* + * Make sure "lib" directories get compiles before any other + * subdirectories. + */ + + if (strcmp(*(char **) p1, "lib")==0) + return -1; + else + if (strcmp(*(char **) p2, "lib")==0) + return 1; + + return strcmp (*(char **) p1, *(char **) p2); +} + +static int +scan_dir (char *path, char *name, char *topdir, conf_t * cfg, int level) +{ + int i; + DIR *dir; + struct dirent *de; + struct stat st; + char tmp[256]; + FILE *f; + FILE *cf; + char cfg_name[64]; + char cfg_header[64]; + int cfg_seen = 0; + + conf_t conf; + + int ndirs = 0; + char *subdirs[MAX_SUBDIRS]; + + int nobjects = 0; + char *objects[MAX_OBJECTS], *obj_src[MAX_OBJECTS]; + int nsources = 0; + char *sources[MAX_OBJECTS]; + char obj[128], *p, *suffix; + char *objdir = "OBJDIR"; + int include_local_makefile = 0; + +#define MAX_FILENAME 128 + char *filenames[MAX_FILENAME]; + int n_filenames = 0; + + char tmp_endian[100]=""; + char autogen_sources[1024]=""; + + memcpy (&conf, cfg, sizeof (conf)); + + if (conf.mode == MD_MODULE_) + conf.mode = MD_MODULE; + + if (conf.mode == MD_KERNEL_) + conf.mode = MD_KERNEL; + + sprintf (tmp, "%s/.name", path); + if ((cf = fopen (tmp, "r")) != NULL) + { + char *p; + + if (fgets(tmp, sizeof(tmp)-1, cf)==NULL) + strcpy(tmp, name); + fclose (cf); + + p=tmp+strlen(tmp)-1; + if (*p=='\n')*p=0; + + conf.purpose=strdup(tmp); + } + else + { + conf.purpose=strdup(name); + } + + sprintf (tmp, "%s/.config", path); + if ((cf = fopen (tmp, "r")) != NULL) + { + if (!parse_config (cf, &conf, path)) + { + /* Not compatible with this environment */ + fclose (cf); + return 0; + } + fclose (cf); + } + else + if (conf.mode == MD_MODULE && exact_architectures) /* .config required for this arch */ + { + printf ("Ignoring %s - No CPU specified\n", path); + return 0; + } + + sprintf (tmp, "%s/.nativemake", path); /* Use the existing makefile */ + if (stat (tmp, &st) != -1) + { + return 1; + } + + sprintf (cfg_name, "%s_cfg.c", name); + sprintf (cfg_header, "%s_cfg.h", name); + + sprintf (tmp, "%s/Makefile.%s", path, conf.system); + unlink (tmp); + + sprintf (tmp, "%s/Makefile", path); + unlink (tmp); + + sprintf (tmp, "%s/.nomake", path); + if (stat (tmp, &st) != -1) + return 0; + + sprintf (tmp, "%s/.makefile", path); + if (stat (tmp, &st) != -1) + include_local_makefile = 1; + + if (kernelonly) + if (conf.mode == MD_USERLAND || conf.mode == MD_SBIN) + return 0; + + if (useronly) + if (conf.mode == MD_KERNEL || conf.mode == MD_MODULE || + conf.mode == MD_KERNEL_ || conf.mode == MD_MODULE_) + return 0; + + if (conf.mode == MD_MODULE) + driver_gen (name, &conf, cfg_name, cfg_header, path, topdir); + + if ((dir = opendir (path)) == NULL) + { + perror (path); + fprintf(stderr, "scan_dir(%s): Opendir failed\n", path); + exit (-1); + } + + while ((de = readdir (dir)) != NULL) + { + if (de->d_name[0] == '.') + continue; + + if (n_filenames >= MAX_FILENAME) + { + fprintf (stderr, "Too many files in directory %s\n", path); + exit (-1); + } + + filenames[n_filenames++] = strdup (de->d_name); + } + + qsort (filenames, n_filenames, sizeof (char *), cmpstringp); + + for (i = 0; i < n_filenames; i++) + { + sprintf (tmp, "%s/%s", path, filenames[i]); + if (stat (tmp, &st) == -1) + { + perror (tmp); + continue; + } + + if (S_ISDIR (st.st_mode)) + { + char top[256]; + + if (topdir == NULL) + strcpy (top, ".."); + else + sprintf (top, "../%s", topdir); + + if (scan_dir (tmp, filenames[i], top, &conf, level + 1)) + { + if (ndirs >= MAX_SUBDIRS) + { + fprintf (stderr, "Too many subdirs in %s\n", path); + exit (-1); + } + + subdirs[ndirs++] = strdup (filenames[i]); + } + continue; + } + /* printf("%s/%s\n", path, filenames[i]); */ + + if (nobjects >= MAX_OBJECTS || nsources >= MAX_OBJECTS) + { + fprintf (stderr, "Too many objects in %s\n", path); + exit (-1); + } + + strcpy (obj, filenames[i]); + p = obj; + suffix = ""; + + while (*p) + { + if (*p == '.') + suffix = p; + p++; + } + + if (strcmp (suffix, ".c") == 0) + { + sources[nsources++] = strdup (obj); + if (strcmp (obj, cfg_name) == 0) + cfg_seen = 1; + } + + if (config_phpmake) + { + if (strcmp(suffix, ".PHc") == 0) + { + if (*autogen_sources != 0) + strcat(autogen_sources, " "); + *suffix=0; + strcat(autogen_sources, obj); + strcat(autogen_sources, ".c"); + *suffix='.'; + strcpy(suffix, ".c"); + } + else + if (strcmp(suffix, ".PHh") == 0) + { + if (*autogen_sources != 0) + strcat(autogen_sources, " "); + *suffix=0; + strcat(autogen_sources, obj); + strcat(autogen_sources, ".h"); + *suffix='.'; + } + else + if (strcmp(suffix, ".PHinc") == 0) + { + if (*autogen_sources != 0) + strcat(autogen_sources, " "); + *suffix=0; + strcat(autogen_sources, obj); + strcat(autogen_sources, ".inc"); + *suffix='.'; + } + } + else + { + char source[256], target[256]; + + if (strcmp(suffix, ".PHc") == 0) + { + *suffix=0; + sprintf (source, "%s.PHc", obj); + sprintf (target, "%s/%s.c", path, obj); + *suffix='.'; + if (symlink (source, target) == -1) + { + perror(source); + exit(1); + } + } + else + if (strcmp(suffix, ".PHh") == 0) + { + *suffix=0; + sprintf (source, "%s.PHh", obj); + sprintf (target, "%s/%s.h", path, obj); + *suffix='.'; + if (symlink (source, target) == -1) + { + perror(source); + exit(1); + } + } + else + if (strcmp(suffix, ".PHinc") == 0) + { + *suffix=0; + sprintf (source, "%s.PHinc", obj); + sprintf (target, "%s/%s.inc", path, obj); + *suffix='.'; +printf("Symlink %s -> %s\n", source, target); + if (symlink (source, target) == -1) + { + perror(source); + exit(1); + } + } + } + + if (strcmp (suffix, ".c") == 0 || + strcmp (suffix, ".C") == 0 || strcmp (suffix, ".cpp") == 0) + { + obj_src[nobjects] = strdup (obj); + *suffix = 0; + strcat (obj, ".o"); + objects[nobjects++] = strdup (obj); + } + } + + closedir (dir); + sprintf (tmp, "%s/.depend", path); + unlink (tmp); + sprintf (tmp, "touch %s/.depend", path); + system (tmp); + + if (level == 1 && *this_os && !useronly) + { + subdirs[ndirs++] = strdup (this_os); + } + +#if 0 + // This block is no longer necessary because the driver_gen () call was moved. + // Now the _cfg.c file should get created so that it gets picked by the readdir() loop. + // However keep it here for a while. + if (!cfg_seen && conf.mode == MD_MODULE) + { +# if !defined(linux) && !defined(__FreeBSD__) + sprintf (tmp, "%s_cfg.c", name); + sources[nsources++] = strdup (tmp); + + obj_src[nobjects] = strdup (tmp); + sprintf (tmp, "%s_cfg.o", name); + objects[nobjects++] = strdup (tmp); +# endif + } +#endif + +#if 0 + // This stuff has been moved above the readdir() loop. + if (conf.mode == MD_MODULE) + driver_gen (name, &conf, cfg_name, cfg_header, path, topdir); +#endif + + if (do_cleanup || (ndirs == 0 && nobjects == 0)) + { + return 0; + } + + if (config_phpmake) + sprintf (tmp, "%s/Makefile.php", path); + else + sprintf (tmp, "%s/Makefile", path); + +#if 0 + if ((f = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + if (include_local_makefile) + { + fprintf (f, "\n"); + fprintf (f, "include .makefile\n"); + fprintf (f, "\n"); + } + + fprintf (f, "all:\n"); + fprintf (f, + "\t$(MAKE) $(BUILDFLAGS) BUILDFLAGS=\"$(BUILDFLAGS)\" -f Makefile.`uname -s` all\n\n"); + + fprintf (f, "config:\n"); + fprintf (f, + "\t$(MAKE) $(BUILDFLAGS) BUILDFLAGS=\"$(BUILDFLAGS)\" -f make.defs config\n\n"); + + fprintf (f, "purge:\n"); + fprintf (f, + "\t$(MAKE) $(BUILDFLAGS) BUILDFLAGS=\"$(BUILDFLAGS)\" -f make.defs purge\n\n"); + + fprintf (f, "dirs:\n"); + fprintf (f, + "\t$(MAKE) $(BUILDFLAGS) BUILDFLAGS=\"$(BUILDFLAGS)\" -f Makefile.`uname -s` dirs\n\n"); + + fprintf (f, "clean:\n"); + fprintf (f, + "\t$(MAKE) $(BUILDFLAGS) BUILDFLAGS=\"$(BUILDFLAGS)\" -f Makefile.`uname -s` clean\n\n"); + + fprintf (f, "lint:\n"); + fprintf (f, + "\t$(MAKE) $(BUILDFLAGS) BUILDFLAGS=\"$(BUILDFLAGS)\" -f Makefile.`uname -s` lint\n\n"); + + fprintf (f, "dep:\n"); + fprintf (f, + "\t$(MAKE) $(BUILDFLAGS) BUILDFLAGS=\"$(BUILDFLAGS)\" -f Makefile.`uname -s` dep\n\n"); + + fclose (f); + + sprintf (tmp, "%s/Makefile.%s", path, conf.system); +#endif + if ((f = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (f, "# Makefile for %s module %s\n\n", conf.project_name, name); + + if (config_phpmake) + fprintf (f, "<?php require getenv(\"PHPMAKE_LIBPATH\") . \"library.php\"; phpmake_makefile_top_rules(); ?>\n"); + + fprintf (f, "CC=%s\n", conf.ccomp); + // fprintf (f, "LD=ld\n"); + fprintf (f, "HOSTCC=%s\n", hostcc); + fprintf (f, "CPLUSPLUS=%s\n", conf.cplusplus); + +#ifdef VXWORKS + vxworks_genheader (f, path); +#endif + +#if defined(__SCO_VERSION__) + if (*conf.cflags != 0) + fprintf (f, "CFLAGS=%s\n", conf.cflags); +#endif + if (*conf.ldflags != 0) + fprintf (f, "LDFLAGS=%s\n", conf.ldflags); + + if (strcmp(conf.endianess, "UNKNOWN") != 0) + sprintf (tmp_endian, " -DOSS_%s_ENDIAN", conf.endianess); + + fprintf (f, "OSFLAGS=%s%s\n", conf.OSflags, tmp_endian); + + fprintf (f, "OS=%s\n", conf.system); + fprintf (f, "ARCH=%s\n", conf.arch); + + if (topdir == NULL) + fprintf (f, "TOPDIR=.\n"); + else + fprintf (f, "TOPDIR=%s\n", topdir); + + fprintf (f, "OBJDIR=$(TOPDIR)/target/objects\n"); + fprintf (f, "TMPDIR=.\n"); + fprintf (f, "MODDIR=$(TOPDIR)/target/modules\n"); + fprintf (f, "BINDIR=$(TOPDIR)/target/bin\n"); + fprintf (f, "LIBDIR=$(TOPDIR)/target/lib\n"); + fprintf (f, "SBINDIR=$(TOPDIR)/target/sbin\n"); + if ((p = getenv("OSSLIBDIR")) != NULL) + fprintf (f, "OSSLIBDIR=\"%s\"\n", p); + + fprintf (f, "THISOS=%s\n", this_os); + + if (config_phpmake) + fprintf (f, "CFLAGS+=-D__USE_PHPMAKE__\n"); + + if (conf.mode == MD_KERNEL || conf.mode == MD_MODULE) + { +#if defined(__SCO_VERSION__) + fprintf (f, "CFLAGS=-O -D_KERNEL -D_DDI=8\n"); +#else + fprintf (f, "CFLAGS += -D_KERNEL\n"); +#endif +#ifdef HAVE_KERNEL_FLAGS + add_kernel_flags (f); +#endif + } +#ifndef __SCO_VERSION__ + else + { + fprintf (f, "CFLAGS+=-O\n"); + } +#endif + +#if !defined(__SCO_VERSION__) + if (*conf.cflags != 0) + fprintf (f, "CFLAGS += %s\n", conf.cflags); + if (conf.mode == MD_SHLIB) + fprintf (f, "CFLAGS += %s\n", shlib_cflags); +#endif + if (conf.mode != MD_KERNEL) + objdir = "TMPDIR"; + + if (nincludes > 0) + { + int i; + fprintf (f, "INCLUDES="); + for (i = 0; i < nincludes; i++) + { + if (i > 0) + fprintf (f, " "); + if (includes[i][0] == '/') + fprintf (f, "%s", includes[i]); + else + fprintf (f, "-I$(TOPDIR)/%s", includes[i]); + } + fprintf (f, "\n"); + } + + if (ndirs > 0) + { + int i; + + if (config_phpmake) + { + fprintf (f, "<?php\n"); + fprintf (f, "\t$subdirs=array("); + for (i = 0; i < ndirs; i++) + { + if (i > 0) + fprintf (f, ", "); + fprintf (f, "\"%s\"", subdirs[i]); + } + fprintf (f, ");\n"); + fprintf (f, "phpmake_print_subdirs($subdirs);\n"); + fprintf (f, "?>\n"); + } + else + { + fprintf (f, "SUBDIRS="); + for (i = 0; i < ndirs; i++) + { + if (i > 0) + fprintf (f, " "); + fprintf (f, "%s", subdirs[i]); + } + fprintf (f, "\n"); + } + } + + if (nobjects > 0) + { + int i; + + fprintf (f, "OBJECTS="); + + for (i = 0; i < nobjects; i++) + { + if (i > 0) + fprintf (f, " "); + fprintf (f, "$(%s)/%s", objdir, objects[i]); + } + + fprintf (f, "\n"); + } + + if (conf.mode == MD_MODULE) + { + fprintf (f, "TARGETS=$(MODDIR)/%s $(MODDIR)/%s.o\n", name, name); + fprintf (f, "DEPDIR=$(TMPDIR)\n"); + } + else if ((conf.mode == MD_USERLAND) && nobjects > 0) + { + fprintf (f, "TARGETS=$(BINDIR)/%s\n", name); + fprintf (f, "DEPDIR=$(BINDIR)/\n"); + } + else if ((conf.mode == MD_SBIN) && nobjects > 0) + { + fprintf (f, "TARGETS=$(SBINDIR)/%s\n", name); + fprintf (f, "DEPDIR=$(SBINDIR)/\n"); + } + else + { + fprintf (f, "TARGETS=%s\n", name); + fprintf (f, "DEPDIR=\n"); + } + + if (nsources > 0) + { + int i; + + fprintf (f, "CSOURCES="); + + for (i = 0; i < nsources; i++) + { + if (i > 0) + fprintf (f, " "); + fprintf (f, "%s", sources[i]); + } + + fprintf (f, "\n"); + } + + if (*autogen_sources != 0) + fprintf (f, "AUTOGEN_SOURCES=%s\n", autogen_sources); + + fprintf (f, "\n"); + + if (include_local_makefile) + { + fprintf (f, "include .makefile\n"); + fprintf (f, "\n"); + } + + if (config_phpmake) + fprintf (f, "<?php phpmake_makefile_rules(); ?>\n"); + /* + * Create the default target + */ + fprintf (f, "all: "); + + if (conf.mode == MD_USERLAND && nsources > 0) + { + fprintf (f, "$(TARGETS) "); + } + else if (conf.mode == MD_MODULE) + { + if (nobjects > 0) + fprintf (f, "$(MODDIR)/%s.o ", name); + } + else if (conf.mode == MD_SHLIB) + { + fprintf (f, "$(LIBDIR)/%s.so ", name); + } + else if (conf.mode != MD_KERNEL) + { + if (nobjects > 0) + { + if (conf.mode == MD_SBIN) + fprintf (f, "$(SBINDIR)/%s ", name); + else + fprintf (f, "$(BINDIR)/%s ", name); + } + } + else + { + if (nobjects > 0) + fprintf (f, "$(AUTOGEN_SOURCES) objects "); + } + + if (ndirs > 0) + fprintf (f, "subdirs "); + fprintf (f, "\n"); +#if 0 + if (level == 1) + fprintf (f, + "\t-sh $(THISOS)/build.sh \"$(ARCH)\" \"$(INCLUDES)\" \"$(CFLAGS)\"\n"); + fprintf (f, "\n"); +#endif + + /* + * Create the lint target + */ + fprintf (f, "lint: "); + if (nobjects > 0) + fprintf (f, "lint_sources "); + if (ndirs > 0) + fprintf (f, "lint_subdirs "); + fprintf (f, "\n\n"); + + /* + * Create the dep target + */ + fprintf (f, "dep: "); + if (nobjects > 0) + fprintf (f, "$(AUTOGEN_SOURCES) dep_local "); + if (ndirs > 0) + fprintf (f, "dep_subdirs "); + fprintf (f, "\n\n"); + + fprintf (f, "include $(TOPDIR)/make.defs\n"); + fprintf (f, "\n"); + + if (conf.mode == MD_USERLAND) + { + fprintf (f, "%s:\t$(BINDIR)/%s\n\n", name, name); + + fprintf (f, "$(BINDIR)/%s:\t$(OBJECTS)\n", name); + fprintf (f, + "\t$(CC) $(CFLAGS) -s -o $(BINDIR)/%s $(OBJECTS) $(LIBRARIES) $(LDFLAGS) %s\n", + name, extra_libraries); + fprintf (f, "\n\n"); + } + + if (conf.mode == MD_SHLIB) + { + fprintf (f, "%s.so:\t$(LIBDIR)/%s.so\n\n", name, name); + + fprintf (f, "$(LIBDIR)/%s.so:\t$(OBJECTS)\n", name); +#if defined(linux) + /* gcc -shared works much better than ld on Linux */ + fprintf (f, + "\t$(CC) $(LDFLAGS) %s -o $(LIBDIR)/%s.so $(OBJECTS)\n", + shlib_cflags, name); +#else + fprintf (f, + "\t$(LD) $(LDFLAGS) %s -o $(LIBDIR)/%s.so $(OBJECTS)\n", + shlib_ldflags, name); +#endif + fprintf (f, "\n\n"); + } + + if (conf.mode == MD_SBIN) + { + fprintf (f, "%s:\t$(SBINDIR)/%s\n\n", name, name); + + fprintf (f, "$(SBINDIR)/%s:\t$(OBJECTS)\n", name); + fprintf (f, + "\t$(CC) $(CFLAGS) -s -o $(SBINDIR)/%s $(OBJECTS) $(LIBRARIES) $(LDFLAGS) %s\n", + name, extra_libraries); + fprintf (f, "\n\n"); + } + + if (conf.mode == MD_MODULE) + { + fprintf (f, "$(MODDIR)/%s.o:\t$(OBJECTS)\n", name); + fprintf (f, "\t$(LD) $(LDARCH) -r -o $(MODDIR)/%s.o $(OBJECTS)\n", + name); + fprintf (f, "\n\n"); + } + + if (nobjects > 0) + { + int i; + + for (i = 0; i < nobjects; i++) + { + fprintf (f, "$(%s)/%s:\t%s\n", objdir, objects[i], obj_src[i]); + + if (is_cplusplus (obj_src[i])) + fprintf (f, + "\t$(CPLUSPLUS) -c $(CFLAGS) $(OSFLAGS) $(INCLUDES) %s -o $(%s)/%s\n", + obj_src[i], objdir, objects[i]); + else + fprintf (f, + "\t$(CC) -c $(CFLAGS) $(OSFLAGS) $(LIBRARIES) $(INCLUDES) %s -o $(%s)/%s\n", + obj_src[i], objdir, objects[i]); + fprintf (f, "\n"); + } + } + + fprintf (f, "clean: clean_local"); + if (ndirs > 0) + fprintf (f, " clean_subdirs"); + fprintf (f, "\n\n"); + + fclose (f); + return 1; +} + +static int already_configured = 0; + +static void +produce_output (conf_t * conf) +{ + if (already_configured) + return; + + scan_dir (".", "main", NULL, conf, 1); + scan_dir (this_os, "main", "../../..", conf, 3); + + symlink (this_os, "targetos"); + + already_configured = 1; +} + +static void +check_endianess (conf_t * conf) +{ + unsigned char probe[4] = { 1, 2, 3, 4 }; + + if ((*(unsigned int *) &probe) == 0x01020304) + { + strcpy (conf->endianess, "BIG"); + } + else + { + strcpy (conf->endianess, "LITTLE"); + } +} + +static void +produce_local_config_h (conf_t * conf) +{ +/* + * Produce local_config.h + */ + int grc_min=3, grc_max=3; // GRC3 min/max quality settings + + FILE *f; + char *p; + int q; + + if ((f=fopen ("kernel/framework/include/local_config.h", "w"))==NULL) + { + perror ("kernel/framework/include/local_config.h"); + exit(-1); + } + + fprintf (f, "/*\n"); + fprintf (f, " * Automatically generated by the configure script (srcconf.c) - Do not edit.\n"); + fprintf (f, "*/\n"); + +/* + * GRC3 sample rate converter min/max quality settings + */ + if ((p=getenv("GRC_MIN_QUALITY"))!= NULL) + { + if (sscanf(p, "%d", &q) != 1) + { + fprintf (stderr, "Bad GRC_MIN_QUALITY '%s'\n", p); + exit (EXIT_FAILURE); + } + + if (q >= 0 && q <= 6) + grc_min = q; + } + + if ((p=getenv("GRC_MAX_QUALITY"))!= NULL) + { + if (sscanf(p, "%d", &q) != 1) + { + fprintf (stderr, "Bad GRC_MAX_QUALITY '%s'\n", p); + exit (EXIT_FAILURE); + } + + if (q >= 0 && q <= 6) + grc_max = q; + } + + if (grc_max < grc_min) + grc_max = grc_min = 3; + + fprintf (f, "#define CONFIG_OSS_GRC_MIN_QUALITY %d\n", grc_min); + fprintf (f, "#define CONFIG_OSS_GRC_MAX_QUALITY %d\n", grc_max); + +/* + * Generate VMIX configuration + */ + + if (strcmp (vmix_mode, "DISABLED") == 0) + { + fprintf (f, "#undef CONFIG_OSS_VMIX\n"); + } + else + { + fprintf (f, "#define CONFIG_OSS_VMIX\n"); + + if (strcmp (vmix_mode, "FLOAT") == 0) + fprintf (f, "#define CONFIG_OSS_VMIX_FLOAT\n"); + else + fprintf (f, "#undef CONFIG_OSS_VMIX_FLOAT\n"); + } + +/* + * Generate MIDI configuration + */ + + if (strcmp (config_midi, "DISABLED") == 0) + fprintf (f, "#undef CONFIG_OSS_MIDI\n"); + else + fprintf (f, "#define CONFIG_OSS_MIDI\n"); + +/* + * Enable DO_TIMINGS code + */ + + if (getenv("DO_TIMINGS") != NULL) + fprintf (f, "#define DO_TIMINGS\n"); + + fclose (f); +} + +static void +produce_errno_h(void) +{ + FILE *f; + +/* + * Generate oss_errno.h that contains all the errno.h codes used by OSS + * but defined as negative numbers. + */ + + if ((f=fopen ("kernel/framework/include/oss_errno.h", "w"))==NULL) + { + perror ("kernel/framework/include/oss_errno.h"); + exit(-1); + } +#define GEN_ERRNO(e) \ + fprintf (f, "#define OSS_"#e"\t\t%d\n", (e<=0) ? e : -(e)); + + fprintf (f, "#ifndef OSS_ERRNO_H\n"); + fprintf (f, "#define OSS_ERRNO_H\n"); + fprintf (f, "\n"); + fprintf (f, "/*\n"); + fprintf (f, " * Error (errno) codes used by OSS.\n"); + fprintf (f, " * \n"); + fprintf (f, " * This file is automatically generated by srcconf.c (produce_errno_h()) - do not edit.\n"); + fprintf (f, " * \n"); + fprintf (f, " * The following codes are derived from the system dependent\n"); + fprintf (f, " * error numbers defined in <errno.h>\n"); + fprintf (f, " */\n"); + fprintf (f, "\n"); + +#ifndef EBADE /* Not in FreeBSD, Haiku */ +#define EBADE EINVAL +#endif + +#ifndef EIDRM /* Not in POSIX, but is in SuS */ +#define EIDRM EFAULT +#endif + +#ifndef ENOTSUP /* Not in Haiku */ +#define ENOTSUP ENOSYS +#endif + +#ifndef EFAULT +#define EFAULT ENOTSUP +#endif + + GEN_ERRNO(E2BIG); + GEN_ERRNO(EACCES); + GEN_ERRNO(EAGAIN); + GEN_ERRNO(EBADE); + GEN_ERRNO(EBUSY); + GEN_ERRNO(ECONNRESET); + GEN_ERRNO(EDOM); + GEN_ERRNO(EFAULT); + GEN_ERRNO(EIDRM); + GEN_ERRNO(EINTR); + GEN_ERRNO(EINVAL); + GEN_ERRNO(EIO); + GEN_ERRNO(ELOOP); + GEN_ERRNO(ENODEV); + GEN_ERRNO(ENOENT); + GEN_ERRNO(ENOMEM); + GEN_ERRNO(ENOSPC); + GEN_ERRNO(ENOTSUP); + GEN_ERRNO(ENXIO); + GEN_ERRNO(EPERM); + GEN_ERRNO(EPIPE); + GEN_ERRNO(ERANGE); + GEN_ERRNO(EWOULDBLOCK); + + fprintf (f, "\n"); + fprintf (f, "#endif\n"); + fclose(f); +} + +static void +check_system (conf_t * conf) +{ + struct utsname un; + char *p; + + if (uname (&un) == -1) + { + perror ("uname"); + exit (-1); + } + + if (strcmp (un.sysname, "UnixWare") == 0) + strcpy (un.sysname, "SCO_SV"); + if (strcmp (un.sysname, "Haiku") == 0) + strcpy (un.sysname, "BeOS"); + printf ("System: %s\n", un.sysname); + strcpy (conf->system, un.sysname); + sprintf (this_os, "kernel/OS/%s", un.sysname); + printf ("Release: %s\n", un.release); + printf ("Machine: %s\n", un.machine); + strcpy (conf->arch, un.machine); + +#ifdef HAVE_SYSDEP + check_sysdep (conf, &un); +#else + +# if defined(__SCO_VERSION__) + shlib_ldflags = "-G -lsocket -lnsl"; +# endif + + if (strcmp (un.machine, "i386") == 0 || + strcmp (un.machine, "i486") == 0 || + strcmp (un.machine, "i586") == 0 || strcmp (un.machine, "i686") == 0) + { + strcpy (conf->platform, "i86pc"); + } + else + { + fprintf (stderr, "Cannot determine the platform for %s\n", un.machine); + exit (-1); + } +#endif + + if (*conf->platform == 0) + { + fprintf (stderr, "Panic: No platform\n"); + exit (-1); + } + + check_endianess (conf); + +/* + * Check virtual mixer configuration (as set by the configure script). + */ + + if ((p=getenv("VMIX_MODE"))!=NULL) + { + vmix_mode = strdup(p); + } + +/* + * Check MIDI enabled/disabled status + */ + + if ((p=getenv("CONFIG_MIDI"))!=NULL) + { + config_midi = strdup(p); + } + + produce_local_config_h (conf); +} + +int +main (int argc, char *argv[]) +{ + int i; + char tmp[256], *env; + + struct stat st; + + if (getenv("USE_PHPMAKE") != NULL) + if (stat("phpmake/library.php", &st) != -1) + config_phpmake=1; + + for (i = 1; i < argc; i++) + if (argv[i][0] == '-') + switch (argv[i][1]) + { + case 'A': + strcpy (arch, &argv[i][2]); + printf ("Arch=%s\n", arch); + break; + case 'K': + kernelonly = 1; + break; /* Compile only the kernel mode parts */ + case 'U': + useronly = 1; + break; /* Compile only the user land utilities */ + } + + if (getenv("NO_WARNING_CHECKS")!=NULL) + do_warning_checks = 0; + + hostcc = getenv ("HOSTCC"); + targetcc = getenv ("CC"); + if (hostcc == NULL) hostcc = DEFAULT_CC; + if (targetcc == NULL) targetcc = DEFAULT_CC; + +#if defined(linux) || defined(__FreeBSD__) || defined(__SCO_VERSION__) + mkdir ("target", 0755); + mkdir ("target/build", 0755); + system ("touch target/build/.nomake"); +#endif + + if (getenv ("SOL9") != NULL) + system ("touch kernel/drv/oss_usb/.nomake"); + + check_system (&conf); + +/* + * Check if setup/$CROSSCOMPILE.conf exists and load the settings in it. + */ + if ((env=getenv("CROSSCOMPILE"))!=NULL) + { + FILE *cf; + + sprintf (tmp, "setup/%s.conf", env); + if ((cf = fopen (tmp, "r")) != NULL) + { + parse_config (cf, &conf, tmp); + fclose (cf); + } + } + + + produce_output (&conf); + + produce_errno_h(); + exit (0); +} diff --git a/setup/srcconf_beos.inc b/setup/srcconf_beos.inc new file mode 100644 index 0000000..8083e50 --- /dev/null +++ b/setup/srcconf_beos.inc @@ -0,0 +1,34 @@ +#define HAVE_SYSDEP +#define HAVE_KERNEL_FLAGS +static void +check_sysdep (conf_t * conf, struct utsname *un) +{ + strcpy (conf->cplusplus, "g++ -fno-rtti -fno-exceptions -I."); + + /* fixup machine names */ + if (strcmp (un->machine, "BePC") == 0) + { + strcpy (conf->arch, "i586"); + } + if (strcmp (un->machine, "BePC") == 0 || + strcmp (un->machine, "i386") == 0 || + strcmp (un->machine, "i486") == 0 || + strcmp (un->machine, "i586") == 0 || strcmp (un->machine, "i686") == 0) + { + strcpy (conf->platform, "i86pc"); + } + if (strcmp (un->machine, "BeMac") == 0 || + strcmp (un->machine, "BeBox") == 0) + { + /* seems to be what Linux uses */ + /* XXX: check for ppc64 ? */ + strcpy (conf->arch, "ppc"); + strcpy (conf->platform, "ppc"); + } +} + +static void +add_kernel_flags (FILE * f) +{ + fprintf (f, "CFLAGS=-O2 -D_KERNEL -D_KERNEL_MODE=1 -no-fpic\n"); +} diff --git a/setup/srcconf_freebsd.inc b/setup/srcconf_freebsd.inc new file mode 100644 index 0000000..273a213 --- /dev/null +++ b/setup/srcconf_freebsd.inc @@ -0,0 +1,17 @@ +#define HAVE_SYSDEP +#define HAVE_KERNEL_FLAGS +static void +check_sysdep (conf_t * conf, struct utsname *un) +{ + strcpy (conf->cplusplus, "g++ -fno-rtti -fno-exceptions -I."); + strcpy (conf->platform, "i86pc"); +} + +static void +add_kernel_flags (FILE * f) +{ +# if defined(__x86_64__) + fprintf (f, + "CFLAGS += -O3 -fno-common -mcmodel=kernel -mno-red-zone -fno-asynchronous-unwind-tables -ffreestanding\n"); +# endif +} diff --git a/setup/srcconf_linux.inc b/setup/srcconf_linux.inc new file mode 100644 index 0000000..319b568 --- /dev/null +++ b/setup/srcconf_linux.inc @@ -0,0 +1,70 @@ +static char * fnsp = " -fno-stack-protector"; + +#define HAVE_SYSDEP +#define HAVE_KERNEL_FLAGS +static void +check_sysdep (conf_t * conf, struct utsname *un) +{ + char *p; + + char cmd[512]; + +#ifndef __arm__ + vmix_mode = "FLOAT"; +#else + exact_architectures = 1; /* Compile only the drivers with targetcpu=arm */ +#endif + + if ((p=getenv("CROSSCOMPILE"))!=NULL) + { + if (strcmp(p, "uclinux-blackfin")==0) + { + hostcc="cc"; + targetcc="uclinux-blackfin-gcc"; + } +#ifdef VXWORKS + else if (strcmp(p, "vxworks-x86")==0) + { + vxworks_setup(conf, "386"); + } +#endif + } + + /* + * Check if cc supports -fno-stack-protector + */ + sprintf (cmd, "%s -c -o srcconf.o -fno-stack-protector setup/srcconf.c >/dev/null 2>&1", targetcc); + if (system(cmd)) + { + fnsp = ""; + } + + if (do_warning_checks) + strcpy(conf->OSflags, "-Wall"); + strcpy (conf->ccomp, targetcc); + strcpy (conf->cplusplus, "g++ -fno-rtti -fno-exceptions -I."); + strcpy (conf->platform, "i86pc"); +} + +static void +add_kernel_flags (FILE * f) +{ +# if defined(__x86_64__) + fprintf (f, + "CFLAGS += -O3 -fno-common -mcmodel=kernel -mno-red-zone -fno-asynchronous-unwind-tables -ffreestanding%s\n", fnsp); +# else +# ifndef __arm__ + if (getenv ("NO_REGPARM") == NULL) + { + fprintf (f, + "CFLAGS += -O3 -fno-common -ffreestanding -mregparm=3 -DUSE_REGPARM%s\n", fnsp); + } + else + { + fprintf (f, "CFLAGS += -O3 -fno-common -ffreestanding -DNO_REGPARM%s\n", fnsp); + } +# else + fprintf (f, "CFLAGS += -O3 -fno-common -ffreestanding%s\n", fnsp); +# endif +# endif +} diff --git a/setup/srcconf_solaris.inc b/setup/srcconf_solaris.inc new file mode 100644 index 0000000..3478548 --- /dev/null +++ b/setup/srcconf_solaris.inc @@ -0,0 +1,146 @@ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +/*#define USE_GCC*/ +#define HAVE_SYSDEP +/* #define HAVE_KERNEL_FLAGS */ +#include <sys/systeminfo.h> +static void +check_sysdep (conf_t * conf, struct utsname *un) +{ + char tmp[64], *p; + + conf->flags |= F_USEARCH; +#ifdef USE_GCC + strcpy (conf->ccomp, "gcc -Wall -O"); +#else + +# if 0 +// Using -fast seems to cause crash if OSS is compiled with certain version of Sun Studio. +// The produced binary uses some instructions that are not permitted in kernel mode. For this reason +// -fast cannot be used at this moment. + + if (getenv("PORTABLE_BUILD") != NULL) + strcpy (conf->ccomp, "cc -xO5"); /* Produce code for generic target */ + else + strcpy (conf->ccomp, "cc -fast"); /* Optimize for the current system/arch */ +# else + strcpy (conf->ccomp, "cc -xO5"); /* Produce code for generic target */ +# endif + + shlib_cflags = "-Bdynamic -Kpic"; + shlib_ldflags = "-G -z text"; +#endif + + extra_libraries = "-lnsl -lsocket -lresolv"; + strcpy (conf->cplusplus, + "CC -DNO_BUILTINS -I. -features=no%except -xvector=no"); + + if (sysinfo (SI_ARCHITECTURE, tmp, sizeof (tmp)) == -1) + { + perror ("sysinfo SI_ARCHITECTURE"); + exit (-1); + } + printf ("Arch: %s\n", tmp); + + if (getenv ("SOL9") != NULL) + strcat (conf->OSflags, "-DSOL9 "); + + if (*arch) + strcpy (tmp, arch); + printf ("Arch K: %s\n", tmp); + strcpy (conf->arch, tmp); + +#ifdef USE_GCC + if (strcmp (tmp, "amd64") == 0) + { + strcpy (conf->OSflags, "-m64 -fno-common -mcmodel=kernel -mno-red-zone"); + strcpy (conf->platform, "i86pc"); + } + else if (strcmp (tmp, "sparcv9") == 0) + { + strcpy (conf->OSflags, "-m64"); + strcpy (conf->platform, "sparc"); + } + else if (strcmp (tmp, "sparc") == 0) + { + strcpy (conf->OSflags, "-Dsparc32"); + strcpy (conf->platform, "sparc"); + } + else if (strcmp (tmp, "i386") == 0) + { + strcpy (conf->OSflags, "-m32"); + strcpy (conf->platform, "i86pc"); + } + else + { + strcpy (conf->OSflags, "-xarch=$(ARCH)"); + fprintf (stderr, "Cannot determine platform for '%s'\n", tmp); + exit (-1); + } +#else + if (strcmp (tmp, "amd64") == 0) + { +#if (__SUNPRO_C >= 0x590) + strcpy (conf->OSflags, "-m64 -xmodel=kernel"); +#else + strcpy (conf->OSflags, "-xarch=$(ARCH) -xmodel=kernel"); +#endif + strcpy (conf->platform, "i86pc"); + strcpy (conf->platform, "i86pc"); + } + else if (strcmp (tmp, "sparcv9") == 0) + { + strcpy (conf->OSflags, "-xarch=v9 -dalign"); + strcpy (conf->platform, "sparc"); + } + else if (strcmp (tmp, "sparc") == 0) + { + strcpy (conf->OSflags, "-Dsparc32"); + strcpy (conf->platform, "sparc"); + } + else if (strcmp (tmp, "i386") == 0) + { +#if (__SUNPRO_C >= 0x590) + strcpy (conf->OSflags, "-m32"); +#else + strcpy (conf->OSflags, "-xarch=386"); +#endif + strcpy (conf->platform, "i86pc"); + } + else + { + strcpy (conf->OSflags, "-xarch=$(ARCH)"); + fprintf (stderr, "Cannot determine platform for '%s'\n", tmp); + exit (-1); + } +#endif + + if (getenv ("SOL9") != NULL) + strcat (conf->OSflags, " -DSOL9"); + + if ((p=getenv("CROSSCOMPILE"))!=NULL) + { + if (strcmp(p, "vxworks-x86")==0) + { + vxworks_setup(conf, "386"); + } + } +} + +static void +add_kernel_flags (FILE * f) +{ +#if 0 + /* fprintf(f, "CFLAGS += -xmodel=kernel\n"); */ +#endif +} diff --git a/setup/srcconf_vxworks.inc b/setup/srcconf_vxworks.inc new file mode 100644 index 0000000..d3a660d --- /dev/null +++ b/setup/srcconf_vxworks.inc @@ -0,0 +1,245 @@ +static void +generate_vxworks_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir); + +static void +vxworks_setup(conf_t *conf, char *arch) +{ +#ifndef linux + char tmp[256]; +#endif + + printf ("\n*** Setting up cross compiling for VxWorks %s target ***\n\n", arch); + + hostcc="cc"; + +#ifdef linux + targetcc="ccpentium"; +#else + sprintf(tmp, "cc%s", arch); + targetcc=strdup(tmp); +#endif + strcpy(conf->OSflags, ""); + strcpy(conf->platform, "vxworks"); + strcpy(conf->ccomp, targetcc); + strcpy(this_os, "kernel/OS/VxWorks"); + strcpy(conf->system, "VxWorks"); + strcpy(conf->arch, arch); + sprintf(conf->cplusplus, "c++%s", arch); + + shlib_cflags = "-shared -fPIC"; + shlib_ldflags = "-shared -fPIC"; + + strcpy (conf->endianess, "LITTLE"); // TODO + + driver_gen = generate_vxworks_driver; +} + +static void +vxworks_genheader(FILE *f, char *path) +{ +#ifdef linux + fprintf (f, "\n"); + fprintf (f, "WIND_BASE=/WindRiver/vxworks-6.6\n"); + fprintf (f, "LD=ldpentium\n"); + fprintf (f, "AR=arpentium\n"); + fprintf (f, "CFLAGS+=-mpentium -nostdinc -O2 -fvolatile -nostdlib -fno-builtin -fno-defer-pop -Wall -I$(WIND_BASE)/target/config/all -I-I/WindRiver/vxworks-6.6/target/h/wrn/coreip -I/WindRiver/vxworks-6.6/target/h/wrn/coreip\n"); + //fprintf (f, "CFLAGS+=-nostdinc -O2 -nostdlib -fno-builtin -fno-defer-pop -Wall -I$(WIND_BASE)/target/config/all\n"); + fprintf (f, "CFLAGS+=-I$(WIND_BASE)/target/h -I$(WIND_BASE)/target/src/config -I$(WIND_BASE)/target/src/drv -I/WindRiver/diab/5.6.0.0/include -DCPU=PENTIUM\n"); + fprintf (f, "PATH+=:/WindRiver/gnu/4.1.2-vxworks-6.6/x86-linux2/bin\n"); + fprintf (f, "\n"); +#else + fprintf (f, "\n"); + fprintf (f, "WIND_BASE=/usr/tornado-2.0\n"); + fprintf (f, "CPU=PENTIUM\n"); + fprintf (f, "TOOL=gnu\n"); + fprintf (f, "WIND_HOST_TYPE=sun4-solaris2\n"); + fprintf (f, "\n"); + fprintf (f, "include $(WIND_BASE)/target/h/make/defs.bsp\n"); + fprintf (f, "include $(WIND_BASE)/target/h/make/make.$(CPU)$(TOOL)\n"); + fprintf (f, "include $(WIND_BASE)/target/h/make/defs.$(WIND_HOST_TYPE)\n"); + fprintf (f, "\n"); + fprintf (f, "exe: all\n"); + fprintf (f, "\n"); +#endif +} + +static void +generate_vxworks_driver (char *name, conf_t * conf, char *cfg_name, char *cfg_header, + char *dirname, char *topdir) +{ + /* VxWorks version */ + + FILE *f, *src; + char tmp[256], line[256], *p, *s; + int n = 0; + char *options[MAXOPTS]; + char *option_desc[MAXOPTS]; + char desc[65536]; + int nopts = 0; + + sprintf (tmp, "%s/%s", dirname, cfg_name); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + fprintf (src, "#include \"%s\"\n\n", cfg_header); + +/* + * Handle driver specific configuration options + */ + *desc = 0; + sprintf (tmp, "%s/.params", dirname); + if ((f = fopen (tmp, "r")) != NULL) + { + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + fprintf (src, "%s\n", line); + if (strncmp (line, "int ", 4) == 0) + { + char *s = line + 4, *p = s; + + while (*p && *p != '=' && *p != ';') + p++; + *p = 0; + if (nopts >= MAXOPTS) + { + fprintf (stderr, "Too many options for driver '%s' (%d)\n", + name, nopts); + exit (-1); + } + + if (nopts != 0 && *desc != 0) + option_desc[nopts - 1] = strdup (desc); + option_desc[nopts] = 0; + options[nopts++] = strdup (s); + *desc = 0; + } + else + { + char *s = line, *p; + char tmp[4096]; + while (*s == ' ' || *s == '/' || *s == '*') + s++; + + p = tmp; + + while (*s) + { + if (*s == '"') + *p++ = '\\'; + + *p++ = *s++;; + } + *p = 0; + + p = desc + strlen (desc); + sprintf (p, "\n\"%s\\n\"", tmp); + } + } + + fclose (f); + } + + if (nopts > 0 && *desc != 0) + option_desc[nopts - 1] = strdup (desc); + + if ((f = fopen ("devices.list", "r")) == NULL) + { + perror ("devices.list"); + exit (-1); + } + + if (strcmp (conf->bus, "PCI") == 0) + { + fprintf (src, "static unsigned int id_table[] = {\n"); + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + int vendor, product; + p = line + strlen (line) - 1; + if (*p == '\n') + *p = 0; + + p = line; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strcmp (line, name) != 0) + continue; + + n++; + + s = p; + while (*p && *p != '\t') + p++; + if (*p == '\t') + *p++ = 0; + + if (strncmp (s, "pci", 3) == 0) + { + if (sscanf (s + 3, "%x,%x", &vendor, &product) != 2) + { + fprintf (stderr, "Bad PCI id %s\n", s); + } + + fprintf (src, + "\t0x%04x%04x,\n", + vendor, product); + } + + } + + fclose (f); + + fprintf (src, "\t0\n"); + fprintf (src, "};\n"); + fprintf (src, "\n"); + } + + if (strcmp (conf->bus, "USB") == 0) + { + fprintf (stderr, "Error: No support available for USB yet\n"); + exit (EXIT_FAILURE); + } + fprintf (src, "#include \"module.inc\"\n"); + fclose(src); + + sprintf (tmp, "%s/%s", dirname, cfg_header); + if ((src = fopen (tmp, "w")) == NULL) + { + perror (tmp); + exit (-1); + } + + fprintf (src, "/*\n"); + fprintf (src, " * Automatically generated file - do not edit.\n"); + fprintf (src, " */\n"); + + fprintf (src, "#include <oss_config.h>\n"); + fprintf (src, "\n"); + + fprintf (src, "#define DRIVER_NAME\t%s\n", name); + fprintf (src, "#define DRIVER_NICK\t\"%s\"\n", name); + fprintf (src, "#define DRIVER_ATTACH\t%s_attach\n", name); + fprintf (src, "#define DRIVER_DETACH\t%s_detach\n", name); + fprintf (src, "#define DRIVER_TYPE\tDRV_%s\n", conf->bus); + fprintf (src, "\n"); + + fprintf (src, "extern int DRIVER_ATTACH(oss_device_t *ossdev);\n"); + fprintf (src, "extern int DRIVER_DETACH(oss_device_t *ossdev);\n"); + + fclose (src); +} diff --git a/setup/txt2man b/setup/txt2man new file mode 100755 index 0000000..d6a0686 --- /dev/null +++ b/setup/txt2man @@ -0,0 +1,383 @@ +#!/bin/sh +test "$HOME" = ~ || exec ksh $0 "$@" # try ksh if sh too old (not yet POSIX) + +# Copyright (C) 2001, 2002, 2003 Marc Vertes + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# release 1.5.5 + +usage() +{ +cat << EOT +NAME + txt2man - convert flat ASCII text to man page format +SYNOPSIS + txt2man [-hpTX] [-t mytitle] [-P pname] [-r rel] [-s sect] + [-v vol] [-I txt] [-B txt] [-d date] [ifile] +DESCRIPTION + txt2man converts the input text into nroff/troff standard man(7) + macros used to format Unix manual pages. Nice pages can be generated + specially for commands (section 1 or 8) or for C functions reference + (sections 2, 3), with the ability to recognize and format command and + function names, flags, types and arguments. + + txt2man is also able to recognize and format sections, paragraphs, + lists (standard, numbered, description, nested), cross references and + literal display blocks. + + If input file ifile is omitted, standard input is used. Result is + displayed on standard output. + + Here is how text patterns are recognized and processed: + Sections These headers are defined by a line in upper case, starting + column 1. If there is one or more leading spaces, a + sub-section will be generated instead. + Paragraphs They must be separated by a blank line, and left aligned. + Tag list The item definition is separated from the item description + by at least 2 blank spaces, even before a new line, if + definition is too long. Definition will be emphasized + by default. + Bullet list + Bullet list items are defined by the first word being "-" + or "*" or "o". + Enumerated list + The first word must be a number followed by a dot. + Literal display blocks + This paragraph type is used to display unmodified text, + for example source code. It must be separated by a blank + line, and be indented. It is primarily used to format + unmodified source code. It will be printed using fixed font + whenever possible (troff). + Cross references + A cross reference (another man page) is defined by a word + followed by a number in parenthesis. + + Special sections: + NAME The function or command name and short description are set in + this section. + SYNOPSIS This section receives a special treatment to identify command + name, flags and arguments, and propagate corresponding + attributes later in the text. If a C like function is recognized + (word immediately followed by an open parenthesis), txt2man will + print function name in bold font, types in normal font, and + variables in italic font. The whole section will be printed using + a fixed font family (courier) whenever possible (troff). + + It is a good practice to embed documentation into source code, by using + comments or constant text variables. txt2man allows to do that, keeping + the document source readable, usable even without further formatting + (i.e. for online help) and easy to write. The result is high quality + and standard complying document. +OPTIONS + -h The option -h displays help. + -d date Set date in header. Defaults to current date. + -P pname Set pname as project name in header. Default to uname -s. + -p Probe title, section name and volume. + -t mytitle Set mytitle as title of generated man page. + -r rel Set rel as project name and release. + -s sect Set sect as section in heading, ususally a value from 1 to 8. + -v vol Set vol as volume name, i.e. "Unix user 's manual". + -I txt Italicize txt in output. Can be specified more than once. + -B txt Emphasize (bold) txt in output. Can be specified more than once. + -T Text result previewing using PAGER, usually more(1). + -X X11 result previewing using gxditview(1). +ENVIRONMENT + PAGER name of paging command, usually more(1), or less(1). If not set + falls back to more(1). +EXAMPLE + Try this command to format this text itself: + + $ txt2man -h 2>&1 | txt2man -T +HINTS + To obtain an overall good formating of output document, keep paragraphs + indented correctly. If you have unwanted bold sections, search for + multiple spaces between words, which are used to identify a tag list + (term followed by a description). Choose also carefully the name of + command line or function parameters, as they will be emphasized each + time they are encountered in the document. +SEE ALSO + man(1), mandoc(7), rman(1), groff(1), more(1), gxditview(1), troff(1). +BUGS + - Automatic probe (-p option) works only if input is a regular file (i.e. + not stdin). +AUTHOR + Marc Vertes <mvertes@free.fr> +EOT +} + +sys=$(uname -s) +rel= +volume= +section= +title=untitled +doprobe= +itxt= +btxt= +post=cat +while getopts :d:hpTXr:s:t:v:P:I:B: opt +do + case $opt in + d) date=$OPTARG;; + r) rel=$OPTARG;; + t) title=$OPTARG;; + s) section=$OPTARG;; + v) volume=$OPTARG;; + P) sys=$OPTARG;; + p) doprobe=1;; + I) itxt="$OPTARG§$itxt";; + B) btxt=$OPTARG;; + T) post="groff -mandoc -Tlatin1 | ${PAGER:-more}";; + X) post="groff -mandoc -X";; + *) usage; exit;; + esac +done +shift $(($OPTIND - 1)) +date=${date:-$(date +'%d %B %Y')} + +if test "$doprobe" +then + title=${1##*/}; title=${title%.txt} + if grep -q '#include ' $1 + then + section=${section:-3} + volume=${volume:-"$sys Programmer's Manual"} + else + section=${section:-1} + volume=${volume:-"$sys Reference Manual"} + fi + # get release from path + rel=$(pwd | sed 's:/.*[^0-9]/::g; s:/.*::g') +fi + +head=".\\\" Text automatically generated by txt2man +.TH $title $section \"$date\" \"$rel\" \"$volume\"" + +# All tabs converted to spaces +expand $* | +# gawk is needed because use of non standard regexp +gawk --re-interval -v head="$head" -v itxt="$itxt" -v btxt="$btxt" ' +BEGIN { + print head + avar[1] = btxt; avar[2] = itxt + for (k in avar) { + mark = (k == 1) ? "\\fB" : "\\fI" + split(avar[k], tt, "§") + for (i in tt) + if (tt[i] != "") + subwords["\\<" tt[i] "\\>"] = mark tt[i] "\\fP" + for (i in tt) + delete tt[i] + } + for (k in avar) + delete avar[k] +} +{ + # to avoid some side effects in regexp + sub(/\.\.\./, "\\.\\.\\.") + # remove spaces in empty lines + sub(/^ +$/,"") +} +/^[[:upper:][:space:]]+$/ { + # Section header + if ((in_bd + 0) == 1) { + in_bd = 0 + print ".fam T\n.fi" + } + if (section == "SYNOPSIS") { + print ".fam T\n.fi" + type["SYNOPSIS"] = "" + } + if ($0 ~/^[^[:space:]]/) + print ".SH " $0 + else + print ".SS" $0 + sub(/^ +/, "") + section = $0 + if (section == "SYNOPSIS") { + print ".nf\n.fam C" + in_bd = 1 + } + ls = 0 # line start index + pls = 0 # previous line start index + pnzls = 0 # previous non zero line start index + ni = 0 # indent level + ind[0] = 0 # indent offset table + prevblankline = 0 + next +} +{ + # Compute line start index, handle start of example display block + pls = ls + if (ls != 0) + pnzls = ls + match($0, /[^ ]/) + ls = RSTART + if (pls == 0 && pnzls > 0 && ls > pnzls && $1 !~ /^[0-9\-\*\o]\.*$/) { + # example display block + if (prevblankline == 1) { + print ".PP" + prevblankline = 0 + } + print ".nf\n.fam C" + in_bd = 1 + eoff = ls + } + if (ls > 0 && ind[0] == 0) + ind[0] = ls +} +(in_bd + 0) == 1 { + # In block display + if (section == "SYNOPSIS") + ; + else if (ls != 0 && ls < eoff) { + # End of litteral display block + in_bd = 0 + print ".fam T\n.fi" + } else { print; next } +} +section == "NAME" { + $1 = "\\fB" $1 + sub(/ \- /, " \\fP- ") +} +section == "SYNOPSIS" { + # Identify arguments of fcts and cmds + if (type["SYNOPSIS"] == "") { + if ($0 ~ /\(/) + type["SYNOPSIS"] = "fct" + else if ($1 == "struct" || $2 == "struct") + type["SYNOPSIS"] = "struct" + else if ($1 && $1 !~ /^#|typedef|struct|union|enum/) + type["SYNOPSIS"] = "cmd" + } + if (type["SYNOPSIS"] == "cmd") { + # Line is a command line + if ($1 !~ /^\[/) { + b = $1 + sub(/^\*/, "", b) + subwords["\\<" b "\\>"] = "\\fB" b "\\fP" + } + for (i = 2; i <= NF; i++) { + a = $i + gsub(/[\[\]\|]/, "", a) + if (a ~ /^[^\-]/) + subwords["\\<" a "\\>"] = "\\fI" a "\\fP" + } + } else if (type["SYNOPSIS"] == "fct") { + # Line is a C function definition + if ($1 == "typedef") { + if ($0 !~ /\(\*/) + subwords["\\<" $2 "\\>"] = "\\fI" $2 "\\fP" + } else if ($1 == "#define") + subwords["\\<" $2 "\\>"] = "\\fI" $2 "\\fP" + for (i = 1; i <= NF; i++) { + if ($i ~ /[\,\)]\;*$/) { + a = $i + sub(/.*\(/, "", a) + gsub(/\W/, "", a) + subwords["\\<" a "\\>"] = "\\fI" a "\\fP" + } + } + } +} +{ + # protect dots inside words + while ($0 ~ /\w\.\w/) + sub(/\./, "_dOt_") + # identify func calls and cross refs + for (i = 1; i <= NF; i++) { + b = $i + sub(/^\*/, "", b) + if ((a = index(b, ")(")) > 3) { + w = substr(b, 3, a - 3) + subwords["\\<" w "\\>"] = "\\fI" w "\\fP" + } + if ((a = index(b, "(")) > 1) { + w = substr(b, 1, a - 1) + subwords["\\<" w "\\("] = "\\fB" w "\\fP(" + } + } + # word attributes + for (i in subwords) + gsub(i, subwords[i]) + # shell options + gsub(/\B\-+\w+(\-\w+)*/, "\\fB&\\fP") + # unprotect dots inside words + gsub(/_dOt_/, ".") + + if (section == "SYNOPSIS") { + sub(/^ /, "") + print + next + } + if (match($0, /[^ ] +/) > 0) { + # tag list item + adjust_indent() + tag = substr($0, 1, RSTART) + sub(/^ */, "", tag) + if (RSTART+RLENGTH < length()) + $0 = substr($0, RSTART + RLENGTH) + else + $0 = "" + print ".TP\n.B" + print tag + prevblankline = 0 + if (NF == 0) + next + } else if ($1 == "-"||$1 == "o"||$1 == "*") { + # bullet list item + adjust_indent() + print ".IP \\(bu 3" + prevblankline = 0 + $1 = "" + } else if ($1 ~ /^[0-9]+[\).]$/) { + # enum list item + adjust_indent() + print ".IP " $1 " 4" + prevblankline = 0 + $1 = "" + } else if (pls == 0) { + # new paragraph + adjust_indent() + } else if (NF == 0) { + # blank line + prevblankline = 1 + next + } else + prevblankline = 0 + # flush vertical space + if (prevblankline == 1) { + print ".PP" + prevblankline = 0 + } + if (section != "SYNOPSIS" || $0 ~ /^ {1,4}/) + sub(/ */,"") + print +} + +function adjust_indent() +{ + if (ls > ind[ni]) { + ind[++ni] = ls + print ".RS" + } else if (ls < ind[ni]) { + while (ls < ind[ni]) { + ni-- + print ".RE" + } + } +} +' | eval $post diff --git a/setup/txt2man.c b/setup/txt2man.c new file mode 100644 index 0000000..8769374 --- /dev/null +++ b/setup/txt2man.c @@ -0,0 +1,117 @@ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <time.h> +#include <string.h> + +int section = 0; +char *volume = "Unknown volume"; +char *title = "unknown"; + +int +main (int argc, char *argv[]) +{ + char line[1024], *s, upper; + const char * date; + int c; + FILE *f; + time_t tt; + extern char *optarg; + extern int optind; + + if (time (&tt) == (time_t)-1) date = "August 31, 2006"; + else { + date = ctime (&tt); + s = strchr (date, '\n'); + if (s) *s = '\0'; + } + + while ((c = getopt (argc, argv, "v:s:t:")) != EOF) + switch (c) + { + case 'v': + volume = optarg; + break; + case 't': + title = optarg; + break; + case 's': + section = atoi (optarg); + break; + } + + if (optind >= argc) + { + fprintf (stderr, "%s: No input file specified\n", argv[0]); + exit (-1); + } + + if ((f = fopen (argv[optind], "r")) == NULL) + { + perror (argv[optind]); + exit (-1); + } + + printf (".\" Automatically generated text\n"); + printf (".TH %s %d \"%s\" \"4Front Technologies\" \"%s\"\n", title, section, date, volume); + + while (fgets (line, sizeof (line), f) != NULL) + { + s = line; + upper = 1; + + while (*s && *s != '\n') + { + if (!isupper (*s) && *s != ' ') + upper = 0; + s++; + } + *s = 0; + if (line[0] == 0) + upper = 0; + + if (upper) { + printf (".SH %s\n", line); + } else { + s = line; + + while (isspace(*s)) s++; + if (*s == '\0') { + printf (".PP\n"); + continue; + } + if (*s == 'o' && isspace(s[1])) + { + printf (".IP \\(bu 3\n"); + s += 2; + printf ("%s\n", s); + continue; + } + if (*s == '-' && !isspace(s[1])) { + printf (".TP\n"); + printf ("\\fB"); + while (!isspace (*s)) printf ("%c", *s++); + printf ("\\fP\n"); + while (isspace(*s)) s++; + } + printf ("%s\n", s); + } + } + + fclose (f); + + exit (0); +} diff --git a/setup/update_errors.c b/setup/update_errors.c new file mode 100644 index 0000000..df1f6d4 --- /dev/null +++ b/setup/update_errors.c @@ -0,0 +1,445 @@ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +#define OSS_LICENSE "" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <libgen.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/stat.h> +#include <sys/utsname.h> +#include "/tmp/buildid.h" + +#define MAX_ERRORS 1000 + +typedef struct +{ + int err; + char *sourcename; + int linenum; + char *msg; + char *desc; +} errordesc_t; + +errordesc_t *errors[MAX_ERRORS]; +int nerrors = 0; + +char * +strmatch (char *s, const char *pattern) +{ + int i, l, pl; + + if (s == NULL || *pattern == 0) + return NULL; + + l = strlen (s); + pl = strlen (pattern); + + if (pl > l) + return NULL; + + while (s && l >= pl) + { + int ok = 0; + + for (i = 0; !ok && i < pl; i++) + if (s[i] != pattern[i]) + { + ok = 1; + continue; + } + + if (!ok) + return s; + + s++; + l--; + } + return NULL; +} + +char * +check_comment (FILE * f, const char *sourcename, int *linenum) +{ + char line[4096]; + int is_desc = 0; + static char errorbuf[64 * 1024]; + int done = 0; + + *errorbuf = 0; + + if (fgets (line, sizeof (line) - 1, f) != NULL) + { + char *s, *p; + int l; + + *linenum = *linenum + 1; + + if ((l = strlen (line)) > 4000) + { + fprintf (stderr, "Too long line in %s\n", sourcename); + exit (-1); + } + + /* + * Strip trailing CR and LF characters. + */ + s = line + l - 1; + while (*s == '\n' || *s == '\r') + *s-- = 0; + + s = line; + + while (*s == ' ' || *s == '\t') + s++; + + if (s[0] != '/' || s[1] != '*') + return NULL; + + if ((p = strmatch (s, "Errordesc:"))) + { + p += 10; + while (*p == ' ') + p++; + + is_desc = 1; + if ((s = strmatch (p, "*/"))) + { + *s = 0; + return p; + } + else + { + strcat (errorbuf, p); + } + } + } + +/* + * Handle comment continuation lines. + */ + + while (!done && fgets (line, sizeof (line) - 1, f) != NULL) + { + char *s, *p; + int l; + + *linenum = *linenum + 1; + + if ((l = strlen (line)) > 4000) + { + fprintf (stderr, "Too long line in %s\n", sourcename); + exit (-1); + } + + /* + * Strip trailing CR and LF characters. + */ + s = line + l - 1; + while (*s == '\n' || *s == '\r') + *s-- = 0; + + s = line; + + while (*s == ' ' || *s == '\t' || *s == '*') + s++; + if (*s == '/' && s[-1] == '*') /* End of comment */ + break; + + if ((p = strmatch (s, "Errordesc:"))) + { + p += 10; + while (*p == ' ') + p++; + + is_desc = 1; + if ((s = strmatch (p, "*/"))) + { + *s = 0; + if (*errorbuf != 0) + strcat (errorbuf, " "); + strcat (errorbuf, p); + done = 1; + } + else + { + if (*errorbuf != 0) + strcat (errorbuf, " "); + strcat (errorbuf, p); + } + continue; + } + + p = s; + if ((s = strmatch (p, "*/"))) + { + *s = 0; + if (*errorbuf != 0) + strcat (errorbuf, " "); + strcat (errorbuf, p); + done = 1; + } + else + { + if (*errorbuf != 0) + strcat (errorbuf, " "); + strcat (errorbuf, p); + } + } + + if (is_desc) + return errorbuf; + return NULL; +} + +void +store_error (int errnum, const char *sourcename, int linenum, const char *msg, + const char *desc) +{ + errordesc_t *err; + + //printf("%s:%d: %05d=%s\n", sourcename, linenum, errnum, msg); + + if (nerrors >= MAX_ERRORS) + { + fprintf (stderr, "Too many errors\n"); + exit (-1); + } + + if ((err = malloc (sizeof (*err))) == NULL) + { + fprintf (stderr, "Too many errors defined\n"); + exit (-1); + } + + err->err = errnum; + err->sourcename = strdup (sourcename); + err->linenum = linenum; + err->msg = strdup (msg); + if (desc == NULL) + err->desc = NULL; + else + err->desc = strdup (desc); + + errors[nerrors++] = err; +} + +void +parse_sourcefile (char *sourcename) +{ + int linenum = 0; + char line[4096]; + FILE *f; + + if (*sourcename == '.') + sourcename += 2; /* Skip the "./" directory prefix */ + +/* + * Don't handle myself or oss_config.h. + */ + + if (strcmp (basename (sourcename), "update_errors.c") == 0) + return; + if (strcmp (basename (sourcename), "oss_config.h") == 0) + return; + + if ((f = fopen (sourcename, "r")) == NULL) + { + perror (sourcename); + exit (-1); + } + + while (fgets (line, sizeof (line) - 1, f) != NULL) + { + char *s; + int l; + + linenum++; + + if ((l = strlen (line)) > 4000) + { + fprintf (stderr, "Too long line in %s\n", sourcename); + exit (-1); + } + + /* + * Strip trailing CR and LF characters. + */ + s = line + l - 1; + while (*s == '\n' || *s == '\r') + *s-- = 0; + + if ((s = strmatch (line, "OSSERR"))) + { + char *p; + char tmp[4096]; + char tmp2[4096]; + int num, thisline; + + s += 6; /* Skip "OSSERR" */ + while (*s == ' ' || *s == '\t' || *s == '(') + s++; + + /* + * Get the error number + */ + p = s; + while (*s >= '0' && *s <= '9') + s++; + + while (*s == ',' || *s == ' ' || *s == '\t' || *s == '"') + *s++ = 0; + + if (sscanf (p, "%d", &num) != 1) + { + fprintf (stderr, "Bad error number in %s:%d\n", + sourcename, linenum); + } + + p = s; + + if (*p == 0) + { + /* + * No '"' was found. Read the continuation line. + */ + fgets (tmp, sizeof (tmp) - 1, f); + p = tmp; + + while (*p == ' ' || *p == '\t' || *p == '"') + p++; + + s = p; + while (*s && *s != '"') + s++; + if (*s) + *s++ = 0; + } + + while (*s && *s != '"') + s++; + if (*s) + *s++ = 0; + // printf("%s:%d: %d=%s\n", sourcename, linenum, num, p); + while (*s && *s != ';') + s++; + + if (*s != ';') /* No semicolon. Discard the next line */ + fgets (tmp2, sizeof (tmp2) - 1, f); + *s = 0; + + /* + * Check if the next line starts the descriptive comment + */ + + thisline = linenum; + if ((s = check_comment (f, sourcename, &linenum))) + store_error (num, sourcename, thisline, p, s); + else + store_error (num, sourcename, thisline, p, NULL); + } + } + + fclose (f); +} + +int +compare (const void *a_, const void *b_) +{ + const char *const *a__ = a_; + const char *const *b__ = b_; + const errordesc_t *a = *a__; + const errordesc_t *b = *b__; + + if (a->err == b->err) + return 0; + if (a->err < b->err) + return -1; + + return 1; +} + +int +main (int argc, char *argv[]) +{ + int i, status = 0; + + for (i = 1; i < argc; i++) + { + parse_sourcefile (argv[i]); + } + + qsort (errors, nerrors, sizeof (errordesc_t *), compare); + + for (i = 0; i < nerrors; i++) + { + if (errors[i]->err == 0) + { + fprintf (stderr, "%s:%d: Error number is zero\n", + errors[i]->sourcename, errors[i]->linenum); + status = 1; + continue; + } + + if (i > 0 && errors[i]->err == errors[i - 1]->err) + { + fprintf (stderr, "%s:%d: duplicate error %05d\n", + errors[i]->sourcename, errors[i]->linenum, errors[i]->err); + status = 1; + continue; + } + + if (i < nerrors - 1 && errors[i]->err == errors[i + 1]->err) + { + fprintf (stderr, "%s:%d: duplicate error %05d\n", + errors[i]->sourcename, errors[i]->linenum, errors[i]->err); + status = 1; + continue; + } + } + + printf ("<html>\n"); + printf ("<head><title>OSS run time error list for OSS v%s</title></head>\n", + OSS_VERSION_STRING); + printf ("<body style=\"font-family: Helvetica,Arial,sans-serif;\">\n"); + printf ("<h2>OSS run time error list for OSS v%s</h2>\n", + OSS_VERSION_STRING); + + printf ("<table border=\"0\">\n"); + printf ("<tr><td><b>Code</b></td><td><b>Description</b></td>/</tr>\n"); + for (i = 0; i < nerrors; i++) + { +#if 1 + printf + ("<tr><td style=\"vertical-align: top;\">%05d</td><td><b>%s</b>\n", + errors[i]->err, errors[i]->msg); + + if (errors[i]->desc != NULL) + printf ("<br>%s\n", errors[i]->desc); + printf ("</td></tr>\n"); +#else + printf ("<p><b>%05d: %s</b></p>\n", errors[i]->err, errors[i]->msg); + + if (errors[i]->desc != NULL) + printf ("<ul><li>%s</li></ul>\n", errors[i]->desc); +#endif + } + printf ("</table>\n"); + printf ("</body>\n"); + printf ("</html>\n"); + + exit (status); +} diff --git a/setup/x11.pc b/setup/x11.pc new file mode 100644 index 0000000..5ce7bd5 --- /dev/null +++ b/setup/x11.pc @@ -0,0 +1,16 @@ +prefix=/usr/openwin +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +xthreadlib= + +Name: X11 +Description: X Library +Version: 0.0 +Requires: xproto kbproto inputproto +Requires.private: xau xdmcp +Cflags: -I${includedir} -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DXTHREADS -DXUSE_MTSAFE_API +Libs: -L${libdir} -R${libdir} -lX11 +Libs.private: + |