add netboot support.
This commit is contained in:
parent
694616c180
commit
be514997d2
51 changed files with 9152 additions and 92 deletions
106
ChangeLog
106
ChangeLog
|
@ -1,3 +1,109 @@
|
||||||
|
1999-09-14 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
* configure.in (--enable-ne): Made the description more clear.
|
||||||
|
(--enable-nepci): Likewise.
|
||||||
|
(--enable-wd): Likewise.
|
||||||
|
(--enable-t503): Likewise.
|
||||||
|
(--enable-t509): Likewise.
|
||||||
|
(--enable-3c59x): Likewise.
|
||||||
|
(--enable-lance): Likewise.
|
||||||
|
(--enable-cs): Likewise.
|
||||||
|
(--enable-eepro100): Likewise.
|
||||||
|
(--enable-wd-default_mem): Renamed to ...
|
||||||
|
(--enable-wd-default-mem): ... this.
|
||||||
|
(--enable-cs-scan): Corrected the description.
|
||||||
|
(NETBOOT_SUPPORT): Defined if NET_CFLAGS is not empty.
|
||||||
|
* stage2/Makefile.am (stage2_exec_LDADD): Defined only if
|
||||||
|
NETBOOT_SUPPORT is true.
|
||||||
|
* netboot/Makefile.am (LIBDRIVERS): New variable. If
|
||||||
|
NETBOOT_SUPPORT is true, set to libdriver.a, otherwise set to an
|
||||||
|
empty string.
|
||||||
|
(noinst_LIBRARIES): Set to LIBDRIVERS.
|
||||||
|
(DRIVERS): Added 3c509.h, cs89x0.h and ns8390.h.
|
||||||
|
(libdrivers_a_SOURCES): Added byteorder.h, config.h, if.h, io.h,
|
||||||
|
ip.h, netboot.h, netdevice.h, nic.h and pic.h.
|
||||||
|
(libdrivers_a_CFLAGS): Added -fno-builtin and -nostdinc and
|
||||||
|
removed -O2.
|
||||||
|
* stage2/char_io.c (grub_sprintf): Added parenthesises to avoid
|
||||||
|
gcc warnings.
|
||||||
|
* stage2/gunzip.c (gunzip_test_header): Check if FSYS_TYPE is
|
||||||
|
TFTP. If so, set IS_TFTP to non-zero, otherwise to zero. And,
|
||||||
|
use IS_TFTP to check if we have GZIP_CRC instead of the equation
|
||||||
|
"FILEMAX == 16 * 1024 * 1024".
|
||||||
|
|
||||||
|
1999-09-13 Edmund GRIMLEY EVANS <edmundo@rano.demon.co.uk>
|
||||||
|
|
||||||
|
The netboot support in the Dresden version of GRUB is integrated.
|
||||||
|
|
||||||
|
* Makefile.am (SUBDIRS): Added netboot.
|
||||||
|
* configure.in (--enable-tftp): New option.
|
||||||
|
(--enable-ne): Likewise.
|
||||||
|
(--enable-nepci): Likewise.
|
||||||
|
(--enable-wd): Likewise.
|
||||||
|
(--enable-t503): Likewise.
|
||||||
|
(--enable-t509): Likewise.
|
||||||
|
(--enable-3c59x): Likewise.
|
||||||
|
(--enable-lance): Likewise.
|
||||||
|
(--enable-cs): Likewise.
|
||||||
|
(--enable-eepro100): Likewise.
|
||||||
|
(--enable-ne-scan): Likewise.
|
||||||
|
(--enable-wd-default_mem): Likewise.
|
||||||
|
(--enable-cs-scan): Likewise.
|
||||||
|
(NET_CFLAGS): New variable.
|
||||||
|
(NET_EXTRAFLAGS): Likewise.
|
||||||
|
Do AC_OUTPUT for netboot/Makefile as well.
|
||||||
|
* stage1/stage1.S: Set the number of sectors for Stage 2 to 130.
|
||||||
|
* stage1/stage1_lba.S: Likewise.
|
||||||
|
* stage2/Makefile.am (stage2_exec_LDADD): Added
|
||||||
|
../netboot/libdrivers.a.
|
||||||
|
* stage2/asm.S [!STAGE1_5] (currticks): New function.
|
||||||
|
* stage2/char_io.c [!STAGE1_5] (grub_sprintf): Likewise.
|
||||||
|
[!STAGE1_5] (grub_memcmp): Likewise.
|
||||||
|
* stage2/disk_io.c (fsys_table) [FSYS_TFTP]: Added an entry for
|
||||||
|
tftp.
|
||||||
|
(sane_partition) [!STAGE1_5]: If CURRENT_DRIVE is a network
|
||||||
|
drive, return 1.
|
||||||
|
(real_open_partition) [!STAGE1_5]: Likewise.
|
||||||
|
(set_device): If DEVICE contains a network drive, set
|
||||||
|
CURRENT_DRIVE to 0x20.
|
||||||
|
* stage2/filesys.h [FSYS_TFTP] (FSYS_TFTP_NUM): Defined as 1.
|
||||||
|
[!FSYS_TFTP] (FSYS_TFTP_NUM): Defined as 0.
|
||||||
|
(NUM_FSYS): Added FSYS_TFTP_NUM.
|
||||||
|
* stage2/gunzip.c (gunzip_test_header): If FILEMAX >= 16MB, do
|
||||||
|
not try to examine the last 8 bytes of the file. This is
|
||||||
|
required for compressed files by TFTP.
|
||||||
|
* stage2/shared.h (sprintf): New macro.
|
||||||
|
(memcmp): Likewise.
|
||||||
|
(currticks): Declared.
|
||||||
|
(grub_sprintf): Likewise.
|
||||||
|
(grub_memcmp): Likewise.
|
||||||
|
* stage2/size_test: Set the maximum size of Stage 2 to 66560.
|
||||||
|
* netboot/3c509.c: New file.
|
||||||
|
* netboot/3c509.h: Likewise.
|
||||||
|
* netboot/3c59x.c: Likewise.
|
||||||
|
* netboot/Makefile.am: Likewise.
|
||||||
|
* netboot/Makefile.in: Likewise.
|
||||||
|
* netboot/byteorder.h: Likewise.
|
||||||
|
* netboot/compile: Likewise.
|
||||||
|
* netboot/config.c: Likewise.
|
||||||
|
* netboot/config.h: Likewise.
|
||||||
|
* netboot/cs89x0.c: Likewise.
|
||||||
|
* netboot/cs89x0.h: Likewise.
|
||||||
|
* netboot/eepro100.c: Likewise.
|
||||||
|
* netboot/fsys_tftp.c: Likewise.
|
||||||
|
* netboot/if.h: Likewise.
|
||||||
|
* netboot/io.h: Likewise.
|
||||||
|
* netboot/ip.c: Likewise.
|
||||||
|
* netboot/ip.h: Likewise.
|
||||||
|
* netboot/lance.c: Likewise.
|
||||||
|
* netboot/netboot.h: Likewise.
|
||||||
|
* netboot/netdevice.h: Likewise.
|
||||||
|
* netboot/nic.h: Likewise.
|
||||||
|
* netboot/ns8390.c: Likewise.
|
||||||
|
* netboot/ns8390.h: Likewise.
|
||||||
|
* netboot/pci.c: Likewise.
|
||||||
|
* netboot/pci.h: Likewise.
|
||||||
|
|
||||||
1999-09-13 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
1999-09-13 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
* configure.in (--enable-maintainer-mode): Do not use our own
|
* configure.in (--enable-maintainer-mode): Do not use our own
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS = stage1 stage2 grub docs debian
|
SUBDIRS = stage1 netboot stage2 grub docs debian
|
||||||
EXTRA_DIST = BUGS
|
EXTRA_DIST = BUGS
|
||||||
|
|
||||||
# We get $(PACKAGE) and $(VERSION) from debian/changelog.
|
# We get $(PACKAGE) and $(VERSION) from debian/changelog.
|
||||||
|
|
|
@ -69,6 +69,8 @@ GRUB_LIBS = @GRUB_LIBS@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NET_CFLAGS = @NET_CFLAGS@
|
||||||
|
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||||
OBJCOPY = @OBJCOPY@
|
OBJCOPY = @OBJCOPY@
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
@ -81,7 +83,7 @@ host_vendor = @host_vendor@
|
||||||
install_sh = @install_sh@
|
install_sh = @install_sh@
|
||||||
|
|
||||||
|
|
||||||
SUBDIRS = stage1 stage2 grub docs debian
|
SUBDIRS = stage1 netboot stage2 grub docs debian
|
||||||
EXTRA_DIST = BUGS
|
EXTRA_DIST = BUGS
|
||||||
subdir = .
|
subdir = .
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -22,6 +22,7 @@ New in 0.5.93:
|
||||||
* The option `--no-floppy' force the grub shell to assume that there is
|
* The option `--no-floppy' force the grub shell to assume that there is
|
||||||
no floppy, and the option `--probe-second-floppy' enables the probe of
|
no floppy, and the option `--probe-second-floppy' enables the probe of
|
||||||
the second floppy drive.
|
the second floppy drive.
|
||||||
|
* Integrated the netboot support in the Dresden version of GRUB.
|
||||||
|
|
||||||
New in 0.5.92 - 1999-07-26:
|
New in 0.5.92 - 1999-07-26:
|
||||||
* Bug fixes (i.e. Stage 1.5 can work fine again).
|
* Bug fixes (i.e. Stage 1.5 can work fine again).
|
||||||
|
|
1
THANKS
1
THANKS
|
@ -11,6 +11,7 @@ Bradford Hovinen <hovinen@redrose.net>
|
||||||
Brian Brunswick <brian@skarpsey.demon.co.uk>
|
Brian Brunswick <brian@skarpsey.demon.co.uk>
|
||||||
Bryan Ford <baford@cs.utah.edu>
|
Bryan Ford <baford@cs.utah.edu>
|
||||||
Dan J. Walters <djw@cs.utexas.edu>
|
Dan J. Walters <djw@cs.utexas.edu>
|
||||||
|
Edmund GRIMLEY EVANS <edmundo@rano.demon.co.uk>
|
||||||
Edward Killips <ekillips@triton.net>
|
Edward Killips <ekillips@triton.net>
|
||||||
Eric Hanchrow <erich@microsoft.com>
|
Eric Hanchrow <erich@microsoft.com>
|
||||||
Heiko Schroeder <heiko@pool.informatik.rwth-aachen.de>
|
Heiko Schroeder <heiko@pool.informatik.rwth-aachen.de>
|
||||||
|
|
7
TODO
7
TODO
|
@ -7,8 +7,6 @@ type''. We need this for clean Hurd install floppies.
|
||||||
Add a real scripting language, possibly retaining backward
|
Add a real scripting language, possibly retaining backward
|
||||||
compatibility so that old config files can be used.
|
compatibility so that old config files can be used.
|
||||||
|
|
||||||
Look at the network booting patches from L4.
|
|
||||||
|
|
||||||
Add internationalization support, emulating gettext as much as is
|
Add internationalization support, emulating gettext as much as is
|
||||||
feasible.
|
feasible.
|
||||||
|
|
||||||
|
@ -25,8 +23,13 @@ larger than 16MB can be read.
|
||||||
|
|
||||||
??? Add command for modifying partition types.
|
??? Add command for modifying partition types.
|
||||||
|
|
||||||
|
Add OpenBSD support. The recent versions cannot be loaded.
|
||||||
|
|
||||||
Fix-up FreeBSD, NetBSD (and OpenBSD ?) command-line boot parameters
|
Fix-up FreeBSD, NetBSD (and OpenBSD ?) command-line boot parameters
|
||||||
|
|
||||||
|
Add a new installation command, such as `setup', which should be easier
|
||||||
|
to use and more automatic than the command `install'.
|
||||||
|
|
||||||
Add keyboard layout configuration support.
|
Add keyboard layout configuration support.
|
||||||
|
|
||||||
Clean up and enhance the manuals, especially concept indexes.
|
Clean up and enhance the manuals, especially concept indexes.
|
||||||
|
|
299
configure
vendored
299
configure
vendored
|
@ -22,8 +22,34 @@ ac_help="$ac_help
|
||||||
--disable-ffs disable FFS support in Stage 2"
|
--disable-ffs disable FFS support in Stage 2"
|
||||||
ac_help="$ac_help
|
ac_help="$ac_help
|
||||||
--disable-minix disable Minix fs support in Stage 2"
|
--disable-minix disable Minix fs support in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-tftp enable TFTP support in Stage 2"
|
||||||
ac_help="$ac_help
|
ac_help="$ac_help
|
||||||
--disable-gunzip disable decompression in Stage 2"
|
--disable-gunzip disable decompression in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-ne enable NE1000/2000 network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-nepci enable PCI NE2000 network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-wd enable WD/SMC network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-t503 enable 3C503 network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-t509 enable 3C509 network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-3c59x enable 3C59x network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-lance enable LANCE network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-cs enable CS89*0 network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-eepro100 enable EtherExpress100 network driver in Stage 2"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-ne-scan set the parameter for NE network driver"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-wd-default-mem set the parameter for WD network driver"
|
||||||
|
ac_help="$ac_help
|
||||||
|
--enable-cs-scan set the parameter for CS network driver"
|
||||||
|
|
||||||
# Initialize some variables set by options.
|
# Initialize some variables set by options.
|
||||||
# The variables have the same names as the options, with
|
# The variables have the same names as the options, with
|
||||||
|
@ -569,7 +595,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
|
||||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||||
# ./install, which can be erroneously created by make from ./install.sh.
|
# ./install, which can be erroneously created by make from ./install.sh.
|
||||||
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
|
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
|
||||||
echo "configure:573: checking for a BSD compatible install" >&5
|
echo "configure:599: checking for a BSD compatible install" >&5
|
||||||
if test -z "$INSTALL"; then
|
if test -z "$INSTALL"; then
|
||||||
if eval "test \"\${ac_cv_path_install+set}\" = set"; then
|
if eval "test \"\${ac_cv_path_install+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
|
@ -626,7 +652,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
|
||||||
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
||||||
|
|
||||||
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
|
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
|
||||||
echo "configure:630: checking whether build environment is sane" >&5
|
echo "configure:656: checking whether build environment is sane" >&5
|
||||||
# Just in case
|
# Just in case
|
||||||
sleep 1
|
sleep 1
|
||||||
echo timestamp > conftestfile
|
echo timestamp > conftestfile
|
||||||
|
@ -687,7 +713,7 @@ do
|
||||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||||
set dummy $ac_prog; ac_word=$2
|
set dummy $ac_prog; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:691: checking for $ac_word" >&5
|
echo "configure:717: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_AWK+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_AWK+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -717,7 +743,7 @@ test -n "$AWK" && break
|
||||||
done
|
done
|
||||||
|
|
||||||
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
|
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
|
||||||
echo "configure:721: checking whether ${MAKE-make} sets \${MAKE}" >&5
|
echo "configure:747: checking whether ${MAKE-make} sets \${MAKE}" >&5
|
||||||
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
|
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
|
||||||
if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
|
@ -766,7 +792,7 @@ EOF
|
||||||
|
|
||||||
missing_dir=`cd $ac_aux_dir && pwd`
|
missing_dir=`cd $ac_aux_dir && pwd`
|
||||||
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
|
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
|
||||||
echo "configure:770: checking for working aclocal" >&5
|
echo "configure:796: checking for working aclocal" >&5
|
||||||
# Run test in a subshell; some versions of sh will print an error if
|
# Run test in a subshell; some versions of sh will print an error if
|
||||||
# an executable is not found, even if stderr is redirected.
|
# an executable is not found, even if stderr is redirected.
|
||||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||||
|
@ -779,7 +805,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
|
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
|
||||||
echo "configure:783: checking for working autoconf" >&5
|
echo "configure:809: checking for working autoconf" >&5
|
||||||
# Run test in a subshell; some versions of sh will print an error if
|
# Run test in a subshell; some versions of sh will print an error if
|
||||||
# an executable is not found, even if stderr is redirected.
|
# an executable is not found, even if stderr is redirected.
|
||||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||||
|
@ -792,7 +818,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking for working automake""... $ac_c" 1>&6
|
echo $ac_n "checking for working automake""... $ac_c" 1>&6
|
||||||
echo "configure:796: checking for working automake" >&5
|
echo "configure:822: checking for working automake" >&5
|
||||||
# Run test in a subshell; some versions of sh will print an error if
|
# Run test in a subshell; some versions of sh will print an error if
|
||||||
# an executable is not found, even if stderr is redirected.
|
# an executable is not found, even if stderr is redirected.
|
||||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||||
|
@ -805,7 +831,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
|
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
|
||||||
echo "configure:809: checking for working autoheader" >&5
|
echo "configure:835: checking for working autoheader" >&5
|
||||||
# Run test in a subshell; some versions of sh will print an error if
|
# Run test in a subshell; some versions of sh will print an error if
|
||||||
# an executable is not found, even if stderr is redirected.
|
# an executable is not found, even if stderr is redirected.
|
||||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||||
|
@ -818,7 +844,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
|
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
|
||||||
echo "configure:822: checking for working makeinfo" >&5
|
echo "configure:848: checking for working makeinfo" >&5
|
||||||
# Run test in a subshell; some versions of sh will print an error if
|
# Run test in a subshell; some versions of sh will print an error if
|
||||||
# an executable is not found, even if stderr is redirected.
|
# an executable is not found, even if stderr is redirected.
|
||||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||||
|
@ -838,7 +864,7 @@ do
|
||||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||||
set dummy $ac_prog; ac_word=$2
|
set dummy $ac_prog; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:842: checking for $ac_word" >&5
|
echo "configure:868: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_AMTAR+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_AMTAR+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -882,7 +908,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||||
echo "configure:886: checking host system type" >&5
|
echo "configure:912: checking host system type" >&5
|
||||||
if test "x$ac_cv_host" = "x" || (test "x$host" != "xNONE" && test "x$host" != "x$ac_cv_host_alias"); then
|
if test "x$ac_cv_host" = "x" || (test "x$host" != "xNONE" && test "x$host" != "x$ac_cv_host_alias"); then
|
||||||
|
|
||||||
# Make sure we can run config.sub.
|
# Make sure we can run config.sub.
|
||||||
|
@ -935,7 +961,7 @@ esac
|
||||||
#
|
#
|
||||||
|
|
||||||
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
|
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
|
||||||
echo "configure:939: checking whether to enable maintainer-specific portions of Makefiles" >&5
|
echo "configure:965: checking whether to enable maintainer-specific portions of Makefiles" >&5
|
||||||
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
|
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
|
||||||
if test "${enable_maintainer_mode+set}" = set; then
|
if test "${enable_maintainer_mode+set}" = set; then
|
||||||
enableval="$enable_maintainer_mode"
|
enableval="$enable_maintainer_mode"
|
||||||
|
@ -961,7 +987,7 @@ if test "x$enable_maintainer_mode" = xyes; then
|
||||||
# Extract the first word of "perl", so it can be a program name with args.
|
# Extract the first word of "perl", so it can be a program name with args.
|
||||||
set dummy perl; ac_word=$2
|
set dummy perl; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:965: checking for $ac_word" >&5
|
echo "configure:991: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_path_PERL+set}\" = set"; then
|
if eval "test \"\${ac_cv_path_PERL+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1009,7 +1035,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||||
echo "configure:1013: checking build system type" >&5
|
echo "configure:1039: checking build system type" >&5
|
||||||
if test "x$ac_cv_build" = "x" || (test "x$build" != "xNONE" && test "x$build" != "x$ac_cv_build_alias"); then
|
if test "x$ac_cv_build" = "x" || (test "x$build" != "xNONE" && test "x$build" != "x$ac_cv_build_alias"); then
|
||||||
|
|
||||||
# Make sure we can run config.sub.
|
# Make sure we can run config.sub.
|
||||||
|
@ -1056,7 +1082,7 @@ fi
|
||||||
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
|
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
|
||||||
set dummy ${ac_tool_prefix}gcc; ac_word=$2
|
set dummy ${ac_tool_prefix}gcc; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:1060: checking for $ac_word" >&5
|
echo "configure:1086: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1088,7 +1114,7 @@ fi
|
||||||
# Extract the first word of "gcc", so it can be a program name with args.
|
# Extract the first word of "gcc", so it can be a program name with args.
|
||||||
set dummy gcc; ac_word=$2
|
set dummy gcc; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:1092: checking for $ac_word" >&5
|
echo "configure:1118: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1118,7 +1144,7 @@ if test -z "$CC"; then
|
||||||
# Extract the first word of "cc", so it can be a program name with args.
|
# Extract the first word of "cc", so it can be a program name with args.
|
||||||
set dummy cc; ac_word=$2
|
set dummy cc; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:1122: checking for $ac_word" >&5
|
echo "configure:1148: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1169,7 +1195,7 @@ fi
|
||||||
# Extract the first word of "cl", so it can be a program name with args.
|
# Extract the first word of "cl", so it can be a program name with args.
|
||||||
set dummy cl; ac_word=$2
|
set dummy cl; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:1173: checking for $ac_word" >&5
|
echo "configure:1199: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1201,7 +1227,7 @@ fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works""... $ac_c" 1>&6
|
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works""... $ac_c" 1>&6
|
||||||
echo "configure:1205: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" >&5
|
echo "configure:1231: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" >&5
|
||||||
|
|
||||||
ac_ext=c
|
ac_ext=c
|
||||||
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
|
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
|
||||||
|
@ -1212,12 +1238,12 @@ cross_compiling=$ac_cv_prog_cc_cross
|
||||||
|
|
||||||
cat > conftest.$ac_ext << EOF
|
cat > conftest.$ac_ext << EOF
|
||||||
|
|
||||||
#line 1216 "configure"
|
#line 1242 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
main(){return(0);}
|
main(){return(0);}
|
||||||
EOF
|
EOF
|
||||||
if { (eval echo configure:1221: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
if { (eval echo configure:1247: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||||
ac_cv_prog_cc_works=yes
|
ac_cv_prog_cc_works=yes
|
||||||
# If we can't run a trivial program, we are probably using a cross compiler.
|
# If we can't run a trivial program, we are probably using a cross compiler.
|
||||||
if (./conftest; exit) 2>/dev/null; then
|
if (./conftest; exit) 2>/dev/null; then
|
||||||
|
@ -1243,12 +1269,12 @@ if test $ac_cv_prog_cc_works = no; then
|
||||||
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
|
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
|
||||||
fi
|
fi
|
||||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
|
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
|
||||||
echo "configure:1247: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" >&5
|
echo "configure:1273: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||||
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
|
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
|
||||||
cross_compiling=$ac_cv_prog_cc_cross
|
cross_compiling=$ac_cv_prog_cc_cross
|
||||||
|
|
||||||
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
|
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
|
||||||
echo "configure:1252: checking whether we are using GNU C" >&5
|
echo "configure:1278: checking whether we are using GNU C" >&5
|
||||||
if eval "test \"\${ac_cv_prog_gcc+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_gcc+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1257,7 +1283,7 @@ else
|
||||||
yes;
|
yes;
|
||||||
#endif
|
#endif
|
||||||
EOF
|
EOF
|
||||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1261: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1287: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||||
ac_cv_prog_gcc=yes
|
ac_cv_prog_gcc=yes
|
||||||
else
|
else
|
||||||
ac_cv_prog_gcc=no
|
ac_cv_prog_gcc=no
|
||||||
|
@ -1276,7 +1302,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
|
||||||
ac_save_CFLAGS="$CFLAGS"
|
ac_save_CFLAGS="$CFLAGS"
|
||||||
CFLAGS=
|
CFLAGS=
|
||||||
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
|
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
|
||||||
echo "configure:1280: checking whether ${CC-cc} accepts -g" >&5
|
echo "configure:1306: checking whether ${CC-cc} accepts -g" >&5
|
||||||
if eval "test \"\${ac_cv_prog_cc_g+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_cc_g+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1310,7 +1336,7 @@ fi
|
||||||
# Extract the first word of "ranlib", so it can be a program name with args.
|
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||||
set dummy ranlib; ac_word=$2
|
set dummy ranlib; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:1314: checking for $ac_word" >&5
|
echo "configure:1340: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_RANLIB+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_RANLIB+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1345,7 +1371,7 @@ if test "x$ac_cv_prog_gcc" = xyes; then
|
||||||
STAGE1_CFLAGS="-O2"
|
STAGE1_CFLAGS="-O2"
|
||||||
GRUB_CFLAGS="-O2"
|
GRUB_CFLAGS="-O2"
|
||||||
echo $ac_n "checking whether optimization for size works""... $ac_c" 1>&6
|
echo $ac_n "checking whether optimization for size works""... $ac_c" 1>&6
|
||||||
echo "configure:1349: checking whether optimization for size works" >&5
|
echo "configure:1375: checking whether optimization for size works" >&5
|
||||||
if eval "test \"\${size_flag+set}\" = set"; then
|
if eval "test \"\${size_flag+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1353,14 +1379,14 @@ else
|
||||||
saved_CFLAGS=$CFLAGS
|
saved_CFLAGS=$CFLAGS
|
||||||
CFLAGS="-Os -g"
|
CFLAGS="-Os -g"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 1357 "configure"
|
#line 1383 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
EOF
|
||||||
if { (eval echo configure:1364: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
if { (eval echo configure:1390: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
size_flag=yes
|
size_flag=yes
|
||||||
else
|
else
|
||||||
|
@ -1393,7 +1419,7 @@ CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused"
|
||||||
# Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args.
|
# Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args.
|
||||||
set dummy ${ac_tool_prefix}ld; ac_word=$2
|
set dummy ${ac_tool_prefix}ld; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:1397: checking for $ac_word" >&5
|
echo "configure:1423: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_LD+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_LD+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1425,7 +1451,7 @@ fi
|
||||||
# Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
|
# Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
|
||||||
set dummy ${ac_tool_prefix}objcopy; ac_word=$2
|
set dummy ${ac_tool_prefix}objcopy; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||||
echo "configure:1429: checking for $ac_word" >&5
|
echo "configure:1455: checking for $ac_word" >&5
|
||||||
if eval "test \"\${ac_cv_prog_OBJCOPY+set}\" = set"; then
|
if eval "test \"\${ac_cv_prog_OBJCOPY+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1458,7 +1484,7 @@ fi
|
||||||
# Defined in acinclude.m4.
|
# Defined in acinclude.m4.
|
||||||
|
|
||||||
echo $ac_n "checking if C symbols get an underscore after compilation""... $ac_c" 1>&6
|
echo $ac_n "checking if C symbols get an underscore after compilation""... $ac_c" 1>&6
|
||||||
echo "configure:1462: checking if C symbols get an underscore after compilation" >&5
|
echo "configure:1488: checking if C symbols get an underscore after compilation" >&5
|
||||||
if eval "test \"\${grub_cv_asm_uscore+set}\" = set"; then
|
if eval "test \"\${grub_cv_asm_uscore+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1471,7 +1497,7 @@ func (int *list)
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if { ac_try='${CC-cc} -S conftest.c'; { (eval echo configure:1475: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then :
|
if { ac_try='${CC-cc} -S conftest.c'; { (eval echo configure:1501: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then :
|
||||||
else
|
else
|
||||||
{ echo "configure: error: ${CC-cc} failed to produce assembly code" 1>&2; exit 1; }
|
{ echo "configure: error: ${CC-cc} failed to produce assembly code" 1>&2; exit 1; }
|
||||||
fi
|
fi
|
||||||
|
@ -1493,7 +1519,7 @@ fi
|
||||||
echo "$ac_t""$grub_cv_asm_uscore" 1>&6
|
echo "$ac_t""$grub_cv_asm_uscore" 1>&6
|
||||||
|
|
||||||
echo $ac_n "checking whether ${OBJCOPY} works for absolute addresses""... $ac_c" 1>&6
|
echo $ac_n "checking whether ${OBJCOPY} works for absolute addresses""... $ac_c" 1>&6
|
||||||
echo "configure:1497: checking whether ${OBJCOPY} works for absolute addresses" >&5
|
echo "configure:1523: checking whether ${OBJCOPY} works for absolute addresses" >&5
|
||||||
if eval "test \"\${grub_cv_prog_objcopy_absolute+set}\" = set"; then
|
if eval "test \"\${grub_cv_prog_objcopy_absolute+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1505,21 +1531,21 @@ blah (void)
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if { (eval echo configure:1509: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then :
|
if { (eval echo configure:1535: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then :
|
||||||
else
|
else
|
||||||
{ echo "configure: error: ${CC-cc} cannot compile C source code" 1>&2; exit 1; }
|
{ echo "configure: error: ${CC-cc} cannot compile C source code" 1>&2; exit 1; }
|
||||||
fi
|
fi
|
||||||
grub_cv_prog_objcopy_absolute=yes
|
grub_cv_prog_objcopy_absolute=yes
|
||||||
for link_addr in 2000 8000 7C00; do
|
for link_addr in 2000 8000 7C00; do
|
||||||
if { ac_try='${LD-ld} -N -Ttext $link_addr conftest.o -o conftest.exec'; { (eval echo configure:1515: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
|
if { ac_try='${LD-ld} -N -Ttext $link_addr conftest.o -o conftest.exec'; { (eval echo configure:1541: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
|
||||||
else
|
else
|
||||||
{ echo "configure: error: ${LD-ld} cannot link at address $link_addr" 1>&2; exit 1; }
|
{ echo "configure: error: ${LD-ld} cannot link at address $link_addr" 1>&2; exit 1; }
|
||||||
fi
|
fi
|
||||||
if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1519: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
|
if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1545: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then :
|
||||||
else
|
else
|
||||||
{ echo "configure: error: ${OBJCOPY-objcopy} cannot create binary files" 1>&2; exit 1; }
|
{ echo "configure: error: ${OBJCOPY-objcopy} cannot create binary files" 1>&2; exit 1; }
|
||||||
fi
|
fi
|
||||||
if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1523: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1549: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||||
mv -f conftest conftest.old
|
mv -f conftest conftest.old
|
||||||
else
|
else
|
||||||
grub_cv_prog_objcopy_absolute=no
|
grub_cv_prog_objcopy_absolute=no
|
||||||
|
@ -1536,7 +1562,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for .code16 addr32 assembler support""... $ac_c" 1>&6
|
echo $ac_n "checking for .code16 addr32 assembler support""... $ac_c" 1>&6
|
||||||
echo "configure:1540: checking for .code16 addr32 assembler support" >&5
|
echo "configure:1566: checking for .code16 addr32 assembler support" >&5
|
||||||
if eval "test \"\${grub_cv_asm_addr32+set}\" = set"; then
|
if eval "test \"\${grub_cv_asm_addr32+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1546,7 +1572,7 @@ l1: addr32
|
||||||
movb %al, l1
|
movb %al, l1
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if { ac_try='${CC-cc} -c conftest.s'; { (eval echo configure:1550: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
|
if { ac_try='${CC-cc} -c conftest.s'; { (eval echo configure:1576: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
|
||||||
grub_cv_asm_addr32=yes
|
grub_cv_asm_addr32=yes
|
||||||
else
|
else
|
||||||
grub_cv_asm_addr32=no
|
grub_cv_asm_addr32=no
|
||||||
|
@ -1561,7 +1587,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking whether addr32 must be in the same line as the instruction""... $ac_c" 1>&6
|
echo $ac_n "checking whether addr32 must be in the same line as the instruction""... $ac_c" 1>&6
|
||||||
echo "configure:1565: checking whether addr32 must be in the same line as the instruction" >&5
|
echo "configure:1591: checking whether addr32 must be in the same line as the instruction" >&5
|
||||||
if eval "test \"\${grub_cv_asm_prefix_requirement+set}\" = set"; then
|
if eval "test \"\${grub_cv_asm_prefix_requirement+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
|
@ -1570,7 +1596,7 @@ else
|
||||||
l1: addr32 movb %al, l1
|
l1: addr32 movb %al, l1
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if { ac_try='${CC-cc} -c conftest.s'; { (eval echo configure:1574: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
|
if { ac_try='${CC-cc} -c conftest.s'; { (eval echo configure:1600: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then
|
||||||
grub_cv_asm_prefix_requirement=yes
|
grub_cv_asm_prefix_requirement=yes
|
||||||
else
|
else
|
||||||
grub_cv_asm_prefix_requirement=no
|
grub_cv_asm_prefix_requirement=no
|
||||||
|
@ -1601,7 +1627,7 @@ fi
|
||||||
|
|
||||||
# Check for curses libraries.
|
# Check for curses libraries.
|
||||||
echo $ac_n "checking for wgetch in -lncurses""... $ac_c" 1>&6
|
echo $ac_n "checking for wgetch in -lncurses""... $ac_c" 1>&6
|
||||||
echo "configure:1605: checking for wgetch in -lncurses" >&5
|
echo "configure:1631: checking for wgetch in -lncurses" >&5
|
||||||
ac_lib_var=`echo ncurses'_'wgetch | sed 'y%./+-:%__p__%'`
|
ac_lib_var=`echo ncurses'_'wgetch | sed 'y%./+-:%__p__%'`
|
||||||
if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
|
if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
|
@ -1609,7 +1635,7 @@ else
|
||||||
ac_save_LIBS="$LIBS"
|
ac_save_LIBS="$LIBS"
|
||||||
LIBS="-lncurses $LIBS"
|
LIBS="-lncurses $LIBS"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 1613 "configure"
|
#line 1639 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
/* Override any gcc2 internal prototype to avoid an error. */
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
/* We use char because int might match the return type of a gcc2
|
/* We use char because int might match the return type of a gcc2
|
||||||
|
@ -1620,7 +1646,7 @@ int main() {
|
||||||
wgetch()
|
wgetch()
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
EOF
|
||||||
if { (eval echo configure:1624: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
if { (eval echo configure:1650: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||||
else
|
else
|
||||||
|
@ -1643,7 +1669,7 @@ EOF
|
||||||
else
|
else
|
||||||
echo "$ac_t""no" 1>&6
|
echo "$ac_t""no" 1>&6
|
||||||
echo $ac_n "checking for wgetch in -lcurses""... $ac_c" 1>&6
|
echo $ac_n "checking for wgetch in -lcurses""... $ac_c" 1>&6
|
||||||
echo "configure:1647: checking for wgetch in -lcurses" >&5
|
echo "configure:1673: checking for wgetch in -lcurses" >&5
|
||||||
ac_lib_var=`echo curses'_'wgetch | sed 'y%./+-:%__p__%'`
|
ac_lib_var=`echo curses'_'wgetch | sed 'y%./+-:%__p__%'`
|
||||||
if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
|
if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
|
@ -1651,7 +1677,7 @@ else
|
||||||
ac_save_LIBS="$LIBS"
|
ac_save_LIBS="$LIBS"
|
||||||
LIBS="-lcurses $LIBS"
|
LIBS="-lcurses $LIBS"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 1655 "configure"
|
#line 1681 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
/* Override any gcc2 internal prototype to avoid an error. */
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
/* We use char because int might match the return type of a gcc2
|
/* We use char because int might match the return type of a gcc2
|
||||||
|
@ -1662,7 +1688,7 @@ int main() {
|
||||||
wgetch()
|
wgetch()
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
EOF
|
||||||
if { (eval echo configure:1666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
if { (eval echo configure:1692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||||
else
|
else
|
||||||
|
@ -1692,7 +1718,7 @@ fi
|
||||||
|
|
||||||
# Check for headers.
|
# Check for headers.
|
||||||
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
|
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
|
||||||
echo "configure:1696: checking how to run the C preprocessor" >&5
|
echo "configure:1722: checking how to run the C preprocessor" >&5
|
||||||
# On Suns, sometimes $CPP names a directory.
|
# On Suns, sometimes $CPP names a directory.
|
||||||
if test -n "$CPP" && test -d "$CPP"; then
|
if test -n "$CPP" && test -d "$CPP"; then
|
||||||
CPP=
|
CPP=
|
||||||
|
@ -1707,13 +1733,13 @@ else
|
||||||
# On the NeXT, cc -E runs the code through the compiler's parser,
|
# On the NeXT, cc -E runs the code through the compiler's parser,
|
||||||
# not just through cpp.
|
# not just through cpp.
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 1711 "configure"
|
#line 1737 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
Syntax Error
|
Syntax Error
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||||
{ (eval echo configure:1717: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
{ (eval echo configure:1743: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
:
|
:
|
||||||
|
@ -1724,13 +1750,13 @@ else
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
CPP="${CC-cc} -E -traditional-cpp"
|
CPP="${CC-cc} -E -traditional-cpp"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 1728 "configure"
|
#line 1754 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
Syntax Error
|
Syntax Error
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||||
{ (eval echo configure:1734: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
{ (eval echo configure:1760: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
:
|
:
|
||||||
|
@ -1741,13 +1767,13 @@ else
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
CPP="${CC-cc} -nologo -E"
|
CPP="${CC-cc} -nologo -E"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 1745 "configure"
|
#line 1771 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
Syntax Error
|
Syntax Error
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||||
{ (eval echo configure:1751: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
{ (eval echo configure:1777: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
:
|
:
|
||||||
|
@ -1775,17 +1801,17 @@ for ac_hdr in string.h strings.h ncurses/curses.h ncurses.h curses.h
|
||||||
do
|
do
|
||||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||||
echo "configure:1779: checking for $ac_hdr" >&5
|
echo "configure:1805: checking for $ac_hdr" >&5
|
||||||
if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
|
if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 1784 "configure"
|
#line 1810 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <$ac_hdr>
|
#include <$ac_hdr>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||||
{ (eval echo configure:1789: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
{ (eval echo configure:1815: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
|
@ -1859,6 +1885,17 @@ if test x"$enable_minix" != xno; then
|
||||||
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_MINIX=1"
|
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_MINIX=1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-tftp or --disable-tftp was given.
|
||||||
|
if test "${enable_tftp+set}" = set; then
|
||||||
|
enableval="$enable_tftp"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_tftp" = xyes; then
|
||||||
|
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
|
||||||
|
fi
|
||||||
|
|
||||||
# Check whether --enable-gunzip or --disable-gunzip was given.
|
# Check whether --enable-gunzip or --disable-gunzip was given.
|
||||||
if test "${enable_gunzip+set}" = set; then
|
if test "${enable_gunzip+set}" = set; then
|
||||||
enableval="$enable_gunzip"
|
enableval="$enable_gunzip"
|
||||||
|
@ -1872,6 +1909,144 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --enable-ne or --disable-ne was given.
|
||||||
|
if test "${enable_ne+set}" = set; then
|
||||||
|
enableval="$enable_ne"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_ne" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-nepci or --disable-nepci was given.
|
||||||
|
if test "${enable_nepci+set}" = set; then
|
||||||
|
enableval="$enable_nepci"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_nepci" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NEPCI=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-wd or --disable-wd was given.
|
||||||
|
if test "${enable_wd+set}" = set; then
|
||||||
|
enableval="$enable_wd"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_wd" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-t503 or --disable-t503 was given.
|
||||||
|
if test "${enable_t503+set}" = set; then
|
||||||
|
enableval="$enable_t503"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_t503" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_T503=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-t509 or --disable-t509 was given.
|
||||||
|
if test "${enable_t509+set}" = set; then
|
||||||
|
enableval="$enable_t509"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_t509" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_T509=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-3c59x or --disable-3c59x was given.
|
||||||
|
if test "${enable_3c59x+set}" = set; then
|
||||||
|
enableval="$enable_3c59x"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_3c59x" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C59X=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-lance or --disable-lance was given.
|
||||||
|
if test "${enable_lance+set}" = set; then
|
||||||
|
enableval="$enable_lance"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_lance" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-cs or --disable-cs was given.
|
||||||
|
if test "${enable_cs+set}" = set; then
|
||||||
|
enableval="$enable_cs"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_cs" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --enable-eepro100 or --disable-eepro100 was given.
|
||||||
|
if test "${enable_eepro100+set}" = set; then
|
||||||
|
enableval="$enable_eepro100"
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$enable_eepro100" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO100=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if test ! -z "$NET_CFLAGS"; then
|
||||||
|
NETBOOT_SUPPORT_TRUE=
|
||||||
|
NETBOOT_SUPPORT_FALSE='#'
|
||||||
|
else
|
||||||
|
NETBOOT_SUPPORT_TRUE='#'
|
||||||
|
NETBOOT_SUPPORT_FALSE=
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --enable-ne-scan or --disable-ne-scan was given.
|
||||||
|
if test "${enable_ne_scan+set}" = set; then
|
||||||
|
enableval="$enable_ne_scan"
|
||||||
|
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=$enable_ne_scan"
|
||||||
|
else
|
||||||
|
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=0x280,0x300,0x320,0x340"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --enable-wd-default-mem or --disable-wd-default-mem was given.
|
||||||
|
if test "${enable_wd_default_mem+set}" = set; then
|
||||||
|
enableval="$enable_wd_default_mem"
|
||||||
|
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=$enable_wd_default_mem"
|
||||||
|
else
|
||||||
|
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --enable-cs-scan or --disable-cs-scan was given.
|
||||||
|
if test "${enable_cs_scan+set}" = set; then
|
||||||
|
enableval="$enable_cs_scan"
|
||||||
|
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Output.
|
# Output.
|
||||||
trap '' 1 2 15
|
trap '' 1 2 15
|
||||||
|
@ -1976,7 +2151,7 @@ ac_given_srcdir=$srcdir
|
||||||
ac_given_INSTALL="$INSTALL"
|
ac_given_INSTALL="$INSTALL"
|
||||||
|
|
||||||
trap 'rm -fr `echo "Makefile stage1/Makefile stage2/Makefile docs/Makefile \
|
trap 'rm -fr `echo "Makefile stage1/Makefile stage2/Makefile docs/Makefile \
|
||||||
debian/Makefile grub/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
debian/Makefile grub/Makefile netboot/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||||
EOF
|
EOF
|
||||||
cat >> $CONFIG_STATUS <<EOF
|
cat >> $CONFIG_STATUS <<EOF
|
||||||
|
|
||||||
|
@ -2047,6 +2222,10 @@ s%@OBJCOPY@%$OBJCOPY%g
|
||||||
s%@GRUB_LIBS@%$GRUB_LIBS%g
|
s%@GRUB_LIBS@%$GRUB_LIBS%g
|
||||||
s%@CPP@%$CPP%g
|
s%@CPP@%$CPP%g
|
||||||
s%@FSYS_CFLAGS@%$FSYS_CFLAGS%g
|
s%@FSYS_CFLAGS@%$FSYS_CFLAGS%g
|
||||||
|
s%@NET_CFLAGS@%$NET_CFLAGS%g
|
||||||
|
s%@NETBOOT_SUPPORT_TRUE@%$NETBOOT_SUPPORT_TRUE%g
|
||||||
|
s%@NETBOOT_SUPPORT_FALSE@%$NETBOOT_SUPPORT_FALSE%g
|
||||||
|
s%@NET_EXTRAFLAGS@%$NET_EXTRAFLAGS%g
|
||||||
|
|
||||||
CEOF
|
CEOF
|
||||||
EOF
|
EOF
|
||||||
|
@ -2089,7 +2268,7 @@ EOF
|
||||||
cat >> $CONFIG_STATUS <<EOF
|
cat >> $CONFIG_STATUS <<EOF
|
||||||
|
|
||||||
CONFIG_FILES=\${CONFIG_FILES-"Makefile stage1/Makefile stage2/Makefile docs/Makefile \
|
CONFIG_FILES=\${CONFIG_FILES-"Makefile stage1/Makefile stage2/Makefile docs/Makefile \
|
||||||
debian/Makefile grub/Makefile"}
|
debian/Makefile grub/Makefile netboot/Makefile"}
|
||||||
EOF
|
EOF
|
||||||
cat >> $CONFIG_STATUS <<\EOF
|
cat >> $CONFIG_STATUS <<\EOF
|
||||||
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
|
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
|
||||||
|
|
92
configure.in
92
configure.in
|
@ -147,6 +147,13 @@ if test x"$enable_minix" != xno; then
|
||||||
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_MINIX=1"
|
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_MINIX=1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(tftp,
|
||||||
|
[ --enable-tftp enable TFTP support in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_tftp" = xyes; then
|
||||||
|
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
|
||||||
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(gunzip,
|
AC_ARG_ENABLE(gunzip,
|
||||||
[ --disable-gunzip disable decompression in Stage 2])
|
[ --disable-gunzip disable decompression in Stage 2])
|
||||||
|
|
||||||
|
@ -156,7 +163,90 @@ fi
|
||||||
|
|
||||||
AC_SUBST(FSYS_CFLAGS)
|
AC_SUBST(FSYS_CFLAGS)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(ne,
|
||||||
|
[ --enable-ne enable NE1000/2000 network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_ne" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(nepci,
|
||||||
|
[ --enable-nepci enable PCI NE2000 network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_nepci" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NEPCI=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(wd,
|
||||||
|
[ --enable-wd enable WD/SMC network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_wd" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(t503,
|
||||||
|
[ --enable-t503 enable 3C503 network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_t503" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_T503=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(t509,
|
||||||
|
[ --enable-t509 enable 3C509 network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_t509" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_T509=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(3c59x,
|
||||||
|
[ --enable-3c59x enable 3C59x network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_3c59x" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C59X=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(lance,
|
||||||
|
[ --enable-lance enable LANCE network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_lance" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(cs,
|
||||||
|
[ --enable-cs enable CS89*0 network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_cs" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(eepro100,
|
||||||
|
[ --enable-eepro100 enable EtherExpress100 network driver in Stage 2])
|
||||||
|
|
||||||
|
if test x"$enable_eepro100" = xyes; then
|
||||||
|
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO100=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(NET_CFLAGS)
|
||||||
|
AM_CONDITIONAL(NETBOOT_SUPPORT, test ! -z "$NET_CFLAGS")
|
||||||
|
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(ne-scan,
|
||||||
|
[ --enable-ne-scan set the parameter for NE network driver],
|
||||||
|
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=$enable_ne_scan"],
|
||||||
|
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=0x280,0x300,0x320,0x340"])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(wd-default-mem,
|
||||||
|
[ --enable-wd-default-mem set the parameter for WD network driver],
|
||||||
|
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=$enable_wd_default_mem"],
|
||||||
|
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(cs-scan,
|
||||||
|
[ --enable-cs-scan set the parameter for CS network driver],
|
||||||
|
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"])
|
||||||
|
|
||||||
|
AC_SUBST(NET_EXTRAFLAGS)
|
||||||
|
|
||||||
|
|
||||||
# Output.
|
# Output.
|
||||||
AC_OUTPUT([Makefile stage1/Makefile stage2/Makefile docs/Makefile \
|
AC_OUTPUT([Makefile stage1/Makefile stage2/Makefile docs/Makefile \
|
||||||
debian/Makefile grub/Makefile])
|
debian/Makefile grub/Makefile netboot/Makefile])
|
||||||
|
|
2
debian/Makefile.in
vendored
2
debian/Makefile.in
vendored
|
@ -69,6 +69,8 @@ GRUB_LIBS = @GRUB_LIBS@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NET_CFLAGS = @NET_CFLAGS@
|
||||||
|
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||||
OBJCOPY = @OBJCOPY@
|
OBJCOPY = @OBJCOPY@
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
|
|
@ -1,3 +1 @@
|
||||||
*.info*
|
*.info*
|
||||||
version.texi
|
|
||||||
stamp-vti
|
|
||||||
|
|
|
@ -69,6 +69,8 @@ GRUB_LIBS = @GRUB_LIBS@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NET_CFLAGS = @NET_CFLAGS@
|
||||||
|
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||||
OBJCOPY = @OBJCOPY@
|
OBJCOPY = @OBJCOPY@
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
|
3
docs/stamp-vti
Normal file
3
docs/stamp-vti
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@set UPDATED 10 September 1999
|
||||||
|
@set EDITION 0.5.93
|
||||||
|
@set VERSION 0.5.93
|
3
docs/version.texi
Normal file
3
docs/version.texi
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@set UPDATED 10 September 1999
|
||||||
|
@set EDITION 0.5.93
|
||||||
|
@set VERSION 0.5.93
|
|
@ -69,6 +69,8 @@ GRUB_LIBS = @GRUB_LIBS@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NET_CFLAGS = @NET_CFLAGS@
|
||||||
|
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||||
OBJCOPY = @OBJCOPY@
|
OBJCOPY = @OBJCOPY@
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
|
574
netboot/3c509.c
Normal file
574
netboot/3c509.c
Normal file
|
@ -0,0 +1,574 @@
|
||||||
|
/**************************************************************************
|
||||||
|
NETBOOT - BOOTP/TFTP Bootstrap Program
|
||||||
|
|
||||||
|
Author: Martin Renters.
|
||||||
|
Date: Mar 22 1995
|
||||||
|
|
||||||
|
This code is based heavily on David Greenman's if_ed.c driver and
|
||||||
|
Andres Vega Garcia's if_ep.c driver.
|
||||||
|
|
||||||
|
Copyright (C) 1993-1994, David Greenman, Martin Renters.
|
||||||
|
Copyright (C) 1993-1995, Andres Vega Garcia.
|
||||||
|
Copyright (C) 1995, Serge Babkin.
|
||||||
|
This software may be used, modified, copied, distributed, and sold, in
|
||||||
|
both source and binary form provided that the above copyright and these
|
||||||
|
terms are retained. Under no circumstances are the authors responsible for
|
||||||
|
the proper functioning of this software, nor do the authors assume any
|
||||||
|
responsibility for damages incurred with its use.
|
||||||
|
|
||||||
|
3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef INCLUDE_T509
|
||||||
|
|
||||||
|
/* #define EDEBUG */
|
||||||
|
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "nic.h"
|
||||||
|
#include "3c509.h"
|
||||||
|
|
||||||
|
static unsigned char eth_vendor, eth_flags, eth_laar;
|
||||||
|
static unsigned short eth_nic_base, eth_asic_base;
|
||||||
|
static char bnc=0, utp=0; /* for 3C509 */
|
||||||
|
|
||||||
|
static void safetwiddle()
|
||||||
|
{
|
||||||
|
static int count=0;
|
||||||
|
static int count2=0;
|
||||||
|
static char tiddles[]="-\\|/";
|
||||||
|
putchar(tiddles[(count2++)&0xfff?count&3:(count++)&3]);
|
||||||
|
putchar('\b');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a surrogate */
|
||||||
|
|
||||||
|
static void DELAY(int val)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for(c=0; c<val; c+=20) {
|
||||||
|
twiddle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SAFEDELAY(int val)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for (c=0; c<val; c+=20) {
|
||||||
|
safetwiddle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_RESET - Reset adapter
|
||||||
|
***************************************************************************/
|
||||||
|
static void t509_reset(struct nic *nic)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
Reset 3Com 509 card
|
||||||
|
*************************************************************/
|
||||||
|
|
||||||
|
if (eth_vendor != VENDOR_3C509)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* stop card */
|
||||||
|
outw(BASE + EP_COMMAND, RX_DISABLE);
|
||||||
|
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||||
|
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
|
||||||
|
outw(BASE + EP_COMMAND, TX_DISABLE);
|
||||||
|
outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
|
||||||
|
outw(BASE + EP_COMMAND, RX_RESET);
|
||||||
|
outw(BASE + EP_COMMAND, TX_RESET);
|
||||||
|
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||||
|
outw(BASE + EP_COMMAND, SET_RD_0_MASK);
|
||||||
|
outw(BASE + EP_COMMAND, SET_INTR_MASK);
|
||||||
|
outw(BASE + EP_COMMAND, SET_RX_FILTER);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialize card
|
||||||
|
*/
|
||||||
|
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
|
||||||
|
|
||||||
|
GO_WINDOW(0);
|
||||||
|
|
||||||
|
/* Disable the card */
|
||||||
|
outw(BASE + EP_W0_CONFIG_CTRL, 0);
|
||||||
|
|
||||||
|
/* Configure IRQ to none */
|
||||||
|
outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(0));
|
||||||
|
|
||||||
|
/* Enable the card */
|
||||||
|
outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
|
||||||
|
|
||||||
|
GO_WINDOW(2);
|
||||||
|
|
||||||
|
/* Reload the ether_addr. */
|
||||||
|
for (i = 0; i < ETHER_ADDR_SIZE; i++)
|
||||||
|
outb(BASE + EP_W2_ADDR_0 + i, nic->node_addr[i]);
|
||||||
|
|
||||||
|
outw(BASE + EP_COMMAND, RX_RESET);
|
||||||
|
outw(BASE + EP_COMMAND, TX_RESET);
|
||||||
|
|
||||||
|
/* Window 1 is operating window */
|
||||||
|
GO_WINDOW(1);
|
||||||
|
for (i = 0; i < 31; i++)
|
||||||
|
inb(BASE + EP_W1_TX_STATUS);
|
||||||
|
|
||||||
|
/* get rid of stray intr's */
|
||||||
|
outw(BASE + EP_COMMAND, ACK_INTR | 0xff);
|
||||||
|
|
||||||
|
outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
|
||||||
|
|
||||||
|
outw(BASE + EP_COMMAND, SET_INTR_MASK);
|
||||||
|
|
||||||
|
outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
|
||||||
|
FIL_BRDCST);
|
||||||
|
|
||||||
|
/* configure BNC */
|
||||||
|
if (bnc) {
|
||||||
|
outw(BASE + EP_COMMAND, START_TRANSCEIVER);
|
||||||
|
SAFEDELAY(1000);
|
||||||
|
}
|
||||||
|
/* configure UTP */
|
||||||
|
if (utp) {
|
||||||
|
GO_WINDOW(4);
|
||||||
|
outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
|
||||||
|
GO_WINDOW(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start tranciever and receiver */
|
||||||
|
outw(BASE + EP_COMMAND, RX_ENABLE);
|
||||||
|
outw(BASE + EP_COMMAND, TX_ENABLE);
|
||||||
|
|
||||||
|
/* set early threshold for minimal packet length */
|
||||||
|
outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | ETH_MIN_PACKET);
|
||||||
|
|
||||||
|
outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_TRANSMIT - Transmit a frame
|
||||||
|
***************************************************************************/
|
||||||
|
static char padmap[] = {
|
||||||
|
0, 3, 2, 1};
|
||||||
|
|
||||||
|
static void t509_transmit(
|
||||||
|
struct nic *nic,
|
||||||
|
char *d, /* Destination */
|
||||||
|
unsigned int t, /* Type */
|
||||||
|
unsigned int s, /* size */
|
||||||
|
char *p) /* Packet */
|
||||||
|
{
|
||||||
|
register u_int len;
|
||||||
|
int pad;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(eth_vendor != VENDOR_3C509)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef EDEBUG
|
||||||
|
printf("{l=%d,t=%x}",s+ETHER_HDR_SIZE,t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* swap bytes of type */
|
||||||
|
t= htons(t);
|
||||||
|
|
||||||
|
len=s+ETHER_HDR_SIZE; /* actual length of packet */
|
||||||
|
pad = padmap[len & 3];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 3c509 automatically pads short packets to minimum ethernet length,
|
||||||
|
* but we drop packets that are too large. Perhaps we should truncate
|
||||||
|
* them instead?
|
||||||
|
*/
|
||||||
|
if (len + pad > ETH_MAX_PACKET) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* drop acknowledgements */
|
||||||
|
while(( status=inb(BASE + EP_W1_TX_STATUS) )& TXS_COMPLETE ) {
|
||||||
|
if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
|
||||||
|
outw(BASE + EP_COMMAND, TX_RESET);
|
||||||
|
outw(BASE + EP_COMMAND, TX_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
outb(BASE + EP_W1_TX_STATUS, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
|
||||||
|
/* no room in FIFO */
|
||||||
|
}
|
||||||
|
|
||||||
|
outw(BASE + EP_W1_TX_PIO_WR_1, len);
|
||||||
|
outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
|
||||||
|
|
||||||
|
/* write packet */
|
||||||
|
outsw(BASE + EP_W1_TX_PIO_WR_1, d, ETHER_ADDR_SIZE/2);
|
||||||
|
outsw(BASE + EP_W1_TX_PIO_WR_1, nic->node_addr, ETHER_ADDR_SIZE/2);
|
||||||
|
outw(BASE + EP_W1_TX_PIO_WR_1, t);
|
||||||
|
outsw(BASE + EP_W1_TX_PIO_WR_1, p, s / 2);
|
||||||
|
if (s & 1)
|
||||||
|
outb(BASE + EP_W1_TX_PIO_WR_1, *(p+s - 1));
|
||||||
|
|
||||||
|
while (pad--)
|
||||||
|
outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */
|
||||||
|
|
||||||
|
/* timeout after sending */
|
||||||
|
DELAY(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_POLL - Wait for a frame
|
||||||
|
***************************************************************************/
|
||||||
|
static int t509_poll(struct nic *nic)
|
||||||
|
{
|
||||||
|
/* common variables */
|
||||||
|
unsigned short type = 0; /* used by EDEBUG */
|
||||||
|
/* variables for 3C509 */
|
||||||
|
short status, cst;
|
||||||
|
register short rx_fifo;
|
||||||
|
|
||||||
|
if(eth_vendor!=VENDOR_3C509)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cst=inw(BASE + EP_STATUS);
|
||||||
|
|
||||||
|
#ifdef EDEBUG
|
||||||
|
if(cst & 0x1FFF)
|
||||||
|
printf("-%x-",cst);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( (cst & S_RX_COMPLETE)==0 ) {
|
||||||
|
/* acknowledge everything */
|
||||||
|
outw(BASE + EP_COMMAND, ACK_INTR| (cst & S_5_INTS));
|
||||||
|
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = inw(BASE + EP_W1_RX_STATUS);
|
||||||
|
#ifdef EDEBUG
|
||||||
|
printf("*%x*",status);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (status & ERR_RX) {
|
||||||
|
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rx_fifo = status & RX_BYTES_MASK;
|
||||||
|
if (rx_fifo==0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* read packet */
|
||||||
|
#ifdef EDEBUG
|
||||||
|
printf("[l=%d",rx_fifo);
|
||||||
|
#endif
|
||||||
|
insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
|
||||||
|
if(rx_fifo & 1)
|
||||||
|
nic->packet[rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
|
||||||
|
nic->packetlen=rx_fifo;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
status = inw(BASE + EP_W1_RX_STATUS);
|
||||||
|
#ifdef EDEBUG
|
||||||
|
printf("*%x*",status);
|
||||||
|
#endif
|
||||||
|
rx_fifo = status & RX_BYTES_MASK;
|
||||||
|
|
||||||
|
if(rx_fifo>0) {
|
||||||
|
insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
|
||||||
|
if(rx_fifo & 1)
|
||||||
|
nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
|
||||||
|
nic->packetlen+=rx_fifo;
|
||||||
|
#ifdef EDEBUG
|
||||||
|
printf("+%d",rx_fifo);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if(( status & RX_INCOMPLETE )==0) {
|
||||||
|
#ifdef EDEBUG
|
||||||
|
printf("=%d",nic->packetlen);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DELAY(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* acknowledge reception of packet */
|
||||||
|
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||||
|
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
|
||||||
|
#ifdef EDEBUG
|
||||||
|
type = (nic->packet[12]<<8) | nic->packet[13];
|
||||||
|
if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
|
||||||
|
nic->packet[5] == 0xFF*ETHER_ADDR_SIZE)
|
||||||
|
printf(",t=0x%x,b]",type);
|
||||||
|
else
|
||||||
|
printf(",t=0x%x]",type);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
3Com 509 - specific routines
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
static int
|
||||||
|
eeprom_rdy()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);
|
||||||
|
if (i >= MAX_EEPROMBUSY) {
|
||||||
|
/* printf("3c509: eeprom failed to come ready.\r\n"); */
|
||||||
|
printf("3c509: eeprom is busy.\r\n"); /* memory in EPROM is tight */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_e: gets a 16 bits word from the EEPROM. we must have set the window
|
||||||
|
* before
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_e(offset)
|
||||||
|
int offset;
|
||||||
|
{
|
||||||
|
if (!eeprom_rdy())
|
||||||
|
return (0xffff);
|
||||||
|
outw(IS_BASE + EP_W0_EEPROM_COMMAND, EEPROM_CMD_RD | offset);
|
||||||
|
if (!eeprom_rdy())
|
||||||
|
return (0xffff);
|
||||||
|
return (inw(IS_BASE + EP_W0_EEPROM_DATA));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
send_ID_sequence(port)
|
||||||
|
int port;
|
||||||
|
{
|
||||||
|
int cx, al;
|
||||||
|
|
||||||
|
for (al = 0xff, cx = 0; cx < 255; cx++) {
|
||||||
|
outb(port, al);
|
||||||
|
al <<= 1;
|
||||||
|
if (al & 0x100)
|
||||||
|
al ^= 0xcf;
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We get eeprom data from the id_port given an offset into the eeprom.
|
||||||
|
* Basically; after the ID_sequence is sent to all of the cards; they enter
|
||||||
|
* the ID_CMD state where they will accept command requests. 0x80-0xbf loads
|
||||||
|
* the eeprom data. We then read the port 16 times and with every read; the
|
||||||
|
* cards check for contention (ie: if one card writes a 0 bit and another
|
||||||
|
* writes a 1 bit then the host sees a 0. At the end of the cycle; each card
|
||||||
|
* compares the data on the bus; if there is a difference then that card goes
|
||||||
|
* into ID_WAIT state again). In the meantime; one bit of data is returned in
|
||||||
|
* the AX register which is conveniently returned to us by inb(). Hence; we
|
||||||
|
* read 16 times getting one bit of data with each read.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_eeprom_data(id_port, offset)
|
||||||
|
int id_port;
|
||||||
|
int offset;
|
||||||
|
{
|
||||||
|
int i, data = 0;
|
||||||
|
outb(id_port, 0x80 + offset);
|
||||||
|
DELAY(1000);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
data = (data << 1) | (inw(id_port) & 1);
|
||||||
|
return (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t509_disable(struct nic *nic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_PROBE - Look for an adapter
|
||||||
|
***************************************************************************/
|
||||||
|
struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||||
|
{
|
||||||
|
/* common variables */
|
||||||
|
int i;
|
||||||
|
int failcount;
|
||||||
|
|
||||||
|
|
||||||
|
/* variables for 3C509 */
|
||||||
|
|
||||||
|
|
||||||
|
for (failcount=0; failcount<4000; failcount++) {
|
||||||
|
int data, j, io_base, id_port = EP_ID_PORT;
|
||||||
|
u_short k;
|
||||||
|
int ep_current_tag = EP_LAST_TAG + 1;
|
||||||
|
short *p;
|
||||||
|
|
||||||
|
id_port = EP_ID_PORT;
|
||||||
|
ep_current_tag = EP_LAST_TAG + 1;
|
||||||
|
eth_vendor = VENDOR_NONE;
|
||||||
|
|
||||||
|
/*********************************************************
|
||||||
|
Search for 3Com 509 card
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
/* Look for the EISA boards, leave them activated */
|
||||||
|
/* search for the first card, ignore all others */
|
||||||
|
for(j = 1; j < 16 && eth_vendor==VENDOR_NONE ; j++) {
|
||||||
|
io_base = (j * EP_EISA_START) | EP_EISA_W0;
|
||||||
|
if (inw(io_base + EP_W0_MFG_ID) != MFG_ID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* we must found 0x1f if the board is EISA configurated */
|
||||||
|
if ((inw(io_base + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Reset and Enable the card */
|
||||||
|
outb(io_base + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER);
|
||||||
|
SAFEDELAY(1000); /* we must wait at least 1 ms */
|
||||||
|
outb(io_base + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Once activated, all the registers are mapped in the range
|
||||||
|
* x000 - x00F, where x is the slot number.
|
||||||
|
*/
|
||||||
|
eth_nic_base = j * EP_EISA_START;
|
||||||
|
eth_vendor = VENDOR_3C509;
|
||||||
|
}
|
||||||
|
ep_current_tag--;
|
||||||
|
|
||||||
|
/* Look for the ISA boards. Init and leave them actived */
|
||||||
|
/* search for the first card, ignore all others */
|
||||||
|
outb(id_port, 0xc0); /* Global reset */
|
||||||
|
SAFEDELAY(1000);
|
||||||
|
for (i = 0; i < EP_MAX_BOARDS && eth_vendor==VENDOR_NONE; i++) {
|
||||||
|
outb(id_port, 0);
|
||||||
|
outb(id_port, 0);
|
||||||
|
send_ID_sequence(id_port);
|
||||||
|
|
||||||
|
data = get_eeprom_data(id_port, EEPROM_MFG_ID);
|
||||||
|
if (data != MFG_ID)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* resolve contention using the Ethernet address */
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
data = get_eeprom_data(id_port, j);
|
||||||
|
|
||||||
|
eth_nic_base =
|
||||||
|
(get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
|
||||||
|
outb(id_port, ep_current_tag); /* tags board */
|
||||||
|
outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG);
|
||||||
|
eth_vendor = VENDOR_3C509;
|
||||||
|
ep_current_tag--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(eth_vendor != VENDOR_3C509)
|
||||||
|
goto no3c509;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
|
||||||
|
* 0x9[0-f]50
|
||||||
|
*/
|
||||||
|
GO_WINDOW(0);
|
||||||
|
k = get_e(EEPROM_PROD_ID);
|
||||||
|
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
|
||||||
|
goto no3c509;
|
||||||
|
|
||||||
|
if(eth_nic_base >= EP_EISA_START) {
|
||||||
|
printf("3C5x9 board on EISA at 0x%x - ",eth_nic_base);
|
||||||
|
} else {
|
||||||
|
printf("3C5x9 board on ISA at 0x%x - ",eth_nic_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test for presence of connectors */
|
||||||
|
i = inw(IS_BASE + EP_W0_CONFIG_CTRL);
|
||||||
|
j = inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14;
|
||||||
|
|
||||||
|
switch(j) {
|
||||||
|
case 0:
|
||||||
|
if(i & IS_UTP) {
|
||||||
|
printf("10baseT\r\n");
|
||||||
|
utp=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("10baseT not present\r\n");
|
||||||
|
eth_vendor=VENDOR_NONE;
|
||||||
|
goto no3c509;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(i & IS_AUI)
|
||||||
|
printf("10base5\r\n");
|
||||||
|
else {
|
||||||
|
printf("10base5 not present\r\n");
|
||||||
|
eth_vendor=VENDOR_NONE;
|
||||||
|
goto no3c509;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(i & IS_BNC) {
|
||||||
|
printf("10base2\r\n");
|
||||||
|
bnc=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("10base2 not present\r\n");
|
||||||
|
eth_vendor=VENDOR_NONE;
|
||||||
|
goto no3c509;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unknown connector\r\n");
|
||||||
|
eth_vendor=VENDOR_NONE;
|
||||||
|
goto no3c509;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Read the station address from the eeprom
|
||||||
|
*/
|
||||||
|
p = (u_short *) nic->node_addr;
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
GO_WINDOW(0);
|
||||||
|
p[i] = htons(get_e(i));
|
||||||
|
GO_WINDOW(2);
|
||||||
|
outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Ethernet address: ");
|
||||||
|
for(i=0; i<5; i++) {
|
||||||
|
printf("%b:",nic->node_addr[i]);
|
||||||
|
}
|
||||||
|
printf("%b\r\n",nic->node_addr[i]);
|
||||||
|
|
||||||
|
t509_reset(nic);
|
||||||
|
nic->reset = t509_reset;
|
||||||
|
nic->poll = t509_poll;
|
||||||
|
nic->transmit = t509_transmit;
|
||||||
|
nic->disable = t509_disable;
|
||||||
|
return nic;
|
||||||
|
no3c509:
|
||||||
|
eth_vendor = VENDOR_NONE;
|
||||||
|
printf("(probe fail)");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* INCLUDE_T509 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* End:
|
||||||
|
*/
|
389
netboot/3c509.h
Normal file
389
netboot/3c509.h
Normal file
|
@ -0,0 +1,389 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) 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. The name
|
||||||
|
* of the author may not be used to endorse or promote products derived from
|
||||||
|
* this software withough specific prior written permission
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
|
||||||
|
*
|
||||||
|
* if_epreg.h,v 1.4 1994/11/13 10:12:37 gibbs Exp Modified by:
|
||||||
|
*
|
||||||
|
October 2, 1994
|
||||||
|
|
||||||
|
Modified by: Andres Vega Garcia
|
||||||
|
|
||||||
|
INRIA - Sophia Antipolis, France
|
||||||
|
e-mail: avega@sophia.inria.fr
|
||||||
|
finger: avega@pax.inria.fr
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ethernet software status per interface.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Some global constants
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TX_INIT_RATE 16
|
||||||
|
#define TX_INIT_MAX_RATE 64
|
||||||
|
#define RX_INIT_LATENCY 64
|
||||||
|
#define RX_INIT_EARLY_THRESH 64
|
||||||
|
#define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */
|
||||||
|
#define MIN_RX_EARLY_THRESHL 4
|
||||||
|
|
||||||
|
#define EEPROMSIZE 0x40
|
||||||
|
#define MAX_EEPROMBUSY 1000
|
||||||
|
#define EP_LAST_TAG 0xd7
|
||||||
|
#define EP_MAX_BOARDS 16
|
||||||
|
#define EP_ID_PORT 0x100
|
||||||
|
|
||||||
|
/*
|
||||||
|
* some macros to acces long named fields
|
||||||
|
*/
|
||||||
|
#define IS_BASE (eth_nic_base)
|
||||||
|
#define BASE (eth_nic_base)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Commands to read/write EEPROM trough EEPROM command register (Window 0,
|
||||||
|
* Offset 0xa)
|
||||||
|
*/
|
||||||
|
#define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */
|
||||||
|
#define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */
|
||||||
|
#define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */
|
||||||
|
#define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */
|
||||||
|
|
||||||
|
#define EEPROM_BUSY (1<<15)
|
||||||
|
#define EEPROM_TST_MODE (1<<14)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some short functions, worth to let them be a macro
|
||||||
|
*/
|
||||||
|
#define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
|
||||||
|
#define GO_WINDOW(x) outw(BASE+EP_COMMAND, WINDOW_SELECT|(x))
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* *
|
||||||
|
* These define the EEPROM data structure. They are used in the probe
|
||||||
|
* function to verify the existance of the adapter after having sent
|
||||||
|
* the ID_Sequence.
|
||||||
|
*
|
||||||
|
* There are others but only the ones we use are defined here.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define EEPROM_NODE_ADDR_0 0x0 /* Word */
|
||||||
|
#define EEPROM_NODE_ADDR_1 0x1 /* Word */
|
||||||
|
#define EEPROM_NODE_ADDR_2 0x2 /* Word */
|
||||||
|
#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
|
||||||
|
#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
|
||||||
|
#define EEPROM_ADDR_CFG 0x8 /* Base addr */
|
||||||
|
#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* *
|
||||||
|
* These are the registers for the 3Com 3c509 and their bit patterns when *
|
||||||
|
* applicable. They have been taken out the the "EtherLink III Parallel *
|
||||||
|
* Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
|
||||||
|
* from 3com. *
|
||||||
|
* *
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define EP_COMMAND 0x0e /* Write. BASE+0x0e is always a
|
||||||
|
* command reg. */
|
||||||
|
#define EP_STATUS 0x0e /* Read. BASE+0x0e is always status
|
||||||
|
* reg. */
|
||||||
|
#define EP_WINDOW 0x0f /* Read. BASE+0x0f is always window
|
||||||
|
* reg. */
|
||||||
|
/*
|
||||||
|
* Window 0 registers. Setup.
|
||||||
|
*/
|
||||||
|
/* Write */
|
||||||
|
#define EP_W0_EEPROM_DATA 0x0c
|
||||||
|
#define EP_W0_EEPROM_COMMAND 0x0a
|
||||||
|
#define EP_W0_RESOURCE_CFG 0x08
|
||||||
|
#define EP_W0_ADDRESS_CFG 0x06
|
||||||
|
#define EP_W0_CONFIG_CTRL 0x04
|
||||||
|
/* Read */
|
||||||
|
#define EP_W0_PRODUCT_ID 0x02
|
||||||
|
#define EP_W0_MFG_ID 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window 1 registers. Operating Set.
|
||||||
|
*/
|
||||||
|
/* Write */
|
||||||
|
#define EP_W1_TX_PIO_WR_2 0x02
|
||||||
|
#define EP_W1_TX_PIO_WR_1 0x00
|
||||||
|
/* Read */
|
||||||
|
#define EP_W1_FREE_TX 0x0c
|
||||||
|
#define EP_W1_TX_STATUS 0x0b /* byte */
|
||||||
|
#define EP_W1_TIMER 0x0a /* byte */
|
||||||
|
#define EP_W1_RX_STATUS 0x08
|
||||||
|
#define EP_W1_RX_PIO_RD_2 0x02
|
||||||
|
#define EP_W1_RX_PIO_RD_1 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window 2 registers. Station Address Setup/Read
|
||||||
|
*/
|
||||||
|
/* Read/Write */
|
||||||
|
#define EP_W2_ADDR_5 0x05
|
||||||
|
#define EP_W2_ADDR_4 0x04
|
||||||
|
#define EP_W2_ADDR_3 0x03
|
||||||
|
#define EP_W2_ADDR_2 0x02
|
||||||
|
#define EP_W2_ADDR_1 0x01
|
||||||
|
#define EP_W2_ADDR_0 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window 3 registers. FIFO Management.
|
||||||
|
*/
|
||||||
|
/* Read */
|
||||||
|
#define EP_W3_FREE_TX 0x0c
|
||||||
|
#define EP_W3_FREE_RX 0x0a
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window 4 registers. Diagnostics.
|
||||||
|
*/
|
||||||
|
/* Read/Write */
|
||||||
|
#define EP_W4_MEDIA_TYPE 0x0a
|
||||||
|
#define EP_W4_CTRLR_STATUS 0x08
|
||||||
|
#define EP_W4_NET_DIAG 0x06
|
||||||
|
#define EP_W4_FIFO_DIAG 0x04
|
||||||
|
#define EP_W4_HOST_DIAG 0x02
|
||||||
|
#define EP_W4_TX_DIAG 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window 5 Registers. Results and Internal status.
|
||||||
|
*/
|
||||||
|
/* Read */
|
||||||
|
#define EP_W5_READ_0_MASK 0x0c
|
||||||
|
#define EP_W5_INTR_MASK 0x0a
|
||||||
|
#define EP_W5_RX_FILTER 0x08
|
||||||
|
#define EP_W5_RX_EARLY_THRESH 0x06
|
||||||
|
#define EP_W5_TX_AVAIL_THRESH 0x02
|
||||||
|
#define EP_W5_TX_START_THRESH 0x00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window 6 registers. Statistics.
|
||||||
|
*/
|
||||||
|
/* Read/Write */
|
||||||
|
#define TX_TOTAL_OK 0x0c
|
||||||
|
#define RX_TOTAL_OK 0x0a
|
||||||
|
#define TX_DEFERRALS 0x08
|
||||||
|
#define RX_FRAMES_OK 0x07
|
||||||
|
#define TX_FRAMES_OK 0x06
|
||||||
|
#define RX_OVERRUNS 0x05
|
||||||
|
#define TX_COLLISIONS 0x04
|
||||||
|
#define TX_AFTER_1_COLLISION 0x03
|
||||||
|
#define TX_AFTER_X_COLLISIONS 0x02
|
||||||
|
#define TX_NO_SQE 0x01
|
||||||
|
#define TX_CD_LOST 0x00
|
||||||
|
|
||||||
|
/****************************************
|
||||||
|
*
|
||||||
|
* Register definitions.
|
||||||
|
*
|
||||||
|
****************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command register. All windows.
|
||||||
|
*
|
||||||
|
* 16 bit register.
|
||||||
|
* 15-11: 5-bit code for command to be executed.
|
||||||
|
* 10-0: 11-bit arg if any. For commands with no args;
|
||||||
|
* this can be set to anything.
|
||||||
|
*/
|
||||||
|
#define GLOBAL_RESET (u_short) 0x0000 /* Wait at least 1ms
|
||||||
|
* after issuing */
|
||||||
|
#define WINDOW_SELECT (u_short) (0x1<<11)
|
||||||
|
#define START_TRANSCEIVER (u_short) (0x2<<11) /* Read ADDR_CFG reg to
|
||||||
|
* determine whether
|
||||||
|
* this is needed. If
|
||||||
|
* so; wait 800 uSec
|
||||||
|
* before using trans-
|
||||||
|
* ceiver. */
|
||||||
|
#define RX_DISABLE (u_short) (0x3<<11) /* state disabled on
|
||||||
|
* power-up */
|
||||||
|
#define RX_ENABLE (u_short) (0x4<<11)
|
||||||
|
#define RX_RESET (u_short) (0x5<<11)
|
||||||
|
#define RX_DISCARD_TOP_PACK (u_short) (0x8<<11)
|
||||||
|
#define TX_ENABLE (u_short) (0x9<<11)
|
||||||
|
#define TX_DISABLE (u_short) (0xa<<11)
|
||||||
|
#define TX_RESET (u_short) (0xb<<11)
|
||||||
|
#define REQ_INTR (u_short) (0xc<<11)
|
||||||
|
#define SET_INTR_MASK (u_short) (0xe<<11)
|
||||||
|
#define SET_RD_0_MASK (u_short) (0xf<<11)
|
||||||
|
#define SET_RX_FILTER (u_short) (0x10<<11)
|
||||||
|
#define FIL_INDIVIDUAL (u_short) (0x1)
|
||||||
|
#define FIL_GROUP (u_short) (0x2)
|
||||||
|
#define FIL_BRDCST (u_short) (0x4)
|
||||||
|
#define FIL_ALL (u_short) (0x8)
|
||||||
|
#define SET_RX_EARLY_THRESH (u_short) (0x11<<11)
|
||||||
|
#define SET_TX_AVAIL_THRESH (u_short) (0x12<<11)
|
||||||
|
#define SET_TX_START_THRESH (u_short) (0x13<<11)
|
||||||
|
#define STATS_ENABLE (u_short) (0x15<<11)
|
||||||
|
#define STATS_DISABLE (u_short) (0x16<<11)
|
||||||
|
#define STOP_TRANSCEIVER (u_short) (0x17<<11)
|
||||||
|
/*
|
||||||
|
* The following C_* acknowledge the various interrupts. Some of them don't
|
||||||
|
* do anything. See the manual.
|
||||||
|
*/
|
||||||
|
#define ACK_INTR (u_short) (0x6800)
|
||||||
|
#define C_INTR_LATCH (u_short) (ACK_INTR|0x1)
|
||||||
|
#define C_CARD_FAILURE (u_short) (ACK_INTR|0x2)
|
||||||
|
#define C_TX_COMPLETE (u_short) (ACK_INTR|0x4)
|
||||||
|
#define C_TX_AVAIL (u_short) (ACK_INTR|0x8)
|
||||||
|
#define C_RX_COMPLETE (u_short) (ACK_INTR|0x10)
|
||||||
|
#define C_RX_EARLY (u_short) (ACK_INTR|0x20)
|
||||||
|
#define C_INT_RQD (u_short) (ACK_INTR|0x40)
|
||||||
|
#define C_UPD_STATS (u_short) (ACK_INTR|0x80)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status register. All windows.
|
||||||
|
*
|
||||||
|
* 15-13: Window number(0-7).
|
||||||
|
* 12: Command_in_progress.
|
||||||
|
* 11: reserved.
|
||||||
|
* 10: reserved.
|
||||||
|
* 9: reserved.
|
||||||
|
* 8: reserved.
|
||||||
|
* 7: Update Statistics.
|
||||||
|
* 6: Interrupt Requested.
|
||||||
|
* 5: RX Early.
|
||||||
|
* 4: RX Complete.
|
||||||
|
* 3: TX Available.
|
||||||
|
* 2: TX Complete.
|
||||||
|
* 1: Adapter Failure.
|
||||||
|
* 0: Interrupt Latch.
|
||||||
|
*/
|
||||||
|
#define S_INTR_LATCH (u_short) (0x1)
|
||||||
|
#define S_CARD_FAILURE (u_short) (0x2)
|
||||||
|
#define S_TX_COMPLETE (u_short) (0x4)
|
||||||
|
#define S_TX_AVAIL (u_short) (0x8)
|
||||||
|
#define S_RX_COMPLETE (u_short) (0x10)
|
||||||
|
#define S_RX_EARLY (u_short) (0x20)
|
||||||
|
#define S_INT_RQD (u_short) (0x40)
|
||||||
|
#define S_UPD_STATS (u_short) (0x80)
|
||||||
|
#define S_5_INTS (S_CARD_FAILURE|S_TX_COMPLETE|\
|
||||||
|
S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY)
|
||||||
|
#define S_COMMAND_IN_PROGRESS (u_short) (0x1000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIFO Registers.
|
||||||
|
* RX Status. Window 1/Port 08
|
||||||
|
*
|
||||||
|
* 15: Incomplete or FIFO empty.
|
||||||
|
* 14: 1: Error in RX Packet 0: Incomplete or no error.
|
||||||
|
* 13-11: Type of error.
|
||||||
|
* 1000 = Overrun.
|
||||||
|
* 1011 = Run Packet Error.
|
||||||
|
* 1100 = Alignment Error.
|
||||||
|
* 1101 = CRC Error.
|
||||||
|
* 1001 = Oversize Packet Error (>1514 bytes)
|
||||||
|
* 0010 = Dribble Bits.
|
||||||
|
* (all other error codes, no errors.)
|
||||||
|
*
|
||||||
|
* 10-0: RX Bytes (0-1514)
|
||||||
|
*/
|
||||||
|
#define ERR_RX_INCOMPLETE (u_short) (0x1<<15)
|
||||||
|
#define ERR_RX (u_short) (0x1<<14)
|
||||||
|
#define ERR_RX_OVERRUN (u_short) (0x8<<11)
|
||||||
|
#define ERR_RX_RUN_PKT (u_short) (0xb<<11)
|
||||||
|
#define ERR_RX_ALIGN (u_short) (0xc<<11)
|
||||||
|
#define ERR_RX_CRC (u_short) (0xd<<11)
|
||||||
|
#define ERR_RX_OVERSIZE (u_short) (0x9<<11)
|
||||||
|
#define ERR_RX_DRIBBLE (u_short) (0x2<<11)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIFO Registers.
|
||||||
|
* TX Status. Window 1/Port 0B
|
||||||
|
*
|
||||||
|
* Reports the transmit status of a completed transmission. Writing this
|
||||||
|
* register pops the transmit completion stack.
|
||||||
|
*
|
||||||
|
* Window 1/Port 0x0b.
|
||||||
|
*
|
||||||
|
* 7: Complete
|
||||||
|
* 6: Interrupt on successful transmission requested.
|
||||||
|
* 5: Jabber Error (TP Only, TX Reset required. )
|
||||||
|
* 4: Underrun (TX Reset required. )
|
||||||
|
* 3: Maximum Collisions.
|
||||||
|
* 2: TX Status Overflow.
|
||||||
|
* 1-0: Undefined.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define TXS_COMPLETE 0x80
|
||||||
|
#define TXS_SUCCES_INTR_REQ 0x40
|
||||||
|
#define TXS_JABBER 0x20
|
||||||
|
#define TXS_UNDERRUN 0x10
|
||||||
|
#define TXS_MAX_COLLISION 0x8
|
||||||
|
#define TXS_STATUS_OVERFLOW 0x4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configuration control register.
|
||||||
|
* Window 0/Port 04
|
||||||
|
*/
|
||||||
|
/* Read */
|
||||||
|
#define IS_AUI (1<<13)
|
||||||
|
#define IS_BNC (1<<12)
|
||||||
|
#define IS_UTP (1<<9)
|
||||||
|
/* Write */
|
||||||
|
#define ENABLE_DRQ_IRQ 0x0001
|
||||||
|
#define W0_P4_CMD_RESET_ADAPTER 0x4
|
||||||
|
#define W0_P4_CMD_ENABLE_ADAPTER 0x1
|
||||||
|
/*
|
||||||
|
* Media type and status.
|
||||||
|
* Window 4/Port 0A
|
||||||
|
*/
|
||||||
|
#define ENABLE_UTP 0xc0
|
||||||
|
#define DISABLE_UTP 0x0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resource control register
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SET_IRQ(i) ( ((i)<<12) | 0xF00) /* set IRQ i */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Receive status register
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RX_BYTES_MASK (u_short) (0x07ff)
|
||||||
|
#define RX_ERROR 0x4000
|
||||||
|
#define RX_INCOMPLETE 0x8000
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Misc defines for various things.
|
||||||
|
*/
|
||||||
|
#define ACTIVATE_ADAPTER_TO_CONFIG 0xff /* to the id_port */
|
||||||
|
#define MFG_ID 0x6d50 /* in EEPROM and W0 ADDR_CONFIG */
|
||||||
|
#define PROD_ID 0x9150
|
||||||
|
|
||||||
|
#define AUI 0x1
|
||||||
|
#define BNC 0x2
|
||||||
|
#define UTP 0x4
|
||||||
|
|
||||||
|
#define RX_BYTES_MASK (u_short) (0x07ff)
|
||||||
|
|
||||||
|
/* EISA support */
|
||||||
|
#define EP_EISA_START 0x1000
|
||||||
|
#define EP_EISA_W0 0x0c80
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
|
|
1172
netboot/3c59x.c
Normal file
1172
netboot/3c59x.c
Normal file
File diff suppressed because it is too large
Load diff
20
netboot/Makefile.am
Normal file
20
netboot/Makefile.am
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
# For <stage1.h>.
|
||||||
|
INCLUDES = -I$(top_srcdir)/stage1
|
||||||
|
|
||||||
|
if NETBOOT_SUPPORT
|
||||||
|
LIBDRIVERS = libdrivers.a
|
||||||
|
else
|
||||||
|
LIBDRIVERS =
|
||||||
|
endif
|
||||||
|
|
||||||
|
noinst_LIBRARIES = $(LIBDRIVERS)
|
||||||
|
|
||||||
|
DRIVERS = 3c509.c 3c509.h 3c59x.c cs89x0.c cs89x0.h eepro100.c \
|
||||||
|
lance.c ns8390.c ns8390.h
|
||||||
|
|
||||||
|
libdrivers_a_SOURCES = byteorder.h config.c config.h fsys_tftp.c \
|
||||||
|
if.h io.h ip.c ip.h netboot.h netdevice.h nic.h pci.c pci.h \
|
||||||
|
$(DRIVERS)
|
||||||
|
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||||
|
-DFSYS_TFTP $(NET_CFLAGS) $(NET_EXTRAFLAGS)
|
536
netboot/Makefile.in
Normal file
536
netboot/Makefile.in
Normal file
|
@ -0,0 +1,536 @@
|
||||||
|
# Makefile.in generated automatically by automake 1.4a from Makefile.am
|
||||||
|
|
||||||
|
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
|
||||||
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
SHELL = @SHELL@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
|
||||||
|
bindir = @bindir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
datadir = @datadir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
libdir = @libdir@
|
||||||
|
infodir = @infodir@
|
||||||
|
mandir = @mandir@
|
||||||
|
includedir = @includedir@
|
||||||
|
oldincludedir = /usr/include
|
||||||
|
|
||||||
|
DESTDIR =
|
||||||
|
|
||||||
|
pkgdatadir = $(datadir)/@PACKAGE@
|
||||||
|
pkglibdir = $(libdir)/@PACKAGE@
|
||||||
|
pkgincludedir = $(includedir)/@PACKAGE@
|
||||||
|
|
||||||
|
top_builddir = ..
|
||||||
|
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
INSTALL_STRIP_FLAG =
|
||||||
|
transform = @program_transform_name@
|
||||||
|
|
||||||
|
NORMAL_INSTALL = :
|
||||||
|
PRE_INSTALL = :
|
||||||
|
POST_INSTALL = :
|
||||||
|
NORMAL_UNINSTALL = :
|
||||||
|
PRE_UNINSTALL = :
|
||||||
|
POST_UNINSTALL = :
|
||||||
|
host_alias = @host_alias@
|
||||||
|
host_triplet = @host@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AMTARFLAGS = @AMTARFLAGS@
|
||||||
|
AWK = @AWK@
|
||||||
|
CC = @CC@
|
||||||
|
FSYS_CFLAGS = @FSYS_CFLAGS@
|
||||||
|
GRUB_CFLAGS = @GRUB_CFLAGS@
|
||||||
|
GRUB_LIBS = @GRUB_LIBS@
|
||||||
|
LD = @LD@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NET_CFLAGS = @NET_CFLAGS@
|
||||||
|
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||||
|
OBJCOPY = @OBJCOPY@
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
PERL = @PERL@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
STAGE1_CFLAGS = @STAGE1_CFLAGS@
|
||||||
|
STAGE2_CFLAGS = @STAGE2_CFLAGS@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
host_cpu = @host_cpu@
|
||||||
|
host_vendor = @host_vendor@
|
||||||
|
install_sh = @install_sh@
|
||||||
|
|
||||||
|
# For <stage1.h>.
|
||||||
|
|
||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/stage1
|
||||||
|
@NETBOOT_SUPPORT_TRUE@LIBDRIVERS = @NETBOOT_SUPPORT_TRUE@libdrivers.a
|
||||||
|
@NETBOOT_SUPPORT_FALSE@LIBDRIVERS =
|
||||||
|
|
||||||
|
noinst_LIBRARIES = $(LIBDRIVERS)
|
||||||
|
|
||||||
|
DRIVERS = 3c509.c 3c509.h 3c59x.c cs89x0.c cs89x0.h eepro100.c \
|
||||||
|
lance.c ns8390.c ns8390.h
|
||||||
|
|
||||||
|
|
||||||
|
libdrivers_a_SOURCES = byteorder.h config.c config.h fsys_tftp.c \
|
||||||
|
if.h io.h ip.c ip.h netboot.h netdevice.h nic.h pci.c pci.h \
|
||||||
|
$(DRIVERS)
|
||||||
|
|
||||||
|
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||||
|
-DFSYS_TFTP $(NET_CFLAGS) $(NET_EXTRAFLAGS)
|
||||||
|
|
||||||
|
subdir = netboot
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
|
CONFIG_HEADER = ../config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
LIBRARIES = $(noinst_LIBRARIES)
|
||||||
|
|
||||||
|
|
||||||
|
DEFS = @DEFS@ -I. -I$(srcdir) -I..
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
libdrivers_a_AR = $(AR) cru
|
||||||
|
libdrivers_a_LIBADD =
|
||||||
|
am_libdrivers_a_OBJECTS = libdrivers_a-config.o \
|
||||||
|
libdrivers_a-fsys_tftp.o libdrivers_a-ip.o libdrivers_a-pci.o \
|
||||||
|
libdrivers_a-3c509.o libdrivers_a-3c59x.o libdrivers_a-cs89x0.o \
|
||||||
|
libdrivers_a-eepro100.o libdrivers_a-lance.o libdrivers_a-ns8390.o
|
||||||
|
libdrivers_a_OBJECTS = $(am_libdrivers_a_OBJECTS)
|
||||||
|
AR = ar
|
||||||
|
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CCLD = $(CC)
|
||||||
|
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||||
|
DIST_SOURCES = $(libdrivers_a_SOURCES)
|
||||||
|
DIST_COMMON = Makefile.am Makefile.in compile
|
||||||
|
|
||||||
|
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
|
GZIP_ENV = --best
|
||||||
|
DEP_FILES = .deps/3c509.P .deps/3c59x.P .deps/config.P .deps/cs89x0.P \
|
||||||
|
.deps/eepro100.P .deps/fsys_tftp.P .deps/ip.P .deps/lance.P \
|
||||||
|
.deps/ns8390.P .deps/pci.P
|
||||||
|
SOURCES = $(libdrivers_a_SOURCES)
|
||||||
|
OBJECTS = $(am_libdrivers_a_OBJECTS)
|
||||||
|
|
||||||
|
all: all-redirect
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .h .o
|
||||||
|
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
|
cd $(top_srcdir) && $(AUTOMAKE) --gnu netboot/Makefile
|
||||||
|
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
|
||||||
|
cd $(top_builddir) \
|
||||||
|
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||||
|
|
||||||
|
|
||||||
|
mostlyclean-noinstLIBRARIES:
|
||||||
|
|
||||||
|
clean-noinstLIBRARIES:
|
||||||
|
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||||
|
|
||||||
|
distclean-noinstLIBRARIES:
|
||||||
|
|
||||||
|
maintainer-clean-noinstLIBRARIES:
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.o core *.core
|
||||||
|
|
||||||
|
clean-compile:
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
maintainer-clean-compile:
|
||||||
|
libdrivers_a-config.o: config.c
|
||||||
|
libdrivers_a-fsys_tftp.o: fsys_tftp.c
|
||||||
|
libdrivers_a-ip.o: ip.c
|
||||||
|
libdrivers_a-pci.o: pci.c
|
||||||
|
libdrivers_a-3c509.o: 3c509.c
|
||||||
|
libdrivers_a-3c59x.o: 3c59x.c
|
||||||
|
libdrivers_a-cs89x0.o: cs89x0.c
|
||||||
|
libdrivers_a-eepro100.o: eepro100.c
|
||||||
|
libdrivers_a-lance.o: lance.c
|
||||||
|
libdrivers_a-ns8390.o: ns8390.c
|
||||||
|
|
||||||
|
libdrivers.a: $(libdrivers_a_OBJECTS) $(libdrivers_a_DEPENDENCIES)
|
||||||
|
-rm -f libdrivers.a
|
||||||
|
$(libdrivers_a_AR) libdrivers.a $(libdrivers_a_OBJECTS) $(libdrivers_a_LIBADD)
|
||||||
|
$(RANLIB) libdrivers.a
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -f$$here/ID $$unique $(LISP)
|
||||||
|
|
||||||
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||||
|
|| etags $(ETAGS_ARGS) $$tags $$unique $(LISP)
|
||||||
|
|
||||||
|
mostlyclean-tags:
|
||||||
|
|
||||||
|
clean-tags:
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID
|
||||||
|
|
||||||
|
maintainer-clean-tags:
|
||||||
|
|
||||||
|
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
here=`cd $(top_builddir) && pwd`; \
|
||||||
|
top_distdir=`cd $(top_distdir) && pwd`; \
|
||||||
|
distdir=`cd $(distdir) && pwd`; \
|
||||||
|
cd $(top_srcdir) \
|
||||||
|
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu netboot/Makefile
|
||||||
|
@for file in $(DISTFILES); do \
|
||||||
|
d=$(srcdir); \
|
||||||
|
if test -d $$d/$$file; then \
|
||||||
|
cp -pr $$d/$$file $(distdir)/$$file; \
|
||||||
|
else \
|
||||||
|
test -f $(distdir)/$$file \
|
||||||
|
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||||
|
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
|
||||||
|
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
|
||||||
|
|
||||||
|
-include $(DEP_FILES)
|
||||||
|
|
||||||
|
mostlyclean-depend:
|
||||||
|
|
||||||
|
clean-depend:
|
||||||
|
|
||||||
|
distclean-depend:
|
||||||
|
-rm -rf .deps
|
||||||
|
|
||||||
|
maintainer-clean-depend:
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
@echo '$(COMPILE) -c -o $@ $<'; \
|
||||||
|
$(COMPILE) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
%.lo: %.c
|
||||||
|
@echo '$(LTCOMPILE) -c -o $@ $<'; \
|
||||||
|
$(LTCOMPILE) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-config.o: config.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-config.lo: config.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-fsys_tftp.o: fsys_tftp.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-fsys_tftp.lo: fsys_tftp.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-ip.o: ip.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-ip.lo: ip.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-pci.o: pci.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-pci.lo: pci.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-3c509.o: 3c509.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-3c509.lo: 3c509.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-3c59x.o: 3c59x.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-3c59x.lo: 3c59x.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-cs89x0.o: cs89x0.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-cs89x0.lo: cs89x0.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-eepro100.o: eepro100.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-eepro100.lo: eepro100.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-lance.o: lance.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-lance.lo: lance.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-ns8390.o: ns8390.c
|
||||||
|
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm .deps/$(*D)/$(*F).pp
|
||||||
|
|
||||||
|
libdrivers_a-ns8390.lo: ns8390.c
|
||||||
|
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||||
|
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||||
|
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||||
|
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||||
|
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||||
|
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||||
|
>> .deps/$(*D)/$(*F).P; \
|
||||||
|
rm -f .deps/$(*D)/$(*F).pp
|
||||||
|
info-am:
|
||||||
|
info: info-am
|
||||||
|
dvi-am:
|
||||||
|
dvi: dvi-am
|
||||||
|
check-am: all-am
|
||||||
|
check: check-am
|
||||||
|
installcheck-am:
|
||||||
|
installcheck: installcheck-am
|
||||||
|
install-exec-am:
|
||||||
|
install-exec: install-exec-am
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
install-data: install-data-am
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
install: install-am
|
||||||
|
uninstall-am:
|
||||||
|
uninstall: uninstall-am
|
||||||
|
all-am: Makefile $(LIBRARIES)
|
||||||
|
all-redirect: all-am
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
|
||||||
|
installdirs:
|
||||||
|
|
||||||
|
|
||||||
|
mostlyclean-generic:
|
||||||
|
|
||||||
|
clean-generic:
|
||||||
|
|
||||||
|
distclean-generic:
|
||||||
|
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||||
|
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
|
||||||
|
mostlyclean-tags mostlyclean-depend mostlyclean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-am
|
||||||
|
|
||||||
|
clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
|
||||||
|
clean-generic mostlyclean-am
|
||||||
|
|
||||||
|
clean: clean-am
|
||||||
|
|
||||||
|
distclean-am: distclean-noinstLIBRARIES distclean-compile \
|
||||||
|
distclean-tags distclean-depend distclean-generic \
|
||||||
|
clean-am
|
||||||
|
|
||||||
|
distclean: distclean-am
|
||||||
|
|
||||||
|
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
|
||||||
|
maintainer-clean-compile maintainer-clean-tags \
|
||||||
|
maintainer-clean-depend maintainer-clean-generic \
|
||||||
|
distclean-am
|
||||||
|
@echo "This command is intended for maintainers to use;"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-am
|
||||||
|
|
||||||
|
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
|
||||||
|
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
|
||||||
|
mostlyclean-compile distclean-compile clean-compile \
|
||||||
|
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
|
||||||
|
clean-tags maintainer-clean-tags distdir mostlyclean-depend \
|
||||||
|
distclean-depend clean-depend maintainer-clean-depend info-am info \
|
||||||
|
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
|
||||||
|
install-exec install-data-am install-data install-am install \
|
||||||
|
uninstall-am uninstall all-redirect all-am all install-strip \
|
||||||
|
installdirs mostlyclean-generic distclean-generic clean-generic \
|
||||||
|
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||||
|
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
77
netboot/byteorder.h
Normal file
77
netboot/byteorder.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#ifndef _I386_BYTEORDER_H
|
||||||
|
#define _I386_BYTEORDER_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains parts of Linux's /usr/include/asm/byteorder.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef ntohl
|
||||||
|
#undef ntohs
|
||||||
|
#undef htonl
|
||||||
|
#undef htons
|
||||||
|
|
||||||
|
extern unsigned long int ntohl(unsigned long int);
|
||||||
|
extern unsigned short int ntohs(unsigned short int);
|
||||||
|
extern unsigned long int htonl(unsigned long int);
|
||||||
|
extern unsigned short int htons(unsigned short int);
|
||||||
|
|
||||||
|
extern __inline__ unsigned long int __ntohl(unsigned long int);
|
||||||
|
extern __inline__ unsigned short int __ntohs(unsigned short int);
|
||||||
|
extern __inline__ unsigned long int __constant_ntohl(unsigned long int);
|
||||||
|
extern __inline__ unsigned short int __constant_ntohs(unsigned short int);
|
||||||
|
|
||||||
|
extern __inline__ unsigned long int
|
||||||
|
__ntohl(unsigned long int x)
|
||||||
|
{
|
||||||
|
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
|
||||||
|
"rorl $16,%0\n\t" /* swap words */
|
||||||
|
"xchgb %b0,%h0" /* swap higher bytes */
|
||||||
|
:"=q" (x)
|
||||||
|
: "0" (x));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __constant_ntohl(x) \
|
||||||
|
((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
|
||||||
|
(((unsigned long int)(x) & 0x0000ff00U) << 8) | \
|
||||||
|
(((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
|
||||||
|
(((unsigned long int)(x) & 0xff000000U) >> 24)))
|
||||||
|
|
||||||
|
extern __inline__ unsigned short int
|
||||||
|
__ntohs(unsigned short int x)
|
||||||
|
{
|
||||||
|
__asm__("xchgb %b0,%h0" /* swap bytes */
|
||||||
|
: "=q" (x)
|
||||||
|
: "0" (x));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __constant_ntohs(x) \
|
||||||
|
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
|
||||||
|
(((unsigned short int)(x) & 0xff00) >> 8))) \
|
||||||
|
|
||||||
|
#define __htonl(x) __ntohl(x)
|
||||||
|
#define __htons(x) __ntohs(x)
|
||||||
|
#define __constant_htonl(x) __constant_ntohl(x)
|
||||||
|
#define __constant_htons(x) __constant_ntohs(x)
|
||||||
|
|
||||||
|
#ifdef __OPTIMIZE__
|
||||||
|
# define ntohl(x) \
|
||||||
|
(__builtin_constant_p((long)(x)) ? \
|
||||||
|
__constant_ntohl((x)) : \
|
||||||
|
__ntohl((x)))
|
||||||
|
# define ntohs(x) \
|
||||||
|
(__builtin_constant_p((short)(x)) ? \
|
||||||
|
__constant_ntohs((x)) : \
|
||||||
|
__ntohs((x)))
|
||||||
|
# define htonl(x) \
|
||||||
|
(__builtin_constant_p((long)(x)) ? \
|
||||||
|
__constant_htonl((x)) : \
|
||||||
|
__htonl((x)))
|
||||||
|
# define htons(x) \
|
||||||
|
(__builtin_constant_p((short)(x)) ? \
|
||||||
|
__constant_htons((x)) : \
|
||||||
|
__htons((x)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
82
netboot/compile
Normal file
82
netboot/compile
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# Wrapper for compilers which do not understand `-c -o'.
|
||||||
|
|
||||||
|
# Copyright (C) 1999 Free Software Foundation, Inc.
|
||||||
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# compile PROGRAM [ARGS]...
|
||||||
|
# `-o FOO.o' is removed from the args passed to the actual compile.
|
||||||
|
|
||||||
|
prog="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
ofile=
|
||||||
|
cfile=
|
||||||
|
args=
|
||||||
|
while test $# -gt 0; do
|
||||||
|
case "$1" in
|
||||||
|
-o)
|
||||||
|
ofile="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*.c)
|
||||||
|
cfile="$1"
|
||||||
|
args="$args $1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
args="$args $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
test -z "$ofile" && {
|
||||||
|
echo "compile: no \`-o' option seen" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
test -z "$cfile" && {
|
||||||
|
echo "compile: no \`.c' file seen" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Name of file we expect compiler to create.
|
||||||
|
cofile="`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`"
|
||||||
|
|
||||||
|
# Create the lock directory.
|
||||||
|
lockdir="`echo $ofile | sed -e 's|/|_|g'`"
|
||||||
|
while true; do
|
||||||
|
if mkdir $lockdir > /dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
# FIXME: race condition here if user kills between mkdir and trap.
|
||||||
|
trap "rmdir $lockdir; exit 1" 1 2 15
|
||||||
|
|
||||||
|
# Run the compile.
|
||||||
|
"$prog" $args
|
||||||
|
status=$?
|
||||||
|
|
||||||
|
if test -f "$cofile"; then
|
||||||
|
mv "$cofile" "$ofile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rmdir $lockdir
|
||||||
|
exit $status
|
225
netboot/config.c
Normal file
225
netboot/config.c
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "nic.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#undef INCLUDE_PCI
|
||||||
|
#if defined(INCLUDE_NEPCI) || defined(INCLUDE_EEPRO100) || defined (INCLUDE_3c59x)
|
||||||
|
/* || others later */
|
||||||
|
#if defined(NETBOOT32) /* only for 32 bit machines */
|
||||||
|
#define INCLUDE_PCI
|
||||||
|
/* #include <linux/pci.h> */
|
||||||
|
#include "pci.h"
|
||||||
|
static unsigned short pci_addrs[16];
|
||||||
|
|
||||||
|
struct pci_device pci_nic_list[] = {
|
||||||
|
#ifdef INCLUDE_NEPCI
|
||||||
|
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029,
|
||||||
|
"Realtek 8029"},
|
||||||
|
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940,
|
||||||
|
"Winbond NE2000-PCI"}, /* "Winbond 89C940" */
|
||||||
|
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000,
|
||||||
|
"Compex ReadyLink 2000"},
|
||||||
|
{ PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2,
|
||||||
|
"KTI ET32P2"},
|
||||||
|
{PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC,
|
||||||
|
"NetVin NV5000"},
|
||||||
|
{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C926,
|
||||||
|
"VIA 82C926 Amazon"},
|
||||||
|
{PCI_VENDOR_ID_SURECOM, PCI_DEVICE_ID_SURECOM_NE34,
|
||||||
|
"SureCom NE34"},
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_EEPRO100
|
||||||
|
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,
|
||||||
|
"Intel EtherExpressPro100"},
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_3c59x
|
||||||
|
{PCI_VENDOR_ID_VORTEX, PCI_DEVICE_ID_VORTEX_3c595, "3c595"},
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* other PCI NICs go here */
|
||||||
|
{0,}
|
||||||
|
};
|
||||||
|
#endif /* NETBOOT32 */
|
||||||
|
#endif /* INCLUDE_*PCI */
|
||||||
|
|
||||||
|
struct dispatch_table
|
||||||
|
{
|
||||||
|
char *nic_name;
|
||||||
|
struct nic *(*eth_probe)(struct nic *, unsigned short *);
|
||||||
|
unsigned short *probe_addrs; /* for probe overrides */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef INCLUDE_WD
|
||||||
|
extern struct nic *wd_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INCLUDE_T503
|
||||||
|
extern struct nic *t503_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(INCLUDE_NE)
|
||||||
|
extern struct nic *ne_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(INCLUDE_NEPCI)
|
||||||
|
extern struct nic *nepci_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INCLUDE_T509
|
||||||
|
extern struct nic *t509_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INCLUDE_EEPRO100
|
||||||
|
extern struct nic *eepro100_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INCLUDE_CS
|
||||||
|
extern struct nic *cs89x0_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INCLUDE_NE2100
|
||||||
|
extern struct nic *ne2100_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INCLUDE_3c59x
|
||||||
|
extern struct nic *VX_probe(struct nic *, unsigned short *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NIC probing is in order of appearance in this table.
|
||||||
|
* If for some reason you want to change the order,
|
||||||
|
* just rearrange the entries (bracketed by the #ifdef/#endif)
|
||||||
|
*/
|
||||||
|
static struct dispatch_table NIC[] =
|
||||||
|
{
|
||||||
|
#ifdef INCLUDE_WD
|
||||||
|
{ "WD", wd_probe, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_T503
|
||||||
|
{ "3C503", t503_probe, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_NE
|
||||||
|
{ "NE*000", ne_probe, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_T509
|
||||||
|
{ "3C5x9", t509_probe, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_EEPRO100
|
||||||
|
{ "EEPRO100", eepro100_probe, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_CS
|
||||||
|
{ "CS89x0", cs89x0_probe, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_NE2100
|
||||||
|
{ "NE2100", ne2100_probe, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_NEPCI
|
||||||
|
{ "NE*000/PCI", nepci_probe, pci_addrs },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INCLUDE_3c59x
|
||||||
|
{"VorTex/PCI", VX_probe, pci_addrs},
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this entry must always be last to mark the end of list */
|
||||||
|
{ 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NIC_TABLE_SIZE (sizeof(NIC)/sizeof(NIC[0]))
|
||||||
|
|
||||||
|
static int eth_dummy(struct nic *nic)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char packet[ETH_MAX_PACKET];
|
||||||
|
|
||||||
|
struct nic nic =
|
||||||
|
{
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
(void (*)(struct nic *))eth_dummy, /* reset */
|
||||||
|
eth_dummy, /* poll */
|
||||||
|
(void (*)(struct nic *, char *,
|
||||||
|
unsigned int, unsigned int,
|
||||||
|
char *))eth_dummy, /* transmit */
|
||||||
|
(void (*)(struct nic *))eth_dummy, /* disable */
|
||||||
|
#endif
|
||||||
|
/* bcc has problems with complicated casts */
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
eth_dummy,
|
||||||
|
eth_dummy,
|
||||||
|
eth_dummy,
|
||||||
|
eth_dummy,
|
||||||
|
#endif
|
||||||
|
1, /* aui */
|
||||||
|
arptable[ARP_CLIENT].node, /* node_addr */
|
||||||
|
packet, /* packet */
|
||||||
|
0, /* packetlen */
|
||||||
|
0 /* priv_data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void print_config(void)
|
||||||
|
{
|
||||||
|
struct dispatch_table *t;
|
||||||
|
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
printf("Etherboot/32 version " VERSION
|
||||||
|
#ifdef NFS_BOOT
|
||||||
|
" ESC for menu"
|
||||||
|
#endif
|
||||||
|
" for ");
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
/* you need to edit the version manually because bcc doesn't
|
||||||
|
do string literal concatenation yet */
|
||||||
|
printf("Etherboot/16 version 3.2 for ");
|
||||||
|
#endif
|
||||||
|
for (t = NIC; t->nic_name != 0; ++t)
|
||||||
|
printf("[%s]", t->nic_name);
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void eth_reset(void)
|
||||||
|
{
|
||||||
|
(*nic.reset)(&nic);
|
||||||
|
}
|
||||||
|
|
||||||
|
int eth_probe(void)
|
||||||
|
{
|
||||||
|
struct dispatch_table *t;
|
||||||
|
|
||||||
|
#ifdef INCLUDE_PCI
|
||||||
|
pci_addrs[0] = 0;
|
||||||
|
eth_pci_init(pci_nic_list, pci_addrs);
|
||||||
|
pci_addrs[1] = 0;
|
||||||
|
#endif
|
||||||
|
printf("Probing...");
|
||||||
|
for (t = NIC; t->nic_name != 0; ++t)
|
||||||
|
{
|
||||||
|
printf("[%s]", t->nic_name);
|
||||||
|
if ((*t->eth_probe)(&nic, t->probe_addrs))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int eth_poll(void)
|
||||||
|
{
|
||||||
|
return ((*nic.poll)(&nic));
|
||||||
|
}
|
||||||
|
|
||||||
|
void eth_transmit(char *d, unsigned int t, unsigned int s, char *p)
|
||||||
|
{
|
||||||
|
(*nic.transmit)(&nic, d, t, s, p);
|
||||||
|
twiddle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void eth_disable(void)
|
||||||
|
{
|
||||||
|
(*nic.disable)(&nic);
|
||||||
|
}
|
8
netboot/config.h
Normal file
8
netboot/config.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
extern struct nic nic;
|
||||||
|
|
||||||
|
extern void print_config(void);
|
||||||
|
extern void eth_reset(void);
|
||||||
|
extern int eth_probe(void);
|
||||||
|
extern int eth_poll(void);
|
||||||
|
extern void eth_transmit(char *d, unsigned int t, unsigned int s, char *p);
|
||||||
|
extern void eth_disable(void);
|
699
netboot/cs89x0.c
Normal file
699
netboot/cs89x0.c
Normal file
|
@ -0,0 +1,699 @@
|
||||||
|
/* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */
|
||||||
|
/*
|
||||||
|
This code is heavily based on the linux driver as written by
|
||||||
|
Russell Nelson <nelson@crynwr.com> and Donald Becker
|
||||||
|
<becker@cesdis.gsfc.nasa.gov> and modified by Mike Cruse
|
||||||
|
<mcruse@cti-ltd.com>. That driver has been released under the
|
||||||
|
conditions of the GNU Public License, thus this one is probably to
|
||||||
|
be considered "derived work". Therefore, there are some legal
|
||||||
|
obstacles in combining this file with etherboot's code, which is
|
||||||
|
released under a BSD style license.
|
||||||
|
|
||||||
|
So, if you want to actually use this code, you should make sure that
|
||||||
|
you are aware of the legal implications. I release *my* work into
|
||||||
|
the PUBLIC DOMAIN which implies that you can use it either under a
|
||||||
|
BSD style license, or under the conditions of the GPL, or under any
|
||||||
|
other conditions that you like. N.B. this does not apply to the
|
||||||
|
parts that originate from other authors. So, you should probably
|
||||||
|
contact them first and verify if they agree with your intended use.
|
||||||
|
|
||||||
|
If you contacted all of the above authors and they agreed to give
|
||||||
|
special permission for using this code under the conditions of a BSD
|
||||||
|
style license, then please do let me know.
|
||||||
|
|
||||||
|
ChangeLog:
|
||||||
|
|
||||||
|
Thu Dec 6 22:40:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||||
|
|
||||||
|
* disabled all "advanced" features; this should make the code more reliable
|
||||||
|
|
||||||
|
* reorganized the reset function
|
||||||
|
|
||||||
|
* always reset the address port, so that autoprobing will continue working
|
||||||
|
|
||||||
|
* some cosmetic changes
|
||||||
|
|
||||||
|
* 2.5
|
||||||
|
|
||||||
|
Thu Dec 5 21:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||||
|
|
||||||
|
* tested the code against a CS8900 card
|
||||||
|
|
||||||
|
* lots of minor bug fixes and adjustments
|
||||||
|
|
||||||
|
* this is the first release, that actually works! it still requires some
|
||||||
|
changes in order to be more tolerant to different environments
|
||||||
|
|
||||||
|
* 4
|
||||||
|
|
||||||
|
Fri Nov 22 23:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||||
|
|
||||||
|
* read the manuals for the CS89x0 chipsets and took note of all the
|
||||||
|
changes that will be neccessary in order to adapt Russel Nelson's code
|
||||||
|
to the requirements of a BOOT-Prom
|
||||||
|
|
||||||
|
* 6
|
||||||
|
|
||||||
|
Thu Nov 19 22:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||||
|
|
||||||
|
* Synched with Russel Nelson's current code (v1.00)
|
||||||
|
|
||||||
|
* 2
|
||||||
|
|
||||||
|
Thu Nov 12 18:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||||
|
|
||||||
|
* Cleaned up some of the code and tried to optimize the code size.
|
||||||
|
|
||||||
|
* 1.5
|
||||||
|
|
||||||
|
Sun Nov 10 16:30:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
|
||||||
|
|
||||||
|
* First experimental release. This code compiles fine, but I
|
||||||
|
have no way of testing whether it actually works.
|
||||||
|
|
||||||
|
* I did not (yet) bother to make the code 16bit aware, so for
|
||||||
|
the time being, it will only work for netboot-32.
|
||||||
|
|
||||||
|
* 12
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef INCLUDE_CS
|
||||||
|
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "nic.h"
|
||||||
|
#include "cs89x0.h"
|
||||||
|
|
||||||
|
static unsigned short eth_nic_base;
|
||||||
|
static unsigned long eth_mem_start;
|
||||||
|
static unsigned short eth_irq;
|
||||||
|
static unsigned short eth_cs_type; /* one of: CS8900, CS8920, CS8920M */
|
||||||
|
static unsigned short eth_auto_neg_cnf;
|
||||||
|
static unsigned short eth_adapter_cnf;
|
||||||
|
static unsigned short eth_linectl;
|
||||||
|
static unsigned char eth_vendor;
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
CS89x0 - specific routines
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
static int inline readreg(portno)
|
||||||
|
int portno;
|
||||||
|
{
|
||||||
|
outw(eth_nic_base + ADD_PORT, portno);
|
||||||
|
return inw(eth_nic_base + DATA_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline writereg(portno,value)
|
||||||
|
int portno;
|
||||||
|
int value;
|
||||||
|
{
|
||||||
|
outw(eth_nic_base + ADD_PORT, portno);
|
||||||
|
outw(eth_nic_base + DATA_PORT, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
EEPROM access
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
static int wait_eeprom_ready()
|
||||||
|
{
|
||||||
|
long tmo = currticks() + 4*18L;
|
||||||
|
|
||||||
|
/* check to see if the EEPROM is ready, a timeout is used -
|
||||||
|
just in case EEPROM is ready when SI_BUSY in the
|
||||||
|
PP_SelfST is clear */
|
||||||
|
while(readreg(PP_SelfST) & SI_BUSY) {
|
||||||
|
if (currticks() - tmo >= 0)
|
||||||
|
return -1; }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_eeprom_data(off,len,buffer)
|
||||||
|
int off;
|
||||||
|
int len;
|
||||||
|
unsigned short *buffer;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#if defined(EDEBUG)
|
||||||
|
printf("\r\ncs: EEPROM data from %x for %x:",off,len);
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (wait_eeprom_ready() < 0)
|
||||||
|
return -1;
|
||||||
|
/* Now send the EEPROM read command and EEPROM location
|
||||||
|
to read */
|
||||||
|
writereg(PP_EECMD, (off + i) | EEPROM_READ_CMD);
|
||||||
|
if (wait_eeprom_ready() < 0)
|
||||||
|
return -1;
|
||||||
|
buffer[i] = readreg(PP_EEData);
|
||||||
|
#if defined(EDEBUG)
|
||||||
|
if (!(i%10))
|
||||||
|
printf("\r\ncs: ");
|
||||||
|
printf("%x ", buffer[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if defined(EDEBUG)
|
||||||
|
printf("\r\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_eeprom_chksum(off, len, buffer)
|
||||||
|
int off;
|
||||||
|
int len;
|
||||||
|
unsigned short *buffer;
|
||||||
|
{
|
||||||
|
int i, cksum;
|
||||||
|
|
||||||
|
cksum = 0;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
cksum += buffer[i];
|
||||||
|
cksum &= 0xffff;
|
||||||
|
if (cksum == 0)
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Activate all of the available media and probe for network
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
static void clrline()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
putchar('\r');
|
||||||
|
for (i = 79; i--; ) putchar(' ');
|
||||||
|
printf("\rcs: ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void control_dc_dc(on_not_off)
|
||||||
|
int on_not_off;
|
||||||
|
{
|
||||||
|
unsigned int selfcontrol;
|
||||||
|
long tmo = currticks() + 18;
|
||||||
|
|
||||||
|
/* control the DC to DC convertor in the SelfControl register. */
|
||||||
|
selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
|
||||||
|
if (((eth_adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
|
||||||
|
selfcontrol |= HCB1;
|
||||||
|
else
|
||||||
|
selfcontrol &= ~HCB1;
|
||||||
|
writereg(PP_SelfCTL, selfcontrol);
|
||||||
|
|
||||||
|
/* Wait for the DC/DC converter to power up - 1000ms */
|
||||||
|
while (currticks() - tmo < 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int detect_tp()
|
||||||
|
{
|
||||||
|
long tmo;
|
||||||
|
|
||||||
|
/* Turn on the chip auto detection of 10BT/ AUI */
|
||||||
|
|
||||||
|
clrline(); printf("attempting %s:","TP");
|
||||||
|
|
||||||
|
/* If connected to another full duplex capable 10-Base-T card
|
||||||
|
the link pulses seem to be lost when the auto detect bit in
|
||||||
|
the LineCTL is set. To overcome this the auto detect bit
|
||||||
|
will be cleared whilst testing the 10-Base-T interface.
|
||||||
|
This would not be necessary for the sparrow chip but is
|
||||||
|
simpler to do it anyway. */
|
||||||
|
writereg(PP_LineCTL, eth_linectl &~ AUI_ONLY);
|
||||||
|
control_dc_dc(0);
|
||||||
|
|
||||||
|
/* Delay for the hardware to work out if the TP cable is
|
||||||
|
present - 150ms */
|
||||||
|
for (tmo = currticks() + 4; currticks() - tmo < 0; );
|
||||||
|
|
||||||
|
if ((readreg(PP_LineST) & LINK_OK) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (eth_cs_type != CS8900) {
|
||||||
|
|
||||||
|
writereg(PP_AutoNegCTL, eth_auto_neg_cnf & AUTO_NEG_MASK);
|
||||||
|
|
||||||
|
if ((eth_auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
|
||||||
|
printf(" negotiating duplex... ");
|
||||||
|
while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
|
||||||
|
if (currticks() - tmo > 40*18) {
|
||||||
|
printf("time out ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (readreg(PP_AutoNegST) & FDX_ACTIVE)
|
||||||
|
printf("using full duplex");
|
||||||
|
else
|
||||||
|
printf("using half duplex");
|
||||||
|
}
|
||||||
|
|
||||||
|
return A_CNF_MEDIA_10B_T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send a test packet - return true if carrier bits are ok */
|
||||||
|
static int send_test_pkt(struct nic *nic)
|
||||||
|
{
|
||||||
|
static char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
|
||||||
|
0, 46, /*A 46 in network order */
|
||||||
|
0, 0, /*DSAP=0 & SSAP=0 fields */
|
||||||
|
0xf3,0 /*Control (Test Req+P bit set)*/ };
|
||||||
|
long tmo;
|
||||||
|
|
||||||
|
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
|
||||||
|
|
||||||
|
bcopy(nic->node_addr,testpacket,ETHER_ADDR_SIZE);
|
||||||
|
bcopy(nic->node_addr,testpacket+ETHER_ADDR_SIZE,
|
||||||
|
ETHER_ADDR_SIZE);
|
||||||
|
|
||||||
|
outw(eth_nic_base + TX_CMD_PORT, TX_AFTER_ALL);
|
||||||
|
outw(eth_nic_base + TX_LEN_PORT, ETH_MIN_PACKET);
|
||||||
|
|
||||||
|
/* Test to see if the chip has allocated memory for the packet */
|
||||||
|
for (tmo = currticks() + 2;
|
||||||
|
(readreg(PP_BusST) & READY_FOR_TX_NOW) == 0; )
|
||||||
|
if (currticks() - tmo >= 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/* Write the contents of the packet */
|
||||||
|
outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
|
||||||
|
(ETH_MIN_PACKET+1)>>1);
|
||||||
|
|
||||||
|
printf(" sending test packet ");
|
||||||
|
/* wait a couple of timer ticks for packet to be received */
|
||||||
|
for (tmo = currticks() + 2; currticks() - tmo < 0; );
|
||||||
|
|
||||||
|
if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
|
||||||
|
printf("succeeded");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int detect_aui(struct nic *nic)
|
||||||
|
{
|
||||||
|
clrline(); printf("attempting %s:","AUI");
|
||||||
|
control_dc_dc(0);
|
||||||
|
|
||||||
|
writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
|
||||||
|
|
||||||
|
if (send_test_pkt(nic)) {
|
||||||
|
return A_CNF_MEDIA_AUI; }
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int detect_bnc(struct nic *nic)
|
||||||
|
{
|
||||||
|
clrline(); printf("attempting %s:","BNC");
|
||||||
|
control_dc_dc(1);
|
||||||
|
|
||||||
|
writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
|
||||||
|
|
||||||
|
if (send_test_pkt(nic)) {
|
||||||
|
return A_CNF_MEDIA_10B_2; }
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_RESET - Reset adapter
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
void cs89x0_reset(struct nic *nic)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long reset_tmo;
|
||||||
|
|
||||||
|
if(eth_vendor!=VENDOR_CS89x0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
|
||||||
|
|
||||||
|
/* wait for two ticks; that is 2*55ms */
|
||||||
|
for (reset_tmo = currticks() + 2;
|
||||||
|
reset_tmo > currticks(); );
|
||||||
|
|
||||||
|
if (eth_cs_type != CS8900) {
|
||||||
|
/* Hardware problem requires PNP registers to be reconfigured
|
||||||
|
after a reset */
|
||||||
|
if (eth_irq != 0xFFFF) {
|
||||||
|
outw(eth_nic_base + ADD_PORT, PP_CS8920_ISAINT);
|
||||||
|
outb(eth_nic_base + DATA_PORT, eth_irq);
|
||||||
|
outb(eth_nic_base + DATA_PORT + 1, 0); }
|
||||||
|
|
||||||
|
if (eth_mem_start) {
|
||||||
|
outw(eth_nic_base + ADD_PORT, PP_CS8920_ISAMemB);
|
||||||
|
outb(eth_nic_base + DATA_PORT, (eth_mem_start >> 8) & 0xff);
|
||||||
|
outb(eth_nic_base + DATA_PORT + 1, (eth_mem_start >> 24) & 0xff); } }
|
||||||
|
|
||||||
|
/* Wait until the chip is reset */
|
||||||
|
for (reset_tmo = currticks() + 2;
|
||||||
|
(readreg(PP_SelfST) & INIT_DONE) == 0 &&
|
||||||
|
currticks() - reset_tmo < 0; );
|
||||||
|
|
||||||
|
/* disable interrupts and memory accesses */
|
||||||
|
writereg(PP_BusCTL, 0);
|
||||||
|
|
||||||
|
/* set the ethernet address */
|
||||||
|
for (i=0; i < ETHER_ADDR_SIZE/2; i++)
|
||||||
|
writereg(PP_IA+i*2,
|
||||||
|
nic->node_addr[i*2] |
|
||||||
|
(nic->node_addr[i*2+1] << 8));
|
||||||
|
|
||||||
|
/* receive only error free packets addressed to this card */
|
||||||
|
writereg(PP_RxCTL, DEF_RX_ACCEPT);
|
||||||
|
|
||||||
|
/* do not generate any interrupts on receive operations */
|
||||||
|
writereg(PP_RxCFG, 0);
|
||||||
|
|
||||||
|
/* do not generate any interrupts on transmit operations */
|
||||||
|
writereg(PP_TxCFG, 0);
|
||||||
|
|
||||||
|
/* do not generate any interrupts on buffer operations */
|
||||||
|
writereg(PP_BufCFG, 0);
|
||||||
|
|
||||||
|
/* reset address port, so that autoprobing will keep working */
|
||||||
|
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_TRANSMIT - Transmit a frame
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
static void cs89x0_transmit(
|
||||||
|
struct nic *nic,
|
||||||
|
char *d, /* Destination */
|
||||||
|
unsigned int t, /* Type */
|
||||||
|
unsigned int s, /* size */
|
||||||
|
char *p) /* Packet */
|
||||||
|
{
|
||||||
|
long tmo;
|
||||||
|
int sr;
|
||||||
|
|
||||||
|
if(eth_vendor!=VENDOR_CS89x0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* does this size have to be rounded??? please,
|
||||||
|
somebody have a look in the specs */
|
||||||
|
if ((sr = ((s + ETHER_HDR_SIZE + 1)&~1)) < ETH_MIN_PACKET)
|
||||||
|
sr = ETH_MIN_PACKET;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
/* initiate a transmit sequence */
|
||||||
|
outw(eth_nic_base + TX_CMD_PORT, TX_AFTER_ALL);
|
||||||
|
outw(eth_nic_base + TX_LEN_PORT, sr);
|
||||||
|
|
||||||
|
/* Test to see if the chip has allocated memory for the packet */
|
||||||
|
if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
||||||
|
/* Oops... this should not happen! */
|
||||||
|
printf("cs: unable to send packet; retrying...\r\n");
|
||||||
|
for (tmo = currticks() + 5*18; currticks() - tmo < 0; );
|
||||||
|
cs89x0_reset(nic);
|
||||||
|
goto retry; }
|
||||||
|
|
||||||
|
/* Write the contents of the packet */
|
||||||
|
outsw(eth_nic_base + TX_FRAME_PORT, d, ETHER_ADDR_SIZE/2);
|
||||||
|
outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
|
||||||
|
ETHER_ADDR_SIZE/2);
|
||||||
|
outw(eth_nic_base + TX_FRAME_PORT, ((t >> 8)&0xFF)|(t << 8));
|
||||||
|
outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
|
||||||
|
for (sr = sr/2 - (s+1)/2 - ETHER_ADDR_SIZE - 1; sr-- > 0;
|
||||||
|
outw(eth_nic_base + TX_FRAME_PORT, 0));
|
||||||
|
|
||||||
|
/* wait for transfer to succeed */
|
||||||
|
for (tmo = currticks()+5*18;
|
||||||
|
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() - tmo < 0;
|
||||||
|
twiddle());
|
||||||
|
if ((s & TX_SEND_OK_BITS) != TX_OK) {
|
||||||
|
printf("\r\ntransmission error 0x%x\r\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_POLL - Wait for a frame
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
static int cs89x0_poll(struct nic *nic)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(eth_vendor!=VENDOR_CS89x0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
status = readreg(PP_RxEvent);
|
||||||
|
|
||||||
|
if ((status & RX_OK) == 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
status = inw(eth_nic_base + RX_FRAME_PORT);
|
||||||
|
nic->packetlen = inw(eth_nic_base + RX_FRAME_PORT);
|
||||||
|
insw(eth_nic_base + RX_FRAME_PORT, nic->packet, nic->packetlen >> 1);
|
||||||
|
if (nic->packetlen & 1)
|
||||||
|
nic->packet[nic->packetlen-1] = inw(eth_nic_base + RX_FRAME_PORT);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cs89x0_disable(struct nic *nic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_PROBE - Look for an adapter
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||||
|
{
|
||||||
|
static const unsigned int netcard_portlist[] = {
|
||||||
|
#ifdef CS_SCAN
|
||||||
|
CS_SCAN,
|
||||||
|
#else /* use "conservative" default values for autoprobing */
|
||||||
|
0x300,0x320,0x340,0x200,0x220,0x240,
|
||||||
|
0x260,0x280,0x2a0,0x2c0,0x2e0,
|
||||||
|
/* if that did not work, then be more aggressive */
|
||||||
|
0x301,0x321,0x341,0x201,0x221,0x241,
|
||||||
|
0x261,0x281,0x2a1,0x2c1,0x2e1,
|
||||||
|
#endif
|
||||||
|
0};
|
||||||
|
|
||||||
|
int i, result = -1;
|
||||||
|
unsigned rev_type = 0, ioaddr, ioidx, isa_cnf, cs_revision;
|
||||||
|
unsigned short eeprom_buff[CHKSUM_LEN];
|
||||||
|
|
||||||
|
|
||||||
|
for (eth_vendor = VENDOR_NONE, ioidx = 0;
|
||||||
|
eth_vendor == VENDOR_NONE &&
|
||||||
|
(ioaddr=netcard_portlist[ioidx++]) != 0;) {
|
||||||
|
/* if they give us an odd I/O address, then do ONE write to
|
||||||
|
the address port, to get it back to address zero, where we
|
||||||
|
expect to find the EISA signature word. */
|
||||||
|
if (ioaddr & 1) {
|
||||||
|
ioaddr &= ~1;
|
||||||
|
if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
|
||||||
|
continue;
|
||||||
|
outw(ioaddr + ADD_PORT, PP_ChipID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
|
||||||
|
continue;
|
||||||
|
eth_nic_base = ioaddr;
|
||||||
|
|
||||||
|
/* get the chip type */
|
||||||
|
rev_type = readreg(PRODUCT_ID_ADD);
|
||||||
|
eth_cs_type = rev_type &~ REVISON_BITS;
|
||||||
|
cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
|
||||||
|
|
||||||
|
printf("\r\ncs: cs89%c0%s rev %c, base 0x%x",
|
||||||
|
eth_cs_type==CS8900?'0':'2',
|
||||||
|
eth_cs_type==CS8920M?"M":"",
|
||||||
|
cs_revision,
|
||||||
|
eth_nic_base);
|
||||||
|
|
||||||
|
/* First check to see if an EEPROM is attached*/
|
||||||
|
if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
|
||||||
|
printf("\r\ncs: no EEPROM...\r\n");
|
||||||
|
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||||
|
continue; }
|
||||||
|
else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,
|
||||||
|
eeprom_buff) < 0) {
|
||||||
|
printf("\r\ncs: EEPROM read failed...\r\n");
|
||||||
|
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||||
|
continue; }
|
||||||
|
else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,
|
||||||
|
eeprom_buff) < 0) {
|
||||||
|
printf("\r\ncs: EEPROM checksum bad...\r\n");
|
||||||
|
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||||
|
continue; }
|
||||||
|
|
||||||
|
/* get transmission control word but keep the
|
||||||
|
autonegotiation bits */
|
||||||
|
eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
|
||||||
|
/* Store adapter configuration */
|
||||||
|
eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
|
||||||
|
/* Store ISA configuration */
|
||||||
|
isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];
|
||||||
|
|
||||||
|
/* store the initial memory base address */
|
||||||
|
eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
|
||||||
|
|
||||||
|
printf("%s%s%s, addr ",
|
||||||
|
(eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",
|
||||||
|
(eth_adapter_cnf & A_CNF_AUI)?", AUI":"",
|
||||||
|
(eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");
|
||||||
|
|
||||||
|
/* If this is a CS8900 then no pnp soft */
|
||||||
|
if (eth_cs_type != CS8900 &&
|
||||||
|
/* Check if the ISA IRQ has been set */
|
||||||
|
(i = readreg(PP_CS8920_ISAINT) & 0xff,
|
||||||
|
(i != 0 && i < CS8920_NO_INTS)))
|
||||||
|
eth_irq = i;
|
||||||
|
else {
|
||||||
|
i = isa_cnf & INT_NO_MASK;
|
||||||
|
if (eth_cs_type == CS8900) {
|
||||||
|
/* the table that follows is dependent
|
||||||
|
upon how you wired up your cs8900
|
||||||
|
in your system. The table is the
|
||||||
|
same as the cs8900 engineering demo
|
||||||
|
board. irq_map also depends on the
|
||||||
|
contents of the table. Also see
|
||||||
|
write_irq, which is the reverse
|
||||||
|
mapping of the table below. */
|
||||||
|
if (i < 4) i = "\012\013\014\005"[i];
|
||||||
|
else printf("\r\ncs: BUG: isa_config is %d\r\n", i); }
|
||||||
|
eth_irq = i; }
|
||||||
|
|
||||||
|
/* Retrieve and print the ethernet address. */
|
||||||
|
for (i=0; i<ETHER_ADDR_SIZE; i++) {
|
||||||
|
printf("%b%s",(int)(nic->node_addr[i] =
|
||||||
|
((unsigned char *)eeprom_buff)[i]),
|
||||||
|
i < ETHER_ADDR_SIZE-1 ? ":" : "\r\n"); }
|
||||||
|
|
||||||
|
/* Set the LineCTL quintuplet based on adapter
|
||||||
|
configuration read from EEPROM */
|
||||||
|
if ((eth_adapter_cnf & A_CNF_EXTND_10B_2) &&
|
||||||
|
(eth_adapter_cnf & A_CNF_LOW_RX_SQUELCH))
|
||||||
|
eth_linectl = LOW_RX_SQUELCH;
|
||||||
|
else
|
||||||
|
eth_linectl = 0;
|
||||||
|
|
||||||
|
/* check to make sure that they have the "right"
|
||||||
|
hardware available */
|
||||||
|
switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
|
||||||
|
case A_CNF_MEDIA_10B_T: result = eth_adapter_cnf & A_CNF_10B_T;
|
||||||
|
break;
|
||||||
|
case A_CNF_MEDIA_AUI: result = eth_adapter_cnf & A_CNF_AUI;
|
||||||
|
break;
|
||||||
|
case A_CNF_MEDIA_10B_2: result = eth_adapter_cnf & A_CNF_10B_2;
|
||||||
|
break;
|
||||||
|
default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |
|
||||||
|
A_CNF_10B_2);
|
||||||
|
}
|
||||||
|
if (!result) {
|
||||||
|
printf("cs: EEPROM is configured for unavailable media\r\n");
|
||||||
|
error:
|
||||||
|
writereg(PP_LineCTL, readreg(PP_LineCTL) &
|
||||||
|
~(SERIAL_TX_ON | SERIAL_RX_ON));
|
||||||
|
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the card for probing of the attached media */
|
||||||
|
eth_vendor = VENDOR_CS89x0;
|
||||||
|
cs89x0_reset(nic);
|
||||||
|
eth_vendor = VENDOR_NONE;
|
||||||
|
|
||||||
|
/* set the hardware to the configured choice */
|
||||||
|
switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
|
||||||
|
case A_CNF_MEDIA_10B_T:
|
||||||
|
result = detect_tp();
|
||||||
|
if (!result) {
|
||||||
|
clrline();
|
||||||
|
printf("10Base-T (RJ-45%s",
|
||||||
|
") has no cable\r\n"); }
|
||||||
|
/* check "ignore missing media" bit */
|
||||||
|
if (eth_auto_neg_cnf & IMM_BIT)
|
||||||
|
/* Yes! I don't care if I see a link pulse */
|
||||||
|
result = A_CNF_MEDIA_10B_T;
|
||||||
|
break;
|
||||||
|
case A_CNF_MEDIA_AUI:
|
||||||
|
result = detect_aui(nic);
|
||||||
|
if (!result) {
|
||||||
|
clrline();
|
||||||
|
printf("10Base-5 (AUI%s",
|
||||||
|
") has no cable\r\n"); }
|
||||||
|
/* check "ignore missing media" bit */
|
||||||
|
if (eth_auto_neg_cnf & IMM_BIT)
|
||||||
|
/* Yes! I don't care if I see a carrrier */
|
||||||
|
result = A_CNF_MEDIA_AUI;
|
||||||
|
break;
|
||||||
|
case A_CNF_MEDIA_10B_2:
|
||||||
|
result = detect_bnc(nic);
|
||||||
|
if (!result) {
|
||||||
|
clrline();
|
||||||
|
printf("10Base-2 (BNC%s",
|
||||||
|
") has no cable\r\n"); }
|
||||||
|
/* check "ignore missing media" bit */
|
||||||
|
if (eth_auto_neg_cnf & IMM_BIT)
|
||||||
|
/* Yes! I don't care if I can xmit a packet */
|
||||||
|
result = A_CNF_MEDIA_10B_2;
|
||||||
|
break;
|
||||||
|
case A_CNF_MEDIA_AUTO:
|
||||||
|
writereg(PP_LineCTL, eth_linectl | AUTO_AUI_10BASET);
|
||||||
|
if (eth_adapter_cnf & A_CNF_10B_T)
|
||||||
|
if ((result = detect_tp()) != 0)
|
||||||
|
break;
|
||||||
|
if (eth_adapter_cnf & A_CNF_AUI)
|
||||||
|
if ((result = detect_aui(nic)) != 0)
|
||||||
|
break;
|
||||||
|
if (eth_adapter_cnf & A_CNF_10B_2)
|
||||||
|
if ((result = detect_bnc(nic)) != 0)
|
||||||
|
break;
|
||||||
|
clrline(); printf("no media detected\r\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
clrline();
|
||||||
|
switch(result) {
|
||||||
|
case 0: printf("no network cable attached to configured media\r\n");
|
||||||
|
goto error;
|
||||||
|
case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\r\n");
|
||||||
|
break;
|
||||||
|
case A_CNF_MEDIA_AUI: printf("using 10Base-5 (AUI)\r\n");
|
||||||
|
break;
|
||||||
|
case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn on both receive and transmit operations */
|
||||||
|
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |
|
||||||
|
SERIAL_TX_ON);
|
||||||
|
|
||||||
|
eth_vendor = VENDOR_CS89x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nic->reset = cs89x0_reset;
|
||||||
|
nic->poll = cs89x0_poll;
|
||||||
|
nic->transmit = cs89x0_transmit;
|
||||||
|
nic->disable = cs89x0_disable;
|
||||||
|
return nic;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* INCLUDE_CS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* End:
|
||||||
|
*/
|
465
netboot/cs89x0.h
Normal file
465
netboot/cs89x0.h
Normal file
|
@ -0,0 +1,465 @@
|
||||||
|
/* This file has been copied from Russel Nelson's device driver for
|
||||||
|
Linux. Please look into the header of cs89x0.c for details on the
|
||||||
|
legal implications! */
|
||||||
|
|
||||||
|
/* Copyright, 1988-1992, Russell Nelson, Crynwr Software
|
||||||
|
|
||||||
|
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 1.
|
||||||
|
|
||||||
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */
|
||||||
|
/* offset 2h -> Model/Product Number */
|
||||||
|
/* offset 3h -> Chip Revision Number */
|
||||||
|
|
||||||
|
#define PP_ISAIOB 0x0020 /* IO base address */
|
||||||
|
#define PP_CS8900_ISAINT 0x0022 /* ISA interrupt select */
|
||||||
|
#define PP_CS8920_ISAINT 0x0370 /* ISA interrupt select */
|
||||||
|
#define PP_CS8900_ISADMA 0x0024 /* ISA Rec DMA channel */
|
||||||
|
#define PP_CS8920_ISADMA 0x0374 /* ISA Rec DMA channel */
|
||||||
|
#define PP_ISASOF 0x0026 /* ISA DMA offset */
|
||||||
|
#define PP_DmaFrameCnt 0x0028 /* ISA DMA Frame count */
|
||||||
|
#define PP_DmaByteCnt 0x002A /* ISA DMA Byte count */
|
||||||
|
#define PP_CS8900_ISAMemB 0x002C /* Memory base */
|
||||||
|
#define PP_CS8920_ISAMemB 0x0348 /* */
|
||||||
|
|
||||||
|
#define PP_ISABootBase 0x0030 /* Boot Prom base */
|
||||||
|
#define PP_ISABootMask 0x0034 /* Boot Prom Mask */
|
||||||
|
|
||||||
|
/* EEPROM data and command registers */
|
||||||
|
#define PP_EECMD 0x0040 /* NVR Interface Command register */
|
||||||
|
#define PP_EEData 0x0042 /* NVR Interface Data Register */
|
||||||
|
#define PP_DebugReg 0x0044 /* Debug Register */
|
||||||
|
|
||||||
|
#define PP_RxCFG 0x0102 /* Rx Bus config */
|
||||||
|
#define PP_RxCTL 0x0104 /* Receive Control Register */
|
||||||
|
#define PP_TxCFG 0x0106 /* Transmit Config Register */
|
||||||
|
#define PP_TxCMD 0x0108 /* Transmit Command Register */
|
||||||
|
#define PP_BufCFG 0x010A /* Bus configuration Register */
|
||||||
|
#define PP_LineCTL 0x0112 /* Line Config Register */
|
||||||
|
#define PP_SelfCTL 0x0114 /* Self Command Register */
|
||||||
|
#define PP_BusCTL 0x0116 /* ISA bus control Register */
|
||||||
|
#define PP_TestCTL 0x0118 /* Test Register */
|
||||||
|
#define PP_AutoNegCTL 0x011C /* Auto Negotiation Ctrl */
|
||||||
|
|
||||||
|
#define PP_ISQ 0x0120 /* Interrupt Status */
|
||||||
|
#define PP_RxEvent 0x0124 /* Rx Event Register */
|
||||||
|
#define PP_TxEvent 0x0128 /* Tx Event Register */
|
||||||
|
#define PP_BufEvent 0x012C /* Bus Event Register */
|
||||||
|
#define PP_RxMiss 0x0130 /* Receive Miss Count */
|
||||||
|
#define PP_TxCol 0x0132 /* Transmit Collision Count */
|
||||||
|
#define PP_LineST 0x0134 /* Line State Register */
|
||||||
|
#define PP_SelfST 0x0136 /* Self State register */
|
||||||
|
#define PP_BusST 0x0138 /* Bus Status */
|
||||||
|
#define PP_TDR 0x013C /* Time Domain Reflectometry */
|
||||||
|
#define PP_AutoNegST 0x013E /* Auto Neg Status */
|
||||||
|
#define PP_TxCommand 0x0144 /* Tx Command */
|
||||||
|
#define PP_TxLength 0x0146 /* Tx Length */
|
||||||
|
#define PP_LAF 0x0150 /* Hash Table */
|
||||||
|
#define PP_IA 0x0158 /* Physical Address Register */
|
||||||
|
|
||||||
|
#define PP_RxStatus 0x0400 /* Receive start of frame */
|
||||||
|
#define PP_RxLength 0x0402 /* Receive Length of frame */
|
||||||
|
#define PP_RxFrame 0x0404 /* Receive frame pointer */
|
||||||
|
#define PP_TxFrame 0x0A00 /* Transmit frame pointer */
|
||||||
|
|
||||||
|
/* Primary I/O Base Address. If no I/O base is supplied by the user, then this */
|
||||||
|
/* can be used as the default I/O base to access the PacketPage Area. */
|
||||||
|
#define DEFAULTIOBASE 0x0300
|
||||||
|
#define FIRST_IO 0x020C /* First I/O port to check */
|
||||||
|
#define LAST_IO 0x037C /* Last I/O port to check (+10h) */
|
||||||
|
#define ADD_MASK 0x3000 /* Mask it use of the ADD_PORT register */
|
||||||
|
#define ADD_SIG 0x3000 /* Expected ID signature */
|
||||||
|
|
||||||
|
#define CHIP_EISA_ID_SIG 0x630E /* Product ID Code for Crystal Chip (CS8900 spec 4.3) */
|
||||||
|
|
||||||
|
#ifdef IBMEIPKT
|
||||||
|
#define EISA_ID_SIG 0x4D24 /* IBM */
|
||||||
|
#define PART_NO_SIG 0x1010 /* IBM */
|
||||||
|
#define MONGOOSE_BIT 0x0000 /* IBM */
|
||||||
|
#else
|
||||||
|
#define EISA_ID_SIG 0x630E /* PnP Vendor ID (same as chip id for Crystal board) */
|
||||||
|
#define PART_NO_SIG 0x4000 /* ID code CS8920 board (PnP Vendor Product code) */
|
||||||
|
#define MONGOOSE_BIT 0x2000 /* PART_NO_SIG + MONGOOSE_BUT => ID of mongoose */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PRODUCT_ID_ADD 0x0002 /* Address of product ID */
|
||||||
|
|
||||||
|
/* Mask to find out the types of registers */
|
||||||
|
#define REG_TYPE_MASK 0x001F
|
||||||
|
|
||||||
|
/* Eeprom Commands */
|
||||||
|
#define ERSE_WR_ENBL 0x00F0
|
||||||
|
#define ERSE_WR_DISABLE 0x0000
|
||||||
|
|
||||||
|
/* Defines Control/Config register quintuplet numbers */
|
||||||
|
#define RX_BUF_CFG 0x0003
|
||||||
|
#define RX_CONTROL 0x0005
|
||||||
|
#define TX_CFG 0x0007
|
||||||
|
#define TX_COMMAND 0x0009
|
||||||
|
#define BUF_CFG 0x000B
|
||||||
|
#define LINE_CONTROL 0x0013
|
||||||
|
#define SELF_CONTROL 0x0015
|
||||||
|
#define BUS_CONTROL 0x0017
|
||||||
|
#define TEST_CONTROL 0x0019
|
||||||
|
|
||||||
|
/* Defines Status/Count registers quintuplet numbers */
|
||||||
|
#define RX_EVENT 0x0004
|
||||||
|
#define TX_EVENT 0x0008
|
||||||
|
#define BUF_EVENT 0x000C
|
||||||
|
#define RX_MISS_COUNT 0x0010
|
||||||
|
#define TX_COL_COUNT 0x0012
|
||||||
|
#define LINE_STATUS 0x0014
|
||||||
|
#define SELF_STATUS 0x0016
|
||||||
|
#define BUS_STATUS 0x0018
|
||||||
|
#define TDR 0x001C
|
||||||
|
|
||||||
|
/* PP_RxCFG - Receive Configuration and Interrupt Mask bit definition - Read/write */
|
||||||
|
#define SKIP_1 0x0040
|
||||||
|
#define RX_STREAM_ENBL 0x0080
|
||||||
|
#define RX_OK_ENBL 0x0100
|
||||||
|
#define RX_DMA_ONLY 0x0200
|
||||||
|
#define AUTO_RX_DMA 0x0400
|
||||||
|
#define BUFFER_CRC 0x0800
|
||||||
|
#define RX_CRC_ERROR_ENBL 0x1000
|
||||||
|
#define RX_RUNT_ENBL 0x2000
|
||||||
|
#define RX_EXTRA_DATA_ENBL 0x4000
|
||||||
|
|
||||||
|
/* PP_RxCTL - Receive Control bit definition - Read/write */
|
||||||
|
#define RX_IA_HASH_ACCEPT 0x0040
|
||||||
|
#define RX_PROM_ACCEPT 0x0080
|
||||||
|
#define RX_OK_ACCEPT 0x0100
|
||||||
|
#define RX_MULTCAST_ACCEPT 0x0200
|
||||||
|
#define RX_IA_ACCEPT 0x0400
|
||||||
|
#define RX_BROADCAST_ACCEPT 0x0800
|
||||||
|
#define RX_BAD_CRC_ACCEPT 0x1000
|
||||||
|
#define RX_RUNT_ACCEPT 0x2000
|
||||||
|
#define RX_EXTRA_DATA_ACCEPT 0x4000
|
||||||
|
#define RX_ALL_ACCEPT (RX_PROM_ACCEPT|RX_BAD_CRC_ACCEPT|RX_RUNT_ACCEPT|RX_EXTRA_DATA_ACCEPT)
|
||||||
|
/* Default receive mode - individually addressed, broadcast, and error free */
|
||||||
|
#define DEF_RX_ACCEPT (RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | RX_OK_ACCEPT)
|
||||||
|
|
||||||
|
/* PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write */
|
||||||
|
#define TX_LOST_CRS_ENBL 0x0040
|
||||||
|
#define TX_SQE_ERROR_ENBL 0x0080
|
||||||
|
#define TX_OK_ENBL 0x0100
|
||||||
|
#define TX_LATE_COL_ENBL 0x0200
|
||||||
|
#define TX_JBR_ENBL 0x0400
|
||||||
|
#define TX_ANY_COL_ENBL 0x0800
|
||||||
|
#define TX_16_COL_ENBL 0x8000
|
||||||
|
|
||||||
|
/* PP_TxCMD - Transmit Command bit definition - Read-only */
|
||||||
|
#define TX_START_4_BYTES 0x0000
|
||||||
|
#define TX_START_64_BYTES 0x0040
|
||||||
|
#define TX_START_128_BYTES 0x0080
|
||||||
|
#define TX_START_ALL_BYTES 0x00C0
|
||||||
|
#define TX_FORCE 0x0100
|
||||||
|
#define TX_ONE_COL 0x0200
|
||||||
|
#define TX_TWO_PART_DEFF_DISABLE 0x0400
|
||||||
|
#define TX_NO_CRC 0x1000
|
||||||
|
#define TX_RUNT 0x2000
|
||||||
|
|
||||||
|
/* PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write */
|
||||||
|
#define GENERATE_SW_INTERRUPT 0x0040
|
||||||
|
#define RX_DMA_ENBL 0x0080
|
||||||
|
#define READY_FOR_TX_ENBL 0x0100
|
||||||
|
#define TX_UNDERRUN_ENBL 0x0200
|
||||||
|
#define RX_MISS_ENBL 0x0400
|
||||||
|
#define RX_128_BYTE_ENBL 0x0800
|
||||||
|
#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000
|
||||||
|
#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000
|
||||||
|
#define RX_DEST_MATCH_ENBL 0x8000
|
||||||
|
|
||||||
|
/* PP_LineCTL - Line Control bit definition - Read/write */
|
||||||
|
#define SERIAL_RX_ON 0x0040
|
||||||
|
#define SERIAL_TX_ON 0x0080
|
||||||
|
#define AUI_ONLY 0x0100
|
||||||
|
#define AUTO_AUI_10BASET 0x0200
|
||||||
|
#define MODIFIED_BACKOFF 0x0800
|
||||||
|
#define NO_AUTO_POLARITY 0x1000
|
||||||
|
#define TWO_PART_DEFDIS 0x2000
|
||||||
|
#define LOW_RX_SQUELCH 0x4000
|
||||||
|
|
||||||
|
/* PP_SelfCTL - Software Self Control bit definition - Read/write */
|
||||||
|
#define POWER_ON_RESET 0x0040
|
||||||
|
#define SW_STOP 0x0100
|
||||||
|
#define SLEEP_ON 0x0200
|
||||||
|
#define AUTO_WAKEUP 0x0400
|
||||||
|
#define HCB0_ENBL 0x1000
|
||||||
|
#define HCB1_ENBL 0x2000
|
||||||
|
#define HCB0 0x4000
|
||||||
|
#define HCB1 0x8000
|
||||||
|
|
||||||
|
/* PP_BusCTL - ISA Bus Control bit definition - Read/write */
|
||||||
|
#define RESET_RX_DMA 0x0040
|
||||||
|
#define MEMORY_ON 0x0400
|
||||||
|
#define DMA_BURST_MODE 0x0800
|
||||||
|
#define IO_CHANNEL_READY_ON 0x1000
|
||||||
|
#define RX_DMA_SIZE_64K 0x2000
|
||||||
|
#define ENABLE_IRQ 0x8000
|
||||||
|
|
||||||
|
/* PP_TestCTL - Test Control bit definition - Read/write */
|
||||||
|
#define LINK_OFF 0x0080
|
||||||
|
#define ENDEC_LOOPBACK 0x0200
|
||||||
|
#define AUI_LOOPBACK 0x0400
|
||||||
|
#define BACKOFF_OFF 0x0800
|
||||||
|
#define FAST_TEST 0x8000
|
||||||
|
|
||||||
|
/* PP_RxEvent - Receive Event Bit definition - Read-only */
|
||||||
|
#define RX_IA_HASHED 0x0040
|
||||||
|
#define RX_DRIBBLE 0x0080
|
||||||
|
#define RX_OK 0x0100
|
||||||
|
#define RX_HASHED 0x0200
|
||||||
|
#define RX_IA 0x0400
|
||||||
|
#define RX_BROADCAST 0x0800
|
||||||
|
#define RX_CRC_ERROR 0x1000
|
||||||
|
#define RX_RUNT 0x2000
|
||||||
|
#define RX_EXTRA_DATA 0x4000
|
||||||
|
|
||||||
|
#define HASH_INDEX_MASK 0x0FC00
|
||||||
|
|
||||||
|
/* PP_TxEvent - Transmit Event Bit definition - Read-only */
|
||||||
|
#define TX_LOST_CRS 0x0040
|
||||||
|
#define TX_SQE_ERROR 0x0080
|
||||||
|
#define TX_OK 0x0100
|
||||||
|
#define TX_LATE_COL 0x0200
|
||||||
|
#define TX_JBR 0x0400
|
||||||
|
#define TX_16_COL 0x8000
|
||||||
|
#define TX_SEND_OK_BITS (TX_OK|TX_LOST_CRS)
|
||||||
|
#define TX_COL_COUNT_MASK 0x7800
|
||||||
|
|
||||||
|
/* PP_BufEvent - Buffer Event Bit definition - Read-only */
|
||||||
|
#define SW_INTERRUPT 0x0040
|
||||||
|
#define RX_DMA 0x0080
|
||||||
|
#define READY_FOR_TX 0x0100
|
||||||
|
#define TX_UNDERRUN 0x0200
|
||||||
|
#define RX_MISS 0x0400
|
||||||
|
#define RX_128_BYTE 0x0800
|
||||||
|
#define TX_COL_OVRFLW 0x1000
|
||||||
|
#define RX_MISS_OVRFLW 0x2000
|
||||||
|
#define RX_DEST_MATCH 0x8000
|
||||||
|
|
||||||
|
/* PP_LineST - Ethernet Line Status bit definition - Read-only */
|
||||||
|
#define LINK_OK 0x0080
|
||||||
|
#define AUI_ON 0x0100
|
||||||
|
#define TENBASET_ON 0x0200
|
||||||
|
#define POLARITY_OK 0x1000
|
||||||
|
#define CRS_OK 0x4000
|
||||||
|
|
||||||
|
/* PP_SelfST - Chip Software Status bit definition */
|
||||||
|
#define ACTIVE_33V 0x0040
|
||||||
|
#define INIT_DONE 0x0080
|
||||||
|
#define SI_BUSY 0x0100
|
||||||
|
#define EEPROM_PRESENT 0x0200
|
||||||
|
#define EEPROM_OK 0x0400
|
||||||
|
#define EL_PRESENT 0x0800
|
||||||
|
#define EE_SIZE_64 0x1000
|
||||||
|
|
||||||
|
/* PP_BusST - ISA Bus Status bit definition */
|
||||||
|
#define TX_BID_ERROR 0x0080
|
||||||
|
#define READY_FOR_TX_NOW 0x0100
|
||||||
|
|
||||||
|
/* PP_AutoNegCTL - Auto Negotiation Control bit definition */
|
||||||
|
#define RE_NEG_NOW 0x0040
|
||||||
|
#define ALLOW_FDX 0x0080
|
||||||
|
#define AUTO_NEG_ENABLE 0x0100
|
||||||
|
#define NLP_ENABLE 0x0200
|
||||||
|
#define FORCE_FDX 0x8000
|
||||||
|
#define AUTO_NEG_BITS (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE)
|
||||||
|
#define AUTO_NEG_MASK (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE|ALLOW_FDX|RE_NEG_NOW)
|
||||||
|
|
||||||
|
/* PP_AutoNegST - Auto Negotiation Status bit definition */
|
||||||
|
#define AUTO_NEG_BUSY 0x0080
|
||||||
|
#define FLP_LINK 0x0100
|
||||||
|
#define FLP_LINK_GOOD 0x0800
|
||||||
|
#define LINK_FAULT 0x1000
|
||||||
|
#define HDX_ACTIVE 0x4000
|
||||||
|
#define FDX_ACTIVE 0x8000
|
||||||
|
|
||||||
|
/* The following block defines the ISQ event types */
|
||||||
|
#define ISQ_RECEIVER_EVENT 0x04
|
||||||
|
#define ISQ_TRANSMITTER_EVENT 0x08
|
||||||
|
#define ISQ_BUFFER_EVENT 0x0c
|
||||||
|
#define ISQ_RX_MISS_EVENT 0x10
|
||||||
|
#define ISQ_TX_COL_EVENT 0x12
|
||||||
|
|
||||||
|
#define ISQ_EVENT_MASK 0x003F /* ISQ mask to find out type of event */
|
||||||
|
#define ISQ_HIST 16 /* small history buffer */
|
||||||
|
#define AUTOINCREMENT 0x8000 /* Bit mask to set bit-15 for autoincrement */
|
||||||
|
|
||||||
|
#define TXRXBUFSIZE 0x0600
|
||||||
|
#define RXDMABUFSIZE 0x8000
|
||||||
|
#define RXDMASIZE 0x4000
|
||||||
|
#define TXRX_LENGTH_MASK 0x07FF
|
||||||
|
|
||||||
|
/* rx options bits */
|
||||||
|
#define RCV_WITH_RXON 1 /* Set SerRx ON */
|
||||||
|
#define RCV_COUNTS 2 /* Use Framecnt1 */
|
||||||
|
#define RCV_PONG 4 /* Pong respondent */
|
||||||
|
#define RCV_DONG 8 /* Dong operation */
|
||||||
|
#define RCV_POLLING 0x10 /* Poll RxEvent */
|
||||||
|
#define RCV_ISQ 0x20 /* Use ISQ, int */
|
||||||
|
#define RCV_AUTO_DMA 0x100 /* Set AutoRxDMAE */
|
||||||
|
#define RCV_DMA 0x200 /* Set RxDMA only */
|
||||||
|
#define RCV_DMA_ALL 0x400 /* Copy all DMA'ed */
|
||||||
|
#define RCV_FIXED_DATA 0x800 /* Every frame same */
|
||||||
|
#define RCV_IO 0x1000 /* Use ISA IO only */
|
||||||
|
#define RCV_MEMORY 0x2000 /* Use ISA Memory */
|
||||||
|
|
||||||
|
#define RAM_SIZE 0x1000 /* The card has 4k bytes or RAM */
|
||||||
|
#define PKT_START PP_TxFrame /* Start of packet RAM */
|
||||||
|
|
||||||
|
#define RX_FRAME_PORT 0x0000
|
||||||
|
#define TX_FRAME_PORT RX_FRAME_PORT
|
||||||
|
#define TX_CMD_PORT 0x0004
|
||||||
|
#define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */
|
||||||
|
#define TX_AFTER_381 0x0020 /* Tx packet after 381 bytes copied */
|
||||||
|
#define TX_AFTER_ALL 0x0060 /* Tx packet after all bytes copied */
|
||||||
|
#define TX_LEN_PORT 0x0006
|
||||||
|
#define ISQ_PORT 0x0008
|
||||||
|
#define ADD_PORT 0x000A
|
||||||
|
#define DATA_PORT 0x000C
|
||||||
|
|
||||||
|
#define EEPROM_WRITE_EN 0x00F0
|
||||||
|
#define EEPROM_WRITE_DIS 0x0000
|
||||||
|
#define EEPROM_WRITE_CMD 0x0100
|
||||||
|
#define EEPROM_READ_CMD 0x0200
|
||||||
|
|
||||||
|
/* Receive Header */
|
||||||
|
/* Description of header of each packet in receive area of memory */
|
||||||
|
#define RBUF_EVENT_LOW 0 /* Low byte of RxEvent - status of received frame */
|
||||||
|
#define RBUF_EVENT_HIGH 1 /* High byte of RxEvent - status of received frame */
|
||||||
|
#define RBUF_LEN_LOW 2 /* Length of received data - low byte */
|
||||||
|
#define RBUF_LEN_HI 3 /* Length of received data - high byte */
|
||||||
|
#define RBUF_HEAD_LEN 4 /* Length of this header */
|
||||||
|
|
||||||
|
#define CHIP_READ 0x1 /* Used to mark state of the repins code (chip or dma) */
|
||||||
|
#define DMA_READ 0x2 /* Used to mark state of the repins code (chip or dma) */
|
||||||
|
|
||||||
|
/* for bios scan */
|
||||||
|
/* */
|
||||||
|
#ifdef CSDEBUG
|
||||||
|
/* use these values for debugging bios scan */
|
||||||
|
#define BIOS_START_SEG 0x00000
|
||||||
|
#define BIOS_OFFSET_INC 0x0010
|
||||||
|
#else
|
||||||
|
#define BIOS_START_SEG 0x0c000
|
||||||
|
#define BIOS_OFFSET_INC 0x0200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BIOS_LAST_OFFSET 0x0fc00
|
||||||
|
|
||||||
|
/* Byte offsets into the EEPROM configuration buffer */
|
||||||
|
#define ISA_CNF_OFFSET 0x6
|
||||||
|
#define TX_CTL_OFFSET (ISA_CNF_OFFSET + 8) /* 8900 eeprom */
|
||||||
|
#define AUTO_NEG_CNF_OFFSET (ISA_CNF_OFFSET + 8) /* 8920 eeprom */
|
||||||
|
|
||||||
|
/* the assumption here is that the bits in the eeprom are generally */
|
||||||
|
/* in the same position as those in the autonegctl register. */
|
||||||
|
/* Of course the IMM bit is not in that register so it must be */
|
||||||
|
/* masked out */
|
||||||
|
#define EE_FORCE_FDX 0x8000
|
||||||
|
#define EE_NLP_ENABLE 0x0200
|
||||||
|
#define EE_AUTO_NEG_ENABLE 0x0100
|
||||||
|
#define EE_ALLOW_FDX 0x0080
|
||||||
|
#define EE_AUTO_NEG_CNF_MASK (EE_FORCE_FDX|EE_NLP_ENABLE|EE_AUTO_NEG_ENABLE|EE_ALLOW_FDX)
|
||||||
|
|
||||||
|
#define IMM_BIT 0x0040 /* ignore missing media */
|
||||||
|
|
||||||
|
#define ADAPTER_CNF_OFFSET (AUTO_NEG_CNF_OFFSET + 2)
|
||||||
|
#define A_CNF_10B_T 0x0001
|
||||||
|
#define A_CNF_AUI 0x0002
|
||||||
|
#define A_CNF_10B_2 0x0004
|
||||||
|
#define A_CNF_MEDIA_TYPE 0x0060
|
||||||
|
#define A_CNF_MEDIA_AUTO 0x0000
|
||||||
|
#define A_CNF_MEDIA_10B_T 0x0020
|
||||||
|
#define A_CNF_MEDIA_AUI 0x0040
|
||||||
|
#define A_CNF_MEDIA_10B_2 0x0060
|
||||||
|
#define A_CNF_DC_DC_POLARITY 0x0080
|
||||||
|
#define A_CNF_NO_AUTO_POLARITY 0x2000
|
||||||
|
#define A_CNF_LOW_RX_SQUELCH 0x4000
|
||||||
|
#define A_CNF_EXTND_10B_2 0x8000
|
||||||
|
|
||||||
|
#define PACKET_PAGE_OFFSET 0x8
|
||||||
|
|
||||||
|
/* Bit definitions for the ISA configuration word from the EEPROM */
|
||||||
|
#define INT_NO_MASK 0x000F
|
||||||
|
#define DMA_NO_MASK 0x0070
|
||||||
|
#define ISA_DMA_SIZE 0x0200
|
||||||
|
#define ISA_AUTO_RxDMA 0x0400
|
||||||
|
#define ISA_RxDMA 0x0800
|
||||||
|
#define DMA_BURST 0x1000
|
||||||
|
#define STREAM_TRANSFER 0x2000
|
||||||
|
#define ANY_ISA_DMA (ISA_AUTO_RxDMA | ISA_RxDMA)
|
||||||
|
|
||||||
|
/* DMA controller registers */
|
||||||
|
#define DMA_BASE 0x00 /* DMA controller base */
|
||||||
|
#define DMA_BASE_2 0x0C0 /* DMA controller base */
|
||||||
|
|
||||||
|
#define DMA_STAT 0x0D0 /* DMA controller status register */
|
||||||
|
#define DMA_MASK 0x0D4 /* DMA controller mask register */
|
||||||
|
#define DMA_MODE 0x0D6 /* DMA controller mode register */
|
||||||
|
#define DMA_RESETFF 0x0D8 /* DMA controller first/last flip flop */
|
||||||
|
|
||||||
|
/* DMA data */
|
||||||
|
#define DMA_DISABLE 0x04 /* Disable channel n */
|
||||||
|
#define DMA_ENABLE 0x00 /* Enable channel n */
|
||||||
|
/* Demand transfers, incr. address, auto init, writes, ch. n */
|
||||||
|
#define DMA_RX_MODE 0x14
|
||||||
|
/* Demand transfers, incr. address, auto init, reads, ch. n */
|
||||||
|
#define DMA_TX_MODE 0x18
|
||||||
|
|
||||||
|
#define DMA_SIZE (16*1024) /* Size of dma buffer - 16k */
|
||||||
|
|
||||||
|
#define CS8900 0x0000
|
||||||
|
#define CS8920 0x4000
|
||||||
|
#define CS8920M 0x6000
|
||||||
|
#define REVISON_BITS 0x1F00
|
||||||
|
#define EEVER_NUMBER 0x12
|
||||||
|
#define CHKSUM_LEN 0x14
|
||||||
|
#define CHKSUM_VAL 0x0000
|
||||||
|
#define START_EEPROM_DATA 0x001c /* Offset into eeprom for start of data */
|
||||||
|
#define IRQ_MAP_EEPROM_DATA 0x0046 /* Offset into eeprom for the IRQ map */
|
||||||
|
#define IRQ_MAP_LEN 0x0004 /* No of bytes to read for the IRQ map */
|
||||||
|
#define PNP_IRQ_FRMT 0x0022 /* PNP small item IRQ format */
|
||||||
|
#define CS8900_IRQ_MAP 0x1c20 /* This IRQ map is fixed */
|
||||||
|
|
||||||
|
#define CS8920_NO_INTS 0x0F /* Max CS8920 interrupt select # */
|
||||||
|
|
||||||
|
#define PNP_ADD_PORT 0x0279
|
||||||
|
#define PNP_WRITE_PORT 0x0A79
|
||||||
|
|
||||||
|
#define GET_PNP_ISA_STRUCT 0x40
|
||||||
|
#define PNP_ISA_STRUCT_LEN 0x06
|
||||||
|
#define PNP_CSN_CNT_OFF 0x01
|
||||||
|
#define PNP_RD_PORT_OFF 0x02
|
||||||
|
#define PNP_FUNCTION_OK 0x00
|
||||||
|
#define PNP_WAKE 0x03
|
||||||
|
#define PNP_RSRC_DATA 0x04
|
||||||
|
#define PNP_RSRC_READY 0x01
|
||||||
|
#define PNP_STATUS 0x05
|
||||||
|
#define PNP_ACTIVATE 0x30
|
||||||
|
#define PNP_CNF_IO_H 0x60
|
||||||
|
#define PNP_CNF_IO_L 0x61
|
||||||
|
#define PNP_CNF_INT 0x70
|
||||||
|
#define PNP_CNF_DMA 0x74
|
||||||
|
#define PNP_CNF_MEM 0x48
|
||||||
|
|
||||||
|
#define BIT0 1
|
||||||
|
#define BIT15 0x8000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
|
|
800
netboot/eepro100.c
Normal file
800
netboot/eepro100.c
Normal file
|
@ -0,0 +1,800 @@
|
||||||
|
/*
|
||||||
|
* eepro100.c -- This file implements the eepro100 driver for etherboot.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) AW Computer Systems.
|
||||||
|
* written by R.E.Wolff -- R.E.Wolff@BitWizard.nl
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* AW Computer Systems is contributing to the free software community
|
||||||
|
* by paying for this driver and then putting the result under GPL.
|
||||||
|
*
|
||||||
|
* If you need a Linux device driver, please contact BitWizard for a
|
||||||
|
* quote.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* date version by what
|
||||||
|
* Written: May 29 1997 V0.10 REW Initial revision.
|
||||||
|
* changes: May 31 1997 V0.90 REW Works!
|
||||||
|
* Jun 1 1997 V0.91 REW Cleanup
|
||||||
|
* Jun 2 1997 V0.92 REW Add some code documentation
|
||||||
|
* Jul 25 1997 V1.00 REW Tested by AW to work in a PROM
|
||||||
|
* Cleanup for publication
|
||||||
|
*
|
||||||
|
* This is the etherboot-3.1 compatible intel etherexpress Pro/100B
|
||||||
|
* driver.
|
||||||
|
*
|
||||||
|
* It was written from scratch, with Donald Beckers eepro100.c kernel
|
||||||
|
* driver as a guideline. Mostly the 82557 related definitions and the
|
||||||
|
* lower level routines have been cut-and-pasted into this source.
|
||||||
|
*
|
||||||
|
* The driver was finished before Intel got the NDA out of the closet.
|
||||||
|
* I still don't have the docs.
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Philosophy of this driver.
|
||||||
|
*
|
||||||
|
* Probing:
|
||||||
|
*
|
||||||
|
* Using a subset of "bios32" and "pci" functions of the linux kernel,
|
||||||
|
* the pci 82557 chip is detected.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Initialization:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The chip is then initialized to "know" its ethernet address, and to
|
||||||
|
* start recieving packets. The Linux driver has a whole transmit and
|
||||||
|
* recieve ring of buffers. This is neat if you need high performance:
|
||||||
|
* you can write the buffers asynchronously to the chip reading the
|
||||||
|
* buffers and transmitting them over the network. Performance is NOT
|
||||||
|
* an issue here. We can boot a 400k kernel in about two
|
||||||
|
* seconds. (Theory: 0.4 seconds). Booting a system is going to take
|
||||||
|
* about half a minute anyway, so getting 10 times closer to the
|
||||||
|
* theoretical limit is going to make a difference of a few percent.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Transmitting and recieving.
|
||||||
|
*
|
||||||
|
* We have only one transmit descriptor. It has two buffer descriptors:
|
||||||
|
* one for the header, and the other for the data.
|
||||||
|
* We have only one receive buffer. The chip is told to recieve packets,
|
||||||
|
* and suspend itself once it got one. The recieve (poll) routine simply
|
||||||
|
* looks at the recieve buffer to see if there is already a packet there.
|
||||||
|
* if there is, the buffer is copied, and the reciever is restarted.
|
||||||
|
*
|
||||||
|
* Caveats:
|
||||||
|
*
|
||||||
|
* The etherboot framework moves the code to the 32k segment from
|
||||||
|
* 0x98000 to 0xa0000. There is just a little room between the end of
|
||||||
|
* this driver and the 0xa0000 address. If you compile in too many
|
||||||
|
* features, this will overflow.
|
||||||
|
* The number under "hex" in the output of size that scrolls by while
|
||||||
|
* compiling should be less than 8000. Maybe even the stack is up there,
|
||||||
|
* so that you need even more headroom.
|
||||||
|
*
|
||||||
|
* If you run into trouble, the method used to give "pci.c" dynamic
|
||||||
|
* allocation should be used to allocate the larger variables (like
|
||||||
|
* the packet buffers)
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifdef INCLUDE_EEPRO100
|
||||||
|
|
||||||
|
|
||||||
|
/* The etherboot authors seem to dislike the argument ordering in
|
||||||
|
* outb macros that Linux uses. I disklike the confusion that this
|
||||||
|
* has caused even more.... This file uses the Linux argument ordering. */
|
||||||
|
#define LINUX_OUT_MACROS
|
||||||
|
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "nic.h"
|
||||||
|
#include <linux/bios32.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
|
||||||
|
static int ioaddr;
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef signed char s8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef signed short s16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef signed int s32;
|
||||||
|
|
||||||
|
|
||||||
|
enum speedo_offsets {
|
||||||
|
SCBStatus = 0, SCBCmd = 2, /* Rx/Command Unit command and status. */
|
||||||
|
SCBPointer = 4, /* General purpose pointer. */
|
||||||
|
SCBPort = 8, /* Misc. commands and operands. */
|
||||||
|
SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */
|
||||||
|
SCBCtrlMDI = 16, /* MDI interface control. */
|
||||||
|
SCBEarlyRx = 20, /* Early receive byte count. */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int read_eeprom(int ioaddr, int location);
|
||||||
|
static void udelay (int val);
|
||||||
|
void hd (void *where, int n);
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* I82557 related defines */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/* Serial EEPROM section.
|
||||||
|
A "bit" grungy, but we work our way through bit-by-bit :->. */
|
||||||
|
/* EEPROM_Ctrl bits. */
|
||||||
|
#define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */
|
||||||
|
#define EE_CS 0x02 /* EEPROM chip select. */
|
||||||
|
#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
|
||||||
|
#define EE_WRITE_0 0x01
|
||||||
|
#define EE_WRITE_1 0x05
|
||||||
|
#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
|
||||||
|
#define EE_ENB (0x4800 | EE_CS)
|
||||||
|
|
||||||
|
|
||||||
|
/* Delay between EEPROM clock transitions.
|
||||||
|
This is a "nasty" timing loop, but PC compatible machines are defined
|
||||||
|
to delay an ISA compatible period for the SLOW_DOWN_IO macro. */
|
||||||
|
#define eeprom_delay(nanosec) do { int _i = 3; while (--_i > 0) \
|
||||||
|
{ __SLOW_DOWN_IO; }} while (0)
|
||||||
|
|
||||||
|
/* The EEPROM commands include the alway-set leading bit. */
|
||||||
|
#define EE_WRITE_CMD (5 << 6)
|
||||||
|
#define EE_READ_CMD (6 << 6)
|
||||||
|
#define EE_ERASE_CMD (7 << 6)
|
||||||
|
|
||||||
|
/* The SCB accepts the following controls for the Tx and Rx units: */
|
||||||
|
#define CU_START 0x0010
|
||||||
|
#define CU_RESUME 0x0020
|
||||||
|
#define CU_STATSADDR 0x0040
|
||||||
|
#define CU_SHOWSTATS 0x0050 /* Dump statistics counters. */
|
||||||
|
#define CU_CMD_BASE 0x0060 /* Base address to add to add CU commands. */
|
||||||
|
#define CU_DUMPSTATS 0x0070 /* Dump then reset stats counters. */
|
||||||
|
|
||||||
|
#define RX_START 0x0001
|
||||||
|
#define RX_RESUME 0x0002
|
||||||
|
#define RX_ABORT 0x0004
|
||||||
|
#define RX_ADDR_LOAD 0x0006
|
||||||
|
#define RX_RESUMENR 0x0007
|
||||||
|
#define INT_MASK 0x0100
|
||||||
|
#define DRVR_INT 0x0200 /* Driver generated interrupt. */
|
||||||
|
|
||||||
|
enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
|
||||||
|
S80C24, PhyUndefined, DP83840A=10, };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Commands that can be put in a command list entry. */
|
||||||
|
enum commands {
|
||||||
|
CmdNOp = 0,
|
||||||
|
CmdIASetup = 1,
|
||||||
|
CmdConfigure = 2,
|
||||||
|
CmdMulticastList = 3,
|
||||||
|
CmdTx = 4,
|
||||||
|
CmdTDR = 5,
|
||||||
|
CmdDump = 6,
|
||||||
|
CmdDiagnose = 7,
|
||||||
|
|
||||||
|
/* And some extra flags: */
|
||||||
|
CmdSuspend = 0x4000, /* Suspend after completion. */
|
||||||
|
CmdIntr = 0x2000, /* Interrupt after completion. */
|
||||||
|
CmdTxFlex = 0x0008, /* Use "Flexible mode" for CmdTx command. */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* How to wait for the command unit to accept a command.
|
||||||
|
Typically this takes 0 ticks. */
|
||||||
|
static inline void wait_for_cmd_done(int cmd_ioaddr)
|
||||||
|
{
|
||||||
|
short wait = 100;
|
||||||
|
do ;
|
||||||
|
while(inb(cmd_ioaddr) && --wait >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Elements of the dump_statistics block. This block must be lword aligned. */
|
||||||
|
struct speedo_stats {
|
||||||
|
u32 tx_good_frames;
|
||||||
|
u32 tx_coll16_errs;
|
||||||
|
u32 tx_late_colls;
|
||||||
|
u32 tx_underruns;
|
||||||
|
u32 tx_lost_carrier;
|
||||||
|
u32 tx_deferred;
|
||||||
|
u32 tx_one_colls;
|
||||||
|
u32 tx_multi_colls;
|
||||||
|
u32 tx_total_colls;
|
||||||
|
u32 rx_good_frames;
|
||||||
|
u32 rx_crc_errs;
|
||||||
|
u32 rx_align_errs;
|
||||||
|
u32 rx_resource_errs;
|
||||||
|
u32 rx_overrun_errs;
|
||||||
|
u32 rx_colls_errs;
|
||||||
|
u32 rx_runt_errs;
|
||||||
|
u32 done_marker;
|
||||||
|
} lstats;
|
||||||
|
|
||||||
|
|
||||||
|
/* A speedo3 TX buffer descriptor with two buffers... */
|
||||||
|
struct TxFD {
|
||||||
|
volatile s16 status;
|
||||||
|
s16 command;
|
||||||
|
u32 link; /* void * */
|
||||||
|
u32 tx_desc_addr; /* (almost) Always points to the tx_buf_addr element. */
|
||||||
|
s32 count; /* # of TBD (=2), Tx start thresh., etc. */
|
||||||
|
/* This constitutes two "TBD" entries: hdr and data */
|
||||||
|
u32 tx_buf_addr0; /* void *, header of frame to be transmitted. */
|
||||||
|
s32 tx_buf_size0; /* Length of Tx hdr. */
|
||||||
|
u32 tx_buf_addr1; /* void *, data to be transmitted. */
|
||||||
|
s32 tx_buf_size1; /* Length of Tx data. */
|
||||||
|
} txfd;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The Speedo3 Rx buffer descriptors. */
|
||||||
|
struct RxFD { /* Receive frame descriptor. */
|
||||||
|
volatile s16 status;
|
||||||
|
s16 command;
|
||||||
|
u32 link; /* struct RxFD * */
|
||||||
|
u32 rx_buf_addr; /* void * */
|
||||||
|
u16 count;
|
||||||
|
u16 size;
|
||||||
|
char packet[1518];
|
||||||
|
} rxfd;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int congenb = 0; /* Enable congestion control in the DP83840. */
|
||||||
|
static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */
|
||||||
|
static int rxfifo = 8; /* Rx FIFO threshold, default 32 bytes. */
|
||||||
|
static int txdmacount = 0; /* Tx DMA burst length, 0-127, default 0. */
|
||||||
|
static int rxdmacount = 0; /* Rx DMA length, 0 means no preemption. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* I don't understand a byte in this structure. It was copied from the
|
||||||
|
* Linux kernel initialization for the eepro100. -- REW */
|
||||||
|
struct ConfCmd {
|
||||||
|
s16 status;
|
||||||
|
s16 command;
|
||||||
|
u32 link;
|
||||||
|
unsigned char data[22];
|
||||||
|
} confcmd = {
|
||||||
|
0, CmdConfigure,
|
||||||
|
(u32) & txfd,
|
||||||
|
{22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */
|
||||||
|
0, 0x2E, 0, 0x60, 0,
|
||||||
|
0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */
|
||||||
|
0x3f, 0x05, }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define TIME_OUT 1000000
|
||||||
|
|
||||||
|
/* The "pci" code needs to allocate a few structures. It wants to
|
||||||
|
* increment the "kernel memory ends here" pointer to allocate memory.
|
||||||
|
* I guess that a machine with PCI has more than 2Mb of memory, so
|
||||||
|
* that is where those things are put. Those structures don't survive
|
||||||
|
* the "jump to kernel start".
|
||||||
|
* */
|
||||||
|
#define MEM_START 0x200000 /* Memory starts at 2Mb for now.... */
|
||||||
|
#define MEM_END 0
|
||||||
|
|
||||||
|
static unsigned short eeprom [0x40];
|
||||||
|
|
||||||
|
static void calibrate_delay (void);
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Locally used functions */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* Support function: mdio_write
|
||||||
|
*
|
||||||
|
* This probably writes to the "physical media interface chip".
|
||||||
|
* -- REW
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static int mdio_write(int ioaddr, int phy_id, int location, int value)
|
||||||
|
{
|
||||||
|
int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
|
||||||
|
|
||||||
|
outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
|
||||||
|
ioaddr + SCBCtrlMDI);
|
||||||
|
do {
|
||||||
|
udelay(16);
|
||||||
|
|
||||||
|
val = inl(ioaddr + SCBCtrlMDI);
|
||||||
|
if (--boguscnt < 0) {
|
||||||
|
printf(" mdio_write() timed out with val = %8.8x.\n", val);
|
||||||
|
}
|
||||||
|
} while (! (val & 0x10000000));
|
||||||
|
return val & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Support function: mdio_read
|
||||||
|
*
|
||||||
|
* This probably reads a register in the "physical media interface chip".
|
||||||
|
* -- REW
|
||||||
|
*/
|
||||||
|
static int mdio_read(int ioaddr, int phy_id, int location)
|
||||||
|
{
|
||||||
|
int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
|
||||||
|
outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
|
||||||
|
do {
|
||||||
|
udelay(16);
|
||||||
|
|
||||||
|
val = inl(ioaddr + SCBCtrlMDI);
|
||||||
|
if (--boguscnt < 0) {
|
||||||
|
printf( " mdio_read() timed out with val = %8.8x.\n", val);
|
||||||
|
}
|
||||||
|
} while (! (val & 0x10000000));
|
||||||
|
return val & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Support function: read_eeprom
|
||||||
|
* reads a value from the eeprom at a specified location.
|
||||||
|
* Arguments: ioaddr: address of the 82557 chip
|
||||||
|
* location: address of the location to read from the eeprom.
|
||||||
|
* returns: value read from eeprom at location.
|
||||||
|
*/
|
||||||
|
static int read_eeprom(int ioaddr, int location)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned short retval = 0;
|
||||||
|
int ee_addr = ioaddr + SCBeeprom;
|
||||||
|
int read_cmd = location | EE_READ_CMD;
|
||||||
|
|
||||||
|
outw(EE_ENB & ~EE_CS, ee_addr);
|
||||||
|
outw(EE_ENB, ee_addr);
|
||||||
|
|
||||||
|
/* Shift the read command bits out. */
|
||||||
|
for (i = 10; i >= 0; i--) {
|
||||||
|
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
||||||
|
outw(EE_ENB | dataval, ee_addr);
|
||||||
|
eeprom_delay(100);
|
||||||
|
outw(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
|
||||||
|
eeprom_delay(150);
|
||||||
|
outw(EE_ENB | dataval, ee_addr); /* Finish EEPROM a clock tick. */
|
||||||
|
eeprom_delay(250);
|
||||||
|
}
|
||||||
|
outw(EE_ENB, ee_addr);
|
||||||
|
|
||||||
|
for (i = 15; i >= 0; i--) {
|
||||||
|
outw(EE_ENB | EE_SHIFT_CLK, ee_addr);
|
||||||
|
eeprom_delay(100);
|
||||||
|
retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
|
||||||
|
outw(EE_ENB, ee_addr);
|
||||||
|
eeprom_delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate the EEPROM access. */
|
||||||
|
outw(EE_ENB & ~EE_CS, ee_addr);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void inline whereami (char *str)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
printf ("%s\r\n", str);
|
||||||
|
sleep (2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Externally visible functions */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* function: eepro100_reset / eth_reset
|
||||||
|
* resets the card. This is used to allow Linux to probe the card again
|
||||||
|
* from a "virginal" state....
|
||||||
|
* Arguments: none
|
||||||
|
*
|
||||||
|
* returns: void.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void eepro100_reset(struct nic *nic)
|
||||||
|
{
|
||||||
|
outl(0, ioaddr + SCBPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* function: eepro100_transmit / eth_transmit
|
||||||
|
* This transmits a packet.
|
||||||
|
*
|
||||||
|
* Arguments: char d[6]: destination ethernet address.
|
||||||
|
* unsigned short t: ethernet protocol type.
|
||||||
|
* unsigned short s: size of the data-part of the packet.
|
||||||
|
* char *p: the data for the packet.
|
||||||
|
* returns: void.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void eepro100_transmit(struct nic *nic, char *d, unsigned int t, unsigned int s, char *p)
|
||||||
|
{
|
||||||
|
struct eth_hdr {
|
||||||
|
unsigned char dst_addr[6];
|
||||||
|
unsigned char src_addr[6];
|
||||||
|
unsigned short type;
|
||||||
|
} hdr;
|
||||||
|
unsigned short status;
|
||||||
|
int to;
|
||||||
|
int s1, s2;
|
||||||
|
|
||||||
|
status = inw(ioaddr + SCBStatus);
|
||||||
|
/* Acknowledge all of the current interrupt sources ASAP. */
|
||||||
|
outw(status & 0xfc00, ioaddr + SCBStatus);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("transmitting type %x packet (%d bytes). status = %x, cmd=%x\r\n",
|
||||||
|
t, s, status, inw (ioaddr + SCBCmd));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
memcpy (&hdr.dst_addr, d, 6);
|
||||||
|
memcpy (&hdr.src_addr, &arptable[ARP_CLIENT].node, 6);
|
||||||
|
|
||||||
|
hdr.type = htons (t);
|
||||||
|
|
||||||
|
txfd.status = 0;
|
||||||
|
txfd.command = CmdSuspend | CmdTx | CmdTxFlex;
|
||||||
|
txfd.link = virt_to_bus (&txfd);
|
||||||
|
txfd.count = 0x02208000;
|
||||||
|
txfd.tx_desc_addr = (u32)&txfd.tx_buf_addr0;
|
||||||
|
|
||||||
|
txfd.tx_buf_addr0 = virt_to_bus (&hdr);
|
||||||
|
txfd.tx_buf_size0 = sizeof (hdr);
|
||||||
|
|
||||||
|
txfd.tx_buf_addr1 = virt_to_bus (p);
|
||||||
|
txfd.tx_buf_size1 = s;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("txfd: \r\n");
|
||||||
|
hd (&txfd, sizeof (txfd));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | CU_START, ioaddr + SCBCmd);
|
||||||
|
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
s1 = inw (ioaddr + SCBStatus);
|
||||||
|
to = TIME_OUT;
|
||||||
|
while (!txfd.status && --to)
|
||||||
|
/* Wait */;
|
||||||
|
s2 = inw (ioaddr + SCBStatus);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Tx: Loop executed %d times.\r\n", TIME_OUT-to);
|
||||||
|
printf ("s1 = %x, s2 = %x.\r\n", s1, s2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* function: eepro100_poll / eth_poll
|
||||||
|
* This recieves a packet from the network.
|
||||||
|
*
|
||||||
|
* Arguments: none
|
||||||
|
*
|
||||||
|
* returns: 1 if a packet was recieved.
|
||||||
|
* 0 if no pacet was recieved.
|
||||||
|
* side effects:
|
||||||
|
* returns the packet in the array nic->packet.
|
||||||
|
* returns the length of the packet in nic->packetlen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int eepro100_poll(struct nic *nic)
|
||||||
|
{
|
||||||
|
int to;
|
||||||
|
|
||||||
|
to = TIME_OUT;
|
||||||
|
while (!rxfd.status && --to)
|
||||||
|
/* Wait */;
|
||||||
|
|
||||||
|
/* Ok. We got a packet. Now restart the reciever.... */
|
||||||
|
rxfd.status = 0;
|
||||||
|
rxfd.command = 0xc000;
|
||||||
|
outl(virt_to_bus(&rxfd), ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
|
||||||
|
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
if (to) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Got a packet: Len = %d.\r\n", rxfd.count & 0x3fff);
|
||||||
|
#endif
|
||||||
|
nic->packetlen = rxfd.count & 0x3fff;
|
||||||
|
bcopy (rxfd.packet, nic->packet, sizeof (rxfd.packet));
|
||||||
|
#ifdef DEBUG
|
||||||
|
hd (nic->packet, 0x30);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eepro100_disable(struct nic *nic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* exported function: eepro100_probe / eth_probe
|
||||||
|
* initializes a card
|
||||||
|
*
|
||||||
|
* side effects:
|
||||||
|
* leaves the ioaddress of the 82557 chip in the variable ioaddr.
|
||||||
|
* leaves the 82557 initialized, and ready to recieve packets.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
|
||||||
|
{
|
||||||
|
int pci_index;
|
||||||
|
u16 sum = 0;
|
||||||
|
int i, j, to;
|
||||||
|
unsigned short value;
|
||||||
|
int options;
|
||||||
|
int promisc;
|
||||||
|
|
||||||
|
if (probeaddrs == 0 || probeaddrs[0] == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
|
||||||
|
|
||||||
|
/* Ok. Got one. Read the eeprom. */
|
||||||
|
for (j = 0, i = 0; i < 0x40; i++) {
|
||||||
|
value = read_eeprom(ioaddr, i);
|
||||||
|
eeprom[i] = value;
|
||||||
|
sum += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Ethernet addr: ");
|
||||||
|
for (i=0;i<6;i++) {
|
||||||
|
arptable[ARP_CLIENT].node[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
|
||||||
|
printf ("%b%c", arptable[ARP_CLIENT].node[i] , i < 5?':':' ');
|
||||||
|
}
|
||||||
|
printf ("\r\n");
|
||||||
|
|
||||||
|
if (sum != 0xBABA)
|
||||||
|
printf("eepro100: Invalid EEPROM checksum %#4.4x, "
|
||||||
|
"check settings before activating this device!\r\n", sum);
|
||||||
|
outl(0, ioaddr + SCBPort);
|
||||||
|
udelay (10);
|
||||||
|
|
||||||
|
whereami ("Got eeprom.");
|
||||||
|
|
||||||
|
outl(virt_to_bus(&lstats), ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | CU_STATSADDR, ioaddr + SCBCmd);
|
||||||
|
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
whereami ("set stats addr.");
|
||||||
|
/* INIT RX stuff. */
|
||||||
|
|
||||||
|
/* Base = 0 */
|
||||||
|
outl(0, ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd);
|
||||||
|
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
whereami ("set rx base addr.");
|
||||||
|
|
||||||
|
rxfd.status = 0x0001;
|
||||||
|
rxfd.command = 0x0000;
|
||||||
|
rxfd.link = virt_to_bus(&rxfd);
|
||||||
|
rxfd.rx_buf_addr = (int) &nic->packet;
|
||||||
|
rxfd.count = 0;
|
||||||
|
rxfd.size = 1528;
|
||||||
|
|
||||||
|
outl(virt_to_bus(&rxfd), ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
|
||||||
|
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
whereami ("started RX process.");
|
||||||
|
|
||||||
|
/* Start the reciever.... */
|
||||||
|
rxfd.status = 0;
|
||||||
|
rxfd.command = 0xc000;
|
||||||
|
outl(virt_to_bus(&rxfd), ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
|
||||||
|
/* INIT TX stuff. */
|
||||||
|
|
||||||
|
/* Base = 0 */
|
||||||
|
outl(0, ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | CU_CMD_BASE, ioaddr + SCBCmd);
|
||||||
|
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
whereami ("set TX base addr.");
|
||||||
|
|
||||||
|
txfd.command = (CmdIASetup);
|
||||||
|
txfd.status = 0x0000;
|
||||||
|
txfd.link = virt_to_bus (&confcmd);
|
||||||
|
|
||||||
|
{
|
||||||
|
char *p = (char *)&txfd.tx_desc_addr;
|
||||||
|
|
||||||
|
for (i=0;i<6;i++)
|
||||||
|
p[i] = arptable[ARP_CLIENT].node[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Setup_eaddr:\r\n");
|
||||||
|
hd (&txfd, 0x20);
|
||||||
|
#endif
|
||||||
|
/* options = 0x40; */ /* 10mbps half duplex... */
|
||||||
|
options = 0x00; /* Autosense */
|
||||||
|
|
||||||
|
promisc = 0;
|
||||||
|
|
||||||
|
printf ("eeprom[6] = %x \r\n", eeprom[6]);
|
||||||
|
if ( ((eeprom[6]>>8) & 0x3f) == DP83840
|
||||||
|
|| ((eeprom[6]>>8) & 0x3f) == DP83840A) {
|
||||||
|
int mdi_reg23 = mdio_read(ioaddr, eeprom[6] & 0x1f, 23) | 0x0422;
|
||||||
|
if (congenb)
|
||||||
|
mdi_reg23 |= 0x0100;
|
||||||
|
printf(" DP83840 specific setup, setting register 23 to %x.\r\n",
|
||||||
|
mdi_reg23);
|
||||||
|
mdio_write(ioaddr, eeprom[6] & 0x1f, 23, mdi_reg23);
|
||||||
|
}
|
||||||
|
whereami ("Done DP8340 special setup.");
|
||||||
|
if (options != 0) {
|
||||||
|
mdio_write(ioaddr, eeprom[6] & 0x1f, 0,
|
||||||
|
((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */
|
||||||
|
((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
|
||||||
|
whereami ("set mdio_register.");
|
||||||
|
}
|
||||||
|
|
||||||
|
confcmd.command = CmdSuspend | CmdConfigure;
|
||||||
|
confcmd.status = 0x0000;
|
||||||
|
confcmd.link = virt_to_bus (&txfd);
|
||||||
|
confcmd.data[1] = (txfifo << 4) | rxfifo;
|
||||||
|
confcmd.data[4] = rxdmacount;
|
||||||
|
confcmd.data[5] = txdmacount + 0x80;
|
||||||
|
confcmd.data[15] = promisc ? 0x49: 0x48;
|
||||||
|
confcmd.data[19] = (options & 0x10) ? 0xC0 : 0x80;
|
||||||
|
confcmd.data[21] = promisc ? 0x0D: 0x05;
|
||||||
|
|
||||||
|
outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
|
||||||
|
outw(INT_MASK | CU_START, ioaddr + SCBCmd);
|
||||||
|
wait_for_cmd_done(ioaddr + SCBCmd);
|
||||||
|
|
||||||
|
whereami ("started TX thingy (config, iasetup).");
|
||||||
|
|
||||||
|
to = TIME_OUT;
|
||||||
|
while (!txfd.status && --to)
|
||||||
|
/* Wait */;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("\r\nLoop executed %d times.\r\n", TIME_OUT-to);
|
||||||
|
#endif
|
||||||
|
nic->reset = eepro100_reset;
|
||||||
|
nic->poll = eepro100_poll;
|
||||||
|
nic->transmit = eepro100_transmit;
|
||||||
|
nic->disable = eepro100_disable;
|
||||||
|
return nic;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int loops_per_sec;
|
||||||
|
static int loops_per_usec;
|
||||||
|
|
||||||
|
static void udelay (int val)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for(c=0; c<val*loops_per_usec; c++) {
|
||||||
|
/* Nothing */;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
/* I don't have the possibility to test the below code. Murphey tells me
|
||||||
|
* it won't work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void calibrate_delay (void)
|
||||||
|
{
|
||||||
|
loops_per_usec = 500;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
#define __delay udelay
|
||||||
|
#define jiffies currticks()
|
||||||
|
#define HZ 18
|
||||||
|
|
||||||
|
#define LPS_PREC 8
|
||||||
|
|
||||||
|
/* Copied from /usr/src/linux/init/main.c */
|
||||||
|
/* with just a few modifications. */
|
||||||
|
void calibrate_delay (void)
|
||||||
|
{
|
||||||
|
int ticks;
|
||||||
|
int loopbit;
|
||||||
|
int lps_precision = LPS_PREC;
|
||||||
|
|
||||||
|
loops_per_sec = (1<<12);
|
||||||
|
loops_per_usec = 1;
|
||||||
|
|
||||||
|
printk("Calibrating delay loop.. ");
|
||||||
|
while (loops_per_sec <<= 1) {
|
||||||
|
/* wait for "start of" clock tick */
|
||||||
|
ticks = jiffies;
|
||||||
|
while (ticks == jiffies)
|
||||||
|
/* nothing */;
|
||||||
|
/* Go .. */
|
||||||
|
ticks = jiffies;
|
||||||
|
__delay(loops_per_sec);
|
||||||
|
ticks = jiffies - ticks;
|
||||||
|
if (ticks)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do a binary approximation to get loops_per_second set to equal one clock
|
||||||
|
(up to lps_precision bits) */
|
||||||
|
loops_per_sec >>= 1;
|
||||||
|
loopbit = loops_per_sec;
|
||||||
|
while ( lps_precision-- && (loopbit >>= 1) ) {
|
||||||
|
loops_per_sec |= loopbit;
|
||||||
|
ticks = jiffies;
|
||||||
|
while (ticks == jiffies);
|
||||||
|
ticks = jiffies;
|
||||||
|
__delay(loops_per_sec);
|
||||||
|
if (jiffies != ticks) /* longer than 1 tick */
|
||||||
|
loops_per_sec &= ~loopbit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finally, adjust loops per second in terms of seconds instead of clocks */
|
||||||
|
loops_per_sec *= HZ;
|
||||||
|
/* Round the value and print it */
|
||||||
|
printk("ok - %d.%d BogoMIPS\n",
|
||||||
|
(loops_per_sec+25000)/500000,
|
||||||
|
((loops_per_sec+25000)/50000) % 10);
|
||||||
|
loops_per_usec = loops_per_sec / 1000000;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
/* Hexdump a number of bytes from memory... */
|
||||||
|
void hd (void *where, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while (n > 0) {
|
||||||
|
printf ("%X ", where);
|
||||||
|
for (i=0;i < ( (n>16)?16:n);i++)
|
||||||
|
printf (" %b", ((char *)where)[i]);
|
||||||
|
printf ("\n\r");
|
||||||
|
n -= 16;
|
||||||
|
where += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INCLUDE_EEPRO100 */
|
227
netboot/fsys_tftp.c
Normal file
227
netboot/fsys_tftp.c
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
#include "../stage2/filesys.h"
|
||||||
|
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "nic.h"
|
||||||
|
|
||||||
|
#include "ip.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
#define BUFSIZE (20*TFTP_DEFAULTSIZE_PACKET)
|
||||||
|
static char buf[BUFSIZE];
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* use GRUB's file system buffer */
|
||||||
|
#define BUFSIZE (32*1024)
|
||||||
|
#define buf ((char *)(FSYS_BUF))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int buf_read = 0, buf_eof = 0;
|
||||||
|
static unsigned long buf_fileoff;
|
||||||
|
|
||||||
|
static int retry;
|
||||||
|
static unsigned short isocket = 2000;
|
||||||
|
static unsigned short osocket;
|
||||||
|
static unsigned short len, block, prevblock;
|
||||||
|
static struct tftp_t *tr;
|
||||||
|
static struct tftp_t tp;
|
||||||
|
static int packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||||
|
|
||||||
|
static int buf_fill(int abort);
|
||||||
|
|
||||||
|
int tftp_mount(void)
|
||||||
|
{
|
||||||
|
if (current_drive != 0x20) /* only mount network drives */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!ip_init())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read "size" bytes from file position "filepos" to "addr" */
|
||||||
|
int tftp_read(char *addr, int size)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (filepos < buf_fileoff)
|
||||||
|
{
|
||||||
|
printf("tftp_read: can't read from filepos=%d, buf_fileoff=%d\n",
|
||||||
|
filepos, buf_fileoff);
|
||||||
|
errnum = ERR_BOOT_FAILURE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (size > 0)
|
||||||
|
{
|
||||||
|
if (filepos < buf_fileoff + buf_read)
|
||||||
|
{
|
||||||
|
/* can copy stuff from buffer */
|
||||||
|
int tocopy = buf_fileoff + buf_read - filepos;
|
||||||
|
if (tocopy > size) tocopy = size;
|
||||||
|
bcopy(buf + (filepos - buf_fileoff), (void*) addr, tocopy);
|
||||||
|
size -= tocopy;
|
||||||
|
addr += tocopy;
|
||||||
|
filepos += tocopy;
|
||||||
|
ret += tocopy;
|
||||||
|
|
||||||
|
if (buf_eof && (filepos + size >= buf_fileoff + buf_read))
|
||||||
|
break; /* end of file */
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ((filepos == buf_fileoff + buf_read) && buf_eof)
|
||||||
|
break; /* end of file */
|
||||||
|
|
||||||
|
if (buf_eof) /* filepos beyond end of file */
|
||||||
|
{
|
||||||
|
errnum = ERR_READ;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move buffer contents forward by 1/2 buffer size */
|
||||||
|
bcopy(buf + BUFSIZE/2, buf, BUFSIZE/2);
|
||||||
|
buf_fileoff += BUFSIZE/2;
|
||||||
|
buf_read -= BUFSIZE/2;
|
||||||
|
|
||||||
|
if (! buf_fill(0)) /* read more data */
|
||||||
|
{
|
||||||
|
errnum = ERR_READ;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tftp_dir(char *dirname)
|
||||||
|
{
|
||||||
|
char name[100], *np;
|
||||||
|
|
||||||
|
if (print_possibilities)
|
||||||
|
{
|
||||||
|
printf(" TFTP doesn't support listing the directory; Sorry!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open the file */
|
||||||
|
np = name;
|
||||||
|
while (dirname && *dirname && !isspace(*dirname))
|
||||||
|
*np++ = *dirname++;
|
||||||
|
*np = 0;
|
||||||
|
|
||||||
|
buf_eof = buf_read = buf_fileoff = 0;
|
||||||
|
|
||||||
|
retry = 0;
|
||||||
|
block = 0;
|
||||||
|
prevblock = 0;
|
||||||
|
packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||||
|
|
||||||
|
/* send tftp read request */
|
||||||
|
tp.opcode = htons(TFTP_RRQ);
|
||||||
|
len = 30 + sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
|
||||||
|
name, 0, 0, 0, TFTP_MAX_PACKET) + 1;
|
||||||
|
|
||||||
|
if (!udp_transmit(arptable[ARP_SERVER].ipaddr, ++isocket, TFTP,
|
||||||
|
len, (char *)&tp))
|
||||||
|
{
|
||||||
|
printf("tftp_dir: can't transmit TFTP read request\n");
|
||||||
|
errnum = ERR_BOOT_FAILURE;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (! buf_fill(0))
|
||||||
|
{
|
||||||
|
printf("tftp_dir: can't read from file\n");
|
||||||
|
errnum = ERR_FILE_NOT_FOUND;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* filemax = 234620; */
|
||||||
|
filemax = 16L*1024*1024; /* XXX 16MB is max filesize */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void tftp_close(void)
|
||||||
|
{
|
||||||
|
buf_read = 0;
|
||||||
|
buf_fill(1); /* abort. */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int buf_fill(int abort)
|
||||||
|
{
|
||||||
|
while (!buf_eof && (buf_read + packetsize <= BUFSIZE))
|
||||||
|
{
|
||||||
|
/* read a packet from the network */
|
||||||
|
if (!await_reply(AWAIT_TFTP, isocket, NULL))
|
||||||
|
{
|
||||||
|
if (ip_abort)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (prevblock == 0 && retry++ < MAX_TFTP_RETRIES)
|
||||||
|
{ /* maybe initial request was lost */
|
||||||
|
rfc951_sleep(retry);
|
||||||
|
if (!udp_transmit(arptable[ARP_SERVER].ipaddr,
|
||||||
|
++isocket, TFTP, len, (char *)&tp))
|
||||||
|
return (0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return 0; /* timeout on other blocks */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we got a packet */
|
||||||
|
|
||||||
|
tr = (struct tftp_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||||
|
|
||||||
|
if (tr->opcode == ntohs(TFTP_ERROR)) /* error? */
|
||||||
|
{
|
||||||
|
printf("TFTP error %d (%s)\r\n",
|
||||||
|
ntohs(tr->u.err.errcode),
|
||||||
|
tr->u.err.errmsg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (tr->opcode == ntohs(TFTP_OACK))
|
||||||
|
{
|
||||||
|
continue; /* ignore */
|
||||||
|
}
|
||||||
|
else if (tr->opcode == ntohs(TFTP_DATA))
|
||||||
|
{
|
||||||
|
retry = MAX_TFTP_RETRIES; /*no more retries! */
|
||||||
|
len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
|
||||||
|
if (len > packetsize) /* shouldn't happen */
|
||||||
|
continue; /* ignore it */
|
||||||
|
block = ntohs(tp.u.ack.block = tr->u.data.block);
|
||||||
|
}
|
||||||
|
else /* neither TFTP_OACK nor TFTP_DATA */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
tp.opcode = abort ? htons(TFTP_ERROR) : htons(TFTP_ACK);
|
||||||
|
osocket = ntohs(tr->udp.src);
|
||||||
|
udp_transmit(arptable[ARP_SERVER].ipaddr, isocket,
|
||||||
|
osocket, TFTP_MIN_PACKET, (char *)&tp); /* ack */
|
||||||
|
|
||||||
|
if (abort)
|
||||||
|
{
|
||||||
|
buf_eof = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block <= prevblock) /* retransmission or OACK */
|
||||||
|
continue; /* don't process */
|
||||||
|
prevblock = block;
|
||||||
|
|
||||||
|
bcopy(tr->u.data.download, buf + buf_read, len);
|
||||||
|
buf_read += len;
|
||||||
|
|
||||||
|
if (len < packetsize) /* End of data */
|
||||||
|
buf_eof = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
18
netboot/if.h
Normal file
18
netboot/if.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
/* Standard interface flags. */
|
||||||
|
#define IFF_UP 0x1 /* interface is up */
|
||||||
|
#define IFF_BROADCAST 0x2 /* broadcast address valid */
|
||||||
|
#define IFF_DEBUG 0x4 /* turn on debugging */
|
||||||
|
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
||||||
|
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
|
||||||
|
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
|
||||||
|
#define IFF_RUNNING 0x40 /* resources allocated */
|
||||||
|
#define IFF_NOARP 0x80 /* no ARP protocol */
|
||||||
|
#define IFF_PROMISC 0x100 /* receive all packets */
|
||||||
|
/* Not supported */
|
||||||
|
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/
|
||||||
|
|
||||||
|
#define IFF_MASTER 0x400 /* master of a load balancer */
|
||||||
|
#define IFF_SLAVE 0x800 /* slave of a load balancer */
|
||||||
|
|
||||||
|
#define IFF_MULTICAST 0x1000 /* Supports multicast */
|
93
netboot/io.h
Normal file
93
netboot/io.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#ifndef _ASM_IO_H
|
||||||
|
#define _ASM_IO_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains parts of Linux's /usr/include/asm/io.h, but
|
||||||
|
* with the argument order reversed for outb, outb_p, outw, outw_p.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
|
||||||
|
|
||||||
|
#define __OUT1(s,x) \
|
||||||
|
extern inline void __out##s(unsigned x value, unsigned short port); \
|
||||||
|
extern inline void __out##s(unsigned x value, unsigned short port) {
|
||||||
|
|
||||||
|
#define __OUT2(s,s1,s2) \
|
||||||
|
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
|
||||||
|
|
||||||
|
#define __OUT(s,s1,x) \
|
||||||
|
__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \
|
||||||
|
__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \
|
||||||
|
__OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
|
||||||
|
__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
|
||||||
|
|
||||||
|
#define __IN1(s) \
|
||||||
|
extern inline RETURN_TYPE __in##s(unsigned short port); \
|
||||||
|
extern inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v;
|
||||||
|
|
||||||
|
#define __IN2(s,s1,s2) \
|
||||||
|
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
|
||||||
|
|
||||||
|
#define __IN(s,s1,i...) \
|
||||||
|
__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
|
||||||
|
__IN1(s##c) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
|
||||||
|
__IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
|
||||||
|
__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
|
||||||
|
|
||||||
|
#define RETURN_TYPE unsigned char
|
||||||
|
/* __IN(b,"b","0" (0)) */
|
||||||
|
__IN(b,"")
|
||||||
|
#undef RETURN_TYPE
|
||||||
|
#define RETURN_TYPE unsigned short
|
||||||
|
/* __IN(w,"w","0" (0)) */
|
||||||
|
__IN(w,"")
|
||||||
|
#undef RETURN_TYPE
|
||||||
|
#define RETURN_TYPE unsigned int
|
||||||
|
__IN(l,"")
|
||||||
|
#undef RETURN_TYPE
|
||||||
|
|
||||||
|
__OUT(b,"b",char)
|
||||||
|
__OUT(w,"w",short)
|
||||||
|
__OUT(l,,int)
|
||||||
|
|
||||||
|
#define outb(port,val) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__outbc((val),(port)) : \
|
||||||
|
__outb((val),(port)))
|
||||||
|
|
||||||
|
#define inb(port) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__inbc(port) : \
|
||||||
|
__inb(port))
|
||||||
|
|
||||||
|
#define outb_p(port,val) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__outbc_p((val),(port)) : \
|
||||||
|
__outb_p((val),(port)))
|
||||||
|
|
||||||
|
#define inb_p(port) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__inbc_p(port) : \
|
||||||
|
__inb_p(port))
|
||||||
|
|
||||||
|
#define outw(port,val) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__outwc((val),(port)) : \
|
||||||
|
__outw((val),(port)))
|
||||||
|
|
||||||
|
#define inw(port) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__inwc(port) : \
|
||||||
|
__inw(port))
|
||||||
|
|
||||||
|
#define outw_p(port,val) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__outwc_p((val),(port)) : \
|
||||||
|
__outw_p((val),(port)))
|
||||||
|
|
||||||
|
#define inw_p(port) \
|
||||||
|
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||||
|
__inwc_p(port) : \
|
||||||
|
__inw_p(port))
|
||||||
|
|
||||||
|
#endif
|
645
netboot/ip.c
Normal file
645
netboot/ip.c
Normal file
|
@ -0,0 +1,645 @@
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "nic.h"
|
||||||
|
|
||||||
|
#include "ip.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct arptable_t arptable[MAX_ARP];
|
||||||
|
int _pending_key;
|
||||||
|
|
||||||
|
static unsigned long netmask;
|
||||||
|
static char rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };
|
||||||
|
static char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
||||||
|
static char *kernel;
|
||||||
|
static char kernel_buf[128];
|
||||||
|
static struct bootpd_t bootp_data;
|
||||||
|
static int vendorext_isvalid;
|
||||||
|
static unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* äEth */
|
||||||
|
static unsigned char *end_of_rfc1533 = NULL;
|
||||||
|
|
||||||
|
int ip_abort = 0;
|
||||||
|
|
||||||
|
static int bootp(void);
|
||||||
|
static void default_netmask(void);
|
||||||
|
static void convert_ipaddr(register char *d, register char *s);
|
||||||
|
static int decode_rfc1533(register unsigned char *p, int block, int len,
|
||||||
|
int eof);
|
||||||
|
|
||||||
|
|
||||||
|
int ip_init(void)
|
||||||
|
{
|
||||||
|
static int bootp_completed = 0,
|
||||||
|
probe_completed = 0;
|
||||||
|
|
||||||
|
if (!probe_completed && !eth_probe())
|
||||||
|
{
|
||||||
|
printf("No ethernet adapter found\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
probe_completed = 1;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if ((!bootp_completed ||
|
||||||
|
!arptable[ARP_CLIENT].ipaddr || !arptable[ARP_SERVER].ipaddr))
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
if (!bootp())
|
||||||
|
{
|
||||||
|
printf("No BOOTP server found\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("My IP 0x%x, Server IP 0x%x, GW IP 0x%x\n",
|
||||||
|
arptable[ARP_CLIENT].ipaddr,
|
||||||
|
arptable[ARP_SERVER].ipaddr,
|
||||||
|
arptable[ARP_GATEWAY].ipaddr);
|
||||||
|
#ifdef CONFIG_FILE_EXT
|
||||||
|
{
|
||||||
|
char *ext = &config_file;
|
||||||
|
|
||||||
|
/* seek to end of config file name */
|
||||||
|
while(*ext)
|
||||||
|
ext++;
|
||||||
|
|
||||||
|
sprintf(ext, ".%d", arptable[ARP_CLIENT].ipaddr & 0xff);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
}
|
||||||
|
bootp_completed = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
UDP_TRANSMIT - Send a UDP datagram
|
||||||
|
**************************************************************************/
|
||||||
|
int udp_transmit(destip, srcsock, destsock, len, buf)
|
||||||
|
unsigned long destip;
|
||||||
|
unsigned int srcsock, destsock;
|
||||||
|
int len;
|
||||||
|
char *buf;
|
||||||
|
{
|
||||||
|
struct iphdr *ip;
|
||||||
|
struct udphdr *udp;
|
||||||
|
struct arprequest arpreq;
|
||||||
|
int arpentry, i;
|
||||||
|
int retry;
|
||||||
|
|
||||||
|
ip = (struct iphdr *)buf;
|
||||||
|
udp = (struct udphdr *)(buf + sizeof(struct iphdr));
|
||||||
|
ip->verhdrlen = 0x45;
|
||||||
|
ip->service = 0;
|
||||||
|
ip->len = htons(len);
|
||||||
|
ip->ident = 0;
|
||||||
|
ip->frags = 0;
|
||||||
|
ip->ttl = 60;
|
||||||
|
ip->protocol = IP_UDP;
|
||||||
|
ip->chksum = 0;
|
||||||
|
convert_ipaddr(ip->src, (char *)&arptable[ARP_CLIENT].ipaddr);
|
||||||
|
convert_ipaddr(ip->dest, (char *)&destip);
|
||||||
|
ip->chksum = ipchksum((unsigned short *)buf, sizeof(struct iphdr));
|
||||||
|
udp->src = htons(srcsock);
|
||||||
|
udp->dest = htons(destsock);
|
||||||
|
udp->len = htons(len - sizeof(struct iphdr));
|
||||||
|
udp->chksum = 0;
|
||||||
|
if (destip == IP_BROADCAST) {
|
||||||
|
eth_transmit(broadcast, IP, len, buf);
|
||||||
|
} else {
|
||||||
|
long h_netmask = ntohl(netmask);
|
||||||
|
/* Check to see if we need gateway */
|
||||||
|
if (((destip & h_netmask) !=
|
||||||
|
(arptable[ARP_CLIENT].ipaddr & h_netmask)) &&
|
||||||
|
arptable[ARP_GATEWAY].ipaddr)
|
||||||
|
destip = arptable[ARP_GATEWAY].ipaddr;
|
||||||
|
for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
|
||||||
|
if (arptable[arpentry].ipaddr == destip) break;
|
||||||
|
if (arpentry == MAX_ARP) {
|
||||||
|
printf("%I is not in my arp table!\r\n", destip);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
for (i = 0; i<ETHER_ADDR_SIZE; i++)
|
||||||
|
if (arptable[arpentry].node[i]) break;
|
||||||
|
if (i == ETHER_ADDR_SIZE) { /* Need to do arp request */
|
||||||
|
arpreq.hwtype = htons(1);
|
||||||
|
arpreq.protocol = htons(IP);
|
||||||
|
arpreq.hwlen = ETHER_ADDR_SIZE;
|
||||||
|
arpreq.protolen = 4;
|
||||||
|
arpreq.opcode = htons(ARP_REQUEST);
|
||||||
|
bcopy(arptable[ARP_CLIENT].node, arpreq.shwaddr,
|
||||||
|
ETHER_ADDR_SIZE);
|
||||||
|
convert_ipaddr(arpreq.sipaddr,
|
||||||
|
(char *)&arptable[ARP_CLIENT].ipaddr);
|
||||||
|
bzero(arpreq.thwaddr, ETHER_ADDR_SIZE);
|
||||||
|
convert_ipaddr(arpreq.tipaddr, (char *)&destip);
|
||||||
|
for (retry = 0; retry < MAX_ARP_RETRIES;
|
||||||
|
rfc951_sleep(++retry)) {
|
||||||
|
eth_transmit(broadcast, ARP, sizeof(arpreq),
|
||||||
|
(char *)&arpreq);
|
||||||
|
if (await_reply(AWAIT_ARP, arpentry,
|
||||||
|
arpreq.tipaddr)) goto xmit;
|
||||||
|
if (ip_abort)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
xmit: eth_transmit(arptable[arpentry].node, IP, len, buf);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
AWAIT_REPLY - Wait until we get a response for our request
|
||||||
|
**************************************************************************/
|
||||||
|
int await_reply(type, ival, ptr)
|
||||||
|
int type, ival;
|
||||||
|
char *ptr;
|
||||||
|
{
|
||||||
|
unsigned long time;
|
||||||
|
struct iphdr *ip;
|
||||||
|
struct udphdr *udp;
|
||||||
|
struct arprequest *arpreply;
|
||||||
|
struct bootp_t *bootpreply;
|
||||||
|
struct rpc_t *rpc;
|
||||||
|
|
||||||
|
int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +
|
||||||
|
sizeof(struct udphdr);
|
||||||
|
|
||||||
|
ip_abort = 0;
|
||||||
|
|
||||||
|
time = currticks() + TIMEOUT;
|
||||||
|
while(time > currticks()) {
|
||||||
|
#if 0
|
||||||
|
if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1);
|
||||||
|
#else
|
||||||
|
if (iskey() && (getchar() == ESC))
|
||||||
|
{
|
||||||
|
ip_abort = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (eth_poll())
|
||||||
|
{ /* We have something! */
|
||||||
|
/* Check for ARP - No IP hdr */
|
||||||
|
if ((nic.packetlen >= ETHER_HDR_SIZE +
|
||||||
|
sizeof(struct arprequest)) &&
|
||||||
|
(((nic.packet[12] << 8) | nic.packet[13]) == ARP))
|
||||||
|
{
|
||||||
|
unsigned long target_ip;
|
||||||
|
|
||||||
|
arpreply = (struct arprequest *)
|
||||||
|
&nic.packet[ETHER_HDR_SIZE];
|
||||||
|
|
||||||
|
if (arpreply->opcode == ntohs(ARP_REQUEST)
|
||||||
|
&& (convert_ipaddr(&target_ip,
|
||||||
|
&arpreply->tipaddr),
|
||||||
|
arptable[ARP_CLIENT].ipaddr == target_ip))
|
||||||
|
{
|
||||||
|
/* request for our ether address -- send a reply */
|
||||||
|
|
||||||
|
unsigned long my_ip_net
|
||||||
|
= *(unsigned long*)(arpreply->tipaddr);
|
||||||
|
|
||||||
|
bcopy(arpreply->shwaddr, arpreply->thwaddr, 10);
|
||||||
|
bcopy(arptable[ARP_CLIENT].node,
|
||||||
|
arpreply->shwaddr, ETHER_ADDR_SIZE);
|
||||||
|
*(unsigned long*)(arpreply->sipaddr) = my_ip_net;
|
||||||
|
arpreply->opcode = htons(ARP_REPLY);
|
||||||
|
eth_transmit(arpreply->thwaddr, ARP,
|
||||||
|
sizeof(struct arprequest),
|
||||||
|
(char *) arpreply);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (type == AWAIT_ARP &&
|
||||||
|
(arpreply->opcode == ntohs(ARP_REPLY)) &&
|
||||||
|
!bcmp(arpreply->sipaddr, ptr, 4)) {
|
||||||
|
bcopy(arpreply->shwaddr,
|
||||||
|
arptable[ival].node,
|
||||||
|
ETHER_ADDR_SIZE);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Anything else has IP header */
|
||||||
|
if ((nic.packetlen < protohdrlen) ||
|
||||||
|
(((nic.packet[12] << 8) | nic.packet[13]) != IP)) continue;
|
||||||
|
ip = (struct iphdr *)&nic.packet[ETHER_HDR_SIZE];
|
||||||
|
if ((ip->verhdrlen != 0x45) ||
|
||||||
|
ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
|
||||||
|
(ip->protocol != IP_UDP)) continue;
|
||||||
|
udp = (struct udphdr *)&nic.packet[ETHER_HDR_SIZE +
|
||||||
|
sizeof(struct iphdr)];
|
||||||
|
|
||||||
|
/* BOOTP ? */
|
||||||
|
bootpreply = (struct bootp_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||||
|
if ((type == AWAIT_BOOTP) &&
|
||||||
|
(nic.packetlen >= (ETHER_HDR_SIZE +
|
||||||
|
sizeof(struct bootp_t))) &&
|
||||||
|
(ntohs(udp->dest) == BOOTP_CLIENT) &&
|
||||||
|
(bootpreply->bp_op == BOOTP_REPLY)) {
|
||||||
|
convert_ipaddr((char *)&arptable[ARP_CLIENT].ipaddr,
|
||||||
|
bootpreply->bp_yiaddr);
|
||||||
|
default_netmask();
|
||||||
|
convert_ipaddr((char *)&arptable[ARP_SERVER].ipaddr,
|
||||||
|
bootpreply->bp_siaddr);
|
||||||
|
bzero(arptable[ARP_SERVER].node,
|
||||||
|
ETHER_ADDR_SIZE); /* Kill arp */
|
||||||
|
convert_ipaddr((char *)&arptable[ARP_GATEWAY].ipaddr,
|
||||||
|
bootpreply->bp_giaddr);
|
||||||
|
bzero(arptable[ARP_GATEWAY].node,
|
||||||
|
ETHER_ADDR_SIZE); /* Kill arp */
|
||||||
|
if (bootpreply->bp_file[0]) {
|
||||||
|
bcopy(bootpreply->bp_file,
|
||||||
|
kernel_buf, 128);
|
||||||
|
kernel = kernel_buf;
|
||||||
|
}
|
||||||
|
bcopy((char *)bootpreply,
|
||||||
|
(char *)&bootp_data,
|
||||||
|
sizeof(struct bootp_t));
|
||||||
|
decode_rfc1533(bootp_data.bootp_reply.bp_vend,
|
||||||
|
0, BOOTP_VENDOR_LEN, 1);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TFTP ? */
|
||||||
|
if ((type == AWAIT_TFTP) &&
|
||||||
|
(ntohs(udp->dest) == ival)) return(1);
|
||||||
|
|
||||||
|
/* RPC */
|
||||||
|
rpc = (struct rpc_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||||
|
#ifdef NFS_BOOT
|
||||||
|
if ((type == AWAIT_RPC) &&
|
||||||
|
(ntohs(udp->dest) == RPC_SOCKET) &&
|
||||||
|
(ntohl(rpc->u.reply.id) == ival) &&
|
||||||
|
(ntohl(rpc->u.reply.type) == MSG_REPLY)) {
|
||||||
|
rpc_id++;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
#endif /* NFS_BOOT */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
IPCHKSUM - Checksum IP Header
|
||||||
|
**************************************************************************/
|
||||||
|
unsigned short ipchksum(ip, len)
|
||||||
|
register unsigned short *ip;
|
||||||
|
register int len;
|
||||||
|
{
|
||||||
|
unsigned long sum = 0;
|
||||||
|
len >>= 1;
|
||||||
|
while (len--) {
|
||||||
|
sum += *(ip++);
|
||||||
|
if (sum > 0xFFFF)
|
||||||
|
sum -= 0xFFFF;
|
||||||
|
}
|
||||||
|
return((~sum) & 0x0000FFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
TFTP - Download extended BOOTP data, configuration file or kernel image
|
||||||
|
**************************************************************************/
|
||||||
|
int tftp(name,fnc)
|
||||||
|
char *name;
|
||||||
|
int (*fnc)(unsigned char *, int, int, int);
|
||||||
|
{
|
||||||
|
int retry = 0;
|
||||||
|
static unsigned short isocket = 2000;
|
||||||
|
unsigned short osocket;
|
||||||
|
unsigned short len, block = 0, prevblock = 0;
|
||||||
|
struct tftp_t *tr;
|
||||||
|
struct tftp_t tp;
|
||||||
|
int rc;
|
||||||
|
int packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||||
|
|
||||||
|
tp.opcode = htons(TFTP_RRQ);
|
||||||
|
len = 30 + sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
|
||||||
|
name, 0, 0, 0, TFTP_MAX_PACKET) + 1;
|
||||||
|
if (!udp_transmit(arptable[ARP_SERVER].ipaddr, ++isocket, TFTP,
|
||||||
|
len, (char *)&tp))
|
||||||
|
return (0);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (!await_reply(AWAIT_TFTP, isocket, NULL))
|
||||||
|
{
|
||||||
|
if (ip_abort)
|
||||||
|
return 0;
|
||||||
|
if (prevblock == 0 && retry++ < MAX_TFTP_RETRIES)
|
||||||
|
{ /* maybe initial request was lost */
|
||||||
|
rfc951_sleep(retry);
|
||||||
|
if (!udp_transmit(arptable[ARP_SERVER].ipaddr,
|
||||||
|
++isocket, TFTP, len, (char *)&tp))
|
||||||
|
return (0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break; /* timeout on other blocks */
|
||||||
|
}
|
||||||
|
tr = (struct tftp_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||||
|
if (tr->opcode == ntohs(TFTP_ERROR))
|
||||||
|
{
|
||||||
|
printf("TFTP error %d (%s)\r\n",
|
||||||
|
ntohs(tr->u.err.errcode),
|
||||||
|
tr->u.err.errmsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tr->opcode == ntohs(TFTP_OACK)) {
|
||||||
|
#if 0
|
||||||
|
char *p = tr->u.oack.data, *e;
|
||||||
|
|
||||||
|
retry = MAX_TFTP_RETRIES;/*no more retries! */
|
||||||
|
if (prevblock) /* shouldn't happen */
|
||||||
|
continue; /* ignore it */
|
||||||
|
len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 2;
|
||||||
|
if (len > TFTP_MAX_PACKET)
|
||||||
|
goto noak;
|
||||||
|
e = p + len;
|
||||||
|
while (*p != '\000' && p < e) {
|
||||||
|
if (!strcasecmp("blksize", p)) {
|
||||||
|
p += 8;
|
||||||
|
if ((packetsize = getdec(&p)) <
|
||||||
|
TFTP_DEFAULTSIZE_PACKET)
|
||||||
|
goto noak;
|
||||||
|
while (p < e && *p) p++;
|
||||||
|
if (p < e)
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
noak:
|
||||||
|
tp.opcode = htons(TFTP_ERROR);
|
||||||
|
tp.u.err.errcode = 8;
|
||||||
|
len = 30 + sprintf((char *)tp.u.err.errmsg,
|
||||||
|
"RFC1782 error")+ 1;
|
||||||
|
udp_transmit(arptable[ARP_SERVER].
|
||||||
|
ipaddr, isocket,
|
||||||
|
ntohs(tr->udp.src),
|
||||||
|
len, (char *)&tp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p > e)
|
||||||
|
goto noak;
|
||||||
|
block = tp.u.ack.block = 0; /* this ensures, that */
|
||||||
|
/* the packet does not get */
|
||||||
|
/* processed as data! */
|
||||||
|
#else
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (tr->opcode == ntohs(TFTP_DATA)) {
|
||||||
|
retry = MAX_TFTP_RETRIES;/*no more retries! */
|
||||||
|
len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
|
||||||
|
if (len > packetsize) /* shouldn't happen */
|
||||||
|
continue; /* ignore it */
|
||||||
|
block = ntohs(tp.u.ack.block = tr->u.data.block); }
|
||||||
|
else /* neither TFTP_OACK nor TFTP_DATA */
|
||||||
|
break;
|
||||||
|
|
||||||
|
tp.opcode = htons(TFTP_ACK);
|
||||||
|
osocket = ntohs(tr->udp.src);
|
||||||
|
udp_transmit(arptable[ARP_SERVER].ipaddr, isocket,
|
||||||
|
osocket, TFTP_MIN_PACKET, (char *)&tp); /* ack */
|
||||||
|
if (block <= prevblock) /* retransmission or OACK */
|
||||||
|
continue; /* don't process */
|
||||||
|
prevblock = block;
|
||||||
|
if ((rc = fnc(tr->u.data.download,
|
||||||
|
block, len, len < packetsize)) >= 0)
|
||||||
|
return(rc);
|
||||||
|
if (len < packetsize) /* End of data */
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
CONVERT_IPADDR - Convert IP address from net to machine order
|
||||||
|
**************************************************************************/
|
||||||
|
static void convert_ipaddr(d, s)
|
||||||
|
register char *d,*s;
|
||||||
|
{
|
||||||
|
d[3] = s[0];
|
||||||
|
d[2] = s[1];
|
||||||
|
d[1] = s[2];
|
||||||
|
d[0] = s[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
RFC951_SLEEP - sleep for expotentially longer times
|
||||||
|
**************************************************************************/
|
||||||
|
void rfc951_sleep(exp)
|
||||||
|
int exp;
|
||||||
|
{
|
||||||
|
static long seed = 0;
|
||||||
|
long q,z,tmo;
|
||||||
|
|
||||||
|
if (!seed) /* Initialize linear congruential generator */
|
||||||
|
seed = currticks() + *(long *)&arptable[ARP_CLIENT].node
|
||||||
|
+ ((short *)arptable[ARP_CLIENT].node)[2];
|
||||||
|
/* simplified version of the LCG given in Bruce Scheier's
|
||||||
|
"Applied Cryptography" */
|
||||||
|
q = seed/53668;
|
||||||
|
if ((seed = 40014*(seed-53668*q) - 12211*q) < 0) seed += 2147483563l;
|
||||||
|
/* compute mask */
|
||||||
|
for (tmo = 63; tmo <= 60*18 && --exp > 0; tmo = 2*tmo+1);
|
||||||
|
/* sleep */
|
||||||
|
printf("<sleep>\r\n");
|
||||||
|
for (tmo = (tmo&seed)+currticks(); currticks() < tmo; )
|
||||||
|
/* if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1) */ ;
|
||||||
|
eth_reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
TWIDDLE
|
||||||
|
**************************************************************************/
|
||||||
|
void twiddle()
|
||||||
|
{
|
||||||
|
static unsigned long lastticks = 0;
|
||||||
|
static int count=0;
|
||||||
|
static char tiddles[]="-\\|/";
|
||||||
|
unsigned long ticks;
|
||||||
|
if ((ticks = currticks()) < lastticks)
|
||||||
|
return;
|
||||||
|
lastticks = ticks+1;
|
||||||
|
putchar(tiddles[(count++)&3]);
|
||||||
|
putchar('\b');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
BOOTP - Get my IP address and load information
|
||||||
|
**************************************************************************/
|
||||||
|
static int bootp()
|
||||||
|
{
|
||||||
|
int retry;
|
||||||
|
struct bootp_t bp;
|
||||||
|
unsigned long starttime;
|
||||||
|
#ifdef T509HACK
|
||||||
|
int flag;
|
||||||
|
|
||||||
|
flag = 1;
|
||||||
|
#endif
|
||||||
|
bzero(&bp, sizeof(struct bootp_t));
|
||||||
|
bp.bp_op = BOOTP_REQUEST;
|
||||||
|
bp.bp_htype = 1;
|
||||||
|
bp.bp_hlen = ETHER_ADDR_SIZE;
|
||||||
|
bp.bp_xid = starttime = currticks();
|
||||||
|
bcopy(arptable[ARP_CLIENT].node, bp.bp_hwaddr, ETHER_ADDR_SIZE);
|
||||||
|
bcopy(rfc1533_cookie, bp.bp_vend, 5); /* request RFC-style options */
|
||||||
|
|
||||||
|
for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
|
||||||
|
udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
|
||||||
|
sizeof(struct bootp_t), (char *)&bp);
|
||||||
|
#ifdef T509HACK
|
||||||
|
if (flag) {
|
||||||
|
flag--;
|
||||||
|
} else {
|
||||||
|
if (await_reply(AWAIT_BOOTP, 0, NULL))
|
||||||
|
return(1);
|
||||||
|
if (ip_abort) /* hohmuth */
|
||||||
|
return 0;
|
||||||
|
rfc951_sleep(++retry);
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (await_reply(AWAIT_BOOTP, 0, NULL))
|
||||||
|
return(1);
|
||||||
|
if (ip_abort) /* hohmuth */
|
||||||
|
return 0;
|
||||||
|
rfc951_sleep(++retry);
|
||||||
|
#endif
|
||||||
|
bp.bp_secs = htons((currticks()-starttime)/20);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
DEFAULT_NETMASK - Set a default netmask for IP address
|
||||||
|
**************************************************************************/
|
||||||
|
static void default_netmask()
|
||||||
|
{
|
||||||
|
int net = arptable[ARP_CLIENT].ipaddr >> 24;
|
||||||
|
if (net <= 127)
|
||||||
|
netmask = htonl(0xff000000);
|
||||||
|
else if (net < 192)
|
||||||
|
netmask = htonl(0xffff0000);
|
||||||
|
else
|
||||||
|
netmask = htonl(0xffffff00);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
DECODE_RFC1533 - Decodes RFC1533 header
|
||||||
|
**************************************************************************/
|
||||||
|
static int decode_rfc1533(p, block, len, eof)
|
||||||
|
register unsigned char *p;
|
||||||
|
int block, len, eof;
|
||||||
|
{
|
||||||
|
static unsigned char *extdata = NULL, *extend = NULL;
|
||||||
|
unsigned char *extpath = NULL;
|
||||||
|
unsigned char *end, *q;
|
||||||
|
|
||||||
|
if (block == 0) {
|
||||||
|
#ifdef IMAGE_MENU
|
||||||
|
bzero(imagelist, sizeof(imagelist));
|
||||||
|
menudefault = useimagemenu = 0;
|
||||||
|
menutmo = -1;
|
||||||
|
#endif
|
||||||
|
#ifdef MOTD
|
||||||
|
bzero(motd, sizeof(motd));
|
||||||
|
#endif
|
||||||
|
end_of_rfc1533 = NULL;
|
||||||
|
vendorext_isvalid = 0;
|
||||||
|
if (bcmp(p, rfc1533_cookie, 4))
|
||||||
|
return(0); /* no RFC 1533 header found */
|
||||||
|
p += 4;
|
||||||
|
end = p + len; }
|
||||||
|
else {
|
||||||
|
if (block == 1) {
|
||||||
|
if (bcmp(p, rfc1533_cookie, 4))
|
||||||
|
return(0); /* no RFC 1533 header found */
|
||||||
|
p += 4;
|
||||||
|
len -= 4; }
|
||||||
|
if (extend + len <= (unsigned char *)(&bootp_data+1)) {
|
||||||
|
bcopy(p, extend, len);
|
||||||
|
extend += len;
|
||||||
|
} else {
|
||||||
|
printf("Overflow in vendor data buffer! Aborting...\r\n");
|
||||||
|
*extdata = RFC1533_END;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
p = extdata; end = extend;
|
||||||
|
}
|
||||||
|
if (eof) {
|
||||||
|
while(p < end) {
|
||||||
|
unsigned char c = *p;
|
||||||
|
if (c == RFC1533_PAD) {p++; continue;}
|
||||||
|
else if (c == RFC1533_END) {
|
||||||
|
end_of_rfc1533 = end = p; continue; }
|
||||||
|
else if (c == RFC1533_NETMASK) {bcopy(p+2,&netmask,4);}
|
||||||
|
#ifdef NFS_BOOT
|
||||||
|
else if (c == RFC1533_HOSTNAME) {
|
||||||
|
if (TAG_LEN(p) < (MNAMELEN&~3)-1) {
|
||||||
|
bcopy(p+2,&nfsdiskless.my_hostnam,TAG_LEN(p));
|
||||||
|
nfsdiskless.my_hostnam[TAG_LEN(p)] = '\000';
|
||||||
|
hostnamelen = (TAG_LEN(p)+3)&~3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (c == RFC1533_GATEWAY) {
|
||||||
|
/* This is a little simplistic, but it will
|
||||||
|
usually be sufficient; look into the gate-
|
||||||
|
way list, only if there has been no BOOTP
|
||||||
|
gateway. Take only the first entry */
|
||||||
|
if (TAG_LEN(p) >= 4 &&
|
||||||
|
arptable[ARP_GATEWAY].ipaddr == 0)
|
||||||
|
convert_ipaddr((char *)&arptable[ARP_GATEWAY].ipaddr,
|
||||||
|
p+2);
|
||||||
|
}
|
||||||
|
else if (c == RFC1533_EXTENSIONPATH)
|
||||||
|
extpath = p;
|
||||||
|
else if (c == RFC1533_VENDOR_MAGIC &&
|
||||||
|
TAG_LEN(p) >= 6 &&
|
||||||
|
!bcmp(p+2,vendorext_magic,4) &&
|
||||||
|
p[6] == RFC1533_VENDOR_MAJOR)
|
||||||
|
vendorext_isvalid++;
|
||||||
|
#ifdef IMAGE_MENU
|
||||||
|
else if (c == RFC1533_VENDOR_MNUOPTS) {
|
||||||
|
parse_menuopts(p+2, TAG_LEN(p));
|
||||||
|
}
|
||||||
|
else if (c >= RFC1533_VENDOR_IMG &&
|
||||||
|
c<RFC1533_VENDOR_IMG+RFC1533_VENDOR_NUMOFIMG){
|
||||||
|
imagelist[c - RFC1533_VENDOR_IMG] = p;
|
||||||
|
useimagemenu++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef MOTD
|
||||||
|
else if (c >= RFC1533_VENDOR_MOTD &&
|
||||||
|
c < RFC1533_VENDOR_MOTD +
|
||||||
|
RFC1533_VENDOR_NUMOFMOTD)
|
||||||
|
motd[c - RFC1533_VENDOR_MOTD] = p;
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
/* printf("Unknown RFC1533-tag ");
|
||||||
|
for(q=p;q<p+2+TAG_LEN(p);q++)
|
||||||
|
printf("%x ",*q);
|
||||||
|
printf("\n\r"); */ }
|
||||||
|
p += TAG_LEN(p) + 2;
|
||||||
|
}
|
||||||
|
extdata = extend = end;
|
||||||
|
if (block == 0 && extpath != NULL) {
|
||||||
|
char fname[64];
|
||||||
|
bcopy(extpath+2,fname,TAG_LEN(extpath));
|
||||||
|
fname[(int)TAG_LEN(extpath)] = '\000';
|
||||||
|
printf("Loading BOOTP-extension file: %s\r\n",fname);
|
||||||
|
tftp(fname,decode_rfc1533);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(-1); /* proceed with next block */
|
||||||
|
}
|
15
netboot/ip.h
Normal file
15
netboot/ip.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
int ip_init(void);
|
||||||
|
int tftp(char *name, int (*fnc)(unsigned char *, int, int, int));
|
||||||
|
|
||||||
|
extern int ip_abort;
|
||||||
|
|
||||||
|
extern int udp_transmit (unsigned long destip, unsigned int srcsock,
|
||||||
|
unsigned int destsock, int len, char *buf);
|
||||||
|
|
||||||
|
extern int await_reply (int type, int ival, char *ptr);
|
||||||
|
|
||||||
|
extern unsigned short ipchksum (unsigned short *, int len);
|
||||||
|
|
||||||
|
extern void rfc951_sleep (int);
|
||||||
|
|
||||||
|
extern void twiddle (void);
|
426
netboot/lance.c
Normal file
426
netboot/lance.c
Normal file
|
@ -0,0 +1,426 @@
|
||||||
|
/**************************************************************************
|
||||||
|
Etherboot - BOOTP/TFTP Bootstrap Program
|
||||||
|
LANCE NIC driver for Etherboot
|
||||||
|
Large portions borrowed from the Linux LANCE driver by Donald Becker
|
||||||
|
Ken Yap, July 1997
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef INCLUDE_NE2100
|
||||||
|
|
||||||
|
/* to get some global routines like printf */
|
||||||
|
#include "netboot.h"
|
||||||
|
/* to get the interface to the body of the program */
|
||||||
|
#include "nic.h"
|
||||||
|
|
||||||
|
/* Offsets from base I/O address */
|
||||||
|
#define LANCE_DATA 0x10
|
||||||
|
#define LANCE_ADDR 0x12
|
||||||
|
#define LANCE_RESET 0x14
|
||||||
|
#define LANCE_BUS_IF 0x16
|
||||||
|
#define LANCE_TOTAL_SIZE 0x18
|
||||||
|
|
||||||
|
struct lance_init_block
|
||||||
|
{
|
||||||
|
unsigned short mode;
|
||||||
|
unsigned char phys_addr[6];
|
||||||
|
unsigned long filter[2];
|
||||||
|
Address rx_ring;
|
||||||
|
Address tx_ring;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lance_rx_head
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
Address base;
|
||||||
|
char addr[4];
|
||||||
|
} u;
|
||||||
|
short buf_length; /* 2s complement */
|
||||||
|
short msg_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lance_tx_head
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
Address base;
|
||||||
|
char addr[4];
|
||||||
|
} u;
|
||||||
|
short buf_length; /* 2s complement */
|
||||||
|
short misc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lance_interface
|
||||||
|
{
|
||||||
|
struct lance_init_block init_block;
|
||||||
|
struct lance_rx_head rx_ring;
|
||||||
|
struct lance_tx_head tx_ring;
|
||||||
|
unsigned char rbuf[ETH_MAX_PACKET];
|
||||||
|
unsigned char tbuf[ETH_MAX_PACKET];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LANCE_MUST_PAD 0x00000001
|
||||||
|
#define LANCE_ENABLE_AUTOSELECT 0x00000002
|
||||||
|
#define LANCE_MUST_REINIT_RING 0x00000004
|
||||||
|
#define LANCE_MUST_UNRESET 0x00000008
|
||||||
|
#define LANCE_HAS_MISSED_FRAME 0x00000010
|
||||||
|
|
||||||
|
/* A mapping from the chip ID number to the part number and features.
|
||||||
|
These are from the datasheets -- in real life the '970 version
|
||||||
|
reportedly has the same ID as the '965. */
|
||||||
|
static struct lance_chip_type
|
||||||
|
{
|
||||||
|
int id_number;
|
||||||
|
char *name;
|
||||||
|
int flags;
|
||||||
|
} chip_table[] = {
|
||||||
|
{0x0000, "LANCE 7990", /* Ancient lance chip. */
|
||||||
|
LANCE_MUST_PAD + LANCE_MUST_UNRESET},
|
||||||
|
{0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
|
||||||
|
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
|
||||||
|
LANCE_HAS_MISSED_FRAME},
|
||||||
|
{0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
|
||||||
|
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
|
||||||
|
LANCE_HAS_MISSED_FRAME},
|
||||||
|
{0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
|
||||||
|
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
|
||||||
|
LANCE_HAS_MISSED_FRAME},
|
||||||
|
/* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
|
||||||
|
it the PCnet32. */
|
||||||
|
{0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
|
||||||
|
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
|
||||||
|
LANCE_HAS_MISSED_FRAME},
|
||||||
|
{0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
|
||||||
|
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
|
||||||
|
LANCE_HAS_MISSED_FRAME},
|
||||||
|
{0x0, "PCnet (unknown)",
|
||||||
|
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
|
||||||
|
LANCE_HAS_MISSED_FRAME},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Define a macro for converting program addresses to real addresses */
|
||||||
|
/* Linux already defines it in asm/io.h */
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
#define virt_to_bus(x) (((Address)x)+RELOC)
|
||||||
|
#endif /* NETBOOT16 */
|
||||||
|
|
||||||
|
static int chip_version;
|
||||||
|
static unsigned short ioaddr;
|
||||||
|
static int dma;
|
||||||
|
static struct lance_interface *lp;
|
||||||
|
/* additional 8 bytes for 8-byte alignment space */
|
||||||
|
static char lance[sizeof(struct lance_interface)+8];
|
||||||
|
|
||||||
|
#if defined(INCLUDE_NE2100)
|
||||||
|
#define lance_probe ne2100_probe
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DMA defines and helper routines */
|
||||||
|
|
||||||
|
/* DMA controller registers */
|
||||||
|
#define DMA1_CMD_REG 0x08 /* command register (w) */
|
||||||
|
#define DMA1_STAT_REG 0x08 /* status register (r) */
|
||||||
|
#define DMA1_REQ_REG 0x09 /* request register (w) */
|
||||||
|
#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
|
||||||
|
#define DMA1_MODE_REG 0x0B /* mode register (w) */
|
||||||
|
#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
|
||||||
|
#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
|
||||||
|
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
|
||||||
|
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
|
||||||
|
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
|
||||||
|
|
||||||
|
#define DMA2_CMD_REG 0xD0 /* command register (w) */
|
||||||
|
#define DMA2_STAT_REG 0xD0 /* status register (r) */
|
||||||
|
#define DMA2_REQ_REG 0xD2 /* request register (w) */
|
||||||
|
#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
|
||||||
|
#define DMA2_MODE_REG 0xD6 /* mode register (w) */
|
||||||
|
#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
|
||||||
|
#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
|
||||||
|
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
|
||||||
|
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
|
||||||
|
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
|
||||||
|
|
||||||
|
|
||||||
|
#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
|
||||||
|
#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
|
||||||
|
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
|
||||||
|
|
||||||
|
/* enable/disable a specific DMA channel */
|
||||||
|
static void enable_dma(unsigned int dmanr)
|
||||||
|
{
|
||||||
|
if (dmanr <= 3)
|
||||||
|
outb_p(DMA1_MASK_REG, dmanr);
|
||||||
|
else
|
||||||
|
outb_p(DMA2_MASK_REG, dmanr & 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disable_dma(unsigned int dmanr)
|
||||||
|
{
|
||||||
|
if (dmanr <= 3)
|
||||||
|
outb_p(DMA1_MASK_REG, dmanr | 4);
|
||||||
|
else
|
||||||
|
outb_p(DMA2_MASK_REG, (dmanr & 3) | 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set mode (above) for a specific DMA channel */
|
||||||
|
static void set_dma_mode(unsigned int dmanr, char mode)
|
||||||
|
{
|
||||||
|
if (dmanr <= 3)
|
||||||
|
outb_p(DMA1_MODE_REG, mode | dmanr);
|
||||||
|
else
|
||||||
|
outb_p(DMA2_MODE_REG, mode | (dmanr&3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
RESET - Reset adapter
|
||||||
|
***************************************************************************/
|
||||||
|
static void lance_reset(struct nic *nic)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Address l;
|
||||||
|
|
||||||
|
/* Reset the LANCE */
|
||||||
|
(void)inw(ioaddr+LANCE_RESET);
|
||||||
|
/* Un-Reset the LANCE, needed only for the NE2100 */
|
||||||
|
if (chip_table[chip_version].flags & LANCE_MUST_UNRESET)
|
||||||
|
outw(ioaddr+LANCE_RESET, 0);
|
||||||
|
if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT)
|
||||||
|
{
|
||||||
|
/* This is 79C960 specific; Turn on auto-select of media
|
||||||
|
(AUI, BNC). */
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x2);
|
||||||
|
outw(ioaddr+LANCE_BUS_IF, 0x2);
|
||||||
|
}
|
||||||
|
/* Re-initialise the LANCE, and start it when done. */
|
||||||
|
/* Set station address */
|
||||||
|
for (i = 0; i < ETHER_ADDR_SIZE; ++i)
|
||||||
|
lp->init_block.phys_addr[i] = nic->node_addr[i];
|
||||||
|
/* Preset the receive ring header */
|
||||||
|
lp->rx_ring.buf_length = -ETH_MAX_PACKET;
|
||||||
|
/* OWN */
|
||||||
|
lp->rx_ring.u.base = virt_to_bus(lp->rbuf) & 0xffffff;
|
||||||
|
/* we set the top byte as the very last thing */
|
||||||
|
lp->rx_ring.u.addr[3] = 0x80;
|
||||||
|
lp->init_block.mode = 0x0; /* enable Rx and Tx */
|
||||||
|
l = (Address)virt_to_bus(&lp->init_block);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x1);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, (short)l);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x2);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, (short)(l >> 16));
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x4);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x915);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x4); /* stop */
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x1); /* init */
|
||||||
|
for (i = 100; i > 0; --i)
|
||||||
|
if (inw(ioaddr+LANCE_DATA) & 0x100)
|
||||||
|
break;
|
||||||
|
/* Apparently clearing the InitDone bit here triggers a bug
|
||||||
|
in the '974. (Mark Stockton) */
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x2); /* start */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
POLL - Wait for a frame
|
||||||
|
***************************************************************************/
|
||||||
|
static int lance_poll(struct nic *nic)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = lp->rx_ring.u.base >> 24;
|
||||||
|
if (status & 0x80)
|
||||||
|
return (0);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("LANCE packet received rx_ring.u.base %X mcnt %x csr0 %x\r\n",
|
||||||
|
lp->rx_ring.u.base, lp->rx_ring.msg_length,
|
||||||
|
inw(ioaddr+LANCE_DATA));
|
||||||
|
#endif
|
||||||
|
if (status == 0x3)
|
||||||
|
bcopy(lp->rbuf, nic->packet, nic->packetlen = lp->rx_ring.msg_length);
|
||||||
|
/* Andrew Boyd of QNX reports that some revs of the 79C765
|
||||||
|
clear the buffer length */
|
||||||
|
lp->rx_ring.buf_length = -ETH_MAX_PACKET;
|
||||||
|
lp->rx_ring.u.addr[3] |= 0x80; /* prime for next receive */
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x500); /* clear receive + InitDone */
|
||||||
|
return (status == 0x3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
TRANSMIT - Transmit a frame
|
||||||
|
***************************************************************************/
|
||||||
|
static void lance_transmit(
|
||||||
|
struct nic *nic,
|
||||||
|
char *d, /* Destination */
|
||||||
|
unsigned int t, /* Type */
|
||||||
|
unsigned int s, /* size */
|
||||||
|
char *p) /* Packet */
|
||||||
|
{
|
||||||
|
unsigned long time;
|
||||||
|
|
||||||
|
/* copy the packet to ring buffer */
|
||||||
|
bcopy(d, lp->tbuf, ETHER_ADDR_SIZE); /* dst */
|
||||||
|
bcopy(nic->node_addr, &lp->tbuf[ETHER_ADDR_SIZE], ETHER_ADDR_SIZE); /* src */
|
||||||
|
lp->tbuf[ETHER_ADDR_SIZE+ETHER_ADDR_SIZE] = t >> 8; /* type */
|
||||||
|
lp->tbuf[ETHER_ADDR_SIZE+ETHER_ADDR_SIZE+1] = t; /* type */
|
||||||
|
bcopy(p, &lp->tbuf[ETHER_HDR_SIZE], s);
|
||||||
|
s += ETHER_HDR_SIZE;
|
||||||
|
if (chip_table[chip_version].flags & LANCE_MUST_PAD)
|
||||||
|
while (s < ETH_MIN_PACKET) /* pad to min length */
|
||||||
|
lp->tbuf[s++] = 0;
|
||||||
|
lp->tx_ring.buf_length = -s;
|
||||||
|
lp->tx_ring.misc = 0x0;
|
||||||
|
/* OWN, STP, ENP */
|
||||||
|
lp->tx_ring.u.base = virt_to_bus(lp->tbuf) & 0xffffff;
|
||||||
|
/* we set the top byte as the very last thing */
|
||||||
|
lp->tx_ring.u.addr[3] = 0x83;
|
||||||
|
/* Trigger an immediate send poll */
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x48);
|
||||||
|
/* wait for transmit complete */
|
||||||
|
time = currticks() + 18; /* wait one second */
|
||||||
|
while (currticks() < time && (lp->tx_ring.u.base & 0x80000000) != 0)
|
||||||
|
;
|
||||||
|
if ((lp->tx_ring.u.base & 0x80000000) != 0)
|
||||||
|
printf("LANCE timed out on transmit\r\n");
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x200); /* clear transmit + InitDone */
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("tx_ring.u.base %X tx_ring.buf_length %x tx_ring.misc %x csr0 %x\r\n",
|
||||||
|
lp->tx_ring.u.base, lp->tx_ring.buf_length, lp->tx_ring.misc,
|
||||||
|
inw(ioaddr+LANCE_DATA));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lance_disable(struct nic *nic)
|
||||||
|
{
|
||||||
|
disable_dma(dma);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lance_probe1(struct nic *nic)
|
||||||
|
{
|
||||||
|
int reset_val, lance_version, i;
|
||||||
|
Address l;
|
||||||
|
short dma_channels;
|
||||||
|
static char dmas[] = { 5, 6, 7, 3 };
|
||||||
|
|
||||||
|
reset_val = inw(ioaddr+LANCE_RESET);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x0); /* Switch to window 0 */
|
||||||
|
if (inw(ioaddr+LANCE_DATA) != 0x4)
|
||||||
|
return (-1);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 88); /* Get the version of the chip */
|
||||||
|
if (inw(ioaddr+LANCE_ADDR) != 88)
|
||||||
|
lance_version = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chip_version = inw(ioaddr+LANCE_DATA);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 89);
|
||||||
|
chip_version |= inw(ioaddr+LANCE_DATA) << 16;
|
||||||
|
if ((chip_version & 0xfff) != 0x3)
|
||||||
|
return (-1);
|
||||||
|
chip_version = (chip_version >> 12) & 0xffff;
|
||||||
|
for (lance_version = 1; chip_table[lance_version].id_number != 0; ++lance_version)
|
||||||
|
if (chip_table[lance_version].id_number == chip_version)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* make sure data structure is 8-byte aligned */
|
||||||
|
l = ((Address)lance + 7) & ~7;
|
||||||
|
lp = (struct lance_interface *)l;
|
||||||
|
lp->init_block.mode = 0x3; /* disable Rx and Tx */
|
||||||
|
lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
|
||||||
|
/* top bits are zero, we have only one buffer each for Rx and Tx */
|
||||||
|
lp->init_block.rx_ring = virt_to_bus(&lp->rx_ring) & 0xffffff;
|
||||||
|
lp->init_block.tx_ring = virt_to_bus(&lp->tx_ring) & 0xffffff;
|
||||||
|
l = virt_to_bus(&lp->init_block);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x1);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, (unsigned short)l);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x2);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, (unsigned short)(l >> 16));
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x4);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x915);
|
||||||
|
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||||
|
(void)inw(ioaddr+LANCE_ADDR);
|
||||||
|
/* now probe for DMA channel */
|
||||||
|
dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0xf) |
|
||||||
|
(inb(DMA2_STAT_REG) & 0xf0);
|
||||||
|
/* need to fix when PCI provides DMA info */
|
||||||
|
for (i = 0; i < (sizeof(dmas)/sizeof(dmas[0])); ++i)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
dma = dmas[i];
|
||||||
|
/* Don't enable a permanently busy DMA channel,
|
||||||
|
or the machine will hang */
|
||||||
|
if (dma_channels & (1 << dma))
|
||||||
|
continue;
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x7f04); /* clear memory error bits */
|
||||||
|
set_dma_mode(dma, DMA_MODE_CASCADE);
|
||||||
|
enable_dma(dma);
|
||||||
|
outw(ioaddr+LANCE_DATA, 0x1); /* init */
|
||||||
|
for (j = 100; j > 0; --j)
|
||||||
|
if (inw(ioaddr+LANCE_DATA) & 0x900)
|
||||||
|
break;
|
||||||
|
if (inw(ioaddr+LANCE_DATA) & 0x100)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
disable_dma(dma);
|
||||||
|
}
|
||||||
|
if (i >= (sizeof(dmas)/sizeof(dmas[0])))
|
||||||
|
dma = 0;
|
||||||
|
printf("\r\n%s base 0x%x, DMA %d, addr ",
|
||||||
|
chip_table[lance_version].name, ioaddr, dma);
|
||||||
|
/* Get station address */
|
||||||
|
for (i = 0; i < ETHER_ADDR_SIZE; ++i)
|
||||||
|
{
|
||||||
|
printf("%b", nic->node_addr[i] = inb(ioaddr+i));
|
||||||
|
if (i < ETHER_ADDR_SIZE -1)
|
||||||
|
printf(":");
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
return (lance_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
PROBE - Look for an adapter, this routine's visible to the outside
|
||||||
|
***************************************************************************/
|
||||||
|
struct nic *lance_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||||
|
{
|
||||||
|
unsigned short *p;
|
||||||
|
static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x360, 0 };
|
||||||
|
|
||||||
|
/* if probe_addrs is 0, then routine can use a hardwired default */
|
||||||
|
if (probe_addrs == 0)
|
||||||
|
probe_addrs = io_addrs;
|
||||||
|
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
|
||||||
|
{
|
||||||
|
char offset15, offset14 = inb(ioaddr + 14);
|
||||||
|
|
||||||
|
if ((offset14 == 0x52 || offset14 == 0x57) &&
|
||||||
|
((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
|
||||||
|
if (lance_probe1(nic) >= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* if board found */
|
||||||
|
if (ioaddr != 0)
|
||||||
|
{
|
||||||
|
/* point to NIC specific routines */
|
||||||
|
lance_reset(nic);
|
||||||
|
nic->reset = lance_reset;
|
||||||
|
nic->poll = lance_poll;
|
||||||
|
nic->transmit = lance_transmit;
|
||||||
|
nic->disable = lance_disable;
|
||||||
|
return nic;
|
||||||
|
}
|
||||||
|
/* else */
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* INCLUDE_NE2100 */
|
471
netboot/netboot.h
Normal file
471
netboot/netboot.h
Normal file
|
@ -0,0 +1,471 @@
|
||||||
|
/**************************************************************************
|
||||||
|
NETBOOT - BOOTP/TFTP Bootstrap Program
|
||||||
|
|
||||||
|
Author: Martin Renters
|
||||||
|
Date: Dec/93
|
||||||
|
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define NETBOOT32
|
||||||
|
|
||||||
|
#include "../stage2/shared.h"
|
||||||
|
|
||||||
|
#include "byteorder.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
typedef unsigned long Address;
|
||||||
|
|
||||||
|
extern int _pending_key;
|
||||||
|
extern inline int getchar(void);
|
||||||
|
extern inline int getchar(void) {
|
||||||
|
int foo;
|
||||||
|
|
||||||
|
if (_pending_key == -1)
|
||||||
|
return getkey();
|
||||||
|
foo = _pending_key;
|
||||||
|
_pending_key = -1;
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
extern inline int iskey(void);
|
||||||
|
extern inline int iskey(void) {
|
||||||
|
return _pending_key != -1 ? 1 : ((_pending_key = checkkey()) != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /*Edmund*/
|
||||||
|
#define bcmp __builtin_memcmp
|
||||||
|
#define memcpy(d,s,sz) bcopy((s),(d),(sz))
|
||||||
|
#else
|
||||||
|
#define bcopy(src, dest, n) memcpy(dest, src, n)
|
||||||
|
#define bzero(s, n) memset(s, 0, n)
|
||||||
|
#define bcmp(s1, s2, n) memcmp(s1, s2, n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ANSI prototyping macro */
|
||||||
|
#ifdef __STDC__
|
||||||
|
#define P(x) x
|
||||||
|
#else
|
||||||
|
#define P(x) ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ESC 0x1B
|
||||||
|
|
||||||
|
#ifndef DEFAULT_BOOTFILE
|
||||||
|
#define DEFAULT_BOOTFILE "/kernel"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_TFTP_RETRIES
|
||||||
|
#define MAX_TFTP_RETRIES 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_BOOTP_RETRIES
|
||||||
|
#define MAX_BOOTP_RETRIES 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_BOOTP_EXTLEN
|
||||||
|
#define MAX_BOOTP_EXTLEN 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_ARP_RETRIES
|
||||||
|
#define MAX_ARP_RETRIES 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_RPC_RETRIES
|
||||||
|
#define MAX_RPC_RETRIES 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TIMEOUT /* Inter-packet retry in ticks 18/sec */
|
||||||
|
#define TIMEOUT 180
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
#define ETHER_ADDR_SIZE 6 /* Size of Ethernet address */
|
||||||
|
#define ETHER_HDR_SIZE 14 /* Size of ethernet header */
|
||||||
|
#define ETH_MIN_PACKET 64
|
||||||
|
#define ETH_MAX_PACKET 1518
|
||||||
|
|
||||||
|
#define VENDOR_NONE 0
|
||||||
|
#define VENDOR_WD 1
|
||||||
|
#define VENDOR_NOVELL 2
|
||||||
|
#define VENDOR_3COM 3
|
||||||
|
#define VENDOR_3C509 4
|
||||||
|
#define VENDOR_CS89x0 5
|
||||||
|
|
||||||
|
#define FLAG_PIO 0x01
|
||||||
|
#define FLAG_16BIT 0x02
|
||||||
|
#define FLAG_790 0x04
|
||||||
|
|
||||||
|
#define ARP_CLIENT 0
|
||||||
|
#define ARP_SERVER 1
|
||||||
|
#define ARP_GATEWAY 2
|
||||||
|
#define ARP_ROOTSERVER 3
|
||||||
|
#define ARP_SWAPSERVER 4
|
||||||
|
#define MAX_ARP ARP_SWAPSERVER+1
|
||||||
|
|
||||||
|
#define IP 0x0800
|
||||||
|
#define ARP 0x0806
|
||||||
|
|
||||||
|
#define BOOTP_SERVER 67
|
||||||
|
#define BOOTP_CLIENT 68
|
||||||
|
#define TFTP 69
|
||||||
|
#define SUNRPC 111
|
||||||
|
|
||||||
|
#define RPC_SOCKET 620 /* Arbitrary */
|
||||||
|
|
||||||
|
#define IP_UDP 17
|
||||||
|
#define IP_BROADCAST 0xFFFFFFFF
|
||||||
|
|
||||||
|
#define ARP_REQUEST 1
|
||||||
|
#define ARP_REPLY 2
|
||||||
|
|
||||||
|
#define BOOTP_REQUEST 1
|
||||||
|
#define BOOTP_REPLY 2
|
||||||
|
|
||||||
|
#define TAG_LEN(p) (*((p)+1))
|
||||||
|
#define RFC1533_COOKIE 99, 130, 83, 99
|
||||||
|
#define RFC1533_PAD 0
|
||||||
|
#define RFC1533_NETMASK 1
|
||||||
|
#define RFC1533_TIMEOFFSET 2
|
||||||
|
#define RFC1533_GATEWAY 3
|
||||||
|
#define RFC1533_TIMESERVER 4
|
||||||
|
#define RFC1533_IEN116NS 5
|
||||||
|
#define RFC1533_DNS 6
|
||||||
|
#define RFC1533_LOGSERVER 7
|
||||||
|
#define RFC1533_COOKIESERVER 8
|
||||||
|
#define RFC1533_LPRSERVER 9
|
||||||
|
#define RFC1533_IMPRESSSERVER 10
|
||||||
|
#define RFC1533_RESOURCESERVER 11
|
||||||
|
#define RFC1533_HOSTNAME 12
|
||||||
|
#define RFC1533_BOOTFILESIZE 13
|
||||||
|
#define RFC1533_MERITDUMPFILE 14
|
||||||
|
#define RFC1533_DOMAINNAME 15
|
||||||
|
#define RFC1533_SWAPSERVER 16
|
||||||
|
#define RFC1533_ROOTPATH 17
|
||||||
|
#define RFC1533_EXTENSIONPATH 18
|
||||||
|
#define RFC1533_IPFORWARDING 19
|
||||||
|
#define RFC1533_IPSOURCEROUTING 20
|
||||||
|
#define RFC1533_IPPOLICYFILTER 21
|
||||||
|
#define RFC1533_IPMAXREASSEMBLY 22
|
||||||
|
#define RFC1533_IPTTL 23
|
||||||
|
#define RFC1533_IPMTU 24
|
||||||
|
#define RFC1533_IPMTUPLATEAU 25
|
||||||
|
#define RFC1533_INTMTU 26
|
||||||
|
#define RFC1533_INTLOCALSUBNETS 27
|
||||||
|
#define RFC1533_INTBROADCAST 28
|
||||||
|
#define RFC1533_INTICMPDISCOVER 29
|
||||||
|
#define RFC1533_INTICMPRESPOND 30
|
||||||
|
#define RFC1533_INTROUTEDISCOVER 31
|
||||||
|
#define RFC1533_INTROUTESOLICIT 32
|
||||||
|
#define RFC1533_INTSTATICROUTES 33
|
||||||
|
#define RFC1533_LLTRAILERENCAP 34
|
||||||
|
#define RFC1533_LLARPCACHETMO 35
|
||||||
|
#define RFC1533_LLETHERNETENCAP 36
|
||||||
|
#define RFC1533_TCPTTL 37
|
||||||
|
#define RFC1533_TCPKEEPALIVETMO 38
|
||||||
|
#define RFC1533_TCPKEEPALIVEGB 39
|
||||||
|
#define RFC1533_NISDOMAIN 40
|
||||||
|
#define RFC1533_NISSERVER 41
|
||||||
|
#define RFC1533_NTPSERVER 42
|
||||||
|
#define RFC1533_VENDOR 43
|
||||||
|
#define RFC1533_NBNS 44
|
||||||
|
#define RFC1533_NBDD 45
|
||||||
|
#define RFC1533_NBNT 46
|
||||||
|
#define RFC1533_NBSCOPE 47
|
||||||
|
#define RFC1533_XFS 48
|
||||||
|
#define RFC1533_XDM 49
|
||||||
|
|
||||||
|
#define RFC1533_VENDOR_MAJOR 0
|
||||||
|
#define RFC1533_VENDOR_MINOR 0
|
||||||
|
|
||||||
|
#define RFC1533_VENDOR_MAGIC 128
|
||||||
|
#define RFC1533_VENDOR_ADDPARM 129
|
||||||
|
#define RFC1533_VENDOR_MNUOPTS 160
|
||||||
|
#define RFC1533_VENDOR_SELECTION 176
|
||||||
|
#define RFC1533_VENDOR_MOTD 184
|
||||||
|
#define RFC1533_VENDOR_NUMOFMOTD 8
|
||||||
|
#define RFC1533_VENDOR_IMG 192
|
||||||
|
#define RFC1533_VENDOR_NUMOFIMG 16
|
||||||
|
|
||||||
|
#define RFC1533_END 255
|
||||||
|
#define BOOTP_VENDOR_LEN 64
|
||||||
|
|
||||||
|
#define TFTP_DEFAULTSIZE_PACKET 512
|
||||||
|
#define TFTP_MAX_PACKET 1432 /* 512 */
|
||||||
|
|
||||||
|
#define TFTP_RRQ 1
|
||||||
|
#define TFTP_WRQ 2
|
||||||
|
#define TFTP_DATA 3
|
||||||
|
#define TFTP_ACK 4
|
||||||
|
#define TFTP_ERROR 5
|
||||||
|
#define TFTP_OACK 6
|
||||||
|
|
||||||
|
#define TFTP_CODE_EOF 1
|
||||||
|
#define TFTP_CODE_MORE 2
|
||||||
|
#define TFTP_CODE_ERROR 3
|
||||||
|
#define TFTP_CODE_BOOT 4
|
||||||
|
#define TFTP_CODE_CFG 5
|
||||||
|
|
||||||
|
#define PROG_PORTMAP 100000
|
||||||
|
#define PROG_NFS 100003
|
||||||
|
#define PROG_MOUNT 100005
|
||||||
|
|
||||||
|
#define MSG_CALL 0
|
||||||
|
#define MSG_REPLY 1
|
||||||
|
|
||||||
|
#define PORTMAP_LOOKUP 3
|
||||||
|
|
||||||
|
#define MOUNT_ADDENTRY 1
|
||||||
|
#define MOUNT_UMNTALL 4
|
||||||
|
#define NFS_LOOKUP 4
|
||||||
|
#define NFS_READ 6
|
||||||
|
|
||||||
|
#define NFS_READ_SIZE 1024
|
||||||
|
|
||||||
|
|
||||||
|
#define AWAIT_ARP 0
|
||||||
|
#define AWAIT_BOOTP 1
|
||||||
|
#define AWAIT_TFTP 2
|
||||||
|
#define AWAIT_RPC 3
|
||||||
|
|
||||||
|
struct arptable_t {
|
||||||
|
unsigned long ipaddr;
|
||||||
|
unsigned char node[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arprequest {
|
||||||
|
unsigned short hwtype;
|
||||||
|
unsigned short protocol;
|
||||||
|
char hwlen;
|
||||||
|
char protolen;
|
||||||
|
unsigned short opcode;
|
||||||
|
char shwaddr[6];
|
||||||
|
char sipaddr[4];
|
||||||
|
char thwaddr[6];
|
||||||
|
char tipaddr[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iphdr {
|
||||||
|
char verhdrlen;
|
||||||
|
char service;
|
||||||
|
unsigned short len;
|
||||||
|
unsigned short ident;
|
||||||
|
unsigned short frags;
|
||||||
|
char ttl;
|
||||||
|
char protocol;
|
||||||
|
unsigned short chksum;
|
||||||
|
char src[4];
|
||||||
|
char dest[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct udphdr {
|
||||||
|
unsigned short src;
|
||||||
|
unsigned short dest;
|
||||||
|
unsigned short len;
|
||||||
|
unsigned short chksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bootp_t {
|
||||||
|
struct iphdr ip;
|
||||||
|
struct udphdr udp;
|
||||||
|
char bp_op;
|
||||||
|
char bp_htype;
|
||||||
|
char bp_hlen;
|
||||||
|
char bp_hops;
|
||||||
|
unsigned long bp_xid;
|
||||||
|
unsigned short bp_secs;
|
||||||
|
unsigned short unused;
|
||||||
|
char bp_ciaddr[4];
|
||||||
|
char bp_yiaddr[4];
|
||||||
|
char bp_siaddr[4];
|
||||||
|
char bp_giaddr[4];
|
||||||
|
char bp_hwaddr[16];
|
||||||
|
char bp_sname[64];
|
||||||
|
char bp_file[128];
|
||||||
|
char bp_vend[BOOTP_VENDOR_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bootpd_t {
|
||||||
|
struct bootp_t bootp_reply;
|
||||||
|
unsigned char bootp_extension[MAX_BOOTP_EXTLEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct tftp_t {
|
||||||
|
struct iphdr ip;
|
||||||
|
struct udphdr udp;
|
||||||
|
unsigned short opcode;
|
||||||
|
union {
|
||||||
|
char rrq[TFTP_DEFAULTSIZE_PACKET];
|
||||||
|
struct {
|
||||||
|
unsigned short block;
|
||||||
|
char download[TFTP_MAX_PACKET];
|
||||||
|
} data;
|
||||||
|
struct {
|
||||||
|
unsigned short block;
|
||||||
|
} ack;
|
||||||
|
struct {
|
||||||
|
unsigned short errcode;
|
||||||
|
char errmsg[TFTP_DEFAULTSIZE_PACKET];
|
||||||
|
} err;
|
||||||
|
struct {
|
||||||
|
char data[TFTP_DEFAULTSIZE_PACKET+2];
|
||||||
|
} oack;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rpc_t {
|
||||||
|
struct iphdr ip;
|
||||||
|
struct udphdr udp;
|
||||||
|
union {
|
||||||
|
char data[1400];
|
||||||
|
struct {
|
||||||
|
long id;
|
||||||
|
long type;
|
||||||
|
long rstatus;
|
||||||
|
long verifier;
|
||||||
|
long v2;
|
||||||
|
long astatus;
|
||||||
|
long data[1];
|
||||||
|
} reply;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
RPC Functions
|
||||||
|
***************************************************************************/
|
||||||
|
#define PUTLONG(val) {\
|
||||||
|
register int lval = val; \
|
||||||
|
*(rpcptr++) = ((lval) >> 24); \
|
||||||
|
*(rpcptr++) = ((lval) >> 16); \
|
||||||
|
*(rpcptr++) = ((lval) >> 8); \
|
||||||
|
*(rpcptr++) = (lval); \
|
||||||
|
rpclen+=4; }
|
||||||
|
|
||||||
|
#if 0 /* XXX */
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
External prototypes
|
||||||
|
***************************************************************************/
|
||||||
|
/* main.c */
|
||||||
|
extern void load P((void));
|
||||||
|
extern int load_linux P((int root_mount_port,int swap_mount_port,
|
||||||
|
int root_nfs_port,char *kernel_handle));
|
||||||
|
extern int linux_tftp P((unsigned int block,unsigned char *data,int len));
|
||||||
|
extern int tftpkernel P((unsigned char *, int, int, int));
|
||||||
|
extern int tftp P((char *name, int (*)(unsigned char *, int, int, int)));
|
||||||
|
extern int bootp P((void));
|
||||||
|
extern int udp_transmit P((unsigned long destip, unsigned int srcsock,
|
||||||
|
unsigned int destsock, int len, char *buf));
|
||||||
|
extern int await_reply P((int type, int ival, char *ptr));
|
||||||
|
extern void default_netmask P((void));
|
||||||
|
extern int decode_rfc1533 P((unsigned char *, int, int, int));
|
||||||
|
extern unsigned short ipchksum P((unsigned short *, int len));
|
||||||
|
extern void convert_ipaddr P((char *, char *));
|
||||||
|
extern void rfc951_sleep P((int));
|
||||||
|
|
||||||
|
/* bootmenu.c */
|
||||||
|
extern int execute P((char *string));
|
||||||
|
extern void bootmenu P((void));
|
||||||
|
extern void show_motd P((void));
|
||||||
|
extern void parse_menuopts P((char *,int));
|
||||||
|
extern int getoptvalue P((char **, int *, int *));
|
||||||
|
extern void selectImage P((char **, char *, struct arptable_t *));
|
||||||
|
|
||||||
|
/* linuxloader.c */
|
||||||
|
extern char *linux_add_cmdline P((char *string));
|
||||||
|
|
||||||
|
/* rpc.c */
|
||||||
|
extern int rpclookup P((int addr, int prog, int ver));
|
||||||
|
extern int nfs_mount P((int server, int port, char *path, char *fh));
|
||||||
|
extern int nfs_umountall P((int server, int port));
|
||||||
|
extern int nfs_lookup P((int server, int port, char *fh, char *path, char *file_fh));
|
||||||
|
extern int nfs_read P((int server, int port, char *fh, int offset, int len, char *buffer));
|
||||||
|
extern void rpc_err P((struct rpc_t *rpc));
|
||||||
|
extern void nfs_err P((int err));
|
||||||
|
|
||||||
|
/* misc.c */
|
||||||
|
#if 0 /*Edmund*/
|
||||||
|
extern void bcopy P((void *src, void *dst, int cnt));
|
||||||
|
extern void bzero P((void *dst, int cnt));
|
||||||
|
extern int bcmp P((void *src, void *dst, int cnt));
|
||||||
|
#endif
|
||||||
|
extern int strcasecmp P((char *a, char *b));
|
||||||
|
extern char *substr P((char *a, char *b));
|
||||||
|
extern int getdec P((char **));
|
||||||
|
extern void twiddle P((void));
|
||||||
|
extern void printf(); /* old style to avoid varargs */
|
||||||
|
extern char *sprintf();
|
||||||
|
extern int setip P((char *p, unsigned long *i));
|
||||||
|
extern void gateA20 P((void));
|
||||||
|
|
||||||
|
/* start*.S */
|
||||||
|
extern int getchar P((void));
|
||||||
|
extern void putchar P((int));
|
||||||
|
extern int iskey P((void));
|
||||||
|
extern int getshift P((void));
|
||||||
|
extern unsigned short memsize P((void));
|
||||||
|
extern void disk_init P((void));
|
||||||
|
extern short disk_read P((int drv,int c,int h,int s,char *buf));
|
||||||
|
extern void start_linux P((void));
|
||||||
|
extern void xstart P((unsigned long, unsigned long, unsigned long));
|
||||||
|
extern long currticks P((void));
|
||||||
|
extern int setjmp P((void *jmpbuf));
|
||||||
|
extern void longjmp P((void *jmpbuf, int where));
|
||||||
|
extern void exit P((int status));
|
||||||
|
|
||||||
|
/* ansiesc.c */
|
||||||
|
extern void ansi_reset P((void));
|
||||||
|
extern void enable_cursor P((int));
|
||||||
|
|
||||||
|
/* md5.c */
|
||||||
|
extern void md5_put P((unsigned int ch));
|
||||||
|
extern void md5_done P((unsigned char *buf));
|
||||||
|
|
||||||
|
/* floppy.c */
|
||||||
|
extern int bootdisk P((int dev,int part));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
External variables
|
||||||
|
***************************************************************************/
|
||||||
|
/* main.c */
|
||||||
|
extern char *kernel;
|
||||||
|
extern char kernel_buf[];
|
||||||
|
extern struct nfs_diskless nfsdiskless;
|
||||||
|
extern int hostnamelen;
|
||||||
|
extern unsigned long netmask;
|
||||||
|
extern int jmp_bootmenu[10];
|
||||||
|
extern char kernel_buf[128];
|
||||||
|
extern struct bootpd_t bootp_data;
|
||||||
|
extern struct arptable_t arptable[MAX_ARP];
|
||||||
|
extern char *imagelist[RFC1533_VENDOR_NUMOFIMG];
|
||||||
|
extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
|
||||||
|
extern int menutmo,menudefault;
|
||||||
|
extern unsigned char *end_of_rfc1533;
|
||||||
|
|
||||||
|
/* bootmenu.c */
|
||||||
|
|
||||||
|
/* linuxloader.c */
|
||||||
|
|
||||||
|
/* rpc.c */
|
||||||
|
extern int rpc_id;
|
||||||
|
|
||||||
|
/* created by linker */
|
||||||
|
extern char _edata[], _end[];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* End:
|
||||||
|
*/
|
195
netboot/netdevice.h
Normal file
195
netboot/netdevice.h
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||||
|
* operating system. INET is implemented using the BSD Socket
|
||||||
|
* interface as the means of communication with the user level.
|
||||||
|
*
|
||||||
|
* Definitions for the Interfaces handler.
|
||||||
|
*
|
||||||
|
* Version: @(#)dev.h 1.0.10 08/12/93
|
||||||
|
*
|
||||||
|
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
|
||||||
|
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
|
||||||
|
* Corey Minyard <wf-rch!minyard@relay.EU.net>
|
||||||
|
* Donald J. Becker, <becker@super.org>
|
||||||
|
* Alan Cox, <A.Cox@swansea.ac.uk>
|
||||||
|
* Bjorn Ekwall. <bj0rn@blox.se>
|
||||||
|
*
|
||||||
|
* 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 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Moved to /usr/include/linux for NET3
|
||||||
|
*/
|
||||||
|
/* for future expansion when we will have different priorities. */
|
||||||
|
#define DEV_NUMBUFFS 3
|
||||||
|
#define MAX_ADDR_LEN 7
|
||||||
|
#ifndef CONFIG_AX25
|
||||||
|
#ifndef CONFIG_TR
|
||||||
|
#ifndef CONFIG_NET_IPIP
|
||||||
|
#define MAX_HEADER 32 /* We really need about 18 worst case .. so 32 is aligned */
|
||||||
|
#else
|
||||||
|
#define MAX_HEADER 80 /* We need to allow for having tunnel headers */
|
||||||
|
#endif /* IPIP */
|
||||||
|
#else
|
||||||
|
#define MAX_HEADER 48 /* Token Ring header needs 40 bytes ... 48 is aligned */
|
||||||
|
#endif /* TR */
|
||||||
|
#else
|
||||||
|
#define MAX_HEADER 96 /* AX.25 + NetROM */
|
||||||
|
#endif /* AX25 */
|
||||||
|
|
||||||
|
#define IS_MYADDR 1 /* address is (one of) our own */
|
||||||
|
#define IS_LOOPBACK 2 /* address is for LOOPBACK */
|
||||||
|
#define IS_BROADCAST 3 /* address is a valid broadcast */
|
||||||
|
#define IS_INVBCAST 4 /* Wrong netmask bcast not for us (unused)*/
|
||||||
|
#define IS_MULTICAST 5 /* Multicast IP address */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The DEVICE structure.
|
||||||
|
* Actually, this whole structure is a big mistake. It mixes I/O
|
||||||
|
* data with strictly "high-level" data, and it has to know about
|
||||||
|
* almost every data structure used in the INET module.
|
||||||
|
*/
|
||||||
|
struct device
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the first field of the "visible" part of this structure
|
||||||
|
* (i.e. as seen by users in the "Space.c" file). It is the name
|
||||||
|
* the interface.
|
||||||
|
*/
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* I/O specific fields - FIXME: Merge these and struct ifmap into one */
|
||||||
|
unsigned long rmem_end; /* shmem "recv" end */
|
||||||
|
unsigned long rmem_start; /* shmem "recv" start */
|
||||||
|
unsigned long mem_end; /* shared mem end */
|
||||||
|
unsigned long mem_start; /* shared mem start */
|
||||||
|
unsigned long base_addr; /* device I/O address */
|
||||||
|
unsigned char irq; /* device IRQ number */
|
||||||
|
|
||||||
|
/* Low-level status flags. */
|
||||||
|
volatile unsigned char start, /* start an operation */
|
||||||
|
interrupt; /* interrupt arrived */
|
||||||
|
unsigned long tbusy; /* transmitter busy must be long for bitops */
|
||||||
|
|
||||||
|
struct device *next;
|
||||||
|
|
||||||
|
/* The device initialization function. Called only once. */
|
||||||
|
int (*init)(struct device *dev);
|
||||||
|
|
||||||
|
/* Some hardware also needs these fields, but they are not part of the
|
||||||
|
usual set specified in Space.c. */
|
||||||
|
unsigned char if_port; /* Selectable AUI, TP,..*/
|
||||||
|
unsigned char dma; /* DMA channel */
|
||||||
|
|
||||||
|
/* struct enet_statistics* (*get_stats)(struct device *dev); */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This marks the end of the "visible" part of the structure. All
|
||||||
|
* fields hereafter are internal to the system, and may change at
|
||||||
|
* will (read: may be cleaned up at will).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* These may be needed for future network-power-down code. */
|
||||||
|
unsigned long trans_start; /* Time (in jiffies) of last Tx */
|
||||||
|
unsigned long last_rx; /* Time of last Rx */
|
||||||
|
|
||||||
|
unsigned short flags; /* interface flags (a la BSD) */
|
||||||
|
unsigned short family; /* address family ID (AF_INET) */
|
||||||
|
unsigned short metric; /* routing metric (not used) */
|
||||||
|
unsigned short mtu; /* interface MTU value */
|
||||||
|
unsigned short type; /* interface hardware type */
|
||||||
|
unsigned short hard_header_len; /* hardware hdr length */
|
||||||
|
void *priv; /* pointer to private data */
|
||||||
|
|
||||||
|
/* Interface address info. */
|
||||||
|
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
|
||||||
|
unsigned char pad; /* make dev_addr aligned to 8 bytes */
|
||||||
|
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
|
||||||
|
unsigned char addr_len; /* hardware address length */
|
||||||
|
unsigned long pa_addr; /* protocol address */
|
||||||
|
unsigned long pa_brdaddr; /* protocol broadcast addr */
|
||||||
|
unsigned long pa_dstaddr; /* protocol P-P other side addr */
|
||||||
|
unsigned long pa_mask; /* protocol netmask */
|
||||||
|
unsigned short pa_alen; /* protocol address length */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct dev_mc_list *mc_list; /* Multicast mac addresses */
|
||||||
|
#endif
|
||||||
|
int mc_count; /* Number of installed mcasts */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct ip_mc_list *ip_mc_list; /* IP multicast filter chain */
|
||||||
|
#endif
|
||||||
|
unsigned int tx_queue_len; /* Max frames per queue allowed */
|
||||||
|
|
||||||
|
/* For load balancing driver pair support */
|
||||||
|
|
||||||
|
unsigned long pkt_queue; /* Packets queued */
|
||||||
|
#if 0
|
||||||
|
struct device *slave; /* Slave device */
|
||||||
|
|
||||||
|
struct net_alias_info *alias_info; /* main dev alias info */
|
||||||
|
struct net_alias *my_alias; /* alias devs */
|
||||||
|
/* Pointer to the interface buffers. */
|
||||||
|
struct sk_buff_head buffs[DEV_NUMBUFFS];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int (*change_mtu)(struct device *dev, int new_mtu);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct packet_type {
|
||||||
|
unsigned short type; /* This is really htons(ether_type). */
|
||||||
|
struct device * dev;
|
||||||
|
int (*func) (struct sk_buff *, struct device *,
|
||||||
|
struct packet_type *);
|
||||||
|
void *data;
|
||||||
|
struct packet_type *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Used by dev_rint */
|
||||||
|
#define IN_SKBUFF 1
|
||||||
|
|
||||||
|
extern int dev_lockct;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These two don't currently need to be interrupt-safe
|
||||||
|
* but they may do soon. Do it properly anyway.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern __inline__ void dev_lock_list(void)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
dev_lockct++;
|
||||||
|
restore_flags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern __inline__ void dev_unlock_list(void)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
dev_lockct--;
|
||||||
|
restore_flags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This almost never occurs, isn't in performance critical paths
|
||||||
|
* and we can thus be relaxed about it
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern __inline__ void dev_lock_wait(void)
|
||||||
|
{
|
||||||
|
while(dev_lockct)
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _LINUX_DEV_H */
|
18
netboot/nic.h
Normal file
18
netboot/nic.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Structure returned from eth_probe and passed to other driver
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct nic
|
||||||
|
{
|
||||||
|
void (*reset)P((struct nic *));
|
||||||
|
int (*poll)P((struct nic *));
|
||||||
|
void (*transmit)P((struct nic *, char *d,
|
||||||
|
unsigned int t, unsigned int s, char *p));
|
||||||
|
void (*disable)P((struct nic *));
|
||||||
|
char aui;
|
||||||
|
char *node_addr;
|
||||||
|
char *packet;
|
||||||
|
int packetlen;
|
||||||
|
void *priv_data; /* driver can hang private data here */
|
||||||
|
};
|
746
netboot/ns8390.c
Normal file
746
netboot/ns8390.c
Normal file
|
@ -0,0 +1,746 @@
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
NETBOOT - BOOTP/TFTP Bootstrap Program
|
||||||
|
|
||||||
|
Author: Martin Renters
|
||||||
|
Date: May/94
|
||||||
|
|
||||||
|
This code is based heavily on David Greenman's if_ed.c driver
|
||||||
|
|
||||||
|
Copyright (C) 1993-1994, David Greenman, Martin Renters.
|
||||||
|
This software may be used, modified, copied, distributed, and sold, in
|
||||||
|
both source and binary form provided that the above copyright and these
|
||||||
|
terms are retained. Under no circumstances are the authors responsible for
|
||||||
|
the proper functioning of this software, nor do the authors assume any
|
||||||
|
responsibility for damages incurred with its use.
|
||||||
|
|
||||||
|
3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94
|
||||||
|
SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
|
||||||
|
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if defined(INCLUDE_NE) || defined(INCLUDE_NEPCI) || defined(INCLUDE_WD) || defined(INCLUDE_T503)
|
||||||
|
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "nic.h"
|
||||||
|
#include "ns8390.h"
|
||||||
|
|
||||||
|
static unsigned char eth_vendor, eth_flags, eth_laar;
|
||||||
|
static unsigned short eth_nic_base, eth_asic_base;
|
||||||
|
static unsigned char eth_memsize, eth_rx_start, eth_tx_start;
|
||||||
|
static Address eth_bmem, eth_rmem;
|
||||||
|
|
||||||
|
#if defined(INCLUDE_WD)
|
||||||
|
#define eth_probe wd_probe
|
||||||
|
#else
|
||||||
|
#if defined(INCLUDE_T503)
|
||||||
|
#define eth_probe t503_probe
|
||||||
|
#else
|
||||||
|
#if defined(INCLUDE_NE)
|
||||||
|
#define eth_probe ne_probe
|
||||||
|
#else
|
||||||
|
#if defined(INCLUDE_NEPCI)
|
||||||
|
#define eth_probe nepci_probe
|
||||||
|
#else
|
||||||
|
Error you must define one of the above
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void net_bcopy (char *s, char *d, int l)
|
||||||
|
{
|
||||||
|
while (l--)
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(INCLUDE_NE) || defined(INCLUDE_NEPCI)
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_PIO_READ - Read a frame via Programmed I/O
|
||||||
|
**************************************************************************/
|
||||||
|
static void eth_pio_read(src, dst, cnt)
|
||||||
|
unsigned int src;
|
||||||
|
unsigned char *dst;
|
||||||
|
unsigned int cnt;
|
||||||
|
{
|
||||||
|
if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
|
||||||
|
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD2 |
|
||||||
|
D8390_COMMAND_STA);
|
||||||
|
outb(eth_nic_base + D8390_P0_RBCR0, cnt);
|
||||||
|
outb(eth_nic_base + D8390_P0_RBCR1, cnt>>8);
|
||||||
|
outb(eth_nic_base + D8390_P0_RSAR0, src);
|
||||||
|
outb(eth_nic_base + D8390_P0_RSAR1, src>>8);
|
||||||
|
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD0 |
|
||||||
|
D8390_COMMAND_STA);
|
||||||
|
if (eth_flags & FLAG_16BIT) {
|
||||||
|
cnt >>= 1; /* number of words */
|
||||||
|
while (cnt--) {
|
||||||
|
*((unsigned short *)dst) = inw(eth_asic_base + NE_DATA);
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (cnt--)
|
||||||
|
*(dst++) = inb(eth_asic_base + NE_DATA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_PIO_WRITE - Write a frame via Programmed I/O
|
||||||
|
**************************************************************************/
|
||||||
|
static void eth_pio_write(src, dst, cnt)
|
||||||
|
unsigned char *src;
|
||||||
|
unsigned int dst;
|
||||||
|
unsigned int cnt;
|
||||||
|
{
|
||||||
|
if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
|
||||||
|
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD2 |
|
||||||
|
D8390_COMMAND_STA);
|
||||||
|
outb(eth_nic_base + D8390_P0_ISR, D8390_ISR_RDC);
|
||||||
|
outb(eth_nic_base + D8390_P0_RBCR0, cnt);
|
||||||
|
outb(eth_nic_base + D8390_P0_RBCR1, cnt>>8);
|
||||||
|
outb(eth_nic_base + D8390_P0_RSAR0, dst);
|
||||||
|
outb(eth_nic_base + D8390_P0_RSAR1, dst>>8);
|
||||||
|
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD1 |
|
||||||
|
D8390_COMMAND_STA);
|
||||||
|
if (eth_flags & FLAG_16BIT) {
|
||||||
|
cnt >>= 1; /* number of words */
|
||||||
|
while (cnt--) {
|
||||||
|
outw_p(eth_asic_base + NE_DATA, *((unsigned short *)src));
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (cnt--)
|
||||||
|
outb_p(eth_asic_base + NE_DATA, *(src++));
|
||||||
|
}
|
||||||
|
while((inb_p(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
|
||||||
|
!= D8390_ISR_RDC);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_PIO_READ - Dummy routine when NE2000 not compiled in
|
||||||
|
**************************************************************************/
|
||||||
|
static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_RESET - Reset adapter
|
||||||
|
**************************************************************************/
|
||||||
|
static void eth_reset(struct nic *nic)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (eth_flags & FLAG_790)
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND,
|
||||||
|
D8390_COMMAND_PS0 | D8390_COMMAND_STP);
|
||||||
|
else
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND,
|
||||||
|
D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
|
||||||
|
D8390_COMMAND_STP);
|
||||||
|
if (eth_flags & FLAG_16BIT)
|
||||||
|
outb(eth_nic_base+D8390_P0_DCR, 0x49);
|
||||||
|
else
|
||||||
|
outb(eth_nic_base+D8390_P0_DCR, 0x48);
|
||||||
|
outb(eth_nic_base+D8390_P0_RBCR0, 0);
|
||||||
|
outb(eth_nic_base+D8390_P0_RBCR1, 0);
|
||||||
|
outb(eth_nic_base+D8390_P0_RCR, 0x20); /* monitor mode */
|
||||||
|
outb(eth_nic_base+D8390_P0_TCR, 2);
|
||||||
|
outb(eth_nic_base+D8390_P0_TPSR, eth_tx_start);
|
||||||
|
outb(eth_nic_base+D8390_P0_PSTART, eth_rx_start);
|
||||||
|
if (eth_flags & FLAG_790) outb(eth_nic_base + 0x09, 0);
|
||||||
|
outb(eth_nic_base+D8390_P0_PSTOP, eth_memsize);
|
||||||
|
outb(eth_nic_base+D8390_P0_BOUND, eth_memsize - 1);
|
||||||
|
outb(eth_nic_base+D8390_P0_ISR, 0xFF);
|
||||||
|
outb(eth_nic_base+D8390_P0_IMR, 0);
|
||||||
|
if (eth_flags & FLAG_790)
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS1 |
|
||||||
|
D8390_COMMAND_STP);
|
||||||
|
else
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS1 |
|
||||||
|
D8390_COMMAND_RD2 | D8390_COMMAND_STP);
|
||||||
|
for (i=0; i<ETHER_ADDR_SIZE; i++)
|
||||||
|
outb(eth_nic_base+D8390_P1_PAR0+i, nic->node_addr[i]);
|
||||||
|
for (i=0; i<ETHER_ADDR_SIZE; i++)
|
||||||
|
outb(eth_nic_base+D8390_P1_MAR0+i, 0xFF);
|
||||||
|
outb(eth_nic_base+D8390_P1_CURR, eth_rx_start);
|
||||||
|
if (eth_flags & FLAG_790)
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |
|
||||||
|
D8390_COMMAND_STA);
|
||||||
|
else
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |
|
||||||
|
D8390_COMMAND_RD2 | D8390_COMMAND_STA);
|
||||||
|
outb(eth_nic_base+D8390_P0_ISR, 0xFF);
|
||||||
|
outb(eth_nic_base+D8390_P0_TCR, 0);
|
||||||
|
outb(eth_nic_base+D8390_P0_RCR, 4); /* allow broadcast frames */
|
||||||
|
#ifdef INCLUDE_T503
|
||||||
|
if (eth_vendor == VENDOR_3COM) {
|
||||||
|
/*
|
||||||
|
* No way to tell whether or not we're supposed to use
|
||||||
|
* the 3Com's transceiver unless the user tells us.
|
||||||
|
* 'aui' should have some compile time default value
|
||||||
|
* which can be changed from the command menu.
|
||||||
|
*/
|
||||||
|
if (nic->aui)
|
||||||
|
outb(eth_asic_base + _3COM_CR, 0);
|
||||||
|
else
|
||||||
|
outb(eth_asic_base + _3COM_CR, _3COM_CR_XSEL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_TRANSMIT - Transmit a frame
|
||||||
|
**************************************************************************/
|
||||||
|
static void eth_transmit(
|
||||||
|
struct nic *nic,
|
||||||
|
char *d, /* Destination */
|
||||||
|
unsigned int t, /* Type */
|
||||||
|
unsigned int s, /* size */
|
||||||
|
char *p) /* Packet */
|
||||||
|
{
|
||||||
|
int c; /* used in NETBOOT16 */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef INCLUDE_T503
|
||||||
|
if (eth_vendor == VENDOR_3COM) {
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
net_bcopy(d, (void *)eth_bmem, ETHER_ADDR_SIZE); /* dst */
|
||||||
|
net_bcopy(nic->node_addr, (void *)eth_bmem+ETHER_ADDR_SIZE, ETHER_ADDR_SIZE); /* src */
|
||||||
|
*((char *)eth_bmem+12) = t>>8; /* type */
|
||||||
|
*((char *)eth_bmem+13) = t;
|
||||||
|
net_bcopy(p, (void *)eth_bmem+ETHER_HDR_SIZE, s);
|
||||||
|
s += ETHER_HDR_SIZE;
|
||||||
|
while (s < ETH_MIN_PACKET) *((char *)eth_bmem+(s++)) = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
bcopyf(d, eth_bmem, ETHER_ADDR_SIZE);
|
||||||
|
bcopyf(nic->node_addr, eth_bmem+ETHER_ADDR_SIZE, ETHER_ADDR_SIZE);
|
||||||
|
c = t >> 8;
|
||||||
|
bcopyf(&c, eth_bmem+12, 1);
|
||||||
|
c = t;
|
||||||
|
bcopyf(&c, eth_bmem+13, 1);
|
||||||
|
bcopyf(p, (Address)(eth_bmem+ETHER_HDR_SIZE), s);
|
||||||
|
s += ETHER_HDR_SIZE;
|
||||||
|
if (s < ETH_MIN_PACKET)
|
||||||
|
bzerof(eth_bmem+s, ETH_MIN_PACKET-s), s = ETH_MIN_PACKET;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_WD
|
||||||
|
if (eth_vendor == VENDOR_WD) { /* Memory interface */
|
||||||
|
if (eth_flags & FLAG_16BIT) {
|
||||||
|
outb(eth_asic_base + WD_LAAR, eth_laar | WD_LAAR_M16EN);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
if (eth_flags & FLAG_790) {
|
||||||
|
outb(eth_asic_base + WD_MSR, WD_MSR_MENB);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
inb(0x84);
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
net_bcopy(d, (void *)eth_bmem, ETHER_ADDR_SIZE); /* dst */
|
||||||
|
|
||||||
|
net_bcopy(nic->node_addr, (void *)eth_bmem+ETHER_ADDR_SIZE, ETHER_ADDR_SIZE); /* src */
|
||||||
|
*((char *)eth_bmem+12) = t>>8; /* type */
|
||||||
|
*((char *)eth_bmem+13) = t;
|
||||||
|
net_bcopy(p, (void *)eth_bmem+ETHER_HDR_SIZE, s);
|
||||||
|
s += ETHER_HDR_SIZE;
|
||||||
|
while (s < ETH_MIN_PACKET) *((char *)eth_bmem+(s++)) = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
bcopyf(d, eth_bmem, ETHER_ADDR_SIZE);
|
||||||
|
bcopyf(nic->node_addr, eth_bmem+ETHER_ADDR_SIZE, ETHER_ADDR_SIZE);
|
||||||
|
c = t >> 8;
|
||||||
|
/* bcc generates worse code without (const+const) below */
|
||||||
|
bcopyf(&c, eth_bmem+(ETHER_ADDR_SIZE+ETHER_ADDR_SIZE), 1);
|
||||||
|
c = t;
|
||||||
|
bcopyf(&c, eth_bmem+(ETHER_ADDR_SIZE+ETHER_ADDR_SIZE+1), 1);
|
||||||
|
bcopyf(p, (Address)(eth_bmem+ETHER_HDR_SIZE), s);
|
||||||
|
s += ETHER_HDR_SIZE;
|
||||||
|
if (s < ETH_MIN_PACKET)
|
||||||
|
bzerof(eth_bmem+s, ETH_MIN_PACKET-s), s = ETH_MIN_PACKET;
|
||||||
|
#endif
|
||||||
|
if (eth_flags & FLAG_790) {
|
||||||
|
outb(eth_asic_base + WD_MSR, 0);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
if (eth_flags & FLAG_16BIT) {
|
||||||
|
outb(eth_asic_base + WD_LAAR, eth_laar & ~WD_LAAR_M16EN);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(INCLUDE_NE) || defined(INCLUDE_NEPCI)
|
||||||
|
if (eth_vendor == VENDOR_NOVELL) { /* Programmed I/O */
|
||||||
|
unsigned short type;
|
||||||
|
type = (t >> 8) | (t << 8);
|
||||||
|
eth_pio_write(d, eth_tx_start<<8, ETHER_ADDR_SIZE);
|
||||||
|
eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETHER_ADDR_SIZE, ETHER_ADDR_SIZE);
|
||||||
|
/* bcc generates worse code without (const+const) below */
|
||||||
|
eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETHER_ADDR_SIZE+ETHER_ADDR_SIZE), 2);
|
||||||
|
eth_pio_write(p, (eth_tx_start<<8)+ETHER_HDR_SIZE, s);
|
||||||
|
s += ETHER_HDR_SIZE;
|
||||||
|
if (s < ETH_MIN_PACKET) s = ETH_MIN_PACKET;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (eth_flags & FLAG_790)
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |
|
||||||
|
D8390_COMMAND_STA);
|
||||||
|
else
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |
|
||||||
|
D8390_COMMAND_RD2 | D8390_COMMAND_STA);
|
||||||
|
outb(eth_nic_base+D8390_P0_TPSR, eth_tx_start);
|
||||||
|
outb(eth_nic_base+D8390_P0_TBCR0, s);
|
||||||
|
outb(eth_nic_base+D8390_P0_TBCR1, s>>8);
|
||||||
|
if (eth_flags & FLAG_790)
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |
|
||||||
|
D8390_COMMAND_TXP | D8390_COMMAND_STA);
|
||||||
|
else
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |
|
||||||
|
D8390_COMMAND_TXP | D8390_COMMAND_RD2 |
|
||||||
|
D8390_COMMAND_STA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_POLL - Wait for a frame
|
||||||
|
**************************************************************************/
|
||||||
|
static int eth_poll(struct nic *nic)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
unsigned char rstat, curr, next;
|
||||||
|
unsigned short len, frag;
|
||||||
|
unsigned short pktoff;
|
||||||
|
unsigned char *p;
|
||||||
|
struct ringbuffer pkthdr;
|
||||||
|
rstat = inb(eth_nic_base+D8390_P0_RSR);
|
||||||
|
if (rstat & D8390_RSTAT_OVER) {
|
||||||
|
eth_reset(nic);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if (!(rstat & D8390_RSTAT_PRX)) return(0);
|
||||||
|
next = inb(eth_nic_base+D8390_P0_BOUND)+1;
|
||||||
|
if (next >= eth_memsize) next = eth_rx_start;
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS1);
|
||||||
|
curr = inb(eth_nic_base+D8390_P1_CURR);
|
||||||
|
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0);
|
||||||
|
if (curr >= eth_memsize) curr=eth_rx_start;
|
||||||
|
if (curr == next) return(0);
|
||||||
|
if (eth_vendor == VENDOR_WD) {
|
||||||
|
if (eth_flags & FLAG_16BIT) {
|
||||||
|
outb(eth_asic_base + WD_LAAR, eth_laar | WD_LAAR_M16EN);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
if (eth_flags & FLAG_790) {
|
||||||
|
outb(eth_asic_base + WD_MSR, WD_MSR_MENB);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
pktoff = next << 8;
|
||||||
|
if (eth_flags & FLAG_PIO)
|
||||||
|
eth_pio_read(pktoff, (char *)&pkthdr, 4);
|
||||||
|
else
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
net_bcopy((void *)eth_rmem + pktoff, &pkthdr, 4);
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
fnet_bcopy(eth_rmem + pktoff, &pkthdr, 4);
|
||||||
|
#endif
|
||||||
|
pktoff += sizeof(pkthdr);
|
||||||
|
len = pkthdr.len - 4; /* sub CRC */
|
||||||
|
if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || pkthdr.len < ETH_MIN_PACKET || pkthdr.len > ETH_MAX_PACKET) {
|
||||||
|
printf("B");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = nic->packet;
|
||||||
|
nic->packetlen = len; /* available to caller */
|
||||||
|
frag = (eth_memsize << 8) - pktoff;
|
||||||
|
if (len > frag) { /* We have a wrap-around */
|
||||||
|
/* read first part */
|
||||||
|
if (eth_flags & FLAG_PIO)
|
||||||
|
eth_pio_read(pktoff, p, frag);
|
||||||
|
else
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
net_bcopy((void *)eth_rmem + pktoff, p, frag);
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
fnet_bcopy(eth_rmem + pktoff, p, frag);
|
||||||
|
#endif
|
||||||
|
pktoff = eth_rx_start << 8;
|
||||||
|
p += frag;
|
||||||
|
len -= frag;
|
||||||
|
}
|
||||||
|
/* read second part */
|
||||||
|
if (eth_flags & FLAG_PIO)
|
||||||
|
eth_pio_read(pktoff, p, len);
|
||||||
|
else
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
net_bcopy((void *)eth_rmem + pktoff, p, len);
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
fnet_bcopy(eth_rmem + pktoff, p, len);
|
||||||
|
#endif
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
if (eth_vendor == VENDOR_WD) {
|
||||||
|
if (eth_flags & FLAG_790) {
|
||||||
|
outb(eth_asic_base + WD_MSR, 0);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
if (eth_flags & FLAG_16BIT) {
|
||||||
|
outb(eth_asic_base + WD_LAAR, eth_laar &
|
||||||
|
~WD_LAAR_M16EN);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
next = pkthdr.next; /* frame number of next packet */
|
||||||
|
if (next == eth_rx_start)
|
||||||
|
next = eth_memsize;
|
||||||
|
outb(eth_nic_base+D8390_P0_BOUND, next-1);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_DISABLE - Turn off adapter
|
||||||
|
**************************************************************************/
|
||||||
|
static void eth_disable(struct nic *nic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
ETH_PROBE - Look for an adapter
|
||||||
|
**************************************************************************/
|
||||||
|
struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct wd_board *brd;
|
||||||
|
unsigned short chksum;
|
||||||
|
unsigned char c;
|
||||||
|
#if defined(INCLUDE_WD) && defined(NETBOOT16)
|
||||||
|
unsigned char bmem13, bmem11;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
eth_vendor = VENDOR_NONE;
|
||||||
|
|
||||||
|
#ifdef INCLUDE_WD
|
||||||
|
/******************************************************************
|
||||||
|
Search for WD/SMC cards
|
||||||
|
******************************************************************/
|
||||||
|
for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
|
||||||
|
eth_asic_base += 0x20) {
|
||||||
|
chksum = 0;
|
||||||
|
for (i=8; i<16; i++)
|
||||||
|
chksum += inb(i+eth_asic_base);
|
||||||
|
if ((chksum & 0x00FF) == 0x00FF)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (eth_asic_base <= WD_HIGH_BASE) { /* We've found a board */
|
||||||
|
eth_vendor = VENDOR_WD;
|
||||||
|
eth_nic_base = eth_asic_base + WD_NIC_ADDR;
|
||||||
|
c = inb(eth_asic_base+WD_BID); /* Get board id */
|
||||||
|
for (brd = wd_boards; brd->name; brd++)
|
||||||
|
if (brd->id == c) break;
|
||||||
|
if (!brd->name) {
|
||||||
|
printf("\r\nUnknown Ethernet type %x\r\n", c);
|
||||||
|
return(0); /* Unknown type */
|
||||||
|
}
|
||||||
|
eth_flags = brd->flags;
|
||||||
|
eth_memsize = brd->memsize;
|
||||||
|
eth_tx_start = 0;
|
||||||
|
eth_rx_start = D8390_TXBUF_SIZE;
|
||||||
|
if ((c == TYPE_WD8013EP) &&
|
||||||
|
(inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) {
|
||||||
|
eth_flags = FLAG_16BIT;
|
||||||
|
eth_memsize = MEM_16384;
|
||||||
|
}
|
||||||
|
if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) {
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
eth_bmem = (0x80000 |
|
||||||
|
((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
eth_bmem = inb(eth_asic_base + WD_MSR) & 0x3F;
|
||||||
|
eth_bmem <<= 13;
|
||||||
|
eth_bmem |= 0x80000;
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
|
eth_bmem = WD_DEFAULT_MEM;
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
/* cast is to force evaluation in long precision */
|
||||||
|
bmem13 = (Address)eth_bmem >> 13;
|
||||||
|
bmem11 = (Address)eth_bmem >> 11;
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
|
||||||
|
*((unsigned int *)(eth_bmem + 8192)) = (unsigned int)0;
|
||||||
|
if (*((unsigned int *)(eth_bmem + 8192))) {
|
||||||
|
brd += 2;
|
||||||
|
eth_memsize = brd->memsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
|
||||||
|
i = 0;
|
||||||
|
bcopyf(&i, eth_bmem + 8192, sizeof(i));
|
||||||
|
if (!fbsame(eth_bmem + 8192, 0, sizeof(i))) {
|
||||||
|
brd += 2;
|
||||||
|
eth_memsize = brd->memsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
outb(eth_asic_base + WD_MSR, 0x80); /* Reset */
|
||||||
|
printf("\r\n%s base 0x%x, memory 0x%x, addr ",
|
||||||
|
brd->name, eth_asic_base, eth_bmem);
|
||||||
|
for (i=0; i<ETHER_ADDR_SIZE; i++) {
|
||||||
|
printf("%x",((int)(nic->node_addr[i] =
|
||||||
|
inb(i+eth_asic_base+WD_LAR)) & 0xff));
|
||||||
|
if (i < ETHER_ADDR_SIZE-1) printf (":");
|
||||||
|
}
|
||||||
|
if (eth_flags & FLAG_790) {
|
||||||
|
outb(eth_asic_base+WD_MSR, WD_MSR_MENB);
|
||||||
|
outb(eth_asic_base+0x04, (inb(eth_asic_base+0x04) |
|
||||||
|
0x80));
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
outb(eth_asic_base+0x0B,
|
||||||
|
(((unsigned)eth_bmem >> 13) & 0x0F) |
|
||||||
|
(((unsigned)eth_bmem >> 11) & 0x40) |
|
||||||
|
(inb(eth_asic_base+0x0B) & 0xB0));
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
outb(eth_asic_base+0x0B,
|
||||||
|
(bmem13 & 0x0F) |
|
||||||
|
(bmem11 & 0x40) |
|
||||||
|
(inb(eth_asic_base+0x0B) & 0xB0));
|
||||||
|
#endif
|
||||||
|
outb(eth_asic_base+0x04, (inb(eth_asic_base+0x04) &
|
||||||
|
~0x80));
|
||||||
|
} else {
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
outb(eth_asic_base+WD_MSR,
|
||||||
|
(((unsigned)eth_bmem >> 13) & 0x3F) | 0x40);
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
outb(eth_asic_base+WD_MSR,
|
||||||
|
(bmem13 & 0x3F) | 0x40);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (eth_flags & FLAG_16BIT) {
|
||||||
|
if (eth_flags & FLAG_790) {
|
||||||
|
eth_laar = inb(eth_asic_base + WD_LAAR);
|
||||||
|
outb(eth_asic_base + WD_LAAR, WD_LAAR_M16EN);
|
||||||
|
inb(0x84);
|
||||||
|
} else {
|
||||||
|
outb(eth_asic_base + WD_LAAR, (eth_laar =
|
||||||
|
WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef INCLUDE_T503
|
||||||
|
/******************************************************************
|
||||||
|
Search for 3Com 3c503 if no WD/SMC cards
|
||||||
|
******************************************************************/
|
||||||
|
if (eth_vendor == VENDOR_NONE) {
|
||||||
|
int idx;
|
||||||
|
static unsigned short base[] = {
|
||||||
|
0x300, 0x310, 0x330, 0x350,
|
||||||
|
0x250, 0x280, 0x2A0, 0x2E0, 0 };
|
||||||
|
/* this must parallel the table above */
|
||||||
|
static unsigned char bcfr[] = {
|
||||||
|
_3COM_BCFR_300, _3COM_BCFR_310,
|
||||||
|
_3COM_BCFR_330, _3COM_BCFR_350,
|
||||||
|
_3COM_BCFR_250, _3COM_BCFR_280,
|
||||||
|
_3COM_BCFR_2A0, _3COM_BCFR_2E0, 0 };
|
||||||
|
|
||||||
|
/* Loop through possible addresses checking each one */
|
||||||
|
|
||||||
|
for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) {
|
||||||
|
|
||||||
|
eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET;
|
||||||
|
/*
|
||||||
|
* Note that we use the same settings for both 8 and 16 bit cards:
|
||||||
|
* both have an 8K bank of memory at page 1 while only the 16 bit
|
||||||
|
* cards have a bank at page 0.
|
||||||
|
*/
|
||||||
|
eth_memsize = MEM_16384;
|
||||||
|
eth_tx_start = 32;
|
||||||
|
eth_rx_start = 32 + D8390_TXBUF_SIZE;
|
||||||
|
|
||||||
|
/* Check our base address */
|
||||||
|
|
||||||
|
if (inb(eth_asic_base + _3COM_BCFR) != bcfr[idx])
|
||||||
|
continue; /* nope */
|
||||||
|
|
||||||
|
/* Now get the shared memory address */
|
||||||
|
|
||||||
|
switch (inb(eth_asic_base + _3COM_PCFR)) {
|
||||||
|
case _3COM_PCFR_DC000:
|
||||||
|
eth_bmem = 0xdc000;
|
||||||
|
break;
|
||||||
|
case _3COM_PCFR_D8000:
|
||||||
|
eth_bmem = 0xd8000;
|
||||||
|
break;
|
||||||
|
case _3COM_PCFR_CC000:
|
||||||
|
eth_bmem = 0xcc000;
|
||||||
|
break;
|
||||||
|
case _3COM_PCFR_C8000:
|
||||||
|
eth_bmem = 0xc8000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue; /* nope */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base[idx] == 0) /* not found */
|
||||||
|
return (0);
|
||||||
|
eth_vendor = VENDOR_3COM;
|
||||||
|
|
||||||
|
|
||||||
|
/* Need this to make eth_poll() happy. */
|
||||||
|
|
||||||
|
eth_rmem = eth_bmem - 0x2000;
|
||||||
|
|
||||||
|
/* Reset NIC and ASIC */
|
||||||
|
|
||||||
|
outb (eth_asic_base + _3COM_CR , _3COM_CR_RST | _3COM_CR_XSEL);
|
||||||
|
outb (eth_asic_base + _3COM_CR , _3COM_CR_XSEL);
|
||||||
|
|
||||||
|
/* Get our ethernet address */
|
||||||
|
|
||||||
|
outb(eth_asic_base + _3COM_CR, _3COM_CR_EALO | _3COM_CR_XSEL);
|
||||||
|
printf("\r\n3Com 3c503 base 0x%x, memory 0x%X addr ",
|
||||||
|
eth_nic_base, eth_bmem);
|
||||||
|
for (i=0; i<ETHER_ADDR_SIZE; i++) {
|
||||||
|
printf("%b",(int)(nic->node_addr[i] =
|
||||||
|
inb(eth_nic_base+i)));
|
||||||
|
if (i < ETHER_ADDR_SIZE-1) printf (":");
|
||||||
|
}
|
||||||
|
outb(eth_asic_base + _3COM_CR, _3COM_CR_XSEL);
|
||||||
|
/*
|
||||||
|
* Initialize GA configuration register. Set bank and enable shared
|
||||||
|
* mem. We always use bank 1.
|
||||||
|
*/
|
||||||
|
outb(eth_asic_base + _3COM_GACFR, _3COM_GACFR_RSEL |
|
||||||
|
_3COM_GACFR_MBS0);
|
||||||
|
|
||||||
|
outb(eth_asic_base + _3COM_VPTR2, 0xff);
|
||||||
|
outb(eth_asic_base + _3COM_VPTR1, 0xff);
|
||||||
|
outb(eth_asic_base + _3COM_VPTR0, 0x00);
|
||||||
|
/*
|
||||||
|
* Clear memory and verify that it worked (we use only 8K)
|
||||||
|
*/
|
||||||
|
#ifdef NETBOOT32
|
||||||
|
bzero((char *)eth_bmem, 0x2000);
|
||||||
|
for(i = 0; i < 0x2000; ++i)
|
||||||
|
if (*(((char *)eth_bmem)+i)) {
|
||||||
|
printf ("Failed to clear 3c503 shared mem.\r\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef NETBOOT16
|
||||||
|
bzerof(eth_bmem, 0x2000);
|
||||||
|
if (!fbsame(eth_bmem, 0, 0x2000)) {
|
||||||
|
printf ("Failed to clear 3c503 shared mem.\r\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Initialize GA page/start/stop registers.
|
||||||
|
*/
|
||||||
|
outb(eth_asic_base + _3COM_PSTR, eth_tx_start);
|
||||||
|
outb(eth_asic_base + _3COM_PSPR, eth_memsize);
|
||||||
|
|
||||||
|
printf ("\r\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(INCLUDE_NE) || defined(INCLUDE_NEPCI)
|
||||||
|
/******************************************************************
|
||||||
|
Search for NE1000/2000 if no WD/SMC or 3com cards
|
||||||
|
******************************************************************/
|
||||||
|
if (eth_vendor == VENDOR_NONE) {
|
||||||
|
char romdata[16], testbuf[32];
|
||||||
|
int idx;
|
||||||
|
static char test[] = "NE1000/2000 memory";
|
||||||
|
#ifndef NE_SCAN
|
||||||
|
#define NE_SCAN 0
|
||||||
|
#endif
|
||||||
|
static unsigned short base[] = {NE_SCAN, 0};
|
||||||
|
/* if no addresses supplied, fall back on defaults */
|
||||||
|
if (probe_addrs == 0 || probe_addrs[0] == 0)
|
||||||
|
probe_addrs = base;
|
||||||
|
eth_bmem = 0; /* No shared memory */
|
||||||
|
for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) {
|
||||||
|
eth_flags = FLAG_PIO;
|
||||||
|
eth_asic_base = eth_nic_base + NE_ASIC_OFFSET;
|
||||||
|
eth_memsize = MEM_16384;
|
||||||
|
eth_tx_start = 32;
|
||||||
|
eth_rx_start = 32 + D8390_TXBUF_SIZE;
|
||||||
|
c = inb(eth_asic_base + NE_RESET);
|
||||||
|
outb(eth_asic_base + NE_RESET, c);
|
||||||
|
inb(0x84);
|
||||||
|
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_STP |
|
||||||
|
D8390_COMMAND_RD2);
|
||||||
|
outb(eth_nic_base + D8390_P0_RCR, D8390_RCR_MON);
|
||||||
|
outb(eth_nic_base + D8390_P0_DCR, D8390_DCR_FT1 | D8390_DCR_LS);
|
||||||
|
outb(eth_nic_base + D8390_P0_PSTART, MEM_8192);
|
||||||
|
outb(eth_nic_base + D8390_P0_PSTOP, MEM_16384);
|
||||||
|
eth_pio_write(test, 8192, sizeof(test));
|
||||||
|
eth_pio_read(8192, testbuf, sizeof(test));
|
||||||
|
if (!bcmp(test, testbuf, sizeof(test)))
|
||||||
|
break;
|
||||||
|
eth_flags |= FLAG_16BIT;
|
||||||
|
eth_memsize = MEM_32768;
|
||||||
|
eth_tx_start = 64;
|
||||||
|
eth_rx_start = 64 + D8390_TXBUF_SIZE;
|
||||||
|
outb(eth_nic_base + D8390_P0_DCR, D8390_DCR_WTS |
|
||||||
|
D8390_DCR_FT1 | D8390_DCR_LS);
|
||||||
|
outb(eth_nic_base + D8390_P0_PSTART, MEM_16384);
|
||||||
|
outb(eth_nic_base + D8390_P0_PSTOP, MEM_32768);
|
||||||
|
eth_pio_write(test, 16384, sizeof(test));
|
||||||
|
eth_pio_read(16384, testbuf, sizeof(test));
|
||||||
|
if (!bcmp(testbuf, test, sizeof(test)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (eth_nic_base == 0)
|
||||||
|
return (0);
|
||||||
|
if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */
|
||||||
|
eth_flags |= FLAG_16BIT;
|
||||||
|
eth_vendor = VENDOR_NOVELL;
|
||||||
|
eth_pio_read(0, romdata, 16);
|
||||||
|
printf("\r\nNE*000 base 0x%x, addr ", eth_nic_base);
|
||||||
|
for (i=0; i<ETHER_ADDR_SIZE; i++) {
|
||||||
|
printf("%x",(int)(nic->node_addr[i] = romdata[i
|
||||||
|
+ ((eth_flags & FLAG_16BIT) ? i : 0)]));
|
||||||
|
if (i < ETHER_ADDR_SIZE-1) printf (":");
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (eth_vendor == VENDOR_NONE) return(0);
|
||||||
|
|
||||||
|
if (eth_vendor != VENDOR_3COM) eth_rmem = eth_bmem;
|
||||||
|
eth_reset(nic);
|
||||||
|
nic->reset = eth_reset;
|
||||||
|
nic->poll = eth_poll;
|
||||||
|
nic->transmit = eth_transmit;
|
||||||
|
nic->disable = eth_disable;
|
||||||
|
return(nic);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* End:
|
||||||
|
*/
|
251
netboot/ns8390.h
Normal file
251
netboot/ns8390.h
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
/**************************************************************************
|
||||||
|
NETBOOT - BOOTP/TFTP Bootstrap Program
|
||||||
|
|
||||||
|
Author: Martin Renters
|
||||||
|
Date: Jun/94
|
||||||
|
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define MEM_8192 32
|
||||||
|
#define MEM_16384 64
|
||||||
|
#define MEM_32768 128
|
||||||
|
|
||||||
|
#define ISA_MAX_ADDR 0x400
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
Western Digital/SMC Board Definitions
|
||||||
|
**************************************************************************/
|
||||||
|
#define WD_LOW_BASE 0x200
|
||||||
|
#define WD_HIGH_BASE 0x3e0
|
||||||
|
#ifndef WD_DEFAULT_MEM
|
||||||
|
#define WD_DEFAULT_MEM 0xD0000
|
||||||
|
#endif
|
||||||
|
#define WD_NIC_ADDR 0x10
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
Western Digital/SMC ASIC Addresses
|
||||||
|
**************************************************************************/
|
||||||
|
#define WD_MSR 0x00
|
||||||
|
#define WD_ICR 0x01
|
||||||
|
#define WD_IAR 0x02
|
||||||
|
#define WD_BIO 0x03
|
||||||
|
#define WD_IRR 0x04
|
||||||
|
#define WD_LAAR 0x05
|
||||||
|
#define WD_IJR 0x06
|
||||||
|
#define WD_GP2 0x07
|
||||||
|
#define WD_LAR 0x08
|
||||||
|
#define WD_BID 0x0E
|
||||||
|
|
||||||
|
#define WD_ICR_16BIT 0x01
|
||||||
|
|
||||||
|
#define WD_MSR_MENB 0x40
|
||||||
|
|
||||||
|
#define WD_LAAR_L16EN 0x40
|
||||||
|
#define WD_LAAR_M16EN 0x80
|
||||||
|
|
||||||
|
#define WD_SOFTCONFIG 0x20
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
Western Digital/SMC Board Types
|
||||||
|
**************************************************************************/
|
||||||
|
#define TYPE_WD8003S 0x02
|
||||||
|
#define TYPE_WD8003E 0x03
|
||||||
|
#define TYPE_WD8013EBT 0x05
|
||||||
|
#define TYPE_WD8003W 0x24
|
||||||
|
#define TYPE_WD8003EB 0x25
|
||||||
|
#define TYPE_WD8013W 0x26
|
||||||
|
#define TYPE_WD8013EP 0x27
|
||||||
|
#define TYPE_WD8013WC 0x28
|
||||||
|
#define TYPE_WD8013EPC 0x29
|
||||||
|
#define TYPE_SMC8216T 0x2a
|
||||||
|
#define TYPE_SMC8216C 0x2b
|
||||||
|
#define TYPE_SMC8416T 0x00 /* Bogus entries: the 8416 generates the */
|
||||||
|
#define TYPE_SMC8416C 0x00 /* the same codes as the 8216. */
|
||||||
|
#define TYPE_SMC8013EBP 0x2c
|
||||||
|
|
||||||
|
#ifdef INCLUDE_WD
|
||||||
|
struct wd_board {
|
||||||
|
char *name;
|
||||||
|
char id;
|
||||||
|
char flags;
|
||||||
|
char memsize;
|
||||||
|
} wd_boards[] = {
|
||||||
|
{"WD8003S", TYPE_WD8003S, 0, MEM_8192},
|
||||||
|
{"WD8003E", TYPE_WD8003E, 0, MEM_8192},
|
||||||
|
{"WD8013EBT", TYPE_WD8013EBT, FLAG_16BIT, MEM_16384},
|
||||||
|
{"WD8003W", TYPE_WD8003W, 0, MEM_8192},
|
||||||
|
{"WD8003EB", TYPE_WD8003EB, 0, MEM_8192},
|
||||||
|
{"WD8013W", TYPE_WD8013W, FLAG_16BIT, MEM_16384},
|
||||||
|
{"WD8003EP/WD8013EP",
|
||||||
|
TYPE_WD8013EP, 0, MEM_8192},
|
||||||
|
{"WD8013WC", TYPE_WD8013WC, FLAG_16BIT, MEM_16384},
|
||||||
|
{"WD8013EPC", TYPE_WD8013EPC, FLAG_16BIT, MEM_16384},
|
||||||
|
{"SMC8216T", TYPE_SMC8216T, FLAG_16BIT | FLAG_790, MEM_16384},
|
||||||
|
{"SMC8216C", TYPE_SMC8216C, FLAG_16BIT | FLAG_790, MEM_16384},
|
||||||
|
{"SMC8416T", TYPE_SMC8416T, FLAG_16BIT | FLAG_790, MEM_8192},
|
||||||
|
{"SMC8416C/BT", TYPE_SMC8416C, FLAG_16BIT | FLAG_790, MEM_8192},
|
||||||
|
{"SMC8013EBP", TYPE_SMC8013EBP,FLAG_16BIT, MEM_16384},
|
||||||
|
{NULL, 0, 0}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
/**************************************************************************
|
||||||
|
3com 3c503 definitions
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _3COM_BASE
|
||||||
|
#define _3COM_BASE 0x300
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _3COM_TX_PAGE_OFFSET_8BIT 0x20
|
||||||
|
#define _3COM_TX_PAGE_OFFSET_16BIT 0x0
|
||||||
|
#define _3COM_RX_PAGE_OFFSET_16BIT 0x20
|
||||||
|
|
||||||
|
#define _3COM_ASIC_OFFSET 0x400
|
||||||
|
#define _3COM_NIC_OFFSET 0x0
|
||||||
|
|
||||||
|
#define _3COM_PSTR 0
|
||||||
|
#define _3COM_PSPR 1
|
||||||
|
|
||||||
|
#define _3COM_BCFR 3
|
||||||
|
#define _3COM_BCFR_2E0 0x01
|
||||||
|
#define _3COM_BCFR_2A0 0x02
|
||||||
|
#define _3COM_BCFR_280 0x04
|
||||||
|
#define _3COM_BCFR_250 0x08
|
||||||
|
#define _3COM_BCFR_350 0x10
|
||||||
|
#define _3COM_BCFR_330 0x20
|
||||||
|
#define _3COM_BCFR_310 0x40
|
||||||
|
#define _3COM_BCFR_300 0x80
|
||||||
|
#define _3COM_PCFR 4
|
||||||
|
#define _3COM_PCFR_C8000 0x10
|
||||||
|
#define _3COM_PCFR_CC000 0x20
|
||||||
|
#define _3COM_PCFR_D8000 0x40
|
||||||
|
#define _3COM_PCFR_DC000 0x80
|
||||||
|
#define _3COM_CR 6
|
||||||
|
#define _3COM_CR_RST 0x01 /* Reset GA and NIC */
|
||||||
|
#define _3COM_CR_XSEL 0x02 /* Transceiver select. BNC=1(def) AUI=0 */
|
||||||
|
#define _3COM_CR_EALO 0x04 /* window EA PROM 0-15 to I/O base */
|
||||||
|
#define _3COM_CR_EAHI 0x08 /* window EA PROM 16-31 to I/O base */
|
||||||
|
#define _3COM_CR_SHARE 0x10 /* select interrupt sharing option */
|
||||||
|
#define _3COM_CR_DBSEL 0x20 /* Double buffer select */
|
||||||
|
#define _3COM_CR_DDIR 0x40 /* DMA direction select */
|
||||||
|
#define _3COM_CR_START 0x80 /* Start DMA controller */
|
||||||
|
#define _3COM_GACFR 5
|
||||||
|
#define _3COM_GACFR_MBS0 0x01
|
||||||
|
#define _3COM_GACFR_MBS1 0x02
|
||||||
|
#define _3COM_GACFR_MBS2 0x04
|
||||||
|
#define _3COM_GACFR_RSEL 0x08 /* enable shared memory */
|
||||||
|
#define _3COM_GACFR_TEST 0x10 /* for GA testing */
|
||||||
|
#define _3COM_GACFR_OWS 0x20 /* select 0WS access to GA */
|
||||||
|
#define _3COM_GACFR_TCM 0x40 /* Mask DMA interrupts */
|
||||||
|
#define _3COM_GACFR_NIM 0x80 /* Mask NIC interrupts */
|
||||||
|
#define _3COM_STREG 7
|
||||||
|
#define _3COM_STREG_REV 0x07 /* GA revision */
|
||||||
|
#define _3COM_STREG_DIP 0x08 /* DMA in progress */
|
||||||
|
#define _3COM_STREG_DTC 0x10 /* DMA terminal count */
|
||||||
|
#define _3COM_STREG_OFLW 0x20 /* Overflow */
|
||||||
|
#define _3COM_STREG_UFLW 0x40 /* Underflow */
|
||||||
|
#define _3COM_STREG_DPRDY 0x80 /* Data port ready */
|
||||||
|
#define _3COM_IDCFR 8
|
||||||
|
#define _3COM_IDCFR_DRQ0 0x01 /* DMA request 1 select */
|
||||||
|
#define _3COM_IDCFR_DRQ1 0x02 /* DMA request 2 select */
|
||||||
|
#define _3COM_IDCFR_DRQ2 0x04 /* DMA request 3 select */
|
||||||
|
#define _3COM_IDCFR_UNUSED 0x08 /* not used */
|
||||||
|
#define _3COM_IDCFR_IRQ2 0x10 /* Interrupt request 2 select */
|
||||||
|
#define _3COM_IDCFR_IRQ3 0x20 /* Interrupt request 3 select */
|
||||||
|
#define _3COM_IDCFR_IRQ4 0x40 /* Interrupt request 4 select */
|
||||||
|
#define _3COM_IDCFR_IRQ5 0x80 /* Interrupt request 5 select */
|
||||||
|
#define _3COM_IRQ2 2
|
||||||
|
#define _3COM_IRQ3 3
|
||||||
|
#define _3COM_IRQ4 4
|
||||||
|
#define _3COM_IRQ5 5
|
||||||
|
#define _3COM_DAMSB 9
|
||||||
|
#define _3COM_DALSB 0x0a
|
||||||
|
#define _3COM_VPTR2 0x0b
|
||||||
|
#define _3COM_VPTR1 0x0c
|
||||||
|
#define _3COM_VPTR0 0x0d
|
||||||
|
#define _3COM_RFMSB 0x0e
|
||||||
|
#define _3COM_RFLSB 0x0f
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
NE1000/2000 definitions
|
||||||
|
**************************************************************************/
|
||||||
|
#define NE_ASIC_OFFSET 0x10
|
||||||
|
#define NE_RESET 0x0F /* Used to reset card */
|
||||||
|
#define NE_DATA 0x00 /* Used to read/write NIC mem */
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
8390 Register Definitions
|
||||||
|
**************************************************************************/
|
||||||
|
#define D8390_P0_COMMAND 0x00
|
||||||
|
#define D8390_P0_PSTART 0x01
|
||||||
|
#define D8390_P0_PSTOP 0x02
|
||||||
|
#define D8390_P0_BOUND 0x03
|
||||||
|
#define D8390_P0_TSR 0x04
|
||||||
|
#define D8390_P0_TPSR 0x04
|
||||||
|
#define D8390_P0_TBCR0 0x05
|
||||||
|
#define D8390_P0_TBCR1 0x06
|
||||||
|
#define D8390_P0_ISR 0x07
|
||||||
|
#define D8390_P0_RSAR0 0x08
|
||||||
|
#define D8390_P0_RSAR1 0x09
|
||||||
|
#define D8390_P0_RBCR0 0x0A
|
||||||
|
#define D8390_P0_RBCR1 0x0B
|
||||||
|
#define D8390_P0_RSR 0x0C
|
||||||
|
#define D8390_P0_RCR 0x0C
|
||||||
|
#define D8390_P0_TCR 0x0D
|
||||||
|
#define D8390_P0_DCR 0x0E
|
||||||
|
#define D8390_P0_IMR 0x0F
|
||||||
|
#define D8390_P1_COMMAND 0x00
|
||||||
|
#define D8390_P1_PAR0 0x01
|
||||||
|
#define D8390_P1_PAR1 0x02
|
||||||
|
#define D8390_P1_PAR2 0x03
|
||||||
|
#define D8390_P1_PAR3 0x04
|
||||||
|
#define D8390_P1_PAR4 0x05
|
||||||
|
#define D8390_P1_PAR5 0x06
|
||||||
|
#define D8390_P1_CURR 0x07
|
||||||
|
#define D8390_P1_MAR0 0x08
|
||||||
|
|
||||||
|
#define D8390_COMMAND_PS0 0x0 /* Page 0 select */
|
||||||
|
#define D8390_COMMAND_PS1 0x40 /* Page 1 select */
|
||||||
|
#define D8390_COMMAND_PS2 0x80 /* Page 2 select */
|
||||||
|
#define D8390_COMMAND_RD2 0x20 /* Remote DMA control */
|
||||||
|
#define D8390_COMMAND_RD1 0x10
|
||||||
|
#define D8390_COMMAND_RD0 0x08
|
||||||
|
#define D8390_COMMAND_TXP 0x04 /* transmit packet */
|
||||||
|
#define D8390_COMMAND_STA 0x02 /* start */
|
||||||
|
#define D8390_COMMAND_STP 0x01 /* stop */
|
||||||
|
|
||||||
|
#define D8390_RCR_MON 0x20 /* monitor mode */
|
||||||
|
|
||||||
|
#define D8390_DCR_FT1 0x40
|
||||||
|
#define D8390_DCR_LS 0x08 /* Loopback select */
|
||||||
|
#define D8390_DCR_WTS 0x01 /* Word transfer select */
|
||||||
|
|
||||||
|
#define D8390_ISR_PRX 0x01 /* successful recv */
|
||||||
|
#define D8390_ISR_PTX 0x02 /* successful xmit */
|
||||||
|
#define D8390_ISR_RXE 0x04 /* receive error */
|
||||||
|
#define D8390_ISR_TXE 0x08 /* transmit error */
|
||||||
|
#define D8390_ISR_OVW 0x10 /* Overflow */
|
||||||
|
#define D8390_ISR_CNT 0x20 /* Counter overflow */
|
||||||
|
#define D8390_ISR_RDC 0x40 /* Remote DMA complete */
|
||||||
|
#define D8390_ISR_RST 0x80 /* reset */
|
||||||
|
|
||||||
|
#define D8390_RSTAT_PRX 0x01 /* successful recv */
|
||||||
|
#define D8390_RSTAT_CRC 0x02 /* CRC error */
|
||||||
|
#define D8390_RSTAT_FAE 0x04 /* Frame alignment error */
|
||||||
|
#define D8390_RSTAT_OVER 0x08 /* overflow */
|
||||||
|
|
||||||
|
#define D8390_TXBUF_SIZE 6
|
||||||
|
#define D8390_RXBUF_END 32
|
||||||
|
#define D8390_PAGE_SIZE 256
|
||||||
|
|
||||||
|
struct ringbuffer {
|
||||||
|
unsigned char status;
|
||||||
|
unsigned char next;
|
||||||
|
unsigned short len;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
|
|
261
netboot/pci.c
Normal file
261
netboot/pci.c
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
** Support for NE2000 PCI clones added David Monro June 1997
|
||||||
|
** Generalised to other NICs by Ken Yap July 1997
|
||||||
|
**
|
||||||
|
** Most of this is taken from:
|
||||||
|
**
|
||||||
|
** /usr/src/linux/drivers/pci/pci.c
|
||||||
|
** /usr/src/linux/include/linux/pci.h
|
||||||
|
** /usr/src/linux/arch/i386/bios32.c
|
||||||
|
** /usr/src/linux/include/linux/bios32.h
|
||||||
|
** /usr/src/linux/drivers/net/ne.c
|
||||||
|
**
|
||||||
|
** Limitations: only finds devices on bus 0 (I figure that anybody with
|
||||||
|
** a multi-pcibus machine will have something better than an ne2000)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "netboot.h"
|
||||||
|
#include "pci.h"
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
static unsigned int pci_ioaddr = 0;
|
||||||
|
|
||||||
|
static unsigned long bios32_entry = 0;
|
||||||
|
static struct {
|
||||||
|
unsigned long address;
|
||||||
|
unsigned short segment;
|
||||||
|
} bios32_indirect = { 0, KERN_CODE_SEG };
|
||||||
|
|
||||||
|
static long pcibios_entry = 0;
|
||||||
|
static struct {
|
||||||
|
unsigned long address;
|
||||||
|
unsigned short segment;
|
||||||
|
} pci_indirect = { 0, KERN_CODE_SEG };
|
||||||
|
|
||||||
|
static unsigned long bios32_service(unsigned long service)
|
||||||
|
{
|
||||||
|
unsigned char return_code; /* %al */
|
||||||
|
unsigned long address; /* %ebx */
|
||||||
|
unsigned long length; /* %ecx */
|
||||||
|
unsigned long entry; /* %edx */
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
__asm__("lcall (%%edi)"
|
||||||
|
: "=a" (return_code),
|
||||||
|
"=b" (address),
|
||||||
|
"=c" (length),
|
||||||
|
"=d" (entry)
|
||||||
|
: "0" (service),
|
||||||
|
"1" (0),
|
||||||
|
"D" (&bios32_indirect));
|
||||||
|
restore_flags(flags);
|
||||||
|
|
||||||
|
switch (return_code) {
|
||||||
|
case 0:
|
||||||
|
return address + entry;
|
||||||
|
case 0x80: /* Not present */
|
||||||
|
printf("bios32_service(%d) : not present\r\n", service);
|
||||||
|
return 0;
|
||||||
|
default: /* Shouldn't happen */
|
||||||
|
printf("bios32_service(%d) : returned 0x%x, mail drew@colorado.edu\r\n",
|
||||||
|
service, return_code);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcibios_read_config_byte(unsigned char bus,
|
||||||
|
unsigned char device_fn, unsigned char where, unsigned char *value)
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
unsigned long bx = (bus << 8) | device_fn;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
__asm__("lcall (%%esi)\n\t"
|
||||||
|
"jc 1f\n\t"
|
||||||
|
"xor %%ah, %%ah\n"
|
||||||
|
"1:"
|
||||||
|
: "=c" (*value),
|
||||||
|
"=a" (ret)
|
||||||
|
: "1" (PCIBIOS_READ_CONFIG_BYTE),
|
||||||
|
"b" (bx),
|
||||||
|
"D" ((long) where),
|
||||||
|
"S" (&pci_indirect));
|
||||||
|
restore_flags(flags);
|
||||||
|
return (int) (ret & 0xff00) >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcibios_read_config_dword (unsigned char bus,
|
||||||
|
unsigned char device_fn, unsigned char where, unsigned int *value)
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
unsigned long bx = (bus << 8) | device_fn;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
__asm__("lcall (%%esi)\n\t"
|
||||||
|
"jc 1f\n\t"
|
||||||
|
"xor %%ah, %%ah\n"
|
||||||
|
"1:"
|
||||||
|
: "=c" (*value),
|
||||||
|
"=a" (ret)
|
||||||
|
: "1" (PCIBIOS_READ_CONFIG_DWORD),
|
||||||
|
"b" (bx),
|
||||||
|
"D" ((long) where),
|
||||||
|
"S" (&pci_indirect));
|
||||||
|
restore_flags(flags);
|
||||||
|
return (int) (ret & 0xff00) >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_pcibios(void)
|
||||||
|
{
|
||||||
|
unsigned long signature;
|
||||||
|
unsigned char present_status;
|
||||||
|
unsigned char major_revision;
|
||||||
|
unsigned char minor_revision;
|
||||||
|
unsigned long flags;
|
||||||
|
int pack;
|
||||||
|
|
||||||
|
if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
|
||||||
|
pci_indirect.address = pcibios_entry;
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
__asm__("lcall (%%edi)\n\t"
|
||||||
|
"jc 1f\n\t"
|
||||||
|
"xor %%ah, %%ah\n"
|
||||||
|
"1:\tshl $8, %%eax\n\t"
|
||||||
|
"movw %%bx, %%ax"
|
||||||
|
: "=d" (signature),
|
||||||
|
"=a" (pack)
|
||||||
|
: "1" (PCIBIOS_PCI_BIOS_PRESENT),
|
||||||
|
"D" (&pci_indirect)
|
||||||
|
: "bx", "cx");
|
||||||
|
restore_flags(flags);
|
||||||
|
|
||||||
|
present_status = (pack >> 16) & 0xff;
|
||||||
|
major_revision = (pack >> 8) & 0xff;
|
||||||
|
minor_revision = pack & 0xff;
|
||||||
|
if (present_status || (signature != PCI_SIGNATURE)) {
|
||||||
|
printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
|
||||||
|
"BIOS????\r\n");
|
||||||
|
pcibios_entry = 0;
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
if (pcibios_entry) {
|
||||||
|
printf ("pcibios_init : PCI BIOS revision %b.%b"
|
||||||
|
" entry at 0x%X\r\n", major_revision,
|
||||||
|
minor_revision, pcibios_entry);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pcibios_init(void)
|
||||||
|
{
|
||||||
|
union bios32 *check;
|
||||||
|
unsigned char sum;
|
||||||
|
int i, length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Follow the standard procedure for locating the BIOS32 Service
|
||||||
|
* directory by scanning the permissible address range from
|
||||||
|
* 0xe0000 through 0xfffff for a valid BIOS32 structure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
|
||||||
|
if (check->fields.signature != BIOS32_SIGNATURE)
|
||||||
|
continue;
|
||||||
|
length = check->fields.length * 16;
|
||||||
|
if (!length)
|
||||||
|
continue;
|
||||||
|
sum = 0;
|
||||||
|
for (i = 0; i < length ; ++i)
|
||||||
|
sum += check->chars[i];
|
||||||
|
if (sum != 0)
|
||||||
|
continue;
|
||||||
|
if (check->fields.revision != 0) {
|
||||||
|
printf("pcibios_init : unsupported revision %d at 0x%X, mail drew@colorado.edu\r\n",
|
||||||
|
check->fields.revision, check);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
printf("pcibios_init : BIOS32 Service Directory "
|
||||||
|
"structure at 0x%X\r\n", check);
|
||||||
|
#endif
|
||||||
|
if (!bios32_entry) {
|
||||||
|
if (check->fields.entry >= 0x100000) {
|
||||||
|
printf("pcibios_init: entry in high "
|
||||||
|
"memory, giving up\r\n");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
bios32_entry = check->fields.entry;
|
||||||
|
#if DEBUG
|
||||||
|
printf("pcibios_init : BIOS32 Service Directory"
|
||||||
|
" entry at 0x%X\r\n", bios32_entry);
|
||||||
|
#endif
|
||||||
|
bios32_indirect.address = bios32_entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bios32_entry)
|
||||||
|
check_pcibios();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scan_bus(struct pci_device *pcidev)
|
||||||
|
{
|
||||||
|
unsigned int devfn, l;
|
||||||
|
unsigned char hdr_type = 0;
|
||||||
|
unsigned short vendor, device;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (devfn = 0; devfn < 0xff; ++devfn) {
|
||||||
|
if (PCI_FUNC(devfn) == 0) {
|
||||||
|
pcibios_read_config_byte(0, devfn,
|
||||||
|
PCI_HEADER_TYPE, &hdr_type);
|
||||||
|
} else if (!(hdr_type & 0x80)) {
|
||||||
|
/* not a multi-function device */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcibios_read_config_dword(0, devfn,
|
||||||
|
PCI_VENDOR_ID, &l);
|
||||||
|
/* some broken boards return 0 if a slot is empty: */
|
||||||
|
if (l == 0xffffffff || l == 0x00000000) {
|
||||||
|
hdr_type = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vendor = l & 0xffff;
|
||||||
|
device = (l >> 16) & 0xffff;
|
||||||
|
#if DEBUG
|
||||||
|
printf("bus 0, function %x, vendor %x, device %x\r\n",
|
||||||
|
devfn, vendor, device);
|
||||||
|
#endif
|
||||||
|
for (i = 0; pcidev[i].vendor != 0; i++) {
|
||||||
|
if (vendor == pcidev[i].vendor
|
||||||
|
&& device == pcidev[i].dev_id) {
|
||||||
|
pcibios_read_config_dword(0, devfn,
|
||||||
|
PCI_BASE_ADDRESS_0, &pci_ioaddr);
|
||||||
|
/* Strip the I/O address out of the
|
||||||
|
* returned value */
|
||||||
|
pci_ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
|
||||||
|
printf("Found %s at 0x%x\r\n",
|
||||||
|
pcidev[i].name, pci_ioaddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eth_pci_init(struct pci_device *pcidev, unsigned short *ioaddr)
|
||||||
|
{
|
||||||
|
pcibios_init();
|
||||||
|
if (!pcibios_entry) {
|
||||||
|
printf("pci_init: no BIOS32 detected\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scan_bus(pcidev);
|
||||||
|
/* we only return one address at the moment, maybe more later? */
|
||||||
|
*ioaddr = pci_ioaddr;
|
||||||
|
}
|
89
netboot/pci.h
Normal file
89
netboot/pci.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
** Support for NE2000 PCI clones added David Monro June 1997
|
||||||
|
** Generalised for other PCI NICs by Ken Yap July 1997
|
||||||
|
**
|
||||||
|
** Most of this is taken from:
|
||||||
|
**
|
||||||
|
** /usr/src/linux/drivers/pci/pci.c
|
||||||
|
** /usr/src/linux/include/linux/pci.h
|
||||||
|
** /usr/src/linux/arch/i386/bios32.c
|
||||||
|
** /usr/src/linux/include/linux/bios32.h
|
||||||
|
** /usr/src/linux/drivers/net/ne.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
|
||||||
|
#define PCIBIOS_PCI_BIOS_PRESENT 0xb101
|
||||||
|
#define PCIBIOS_FIND_PCI_DEVICE 0xb102
|
||||||
|
#define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103
|
||||||
|
#define PCIBIOS_GENERATE_SPECIAL_CYCLE 0xb106
|
||||||
|
#define PCIBIOS_READ_CONFIG_BYTE 0xb108
|
||||||
|
#define PCIBIOS_READ_CONFIG_WORD 0xb109
|
||||||
|
#define PCIBIOS_READ_CONFIG_DWORD 0xb10a
|
||||||
|
#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
|
||||||
|
#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
|
||||||
|
#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
|
||||||
|
|
||||||
|
#define PCI_VENDOR_ID 0x00 /* 16 bits */
|
||||||
|
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
||||||
|
#define PCI_COMMAND 0x04 /* 16 bits */
|
||||||
|
|
||||||
|
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
||||||
|
|
||||||
|
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
|
||||||
|
|
||||||
|
#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
|
||||||
|
|
||||||
|
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
||||||
|
|
||||||
|
#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
|
||||||
|
|
||||||
|
/* PCI signature: "PCI " */
|
||||||
|
#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
|
||||||
|
|
||||||
|
/* PCI service signature: "$PCI" */
|
||||||
|
#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
|
||||||
|
|
||||||
|
union bios32 {
|
||||||
|
struct {
|
||||||
|
unsigned long signature; /* _32_ */
|
||||||
|
unsigned long entry; /* 32 bit physical address */
|
||||||
|
unsigned char revision; /* Revision level, 0 */
|
||||||
|
unsigned char length; /* Length in paragraphs should be 01 */
|
||||||
|
unsigned char checksum; /* All bytes must add up to zero */
|
||||||
|
unsigned char reserved[5]; /* Must be zero */
|
||||||
|
} fields;
|
||||||
|
char chars[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define KERN_CODE_SEG 0x8 /* This _MUST_ match start.S */
|
||||||
|
|
||||||
|
/* Stuff for asm */
|
||||||
|
#define save_flags(x) \
|
||||||
|
__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
|
||||||
|
|
||||||
|
#define restore_flags(x) \
|
||||||
|
__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
|
||||||
|
|
||||||
|
#define PCI_VENDOR_ID_REALTEK 0x10ec
|
||||||
|
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
|
||||||
|
#define PCI_VENDOR_ID_WINBOND2 0x1050
|
||||||
|
#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
|
||||||
|
#define PCI_VENDOR_ID_COMPEX 0x11f6
|
||||||
|
#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
|
||||||
|
#define PCI_VENDOR_ID_KTI 0x8e2e
|
||||||
|
#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
|
||||||
|
#define PCI_VENDOR_ID_INTEL 0x8086
|
||||||
|
#define PCI_DEVICE_ID_INTEL_82557 0x1229
|
||||||
|
#define PCI_VENDOR_ID_NETVIN 0x4a14
|
||||||
|
#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
|
||||||
|
#define PCI_VENDOR_ID_VIA 0x1106
|
||||||
|
#define PCI_DEVICE_ID_VIA_82C926 0x0926
|
||||||
|
#define PCI_VENDOR_ID_SURECOM 0x10bd
|
||||||
|
#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34
|
||||||
|
|
||||||
|
struct pci_device {
|
||||||
|
unsigned short vendor, dev_id;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void eth_pci_init(struct pci_device *, unsigned short *);
|
|
@ -67,6 +67,8 @@ GRUB_LIBS = @GRUB_LIBS@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NET_CFLAGS = @NET_CFLAGS@
|
||||||
|
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||||
OBJCOPY = @OBJCOPY@
|
OBJCOPY = @OBJCOPY@
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
|
|
@ -398,7 +398,7 @@ lastlist:
|
||||||
#else
|
#else
|
||||||
.long 1 /* this is the sector start parameter, in logical
|
.long 1 /* this is the sector start parameter, in logical
|
||||||
sectors from the start of the disk, sector 0 */
|
sectors from the start of the disk, sector 0 */
|
||||||
.word 110 /* this is the number of sectors to read */
|
.word 130 /* this is the number of sectors to read */
|
||||||
.word 0x0800 /* this is the segment of the starting address
|
.word 0x0800 /* this is the segment of the starting address
|
||||||
to load the data into */
|
to load the data into */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -345,7 +345,7 @@ lastlist:
|
||||||
#else
|
#else
|
||||||
.long 1 /* this is the sector start parameter, in logical
|
.long 1 /* this is the sector start parameter, in logical
|
||||||
sectors from the start of the disk, sector 0 */
|
sectors from the start of the disk, sector 0 */
|
||||||
.word 110 /* this is the number of sectors to read */
|
.word 130 /* this is the number of sectors to read */
|
||||||
.word 0x0800 /* this is the segment of the starting address
|
.word 0x0800 /* this is the segment of the starting address
|
||||||
to load the data into */
|
to load the data into */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,6 +43,10 @@ stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c common.c \
|
||||||
stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
|
stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
|
||||||
stage2_exec_LDFLAGS = $(STAGE2_LINK)
|
stage2_exec_LDFLAGS = $(STAGE2_LINK)
|
||||||
|
|
||||||
|
if NETBOOT_SUPPORT
|
||||||
|
stage2_exec_LDADD = ../netboot/libdrivers.a
|
||||||
|
endif
|
||||||
|
|
||||||
# For e2fs_stage1_5 target.
|
# For e2fs_stage1_5 target.
|
||||||
e2fs_stage1_5_exec_SOURCES = asm.S common.c char_io.c disk_io.c \
|
e2fs_stage1_5_exec_SOURCES = asm.S common.c char_io.c disk_io.c \
|
||||||
stage1_5.c fsys_ext2fs.c bios.c
|
stage1_5.c fsys_ext2fs.c bios.c
|
||||||
|
|
|
@ -67,6 +67,8 @@ GRUB_LIBS = @GRUB_LIBS@
|
||||||
LD = @LD@
|
LD = @LD@
|
||||||
MAINT = @MAINT@
|
MAINT = @MAINT@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NET_CFLAGS = @NET_CFLAGS@
|
||||||
|
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||||
OBJCOPY = @OBJCOPY@
|
OBJCOPY = @OBJCOPY@
|
||||||
PACKAGE = @PACKAGE@
|
PACKAGE = @PACKAGE@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
@ -132,6 +134,8 @@ stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c common.c \
|
||||||
stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
|
stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
|
||||||
stage2_exec_LDFLAGS = $(STAGE2_LINK)
|
stage2_exec_LDFLAGS = $(STAGE2_LINK)
|
||||||
|
|
||||||
|
@NETBOOT_SUPPORT_TRUE@stage2_exec_LDADD = @NETBOOT_SUPPORT_TRUE@../netboot/libdrivers.a
|
||||||
|
|
||||||
# For e2fs_stage1_5 target.
|
# For e2fs_stage1_5 target.
|
||||||
e2fs_stage1_5_exec_SOURCES = asm.S common.c char_io.c disk_io.c \
|
e2fs_stage1_5_exec_SOURCES = asm.S common.c char_io.c disk_io.c \
|
||||||
stage1_5.c fsys_ext2fs.c bios.c
|
stage1_5.c fsys_ext2fs.c bios.c
|
||||||
|
@ -223,8 +227,8 @@ stage2_exec-gunzip.o stage2_exec-fsys_ext2fs.o stage2_exec-fsys_fat.o \
|
||||||
stage2_exec-fsys_ffs.o stage2_exec-fsys_minix.o stage2_exec-smp-imps.o \
|
stage2_exec-fsys_ffs.o stage2_exec-fsys_minix.o stage2_exec-smp-imps.o \
|
||||||
stage2_exec-stage2.o
|
stage2_exec-stage2.o
|
||||||
stage2_exec_OBJECTS = $(am_stage2_exec_OBJECTS)
|
stage2_exec_OBJECTS = $(am_stage2_exec_OBJECTS)
|
||||||
stage2_exec_LDADD = $(LDADD)
|
@NETBOOT_SUPPORT_TRUE@stage2_exec_DEPENDENCIES = \
|
||||||
stage2_exec_DEPENDENCIES =
|
@NETBOOT_SUPPORT_TRUE@../netboot/libdrivers.a
|
||||||
SCRIPTS = $(noinst_SCRIPTS)
|
SCRIPTS = $(noinst_SCRIPTS)
|
||||||
|
|
||||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
|
31
stage2/asm.S
31
stage2/asm.S
|
@ -1328,6 +1328,37 @@ gottime:
|
||||||
pop %ebp
|
pop %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef STAGE1_5
|
||||||
|
/*
|
||||||
|
* currticks()
|
||||||
|
* return the real time in ticks, of which there are about
|
||||||
|
* 18-20 per second
|
||||||
|
*/
|
||||||
|
ENTRY(currticks)
|
||||||
|
pushl %ebp
|
||||||
|
pushl %ecx
|
||||||
|
pushl %edx
|
||||||
|
|
||||||
|
call EXT_C(prot_to_real) /* enter real mode */
|
||||||
|
.code16
|
||||||
|
|
||||||
|
xorl %eax, %eax
|
||||||
|
int $0x1a
|
||||||
|
|
||||||
|
DATA32 call EXT_C(real_to_prot)
|
||||||
|
.code32
|
||||||
|
|
||||||
|
shll $16, %ecx
|
||||||
|
movl %edx, %eax
|
||||||
|
orl %ecx, %eax
|
||||||
|
|
||||||
|
popl %edx
|
||||||
|
popl %ecx
|
||||||
|
popl %ebp
|
||||||
|
ret
|
||||||
|
#endif /* ! STAGE1_5 */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getkey()
|
* getkey()
|
||||||
|
|
|
@ -126,6 +126,53 @@ grub_printf (const char *format,...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef STAGE1_5
|
||||||
|
int
|
||||||
|
grub_sprintf (char *buffer, const char *format, ...)
|
||||||
|
{
|
||||||
|
/* XXX hohmuth
|
||||||
|
ugly hack -- should unify with printf() */
|
||||||
|
int *dataptr = (int *) &format;
|
||||||
|
char c, *ptr, str[16];
|
||||||
|
char *bp = buffer;
|
||||||
|
|
||||||
|
dataptr++;
|
||||||
|
|
||||||
|
while ((c = *format++) != 0)
|
||||||
|
{
|
||||||
|
if (c != '%')
|
||||||
|
*bp++ = c; /* putchar(c); */
|
||||||
|
else
|
||||||
|
switch (c = *(format++))
|
||||||
|
{
|
||||||
|
case 'd': case 'u': case 'x':
|
||||||
|
*convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
|
||||||
|
|
||||||
|
ptr = str;
|
||||||
|
|
||||||
|
while (*ptr)
|
||||||
|
*bp++ = *(ptr++); /* putchar(*(ptr++)); */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c': *bp++ = (*(dataptr++))&0xff;
|
||||||
|
/* putchar((*(dataptr++))&0xff); */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
ptr = (char *) (*(dataptr++));
|
||||||
|
|
||||||
|
while ((c = *ptr++) != 0)
|
||||||
|
*bp++ = c; /* putchar(c); */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*bp = 0;
|
||||||
|
return bp - buffer;
|
||||||
|
}
|
||||||
|
#endif /* ! STAGE1_5 */
|
||||||
|
|
||||||
|
|
||||||
#ifndef STAGE1_5
|
#ifndef STAGE1_5
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -520,6 +567,24 @@ grub_isspace (int c)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef STAGE1_5
|
||||||
|
int
|
||||||
|
grub_memcmp (const char *s1, const char *s2, int n)
|
||||||
|
{
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
if (*s1 < *s2)
|
||||||
|
return -1;
|
||||||
|
else if (*s1 > *s2)
|
||||||
|
return 1;
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* ! STAGE1_5 */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int
|
int
|
||||||
|
|
|
@ -35,6 +35,10 @@ int print_possibilities;
|
||||||
int fsmax;
|
int fsmax;
|
||||||
struct fsys_entry fsys_table[NUM_FSYS + 1] =
|
struct fsys_entry fsys_table[NUM_FSYS + 1] =
|
||||||
{
|
{
|
||||||
|
/* TFTP should come first because others don't handle net device. */
|
||||||
|
# ifdef FSYS_TFTP
|
||||||
|
{"tftp", tftp_mount, tftp_read, tftp_dir},
|
||||||
|
# endif
|
||||||
# ifdef FSYS_FAT
|
# ifdef FSYS_FAT
|
||||||
{"fat", fat_mount, 0, fat_dir},
|
{"fat", fat_mount, 0, fat_dir},
|
||||||
# endif
|
# endif
|
||||||
|
@ -236,6 +240,12 @@ devread (int sector, int byte_offset, int byte_len, char *buf)
|
||||||
static int
|
static int
|
||||||
sane_partition (void)
|
sane_partition (void)
|
||||||
{
|
{
|
||||||
|
#ifndef STAGE1_5
|
||||||
|
/* network drive */
|
||||||
|
if (current_drive == 0x20)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(current_partition & 0xFF000000uL)
|
if (!(current_partition & 0xFF000000uL)
|
||||||
&& (current_drive & 0xFFFFFF7F) < 8
|
&& (current_drive & 0xFFFFFF7F) < 8
|
||||||
&& (current_partition & 0xFF) == 0xFF
|
&& (current_partition & 0xFF) == 0xFF
|
||||||
|
@ -440,6 +450,10 @@ real_open_partition (int flags)
|
||||||
int i, part_no, slice_no, ext = 0;
|
int i, part_no, slice_no, ext = 0;
|
||||||
|
|
||||||
#ifndef STAGE1_5
|
#ifndef STAGE1_5
|
||||||
|
/* network drive */
|
||||||
|
if (current_drive == 0x20)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (! sane_partition ())
|
if (! sane_partition ())
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -674,15 +688,20 @@ set_device (char *device)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((*device == 'f' || *device == 'h')
|
if ((*device == 'f' || *device == 'h' || *device == 'n')
|
||||||
&& (device += 2, (*(device - 1) != 'd')))
|
&& (device += 2, (*(device - 1) != 'd')))
|
||||||
errnum = ERR_NUMBER_PARSING;
|
errnum = ERR_NUMBER_PARSING;
|
||||||
|
|
||||||
safe_parse_maxint (&device, (int *) ¤t_drive);
|
if (ch == 'n')
|
||||||
|
current_drive = 0x20;
|
||||||
disk_choice = 0;
|
else
|
||||||
if (ch == 'h')
|
{
|
||||||
current_drive += 0x80;
|
safe_parse_maxint (&device, (int *) ¤t_drive);
|
||||||
|
|
||||||
|
disk_choice = 0;
|
||||||
|
if (ch == 'h')
|
||||||
|
current_drive += 0x80;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errnum)
|
if (errnum)
|
||||||
|
|
|
@ -60,9 +60,19 @@ int minix_dir (char *dirname);
|
||||||
#define FSYS_MINIX_NUM 0
|
#define FSYS_MINIX_NUM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FSYS_TFTP
|
||||||
|
#define FSYS_TFTP_NUM 1
|
||||||
|
int tftp_mount (void);
|
||||||
|
int tftp_read (char *buf, int len);
|
||||||
|
int tftp_dir (char *dirname);
|
||||||
|
#else
|
||||||
|
#define FSYS_TFTP_NUM 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NUM_FSYS
|
#ifndef NUM_FSYS
|
||||||
#define NUM_FSYS \
|
#define NUM_FSYS \
|
||||||
(FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM)
|
(FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM \
|
||||||
|
+ FSYS_TFTP_NUM)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* defines for the block filesystem info area */
|
/* defines for the block filesystem info area */
|
||||||
|
|
|
@ -269,7 +269,11 @@ int
|
||||||
gunzip_test_header (void)
|
gunzip_test_header (void)
|
||||||
{
|
{
|
||||||
unsigned char buf[10];
|
unsigned char buf[10];
|
||||||
|
int is_tftp = 0;
|
||||||
|
|
||||||
|
if (grub_strcmp (fsys_table[fsys_type].name, "tftp") == 0)
|
||||||
|
is_tftp = 1;
|
||||||
|
|
||||||
/* "compressed_file" is already reset to zero by this point */
|
/* "compressed_file" is already reset to zero by this point */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -277,12 +281,13 @@ gunzip_test_header (void)
|
||||||
* (other than a real error with the disk) then we don't think it
|
* (other than a real error with the disk) then we don't think it
|
||||||
* is a compressed file, and simply mark it as such.
|
* is a compressed file, and simply mark it as such.
|
||||||
*/
|
*/
|
||||||
if (no_decompression || grub_read (buf, 10) != 10
|
if (no_decompression
|
||||||
|
|| grub_read (buf, 10) != 10
|
||||||
|| ((*((unsigned short *) buf) != GZIP_HDR_LE)
|
|| ((*((unsigned short *) buf) != GZIP_HDR_LE)
|
||||||
& (*((unsigned short *) buf) != OLD_GZIP_HDR_LE)))
|
&& (*((unsigned short *) buf) != OLD_GZIP_HDR_LE)))
|
||||||
{
|
{
|
||||||
filepos = 0;
|
filepos = 0;
|
||||||
return (!errnum);
|
return ! errnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -290,23 +295,44 @@ gunzip_test_header (void)
|
||||||
* problem occurs from here on, then we have corrupt or otherwise
|
* problem occurs from here on, then we have corrupt or otherwise
|
||||||
* bad data, and the error should be reported to the user.
|
* bad data, and the error should be reported to the user.
|
||||||
*/
|
*/
|
||||||
if (buf[2] != DEFLATED || (buf[3] & UNSUPP_FLAGS)
|
if (buf[2] != DEFLATED
|
||||||
|
|| (buf[3] & UNSUPP_FLAGS)
|
||||||
|| ((buf[3] & EXTRA_FIELD)
|
|| ((buf[3] & EXTRA_FIELD)
|
||||||
&& (grub_read (buf, 2) != 2 ||
|
&& (grub_read (buf, 2) != 2
|
||||||
bad_field (*((unsigned short *) buf))))
|
|| bad_field (*((unsigned short *) buf))))
|
||||||
|| ((buf[3] & ORIG_NAME) && bad_field (-1))
|
|| ((buf[3] & ORIG_NAME) && bad_field (-1))
|
||||||
|| ((buf[3] & COMMENT) && bad_field (-1))
|
|| ((buf[3] & COMMENT) && bad_field (-1)))
|
||||||
|| ((gzip_data_offset = filepos), (filepos = filemax - 8),
|
|
||||||
(grub_read (buf, 8) != 8)))
|
|
||||||
{
|
{
|
||||||
if (!errnum)
|
if (! errnum)
|
||||||
errnum = ERR_BAD_GZIP_HEADER;
|
errnum = ERR_BAD_GZIP_HEADER;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gzip_crc = *((unsigned long *) buf);
|
gzip_data_offset = filepos;
|
||||||
gzip_fsmax = gzip_filemax = *((unsigned long *) (buf + 4));
|
|
||||||
|
if (! is_tftp)
|
||||||
|
filepos = filemax - 8;
|
||||||
|
|
||||||
|
if (grub_read (buf, 8) != 8)
|
||||||
|
{
|
||||||
|
if (! errnum)
|
||||||
|
errnum = ERR_BAD_GZIP_HEADER;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! is_tftp)
|
||||||
|
{
|
||||||
|
gzip_crc = *((unsigned long *) buf);
|
||||||
|
gzip_fsmax = gzip_filemax = *((unsigned long *) (buf + 4));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We don't have gzip_crc. */
|
||||||
|
gzip_fsmax = gzip_filemax = 16 * 1024 * 1024;
|
||||||
|
filepos = filemax;
|
||||||
|
}
|
||||||
|
|
||||||
initialize_tables ();
|
initialize_tables ();
|
||||||
|
|
||||||
|
|
|
@ -263,10 +263,12 @@ extern char *grub_scratch_mem;
|
||||||
#define memset grub_memset
|
#define memset grub_memset
|
||||||
#define isspace grub_isspace
|
#define isspace grub_isspace
|
||||||
#define printf grub_printf
|
#define printf grub_printf
|
||||||
|
#define sprintf grub_sprintf
|
||||||
#undef putchar
|
#undef putchar
|
||||||
#define putchar grub_putchar
|
#define putchar grub_putchar
|
||||||
#define strncat grub_strncat
|
#define strncat grub_strncat
|
||||||
#define strstr grub_strstr
|
#define strstr grub_strstr
|
||||||
|
#define memcmp grub_memcmp
|
||||||
#define strcmp grub_strcmp
|
#define strcmp grub_strcmp
|
||||||
#define tolower grub_tolower
|
#define tolower grub_tolower
|
||||||
#define strlen grub_strlen
|
#define strlen grub_strlen
|
||||||
|
@ -494,6 +496,7 @@ int get_code_end (void);
|
||||||
|
|
||||||
/* low-level timing info */
|
/* low-level timing info */
|
||||||
int getrtsecs (void);
|
int getrtsecs (void);
|
||||||
|
int currticks (void);
|
||||||
|
|
||||||
/* Clear the screen. */
|
/* Clear the screen. */
|
||||||
void cls (void);
|
void cls (void);
|
||||||
|
@ -585,12 +588,14 @@ int run_script (char *script, char *heap);
|
||||||
|
|
||||||
/* C library replacement functions with identical semantics. */
|
/* C library replacement functions with identical semantics. */
|
||||||
void grub_printf (const char *format,...);
|
void grub_printf (const char *format,...);
|
||||||
|
int grub_sprintf (char *buffer, const char *format, ...);
|
||||||
int grub_tolower (int c);
|
int grub_tolower (int c);
|
||||||
int grub_isspace (int c);
|
int grub_isspace (int c);
|
||||||
int grub_strncat (char *s1, const char *s2, int n);
|
int grub_strncat (char *s1, const char *s2, int n);
|
||||||
char *grub_memmove (char *to, const char *from, int len);
|
char *grub_memmove (char *to, const char *from, int len);
|
||||||
void *grub_memset (void *start, int c, int len);
|
void *grub_memset (void *start, int c, int len);
|
||||||
char *grub_strstr (const char *s1, const char *s2);
|
char *grub_strstr (const char *s1, const char *s2);
|
||||||
|
int grub_memcmp (const char *s1, const char *s2, int n);
|
||||||
int grub_strcmp (const char *s1, const char *s2);
|
int grub_strcmp (const char *s1, const char *s2);
|
||||||
int grub_strlen (const char *str);
|
int grub_strlen (const char *str);
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ check minix_stage1_5 31744
|
||||||
|
|
||||||
# This limitation is arbitrary; If you want to make this larger, just
|
# This limitation is arbitrary; If you want to make this larger, just
|
||||||
# modify Stage 1.
|
# modify Stage 1.
|
||||||
check stage2 56320
|
check stage2 66560
|
||||||
|
|
||||||
# Success.
|
# Success.
|
||||||
exit 0
|
exit 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue