Remove all files not related to Multiboot.

This commit is contained in:
Robert Millan 2009-11-13 15:19:32 +00:00
parent 89e617e847
commit 29bfa2494c
179 changed files with 0 additions and 99150 deletions

7
BUGS
View file

@ -1,7 +0,0 @@
See the Bug Tracking System for GNU GRUB on Savannah. The URL is:
http://savannah.gnu.org/bugs/?group_id=68 (without SSL)
or
https://savannah.gnu.org/bugs/?group_id=68 (with SSL)

View file

@ -1,60 +0,0 @@
-*- text -*-
This is a list of random notes for GRUB maintainers. If you are not a
maintainer, you need to ask maintainers to do these instead of doing
these yourself.
How to update the online manual: (FIXME: this is obsoelete)
1. Copy docs/*.texi (excluding "multiboot.texi") to fencepost.gnu.org.
2. Make a symbolic link from ~mohit/gnudoc/gnudoc_template to the
directory under which *.texi were copied, if the link isn't present.
3. Run ``~mohit/gnudoc/gendocs.sh grub "GNU GRUB Manual"''.
4. Copy the contents of the directory ``manual'' to
gnudist.gnu.org:~ftp/gnu/Manuals/grub-VERSION (VERSION is, for
example, 1.0).
5. Run ``ln -sf grub-VERSION grub'' in gnudist.gnu.org:~ftp/gnu/Manuals.
6. Run ``cd grub; ln -s grub.html index.html''.
7. Verify the new online manual with a WWW browser.
8. Update manual.html by hand.
How to release a version:
1. Check out the source tree from the CVS from scratch.
2. Check if ``make distcheck'' succeeds.
3. Run ``util/grub-image''.
4. Check the resulted images, for example, using bochs.
5. Copy grub-VERSION.tar.gz, grub-VERSION-i386-pc.tar.gz and
grub-VERSION-i386-pc.ext2fs to fencepost.gnu.org:~ftp/gnu/grub.
6. Move older files in that directory above to the directory ``old'',
if you think they are eyesores.
7. Post an announcement to bug-grub@gnu.org. It would be a good idea to
send a carbon copy to bug-hurd@gnu.org and
debian-hurd@lists.debian.org. If the announcement is for a stable
version, you can inform info-gnu@gnu.org as well.
8. Optionally, post an announcement to Freshmeat.net.
Legal issues:
1. If a patch is not significant (in size), you don't have to care about
the copyright.
2. If a patch is significant, you shouldn't apply the patch to the CVS.
Before doing that, you must ask the contributor to assign or disclaim
the copyright. Send ``/gd/gnuorg/request-assign.changes'' or
``/gd/gnuorg/request-assign.future'' to the contributor, and wait
until the FSF finishes the legal work.
3. You can check if a contributor has already assigned his/her copyright
to the FSF by looking at ``/gd/gnuorg/copyright.list''.
What you should have in your mind:
1. Don't add features unnecessarily! You may think it is a Good Thing to
have more features, but you must be prepared for more burdens.
DO THAT ONLY IF YOU BELIEVE THAT THE FEATURE IS ESSENTIAL.
2. Don't break backward-compatibility! Don't apply any patch which could
break existing features. Otherwise you would receive a lot of
complaints. DO THAT ONLY IF YOU BELIEVE THAT THE INCOMPATIBILITY IS
INEVITABLE.
3. Write good code. Be not satisfied with ad hoc workarounds or quick
hacks. NEVER WRITE BAD CODE.
Resources:
* http://www.gnu.org/prep/maintain_toc.html
* http://www.gnu.org/prep/standards_toc.html
* http://www.gnu.org/server/fsf-html-style-sheet.html

View file

@ -1,605 +0,0 @@
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 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.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
THANKS TODO compile config.guess config.sub depcomp install-sh \
missing mkinstalldirs
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FSYS_CFLAGS = @FSYS_CFLAGS@
GRUB_CFLAGS = @GRUB_CFLAGS@
GRUB_LIBS = @GRUB_LIBS@
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
NET_CFLAGS = @NET_CFLAGS@
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
RANLIB = @RANLIB@
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STAGE1_CFLAGS = @STAGE1_CFLAGS@
STAGE2_CFLAGS = @STAGE2_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
# Do not change this order if you don't know what you are doing.
AUTOMAKE_OPTIONS = 1.7 gnu
SUBDIRS = netboot stage2 stage1 lib grub util docs
EXTRA_DIST = BUGS MAINTENANCE
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
cd $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(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 -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(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; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(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 "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkdir_p) $(distdir)/util
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(mkdir_p) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
check-am clean clean-generic clean-recursive ctags \
ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
dist-tarZ dist-zip distcheck distclean distclean-generic \
distclean-hdr distclean-recursive distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic maintainer-clean-recursive \
mostlyclean mostlyclean-generic mostlyclean-recursive pdf \
pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
uninstall-info-am
# 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:

102
TODO
View file

@ -1,102 +0,0 @@
-*- Mode: Outline -*-
Before working on anything in this file, it's very important that you
make contact with the core GRUB developers. Things herein might be
slightly out of date or otherwise not easy to understand at first
glance. So write to <bug-grub@gnu.org> first.
Priorities:
Reported bugs generally have top priority.
Non-reported and non-encountered bugs (things we know don't work,
but don't really impede things) have lower priority.
Things in this file are ranked with one to three !; the more, the
higher priority.
Things that should be done before 1.0:
* Finish the Multiboot Speicification 0.7. !!!
* Add more --disable-FOO options to configure, so that you can create a
minimum GRUB image. This is useful for boot floppies because of the size
restriction. !
* Implement a new version of track_int13, using Virtual 8086 Mode. !!!
* Add missing features of graphics support. !!
Things that should _not_ be done before 1.0:
* Add configuration inclusion support by adding a command "include". !
* Add automatic configuration support.
* Add bunzip2 support.
* Define the module system.
* Add BSD syntax support, using results of ioprobe to map drives. !
(0x1f0-0x1f7 = primary IDE, 0x170-0x176 = secondary,
0x1e8-0x1ef = tertiary, 0x168-0x16f = quaternary).
* Add a real scripting language, possibly retaining backward
compatibility so that old config files can be used.
* Add internationalization support, emulating gettext as much as is
feasible.
* Support other architectures than i386-pc.
* Add real memory management.
Things that may be done anytime:
* Port the script ``grub-install'' to OpenBSD. At least you will have to
modify the function `convert' so that it can translate a native device
name into the corresponding GRUB drive representation. !
* Add a command to run a GRUB script file. !!
* Add commands to manipulate the menu from the command-line interface. !
* Make symbolic links work for BSD FFS.
* Add indirect block support to the BSD FFS filesystem code, so files
larger than 16MB can be read.
* Fix-up FreeBSD, NetBSD (and OpenBSD ?) command-line boot
parameters.
* Support embedding a Stage 1.5 in the "bootloader" area of a FFS
partition. (We already have the code, but need an approval by an
expert before turning on the support. Any volunteers?)
* Support embedding a Stage 1.5 in the EXT2_BOOT_LOADER_INO of an ext2fs
partition, so that it won't be accidentally erased or modified by
the kernel.
* Add ISA PnP support.
* Add more filesystems support (NTFS, etc.)
* Add more remote console support (parallel and net).
* Add (real) RAID support.
? Add a partition naming syntax that means ``the first partition of
this type''. We need this for clean Hurd install floppies.
Nope. Improving the `find' command would solve this problem.
* Add CDROM-chainloading support. It would be enough to support only
BIOSes which have bootable-CDROM support (so you may use the "Bootable
CDROM" BIOS calls). It is not trivial to support BIOSes without the
capability to boot CDROM.
? Divide pxegrub into two parts, so the initial image doesn't exceed
the 32KB limit. I'm not sure if this is really necessary, because the
PXE standard just says that it is _recommended_ to improve the
modularity of a boot image. Obviously, this reason doesn't apply to
GRUB, as pxegrub is merely a secondary boot loader. So whether this
task should be done depends on if existing PXE ROMs support >32KB
images or not, after all.

View file

@ -1,366 +0,0 @@
dnl grub_ASM_USCORE checks if C symbols get an underscore after
dnl compiling to assembler.
dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by
dnl Erich Boleyn and modified by OKUJI Yoshinori
AC_DEFUN([grub_ASM_USCORE],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if C symbols get an underscore after compilation])
AC_CACHE_VAL(grub_cv_asm_uscore,
[cat > conftest.c <<\EOF
int
func (int *list)
{
*list = 0;
return *list;
}
EOF
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then
true
else
AC_MSG_ERROR([${CC-cc} failed to produce assembly code])
fi
if grep _func conftest.s >/dev/null 2>&1; then
grub_cv_asm_uscore=yes
else
grub_cv_asm_uscore=no
fi
rm -f conftest*])
if test "x$grub_cv_asm_uscore" = xyes; then
AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore,
[Define if C symbols get an underscore after compilation])
fi
AC_MSG_RESULT([$grub_cv_asm_uscore])
])
dnl Some versions of `objcopy -O binary' vary their output depending
dnl on the link address.
AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses])
AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
[cat > conftest.c <<\EOF
void
cmain (void)
{
*((int *) 0x1000) = 2;
}
EOF
if AC_TRY_EVAL(ac_compile) && test -s conftest.o; then :
else
AC_MSG_ERROR([${CC-cc} cannot compile C source code])
fi
grub_cv_prog_objcopy_absolute=yes
for link_addr in 2000 8000 7C00; do
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} ${LDFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
else
AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
fi
if AC_TRY_COMMAND([${OBJCOPY-objcopy} -O binary conftest.exec conftest]); then :
else
AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files])
fi
if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then
mv -f conftest conftest.old
else
grub_cv_prog_objcopy_absolute=no
break
fi
done
rm -f conftest*])
AC_MSG_RESULT([$grub_cv_prog_objcopy_absolute])])
dnl Mass confusion!
dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit
dnl instructions, but implicitly insert addr32 and data32 bytes so
dnl that the code works in real mode''.
dnl
dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit
dnl instructions,'' which seems right. This requires the programmer
dnl to explicitly insert addr32 and data32 instructions when they want
dnl them.
dnl
dnl We only support the newer versions, because the old versions cause
dnl major pain, by requiring manual assembly to get 16-bit instructions into
dnl stage1/stage1.S.
AC_DEFUN([grub_ASM_ADDR32],
[AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([grub_ASM_PREFIX_REQUIREMENT])
AC_MSG_CHECKING([for .code16 addr32 assembler support])
AC_CACHE_VAL(grub_cv_asm_addr32,
[cat > conftest.s.in <<\EOF
.code16
l1: @ADDR32@ movb %al, l1
EOF
if test "x$grub_cv_asm_prefix_requirement" = xyes; then
sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s
else
sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
fi
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
grub_cv_asm_addr32=yes
else
grub_cv_asm_addr32=no
fi
rm -f conftest*])
AC_MSG_RESULT([$grub_cv_asm_addr32])])
dnl
dnl Later versions of GAS requires that addr32 and data32 prefixes
dnl appear in the same lines as the instructions they modify, while
dnl earlier versions requires that they appear in separate lines.
AC_DEFUN([grub_ASM_PREFIX_REQUIREMENT],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(dnl
[whether addr32 must be in the same line as the instruction])
AC_CACHE_VAL(grub_cv_asm_prefix_requirement,
[cat > conftest.s <<\EOF
.code16
l1: addr32 movb %al, l1
EOF
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
grub_cv_asm_prefix_requirement=yes
else
grub_cv_asm_prefix_requirement=no
fi
rm -f conftest*])
if test "x$grub_cv_asm_prefix_requirement" = xyes; then
grub_tmp_addr32="addr32"
grub_tmp_data32="data32"
else
grub_tmp_addr32="addr32;"
grub_tmp_data32="data32;"
fi
AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32,
[Define it to \"addr32\" or \"addr32;\" to make GAS happy])
AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32,
[Define it to \"data32\" or \"data32;\" to make GAS happy])
AC_MSG_RESULT([$grub_cv_asm_prefix_requirement])])
dnl
dnl Older versions of GAS require that absolute indirect calls/jumps are
dnl not prefixed with `*', while later versions warn if not prefixed.
AC_DEFUN([grub_ASM_ABSOLUTE_WITHOUT_ASTERISK],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(dnl
[whether an absolute indirect call/jump must not be prefixed with an asterisk])
AC_CACHE_VAL(grub_cv_asm_absolute_without_asterisk,
[cat > conftest.s <<\EOF
lcall *(offset)
offset:
.long 0
.word 0
EOF
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
grub_cv_asm_absolute_without_asterisk=no
else
grub_cv_asm_absolute_without_asterisk=yes
fi
rm -f conftest*])
if test "x$grub_cv_asm_absolute_without_asterisk" = xyes; then
AC_DEFINE(ABSOLUTE_WITHOUT_ASTERISK, 1, [Define if an absolute indirect call/jump must NOT be prefixed with `*'])
fi
AC_MSG_RESULT([$grub_cv_asm_absolute_without_asterisk])])
dnl
dnl grub_CHECK_START_SYMBOL checks if start is automatically defined by
dnl the compiler.
dnl Written by OKUJI Yoshinori
AC_DEFUN([grub_CHECK_START_SYMBOL],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if start is defined by the compiler])
AC_CACHE_VAL(grub_cv_check_start_symbol,
[AC_TRY_LINK([], [asm ("incl start")],
grub_cv_check_start_symbol=yes,
grub_cv_check_start_symbol=no)])
if test "x$grub_cv_check_start_symbol" = xyes; then
AC_DEFINE(HAVE_START_SYMBOL, 1, [Define if start is defined])
fi
AC_MSG_RESULT([$grub_cv_check_start_symbol])
])
dnl
dnl grub_CHECK_USCORE_START_SYMBOL checks if _start is automatically
dnl defined by the compiler.
dnl Written by OKUJI Yoshinori
AC_DEFUN([grub_CHECK_USCORE_START_SYMBOL],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if _start is defined by the compiler])
AC_CACHE_VAL(grub_cv_check_uscore_start_symbol,
[AC_TRY_LINK([], [asm ("incl _start")],
grub_cv_check_uscore_start_symbol=yes,
grub_cv_check_uscore_start_symbol=no)])
if test "x$grub_cv_check_uscore_start_symbol" = xyes; then
AC_DEFINE(HAVE_USCORE_START_SYMBOL, 1, [Define if _start is defined])
fi
AC_MSG_RESULT([$grub_cv_check_uscore_start_symbol])
])
dnl
dnl grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL checks if __bss_start is
dnl automatically defined by the compiler.
dnl Written by Michael Hohmoth.
AC_DEFUN([grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if __bss_start is defined by the compiler])
AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol,
[AC_TRY_LINK([], [asm ("incl __bss_start")],
grub_cv_check_uscore_uscore_bss_start_symbol=yes,
grub_cv_check_uscore_uscore_bss_start_symbol=no)])
if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then
AC_DEFINE(HAVE_USCORE_USCORE_BSS_START_SYMBOL, 1, [Define if __bss_start is defined])
fi
AC_MSG_RESULT([$grub_cv_check_uscore_uscore_bss_start_symbol])
])
dnl
dnl grub_CHECK_EDATA_SYMBOL checks if edata is automatically defined by the
dnl compiler.
dnl Written by Michael Hohmuth.
AC_DEFUN([grub_CHECK_EDATA_SYMBOL],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if edata is defined by the compiler])
AC_CACHE_VAL(grub_cv_check_edata_symbol,
[AC_TRY_LINK([], [asm ("incl edata")],
grub_cv_check_edata_symbol=yes,
grub_cv_check_edata_symbol=no)])
if test "x$grub_cv_check_edata_symbol" = xyes; then
AC_DEFINE(HAVE_EDATA_SYMBOL, 1, [Define if edata is defined])
fi
AC_MSG_RESULT([$grub_cv_check_edata_symbol])
])
dnl
dnl grub_CHECK_USCORE_EDATA_SYMBOL checks if _edata is automatically
dnl defined by the compiler.
dnl Written by Michael Hohmuth.
AC_DEFUN([grub_CHECK_USCORE_EDATA_SYMBOL],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if _edata is defined by the compiler])
AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol,
[AC_TRY_LINK([], [asm ("incl _edata")],
grub_cv_check_uscore_edata_symbol=yes,
grub_cv_check_uscore_edata_symbol=no)])
if test "x$grub_cv_check_uscore_edata_symbol" = xyes; then
AC_DEFINE(HAVE_USCORE_EDATA_SYMBOL, 1, [Define if _edata is defined])
fi
AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol])
])
dnl
dnl grub_CHECK_END_SYMBOL checks if end is automatically defined by the
dnl compiler.
dnl Written by OKUJI Yoshinori
AC_DEFUN([grub_CHECK_END_SYMBOL],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if end is defined by the compiler])
AC_CACHE_VAL(grub_cv_check_end_symbol,
[AC_TRY_LINK([], [asm ("incl end")],
grub_cv_check_end_symbol=yes,
grub_cv_check_end_symbol=no)])
if test "x$grub_cv_check_end_symbol" = xyes; then
AC_DEFINE(HAVE_END_SYMBOL, 1, [Define if end is defined])
fi
AC_MSG_RESULT([$grub_cv_check_end_symbol])
])
dnl
dnl grub_CHECK_USCORE_END_SYMBOL checks if _end is automatically defined
dnl by the compiler.
dnl Written by OKUJI Yoshinori
AC_DEFUN([grub_CHECK_USCORE_END_SYMBOL],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if _end is defined by the compiler])
AC_CACHE_VAL(grub_cv_check_uscore_end_symbol,
[AC_TRY_LINK([], [asm ("incl _end")],
grub_cv_check_uscore_end_symbol=yes,
grub_cv_check_uscore_end_symbol=no)])
if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
AC_DEFINE(HAVE_USCORE_END_SYMBOL, 1, [Define if end is defined])
fi
AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
])
dnl grub_DEFINE_FILE(MACRO_NAME, FILE_NAME, DESCRIPTION)
dnl grub_DEFINE_FILE defines a macro as the contents of a file safely.
dnl Replace some escape sequences, because autoconf doesn't handle them
dnl gracefully.
dnl Written by OKUJI Yoshinori.
AC_DEFUN([grub_DEFINE_FILE],
[AC_REQUIRE([AC_PROG_CC])
# Because early versions of GNU sed 3.x are too buggy, use a C program
# instead of shell commands. *sigh*
cat >conftest.c <<\EOF
#include <stdio.h>
int
main (void)
{
int c;
while ((c = getchar ()) != EOF)
{
switch (c)
{
case '\n':
fputs ("\\n", stdout);
break;
case '\r':
fputs ("\\r", stdout);
break;
case '\\':
fputs ("\\\\", stdout);
break;
case '"':
fputs ("\\\"", stdout);
break;
default:
putchar (c);
}
}
return 0;
}
EOF
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} conftest.c -o conftest]) && test -s conftest; then
grub_tmp_value=`./conftest < "[$2]"`
else
AC_MSG_ERROR([${CC-cc} failed to produce an executable file])
fi
AC_DEFINE_UNQUOTED([$1], "$grub_tmp_value", [$3])
rm -f conftest*
])

1061
aclocal.m4 vendored

File diff suppressed because it is too large Load diff

142
compile
View file

@ -1,142 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
scriptversion=2004-10-12.08
# Copyright (C) 1999, 2000, 2003, 2004 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit 0
;;
-v | --v*)
echo "compile $scriptversion"
exit 0
;;
esac
ofile=
cfile=
eat=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we strip `-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
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.
"$@"
ret=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

1453
config.guess vendored

File diff suppressed because it is too large Load diff

View file

@ -1,106 +0,0 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if an absolute indirect call/jump must NOT be prefixed with `*' */
#undef ABSOLUTE_WITHOUT_ASTERISK
/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
#undef ADDR32
/* Define if you don't want to pass the mem= option to Linux */
#undef AUTO_LINUX_MEM_OPT
/* Define it to \"data32\" or \"data32;\" to make GAS happy */
#undef DATA32
/* Define if C symbols get an underscore after compilation */
#undef HAVE_ASM_USCORE
/* Define to 1 if you have the <curses.h> header file. */
#undef HAVE_CURSES_H
/* Define if edata is defined */
#undef HAVE_EDATA_SYMBOL
/* Define if end is defined */
#undef HAVE_END_SYMBOL
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if you have a curses library */
#undef HAVE_LIBCURSES
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <ncurses/curses.h> header file. */
#undef HAVE_NCURSES_CURSES_H
/* Define to 1 if you have the <ncurses.h> header file. */
#undef HAVE_NCURSES_H
/* Define if opendisk() in -lutil can be used */
#undef HAVE_OPENDISK
/* Define if start is defined */
#undef HAVE_START_SYMBOL
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if _edata is defined */
#undef HAVE_USCORE_EDATA_SYMBOL
/* Define if end is defined */
#undef HAVE_USCORE_END_SYMBOL
/* Define if _start is defined */
#undef HAVE_USCORE_START_SYMBOL
/* Define if __bss_start is defined */
#undef HAVE_USCORE_USCORE_BSS_START_SYMBOL
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define if there is user specified preset menu string */
#undef PRESET_MENU_STRING
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION

1566
config.sub vendored

File diff suppressed because it is too large Load diff

7697
configure vendored

File diff suppressed because it is too large Load diff

522
depcomp
View file

@ -1,522 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2004-05-31.23
# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
# 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit 0
;;
-v | --v*)
echo "depcomp $scriptversion"
exit 0
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# Dependencies are output in .lo.d with libtool 1.4.
# With libtool 1.5 they are output both in $dir.libs/$base.o.d
# and in $dir.libs/$base.o.d and $dir$base.o.d. We process the
# latter, because the former will be cleaned when $dir.libs is
# erased.
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir$base.o.d"
tmpdepfile3="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
tmpdepfile3="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
elif test -f "$tmpdepfile2"; then
tmpdepfile="$tmpdepfile2"
else
tmpdepfile="$tmpdepfile3"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View file

@ -1,770 +0,0 @@
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 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.
@SET_MAKE@
SOURCES = $(kernel_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
EXTRA_PROGRAMS = kernel$(EXEEXT)
@BUILD_EXAMPLE_KERNEL_TRUE@noinst_PROGRAMS = kernel$(EXEEXT)
subdir = docs
DIST_COMMON = $(grub_TEXINFOS) $(multiboot_TEXINFOS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/stamp-vti $(srcdir)/version.texi mdate-sh \
texinfo.tex
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am__kernel_SOURCES_DIST = boot.S kernel.c multiboot.h
am__objects_1 = boot.$(OBJEXT) kernel-kernel.$(OBJEXT)
@BUILD_EXAMPLE_KERNEL_TRUE@am_kernel_OBJECTS = $(am__objects_1)
kernel_OBJECTS = $(am_kernel_OBJECTS)
kernel_LDADD = $(LDADD)
SCRIPTS = $(noinst_SCRIPTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(kernel_SOURCES)
DIST_SOURCES = $(am__kernel_SOURCES_DIST)
INFO_DEPS = $(srcdir)/grub.info $(srcdir)/multiboot.info
am__TEXINFO_TEX_DIR = $(srcdir)
DVIS = grub.dvi multiboot.dvi
PDFS = grub.pdf multiboot.pdf
PSS = grub.ps multiboot.ps
HTMLS = grub.html multiboot.html
TEXINFOS = grub.texi multiboot.texi
TEXI2DVI = texi2dvi
TEXI2PDF = $(TEXI2DVI) --pdf --batch
MAKEINFOHTML = $(MAKEINFO) --html
AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
DVIPS = dvips
am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" \
"$(DESTDIR)$(man8dir)"
man1dir = $(mandir)/man1
man8dir = $(mandir)/man8
NROFF = nroff
MANS = $(man_MANS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FSYS_CFLAGS = @FSYS_CFLAGS@
GRUB_CFLAGS = @GRUB_CFLAGS@
GRUB_LIBS = @GRUB_LIBS@
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
NET_CFLAGS = @NET_CFLAGS@
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
RANLIB = @RANLIB@
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STAGE1_CFLAGS = @STAGE1_CFLAGS@
STAGE2_CFLAGS = @STAGE2_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
info_TEXINFOS = grub.texi multiboot.texi
grub_TEXINFOS = internals.texi fdl.texi
EXAMPLES = boot.S kernel.c multiboot.h
multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
man_MANS = grub.8 mbchk.1 grub-install.8 grub-md5-crypt.8 grub-terminfo.8
HELP2MAN = help2man
SRC2TEXI = src2texi
noinst_SCRIPTS = $(HELP2MAN) $(SRC2TEXI)
@BUILD_EXAMPLE_KERNEL_TRUE@kernel_SOURCES = $(EXAMPLES)
@BUILD_EXAMPLE_KERNEL_TRUE@kernel_CFLAGS = -fno-builtin -nostdinc -O -g -Wall \
@BUILD_EXAMPLE_KERNEL_TRUE@ -imacros $(top_builddir)/config.h
@BUILD_EXAMPLE_KERNEL_TRUE@kernel_LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000
EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS) \
$(EXAMPLES) $(multiboot_TEXINFOS)
CLEANFILES = $(noinst_PROGRAMS)
all: all-am
.SUFFIXES:
.SUFFIXES: .S .c .dvi .html .info .o .obj .pdf .ps .texi
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu docs/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
kernel$(EXEEXT): $(kernel_OBJECTS) $(kernel_DEPENDENCIES)
@rm -f kernel$(EXEEXT)
$(LINK) $(kernel_LDFLAGS) $(kernel_OBJECTS) $(kernel_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel-kernel.Po@am__quote@
.S.o:
$(CCASCOMPILE) -c $<
.S.obj:
$(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
kernel-kernel.o: kernel.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -MT kernel-kernel.o -MD -MP -MF "$(DEPDIR)/kernel-kernel.Tpo" -c -o kernel-kernel.o `test -f 'kernel.c' || echo '$(srcdir)/'`kernel.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/kernel-kernel.Tpo" "$(DEPDIR)/kernel-kernel.Po"; else rm -f "$(DEPDIR)/kernel-kernel.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel.c' object='kernel-kernel.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -c -o kernel-kernel.o `test -f 'kernel.c' || echo '$(srcdir)/'`kernel.c
kernel-kernel.obj: kernel.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -MT kernel-kernel.obj -MD -MP -MF "$(DEPDIR)/kernel-kernel.Tpo" -c -o kernel-kernel.obj `if test -f 'kernel.c'; then $(CYGPATH_W) 'kernel.c'; else $(CYGPATH_W) '$(srcdir)/kernel.c'; fi`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/kernel-kernel.Tpo" "$(DEPDIR)/kernel-kernel.Po"; else rm -f "$(DEPDIR)/kernel-kernel.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel.c' object='kernel-kernel.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -c -o kernel-kernel.obj `if test -f 'kernel.c'; then $(CYGPATH_W) 'kernel.c'; else $(CYGPATH_W) '$(srcdir)/kernel.c'; fi`
.texi.info:
restore=: && backupdir="$(am__leading_dot)am$$$$" && \
am__cwd=`pwd` && cd $(srcdir) && \
rm -rf $$backupdir && mkdir $$backupdir && \
for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
done; \
cd "$$am__cwd"; \
if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
-o $@ $<; \
then \
rc=0; \
cd $(srcdir); \
else \
rc=$$?; \
cd $(srcdir) && \
$$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
fi; \
rm -rf $$backupdir; exit $$rc
.texi.dvi:
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
$(TEXI2DVI) $<
.texi.pdf:
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
$(TEXI2PDF) $<
.texi.html:
rm -rf $(@:.html=.htp)
if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
-o $(@:.html=.htp) $<; \
then \
rm -rf $@; \
if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
else \
if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
exit 1; \
fi
$(srcdir)/grub.info: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
grub.dvi: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
grub.pdf: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
grub.html: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
$(srcdir)/stamp-vti: grub.texi $(top_srcdir)/configure
@(dir=.; test -f ./grub.texi || dir=$(srcdir); \
set `$(SHELL) $(srcdir)/mdate-sh $$dir/grub.texi`; \
echo "@set UPDATED $$1 $$2 $$3"; \
echo "@set UPDATED-MONTH $$2 $$3"; \
echo "@set EDITION $(VERSION)"; \
echo "@set VERSION $(VERSION)") > vti.tmp
@cmp -s vti.tmp $(srcdir)/version.texi \
|| (echo "Updating $(srcdir)/version.texi"; \
cp vti.tmp $(srcdir)/version.texi)
-@rm -f vti.tmp
@cp $(srcdir)/version.texi $@
mostlyclean-vti:
-rm -f vti.tmp
maintainer-clean-vti:
@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
$(srcdir)/multiboot.info: multiboot.texi $(multiboot_TEXINFOS)
multiboot.dvi: multiboot.texi $(multiboot_TEXINFOS)
multiboot.pdf: multiboot.texi $(multiboot_TEXINFOS)
multiboot.html: multiboot.texi $(multiboot_TEXINFOS)
.dvi.ps:
$(DVIPS) -o $@ $<
uninstall-info-am:
$(PRE_UNINSTALL)
@if (install-info --version && \
install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
list='$(INFO_DEPS)'; \
for file in $$list; do \
relfile=`echo "$$file" | sed 's|^.*/||'`; \
echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
done; \
else :; fi
@$(NORMAL_UNINSTALL)
@list='$(INFO_DEPS)'; \
for file in $$list; do \
relfile=`echo "$$file" | sed 's|^.*/||'`; \
relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
(if cd "$(DESTDIR)$(infodir)"; then \
echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \
rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
else :; fi); \
done
dist-info: $(INFO_DEPS)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
list='$(INFO_DEPS)'; \
for base in $$list; do \
case $$base in \
$(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
esac; \
if test -f $$base; then d=.; else d=$(srcdir); fi; \
for file in $$d/$$base*; do \
relfile=`expr "$$file" : "$$d/\(.*\)"`; \
test -f $(distdir)/$$relfile || \
cp -p $$file $(distdir)/$$relfile; \
done; \
done
mostlyclean-aminfo:
-rm -rf grub.aux grub.cp grub.cps grub.fn grub.ky grub.log grub.pg grub.tmp \
grub.toc grub.tp grub.vr grub.dvi grub.pdf grub.ps grub.html \
multiboot.aux multiboot.cp multiboot.cps multiboot.fn \
multiboot.ky multiboot.log multiboot.pg multiboot.tmp \
multiboot.toc multiboot.tp multiboot.vr multiboot.dvi \
multiboot.pdf multiboot.ps multiboot.html
maintainer-clean-aminfo:
@list='$(INFO_DEPS)'; for i in $$list; do \
i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
done
install-man1: $(man1_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
1*) ;; \
*) ext='1' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
done
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
1*) ;; \
*) ext='1' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
done
install-man8: $(man8_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man8dir)" || $(mkdir_p) "$(DESTDIR)$(man8dir)"
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
*) ext='8' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
done
uninstall-man8:
@$(NORMAL_UNINSTALL)
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
*) ext='8' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(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 -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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 "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-info
check-am: all-am
check: check-am
all-am: Makefile $(INFO_DEPS) $(PROGRAMS) $(SCRIPTS) $(MANS)
installdirs:
for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am: $(DVIS)
html: html-am
html-am: $(HTMLS)
info: info-am
info-am: $(INFO_DEPS)
install-data-am: install-info-am install-man
install-exec-am:
install-info: install-info-am
install-info-am: $(INFO_DEPS)
@$(NORMAL_INSTALL)
test -z "$(infodir)" || $(mkdir_p) "$(DESTDIR)$(infodir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
list='$(INFO_DEPS)'; \
for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
esac; \
if test -f $$file; then d=.; else d=$(srcdir); fi; \
file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
$$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
if test -f $$ifile; then \
relfile=`echo "$$ifile" | sed 's|^.*/||'`; \
echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \
$(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \
else : ; fi; \
done; \
done
@$(POST_INSTALL)
@if (install-info --version && \
install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
list='$(INFO_DEPS)'; \
for file in $$list; do \
relfile=`echo "$$file" | sed 's|^.*/||'`; \
echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
done; \
else : ; fi
install-man: install-man1 install-man8
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
maintainer-clean-generic maintainer-clean-vti
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-aminfo mostlyclean-compile \
mostlyclean-generic mostlyclean-vti
pdf: pdf-am
pdf-am: $(PDFS)
ps: ps-am
ps-am: $(PSS)
uninstall-am: uninstall-info-am uninstall-man
uninstall-man: uninstall-man1 uninstall-man8
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstPROGRAMS ctags dist-info distclean \
distclean-compile distclean-generic distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-man install-man1 \
install-man8 install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-aminfo \
maintainer-clean-generic maintainer-clean-vti mostlyclean \
mostlyclean-aminfo mostlyclean-compile mostlyclean-generic \
mostlyclean-vti pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-info-am uninstall-man uninstall-man1 \
uninstall-man8
@BUILD_EXAMPLE_KERNEL_TRUE@boot.o: multiboot.h
# Cancel the rule %.texi -> %. This rule may confuse make to determine
# the dependecies.
.texi:
%.c.texi: %.c $(srcdir)/$(SRC2TEXI)
$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
%.h.texi: %.h $(srcdir)/$(SRC2TEXI)
$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
%.S.texi: %.S $(srcdir)/$(SRC2TEXI)
$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
@MAINTAINER_MODE_TRUE@$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN)
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) --name="the grub shell" \
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
@MAINTAINER_MODE_TRUE@$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN)
@MAINTAINER_MODE_TRUE@ chmod 755 $<
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) --name="install GRUB on your drive" \
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
@MAINTAINER_MODE_TRUE@$(srcdir)/mbchk.1: ../util/mbchk $(srcdir)/$(HELP2MAN)
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) \
@MAINTAINER_MODE_TRUE@ --name="check the format of a Multiboot kernel" \
@MAINTAINER_MODE_TRUE@ --section=1 --output=$@ $<
@MAINTAINER_MODE_TRUE@$(srcdir)/grub-md5-crypt.8: ../util/grub-md5-crypt $(srcdir)/$(HELP2MAN)
@MAINTAINER_MODE_TRUE@ chmod 755 $<
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) \
@MAINTAINER_MODE_TRUE@ --name="Encrypt a password in MD5 format" \
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
@MAINTAINER_MODE_TRUE@$(srcdir)/grub-terminfo.8: ../util/grub-terminfo $(srcdir)/$(HELP2MAN)
@MAINTAINER_MODE_TRUE@ chmod 755 $<
@MAINTAINER_MODE_TRUE@ $(PERL) $(srcdir)/$(HELP2MAN) \
@MAINTAINER_MODE_TRUE@ --name="Generate a terminfo command from a terminfo name" \
@MAINTAINER_MODE_TRUE@ --section=8 --output=$@ $<
# 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:

View file

@ -1,79 +0,0 @@
/* @r{boot.S - bootstrap the kernel} */
/* @r{Copyright (C) 1999, 2001 Free Software Foundation, Inc.
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.
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 ASM 1
#include <multiboot.h>
.text
.globl start, _start
start:
_start:
jmp multiboot_entry
/* @r{Align 32 bits boundary.} */
.align 4
/* @r{Multiboot header.} */
multiboot_header:
/* @r{magic} */
.long MULTIBOOT_HEADER_MAGIC
/* @r{flags} */
.long MULTIBOOT_HEADER_FLAGS
/* @r{checksum} */
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
#ifndef __ELF__
/* @r{header_addr} */
.long multiboot_header
/* @r{load_addr} */
.long _start
/* @r{load_end_addr} */
.long _edata
/* @r{bss_end_addr} */
.long _end
/* @r{entry_addr} */
.long multiboot_entry
#endif /* @r{! __ELF__} */
multiboot_entry:
/* @r{Initialize the stack pointer.} */
movl $(stack + STACK_SIZE), %esp
/* @r{Reset EFLAGS.} */
pushl $0
popf
/* @r{Push the pointer to the Multiboot information structure.} */
pushl %ebx
/* @r{Push the magic value.} */
pushl %eax
/* @r{Now enter the C main function...} */
call EXT_C(cmain)
/* @r{Halt.} */
pushl $halt_message
call EXT_C(printf)
loop: hlt
jmp loop
halt_message:
.asciz "Halted."
/* @r{Our stack area.} */
.comm stack, STACK_SIZE

View file

@ -1,52 +0,0 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
.TH GRUB-INSTALL "8" "June 2006" "grub-install (GNU GRUB 0.97)" FSF
.SH NAME
grub-install \- install GRUB on your drive
.SH SYNOPSIS
.B grub-install
[\fIOPTION\fR] \fIinstall_device\fR
.SH DESCRIPTION
Install GRUB on your drive.
.TP
\fB\-h\fR, \fB\-\-help\fR
print this message and exit
.TP
\fB\-v\fR, \fB\-\-version\fR
print the version information and exit
.TP
\fB\-\-root\-directory\fR=\fIDIR\fR
install GRUB images under the directory DIR
instead of the root directory
.TP
\fB\-\-grub\-shell\fR=\fIFILE\fR
use FILE as the grub shell
.TP
\fB\-\-no\-floppy\fR
do not probe any floppy drive
.TP
\fB\-\-force\-lba\fR
force GRUB to use LBA mode even for a buggy
BIOS
.TP
\fB\-\-recheck\fR
probe a device map even if it already exists
.PP
INSTALL_DEVICE can be a GRUB device name or a system device filename.
.PP
grub-install copies GRUB images into the DIR/boot directory specfied by
\fB\-\-root\-directory\fR, and uses the grub shell to install grub into the boot
sector.
.SH "REPORTING BUGS"
Report bugs to <bug-grub@gnu.org>.
.SH "SEE ALSO"
The full documentation for
.B grub-install
is maintained as a Texinfo manual. If the
.B info
and
.B grub-install
programs are properly installed at your site, the command
.IP
.B info grub-install
.PP
should give you access to the complete manual.

View file

@ -1,32 +0,0 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
.TH GRUB-MD5-CRYPT "8" "June 2006" "grub-md5-crypt (GNU GRUB )" FSF
.SH NAME
grub-md5-crypt \- Encrypt a password in MD5 format
.SH SYNOPSIS
.B grub-md5-crypt
[\fIOPTION\fR]
.SH DESCRIPTION
Encrypt a password in MD5 format.
.TP
\fB\-h\fR, \fB\-\-help\fR
print this message and exit
.TP
\fB\-v\fR, \fB\-\-version\fR
print the version information and exit
.TP
\fB\-\-grub\-shell\fR=\fIFILE\fR
use FILE as the grub shell
.SH "REPORTING BUGS"
Report bugs to <bug-grub@gnu.org>.
.SH "SEE ALSO"
The full documentation for
.B grub-md5-crypt
is maintained as a Texinfo manual. If the
.B info
and
.B grub-md5-crypt
programs are properly installed at your site, the command
.IP
.B info grub-md5-crypt
.PP
should give you access to the complete manual.

View file

@ -1,29 +0,0 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
.TH GRUB-TERMINFO "8" "June 2006" "grub-terminfo (GNU GRUB 0.97)" FSF
.SH NAME
grub-terminfo \- Generate a terminfo command from a terminfo name
.SH SYNOPSIS
.B grub-terminfo
\fITERMNAME\fR
.SH DESCRIPTION
Generate a terminfo command from a terminfo name.
.TP
\fB\-h\fR, \fB\-\-help\fR
print this message and exit
.TP
\fB\-v\fR, \fB\-\-version\fR
print the version information and exit
.SH "REPORTING BUGS"
Report bugs to <bug-grub@gnu.org>.
.SH "SEE ALSO"
The full documentation for
.B grub-terminfo
is maintained as a Texinfo manual. If the
.B info
and
.B grub-terminfo
programs are properly installed at your site, the command
.IP
.B info grub-terminfo
.PP
should give you access to the complete manual.

View file

@ -1,71 +0,0 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
.TH GRUB "8" "June 2006" "grub (GNU GRUB 0.97)" FSF
.SH NAME
grub \- the grub shell
.SH SYNOPSIS
.B grub
[\fIOPTION\fR]...
.SH DESCRIPTION
Enter the GRand Unified Bootloader command shell.
.TP
\fB\-\-batch\fR
turn on batch mode for non-interactive use
.TP
\fB\-\-boot\-drive\fR=\fIDRIVE\fR
specify stage2 boot_drive [default=0x0]
.TP
\fB\-\-config\-file\fR=\fIFILE\fR
specify stage2 config_file [default=/boot/grub/menu.lst]
.TP
\fB\-\-device\-map\fR=\fIFILE\fR
use the device map file FILE
.TP
\fB\-\-help\fR
display this message and exit
.TP
\fB\-\-hold\fR
wait until a debugger will attach
.TP
\fB\-\-install\-partition\fR=\fIPAR\fR
specify stage2 install_partition [default=0x20000]
.TP
\fB\-\-no\-config\-file\fR
do not use the config file
.TP
\fB\-\-no\-curses\fR
do not use curses
.TP
\fB\-\-no\-floppy\fR
do not probe any floppy drive
.TP
\fB\-\-no\-pager\fR
do not use internal pager
.TP
\fB\-\-preset\-menu\fR
use the preset menu
.TP
\fB\-\-probe\-second\-floppy\fR
probe the second floppy drive
.TP
\fB\-\-read\-only\fR
do not write anything to devices
.TP
\fB\-\-verbose\fR
print verbose messages
.TP
\fB\-\-version\fR
print version information and exit
.SH "REPORTING BUGS"
Report bugs to <bug-grub@gnu.org>.
.SH "SEE ALSO"
The full documentation for
.B grub
is maintained as a Texinfo manual. If the
.B info
and
.B grub
programs are properly installed at your site, the command
.IP
.B info grub
.PP
should give you access to the complete manual.

File diff suppressed because it is too large Load diff

View file

@ -1,427 +0,0 @@
@node Internals
@appendix Hacking GRUB
This chapter documents the user-invisible aspect of GRUB.
As a general rule of software development, it is impossible to keep the
descriptions of the internals up-to-date, and it is quite hard to
document everything. So refer to the source code, whenever you are not
satisfied with this documentation. Please assume that this gives just
hints to you.
@menu
* Memory map:: The memory map of various components
* Embedded data:: Embedded variables in GRUB
* Filesystem interface:: The generic interface for filesystems
* Command interface:: The generic interface for built-ins
* Bootstrap tricks:: The bootstrap mechanism used in GRUB
* I/O ports detection:: How to probe I/O ports used by INT 13H
* Memory detection:: How to detect all installed RAM
* Low-level disk I/O:: INT 13H disk I/O interrupts
* MBR:: The structure of Master Boot Record
* Partition table:: The format of partition tables
* Submitting patches:: Where and how you should send patches
@end menu
@node Memory map
@section The memory map of various components
GRUB consists of two distinct components, called @dfn{stages}, which are
loaded at different times in the boot process. Because they run
mutual-exclusively, sometimes a memory area overlaps with another
memory area. And, even in one stage, a single memory area can be used
for various purposes, because their usages are mutually exclusive.
Here is the memory map of the various components:
@table @asis
@item 0 to 4K-1
BIOS and real mode interrupts
@item 0x07BE to 0x07FF
Partition table passed to another boot loader
@item down from 8K-1
Real mode stack
@item 0x2000 to ?
The optional Stage 1.5 is loaded here
@item 0x2000 to 0x7FFF
Command-line buffer for Multiboot kernels and modules
@item 0x7C00 to 0x7DFF
Stage 1 is loaded here by BIOS or another boot loader
@item 0x7F00 to 0x7F42
LBA drive parameters
@item 0x8000 to ?
Stage2 is loaded here
@item The end of Stage 2 to 416K-1
Heap, in particular used for the menu
@item down from 416K-1
Protected mode stack
@item 416K to 448K-1
Filesystem buffer
@item 448K to 479.5K-1
Raw device buffer
@item 479.5K to 480K-1
512-byte scratch area
@item 480K to 512K-1
Buffers for various functions, such as password, command-line, cut and
paste, and completion.
@item The last 1K of lower memory
Disk swapping code and data
@end table
See the file @file{stage2/shared.h}, for more information.
@node Embedded data
@section Embedded variables in GRUB
Stage 1 and Stage 2 have embedded variables whose locations are
well-defined, so that the installation can patch the binary file
directly without recompilation of the stages.
In Stage 1, these are defined:
@table @code
@item 0x3E
The version number (not GRUB's, but the installation mechanism's).
@item 0x40
The boot drive. If it is 0xFF, use a drive passed by BIOS.
@item 0x41
The flag for if forcing LBA.
@item 0x42
The starting address of Stage 2.
@item 0x44
The first sector of Stage 2.
@item 0x48
The starting segment of Stage 2.
@item 0x1FE
The signature (@code{0xAA55}).
@end table
See the file @file{stage1/stage1.S}, for more information.
In the first sector of Stage 1.5 and Stage 2, the blocklists are
recorded between @code{firstlist} and @code{lastlist}. The address of
@code{lastlist} is determined when assembling the file
@file{stage2/start.S}.
The trick here is that it is actually read backward, and the first
8-byte blocklist is not read here, but after the pointer is decremented
8 bytes, then after reading it, it decrements again, reads, and so on,
until it is finished. The terminating condition is when the number of
sectors to be read in the next blocklist is zero.
The format of a blocklist can be seen from the example in the code just
before the @code{firstlist} label. Note that it is always from the
beginning of the disk, but @emph{not} relative to the partition
boundaries.
In the second sector of Stage 1.5 and Stage 2, these are defined:
@table @asis
@item @code{0x6}
The version number (likewise, the installation mechanism's).
@item @code{0x8}
The installed partition.
@item @code{0xC}
The saved entry number.
@item @code{0x10}
The identifier.
@item @code{0x11}
The flag for if forcing LBA.
@item @code{0x12}
The version string (GRUB's).
@item @code{0x12} + @dfn{the length of the version string}
The name of a configuration file.
@end table
See the file @file{stage2/asm.S}, for more information.
@node Filesystem interface
@section The generic interface for filesystems
For any particular partition, it is presumed that only one of the
@dfn{normal} filesystems such as FAT, FFS, or ext2fs can be used, so
there is a switch table managed by the functions in
@file{disk_io.c}. The notation is that you can only @dfn{mount} one at a
time.
The blocklist filesystem has a special place in the system. In addition
to the @dfn{normal} filesystem (or even without one mounted), you can
access disk blocks directly (in the indicated partition) via the block
list notation. Using the blocklist filesystem doesn't effect any other
filesystem mounts.
The variables which can be read by the filesystem backend are:
@vtable @code
@item current_drive
The current BIOS drive number (numbered from 0, if a floppy, and
numbered from 0x80, if a hard disk).
@item current_partition
The current partition number.
@item current_slice
The current partition type.
@item saved_drive
The @dfn{drive} part of the root device.
@item saved_partition
The @dfn{partition} part of the root device.
@item part_start
The current partition starting address, in sectors.
@item part_length
The current partition length, in sectors.
@item print_possibilities
True when the @code{dir} function should print the possible completions
of a file, and false when it should try to actually open a file of that
name.
@item FSYS_BUF
Filesystem buffer which is 32K in size, to use in any way which the
filesystem backend desires.
@end vtable
The variables which need to be written by a filesystem backend are:
@vtable @code
@item filepos
The current position in the file, in sectors.
@strong{Caution:} the value of @var{filepos} can be changed out from
under the filesystem code in the current implementation. Don't depend on
it being the same for later calls into the backend code!
@item filemax
The length of the file.
@item disk_read_func
The value of @var{disk_read_hook} @emph{only} during reading of data
for the file, not any other fs data, inodes, FAT tables, whatever, then
set to @code{NULL} at all other times (it will be @code{NULL} by
default). If this isn't done correctly, then the @command{testload} and
@command{install} commands won't work correctly.
@end vtable
The functions expected to be used by the filesystem backend are:
@ftable @code
@item devread
Only read sectors from within a partition. Sector 0 is the first sector
in the partition.
@item grub_read
If the backend uses the blocklist code, then @code{grub_read} can be
used, after setting @var{block_file} to 1.
@item print_a_completion
If @var{print_possibilities} is true, call @code{print_a_completion} for
each possible file name. Otherwise, the file name completion won't work.
@end ftable
The functions expected to be defined by the filesystem backend are
described at least moderately in the file @file{filesys.h}. Their usage
is fairly evident from their use in the functions in @file{disk_io.c},
look for the use of the @var{fsys_table} array.
@strong{Caution:} The semantics are such that then @samp{mount}ing the
filesystem, presume the filesystem buffer @code{FSYS_BUF} is corrupted,
and (re-)load all important contents. When opening and reading a file,
presume that the data from the @samp{mount} is available, and doesn't
get corrupted by the open/read (i.e. multiple opens and/or reads will be
done with only one mount if in the same filesystem).
@node Command interface
@section The generic interface for built-ins
GRUB built-in commands are defined in a uniform interface, whether
they are menu-specific or can be used anywhere. The definition of a
built-in command consists of two parts: the code itself and the table of
the information.
The code must be a function which takes two arguments, a command-line
string and flags, and returns an @samp{int} value. The @dfn{flags}
argument specifies how the function is called, using a bit mask. The
return value must be zero if successful, otherwise non-zero. So it is
normally enough to return @var{errnum}.
The table of the information is represented by the structure
@code{struct builtin}, which contains the name of the command, a pointer
to the function, flags, a short description of the command and a long
description of the command. Since the descriptions are used only for
help messages interactively, you don't have to define them, if the
command may not be called interactively (such as @command{title}).
The table is finally registered in the table @var{builtin_table}, so
that @code{run_script} and @code{enter_cmdline} can find the
command. See the files @file{cmdline.c} and @file{builtins.c}, for more
details.
@node Bootstrap tricks
@section The bootstrap mechanism used in GRUB
The disk space can be used in a boot loader is very restricted because
a MBR (@pxref{MBR}) is only 512 bytes but it also contains a partition
table (@pxref{Partition table}) and a BPB. So the question is how to
make a boot loader code enough small to be fit in a MBR.
However, GRUB is a very large program, so we break GRUB into 2 (or 3)
distinct components, @dfn{Stage 1} and @dfn{Stage 2} (and optionally
@dfn{Stage 1.5}). @xref{Memory map}, for more information.
We embed Stage 1 in a MBR or in the boot sector of a partition, and
place Stage 2 in a filesystem. The optional Stage 1.5 can be installed
in a filesystem, in the @dfn{boot loader} area in a FFS or a ReiserFS,
and in the sectors right after a MBR, because Stage 1.5 is enough small
and the sectors right after a MBR is normally an unused region. The size
of this region is the number of sectors per head minus 1.
Thus, all Stage1 must do is just load Stage2 or Stage1.5. But even if
Stage 1 needs not to support the user interface or the filesystem
interface, it is impossible to make Stage 1 less than 400 bytes, because
GRUB should support both the CHS mode and the LBA mode (@pxref{Low-level
disk I/O}).
The solution used by GRUB is that Stage 1 loads only the first sector of
Stage 2 (or Stage 1.5) and Stage 2 itself loads the rest. The flow of
Stage 1 is:
@enumerate
@item
Initialize the system briefly.
@item
Detect the geometry and the accessing mode of the @dfn{loading drive}.
@item
Load the first sector of Stage 2.
@item
Jump to the starting address of the Stage 2.
@end enumerate
The flow of Stage 2 (and Stage 1.5) is:
@enumerate
@item
Load the rest of itself to the real starting address, that is, the
starting address plus 512 bytes. The blocklists are stored in the last
part of the first sector.
@item
Long jump to the real starting address.
@end enumerate
Note that Stage 2 (or Stage 1.5) does not probe the geometry
or the accessing mode of the @dfn{loading drive}, since Stage 1 has
already probed them.
@node I/O ports detection
@section How to probe I/O ports used by INT 13H
FIXME: I will write this chapter after implementing the new technique.
@node Memory detection
@section How to detect all installed RAM
FIXME: I doubt if Erich didn't write this chapter only himself wholly,
so I will rewrite this chapter.
@node Low-level disk I/O
@section INT 13H disk I/O interrupts
FIXME: I'm not sure where some part of the original chapter is derived,
so I will rewrite this chapter.
@node MBR
@section The structure of Master Boot Record
FIXME: Likewise.
@node Partition table
@section The format of partition tables
FIXME: Probably the original chapter is derived from "How It Works", so
I will rewrite this chapter.
@node Submitting patches
@section Where and how you should send patches
When you write patches for GRUB, please send them to the mailing list
@email{bug-grub@@gnu.org}. Here is the list of items of which you
should take care:
@itemize @bullet
@item
Please make your patch as small as possible. Generally, it is not a good
thing to make one big patch which changes many things. Instead,
segregate features and produce many patches.
@item
Use as late code as possible, for the original code. The CVS repository
always has the current version (@pxref{Obtaining and Building GRUB}).
@item
Write ChangeLog entries. @xref{Change Logs, , Change Logs, standards,
GNU Coding Standards}, if you don't know how to write ChangeLog.
@item
Make patches in unified diff format. @samp{diff -urN} is appropriate in
most cases.
@item
Don't make patches reversely. Reverse patches are difficult to read and
use.
@item
Be careful enough of the license term and the copyright. Because GRUB
is under GNU General Public License, you may not steal code from
software whose license is incompatible against GPL. And, if you copy
code written by others, you must not ignore their copyrights. Feel free
to ask GRUB maintainers, whenever you are not sure what you should do.
@item
If your patch is too large to send in e-mail, put it at somewhere we can
see. Usually, you shouldn't send e-mail over 20K.
@end itemize

View file

@ -1,27 +0,0 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
.TH MBCHK "1" "June 2006" "mbchk (GNU GRUB 0.97)" FSF
.SH NAME
mbchk \- check the format of a Multiboot kernel
.SH SYNOPSIS
.B mbchk
[\fIOPTION\fR]... [\fIFILE\fR]...
.SH DESCRIPTION
Check if the format of FILE complies with the Multiboot Specification.
.PP
\fB\-q\fR, \fB\-\-quiet\fR suppress all normal output
\fB\-h\fR, \fB\-\-help\fR display this help and exit
\fB\-v\fR, \fB\-\-version\fR output version information and exit.
.SH "REPORTING BUGS"
Report bugs to <bug-grub@gnu.org>.
.SH "SEE ALSO"
The full documentation for
.B mbchk
is maintained as a Texinfo manual. If the
.B info
and
.B mbchk
programs are properly installed at your site, the command
.IP
.B info mbchk
.PP
should give you access to the complete manual.

View file

@ -1,170 +0,0 @@
#!/bin/sh
# Get modification time of a file or directory and pretty-print it.
scriptversion=2004-12-08.12
# Copyright (C) 1995, 1996, 1997, 2003, 2004 Free Software Foundation, Inc.
# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
#
# 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No file. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: mdate-sh [--help] [--version] FILE
Pretty-print the modification time of FILE.
Report bugs to <bug-automake@gnu.org>.
EOF
exit 0
;;
-v | --v*)
echo "mdate-sh $scriptversion"
exit 0
;;
esac
# Prevent date giving response in another language.
LANG=C
export LANG
LC_ALL=C
export LC_ALL
LC_TIME=C
export LC_TIME
save_arg1="$1"
# Find out how to get the extended ls output of a file or directory.
if ls -L /dev/null 1>/dev/null 2>&1; then
ls_command='ls -L -l -d'
else
ls_command='ls -l -d'
fi
# A `ls -l' line looks as follows on OS/2.
# drwxrwx--- 0 Aug 11 2001 foo
# This differs from Unix, which adds ownership information.
# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
#
# To find the date, we split the line on spaces and iterate on words
# until we find a month. This cannot work with files whose owner is a
# user named `Jan', or `Feb', etc. However, it's unlikely that `/'
# will be owned by a user whose name is a month. So we first look at
# the extended ls output of the root directory to decide how many
# words should be skipped to get the date.
# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
set x`ls -l -d /`
# Find which argument is the month.
month=
command=
until test $month
do
shift
# Add another shift to the command.
command="$command shift;"
case $1 in
Jan) month=January; nummonth=1;;
Feb) month=February; nummonth=2;;
Mar) month=March; nummonth=3;;
Apr) month=April; nummonth=4;;
May) month=May; nummonth=5;;
Jun) month=June; nummonth=6;;
Jul) month=July; nummonth=7;;
Aug) month=August; nummonth=8;;
Sep) month=September; nummonth=9;;
Oct) month=October; nummonth=10;;
Nov) month=November; nummonth=11;;
Dec) month=December; nummonth=12;;
esac
done
# Get the extended ls output of the file or directory.
set x`eval "$ls_command \"\$save_arg1\""`
# Remove all preceding arguments
eval $command
# Get the month. Next argument is day, followed by the year or time.
case $1 in
Jan) month=January; nummonth=1;;
Feb) month=February; nummonth=2;;
Mar) month=March; nummonth=3;;
Apr) month=April; nummonth=4;;
May) month=May; nummonth=5;;
Jun) month=June; nummonth=6;;
Jul) month=July; nummonth=7;;
Aug) month=August; nummonth=8;;
Sep) month=September; nummonth=9;;
Oct) month=October; nummonth=10;;
Nov) month=November; nummonth=11;;
Dec) month=December; nummonth=12;;
esac
day=$2
# Here we have to deal with the problem that the ls output gives either
# the time of day or the year.
case $3 in
*:*) set `date`; eval year=\$$#
case $2 in
Jan) nummonthtod=1;;
Feb) nummonthtod=2;;
Mar) nummonthtod=3;;
Apr) nummonthtod=4;;
May) nummonthtod=5;;
Jun) nummonthtod=6;;
Jul) nummonthtod=7;;
Aug) nummonthtod=8;;
Sep) nummonthtod=9;;
Oct) nummonthtod=10;;
Nov) nummonthtod=11;;
Dec) nummonthtod=12;;
esac
# For the first six month of the year the time notation can also
# be used for files modified in the last year.
if (expr $nummonth \> $nummonthtod) > /dev/null;
then
year=`expr $year - 1`
fi;;
*) year=$3;;
esac
# The result.
echo $day $month $year
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View file

@ -1,82 +0,0 @@
#
# Sample boot menu configuration file
#
# Boot automatically after 30 secs.
timeout 30
# By default, boot the first entry.
default 0
# Fallback to the second entry.
fallback 1
# For booting GNU/Hurd
title GNU/Hurd
root (hd0,0)
kernel /boot/gnumach.gz root=hd0s1
module /boot/serverboot.gz
# For booting GNU/Linux
title GNU/Linux
root (hd1,0)
kernel /vmlinuz root=/dev/hdb1
#initrd /initrd.img
# For booting GNU/kFreeBSD
title GNU/kFreeBSD
root (hd0,2,a)
kernel /boot/loader.gz
# For booting GNU/kNetBSD
title GNU/kNetBSD
root (hd0,2,a)
kernel --type=netbsd /boot/knetbsd.gz
# For booting Mach (getting kernel from floppy)
title Utah Mach4 multiboot
root (hd0,2)
pause Insert the diskette now!!
kernel (fd0)/boot/kernel root=hd0s3
module (fd0)/boot/bootstrap
# For booting FreeBSD
title FreeBSD
root (hd0,2,a)
kernel /boot/loader
# For booting NetBSD
title NetBSD
root (hd0,2,a)
kernel --type=netbsd /netbsd
# For booting OpenBSD
title OpenBSD
root (hd0,2,a)
kernel --type=netbsd /bsd
# For booting OS/2
title OS/2
root (hd0,1)
makeactive
# chainload OS/2 bootloader from the first sector
chainloader +1
# This is similar to "chainload", but loads a specific file
#chainloader /boot/chain.os2
# For booting Windows NT or Windows95
title Windows NT / Windows 95 boot menu
rootnoverify (hd0,0)
makeactive
chainloader +1
# For loading DOS if Windows NT is installed
# chainload /bootsect.dos
# For installing GRUB into the hard disk
title Install GRUB into the hard disk
root (hd0,0)
setup (hd0)
# Change the colors.
title Change the colors
color light-green/brown blink-red/blue

View file

@ -1,4 +0,0 @@
@set UPDATED 8 May 2005
@set UPDATED-MONTH May 2005
@set EDITION 0.97
@set VERSION 0.97

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
.deps
Makefile
grub

View file

@ -1,19 +0,0 @@
sbin_PROGRAMS = grub
if SERIAL_SPEED_SIMULATION
SERIAL_FLAGS = -DSUPPORT_SERIAL=1 -DSIMULATE_SLOWNESS_OF_SERIAL=1
else
SERIAL_FLAGS = -DSUPPORT_SERIAL=1
endif
AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
AM_CFLAGS = $(GRUB_CFLAGS)
grub_SOURCES = main.c asmstub.c
grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS)

View file

@ -1,445 +0,0 @@
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 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.
@SET_MAKE@
SOURCES = $(grub_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
sbin_PROGRAMS = grub$(EXEEXT)
subdir = grub
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
am_grub_OBJECTS = main.$(OBJEXT) asmstub.$(OBJEXT)
grub_OBJECTS = $(am_grub_OBJECTS)
am__DEPENDENCIES_1 =
grub_DEPENDENCIES = ../stage2/libgrub.a ../lib/libcommon.a \
$(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(grub_SOURCES)
DIST_SOURCES = $(grub_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FSYS_CFLAGS = @FSYS_CFLAGS@
GRUB_CFLAGS = @GRUB_CFLAGS@
GRUB_LIBS = @GRUB_LIBS@
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
NET_CFLAGS = @NET_CFLAGS@
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
RANLIB = @RANLIB@
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STAGE1_CFLAGS = @STAGE1_CFLAGS@
STAGE2_CFLAGS = @STAGE2_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
@SERIAL_SPEED_SIMULATION_FALSE@SERIAL_FLAGS = -DSUPPORT_SERIAL=1
@SERIAL_SPEED_SIMULATION_TRUE@SERIAL_FLAGS = -DSUPPORT_SERIAL=1 -DSIMULATE_SLOWNESS_OF_SERIAL=1
AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
AM_CFLAGS = $(GRUB_CFLAGS)
grub_SOURCES = main.c asmstub.c
grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu grub/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu grub/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
@list='$(sbin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-sbinPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(sbin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
rm -f "$(DESTDIR)$(sbindir)/$$f"; \
done
clean-sbinPROGRAMS:
-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
grub$(EXEEXT): $(grub_OBJECTS) $(grub_DEPENDENCIES)
@rm -f grub$(EXEEXT)
$(LINK) $(grub_LDFLAGS) $(grub_OBJECTS) $(grub_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asmstub.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(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 -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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 "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(sbindir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am: install-sbinPROGRAMS
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-sbinPROGRAMS ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-sbinPROGRAMS install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-info-am uninstall-sbinPROGRAMS
# 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:

File diff suppressed because it is too large Load diff

View file

@ -1,272 +0,0 @@
/* main.c - experimental GRUB stage2 that runs under Unix */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
*
* 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.
*
* 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.
*/
/* Simulator entry point. */
int grub_stage2 (void);
#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <setjmp.h>
#define WITHOUT_LIBC_STUBS 1
#include <shared.h>
#include <term.h>
#include <device.h>
char *program_name = 0;
int use_config_file = 1;
int use_preset_menu = 0;
#ifdef HAVE_LIBCURSES
int use_curses = 1;
#else
int use_curses = 0;
#endif
int verbose = 0;
int read_only = 0;
int floppy_disks = 1;
char *device_map_file = 0;
static int default_boot_drive;
static int default_install_partition;
static char *default_config_file;
#define OPT_HELP -2
#define OPT_VERSION -3
#define OPT_HOLD -4
#define OPT_CONFIG_FILE -5
#define OPT_INSTALL_PARTITION -6
#define OPT_BOOT_DRIVE -7
#define OPT_NO_CONFIG_FILE -8
#define OPT_NO_CURSES -9
#define OPT_BATCH -10
#define OPT_VERBOSE -11
#define OPT_READ_ONLY -12
#define OPT_PROBE_SECOND_FLOPPY -13
#define OPT_NO_FLOPPY -14
#define OPT_DEVICE_MAP -15
#define OPT_PRESET_MENU -16
#define OPT_NO_PAGER -17
#define OPTSTRING ""
static struct option longopts[] =
{
{"batch", no_argument, 0, OPT_BATCH},
{"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
{"config-file", required_argument, 0, OPT_CONFIG_FILE},
{"device-map", required_argument, 0, OPT_DEVICE_MAP},
{"help", no_argument, 0, OPT_HELP},
{"hold", optional_argument, 0, OPT_HOLD},
{"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
{"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE},
{"no-curses", no_argument, 0, OPT_NO_CURSES},
{"no-floppy", no_argument, 0, OPT_NO_FLOPPY},
{"no-pager", no_argument, 0, OPT_NO_PAGER},
{"preset-menu", no_argument, 0, OPT_PRESET_MENU},
{"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY},
{"read-only", no_argument, 0, OPT_READ_ONLY},
{"verbose", no_argument, 0, OPT_VERBOSE},
{"version", no_argument, 0, OPT_VERSION},
{0},
};
static void
usage (int status)
{
if (status)
fprintf (stderr, "Try ``grub --help'' for more information.\n");
else
printf ("\
Usage: grub [OPTION]...\n\
\n\
Enter the GRand Unified Bootloader command shell.\n\
\n\
--batch turn on batch mode for non-interactive use\n\
--boot-drive=DRIVE specify stage2 boot_drive [default=0x%x]\n\
--config-file=FILE specify stage2 config_file [default=%s]\n\
--device-map=FILE use the device map file FILE\n\
--help display this message and exit\n\
--hold wait until a debugger will attach\n\
--install-partition=PAR specify stage2 install_partition [default=0x%x]\n\
--no-config-file do not use the config file\n\
--no-curses do not use curses\n\
--no-floppy do not probe any floppy drive\n\
--no-pager do not use internal pager\n\
--preset-menu use the preset menu\n\
--probe-second-floppy probe the second floppy drive\n\
--read-only do not write anything to devices\n\
--verbose print verbose messages\n\
--version print version information and exit\n\
\n\
Report bugs to <bug-grub@gnu.org>.\n\
",
default_boot_drive, default_config_file,
default_install_partition);
exit (status);
}
int
main (int argc, char **argv)
{
int c;
int hold = 0;
/* First of all, call sync so that all in-core data is scheduled to be
actually written to disks. This is very important because GRUB does
not use ordinary stdio interface but raw devices. */
sync ();
program_name = argv[0];
default_boot_drive = boot_drive;
default_install_partition = install_partition;
if (config_file)
default_config_file = config_file;
else
default_config_file = "NONE";
/* Parse command-line options. */
do
{
c = getopt_long (argc, argv, OPTSTRING, longopts, 0);
switch (c)
{
case EOF:
/* Fall through the bottom of the loop. */
break;
case OPT_HELP:
usage (0);
break;
case OPT_VERSION:
printf ("grub (GNU GRUB " VERSION ")\n");
exit (0);
break;
case OPT_HOLD:
if (! optarg)
hold = -1;
else
hold = atoi (optarg);
break;
case OPT_CONFIG_FILE:
strncpy (config_file, optarg, 127); /* FIXME: arbitrary */
config_file[127] = '\0';
break;
case OPT_INSTALL_PARTITION:
install_partition = strtoul (optarg, 0, 0);
if (install_partition == ULONG_MAX)
{
perror ("strtoul");
exit (1);
}
break;
case OPT_BOOT_DRIVE:
boot_drive = strtoul (optarg, 0, 0);
if (boot_drive == ULONG_MAX)
{
perror ("strtoul");
exit (1);
}
if (boot_drive >= NUM_DISKS)
{
fprintf (stderr, "boot_drive should be from 0 to %d\n",
NUM_DISKS - 1);
exit (1);
}
break;
case OPT_NO_CONFIG_FILE:
use_config_file = 0;
break;
case OPT_NO_CURSES:
use_curses = 0;
break;
case OPT_NO_PAGER:
use_pager = 0;
break;
case OPT_BATCH:
/* This is the same as "--no-config-file --no-curses --no-pager". */
use_config_file = 0;
use_curses = 0;
use_pager = 0;
break;
case OPT_READ_ONLY:
read_only = 1;
break;
case OPT_VERBOSE:
verbose = 1;
break;
case OPT_NO_FLOPPY:
floppy_disks = 0;
break;
case OPT_PROBE_SECOND_FLOPPY:
floppy_disks = 2;
break;
case OPT_DEVICE_MAP:
device_map_file = strdup (optarg);
break;
case OPT_PRESET_MENU:
use_preset_menu = 1;
break;
default:
usage (1);
}
}
while (c != EOF);
/* Wait until the HOLD variable is cleared by an attached debugger. */
if (hold && verbose)
printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
program_name, (int) getpid ());
while (hold)
{
if (hold > 0)
hold--;
sleep (1);
}
/* If we don't have curses (!HAVE_LIBCURSES or --no-curses or
--batch) put terminal to dumb for better handling of line i/o */
if (! use_curses)
current_term->flags = TERM_NO_EDIT | TERM_DUMB;
/* Transfer control to the stage2 simulator. */
exit (grub_stage2 ());
}

View file

@ -1,323 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2004-12-17.09
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit 0;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit 0;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
shift
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit 1; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View file

@ -1,2 +0,0 @@
.deps
Makefile

View file

@ -1,6 +0,0 @@
noinst_LIBRARIES = libcommon.a
AM_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/stage2 \
-I$(top_srcdir)/stage1
libcommon_a_SOURCES = getopt.c getopt1.c getopt.h device.c device.h

View file

@ -1,416 +0,0 @@
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 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.
@SET_MAKE@
SOURCES = $(libcommon_a_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = lib
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
AR = ar
ARFLAGS = cru
libcommon_a_AR = $(AR) $(ARFLAGS)
libcommon_a_LIBADD =
am_libcommon_a_OBJECTS = getopt.$(OBJEXT) getopt1.$(OBJEXT) \
device.$(OBJEXT)
libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libcommon_a_SOURCES)
DIST_SOURCES = $(libcommon_a_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FSYS_CFLAGS = @FSYS_CFLAGS@
GRUB_CFLAGS = @GRUB_CFLAGS@
GRUB_LIBS = @GRUB_LIBS@
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
NET_CFLAGS = @NET_CFLAGS@
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
RANLIB = @RANLIB@
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STAGE1_CFLAGS = @STAGE1_CFLAGS@
STAGE2_CFLAGS = @STAGE2_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
noinst_LIBRARIES = libcommon.a
AM_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/stage2 \
-I$(top_srcdir)/stage1
libcommon_a_SOURCES = getopt.c getopt1.c getopt.h device.c device.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES)
-rm -f libcommon.a
$(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
$(RANLIB) libcommon.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(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 -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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 "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-info-am
# 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:

View file

@ -1,950 +0,0 @@
/* device.c - Some helper functions for OS devices and BIOS drives */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
*
* 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.
*
* 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.
*/
/* Try to use glibc's transparant LFS support. */
#define _LARGEFILE_SOURCE 1
/* lseek becomes synonymous with lseek64. */
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#ifdef __linux__
# if !defined(__GLIBC__) || \
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
/* Maybe libc doesn't have large file support. */
# include <linux/unistd.h> /* _llseek */
# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
# include <sys/ioctl.h> /* ioctl */
# ifndef HDIO_GETGEO
# define HDIO_GETGEO 0x0301 /* get device geometry */
/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
defined. */
struct hd_geometry
{
unsigned char heads;
unsigned char sectors;
unsigned short cylinders;
unsigned long start;
};
# endif /* ! HDIO_GETGEO */
# ifndef FLOPPY_MAJOR
# define FLOPPY_MAJOR 2 /* the major number for floppy */
# endif /* ! FLOPPY_MAJOR */
# ifndef MAJOR
# define MAJOR(dev) \
({ \
unsigned long long __dev = (dev); \
(unsigned) ((__dev >> 8) & 0xfff) \
| ((unsigned int) (__dev >> 32) & ~0xfff); \
})
# endif /* ! MAJOR */
# ifndef CDROM_GET_CAPABILITY
# define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
# endif /* ! CDROM_GET_CAPABILITY */
# ifndef BLKGETSIZE64
# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size */
# endif /* ! BLKGETSIZE64 */
#endif /* __linux__ */
/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */
#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__)
# define __FreeBSD_kernel__
#endif
#ifdef __FreeBSD_kernel__
/* Obtain version of kFreeBSD headers */
# include <osreldate.h>
# ifndef __FreeBSD_kernel_version
# define __FreeBSD_kernel_version __FreeBSD_version
# endif
/* Runtime detection of kernel */
# include <sys/utsname.h>
int
get_kfreebsd_version ()
{
struct utsname uts;
int major; int minor, v[2];
uname (&uts);
sscanf (uts.release, "%d.%d", &major, &minor);
if (major >= 9)
major = 9;
if (major >= 5)
{
v[0] = minor/10; v[1] = minor%10;
}
else
{
v[0] = minor%10; v[1] = minor/10;
}
return major*100000+v[0]*10000+v[1]*1000;
}
#endif /* __FreeBSD_kernel__ */
#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/ioctl.h> /* ioctl */
# include <sys/disklabel.h>
# include <sys/cdio.h> /* CDIOCCLRDEBUG */
# if defined(__FreeBSD_kernel__)
# include <sys/param.h>
# if __FreeBSD_kernel_version >= 500040
# include <sys/disk.h>
# endif
# endif /* __FreeBSD_kernel__ */
#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
#ifdef HAVE_OPENDISK
# include <util.h>
#endif /* HAVE_OPENDISK */
#define WITHOUT_LIBC_STUBS 1
#include <shared.h>
#include <device.h>
/* Get the geometry of a drive DRIVE. */
void
get_drive_geometry (struct geometry *geom, char **map, int drive)
{
int fd;
if (geom->flags == -1)
{
fd = open (map[drive], O_RDONLY);
assert (fd >= 0);
}
else
fd = geom->flags;
/* XXX This is the default size. */
geom->sector_size = SECTOR_SIZE;
#if defined(__linux__)
/* Linux */
{
struct hd_geometry hdg;
unsigned long long nr;
if (ioctl (fd, HDIO_GETGEO, &hdg))
goto fail;
if (ioctl (fd, BLKGETSIZE64, &nr))
goto fail;
/* Got the geometry, so save it. */
geom->cylinders = hdg.cylinders;
geom->heads = hdg.heads;
geom->sectors = hdg.sectors;
geom->total_sectors = nr / 512;
goto success;
}
#elif defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
# if defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version >= 500040
/* kFreeBSD version 5 or later */
if (get_kfreebsd_version () >= 500040)
{
unsigned int sector_size;
off_t media_size;
unsigned int tmp;
if(ioctl (fd, DIOCGSECTORSIZE, &sector_size) != 0)
sector_size = 512;
if (ioctl (fd, DIOCGMEDIASIZE, &media_size) != 0)
goto fail;
geom->total_sectors = media_size / sector_size;
if (ioctl (fd, DIOCGFWSECTORS, &tmp) == 0)
geom->sectors = tmp;
else
geom->sectors = 63;
if (ioctl (fd, DIOCGFWHEADS, &tmp) == 0)
geom->heads = tmp;
else if (geom->total_sectors <= 63 * 1 * 1024)
geom->heads = 1;
else if (geom->total_sectors <= 63 * 16 * 1024)
geom->heads = 16;
else
geom->heads = 255;
geom->cylinders = (geom->total_sectors
/ geom->heads
/ geom->sectors);
goto success;
}
else
#endif /* defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version >= 500040 */
/* kFreeBSD < 5, NetBSD or OpenBSD */
{
struct disklabel hdg;
if (ioctl (fd, DIOCGDINFO, &hdg))
goto fail;
geom->cylinders = hdg.d_ncylinders;
geom->heads = hdg.d_ntracks;
geom->sectors = hdg.d_nsectors;
geom->total_sectors = hdg.d_secperunit;
goto success;
}
#else
/* Notably, defined(__GNU__) */
# warning "Automatic detection of geometries will be performed only \
partially. This is not fatal."
#endif
fail:
{
struct stat st;
/* FIXME: It would be nice to somehow compute fake C/H/S settings,
given a proper st_blocks size. */
if (drive & 0x80)
{
geom->cylinders = DEFAULT_HD_CYLINDERS;
geom->heads = DEFAULT_HD_HEADS;
geom->sectors = DEFAULT_HD_SECTORS;
}
else
{
geom->cylinders = DEFAULT_FD_CYLINDERS;
geom->heads = DEFAULT_FD_HEADS;
geom->sectors = DEFAULT_FD_SECTORS;
}
/* Set the total sectors properly, if we can. */
if (! fstat (fd, &st) && st.st_size)
geom->total_sectors = st.st_size >> SECTOR_BITS;
else
geom->total_sectors = geom->cylinders * geom->heads * geom->sectors;
}
success:
if (geom->flags == -1)
close (fd);
}
#ifdef __linux__
/* Check if we have devfs support. */
static int
have_devfs (void)
{
static int dev_devfsd_exists = -1;
if (dev_devfsd_exists < 0)
{
struct stat st;
dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
}
return dev_devfsd_exists;
}
#endif /* __linux__ */
/* These three functions are quite different among OSes. */
static void
get_floppy_disk_name (char *name, int unit)
{
#if defined(__linux__)
/* GNU/Linux */
if (have_devfs ())
sprintf (name, "/dev/floppy/%d", unit);
else
sprintf (name, "/dev/fd%d", unit);
#elif defined(__GNU__)
/* GNU/Hurd */
sprintf (name, "/dev/fd%d", unit);
#elif defined(__FreeBSD_kernel__)
/* kFreeBSD */
if (get_kfreebsd_version () >= 400000)
sprintf (name, "/dev/fd%d", unit);
else
sprintf (name, "/dev/rfd%d", unit);
#elif defined(__NetBSD__)
/* NetBSD */
/* opendisk() doesn't work for floppies. */
sprintf (name, "/dev/rfd%da", unit);
#elif defined(__OpenBSD__)
/* OpenBSD */
sprintf (name, "/dev/rfd%dc", unit);
#elif defined(__QNXNTO__)
/* QNX RTP */
sprintf (name, "/dev/fd%d", unit);
#else
# warning "BIOS floppy drives cannot be guessed in your operating system."
/* Set NAME to a bogus string. */
*name = 0;
#endif
}
static void
get_ide_disk_name (char *name, int unit)
{
#if defined(__linux__)
/* GNU/Linux */
sprintf (name, "/dev/hd%c", unit + 'a');
#elif defined(__GNU__)
/* GNU/Hurd */
sprintf (name, "/dev/hd%d", unit);
#elif defined(__FreeBSD_kernel__)
/* kFreeBSD */
if (get_kfreebsd_version () >= 400000)
sprintf (name, "/dev/ad%d", unit);
else
sprintf (name, "/dev/rwd%d", unit);
#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
/* NetBSD */
char shortname[16];
int fd;
sprintf (shortname, "wd%d", unit);
fd = opendisk (shortname, O_RDONLY, name,
16, /* length of NAME */
0 /* char device */
);
close (fd);
#elif defined(__OpenBSD__)
/* OpenBSD */
sprintf (name, "/dev/rwd%dc", unit);
#elif defined(__QNXNTO__)
/* QNX RTP */
/* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
contain SCSI disks. */
sprintf (name, "/dev/hd%d", unit);
#else
# warning "BIOS IDE drives cannot be guessed in your operating system."
/* Set NAME to a bogus string. */
*name = 0;
#endif
}
static void
get_scsi_disk_name (char *name, int unit)
{
#if defined(__linux__)
/* GNU/Linux */
sprintf (name, "/dev/sd%c", unit + 'a');
#elif defined(__GNU__)
/* GNU/Hurd */
sprintf (name, "/dev/sd%d", unit);
#elif defined(__FreeBSD_kernel__)
/* kFreeBSD */
if (get_kfreebsd_version () >= 400000)
sprintf (name, "/dev/da%d", unit);
else
sprintf (name, "/dev/rda%d", unit);
#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
/* NetBSD */
char shortname[16];
int fd;
sprintf (shortname, "sd%d", unit);
fd = opendisk (shortname, O_RDONLY, name,
16, /* length of NAME */
0 /* char device */
);
close (fd);
#elif defined(__OpenBSD__)
/* OpenBSD */
sprintf (name, "/dev/rsd%dc", unit);
#elif defined(__QNXNTO__)
/* QNX RTP */
/* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
disable the detection of SCSI disks here. */
*name = 0;
#else
# warning "BIOS SCSI drives cannot be guessed in your operating system."
/* Set NAME to a bogus string. */
*name = 0;
#endif
}
#ifdef __linux__
static void
get_dac960_disk_name (char *name, int controller, int drive)
{
sprintf (name, "/dev/rd/c%dd%d", controller, drive);
}
static void
get_ataraid_disk_name (char *name, int unit)
{
sprintf (name, "/dev/ataraid/d%c", unit + '0');
}
static void
get_i2o_disk_name (char *name, char unit)
{
sprintf (name, "/dev/i2o/hd%c", unit);
}
#endif
/* Check if DEVICE can be read. If an error occurs, return zero,
otherwise return non-zero. */
int
check_device (const char *device)
{
char buf[512];
FILE *fp;
/* If DEVICE is empty, just return 1. */
if (*device == 0)
return 1;
fp = fopen (device, "r");
if (! fp)
{
switch (errno)
{
#ifdef ENOMEDIUM
case ENOMEDIUM:
# if 0
/* At the moment, this finds only CDROMs, which can't be
read anyway, so leave it out. Code should be
reactivated if `removable disks' and CDROMs are
supported. */
/* Accept it, it may be inserted. */
return 1;
# endif
break;
#endif /* ENOMEDIUM */
default:
/* Break case and leave. */
break;
}
/* Error opening the device. */
return 0;
}
/* Make sure CD-ROMs don't get assigned a BIOS disk number
before SCSI disks! */
#ifdef __linux__
# ifdef CDROM_GET_CAPABILITY
if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
return 0;
# else /* ! CDROM_GET_CAPABILITY */
/* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */
{
struct hd_geometry hdg;
struct stat st;
if (fstat (fileno (fp), &st))
return 0;
/* If it is a block device and isn't a floppy, check if HDIO_GETGEO
succeeds. */
if (S_ISBLK (st.st_mode)
&& MAJOR (st.st_rdev) != FLOPPY_MAJOR
&& ioctl (fileno (fp), HDIO_GETGEO, &hdg))
return 0;
}
# endif /* ! CDROM_GET_CAPABILITY */
#endif /* __linux__ */
#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
# ifdef CDIOCCLRDEBUG
if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
return 0;
# endif /* CDIOCCLRDEBUG */
#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
/* Attempt to read the first sector. */
if (fread (buf, 1, 512, fp) != 512)
{
fclose (fp);
return 0;
}
fclose (fp);
return 1;
}
/* Read mapping information from FP, and write it to MAP. */
static int
read_device_map (FILE *fp, char **map, const char *map_file)
{
auto void show_error (int no, const char *msg);
auto void show_warning (int no, const char *msg, ...);
auto void show_error (int no, const char *msg)
{
fprintf (stderr, "%s:%d: error: %s\n", map_file, no, msg);
}
auto void show_warning (int no, const char *msg, ...)
{
va_list ap;
va_start (ap, msg);
fprintf (stderr, "%s:%d: warning: ", map_file, no);
vfprintf (stderr, msg, ap);
va_end (ap);
}
/* If there is the device map file, use the data in it instead of
probing devices. */
char buf[1024]; /* XXX */
int line_number = 0;
while (fgets (buf, sizeof (buf), fp))
{
char *ptr, *eptr;
int drive;
int is_floppy = 0;
/* Increase the number of lines. */
line_number++;
/* If the first character is '#', skip it. */
if (buf[0] == '#')
continue;
ptr = buf;
/* Skip leading spaces. */
while (*ptr && isspace (*ptr))
ptr++;
/* Skip empty lines. */
if (! *ptr)
continue;
if (*ptr != '(')
{
show_error (line_number, "No open parenthesis found");
return 0;
}
ptr++;
if ((*ptr != 'f' && *ptr != 'h') || *(ptr + 1) != 'd')
{
show_error (line_number, "Bad drive name");
return 0;
}
if (*ptr == 'f')
is_floppy = 1;
ptr += 2;
drive = strtoul (ptr, &ptr, 10);
if (drive < 0)
{
show_error (line_number, "Bad device number");
return 0;
}
else if (drive > 127)
{
show_warning (line_number,
"Ignoring %cd%d due to a BIOS limitation",
is_floppy ? 'f' : 'h', drive);
continue;
}
if (! is_floppy)
drive += 0x80;
if (*ptr != ')')
{
show_error (line_number, "No close parenthesis found");
return 0;
}
ptr++;
/* Skip spaces. */
while (*ptr && isspace (*ptr))
ptr++;
if (! *ptr)
{
show_error (line_number, "No filename found");
return 0;
}
/* Terminate the filename. */
eptr = ptr;
while (*eptr && ! isspace (*eptr))
eptr++;
*eptr = 0;
/* Multiple entries for a given drive is not allowed. */
if (map[drive])
{
show_error (line_number, "Duplicated entry found");
return 0;
}
map[drive] = strdup (ptr);
assert (map[drive]);
}
return 1;
}
/* Initialize the device map MAP. *MAP will be allocated from the heap
space. If MAP_FILE is not NULL, then read mappings from the file
MAP_FILE if it exists, otherwise, write guessed mappings to the file.
FLOPPY_DISKS is the number of floppy disk drives which will be probed.
If it is zero, don't probe any floppy at all. If it is one, probe one
floppy. If it is two, probe two floppies. And so on. */
int
init_device_map (char ***map, const char *map_file, int floppy_disks)
{
int i;
int num_hd = 0;
FILE *fp = 0;
assert (map);
assert (*map == 0);
*map = malloc (NUM_DISKS * sizeof (char *));
assert (*map);
/* Probe devices for creating the device map. */
/* Initialize DEVICE_MAP. */
for (i = 0; i < NUM_DISKS; i++)
(*map)[i] = 0;
if (map_file)
{
/* Open the device map file. */
fp = fopen (map_file, "r");
if (fp)
{
int ret;
ret = read_device_map (fp, *map, map_file);
fclose (fp);
return ret;
}
}
/* Print something so that the user does not think GRUB has been
crashed. */
fprintf (stderr,
"Probing devices to guess BIOS drives. "
"This may take a long time.\n");
if (map_file)
/* Try to open the device map file to write the probed data. */
fp = fopen (map_file, "w");
/* Floppies. */
for (i = 0; i < floppy_disks; i++)
{
char name[16];
get_floppy_disk_name (name, i);
/* In floppies, write the map, whether check_device succeeds
or not, because the user just does not insert floppies. */
if (fp)
fprintf (fp, "(fd%d)\t%s\n", i, name);
if (check_device (name))
{
(*map)[i] = strdup (name);
assert ((*map)[i]);
}
}
#ifdef __linux__
if (have_devfs ())
{
while (1)
{
char discn[32];
char name[PATH_MAX];
struct stat st;
/* Linux creates symlinks "/dev/discs/discN" for convenience.
The way to number disks is the same as GRUB's. */
sprintf (discn, "/dev/discs/disc%d", num_hd);
if (stat (discn, &st) < 0)
break;
if (realpath (discn, name))
{
strcat (name, "/disc");
(*map)[num_hd + 0x80] = strdup (name);
assert ((*map)[num_hd + 0x80]);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
}
num_hd++;
}
/* OK, close the device map file if opened. */
if (fp)
fclose (fp);
return 1;
}
#endif /* __linux__ */
/* IDE disks. */
for (i = 0; i < 8; i++)
{
char name[16];
get_ide_disk_name (name, i);
if (check_device (name))
{
(*map)[num_hd + 0x80] = strdup (name);
assert ((*map)[num_hd + 0x80]);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
num_hd++;
}
}
#ifdef __linux__
/* ATARAID disks. */
for (i = 0; i < 8; i++)
{
char name[20];
get_ataraid_disk_name (name, i);
if (check_device (name))
{
(*map)[num_hd + 0x80] = strdup (name);
assert ((*map)[num_hd + 0x80]);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
num_hd++;
}
}
#endif /* __linux__ */
/* The rest is SCSI disks. */
for (i = 0; i < 16; i++)
{
char name[16];
get_scsi_disk_name (name, i);
if (check_device (name))
{
(*map)[num_hd + 0x80] = strdup (name);
assert ((*map)[num_hd + 0x80]);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
num_hd++;
}
}
#ifdef __linux__
/* This is for DAC960 - we have
/dev/rd/c<controller>d<logical drive>p<partition>.
DAC960 driver currently supports up to 8 controllers, 32 logical
drives, and 7 partitions. */
{
int controller, drive;
for (controller = 0; controller < 8; controller++)
{
for (drive = 0; drive < 15; drive++)
{
char name[24];
get_dac960_disk_name (name, controller, drive);
if (check_device (name))
{
(*map)[num_hd + 0x80] = strdup (name);
assert ((*map)[num_hd + 0x80]);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
num_hd++;
}
}
}
}
/* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
{
int unit;
for (unit = 'a'; unit < 'f'; unit++)
{
char name[24];
get_i2o_disk_name (name, unit);
if (check_device (name))
{
(*map)[num_hd + 0x80] = strdup (name);
assert ((*map)[num_hd + 0x80]);
/* If the device map file is opened, write the map. */
if (fp)
fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
num_hd++;
}
}
}
#endif /* __linux__ */
/* OK, close the device map file if opened. */
if (fp)
fclose (fp);
return 1;
}
/* Restore the memory consumed for MAP. */
void
restore_device_map (char **map)
{
int i;
for (i = 0; i < NUM_DISKS; i++)
if (map[i])
free (map[i]);
free (map);
}
#ifdef __linux__
/* Linux-only functions, because Linux has a bug that the disk cache for
a whole disk is not consistent with the one for a partition of the
disk. */
int
is_disk_device (char **map, int drive)
{
struct stat st;
assert (map[drive] != 0);
assert (stat (map[drive], &st) == 0);
/* For now, disk devices under Linux are all block devices. */
return S_ISBLK (st.st_mode);
}
int
write_to_partition (char **map, int drive, int partition,
int sector, int size, const char *buf)
{
char dev[PATH_MAX]; /* XXX */
int fd;
if ((partition & 0x00FF00) != 0x00FF00)
{
/* If the partition is a BSD partition, it is difficult to
obtain the representation in Linux. So don't support that. */
errnum = ERR_DEV_VALUES;
return 1;
}
assert (map[drive] != 0);
strcpy (dev, map[drive]);
if (have_devfs ())
{
if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
strcpy (dev + strlen(dev) - 5, "/part");
}
else
{
if ((strncmp (dev, "/dev/ataraid/", 13) == 0) ||
(strncmp (dev, "/dev/rd/", 8) == 0))
strcpy (dev + strlen(dev), "p");
}
sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
/* Open the partition. */
fd = open (dev, O_RDWR);
if (fd < 0)
{
errnum = ERR_NO_PART;
return 0;
}
#if defined(__linux__) && (!defined(__GLIBC__) || \
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
/* Maybe libc doesn't have large file support. */
{
loff_t offset, result;
static int _llseek (uint filedes, ulong hi, ulong lo,
loff_t *res, uint wh);
_syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
loff_t *, res, uint, wh);
offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
{
errnum = ERR_DEV_VALUES;
return 0;
}
}
#else
{
off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
if (lseek (fd, offset, SEEK_SET) != offset)
{
errnum = ERR_DEV_VALUES;
return 0;
}
}
#endif
if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
{
close (fd);
errnum = ERR_WRITE;
return 0;
}
sync (); /* Paranoia. */
close (fd);
return 1;
}
#endif /* __linux__ */

View file

@ -1,48 +0,0 @@
/* device.h - Define macros and declare prototypes for device.c */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2004 Free Software Foundation, Inc.
*
* 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.
*
* 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.
*/
#ifndef DEVICE_MAP_HEADER
#define DEVICE_MAP_HEADER 1
/* The maximum number of BIOS disks. */
#define NUM_DISKS 256
/* Simulated disk sizes. */
#define DEFAULT_FD_CYLINDERS 80
#define DEFAULT_FD_HEADS 2
#define DEFAULT_FD_SECTORS 18
#define DEFAULT_HD_CYLINDERS 620
#define DEFAULT_HD_HEADS 128
#define DEFAULT_HD_SECTORS 63
/* Function prototypes. */
extern void get_drive_geometry (struct geometry *geom, char **map, int drive);
extern int check_device (const char *device);
extern int init_device_map (char ***map, const char *map_file,
int no_floppies);
extern void restore_device_map (char **map);
#ifdef __linux__
extern int is_disk_device (char **map, int drive);
extern int write_to_partition (char **map, int drive, int partition,
int offset, int size, const char *buf);
#endif /* __linux__ */
#endif /* DEVICE_MAP_HEADER */

File diff suppressed because it is too large Load diff

View file

@ -1,133 +0,0 @@
/* Declarations for getopt.
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
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. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if defined (__STDC__) && __STDC__
#ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt ();
#endif /* __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* getopt.h */

View file

@ -1,190 +0,0 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
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. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "getopt.h"
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

353
missing
View file

@ -1,353 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2004-09-07.08
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit 0
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit 0
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View file

@ -1,150 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
scriptversion=2004-02-15.20
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit 0
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View file

@ -1,2 +0,0 @@
.deps
Makefile

View file

@ -1,620 +0,0 @@
/**************************************************************************
ETHERBOOT - 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$
***************************************************************************/
/* #define EDEBUG */
#include "etherboot.h"
#include "nic.h"
#include "cards.h"
#include "timer.h"
#include "3c509.h"
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
static unsigned short eth_nic_base;
static enum { none, bnc, utp } connector = none; /* for 3C509 */
#ifdef INCLUDE_3C529
/*
* This table and several other pieces of the MCA support
* code were shamelessly borrowed from the Linux kernel source.
*
* MCA support added by Adam Fritzler (mid@auk.cx)
*
*/
struct el3_mca_adapters_struct {
const char *name;
int id;
};
static struct el3_mca_adapters_struct el3_mca_adapters[] = {
{ "3Com 3c529 EtherLink III (10base2)", 0x627c },
{ "3Com 3c529 EtherLink III (10baseT)", 0x627d },
{ "3Com 3c529 EtherLink III (test mode)", 0x62db },
{ "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },
{ "3Com 3c529 EtherLink III (TP)", 0x62f7 },
{ NULL, 0 },
};
#endif
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
static void t509_reset(struct nic *nic)
{
int i;
/***********************************************************
Reset 3Com 509 card
*************************************************************/
/* stop card */
outw(RX_DISABLE, BASE + EP_COMMAND);
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
;
outw(TX_DISABLE, BASE + EP_COMMAND);
outw(STOP_TRANSCEIVER, BASE + EP_COMMAND);
udelay(1000);
outw(RX_RESET, BASE + EP_COMMAND);
outw(TX_RESET, BASE + EP_COMMAND);
outw(C_INTR_LATCH, BASE + EP_COMMAND);
outw(SET_RD_0_MASK, BASE + EP_COMMAND);
outw(SET_INTR_MASK, BASE + EP_COMMAND);
outw(SET_RX_FILTER, BASE + EP_COMMAND);
/*
* initialize card
*/
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
;
GO_WINDOW(0);
/* Disable the card */
outw(0, BASE + EP_W0_CONFIG_CTRL);
/* Configure IRQ to none */
outw(SET_IRQ(0), BASE + EP_W0_RESOURCE_CFG);
/* Enable the card */
outw(ENABLE_DRQ_IRQ, BASE + EP_W0_CONFIG_CTRL);
GO_WINDOW(2);
/* Reload the ether_addr. */
for (i = 0; i < ETH_ALEN; i++)
outb(nic->node_addr[i], BASE + EP_W2_ADDR_0 + i);
outw(RX_RESET, BASE + EP_COMMAND);
outw(TX_RESET, BASE + EP_COMMAND);
/* 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(ACK_INTR | 0xff, BASE + EP_COMMAND);
outw(SET_RD_0_MASK | S_5_INTS, BASE + EP_COMMAND);
outw(SET_INTR_MASK, BASE + EP_COMMAND);
outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + EP_COMMAND);
/* configure BNC */
if (connector == bnc) {
outw(START_TRANSCEIVER, BASE + EP_COMMAND);
udelay(1000);
}
/* configure UTP */
else if (connector == utp) {
GO_WINDOW(4);
outw(ENABLE_UTP, BASE + EP_W4_MEDIA_TYPE);
sleep(2); /* Give time for media to negotiate */
GO_WINDOW(1);
}
/* start transceiver and receiver */
outw(RX_ENABLE, BASE + EP_COMMAND);
outw(TX_ENABLE, BASE + EP_COMMAND);
/* set early threshold for minimal packet length */
outw(SET_RX_EARLY_THRESH | ETH_ZLEN, BASE + EP_COMMAND);
outw(SET_TX_START_THRESH | 16, BASE + EP_COMMAND);
}
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static char padmap[] = {
0, 3, 2, 1};
static void t509_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
register unsigned int len;
int pad;
int status;
#ifdef EDEBUG
printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
#endif
/* swap bytes of type */
t= htons(t);
len=s+ETH_HLEN; /* 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_FRAME_LEN) {
return;
}
/* drop acknowledgements */
while ((status=inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE ) {
if (status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
outw(TX_RESET, BASE + EP_COMMAND);
outw(TX_ENABLE, BASE + EP_COMMAND);
}
outb(0x0, BASE + EP_W1_TX_STATUS);
}
while (inw(BASE + EP_W1_FREE_TX) < (unsigned short)len + pad + 4)
; /* no room in FIFO */
outw(len, BASE + EP_W1_TX_PIO_WR_1);
outw(0x0, BASE + EP_W1_TX_PIO_WR_1); /* Second dword meaningless */
/* write packet */
outsw(BASE + EP_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
outsw(BASE + EP_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
outw(t, BASE + EP_W1_TX_PIO_WR_1);
outsw(BASE + EP_W1_TX_PIO_WR_1, p, s / 2);
if (s & 1)
outb(*(p+s - 1), BASE + EP_W1_TX_PIO_WR_1);
while (pad--)
outb(0, BASE + EP_W1_TX_PIO_WR_1); /* Padding */
/* wait for Tx complete */
while((inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
;
}
/**************************************************************************
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;
cst=inw(BASE + EP_STATUS);
#ifdef EDEBUG
if(cst & 0x1FFF)
printf("-%hX-",cst);
#endif
if( (cst & S_RX_COMPLETE)==0 ) {
/* acknowledge everything */
outw(ACK_INTR| (cst & S_5_INTS), BASE + EP_COMMAND);
outw(C_INTR_LATCH, BASE + EP_COMMAND);
return 0;
}
status = inw(BASE + EP_W1_RX_STATUS);
#ifdef EDEBUG
printf("*%hX*",status);
#endif
if (status & ERR_RX) {
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
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("*%hX*",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;
}
udelay(1000); /* if incomplete wait 1 ms */
}
/* acknowledge reception of packet */
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
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*ETH_ALEN)
printf(",t=%hX,b]",type);
else
printf(",t=%hX]",type);
#endif
return (1);
}
/*************************************************************************
3Com 509 - specific routines
**************************************************************************/
static int
eeprom_rdy(void)
{
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.\n"); */
printf("3c509: eeprom busy.\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(int offset)
{
if (!eeprom_rdy())
return (0xffff);
outw(EEPROM_CMD_RD | offset, IS_BASE + EP_W0_EEPROM_COMMAND);
if (!eeprom_rdy())
return (0xffff);
return (inw(IS_BASE + EP_W0_EEPROM_DATA));
}
static int
send_ID_sequence(int port)
{
int cx, al;
for (al = 0xff, cx = 0; cx < 255; cx++) {
outb(al, port);
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(int id_port, int offset)
{
int i, data = 0;
outb(0x80 + offset, id_port);
/* Do we really need this wait? Won't be noticeable anyway */
udelay(10000);
for (i = 0; i < 16; i++)
data = (data << 1) | (inw(id_port) & 1);
return (data);
}
static void t509_disable(struct nic *nic)
{
outb(0xc0, EP_ID_PORT);
}
/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
#ifdef INCLUDE_3C529
struct nic *t529_probe(struct nic *nic, unsigned short *probe_addrs)
#else
struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
#endif
{
/* common variables */
int i;
int failcount;
#ifdef INCLUDE_3C529
struct el3_mca_adapters_struct *mcafound = NULL;
int mca_pos4 = 0, mca_pos5 = 0, mca_irq = 0;
#endif
t509_disable(nic); /* in case board was active */
/* note that nic is not used */
for (failcount = 0; failcount < 4000; failcount++) {
int data, j, io_base, id_port;
unsigned short k;
int ep_current_tag;
short *p;
#ifdef INCLUDE_3C529
int curboard;
#endif
id_port = EP_ID_PORT;
ep_current_tag = EP_LAST_TAG + 1;
/*********************************************************
Search for 3Com 509 card
***********************************************************/
#ifdef INCLUDE_3C529
/*
* XXX: We should really check to make sure we have an MCA
* bus controller before going ahead with this...
*
* For now, we avoid any hassle by making it a compile
* time option.
*
*/
printf("\nWarning: Assuming presence of MCA bus\n");
/* Make sure motherboard setup is off */
outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
/* Cycle through slots */
for(curboard=0; curboard<MCA_MAX_SLOT_NR; curboard++) {
int boardid;
int curcard;
outb_p(0x8|(curboard&0xf), MCA_ADAPTER_SETUP_REG);
boardid = inb_p(MCA_POS_REG(0));
boardid += inb_p(MCA_POS_REG(1)) << 8;
curcard = 0;
while (el3_mca_adapters[curcard].name) {
if (el3_mca_adapters[curcard].id == boardid) {
mcafound = &el3_mca_adapters[curcard];
mca_pos4 = inb_p(MCA_POS_REG(4));
mca_pos5 = inb_p(MCA_POS_REG(5));
goto donewithdetect;
}
else
curcard++;
}
}
donewithdetect:
/* Kill all setup modes */
outb_p(0, MCA_ADAPTER_SETUP_REG);
if (mcafound) {
eth_nic_base = ((short)((mca_pos4&0xfc)|0x02)) << 8;
mca_irq = mca_pos5 & 0x0f;
ep_current_tag--;
}
else
printf("MCA Card not found\n");
#endif
/* Look for the EISA boards, leave them activated */
/* search for the first card, ignore all others */
for(j = 1; j < 16; j++) {
io_base = (j * EP_EISA_START) | EP_EISA_W0;
if (inw(io_base + EP_W0_MFG_ID) != MFG_ID)
continue;
/* we must have 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(W0_P4_CMD_RESET_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
udelay(1000); /* Must wait 800 µs, be conservative */
outb(W0_P4_CMD_ENABLE_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
/*
* 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;
break;
}
ep_current_tag--;
/* Look for the ISA boards. Init and leave them actived */
/* search for the first card, ignore all others */
outb(0xc0, id_port); /* Global reset */
udelay(1000); /* wait 1 ms */
for (i = 0; i < EP_MAX_BOARDS; i++) {
outb(0, id_port);
outb(0, id_port);
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(ep_current_tag, id_port); /* tags board */
outb(ACTIVATE_ADAPTER_TO_CONFIG, id_port);
ep_current_tag--;
break;
}
if (i >= EP_MAX_BOARDS)
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);
#ifdef INCLUDE_3C529
/*
* On MCA, the PROD_ID matches the MCA card ID (POS0+POS1)
*/
if (mcafound) {
if (mcafound->id != k) {
printf("MCA: PROD_ID in EEPROM does not match MCA card ID! (%hX != %hX)\n", k, mcafound->id);
goto no3c509;
}
} else { /* for ISA/EISA */
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
goto no3c509;
}
#else
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
goto no3c509;
#endif
#ifdef INCLUDE_3C529
if (mcafound) {
printf("%s board found on MCA at %#hx IRQ %d -",
mcafound->name, eth_nic_base, mca_irq);
} else {
#endif
if(eth_nic_base >= EP_EISA_START)
printf("3C5x9 board on EISA at %#hx - ",eth_nic_base);
else
printf("3C5x9 board on ISA at %#hx - ",eth_nic_base);
#ifdef INCLUDE_3C529
}
#endif
/* test for presence of connectors */
i = inw(IS_BASE + EP_W0_CONFIG_CTRL);
j = (inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14) & 0x3;
switch(j) {
case 0:
if (i & IS_UTP) {
printf("10baseT\n");
connector = utp;
}
else {
printf("10baseT not present\n");
goto no3c509;
}
break;
case 1:
if (i & IS_AUI)
printf("10base5\n");
else {
printf("10base5 not present\n");
goto no3c509;
}
break;
case 3:
if (i & IS_BNC) {
printf("10base2\n");
connector = bnc;
}
else {
printf("10base2 not present\n");
goto no3c509;
}
break;
default:
printf("unknown connector\n");
goto no3c509;
}
/*
* Read the station address from the eeprom
*/
p = (unsigned short *) nic->node_addr;
for (i = 0; i < ETH_ALEN / 2; i++) {
GO_WINDOW(0);
p[i] = htons(get_e(i));
GO_WINDOW(2);
outw(ntohs(p[i]), BASE + EP_W2_ADDR_0 + (i * 2));
}
printf("Ethernet address: %!\n", nic->node_addr);
t509_reset(nic);
nic->reset = t509_reset;
nic->poll = t509_poll;
nic->transmit = t509_transmit;
nic->disable = t509_disable;
return nic;
no3c509:
printf("(probe fail)");
}
return 0;
}
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,397 +0,0 @@
/*
* 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(WINDOW_SELECT|(x), BASE+EP_COMMAND)
/**************************************************************************
*
* 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 (unsigned short) 0x0000 /* Wait at least 1ms
* after issuing */
#define WINDOW_SELECT (unsigned short) (0x1<<11)
#define START_TRANSCEIVER (unsigned 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 (unsigned short) (0x3<<11) /* state disabled on
* power-up */
#define RX_ENABLE (unsigned short) (0x4<<11)
#define RX_RESET (unsigned short) (0x5<<11)
#define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11)
#define TX_ENABLE (unsigned short) (0x9<<11)
#define TX_DISABLE (unsigned short) (0xa<<11)
#define TX_RESET (unsigned short) (0xb<<11)
#define REQ_INTR (unsigned short) (0xc<<11)
#define SET_INTR_MASK (unsigned short) (0xe<<11)
#define SET_RD_0_MASK (unsigned short) (0xf<<11)
#define SET_RX_FILTER (unsigned short) (0x10<<11)
#define FIL_INDIVIDUAL (unsigned short) (0x1)
#define FIL_GROUP (unsigned short) (0x2)
#define FIL_BRDCST (unsigned short) (0x4)
#define FIL_ALL (unsigned short) (0x8)
#define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11)
#define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11)
#define SET_TX_START_THRESH (unsigned short) (0x13<<11)
#define STATS_ENABLE (unsigned short) (0x15<<11)
#define STATS_DISABLE (unsigned short) (0x16<<11)
#define STOP_TRANSCEIVER (unsigned short) (0x17<<11)
/*
* The following C_* acknowledge the various interrupts. Some of them don't
* do anything. See the manual.
*/
#define ACK_INTR (unsigned short) (0x6800)
#define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1)
#define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2)
#define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4)
#define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8)
#define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10)
#define C_RX_EARLY (unsigned short) (ACK_INTR|0x20)
#define C_INT_RQD (unsigned short) (ACK_INTR|0x40)
#define C_UPD_STATS (unsigned 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 (unsigned short) (0x1)
#define S_CARD_FAILURE (unsigned short) (0x2)
#define S_TX_COMPLETE (unsigned short) (0x4)
#define S_TX_AVAIL (unsigned short) (0x8)
#define S_RX_COMPLETE (unsigned short) (0x10)
#define S_RX_EARLY (unsigned short) (0x20)
#define S_INT_RQD (unsigned short) (0x40)
#define S_UPD_STATS (unsigned 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 (unsigned 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 (unsigned short) (0x1<<15)
#define ERR_RX (unsigned short) (0x1<<14)
#define ERR_RX_OVERRUN (unsigned short) (0x8<<11)
#define ERR_RX_RUN_PKT (unsigned short) (0xb<<11)
#define ERR_RX_ALIGN (unsigned short) (0xc<<11)
#define ERR_RX_CRC (unsigned short) (0xd<<11)
#define ERR_RX_OVERSIZE (unsigned short) (0x9<<11)
#define ERR_RX_DRIBBLE (unsigned 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 (unsigned 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 (unsigned short) (0x07ff)
/* EISA support */
#define EP_EISA_START 0x1000
#define EP_EISA_W0 0x0c80
#ifdef INCLUDE_3C529
/* MCA support */
#define MCA_MOTHERBOARD_SETUP_REG 0x94
#define MCA_ADAPTER_SETUP_REG 0x96
#define MCA_MAX_SLOT_NR 8
#define MCA_POS_REG(n) (0x100+(n))
#endif
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,503 +0,0 @@
/*
* 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot
*
* Copyright (C) 2000 Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
* All rights reserved.
* Mar. 14, 2000
*
* 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.
*
* This code is based on Martin Renters' etherboot-4.4.3 3c509.c and
* Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver.
*
* Copyright (C) 1993-1994, David Greenman, Martin Renters.
* Copyright (C) 1993-1995, Andres Vega Garcia.
* Copyright (C) 1995, Serge Babkin.
*
* Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
*
*/
/* #define EDEBUG */
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "3c595.h"
#include "timer.h"
static unsigned short eth_nic_base, eth_asic_base;
static unsigned short vx_connector, vx_connectors;
static struct connector_entry {
int bit;
char *name;
} conn_tab[VX_CONNECTORS] = {
#define CONNECTOR_UTP 0
{ 0x08, "utp"},
#define CONNECTOR_AUI 1
{ 0x20, "aui"},
/* dummy */
{ 0, "???"},
#define CONNECTOR_BNC 3
{ 0x10, "bnc"},
#define CONNECTOR_TX 4
{ 0x02, "tx"},
#define CONNECTOR_FX 5
{ 0x04, "fx"},
#define CONNECTOR_MII 6
{ 0x40, "mii"},
{ 0, "???"}
};
static void vxgetlink(void);
static void vxsetlink(void);
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
static void t595_reset(struct nic *nic)
{
int i, j;
/***********************************************************
Reset 3Com 595 card
*************************************************************/
/* stop card */
outw(RX_DISABLE, BASE + VX_COMMAND);
outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
VX_BUSY_WAIT;
outw(TX_DISABLE, BASE + VX_COMMAND);
outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
udelay(8000);
outw(RX_RESET, BASE + VX_COMMAND);
VX_BUSY_WAIT;
outw(TX_RESET, BASE + VX_COMMAND);
VX_BUSY_WAIT;
outw(C_INTR_LATCH, BASE + VX_COMMAND);
outw(SET_RD_0_MASK, BASE + VX_COMMAND);
outw(SET_INTR_MASK, BASE + VX_COMMAND);
outw(SET_RX_FILTER, BASE + VX_COMMAND);
/*
* initialize card
*/
VX_BUSY_WAIT;
GO_WINDOW(0);
/* Disable the card */
/* outw(0, BASE + VX_W0_CONFIG_CTRL); */
/* Configure IRQ to none */
/* outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */
/* Enable the card */
/* outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */
GO_WINDOW(2);
/* Reload the ether_addr. */
for (i = 0; i < ETH_ALEN; i++)
outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);
outw(RX_RESET, BASE + VX_COMMAND);
VX_BUSY_WAIT;
outw(TX_RESET, BASE + VX_COMMAND);
VX_BUSY_WAIT;
/* Window 1 is operating window */
GO_WINDOW(1);
for (i = 0; i < 31; i++)
inb(BASE + VX_W1_TX_STATUS);
outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
/*
* Attempt to get rid of any stray interrupts that occured during
* configuration. On the i386 this isn't possible because one may
* already be queued. However, a single stray interrupt is
* unimportant.
*/
outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
outw(SET_RX_FILTER | FIL_INDIVIDUAL |
FIL_BRDCST, BASE + VX_COMMAND);
vxsetlink();
/*{
int i,j;
i = CONNECTOR_TX;
GO_WINDOW(3);
j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
GO_WINDOW(4);
outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
GO_WINDOW(1);
}*/
/* start tranciever and receiver */
outw(RX_ENABLE, BASE + VX_COMMAND);
outw(TX_ENABLE, BASE + VX_COMMAND);
}
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static char padmap[] = {
0, 3, 2, 1};
static void t595_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
register int len;
int pad;
int status;
#ifdef EDEBUG
printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
#endif
/* swap bytes of type */
t= htons(t);
len=s+ETH_HLEN; /* actual length of packet */
pad = padmap[len & 3];
/*
* The 3c595 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_FRAME_LEN) {
return;
}
/* drop acknowledgements */
while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
outw(TX_RESET, BASE + VX_COMMAND);
outw(TX_ENABLE, BASE + VX_COMMAND);
}
outb(0x0, BASE + VX_W1_TX_STATUS);
}
while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) {
/* no room in FIFO */
}
outw(len, BASE + VX_W1_TX_PIO_WR_1);
outw(0x0, BASE + VX_W1_TX_PIO_WR_1); /* Second dword meaningless */
/* write packet */
outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
outw(t, BASE + VX_W1_TX_PIO_WR_1);
outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2);
if (s & 1)
outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1);
while (pad--)
outb(0, BASE + VX_W1_TX_PIO_WR_1); /* Padding */
/* wait for Tx complete */
while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
;
}
/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
static int t595_poll(struct nic *nic)
{
/* common variables */
unsigned short type = 0; /* used by EDEBUG */
/* variables for 3C595 */
short status, cst;
register short rx_fifo;
cst=inw(BASE + VX_STATUS);
#ifdef EDEBUG
if(cst & 0x1FFF)
printf("-%hX-",cst);
#endif
if( (cst & S_RX_COMPLETE)==0 ) {
/* acknowledge everything */
outw(ACK_INTR | cst, BASE + VX_COMMAND);
outw(C_INTR_LATCH, BASE + VX_COMMAND);
return 0;
}
status = inw(BASE + VX_W1_RX_STATUS);
#ifdef EDEBUG
printf("*%hX*",status);
#endif
if (status & ERR_RX) {
outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
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 + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
if(rx_fifo & 1)
nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
nic->packetlen=rx_fifo;
while(1) {
status = inw(BASE + VX_W1_RX_STATUS);
#ifdef EDEBUG
printf("*%hX*",status);
#endif
rx_fifo = status & RX_BYTES_MASK;
if(rx_fifo>0) {
insw(BASE + VX_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 + VX_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;
}
udelay(1000);
}
/* acknowledge reception of packet */
outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
while (inw(BASE + VX_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*ETH_ALEN)
printf(",t=%hX,b]",type);
else
printf(",t=%hX]",type);
#endif
return 1;
}
/*************************************************************************
3Com 595 - specific routines
**************************************************************************/
static int
eeprom_rdy()
{
int i;
for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
udelay(1000);
if (i >= MAX_EEPROMBUSY) {
/* printf("3c595: eeprom failed to come ready.\n"); */
printf("3c595: eeprom is busy.\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(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND);
if (!eeprom_rdy())
return (0xffff);
return (inw(BASE + VX_W0_EEPROM_DATA));
}
static void
vxgetlink(void)
{
int n, k;
GO_WINDOW(3);
vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f;
for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
if (vx_connectors & conn_tab[k].bit) {
if (n > 0) {
printf("/");
}
printf(conn_tab[k].name);
n++;
}
}
if (vx_connectors == 0) {
printf("no connectors!");
return;
}
GO_WINDOW(3);
vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG)
& INTERNAL_CONNECTOR_MASK)
>> INTERNAL_CONNECTOR_BITS;
if (vx_connector & 0x10) {
vx_connector &= 0x0f;
printf("[*%s*]", conn_tab[vx_connector].name);
printf(": disable 'auto select' with DOS util!");
} else {
printf("[*%s*]", conn_tab[vx_connector].name);
}
}
static void
vxsetlink(void)
{
int i, j, k;
char *reason, *warning;
static short prev_flags;
static char prev_conn = -1;
if (prev_conn == -1) {
prev_conn = vx_connector;
}
i = vx_connector; /* default in EEPROM */
reason = "default";
warning = 0;
if ((vx_connectors & conn_tab[vx_connector].bit) == 0) {
warning = "strange connector type in EEPROM.";
reason = "forced";
i = CONNECTOR_UTP;
}
if (warning != 0) {
printf("warning: %s\n", warning);
}
printf("selected %s. (%s)\n", conn_tab[i].name, reason);
/* Set the selected connector. */
GO_WINDOW(3);
j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG);
/* First, disable all. */
outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
udelay(8000);
GO_WINDOW(4);
outw(0, BASE + VX_W4_MEDIA_TYPE);
/* Second, enable the selected one. */
switch(i) {
case CONNECTOR_UTP:
GO_WINDOW(4);
outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
break;
case CONNECTOR_BNC:
outw(START_TRANSCEIVER,BASE + VX_COMMAND);
udelay(8000);
break;
case CONNECTOR_TX:
case CONNECTOR_FX:
GO_WINDOW(4);
outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
break;
default: /* AUI and MII fall here */
break;
}
GO_WINDOW(1);
}
static void t595_disable(struct nic *nic)
{
outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
udelay(8000);
GO_WINDOW(4);
outw(0, BASE + VX_W4_MEDIA_TYPE);
GO_WINDOW(1);
}
/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
struct nic *t595_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
{
int i;
unsigned short *p;
if (probeaddrs == 0 || probeaddrs[0] == 0)
return 0;
/* eth_nic_base = probeaddrs[0] & ~3; */
eth_nic_base = pci->ioaddr;
GO_WINDOW(0);
outw(GLOBAL_RESET, BASE + VX_COMMAND);
VX_BUSY_WAIT;
vxgetlink();
/*
printf("\nEEPROM:");
for (i = 0; i < (EEPROMSIZE/2); i++) {
printf("%hX:", get_e(i));
}
printf("\n");
*/
/*
* Read the station address from the eeprom
*/
p = (unsigned short *) nic->node_addr;
for (i = 0; i < 3; i++) {
GO_WINDOW(0);
p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i));
GO_WINDOW(2);
outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2));
}
printf("Ethernet address: %!\n", nic->node_addr);
t595_reset(nic);
nic->reset = t595_reset;
nic->poll = t595_poll;
nic->transmit = t595_transmit;
nic->disable = t595_disable;
return nic;
}
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,435 +0,0 @@
/*
* 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 without 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.
*
October 2, 1994
Modified by: Andres Vega Garcia
INRIA - Sophia Antipolis, France
e-mail: avega@sophia.inria.fr
finger: avega@pax.inria.fr
*/
/*
* Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the
* 3c590 family.
*/
/*
* Modified by Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
* for etherboot
* Mar. 14, 2000
*/
/*
* 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 VX_LAST_TAG 0xd7
#define VX_MAX_BOARDS 16
#define VX_ID_PORT 0x100
/*
* some macros to acces long named fields
*/
#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)
/*
* Some short functions, worth to let them be a macro
*/
/**************************************************************************
* *
* These define the EEPROM data structure. They are used in the probe
* function to verify the existence 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 */
#define EEPROM_OEM_ADDR_0 0xa /* Word */
#define EEPROM_OEM_ADDR_1 0xb /* Word */
#define EEPROM_OEM_ADDR_2 0xc /* Word */
#define EEPROM_SOFT_INFO_2 0xf /* Software information 2 */
#define NO_RX_OVN_ANOMALY (1<<5)
/**************************************************************************
* *
* 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 VX_COMMAND 0x0e /* Write. BASE+0x0e is always a
* command reg. */
#define VX_STATUS 0x0e /* Read. BASE+0x0e is always status
* reg. */
#define VX_WINDOW 0x0f /* Read. BASE+0x0f is always window
* reg. */
/*
* Window 0 registers. Setup.
*/
/* Write */
#define VX_W0_EEPROM_DATA 0x0c
#define VX_W0_EEPROM_COMMAND 0x0a
#define VX_W0_RESOURCE_CFG 0x08
#define VX_W0_ADDRESS_CFG 0x06
#define VX_W0_CONFIG_CTRL 0x04
/* Read */
#define VX_W0_PRODUCT_ID 0x02
#define VX_W0_MFG_ID 0x00
/*
* Window 1 registers. Operating Set.
*/
/* Write */
#define VX_W1_TX_PIO_WR_2 0x02
#define VX_W1_TX_PIO_WR_1 0x00
/* Read */
#define VX_W1_FREE_TX 0x0c
#define VX_W1_TX_STATUS 0x0b /* byte */
#define VX_W1_TIMER 0x0a /* byte */
#define VX_W1_RX_STATUS 0x08
#define VX_W1_RX_PIO_RD_2 0x02
#define VX_W1_RX_PIO_RD_1 0x00
/*
* Window 2 registers. Station Address Setup/Read
*/
/* Read/Write */
#define VX_W2_ADDR_5 0x05
#define VX_W2_ADDR_4 0x04
#define VX_W2_ADDR_3 0x03
#define VX_W2_ADDR_2 0x02
#define VX_W2_ADDR_1 0x01
#define VX_W2_ADDR_0 0x00
/*
* Window 3 registers. FIFO Management.
*/
/* Read */
#define VX_W3_INTERNAL_CFG 0x00
#define VX_W3_RESET_OPT 0x08
#define VX_W3_FREE_TX 0x0c
#define VX_W3_FREE_RX 0x0a
/*
* Window 4 registers. Diagnostics.
*/
/* Read/Write */
#define VX_W4_MEDIA_TYPE 0x0a
#define VX_W4_CTRLR_STATUS 0x08
#define VX_W4_NET_DIAG 0x06
#define VX_W4_FIFO_DIAG 0x04
#define VX_W4_HOST_DIAG 0x02
#define VX_W4_TX_DIAG 0x00
/*
* Window 5 Registers. Results and Internal status.
*/
/* Read */
#define VX_W5_READ_0_MASK 0x0c
#define VX_W5_INTR_MASK 0x0a
#define VX_W5_RX_FILTER 0x08
#define VX_W5_RX_EARLY_THRESH 0x06
#define VX_W5_TX_AVAIL_THRESH 0x02
#define VX_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 (unsigned short) 0x0000 /* Wait at least 1ms
* after issuing */
#define WINDOW_SELECT (unsigned short) (0x1<<11)
#define START_TRANSCEIVER (unsigned 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 (unsigned short) (0x3<<11) /* state disabled on
* power-up */
#define RX_ENABLE (unsigned short) (0x4<<11)
#define RX_RESET (unsigned short) (0x5<<11)
#define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11)
#define TX_ENABLE (unsigned short) (0x9<<11)
#define TX_DISABLE (unsigned short) (0xa<<11)
#define TX_RESET (unsigned short) (0xb<<11)
#define REQ_INTR (unsigned short) (0xc<<11)
/*
* The following C_* acknowledge the various interrupts. Some of them don't
* do anything. See the manual.
*/
#define ACK_INTR (unsigned short) (0x6800)
# define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1)
# define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2)
# define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4)
# define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8)
# define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10)
# define C_RX_EARLY (unsigned short) (ACK_INTR|0x20)
# define C_INT_RQD (unsigned short) (ACK_INTR|0x40)
# define C_UPD_STATS (unsigned short) (ACK_INTR|0x80)
#define SET_INTR_MASK (unsigned short) (0xe<<11)
#define SET_RD_0_MASK (unsigned short) (0xf<<11)
#define SET_RX_FILTER (unsigned short) (0x10<<11)
# define FIL_INDIVIDUAL (unsigned short) (0x1)
# define FIL_MULTICAST (unsigned short) (0x02)
# define FIL_BRDCST (unsigned short) (0x04)
# define FIL_PROMISC (unsigned short) (0x08)
#define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11)
#define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11)
#define SET_TX_START_THRESH (unsigned short) (0x13<<11)
#define STATS_ENABLE (unsigned short) (0x15<<11)
#define STATS_DISABLE (unsigned short) (0x16<<11)
#define STOP_TRANSCEIVER (unsigned short) (0x17<<11)
/*
* 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 (unsigned short) (0x1)
#define S_CARD_FAILURE (unsigned short) (0x2)
#define S_TX_COMPLETE (unsigned short) (0x4)
#define S_TX_AVAIL (unsigned short) (0x8)
#define S_RX_COMPLETE (unsigned short) (0x10)
#define S_RX_EARLY (unsigned short) (0x20)
#define S_INT_RQD (unsigned short) (0x40)
#define S_UPD_STATS (unsigned short) (0x80)
#define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000)
#define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS)
/* Address Config. Register.
* Window 0/Port 06
*/
#define ACF_CONNECTOR_BITS 14
#define ACF_CONNECTOR_UTP 0
#define ACF_CONNECTOR_AUI 1
#define ACF_CONNECTOR_BNC 3
#define INTERNAL_CONNECTOR_BITS 20
#define INTERNAL_CONNECTOR_MASK 0x01700000
/*
* FIFO Registers. RX Status.
*
* 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_INCOMPLETE (unsigned short) (0x8000)
#define ERR_RX (unsigned short) (0x4000)
#define ERR_MASK (unsigned short) (0x7800)
#define ERR_OVERRUN (unsigned short) (0x4000)
#define ERR_RUNT (unsigned short) (0x5800)
#define ERR_ALIGNMENT (unsigned short) (0x6000)
#define ERR_CRC (unsigned short) (0x6800)
#define ERR_OVERSIZE (unsigned short) (0x4800)
#define ERR_DRIBBLE (unsigned short) (0x1000)
/*
* TX Status.
*
* 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_INTR_REQ 0x40
#define TXS_JABBER 0x20
#define TXS_UNDERRUN 0x10
#define TXS_MAX_COLLISION 0x8
#define TXS_STATUS_OVERFLOW 0x4
#define RS_AUI (1<<5)
#define RS_BNC (1<<4)
#define RS_UTP (1<<3)
#define RS_T4 (1<<0)
#define RS_TX (1<<1)
#define RS_FX (1<<2)
#define RS_MII (1<<6)
/*
* FIFO Status (Window 4)
*
* Supports FIFO diagnostics
*
* Window 4/Port 0x04.1
*
* 15: 1=RX receiving (RO). Set when a packet is being received
* into the RX FIFO.
* 14: Reserved
* 13: 1=RX underrun (RO). Generates Adapter Failure interrupt.
* Requires RX Reset or Global Reset command to recover.
* It is generated when you read past the end of a packet -
* reading past what has been received so far will give bad
* data.
* 12: 1=RX status overrun (RO). Set when there are already 8
* packets in the RX FIFO. While this bit is set, no additional
* packets are received. Requires no action on the part of
* the host. The condition is cleared once a packet has been
* read out of the RX FIFO.
* 11: 1=RX overrun (RO). Set when the RX FIFO is full (there
* may not be an overrun packet yet). While this bit is set,
* no additional packets will be received (some additional
* bytes can still be pending between the wire and the RX
* FIFO). Requires no action on the part of the host. The
* condition is cleared once a few bytes have been read out
* from the RX FIFO.
* 10: 1=TX overrun (RO). Generates adapter failure interrupt.
* Requires TX Reset or Global Reset command to recover.
* Disables Transmitter.
* 9-8: Unassigned.
* 7-0: Built in self test bits for the RX and TX FIFO's.
*/
#define FIFOS_RX_RECEIVING (unsigned short) 0x8000
#define FIFOS_RX_UNDERRUN (unsigned short) 0x2000
#define FIFOS_RX_STATUS_OVERRUN (unsigned short) 0x1000
#define FIFOS_RX_OVERRUN (unsigned short) 0x0800
#define FIFOS_TX_OVERRUN (unsigned short) 0x0400
/*
* Misc defines for various things.
*/
#define TAG_ADAPTER 0xd0
#define ACTIVATE_ADAPTER_TO_CONFIG 0xff
#define ENABLE_DRQ_IRQ 0x0001
#define MFG_ID 0x506d /* `TCM' */
#define PROD_ID 0x5090
#define GO_WINDOW(x) outw(WINDOW_SELECT|(x),BASE+VX_COMMAND)
#define JABBER_GUARD_ENABLE 0x40
#define LINKBEAT_ENABLE 0x80
#define ENABLE_UTP (JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
#define DISABLE_UTP 0x0
#define RX_BYTES_MASK (unsigned short) (0x07ff)
#define RX_ERROR 0x4000
#define RX_INCOMPLETE 0x8000
#define TX_INDICATE 1<<15
#define is_eeprom_busy(b) (inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY)
#define VX_IOSIZE 0x20
#define VX_CONNECTORS 8
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,929 +0,0 @@
/*
* 3c90x.c -- This file implements the 3c90x driver for etherboot. Written
* by Greg Beeley, Greg.Beeley@LightSys.org. Modified by Steve Smith,
* Steve.Smith@Juno.Com
*
* This program Copyright (C) 1999 LightSys Technology Services, Inc.
* Portions Copyright (C) 1999 Steve Smith
*
* This program may be re-distributed in source or binary form, modified,
* sold, or copied for any purpose, provided that the above copyright message
* and this text are included with all source copies or derivative works, and
* provided that the above copyright message and this text are included in the
* documentation of any binary-only distributions. This program is distributed
* WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR
* PURPOSE or MERCHANTABILITY. Please read the associated documentation
* "3c90x.txt" before compiling and using this driver.
*
* --------
*
* Program written with the assistance of the 3com documentation for
* the 3c905B-TX card, as well as with some assistance from the 3c59x
* driver Donald Becker wrote for the Linux kernel, and with some assistance
* from the remainder of the Etherboot distribution.
*
* REVISION HISTORY:
*
* v0.10 1-26-1998 GRB Initial implementation.
* v0.90 1-27-1998 GRB System works.
* v1.00pre1 2-11-1998 GRB Got prom boot issue fixed.
* v2.0 9-24-1999 SCS Modified for 3c905 (from 3c905b code)
* Re-wrote poll and transmit for
* better error recovery and heavy
* network traffic operation
*
*/
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
#include "timer.h"
#define XCVR_MAGIC (0x5A00)
/** any single transmission fails after 16 collisions or other errors
** this is the number of times to retry the transmission -- this should
** be plenty
**/
#define XMIT_RETRIES 250
#undef virt_to_bus
#define virt_to_bus(x) ((unsigned long)x)
/*** Register definitions for the 3c905 ***/
enum Registers
{
regPowerMgmtCtrl_w = 0x7c, /** 905B Revision Only **/
regUpMaxBurst_w = 0x7a, /** 905B Revision Only **/
regDnMaxBurst_w = 0x78, /** 905B Revision Only **/
regDebugControl_w = 0x74, /** 905B Revision Only **/
regDebugData_l = 0x70, /** 905B Revision Only **/
regRealTimeCnt_l = 0x40, /** Universal **/
regUpBurstThresh_b = 0x3e, /** 905B Revision Only **/
regUpPoll_b = 0x3d, /** 905B Revision Only **/
regUpPriorityThresh_b = 0x3c, /** 905B Revision Only **/
regUpListPtr_l = 0x38, /** Universal **/
regCountdown_w = 0x36, /** Universal **/
regFreeTimer_w = 0x34, /** Universal **/
regUpPktStatus_l = 0x30, /** Universal with Exception, pg 130 **/
regTxFreeThresh_b = 0x2f, /** 90X Revision Only **/
regDnPoll_b = 0x2d, /** 905B Revision Only **/
regDnPriorityThresh_b = 0x2c, /** 905B Revision Only **/
regDnBurstThresh_b = 0x2a, /** 905B Revision Only **/
regDnListPtr_l = 0x24, /** Universal with Exception, pg 107 **/
regDmaCtrl_l = 0x20, /** Universal with Exception, pg 106 **/
/** **/
regIntStatusAuto_w = 0x1e, /** 905B Revision Only **/
regTxStatus_b = 0x1b, /** Universal with Exception, pg 113 **/
regTimer_b = 0x1a, /** Universal **/
regTxPktId_b = 0x18, /** 905B Revision Only **/
regCommandIntStatus_w = 0x0e, /** Universal (Command Variations) **/
};
/** following are windowed registers **/
enum Registers7
{
regPowerMgmtEvent_7_w = 0x0c, /** 905B Revision Only **/
regVlanEtherType_7_w = 0x04, /** 905B Revision Only **/
regVlanMask_7_w = 0x00, /** 905B Revision Only **/
};
enum Registers6
{
regBytesXmittedOk_6_w = 0x0c, /** Universal **/
regBytesRcvdOk_6_w = 0x0a, /** Universal **/
regUpperFramesOk_6_b = 0x09, /** Universal **/
regFramesDeferred_6_b = 0x08, /** Universal **/
regFramesRecdOk_6_b = 0x07, /** Universal with Exceptions, pg 142 **/
regFramesXmittedOk_6_b = 0x06, /** Universal **/
regRxOverruns_6_b = 0x05, /** Universal **/
regLateCollisions_6_b = 0x04, /** Universal **/
regSingleCollisions_6_b = 0x03, /** Universal **/
regMultipleCollisions_6_b = 0x02, /** Universal **/
regSqeErrors_6_b = 0x01, /** Universal **/
regCarrierLost_6_b = 0x00, /** Universal **/
};
enum Registers5
{
regIndicationEnable_5_w = 0x0c, /** Universal **/
regInterruptEnable_5_w = 0x0a, /** Universal **/
regTxReclaimThresh_5_b = 0x09, /** 905B Revision Only **/
regRxFilter_5_b = 0x08, /** Universal **/
regRxEarlyThresh_5_w = 0x06, /** Universal **/
regTxStartThresh_5_w = 0x00, /** Universal **/
};
enum Registers4
{
regUpperBytesOk_4_b = 0x0d, /** Universal **/
regBadSSD_4_b = 0x0c, /** Universal **/
regMediaStatus_4_w = 0x0a, /** Universal with Exceptions, pg 201 **/
regPhysicalMgmt_4_w = 0x08, /** Universal **/
regNetworkDiagnostic_4_w = 0x06, /** Universal with Exceptions, pg 203 **/
regFifoDiagnostic_4_w = 0x04, /** Universal with Exceptions, pg 196 **/
regVcoDiagnostic_4_w = 0x02, /** Undocumented? **/
};
enum Registers3
{
regTxFree_3_w = 0x0c, /** Universal **/
regRxFree_3_w = 0x0a, /** Universal with Exceptions, pg 125 **/
regResetMediaOptions_3_w = 0x08, /** Media Options on B Revision, **/
/** Reset Options on Non-B Revision **/
regMacControl_3_w = 0x06, /** Universal with Exceptions, pg 199 **/
regMaxPktSize_3_w = 0x04, /** 905B Revision Only **/
regInternalConfig_3_l = 0x00, /** Universal, different bit **/
/** definitions, pg 59 **/
};
enum Registers2
{
regResetOptions_2_w = 0x0c, /** 905B Revision Only **/
regStationMask_2_3w = 0x06, /** Universal with Exceptions, pg 127 **/
regStationAddress_2_3w = 0x00, /** Universal with Exceptions, pg 127 **/
};
enum Registers1
{
regRxStatus_1_w = 0x0a, /** 90X Revision Only, Pg 126 **/
};
enum Registers0
{
regEepromData_0_w = 0x0c, /** Universal **/
regEepromCommand_0_w = 0x0a, /** Universal **/
regBiosRomData_0_b = 0x08, /** 905B Revision Only **/
regBiosRomAddr_0_l = 0x04, /** 905B Revision Only **/
};
/*** The names for the eight register windows ***/
enum Windows
{
winPowerVlan7 = 0x07,
winStatistics6 = 0x06,
winTxRxControl5 = 0x05,
winDiagnostics4 = 0x04,
winTxRxOptions3 = 0x03,
winAddressing2 = 0x02,
winUnused1 = 0x01,
winEepromBios0 = 0x00,
};
/*** Command definitions for the 3c90X ***/
enum Commands
{
cmdGlobalReset = 0x00, /** Universal with Exceptions, pg 151 **/
cmdSelectRegisterWindow = 0x01, /** Universal **/
cmdEnableDcConverter = 0x02, /** **/
cmdRxDisable = 0x03, /** **/
cmdRxEnable = 0x04, /** Universal **/
cmdRxReset = 0x05, /** Universal **/
cmdStallCtl = 0x06, /** Universal **/
cmdTxEnable = 0x09, /** Universal **/
cmdTxDisable = 0x0A, /** **/
cmdTxReset = 0x0B, /** Universal **/
cmdRequestInterrupt = 0x0C, /** **/
cmdAcknowledgeInterrupt = 0x0D, /** Universal **/
cmdSetInterruptEnable = 0x0E, /** Universal **/
cmdSetIndicationEnable = 0x0F, /** Universal **/
cmdSetRxFilter = 0x10, /** Universal **/
cmdSetRxEarlyThresh = 0x11, /** **/
cmdSetTxStartThresh = 0x13, /** **/
cmdStatisticsEnable = 0x15, /** **/
cmdStatisticsDisable = 0x16, /** **/
cmdDisableDcConverter = 0x17, /** **/
cmdSetTxReclaimThresh = 0x18, /** **/
cmdSetHashFilterBit = 0x19, /** **/
};
/*** Values for int status register bitmask **/
#define INT_INTERRUPTLATCH (1<<0)
#define INT_HOSTERROR (1<<1)
#define INT_TXCOMPLETE (1<<2)
#define INT_RXCOMPLETE (1<<4)
#define INT_RXEARLY (1<<5)
#define INT_INTREQUESTED (1<<6)
#define INT_UPDATESTATS (1<<7)
#define INT_LINKEVENT (1<<8)
#define INT_DNCOMPLETE (1<<9)
#define INT_UPCOMPLETE (1<<10)
#define INT_CMDINPROGRESS (1<<12)
#define INT_WINDOWNUMBER (7<<13)
/*** TX descriptor ***/
typedef struct
{
unsigned int DnNextPtr;
unsigned int FrameStartHeader;
unsigned int HdrAddr;
unsigned int HdrLength;
unsigned int DataAddr;
unsigned int DataLength;
}
TXD;
/*** RX descriptor ***/
typedef struct
{
unsigned int UpNextPtr;
unsigned int UpPktStatus;
unsigned int DataAddr;
unsigned int DataLength;
}
RXD;
/*** Global variables ***/
static struct
{
unsigned char isBrev;
unsigned char CurrentWindow;
unsigned int IOAddr;
unsigned char HWAddr[ETH_ALEN];
TXD TransmitDPD;
RXD ReceiveUPD;
}
INF_3C90X;
/*** a3c90x_internal_IssueCommand: sends a command to the 3c90x card
***/
static int
a3c90x_internal_IssueCommand(int ioaddr, int cmd, int param)
{
unsigned int val;
/** Build the cmd. **/
val = cmd;
val <<= 11;
val |= param;
/** Send the cmd to the cmd register **/
outw(val, ioaddr + regCommandIntStatus_w);
/** Wait for the cmd to complete, if necessary **/
while (inw(ioaddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
return 0;
}
/*** a3c90x_internal_SetWindow: selects a register window set.
***/
static int
a3c90x_internal_SetWindow(int ioaddr, int window)
{
/** Window already as set? **/
if (INF_3C90X.CurrentWindow == window) return 0;
/** Issue the window command. **/
a3c90x_internal_IssueCommand(ioaddr, cmdSelectRegisterWindow, window);
INF_3C90X.CurrentWindow = window;
return 0;
}
/*** a3c90x_internal_ReadEeprom - read data from the serial eeprom.
***/
static unsigned short
a3c90x_internal_ReadEeprom(int ioaddr, int address)
{
unsigned short val;
/** Select correct window **/
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winEepromBios0);
/** Make sure the eeprom isn't busy **/
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
/** Read the value. **/
outw(address + ((0x02)<<6), ioaddr + regEepromCommand_0_w);
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
val = inw(ioaddr + regEepromData_0_w);
return val;
}
/*** a3c90x_internal_WriteEepromWord - write a physical word of
*** data to the onboard serial eeprom (not the BIOS prom, but the
*** nvram in the card that stores, among other things, the MAC
*** address).
***/
static int
a3c90x_internal_WriteEepromWord(int ioaddr, int address, unsigned short value)
{
/** Select register window **/
a3c90x_internal_SetWindow(ioaddr, winEepromBios0);
/** Verify Eeprom not busy **/
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
/** Issue WriteEnable, and wait for completion. **/
outw(0x30, ioaddr + regEepromCommand_0_w);
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
/** Issue EraseRegister, and wait for completion. **/
outw(address + ((0x03)<<6), ioaddr + regEepromCommand_0_w);
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
/** Send the new data to the eeprom, and wait for completion. **/
outw(value, ioaddr + regEepromData_0_w);
outw(0x30, ioaddr + regEepromCommand_0_w);
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
/** Burn the new data into the eeprom, and wait for completion. **/
outw(address + ((0x01)<<6), ioaddr + regEepromCommand_0_w);
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
return 0;
}
/*** a3c90x_internal_WriteEeprom - write data to the serial eeprom,
*** and re-compute the eeprom checksum.
***/
static int
a3c90x_internal_WriteEeprom(int ioaddr, int address, unsigned short value)
{
int cksum = 0,v;
int i;
int maxAddress, cksumAddress;
if (INF_3C90X.isBrev)
{
maxAddress=0x1f;
cksumAddress=0x20;
}
else
{
maxAddress=0x16;
cksumAddress=0x17;
}
/** Write the value. **/
if (a3c90x_internal_WriteEepromWord(ioaddr, address, value) == -1)
return -1;
/** Recompute the checksum. **/
for(i=0;i<=maxAddress;i++)
{
v = a3c90x_internal_ReadEeprom(ioaddr, i);
cksum ^= (v & 0xFF);
cksum ^= ((v>>8) & 0xFF);
}
/** Write the checksum to the location in the eeprom **/
if (a3c90x_internal_WriteEepromWord(ioaddr, cksumAddress, cksum) == -1)
return -1;
return 0;
}
/*** a3c90x_reset: exported function that resets the card to its default
*** state. This is so the Linux driver can re-set the card up the way
*** it wants to. If CFG_3C90X_PRESERVE_XCVR is defined, then the reset will
*** not alter the selected transceiver that we used to download the boot
*** image.
***/
static void
a3c90x_reset(struct nic *nic)
{
int cfg;
#ifdef CFG_3C90X_PRESERVE_XCVR
/** Read the current InternalConfig value. **/
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
cfg = inl(INF_3C90X.IOAddr + regInternalConfig_3_l);
#endif
/** Send the reset command to the card **/
printf("Issuing RESET:\n");
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdGlobalReset, 0);
/** wait for reset command to complete **/
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
/** global reset command resets station mask, non-B revision cards
** require explicit reset of values
**/
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+0);
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+2);
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+4);
#ifdef CFG_3C90X_PRESERVE_XCVR
/** Re-set the original InternalConfig value from before reset **/
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
outl(cfg, INF_3C90X.IOAddr + regInternalConfig_3_l);
/** enable DC converter for 10-Base-T **/
if ((cfg&0x0300) == 0x0300)
{
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdEnableDcConverter, 0);
}
#endif
/** Issue transmit reset, wait for command completion **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxReset, 0);
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
;
if (! INF_3C90X.isBrev)
outb(0x01, INF_3C90X.IOAddr + regTxFreeThresh_b);
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
/**
** reset of the receiver on B-revision cards re-negotiates the link
** takes several seconds (a computer eternity)
**/
if (INF_3C90X.isBrev)
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x04);
else
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x00);
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
;
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxEnable, 0);
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
cmdSetInterruptEnable, 0);
/** enable rxComplete and txComplete **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
cmdSetIndicationEnable, 0x0014);
/** acknowledge any pending status flags **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
cmdAcknowledgeInterrupt, 0x661);
return;
}
/*** a3c90x_transmit: exported function that transmits a packet. Does not
*** return any particular status. Parameters are:
*** d[6] - destination address, ethernet;
*** t - protocol type (ARP, IP, etc);
*** s - size of the non-header part of the packet that needs transmitted;
*** p - the pointer to the packet data itself.
***/
static void
a3c90x_transmit(struct nic *nic, const char *d, unsigned int t,
unsigned int s, const char *p)
{
struct eth_hdr
{
unsigned char dst_addr[ETH_ALEN];
unsigned char src_addr[ETH_ALEN];
unsigned short type;
} hdr;
unsigned char status;
unsigned i, retries;
for (retries=0; retries < XMIT_RETRIES ; retries++)
{
/** Stall the download engine **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdStallCtl, 2);
/** Make sure the card is not waiting on us **/
inw(INF_3C90X.IOAddr + regCommandIntStatus_w);
inw(INF_3C90X.IOAddr + regCommandIntStatus_w);
while (inw(INF_3C90X.IOAddr+regCommandIntStatus_w) &
INT_CMDINPROGRESS)
;
/** Set the ethernet packet type **/
hdr.type = htons(t);
/** Copy the destination address **/
memcpy(hdr.dst_addr, d, ETH_ALEN);
/** Copy our MAC address **/
memcpy(hdr.src_addr, INF_3C90X.HWAddr, ETH_ALEN);
/** Setup the DPD (download descriptor) **/
INF_3C90X.TransmitDPD.DnNextPtr = 0;
/** set notification for transmission completion (bit 15) **/
INF_3C90X.TransmitDPD.FrameStartHeader = (s + sizeof(hdr)) | 0x8000;
INF_3C90X.TransmitDPD.HdrAddr = virt_to_bus(&hdr);
INF_3C90X.TransmitDPD.HdrLength = sizeof(hdr);
INF_3C90X.TransmitDPD.DataAddr = virt_to_bus(p);
INF_3C90X.TransmitDPD.DataLength = s + (1<<31);
/** Send the packet **/
outl(virt_to_bus(&(INF_3C90X.TransmitDPD)),
INF_3C90X.IOAddr + regDnListPtr_l);
/** End Stall and Wait for upload to complete. **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdStallCtl, 3);
while(inl(INF_3C90X.IOAddr + regDnListPtr_l) != 0)
;
/** Wait for NIC Transmit to Complete **/
load_timer2(10*TICKS_PER_MS); /* Give it 10 ms */
while (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0004) &&
timer2_running())
;
if (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0004))
{
printf("3C90X: Tx Timeout\n");
continue;
}
status = inb(INF_3C90X.IOAddr + regTxStatus_b);
/** acknowledge transmit interrupt by writing status **/
outb(0x00, INF_3C90X.IOAddr + regTxStatus_b);
/** successful completion (sans "interrupt Requested" bit) **/
if ((status & 0xbf) == 0x80)
return;
printf("3C90X: Status (%hhX)\n", status);
/** check error codes **/
if (status & 0x02)
{
printf("3C90X: Tx Reclaim Error (%hhX)\n", status);
a3c90x_reset(NULL);
}
else if (status & 0x04)
{
printf("3C90X: Tx Status Overflow (%hhX)\n", status);
for (i=0; i<32; i++)
outb(0x00, INF_3C90X.IOAddr + regTxStatus_b);
/** must re-enable after max collisions before re-issuing tx **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
}
else if (status & 0x08)
{
printf("3C90X: Tx Max Collisions (%hhX)\n", status);
/** must re-enable after max collisions before re-issuing tx **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
}
else if (status & 0x10)
{
printf("3C90X: Tx Underrun (%hhX)\n", status);
a3c90x_reset(NULL);
}
else if (status & 0x20)
{
printf("3C90X: Tx Jabber (%hhX)\n", status);
a3c90x_reset(NULL);
}
else if ((status & 0x80) != 0x80)
{
printf("3C90X: Internal Error - Incomplete Transmission (%hhX)\n",
status);
a3c90x_reset(NULL);
}
}
/** failed after RETRY attempts **/
printf("Failed to send after %d retries\n", retries);
return;
}
/*** a3c90x_poll: exported routine that waits for a certain length of time
*** for a packet, and if it sees none, returns 0. This routine should
*** copy the packet to nic->packet if it gets a packet and set the size
*** in nic->packetlen. Return 1 if a packet was found.
***/
static int
a3c90x_poll(struct nic *nic)
{
int i, errcode;
if (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0010))
{
return 0;
}
/** we don't need to acknowledge rxComplete -- the upload engine
** does it for us.
**/
/** Build the up-load descriptor **/
INF_3C90X.ReceiveUPD.UpNextPtr = 0;
INF_3C90X.ReceiveUPD.UpPktStatus = 0;
INF_3C90X.ReceiveUPD.DataAddr = virt_to_bus(nic->packet);
INF_3C90X.ReceiveUPD.DataLength = 1536 + (1<<31);
/** Submit the upload descriptor to the NIC **/
outl(virt_to_bus(&(INF_3C90X.ReceiveUPD)),
INF_3C90X.IOAddr + regUpListPtr_l);
/** Wait for upload completion (upComplete(15) or upError (14)) **/
for(i=0;i<40000;i++);
while((INF_3C90X.ReceiveUPD.UpPktStatus & ((1<<14) | (1<<15))) == 0)
for(i=0;i<40000;i++);
/** Check for Error (else we have good packet) **/
if (INF_3C90X.ReceiveUPD.UpPktStatus & (1<<14))
{
errcode = INF_3C90X.ReceiveUPD.UpPktStatus;
if (errcode & (1<<16))
printf("3C90X: Rx Overrun (%hX)\n",errcode>>16);
else if (errcode & (1<<17))
printf("3C90X: Runt Frame (%hX)\n",errcode>>16);
else if (errcode & (1<<18))
printf("3C90X: Alignment Error (%hX)\n",errcode>>16);
else if (errcode & (1<<19))
printf("3C90X: CRC Error (%hX)\n",errcode>>16);
else if (errcode & (1<<20))
printf("3C90X: Oversized Frame (%hX)\n",errcode>>16);
else
printf("3C90X: Packet error (%hX)\n",errcode>>16);
return 0;
}
/** Ok, got packet. Set length in nic->packetlen. **/
nic->packetlen = (INF_3C90X.ReceiveUPD.UpPktStatus & 0x1FFF);
return 1;
}
/*** a3c90x_disable: exported routine to disable the card. What's this for?
*** the eepro100.c driver didn't have one, so I just left this one empty too.
*** Ideas anyone?
*** Must turn off receiver at least so stray packets will not corrupt memory
*** [Ken]
***/
static void
a3c90x_disable(struct nic *nic)
{
/* Disable the receiver and transmitter. */
outw(cmdRxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
outw(cmdTxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
}
/*** a3c90x_probe: exported routine to probe for the 3c905 card and perform
*** initialization. If this routine is called, the pci functions did find the
*** card. We just have to init it here.
***/
struct nic*
a3c90x_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
{
int i, c;
unsigned short eeprom[0x21];
unsigned int cfg;
unsigned int mopt;
unsigned short linktype;
if (probeaddrs == 0 || probeaddrs[0] == 0)
return 0;
adjust_pci_device(pci);
INF_3C90X.IOAddr = probeaddrs[0] & ~3;
INF_3C90X.CurrentWindow = 255;
switch (a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, 0x03))
{
case 0x9000: /** 10 Base TPO **/
case 0x9001: /** 10/100 T4 **/
case 0x9050: /** 10/100 TPO **/
case 0x9051: /** 10 Base Combo **/
INF_3C90X.isBrev = 0;
break;
case 0x9004: /** 10 Base TPO **/
case 0x9005: /** 10 Base Combo **/
case 0x9006: /** 10 Base TPO and Base2 **/
case 0x900A: /** 10 Base FL **/
case 0x9055: /** 10/100 TPO **/
case 0x9056: /** 10/100 T4 **/
case 0x905A: /** 10 Base FX **/
default:
INF_3C90X.isBrev = 1;
break;
}
/** Load the EEPROM contents **/
if (INF_3C90X.isBrev)
{
for(i=0;i<=0x20;i++)
{
eeprom[i] = a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, i);
}
#ifdef CFG_3C90X_BOOTROM_FIX
/** Set xcvrSelect in InternalConfig in eeprom. **/
/* only necessary for 3c905b revision cards with boot PROM bug!!! */
a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x13, 0x0160);
#endif
#ifdef CFG_3C90X_XCVR
if (CFG_3C90X_XCVR == 255)
{
/** Clear the LanWorks register **/
a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x16, 0);
}
else
{
/** Set the selected permanent-xcvrSelect in the
** LanWorks register
**/
a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x16,
XCVR_MAGIC + ((CFG_3C90X_XCVR) & 0x000F));
}
#endif
}
else
{
for(i=0;i<=0x17;i++)
{
eeprom[i] = a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, i);
}
}
/** Print identification message **/
printf("\n\n3C90X Driver 2.00 "
"Copyright 1999 LightSys Technology Services, Inc.\n"
"Portions Copyright 1999 Steve Smith\n");
printf("Provided with ABSOLUTELY NO WARRANTY.\n");
printf("-------------------------------------------------------"
"------------------------\n");
/** Retrieve the Hardware address and print it on the screen. **/
INF_3C90X.HWAddr[0] = eeprom[0]>>8;
INF_3C90X.HWAddr[1] = eeprom[0]&0xFF;
INF_3C90X.HWAddr[2] = eeprom[1]>>8;
INF_3C90X.HWAddr[3] = eeprom[1]&0xFF;
INF_3C90X.HWAddr[4] = eeprom[2]>>8;
INF_3C90X.HWAddr[5] = eeprom[2]&0xFF;
printf("MAC Address = %!\n", INF_3C90X.HWAddr);
/** Program the MAC address into the station address registers **/
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
outw(htons(eeprom[0]), INF_3C90X.IOAddr + regStationAddress_2_3w);
outw(htons(eeprom[1]), INF_3C90X.IOAddr + regStationAddress_2_3w+2);
outw(htons(eeprom[2]), INF_3C90X.IOAddr + regStationAddress_2_3w+4);
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+0);
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+2);
outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+4);
/** Fill in our entry in the etherboot arp table **/
for(i=0;i<ETH_ALEN;i++)
nic->node_addr[i] = (eeprom[i/2] >> (8*((i&1)^1))) & 0xff;
/** Read the media options register, print a message and set default
** xcvr.
**
** Uses Media Option command on B revision, Reset Option on non-B
** revision cards -- same register address
**/
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
mopt = inw(INF_3C90X.IOAddr + regResetMediaOptions_3_w);
/** mask out VCO bit that is defined as 10baseFL bit on B-rev cards **/
if (! INF_3C90X.isBrev)
{
mopt &= 0x7F;
}
printf("Connectors present: ");
c = 0;
linktype = 0x0008;
if (mopt & 0x01)
{
printf("%s100Base-T4",(c++)?", ":"");
linktype = 0x0006;
}
if (mopt & 0x04)
{
printf("%s100Base-FX",(c++)?", ":"");
linktype = 0x0005;
}
if (mopt & 0x10)
{
printf("%s10Base-2",(c++)?", ":"");
linktype = 0x0003;
}
if (mopt & 0x20)
{
printf("%sAUI",(c++)?", ":"");
linktype = 0x0001;
}
if (mopt & 0x40)
{
printf("%sMII",(c++)?", ":"");
linktype = 0x0006;
}
if ((mopt & 0xA) == 0xA)
{
printf("%s10Base-T / 100Base-TX",(c++)?", ":"");
linktype = 0x0008;
}
else if ((mopt & 0xA) == 0x2)
{
printf("%s100Base-TX",(c++)?", ":"");
linktype = 0x0008;
}
else if ((mopt & 0xA) == 0x8)
{
printf("%s10Base-T",(c++)?", ":"");
linktype = 0x0008;
}
printf(".\n");
/** Determine transceiver type to use, depending on value stored in
** eeprom 0x16
**/
if (INF_3C90X.isBrev)
{
if ((eeprom[0x16] & 0xFF00) == XCVR_MAGIC)
{
/** User-defined **/
linktype = eeprom[0x16] & 0x000F;
}
}
else
{
#ifdef CFG_3C90X_XCVR
if (CFG_3C90X_XCVR != 255)
linktype = CFG_3C90X_XCVR;
#endif /* CFG_3C90X_XCVR */
/** I don't know what MII MAC only mode is!!! **/
if (linktype == 0x0009)
{
if (INF_3C90X.isBrev)
printf("WARNING: MII External MAC Mode only supported on B-revision "
"cards!!!!\nFalling Back to MII Mode\n");
linktype = 0x0006;
}
}
/** enable DC converter for 10-Base-T **/
if (linktype == 0x0003)
{
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdEnableDcConverter, 0);
}
/** Set the link to the type we just determined. **/
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
cfg = inl(INF_3C90X.IOAddr + regInternalConfig_3_l);
cfg &= ~(0xF<<20);
cfg |= (linktype<<20);
outl(cfg, INF_3C90X.IOAddr + regInternalConfig_3_l);
/** Now that we set the xcvr type, reset the Tx and Rx, re-enable. **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxReset, 0x00);
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
;
if (!INF_3C90X.isBrev)
outb(0x01, INF_3C90X.IOAddr + regTxFreeThresh_b);
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
/**
** reset of the receiver on B-revision cards re-negotiates the link
** takes several seconds (a computer eternity)
**/
if (INF_3C90X.isBrev)
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x04);
else
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x00);
while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
;
/** Set the RX filter = receive only individual pkts & bcast. **/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetRxFilter, 0x01 + 0x04);
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxEnable, 0);
/**
** set Indication and Interrupt flags , acknowledge any IRQ's
**/
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetInterruptEnable, 0);
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
cmdSetIndicationEnable, 0x0014);
a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
cmdAcknowledgeInterrupt, 0x661);
/** Set our exported functions **/
nic->reset = a3c90x_reset;
nic->poll = a3c90x_poll;
nic->transmit = a3c90x_transmit;
nic->disable = a3c90x_disable;
return nic;
}

View file

@ -1,307 +0,0 @@
Instructions for use of the 3C90X driver for EtherBoot
Original 3C905B support by:
Greg Beeley (Greg.Beeley@LightSys.org),
LightSys Technology Services, Inc.
February 11, 1999
Updates for 3C90X family by:
Steve Smith (steve.smith@juno.com)
October 1, 1999
Minor documentation updates by
Greg Beeley (Greg.Beeley@LightSys.org)
March 29, 2000
-------------------------------------------------------------------------------
I OVERVIEW
The 3c90X series ethernet cards are a group of high-performance busmaster
DMA cards from 3Com. This particular driver supports both the 3c90x and
the 3c90xB revision cards. 3C90xC family support has been tested to some
degree but not extensively.
Here's the licensing information:
This program Copyright (C) 1999 LightSys Technology Services, Inc.
Portions Copyright (C) 1999 Steve Smith.
This program may be re-distributed in source or binary form, modified,
sold, or copied for any purpose, provided that the above copyright message
and this text are included with all source copies or derivative works, and
provided that the above copyright message and this text are included in the
documentation of any binary-only distributions. This program is
distributed WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR
A PARTICULAR PURPOSE or MERCHANTABILITY. Please read the associated
documentation "3c90x.txt" before compiling and using this driver.
II FLASH PROMS
The 3c90xB cards, according to the 3Com documentation, only accept the
following flash memory chips:
Atmel AT29C512 (64 kilobyte)
Atmel AT29C010 (128 kilobyte)
The 3c90x cards, according to the 3Com documentation, accept the
following flash memory chips capacities:
64 kb (8 kB)
128 kb (16 kB)
256 kb (32 kB) and
512 kb (64 kB)
Atmel AT29C512 (64 kilobyte) chips are specifically listed for both
adapters, but flashing on the 3c905b cards would only be supported
through the Atmel parts. Any device, of the supported size, should
be supported when programmed by a dedicated PROM programmer (e.g.
not the card).
To use this driver in such a PROM, visit Atmel's web site and download
their .PDF file containing a list of their distributors. Contact the
distributors for pricing information. The prices are quite reasonable
(about $3 US each for the 64 kB part), and are comparable to what one would
expect for similarly sized standard EPROMs. And, the flash chips are much
easier to work with, as they don't need to be UV-erased to be reprogrammed.
The 3C905B card actually provides a method to program the flash memory
while it is resident on board the card itself; if someone would like to
write a small DOS program to do the programming, I can provide the
information about the registers and so forth.
A utility program, 3c90xutil, is provided with Etherboot in the 'contrib'
directory that allows for the on-board flashing of the ROM while Linux
is running. The program has been successfully used under Linux, but I
have heard problem reports of its use under FreeBSD. Anyone willing to
make it work under FreeBSD is more than welcome to do so!
You also have the option of using EPROM chips - the 3C905B-TX-NM has been
successfully tested with 27C256 (32kB) and 27C512 (64kB) chips with a
specified access time of 100ns and faster.
III GENERAL USE
Normally, the basic procedure for using this driver is as follows:
1. Run the 3c90xcfg program on the driver diskette to enable the
boot PROM and set it to 64k or 128k, as appropriate.
2. Build the appropriate 3c90x.fd0 or 3c90x.fd0 floppy image with
possibly the value CFG_3C90X_XCVR defined to the transceiver type that
you want to use (i.e., 10/100 rj45, AUI, coax, MII).
3. Run the floppy image on the PC to be network booted, to get
it configured, and to verify that it will boot properly.
4. Build the 3c90x.rom or 3c90x.lzrom PROM image and program
it into the flash or EPROM memory chip.
5. Put the PROM in the ethernet card, boot and enable 'boot from
network first' in the system BIOS, save and reboot.
Here are some issues to be aware of:
1. If you experience crashes or different behaviour when using the
boot PROM, add the setting CFG_3C90X_BOOTROM_FIX and go through the
steps 2-5 above. This works around a bug in some 3c905B cards (see
below), but has some side-effects which may not be desirable.
Please note that you have to boot off a floppy (not PROM!) once for
this fix to take effect.
2. The possible need to manually set the CFG_3C90X_XCVR value to
configure the transceiver type. Values are listed below.
3. The possible need to define CFG_3C90X_PRESERVE_XCVR for use in
operating systems that don't intelligently determine the
transceiver type.
Some things that are on the 'To-Do' list, perhaps for me, but perhaps
for any other volunteers out there:
1. Extend the driver to fully implement the auto-select
algorithm if the card has multiple media ports.
2. Fix any bugs in the code <grin>....
3. Extend the driver to support the 3c905c revision cards
"officially". Right now, the support has been primarily empirical
and not based on 3c905C documentation.
Now for the details....
This driver has been tested on roughly 300 systems. The main two
configuration issues to contend with are:
1. Ensure that PCI Busmastering is enabled for the adapter (configured
in the CMOS setup)
2. Some systems don't work properly with the adapter when plug and
play OS is enabled; I always set it to "No" or "Disabled" -- this makes
it easier and really doesn't adversely affect anything.
Roughly 95% of the systems worked when configured properly. A few
have issues with booting locally once the boot PROM has been installed
(this number has been less than 2%). Other configuration issues that
to check:
1. Newer BIOS's actually work correctly with the network boot order.
Set the network adapter first. Most older BIOS's automatically go to
the network boot PROM first.
2. For systems where the adapter was already installed and is just
having the PROM installed, try setting the "reset configuration data"
to yes in the CMOS setup if the BIOS isn't seen at first. If your BIOS
doesn't have this option, remove the card, start the system, shut down,
install the card and restart (or switch to a different PCI slot).
3. Make sure the CMOS security settings aren't preventing a boot.
The 3c905B cards have a significant 'bug' that relates to the flash prom:
unless the card is set internally to the MII transceiver, it will only
read the first 8k of the PROM image. Don't ask why -- it seems really
obscure, but it has to do with the way they mux'd the address lines
from the PCI bus to the ROM. Unfortunately, most of us are not using
MII transceivers, and even the .lzrom image ends up being just a little
bit larger than 8k. Note that the workaround for this is disabled by
default, because the Windows NT 4.0 driver does not like it (no packets
are transmitted).
So, the solution that I've used is to internally set the card's nvram
configuration to use MII when it boots. The 3c905b driver does this
automatically. This way, the 16k prom image can be loaded into memory,
and then the 3c905b driver can set the temporary configuration of the
card to an appropriate value, either configurable by the user or chosen
by the driver.
To enable the 3c905B bugfix, which is necessary for these cards when
booting from the Flash ROM, define -DCFG_3C90X_BOOTROM_FIX when building,
create a floppy image and boot it once.
Thereafter, the card should accept the larger prom image.
The driver should choose an appropriate transceiver on the card. However,
if it doesn't on your card or if you need to, for instance, set your
card to 10mbps when connected to an unmanaged 10/100 hub, you can specify
which transceiver you want to use. To do this, build the 3c905b.fd0
image with -DCFG_3C90X_XCVR=x, where 'x' is one of the following
values:
0 10Base-T
1 10mbps AUI
3 10Base-2 (thinnet/coax)
4 100Base-TX
5 100Base-FX
6 MII
8 Auto-negotiation 10Base-T / 100Base-TX (usually the default)
9 MII External MAC Mode
255 Allow driver to choose an 'appropriate' media port.
Then proceed from step 2 in the above 'general use' instructions. The
.rom image can be built with CFG_3C90X_XCVR set to a value, but you
normally don't want to do this, since it is easier to change the
transceiver type by rebuilding a new floppy, changing the BIOS to floppy
boot, booting, and then changing the BIOS back to network boot. If
CFG_3C90X_XCVR is not set in a particular build, it just uses the
current configuration (either its 'best guess' or whatever the stored
CFG_3C90X_XCVR value was from the last time it was set).
[[ Note for the more technically inclined: The CFG_3C90X_XCVR value is
programmed into a register in the card's NVRAM that was reserved for
LanWorks PROM images to use. When the driver boots, the card comes
up in MII mode, and the driver checks the LanWorks register to find
out if the user specified a transceiver type. If it finds that
information, it uses that, otherwise it picks a transceiver that the
card has based on the 3c905b's MediaOptions register. This driver isn't
quite smart enough to always determine which media port is actually
_connected_; maybe someone else would like to take on that task (it
actually involves sending a self-directed packet and seeing if it
comes back. IF it does, that port is connected). ]]
Another issue to keep in mind is that it is possible that some OS'es
might not be happy with the way I've handled the PROM-image hack with
setting MII mode on bootup. Linux 2.0.35 does not have this problem.
Behavior of other systems may vary. The 3com documentation specifically
says that, at least with the card that I have, the device driver in the
OS should auto-select the media port, so other drivers should work fine
with this 'hack'. However, if yours doesn't seem to, you can try defining
CFG_3C90X_PRESERVE_XCVR when building to cause Etherboot to keep the
working setting (that allowed the bootp/tftp process) across the eth_reset
operation.
IV FOR DEVELOPERS....
If you would like to fix/extend/etc. this driver, feel free to do so; just
be sure you can test the modified version on the 3c905B-TX cards that the
driver was originally designed for. This section of this document gives
some information that might be relevant to a programmer.
A. Main Entry Point
a3c90x_probe is the main entry point for this driver. It is referred
to in an array in 'config.c'.
B. Other Important Functions
The functions a3c90x_transmit, a3c90x_poll, a3c90x_reset, and
a3c90x_disable are static functions that EtherBoot finds out about
as a result of a3c90x_probe setting entries in the nic structure
for them. The EtherBoot framework does not use interrupts. It is
polled. All transmit and receive operations are initiated by the
etherboot framework, not by an interrupt or by the driver.
C. Internal Functions
The following functions are internal to the driver:
a3c90x_internal_IssueCommand - sends a command to the 3c905b card.
a3c90x_internal_SetWindow - shifts between one of eight register
windows onboard the 3c90x. The bottom 16 bytes of the card's
I/O space are multiplexed among 128 bytes, only 16 of which are
visible at any one time. This SetWindow function selects one of
the eight sets.
a3c90x_internal_ReadEeprom - reads a word (16 bits) from the
card's onboard nvram. This is NOT the BIOS boot rom. This is
where the card stores such things as its hardware address.
a3c90x_internal_WriteEeprom - writes a word (16 bits) to the
card's nvram, and recomputes the eeprom checksum.
a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
card's nvram. Used by the above routine.
a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
card's nvram. Used by the above routine.
D. Globals
All global variables are inside a global structure named INF_3C90X.
So, wherever you see that structure referenced, you know the variable
is a global. Just keeps things a little neater.
E. Enumerations
There are quite a few enumerated type definitions for registers and
so forth, many for registers that I didn't even touch in the driver.
Register types start with 'reg', window numbers (for SetWindow)
start with 'win', and commands (for IssueCommand) start with 'cmd'.
Register offsets also include an indication in the name as to the
size of the register (_b = byte, _w = word, _l = long), and which
window the register is in, if it is windowed (0-7).
F. Why the 'a3c90x' name?
I had to come up with a letter at the beginning of all of the
identifiers, since 3com so conveniently had their name start with a
number. Another driver used 't' (for 'three'?); I chose 'a' for
no reason at all.
Addendum by Jorge L. deLyra <delyra@latt.if.usp.br>, 22Nov2000 re
working around the 3C905 hardware bug mentioned above:
Use this floppy to fix any 3COM model 3C905B PCI 10/100 Ethernet cards
that fail to load and run the boot program the first time around. If
they have a "Lucent" rather than a "Broadcom" chipset these cards have
a configuration bug that causes a hang when trying to load the boot
program from the PROM, if you try to use them right out of the box.
The boot program in this floppy is the file named 3c905b-tpo100.rom
from Etherboot version 4.6.10, compiled with the bugfix parameter
CFG_3C90X_BOOTROM_FIX
You have to take the chip off the card and boot the system once using
this floppy. Once loaded from the floppy, the boot program will access
the card and change some setting in it, correcting the problem. After
that you may use either this boot program or the normal one, compiled
without this bugfix parameter, to boot the machine from the PROM chip.
[Any recent Etherboot version should do, not just 4.6.10 - Ed.]

View file

@ -1,219 +0,0 @@
# For <shared.h> and <stage1.h>.
INCLUDES = -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1
# Don't build the netboot support by default.
if NETBOOT_SUPPORT
LIBDRIVERS = libdrivers.a
else
LIBDRIVERS =
endif
noinst_LIBRARIES = $(LIBDRIVERS)
libdrivers_a_SOURCES = cards.h config.c etherboot.h \
fsys_tftp.c linux-asm-io.h linux-asm-string.h \
main.c misc.c nic.h osdep.h pci.c pci.h timer.c timer.h
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
cs89x0.c cs89x0.h davicom.c depca.c eepro.c eepro100.c \
epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
tiara.c tlan.c tulip.c via-rhine.c w89c840.c
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
-DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
# Filled by configure.
libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
EXTRA_DIST = README.netboot 3c90x.txt cs89x0.txt sis900.txt tulip.txt
# These below are several special rules for the device drivers.
# We cannot use a simple rule for them...
# What objects are derived from a driver?
3c509_drivers = 3c509.o 3c529.o
3c595_drivers = 3c595.o
3c90x_drivers = 3c90x.o
cs89x0_drivers = cs89x0.o
davicom_drivers = davicom.o
depca_drivers = depca.o
eepro_drivers = eepro.o
eepro100_drivers = eepro100.o
epic100_drivers = epic100.o
#fa311_drivers = fa311.o
i82586_drivers = 3c507.o exos205.o ni5210.o
lance_drivers = lance.o ne2100.o ni6510.o
natsemi_drivers = natsemi.o
ni5010_drivers = ni5010.o
ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
otulip_drivers = otulip.o
rtl8139_drivers = rtl8139.o
sis900_drivers = sis900.o
sk_g16_drivers = sk_g16.o
smc9000_drivers = smc9000.o
tiara_drivers = tiara.o
#tlan_drivers = tlan.o
tulip_drivers = tulip.o
via_rhine_drivers = via_rhine.o
w89c840_drivers = w89c840.o
# Is it really necessary to specify dependecies explicitly?
$(3c509_drivers): 3c509.c 3c509.h
$(3c509_drivers): %.o: 3c509.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(3c595_drivers): 3c595.c 3c595.h
$(3c595_drivers): %.o: 3c595.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(3c90x_drivers): 3c90x.c
$(3c90x_drivers): %.o: 3c90x.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(cs89x0_drivers): cs89x0.c cs89x0.h
$(cs89x0_drivers): %.o: cs89x0.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(davicom_drivers): davicom.c
$(davicom_drivers): %.o: davicom.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(depca_drivers): depca.c
$(depca_drivers): %.o: depca.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(eepro_drivers): eepro.c
$(eepro_drivers): %.o: eepro.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(eepro100_drivers): eepro100.c
$(eepro100_drivers): %.o: eepro100.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(epic100_drivers): epic100.c epic100.h
$(epic100_drivers): %.o: epic100.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
#$(fa311_drivers): fa311.c
#$(fa311_drivers): %.o: fa311.c
# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(i82586_drivers): i82586.c
$(i82586_drivers): %.o: i82586.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(lance_drivers): lance.c
$(lance_drivers): %.o: lance.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(natsemi_drivers): natsemi.c
$(natsemi_drivers): %.o: natsemi.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(ni5010_drivers): ni5010.c
$(ni5010_drivers): %.o: ni5010.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(ns8390_drivers): ns8390.c ns8390.h
$(ns8390_drivers): %.o: ns8390.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(otulip_drivers): otulip.c otulip.h
$(otulip_drivers): %.o: otulip.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(rtl8139_drivers): rtl8139.c
$(rtl8139_drivers): %.o: rtl8139.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(sis900_drivers): sis900.c
$(sis900_drivers): %.o: sis900.c sis900.h
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(sk_g16_drivers): sk_g16.c sk_g16.h
$(sk_g16_drivers): %.o: sk_g16.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(smc9000_drivers): smc9000.c smc9000.h
$(smc9000_drivers): %.o: smc9000.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(tiara_drivers): tiara.c
$(tiara_drivers): %.o: tiara.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
#$(tlan_drivers): tlan.c
#$(tlan_drivers): %.o: tlan.c
# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(tulip_drivers): tulip.c
$(tulip_drivers): %.o: tulip.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(via_rhine_drivers): via-rhine.c
$(via_rhine_drivers): %.o: via-rhine.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
$(w89c840_drivers): w89c840.c
$(w89c840_drivers): %.o: w89c840.c
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
# Per-object flags.
3c509_o_CFLAGS = -DINCLUDE_3C509=1
3c529_o_CFLAGS = -DINCLUDE_3C529=1
3c595_o_CFLAGS = -DINCLUDE_3C595=1
3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
davicom_o_CFLAGS = -DINCLUDE_DAVICOM=1
depca_o_CFLAGS = -DINCLUDE_DEPCA=1
eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
#fa311_o_CFLAGS = -DINCLUDE_FA311=1
3c507_o_CFLAGS = -DINCLUDE_3C507=1
exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
lance_o_CFLAGS = -DINCLUDE_LANCE=1
ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
natsemi_o_CFLAGS = -DINCLUDE_NATSEMI=1
ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
3c503_o_CFLAGS = -DINCLUDE_3C503=1
ne_o_CFLAGS = -DINCLUDE_NE=1
ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
wd_o_CFLAGS = -DINCLUDE_WD=1
otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
sis900_o_CFLAGS = -DINCLUDE_SIS900=1
sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
tiara_o_CFLAGS = -DINCLUDE_TIARA=1
#tlan_o_CFLAGS = -DINCLUDE_TLAN=1
tulip_o_CFLAGS = -DINCLUDE_TULIP=1
via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
w89c840_o_CFLAGS = -DINCLUDE_W89C840=1

File diff suppressed because it is too large Load diff

View file

@ -1,168 +0,0 @@
You can use the netboot support to download OS images from a network.
Nearly all the device drivers are coming from the network-based boot
loader, Etherboot. Please visit its web page. They have rich
documentations so you will be able to get useful information from there.
The URL is <http://etherboot.sourceforge.net/>.
These below are common options for configure. Perhaps you may not need
to specify them.
--disable-packet-retransmission
Turns off packet retransmission. Use it on an empty network, where
no packet collision can happen.
--enable-pci-direct
Define this for PCI BIOSes that do not implement BIOS32 or not
correctly.
--enable-diskless
Enable the diskless support. If specified, you will get two optional
images, called "nbgrub" and "pxegrub". The former is the ``Net Boot
Image Proposal'' format, which is used by Etherboot and Netboot, while
the latter is the ``Preboot Execution Environment" format, which is
used by a PXE ROM. You may buy a PXE ROM from some companies.
Here is the information about the device drivers. They are all disabled
by default, so you must specify configure options to enable drivers you
want to use. Some drivers have extra per-driver options, so the extra
options are also described below.
Caution: You should enable them as you need. Don't enable any
unnecessary driver, because GRUB might crash if you include too many
drivers at the same time.
3Com509, ISA/EISA
--enable-3c509
3Com529 == MCA 3c509
--enable-3c529
3Com59x and 3Com900
--enable-3c595
3Com90x
--enable-3c90x
Crystal Semiconductor CS89x0
--enable-cs89x0
--enable-cs-scan=LIST
Probe for CS89x0 base address using LIST of comma separated hex
addresses; increasing the address by one (0x300 -> 0x301) will force
a more aggressive probing algorithm. This might be neccessary after
a soft-reset of the NIC.
Davicom DM9102 and 9009
--enable-davicom
Digital DE100 and DE200
--enable-depca
Intel Etherexpress Pro/10 (ISA card)
--enable-eepro
Intel Etherexpress Pro/100
--enable-eepro100
SMC 83c170 EPIC/100
--enable-epic100
3Com507
--enable-3c507
EXOS205
--enable-exos205
Racal-Interlan NI5210
--enable-ni5210
Lance PCI PCNet/32
AMD HomePNA
--enable-lance
Novell NE2100 and NE1500
--enable-ne2100
Racal-Interlan NI6510
--enable-ni6510
National Semiconductor DP8381x (Netgear FA311 and FA312)
--enable-natsemi
Racal-Interlan NI5010
--enable-ni5010
3Com503, aka Etherlink II, also /16 model
--enable-3c503
--enable-3c503-shmem
Use 3c503 shared memory mode.
--enable-3c503-aui
Use AUI by default on 3c503 cards.
NE1000/2000 and clones (ISA)
--enable-ne
--enable-ne-scan=LIST (0x280,0x300,0x320,0x340)
Probe for NE base address using LIST of comma separated hex
addresses.
NE2000 PCI clone (RTL8029)
Winbond 86C940
Compex RL2000
KTI ET32P2
NetVin 5000SC
Holtek 80232
--enable-ns8390
--enable-compex-rl2000-fix
If you have a Compex RL2000 PCI 32-bit (11F6:1401), and the probe
hangs in "Probing...[NE*000/PCI]", try enabling this fix... it
worked for me :).
WD8003/8013, SMC8216/8416
--enable-wd
--enable-wd-default-mem=MEM (0xCC000)
Default memory location for WD/SMC cards.
Old base driver for Tulip clones
--enable-otulip
Realtek 8139
SMC 1211
D-Link DFE530TX+ and DFE538TX
--enable-rtl8139
SIS 900 and SIS 7016
--enable-sis900
Schneider and Koch G16
--enable-sk-g16
SMC9000
--enable-smc9000
--enable-smc9000-scan=LIST
List of I/O addresses to probe.
Tiara, Fujitsu Lancard
--enable-tiara
Linksys LNE100TX and other NICs using this Tulip clone chip
Netgear FA310TX and other NICs using this Tulip clone chip
Tulip clones based on the ADMtek Centaur-P
Tulip clones based on the Macronix 987x5
Tulip-Fast
Tulip+
Tulip 21142
ASIX AX88140
Intel Tulip
Compex RL100-TX
--enable-tulip
Rhine-I, e.g. D-Link DFE-530TX
Rhine-II
--enable-via-rhine
Winbond W89c840
Compex RL100-ATX
--enable-w89c840
The description about how to use the support can be found in the GRUB
manual. Run "info grub" in the shell prompt.

View file

@ -1,183 +0,0 @@
#ifndef CARDS_H
#define CARDS_H
/*
* 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.
*/
#include "nic.h"
/* OK, this is how the PCI support hack works: if pci.h is included before
* this file is included, assume that the driver supports PCI. This means that
* this file is usually included last. */
#ifdef PCI_H
#define PCI_ARG(x) ,x
#else
#define PCI_ARG(x)
#endif
#ifdef INCLUDE_WD
extern struct nic *wd_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_3C503
extern struct nic *t503_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_VIA_RHINE
extern struct nic *rhine_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_NE
extern struct nic *ne_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_NS8390
extern struct nic *nepci_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_3C509
extern struct nic *t509_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_3C529
extern struct nic *t529_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_3C595
extern struct nic *t595_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_3C90X
extern struct nic *a3c90x_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_EEPRO
extern struct nic *eepro_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_EEPRO100
extern struct nic *eepro100_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_EPIC100
extern struct nic *epic100_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_OTULIP
extern struct nic *otulip_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_TULIP
extern struct nic *tulip_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_DAVICOM
extern struct nic *davicom_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_CS89X0
extern struct nic *cs89x0_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_LANCE
extern struct nic *lancepci_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_NE2100
extern struct nic *ne2100_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_NI6510
extern struct nic *ni6510_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_SK_G16
extern struct nic *SK_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_3C507
extern struct nic *t507_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_NI5010
extern struct nic *ni5010_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_NI5210
extern struct nic *ni5210_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_EXOS205
extern struct nic *exos205_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_SMC9000
extern struct nic *smc9000_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_TIARA
extern struct nic *tiara_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_DEPCA
extern struct nic *depca_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_RTL8139
extern struct nic *rtl8139_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_W89C840
extern struct nic *w89c840_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_SIS900
extern struct nic *sis900_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_NATSEMI
extern struct nic *natsemi_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#ifdef INCLUDE_TLAN
extern struct nic *tlan_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
#endif /* CARDS_H */

View file

@ -1,598 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2001,2002 Free Software Foundation, Inc.
*
* 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.
*
* 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.
*/
/* Based on "src/config.c" in etherboot-5.0.5. */
/*
* 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.
*/
#define GRUB 1
#include <etherboot.h>
#include <nic.h>
#undef INCLUDE_PCI
#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900) || defined(INCLUDE_NATSEMI) || defined(INCLUDE_TLAN)
/* || others later */
# define INCLUDE_PCI
# include <pci.h>
static unsigned short pci_ioaddrs[16];
static struct pci_device pci_nic_list[] =
{
#ifdef INCLUDE_NS8390
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029,
"Realtek 8029", 0, 0, 0, 0},
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940,
"Winbond NE2000-PCI", 0, 0, 0, 0},
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000,
"Compex ReadyLink 2000", 0, 0, 0, 0},
{ PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2,
"KTI ET32P2", 0, 0, 0, 0},
{ PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC,
"NetVin NV5000SC", 0, 0, 0, 0},
{ PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_HT80232,
"Holtek HT80232", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_3C90X
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
"3Com900-TPO", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
"3Com900-Combo", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX,
"3Com905-TX", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4,
"3Com905-T4", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9004,
"3Com900B-TPO", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9005,
"3Com900B-Combo", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9006,
"3Com900B-2/T", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x900A,
"3Com900B-FL", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905B_TX,
"3Com905B-TX", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9056,
"3Com905B-T4", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x905A,
"3Com905B-FL", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C_TXM,
"3Com905C-TXM", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9800,
"3Com980-Cyclone", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9805,
"3Com9805", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x7646,
"3CSOHO100-TX", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_3C595
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590,
"3Com590", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595,
"3Com595", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_1,
"3Com595", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_2,
"3Com595", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
"3Com900-TPO", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
"3Com900-Combo", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9004,
"3Com900B-TPO", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9005,
"3Com900B-Combo", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9006,
"3Com900B-2/T", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x900A,
"3Com900B-FL", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9800,
"3Com980-Cyclone", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x9805,
"3Com9805", 0, 0, 0, 0},
{ PCI_VENDOR_ID_3COM, 0x7646,
"3CSOHO100-TX", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_EEPRO100
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,
"Intel EtherExpressPro100", 0, 0, 0, 0},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER,
"Intel EtherExpressPro100 82559ER", 0, 0, 0, 0},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029,
"Intel EtherExpressPro100 ID1029", 0, 0, 0, 0},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030,
"Intel Corporation 82559 InBusiness 10/100", 0, 0, 0, 0},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562,
"Intel EtherExpressPro100 82562EM", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_EPIC100
{ PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100,
"SMC EtherPowerII", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_LANCE
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
"AMD Lance/PCI", 0, 0, 0, 0},
{ PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA,
"AMD Lance/HomePNA", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_RTL8139
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
"Realtek 8139", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DFE530TXP,
"DFE530TX+/DFE538TX", 0, 0, 0, 0},
{ PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211,
"SMC EZ10/100", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_OTULIP
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
"Digital Tulip", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
"Digital Tulip Fast", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
"Digital Tulip+", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
"Digital Tulip 21142", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_TULIP
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
"Digital Tulip", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
"Digital Tulip Fast", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
"Digital Tulip+", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
"Digital Tulip 21142", 0, 0, 0, 0},
{ PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5,
"Macronix MX987x5", 0, 0, 0, 0},
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LC82C115,
"LinkSys LNE100TX", 0, 0, 0, 0},
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_DEC_TULIP,
"Netgear FA310TX", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102,
"Davicom 9102", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009,
"Davicom 9009", 0, 0, 0, 0},
{ PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_0985,
"ADMtek Centaur-P", 0, 0, 0, 0},
{ PCI_VENDOR_ID_ADMTEK, 0x0981,
"ADMtek AN981 Comet", 0, 0, 0, 0},
{ 0x125B, 0x1400,
"ASIX AX88140", 0, 0, 0, 0 },
{ 0x11F6, 0x9881,
"Compex RL100-TX", 0, 0, 0, 0 },
#endif
#ifdef INCLUDE_DAVICOM
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102,
"Davicom 9102", 0, 0, 0, 0},
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009,
"Davicom 9009", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_VIA_RHINE
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_VT6102,
"VIA 6102", 0, 0, 0, 0},
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_RHINE_I,
"VIA 3043", 0, 0, 0, 0},
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A,
"VIA 86C100A", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_W89C840
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C840,
"Winbond W89C840F", 0, 0, 0, 0},
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL100ATX,
"Compex RL100ATX", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_SIS900
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
"SIS900", 0, 0, 0, 0},
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
"SIS7016", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_NATSEMI
{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP83815,
"DP83815", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_TLAN
{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
"OC2326", 0, 0, 0, 0},
#endif
/* other PCI NICs go here */
{0, 0, NULL, 0, 0, 0, 0}
};
#endif /* INCLUDE_*PCI */
#include <cards.h>
#ifdef INCLUDE_PCI
struct pci_dispatch_table
{
unsigned short vendor;
unsigned short dev_id;
struct nic *(*eth_probe) (struct nic *, unsigned short *,
struct pci_device *);
};
static struct pci_dispatch_table PCI_NIC[] =
{
# ifdef INCLUDE_NS8390
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029, nepci_probe },
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940, nepci_probe },
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000, nepci_probe },
{ PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2, nepci_probe },
{ PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC, nepci_probe },
{ PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_HT80232, nepci_probe },
# endif /* INCLUDE_NS8390 */
# ifdef INCLUDE_3C90X
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x9004, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x9005, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x9006, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x900A, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905B_TX, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x9056, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x905A, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C_TXM, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x9800, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x9805, a3c90x_probe },
{ PCI_VENDOR_ID_3COM, 0x7646, a3c90x_probe },
# endif /* INCLUDE_3C90X */
# ifdef INCLUDE_3C595
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590, t595_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595, t595_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_1, t595_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_2, t595_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO, t595_probe },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO, t595_probe },
{ PCI_VENDOR_ID_3COM, 0x9004, t595_probe },
{ PCI_VENDOR_ID_3COM, 0x9005, t595_probe },
{ PCI_VENDOR_ID_3COM, 0x9006, t595_probe },
{ PCI_VENDOR_ID_3COM, 0x900A, t595_probe },
{ PCI_VENDOR_ID_3COM, 0x9800, t595_probe },
{ PCI_VENDOR_ID_3COM, 0x9805, t595_probe },
{ PCI_VENDOR_ID_3COM, 0x7646, t595_probe },
# endif /* INCLUDE_3C595 */
# ifdef INCLUDE_EEPRO100
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557, eepro100_probe },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER, eepro100_probe },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029, eepro100_probe },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030, eepro100_probe },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562, eepro100_probe },
# endif /* INCLUDE_EEPRO100 */
# ifdef INCLUDE_EPIC100
{ PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100, epic100_probe },
# endif /* INCLUDE_EPIC100 */
# ifdef INCLUDE_LANCE
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, lancepci_probe },
{ PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA, lancepci_probe },
# endif /* INCLUDE_LANCE */
# ifdef INCLUDE_RTL8139
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, rtl8139_probe },
{ PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DFE530TXP, rtl8139_probe },
{ PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211, rtl8139_probe },
# endif /* INCLUDE_RTL8139 */
# ifdef INCLUDE_OTULIP
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, otulip_probe },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, otulip_probe },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, otulip_probe },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, otulip_probe },
# endif /* INCLUDE_OTULIP */
# ifdef INCLUDE_TULIP
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, tulip_probe },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, tulip_probe },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, tulip_probe },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, tulip_probe },
{ PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5, tulip_probe },
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LC82C115, tulip_probe },
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_DEC_TULIP, tulip_probe },
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102, tulip_probe },
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009, tulip_probe },
{ PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_0985, tulip_probe },
{ PCI_VENDOR_ID_ADMTEK, 0x0981, tulip_probe },
{ 0x125B, 0x1400, tulip_probe },
{ 0x11F6, 0x9881, tulip_probe },
# endif /* INCLUDE_TULIP */
# ifdef INCLUDE_DAVICOM
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102, davicom_probe },
{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009, davicom_probe },
# endif /* INCLUDE_DAVICOM */
# ifdef INCLUDE_VIA_RHINE
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_VT6102, rhine_probe },
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_RHINE_I, rhine_probe },
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A, rhine_probe },
# endif /* INCLUDE_VIA_RHINE */
# ifdef INCLUDE_W89C840
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C840, w89c840_probe },
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL100ATX, w89c840_probe },
# endif /* INCLUDE_W89C840 */
# ifdef INCLUDE_SIS900
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900, sis900_probe },
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016, sis900_probe },
# endif /* INCLUDE_SIS900 */
# ifdef INCLUDE_NATSEMI
{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP83815, natsemi_probe },
# endif /* INCLUDE_NATSEMI */
# ifdef INCLUDE_TLAN
{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326, tlan_probe },
# endif /* INCLUDE_TLAN */
{ 0, 0, 0 }
};
#endif /* GRUB && INCLUDE_PCI */
struct dispatch_table
{
const char *nic_name;
#ifdef INCLUDE_PCI
struct nic *(*eth_probe) (struct nic *, unsigned short *,
struct pci_device *);
#else
struct nic *(*eth_probe) (struct nic *, unsigned short *);
#endif /* INCLUDE_PCI */
unsigned short *probe_ioaddrs; /* for probe overrides */
};
/*
* 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_RTL8139
{ "RTL8139", rtl8139_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_SIS900
{ "SIS900", sis900_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_NATSEMI
{ "NATSEMI", natsemi_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_WD
{ "WD", wd_probe, 0 },
#endif
#ifdef INCLUDE_3C503
{ "3C503", t503_probe, 0 },
#endif
#ifdef INCLUDE_NE
{ "NE*000", ne_probe, 0 },
#endif
#ifdef INCLUDE_3C509
{ "3C5x9", t509_probe, 0 },
#endif
#ifdef INCLUDE_3C529
{ "3C5x9", t529_probe, 0 },
#endif
#ifdef INCLUDE_3C595
{ "3C595", t595_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_3C90X
{ "3C90X", a3c90x_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_EEPRO
{ "EEPRO", eepro_probe, 0 },
#endif
#ifdef INCLUDE_EEPRO100
{ "EEPRO100", eepro100_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_EPIC100
{ "EPIC100", epic100_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_OTULIP
{ "OTulip", otulip_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_TULIP
{ "Tulip", tulip_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_DAVICOM
{ "DAVICOM", davicom_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_CS89X0
{ "CS89x0", cs89x0_probe, 0 },
#endif
#ifdef INCLUDE_NE2100
{ "NE2100", ne2100_probe, 0 },
#endif
#ifdef INCLUDE_NI6510
{ "NI6510", ni6510_probe, 0 },
#endif
#ifdef INCLUDE_SK_G16
{ "SK_G16", SK_probe, 0 },
#endif
#ifdef INCLUDE_3C507
{ "3C507", t507_probe, 0 },
#endif
#ifdef INCLUDE_NI5010
{ "NI5010", ni5010_probe, 0 },
#endif
#ifdef INCLUDE_NI5210
{ "NI5210", ni5210_probe, 0 },
#endif
#ifdef INCLUDE_EXOS205
{ "EXOS205", exos205_probe, 0 },
#endif
#ifdef INCLUDE_SMC9000
{ "SMC9000", smc9000_probe, 0 },
#endif
#ifdef INCLUDE_TIARA
{ "TIARA", tiara_probe, 0 },
#endif
#ifdef INCLUDE_DEPCA
{ "DEPCA", depca_probe, 0 },
#endif
#ifdef INCLUDE_NS8390
{ "NE2000/PCI", nepci_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_LANCE
{ "LANCE/PCI", lancepci_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_VIA_RHINE
{ "VIA 86C100", rhine_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_W89C840
{ "W89C840F", w89c840_probe, pci_ioaddrs },
#endif
#ifdef INCLUDE_TLAN
{ "Olicom 2326", tlan_probe, pci_ioaddrs },
#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 *dummy)
{
return 0;
}
static char packet[ETH_FRAME_LEN];
struct nic nic =
{
(void (*) (struct nic *)) eth_dummy, /* reset */
eth_dummy, /* poll */
(void (*) (struct nic *, const char *,
unsigned int, unsigned int,
const char *)) eth_dummy, /* transmit */
(void (*) (struct nic *)) eth_dummy, /* disable */
#ifdef T503_AUI
1, /* aui */
#else
0, /* no aui */
#endif
&rom, /* rom_info */
arptable[ARP_CLIENT].node, /* node_addr */
packet, /* packet */
0, /* packetlen */
0, /* priv_data */
};
void
eth_reset (void)
{
(*nic.reset) (&nic);
}
int
eth_probe (void)
{
struct pci_device *p;
const struct dispatch_table *t;
static int probed = 0;
/* If already probed, don't try to probe it any longer. */
if (probed)
return 1;
/* Clear the ready flag. */
network_ready = 0;
/* Clear the ARP table. */
grub_memset ((char *) arptable, 0,
MAX_ARP * sizeof (struct arptable_t));
p = 0;
#ifdef INCLUDE_PCI
/* In GRUB, the ROM info is initialized here. */
rom = *((struct rom_info *) ROM_INFO_LOCATION);
eth_pci_init(pci_nic_list);
pci_ioaddrs[0] = 0;
pci_ioaddrs[1] = 0;
/* at this point we have a list of possible PCI candidates
we just pick the first one with a non-zero ioaddr */
for (p = pci_nic_list; p->vendor != 0; ++p)
{
if (p->ioaddr != 0)
{
pci_ioaddrs[0] = p->ioaddr;
break;
}
}
#endif
etherboot_printf("Probing...");
#ifdef INCLUDE_PCI
if (p->vendor)
{
struct pci_dispatch_table *pt;
for (pt = PCI_NIC; pt->eth_probe != 0; pt++)
if (p->vendor == pt->vendor && p->dev_id == pt->dev_id)
{
etherboot_printf ("[%s]", p->name);
if ((pt->eth_probe) (&nic, pci_ioaddrs, p))
{
probed = 1;
return 1;
}
}
}
#endif /* INCLUDE_PCI */
for (t = NIC; t->nic_name != 0; ++t)
{
etherboot_printf("[%s]", t->nic_name);
#ifdef INCLUDE_PCI
if ((*t->eth_probe) (&nic, t->probe_ioaddrs, p))
{
probed = 1;
return 1;
}
#else
if ((*t->eth_probe) (&nic, t->probe_ioaddrs))
{
probed = 1;
return 1;
}
#endif /* INCLUDE_PCI */
}
return 0;
}
int
eth_poll (void)
{
return ((*nic.poll) (&nic));
}
void
eth_transmit (const char *d, unsigned int t, unsigned int s, const void *p)
{
(*nic.transmit) (&nic, d, t, s, p);
if (t == IP)
twiddle ();
}
void
eth_disable (void)
{
(*nic.disable) (&nic);
}

View file

@ -1,677 +0,0 @@
/**
Per an email message from Russ Nelson <nelson@crynwr.com> on
18 March 2008 this file is now licensed under GPL Version 2.
From: Russ Nelson <nelson@crynwr.com>
Date: Tue, 18 Mar 2008 12:42:00 -0400
Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
-- quote from email
As copyright holder, if I say it doesn't conflict with the GPL,
then it doesn't conflict with the GPL.
However, there's no point in causing people's brains to overheat,
so yes, I grant permission for the code to be relicensed under the
GPLv2. Please make sure that this change in licensing makes its
way upstream. -russ
-- quote from email
**/
/* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */
/*
Permission is granted to distribute the enclosed cs89x0.[ch] driver
only in conjunction with the Etherboot package. The code is
ordinarily distributed under the GPL.
Russ Nelson, January 2000
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 Etherboot/32.
* 12
*/
#include "etherboot.h"
#include "nic.h"
#include "cards.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;
/*************************************************************************
CS89x0 - specific routines
**************************************************************************/
static inline int readreg(int portno)
{
outw(portno, eth_nic_base + ADD_PORT);
return inw(eth_nic_base + DATA_PORT);
}
static inline void writereg(int portno, int value)
{
outw(portno, eth_nic_base + ADD_PORT);
outw(value, eth_nic_base + DATA_PORT);
return;
}
/*************************************************************************
EEPROM access
**************************************************************************/
static int wait_eeprom_ready(void)
{
unsigned long tmo = currticks() + 4*TICKS_PER_SEC;
/* 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)
return -1; }
return 0;
}
static int get_eeprom_data(int off, int len, unsigned short *buffer)
{
int i;
#ifdef EDEBUG
printf("\ncs: EEPROM data from %hX for %hX:",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);
#ifdef EDEBUG
if (!(i%10))
printf("\ncs: ");
printf("%hX ", buffer[i]);
#endif
}
#ifdef EDEBUG
putchar('\n');
#endif
return(0);
}
static int get_eeprom_chksum(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(void)
{
int i;
putchar('\r');
for (i = 79; i--; ) putchar(' ');
printf("\rcs: ");
return;
}
static void control_dc_dc(int on_not_off)
{
unsigned int selfcontrol;
unsigned long tmo = currticks() + TICKS_PER_SEC;
/* 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);
return;
}
static int detect_tp(void)
{
unsigned 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; );
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*TICKS_PER_SEC) {
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 unsigned 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)*/ };
unsigned long tmo;
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
memcpy(testpacket, nic->node_addr, ETH_ALEN);
memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN);
outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
outw(ETH_ZLEN, eth_nic_base + TX_LEN_PORT);
/* 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)
return(0);
/* Write the contents of the packet */
outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
(ETH_ZLEN+1)>>1);
printf(" sending test packet ");
/* wait a couple of timer ticks for packet to be received */
for (tmo = currticks() + 2; currticks() < tmo; );
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
***************************************************************************/
static void cs89x0_reset(struct nic *nic)
{
int i;
unsigned long reset_tmo;
writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
/* wait for two ticks; that is 2*55ms */
for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );
if (eth_cs_type != CS8900) {
/* Hardware problem requires PNP registers to be reconfigured
after a reset */
if (eth_irq != 0xFFFF) {
outw(PP_CS8920_ISAINT, eth_nic_base + ADD_PORT);
outb(eth_irq, eth_nic_base + DATA_PORT);
outb(0, eth_nic_base + DATA_PORT + 1); }
if (eth_mem_start) {
outw(PP_CS8920_ISAMemB, eth_nic_base + ADD_PORT);
outb((eth_mem_start >> 8) & 0xff, eth_nic_base + DATA_PORT);
outb((eth_mem_start >> 24) & 0xff, eth_nic_base + DATA_PORT + 1); } }
/* Wait until the chip is reset */
for (reset_tmo = currticks() + 2;
(readreg(PP_SelfST) & INIT_DONE) == 0 &&
currticks() < reset_tmo; );
/* disable interrupts and memory accesses */
writereg(PP_BusCTL, 0);
/* set the ethernet address */
for (i=0; i < ETH_ALEN/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(PP_ChipID, eth_nic_base + ADD_PORT);
return;
}
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static void cs89x0_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
unsigned long tmo;
int sr;
/* does this size have to be rounded??? please,
somebody have a look in the specs */
if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)
sr = ETH_ZLEN;
retry:
/* initiate a transmit sequence */
outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
outw(sr, eth_nic_base + TX_LEN_PORT);
/* 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...\n");
for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
cs89x0_reset(nic);
goto retry; }
/* Write the contents of the packet */
outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2);
outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
ETH_ALEN/2);
outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);
outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr-- > 0;
outw(0, eth_nic_base + TX_FRAME_PORT));
/* wait for transfer to succeed */
for (tmo = currticks()+5*TICKS_PER_SEC;
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
/* nothing */ ;
if ((s & TX_SEND_OK_BITS) != TX_OK) {
printf("\ntransmission error %#hX\n", s);
}
return;
}
/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
static int cs89x0_poll(struct nic *nic)
{
int status;
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)
{
cs89x0_reset(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 (ioidx = 0; (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(PP_ChipID, ioaddr + ADD_PORT);
}
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("\ncs: cs89%c0%s rev %c, base %#hX",
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("\ncs: no EEPROM...\n");
outw(PP_ChipID, eth_nic_base + ADD_PORT);
continue; }
else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,
eeprom_buff) < 0) {
printf("\ncs: EEPROM read failed...\n");
outw(PP_ChipID, eth_nic_base + ADD_PORT);
continue; }
else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,
eeprom_buff) < 0) {
printf("\ncs: EEPROM checksum bad...\n");
outw(PP_ChipID, eth_nic_base + ADD_PORT);
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("\ncs: BUG: isa_config is %d\n", i); }
eth_irq = i; }
/* Retrieve and print the ethernet address. */
for (i=0; i<ETH_ALEN; i++) {
nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];
}
printf("%!\n", nic->node_addr);
/* 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\n");
error:
writereg(PP_LineCTL, readreg(PP_LineCTL) &
~(SERIAL_TX_ON | SERIAL_RX_ON));
outw(PP_ChipID, eth_nic_base + ADD_PORT);
continue;
}
/* Initialize the card for probing of the attached media */
cs89x0_reset(nic);
/* 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\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\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\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\n");
goto error;
}
clrline();
switch(result) {
case 0: printf("no network cable attached to configured media\n");
goto error;
case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
break;
case A_CNF_MEDIA_AUI: printf("using 10Base-5 (AUI)\n");
break;
case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
break;
}
/* Turn on both receive and transmit operations */
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |
SERIAL_TX_ON);
break;
}
if (ioaddr == 0)
return (0);
nic->reset = cs89x0_reset;
nic->poll = cs89x0_poll;
nic->transmit = cs89x0_transmit;
nic->disable = cs89x0_disable;
return (nic);
}
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,479 +0,0 @@
/**
Per an email message from Russ Nelson <nelson@crynwr.com> on
18 March 2008 this file is now licensed under GPL Version 2.
From: Russ Nelson <nelson@crynwr.com>
Date: Tue, 18 Mar 2008 12:42:00 -0400
Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
-- quote from email
As copyright holder, if I say it doesn't conflict with the GPL,
then it doesn't conflict with the GPL.
However, there's no point in causing people's brains to overheat,
so yes, I grant permission for the code to be relicensed under the
GPLv2. Please make sure that this change in licensing makes its
way upstream. -russ
-- quote from email
**/
/* 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:
*/

View file

@ -1,26 +0,0 @@
Permission is granted to distribute the enclosed cs89x0.[ch] driver
only in conjunction with the Etherboot package. The code is
ordinarily distributed under the GPL.
Russ Nelson, January 2000
CREDITS
I want to thank
Mike Cruse <mcruse@cti-ltd.com>
for providing an evaluation NIC and for sponsoring the
development of this driver.
Randall Sears <sears@crystal.cirrus.com>
Deva Bodas <bodas@crystal.cirrus.com>
Andreas Kraemer <akraemer@crystal.cirrus.com>
Wolfgang Krause <100303.2673@compuserve.com>
for excellent technical support and for providing the required
programming information. I appreciate Crystal Semiconductor's
commitment towards free software.
Russell Nelson <nelson@crynwr.com>
for writing the Linux device driver for the CS89x0
chipset. Russel's code is very well designed and simplified my
job a lot.

View file

@ -1,692 +0,0 @@
/*
DAVICOM DM9009/DM9102/DM9102A Etherboot Driver V1.00
This driver was ported from Marty Conner's Tulip Etherboot driver.
Thanks Marty Connor (mdc@thinguin.org)
You can get Tulip driver source file from this URL:
"http://etherboot.sourceforge..net/#Distribution"
This davicom etherboot driver supports DM9009/DM9102/DM9102A/
DM9102A+DM9801/DM9102A+DM9802 NICs.
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
*/
/*********************************************************************/
/* Revision History */
/*********************************************************************/
/*
19 OCT 2000 Sten 1.00
Different half and full duplex mode
Do the different programming for DM9801/DM9802
12 OCT 2000 Sten 0.90
This driver was ported from tulip driver and it
has the following difference.
Changed symbol tulip/TULIP to davicom/DAVICOM
Deleted some code that did not use in this driver.
Used chain-strcture to replace ring structure
for both TX/RX descriptor.
Allocated two tx descriptor.
According current media mode to set operating
register(CR6)
*/
/*********************************************************************/
/* Declarations */
/*********************************************************************/
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
#undef DAVICOM_DEBUG
#undef DAVICOM_DEBUG_WHERE
#define TX_TIME_OUT 2*TICKS_PER_SEC
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
/* Register offsets for davicom device */
enum davicom_offsets {
CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
};
/* EEPROM Address width definitions */
#define EEPROM_ADDRLEN 6
#define EEPROM_SIZE 32 /* 1 << EEPROM_ADDRLEN */
/* Used to be 128, but we only need to read enough to get the MAC
address at bytes 20..25 */
/* Data Read from the EEPROM */
static unsigned char ee_data[EEPROM_SIZE];
/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD (5 << addr_len)
#define EE_READ_CMD (6 << addr_len)
#define EE_ERASE_CMD (7 << addr_len)
/* EEPROM_Ctrl bits. */
#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */
#define EE_CS 0x01 /* 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)
/* Sten 10/11 for phyxcer */
#define PHY_DATA_0 0x0
#define PHY_DATA_1 0x20000
#define MDCLKH 0x10000
/* Delay between EEPROM clock transitions. Even at 33Mhz current PCI
implementations don't overrun the EEPROM clock. We add a bus
turn-around to insure that this remains true. */
#define eeprom_delay() inl(ee_addr)
/* helpful macro if on a big_endian machine for changing byte order.
not strictly needed on Intel */
#define le16_to_cpu(val) (val)
/* transmit and receive descriptor format */
struct txdesc {
volatile unsigned long status; /* owner, status */
unsigned long buf1sz:11, /* size of buffer 1 */
buf2sz:11, /* size of buffer 2 */
control:10; /* control bits */
const unsigned char *buf1addr; /* buffer 1 address */
const unsigned char *buf2addr; /* buffer 2 address */
};
struct rxdesc {
volatile unsigned long status; /* owner, status */
unsigned long buf1sz:11, /* size of buffer 1 */
buf2sz:11, /* size of buffer 2 */
control:10; /* control bits */
unsigned char *buf1addr; /* buffer 1 address */
unsigned char *buf2addr; /* buffer 2 address */
};
/* Size of transmit and receive buffers */
#define BUFLEN 1536
/*********************************************************************/
/* Global Storage */
/*********************************************************************/
/* PCI Bus parameters */
static unsigned short vendor, dev_id;
static unsigned long ioaddr;
/* Note: transmit and receive buffers must be longword aligned and
longword divisable */
/* transmit descriptor and buffer */
#define NTXD 2
static struct txdesc txd[NTXD] __attribute__ ((aligned(4)));
#ifdef USE_LOWMEM_BUFFER
#define txb ((char *)0x10000 - BUFLEN)
#else
static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
#endif
/* receive descriptor(s) and buffer(s) */
#define NRXD 4
static struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));
#ifdef USE_LOWMEM_BUFFER
#define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
#else
static unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
#endif
static int rxd_tail;
static int TxPtr;
/*********************************************************************/
/* Function Prototypes */
/*********************************************************************/
static void whereami(const char *str);
static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
struct pci_device *pci);
static void davicom_init_chain(struct nic *nic); /* Sten 10/9 */
static void davicom_reset(struct nic *nic);
static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
unsigned int s, const char *p);
static int davicom_poll(struct nic *nic);
static void davicom_disable(struct nic *nic);
static void whereami (const char *str);
#ifdef DAVICOM_DEBUG
static void davicom_more(void);
#endif /* DAVICOM_DEBUG */
static void davicom_wait(unsigned int nticks);
static int phy_read(int);
static void phy_write(int, u16);
static void phy_write_1bit(u32, u32);
static int phy_read_1bit(u32);
static void davicom_media_chk(struct nic *);
/*********************************************************************/
/* Utility Routines */
/*********************************************************************/
static inline void whereami (const char *str)
{
#ifdef DAVICOM_DEBUG_WHERE
printf("%s\n", str);
/* sleep(2); */
#endif
}
#ifdef DAVICOM_DEBUG
static void davicom_more()
{
printf("\n\n-- more --");
while (!iskey())
/* wait */;
getchar();
printf("\n\n");
}
#endif /* DAVICOM_DEBUG */
static void davicom_wait(unsigned int nticks)
{
unsigned int to = currticks() + nticks;
while (currticks() < to)
/* wait */ ;
}
/*********************************************************************/
/* For DAVICOM phyxcer register by MII interface */
/*********************************************************************/
/*
Read a word data from phy register
*/
static int phy_read(int location)
{
int i, phy_addr=1;
u16 phy_data;
u32 io_dcr9;
whereami("phy_read\n");
io_dcr9 = ioaddr + CSR9;
/* Send 33 synchronization clock to Phy controller */
for (i=0; i<34; i++)
phy_write_1bit(io_dcr9, PHY_DATA_1);
/* Send start command(01) to Phy */
phy_write_1bit(io_dcr9, PHY_DATA_0);
phy_write_1bit(io_dcr9, PHY_DATA_1);
/* Send read command(10) to Phy */
phy_write_1bit(io_dcr9, PHY_DATA_1);
phy_write_1bit(io_dcr9, PHY_DATA_0);
/* Send Phy addres */
for (i=0x10; i>0; i=i>>1)
phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
/* Send register addres */
for (i=0x10; i>0; i=i>>1)
phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
/* Skip transition state */
phy_read_1bit(io_dcr9);
/* read 16bit data */
for (phy_data=0, i=0; i<16; i++) {
phy_data<<=1;
phy_data|=phy_read_1bit(io_dcr9);
}
return phy_data;
}
/*
Write a word to Phy register
*/
static void phy_write(int location, u16 phy_data)
{
u16 i, phy_addr=1;
u32 io_dcr9;
whereami("phy_write\n");
io_dcr9 = ioaddr + CSR9;
/* Send 33 synchronization clock to Phy controller */
for (i=0; i<34; i++)
phy_write_1bit(io_dcr9, PHY_DATA_1);
/* Send start command(01) to Phy */
phy_write_1bit(io_dcr9, PHY_DATA_0);
phy_write_1bit(io_dcr9, PHY_DATA_1);
/* Send write command(01) to Phy */
phy_write_1bit(io_dcr9, PHY_DATA_0);
phy_write_1bit(io_dcr9, PHY_DATA_1);
/* Send Phy addres */
for (i=0x10; i>0; i=i>>1)
phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
/* Send register addres */
for (i=0x10; i>0; i=i>>1)
phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
/* written trasnition */
phy_write_1bit(io_dcr9, PHY_DATA_1);
phy_write_1bit(io_dcr9, PHY_DATA_0);
/* Write a word data to PHY controller */
for (i=0x8000; i>0; i>>=1)
phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0);
}
/*
Write one bit data to Phy Controller
*/
static void phy_write_1bit(u32 ee_addr, u32 phy_data)
{
whereami("phy_write_1bit\n");
outl(phy_data, ee_addr); /* MII Clock Low */
eeprom_delay();
outl(phy_data|MDCLKH, ee_addr); /* MII Clock High */
eeprom_delay();
outl(phy_data, ee_addr); /* MII Clock Low */
eeprom_delay();
}
/*
Read one bit phy data from PHY controller
*/
static int phy_read_1bit(u32 ee_addr)
{
int phy_data;
whereami("phy_read_1bit\n");
outl(0x50000, ee_addr);
eeprom_delay();
phy_data=(inl(ee_addr)>>19) & 0x1;
outl(0x40000, ee_addr);
eeprom_delay();
return phy_data;
}
/*
DM9801/DM9802 present check and program
*/
static void HPNA_process(void)
{
if ( (phy_read(3) & 0xfff0) == 0xb900 ) {
if ( phy_read(31) == 0x4404 ) {
/* DM9801 present */
if (phy_read(3) == 0xb901)
phy_write(16, 0x5); /* DM9801 E4 */
else
phy_write(16, 0x1005); /* DM9801 E3 and others */
phy_write(25, ((phy_read(24) + 3) & 0xff) | 0xf000);
} else {
/* DM9802 present */
phy_write(16, 0x5);
phy_write(25, (phy_read(25) & 0xff00) + 2);
}
}
}
/*
Sense media mode and set CR6
*/
static void davicom_media_chk(struct nic * nic)
{
unsigned long to, csr6;
csr6 = 0x00200000; /* SF */
outl(csr6, ioaddr + CSR6);
if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9009) {
/* Set to 10BaseT mode for DM9009 */
phy_write(0, 0);
} else {
/* For DM9102/DM9102A */
to = currticks() + 2 * TICKS_PER_SEC;
while ( ((phy_read(1) & 0x24)!=0x24) && (currticks() < to))
/* wait */ ;
if ( (phy_read(1) & 0x24) == 0x24 ) {
if (phy_read(17) & 0xa000)
csr6 |= 0x00000200; /* Full Duplex mode */
} else
csr6 |= 0x00040000; /* Select DM9801/DM9802 when Ethernet link failed */
}
/* set the chip's operating mode */
outl(csr6, ioaddr + CSR6);
/* DM9801/DM9802 present check & program */
if (csr6 & 0x40000)
HPNA_process();
}
/*********************************************************************/
/* EEPROM Reading Code */
/*********************************************************************/
/* EEPROM routines adapted from the Linux Tulip Code */
/* Reading a serial EEPROM is a "bit" grungy, but we work our way
through:->.
*/
static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
{
int i;
unsigned short retval = 0;
long ee_addr = ioaddr + CSR9;
int read_cmd = location | EE_READ_CMD;
whereami("read_eeprom\n");
outl(EE_ENB & ~EE_CS, ee_addr);
outl(EE_ENB, ee_addr);
/* Shift the read command bits out. */
for (i = 4 + addr_len; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
outl(EE_ENB | dataval, ee_addr);
eeprom_delay();
outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
eeprom_delay();
}
outl(EE_ENB, ee_addr);
for (i = 16; i > 0; i--) {
outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
eeprom_delay();
retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
outl(EE_ENB, ee_addr);
eeprom_delay();
}
/* Terminate the EEPROM access. */
outl(EE_ENB & ~EE_CS, ee_addr);
return retval;
}
/*********************************************************************/
/* davicom_init_chain - setup the tx and rx descriptors */
/* Sten 10/9 */
/*********************************************************************/
static void davicom_init_chain(struct nic *nic)
{
int i;
/* setup the transmit descriptor */
/* Sten: Set 2 TX descriptor but use one TX buffer because
it transmit a packet and wait complete every time. */
for (i=0; i<NTXD; i++) {
txd[i].buf1addr = &txb[0]; /* Used same TX buffer */
txd[i].buf2addr = (unsigned char *)&txd[i+1]; /* Point to Next TX desc */
txd[i].buf1sz = 0;
txd[i].buf2sz = 0;
txd[i].control = 0x184; /* Begin/End/Chain */
txd[i].status = 0x00000000; /* give ownership to Host */
}
/* construct perfect filter frame with mac address as first match
and broadcast address for all others */
for (i=0; i<192; i++) txb[i] = 0xFF;
txb[0] = nic->node_addr[0];
txb[1] = nic->node_addr[1];
txb[4] = nic->node_addr[2];
txb[5] = nic->node_addr[3];
txb[8] = nic->node_addr[4];
txb[9] = nic->node_addr[5];
/* setup receive descriptor */
for (i=0; i<NRXD; i++) {
rxd[i].buf1addr = &rxb[i * BUFLEN];
rxd[i].buf2addr = (unsigned char *)&rxd[i+1]; /* Point to Next RX desc */
rxd[i].buf1sz = BUFLEN;
rxd[i].buf2sz = 0; /* not used */
rxd[i].control = 0x4; /* Chain Structure */
rxd[i].status = 0x80000000; /* give ownership to device */
}
/* Chain the last descriptor to first */
txd[NTXD - 1].buf2addr = (unsigned char *)&txd[0];
rxd[NRXD - 1].buf2addr = (unsigned char *)&rxd[0];
TxPtr = 0;
rxd_tail = 0;
}
/*********************************************************************/
/* davicom_reset - Reset adapter */
/*********************************************************************/
static void davicom_reset(struct nic *nic)
{
unsigned long to;
u32 addr_low, addr_high;
whereami("davicom_reset\n");
/* Stop Tx and RX */
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
outl(0x00000001, ioaddr + CSR0);
davicom_wait(TICKS_PER_SEC);
/* TX/RX descriptor burst */
outl(0x0C00000, ioaddr + CSR0); /* Sten 10/9 */
/* set up transmit and receive descriptors */
davicom_init_chain(nic); /* Sten 10/9 */
/* Point to receive descriptor */
outl((unsigned long)&rxd[0], ioaddr + CSR3);
outl((unsigned long)&txd[0], ioaddr + CSR4); /* Sten 10/9 */
/* According phyxcer media mode to set CR6,
DM9102/A phyxcer can auto-detect media mode */
davicom_media_chk(nic);
/* Prepare Setup Frame Sten 10/9 */
txd[TxPtr].buf1sz = 192;
txd[TxPtr].control = 0x024; /* SF/CE */
txd[TxPtr].status = 0x80000000; /* Give ownership to device */
/* Start Tx */
outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
/* immediate transmit demand */
outl(0, ioaddr + CSR1);
to = currticks() + TX_TIME_OUT;
while ((txd[TxPtr].status & 0x80000000) && (currticks() < to)) /* Sten 10/9 */
/* wait */ ;
if (currticks() >= to) {
printf ("TX Setup Timeout!\n");
}
/* Point to next TX descriptor */
TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */
#ifdef DAVICOM_DEBUG
printf("txd.status = %X\n", txd.status);
printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT));
davicom_more();
#endif
/* enable RX */
outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);
/* immediate poll demand */
outl(0, ioaddr + CSR2);
}
/*********************************************************************/
/* eth_transmit - Transmit a frame */
/*********************************************************************/
static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
unsigned int s, const char *p)
{
unsigned long to;
whereami("davicom_transmit\n");
/* Stop Tx */
/* outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6); */
/* setup ethernet header */
memcpy(&txb[0], d, ETH_ALEN); /* DA 6byte */
memcpy(&txb[ETH_ALEN], nic->node_addr, ETH_ALEN); /* SA 6byte*/
txb[ETH_ALEN*2] = (t >> 8) & 0xFF; /* Frame type: 2byte */
txb[ETH_ALEN*2+1] = t & 0xFF;
memcpy(&txb[ETH_HLEN], p, s); /* Frame data */
/* setup the transmit descriptor */
txd[TxPtr].buf1sz = ETH_HLEN+s;
txd[TxPtr].control = 0x00000184; /* LS+FS+CE */
txd[TxPtr].status = 0x80000000; /* give ownership to device */
/* immediate transmit demand */
outl(0, ioaddr + CSR1);
to = currticks() + TX_TIME_OUT;
while ((txd[TxPtr].status & 0x80000000) && (currticks() < to))
/* wait */ ;
if (currticks() >= to) {
printf ("TX Timeout!\n");
}
/* Point to next TX descriptor */
TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */
}
/*********************************************************************/
/* eth_poll - Wait for a frame */
/*********************************************************************/
static int davicom_poll(struct nic *nic)
{
whereami("davicom_poll\n");
if (rxd[rxd_tail].status & 0x80000000)
return 0;
whereami("davicom_poll got one\n");
nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
if( rxd[rxd_tail].status & 0x00008000){
rxd[rxd_tail].status = 0x80000000;
rxd_tail++;
if (rxd_tail == NRXD) rxd_tail = 0;
return 0;
}
/* copy packet to working buffer */
/* XXX - this copy could be avoided with a little more work
but for now we are content with it because the optimised
memcpy is quite fast */
memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
/* return the descriptor and buffer to receive ring */
rxd[rxd_tail].status = 0x80000000;
rxd_tail++;
if (rxd_tail == NRXD) rxd_tail = 0;
return 1;
}
/*********************************************************************/
/* eth_disable - Disable the interface */
/*********************************************************************/
static void davicom_disable(struct nic *nic)
{
whereami("davicom_disable\n");
/* disable interrupts */
outl(0x00000000, ioaddr + CSR7);
/* Stop the chip's Tx and Rx processes. */
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
/* Clear the missed-packet counter. */
(volatile unsigned long)inl(ioaddr + CSR8);
}
/*********************************************************************/
/* eth_probe - Look for an adapter */
/*********************************************************************/
struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
struct pci_device *pci)
{
unsigned int i;
u32 l1, l2;
whereami("davicom_probe\n");
if (io_addrs == 0 || *io_addrs == 0)
return 0;
vendor = pci->vendor;
dev_id = pci->dev_id;
ioaddr = *io_addrs;
/* wakeup chip */
pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
/* Stop the chip's Tx and Rx processes. */
outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
/* Clear the missed-packet counter. */
(volatile unsigned long)inl(ioaddr + CSR8);
/* Get MAC Address */
/* read EEPROM data */
for (i = 0; i < sizeof(ee_data)/2; i++)
((unsigned short *)ee_data)[i] =
le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN));
/* extract MAC address from EEPROM buffer */
for (i=0; i<ETH_ALEN; i++)
nic->node_addr[i] = ee_data[20+i];
printf("Davicom %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
/* initialize device */
davicom_reset(nic);
nic->reset = davicom_reset;
nic->poll = davicom_poll;
nic->transmit = davicom_transmit;
nic->disable = davicom_disable;
return nic;
}

View file

@ -1,752 +0,0 @@
/* Etherboot: depca.h merged, comments from Linux driver retained */
/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
Written 1994, 1995 by David C. Davies.
Copyright 1994 David C. Davies
and
United States Government
(as represented by the Director, National Security Agency).
Copyright 1995 Digital Equipment Corporation.
This software may be used and distributed according to the terms of
the GNU Public License, incorporated herein by reference.
This driver is written for the Digital Equipment Corporation series
of DEPCA and EtherWORKS ethernet cards:
DEPCA (the original)
DE100
DE101
DE200 Turbo
DE201 Turbo
DE202 Turbo (TP BNC)
DE210
DE422 (EISA)
The driver has been tested on DE100, DE200 and DE202 cards in a
relatively busy network. The DE422 has been tested a little.
This driver will NOT work for the DE203, DE204 and DE205 series of
cards, since they have a new custom ASIC in place of the AMD LANCE
chip. See the 'ewrk3.c' driver in the Linux source tree for running
those cards.
I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
a DECstation 5000/200.
The author may be reached at davies@maniac.ultranet.com
=========================================================================
The driver was originally based on the 'lance.c' driver from Donald
Becker which is included with the standard driver distribution for
linux. V0.4 is a complete re-write with only the kernel interface
remaining from the original code.
1) Lance.c code in /linux/drivers/net/
2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
AMD, 1992 [(800) 222-9323].
3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
AMD, Pub. #17881, May 1993.
4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
AMD, Pub. #16907, May 1992
5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
Digital Equipment Corporation, 1989
8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
driver.
The original DEPCA card requires that the ethernet ROM address counter
be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
only done when a 0x08 is read as the first address octet (to minimise
the chances of writing over some other hardware's I/O register). The
NICSR accesses have been changed to byte accesses for all the cards
supported by this driver, since there is only one useful bit in the MSB
(remote boot timeout) and it is not used. Also, there is a maximum of
only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
help debugging all this (and holding my feet to the fire until I got it
right).
The DE200 series boards have on-board 64kB RAM for use as a shared
memory network buffer. Only the DE100 cards make use of a 2kB buffer
mode which has not been implemented in this driver (only the 32kB and
64kB modes are supported [16kB/48kB for the original DEPCA]).
At the most only 2 DEPCA cards can be supported on the ISA bus because
there is only provision for two I/O base addresses on each card (0x300
and 0x200). The I/O address is detected by searching for a byte sequence
in the Ethernet station address PROM at the expected I/O address for the
Ethernet PROM. The shared memory base address is 'autoprobed' by
looking for the self test PROM and detecting the card name. When a
second DEPCA is detected, information is placed in the base_addr
variable of the next device structure (which is created if necessary),
thus enabling ethif_probe initialization for the device. More than 2
EISA cards can be supported, but care will be needed assigning the
shared memory to ensure that each slot has the correct IRQ, I/O address
and shared memory address assigned.
************************************************************************
NOTE: If you are using two ISA DEPCAs, it is important that you assign
the base memory addresses correctly. The driver autoprobes I/O 0x300
then 0x200. The base memory address for the first device must be less
than that of the second so that the auto probe will correctly assign the
I/O and memory addresses on the same card. I can't think of a way to do
this unambiguously at the moment, since there is nothing on the cards to
tie I/O and memory information together.
I am unable to test 2 cards together for now, so this code is
unchecked. All reports, good or bad, are welcome.
************************************************************************
The board IRQ setting must be at an unused IRQ which is auto-probed
using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
{2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
really IRQ9 in machines with 16 IRQ lines.
No 16MB memory limitation should exist with this driver as DMA is not
used and the common memory area is in low memory on the network card (my
current system has 20MB and I've not had problems yet).
The ability to load this driver as a loadable module has been added. To
utilise this ability, you have to do <8 things:
0) have a copy of the loadable modules code installed on your system.
1) copy depca.c from the /linux/drivers/net directory to your favourite
temporary directory.
2) if you wish, edit the source code near line 1530 to reflect the I/O
address and IRQ you're using (see also 5).
3) compile depca.c, but include -DMODULE in the command line to ensure
that the correct bits are compiled (see end of source code).
4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
kernel with the depca configuration turned off and reboot.
5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
[Alan Cox: Changed the code to allow command line irq/io assignments]
[Dave Davies: Changed the code to allow command line mem/name
assignments]
6) run the net startup bits for your eth?? interface manually
(usually /etc/rc.inet[12] at boot time).
7) enjoy!
Note that autoprobing is not allowed in loadable modules - the system is
already up and running and you're messing with interrupts.
To unload a module, turn off the associated interface
'ifconfig eth?? down' then 'rmmod depca'.
To assign a base memory address for the shared memory when running as a
loadable module, see 5 above. To include the adapter name (if you have
no PROM but know the card name) also see 5 above. Note that this last
option will not work with kernel built-in depca's.
The shared memory assignment for a loadable module makes sense to avoid
the 'memory autoprobe' picking the wrong shared memory (for the case of
2 depca's in a PC).
************************************************************************
Support for MCA EtherWORKS cards added 11-3-98.
Verified to work with up to 2 DE212 cards in a system (although not
fully stress-tested).
Currently known bugs/limitations:
Note: with the MCA stuff as a module, it trusts the MCA configuration,
not the command line for IRQ and memory address. You can
specify them if you want, but it will throw your values out.
You still have to pass the IO address it was configured as
though.
************************************************************************
TO DO:
------
Revision History
----------------
Version Date Description
0.1 25-jan-94 Initial writing.
0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
0.3 1-feb-94 Added multiple DEPCA support.
0.31 4-feb-94 Added DE202 recognition.
0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
Add jabber packet fix from murf@perftech.com
and becker@super.org
0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
0.35 8-mar-94 Added DE201 recognition. Tidied up.
0.351 30-apr-94 Added EISA support. Added DE422 recognition.
0.36 16-may-94 DE422 fix released.
0.37 22-jul-94 Added MODULE support
0.38 15-aug-94 Added DBR ROM switch in depca_close().
Multi DEPCA bug fix.
0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
<stromain@alf.dec.com>
0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
0.385 3-apr-95 Fix a recognition bug reported by
<ryan.niemi@lastfrontier.com>
0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
0.40 25-May-95 Rewrite for portability & updated.
ALPHA support from <jestabro@amt.tay1.dec.com>
0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
suggestion by <heiko@colossus.escape.de>
0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable
modules.
Add 'adapter_name' for loadable modules when no PROM.
Both above from a suggestion by
<pchen@woodruffs121.residence.gatech.edu>.
Add new multicasting code.
0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
0.44 1-Sep-97 Fix *_probe() to test check_region() first - bug
reported by <mmogilvi@elbert.uccs.edu>
0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards
by <tymm@computer.org>
0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. <tymm@computer.org>
0.5 14-Nov-98 Re-spin for 2.1.x kernels.
0.51 27-Jun-99 Correct received packet length for CRC from
report by <worm@dkik.dk>
=========================================================================
*/
#include "etherboot.h"
#include "nic.h"
#include "cards.h"
/*
** I/O addresses. Note that the 2k buffer option is not supported in
** this driver.
*/
#define DEPCA_NICSR ioaddr+0x00 /* Network interface CSR */
#define DEPCA_RBI ioaddr+0x02 /* RAM buffer index (2k buffer mode) */
#define DEPCA_DATA ioaddr+0x04 /* LANCE registers' data port */
#define DEPCA_ADDR ioaddr+0x06 /* LANCE registers' address port */
#define DEPCA_HBASE ioaddr+0x08 /* EISA high memory base address reg. */
#define DEPCA_PROM ioaddr+0x0c /* Ethernet address ROM data port */
#define DEPCA_CNFG ioaddr+0x0c /* EISA Configuration port */
#define DEPCA_RBSA ioaddr+0x0e /* RAM buffer starting address (2k buff.) */
/*
** These are LANCE registers addressable through DEPCA_ADDR
*/
#define CSR0 0
#define CSR1 1
#define CSR2 2
#define CSR3 3
/*
** NETWORK INTERFACE CSR (NI_CSR) bit definitions
*/
#define TO 0x0100 /* Time Out for remote boot */
#define SHE 0x0080 /* SHadow memory Enable */
#define BS 0x0040 /* Bank Select */
#define BUF 0x0020 /* BUFfer size (1->32k, 0->64k) */
#define RBE 0x0010 /* Remote Boot Enable (1->net boot) */
#define AAC 0x0008 /* Address ROM Address Counter (1->enable) */
#define _128KB 0x0008 /* 128kB Network RAM (1->enable) */
#define IM 0x0004 /* Interrupt Mask (1->mask) */
#define IEN 0x0002 /* Interrupt tristate ENable (1->enable) */
#define LED 0x0001 /* LED control */
/*
** Control and Status Register 0 (CSR0) bit definitions
*/
#define ERR 0x8000 /* Error summary */
#define BABL 0x4000 /* Babble transmitter timeout error */
#define CERR 0x2000 /* Collision Error */
#define MISS 0x1000 /* Missed packet */
#define MERR 0x0800 /* Memory Error */
#define RINT 0x0400 /* Receiver Interrupt */
#define TINT 0x0200 /* Transmit Interrupt */
#define IDON 0x0100 /* Initialization Done */
#define INTR 0x0080 /* Interrupt Flag */
#define INEA 0x0040 /* Interrupt Enable */
#define RXON 0x0020 /* Receiver on */
#define TXON 0x0010 /* Transmitter on */
#define TDMD 0x0008 /* Transmit Demand */
#define STOP 0x0004 /* Stop */
#define STRT 0x0002 /* Start */
#define INIT 0x0001 /* Initialize */
#define INTM 0xff00 /* Interrupt Mask */
#define INTE 0xfff0 /* Interrupt Enable */
/*
** CONTROL AND STATUS REGISTER 3 (CSR3)
*/
#define BSWP 0x0004 /* Byte SWaP */
#define ACON 0x0002 /* ALE control */
#define BCON 0x0001 /* Byte CONtrol */
/*
** Initialization Block Mode Register
*/
#define PROM 0x8000 /* Promiscuous Mode */
#define EMBA 0x0080 /* Enable Modified Back-off Algorithm */
#define INTL 0x0040 /* Internal Loopback */
#define DRTY 0x0020 /* Disable Retry */
#define COLL 0x0010 /* Force Collision */
#define DTCR 0x0008 /* Disable Transmit CRC */
#define LOOP 0x0004 /* Loopback */
#define DTX 0x0002 /* Disable the Transmitter */
#define DRX 0x0001 /* Disable the Receiver */
/*
** Receive Message Descriptor 1 (RMD1) bit definitions.
*/
#define R_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
#define R_ERR 0x4000 /* Error Summary */
#define R_FRAM 0x2000 /* Framing Error */
#define R_OFLO 0x1000 /* Overflow Error */
#define R_CRC 0x0800 /* CRC Error */
#define R_BUFF 0x0400 /* Buffer Error */
#define R_STP 0x0200 /* Start of Packet */
#define R_ENP 0x0100 /* End of Packet */
/*
** Transmit Message Descriptor 1 (TMD1) bit definitions.
*/
#define T_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
#define T_ERR 0x4000 /* Error Summary */
#define T_ADD_FCS 0x2000 /* More the 1 retry needed to Xmit */
#define T_MORE 0x1000 /* >1 retry to transmit packet */
#define T_ONE 0x0800 /* 1 try needed to transmit the packet */
#define T_DEF 0x0400 /* Deferred */
#define T_STP 0x02000000 /* Start of Packet */
#define T_ENP 0x01000000 /* End of Packet */
#define T_FLAGS 0xff000000 /* TX Flags Field */
/*
** Transmit Message Descriptor 3 (TMD3) bit definitions.
*/
#define TMD3_BUFF 0x8000 /* BUFFer error */
#define TMD3_UFLO 0x4000 /* UnderFLOw error */
#define TMD3_RES 0x2000 /* REServed */
#define TMD3_LCOL 0x1000 /* Late COLlision */
#define TMD3_LCAR 0x0800 /* Loss of CARrier */
#define TMD3_RTRY 0x0400 /* ReTRY error */
/*
** Ethernet PROM defines
*/
#define PROBE_LENGTH 32
/*
** Set the number of Tx and Rx buffers. Ensure that the memory requested
** here is <= to the amount of shared memory set up by the board switches.
** The number of descriptors MUST BE A POWER OF 2.
**
** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
*/
#define NUM_RX_DESC 2 /* Number of RX descriptors */
#define NUM_TX_DESC 2 /* Number of TX descriptors */
#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
/*
** ISA Bus defines
*/
#define DEPCA_IO_PORTS {0x300, 0x200, 0}
#ifndef DEPCA_MODEL
#define DEPCA_MODEL DEPCA
#endif
static enum {
DEPCA, DE100, DE101, DE200, DE201, DE202, DE210, DE212, DE422, unknown
} adapter = DEPCA_MODEL;
/*
** Name <-> Adapter mapping
*/
static char *adapter_name[] = {
"DEPCA",
"DE100","DE101",
"DE200","DE201","DE202",
"DE210","DE212",
"DE422",
""
};
#ifndef DEPCA_RAM_BASE
#define DEPCA_RAM_BASE 0xd0000
#endif
/*
** Memory Alignment. Each descriptor is 4 longwords long. To force a
** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
** DESC_ALIGN. ALIGN aligns the start address of the private memory area
** and hence the RX descriptor ring's first entry.
*/
#define ALIGN4 ((u32)4 - 1) /* 1 longword align */
#define ALIGN8 ((u32)8 - 1) /* 2 longword (quadword) align */
#define ALIGN ALIGN8 /* Keep the LANCE happy... */
typedef long s32;
typedef unsigned long u32;
typedef short s16;
typedef unsigned short u16;
typedef char s8;
typedef unsigned char u8;
/*
** The DEPCA Rx and Tx ring descriptors.
*/
struct depca_rx_desc {
volatile s32 base;
s16 buf_length; /* This length is negative 2's complement! */
s16 msg_length; /* This length is "normal". */
};
struct depca_tx_desc {
volatile s32 base;
s16 length; /* This length is negative 2's complement! */
s16 misc; /* Errors and TDR info */
};
#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
to LANCE memory address space */
/*
** The Lance initialization block, described in databook, in common memory.
*/
struct depca_init {
u16 mode; /* Mode register */
u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
u8 mcast_table[8]; /* Multicast Hash Table. */
u32 rx_ring; /* Rx ring base pointer & ring length */
u32 tx_ring; /* Tx ring base pointer & ring length */
};
struct depca_private {
struct depca_rx_desc *rx_ring;
struct depca_tx_desc *tx_ring;
struct depca_init init_block; /* Shadow init block */
char *rx_memcpy[NUM_RX_DESC];
char *tx_memcpy[NUM_TX_DESC];
u32 bus_offset; /* ISA bus address offset */
u32 sh_mem; /* address of shared mem */
u32 dma_buffs; /* Rx & Tx buffer start */
int rx_cur, tx_cur; /* Next free ring entry */
int txRingMask, rxRingMask;
s32 rx_rlen, tx_rlen;
/* log2([rt]xRingMask+1) for the descriptors */
};
static Address mem_start = DEPCA_RAM_BASE;
static Address mem_len, offset;
static unsigned short ioaddr = 0;
static struct depca_private lp;
/*
** Miscellaneous defines...
*/
#define STOP_DEPCA \
outw(CSR0, DEPCA_ADDR);\
outw(STOP, DEPCA_DATA)
/* Initialize the lance Rx and Tx descriptor rings. */
static void depca_init_ring(struct nic *nic)
{
int i;
u32 p;
lp.rx_cur = lp.tx_cur = 0;
/* Initialize the base addresses and length of each buffer in the ring */
for (i = 0; i <= lp.rxRingMask; i++) {
writel((p = lp.dma_buffs + i * RX_BUFF_SZ) | R_OWN, &lp.rx_ring[i].base);
writew(-RX_BUFF_SZ, &lp.rx_ring[i].buf_length);
lp.rx_memcpy[i] = (char *) (p + lp.bus_offset);
}
for (i = 0; i <= lp.txRingMask; i++) {
writel((p = lp.dma_buffs + (i + lp.txRingMask + 1) * TX_BUFF_SZ) & 0x00ffffff, &lp.tx_ring[i].base);
lp.tx_memcpy[i] = (char *) (p + lp.bus_offset);
}
/* Set up the initialization block */
lp.init_block.rx_ring = ((u32) ((u32) lp.rx_ring) & LA_MASK) | lp.rx_rlen;
lp.init_block.tx_ring = ((u32) ((u32) lp.tx_ring) & LA_MASK) | lp.tx_rlen;
for (i = 0; i < ETH_ALEN; i++)
lp.init_block.phys_addr[i] = nic->node_addr[i];
lp.init_block.mode = 0x0000; /* Enable the Tx and Rx */
memset(lp.init_block.mcast_table, 0, sizeof(lp.init_block.mcast_table));
}
static void LoadCSRs(void)
{
outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
outw((u16) (lp.sh_mem & LA_MASK), DEPCA_DATA);
outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
outw((u16) ((lp.sh_mem & LA_MASK) >> 16), DEPCA_DATA);
outw(CSR3, DEPCA_ADDR); /* ALE control */
outw(ACON, DEPCA_DATA);
outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
}
static int InitRestartDepca(void)
{
int i;
/* Copy the shadow init_block to shared memory */
memcpy_toio((char *)lp.sh_mem, &lp.init_block, sizeof(struct depca_init));
outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
outw(INIT, DEPCA_DATA); /* initialise DEPCA */
for (i = 0; i < 100 && !(inw(DEPCA_DATA) & IDON); i++)
;
if (i < 100) {
/* clear IDON by writing a 1, and start LANCE */
outw(IDON | STRT, DEPCA_DATA);
} else {
printf("DEPCA not initialised\n");
return (1);
}
return (0);
}
/**************************************************************************
RESET - Reset adapter
***************************************************************************/
static void depca_reset(struct nic *nic)
{
s16 nicsr;
int i, j;
STOP_DEPCA;
nicsr = inb(DEPCA_NICSR);
nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
outb(nicsr, DEPCA_NICSR);
if (inw(DEPCA_DATA) != STOP)
{
printf("depca: Cannot stop NIC\n");
return;
}
/* Initialisation block */
lp.sh_mem = mem_start;
mem_start += sizeof(struct depca_init);
/* Tx & Rx descriptors (aligned to a quadword boundary) */
mem_start = (mem_start + ALIGN) & ~ALIGN;
lp.rx_ring = (struct depca_rx_desc *) mem_start;
mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
lp.tx_ring = (struct depca_tx_desc *) mem_start;
mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
lp.bus_offset = mem_start & 0x00ff0000;
/* LANCE re-mapped start address */
lp.dma_buffs = mem_start & LA_MASK;
/* Finish initialising the ring information. */
lp.rxRingMask = NUM_RX_DESC - 1;
lp.txRingMask = NUM_TX_DESC - 1;
/* Calculate Tx/Rx RLEN size for the descriptors. */
for (i = 0, j = lp.rxRingMask; j > 0; i++) {
j >>= 1;
}
lp.rx_rlen = (s32) (i << 29);
for (i = 0, j = lp.txRingMask; j > 0; i++) {
j >>= 1;
}
lp.tx_rlen = (s32) (i << 29);
/* Load the initialisation block */
depca_init_ring(nic);
LoadCSRs();
InitRestartDepca();
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int depca_poll(struct nic *nic)
{
int entry;
u32 status;
entry = lp.rx_cur;
if ((status = readl(&lp.rx_ring[entry].base) & R_OWN))
return (0);
memcpy(nic->packet, lp.rx_memcpy[entry], nic->packetlen = lp.rx_ring[entry].msg_length);
lp.rx_ring[entry].base |= R_OWN;
lp.rx_cur = (++lp.rx_cur) & lp.rxRingMask;
return (1);
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
static void depca_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
int entry, len;
char *mem;
/* send the packet to destination */
/*
** Caution: the right order is important here... dont
** setup the ownership rights until all the other
** information is in place
*/
mem = lp.tx_memcpy[entry = lp.tx_cur];
memcpy_toio(mem, d, ETH_ALEN);
memcpy_toio(mem + ETH_ALEN, nic->node_addr, ETH_ALEN);
mem[ETH_ALEN * 2] = t >> 8;
mem[ETH_ALEN * 2 + 1] = t;
memcpy_toio(mem + ETH_HLEN, p, s);
s += ETH_HLEN;
len = (s < ETH_ZLEN ? ETH_ZLEN : s);
/* clean out flags */
writel(readl(&lp.tx_ring[entry].base) & ~T_FLAGS, &lp.tx_ring[entry].base);
/* clears other error flags */
writew(0x0000, &lp.tx_ring[entry].misc);
/* packet length in buffer */
writew(-len, &lp.tx_ring[entry].length);
/* start and end of packet, ownership */
writel(readl(&lp.tx_ring[entry].base) | (T_STP|T_ENP|T_OWN), &lp.tx_ring[entry].base);
/* update current pointers */
lp.tx_cur = (++lp.tx_cur) & lp.txRingMask;
}
/**************************************************************************
DISABLE - Turn off ethernet interface
***************************************************************************/
static void depca_disable(struct nic *nic)
{
STOP_DEPCA;
}
/*
** Look for a special sequence in the Ethernet station address PROM that
** is common across all DEPCA products. Note that the original DEPCA needs
** its ROM address counter to be initialized and enabled. Only enable
** if the first address octet is a 0x08 - this minimises the chances of
** messing around with some other hardware, but it assumes that this DEPCA
** card initialized itself correctly.
**
** Search the Ethernet address ROM for the signature. Since the ROM address
** counter can start at an arbitrary point, the search must include the entire
** probe sequence length plus the (length_of_the_signature - 1).
** Stop the search IMMEDIATELY after the signature is found so that the
** PROM address counter is correctly positioned at the start of the
** ethernet address for later read out.
*/
static int depca_probe1(struct nic *nic)
{
u8 data, nicsr;
/* This is only correct for little endian machines, but then
Etherboot doesn't work on anything but a PC */
u8 sig[] = { 0xFF, 0x00, 0x55, 0xAA, 0xFF, 0x00, 0x55, 0xAA };
int i, j;
long sum, chksum;
data = inb(DEPCA_PROM); /* clear counter on DEPCA */
data = inb(DEPCA_PROM); /* read data */
if (data == 0x8) {
nicsr = inb(DEPCA_NICSR);
nicsr |= AAC;
outb(nicsr, DEPCA_NICSR);
}
for (i = 0, j = 0; j < (int)sizeof(sig) && i < PROBE_LENGTH+((int)sizeof(sig))-1; ++i) {
data = inb(DEPCA_PROM);
if (data == sig[j]) /* track signature */
++j;
else
j = (data == sig[0]) ? 1 : 0;
}
if (j != sizeof(sig))
return (0);
/* put the card in its initial state */
STOP_DEPCA;
nicsr = ((inb(DEPCA_NICSR) & ~SHE & ~RBE & ~IEN) | IM);
outb(nicsr, DEPCA_NICSR);
if (inw(DEPCA_DATA) != STOP)
return (0);
memcpy((char *)mem_start, sig, sizeof(sig));
if (memcmp((char *)mem_start, sig, sizeof(sig)) != 0)
return (0);
for (i = 0, j = 0, sum = 0; j < 3; j++) {
sum <<= 1;
if (sum > 0xFFFF)
sum -= 0xFFFF;
sum += (u8)(nic->node_addr[i++] = inb(DEPCA_PROM));
sum += (u16)((nic->node_addr[i++] = inb(DEPCA_PROM)) << 8);
if (sum > 0xFFFF)
sum -= 0xFFFF;
}
if (sum == 0xFFFF)
sum = 0;
chksum = (u8)inb(DEPCA_PROM);
chksum |= (u16)(inb(DEPCA_PROM) << 8);
mem_len = (adapter == DEPCA) ? (48 << 10) : (64 << 10);
offset = 0;
if (nicsr & BUF) {
offset = 0x8000;
nicsr &= ~BS;
mem_len -= (32 << 10);
}
if (adapter != DEPCA) /* enable shadow RAM */
outb(nicsr |= SHE, DEPCA_NICSR);
printf("%s base %#hX, memory [%#hX-%#hX], addr %!",
adapter_name[adapter], ioaddr, mem_start, mem_start + mem_len,
nic->node_addr);
if (sum != chksum)
printf(" (bad checksum)");
putchar('\n');
return (1);
}
/**************************************************************************
PROBE - Look for an adapter, this routine's visible to the outside
***************************************************************************/
struct nic *depca_probe(struct nic *nic, unsigned short *probe_addrs)
{
static unsigned short base[] = DEPCA_IO_PORTS;
int i;
if (probe_addrs == 0 || probe_addrs[0] == 0)
probe_addrs = base; /* Use defaults */
for (i = 0; (ioaddr = base[i]) != 0; ++i) {
if (depca_probe1(nic))
break;
}
if (ioaddr == 0)
return (0);
depca_reset(nic);
/* point to NIC specific routines */
nic->reset = depca_reset;
nic->poll = depca_poll;
nic->transmit = depca_transmit;
nic->disable = depca_disable;
return (nic);
}

View file

@ -1,586 +0,0 @@
/**************************************************************************
Etherboot - BOOTP/TFTP Bootstrap Program
Intel EEPRO/10 NIC driver for Etherboot
Adapted from Linux eepro.c from kernel 2.2.17
This board accepts a 32 pin EEPROM (29C256), however a test with a
27C010 shows that this EPROM also works in the socket, but it's not clear
how repeatably. The two top address pins appear to be held low, thus
the bottom 32kB of the 27C010 is visible in the CPU's address space.
To be sure you could put 4 copies of the code in the 27C010, then
it doesn't matter whether the extra lines are held low or high, just
hopefully not floating as CMOS chips don't like floating inputs.
Be careful with seating the EPROM as the socket on my board actually
has 34 pins, the top row of 2 are not used.
***************************************************************************/
/*
* 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.
*/
/* to get some global routines like printf */
#include "etherboot.h"
/* to get the interface to the body of the program */
#include "nic.h"
/* to get our own prototype */
#include "cards.h"
/* we use timer2 for microsecond waits */
#include "timer.h"
#undef DEBUG /* only after include files */
/* Different 82595 chips */
#define LAN595 0
#define LAN595TX 1
#define LAN595FX 2
#define LAN595FX_10ISA 3
#define SLOW_DOWN inb(0x80);
/* The station (ethernet) address prefix, used for IDing the board. */
#define SA_ADDR0 0x00 /* Etherexpress Pro/10 */
#define SA_ADDR1 0xaa
#define SA_ADDR2 0x00
#define GetBit(x,y) ((x & (1<<y))>>y)
/* EEPROM Word 0: */
#define ee_PnP 0 /* Plug 'n Play enable bit */
#define ee_Word1 1 /* Word 1? */
#define ee_BusWidth 2 /* 8/16 bit */
#define ee_FlashAddr 3 /* Flash Address */
#define ee_FlashMask 0x7 /* Mask */
#define ee_AutoIO 6 /* */
#define ee_reserved0 7 /* =0! */
#define ee_Flash 8 /* Flash there? */
#define ee_AutoNeg 9 /* Auto Negotiation enabled? */
#define ee_IO0 10 /* IO Address LSB */
#define ee_IO0Mask 0x /*...*/
#define ee_IO1 15 /* IO MSB */
/* EEPROM Word 1: */
#define ee_IntSel 0 /* Interrupt */
#define ee_IntMask 0x7
#define ee_LI 3 /* Link Integrity 0= enabled */
#define ee_PC 4 /* Polarity Correction 0= enabled */
#define ee_TPE_AUI 5 /* PortSelection 1=TPE */
#define ee_Jabber 6 /* Jabber prevention 0= enabled */
#define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */
#define ee_SMOUT 8 /* SMout Pin Control 0= Input */
#define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */
#define ee_reserved1 10 /* .. 12 =0! */
#define ee_AltReady 13 /* Alternate Ready, 0=normal */
#define ee_reserved2 14 /* =0! */
#define ee_Duplex 15
/* Word2,3,4: */
#define ee_IA5 0 /*bit start for individual Addr Byte 5 */
#define ee_IA4 8 /*bit start for individual Addr Byte 5 */
#define ee_IA3 0 /*bit start for individual Addr Byte 5 */
#define ee_IA2 8 /*bit start for individual Addr Byte 5 */
#define ee_IA1 0 /*bit start for individual Addr Byte 5 */
#define ee_IA0 8 /*bit start for individual Addr Byte 5 */
/* Word 5: */
#define ee_BNC_TPE 0 /* 0=TPE */
#define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
#define ee_BootTypeMask 0x3
#define ee_NumConn 3 /* Number of Connections 0= One or Two */
#define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */
#define ee_PortTPE 5
#define ee_PortBNC 6
#define ee_PortAUI 7
#define ee_PowerMgt 10 /* 0= disabled */
#define ee_CP 13 /* Concurrent Processing */
#define ee_CPMask 0x7
/* Word 6: */
#define ee_Stepping 0 /* Stepping info */
#define ee_StepMask 0x0F
#define ee_BoardID 4 /* Manucaturer Board ID, reserved */
#define ee_BoardMask 0x0FFF
/* Word 7: */
#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */
#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
/*..*/
#define ee_SIZE 0x40 /* total EEprom Size */
#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
/* Card identification via EEprom: */
#define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */
#define ee_addr_id 0x11 /* Word offset for Card ID */
#define ee_addr_SN 0x12 /* Serial Number */
#define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */
#define ee_vendor_intel0 0x25 /* Vendor ID Intel */
#define ee_vendor_intel1 0xD4
#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
#define ee_id_eepro10p1 0x31
/* now this section could be used by both boards: the oldies and the ee10:
* ee10 uses tx buffer before of rx buffer and the oldies the inverse.
* (aris)
*/
#define RAM_SIZE 0x8000
#define RCV_HEADER 8
#define RCV_DEFAULT_RAM 0x6000
#define RCV_RAM rcv_ram
static unsigned rcv_ram = RCV_DEFAULT_RAM;
#define XMT_HEADER 8
#define XMT_RAM (RAM_SIZE - RCV_RAM)
#define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE)
#define RCV_LOWER_LIMIT (rcv_start >> 8)
#define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8)
#define XMT_LOWER_LIMIT (XMT_START >> 8)
#define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8)
#define RCV_START_PRO 0x00
#define RCV_START_10 XMT_RAM
/* by default the old driver */
static unsigned rcv_start = RCV_START_PRO;
#define RCV_DONE 0x0008
#define RX_OK 0x2000
#define RX_ERROR 0x0d81
#define TX_DONE_BIT 0x0080
#define CHAIN_BIT 0x8000
#define XMT_STATUS 0x02
#define XMT_CHAIN 0x04
#define XMT_COUNT 0x06
#define BANK0_SELECT 0x00
#define BANK1_SELECT 0x40
#define BANK2_SELECT 0x80
/* Bank 0 registers */
#define COMMAND_REG 0x00 /* Register 0 */
#define MC_SETUP 0x03
#define XMT_CMD 0x04
#define DIAGNOSE_CMD 0x07
#define RCV_ENABLE_CMD 0x08
#define RCV_DISABLE_CMD 0x0a
#define STOP_RCV_CMD 0x0b
#define RESET_CMD 0x0e
#define POWER_DOWN_CMD 0x18
#define RESUME_XMT_CMD 0x1c
#define SEL_RESET_CMD 0x1e
#define STATUS_REG 0x01 /* Register 1 */
#define RX_INT 0x02
#define TX_INT 0x04
#define EXEC_STATUS 0x30
#define ID_REG 0x02 /* Register 2 */
#define R_ROBIN_BITS 0xc0 /* round robin counter */
#define ID_REG_MASK 0x2c
#define ID_REG_SIG 0x24
#define AUTO_ENABLE 0x10
#define INT_MASK_REG 0x03 /* Register 3 */
#define RX_STOP_MASK 0x01
#define RX_MASK 0x02
#define TX_MASK 0x04
#define EXEC_MASK 0x08
#define ALL_MASK 0x0f
#define IO_32_BIT 0x10
#define RCV_BAR 0x04 /* The following are word (16-bit) registers */
#define RCV_STOP 0x06
#define XMT_BAR_PRO 0x0a
#define XMT_BAR_10 0x0b
static unsigned xmt_bar = XMT_BAR_PRO;
#define HOST_ADDRESS_REG 0x0c
#define IO_PORT 0x0e
#define IO_PORT_32_BIT 0x0c
/* Bank 1 registers */
#define REG1 0x01
#define WORD_WIDTH 0x02
#define INT_ENABLE 0x80
#define INT_NO_REG 0x02
#define RCV_LOWER_LIMIT_REG 0x08
#define RCV_UPPER_LIMIT_REG 0x09
#define XMT_LOWER_LIMIT_REG_PRO 0x0a
#define XMT_UPPER_LIMIT_REG_PRO 0x0b
#define XMT_LOWER_LIMIT_REG_10 0x0b
#define XMT_UPPER_LIMIT_REG_10 0x0a
static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
/* Bank 2 registers */
#define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */
#define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */
#define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */
#define REG2 0x02
#define PRMSC_Mode 0x01
#define Multi_IA 0x20
#define REG3 0x03
#define TPE_BIT 0x04
#define BNC_BIT 0x20
#define REG13 0x0d
#define FDX 0x00
#define A_N_ENABLE 0x02
#define I_ADD_REG0 0x04
#define I_ADD_REG1 0x05
#define I_ADD_REG2 0x06
#define I_ADD_REG3 0x07
#define I_ADD_REG4 0x08
#define I_ADD_REG5 0x09
#define EEPROM_REG_PRO 0x0a
#define EEPROM_REG_10 0x0b
static unsigned eeprom_reg = EEPROM_REG_PRO;
#define EESK 0x01
#define EECS 0x02
#define EEDI 0x04
#define EEDO 0x08
/* The horrible routine to read a word from the serial EEPROM. */
/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
/* The delay between EEPROM clock transitions. */
#define eeprom_delay() { udelay(40); }
#define EE_READ_CMD (6 << 6)
/* do a full reset */
#define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(40);
/* do a nice reset */
#define eepro_sel_reset(ioaddr) { \
outb(SEL_RESET_CMD, ioaddr); \
SLOW_DOWN; \
SLOW_DOWN; \
}
/* clear all interrupts */
#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
/* enable rx */
#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)
/* disable rx */
#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)
/* switch bank */
#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
static unsigned int rx_start, tx_start;
static int tx_last;
static unsigned tx_end;
static int eepro = 0;
static unsigned short ioaddr = 0;
static unsigned int mem_start, mem_end = RCV_DEFAULT_RAM / 1024;
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
/**************************************************************************
RESET - Reset adapter
***************************************************************************/
static void eepro_reset(struct nic *nic)
{
int temp_reg, i;
/* put the card in its initial state */
eepro_sw2bank2(ioaddr); /* be careful, bank2 now */
temp_reg = inb(ioaddr + eeprom_reg);
#ifdef DEBUG
printf("Stepping %d\n", temp_reg >> 5);
#endif
if (temp_reg & 0x10) /* check the TurnOff Enable bit */
outb(temp_reg & 0xEF, ioaddr + eeprom_reg);
for (i = 0; i < ETH_ALEN; i++) /* fill the MAC address */
outb(nic->node_addr[i], ioaddr + I_ADD_REG0 + i);
temp_reg = inb(ioaddr + REG1);
/* setup Transmit Chaining and discard bad RCV frames */
outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
| RCV_Discard_BadFrame, ioaddr + REG1);
temp_reg = inb(ioaddr + REG2); /* match broadcast */
outb(temp_reg | 0x14, ioaddr + REG2);
temp_reg = inb(ioaddr + REG3);
outb(temp_reg & 0x3F, ioaddr + REG3); /* clear test mode */
/* set the receiving mode */
eepro_sw2bank1(ioaddr); /* be careful, bank1 now */
/* initialise the RCV and XMT upper and lower limits */
outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg);
outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg);
eepro_sw2bank0(ioaddr); /* Switch back to bank 0 */
eepro_clear_int(ioaddr);
/* Initialise RCV */
outw(rx_start = (RCV_LOWER_LIMIT << 8), ioaddr + RCV_BAR);
outw(((RCV_UPPER_LIMIT << 8) | 0xFE), ioaddr + RCV_STOP);
/* Intialise XMT */
outw((XMT_LOWER_LIMIT << 8), ioaddr + xmt_bar);
eepro_sel_reset(ioaddr);
tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
tx_last = 0;
eepro_en_rx(ioaddr);
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int eepro_poll(struct nic *nic)
{
int i;
unsigned int rcv_car = rx_start;
unsigned int rcv_event, rcv_status, rcv_next_frame, rcv_size;
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
/* nic->packetlen should contain length of data */
#if 0
if ((inb(ioaddr + STATUS_REG) & 0x40) == 0)
return (0);
outb(0x40, ioaddr + STATUS_REG);
#endif
outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
rcv_event = inw(ioaddr + IO_PORT);
if (rcv_event != RCV_DONE)
return (0);
rcv_status = inw(ioaddr + IO_PORT);
rcv_next_frame = inw(ioaddr + IO_PORT);
rcv_size = inw(ioaddr + IO_PORT);
#if 0
printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
inb(ioaddr + STATUS_REG));
#endif
if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) {
printf("Receive error %hX\n", rcv_status);
return (0);
}
rcv_size &= 0x3FFF;
insw(ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1));
#if 0
for (i = 0; i < 48; i++) {
printf("%hhX", nic->packet[i]);
putchar(i % 16 == 15 ? '\n' : ' ');
}
#endif
nic->packetlen = rcv_size;
rcv_car = rx_start + RCV_HEADER + rcv_size;
rx_start = rcv_next_frame;
if (rcv_car == 0)
rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
outw(rcv_car - 1, ioaddr + RCV_STOP);
return (1);
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
static void eepro_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
unsigned int status, tx_available, last, end, length;
unsigned short type;
int boguscount = 20;
length = s + ETH_HLEN;
if (tx_end > tx_start)
tx_available = XMT_RAM - (tx_end - tx_start);
else if (tx_end < tx_start)
tx_available = tx_start - tx_end;
else
tx_available = XMT_RAM;
last = tx_end;
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
if (end >= (XMT_UPPER_LIMIT << 8)) {
last = (XMT_LOWER_LIMIT << 8);
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
}
outw(last, ioaddr + HOST_ADDRESS_REG);
outw(XMT_CMD, ioaddr + IO_PORT);
outw(0, ioaddr + IO_PORT);
outw(end, ioaddr + IO_PORT);
outw(length, ioaddr + IO_PORT);
outsw(ioaddr + IO_PORT, d, ETH_ALEN / 2);
outsw(ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
type = htons(t);
outsw(ioaddr + IO_PORT, &type, sizeof(type) / 2);
outsw(ioaddr + IO_PORT, p, (s + 3) >> 1);
/* A dummy read to flush the DRAM write pipeline */
status = inw(ioaddr + IO_PORT);
outw(last, ioaddr + xmt_bar);
outb(XMT_CMD, ioaddr);
tx_start = last;
tx_last = last;
tx_end = end;
#if 0
printf("%d %d\n", tx_start, tx_end);
#endif
while (boguscount > 0) {
if (((status = inw(ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
udelay(40);
boguscount--;
continue;
}
#if DEBUG
if ((status & 0x2000) == 0)
printf("Transmit status %hX\n", status);
#endif
}
}
/**************************************************************************
DISABLE - Turn off ethernet interface
***************************************************************************/
static void eepro_disable(struct nic *nic)
{
eepro_sw2bank0(ioaddr); /* Switch to bank 0 */
/* Flush the Tx and disable Rx */
outb(STOP_RCV_CMD, ioaddr);
tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
tx_last = 0;
/* Reset the 82595 */
eepro_full_reset(ioaddr);
}
static int read_eeprom(int location)
{
int i;
unsigned short retval = 0;
int ee_addr = ioaddr + eeprom_reg;
int read_cmd = location | EE_READ_CMD;
int ctrl_val = EECS;
if (eepro == LAN595FX_10ISA) {
eepro_sw2bank1(ioaddr);
outb(0x00, ioaddr + STATUS_REG);
}
eepro_sw2bank2(ioaddr);
outb(ctrl_val, ee_addr);
/* shift the read command bits out */
for (i = 8; i >= 0; i--) {
short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
outb(outval, ee_addr);
outb(outval | EESK, ee_addr); /* EEPROM clock tick */
eeprom_delay();
outb(outval, ee_addr); /* finish EEPROM clock tick */
eeprom_delay();
}
outb(ctrl_val, ee_addr);
for (i = 16; i > 0; i--) {
outb(ctrl_val | EESK, ee_addr);
eeprom_delay();
retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
outb(ctrl_val, ee_addr);
eeprom_delay();
}
/* terminate the EEPROM access */
ctrl_val &= ~EECS;
outb(ctrl_val | EESK, ee_addr);
eeprom_delay();
outb(ctrl_val, ee_addr);
eeprom_delay();
eepro_sw2bank0(ioaddr);
return (retval);
}
static int eepro_probe1(struct nic *nic)
{
int i, id, counter, l_eepro = 0;
union {
unsigned char caddr[ETH_ALEN];
unsigned short saddr[ETH_ALEN/2];
} station_addr;
char *name;
id = inb(ioaddr + ID_REG);
if ((id & ID_REG_MASK) != ID_REG_SIG)
return (0);
counter = id & R_ROBIN_BITS;
if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40))
return (0);
/* yes the 82595 has been found */
station_addr.saddr[2] = read_eeprom(2);
if (station_addr.saddr[2] == 0x0000 || station_addr.saddr[2] == 0xFFFF) {
l_eepro = 3;
eepro = LAN595FX_10ISA;
eeprom_reg= EEPROM_REG_10;
rcv_start = RCV_START_10;
xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
station_addr.saddr[2] = read_eeprom(2);
}
station_addr.saddr[1] = read_eeprom(3);
station_addr.saddr[0] = read_eeprom(4);
if (l_eepro)
name = "Intel EtherExpress 10 ISA";
else if (read_eeprom(7) == ee_FX_INT2IRQ) {
name = "Intel EtherExpress Pro/10+ ISA";
l_eepro = 2;
} else if (station_addr.saddr[0] == SA_ADDR1) {
name = "Intel EtherExpress Pro/10 ISA";
l_eepro = 1;
} else {
l_eepro = 0;
name = "Intel 82595-based LAN card";
}
station_addr.saddr[0] = swap16(station_addr.saddr[0]);
station_addr.saddr[1] = swap16(station_addr.saddr[1]);
station_addr.saddr[2] = swap16(station_addr.saddr[2]);
for (i = 0; i < ETH_ALEN; i++) {
nic->node_addr[i] = station_addr.caddr[i];
}
printf("\n%s ioaddr %#hX, addr %!", name, ioaddr, nic->node_addr);
mem_start = RCV_LOWER_LIMIT << 8;
if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)
mem_end = RCV_UPPER_LIMIT << 8;
else {
mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8);
rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8);
}
printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10,
GetBit(read_eeprom(5), ee_BNC_TPE) ? "BNC" : "TP");
return (1);
}
/**************************************************************************
PROBE - Look for an adapter, this routine's visible to the outside
***************************************************************************/
struct nic *eepro_probe(struct nic *nic, unsigned short *probe_addrs)
{
unsigned short *p;
/* same probe list as the Linux driver */
static unsigned short ioaddrs[] = {
0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
if (probe_addrs == 0 || probe_addrs[0] == 0)
probe_addrs = ioaddrs;
for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
if (eepro_probe1(nic))
break;
}
if (*p == 0)
return (0);
eepro_reset(nic);
/* point to NIC specific routines */
nic->reset = eepro_reset;
nic->poll = eepro_poll;
nic->transmit = eepro_transmit;
nic->disable = eepro_disable;
return (nic);
}

View file

@ -1,654 +0,0 @@
/*
* 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 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 the pci.c functions of the Etherboot code, the 82557 chip is detected.
* It is verified that the BIOS initialized everything properly and if
* something is missing it is done now.
*
*
* 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.
*/
/* 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. */
/* Sorry not us. It's inherted code from FreeBSD. [The authors] */
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
#include "timer.h"
#undef virt_to_bus
#define virt_to_bus(x) ((unsigned long)x)
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 do_eeprom_cmd(int cmd, int cmd_len);
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_DATA_READ 0x08 /* EEPROM chip data out. */
#define EE_WRITE_0 0x4802
#define EE_WRITE_1 0x4806
#define EE_ENB (0x4800 | EE_CS)
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
/* The EEPROM commands include the alway-set leading bit. */
#define EE_READ_CMD 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. */
static 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... */
static 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;
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];
};
#ifdef USE_LOWMEM_BUFFER
#define rxfd ((struct RxFD *)(0x10000 - sizeof(struct RxFD)))
#define ACCESS(x) x->
#else
static struct RxFD rxfd;
#define ACCESS(x) x.
#endif
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 */
static 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, }
};
/***********************************************************************/
/* Locally used functions */
/***********************************************************************/
/* Support function: mdio_write
*
* This probably writes to the "physical media interface chip".
* -- REW
*/
static int mdio_write(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 = %X.\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 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 = %X.\n", val);
}
} while (! (val & 0x10000000));
return val & 0xffff;
}
/* The fixes for the code were kindly provided by Dragan Stancevic
<visitor@valinux.com> to strictly follow Intel specifications of EEPROM
access timing.
The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
interval for serial EEPROM. However, it looks like that there is an
additional requirement dictating larger udelay's in the code below.
2000/05/24 SAW */
static int do_eeprom_cmd(int cmd, int cmd_len)
{
unsigned retval = 0;
long ee_addr = ioaddr + SCBeeprom;
outw(EE_ENB, ee_addr); udelay(2);
outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
/* Shift the command bits out. */
do {
short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
outw(dataval, ee_addr); udelay(2);
outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
} while (--cmd_len >= 0);
outw(EE_ENB, ee_addr); udelay(2);
/* Terminate the EEPROM access. */
outw(EE_ENB & ~EE_CS, ee_addr);
return retval;
}
static inline void whereami (const char *str)
{
#if 0
printf ("%s\n", str);
sleep (2);
#endif
}
/* function: eepro100_reset
* resets the card. This is used to allow Etherboot 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
* 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, const char *d, unsigned int t, unsigned int s, const char *p)
{
struct eth_hdr {
unsigned char dst_addr[ETH_ALEN];
unsigned char src_addr[ETH_ALEN];
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 %hX packet (%d bytes). status = %hX, cmd=%hX\n",
t, s, status, inw (ioaddr + SCBCmd));
#endif
memcpy (&hdr.dst_addr, d, ETH_ALEN);
memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
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: \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);
load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */
while (!txfd.status && timer2_running())
/* Wait */;
s2 = inw (ioaddr + SCBStatus);
#ifdef DEBUG
printf ("s1 = %hX, s2 = %hX.\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)
{
if (!ACCESS(rxfd)status)
return 0;
/* Ok. We got a packet. Now restart the reciever.... */
ACCESS(rxfd)status = 0;
ACCESS(rxfd)command = 0xc000;
outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
wait_for_cmd_done(ioaddr + SCBCmd);
#ifdef DEBUG
printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
#endif
nic->packetlen = ACCESS(rxfd)count & 0x3fff;
memcpy (nic->packet, ACCESS(rxfd)packet, nic->packetlen);
#ifdef DEBUG
hd (nic->packet, 0x30);
#endif
return 1;
}
static void eepro100_disable(struct nic *nic)
{
/* See if this PartialReset solves the problem with interfering with
kernel operation after Etherboot hands over. - Ken 20001102 */
outl(2, ioaddr + SCBPort);
}
/* 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, struct pci_device *p)
{
unsigned short sum = 0;
int i;
int read_cmd, ee_size;
unsigned short value;
int options;
int promisc;
/* we cache only the first few words of the EEPROM data
be careful not to access beyond this array */
unsigned short eeprom[16];
if (probeaddrs == 0 || probeaddrs[0] == 0)
return 0;
ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
adjust_pci_device(p);
if ((do_eeprom_cmd(EE_READ_CMD << 24, 27) & 0xffe0000)
== 0xffe0000) {
ee_size = 0x100;
read_cmd = EE_READ_CMD << 24;
} else {
ee_size = 0x40;
read_cmd = EE_READ_CMD << 22;
}
for (i = 0, sum = 0; i < ee_size; i++) {
unsigned short value = do_eeprom_cmd(read_cmd | (i << 16), 27);
if (i < (int)(sizeof(eeprom)/sizeof(eeprom[0])))
eeprom[i] = value;
sum += value;
}
for (i=0;i<ETH_ALEN;i++) {
nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
}
printf ("Ethernet addr: %!\n", nic->node_addr);
if (sum != 0xBABA)
printf("eepro100: Invalid EEPROM checksum %#hX, "
"check settings before activating this device!\n", sum);
outl(0, ioaddr + SCBPort);
udelay (10000);
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.");
ACCESS(rxfd)status = 0x0001;
ACCESS(rxfd)command = 0x0000;
ACCESS(rxfd)link = virt_to_bus(&(ACCESS(rxfd)status));
ACCESS(rxfd)rx_buf_addr = (int) &nic->packet;
ACCESS(rxfd)count = 0;
ACCESS(rxfd)size = 1528;
outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
outw(INT_MASK | RX_START, ioaddr + SCBCmd);
wait_for_cmd_done(ioaddr + SCBCmd);
whereami ("started RX process.");
/* Start the reciever.... */
ACCESS(rxfd)status = 0;
ACCESS(rxfd)command = 0xc000;
outl(virt_to_bus(&(ACCESS(rxfd)status)), 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 *t = (char *)&txfd.tx_desc_addr;
for (i=0;i<ETH_ALEN;i++)
t[i] = nic->node_addr[i];
}
#ifdef DEBUG
printf ("Setup_eaddr:\n");
hd (&txfd, 0x20);
#endif
/* options = 0x40; */ /* 10mbps half duplex... */
options = 0x00; /* Autosense */
promisc = 0;
if ( ((eeprom[6]>>8) & 0x3f) == DP83840
|| ((eeprom[6]>>8) & 0x3f) == DP83840A) {
int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
if (congenb)
mdi_reg23 |= 0x0100;
printf(" DP83840 specific setup, setting register 23 to %hX.\n",
mdi_reg23);
mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23);
}
whereami ("Done DP8340 special setup.");
if (options != 0) {
mdio_write(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).");
load_timer2(10*TICKS_PER_MS);
while (!txfd.status && timer2_running())
/* Wait */;
nic->reset = eepro100_reset;
nic->poll = eepro100_poll;
nic->transmit = eepro100_transmit;
nic->disable = eepro100_disable;
return nic;
}
/*********************************************************************/
#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 (" %hhX", ((char *)where)[i]);
printf ("\n");
n -= 16;
where += 16;
}
}
#endif

View file

@ -1,481 +0,0 @@
/* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for Etherboot */
#define LINUX_OUT_MACROS
#include "etherboot.h"
#include "nic.h"
#include "cards.h"
#include "timer.h"
#include "epic100.h"
#undef virt_to_bus
#define virt_to_bus(x) ((unsigned long)x)
#define TX_RING_SIZE 2 /* use at least 2 buffers for TX */
#define RX_RING_SIZE 2
#define PKT_BUF_SZ 1536 /* Size of each temporary Tx/Rx buffer.*/
/*
#define DEBUG_RX
#define DEBUG_TX
#define DEBUG_EEPROM
*/
#define EPIC_DEBUG 0 /* debug level */
/* The EPIC100 Rx and Tx buffer descriptors. */
struct epic_rx_desc {
unsigned short status;
unsigned short rxlength;
unsigned long bufaddr;
unsigned short buflength;
unsigned short control;
unsigned long next;
};
/* description of the tx descriptors control bits commonly used */
#define TD_STDFLAGS TD_LASTDESC
struct epic_tx_desc {
unsigned short status;
unsigned short txlength;
unsigned long bufaddr;
unsigned short buflength;
unsigned short control;
unsigned long next;
};
#define delay(nanosec) do { int _i = 3; while (--_i > 0) \
{ __SLOW_DOWN_IO; }} while (0)
static void epic100_open(void);
static void epic100_init_ring(void);
static void epic100_disable(struct nic *nic);
static int epic100_poll(struct nic *nic);
static void epic100_transmit(struct nic *nic, const char *destaddr,
unsigned int type, unsigned int len, const char *data);
static int read_eeprom(int location);
static int mii_read(int phy_id, int location);
static int ioaddr;
static int command;
static int intstat;
static int intmask;
static int genctl ;
static int eectl ;
static int test ;
static int mmctl ;
static int mmdata ;
static int lan0 ;
static int rxcon ;
static int txcon ;
static int prcdar ;
static int ptcdar ;
static int eththr ;
static unsigned int cur_rx, cur_tx; /* The next free ring entry */
#ifdef DEBUG_EEPROM
static unsigned short eeprom[64];
#endif
static signed char phys[4]; /* MII device addresses. */
static struct epic_rx_desc rx_ring[RX_RING_SIZE];
static struct epic_tx_desc tx_ring[TX_RING_SIZE];
#ifdef USE_LOWMEM_BUFFER
#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
#else
static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
#endif
/***********************************************************************/
/* Externally visible functions */
/***********************************************************************/
static void
epic100_reset(struct nic *nic)
{
/* Soft reset the chip. */
outl(GC_SOFT_RESET, genctl);
}
struct nic*
epic100_probe(struct nic *nic, unsigned short *probeaddrs)
{
unsigned short sum = 0;
unsigned short value;
int i;
unsigned short* ap;
unsigned int phy, phy_idx;
if (probeaddrs == 0 || probeaddrs[0] == 0)
return 0;
/* Ideally we would detect all network cards in slot order. That would
be best done a central PCI probe dispatch, which wouldn't work
well with the current structure. So instead we detect just the
Epic cards in slot order. */
ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
/* compute all used static epic100 registers address */
command = ioaddr + COMMAND; /* Control Register */
intstat = ioaddr + INTSTAT; /* Interrupt Status */
intmask = ioaddr + INTMASK; /* Interrupt Mask */
genctl = ioaddr + GENCTL; /* General Control */
eectl = ioaddr + EECTL; /* EEPROM Control */
test = ioaddr + TEST; /* Test register (clocks) */
mmctl = ioaddr + MMCTL; /* MII Management Interface Control */
mmdata = ioaddr + MMDATA; /* MII Management Interface Data */
lan0 = ioaddr + LAN0; /* MAC address. (0x40-0x48) */
rxcon = ioaddr + RXCON; /* Receive Control */
txcon = ioaddr + TXCON; /* Transmit Control */
prcdar = ioaddr + PRCDAR; /* PCI Receive Current Descr Address */
ptcdar = ioaddr + PTCDAR; /* PCI Transmit Current Descr Address */
eththr = ioaddr + ETHTHR; /* Early Transmit Threshold */
/* Reset the chip & bring it out of low-power mode. */
outl(GC_SOFT_RESET, genctl);
/* Disable ALL interrupts by setting the interrupt mask. */
outl(INTR_DISABLE, intmask);
/*
* set the internal clocks:
* Application Note 7.15 says:
* In order to set the CLOCK TEST bit in the TEST register,
* perform the following:
*
* Write 0x0008 to the test register at least sixteen
* consecutive times.
*
* The CLOCK TEST bit is Write-Only. Writing it several times
* consecutively insures a successful write to the bit...
*/
for (i = 0; i < 16; i++) {
outl(0x00000008, test);
}
#ifdef DEBUG_EEPROM
for (i = 0; i < 64; i++) {
value = read_eeprom(i);
eeprom[i] = value;
sum += value;
}
#if (EPIC_DEBUG > 1)
printf("EEPROM contents\n");
for (i = 0; i < 64; i++) {
printf(" %hhX%s", eeprom[i], i % 16 == 15 ? "\n" : "");
}
#endif
#endif
/* This could also be read from the EEPROM. */
ap = (unsigned short*)nic->node_addr;
for (i = 0; i < 3; i++)
*ap++ = inw(lan0 + i*4);
printf(" I/O %#hX %! ", ioaddr, nic->node_addr);
/* Find the connected MII xcvrs. */
for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) {
int mii_status = mii_read(phy, 0);
if (mii_status != 0xffff && mii_status != 0x0000) {
phys[phy_idx++] = phy;
#if (EPIC_DEBUG > 1)
printf("MII transceiver found at address %d.\n", phy);
#endif
}
}
if (phy_idx == 0) {
#if (EPIC_DEBUG > 1)
printf("***WARNING***: No MII transceiver found!\n");
#endif
/* Use the known PHY address of the EPII. */
phys[0] = 3;
}
epic100_open();
nic->reset = epic100_reset;
nic->poll = epic100_poll;
nic->transmit = epic100_transmit;
nic->disable = epic100_disable;
return nic;
}
static void
epic100_open(void)
{
int mii_reg5;
int full_duplex = 0;
unsigned long tmp;
epic100_init_ring();
/* Pull the chip out of low-power mode, and set for PCI read multiple. */
outl(GC_RX_FIFO_THR_64 | GC_MRC_READ_MULT | GC_ONE_COPY, genctl);
outl(TX_FIFO_THRESH, eththr);
tmp = TC_EARLY_TX_ENABLE | TX_SLOT_TIME;
mii_reg5 = mii_read(phys[0], 5);
if (mii_reg5 != 0xffff && (mii_reg5 & 0x0100)) {
full_duplex = 1;
printf(" full-duplex mode");
tmp |= TC_LM_FULL_DPX;
} else
tmp |= TC_LM_NORMAL;
outl(tmp, txcon);
/* Give adress of RX and TX ring to the chip */
outl(virt_to_bus(&rx_ring), prcdar);
outl(virt_to_bus(&tx_ring), ptcdar);
/* Start the chip's Rx process: receive unicast and broadcast */
outl(0x04, rxcon);
outl(CR_START_RX | CR_QUEUE_RX, command);
putchar('\n');
}
/* Initialize the Rx and Tx rings. */
static void
epic100_init_ring(void)
{
int i;
char* p;
cur_rx = cur_tx = 0;
p = &rx_packet[0];
for (i = 0; i < RX_RING_SIZE; i++) {
rx_ring[i].status = RRING_OWN; /* Owned by Epic chip */
rx_ring[i].buflength = PKT_BUF_SZ;
rx_ring[i].bufaddr = virt_to_bus(p + (PKT_BUF_SZ * i));
rx_ring[i].control = 0;
rx_ring[i].next = virt_to_bus(&(rx_ring[i + 1]) );
}
/* Mark the last entry as wrapping the ring. */
rx_ring[i-1].next = virt_to_bus(&rx_ring[0]);
/*
*The Tx buffer descriptor is filled in as needed,
* but we do need to clear the ownership bit.
*/
p = &tx_packet[0];
for (i = 0; i < TX_RING_SIZE; i++) {
tx_ring[i].status = 0; /* Owned by CPU */
tx_ring[i].bufaddr = virt_to_bus(p + (PKT_BUF_SZ * i));
tx_ring[i].control = TD_STDFLAGS;
tx_ring[i].next = virt_to_bus(&(tx_ring[i + 1]) );
}
tx_ring[i-1].next = virt_to_bus(&tx_ring[0]);
}
/* function: epic100_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
epic100_transmit(struct nic *nic, const char *destaddr, unsigned int type,
unsigned int len, const char *data)
{
unsigned short nstype;
char* txp;
int entry;
/* Calculate the next Tx descriptor entry. */
entry = cur_tx % TX_RING_SIZE;
if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) {
printf("eth_transmit: Unable to transmit. status=%hX. Resetting...\n",
tx_ring[entry].status);
epic100_open();
return;
}
txp = (char*)tx_ring[entry].bufaddr;
memcpy(txp, destaddr, ETH_ALEN);
memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
nstype = htons(type);
memcpy(txp + 12, (char*)&nstype, 2);
memcpy(txp + ETH_HLEN, data, len);
len += ETH_HLEN;
/*
* Caution: the write order is important here,
* set the base address with the "ownership"
* bits last.
*/
tx_ring[entry].txlength = (len >= 60 ? len : 60);
tx_ring[entry].buflength = len;
tx_ring[entry].status = TRING_OWN; /* Pass ownership to the chip. */
cur_tx++;
/* Trigger an immediate transmit demand. */
outl(CR_QUEUE_TX, command);
load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */
while ((tx_ring[entry].status & TRING_OWN) && timer2_running())
/* Wait */;
if ((tx_ring[entry].status & TRING_OWN) != 0)
printf("Oops, transmitter timeout, status=%hX\n",
tx_ring[entry].status);
}
/* function: epic100_poll / eth_poll
* This receives a packet from the network.
*
* Arguments: none
*
* returns: 1 if a packet was received.
* 0 if no pacet was received.
* side effects:
* returns the packet in the array nic->packet.
* returns the length of the packet in nic->packetlen.
*/
static int
epic100_poll(struct nic *nic)
{
int entry;
int status;
int retcode;
entry = cur_rx % RX_RING_SIZE;
if ((status = rx_ring[entry].status & RRING_OWN) == RRING_OWN)
return (0);
/* We own the next entry, it's a new packet. Send it up. */
#if (EPIC_DEBUG > 4)
printf("epic_poll: entry %d status %hX\n", entry, status);
#endif
cur_rx++;
if (status & 0x2000) {
printf("epic_poll: Giant packet\n");
retcode = 0;
} else if (status & 0x0006) {
/* Rx Frame errors are counted in hardware. */
printf("epic_poll: Frame received with errors\n");
retcode = 0;
} else {
/* Omit the four octet CRC from the length. */
nic->packetlen = rx_ring[entry].rxlength - 4;
memcpy(nic->packet, (char*)rx_ring[entry].bufaddr, nic->packetlen);
retcode = 1;
}
/* Clear all error sources. */
outl(status & INTR_CLEARERRS, intstat);
/* Give the descriptor back to the chip */
rx_ring[entry].status = RRING_OWN;
/* Restart Receiver */
outl(CR_START_RX | CR_QUEUE_RX, command);
return retcode;
}
static void
epic100_disable(struct nic *nic)
{
}
#ifdef DEBUG_EEPROM
/* Serial EEPROM section. */
/* EEPROM_Ctrl bits. */
#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
#define EE_CS 0x02 /* EEPROM chip select. */
#define EE_DATA_WRITE 0x08 /* EEPROM chip data in. */
#define EE_WRITE_0 0x01
#define EE_WRITE_1 0x09
#define EE_DATA_READ 0x10 /* EEPROM chip data out. */
#define EE_ENB (0x0001 | EE_CS)
/* 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)
#define eeprom_delay(n) delay(n)
static int
read_eeprom(int location)
{
int i;
int retval = 0;
int read_cmd = location | EE_READ_CMD;
outl(EE_ENB & ~EE_CS, eectl);
outl(EE_ENB, eectl);
/* Shift the read command bits out. */
for (i = 10; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
outl(EE_ENB | dataval, eectl);
eeprom_delay(100);
outl(EE_ENB | dataval | EE_SHIFT_CLK, eectl);
eeprom_delay(150);
outl(EE_ENB | dataval, eectl); /* Finish EEPROM a clock tick. */
eeprom_delay(250);
}
outl(EE_ENB, eectl);
for (i = 16; i > 0; i--) {
outl(EE_ENB | EE_SHIFT_CLK, eectl);
eeprom_delay(100);
retval = (retval << 1) | ((inl(eectl) & EE_DATA_READ) ? 1 : 0);
outl(EE_ENB, eectl);
eeprom_delay(100);
}
/* Terminate the EEPROM access. */
outl(EE_ENB & ~EE_CS, eectl);
return retval;
}
#endif
#define MII_READOP 1
#define MII_WRITEOP 2
static int
mii_read(int phy_id, int location)
{
int i;
outl((phy_id << 9) | (location << 4) | MII_READOP, mmctl);
/* Typical operation takes < 50 ticks. */
for (i = 4000; i > 0; i--)
if ((inl(mmctl) & MII_READOP) == 0)
break;
return inw(mmdata);
}

View file

@ -1,188 +0,0 @@
#ifndef _EPIC100_H_
# define _EPIC100_H_
#ifndef PCI_VENDOR_SMC
# define PCI_VENDOR_SMC 0x10B8
#endif
#ifndef PCI_DEVICE_SMC_EPIC100
# define PCI_DEVICE_SMC_EPIC100 0x0005
#endif
#define PCI_DEVICE_ID_NONE 0xFFFF
/* Offsets to registers (using SMC names). */
enum epic100_registers {
COMMAND= 0, /* Control Register */
INTSTAT= 4, /* Interrupt Status */
INTMASK= 8, /* Interrupt Mask */
GENCTL = 0x0C, /* General Control */
NVCTL = 0x10, /* Non Volatile Control */
EECTL = 0x14, /* EEPROM Control */
TEST = 0x1C, /* Test register: marked as reserved (see in source code) */
CRCCNT = 0x20, /* CRC Error Counter */
ALICNT = 0x24, /* Frame Alignment Error Counter */
MPCNT = 0x28, /* Missed Packet Counter */
MMCTL = 0x30, /* MII Management Interface Control */
MMDATA = 0x34, /* MII Management Interface Data */
MIICFG = 0x38, /* MII Configuration */
IPG = 0x3C, /* InterPacket Gap */
LAN0 = 0x40, /* MAC address. (0x40-0x48) */
IDCHK = 0x4C, /* BoardID/ Checksum */
MC0 = 0x50, /* Multicast filter table. (0x50-0x5c) */
RXCON = 0x60, /* Receive Control */
TXCON = 0x70, /* Transmit Control */
TXSTAT = 0x74, /* Transmit Status */
PRCDAR = 0x84, /* PCI Receive Current Descriptor Address */
PRSTAT = 0xA4, /* PCI Receive DMA Status */
PRCPTHR= 0xB0, /* PCI Receive Copy Threshold */
PTCDAR = 0xC4, /* PCI Transmit Current Descriptor Address */
ETHTHR = 0xDC /* Early Transmit Threshold */
};
/* Command register (CR_) bits */
#define CR_STOP_RX (0x00000001)
#define CR_START_RX (0x00000002)
#define CR_QUEUE_TX (0x00000004)
#define CR_QUEUE_RX (0x00000008)
#define CR_NEXTFRAME (0x00000010)
#define CR_STOP_TX_DMA (0x00000020)
#define CR_STOP_RX_DMA (0x00000040)
#define CR_TX_UGO (0x00000080)
/* Interrupt register bits. NI means No Interrupt generated */
#define INTR_RX_THR_STA (0x00400000) /* rx copy threshold status NI */
#define INTR_RX_BUFF_EMPTY (0x00200000) /* rx buffers empty. NI */
#define INTR_TX_IN_PROG (0x00100000) /* tx copy in progess. NI */
#define INTR_RX_IN_PROG (0x00080000) /* rx copy in progress. NI */
#define INTR_TXIDLE (0x00040000) /* tx idle. NI */
#define INTR_RXIDLE (0x00020000) /* rx idle. NI */
#define INTR_INTR_ACTIVE (0x00010000) /* Interrupt active. NI */
#define INTR_RX_STATUS_OK (0x00008000) /* rx status valid. NI */
#define INTR_PCI_TGT_ABT (0x00004000) /* PCI Target abort */
#define INTR_PCI_MASTER_ABT (0x00002000) /* PCI Master abort */
#define INTR_PCI_PARITY_ERR (0x00001000) /* PCI adress parity error */
#define INTR_PCI_DATA_ERR (0x00000800) /* PCI data parity error */
#define INTR_RX_THR_CROSSED (0x00000400) /* rx copy threshold crossed */
#define INTR_CNTFULL (0x00000200) /* Counter overflow */
#define INTR_TXUNDERRUN (0x00000100) /* tx underrun. */
#define INTR_TXEMPTY (0x00000080) /* tx queue empty */
#define INTR_TX_CH_COMPLETE (0x00000040) /* tx chain complete */
#define INTR_TXDONE (0x00000020) /* tx complete (w or w/o err) */
#define INTR_RXERROR (0x00000010) /* rx error (CRC) */
#define INTR_RXOVERFLOW (0x00000008) /* rx buffer overflow */
#define INTR_RX_QUEUE_EMPTY (0x00000004) /* rx queue empty. */
#define INTR_RXHEADER (0x00000002) /* header copy complete */
#define INTR_RXDONE (0x00000001) /* Receive copy complete */
#define INTR_CLEARINTR (0x00007FFF)
#define INTR_VALIDBITS (0x007FFFFF)
#define INTR_DISABLE (0x00000000)
#define INTR_CLEARERRS (0x00007F18)
#define INTR_ABNINTR (INTR_CNTFULL | INTR_TXUNDERRUN | INTR_RXOVERFLOW)
/* General Control (GC_) bits */
#define GC_SOFT_RESET (0x00000001)
#define GC_INTR_ENABLE (0x00000002)
#define GC_SOFT_INTR (0x00000004)
#define GC_POWER_DOWN (0x00000008)
#define GC_ONE_COPY (0x00000010)
#define GC_BIG_ENDIAN (0x00000020)
#define GC_RX_PREEMPT_TX (0x00000040)
#define GC_TX_PREEMPT_RX (0x00000080)
/*
* Receive FIFO Threshold values
* Control the level at which the PCI burst state machine
* begins to empty the receive FIFO. Possible values: 0-3
*
* 0 => 32, 1 => 64, 2 => 96 3 => 128 bytes.
*/
#define GC_RX_FIFO_THR_32 (0x00000000)
#define GC_RX_FIFO_THR_64 (0x00000100)
#define GC_RX_FIFO_THR_96 (0x00000200)
#define GC_RX_FIFO_THR_128 (0x00000300)
/* Memory Read Control (MRC_) values */
#define GC_MRC_MEM_READ (0x00000000)
#define GC_MRC_READ_MULT (0x00000400)
#define GC_MRC_READ_LINE (0x00000800)
#define GC_SOFTBIT0 (0x00001000)
#define GC_SOFTBIT1 (0x00002000)
#define GC_RESET_PHY (0x00004000)
/* Definitions of the Receive Control (RC_) register bits */
#define RC_SAVE_ERRORED_PKT (0x00000001)
#define RC_SAVE_RUNT_FRAMES (0x00000002)
#define RC_RCV_BROADCAST (0x00000004)
#define RC_RCV_MULTICAST (0x00000008)
#define RC_RCV_INVERSE_PKT (0x00000010)
#define RC_PROMISCUOUS_MODE (0x00000020)
#define RC_MONITOR_MODE (0x00000040)
#define RC_EARLY_RCV_ENABLE (0x00000080)
/* description of the rx descriptors control bits */
#define RD_FRAGLIST (0x0001) /* Desc points to a fragment list */
#define RD_LLFORM (0x0002) /* Frag list format */
#define RD_HDR_CPY (0x0004) /* Desc used for header copy */
/* Definition of the Transmit CONTROL (TC) register bits */
#define TC_EARLY_TX_ENABLE (0x00000001)
/* Loopback Mode (LM_) Select valuesbits */
#define TC_LM_NORMAL (0x00000000)
#define TC_LM_INTERNAL (0x00000002)
#define TC_LM_EXTERNAL (0x00000004)
#define TC_LM_FULL_DPX (0x00000006)
#define TX_SLOT_TIME (0x00000078)
/* Bytes transferred to chip before transmission starts. */
#define TX_FIFO_THRESH 128 /* Rounded down to 4 byte units. */
/* description of rx descriptors status bits */
#define RRING_PKT_INTACT (0x0001)
#define RRING_ALIGN_ERR (0x0002)
#define RRING_CRC_ERR (0x0004)
#define RRING_MISSED_PKT (0x0008)
#define RRING_MULTICAST (0x0010)
#define RRING_BROADCAST (0x0020)
#define RRING_RECEIVER_DISABLE (0x0040)
#define RRING_STATUS_VALID (0x1000)
#define RRING_FRAGLIST_ERR (0x2000)
#define RRING_HDR_COPIED (0x4000)
#define RRING_OWN (0x8000)
/* error summary */
#define RRING_ERROR (RRING_ALIGN_ERR|RRING_CRC_ERR)
/* description of tx descriptors status bits */
#define TRING_PKT_INTACT (0x0001) /* pkt transmitted. */
#define TRING_PKT_NONDEFER (0x0002) /* pkt xmitted w/o deferring */
#define TRING_COLL (0x0004) /* pkt xmitted w collisions */
#define TRING_CARR (0x0008) /* carrier sense lost */
#define TRING_UNDERRUN (0x0010) /* DMA underrun */
#define TRING_HB_COLL (0x0020) /* Collision detect Heartbeat */
#define TRING_WIN_COLL (0x0040) /* out of window collision */
#define TRING_DEFERRED (0x0080) /* Deferring */
#define TRING_COLL_COUNT (0x0F00) /* collision counter (mask) */
#define TRING_COLL_EXCESS (0x1000) /* tx aborted: excessive colls */
#define TRING_OWN (0x8000) /* desc ownership bit */
/* error summary */
#define TRING_ABORT (TRING_COLL_EXCESS|TRING_WIN_COLL|TRING_UNDERRUN)
#define TRING_ERROR (TRING_DEFERRED|TRING_WIN_COLL|TRING_UNDERRUN|TRING_CARR/*|TRING_COLL*/ )
/* description of the tx descriptors control bits */
#define TD_FRAGLIST (0x0001) /* Desc points to a fragment list */
#define TD_LLFORM (0x0002) /* Frag list format */
#define TD_IAF (0x0004) /* Generate Interrupt after tx */
#define TD_NOCRC (0x0008) /* No CRC generated */
#define TD_LASTDESC (0x0010) /* Last desc for this frame */
#endif /* _EPIC100_H_ */

View file

@ -1,544 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
*
* 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.
*
* 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.
*/
/* RULE: You must define the macro ``GRUB'' when including this header
file in GRUB code. */
/* Based on "src/etherboot.h" in etherboot-5.0.5. */
/**************************************************************************
ETHERBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters
Date: Dec/93
**************************************************************************/
/* Include GRUB-specific macros and prototypes here. */
#include <shared.h>
/* FIXME: For now, enable the DHCP support. Perhaps I should segregate
the DHCP support from the BOOTP support, and permit both to
co-exist. */
#undef NO_DHCP_SUPPORT
/* In GRUB, the relocated address in Etherboot doesn't have any sense.
Just define it as a bogus value. */
#define RELOC 0
/* FIXME: Should be an option. */
#define BACKOFF_LIMIT 7
#include <osdep.h>
#define CTRL_C 3
#ifndef MAX_TFTP_RETRIES
# define MAX_TFTP_RETRIES 20
#endif
#ifndef MAX_BOOTP_RETRIES
# define MAX_BOOTP_RETRIES 20
#endif
#define MAX_BOOTP_EXTLEN (ETH_FRAME_LEN - ETH_HLEN - \
sizeof (struct bootp_t))
#ifndef MAX_ARP_RETRIES
# define MAX_ARP_RETRIES 20
#endif
#ifndef MAX_RPC_RETRIES
# define MAX_RPC_RETRIES 20
#endif
#define TICKS_PER_SEC 18
/* Inter-packet retry in ticks */
#define TIMEOUT (10 * TICKS_PER_SEC)
/* These settings have sense only if compiled with -DCONGESTED */
/* total retransmission timeout in ticks */
#define TFTP_TIMEOUT (30 * TICKS_PER_SEC)
/* packet retransmission timeout in ticks */
#define TFTP_REXMT (3 * TICKS_PER_SEC)
#ifndef NULL
# define NULL ((void *) 0)
#endif
/*
I'm moving towards the defined names in linux/if_ether.h for clarity.
The confusion between 60/64 and 1514/1518 arose because the NS8390
counts the 4 byte frame checksum in the incoming packet, but not
in the outgoing packet. 60/1514 are the correct numbers for most
if not all of the other NIC controllers. I will be retiring the
64/1518 defines in the lead-up to 5.0.
*/
#define ETH_ALEN 6 /* Size of Ethernet address */
#define ETH_HLEN 14 /* Size of ethernet header */
#define ETH_ZLEN 60 /* Minimum packet */
/*#define ETH_MIN_PACKET 64*/
#define ETH_FRAME_LEN 1514 /* Maximum packet */
/*#define ETH_MAX_PACKET 1518*/
/* Because some DHCP/BOOTP servers don't treat the maximum length the same
as Etherboot, subtract the size of an IP header and that of an UDP
header. */
#define ETH_MAX_MTU (ETH_FRAME_LEN - ETH_HLEN \
- sizeof (struct iphdr) \
- sizeof (struct udphdr))
#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 RARP_REQUEST 3
#define RARP_REPLY 4
#define IP 0x0800
#define ARP 0x0806
#define RARP 0x8035
#define BOOTP_SERVER 67
#define BOOTP_CLIENT 68
#define TFTP_PORT 69
#define SUNRPC_PORT 111
#define IP_UDP 17
/* Same after going through htonl */
#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
#ifndef NO_DHCP_SUPPORT
#define RFC2132_REQ_ADDR 50
#define RFC2132_MSG_TYPE 53
#define RFC2132_SRV_ID 54
#define RFC2132_PARAM_LIST 55
#define RFC2132_MAX_SIZE 57
#define RFC2132_VENDOR_CLASS_ID 60
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPACK 5
#endif /* NO_DHCP_SUPPORT */
#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_VENDOR_CONFIGFILE 150
#define RFC1533_END 255
#define BOOTP_VENDOR_LEN 64
#ifndef NO_DHCP_SUPPORT
#define DHCP_OPT_LEN 312
#endif /* NO_DHCP_SUPPORT */
#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 AWAIT_ARP 0
#define AWAIT_BOOTP 1
#define AWAIT_TFTP 2
#define AWAIT_RARP 3
#define AWAIT_RPC 4
#define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */
typedef struct
{
unsigned long s_addr;
}
in_addr;
struct arptable_t
{
in_addr ipaddr;
unsigned char node[6];
};
/*
* A pity sipaddr and tipaddr are not longword aligned or we could use
* in_addr. No, I don't want to use #pragma packed.
*/
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;
in_addr src;
in_addr dest;
};
struct udphdr
{
unsigned short src;
unsigned short dest;
unsigned short len;
unsigned short chksum;
};
/* Format of a bootp packet. */
struct bootp_t
{
char bp_op;
char bp_htype;
char bp_hlen;
char bp_hops;
unsigned long bp_xid;
unsigned short bp_secs;
unsigned short unused;
in_addr bp_ciaddr;
in_addr bp_yiaddr;
in_addr bp_siaddr;
in_addr bp_giaddr;
char bp_hwaddr[16];
char bp_sname[64];
char bp_file[128];
#ifdef NO_DHCP_SUPPORT
char bp_vend[BOOTP_VENDOR_LEN];
#else
char bp_vend[DHCP_OPT_LEN];
#endif /* NO_DHCP_SUPPORT */
};
/* Format of a bootp IP packet. */
struct bootpip_t
{
struct iphdr ip;
struct udphdr udp;
struct bootp_t bp;
};
/* Format of bootp packet with extensions. */
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;
};
/* Define a smaller tftp packet solely for making requests to conserve stack
512 bytes should be enough. */
struct tftpreq_t
{
struct iphdr ip;
struct udphdr udp;
unsigned short opcode;
union
{
char rrq[512];
struct
{
unsigned short block;
}
ack;
struct
{
unsigned short errcode;
char errmsg[512-2];
}
err;
}
u;
};
#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
struct rpc_t
{
struct iphdr ip;
struct udphdr udp;
union
{
char data[300]; /* longest RPC call must fit!!!! */
struct
{
long id;
long type;
long rpcvers;
long prog;
long vers;
long proc;
long data[1];
}
call;
struct
{
long id;
long type;
long rstatus;
long verifier;
long v2;
long astatus;
long data[1];
}
reply;
}
u;
};
#define PROG_PORTMAP 100000
#define PROG_NFS 100003
#define PROG_MOUNT 100005
#define MSG_CALL 0
#define MSG_REPLY 1
#define PORTMAP_GETPORT 3
#define MOUNT_ADDENTRY 1
#define MOUNT_UMOUNTALL 4
#define NFS_LOOKUP 4
#define NFS_READ 6
#define NFS_FHSIZE 32
#define NFSERR_PERM 1
#define NFSERR_NOENT 2
#define NFSERR_ACCES 13
/* Block size used for NFS read accesses. A RPC reply packet (including all
* headers) must fit within a single Ethernet frame to avoid fragmentation.
* Chosen to be a power of two, as most NFS servers are optimized for this. */
#define NFS_READ_SIZE 1024
#define FLOPPY_BOOT_LOCATION 0x7c00
/* Must match offsets in loader.S */
#define ROM_SEGMENT 0x1fa
#define ROM_LENGTH 0x1fc
#define ROM_INFO_LOCATION (FLOPPY_BOOT_LOCATION + ROM_SEGMENT)
/* at end of floppy boot block */
struct rom_info
{
unsigned short rom_segment;
unsigned short rom_length;
};
static inline int
rom_address_ok (struct rom_info *rom, int assigned_rom_segment)
{
return (assigned_rom_segment < 0xC000
|| assigned_rom_segment == rom->rom_segment);
}
/* Define a type for passing info to a loaded program. */
struct ebinfo
{
unsigned char major, minor; /* Version */
unsigned short flags; /* Bit flags */
};
/***************************************************************************
External prototypes
***************************************************************************/
/* main.c */
extern void print_network_configuration (void);
extern int ifconfig (char *ip, char *sm, char *gw, char *svr);
extern int udp_transmit (unsigned long destip, unsigned int srcsock,
unsigned int destsock, int len, const void *buf);
extern int await_reply (int type, int ival, void *ptr, int timeout);
extern int decode_rfc1533 (unsigned char *, int, int, int);
extern long rfc2131_sleep_interval (int base, int exp);
extern void cleanup (void);
extern int rarp (void);
extern int bootp (void);
extern void cleanup_net (void);
/* config.c */
extern void print_config (void);
extern void eth_reset (void);
extern int eth_probe (void);
extern int eth_poll (void);
extern void eth_transmit (const char *d, unsigned int t,
unsigned int s, const void *p);
extern void eth_disable (void);
/* misc.c */
extern void twiddle (void);
extern void sleep (int secs);
extern int getdec (char **s);
extern void etherboot_printf (const char *, ...);
extern int etherboot_sprintf (char *, const char *, ...);
extern int inet_aton (char *p, in_addr *i);
/***************************************************************************
External variables
***************************************************************************/
/* main.c */
extern int ip_abort;
extern int network_ready;
extern struct rom_info rom;
extern struct arptable_t arptable[MAX_ARP];
/* config.c */
extern struct nic nic;
/* Local hack - define some macros to use etherboot source files "as is". */
#ifndef GRUB
# undef printf
# define printf etherboot_printf
# undef sprintf
# define sprintf etherboot_sprintf
#endif /* GRUB */

View file

@ -1,421 +0,0 @@
/*
Driver for the National Semiconductor DP83810 Ethernet controller.
Portions Copyright (C) 2001 Inprimis Technologies, Inc.
http://www.inprimis.com/
This driver is based (heavily) on the Linux driver for this chip
which is copyright 1999-2001 by Donald Becker.
This software has no warranties expressed or implied for any
purpose.
This software may be used and distributed according to the terms of
the GNU General Public License (GPL), incorporated herein by reference.
Drivers based on or derived from this code fall under the GPL and must
retain the authorship, copyright and license notice. This file is not
a complete program and may only be used when the entire operating
system is licensed under the GPL. License for under other terms may be
available. Contact the original author for details.
The original author may be reached as becker@scyld.com, or at
Scyld Computing Corporation
410 Severn Ave., Suite 210
Annapolis MD 21403
*/
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#undef virt_to_bus
#define virt_to_bus(x) ((unsigned long)x)
#define cpu_to_le32(val) (val)
#define le32_to_cpu(val) (val)
#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
#define TX_RING_SIZE 1
#define RX_RING_SIZE 4
#define TIME_OUT 1000000
#define PKT_BUF_SZ 1536
/* Offsets to the device registers. */
enum register_offsets {
ChipCmd=0x00, ChipConfig=0x04, EECtrl=0x08, PCIBusCfg=0x0C,
IntrStatus=0x10, IntrMask=0x14, IntrEnable=0x18,
TxRingPtr=0x20, TxConfig=0x24,
RxRingPtr=0x30, RxConfig=0x34,
WOLCmd=0x40, PauseCmd=0x44, RxFilterAddr=0x48, RxFilterData=0x4C,
BootRomAddr=0x50, BootRomData=0x54, StatsCtrl=0x5C, StatsData=0x60,
RxPktErrs=0x60, RxMissed=0x68, RxCRCErrs=0x64,
};
/* Bit in ChipCmd. */
enum ChipCmdBits {
ChipReset=0x100, RxReset=0x20, TxReset=0x10, RxOff=0x08, RxOn=0x04,
TxOff=0x02, TxOn=0x01,
};
/* Bits in the interrupt status/mask registers. */
enum intr_status_bits {
IntrRxDone=0x0001, IntrRxIntr=0x0002, IntrRxErr=0x0004, IntrRxEarly=0x0008,
IntrRxIdle=0x0010, IntrRxOverrun=0x0020,
IntrTxDone=0x0040, IntrTxIntr=0x0080, IntrTxErr=0x0100,
IntrTxIdle=0x0200, IntrTxUnderrun=0x0400,
StatsMax=0x0800, LinkChange=0x4000, WOLPkt=0x2000,
RxResetDone=0x1000000, TxResetDone=0x2000000,
IntrPCIErr=0x00f00000, IntrNormalSummary=0x0251, IntrAbnormalSummary=0xED20,
};
/* Bits in the RxMode register. */
enum rx_mode_bits {
AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0xC0000000,
AcceptMulticast=0x00200000, AcceptAllMulticast=0x20000000,
AcceptAllPhys=0x10000000, AcceptMyPhys=0x08000000,
};
/* Bits in network_desc.status */
enum desc_status_bits {
DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000,
DescNoCRC=0x10000000,
DescPktOK=0x08000000, RxTooLong=0x00400000,
};
/* The Rx and Tx buffer descriptors. */
struct netdev_desc {
u32 next_desc;
s32 cmd_status;
u32 addr;
};
static struct FA311_DEV {
unsigned int ioaddr;
unsigned short vendor;
unsigned short device;
unsigned int cur_rx;
unsigned int cur_tx;
unsigned int rx_buf_sz;
volatile struct netdev_desc *rx_head_desc;
volatile struct netdev_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned (4)));
volatile struct netdev_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned (4)));
} fa311_dev;
static int eeprom_read(long ioaddr, int location);
static void init_ring(struct FA311_DEV *dev);
static void fa311_reset(struct nic *nic);
static int fa311_poll(struct nic *nic);
static void fa311_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
static void fa311_disable(struct nic *nic);
static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned (4)));
static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned (4)));
struct nic * fa311_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
{
int prev_eedata;
int i;
int duplex;
int tx_config;
int rx_config;
unsigned char macaddr[6];
unsigned char mactest;
unsigned char pci_bus = 0;
struct FA311_DEV* dev = &fa311_dev;
if (io_addrs == 0 || *io_addrs == 0)
return (0);
memset(dev, 0, sizeof(*dev));
dev->vendor = pci->vendor;
dev->device = pci->dev_id;
dev->ioaddr = pci->membase;
/* Work around the dropped serial bit. */
prev_eedata = eeprom_read(dev->ioaddr, 6);
for (i = 0; i < 3; i++) {
int eedata = eeprom_read(dev->ioaddr, i + 7);
macaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
macaddr[i*2+1] = eedata >> 7;
prev_eedata = eedata;
}
mactest = 0;
for (i = 0; i < 6; i++)
mactest |= macaddr[i];
if (mactest == 0)
return (0);
for (i = 0; i < 6; i++)
nic->node_addr[i] = macaddr[i];
printf("%! ", nic->node_addr);
adjust_pci_device(pci);
fa311_reset(nic);
nic->reset = fa311_reset;
nic->disable = fa311_disable;
nic->poll = fa311_poll;
nic->transmit = fa311_transmit;
init_ring(dev);
writel(virt_to_bus(dev->rx_ring), dev->ioaddr + RxRingPtr);
writel(virt_to_bus(dev->tx_ring), dev->ioaddr + TxRingPtr);
for (i = 0; i < 6; i += 2)
{
writel(i, dev->ioaddr + RxFilterAddr);
writew(macaddr[i] + (macaddr[i+1] << 8),
dev->ioaddr + RxFilterData);
}
/* Initialize other registers. */
/* Configure for standard, in-spec Ethernet. */
if (readl(dev->ioaddr + ChipConfig) & 0x20000000)
{ /* Full duplex */
tx_config = 0xD0801002;
rx_config = 0x10000020;
}
else
{
tx_config = 0x10801002;
rx_config = 0x0020;
}
writel(tx_config, dev->ioaddr + TxConfig);
writel(rx_config, dev->ioaddr + RxConfig);
duplex = readl(dev->ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
if (duplex) {
rx_config |= 0x10000000;
tx_config |= 0xC0000000;
} else {
rx_config &= ~0x10000000;
tx_config &= ~0xC0000000;
}
writew(tx_config, dev->ioaddr + TxConfig);
writew(rx_config, dev->ioaddr + RxConfig);
writel(AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys,
dev->ioaddr + RxFilterAddr);
writel(RxOn | TxOn, dev->ioaddr + ChipCmd);
writel(4, dev->ioaddr + StatsCtrl); /* Clear Stats */
return nic;
}
static void fa311_reset(struct nic *nic)
{
u32 chip_config;
struct FA311_DEV* dev = &fa311_dev;
/* Reset the chip to erase previous misconfiguration. */
outl(ChipReset, dev->ioaddr + ChipCmd);
if ((readl(dev->ioaddr + ChipConfig) & 0xe000) != 0xe000)
{
chip_config = readl(dev->ioaddr + ChipConfig);
}
}
static int fa311_poll(struct nic *nic)
{
s32 desc_status;
int to;
int entry;
int retcode;
struct FA311_DEV* dev = &fa311_dev;
retcode = 0;
entry = dev->cur_rx;
to = TIME_OUT;
while (to != 0)
{
desc_status = dev->rx_ring[entry].cmd_status;
if ((desc_status & DescOwn) != 0)
break;
else
--to;
}
if (to != 0)
{
readl(dev->ioaddr + IntrStatus); /* clear interrrupt bits */
/* driver owns the next entry it's a new packet. Send it up. */
if ((desc_status & (DescMore|DescPktOK|RxTooLong)) == DescPktOK)
{
nic->packetlen = (desc_status & 0x0fff) - 4; /* Omit CRC size. */
memcpy(nic->packet, (char*)(dev->rx_ring[entry].addr), nic->packetlen);
retcode = 1;
}
/* Give the descriptor back to the chip */
dev->rx_ring[entry].cmd_status = cpu_to_le32(dev->rx_buf_sz);
dev->cur_rx++;
if (dev->cur_rx >= RX_RING_SIZE)
dev->cur_rx = 0;
dev->rx_head_desc = &dev->rx_ring[dev->cur_rx];
}
/* Restart Rx engine if stopped. */
writel(RxOn, dev->ioaddr + ChipCmd);
return retcode;
}
static void fa311_transmit(struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data)
{
unsigned short nstype;
s32 desc_status;
int to;
int entry;
char* txp;
unsigned char* s;
struct FA311_DEV* dev = &fa311_dev;
/* Calculate the next Tx descriptor entry. */
entry = dev->cur_tx;
txp = (char*)(dev->tx_ring[entry].addr);
memcpy(txp, destaddr, ETH_ALEN);
memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
nstype = htons(type);
memcpy(txp + 12, (char*)&nstype, 2);
memcpy(txp + ETH_HLEN, data, len);
len += ETH_HLEN;
/* pad frame */
if (len < ETH_ZLEN)
{
s = (unsigned char*)(txp+len);
while (s < (unsigned char*)(txp+ETH_ZLEN))
*s++ = 0;
len = ETH_ZLEN;
}
dev->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | len);
dev->cur_tx++;
if (dev->cur_tx >= TX_RING_SIZE)
dev->cur_tx = 0;
/* Wake the potentially-idle transmit channel. */
writel(TxOn, dev->ioaddr + ChipCmd);
/* wait for tranmission to complete */
to = TIME_OUT;
while (to != 0)
{
desc_status = dev->tx_ring[entry].cmd_status;
if ((desc_status & DescOwn) == 0)
break;
else
--to;
}
readl(dev->ioaddr + IntrStatus); /* clear interrrupt bits */
return;
}
static void fa311_disable(struct nic *nic)
{
struct FA311_DEV* dev = &fa311_dev;
/* Stop the chip's Tx and Rx processes. */
writel(RxOff | TxOff, dev->ioaddr + ChipCmd);
}
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */
/* Delay between EEPROM clock transitions.
No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
made udelay() unreliable.
The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
depricated.
*/
#define eeprom_delay(ee_addr) inl(ee_addr)
enum EEPROM_Ctrl_Bits {
EE_ShiftClk=0x04, EE_DataIn=0x01, EE_ChipSelect=0x08, EE_DataOut=0x02,
};
#define EE_Write0 (EE_ChipSelect)
#define EE_Write1 (EE_ChipSelect | EE_DataIn)
/* The EEPROM commands include the alway-set leading bit. */
enum EEPROM_Cmds {
EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
};
static int eeprom_read(long addr, int location)
{
int i;
int retval = 0;
int ee_addr = addr + EECtrl;
int read_cmd = location | EE_ReadCmd;
writel(EE_Write0, ee_addr);
/* Shift the read command bits out. */
for (i = 10; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
writel(dataval, ee_addr);
eeprom_delay(ee_addr);
writel(dataval | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
}
writel(EE_ChipSelect, ee_addr);
eeprom_delay(ee_addr);
for (i = 0; i < 16; i++) {
writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0;
writel(EE_ChipSelect, ee_addr);
eeprom_delay(ee_addr);
}
/* Terminate the EEPROM access. */
writel(EE_Write0, ee_addr);
writel(0, ee_addr);
return retval;
}
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
static void init_ring(struct FA311_DEV *dev)
{
int i;
dev->cur_rx = 0;
dev->cur_tx = 0;
dev->rx_buf_sz = PKT_BUF_SZ;
dev->rx_head_desc = &dev->rx_ring[0];
/* Initialize all Rx descriptors. */
for (i = 0; i < RX_RING_SIZE; i++) {
dev->rx_ring[i].next_desc = virt_to_le32desc(&dev->rx_ring[i+1]);
dev->rx_ring[i].cmd_status = DescOwn;
}
/* Mark the last entry as wrapping the ring. */
dev->rx_ring[i-1].next_desc = virt_to_le32desc(&dev->rx_ring[0]);
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
for (i = 0; i < RX_RING_SIZE; i++) {
dev->rx_ring[i].addr = (u32)(&rx_packet[PKT_BUF_SZ * i]);
dev->rx_ring[i].cmd_status = cpu_to_le32(dev->rx_buf_sz);
}
for (i = 0; i < TX_RING_SIZE; i++) {
dev->tx_ring[i].next_desc = virt_to_le32desc(&dev->tx_ring[i+1]);
dev->tx_ring[i].cmd_status = 0;
}
dev->tx_ring[i-1].next_desc = virt_to_le32desc(&dev->tx_ring[0]);
for (i = 0; i < TX_RING_SIZE; i++)
dev->tx_ring[i].addr = (u32)(&tx_packet[PKT_BUF_SZ * i]);
return;
}

View file

@ -1,497 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002,2004 Free Software Foundation, Inc.
*
* 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.
*
* 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.
*/
/* Based on "src/main.c" in etherboot-4.5.8. */
/**************************************************************************
ETHERBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters
Date: Dec/93
**************************************************************************/
/* #define TFTP_DEBUG 1 */
#include <filesys.h>
#define GRUB 1
#include <etherboot.h>
#include <nic.h>
static int retry;
static unsigned short iport = 2000;
static unsigned short oport;
static unsigned short block, prevblock;
static int bcounter;
static struct tftp_t tp, saved_tp;
static int packetsize;
static int buf_eof, buf_read;
static int saved_filepos;
static unsigned short len, saved_len;
static char *buf;
/* Fill the buffer by receiving the data via the TFTP protocol. */
static int
buf_fill (int abort)
{
#ifdef TFTP_DEBUG
grub_printf ("buf_fill (%d)\n", abort);
#endif
while (! buf_eof && (buf_read + packetsize <= FSYS_BUFLEN))
{
struct tftp_t *tr;
long timeout;
#ifdef CONGESTED
timeout = rfc2131_sleep_interval (block ? TFTP_REXMT : TIMEOUT, retry);
#else
timeout = rfc2131_sleep_interval (TIMEOUT, retry);
#endif
if (! await_reply (AWAIT_TFTP, iport, NULL, timeout))
{
if (ip_abort)
return 0;
if (! block && retry++ < MAX_TFTP_RETRIES)
{
/* Maybe initial request was lost. */
#ifdef TFTP_DEBUG
grub_printf ("Maybe initial request was lost.\n");
#endif
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
++iport, TFTP_PORT, len, &tp))
return 0;
continue;
}
#ifdef CONGESTED
if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
{
/* We resend our last ack. */
# ifdef TFTP_DEBUG
grub_printf ("<REXMT>\n");
# endif
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
iport, oport,
TFTP_MIN_PACKET, &tp);
continue;
}
#endif
/* Timeout. */
return 0;
}
tr = (struct tftp_t *) &nic.packet[ETH_HLEN];
if (tr->opcode == ntohs (TFTP_ERROR))
{
grub_printf ("TFTP error %d (%s)\n",
ntohs (tr->u.err.errcode),
tr->u.err.errmsg);
return 0;
}
if (tr->opcode == ntohs (TFTP_OACK))
{
char *p = tr->u.oack.data, *e;
#ifdef TFTP_DEBUG
grub_printf ("OACK ");
#endif
/* Shouldn't happen. */
if (prevblock)
{
/* Ignore it. */
grub_printf ("%s:%d: warning: PREVBLOCK != 0 (0x%x)\n",
__FILE__, __LINE__, prevblock);
continue;
}
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 (! grub_strcmp ("blksize", p))
{
p += 8;
if ((packetsize = getdec (&p)) < TFTP_DEFAULTSIZE_PACKET)
goto noak;
#ifdef TFTP_DEBUG
grub_printf ("blksize = %d\n", packetsize);
#endif
}
else if (! grub_strcmp ("tsize", p))
{
p += 6;
if ((filemax = getdec (&p)) < 0)
{
filemax = -1;
goto noak;
}
#ifdef TFTP_DEBUG
grub_printf ("tsize = %d\n", filemax);
#endif
}
else
{
noak:
#ifdef TFTP_DEBUG
grub_printf ("NOAK\n");
#endif
tp.opcode = htons (TFTP_ERROR);
tp.u.err.errcode = 8;
len = (grub_sprintf ((char *) tp.u.err.errmsg,
"RFC1782 error")
+ sizeof (tp.ip) + sizeof (tp.udp)
+ sizeof (tp.opcode) + sizeof (tp.u.err.errcode)
+ 1);
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
iport, ntohs (tr->udp.src),
len, &tp);
return 0;
}
while (p < e && *p)
p++;
if (p < e)
p++;
}
if (p > e)
goto noak;
/* This ensures that the packet does not get processed as
data! */
block = tp.u.ack.block = 0;
}
else if (tr->opcode == ntohs (TFTP_DATA))
{
#ifdef TFTP_DEBUG
grub_printf ("DATA ");
#endif
len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4;
/* Shouldn't happen. */
if (len > packetsize)
{
/* Ignore it. */
grub_printf ("%s:%d: warning: LEN > PACKETSIZE (0x%x > 0x%x)\n",
__FILE__, __LINE__, len, packetsize);
continue;
}
block = ntohs (tp.u.ack.block = tr->u.data.block);
}
else
/* Neither TFTP_OACK nor TFTP_DATA. */
break;
if ((block || bcounter) && (block != prevblock + (unsigned short) 1))
/* Block order should be continuous */
tp.u.ack.block = htons (block = prevblock);
/* Should be continuous. */
tp.opcode = abort ? htons (TFTP_ERROR) : htons (TFTP_ACK);
oport = ntohs (tr->udp.src);
#ifdef TFTP_DEBUG
grub_printf ("ACK\n");
#endif
/* Ack. */
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
oport, TFTP_MIN_PACKET, &tp);
if (abort)
{
buf_eof = 1;
break;
}
/* Retransmission or OACK. */
if ((unsigned short) (block - prevblock) != 1)
/* Don't process. */
continue;
prevblock = block;
/* Is it the right place to zero the timer? */
retry = 0;
/* In GRUB, this variable doesn't play any important role at all,
but use it for consistency with Etherboot. */
bcounter++;
/* Copy the downloaded data to the buffer. */
grub_memmove (buf + buf_read, tr->u.data.download, len);
buf_read += len;
/* End of data. */
if (len < packetsize)
buf_eof = 1;
}
return 1;
}
/* Send the RRQ whose length is LEN. */
static int
send_rrq (void)
{
/* Initialize some variables. */
retry = 0;
block = 0;
prevblock = 0;
packetsize = TFTP_DEFAULTSIZE_PACKET;
bcounter = 0;
buf = (char *) FSYS_BUF;
buf_eof = 0;
buf_read = 0;
saved_filepos = 0;
/* Clear out the Rx queue first. It contains nothing of interest,
* except possibly ARP requests from the DHCP/TFTP server. We use
* polling throughout Etherboot, so some time may have passed since we
* last polled the receive queue, which may now be filled with
* broadcast packets. This will cause the reply to the packets we are
* about to send to be lost immediately. Not very clever. */
await_reply (AWAIT_QDRAIN, 0, NULL, 0);
#ifdef TFTP_DEBUG
grub_printf ("send_rrq ()\n");
{
int i;
char *p;
for (i = 0, p = (char *) &tp; i < len; i++)
if (p[i] >= ' ' && p[i] <= '~')
grub_putchar (p[i]);
else
grub_printf ("\\%x", (unsigned) p[i]);
grub_putchar ('\n');
}
#endif
/* Send the packet. */
return udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
TFTP_PORT, len, &tp);
}
/* Mount the network drive. If the drive is ready, return one, otherwise
return zero. */
int
tftp_mount (void)
{
/* Check if the current drive is the network drive. */
if (current_drive != NETWORK_DRIVE)
return 0;
/* If the drive is not initialized yet, abort. */
if (! network_ready)
return 0;
return 1;
}
/* Read up to SIZE bytes, returned in ADDR. */
int
tftp_read (char *addr, int size)
{
/* How many bytes is read? */
int ret = 0;
#ifdef TFTP_DEBUG
grub_printf ("tftp_read (0x%x, %d)\n", (int) addr, size);
#endif
if (filepos < saved_filepos)
{
/* Uggh.. FILEPOS has been moved backwards. So reopen the file. */
buf_read = 0;
buf_fill (1);
grub_memmove ((char *) &tp, (char *) &saved_tp, saved_len);
len = saved_len;
#ifdef TFTP_DEBUG
{
int i;
grub_printf ("opcode = 0x%x, rrq = ", (unsigned long) tp.opcode);
for (i = 0; i < TFTP_DEFAULTSIZE_PACKET; i++)
{
if (tp.u.rrq[i] >= ' ' && tp.u.rrq[i] <= '~')
grub_putchar (tp.u.rrq[i]);
else
grub_putchar ('*');
}
grub_putchar ('\n');
}
#endif
if (! send_rrq ())
{
errnum = ERR_WRITE;
return 0;
}
}
while (size > 0)
{
int amt = buf_read + saved_filepos - filepos;
/* If the length that can be copied from the buffer is over the
requested size, cut it down. */
if (amt > size)
amt = size;
if (amt > 0)
{
/* Copy the buffer to the supplied memory space. */
grub_memmove (addr, buf + filepos - saved_filepos, amt);
size -= amt;
addr += amt;
filepos += amt;
ret += amt;
/* If the size of the empty space becomes small, move the unused
data forwards. */
if (filepos - saved_filepos > FSYS_BUFLEN / 2)
{
grub_memmove (buf, buf + FSYS_BUFLEN / 2, FSYS_BUFLEN / 2);
buf_read -= FSYS_BUFLEN / 2;
saved_filepos += FSYS_BUFLEN / 2;
}
}
else
{
/* Skip the whole buffer. */
saved_filepos += buf_read;
buf_read = 0;
}
/* Read the data. */
if (size > 0 && ! buf_fill (0))
{
errnum = ERR_READ;
return 0;
}
/* Sanity check. */
if (size > 0 && buf_read == 0)
{
errnum = ERR_READ;
return 0;
}
}
return ret;
}
/* Check if the file DIRNAME really exists. Get the size and save it in
FILEMAX. */
int
tftp_dir (char *dirname)
{
int ch;
#ifdef TFTP_DEBUG
grub_printf ("tftp_dir (%s)\n", dirname);
#endif
/* In TFTP, there is no way to know what files exist. */
if (print_possibilities)
return 1;
/* Don't know the size yet. */
filemax = -1;
reopen:
/* Construct the TFTP request packet. */
tp.opcode = htons (TFTP_RRQ);
/* Terminate the filename. */
ch = nul_terminate (dirname);
/* Make the request string (octet, blksize and tsize). */
len = (grub_sprintf ((char *) tp.u.rrq,
"%s%coctet%cblksize%c%d%ctsize%c0",
dirname, 0, 0, 0, TFTP_MAX_PACKET, 0, 0)
+ sizeof (tp.ip) + sizeof (tp.udp) + sizeof (tp.opcode) + 1);
/* Restore the original DIRNAME. */
dirname[grub_strlen (dirname)] = ch;
/* Save the TFTP packet so that we can reopen the file later. */
grub_memmove ((char *) &saved_tp, (char *) &tp, len);
saved_len = len;
if (! send_rrq ())
{
errnum = ERR_WRITE;
return 0;
}
/* Read the data. */
if (! buf_fill (0))
{
errnum = ERR_FILE_NOT_FOUND;
return 0;
}
if (filemax == -1)
{
/* The server doesn't support the "tsize" option, so we must read
the file twice... */
/* Zero the size of the file. */
filemax = 0;
do
{
/* Add the length of the downloaded data. */
filemax += buf_read;
/* Reset the offset. Just discard the contents of the buffer. */
buf_read = 0;
/* Read the data. */
if (! buf_fill (0))
{
errnum = ERR_READ;
return 0;
}
}
while (! buf_eof);
/* Maybe a few amounts of data remains. */
filemax += buf_read;
/* Retry the open instruction. */
goto reopen;
}
return 1;
}
/* Close the file. */
void
tftp_close (void)
{
#ifdef TFTP_DEBUG
grub_printf ("tftp_close ()\n");
#endif
buf_read = 0;
buf_fill (1);
}

View file

@ -1,825 +0,0 @@
/**************************************************************************
Etherboot - BOOTP/TFTP Bootstrap Program
i82586 NIC driver for Etherboot
Ken Yap, January 1998
***************************************************************************/
/*
* 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.
*/
#include "etherboot.h"
#include "nic.h"
#include "cards.h"
#include "timer.h"
#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
/* Sources of information:
Donald Becker's excellent 3c507 driver in Linux
Intel 82596 data sheet (yes, 82596; it has a 586 compatibility mode)
*/
/* Code below mostly stolen wholesale from 3c507.c driver in Linux */
/*
Details of the i82586.
You'll really need the databook to understand the details of this part,
but the outline is that the i82586 has two separate processing units.
Both are started from a list of three configuration tables, of which only
the last, the System Control Block (SCB), is used after reset-time. The SCB
has the following fields:
Status word
Command word
Tx/Command block addr.
Rx block addr.
The command word accepts the following controls for the Tx and Rx units:
*/
#define CUC_START 0x0100
#define CUC_RESUME 0x0200
#define CUC_SUSPEND 0x0300
#define RX_START 0x0010
#define RX_RESUME 0x0020
#define RX_SUSPEND 0x0030
/* The Rx unit uses a list of frame descriptors and a list of data buffer
descriptors. We use full-sized (1518 byte) data buffers, so there is
a one-to-one pairing of frame descriptors to buffer descriptors.
The Tx ("command") unit executes a list of commands that look like:
Status word Written by the 82586 when the command is done.
Command word Command in lower 3 bits, post-command action in upper 3
Link word The address of the next command.
Parameters (as needed).
Some definitions related to the Command Word are:
*/
#define CMD_EOL 0x8000 /* The last command of the list, stop. */
#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
enum commands {
CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
/*
Details of the EtherLink16 Implementation
The 3c507 and NI5210 are generic shared-memory i82586 implementations.
3c507: The host can map 16K, 32K, 48K, or 64K of the 64K memory into
0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
NI5210: The host can map 8k or 16k at 0x[CDE][048C]000 but we
assume 8k because to have 16k you cannot put a ROM on the NIC.
*/
/* Offsets from the base I/O address. */
#ifdef INCLUDE_3C507
#define SA_DATA 0 /* Station address data, or 3Com signature. */
#define MISC_CTRL 6 /* Switch the SA_DATA banks, and bus config bits. */
#define RESET_IRQ 10 /* Reset the latched IRQ line. */
#define I82586_ATTN 11 /* Frob the 82586 Channel Attention line. */
#define ROM_CONFIG 13
#define MEM_CONFIG 14
#define IRQ_CONFIG 15
#define EL16_IO_EXTENT 16
/* The ID port is used at boot-time to locate the ethercard. */
#define ID_PORT 0x100
#endif
#ifdef INCLUDE_NI5210
#define NI52_RESET 0 /* writing to this address, resets the i82586 */
#define I82586_ATTN 1 /* channel attention, kick the 586 */
#endif
#ifdef INCLUDE_EXOS205
#define EXOS205_RESET 0 /* writing to this address, resets the i82586 */
#define I82586_ATTN 1 /* channel attention, kick the 586 */
#endif
/* Offsets to registers in the mailbox (SCB). */
#define iSCB_STATUS 0x8
#define iSCB_CMD 0xA
#define iSCB_CBL 0xC /* Command BLock offset. */
#define iSCB_RFA 0xE /* Rx Frame Area offset. */
/* Since the 3c507 maps the shared memory window so that the last byte is
at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
We can account for this be setting the 'SBC Base' entry in the ISCP table
below for all the 16 bit offset addresses, and also adding the 'SCB Base'
value to all 24 bit physical addresses (in the SCP table and the TX and RX
Buffer Descriptors).
-Mark
*/
/*
What follows in 'init_words[]' is the "program" that is downloaded to the
82586 memory. It's mostly tables and command blocks, and starts at the
reset address 0xfffff6. This is designed to be similar to the EtherExpress,
thus the unusual location of the SCB at 0x0008.
Even with the additional "don't care" values, doing it this way takes less
program space than initializing the individual tables, and I feel it's much
cleaner.
The databook is particularly useless for the first two structures, I had
to use the Crynwr driver as an example.
The memory setup is as follows:
*/
#define CONFIG_CMD 0x18
#define SET_SA_CMD 0x24
#define SA_OFFSET 0x2A
#define IDLELOOP 0x30
#define TDR_CMD 0x38
#define TDR_TIME 0x3C
#define DUMP_CMD 0x40
#define DIAG_CMD 0x48
#define SET_MC_CMD 0x4E
#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
#define TX_BUF_START 0x0100
#define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */
#define RX_BUF_START 0x1000
#define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */
#define RX_BUF_END (mem_end - mem_start - 20)
/*
That's it: only 86 bytes to set up the beast, including every extra
command available. The 170 byte buffer at DUMP_DATA is shared between the
Dump command (called only by the diagnostic program) and the SetMulticastList
command.
To complete the memory setup you only have to write the station address at
SA_OFFSET and create the Tx & Rx buffer lists.
The Tx command chain and buffer list is setup as follows:
A Tx command table, with the data buffer pointing to...
A Tx data buffer descriptor. The packet is in a single buffer, rather than
chaining together several smaller buffers.
A NoOp command, which initially points to itself,
And the packet data.
A transmit is done by filling in the Tx command table and data buffer,
re-writing the NoOp command, and finally changing the offset of the last
command to point to the current Tx command. When the Tx command is finished,
it jumps to the NoOp, when it loops until the next Tx command changes the
"link offset" in the NoOp. This way the 82586 never has to go through the
slow restart sequence.
The Rx buffer list is set up in the obvious ring structure. We have enough
memory (and low enough interrupt latency) that we can avoid the complicated
Rx buffer linked lists by alway associating a full-size Rx data buffer with
each Rx data frame.
I currently use one transmit buffer starting at TX_BUF_START (0x0100), and
use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
*/
static unsigned short init_words[] = {
/* System Configuration Pointer (SCP). */
#if defined(INCLUDE_3C507)
0x0000, /* Set bus size to 16 bits. */
#else
0x0001, /* Set bus size to 8 bits */
#endif
0,0, /* pad words. */
0x0000,0x0000, /* ISCP phys addr, set in init_82586_mem(). */
/* Intermediate System Configuration Pointer (ISCP). */
0x0001, /* Status word that's cleared when init is done. */
0x0008,0,0, /* SCB offset, (skip, skip) */
/* System Control Block (SCB). */
0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */
CONFIG_CMD, /* Command list pointer, points to Configure. */
RX_BUF_START, /* Rx block list. */
0,0,0,0, /* Error count: CRC, align, buffer, overrun. */
/* 0x0018: Configure command. Change to put MAC data with packet. */
0, CmdConfigure, /* Status, command. */
SET_SA_CMD, /* Next command is Set Station Addr. */
0x0804, /* "4" bytes of config data, 8 byte FIFO. */
0x2e40, /* Magic values, including MAC data location. */
0, /* Unused pad word. */
/* 0x0024: Setup station address command. */
0, CmdSASetup,
SET_MC_CMD, /* Next command. */
0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */
/* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */
0, CmdNOp, IDLELOOP, 0 /* pad */,
/* 0x0038: A unused Time-Domain Reflectometer command. */
0, CmdTDR, IDLELOOP, 0,
/* 0x0040: An unused Dump State command. */
0, CmdDump, IDLELOOP, DUMP_DATA,
/* 0x0048: An unused Diagnose command. */
0, CmdDiagnose, IDLELOOP,
/* 0x004E: An empty set-multicast-list command. */
0, CmdMulticastList, IDLELOOP, 0,
};
/* NIC specific static variables go here */
static unsigned short ioaddr, irq, scb_base;
static Address mem_start, mem_end;
static unsigned short rx_head, rx_tail;
#define read_mem(m,s) fmemcpy((char *)s, m, sizeof(s))
static void setup_rx_buffers(struct nic *nic)
{
Address write_ptr;
unsigned short cur_rx_buf;
static unsigned short rx_cmd[16] = {
0x0000, /* Rx status */
0x0000, /* Rx command, only and last */
RX_BUF_START, /* Link (will be adjusted) */
RX_BUF_START + 22, /* Buffer offset (will be adjusted) */
0x0000, 0x0000, 0x0000, /* Pad for dest addr */
0x0000, 0x0000, 0x0000, /* Pad for source addr */
0x0000, /* Pad for protocol */
0x0000, /* Buffer: Actual count */
-1, /* Buffer: Next (none) */
RX_BUF_START + 0x20, /* Buffer: Address low (+ scb_base) (will be adjusted) */
0x0000, /* Buffer: Address high */
0x8000 | (RX_BUF_SIZE - 0x20)
};
cur_rx_buf = rx_head = RX_BUF_START;
do { /* While there is room for one more buffer */
write_ptr = mem_start + cur_rx_buf;
/* adjust some contents */
rx_cmd[1] = 0x0000;
rx_cmd[2] = cur_rx_buf + RX_BUF_SIZE;
rx_cmd[3] = cur_rx_buf + 22;
rx_cmd[13] = cur_rx_buf + 0x20 + scb_base;
memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(rx_cmd));
rx_tail = cur_rx_buf;
cur_rx_buf += RX_BUF_SIZE;
} while (cur_rx_buf <= RX_BUF_END - RX_BUF_SIZE);
/* Terminate the list by setting the EOL bit and wrap ther pointer
to make the list a ring. */
write_ptr = mem_start + rx_tail;
rx_cmd[1] = 0xC000;
rx_cmd[2] = rx_head;
memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(unsigned short) * 3);
}
static void ack_status(void)
{
unsigned short cmd, status;
unsigned short *shmem = (short *)mem_start;
cmd = (status = shmem[iSCB_STATUS>>1]) & 0xf000;
if (status & 0x100) /* CU suspended? */
cmd |= CUC_RESUME;
if ((status & 0x200) == 0) /* CU not active? */
cmd |= CUC_START;
if (status & 0x010) /* RU suspended? */
cmd |= RX_RESUME;
else if ((status & 0x040) == 0) /* RU not active? */
cmd |= RX_START;
if (cmd == 0) /* Nothing to do */
return;
shmem[iSCB_CMD>>1] = cmd;
#if defined(DEBUG)
printf("Status %hX Command %hX\n", status, cmd);
#endif
outb(0, ioaddr + I82586_ATTN);
}
/**************************************************************************
RESET - Reset adapter
***************************************************************************/
static void i82586_reset(struct nic *nic)
{
unsigned long time;
unsigned short *shmem = (short *)mem_start;
/* put the card in its initial state */
#ifdef INCLUDE_3C507
/* Enable loopback to protect the wire while starting up,
and hold the 586 in reset during the memory initialisation. */
outb(0x20, ioaddr + MISC_CTRL);
#endif
/* Fix the ISCP address and base. */
init_words[3] = scb_base;
init_words[7] = scb_base;
/* Write the words at 0xfff6. */
/* Write the words at 0x0000. */
/* Fill in the station address. */
memcpy((char *)(mem_end - 10), (char *)init_words, 10);
memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
memcpy((char *)mem_start + SA_OFFSET, nic->node_addr, ETH_ALEN);
setup_rx_buffers(nic);
#ifdef INCLUDE_3C507
/* Start the 586 by releasing the reset line, but leave loopback. */
outb(0xA0, ioaddr + MISC_CTRL);
#endif
/* This was time consuming to track down; you need to give two channel
attention signals to reliably start up the i82586. */
outb(0, ioaddr + I82586_ATTN);
time = currticks() + TICKS_PER_SEC; /* allow 1 second to init */
while (
shmem[iSCB_STATUS>>1] == 0)
{
if (currticks() > time)
{
printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
break;
}
}
/* Issue channel-attn -- the 82586 won't start. */
outb(0, ioaddr + I82586_ATTN);
#ifdef INCLUDE_3C507
/* Disable loopback. */
outb(0x80, ioaddr + MISC_CTRL);
#endif
#if defined(DEBUG)
printf("i82586 status %hX, cmd %hX\n",
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
#endif
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int i82586_poll(struct nic *nic)
{
int status;
unsigned short rfd_cmd, next_rx_frame, data_buffer_addr,
frame_status, pkt_len;
unsigned short *shmem = (short *)mem_start + rx_head;
/* return true if there's an ethernet packet ready to read */
if (
((frame_status = shmem[0]) & 0x8000) == 0)
return (0); /* nope */
rfd_cmd = shmem[1];
next_rx_frame = shmem[2];
data_buffer_addr = shmem[3];
pkt_len = shmem[11];
status = 0;
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|| (pkt_len & 0xC000) != 0xC000)
printf("\nRx frame corrupt, discarded");
else if ((frame_status & 0x2000) == 0)
printf("\nRx frame had error");
else
{
/* We have a frame, copy it to our buffer */
pkt_len &= 0x3FFF;
memcpy(nic->packet, (char *)mem_start + rx_head + 0x20, pkt_len);
/* Only packets not from ourself */
if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) != 0)
{
nic->packetlen = pkt_len;
status = 1;
}
}
/* Clear the status word and set EOL on Rx frame */
shmem[0] = 0;
shmem[1] = 0xC000;
*(short *)(mem_start + rx_tail + 2) = 0;
rx_tail = rx_head;
rx_head = next_rx_frame;
ack_status();
return (status);
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
static void i82586_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
Address bptr;
unsigned short type, z;
static unsigned short tx_cmd[11] = {
0x0, /* Tx status */
CmdTx, /* Tx command */
TX_BUF_START+16, /* Next command is a NoOp */
TX_BUF_START+8, /* Data Buffer offset */
0x8000, /* | with size */
0xffff, /* No next data buffer */
TX_BUF_START+22, /* + scb_base */
0x0, /* Buffer address high bits (always zero) */
0x0, /* Nop status */
CmdNOp, /* Nop command */
TX_BUF_START+16 /* Next is myself */
};
unsigned short *shmem = (short *)mem_start + TX_BUF_START;
/* send the packet to destination */
/* adjust some contents */
type = htons(t);
if (s < ETH_ZLEN)
s = ETH_ZLEN;
tx_cmd[4] = (s + ETH_HLEN) | 0x8000;
tx_cmd[6] = TX_BUF_START + 22 + scb_base;
bptr = mem_start + TX_BUF_START;
memcpy((char *)bptr, (char *)tx_cmd, sizeof(tx_cmd));
bptr += sizeof(tx_cmd);
memcpy((char *)bptr, d, ETH_ALEN);
bptr += ETH_ALEN;
memcpy((char *)bptr, nic->node_addr, ETH_ALEN);
bptr += ETH_ALEN;
memcpy((char *)bptr, (char *)&type, sizeof(type));
bptr += sizeof(type);
memcpy((char *)bptr, p, s);
/* Change the offset in the IDLELOOP */
*(unsigned short *)(mem_start + IDLELOOP + 4) = TX_BUF_START;
/* Wait for transmit completion */
while (
(shmem[0] & 0x2000) == 0)
;
/* Change the offset in the IDLELOOP back and
change the final loop to point here */
*(unsigned short *)(mem_start + IDLELOOP + 4) = IDLELOOP;
*(unsigned short *)(mem_start + TX_BUF_START + 20) = IDLELOOP;
ack_status();
}
/**************************************************************************
DISABLE - Turn off ethernet interface
***************************************************************************/
static void i82586_disable(struct nic *nic)
{
unsigned short *shmem = (short *)mem_start;
#if 0
/* Flush the Tx and disable Rx. */
shmem[iSCB_CMD>>1] = RX_SUSPEND | CUC_SUSPEND;
outb(0, ioaddr + I82586_ATTN);
#ifdef INCLUDE_NI5210
outb(0, ioaddr + NI52_RESET);
#endif
#endif /* 0 */
}
#ifdef INCLUDE_3C507
static int t507_probe1(struct nic *nic, unsigned short ioaddr)
{
int i;
Address size;
char mem_config;
char if_port;
if (inb(ioaddr) != '*' || inb(ioaddr+1) != '3'
|| inb(ioaddr+2) != 'C' || inb(ioaddr+3) != 'O')
return (0);
irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
mem_config = inb(ioaddr + MEM_CONFIG);
if (mem_config & 0x20)
{
size = 65536L;
mem_start = 0xf00000L + (mem_config & 0x08 ? 0x080000L
: (((Address)mem_config & 0x3) << 17));
}
else
{
size = ((((Address)mem_config & 0x3) + 1) << 14);
mem_start = 0x0c0000L + (((Address)mem_config & 0x18) << 12);
}
mem_end = mem_start + size;
scb_base = 65536L - size;
if_port = inb(ioaddr + ROM_CONFIG) & 0x80;
/* Get station address */
outb(0x01, ioaddr + MISC_CTRL);
for (i = 0; i < ETH_ALEN; ++i)
{
nic->node_addr[i] = inb(ioaddr+i);
}
printf("\n3c507 ioaddr %#hX, IRQ %d, mem [%#X-%#X], %sternal xcvr, addr %!\n",
ioaddr, irq, mem_start, mem_end, if_port ? "in" : "ex", nic->node_addr);
return (1);
}
/**************************************************************************
PROBE - Look for an adapter, this routine's visible to the outside
***************************************************************************/
struct nic *t507_probe(struct nic *nic, unsigned short *probe_addrs)
{
static unsigned char init_ID_done = 0;
unsigned short lrs_state = 0xff;
static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x280, 0 };
unsigned short *p;
int i;
if (init_ID_done == 0)
{
/* Send the ID sequence to the ID_PORT to enable the board */
outb(0x00, ID_PORT);
for (i = 0; i < 255; ++i)
{
outb(lrs_state, ID_PORT);
lrs_state <<= 1;
if (lrs_state & 0x100)
lrs_state ^= 0xe7;
}
outb(0x00, ID_PORT);
init_ID_done = 1;
}
/* 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)
if (t507_probe1(nic, ioaddr))
break;
if (ioaddr != 0)
{
/* point to NIC specific routines */
i82586_reset(nic);
nic->reset = i82586_reset;
nic->poll = i82586_poll;
nic->transmit = i82586_transmit;
nic->disable = i82586_disable;
return nic;
}
/* else */
{
return 0;
}
}
#endif
#ifdef INCLUDE_NI5210
static int ni5210_probe2(void)
{
unsigned short i;
unsigned short shmem[10];
/* Fix the ISCP address and base. */
init_words[3] = scb_base;
init_words[7] = scb_base;
/* Write the words at 0xfff6. */
/* Write the words at 0x0000. */
memcpy((char *)(mem_end - 10), (char *)init_words, 10);
memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
if (*(unsigned short *)mem_start != 1)
return (0);
outb(0, ioaddr + NI52_RESET);
outb(0, ioaddr + I82586_ATTN);
udelay(32);
i = 50;
while (
shmem[iSCB_STATUS>>1] == 0)
{
if (--i == 0)
{
printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
break;
}
}
/* Issue channel-attn -- the 82586 won't start. */
outb(0, ioaddr + I82586_ATTN);
if (*(unsigned short *)mem_start != 0)
return (0);
return (1);
}
static int ni5210_probe1(struct nic *nic)
{
int i;
static Address mem_addrs[] = {
0xc0000, 0xc4000, 0xc8000, 0xcc000,
0xd0000, 0xd4000, 0xd8000, 0xdc000,
0xe0000, 0xe4000, 0xe8000, 0xec000,
0 };
Address *p;
if (inb(ioaddr + 6) != 0x0 || inb(ioaddr + 7) != 0x55)
return (0);
scb_base = -8192; /* assume 8k memory */
for (p = mem_addrs; (mem_start = *p) != 0; ++p)
if (mem_end = mem_start + 8192, ni5210_probe2())
break;
if (mem_start == 0)
return (0);
/* Get station address */
for (i = 0; i < ETH_ALEN; ++i)
{
nic->node_addr[i] = inb(ioaddr+i);
}
printf("\nNI5210 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
ioaddr, mem_start, mem_end, nic->node_addr);
return (1);
}
struct nic *ni5210_probe(struct nic *nic, unsigned short *probe_addrs)
{
/* missing entries are addresses usually already used */
static unsigned short io_addrs[] = {
0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 0x238,
0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, /*Par*/
0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8,
0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0, /*Ser*/
0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330, 0x338,
0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, /*Par*/
0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, /*Vid,Par*/
0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, /*Ser*/
0x0
};
unsigned short *p;
int i;
/* 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)
if (ni5210_probe1(nic))
break;
if (ioaddr != 0)
{
/* point to NIC specific routines */
i82586_reset(nic);
nic->reset = i82586_reset;
nic->poll = i82586_poll;
nic->transmit = i82586_transmit;
nic->disable = i82586_disable;
return nic;
}
/* else */
{
return 0;
}
}
#endif
#ifdef INCLUDE_EXOS205
/*
* Code to download to I186 in EXOS205
*/
static unsigned char exos_i186_init[] =
{
0x08,0x00,0x14,0x00,0x00,0x00,0xaa,0xfa,0x33,0xc0,0xba,0xfe,0xff,0xef,0xb8,0xf8,
0xff,0xe7,0xa0,0xb8,0x7c,0x00,0xe7,0xa4,0xb8,0xbc,0x80,0xe7,0xa8,0x8c,0xc8,0x8e,
0xd8,0xbb,0x2f,0x0e,0xc6,0x07,0xa5,0x33,0xc9,0xeb,0x00,0xeb,0x00,0xeb,0x00,0xe2,
0xf8,0xbe,0x2c,0x0e,0xba,0x02,0x05,0x33,0xdb,0xb9,0x03,0x00,0xec,0x24,0x0f,0x8a,
0xe0,0x02,0xd8,0x42,0x42,0xec,0x02,0xd8,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,
0x0a,0xc4,0x88,0x04,0x42,0x42,0x46,0xe2,0xe3,0x8a,0xe3,0xd0,0xec,0xd0,0xec,0xd0,
0xec,0xd0,0xec,0x80,0xe3,0x0f,0x02,0xe3,0x80,0xf4,0x05,0xec,0x3a,0xe0,0x74,0x05,
0xc6,0x04,0x5a,0xeb,0xfe,0xc6,0x04,0x55,0x33,0xc0,0x8e,0xd8,0xbe,0x38,0x00,0xc7,
0x04,0xce,0x0e,0x46,0x46,0xc7,0x04,0x00,0xff,0xfb,0xba,0x3c,0x00,0xb8,0x03,0x00,
0xef,0x33,0xdb,0x33,0xc9,0xbd,0x04,0x0f,0x90,0x90,0x90,0x90,0xe2,0xfa,0x43,0x2e,
0x89,0x5e,0x00,0xeb,0xf3,0x52,0xba,0x00,0x06,0xef,0x50,0x53,0x55,0xbd,0xf8,0x0e,
0x2e,0x8b,0x5e,0x00,0x43,0x2e,0x89,0x5e,0x00,0xba,0x22,0x00,0xb8,0x00,0x80,0xef,
0x5d,0x5b,0x58,0x5a,0xcf,0x49,0x4e,0x54,0x52,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,
0x00,0x4c,0x4f,0x4f,0x50,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x30,0x0e,0x00,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,00
};
/* These offsets are from the end of the i186 download code */
#define OFFSET_SEMA 0x1D1
#define OFFSET_ADDR 0x1D7
static int exos205_probe2(void)
{
unsigned short i;
unsigned short shmem[10];
/* Fix the ISCP address and base. */
init_words[3] = scb_base;
init_words[7] = scb_base;
/* Write the words at 0xfff6. */
/* Write the words at 0x0000. */
memcpy((char *)(mem_end - 10), (char *)init_words, 10);
memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
if (*(unsigned short *)mem_start != 1)
return (0);
outb(0, ioaddr + EXOS205_RESET);
outb(0, ioaddr + I82586_ATTN);
i = 50;
while (
shmem[iSCB_STATUS>>1] == 0)
{
if (--i == 0)
{
printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
break;
}
}
/* Issue channel-attn -- the 82586 won't start. */
outb(0, ioaddr + I82586_ATTN);
if (*(unsigned short *)mem_start != 0)
return (0);
return (1);
}
static int exos205_probe1(struct nic *nic)
{
int i;
/* If you know the other addresses please let me know */
static Address mem_addrs[] = {
0xcc000, 0 };
Address *p;
scb_base = -16384; /* assume 8k memory */
for (p = mem_addrs; (mem_start = *p) != 0; ++p)
if (mem_end = mem_start + 16384, exos205_probe2())
break;
if (mem_start == 0)
return (0);
/* Get station address */
for (i = 0; i < ETH_ALEN; ++i)
{
nic->node_addr[i] = inb(ioaddr+i);
}
printf("\nEXOS205 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
ioaddr, mem_start, mem_end, nic->node_addr);
return (1);
}
struct nic *exos205_probe(struct nic *nic, unsigned short *probe_addrs)
{
/* If you know the other addresses, please let me know */
static unsigned short io_addrs[] = {
0x310, 0x0
};
unsigned short *p;
int i;
/* 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)
if (exos205_probe1(nic))
break;
if (ioaddr != 0)
{
/* point to NIC specific routines */
i82586_reset(nic);
nic->reset = i82586_reset;
nic->poll = i82586_poll;
nic->transmit = i82586_transmit;
nic->disable = i82586_disable;
return nic;
}
/* else */
{
return 0;
}
}
#endif

View file

@ -1,564 +0,0 @@
/**************************************************************************
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
***************************************************************************/
/*
* 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.
*/
/* to get some global routines like printf */
#include "etherboot.h"
/* to get the interface to the body of the program */
#include "nic.h"
#ifdef INCLUDE_LANCE
#include "pci.h"
#endif
#include "cards.h"
/* Offsets from base I/O address */
#if defined(INCLUDE_NE2100) || defined(INCLUDE_LANCE)
#define LANCE_ETH_ADDR 0x0
#define LANCE_DATA 0x10
#define LANCE_ADDR 0x12
#define LANCE_RESET 0x14
#define LANCE_BUS_IF 0x16
#define LANCE_TOTAL_SIZE 0x18
#endif
#ifdef INCLUDE_NI6510
#define LANCE_ETH_ADDR 0x8
#define LANCE_DATA 0x0
#define LANCE_ADDR 0x2
#define LANCE_RESET 0x4
#define LANCE_BUS_IF 0x6
#define LANCE_TOTAL_SIZE 0x10
#endif
/* lance_poll() now can use multiple Rx buffers to prevent packet loss. Set
* Set LANCE_LOG_RX_BUFFERS to 0..7 for 1, 2, 4, 8, 16, 32, 64 or 128 Rx
* buffers. Usually 4 (=16 Rx buffers) is a good value. (Andreas Neuhaus)
* Decreased to 2 (=4 Rx buffers) (Ken Yap, 20010305) */
#define LANCE_LOG_RX_BUFFERS 2 /* Use 2^2=4 Rx buffers */
#define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
struct lance_init_block
{
unsigned short mode;
unsigned char phys_addr[ETH_ALEN];
unsigned long filter[2];
Address rx_ring;
Address tx_ring;
};
struct lance_rx_head
{
union {
Address base;
unsigned char addr[4];
} u;
short buf_length; /* 2s complement */
short msg_length;
};
struct lance_tx_head
{
union {
Address base;
unsigned 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[RX_RING_SIZE];
struct lance_tx_head tx_ring;
unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN+4];
unsigned char tbuf[ETH_FRAME_LEN];
/*
* Do not alter the order of the struct members above;
* the hardware depends on the correct alignment.
*/
int rx_idx;
};
#define LANCE_MUST_PAD 0x00000001
#define LANCE_ENABLE_AUTOSELECT 0x00000002
#define LANCE_SELECT_PHONELINE 0x00000004
#define LANCE_MUST_UNRESET 0x00000008
/* 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 const struct lance_chip_type
{
int id_number;
const 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},
{0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
LANCE_ENABLE_AUTOSELECT},
{0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
LANCE_ENABLE_AUTOSELECT},
/* 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},
{0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
LANCE_ENABLE_AUTOSELECT},
{0x2625, "PCnet-FAST III 79C973", /* 79C973 PCInet-FAST III. */
LANCE_ENABLE_AUTOSELECT},
{0x2626, "PCnet/HomePNA 79C978",
LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
{0x0, "PCnet (unknown)",
LANCE_ENABLE_AUTOSELECT},
};
/* Define a macro for converting program addresses to real addresses */
#undef virt_to_bus
#define virt_to_bus(x) ((unsigned long)x)
static int chip_version;
static int lance_version;
static unsigned short ioaddr;
#ifndef INCLUDE_LANCE
static int dma;
#endif
static struct lance_interface *lp;
/* additional 8 bytes for 8-byte alignment space */
#ifdef USE_LOWMEM_BUFFER
#define lance ((char *)0x10000 - (sizeof(struct lance_interface)+8))
#else
static char lance[sizeof(struct lance_interface)+8];
#endif
#ifndef INCLUDE_LANCE
/* 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(dmanr, DMA1_MASK_REG);
else
outb_p(dmanr & 3, DMA2_MASK_REG);
}
static void disable_dma(unsigned int dmanr)
{
if (dmanr <= 3)
outb_p(dmanr | 4, DMA1_MASK_REG);
else
outb_p((dmanr & 3) | 4, DMA2_MASK_REG);
}
/* set mode (above) for a specific DMA channel */
static void set_dma_mode(unsigned int dmanr, char mode)
{
if (dmanr <= 3)
outb_p(mode | dmanr, DMA1_MODE_REG);
else
outb_p(mode | (dmanr&3), DMA2_MODE_REG);
}
#endif /* !INCLUDE_LANCE */
/**************************************************************************
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[lance_version].flags & LANCE_MUST_UNRESET)
outw(0, ioaddr+LANCE_RESET);
if (chip_table[lance_version].flags & LANCE_ENABLE_AUTOSELECT)
{
/* This is 79C960 specific; Turn on auto-select of media
(AUI, BNC). */
outw(0x2, ioaddr+LANCE_ADDR);
/* Don't touch 10base2 power bit. */
outw(inw(ioaddr+LANCE_BUS_IF) | 0x2, ioaddr+LANCE_BUS_IF);
}
/* HomePNA cards need to explicitly pick the phoneline interface.
* Some of these cards have ethernet interfaces as well, this
* code might require some modification for those.
*/
if (chip_table[lance_version].flags & LANCE_SELECT_PHONELINE) {
short media, check ;
/* this is specific to HomePNA cards... */
outw(49, ioaddr+0x12) ;
media = inw(ioaddr+0x16) ;
#ifdef DEBUG
printf("media was %d\n", media) ;
#endif
media &= ~3 ;
media |= 1 ;
#ifdef DEBUG
printf("media changed to %d\n", media) ;
#endif
media &= ~3 ;
media |= 1 ;
outw(49, ioaddr+0x12) ;
outw(media, ioaddr+0x16) ;
outw(49, ioaddr+0x12) ;
check = inw(ioaddr+0x16) ;
#ifdef DEBUG
printf("check %s, media was set properly\n",
check == media ? "passed" : "FAILED" ) ;
#endif
}
/* Re-initialise the LANCE, and start it when done. */
/* Set station address */
for (i = 0; i < ETH_ALEN; ++i)
lp->init_block.phys_addr[i] = nic->node_addr[i];
/* Preset the receive ring headers */
for (i=0; i<RX_RING_SIZE; i++) {
lp->rx_ring[i].buf_length = -ETH_FRAME_LEN-4;
/* OWN */
lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
/* we set the top byte as the very last thing */
lp->rx_ring[i].u.addr[3] = 0x80;
}
lp->rx_idx = 0;
lp->init_block.mode = 0x0; /* enable Rx and Tx */
l = (Address)virt_to_bus(&lp->init_block);
outw(0x1, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw((short)l, ioaddr+LANCE_DATA);
outw(0x2, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw((short)(l >> 16), ioaddr+LANCE_DATA);
outw(0x4, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw(0x915, ioaddr+LANCE_DATA);
outw(0x0, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw(0x4, ioaddr+LANCE_DATA); /* stop */
outw(0x1, ioaddr+LANCE_DATA); /* init */
for (i = 10000; i > 0; --i)
if (inw(ioaddr+LANCE_DATA) & 0x100)
break;
#ifdef DEBUG
if (i <= 0)
printf("Init timed out\n");
#endif
/* Apparently clearing the InitDone bit here triggers a bug
in the '974. (Mark Stockton) */
outw(0x2, ioaddr+LANCE_DATA); /* start */
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int lance_poll(struct nic *nic)
{
int status;
status = lp->rx_ring[lp->rx_idx].u.base >> 24;
if (status & 0x80)
return (0);
#ifdef DEBUG
printf("LANCE packet received rx_ring.u.base %X mcnt %hX csr0 %hX\n",
lp->rx_ring[lp->rx_idx].u.base, lp->rx_ring[lp->rx_idx].msg_length,
inw(ioaddr+LANCE_DATA));
#endif
if (status == 0x3)
memcpy(nic->packet, lp->rbuf[lp->rx_idx], nic->packetlen = lp->rx_ring[lp->rx_idx].msg_length);
/* Andrew Boyd of QNX reports that some revs of the 79C765
clear the buffer length */
lp->rx_ring[lp->rx_idx].buf_length = -ETH_FRAME_LEN-4;
lp->rx_ring[lp->rx_idx].u.addr[3] |= 0x80; /* prime for next receive */
/* I'm not sure if the following is still ok with multiple Rx buffers, but it works */
outw(0x0, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw(0x500, ioaddr+LANCE_DATA); /* clear receive + InitDone */
/* Switch to the next Rx ring buffer */
lp->rx_idx = (lp->rx_idx + 1) & RX_RING_MOD_MASK;
return (status == 0x3);
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
static void lance_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
unsigned long time;
/* copy the packet to ring buffer */
memcpy(lp->tbuf, d, ETH_ALEN); /* dst */
memcpy(&lp->tbuf[ETH_ALEN], nic->node_addr, ETH_ALEN); /* src */
lp->tbuf[ETH_ALEN+ETH_ALEN] = t >> 8; /* type */
lp->tbuf[ETH_ALEN+ETH_ALEN+1] = t; /* type */
memcpy(&lp->tbuf[ETH_HLEN], p, s);
s += ETH_HLEN;
if (chip_table[chip_version].flags & LANCE_MUST_PAD)
while (s < ETH_ZLEN) /* 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(0x0, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR); /* as in the datasheets... */
/* Klaus Espenlaub: the value below was 0x48, but that enabled the
* interrupt line, causing a hang if for some reasone the interrupt
* controller had the LANCE interrupt enabled. I have no idea why
* nobody ran into this before... */
outw(0x08, ioaddr+LANCE_DATA);
/* wait for transmit complete */
time = currticks() + TICKS_PER_SEC; /* 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\n");
(void)inw(ioaddr+LANCE_ADDR);
outw(0x200, ioaddr+LANCE_DATA); /* clear transmit + InitDone */
#ifdef DEBUG
printf("tx_ring.u.base %X tx_ring.buf_length %hX tx_ring.misc %hX csr0 %hX\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)
{
(void)inw(ioaddr+LANCE_RESET);
if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
outw(0, ioaddr+LANCE_RESET);
outw(0, ioaddr+LANCE_ADDR);
outw(0x0004, ioaddr+LANCE_DATA); /* stop the LANCE */
#ifndef INCLUDE_LANCE
disable_dma(dma);
#endif
}
#ifdef INCLUDE_LANCE
static int lance_probe1(struct nic *nic, struct pci_device *pci)
#else
static int lance_probe1(struct nic *nic)
#endif
{
int reset_val ;
unsigned int i;
Address l;
short dma_channels;
#ifndef INCLUDE_LANCE
static const char dmas[] = { 5, 6, 7, 3 };
#endif
reset_val = inw(ioaddr+LANCE_RESET);
outw(reset_val, ioaddr+LANCE_RESET);
#if 1 /* Klaus Espenlaub -- was #ifdef INCLUDE_NE2100*/
outw(0x0, ioaddr+LANCE_ADDR); /* Switch to window 0 */
if (inw(ioaddr+LANCE_DATA) != 0x4)
return (-1);
#endif
outw(88, ioaddr+LANCE_ADDR); /* Get the version of the chip */
if (inw(ioaddr+LANCE_ADDR) != 88)
lance_version = 0;
else
{
chip_version = inw(ioaddr+LANCE_DATA);
outw(89, ioaddr+LANCE_ADDR);
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;
/* using multiple Rx buffer and a single Tx buffer */
lp->init_block.rx_ring = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
lp->init_block.tx_ring = virt_to_bus(&lp->tx_ring) & 0xffffff;
l = virt_to_bus(&lp->init_block);
outw(0x1, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw((unsigned short)l, ioaddr+LANCE_DATA);
outw(0x2, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw((unsigned short)(l >> 16), ioaddr+LANCE_DATA);
outw(0x4, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
outw(0x915, ioaddr+LANCE_DATA);
outw(0x0, ioaddr+LANCE_ADDR);
(void)inw(ioaddr+LANCE_ADDR);
/* Get station address */
for (i = 0; i < ETH_ALEN; ++i) {
nic->node_addr[i] = inb(ioaddr+LANCE_ETH_ADDR+i);
}
#ifndef INCLUDE_LANCE
/* 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(0x7f04, ioaddr+LANCE_DATA); /* clear memory error bits */
set_dma_mode(dma, DMA_MODE_CASCADE);
enable_dma(dma);
outw(0x1, ioaddr+LANCE_DATA); /* 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("\n%s base %#X, DMA %d, addr %!\n",
chip_table[lance_version].name, ioaddr, dma, nic->node_addr);
#else
printf(" %s base %#hX, addr %!\n", chip_table[lance_version].name, ioaddr, nic->node_addr);
#endif
if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
/* Turn on auto-select of media (10baseT or BNC) so that the
* user watch the LEDs. */
outw(0x0002, ioaddr+LANCE_ADDR);
/* Don't touch 10base2 power bit. */
outw(inw(ioaddr+LANCE_BUS_IF) | 0x0002, ioaddr+LANCE_BUS_IF);
}
return (lance_version);
}
/**************************************************************************
PROBE - Look for an adapter, this routine's visible to the outside
***************************************************************************/
#ifdef INCLUDE_LANCE
struct nic *lancepci_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *pci)
#endif
#ifdef INCLUDE_NE2100
struct nic *ne2100_probe(struct nic *nic, unsigned short *probe_addrs)
#endif
#ifdef INCLUDE_NI6510
struct nic *ni6510_probe(struct nic *nic, unsigned short *probe_addrs)
#endif
{
unsigned short *p;
#ifndef INCLUDE_LANCE
static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x360, 0 };
#endif
/* if probe_addrs is 0, then routine can use a hardwired default */
if (probe_addrs == 0) {
#ifdef INCLUDE_LANCE
return 0;
#else
probe_addrs = io_addrs;
#endif
}
for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
{
char offset15, offset14 = inb(ioaddr + 14);
unsigned short pci_cmd;
#ifdef INCLUDE_NE2100
if ((offset14 == 0x52 || offset14 == 0x57) &&
((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
if (lance_probe1(nic) >= 0)
break;
#endif
#ifdef INCLUDE_NI6510
if ((offset14 == 0x00 || offset14 == 0x52) &&
((offset15 = inb(ioaddr + 15)) == 0x55 || offset15 == 0x44))
if (lance_probe1(nic) >= 0)
break;
#endif
#ifdef INCLUDE_LANCE
adjust_pci_device(pci);
if (lance_probe1(nic, pci) >= 0)
break;
#endif
}
/* 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;
}
/* no board found */
return 0;
}

View file

@ -1,187 +0,0 @@
#ifndef _ASM_IO_H
#define _ASM_IO_H
/*
* This file contains the definitions for the x86 IO instructions
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
* versions of the single-IO instructions (inb_p/inw_p/..).
*
* This file is not meant to be obfuscating: it's just complicated
* to (a) handle it all in a way that makes gcc able to optimize it
* as well as possible and (b) trying to avoid writing the same thing
* over and over again with slight variations and possibly making a
* mistake somewhere.
*/
/*
* Thanks to James van Artsdalen for a better timing-fix than
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
*
* On the other hand, I'd like to be sure of a non-existent port:
* I feel a bit unsafe about using 0x80 (should be safe, though)
*
* Linus
*/
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
#else
#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
#endif
#ifdef REALLY_SLOW_IO
#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
#else
#define SLOW_DOWN_IO __SLOW_DOWN_IO
#endif
/*
* readX/writeX() are used to access memory mapped devices. On some
* architectures the memory mapped IO stuff needs to be accessed
* differently. On the x86 architecture, we just read/write the
* memory location directly.
*/
#define readb(addr) (*(volatile unsigned char *) (addr))
#define readw(addr) (*(volatile unsigned short *) (addr))
#define readl(addr) (*(volatile unsigned int *) (addr))
#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
#define memset_io(a,b,c) memset((void *)(a),(b),(c))
#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
/*
* Again, i386 does not require mem IO specific function.
*/
#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d))
/*
* Talk about misusing macros..
*/
#define __OUT1(s,x) \
extern 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,x) \
extern unsigned x __in##s(unsigned short port); \
extern inline unsigned x __in##s(unsigned short port) { unsigned x _v;
#define __IN2(s,s1,s2) \
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
#define __IN(s,s1,x,i...) \
__IN1(s,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
__IN1(s##c,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
__IN1(s##_p,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
__IN1(s##c_p,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
#define __INS(s) \
extern void ins##s(unsigned short port, void * addr, unsigned long count); \
extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define __OUTS(s) \
extern void outs##s(unsigned short port, const void * addr, unsigned long count); \
extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
__IN(b,"", char)
__IN(w,"",short)
__IN(l,"", long)
__OUT(b,"b",char)
__OUT(w,"w",short)
__OUT(l,,int)
__INS(b)
__INS(w)
__INS(l)
__OUTS(b)
__OUTS(w)
__OUTS(l)
/*
* Note that due to the way __builtin_constant_p() works, you
* - can't use it inside a inline function (it will never be true)
* - you don't have to worry about side effects within the __builtin..
*/
#define outb(val,port) \
((__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(val,port) \
((__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(val,port) \
((__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(val,port) \
((__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))
#define outl(val,port) \
((__builtin_constant_p((port)) && (port) < 256) ? \
__outlc((val),(port)) : \
__outl((val),(port)))
#define inl(port) \
((__builtin_constant_p((port)) && (port) < 256) ? \
__inlc(port) : \
__inl(port))
#define outl_p(val,port) \
((__builtin_constant_p((port)) && (port) < 256) ? \
__outlc_p((val),(port)) : \
__outl_p((val),(port)))
#define inl_p(port) \
((__builtin_constant_p((port)) && (port) < 256) ? \
__inlc_p(port) : \
__inl_p(port))
#endif

View file

@ -1,291 +0,0 @@
/*
* Taken from Linux /usr/include/asm/string.h
* All except memcpy, memmove, memset and memcmp removed.
*/
#ifndef _I386_STRING_H_
#define _I386_STRING_H_
/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
* normal. Most of the string-functions are rather heavily hand-optimized,
* see especially strtok,strstr,str[c]spn. They should work, but are not
* very easy to understand. Everything is done entirely within the register
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
* NO Copyright (C) 1991, 1992 Linus Torvalds,
* consider these trivial functions to be PD.
*/
typedef int size_t;
extern void *__memcpy(void * to, const void * from, size_t n);
extern void *__constant_memcpy(void * to, const void * from, size_t n);
extern void *memmove(void * dest,const void * src, size_t n);
extern void *__memset_generic(void * s, char c,size_t count);
extern void *__constant_c_memset(void * s, unsigned long c, size_t count);
extern void *__constant_c_and_count_memset(void * s, unsigned long pattern, size_t count);
extern inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
"cld\n\t"
"rep ; movsl\n\t"
"testb $2,%b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1,%b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
return (to);
}
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as the count is constant.
*/
extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
switch (n) {
case 0:
return to;
case 1:
*(unsigned char *)to = *(const unsigned char *)from;
return to;
case 2:
*(unsigned short *)to = *(const unsigned short *)from;
return to;
case 3:
*(unsigned short *)to = *(const unsigned short *)from;
*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
return to;
case 4:
*(unsigned long *)to = *(const unsigned long *)from;
return to;
case 6: /* for Ethernet addresses */
*(unsigned long *)to = *(const unsigned long *)from;
*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
return to;
case 8:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
return to;
case 12:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
return to;
case 16:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
return to;
case 20:
*(unsigned long *)to = *(const unsigned long *)from;
*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
return to;
}
#define COMMON(x) \
__asm__ __volatile__( \
"cld\n\t" \
"rep ; movsl" \
x \
: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
: "0" (n/4),"1" ((long) to),"2" ((long) from) \
: "memory");
{
int d0, d1, d2;
switch (n % 4) {
case 0: COMMON(""); return to;
case 1: COMMON("\n\tmovsb"); return to;
case 2: COMMON("\n\tmovsw"); return to;
default: COMMON("\n\tmovsw\n\tmovsb"); return to;
}
}
#undef COMMON
}
#define __HAVE_ARCH_MEMCPY
#define memcpy(t, f, n) \
(__builtin_constant_p(n) ? \
__constant_memcpy((t),(f),(n)) : \
__memcpy((t),(f),(n)))
#define __HAVE_ARCH_MEMMOVE
extern inline void * memmove(void * dest,const void * src, size_t n)
{
int d0, d1, d2;
if (dest<src)
__asm__ __volatile__(
"cld\n\t"
"rep\n\t"
"movsb"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),"1" (src),"2" (dest)
: "memory");
else
__asm__ __volatile__(
"std\n\t"
"rep\n\t"
"movsb\n\t"
"cld"
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
:"0" (n),
"1" (n-1+(const char *)src),
"2" (n-1+(char *)dest)
:"memory");
return dest;
}
#define memcmp __builtin_memcmp
extern inline void * __memset_generic(void * s, char c,size_t count)
{
int d0, d1;
__asm__ __volatile__(
"cld\n\t"
"rep\n\t"
"stosb"
: "=&c" (d0), "=&D" (d1)
:"a" (c),"1" (s),"0" (count)
:"memory");
return s;
}
/* we might want to write optimized versions of these later */
#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
/*
* memset(x,0,y) is a reasonably common thing to do, so we want to fill
* things 32 bits at a time even when we don't know the size of the
* area at compile-time..
*/
extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
"cld\n\t"
"rep ; stosl\n\t"
"testb $2,%b3\n\t"
"je 1f\n\t"
"stosw\n"
"1:\ttestb $1,%b3\n\t"
"je 2f\n\t"
"stosb\n"
"2:"
: "=&c" (d0), "=&D" (d1)
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
:"memory");
return (s);
}
/*
* This looks horribly ugly, but the compiler can optimize it totally,
* as we by now know that both pattern and count is constant..
*/
extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
return s;
case 1:
*(unsigned char *)s = pattern;
return s;
case 2:
*(unsigned short *)s = pattern;
return s;
case 3:
*(unsigned short *)s = pattern;
*(2+(unsigned char *)s) = pattern;
return s;
case 4:
*(unsigned long *)s = pattern;
return s;
}
#define COMMON(x) \
__asm__ __volatile__("cld\n\t" \
"rep ; stosl" \
x \
: "=&c" (d0), "=&D" (d1) \
: "a" (pattern),"0" (count/4),"1" ((long) s) \
: "memory")
{
int d0, d1;
switch (count % 4) {
case 0: COMMON(""); return s;
case 1: COMMON("\n\tstosb"); return s;
case 2: COMMON("\n\tstosw"); return s;
default: COMMON("\n\tstosw\n\tstosb"); return s;
}
}
#undef COMMON
}
#define __constant_c_x_memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_c_and_count_memset((s),(c),(count)) : \
__constant_c_memset((s),(c),(count)))
#define __memset(s, c, count) \
(__builtin_constant_p(count) ? \
__constant_count_memset((s),(c),(count)) : \
__memset_generic((s),(c),(count)))
#define __HAVE_ARCH_MEMSET
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__constant_c_x_memset((s),(c),(count)) : \
__memset((s),(c),(count)))
#define __HAVE_ARCH_STRNCMP
static inline int strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
int d0, d1, d2;
__asm__ __volatile__(
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"scasb\n\t"
"jne 3f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %%eax,%%eax\n\t"
"jmp 4f\n"
"3:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"4:"
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
:"1" (cs),"2" (ct),"3" (count));
return __res;
}
#define __HAVE_ARCH_STRLEN
static inline size_t strlen(const char * s)
{
int d0;
register int __res;
__asm__ __volatile__(
"repne\n\t"
"scasb\n\t"
"notl %0\n\t"
"decl %0"
:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
return __res;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,266 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
*
* 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.
*
* 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.
*/
/* Based on "src/misc.c" in etherboot-5.0.5. */
#define GRUB 1
#include <etherboot.h>
void
sleep (int secs)
{
unsigned long tmo = currticks () + secs;
while (currticks () < tmo)
;
}
void
twiddle (void)
{
static unsigned long lastticks = 0;
static int count = 0;
static const char tiddles[]="-\\|/";
unsigned long ticks;
if (debug)
{
if ((ticks = currticks ()) == lastticks)
return;
lastticks = ticks;
grub_putchar (tiddles[(count++) & 3]);
grub_putchar ('\b');
}
}
/* Because Etherboot uses its own formats for the printf family,
define separate definitions from GRUB. */
/**************************************************************************
PRINTF and friends
Formats:
%[#]x - 4 bytes long (8 hex digits, lower case)
%[#]X - 4 bytes long (8 hex digits, upper case)
%[#]hx - 2 bytes int (4 hex digits, lower case)
%[#]hX - 2 bytes int (4 hex digits, upper case)
%[#]hhx - 1 byte int (2 hex digits, lower case)
%[#]hhX - 1 byte int (2 hex digits, upper case)
- optional # prefixes 0x or 0X
%d - decimal int
%c - char
%s - string
%@ - Internet address in ddd.ddd.ddd.ddd notation
%! - Ethernet address in xx:xx:xx:xx:xx:xx notation
Note: width specification not supported
**************************************************************************/
static int
etherboot_vsprintf (char *buf, const char *fmt, const int *dp)
{
char *p, *s;
s = buf;
for ( ; *fmt != '\0'; ++fmt)
{
if (*fmt != '%')
{
buf ? *s++ = *fmt : grub_putchar (*fmt);
continue;
}
if (*++fmt == 's')
{
for (p = (char *) *dp++; *p != '\0'; p++)
buf ? *s++ = *p : grub_putchar (*p);
}
else
{
/* Length of item is bounded */
char tmp[20], *q = tmp;
int alt = 0;
int shift = 28;
if (*fmt == '#')
{
alt = 1;
fmt++;
}
if (*fmt == 'h')
{
shift = 12;
fmt++;
}
if (*fmt == 'h')
{
shift = 4;
fmt++;
}
/*
* Before each format q points to tmp buffer
* After each format q points past end of item
*/
if ((*fmt | 0x20) == 'x')
{
/* With x86 gcc, sizeof(long) == sizeof(int) */
const long *lp = (const long *) dp;
long h = *lp++;
int ncase = (*fmt & 0x20);
dp = (const int *) lp;
if (alt)
{
*q++ = '0';
*q++ = 'X' | ncase;
}
for (; shift >= 0; shift -= 4)
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
}
else if (*fmt == 'd')
{
int i = *dp++;
char *r;
if (i < 0)
{
*q++ = '-';
i = -i;
}
p = q; /* save beginning of digits */
do
{
*q++ = '0' + (i % 10);
i /= 10;
}
while (i);
/* reverse digits, stop in middle */
r = q; /* don't alter q */
while (--r > p)
{
i = *r;
*r = *p;
*p++ = i;
}
}
else if (*fmt == '@')
{
unsigned char *r;
union
{
long l;
unsigned char c[4];
}
u;
const long *lp = (const long *) dp;
u.l = *lp++;
dp = (const int *) lp;
for (r = &u.c[0]; r < &u.c[4]; ++r)
q += etherboot_sprintf (q, "%d.", *r);
--q;
}
else if (*fmt == '!')
{
char *r;
p = (char *) *dp++;
for (r = p + ETH_ALEN; p < r; ++p)
q += etherboot_sprintf (q, "%hhX:", *p);
--q;
}
else if (*fmt == 'c')
*q++ = *dp++;
else
*q++ = *fmt;
/* now output the saved string */
for (p = tmp; p < q; ++p)
buf ? *s++ = *p : grub_putchar (*p);
}
}
if (buf)
*s = '\0';
return (s - buf);
}
int
etherboot_sprintf (char *buf, const char *fmt, ...)
{
return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1);
}
void
etherboot_printf (const char *fmt, ...)
{
(void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1);
}
int
inet_aton (char *p, in_addr *addr)
{
unsigned long ip = 0;
int val;
int i;
for (i = 0; i < 4; i++)
{
val = getdec (&p);
if (val < 0 || val > 255)
return 0;
if (i != 3 && *p++ != '.')
return 0;
ip = (ip << 8) | val;
}
addr->s_addr = htonl (ip);
return 1;
}
int
getdec (char **ptr)
{
char *p = *ptr;
int ret = 0;
if (*p < '0' || *p > '9')
return -1;
while (*p >= '0' && *p <= '9')
{
ret = ret * 10 + (*p - '0');
p++;
}
*ptr = p;
return ret;
}

View file

@ -1,739 +0,0 @@
/* -*- Mode:C; c-basic-offset:4; -*- */
/*
natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
Copyright (C) 2001 Entity Cyber, Inc.
This development of this Etherboot driver was funded by
Sicom Systems: http://www.sicompos.com/
Author: Marty Connor (mdc@thinguin.org)
Adapted from a Linux driver which was written by Donald Becker
This software may be used and distributed according to the terms
of the GNU Public License (GPL), incorporated herein by reference.
Original Copyright Notice:
Written/copyright 1999-2001 by Donald Becker.
This software may be used and distributed according to the terms of
the GNU General Public License (GPL), incorporated herein by reference.
Drivers based on or derived from this code fall under the GPL and must
retain the authorship, copyright and license notice. This file is not
a complete program and may only be used when the entire operating
system is licensed under the GPL. License for under other terms may be
available. Contact the original author for details.
The original author may be reached as becker@scyld.com, or at
Scyld Computing Corporation
410 Severn Ave., Suite 210
Annapolis MD 21403
Support information and updates available at
http://www.scyld.com/network/netsemi.html
References:
http://www.scyld.com/expert/100mbps.html
http://www.scyld.com/expert/NWay.html
Datasheet is available from:
http://www.national.com/pf/DP/DP83815.html
*/
/* Revision History */
/*
29 May 2001 mdc 1.0
Initial Release. Tested with Netgear FA311 and FA312 boards
*/
/* Includes */
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
/* defines */
#define OWN 0x80000000
#define DSIZE 0x00000FFF
#define CRC_SIZE 4
/* Time in ticks before concluding the transmitter is hung. */
#define TX_TIMEOUT (4*TICKS_PER_SEC)
#define TX_BUF_SIZE 1536
#define RX_BUF_SIZE 1536
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
/* helpful macroes if on a big_endian machine for changing byte order.
not strictly needed on Intel */
#define le16_to_cpu(val) (val)
#define cpu_to_le32(val) (val)
#define get_unaligned(ptr) (*(ptr))
#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
#define get_u16(ptr) (*(u16 *)(ptr))
#define virt_to_bus(x) ((unsigned long)x)
#define virt_to_le32desc(addr) virt_to_bus(addr)
enum pcistuff {
PCI_USES_IO = 0x01,
PCI_USES_MEM = 0x02,
PCI_USES_MASTER = 0x04,
PCI_ADDR0 = 0x08,
PCI_ADDR1 = 0x10,
};
/* MMIO operations required */
#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
/* Offsets to the device registers.
Unlike software-only systems, device drivers interact with complex hardware.
It's not useful to define symbolic names for every register bit in the
device.
*/
enum register_offsets {
ChipCmd = 0x00,
ChipConfig = 0x04,
EECtrl = 0x08,
PCIBusCfg = 0x0C,
IntrStatus = 0x10,
IntrMask = 0x14,
IntrEnable = 0x18,
TxRingPtr = 0x20,
TxConfig = 0x24,
RxRingPtr = 0x30,
RxConfig = 0x34,
ClkRun = 0x3C,
WOLCmd = 0x40,
PauseCmd = 0x44,
RxFilterAddr = 0x48,
RxFilterData = 0x4C,
BootRomAddr = 0x50,
BootRomData = 0x54,
SiliconRev = 0x58,
StatsCtrl = 0x5C,
StatsData = 0x60,
RxPktErrs = 0x60,
RxMissed = 0x68,
RxCRCErrs = 0x64,
PCIPM = 0x44,
PhyStatus = 0xC0,
MIntrCtrl = 0xC4,
MIntrStatus = 0xC8,
/* These are from the spec, around page 78... on a separate table. */
PGSEL = 0xCC,
PMDCSR = 0xE4,
TSTDAT = 0xFC,
DSPCFG = 0xF4,
SDCFG = 0x8C
};
/* Bit in ChipCmd. */
enum ChipCmdBits {
ChipReset = 0x100,
RxReset = 0x20,
TxReset = 0x10,
RxOff = 0x08,
RxOn = 0x04,
TxOff = 0x02,
TxOn = 0x01
};
/* Bits in the RxMode register. */
enum rx_mode_bits {
AcceptErr = 0x20,
AcceptRunt = 0x10,
AcceptBroadcast = 0xC0000000,
AcceptMulticast = 0x00200000,
AcceptAllMulticast = 0x20000000,
AcceptAllPhys = 0x10000000,
AcceptMyPhys = 0x08000000
};
typedef struct _BufferDesc {
u32 link;
volatile u32 cmdsts;
u32 bufptr;
u32 software_use;
} BufferDesc;
/* Bits in network_desc.status */
enum desc_status_bits {
DescOwn = 0x80000000,
DescMore = 0x40000000,
DescIntr = 0x20000000,
DescNoCRC = 0x10000000,
DescPktOK = 0x08000000,
RxTooLong = 0x00400000
};
/* Globals */
static int natsemi_debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
const char *nic_name;
static u32 SavedClkRun;
static unsigned short vendor, dev_id;
static unsigned long ioaddr;
static unsigned int cur_rx;
static unsigned int advertising;
static unsigned int rx_config;
static unsigned int tx_config;
/* Note: transmit and receive buffers and descriptors must be
longword aligned
*/
static BufferDesc txd __attribute__ ((aligned(4)));
static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
#ifdef USE_LOWMEM_BUFFER
#define txb ((char *)0x10000 - TX_BUF_SIZE)
#define rxb ((char *)0x10000 - NUM_RX_DESC*RX_BUF_SIZE - TX_BUF_SIZE)
#else
static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] __attribute__ ((aligned(4)));
#endif
/* Function Prototypes */
struct nic *natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci);
static int eeprom_read(long addr, int location);
static int mdio_read(int phy_id, int location);
static void natsemi_init(struct nic *nic);
static void natsemi_reset(struct nic *nic);
static void natsemi_init_rxfilter(struct nic *nic);
static void natsemi_init_txd(struct nic *nic);
static void natsemi_init_rxd(struct nic *nic);
static void natsemi_set_rx_mode(struct nic *nic);
static void natsemi_check_duplex(struct nic *nic);
static void natsemi_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
static int natsemi_poll(struct nic *nic);
static void natsemi_disable(struct nic *nic);
/*
* Function: natsemi_probe
*
* Description: Retrieves the MAC address of the card, and sets up some
* globals required by other routines, and initializes the NIC, making it
* ready to send and receive packets.
*
* Side effects:
* leaves the ioaddress of the natsemi chip in the variable ioaddr.
* leaves the natsemi initialized, and ready to recieve packets.
*
* Returns: struct nic *: pointer to NIC data structure
*/
struct nic *
natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
{
int i;
int prev_eedata;
u32 tmp;
if (io_addrs == 0 || *io_addrs == 0)
return NULL;
/* initialize some commonly used globals */
ioaddr = *io_addrs & ~3;
vendor = pci->vendor;
dev_id = pci->dev_id;
nic_name = pci->name;
adjust_pci_device(pci);
/* natsemi has a non-standard PM control register
* in PCI config space. Some boards apparently need
* to be brought to D0 in this manner.
*/
pcibios_read_config_dword(pci->bus, pci->devfn, PCIPM, &tmp);
if (tmp & (0x03|0x100)) {
/* D0 state, disable PME assertion */
u32 newtmp = tmp & ~(0x03|0x100);
pcibios_write_config_dword(pci->bus, pci->devfn, PCIPM, newtmp);
}
/* get MAC address */
prev_eedata = eeprom_read(ioaddr, 6);
for (i = 0; i < 3; i++) {
int eedata = eeprom_read(ioaddr, i + 7);
nic->node_addr[i*2] = (eedata << 1) + (prev_eedata >> 15);
nic->node_addr[i*2+1] = eedata >> 7;
prev_eedata = eedata;
}
printf("\nnatsemi_probe: MAC addr %! at ioaddr %#hX\n",
nic->node_addr, ioaddr);
printf("natsemi_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id);
/* Reset the chip to erase any previous misconfiguration. */
outl(ChipReset, ioaddr + ChipCmd);
advertising = mdio_read(1, 4);
{
u32 chip_config = inl(ioaddr + ChipConfig);
printf("%s: Transceiver default autoneg. %s "
"10%s %s duplex.\n",
nic_name,
chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
chip_config & 0x4000 ? "0" : "",
chip_config & 0x8000 ? "full" : "half");
}
printf("%s: Transceiver status %hX advertising %hX\n",
nic_name, (int)inl(ioaddr + 0x84), advertising);
/* Disable PME:
* The PME bit is initialized from the EEPROM contents.
* PCI cards probably have PME disabled, but motherboard
* implementations may have PME set to enable WakeOnLan.
* With PME set the chip will scan incoming packets but
* nothing will be written to memory. */
SavedClkRun = inl(ioaddr + ClkRun);
outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
/* initialize device */
natsemi_init(nic);
nic->reset = natsemi_init;
nic->poll = natsemi_poll;
nic->transmit = natsemi_transmit;
nic->disable = natsemi_disable;
return nic;
}
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses.
*/
/* Delay between EEPROM clock transitions.
No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
a delay. */
#define eeprom_delay(ee_addr) inl(ee_addr)
enum EEPROM_Ctrl_Bits {
EE_ShiftClk = 0x04,
EE_DataIn = 0x01,
EE_ChipSelect = 0x08,
EE_DataOut = 0x02
};
#define EE_Write0 (EE_ChipSelect)
#define EE_Write1 (EE_ChipSelect | EE_DataIn)
/* The EEPROM commands include the alway-set leading bit. */
enum EEPROM_Cmds {
EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
};
static int eeprom_read(long addr, int location)
{
int i;
int retval = 0;
int ee_addr = addr + EECtrl;
int read_cmd = location | EE_ReadCmd;
outl(EE_Write0, ee_addr);
/* Shift the read command bits out. */
for (i = 10; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
outl(dataval, ee_addr);
eeprom_delay(ee_addr);
outl(dataval | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
}
outl(EE_ChipSelect, ee_addr);
eeprom_delay(ee_addr);
for (i = 0; i < 16; i++) {
outl(EE_ChipSelect | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
retval |= (inl(ee_addr) & EE_DataOut) ? 1 << i : 0;
outl(EE_ChipSelect, ee_addr);
eeprom_delay(ee_addr);
}
/* Terminate the EEPROM access. */
outl(EE_Write0, ee_addr);
outl(0, ee_addr);
return retval;
}
/* MII transceiver control section.
The 83815 series has an internal transceiver, and we present the
management registers as if they were MII connected. */
static int mdio_read(int phy_id, int location)
{
if (phy_id == 1 && location < 32)
return inl(ioaddr + 0x80 + (location<<2)) & 0xffff;
else
return 0xffff;
}
/* Function: natsemi_init
*
* Description: resets the ethernet controller chip and configures
* registers and data structures required for sending and receiving packets.
*
* Arguments: struct nic *nic: NIC data structure
*
* returns: void.
*/
static void
natsemi_init(struct nic *nic)
{
natsemi_reset(nic);
/* Disable PME:
* The PME bit is initialized from the EEPROM contents.
* PCI cards probably have PME disabled, but motherboard
* implementations may have PME set to enable WakeOnLan.
* With PME set the chip will scan incoming packets but
* nothing will be written to memory. */
outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
natsemi_init_rxfilter(nic);
natsemi_init_txd(nic);
natsemi_init_rxd(nic);
/* Initialize other registers. */
/* Configure the PCI bus bursts and FIFO thresholds. */
/* Configure for standard, in-spec Ethernet. */
if (inl(ioaddr + ChipConfig) & 0x20000000) { /* Full duplex */
tx_config = 0xD0801002;
rx_config = 0x10000020;
} else {
tx_config = 0x10801002;
rx_config = 0x0020;
}
outl(tx_config, ioaddr + TxConfig);
outl(rx_config, ioaddr + RxConfig);
natsemi_check_duplex(nic);
natsemi_set_rx_mode(nic);
outl(RxOn, ioaddr + ChipCmd);
}
/*
* Function: natsemi_reset
*
* Description: soft resets the controller chip
*
* Arguments: struct nic *nic: NIC data structure
*
* Returns: void.
*/
static void
natsemi_reset(struct nic *nic)
{
outl(ChipReset, ioaddr + ChipCmd);
/* On page 78 of the spec, they recommend some settings for "optimum
performance" to be done in sequence. These settings optimize some
of the 100Mbit autodetection circuitry. Also, we only want to do
this for rev C of the chip.
*/
if (inl(ioaddr + SiliconRev) == 0x302) {
outw(0x0001, ioaddr + PGSEL);
outw(0x189C, ioaddr + PMDCSR);
outw(0x0000, ioaddr + TSTDAT);
outw(0x5040, ioaddr + DSPCFG);
outw(0x008C, ioaddr + SDCFG);
}
/* Disable interrupts using the mask. */
outl(0, ioaddr + IntrMask);
outl(0, ioaddr + IntrEnable);
}
/* Function: natsemi_init_rxfilter
*
* Description: sets receive filter address to our MAC address
*
* Arguments: struct nic *nic: NIC data structure
*
* returns: void.
*/
static void
natsemi_init_rxfilter(struct nic *nic)
{
int i;
for (i = 0; i < ETH_ALEN; i += 2) {
outl(i, ioaddr + RxFilterAddr);
outw(nic->node_addr[i] + (nic->node_addr[i+1] << 8), ioaddr + RxFilterData);
}
}
/*
* Function: natsemi_init_txd
*
* Description: initializes the Tx descriptor
*
* Arguments: struct nic *nic: NIC data structure
*
* returns: void.
*/
static void
natsemi_init_txd(struct nic *nic)
{
txd.link = (u32) 0;
txd.cmdsts = (u32) 0;
txd.bufptr = (u32) &txb[0];
/* load Transmit Descriptor Register */
outl((u32) &txd, ioaddr + TxRingPtr);
if (natsemi_debug > 1)
printf("natsemi_init_txd: TX descriptor register loaded with: %X\n",
inl(ioaddr + TxRingPtr));
}
/* Function: natsemi_init_rxd
*
* Description: initializes the Rx descriptor ring
*
* Arguments: struct nic *nic: NIC data structure
*
* Returns: void.
*/
static void
natsemi_init_rxd(struct nic *nic)
{
int i;
cur_rx = 0;
/* init RX descriptor */
for (i = 0; i < NUM_RX_DESC; i++) {
rxd[i].link = (i+1 < NUM_RX_DESC) ? (u32) &rxd[i+1] : (u32) &rxd[0];
rxd[i].cmdsts = (u32) RX_BUF_SIZE;
rxd[i].bufptr = (u32) &rxb[i*RX_BUF_SIZE];
if (natsemi_debug > 1)
printf("natsemi_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n",
i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
}
/* load Receive Descriptor Register */
outl((u32) &rxd[0], ioaddr + RxRingPtr);
if (natsemi_debug > 1)
printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
inl(ioaddr + RxRingPtr));
}
/* Function: natsemi_set_rx_mode
*
* Description:
* sets the receive mode to accept all broadcast packets and packets
* with our MAC address, and reject all multicast packets.
*
* Arguments: struct nic *nic: NIC data structure
*
* Returns: void.
*/
static void natsemi_set_rx_mode(struct nic *nic)
{
u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
outl(rx_mode, ioaddr + RxFilterAddr);
}
static void natsemi_check_duplex(struct nic *nic)
{
int duplex = inl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
if (natsemi_debug)
printf("%s: Setting %s-duplex based on negotiated link"
" capability.\n", nic_name,
duplex ? "full" : "half");
if (duplex) {
rx_config |= 0x10000000;
tx_config |= 0xC0000000;
} else {
rx_config &= ~0x10000000;
tx_config &= ~0xC0000000;
}
outl(tx_config, ioaddr + TxConfig);
outl(rx_config, ioaddr + RxConfig);
}
/* Function: natsemi_transmit
*
* Description: transmits a packet and waits for completion or timeout.
*
* 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
natsemi_transmit(struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
u32 status, to, nstype;
volatile u32 tx_status;
/* Stop the transmitter */
outl(TxOff, ioaddr + ChipCmd);
/* load Transmit Descriptor Register */
outl((u32) &txd, ioaddr + TxRingPtr);
if (natsemi_debug > 1)
printf("natsemi_transmit: TX descriptor register loaded with: %X\n",
inl(ioaddr + TxRingPtr));
memcpy(txb, d, ETH_ALEN);
memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
nstype = htons(t);
memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
memcpy(txb + ETH_HLEN, p, s);
s += ETH_HLEN;
s &= DSIZE;
if (natsemi_debug > 1)
printf("natsemi_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
/* pad to minimum packet size */
while (s < ETH_ZLEN)
txb[s++] = '\0';
/* set the transmit buffer descriptor and enable Transmit State Machine */
txd.bufptr = (u32) &txb[0];
txd.cmdsts = (u32) OWN | s;
/* restart the transmitter */
outl(TxOn, ioaddr + ChipCmd);
if (natsemi_debug > 1)
printf("natsemi_transmit: Queued Tx packet size %d.\n", (int) s);
to = currticks() + TX_TIMEOUT;
while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
/* wait */ ;
if (currticks() >= to) {
printf("natsemi_transmit: TX Timeout! Tx status %X.\n", tx_status);
}
if (!(tx_status & 0x08000000)) {
printf("natsemi_transmit: Transmit error, Tx status %X.\n", tx_status);
}
}
/* Function: natsemi_poll
*
* Description: checks for a received packet and returns it if found.
*
* Arguments: struct nic *nic: NIC data structure
*
* Returns: 1 if packet was received.
* 0 if no packet was received.
*
* Side effects:
* Returns (copies) the packet to the array nic->packet.
* Returns the length of the packet in nic->packetlen.
*/
static int
natsemi_poll(struct nic *nic)
{
u32 rx_status = rxd[cur_rx].cmdsts;
int retstat = 0;
if (natsemi_debug > 2)
printf("natsemi_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status);
if (!(rx_status & OWN))
return retstat;
if (natsemi_debug > 1)
printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
cur_rx, rx_status);
nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
if ((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
/* corrupted packet received */
printf("natsemi_poll: Corrupted packet received, buffer status = %X\n",
rx_status);
retstat = 0;
} else {
/* give packet to higher level routine */
memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
retstat = 1;
}
/* return the descriptor and buffer to receive ring */
rxd[cur_rx].cmdsts = RX_BUF_SIZE;
rxd[cur_rx].bufptr = (u32) &rxb[cur_rx*RX_BUF_SIZE];
if (++cur_rx == NUM_RX_DESC)
cur_rx = 0;
/* re-enable the potentially idle receive state machine */
outl(RxOn, ioaddr + ChipCmd);
return retstat;
}
/* Function: natsemi_disable
*
* Description: Turns off interrupts and stops Tx and Rx engines
*
* Arguments: struct nic *nic: NIC data structure
*
* Returns: void.
*/
static void
natsemi_disable(struct nic *nic)
{
/* Disable interrupts using the mask. */
outl(0, ioaddr + IntrMask);
outl(0, ioaddr + IntrEnable);
/* Stop the chip's Tx and Rx processes. */
outl(RxOff | TxOff, ioaddr + ChipCmd);
/* Restore PME enable bit */
outl(SavedClkRun, ioaddr + ClkRun);
}

View file

@ -1,371 +0,0 @@
/**************************************************************************
Etherboot - BOOTP/TFTP Bootstrap Program
Driver for NI5010.
Code freely taken from Jan-Pascal van Best and Andreas Mohr's
Linux NI5010 driver.
***************************************************************************/
/*
* 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.
*/
/* to get some global routines like printf */
#include "etherboot.h"
/* to get the interface to the body of the program */
#include "nic.h"
/* to get our own prototype */
#include "cards.h"
/* ni5010.h file included verbatim */
/*
* Racal-Interlan ni5010 Ethernet definitions
*
* This is an extension to the Linux operating system, and is covered by the
* same Gnu Public License that covers that work.
*
* copyrights (c) 1996 by Jan-Pascal van Best (jvbest@wi.leidenuniv.nl)
*
* I have done a look in the following sources:
* crynwr-packet-driver by Russ Nelson
*/
#define NI5010_BUFSIZE 2048 /* number of bytes in a buffer */
#define NI5010_MAGICVAL0 0x00 /* magic-values for ni5010 card */
#define NI5010_MAGICVAL1 0x55
#define NI5010_MAGICVAL2 0xAA
#define SA_ADDR0 0x02
#define SA_ADDR1 0x07
#define SA_ADDR2 0x01
/* The number of low I/O ports used by the ni5010 ethercard. */
#define NI5010_IO_EXTENT 32
#define PRINTK(x) if (NI5010_DEBUG) printk x
#define PRINTK2(x) if (NI5010_DEBUG>=2) printk x
#define PRINTK3(x) if (NI5010_DEBUG>=3) printk x
/* The various IE command registers */
#define EDLC_XSTAT (ioaddr + 0x00) /* EDLC transmit csr */
#define EDLC_XCLR (ioaddr + 0x00) /* EDLC transmit "Clear IRQ" */
#define EDLC_XMASK (ioaddr + 0x01) /* EDLC transmit "IRQ Masks" */
#define EDLC_RSTAT (ioaddr + 0x02) /* EDLC receive csr */
#define EDLC_RCLR (ioaddr + 0x02) /* EDLC receive "Clear IRQ" */
#define EDLC_RMASK (ioaddr + 0x03) /* EDLC receive "IRQ Masks" */
#define EDLC_XMODE (ioaddr + 0x04) /* EDLC transmit Mode */
#define EDLC_RMODE (ioaddr + 0x05) /* EDLC receive Mode */
#define EDLC_RESET (ioaddr + 0x06) /* EDLC RESET register */
#define EDLC_TDR1 (ioaddr + 0x07) /* "Time Domain Reflectometry" reg1 */
#define EDLC_ADDR (ioaddr + 0x08) /* EDLC station address, 6 bytes */
/* 0x0E doesn't exist for r/w */
#define EDLC_TDR2 (ioaddr + 0x0f) /* "Time Domain Reflectometry" reg2 */
#define IE_GP (ioaddr + 0x10) /* GP pointer (word register) */
/* 0x11 is 2nd byte of GP Pointer */
#define IE_RCNT (ioaddr + 0x10) /* Count of bytes in rcv'd packet */
/* 0x11 is 2nd byte of "Byte Count" */
#define IE_MMODE (ioaddr + 0x12) /* Memory Mode register */
#define IE_DMA_RST (ioaddr + 0x13) /* IE DMA Reset. write only */
#define IE_ISTAT (ioaddr + 0x13) /* IE Interrupt Status. read only */
#define IE_RBUF (ioaddr + 0x14) /* IE Receive Buffer port */
#define IE_XBUF (ioaddr + 0x15) /* IE Transmit Buffer port */
#define IE_SAPROM (ioaddr + 0x16) /* window on station addr prom */
#define IE_RESET (ioaddr + 0x17) /* any write causes Board Reset */
/* bits in EDLC_XSTAT, interrupt clear on write, status when read */
#define XS_TPOK 0x80 /* transmit packet successful */
#define XS_CS 0x40 /* carrier sense */
#define XS_RCVD 0x20 /* transmitted packet received */
#define XS_SHORT 0x10 /* transmission media is shorted */
#define XS_UFLW 0x08 /* underflow. iff failed board */
#define XS_COLL 0x04 /* collision occurred */
#define XS_16COLL 0x02 /* 16th collision occurred */
#define XS_PERR 0x01 /* parity error */
#define XS_CLR_UFLW 0x08 /* clear underflow */
#define XS_CLR_COLL 0x04 /* clear collision */
#define XS_CLR_16COLL 0x02 /* clear 16th collision */
#define XS_CLR_PERR 0x01 /* clear parity error */
/* bits in EDLC_XMASK, mask/enable transmit interrupts. register is r/w */
#define XM_TPOK 0x80 /* =1 to enable Xmt Pkt OK interrupts */
#define XM_RCVD 0x20 /* =1 to enable Xmt Pkt Rcvd ints */
#define XM_UFLW 0x08 /* =1 to enable Xmt Underflow ints */
#define XM_COLL 0x04 /* =1 to enable Xmt Collision ints */
#define XM_COLL16 0x02 /* =1 to enable Xmt 16th Coll ints */
#define XM_PERR 0x01 /* =1 to enable Xmt Parity Error ints */
/* note: always clear this bit */
#define XM_ALL (XM_TPOK | XM_RCVD | XM_UFLW | XM_COLL | XM_COLL16)
/* bits in EDLC_RSTAT, interrupt clear on write, status when read */
#define RS_PKT_OK 0x80 /* received good packet */
#define RS_RST_PKT 0x10 /* RESET packet received */
#define RS_RUNT 0x08 /* Runt Pkt rcvd. Len < 64 Bytes */
#define RS_ALIGN 0x04 /* Alignment error. not 8 bit aligned */
#define RS_CRC_ERR 0x02 /* Bad CRC on rcvd pkt */
#define RS_OFLW 0x01 /* overflow for rcv FIFO */
#define RS_VALID_BITS ( RS_PKT_OK | RS_RST_PKT | RS_RUNT | RS_ALIGN | RS_CRC_ERR | RS_OFLW )
/* all valid RSTAT bits */
#define RS_CLR_PKT_OK 0x80 /* clear rcvd packet interrupt */
#define RS_CLR_RST_PKT 0x10 /* clear RESET packet received */
#define RS_CLR_RUNT 0x08 /* clear Runt Pckt received */
#define RS_CLR_ALIGN 0x04 /* clear Alignment error */
#define RS_CLR_CRC_ERR 0x02 /* clear CRC error */
#define RS_CLR_OFLW 0x01 /* clear rcv FIFO Overflow */
/* bits in EDLC_RMASK, mask/enable receive interrupts. register is r/w */
#define RM_PKT_OK 0x80 /* =1 to enable rcvd good packet ints */
#define RM_RST_PKT 0x10 /* =1 to enable RESET packet ints */
#define RM_RUNT 0x08 /* =1 to enable Runt Pkt rcvd ints */
#define RM_ALIGN 0x04 /* =1 to enable Alignment error ints */
#define RM_CRC_ERR 0x02 /* =1 to enable Bad CRC error ints */
#define RM_OFLW 0x01 /* =1 to enable overflow error ints */
/* bits in EDLC_RMODE, set Receive Packet mode. register is r/w */
#define RMD_TEST 0x80 /* =1 for Chip testing. normally 0 */
#define RMD_ADD_SIZ 0x10 /* =1 5-byte addr match. normally 0 */
#define RMD_EN_RUNT 0x08 /* =1 enable runt rcv. normally 0 */
#define RMD_EN_RST 0x04 /* =1 to rcv RESET pkt. normally 0 */
#define RMD_PROMISC 0x03 /* receive *all* packets. unusual */
#define RMD_MULTICAST 0x02 /* receive multicasts too. unusual */
#define RMD_BROADCAST 0x01 /* receive broadcasts & normal. usual */
#define RMD_NO_PACKETS 0x00 /* don't receive any packets. unusual */
/* bits in EDLC_XMODE, set Transmit Packet mode. register is r/w */
#define XMD_COLL_CNT 0xf0 /* coll's since success. read-only */
#define XMD_IG_PAR 0x08 /* =1 to ignore parity. ALWAYS set */
#define XMD_T_MODE 0x04 /* =1 to power xcvr. ALWAYS set this */
#define XMD_LBC 0x02 /* =1 for loopback. normally set */
#define XMD_DIS_C 0x01 /* =1 disables contention. normally 0 */
/* bits in EDLC_RESET, write only */
#define RS_RESET 0x80 /* =1 to hold EDLC in reset state */
/* bits in IE_MMODE, write only */
#define MM_EN_DMA 0x80 /* =1 begin DMA xfer, Cplt clrs it */
#define MM_EN_RCV 0x40 /* =1 allows Pkt rcv. clr'd by rcv */
#define MM_EN_XMT 0x20 /* =1 begin Xmt pkt. Cplt clrs it */
#define MM_BUS_PAGE 0x18 /* =00 ALWAYS. Used when MUX=1 */
#define MM_NET_PAGE 0x06 /* =00 ALWAYS. Used when MUX=0 */
#define MM_MUX 0x01 /* =1 means Rcv Buff on system bus */
/* =0 means Xmt Buff on system bus */
/* bits in IE_ISTAT, read only */
#define IS_TDIAG 0x80 /* =1 if Diagnostic problem */
#define IS_EN_RCV 0x20 /* =1 until frame is rcv'd cplt */
#define IS_EN_XMT 0x10 /* =1 until frame is xmt'd cplt */
#define IS_EN_DMA 0x08 /* =1 until DMA is cplt or aborted */
#define IS_DMA_INT 0x04 /* =0 iff DMA done interrupt. */
#define IS_R_INT 0x02 /* =0 iff unmasked Rcv interrupt */
#define IS_X_INT 0x01 /* =0 iff unmasked Xmt interrupt */
/* NIC specific static variables go here */
static unsigned short ioaddr = 0;
static unsigned int bufsize_rcv = 0;
#if 0
static void show_registers(void)
{
printf("XSTAT %hhX ", inb(EDLC_XSTAT));
printf("XMASK %hhX ", inb(EDLC_XMASK));
printf("RSTAT %hhX ", inb(EDLC_RSTAT));
printf("RMASK %hhX ", inb(EDLC_RMASK));
printf("RMODE %hhX ", inb(EDLC_RMODE));
printf("XMODE %hhX ", inb(EDLC_XMODE));
printf("ISTAT %hhX\n", inb(IE_ISTAT));
}
#endif
static void reset_receiver(void)
{
outw(0, IE_GP); /* Receive packet at start of buffer */
outb(RS_VALID_BITS, EDLC_RCLR); /* Clear all pending Rcv interrupts */
outb(MM_EN_RCV, IE_MMODE); /* Enable rcv */
}
/**************************************************************************
RESET - Reset adapter
***************************************************************************/
static void ni5010_reset(struct nic *nic)
{
int i;
/* Reset the hardware here. Don't forget to set the station address. */
outb(RS_RESET, EDLC_RESET); /* Hold up EDLC_RESET while configing board */
outb(0, IE_RESET); /* Hardware reset of ni5010 board */
outb(0, EDLC_XMASK); /* Disable all Xmt interrupts */
outb(0, EDLC_RMASK); /* Disable all Rcv interrupt */
outb(0xFF, EDLC_XCLR); /* Clear all pending Xmt interrupts */
outb(0xFF, EDLC_RCLR); /* Clear all pending Rcv interrupts */
outb(XMD_LBC, EDLC_XMODE); /* Only loopback xmits */
/* Set the station address */
for(i = 0; i < ETH_ALEN; i++)
outb(nic->node_addr[i], EDLC_ADDR + i);
outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
/* Normal packet xmit mode */
outb(RMD_BROADCAST, EDLC_RMODE);
/* Receive broadcast and normal packets */
reset_receiver();
outb(0x00, EDLC_RESET); /* Un-reset the ni5010 */
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int ni5010_poll(struct nic *nic)
{
int rcv_stat;
if (((rcv_stat = inb(EDLC_RSTAT)) & RS_VALID_BITS) != RS_PKT_OK) {
outb(rcv_stat, EDLC_RSTAT); /* Clear the status */
return (0);
}
outb(rcv_stat, EDLC_RCLR); /* Clear the status */
nic->packetlen = inw(IE_RCNT);
/* Read packet into buffer */
outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
outw(0, IE_GP); /* Seek to beginning of packet */
insb(IE_RBUF, nic->packet, nic->packetlen);
return (1);
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
static void ni5010_transmit(struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
unsigned int len;
int buf_offs, xmt_stat;
unsigned long time;
len = s + ETH_HLEN;
if (len < ETH_ZLEN)
len = ETH_ZLEN;
buf_offs = NI5010_BUFSIZE - len;
outb(0, EDLC_RMASK); /* Mask all receive interrupts */
outb(0, IE_MMODE); /* Put Xmit buffer on system bus */
outb(0xFF, EDLC_RCLR); /* Clear out pending rcv interrupts */
outw(buf_offs, IE_GP); /* Point GP at start of packet */
outsb(IE_XBUF, d, ETH_ALEN); /* Put dst in buffer */
outsb(IE_XBUF, nic->node_addr, ETH_ALEN);/* Put src in buffer */
outb(t >> 8, IE_XBUF);
outb(t, IE_XBUF);
outsb(IE_XBUF, p, s); /* Put data in buffer */
while (s++ < ETH_ZLEN - ETH_HLEN) /* Pad to min size */
outb(0, IE_XBUF);
outw(buf_offs, IE_GP); /* Rewrite where packet starts */
/* should work without that outb() (Crynwr used it) */
/*outb(MM_MUX, IE_MMODE);*/
/* Xmt buffer to EDLC bus */
outb(MM_EN_XMT | MM_MUX, IE_MMODE); /* Begin transmission */
/* wait for transmit complete */
while (((xmt_stat = inb(IE_ISTAT)) & IS_EN_XMT) != 0)
;
reset_receiver(); /* Immediately switch to receive */
}
/**************************************************************************
DISABLE - Turn off ethernet interface
***************************************************************************/
static void ni5010_disable(struct nic *nic)
{
outb(0, IE_MMODE);
outb(RS_RESET, EDLC_RESET);
}
static inline int rd_port(void)
{
inb(IE_RBUF);
return inb(IE_SAPROM);
}
static int ni5010_probe1(struct nic *nic)
{
int i, boguscount = 40, data;
/* The tests are from the Linux NI5010 driver
I don't understand it all, but if it works for them... */
if (inb(ioaddr) == 0xFF)
return (0);
while ((rd_port() & rd_port() & rd_port()
& rd_port() & rd_port() & rd_port()) != 0xFF)
{
if (boguscount-- <= 0)
return (0);
}
for (i = 0; i < 32; i++)
if ((data = rd_port()) != 0xFF)
break;
if (data == 0xFF)
return (0);
if (data == SA_ADDR0 && rd_port() == SA_ADDR1 && rd_port() == SA_ADDR2) {
for (i = 0; i < 4; i++)
rd_port();
if (rd_port() != NI5010_MAGICVAL1 || rd_port() != NI5010_MAGICVAL2)
return (0);
} else
return (0);
for (i = 0; i < ETH_ALEN; i++) {
outw(i, IE_GP);
nic->node_addr[i] = inb(IE_SAPROM);
}
printf("\nNI5010 ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
/* get the size of the onboard receive buffer
* higher addresses than bufsize are wrapped into real buffer
* i.e. data for offs. 0x801 is written to 0x1 with a 2K onboard buffer
*/
if (bufsize_rcv == 0) {
outb(1, IE_MMODE); /* Put Rcv buffer on system bus */
outw(0, IE_GP); /* Point GP at start of packet */
outb(0, IE_RBUF); /* set buffer byte 0 to 0 */
for (i = 1; i < 0xFF; i++) {
outw(i << 8, IE_GP); /* Point GP at packet size to be tested */
outb(i, IE_RBUF);
outw(0x0, IE_GP); /* Point GP at start of packet */
data = inb(IE_RBUF);
if (data == i) break;
}
bufsize_rcv = i << 8;
outw(0, IE_GP); /* Point GP at start of packet */
outb(0, IE_RBUF); /* set buffer byte 0 to 0 again */
}
printf("Bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
return (1);
}
/**************************************************************************
PROBE - Look for an adapter, this routine's visible to the outside
***************************************************************************/
struct nic *ni5010_probe(struct nic *nic, unsigned short *probe_addrs)
{
static unsigned short io_addrs[] = {
0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
unsigned short *p;
/* if probe_addrs is 0, then use list above */
if (probe_addrs == 0 || *probe_addrs == 0)
probe_addrs = io_addrs;
for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
if (ni5010_probe1(nic))
break;
}
if (ioaddr == 0)
return (0);
ni5010_reset(nic);
/* point to NIC specific routines */
nic->reset = ni5010_reset;
nic->poll = ni5010_poll;
nic->transmit = ni5010_transmit;
nic->disable = ni5010_disable;
return (nic);
}

View file

@ -1,31 +0,0 @@
/*
* 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.
*/
#ifndef NIC_H
#define NIC_H
/*
* 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 *, const char *d,
unsigned int t, unsigned int s, const char *p));
void (*disable)P((struct nic *));
int flags; /* driver specific flags */
struct rom_info *rom_info; /* -> rom_info from main */
unsigned char *node_addr;
char *packet;
unsigned int packetlen;
void *priv_data; /* driver can hang private data here */
};
#endif /* NIC_H */

View file

@ -1,835 +0,0 @@
/**************************************************************************
ETHERBOOT - 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
3c503 PIO support added by Jim Hague (jim.hague@acm.org) on 2/17/98
RX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99
parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
**************************************************************************/
#include "etherboot.h"
#include "nic.h"
#include "ns8390.h"
#ifdef INCLUDE_NS8390
#include "pci.h"
#endif
#include "cards.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;
static unsigned char eth_drain_receiver;
#ifdef INCLUDE_WD
static struct wd_board {
const 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, 0}
};
#endif
#ifdef INCLUDE_3C503
static unsigned char t503_output; /* AUI or internal xcvr (Thinnet) */
#endif
#if defined(INCLUDE_WD)
#define eth_probe wd_probe
#if defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
#endif
#endif
#if defined(INCLUDE_3C503)
#define eth_probe t503_probe
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || defined(INCLUDE_WD)
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
#endif
#endif
#if defined(INCLUDE_NE)
#define eth_probe ne_probe
#if defined(INCLUDE_NS8390) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
#endif
#endif
#if defined(INCLUDE_NS8390)
#define eth_probe nepci_probe
#if defined(INCLUDE_NE) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
#endif
#endif
#if defined(INCLUDE_3C503)
#define ASIC_PIO _3COM_RFMSB
#else
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
#define ASIC_PIO NE_DATA
#endif
#endif
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
/**************************************************************************
ETH_PIO_READ - Read a frame via Programmed I/O
**************************************************************************/
static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
{
if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
outb(D8390_COMMAND_RD2 |
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
outb(cnt, eth_nic_base + D8390_P0_RBCR0);
outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
outb(src, eth_nic_base + D8390_P0_RSAR0);
outb(src>>8, eth_nic_base + D8390_P0_RSAR1);
outb(D8390_COMMAND_RD0 |
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
#ifdef INCLUDE_3C503
outb(src & 0xff, eth_asic_base + _3COM_DALSB);
outb(src >> 8, eth_asic_base + _3COM_DAMSB);
outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR);
#endif
if (eth_flags & FLAG_16BIT)
cnt >>= 1;
while(cnt--) {
#ifdef INCLUDE_3C503
while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
;
#endif
if (eth_flags & FLAG_16BIT) {
*((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO);
dst += 2;
}
else
*(dst++) = inb(eth_asic_base + ASIC_PIO);
}
#ifdef INCLUDE_3C503
outb(t503_output, eth_asic_base + _3COM_CR);
#endif
}
/**************************************************************************
ETH_PIO_WRITE - Write a frame via Programmed I/O
**************************************************************************/
static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
{
#ifdef COMPEX_RL2000_FIX
unsigned int x;
#endif /* COMPEX_RL2000_FIX */
if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
outb(D8390_COMMAND_RD2 |
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR);
outb(cnt, eth_nic_base + D8390_P0_RBCR0);
outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
outb(dst, eth_nic_base + D8390_P0_RSAR0);
outb(dst>>8, eth_nic_base + D8390_P0_RSAR1);
outb(D8390_COMMAND_RD1 |
D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
#ifdef INCLUDE_3C503
outb(dst & 0xff, eth_asic_base + _3COM_DALSB);
outb(dst >> 8, eth_asic_base + _3COM_DAMSB);
outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR);
#endif
if (eth_flags & FLAG_16BIT)
cnt >>= 1;
while(cnt--)
{
#ifdef INCLUDE_3C503
while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
;
#endif
if (eth_flags & FLAG_16BIT) {
outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO);
src += 2;
}
else
outb(*(src++), eth_asic_base + ASIC_PIO);
}
#ifdef INCLUDE_3C503
outb(t503_output, eth_asic_base + _3COM_CR);
#else
#ifdef COMPEX_RL2000_FIX
for (x = 0;
x < COMPEX_RL2000_TRIES &&
(inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
!= D8390_ISR_RDC;
++x);
if (x >= COMPEX_RL2000_TRIES)
printf("Warning: Compex RL2000 aborted wait!\n");
#endif /* COMPEX_RL2000_FIX */
while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
!= D8390_ISR_RDC);
#endif
}
#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
/**************************************************************************
NS8390_RESET - Reset adapter
**************************************************************************/
static void ns8390_reset(struct nic *nic)
{
int i;
eth_drain_receiver = 0;
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790)
outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
else
#endif
outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
if (eth_flags & FLAG_16BIT)
outb(0x49, eth_nic_base+D8390_P0_DCR);
else
outb(0x48, eth_nic_base+D8390_P0_DCR);
outb(0, eth_nic_base+D8390_P0_RBCR0);
outb(0, eth_nic_base+D8390_P0_RBCR1);
outb(0x20, eth_nic_base+D8390_P0_RCR); /* monitor mode */
outb(2, eth_nic_base+D8390_P0_TCR);
outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART);
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790) outb(0, eth_nic_base + 0x09);
#endif
outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP);
outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND);
outb(0xFF, eth_nic_base+D8390_P0_ISR);
outb(0, eth_nic_base+D8390_P0_IMR);
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790)
outb(D8390_COMMAND_PS1 |
D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
else
#endif
outb(D8390_COMMAND_PS1 |
D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
for (i=0; i<ETH_ALEN; i++)
outb(nic->node_addr[i], eth_nic_base+D8390_P1_PAR0+i);
for (i=0; i<ETH_ALEN; i++)
outb(0xFF, eth_nic_base+D8390_P1_MAR0+i);
outb(eth_rx_start, eth_nic_base+D8390_P1_CURR);
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790)
outb(D8390_COMMAND_PS0 |
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
else
#endif
outb(D8390_COMMAND_PS0 |
D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
outb(0xFF, eth_nic_base+D8390_P0_ISR);
outb(0, eth_nic_base+D8390_P0_TCR);
outb(4, eth_nic_base+D8390_P0_RCR); /* allow broadcast frames */
#ifdef INCLUDE_3C503
/*
* No way to tell whether or not we're supposed to use
* the 3Com's transceiver unless the user tells us.
* 'flags' should have some compile time default value
* which can be changed from the command menu.
*/
t503_output = (nic->flags) ? 0 : _3COM_CR_XSEL;
outb(t503_output, eth_asic_base + _3COM_CR);
#endif
}
static int ns8390_poll(struct nic *nic);
#ifndef INCLUDE_3C503
/**************************************************************************
ETH_RX_OVERRUN - Bring adapter back to work after an RX overrun
**************************************************************************/
static void eth_rx_overrun(struct nic *nic)
{
int start_time;
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790)
outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
else
#endif
outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
/* wait for at least 1.6ms - we wait one timer tick */
start_time = currticks();
while (currticks() - start_time <= 1)
/* Nothing */;
outb(0, eth_nic_base+D8390_P0_RBCR0); /* reset byte counter */
outb(0, eth_nic_base+D8390_P0_RBCR1);
/*
* Linux driver checks for interrupted TX here. This is not necessary,
* because the transmit routine waits until the frame is sent.
*/
/* enter loopback mode and restart NIC */
outb(2, eth_nic_base+D8390_P0_TCR);
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790)
outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
else
#endif
outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
/* clear the RX ring, acknowledge overrun interrupt */
eth_drain_receiver = 1;
while (ns8390_poll(nic))
/* Nothing */;
eth_drain_receiver = 0;
outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR);
/* leave loopback mode - no packets to be resent (see Linux driver) */
outb(0, eth_nic_base+D8390_P0_TCR);
}
#endif /* INCLUDE_3C503 */
/**************************************************************************
NS8390_TRANSMIT - Transmit a frame
**************************************************************************/
static void ns8390_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
#ifdef INCLUDE_3C503
if (!(eth_flags & FLAG_PIO)) {
memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */
memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
*((char *)eth_bmem+12) = t>>8; /* type */
*((char *)eth_bmem+13) = t;
memcpy((char *)eth_bmem+ETH_HLEN, p, s);
s += ETH_HLEN;
while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
}
#endif
#ifdef INCLUDE_WD
/* Memory interface */
if (eth_flags & FLAG_16BIT) {
outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
inb(0x84);
}
if (eth_flags & FLAG_790) {
outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
inb(0x84);
}
inb(0x84);
memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */
memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
*((char *)eth_bmem+12) = t>>8; /* type */
*((char *)eth_bmem+13) = t;
memcpy((char *)eth_bmem+ETH_HLEN, p, s);
s += ETH_HLEN;
while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
if (eth_flags & FLAG_790) {
outb(0, eth_asic_base + WD_MSR);
inb(0x84);
}
if (eth_flags & FLAG_16BIT) {
outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
inb(0x84);
}
#endif
#if defined(INCLUDE_3C503)
if (eth_flags & FLAG_PIO) {
#endif
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
/* Programmed I/O */
unsigned short type;
type = (t >> 8) | (t << 8);
eth_pio_write(d, eth_tx_start<<8, ETH_ALEN);
eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETH_ALEN, ETH_ALEN);
/* bcc generates worse code without (const+const) below */
eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2);
eth_pio_write(p, (eth_tx_start<<8)+ETH_HLEN, s);
s += ETH_HLEN;
if (s < ETH_ZLEN) s = ETH_ZLEN;
#endif
#if defined(INCLUDE_3C503)
}
#endif
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790)
outb(D8390_COMMAND_PS0 |
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
else
#endif
outb(D8390_COMMAND_PS0 |
D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
outb(s, eth_nic_base+D8390_P0_TBCR0);
outb(s>>8, eth_nic_base+D8390_P0_TBCR1);
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790)
outb(D8390_COMMAND_PS0 |
D8390_COMMAND_TXP | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
else
#endif
outb(D8390_COMMAND_PS0 |
D8390_COMMAND_TXP | D8390_COMMAND_RD2 |
D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
}
/**************************************************************************
NS8390_POLL - Wait for a frame
**************************************************************************/
static int ns8390_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;
#ifndef INCLUDE_3C503
/* avoid infinite recursion: see eth_rx_overrun() */
if (!eth_drain_receiver && (inb(eth_nic_base+D8390_P0_ISR) & D8390_ISR_OVW)) {
eth_rx_overrun(nic);
return(0);
}
#endif /* INCLUDE_3C503 */
rstat = inb(eth_nic_base+D8390_P0_RSR);
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(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND);
curr = inb(eth_nic_base+D8390_P1_CURR);
outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND);
if (curr >= eth_memsize) curr=eth_rx_start;
if (curr == next) return(0);
#ifdef INCLUDE_WD
if (eth_flags & FLAG_16BIT) {
outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
inb(0x84);
}
if (eth_flags & FLAG_790) {
outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
inb(0x84);
}
inb(0x84);
#endif
pktoff = next << 8;
if (eth_flags & FLAG_PIO)
eth_pio_read(pktoff, (char *)&pkthdr, 4);
else
memcpy(&pkthdr, (char *)eth_rmem + pktoff, 4);
pktoff += sizeof(pkthdr);
/* incoming length includes FCS so must sub 4 */
len = pkthdr.len - 4;
if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
|| len > ETH_FRAME_LEN) {
printf("Bogus packet, ignoring\n");
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
memcpy(p, (char *)eth_rmem + pktoff, frag);
pktoff = eth_rx_start << 8;
p += frag;
len -= frag;
}
/* read second part */
if (eth_flags & FLAG_PIO)
eth_pio_read(pktoff, p, len);
else
memcpy(p, (char *)eth_rmem + pktoff, len);
ret = 1;
}
#ifdef INCLUDE_WD
if (eth_flags & FLAG_790) {
outb(0, eth_asic_base + WD_MSR);
inb(0x84);
}
if (eth_flags & FLAG_16BIT) {
outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
inb(0x84);
}
inb(0x84);
#endif
next = pkthdr.next; /* frame number of next packet */
if (next == eth_rx_start)
next = eth_memsize;
outb(next-1, eth_nic_base+D8390_P0_BOUND);
return(ret);
}
/**************************************************************************
NS8390_DISABLE - Turn off adapter
**************************************************************************/
static void ns8390_disable(struct nic *nic)
{
}
/**************************************************************************
ETH_PROBE - Look for an adapter
**************************************************************************/
#ifdef INCLUDE_NS8390
struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs,
struct pci_device *pci)
#else
struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
#endif
{
int i;
struct wd_board *brd;
unsigned short chksum;
unsigned char c;
eth_vendor = VENDOR_NONE;
eth_drain_receiver = 0;
#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(eth_asic_base+i);
/* Extra checks to avoid soundcard */
if ((chksum & 0xFF) == 0xFF &&
inb(eth_asic_base+8) != 0xFF &&
inb(eth_asic_base+9) != 0xFF)
break;
}
if (eth_asic_base > WD_HIGH_BASE)
return (0);
/* 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("Unknown WD/SMC NIC type %hhX\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))) {
eth_bmem = (0x80000 |
((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));
} else
eth_bmem = WD_DEFAULT_MEM;
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;
}
}
outb(0x80, eth_asic_base + WD_MSR); /* Reset */
for (i=0; i<ETH_ALEN; i++) {
nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR);
}
printf("\n%s base %#hx, memory %#hx, addr %!\n",
brd->name, eth_asic_base, eth_bmem, nic->node_addr);
if (eth_flags & FLAG_790) {
outb(WD_MSR_MENB, eth_asic_base+WD_MSR);
outb((inb(eth_asic_base+0x04) |
0x80), eth_asic_base+0x04);
outb((((unsigned)eth_bmem >> 13) & 0x0F) |
(((unsigned)eth_bmem >> 11) & 0x40) |
(inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B);
outb((inb(eth_asic_base+0x04) &
~0x80), eth_asic_base+0x04);
} else {
outb((((unsigned)eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
}
if (eth_flags & FLAG_16BIT) {
if (eth_flags & FLAG_790) {
eth_laar = inb(eth_asic_base + WD_LAAR);
outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
} else {
outb((eth_laar =
WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR);
/*
The previous line used to be
WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made
it work for WD8013s. This seems to work for my 8013 boards. I
don't know what is really happening. I wish I had data sheets
or more time to decode the Linux driver. - Ken
*/
}
inb(0x84);
}
#endif
#ifdef INCLUDE_3C503
/******************************************************************
Search for 3Com 3c503 if no WD/SMC cards
******************************************************************/
if (eth_vendor == VENDOR_NONE) {
int idx;
int iobase_reg, membase_reg;
static unsigned short base[] = {
0x300, 0x310, 0x330, 0x350,
0x250, 0x280, 0x2A0, 0x2E0, 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. iobase and membase should */
/* both have a maximum of 1 bit set or be 0. */
iobase_reg = inb(eth_asic_base + _3COM_BCFR);
membase_reg = inb(eth_asic_base + _3COM_PCFR);
if ((iobase_reg & (iobase_reg - 1)) ||
(membase_reg & (membase_reg - 1)))
continue; /* nope */
/* Now get the shared memory address */
eth_flags = 0;
switch (membase_reg) {
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;
case _3COM_PCFR_PIO:
eth_flags |= FLAG_PIO;
eth_bmem = 0;
break;
default:
continue; /* nope */
}
break;
}
if (base[idx] == 0) /* not found */
return (0);
#ifndef T503_SHMEM
eth_flags |= FLAG_PIO; /* force PIO mode */
eth_bmem = 0;
#endif
eth_vendor = VENDOR_3COM;
/* Need this to make ns8390_poll() happy. */
eth_rmem = eth_bmem - 0x2000;
/* Reset NIC and ASIC */
outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR );
outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR );
/* Get our ethernet address */
outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR);
printf("\n3Com 3c503 base %#hx, ", eth_nic_base);
if (eth_flags & FLAG_PIO)
printf("PIO mode");
else
printf("memory %#hx", eth_bmem);
for (i=0; i<ETH_ALEN; i++) {
nic->node_addr[i] = inb(eth_nic_base+i);
}
printf(", %s, addr %!\n", nic->flags ? "AUI" : "internal xcvr",
nic->node_addr);
outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR);
/*
* Initialize GA configuration register. Set bank and enable shared
* mem. We always use bank 1. Disable interrupts.
*/
outb(_3COM_GACFR_RSEL |
_3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR);
outb(0xff, eth_asic_base + _3COM_VPTR2);
outb(0xff, eth_asic_base + _3COM_VPTR1);
outb(0x00, eth_asic_base + _3COM_VPTR0);
/*
* Clear memory and verify that it worked (we use only 8K)
*/
if (!(eth_flags & FLAG_PIO)) {
memset((char *)eth_bmem, 0, 0x2000);
for(i = 0; i < 0x2000; ++i)
if (*(((char *)eth_bmem)+i)) {
printf ("Failed to clear 3c503 shared mem.\n");
return (0);
}
}
/*
* Initialize GA page/start/stop registers.
*/
outb(eth_tx_start, eth_asic_base + _3COM_PSTR);
outb(eth_memsize, eth_asic_base + _3COM_PSPR);
}
#endif
#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
/******************************************************************
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[] = "NE*000 memory";
static unsigned short base[] = {
#ifdef NE_SCAN
NE_SCAN,
#endif
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(c, eth_asic_base + NE_RESET);
inb(0x84);
outb(D8390_COMMAND_STP |
D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND);
outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR);
outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
outb(MEM_8192, eth_nic_base + D8390_P0_PSTART);
outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);
#ifdef NS8390_FORCE_16BIT
eth_flags |= FLAG_16BIT; /* force 16-bit mode */
#endif
eth_pio_write(test, 8192, sizeof(test));
eth_pio_read(8192, testbuf, sizeof(test));
if (!memcmp(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(D8390_DCR_WTS |
D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
outb(MEM_16384, eth_nic_base + D8390_P0_PSTART);
outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP);
eth_pio_write(test, 16384, sizeof(test));
eth_pio_read(16384, testbuf, sizeof(test));
if (!memcmp(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, sizeof(romdata));
for (i=0; i<ETH_ALEN; i++) {
nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
}
printf("\nNE%c000 base %#hx, addr %!\n",
(eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base,
nic->node_addr);
}
#endif
if (eth_vendor == VENDOR_NONE)
return(0);
if (eth_vendor != VENDOR_3COM)
eth_rmem = eth_bmem;
ns8390_reset(nic);
nic->reset = ns8390_reset;
nic->poll = ns8390_poll;
nic->transmit = ns8390_transmit;
nic->disable = ns8390_disable;
return(nic);
}
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,238 +0,0 @@
/**************************************************************************
ETHERBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters
Date: Jun/94
**************************************************************************/
#define VENDOR_NONE 0
#define VENDOR_WD 1
#define VENDOR_NOVELL 2
#define VENDOR_3COM 3
#define FLAG_PIO 0x01
#define FLAG_16BIT 0x02
#define FLAG_790 0x04
#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
/**************************************************************************
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_PIO 0
#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 */
#define COMPEX_RL2000_TRIES 200
/**************************************************************************
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 /* FIFO overrun */
#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:
*/

View file

@ -1,94 +0,0 @@
#ifndef __OSDEP_H__
#define __OSDEP_H__
/*
* 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.
*/
#define __LITTLE_ENDIAN /* x86 */
/* Taken from /usr/include/linux/hfs_sysdep.h */
#if defined(__BIG_ENDIAN)
# if !defined(__constant_htonl)
# define __constant_htonl(x) (x)
# endif
# if !defined(__constant_htons)
# define __constant_htons(x) (x)
# endif
#elif defined(__LITTLE_ENDIAN)
# if !defined(__constant_htonl)
# define __constant_htonl(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)))
# endif
# if !defined(__constant_htons)
# define __constant_htons(x) \
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
(((unsigned short int)(x) & 0xff00) >> 8)))
# endif
#else
# error "Don't know if bytes are big- or little-endian!"
#endif
#define ntohl(x) \
(__builtin_constant_p(x) ? \
__constant_htonl((x)) : \
__swap32(x))
#define htonl(x) \
(__builtin_constant_p(x) ? \
__constant_htonl((x)) : \
__swap32(x))
#define ntohs(x) \
(__builtin_constant_p(x) ? \
__constant_htons((x)) : \
__swap16(x))
#define htons(x) \
(__builtin_constant_p(x) ? \
__constant_htons((x)) : \
__swap16(x))
static inline unsigned long int __swap32(unsigned long int x)
{
__asm__("xchgb %b0,%h0\n\t"
"rorl $16,%0\n\t"
"xchgb %b0,%h0"
: "=q" (x)
: "0" (x));
return x;
}
static inline unsigned short int __swap16(unsigned short int x)
{
__asm__("xchgb %b0,%h0"
: "=q" (x)
: "0" (x));
return x;
}
/* Make routines available to all */
#define swap32(x) __swap32(x)
#define swap16(x) __swap16(x)
#include "linux-asm-io.h"
typedef unsigned long Address;
/* ANSI prototyping macro */
#ifdef __STDC__
#define P(x) x
#else
#define P(x) ()
#endif
#endif
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -1,374 +0,0 @@
/*
Etherboot DEC Tulip driver
adapted by Ken Yap from
FreeBSD netboot DEC 21143 driver
Author: David Sharp
date: Nov/98
Known to work on DEC DE500 using 21143-PC chipset.
Even on cards with the same chipset there can be
incompatablity problems with the way media selection
and status LED settings are done. See comments below.
Some code fragments were taken from verious places,
Ken Yap's etherboot, FreeBSD's if_de.c, and various
Linux related files. DEC's manuals for the 21143 and
SROM format were very helpful. The Linux de driver
development page has a number of links to useful
related information. Have a look at:
ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html
*/
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
#include "otulip.h"
static unsigned short vendor, dev_id;
static unsigned short ioaddr;
static unsigned int *membase;
static unsigned char srom[1024];
#define BUFLEN 1536 /* must be longword divisable */
/* buffers must be longword aligned */
/* transmit descriptor and buffer */
static struct txdesc txd;
/* receive descriptor(s) and buffer(s) */
#define NRXD 4
static struct rxdesc rxd[NRXD];
static int rxd_tail = 0;
#ifdef USE_LOWMEM_BUFFER
#define rxb ((char *)0x10000 - NRXD * BUFLEN)
#define txb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
#else
static unsigned char rxb[NRXD * BUFLEN];
static unsigned char txb[BUFLEN];
#endif
static unsigned char ehdr[ETH_HLEN]; /* buffer for ethernet header */
enum tulip_offsets {
CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
/***************************************************************************/
/* 21143 specific stuff */
/***************************************************************************/
/* XXX assume 33MHz PCI bus, this is not very accurate and should be
used only with gross over estimations of required delay times unless
you tune UADJUST to your specific processor and I/O subsystem */
#define UADJUST 870
static void udelay(unsigned long usec) {
unsigned long i;
for (i=((usec*UADJUST)/33)+1; i>0; i--) (void) TULIP_CSR_READ(csr_0);
}
/* The following srom related code was taken from FreeBSD's if_de.c */
/* with minor alterations to make it work here. the Linux code is */
/* better but this was easier to use */
static void delay_300ns(void)
{
int idx;
for (idx = (300 / 33) + 1; idx > 0; idx--)
(void) TULIP_CSR_READ(csr_busmode);
}
#define EMIT do { TULIP_CSR_WRITE(csr_srom_mii, csr); delay_300ns(); } while (0)
static void srom_idle(void)
{
unsigned bit, csr;
csr = SROMSEL ; EMIT;
csr = SROMSEL | SROMRD; EMIT;
csr ^= SROMCS; EMIT;
csr ^= SROMCLKON; EMIT;
/*
* Write 25 cycles of 0 which will force the SROM to be idle.
*/
for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
csr ^= SROMCLKON; EMIT; /* clock high; data valid */
}
csr ^= SROMCLKOFF; EMIT;
csr ^= SROMCS; EMIT;
csr = 0; EMIT;
}
static void srom_read(void)
{
unsigned idx;
const unsigned bitwidth = SROM_BITWIDTH;
const unsigned cmdmask = (SROMCMD_RD << bitwidth);
const unsigned msb = 1 << (bitwidth + 3 - 1);
unsigned lastidx = (1 << bitwidth) - 1;
srom_idle();
for (idx = 0; idx <= lastidx; idx++) {
unsigned lastbit, data, bits, bit, csr;
csr = SROMSEL ; EMIT;
csr = SROMSEL | SROMRD; EMIT;
csr ^= SROMCSON; EMIT;
csr ^= SROMCLKON; EMIT;
lastbit = 0;
for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1)
{
const unsigned thisbit = bits & msb;
csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
if (thisbit != lastbit) {
csr ^= SROMDOUT; EMIT; /* clock low; invert data */
} else {
EMIT;
}
csr ^= SROMCLKON; EMIT; /* clock high; data valid */
lastbit = thisbit;
}
csr ^= SROMCLKOFF; EMIT;
for (data = 0, bits = 0; bits < 16; bits++) {
data <<= 1;
csr ^= SROMCLKON; EMIT; /* clock high; data valid */
data |= TULIP_CSR_READ(csr_srom_mii) & SROMDIN ? 1 : 0;
csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
}
srom[idx*2] = data & 0xFF;
srom[idx*2+1] = data >> 8;
csr = SROMSEL | SROMRD; EMIT;
csr = 0; EMIT;
}
srom_idle();
}
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
static void tulip_reset(struct nic *nic)
{
int x,cnt=2;
outl(0x00000001, ioaddr + CSR0);
udelay(1000);
/* turn off reset and set cache align=16lword, burst=unlimit */
outl(0x01A08000, ioaddr + CSR0);
/* for some reason the media selection does not take
the first time se it is repeated. */
while(cnt--) {
/* stop TX,RX processes */
if (cnt == 1)
outl(0x32404000, ioaddr + CSR6);
else
outl(0x32000040, ioaddr + CSR6);
/* XXX - media selection is vendor specific and hard coded right
here. This should be fixed to use the hints in the SROM and
allow media selection by the user at runtime. MII support
should also be added. Support for chips other than the
21143 should be added here as well */
/* start set to 10Mbps half-duplex */
/* setup SIA */
outl(0x0, ioaddr + CSR13); /* reset SIA */
outl(0x7f3f, ioaddr + CSR14);
outl(0x8000008, ioaddr + CSR15);
outl(0x0, ioaddr + CSR13);
outl(0x1, ioaddr + CSR13);
outl(0x2404000, ioaddr + CSR6);
/* initalize GP */
outl(0x8af0008, ioaddr + CSR15);
outl(0x50008, ioaddr + CSR15);
/* end set to 10Mbps half-duplex */
if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
/* do stuff for MX98715 */
outl(0x01a80000, ioaddr + CSR6);
outl(0xFFFFFFFF, ioaddr + CSR14);
outl(0x00001000, ioaddr + CSR12);
}
outl(0x0, ioaddr + CSR7); /* disable interrupts */
/* construct setup packet which is used by the 21143 to
program its CAM to recognize interesting MAC addresses */
memset(&txd, 0, sizeof(struct txdesc));
txd.buf1addr = &txb[0];
txd.buf2addr = &txb[0]; /* just in case */
txd.buf1sz = 192; /* setup packet must be 192 bytes */
txd.buf2sz = 0;
txd.control = 0x020; /* setup packet */
txd.status = 0x80000000; /* give ownership to 21143 */
/* construct perfect filter frame */
/* with mac address as first match */
/* and broadcast address for all others */
for(x=0;x<192;x++) txb[x] = 0xff;
txb[0] = nic->node_addr[0];
txb[1] = nic->node_addr[1];
txb[4] = nic->node_addr[2];
txb[5] = nic->node_addr[3];
txb[8] = nic->node_addr[4];
txb[9] = nic->node_addr[5];
outl((unsigned long)&txd, ioaddr + CSR4); /* set xmit buf */
outl(0x2406000, ioaddr + CSR6); /* start transmiter */
udelay(50000); /* wait for the setup packet to be processed */
}
/* setup receive descriptor */
{
int x;
for(x=0;x<NRXD;x++) {
memset(&rxd[x], 0, sizeof(struct rxdesc));
rxd[x].buf1addr = &rxb[x * BUFLEN];
rxd[x].buf2addr = 0; /* not used */
rxd[x].buf1sz = BUFLEN;
rxd[x].buf2sz = 0; /* not used */
rxd[x].control = 0x0;
rxd[x].status = 0x80000000; /* give ownership it to 21143 */
}
rxd[NRXD - 1].control = 0x008; /* Set Receive end of ring on la
st descriptor */
rxd_tail = 0;
}
/* tell DC211XX where to find rx descriptor list */
outl((unsigned long)&rxd[0], ioaddr + CSR3);
/* start the receiver */
outl(0x2406002, ioaddr + CSR6);
}
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static const char padmap[] = {
0, 3, 2, 1};
static void tulip_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
{
unsigned long time;
/* setup ethernet header */
memcpy(ehdr, d, ETH_ALEN);
memcpy(&ehdr[ETH_ALEN], nic->node_addr, ETH_ALEN);
ehdr[ETH_ALEN*2] = (t >> 8) & 0xff;
ehdr[ETH_ALEN*2+1] = t & 0xff;
/* setup the transmit descriptor */
memset(&txd, 0, sizeof(struct txdesc));
txd.buf1addr = &ehdr[0]; /* ethernet header */
txd.buf1sz = ETH_HLEN;
txd.buf2addr = p; /* packet to transmit */
txd.buf2sz = s;
txd.control = 0x188; /* LS+FS+TER */
txd.status = 0x80000000; /* give it to 21143 */
outl(inl(ioaddr + CSR6) & ~0x00004000, ioaddr + CSR6);
outl((unsigned long)&txd, ioaddr + CSR4);
outl(inl(ioaddr + CSR6) | 0x00004000, ioaddr + CSR6);
/* Wait for transmit to complete before returning. not well tested.
time = currticks();
while(txd.status & 0x80000000) {
if (currticks() - time > 20) {
printf("transmit timeout.\n");
break;
}
}
*/
}
/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
static int tulip_poll(struct nic *nic)
{
if (rxd[rxd_tail].status & 0x80000000) return 0;
nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
/* copy packet to working buffer */
/* XXX - this copy could be avoided with a little more work
but for now we are content with it because the optimised
memcpy(, , ) is quite fast */
memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
/* return the descriptor and buffer to recieve ring */
rxd[rxd_tail].status = 0x80000000;
rxd_tail++;
if (rxd_tail == NRXD) rxd_tail = 0;
return 1;
}
static void tulip_disable(struct nic *nic)
{
/* nothing for the moment */
}
/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
struct nic *otulip_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
{
int i;
if (io_addrs == 0 || *io_addrs == 0)
return (0);
vendor = pci->vendor;
dev_id = pci->dev_id;
ioaddr = *io_addrs;
membase = (unsigned int *)pci->membase;
/* wakeup chip */
pcibios_write_config_dword(pci->bus,pci->devfn,0x40,0x00000000);
/* Stop the chip's Tx and Rx processes. */
/* outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6); */
/* Clear the missed-packet counter. */
/* (volatile int)inl(ioaddr + CSR8); */
srom_read();
for (i=0; i < ETH_ALEN; i++)
nic->node_addr[i] = srom[20+i];
printf("Tulip %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
tulip_reset(nic);
nic->reset = tulip_reset;
nic->poll = tulip_poll;
nic->transmit = tulip_transmit;
nic->disable = tulip_disable;
return nic;
}

View file

@ -1,76 +0,0 @@
/* mostly stolen from FreeBSD if_de.c, if_devar.h */
#define TULIP_CSR_READ(csr) (membase[csr*2])
#define CSR_READ(csr) (membase[csr*2])
#define TULIP_CSR_WRITE(csr, val) (membase[csr*2] = val)
#define CSR_WRITE(csr, val) (membase[csr*2] = val)
#define csr_0 0
#define csr_1 1
#define csr_2 2
#define csr_3 3
#define csr_4 4
#define csr_5 5
#define csr_6 6
#define csr_7 7
#define csr_8 8
#define csr_9 9
#define csr_10 10
#define csr_11 11
#define csr_12 12
#define csr_13 13
#define csr_14 14
#define csr_15 15
#define csr_busmode csr_0
#define csr_txpoll csr_1
#define csr_rxpoll csr_2
#define csr_rxlist csr_3
#define csr_txlist csr_4
#define csr_status csr_5
#define csr_command csr_6
#define csr_intr csr_7
#define csr_missed_frames csr_8
#define csr_enetrom csr_9 /* 21040 */
#define csr_reserved csr_10 /* 21040 */
#define csr_full_duplex csr_11 /* 21040 */
#define csr_bootrom csr_10 /* 21041/21140A/?? */
#define csr_gp csr_12 /* 21140* */
#define csr_watchdog csr_15 /* 21140* */
#define csr_gp_timer csr_11 /* 21041/21140* */
#define csr_srom_mii csr_9 /* 21041/21140* */
#define csr_sia_status csr_12 /* 2104x */
#define csr_sia_connectivity csr_13 /* 2104x */
#define csr_sia_tx_rx csr_14 /* 2104x */
#define csr_sia_general csr_15 /* 2104x */
#define SROMSEL 0x0800
#define SROMCS 0x0001
#define SROMCLKON 0x0002
#define SROMCLKOFF 0x0002
#define SROMRD 0x4000
#define SROMWR 0x2000
#define SROM_BITWIDTH 6
#define SROMCMD_RD 6
#define SROMCSON 0x0001
#define SROMDOUT 0x0004
#define SROMDIN 0x0008
struct txdesc {
unsigned long status; /* owner, status */
unsigned long buf1sz:11, /* size of buffer 1 */
buf2sz:11, /* size of buffer 2 */
control:10; /* control bits */
const unsigned char *buf1addr; /* buffer 1 address */
const unsigned char *buf2addr; /* buffer 2 address */
};
struct rxdesc {
unsigned long status; /* owner, status */
unsigned long buf1sz:11, /* size of buffer 1 */
buf2sz:11, /* size of buffer 2 */
control:10; /* control bits */
unsigned char *buf1addr; /* buffer 1 address */
unsigned char *buf2addr; /* buffer 2 address */
};

View file

@ -1,501 +0,0 @@
/*
** 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
*/
/*
* 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.
*/
#include "etherboot.h"
#include "pci.h"
/*#define DEBUG 1*/
#define DEBUG 0
#ifdef CONFIG_PCI_DIRECT
#define PCIBIOS_SUCCESSFUL 0x00
/*
* Functions for accessing PCI configuration space with type 1 accesses
*/
#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
unsigned int where, unsigned char *value)
{
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
*value = inb(0xCFC + (where&3));
return PCIBIOS_SUCCESSFUL;
}
int pcibios_read_config_word (unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned short *value)
{
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
*value = inw(0xCFC + (where&2));
return PCIBIOS_SUCCESSFUL;
}
int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
unsigned int where, unsigned int *value)
{
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
*value = inl(0xCFC);
return PCIBIOS_SUCCESSFUL;
}
int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
unsigned int where, unsigned char value)
{
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
outb(value, 0xCFC + (where&3));
return PCIBIOS_SUCCESSFUL;
}
int pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
unsigned int where, unsigned short value)
{
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
outw(value, 0xCFC + (where&2));
return PCIBIOS_SUCCESSFUL;
}
int pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value)
{
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
outl(value, 0xCFC);
return PCIBIOS_SUCCESSFUL;
}
#undef CONFIG_CMD
#else /* CONFIG_PCI_DIRECT not defined */
static struct {
unsigned long address;
unsigned short segment;
} bios32_indirect = { 0, KERN_CODE_SEG };
static long pcibios_entry;
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__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%edi)"
#else
"lcall *(%%edi)"
#endif
: "=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\n", service);
return 0;
default: /* Shouldn't happen */
printf("bios32_service(%d) : returned %#X, mail drew@colorado.edu\n",
service, return_code);
return 0;
}
}
int pcibios_read_config_byte(unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned char *value)
{
unsigned long ret;
unsigned long bx = (bus << 8) | device_fn;
unsigned long flags;
save_flags(flags);
__asm__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%esi)\n\t"
#else
"lcall *(%%esi)\n\t"
#endif
"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;
}
int pcibios_read_config_word(unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned short *value)
{
unsigned long ret;
unsigned long bx = (bus << 8) | device_fn;
unsigned long flags;
save_flags(flags);
__asm__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%esi)\n\t"
#else
"lcall *(%%esi)\n\t"
#endif
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=c" (*value),
"=a" (ret)
: "1" (PCIBIOS_READ_CONFIG_WORD),
"b" (bx),
"D" ((long) where),
"S" (&pci_indirect));
restore_flags(flags);
return (int) (ret & 0xff00) >> 8;
}
int pcibios_read_config_dword(unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned int *value)
{
unsigned long ret;
unsigned long bx = (bus << 8) | device_fn;
unsigned long flags;
save_flags(flags);
__asm__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%esi)\n\t"
#else
"lcall *(%%esi)\n\t"
#endif
"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;
}
int pcibios_write_config_byte (unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned char value)
{
unsigned long ret;
unsigned long bx = (bus << 8) | device_fn;
unsigned long flags;
save_flags(flags); cli();
__asm__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%esi)\n\t"
#else
"lcall *(%%esi)\n\t"
#endif
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (ret)
: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
"c" (value),
"b" (bx),
"D" ((long) where),
"S" (&pci_indirect));
restore_flags(flags);
return (int) (ret & 0xff00) >> 8;
}
int pcibios_write_config_word (unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned short value)
{
unsigned long ret;
unsigned long bx = (bus << 8) | device_fn;
unsigned long flags;
save_flags(flags); cli();
__asm__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%esi)\n\t"
#else
"lcall *(%%esi)\n\t"
#endif
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (ret)
: "0" (PCIBIOS_WRITE_CONFIG_WORD),
"c" (value),
"b" (bx),
"D" ((long) where),
"S" (&pci_indirect));
restore_flags(flags);
return (int) (ret & 0xff00) >> 8;
}
int pcibios_write_config_dword (unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned int value)
{
unsigned long ret;
unsigned long bx = (bus << 8) | device_fn;
unsigned long flags;
save_flags(flags); cli();
__asm__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%esi)\n\t"
#else
"lcall *(%%esi)\n\t"
#endif
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (ret)
: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
"c" (value),
"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__(
#ifdef ABSOLUTE_WITHOUT_ASTERISK
"lcall (%%edi)\n\t"
#else
"lcall *(%%edi)\n\t"
#endif
"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????\n");
pcibios_entry = 0;
}
#if DEBUG
if (pcibios_entry) {
printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
" entry at %#X\n", major_revision,
minor_revision, pcibios_entry);
}
#endif
}
}
static void pcibios_init(void)
{
union bios32 *check;
unsigned char sum;
int i, length;
unsigned long bios32_entry = 0;
/*
* 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 %#X, mail drew@colorado.edu\n",
check->fields.revision, check);
continue;
}
#if DEBUG
printf("pcibios_init : BIOS32 Service Directory "
"structure at %#X\n", check);
#endif
if (!bios32_entry) {
if (check->fields.entry >= 0x100000) {
printf("pcibios_init: entry in high "
"memory, giving up\n");
return;
} else {
bios32_entry = check->fields.entry;
#if DEBUG
printf("pcibios_init : BIOS32 Service Directory"
" entry at %#X\n", bios32_entry);
#endif
bios32_indirect.address = bios32_entry;
}
}
}
if (bios32_entry)
check_pcibios();
}
#endif /* CONFIG_PCI_DIRECT not defined*/
static void scan_bus(struct pci_device *pcidev)
{
unsigned int devfn, l, bus, buses;
unsigned char hdr_type = 0;
unsigned short vendor, device;
unsigned int membase, ioaddr, romaddr;
int i, reg;
unsigned int pci_ioaddr = 0;
/* Scan all PCI buses, until we find our card.
* We could be smart only scan the required busses but that
* is error prone, and tricky.
* By scanning all possible pci busses in order we should find
* our card eventually.
*/
buses=256;
for (bus = 0; bus < buses; ++bus) {
for (devfn = 0; devfn < 0xff; ++devfn) {
if (PCI_FUNC (devfn) == 0)
pcibios_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
else if (!(hdr_type & 0x80)) /* not a multi-function device */
continue;
pcibios_read_config_dword(bus, 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 %hhX, function %hhX, vendor %hX, device %hX\n",
bus, devfn, vendor, device);
#endif
for (i = 0; pcidev[i].vendor != 0; i++) {
if (vendor != pcidev[i].vendor
|| device != pcidev[i].dev_id)
continue;
pcidev[i].devfn = devfn;
pcidev[i].bus = bus;
for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
continue;
/* Strip the I/O address out of the returned value */
ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
/* Get the memory base address */
pcibios_read_config_dword(bus, devfn,
PCI_BASE_ADDRESS_1, &membase);
/* Get the ROM base address */
pcibios_read_config_dword(bus, devfn, PCI_ROM_ADDRESS, &romaddr);
romaddr >>= 10;
printf("Found %s at %#hx, ROM address %#hx\n",
pcidev[i].name, ioaddr, romaddr);
/* Take the first one or the one that matches in boot ROM address */
if (pci_ioaddr == 0 || romaddr == ((unsigned long) rom.rom_segment << 4)) {
pcidev[i].membase = membase;
pcidev[i].ioaddr = ioaddr;
return;
}
}
}
}
}
}
void eth_pci_init(struct pci_device *pcidev)
{
#ifndef CONFIG_PCI_DIRECT
pcibios_init();
if (!pcibios_entry) {
printf("pci_init: no BIOS32 detected\n");
return;
}
#endif
scan_bus(pcidev);
/* return values are in pcidev structures */
}
/*
* Set device to be a busmaster in case BIOS neglected to do so.
* Also adjust PCI latency timer to a reasonable value, 32.
*/
void adjust_pci_device(struct pci_device *p)
{
unsigned short new_command, pci_command;
unsigned char pci_latency;
pcibios_read_config_word(p->bus, p->devfn, PCI_COMMAND, &pci_command);
new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
if (pci_command != new_command) {
printf("The PCI BIOS has not enabled this device!\nUpdating PCI command %hX->%hX. pci_bus %hhX pci_device_fn %hhX\n",
pci_command, new_command, p->bus, p->devfn);
pcibios_write_config_word(p->bus, p->devfn, PCI_COMMAND, new_command);
}
pcibios_read_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < 32) {
printf("PCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n", pci_latency);
pcibios_write_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, 32);
}
}

View file

@ -1,192 +0,0 @@
#ifndef PCI_H
#define PCI_H
/*
** 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
*/
/*
* 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.
*/
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEM 0x2 /* Enable response in mem space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#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_REVISION 0x08 /* 8 bits */
#define PCI_CLASS_CODE 0x0b /* 8 bits */
#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
#ifndef PCI_BASE_ADDRESS_IO_MASK
#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
#endif
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
#define PCI_ROM_ADDRESS 0x30 /* 32 bits */
#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM,
bits 31..11 are address,
10..2 are reserved */
#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 cli() __asm__ __volatile__ ("cli": : :"memory")
#define restore_flags(x) \
__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
#define PCI_VENDOR_ID_ADMTEK 0x1317
#define PCI_DEVICE_ID_ADMTEK_0985 0x0985
#define PCI_VENDOR_ID_REALTEK 0x10ec
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
#define PCI_VENDOR_ID_WINBOND2 0x1050
#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
#define PCI_DEVICE_ID_WINBOND2_89C840 0x0840
#define PCI_VENDOR_ID_COMPEX 0x11f6
#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
#define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011
#define PCI_VENDOR_ID_KTI 0x8e2e
#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
#define PCI_VENDOR_ID_NETVIN 0x4a14
#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
#define PCI_VENDOR_ID_HOLTEK 0x12c3
#define PCI_DEVICE_ID_HOLTEK_HT80232 0x0058
#define PCI_VENDOR_ID_3COM 0x10b7
#define PCI_DEVICE_ID_3COM_3C590 0x5900
#define PCI_DEVICE_ID_3COM_3C595 0x5950
#define PCI_DEVICE_ID_3COM_3C595_1 0x5951
#define PCI_DEVICE_ID_3COM_3C595_2 0x5952
#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
#define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_82557 0x1229
#define PCI_DEVICE_ID_INTEL_82559ER 0x1209
#define PCI_DEVICE_ID_INTEL_ID1029 0x1029
#define PCI_DEVICE_ID_INTEL_ID1030 0x1030
#define PCI_DEVICE_ID_INTEL_82562 0x2449
#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
#define PCI_VENDOR_ID_AMD_HOMEPNA 0x1022
#define PCI_DEVICE_ID_AMD_HOMEPNA 0x2001
#define PCI_VENDOR_ID_SMC_1211 0x1113
#define PCI_DEVICE_ID_SMC_1211 0x1211
#define PCI_VENDOR_ID_DEC 0x1011
#define PCI_DEVICE_ID_DEC_TULIP 0x0002
#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
#define PCI_DEVICE_ID_DEC_21142 0x0019
#define PCI_VENDOR_ID_SMC 0x10B8
#ifndef PCI_DEVICE_ID_SMC_EPIC100
# define PCI_DEVICE_ID_SMC_EPIC100 0x0005
#endif
#define PCI_VENDOR_ID_MACRONIX 0x10d9
#define PCI_DEVICE_ID_MX987x5 0x0531
#define PCI_VENDOR_ID_LINKSYS 0x11AD
#define PCI_DEVICE_ID_LC82C115 0xC115
#define PCI_VENDOR_ID_VIATEC 0x1106
#define PCI_DEVICE_ID_VIA_RHINE_I 0x3043
#define PCI_DEVICE_ID_VIA_VT6102 0x3065
#define PCI_DEVICE_ID_VIA_86C100A 0x6100
#define PCI_VENDOR_ID_DAVICOM 0x1282
#define PCI_DEVICE_ID_DM9009 0x9009
#define PCI_DEVICE_ID_DM9102 0x9102
#define PCI_VENDOR_ID_SIS 0x1039
#define PCI_DEVICE_ID_SIS900 0x0900
#define PCI_DEVICE_ID_SIS7016 0x7016
#define PCI_VENDOR_ID_DLINK 0x1186
#define PCI_DEVICE_ID_DFE530TXP 0x1300
#define PCI_VENDOR_ID_NS 0x100B
#define PCI_DEVICE_ID_DP83815 0x0020
#define PCI_VENDOR_ID_OLICOM 0x108d
#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
struct pci_device {
unsigned short vendor, dev_id;
const char *name;
unsigned int membase;
unsigned short ioaddr;
unsigned char devfn;
unsigned char bus;
};
extern void eth_pci_init(struct pci_device *);
extern int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char *value);
extern int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char value);
extern int pcibios_read_config_word(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short *value);
extern int pcibios_write_config_word (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short value);
extern int pcibios_read_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int *value);
extern int pcibios_write_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value);
void adjust_pci_device(struct pci_device *p);
#endif /* PCI_H */

View file

@ -1,458 +0,0 @@
/* rtl8139.c - etherboot driver for the Realtek 8139 chipset
ported from the linux driver written by Donald Becker
by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
changes to the original driver:
- removed support for interrupts, switching to polling mode (yuck!)
- removed support for the 8129 chip (external MII)
*/
/*********************************************************************/
/* Revision History */
/*********************************************************************/
/*
06 Apr 2001 ken_yap@users.sourceforge.net (Ken Yap)
Following email from Hyun-Joon Cha, added a disable routine, otherwise
NIC remains live and can crash the kernel later.
4 Feb 2000 espenlaub@informatik.uni-ulm.de (Klaus Espenlaub)
Shuffled things around, removed the leftovers from the 8129 support
that was in the Linux driver and added a bit more 8139 definitions.
Moved the 8K receive buffer to a fixed, available address outside the
0x98000-0x9ffff range. This is a bit of a hack, but currently the only
way to make room for the Etherboot features that need substantial amounts
of code like the ANSI console support. Currently the buffer is just below
0x10000, so this even conforms to the tagged boot image specification,
which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My
interpretation of this "reserved" is that Etherboot may do whatever it
likes, as long as its environment is kept intact (like the BIOS
variables). Hopefully fixed rtl_poll() once and for all. The symptoms
were that if Etherboot was left at the boot menu for several minutes, the
first eth_poll failed. Seems like I am the only person who does this.
First of all I fixed the debugging code and then set out for a long bug
hunting session. It took me about a week full time work - poking around
various places in the driver, reading Don Becker's and Jeff Garzik's Linux
driver and even the FreeBSD driver (what a piece of crap!) - and
eventually spotted the nasty thing: the transmit routine was acknowledging
each and every interrupt pending, including the RxOverrun and RxFIFIOver
interrupts. This confused the RTL8139 thoroughly. It destroyed the
Rx ring contents by dumping the 2K FIFO contents right where we wanted to
get the next packet. Oh well, what fun.
18 Jan 2000 mdc@thinguin.org (Marty Connor)
Drastically simplified error handling. Basically, if any error
in transmission or reception occurs, the card is reset.
Also, pointed all transmit descriptors to the same buffer to
save buffer space. This should decrease driver size and avoid
corruption because of exceeding 32K during runtime.
28 Jul 1999 (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de)
rtl_poll was quite broken: it used the RxOK interrupt flag instead
of the RxBufferEmpty flag which often resulted in very bad
transmission performace - below 1kBytes/s.
*/
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
#include "timer.h"
#define RTL_TIMEOUT (1*TICKS_PER_SEC)
/* PCI Tuning Parameters
Threshold is bytes transferred to chip before transmission starts. */
#define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */
#define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */
#define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */
#define TX_DMA_BURST 4 /* Calculate as 16<<val. */
#define NUM_TX_DESC 4 /* Number of Tx descriptor registers. */
#define TX_BUF_SIZE ETH_FRAME_LEN /* FCS is added by the chip */
#define RX_BUF_LEN_IDX 0 /* 0, 1, 2 is allowed - 8,16,32K rx buffer */
#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
#undef DEBUG_TX
#undef DEBUG_RX
/* Symbolic offsets to registers. */
enum RTL8139_registers {
MAC0=0, /* Ethernet hardware address. */
MAR0=8, /* Multicast filter. */
TxStatus0=0x10, /* Transmit status (four 32bit registers). */
TxAddr0=0x20, /* Tx descriptors (also four 32bit). */
RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
IntrMask=0x3C, IntrStatus=0x3E,
TxConfig=0x40, RxConfig=0x44,
Timer=0x48, /* general-purpose counter. */
RxMissed=0x4C, /* 24 bits valid, write clears. */
Cfg9346=0x50, Config0=0x51, Config1=0x52,
TimerIntrReg=0x54, /* intr if gp counter reaches this value */
MediaStatus=0x58,
Config3=0x59,
MultiIntr=0x5C,
RevisionID=0x5E, /* revision of the RTL8139 chip */
TxSummary=0x60,
MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
NWayExpansion=0x6A,
DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
NWayTestReg=0x70,
RxCnt=0x72, /* packet received counter */
CSCR=0x74, /* chip status and configuration register */
PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80, /* undocumented */
/* from 0x84 onwards are a number of power management/wakeup frame
* definitions we will probably never need to know about. */
};
enum ChipCmdBits {
CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
/* Interrupt register bits, using my own meaningful names. */
enum IntrStatusBits {
PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
};
enum TxStatusBits {
TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
TxOutOfWindow=0x20000000, TxAborted=0x40000000,
TxCarrierLost=0x80000000,
};
enum RxStatusBits {
RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
RxBadAlign=0x0002, RxStatusOK=0x0001,
};
enum MediaStatusBits {
MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
};
enum MIIBMCRBits {
BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
};
enum CSCRBits {
CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
CSCR_LinkDownCmd=0x0f3c0,
};
/* Bits in RxConfig. */
enum rx_mode_bits {
RxCfgWrap=0x80,
AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
};
static int ioaddr;
static unsigned int cur_rx,cur_tx;
/* The RTL8139 can only transmit from a contiguous, aligned memory block. */
static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
/* I know that this is a MEGA HACK, but the tagged boot image specification
* states that we can do whatever we want below 0x10000 - so we do! */
/* But we still give the user the choice of using an internal buffer
just in case - Ken */
#ifdef USE_LOWMEM_BUFFER
#define rx_ring ((unsigned char *)(0x10000 - (RX_BUF_LEN + 16)))
#else
static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
#endif
struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
struct pci_device *pci);
static int read_eeprom(int location);
static void rtl_reset(struct nic *nic);
static void rtl_transmit(struct nic *nic, const char *destaddr,
unsigned int type, unsigned int len, const char *data);
static int rtl_poll(struct nic *nic);
static void rtl_disable(struct nic*);
struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
struct pci_device *pci)
{
int i;
int speed10, fullduplex;
/* There are enough "RTL8139" strings on the console already, so
* be brief and concentrate on the interesting pieces of info... */
printf(" - ");
/* Mask the bit that says "this is an io addr" */
ioaddr = probeaddrs[0] & ~3;
adjust_pci_device(pci);
/* Bring the chip out of low-power mode. */
outb(0x00, ioaddr + Config1);
if (read_eeprom(0) != 0xffff) {
unsigned short *ap = (unsigned short*)nic->node_addr;
for (i = 0; i < 3; i++)
*ap++ = read_eeprom(i + 7);
} else {
unsigned char *ap = (unsigned char*)nic->node_addr;
for (i = 0; i < ETH_ALEN; i++)
*ap++ = inb(ioaddr + MAC0 + i);
}
speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
printf("ioaddr %#hX, addr %! %sMbps %s-duplex\n", ioaddr,
nic->node_addr, speed10 ? "10" : "100",
fullduplex ? "full" : "half");
rtl_reset(nic);
nic->reset = rtl_reset;
nic->poll = rtl_poll;
nic->transmit = rtl_transmit;
nic->disable = rtl_disable;
return nic;
}
/* Serial EEPROM section. */
/* EEPROM_Ctrl bits. */
#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
#define EE_CS 0x08 /* EEPROM chip select. */
#define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */
#define EE_WRITE_0 0x00
#define EE_WRITE_1 0x02
#define EE_DATA_READ 0x01 /* EEPROM chip data out. */
#define EE_ENB (0x80 | EE_CS)
/*
Delay between EEPROM clock transitions.
No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
*/
#define eeprom_delay() inl(ee_addr)
/* 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)
static int read_eeprom(int location)
{
int i;
unsigned int retval = 0;
long ee_addr = ioaddr + Cfg9346;
int read_cmd = location | EE_READ_CMD;
outb(EE_ENB & ~EE_CS, ee_addr);
outb(EE_ENB, ee_addr);
/* Shift the read command bits out. */
for (i = 10; i >= 0; i--) {
int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
outb(EE_ENB | dataval, ee_addr);
eeprom_delay();
outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
eeprom_delay();
}
outb(EE_ENB, ee_addr);
eeprom_delay();
for (i = 16; i > 0; i--) {
outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
eeprom_delay();
retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
outb(EE_ENB, ee_addr);
eeprom_delay();
}
/* Terminate the EEPROM access. */
outb(~EE_CS, ee_addr);
return retval;
}
static void rtl_reset(struct nic* nic)
{
int i;
outb(CmdReset, ioaddr + ChipCmd);
cur_rx = 0;
cur_tx = 0;
/* Give the chip 10ms to finish the reset. */
load_timer2(10*TICKS_PER_MS);
while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
/* wait */;
for (i = 0; i < ETH_ALEN; i++)
outb(nic->node_addr[i], ioaddr + MAC0 + i);
/* Must enable Tx/Rx before setting transfer thresholds! */
outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8),
ioaddr + RxConfig); /* accept no frames yet! */
outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
/* The Linux driver changes Config1 here to use a different LED pattern
* for half duplex or full/autodetect duplex (for full/autodetect, the
* outputs are TX/RX, Link10/100, FULL, while for half duplex it uses
* TX/RX, Link100, Link10). This is messy, because it doesn't match
* the inscription on the mounting bracket. It should not be changed
* from the configuration EEPROM default, because the card manufacturer
* should have set that to match the card. */
#ifdef DEBUG_RX
printf("rx ring address is %X\n",(unsigned long)rx_ring);
#endif
outl((unsigned long)rx_ring, ioaddr + RxBuf);
/* Start the chip's Tx and Rx process. */
outl(0, ioaddr + RxMissed);
/* set_rx_mode */
outb(AcceptBroadcast|AcceptMyPhys, ioaddr + RxConfig);
/* If we add multicast support, the MAR0 register would have to be
* initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot
* only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */
outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
/* Disable all known interrupts by setting the interrupt mask. */
outw(0, ioaddr + IntrMask);
}
static void rtl_transmit(struct nic *nic, const char *destaddr,
unsigned int type, unsigned int len, const char *data)
{
unsigned int status, to, nstype;
unsigned long txstatus;
memcpy(tx_buffer, destaddr, ETH_ALEN);
memcpy(tx_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);
nstype = htons(type);
memcpy(tx_buffer + 2 * ETH_ALEN, (char*)&nstype, 2);
memcpy(tx_buffer + ETH_HLEN, data, len);
len += ETH_HLEN;
#ifdef DEBUG_TX
printf("sending %d bytes ethtype %hX\n", len, type);
#endif
/* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4
* bytes are sent automatically for the FCS, totalling to 64 bytes). */
while (len < ETH_ZLEN) {
tx_buffer[len++] = '\0';
}
outl((unsigned long)tx_buffer, ioaddr + TxAddr0 + cur_tx*4);
outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
ioaddr + TxStatus0 + cur_tx*4);
to = currticks() + RTL_TIMEOUT;
do {
status = inw(ioaddr + IntrStatus);
/* Only acknlowledge interrupt sources we can properly handle
* here - the RxOverflow/RxFIFOOver MUST be handled in the
* rtl_poll() function. */
outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
} while (currticks() < to);
txstatus = inl(ioaddr+ TxStatus0 + cur_tx*4);
if (status & TxOK) {
cur_tx = (cur_tx + 1) % NUM_TX_DESC;
#ifdef DEBUG_TX
printf("tx done (%d ticks), status %hX txstatus %X\n",
to-currticks(), status, txstatus);
#endif
} else {
#ifdef DEBUG_TX
printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
currticks()-to, status, txstatus);
#endif
rtl_reset(nic);
}
}
static int rtl_poll(struct nic *nic)
{
unsigned int status;
unsigned int ring_offs;
unsigned int rx_size, rx_status;
if (inb(ioaddr + ChipCmd) & RxBufEmpty) {
return 0;
}
status = inw(ioaddr + IntrStatus);
/* See below for the rest of the interrupt acknowledges. */
outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
#ifdef DEBUG_RX
printf("rtl_poll: int %hX ", status);
#endif
ring_offs = cur_rx % RX_BUF_LEN;
rx_status = *(unsigned int*)(rx_ring + ring_offs);
rx_size = rx_status >> 16;
rx_status &= 0xffff;
if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) ||
(rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) {
printf("rx error %hX\n", rx_status);
rtl_reset(nic); /* this clears all interrupts still pending */
return 0;
}
/* Received a good packet */
nic->packetlen = rx_size - 4; /* no one cares about the FCS */
if (ring_offs+4+rx_size-4 > RX_BUF_LEN) {
int semi_count = RX_BUF_LEN - ring_offs - 4;
memcpy(nic->packet, rx_ring + ring_offs + 4, semi_count);
memcpy(nic->packet+semi_count, rx_ring, rx_size-4-semi_count);
#ifdef DEBUG_RX
printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count);
#endif
} else {
memcpy(nic->packet, rx_ring + ring_offs + 4, nic->packetlen);
#ifdef DEBUG_RX
printf("rx packet %d bytes", rx_size-4);
#endif
}
#ifdef DEBUG_RX
printf(" at %X type %hhX%hhX rxstatus %hX\n",
(unsigned long)(rx_ring+ring_offs+4),
nic->packet[12], nic->packet[13], rx_status);
#endif
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
outw(cur_rx - 16, ioaddr + RxBufPtr);
/* See RTL8139 Programming Guide V0.1 for the official handling of
* Rx overflow situations. The document itself contains basically no
* usable information, except for a few exception handling rules. */
outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
return 1;
}
static void rtl_disable(struct nic *nic)
{
/* reset the chip */
outb(CmdReset, ioaddr + ChipCmd);
/* 10 ms timeout */
load_timer2(10*TICKS_PER_MS);
while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
/* wait */;
}

File diff suppressed because it is too large Load diff

View file

@ -1,363 +0,0 @@
/* -*- Mode:C; c-basic-offset:4; -*- */
/* Definitions for SiS ethernet controllers including 7014/7016 and 900
* References:
* SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
* preliminary Rev. 1.0 Jan. 14, 1998
* SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
* preliminary Rev. 1.0 Nov. 10, 1998
* SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
* preliminary Rev. 1.0 Jan. 18, 1998
* http://www.sis.com.tw/support/databook.htm
*/
/* MAC operationl registers of SiS 7016 and SiS 900 ethernet controller */
/* The I/O extent, SiS 900 needs 256 bytes of io address */
#define SIS900_TOTAL_SIZE 0x100
/* Symbolic offsets to registers. */
enum sis900_registers {
cr=0x0, /* Command Register */
cfg=0x4, /* Configuration Register */
mear=0x8, /* EEPROM Access Register */
ptscr=0xc, /* PCI Test Control Register */
isr=0x10, /* Interrupt Status Register */
imr=0x14, /* Interrupt Mask Register */
ier=0x18, /* Interrupt Enable Register */
epar=0x18, /* Enhanced PHY Access Register */
txdp=0x20, /* Transmit Descriptor Pointer Register */
txcfg=0x24, /* Transmit Configuration Register */
rxdp=0x30, /* Receive Descriptor Pointer Register */
rxcfg=0x34, /* Receive Configuration Register */
flctrl=0x38, /* Flow Control Register */
rxlen=0x3c, /* Receive Packet Length Register */
rfcr=0x48, /* Receive Filter Control Register */
rfdr=0x4C, /* Receive Filter Data Register */
pmctrl=0xB0, /* Power Management Control Register */
pmer=0xB4 /* Power Management Wake-up Event Register */
};
/* Symbolic names for bits in various registers */
enum sis900_command_register_bits {
RESET = 0x00000100,
SWI = 0x00000080,
RxRESET = 0x00000020,
TxRESET = 0x00000010,
RxDIS = 0x00000008,
RxENA = 0x00000004,
TxDIS = 0x00000002,
TxENA = 0x00000001
};
enum sis900_configuration_register_bits {
DESCRFMT = 0x00000100, /* 7016 specific */
REQALG = 0x00000080,
SB = 0x00000040,
POW = 0x00000020,
EXD = 0x00000010,
PESEL = 0x00000008,
LPM = 0x00000004,
BEM = 0x00000001
};
enum sis900_eeprom_access_reigster_bits {
MDC = 0x00000040,
MDDIR = 0x00000020,
MDIO = 0x00000010, /* 7016 specific */
EECS = 0x00000008,
EECLK = 0x00000004,
EEDO = 0x00000002,
EEDI = 0x00000001
};
enum sis900_interrupt_register_bits {
WKEVT = 0x10000000,
TxPAUSEEND = 0x08000000,
TxPAUSE = 0x04000000,
TxRCMP = 0x02000000,
RxRCMP = 0x01000000,
DPERR = 0x00800000,
SSERR = 0x00400000,
RMABT = 0x00200000,
RTABT = 0x00100000,
RxSOVR = 0x00010000,
HIBERR = 0x00008000,
SWINT = 0x00001000,
MIBINT = 0x00000800,
TxURN = 0x00000400,
TxIDLE = 0x00000200,
TxERR = 0x00000100,
TxDESC = 0x00000080,
TxOK = 0x00000040,
RxORN = 0x00000020,
RxIDLE = 0x00000010,
RxEARLY = 0x00000008,
RxERR = 0x00000004,
RxDESC = 0x00000002,
RxOK = 0x00000001
};
enum sis900_interrupt_enable_reigster_bits {
IE = 0x00000001
};
/* maximum dma burst fro transmission and receive*/
#define MAX_DMA_RANGE 7 /* actually 0 means MAXIMUM !! */
#define TxMXDMA_shift 20
#define RxMXDMA_shift 20
#define TX_DMA_BURST 0
#define RX_DMA_BURST 0
/* transmit FIFO threshholds */
#define TX_FILL_THRESH 16 /* 1/4 FIFO size */
#define TxFILLT_shift 8
#define TxDRNT_shift 0
#define TxDRNT_100 48 /* 3/4 FIFO size */
#define TxDRNT_10 16 /* 1/2 FIFO size */
enum sis900_transmit_config_register_bits {
TxCSI = 0x80000000,
TxHBI = 0x40000000,
TxMLB = 0x20000000,
TxATP = 0x10000000,
TxIFG = 0x0C000000,
TxFILLT = 0x00003F00,
TxDRNT = 0x0000003F
};
/* recevie FIFO thresholds */
#define RxDRNT_shift 1
#define RxDRNT_100 16 /* 1/2 FIFO size */
#define RxDRNT_10 24 /* 3/4 FIFO size */
enum sis900_reveive_config_register_bits {
RxAEP = 0x80000000,
RxARP = 0x40000000,
RxATX = 0x10000000,
RxAJAB = 0x08000000,
RxDRNT = 0x0000007F
};
#define RFAA_shift 28
#define RFADDR_shift 16
enum sis900_receive_filter_control_register_bits {
RFEN = 0x80000000,
RFAAB = 0x40000000,
RFAAM = 0x20000000,
RFAAP = 0x10000000,
RFPromiscuous = (RFAAB|RFAAM|RFAAP)
};
enum sis900_reveive_filter_data_mask {
RFDAT = 0x0000FFFF
};
/* EEPROM Addresses */
enum sis900_eeprom_address {
EEPROMSignature = 0x00,
EEPROMVendorID = 0x02,
EEPROMDeviceID = 0x03,
EEPROMMACAddr = 0x08,
EEPROMChecksum = 0x0b
};
/* The EEPROM commands include the alway-set leading bit. Refer to NM93Cxx datasheet */
enum sis900_eeprom_command {
EEread = 0x0180,
EEwrite = 0x0140,
EEerase = 0x01C0,
EEwriteEnable = 0x0130,
EEwriteDisable = 0x0100,
EEeraseAll = 0x0120,
EEwriteAll = 0x0110,
EEaddrMask = 0x013F,
};
/* Manamgement Data I/O (mdio) frame */
#define MIIread 0x6000
#define MIIwrite 0x5002
#define MIIpmdShift 7
#define MIIregShift 2
#define MIIcmdLen 16
#define MIIcmdShift 16
/* Buffer Descriptor Status*/
enum sis900_buffer_status {
OWN = 0x80000000,
MORE = 0x40000000,
INTR = 0x20000000,
SUPCRC = 0x10000000,
INCCRC = 0x10000000,
OK = 0x08000000,
DSIZE = 0x00000FFF
};
/* Status for TX Buffers */
enum sis900_tx_buffer_status {
ABORT = 0x04000000,
UNDERRUN = 0x02000000,
NOCARRIER = 0x01000000,
DEFERD = 0x00800000,
EXCDEFER = 0x00400000,
OWCOLL = 0x00200000,
EXCCOLL = 0x00100000,
COLCNT = 0x000F0000
};
enum sis900_rx_bufer_status {
OVERRUN = 0x02000000,
DEST = 0x00800000,
BCAST = 0x01800000,
MCAST = 0x01000000,
UNIMATCH = 0x00800000,
TOOLONG = 0x00400000,
RUNT = 0x00200000,
RXISERR = 0x00100000,
CRCERR = 0x00080000,
FAERR = 0x00040000,
LOOPBK = 0x00020000,
RXCOL = 0x00010000
};
/* MII register offsets */
enum mii_registers {
MII_CONTROL = 0x0000,
MII_STATUS = 0x0001,
MII_PHY_ID0 = 0x0002,
MII_PHY_ID1 = 0x0003,
MII_ANADV = 0x0004,
MII_ANLPAR = 0x0005,
MII_ANEXT = 0x0006
};
/* mii registers specific to SiS 900 */
enum sis_mii_registers {
MII_CONFIG1 = 0x0010,
MII_CONFIG2 = 0x0011,
MII_STSOUT = 0x0012,
MII_MASK = 0x0013
};
/* mii registers specific to AMD 79C901 */
enum amd_mii_registers {
MII_STATUS_SUMMARY = 0x0018
};
/* mii registers specific to ICS 1893 */
enum ics_mii_registers {
MII_EXTCTRL = 0x0010, MII_QPDSTS = 0x0011, MII_10BTOP = 0x0012,
MII_EXTCTRL2 = 0x0013
};
/* MII Control register bit definitions. */
enum mii_control_register_bits {
MII_CNTL_FDX = 0x0100,
MII_CNTL_RST_AUTO = 0x0200,
MII_CNTL_ISOLATE = 0x0400,
MII_CNTL_PWRDWN = 0x0800,
MII_CNTL_AUTO = 0x1000,
MII_CNTL_SPEED = 0x2000,
MII_CNTL_LPBK = 0x4000,
MII_CNTL_RESET = 0x8000
};
/* MII Status register bit */
enum mii_status_register_bits {
MII_STAT_EXT = 0x0001,
MII_STAT_JAB = 0x0002,
MII_STAT_LINK = 0x0004,
MII_STAT_CAN_AUTO = 0x0008,
MII_STAT_FAULT = 0x0010,
MII_STAT_AUTO_DONE = 0x0020,
MII_STAT_CAN_T = 0x0800,
MII_STAT_CAN_T_FDX = 0x1000,
MII_STAT_CAN_TX = 0x2000,
MII_STAT_CAN_TX_FDX = 0x4000,
MII_STAT_CAN_T4 = 0x8000
};
#define MII_ID1_OUI_LO 0xFC00 /* low bits of OUI mask */
#define MII_ID1_MODEL 0x03F0 /* model number */
#define MII_ID1_REV 0x000F /* model number */
/* MII NWAY Register Bits ...
valid for the ANAR (Auto-Negotiation Advertisement) and
ANLPAR (Auto-Negotiation Link Partner) registers */
enum mii_nway_register_bits {
MII_NWAY_NODE_SEL = 0x001f,
MII_NWAY_CSMA_CD = 0x0001,
MII_NWAY_T = 0x0020,
MII_NWAY_T_FDX = 0x0040,
MII_NWAY_TX = 0x0080,
MII_NWAY_TX_FDX = 0x0100,
MII_NWAY_T4 = 0x0200,
MII_NWAY_PAUSE = 0x0400,
MII_NWAY_RF = 0x2000,
MII_NWAY_ACK = 0x4000,
MII_NWAY_NP = 0x8000
};
enum mii_stsout_register_bits {
MII_STSOUT_LINK_FAIL = 0x4000,
MII_STSOUT_SPD = 0x0080,
MII_STSOUT_DPLX = 0x0040
};
enum mii_stsics_register_bits {
MII_STSICS_SPD = 0x8000, MII_STSICS_DPLX = 0x4000,
MII_STSICS_LINKSTS = 0x0001
};
enum mii_stssum_register_bits {
MII_STSSUM_LINK = 0x0008,
MII_STSSUM_DPLX = 0x0004,
MII_STSSUM_AUTO = 0x0002,
MII_STSSUM_SPD = 0x0001
};
enum sis900_revision_id {
SIS630A_900_REV = 0x80, SIS630E_900_REV = 0x81,
SIS630S_900_REV = 0x82, SIS630EA1_900_REV = 0x83
};
enum sis630_revision_id {
SIS630A0 = 0x00, SIS630A1 = 0x01,
SIS630B0 = 0x10, SIS630B1 = 0x11
};
#define FDX_CAPABLE_DUPLEX_UNKNOWN 0
#define FDX_CAPABLE_HALF_SELECTED 1
#define FDX_CAPABLE_FULL_SELECTED 2
#define HW_SPEED_UNCONFIG 0
#define HW_SPEED_HOME 1
#define HW_SPEED_10_MBPS 10
#define HW_SPEED_100_MBPS 100
#define HW_SPEED_DEFAULT (HW_SPEED_100_MBPS)
#define CRC_SIZE 4
#define MAC_HEADER_SIZE 14
#define TX_BUF_SIZE 1536
#define RX_BUF_SIZE 1536
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
/* Time in ticks before concluding the transmitter is hung. */
#define TX_TIMEOUT (4*TICKS_PER_SEC)
typedef struct _BufferDesc {
u32 link;
volatile u32 cmdsts;
u32 bufptr;
} BufferDesc;

View file

@ -1,91 +0,0 @@
How I added the SIS900 card to Etherboot
Author: Marty Connor (mdc@thinguin.org)
Date: 25 Febrary 2001
Description:
This file is intended to help people who want to write an Etherboot
driver or port another driver to Etherboot. It is a starting point.
Perhaps someday I may write a more detailed description of writing an
Etherboot driver. This text should help get people started, and
studying sis900.[ch] should help show the basic structure and
techniques involved in writing and Etherboot driver.
***********************************************************************
0. Back up all the files I need to modify:
cd etherboot-4.7.20/src
cp Makefile Makefile.orig
cp config.c config.c.orig
cp pci.h pci.h.orig
cp NIC NIC.orig
cp cards.h cards.h.orig
1. Edit src/Makefile to add SIS900FLAGS to defines
SIS900FLAGS= -DINCLUDE_SIS900
2. edit src/pci.h to add PCI signatures for card
#define PCI_VENDOR_ID_SIS 0x1039
#define PCI_DEVICE_ID_SIS900 0x0900
#define PCI_DEVICE_ID_SIS7016 0x7016
3. Edit src/config.c to add the card to the card probe list
#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) ||
defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) ||
defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) ||
defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) ||
defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) ||
defined(INCLUDE_SIS900) || defined(INCLUDE_W89C840)
... and ...
#ifdef INCLUDE_SIS900
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
"SIS900", 0, 0, 0, 0},
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
"SIS7016", 0, 0, 0, 0},
#endif
... and ...
#ifdef INCLUDE_SIS900
{ "SIS900", sis900_probe, pci_ioaddrs },
#endif
4. Edit NIC to add sis900 and sis7016 to NIC list
# SIS 900 and SIS 7016
sis900 sis900 0x1039,0x0900
sis7016 sis900 0x1039,0x7016
5. Edit cards.h to add sis900 probe routine declaration
#ifdef INCLUDE_SIS900
extern struct nic *sis900_probe(struct nic *, unsigned short *
PCI_ARG(struct pci_device *));
#endif
***********************************************************************
At this point, you can begin creating your driver source file. See
the "Writing and Etherboot Driver" section of the Etherboot
documentation for some hints. See the skel.c file for a starting
point. If there is a Linux driver for the card, you may be able to
use that. Copy and learn from existing Etherboot drivers (this is GPL
/ Open Source software!).
Join the etherboot-developers and etherboot-users mailing lists
(information is on etherboot.sourceforge.net) for information and
assistance. We invite more developers to help improve Etherboot.
Visit the http://etherboot.sourceforge.net, http://thinguin.org,
http://rom-o-matic.net, and http://ltsp.org sites for information and
assistance.
Enjoy.

File diff suppressed because it is too large Load diff

View file

@ -1,168 +0,0 @@
/*-
*
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
*
* Module : sk_g16.h
* Version : $Revision$
*
* Author : M.Hipp (mhipp@student.uni-tuebingen.de)
* changes by : Patrick J.D. Weichmann
*
* Date Created : 94/05/25
*
* Description : In here are all necessary definitions of
* the am7990 (LANCE) chip used for writing a
* network device driver which uses this chip
*
* $Log$
* Revision 1.3 2000-07-29 19:22:54 okuji
* update the network support to etherboot-4.6.4.
*
-*/
#ifndef SK_G16_H
#define SK_G16_H
/*
* Control and Status Register 0 (CSR0) bit definitions
*
* (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write)
*
*/
#define CSR0_ERR 0x8000 /* Error summary (R) */
#define CSR0_BABL 0x4000 /* Babble transmitter timeout error (RC) */
#define CSR0_CERR 0x2000 /* Collision Error (RC) */
#define CSR0_MISS 0x1000 /* Missed packet (RC) */
#define CSR0_MERR 0x0800 /* Memory Error (RC) */
#define CSR0_RINT 0x0400 /* Receiver Interrupt (RC) */
#define CSR0_TINT 0x0200 /* Transmit Interrupt (RC) */
#define CSR0_IDON 0x0100 /* Initialization Done (RC) */
#define CSR0_INTR 0x0080 /* Interrupt Flag (R) */
#define CSR0_INEA 0x0040 /* Interrupt Enable (RW) */
#define CSR0_RXON 0x0020 /* Receiver on (R) */
#define CSR0_TXON 0x0010 /* Transmitter on (R) */
#define CSR0_TDMD 0x0008 /* Transmit Demand (RS) */
#define CSR0_STOP 0x0004 /* Stop (RS) */
#define CSR0_STRT 0x0002 /* Start (RS) */
#define CSR0_INIT 0x0001 /* Initialize (RS) */
#define CSR0_CLRALL 0x7f00 /* mask for all clearable bits */
/*
* Control and Status Register 3 (CSR3) bit definitions
*
*/
#define CSR3_BSWAP 0x0004 /* Byte Swap (RW) */
#define CSR3_ACON 0x0002 /* ALE Control (RW) */
#define CSR3_BCON 0x0001 /* Byte Control (RW) */
/*
* Initialization Block Mode operation Bit Definitions.
*/
#define MODE_PROM 0x8000 /* Promiscuous Mode */
#define MODE_INTL 0x0040 /* Internal Loopback */
#define MODE_DRTY 0x0020 /* Disable Retry */
#define MODE_COLL 0x0010 /* Force Collision */
#define MODE_DTCR 0x0008 /* Disable Transmit CRC) */
#define MODE_LOOP 0x0004 /* Loopback */
#define MODE_DTX 0x0002 /* Disable the Transmitter */
#define MODE_DRX 0x0001 /* Disable the Receiver */
#define MODE_NORMAL 0x0000 /* Normal operation mode */
/*
* Receive message descriptor status bit definitions.
*/
#define RX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
#define RX_ERR 0x40 /* Error Summary */
#define RX_FRAM 0x20 /* Framing Error */
#define RX_OFLO 0x10 /* Overflow Error */
#define RX_CRC 0x08 /* CRC Error */
#define RX_BUFF 0x04 /* Buffer Error */
#define RX_STP 0x02 /* Start of Packet */
#define RX_ENP 0x01 /* End of Packet */
/*
* Transmit message descriptor status bit definitions.
*/
#define TX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
#define TX_ERR 0x40 /* Error Summary */
#define TX_MORE 0x10 /* More the 1 retry needed to Xmit */
#define TX_ONE 0x08 /* One retry needed to Xmit */
#define TX_DEF 0x04 /* Deferred */
#define TX_STP 0x02 /* Start of Packet */
#define TX_ENP 0x01 /* End of Packet */
/*
* Transmit status (2) (valid if TX_ERR == 1)
*/
#define TX_BUFF 0x8000 /* Buffering error (no ENP) */
#define TX_UFLO 0x4000 /* Underflow (late memory) */
#define TX_LCOL 0x1000 /* Late collision */
#define TX_LCAR 0x0400 /* Loss of Carrier */
#define TX_RTRY 0x0200 /* Failed after 16 retransmissions */
#define TX_TDR 0x003f /* Time-domain-reflectometer-value */
/*
* Structures used for Communication with the LANCE
*/
/* LANCE Initialize Block */
struct init_block
{
unsigned short mode; /* Mode Register */
unsigned char paddr[6]; /* Physical Address (MAC) */
unsigned char laddr[8]; /* Logical Filter Address (not used) */
unsigned int rdrp; /* Receive Descriptor Ring pointer */
unsigned int tdrp; /* Transmit Descriptor Ring pointer */
};
/* Receive Message Descriptor Entry */
struct rmd
{
union rmd_u
{
unsigned long buffer; /* Address of buffer */
struct rmd_s
{
unsigned char unused[3];
unsigned volatile char status; /* Status Bits */
} s;
} u;
volatile short blen; /* Buffer Length (two's complement) */
unsigned short mlen; /* Message Byte Count */
};
/* Transmit Message Descriptor Entry */
struct tmd
{
union tmd_u
{
unsigned long buffer; /* Address of buffer */
struct tmd_s
{
unsigned char unused[3];
unsigned volatile char status; /* Status Bits */
} s;
} u;
unsigned short blen; /* Buffer Length (two's complement) */
unsigned volatile short status2; /* Error Status Bits */
};
#endif /* End of SK_G16_H */

View file

@ -1,522 +0,0 @@
/*------------------------------------------------------------------------
* smc9000.c
* This is a Etherboot driver for SMC's 9000 series of Ethernet cards.
*
* Copyright (C) 1998 Daniel Engström <daniel.engstrom@riksnett.no>
* Based on the Linux SMC9000 driver, smc9194.c by Eric Stahlman
* Copyright (C) 1996 by Erik Stahlman <eric@vt.edu>
*
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
*
* "Features" of the SMC chip:
* 4608 byte packet memory. ( for the 91C92/4. Others have more )
* EEPROM for configuration
* AUI/TP selection
*
* Authors
* Erik Stahlman <erik@vt.edu>
* Daniel Engström <daniel.engstrom@riksnett.no>
*
* History
* 98-09-25 Daniel Engström Etherboot driver crated from Eric's
* Linux driver.
*
*---------------------------------------------------------------------------*/
#define LINUX_OUT_MACROS 1
#define SMC9000_VERBOSE 1
#define SMC9000_DEBUG 0
#include "etherboot.h"
#include "nic.h"
#include "cards.h"
#include "smc9000.h"
# define _outb outb
# define _outw outw
static const char smc9000_version[] = "Version 0.99 98-09-30";
static unsigned int smc9000_base=0;
static const char *interfaces[ 2 ] = { "TP", "AUI" };
static const char *chip_ids[ 15 ] = {
NULL, NULL, NULL,
/* 3 */ "SMC91C90/91C92",
/* 4 */ "SMC91C94",
/* 5 */ "SMC91C95",
NULL,
/* 7 */ "SMC91C100",
/* 8 */ "SMC91C100FD",
NULL, NULL, NULL,
NULL, NULL, NULL
};
static const char smc91c96_id[] = "SMC91C96";
/*
* Function: smc_reset( int ioaddr )
* Purpose:
* This sets the SMC91xx chip to its normal state, hopefully from whatever
* mess that any other DOS driver has put it in.
*
* Maybe I should reset more registers to defaults in here? SOFTRESET should
* do that for me.
*
* Method:
* 1. send a SOFT RESET
* 2. wait for it to finish
* 3. reset the memory management unit
* 4. clear all interrupts
*
*/
static void smc_reset(int ioaddr)
{
/* This resets the registers mostly to defaults, but doesn't
* affect EEPROM. That seems unnecessary */
SMC_SELECT_BANK(ioaddr, 0);
_outw( RCR_SOFTRESET, ioaddr + RCR );
/* this should pause enough for the chip to be happy */
SMC_DELAY(ioaddr);
/* Set the transmit and receive configuration registers to
* default values */
_outw(RCR_CLEAR, ioaddr + RCR);
_outw(TCR_CLEAR, ioaddr + TCR);
/* Reset the MMU */
SMC_SELECT_BANK(ioaddr, 2);
_outw( MC_RESET, ioaddr + MMU_CMD );
/* Note: It doesn't seem that waiting for the MMU busy is needed here,
* but this is a place where future chipsets _COULD_ break. Be wary
* of issuing another MMU command right after this */
_outb(0, ioaddr + INT_MASK);
}
/*----------------------------------------------------------------------
* Function: smc_probe( int ioaddr )
*
* Purpose:
* Tests to see if a given ioaddr points to an SMC9xxx chip.
* Returns a 0 on success
*
* Algorithm:
* (1) see if the high byte of BANK_SELECT is 0x33
* (2) compare the ioaddr with the base register's address
* (3) see if I recognize the chip ID in the appropriate register
*
* ---------------------------------------------------------------------
*/
static int smc_probe( int ioaddr )
{
word bank;
word revision_register;
word base_address_register;
/* First, see if the high byte is 0x33 */
bank = inw(ioaddr + BANK_SELECT);
if ((bank & 0xFF00) != 0x3300) {
return -1;
}
/* The above MIGHT indicate a device, but I need to write to further
* test this. */
_outw(0x0, ioaddr + BANK_SELECT);
bank = inw(ioaddr + BANK_SELECT);
if ((bank & 0xFF00) != 0x3300) {
return -1;
}
/* well, we've already written once, so hopefully another time won't
* hurt. This time, I need to switch the bank register to bank 1,
* so I can access the base address register */
SMC_SELECT_BANK(ioaddr, 1);
base_address_register = inw(ioaddr + BASE);
if (ioaddr != (base_address_register >> 3 & 0x3E0)) {
#ifdef SMC9000_VERBOSE
printf("SMC9000: IOADDR %hX doesn't match configuration (%hX)."
"Probably not a SMC chip\n",
ioaddr, base_address_register >> 3 & 0x3E0);
#endif
/* well, the base address register didn't match. Must not have
* been a SMC chip after all. */
return -1;
}
/* check if the revision register is something that I recognize.
* These might need to be added to later, as future revisions
* could be added. */
SMC_SELECT_BANK(ioaddr, 3);
revision_register = inw(ioaddr + REVISION);
if (!chip_ids[(revision_register >> 4) & 0xF]) {
/* I don't recognize this chip, so... */
#ifdef SMC9000_VERBOSE
printf("SMC9000: IO %hX: Unrecognized revision register:"
" %hX, Contact author.\n", ioaddr, revision_register);
#endif
return -1;
}
/* at this point I'll assume that the chip is an SMC9xxx.
* It might be prudent to check a listing of MAC addresses
* against the hardware address, or do some other tests. */
return 0;
}
/**************************************************************************
* ETH_RESET - Reset adapter
***************************************************************************/
static void smc9000_reset(struct nic *nic)
{
smc_reset(smc9000_base);
}
/**************************************************************************
* ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static void smc9000_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
word length; /* real, length incl. header */
word numPages;
unsigned long time_out;
byte packet_no;
word status;
int i;
/* We dont pad here since we can have the hardware doing it for us */
length = (s + ETH_HLEN + 1)&~1;
/* convert to MMU pages */
numPages = length / 256;
if (numPages > 7 ) {
#ifdef SMC9000_VERBOSE
printf("SMC9000: Far too big packet error. \n");
#endif
return;
}
/* dont try more than, say 30 times */
for (i=0;i<30;i++) {
/* now, try to allocate the memory */
SMC_SELECT_BANK(smc9000_base, 2);
_outw(MC_ALLOC | numPages, smc9000_base + MMU_CMD);
status = 0;
/* wait for the memory allocation to finnish */
for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) {
status = inb(smc9000_base + INTERRUPT);
if ( status & IM_ALLOC_INT ) {
/* acknowledge the interrupt */
_outb(IM_ALLOC_INT, smc9000_base + INTERRUPT);
break;
}
}
if ((status & IM_ALLOC_INT) != 0 ) {
/* We've got the memory */
break;
} else {
printf("SMC9000: Memory allocation timed out, resetting MMU.\n");
_outw(MC_RESET, smc9000_base + MMU_CMD);
}
}
/* If I get here, I _know_ there is a packet slot waiting for me */
packet_no = inb(smc9000_base + PNR_ARR + 1);
if (packet_no & 0x80) {
/* or isn't there? BAD CHIP! */
printf("SMC9000: Memory allocation failed. \n");
return;
}
/* we have a packet address, so tell the card to use it */
_outb(packet_no, smc9000_base + PNR_ARR);
/* point to the beginning of the packet */
_outw(PTR_AUTOINC, smc9000_base + POINTER);
#if SMC9000_DEBUG > 2
printf("Trying to xmit packet of length %hX\n", length );
#endif
/* send the packet length ( +6 for status, length and ctl byte )
* and the status word ( set to zeros ) */
_outw(0, smc9000_base + DATA_1 );
/* send the packet length ( +6 for status words, length, and ctl) */
_outb((length+6) & 0xFF, smc9000_base + DATA_1);
_outb((length+6) >> 8 , smc9000_base + DATA_1);
/* Write the contents of the packet */
/* The ethernet header first... */
outsw(smc9000_base + DATA_1, d, ETH_ALEN >> 1);
outsw(smc9000_base + DATA_1, nic->node_addr, ETH_ALEN >> 1);
_outw(htons(t), smc9000_base + DATA_1);
/* ... the data ... */
outsw(smc9000_base + DATA_1 , p, s >> 1);
/* ... and the last byte, if there is one. */
if ((s & 1) == 0) {
_outw(0, smc9000_base + DATA_1);
} else {
_outb(p[s-1], smc9000_base + DATA_1);
_outb(0x20, smc9000_base + DATA_1);
}
/* and let the chipset deal with it */
_outw(MC_ENQUEUE , smc9000_base + MMU_CMD);
status = 0; time_out = currticks() + 5*TICKS_PER_SEC;
do {
status = inb(smc9000_base + INTERRUPT);
if ((status & IM_TX_INT ) != 0) {
word tx_status;
/* ack interrupt */
_outb(IM_TX_INT, smc9000_base + INTERRUPT);
packet_no = inw(smc9000_base + FIFO_PORTS);
packet_no &= 0x7F;
/* select this as the packet to read from */
_outb( packet_no, smc9000_base + PNR_ARR );
/* read the first word from this packet */
_outw( PTR_AUTOINC | PTR_READ, smc9000_base + POINTER );
tx_status = inw( smc9000_base + DATA_1 );
if (0 == (tx_status & TS_SUCCESS)) {
#ifdef SMC9000_VERBOSE
printf("SMC9000: TX FAIL STATUS: %hX \n", tx_status);
#endif
/* re-enable transmit */
SMC_SELECT_BANK(smc9000_base, 0);
_outw(inw(smc9000_base + TCR ) | TCR_ENABLE, smc9000_base + TCR );
}
/* kill the packet */
SMC_SELECT_BANK(smc9000_base, 2);
_outw(MC_FREEPKT, smc9000_base + MMU_CMD);
return;
}
}while(currticks() < time_out);
printf("SMC9000: Waring TX timed out, resetting board\n");
smc_reset(smc9000_base);
return;
}
/**************************************************************************
* ETH_POLL - Wait for a frame
***************************************************************************/
static int smc9000_poll(struct nic *nic)
{
if(!smc9000_base)
return 0;
SMC_SELECT_BANK(smc9000_base, 2);
if (inw(smc9000_base + FIFO_PORTS) & FP_RXEMPTY)
return 0;
/* start reading from the start of the packet */
_outw(PTR_READ | PTR_RCV | PTR_AUTOINC, smc9000_base + POINTER);
/* First read the status and check that we're ok */
if (!(inw(smc9000_base + DATA_1) & RS_ERRORS)) {
/* Next: read the packet length and mask off the top bits */
nic->packetlen = (inw(smc9000_base + DATA_1) & 0x07ff);
/* the packet length includes the 3 extra words */
nic->packetlen -= 6;
#if SMC9000_DEBUG > 2
printf(" Reading %d words (and %d byte(s))\n",
(nic->packetlen >> 1), nic->packetlen & 1);
#endif
/* read the packet (and the last "extra" word) */
insw(smc9000_base + DATA_1, nic->packet, (nic->packetlen+2) >> 1);
/* is there an odd last byte ? */
if (nic->packet[nic->packetlen+1] & 0x20)
nic->packetlen++;
/* error or good, tell the card to get rid of this packet */
_outw(MC_RELEASE, smc9000_base + MMU_CMD);
return 1;
}
printf("SMC9000: RX error\n");
/* error or good, tell the card to get rid of this packet */
_outw(MC_RELEASE, smc9000_base + MMU_CMD);
return 0;
}
static void smc9000_disable(struct nic *nic)
{
if(!smc9000_base)
return;
/* no more interrupts for me */
SMC_SELECT_BANK(smc9000_base, 2);
_outb( 0, smc9000_base + INT_MASK);
/* and tell the card to stay away from that nasty outside world */
SMC_SELECT_BANK(smc9000_base, 0);
_outb( RCR_CLEAR, smc9000_base + RCR );
_outb( TCR_CLEAR, smc9000_base + TCR );
}
/**************************************************************************
* ETH_PROBE - Look for an adapter
***************************************************************************/
struct nic *smc9000_probe(struct nic *nic, unsigned short *probe_addrs)
{
unsigned short revision;
int memory;
int media;
const char * version_string;
const char * if_string;
int i;
/*
* the SMC9000 can be at any of the following port addresses. To change,
* for a slightly different card, you can add it to the array. Keep in
* mind that the array must end in zero.
*/
static unsigned short portlist[] = {
#ifdef SMC9000_SCAN
SMC9000_SCAN,
#else
0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0,
#endif
0 };
printf("\nSMC9000 %s\n", smc9000_version);
#ifdef SMC9000_VERBOSE
printf("Copyright (C) 1998 Daniel Engstr\x94m\n");
printf("Copyright (C) 1996 Eric Stahlman\n");
#endif
/* if no addresses supplied, fall back on defaults */
if (probe_addrs == 0 || probe_addrs[0] == 0)
probe_addrs = portlist;
/* check every ethernet address */
for (i = 0; probe_addrs[i]; i++) {
/* check this specific address */
if (smc_probe(probe_addrs[i]) == 0)
smc9000_base = probe_addrs[i];
}
/* couldn't find anything */
if(0 == smc9000_base)
goto out;
/*
* Get the MAC address ( bank 1, regs 4 - 9 )
*/
SMC_SELECT_BANK(smc9000_base, 1);
for ( i = 0; i < 6; i += 2 ) {
word address;
address = inw(smc9000_base + ADDR0 + i);
nic->node_addr[i+1] = address >> 8;
nic->node_addr[i] = address & 0xFF;
}
/* get the memory information */
SMC_SELECT_BANK(smc9000_base, 0);
memory = ( inw(smc9000_base + MCR) >> 9 ) & 0x7; /* multiplier */
memory *= 256 * (inw(smc9000_base + MIR) & 0xFF);
/*
* Now, I want to find out more about the chip. This is sort of
* redundant, but it's cleaner to have it in both, rather than having
* one VERY long probe procedure.
*/
SMC_SELECT_BANK(smc9000_base, 3);
revision = inw(smc9000_base + REVISION);
version_string = chip_ids[(revision >> 4) & 0xF];
if (((revision & 0xF0) >> 4 == CHIP_9196) &&
((revision & 0x0F) >= REV_9196)) {
/* This is a 91c96. 'c96 has the same chip id as 'c94 (4) but
* a revision starting at 6 */
version_string = smc91c96_id;
}
if ( !version_string ) {
/* I shouldn't get here because this call was done before.... */
goto out;
}
/* is it using AUI or 10BaseT ? */
SMC_SELECT_BANK(smc9000_base, 1);
if (inw(smc9000_base + CONFIG) & CFG_AUI_SELECT)
media = 2;
else
media = 1;
if_string = interfaces[media - 1];
/* now, reset the chip, and put it into a known state */
smc_reset(smc9000_base);
printf("%s rev:%d I/O port:%hX Interface:%s RAM:%d bytes \n",
version_string, revision & 0xF,
smc9000_base, if_string, memory );
/*
* Print the Ethernet address
*/
printf("Ethernet MAC address: %!\n", nic->node_addr);
SMC_SELECT_BANK(smc9000_base, 0);
/* see the header file for options in TCR/RCR NORMAL*/
_outw(TCR_NORMAL, smc9000_base + TCR);
_outw(RCR_NORMAL, smc9000_base + RCR);
/* Select which interface to use */
SMC_SELECT_BANK(smc9000_base, 1);
if ( media == 1 ) {
_outw( inw( smc9000_base + CONFIG ) & ~CFG_AUI_SELECT,
smc9000_base + CONFIG );
}
else if ( media == 2 ) {
_outw( inw( smc9000_base + CONFIG ) | CFG_AUI_SELECT,
smc9000_base + CONFIG );
}
nic->reset = smc9000_reset;
nic->poll = smc9000_poll;
nic->transmit = smc9000_transmit;
nic->disable = smc9000_disable;
return nic;
out:
#ifdef SMC9000_VERBOSE
printf("No SMC9000 adapters found\n");
#endif
smc9000_base = 0;
return (0);
}

View file

@ -1,205 +0,0 @@
/*------------------------------------------------------------------------
* smc9000.h
*
* Copyright (C) 1998 by Daniel Engström
* Copyright (C) 1996 by Erik Stahlman
*
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
*
* This file contains register information and access macros for
* the SMC91xxx chipset.
*
* Information contained in this file was obtained from the SMC91C94
* manual from SMC. To get a copy, if you really want one, you can find
* information under www.smsc.com in the components division.
* ( this thanks to advice from Donald Becker ).
*
* Authors
* Daniel Engström <daniel.engstrom@riksnett.no>
* Erik Stahlman <erik@vt.edu>
*
* History
* 96-01-06 Erik Stahlman moved definitions here from main .c
* file
* 96-01-19 Erik Stahlman polished this up some, and added
* better error handling
* 98-09-25 Daniel Engström adjusted for Etherboot
* 98-09-27 Daniel Engström moved some static strings back to the
* main .c file
* --------------------------------------------------------------------------*/
#ifndef _SMC9000_H_
# define _SMC9000_H_
/* I want some simple types */
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long int dword;
/*---------------------------------------------------------------
*
* A description of the SMC registers is probably in order here,
* although for details, the SMC datasheet is invaluable.
*
* Basically, the chip has 4 banks of registers ( 0 to 3 ), which
* are accessed by writing a number into the BANK_SELECT register
* ( I also use a SMC_SELECT_BANK macro for this ).
*
* The banks are configured so that for most purposes, bank 2 is all
* that is needed for simple run time tasks.
* ----------------------------------------------------------------------*/
/*
* Bank Select Register:
*
* yyyy yyyy 0000 00xx
* xx = bank number
* yyyy yyyy = 0x33, for identification purposes.
*/
#define BANK_SELECT 14
/* BANK 0 */
#define TCR 0 /* transmit control register */
#define TCR_ENABLE 0x0001 /* if this is 1, we can transmit */
#define TCR_FDUPLX 0x0800 /* receive packets sent out */
#define TCR_STP_SQET 0x1000 /* stop transmitting if Signal quality error */
#define TCR_MON_CNS 0x0400 /* monitors the carrier status */
#define TCR_PAD_ENABLE 0x0080 /* pads short packets to 64 bytes */
#define TCR_CLEAR 0 /* do NOTHING */
/* the normal settings for the TCR register : */
#define TCR_NORMAL (TCR_ENABLE | TCR_PAD_ENABLE)
#define EPH_STATUS 2
#define ES_LINK_OK 0x4000 /* is the link integrity ok ? */
#define RCR 4
#define RCR_SOFTRESET 0x8000 /* resets the chip */
#define RCR_STRIP_CRC 0x200 /* strips CRC */
#define RCR_ENABLE 0x100 /* IFF this is set, we can receive packets */
#define RCR_ALMUL 0x4 /* receive all multicast packets */
#define RCR_PROMISC 0x2 /* enable promiscuous mode */
/* the normal settings for the RCR register : */
#define RCR_NORMAL (RCR_STRIP_CRC | RCR_ENABLE)
#define RCR_CLEAR 0x0 /* set it to a base state */
#define COUNTER 6
#define MIR 8
#define MCR 10
/* 12 is reserved */
/* BANK 1 */
#define CONFIG 0
#define CFG_AUI_SELECT 0x100
#define BASE 2
#define ADDR0 4
#define ADDR1 6
#define ADDR2 8
#define GENERAL 10
#define CONTROL 12
#define CTL_POWERDOWN 0x2000
#define CTL_LE_ENABLE 0x80
#define CTL_CR_ENABLE 0x40
#define CTL_TE_ENABLE 0x0020
#define CTL_AUTO_RELEASE 0x0800
#define CTL_EPROM_ACCESS 0x0003 /* high if Eprom is being read */
/* BANK 2 */
#define MMU_CMD 0
#define MC_BUSY 1 /* only readable bit in the register */
#define MC_NOP 0
#define MC_ALLOC 0x20 /* or with number of 256 byte packets */
#define MC_RESET 0x40
#define MC_REMOVE 0x60 /* remove the current rx packet */
#define MC_RELEASE 0x80 /* remove and release the current rx packet */
#define MC_FREEPKT 0xA0 /* Release packet in PNR register */
#define MC_ENQUEUE 0xC0 /* Enqueue the packet for transmit */
#define PNR_ARR 2
#define FIFO_PORTS 4
#define FP_RXEMPTY 0x8000
#define FP_TXEMPTY 0x80
#define POINTER 6
#define PTR_READ 0x2000
#define PTR_RCV 0x8000
#define PTR_AUTOINC 0x4000
#define PTR_AUTO_INC 0x0040
#define DATA_1 8
#define DATA_2 10
#define INTERRUPT 12
#define INT_MASK 13
#define IM_RCV_INT 0x1
#define IM_TX_INT 0x2
#define IM_TX_EMPTY_INT 0x4
#define IM_ALLOC_INT 0x8
#define IM_RX_OVRN_INT 0x10
#define IM_EPH_INT 0x20
#define IM_ERCV_INT 0x40 /* not on SMC9192 */
/* BANK 3 */
#define MULTICAST1 0
#define MULTICAST2 2
#define MULTICAST3 4
#define MULTICAST4 6
#define MGMT 8
#define REVISION 10 /* ( hi: chip id low: rev # ) */
/* this is NOT on SMC9192 */
#define ERCV 12
/* Note that 9194 and 9196 have the smame chip id,
* the 9196 will have revisions starting at 6 */
#define CHIP_9190 3
#define CHIP_9194 4
#define CHIP_9195 5
#define CHIP_9196 4
#define CHIP_91100 7
#define CHIP_91100FD 8
#define REV_9196 6
/*
* Transmit status bits
*/
#define TS_SUCCESS 0x0001
#define TS_LOSTCAR 0x0400
#define TS_LATCOL 0x0200
#define TS_16COL 0x0010
/*
* Receive status bits
*/
#define RS_ALGNERR 0x8000
#define RS_BADCRC 0x2000
#define RS_ODDFRAME 0x1000
#define RS_TOOLONG 0x0800
#define RS_TOOSHORT 0x0400
#define RS_MULTICAST 0x0001
#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
/*-------------------------------------------------------------------------
* I define some macros to make it easier to do somewhat common
* or slightly complicated, repeated tasks.
--------------------------------------------------------------------------*/
/* select a register bank, 0 to 3 */
#define SMC_SELECT_BANK(x, y) { _outw( y, x + BANK_SELECT ); }
/* define a small delay for the reset */
#define SMC_DELAY(x) { inw( x + RCR );\
inw( x + RCR );\
inw( x + RCR ); }
#endif /* _SMC_9000_H_ */

View file

@ -1,255 +0,0 @@
/**************************************************************************
Etherboot - BOOTP/TFTP Bootstrap Program
TIARA (Fujitsu Etherstar) NIC driver for Etherboot
Copyright (c) Ken Yap 1998
Information gleaned from:
TIARA.ASM Packet driver by Brian Fisher, Queens U, Kingston, Ontario
Fujitsu MB86960 spec sheet (different chip but same family)
***************************************************************************/
/*
* 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.
*/
/* to get some global routines like printf */
#include "etherboot.h"
/* to get the interface to the body of the program */
#include "nic.h"
#include "cards.h"
/*
EtherStar I/O Register offsets
*/
/* Offsets of registers */
#define DLCR_XMIT_STAT 0x00
#define DLCR_XMIT_MASK 0x01
#define DLCR_RECV_STAT 0x02
#define DLCR_RECV_MASK 0x03
#define DLCR_XMIT_MODE 0x04
#define DLCR_RECV_MODE 0x05
#define DLCR_ENABLE 0x06
#define DLCR_TDR_LOW 0x07
#define DLCR_NODE_ID 0x08
#define DLCR_TDR_HIGH 0x0F
#define BMPR_MEM_PORT 0x10
#define BMPR_PKT_LEN 0x12
#define BMPR_DMA_ENABLE 0x14
#define PROM_ID 0x18
#define TMST 0x80
#define TMT_OK 0x80
#define TMT_16COLL 0x02
#define BUF_EMPTY 0x40
#define CARD_DISABLE 0x80 /* written to DLCR_ENABLE to disable card */
#define CARD_ENABLE 0 /* written to DLCR_ENABLE to enable card */
#define CLEAR_STATUS 0x0F /* used to clear status info */
/*
00001111B
!!!!!!!!--------
!!!!!!!+--------CLEAR BUS WRITE ERROR
!!!!!!+---------CLEAR 16 COLLISION
!!!!!+----------CLEAR COLLISION
!!!!+-----------CLEAR UNDERFLOW
!!!+------------NC
!!+-------------NC
!+--------------NC
+---------------NC
*/
#define NO_TX_IRQS 0 /* written to clear transmit IRQs */
#define CLR_RCV_STATUS 0xCF /* clears receive status */
#define EN_RCV_IRQS 0x80 /* enable receive interrupts */
/*
10000000B
!!!!!!!!--------
!!!!!!!+--------ENABLE OVERFLOW
!!!!!!+---------ENABLE CRC
!!!!!+----------ENABLE ALIGN
!!!!+-----------ENABLE SHORT PKT
!!!+------------DISABLE REMOTE RESET
!!+-------------RESERVED
!+--------------RESERVED
+---------------ENABLE PKT READY
*/
#define XMIT_MODE 0x02
/*
00000010B
!!!!!!!!---------ENABLE CARRIER DETECT
!!!!!!!+---------DISABLE LOOPBACK
*/
#define RECV_MODE 0x02
/*
00000010B
!!!!!!!!---------ACCEPT ALL PACKETS
!!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND
!!!!!!+----------BROADCAST PACKETS
!!!!!+-----------DISABLE REMOTE RESET
!!!!+------------DISABLE SHORT PACKETS
!!!+-------------USE 6 BYTE ADDRESS
!!+--------------NC
!+---------------NC
+----------------DISABLE CRC TEST MODE
*/
/* NIC specific static variables go here */
static unsigned short ioaddr;
/**************************************************************************
RESET - Reset adapter
***************************************************************************/
static void tiara_reset(struct nic *nic)
{
int i;
outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
outb(CLEAR_STATUS, ioaddr + DLCR_XMIT_STAT);
outb(NO_TX_IRQS, ioaddr + DLCR_XMIT_MASK);
outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
outb(XMIT_MODE, ioaddr + DLCR_XMIT_MODE);
outb(RECV_MODE, ioaddr + DLCR_RECV_MODE);
/* Vacuum recv buffer */
while ((inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY) == 0)
inb(ioaddr + BMPR_MEM_PORT);
/* Set node address */
for (i = 0; i < ETH_ALEN; ++i)
outb(nic->node_addr[i], ioaddr + DLCR_NODE_ID + i);
outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
outb(CARD_ENABLE, ioaddr + DLCR_ENABLE);
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int tiara_poll(struct nic *nic)
{
unsigned int len;
if (inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY)
return (0);
/* Ack packet */
outw(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
len = inw(ioaddr + BMPR_MEM_PORT); /* throw away status */
len = inw(ioaddr + BMPR_MEM_PORT);
/* Drop overlength packets */
if (len > ETH_FRAME_LEN)
return (0); /* should we drain the buffer? */
insw(ioaddr + BMPR_MEM_PORT, nic->packet, len / 2);
/* If it's our own, drop it */
if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) == 0)
return (0);
nic->packetlen = len;
return (1);
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
static void tiara_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
unsigned int len;
unsigned long time;
len = s + ETH_HLEN;
if (len < ETH_ZLEN)
len = ETH_ZLEN;
t = htons(t);
outsw(ioaddr + BMPR_MEM_PORT, d, ETH_ALEN / 2);
outsw(ioaddr + BMPR_MEM_PORT, nic->node_addr, ETH_ALEN / 2);
outw(t, ioaddr + BMPR_MEM_PORT);
outsw(ioaddr + BMPR_MEM_PORT, p, s / 2);
if (s & 1) /* last byte */
outb(p[s-1], ioaddr + BMPR_MEM_PORT);
while (s++ < ETH_ZLEN - ETH_HLEN) /* pad */
outb(0, ioaddr + BMPR_MEM_PORT);
outw(len | (TMST << 8), ioaddr + BMPR_PKT_LEN);
/* wait for transmit complete */
time = currticks() + TICKS_PER_SEC; /* wait one second */
while (currticks() < time && (inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
;
if ((inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
printf("Tiara timed out on transmit\n");
/* Do we need to ack the transmit? */
}
/**************************************************************************
DISABLE - Turn off ethernet interface
***************************************************************************/
static void tiara_disable(struct nic *nic)
{
/* Apparently only a power down can do this properly */
outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
}
static int tiara_probe1(struct nic *nic)
{
/* Hope all the Tiara cards have this vendor prefix */
static char vendor_prefix[] = { 0x08, 0x00, 0x1A };
static char all_ones[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
int i;
for (i = 0; i < ETH_ALEN; ++i)
nic->node_addr[i] = inb(ioaddr + PROM_ID + i);
if (memcmp(nic->node_addr, vendor_prefix, sizeof(vendor_prefix)) != 0)
return (0);
if (memcmp(nic->node_addr, all_ones, sizeof(all_ones)) == 0)
return (0);
printf("\nTiara ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
return (1);
}
/**************************************************************************
PROBE - Look for an adapter, this routine's visible to the outside
***************************************************************************/
struct nic *tiara_probe(struct nic *nic, unsigned short *probe_addrs)
{
/* missing entries are addresses usually already used */
static unsigned short io_addrs[] = {
0x100, 0x120, 0x140, 0x160,
0x180, 0x1A0, 0x1C0, 0x1E0,
0x200, 0x220, 0x240, /*Par*/
0x280, 0x2A0, 0x2C0, /*Ser*/
0x300, 0x320, 0x340, /*Par*/
0x380, /*Vid,Par*/ 0x3C0, /*Ser*/
0x0
};
unsigned short *p;
/* 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)
if (tiara_probe1(nic))
break;
/* if board found */
if (ioaddr != 0)
{
tiara_reset(nic);
/* point to NIC specific routines */
nic->reset = tiara_reset;
nic->poll = tiara_poll;
nic->transmit = tiara_transmit;
nic->disable = tiara_disable;
return nic;
}
else
return (0);
}

View file

@ -1,127 +0,0 @@
/* A couple of routines to implement a low-overhead timer for drivers */
/*
* 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.
*/
#include "etherboot.h"
#include "timer.h"
void load_timer2(unsigned int ticks)
{
/* Set up the timer gate, turn off the speaker */
outb((inb(PPC_PORTB) & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB);
outb(TIMER2_SEL|WORD_ACCESS|MODE0|BINARY_COUNT, TIMER_MODE_PORT);
outb(ticks & 0xFF, TIMER2_PORT);
outb(ticks >> 8, TIMER2_PORT);
}
#if defined(CONFIG_TSC_CURRTICKS)
#define rdtsc(low,high) \
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
#define rdtscll(val) \
__asm__ __volatile__ ("rdtsc" : "=A" (val))
#define HZ TICKS_PER_SEC
#define CLOCK_TICK_RATE 1193180U /* Underlying HZ */
/* LATCH is used in the interval timer and ftape setup. */
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
/* ------ Calibrate the TSC -------
* Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
* Too much 64-bit arithmetic here to do this cleanly in C, and for
* accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
* output busy loop as low as possible. We avoid reading the CTC registers
* directly because of the awkward 8-bit access mechanism of the 82C54
* device.
*/
#define CALIBRATE_LATCH (5 * LATCH)
static unsigned long long calibrate_tsc(void)
{
/* Set the Gate high, disable speaker */
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
/*
* Now let's take care of CTC channel 2
*
* Set the Gate high, program CTC channel 2 for mode 0,
* (interrupt on terminal count mode), binary count,
* load 5 * LATCH count, (LSB and MSB) to begin countdown.
*/
outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
{
unsigned long startlow, starthigh;
unsigned long endlow, endhigh;
unsigned long count;
rdtsc(startlow,starthigh);
count = 0;
do {
count++;
} while ((inb(0x61) & 0x20) == 0);
rdtsc(endlow,endhigh);
/* Error: ECTCNEVERSET */
if (count <= 1)
goto bad_ctc;
/* 64-bit subtract - gcc just messes up with long longs */
__asm__("subl %2,%0\n\t"
"sbbl %3,%1"
:"=a" (endlow), "=d" (endhigh)
:"g" (startlow), "g" (starthigh),
"0" (endlow), "1" (endhigh));
/* Error: ECPUTOOFAST */
if (endhigh)
goto bad_ctc;
endlow /= 5;
return endlow;
}
/*
* The CTC wasn't reliable: we got a hit on the very first read,
* or the CPU was so fast/slow that the quotient wouldn't fit in
* 32 bits..
*/
bad_ctc:
printf("bad_ctc\n");
return 0;
}
unsigned long currticks(void)
{
static unsigned long clocks_per_tick;
unsigned long clocks_high, clocks_low;
unsigned long currticks;
if (!clocks_per_tick) {
clocks_per_tick = calibrate_tsc();
printf("clocks_per_tick = %d\n", clocks_per_tick);
}
/* Read the Time Stamp Counter */
rdtsc(clocks_low, clocks_high);
/* currticks = clocks / clocks_per_tick; */
__asm__("divl %1"
:"=a" (currticks)
:"r" (clocks_per_tick), "0" (clocks_low), "d" (clocks_high));
return currticks;
}
#endif /* RTC_CURRTICKS */

View file

@ -1,64 +0,0 @@
/* Defines for routines to implement a low-overhead timer for drivers */
/*
* 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.
*/
#ifndef TIMER_H
#define TIMER_H
/* Ports for the 8254 timer chip */
#define TIMER2_PORT 0x42
#define TIMER_MODE_PORT 0x43
/* Meaning of the mode bits */
#define TIMER0_SEL 0x00
#define TIMER1_SEL 0x40
#define TIMER2_SEL 0x80
#define READBACK_SEL 0xC0
#define LATCH_COUNT 0x00
#define LOBYTE_ACCESS 0x10
#define HIBYTE_ACCESS 0x20
#define WORD_ACCESS 0x30
#define MODE0 0x00
#define MODE1 0x02
#define MODE2 0x04
#define MODE3 0x06
#define MODE4 0x08
#define MODE5 0x0A
#define BINARY_COUNT 0x00
#define BCD_COUNT 0x01
/* Timers tick over at this rate */
#define TICKS_PER_MS 1193
/* Parallel Peripheral Controller Port B */
#define PPC_PORTB 0x61
/* Meaning of the port bits */
#define PPCB_T2OUT 0x20 /* Bit 5 */
#define PPCB_SPKR 0x02 /* Bit 1 */
#define PPCB_T2GATE 0x01 /* Bit 0 */
/* Ticks must be between 0 and 65535 (0 == 65536)
because it is a 16 bit counter */
extern void load_timer2(unsigned int ticks);
extern inline int timer2_running(void)
{
return ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
}
extern inline void waiton_timer2(unsigned int ticks)
{
load_timer2(ticks);
while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0)
;
}
#endif /* TIMER_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,53 +0,0 @@
This software may be used and distributed according to the terms of
the GNU Public License, incorporated herein by reference.
This is a tulip and clone driver for Etherboot. See the revision
history in the tulip.c file for information on changes. This version
of the driver incorporates changes from Bob Edwards and Paul Mackerras
who cantributed changes to support the TRENDnet TE100-PCIA NIC which
uses a genuine Intel 21143-PD chipset. There are also various code
cleanups to make time-based activities more reliable.
Of course you have to have all the usual Etherboot environment
(bootp/dhcp/NFS) set up, and you need a Linux kernel with v0.91g
(7.16.99) or later of the tulip.c driver compiled in to support some
MX98715 based cards. That file is available at:
http://cesdis.gsfc.nasa.gov/linux/drivers/test/tulip.c
NOTES
I've tested this driver with a SOHOware Fast 10/100 Model SDA110A,
a Linksys LNE100TX v2.0, and a Netgear FA310TX card, and it worked at
both 10 and 100 mbits. Other cards based on the tulip family may work as
well.
These cards are about 20$US, are supported by Linux and now Etherboot,
and being PCI, they auto-configure IRQ and IOADDR and auto-negotiate
10/100 half/full duplex. It seems like a pretty good value compared to
some of the pricier cards, and can lower the cost of building/adapting
thin client workstations substantially while giving a considerable
performance increase.
On some PCI tulip clone chipsets (MX987x5, LC82C115, LC82C168) this driver
lets the card choose the fastest speed it can negotiate with the peer
device. On other cards, it chooses 10mbit half-duplex.
I burned an AM27C256 (32KByte) EPROM with mx987x5.lzrom and it worked.
According to the data sheet the MX98715A supports up to 64K (27C512)
EPROMs,
I've liberally commented the code and header files in the hope that it
will help the next person who hacks the code or needs to support some
tulip clone card, or wishes to add functionality.
Anyway, please test this if you can on your tulip based card, and let
me (mdc@thinguin.org) and the netboot list (netboot@baghira.han.de)
know how things go. I also would appreciate code review by people who
program. I'm a strong believer in "another set of eyes".
Regards,
Marty Connor
mdc@thinguin.org
http://www.thinguin.org/

File diff suppressed because it is too large Load diff

View file

@ -1,934 +0,0 @@
/*
* Etherboot - BOOTP/TFTP Bootstrap Program
*
* w89c840.c -- This file implements the winbond-840 driver for etherboot.
*
*/
/*
* Adapted by Igor V. Kovalenko
* -- <garrison@mail.ru>
* OR
* -- <iko@crec.mipt.ru>
* Initial adaptaion stage, including testing, completed 23 August 2000.
*/
/*
* 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: Aug 20 2000 V0.10 iko Initial revision.
* changes: Aug 22 2000 V0.90 iko Works!
* Aug 23 2000 V0.91 iko Cleanup, posted to etherboot
* maintainer.
* Aug 26 2000 V0.92 iko Fixed Rx ring handling.
* First Linux Kernel (TM)
* successfully loaded using
* this driver.
* Jan 07 2001 V0.93 iko Transmitter timeouts are handled
* using timer2 routines. Proposed
* by Ken Yap to eliminate CPU speed
* dependency.
*
* This is the etherboot driver for cards based on Winbond W89c840F chip.
*
* It was written from skeleton source, with Donald Becker's winbond-840.c
* kernel driver as a guideline. Mostly the w89c840 related definitions
* and the lower level routines have been cut-and-pasted into this source.
*
* Frankly speaking, about 90% of the code was obtained using cut'n'paste
* sequence :) while the remainder appeared while brainstorming
* Linux Kernel 2.4.0-testX source code. Thanks, Donald and Linus!
*
* There was a demand for using this card in a rather large
* remote boot environment at MSKP OVTI Lab of
* Moscow Institute for Physics and Technology (MIPT) -- http://www.mipt.ru/
* so you may count that for motivation.
*
*/
/*
* If you want to see debugging output then define W89C840_DEBUG
*/
/*
#define W89C840_DEBUG
*/
/*
* Keep using IO_OPS for Etherboot driver!
*/
#define USE_IO_OPS
#include "etherboot.h"
#include "nic.h"
#include "pci.h"
#include "cards.h"
#include "timer.h"
static const char *w89c840_version = "diver Version 0.92 - August 27, 2000";
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
/* Linux support functions */
#define virt_to_bus(x) ((unsigned long)x)
#define bus_to_virt(x) ((void *)x)
#define virt_to_le32desc(addr) virt_to_bus(addr)
#define le32desc_to_virt(addr) bus_to_virt(addr)
/*
#define cpu_to_le32(val) (val)
#define le32_to_cpu(val) (val)
*/
/* Operational parameters that are set at compile time. */
/* Keep the ring sizes a power of two for compile efficiency.
The compiler will convert <unsigned>'%'<2^N> into a bit mask.
Making the Tx ring too large decreases the effectiveness of channel
bonding and packet priority.
There are no ill effects from too-large receive rings. */
#define TX_RING_SIZE 2
#define RX_RING_SIZE 2
/* The presumed FIFO size for working around the Tx-FIFO-overflow bug.
To avoid overflowing we don't queue again until we have room for a
full-size packet.
*/
#define TX_FIFO_SIZE (2048)
#define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16)
/* Operational parameters that usually are not changed. */
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (10*TICKS_PER_MS)
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
/*
* Used to be this much CPU loops on Celeron@400 (?),
* now using real timer and TX_TIMEOUT!
* #define TX_LOOP_COUNT 10000000
*/
#if !defined(__OPTIMIZE__)
#warning You must compile this file with the correct options!
#warning See the last lines of the source file.
#error You must compile this driver with "-O".
#endif
enum chip_capability_flags {CanHaveMII=1, HasBrokenTx=2};
#ifdef USE_IO_OPS
#define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
#else
#define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
#endif
static u32 driver_flags = CanHaveMII | HasBrokenTx;
/* This driver was written to use PCI memory space, however some x86 systems
work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space
accesses instead of memory space. */
#ifdef USE_IO_OPS
#undef readb
#undef readw
#undef readl
#undef writeb
#undef writew
#undef writel
#define readb inb
#define readw inw
#define readl inl
#define writeb outb
#define writew outw
#define writel outl
#endif
/* Offsets to the Command and Status Registers, "CSRs".
While similar to the Tulip, these registers are longword aligned.
Note: It's not useful to define symbolic names for every register bit in
the device. The name can only partially document the semantics and make
the driver longer and more difficult to read.
*/
enum w840_offsets {
PCIBusCfg=0x00, TxStartDemand=0x04, RxStartDemand=0x08,
RxRingPtr=0x0C, TxRingPtr=0x10,
IntrStatus=0x14, NetworkConfig=0x18, IntrEnable=0x1C,
RxMissed=0x20, EECtrl=0x24, MIICtrl=0x24, BootRom=0x28, GPTimer=0x2C,
CurRxDescAddr=0x30, CurRxBufAddr=0x34, /* Debug use */
MulticastFilter0=0x38, MulticastFilter1=0x3C, StationAddr=0x40,
CurTxDescAddr=0x4C, CurTxBufAddr=0x50,
};
/* Bits in the interrupt status/enable registers. */
/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
enum intr_status_bits {
NormalIntr=0x10000, AbnormalIntr=0x8000,
IntrPCIErr=0x2000, TimerInt=0x800,
IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40,
TxFIFOUnderflow=0x20, RxErrIntr=0x10,
TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01,
};
/* Bits in the NetworkConfig register. */
enum rx_mode_bits {
AcceptErr=0x80, AcceptRunt=0x40,
AcceptBroadcast=0x20, AcceptMulticast=0x10,
AcceptAllPhys=0x08, AcceptMyPhys=0x02,
};
enum mii_reg_bits {
MDIO_ShiftClk=0x10000, MDIO_DataIn=0x80000, MDIO_DataOut=0x20000,
MDIO_EnbOutput=0x40000, MDIO_EnbIn = 0x00000,
};
/* The Tulip Rx and Tx buffer descriptors. */
struct w840_rx_desc {
s32 status;
s32 length;
u32 buffer1;
u32 next_desc;
};
struct w840_tx_desc {
s32 status;
s32 length;
u32 buffer1, buffer2; /* We use only buffer 1. */
};
/* Bits in network_desc.status */
enum desc_status_bits {
DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000,
DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000,
DescIntr=0x80000000,
};
#define PRIV_ALIGN 15 /* Required alignment mask */
#define PRIV_ALIGN_BYTES 32
static struct winbond_private
{
/* Descriptor rings first for alignment. */
struct w840_rx_desc rx_ring[RX_RING_SIZE];
struct w840_tx_desc tx_ring[TX_RING_SIZE];
struct net_device *next_module; /* Link for devices of this type. */
void *priv_addr; /* Unaligned address for kfree */
const char *product_name;
/* Frequently used values: keep some adjacent for cache effect. */
int chip_id, drv_flags;
struct pci_dev *pci_dev;
int csr6;
struct w840_rx_desc *rx_head_desc;
unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int cur_tx, dirty_tx;
int tx_q_bytes;
unsigned int tx_full:1; /* The Tx queue is full. */
/* These values are keep track of the transceiver/media in use. */
unsigned int full_duplex:1; /* Full-duplex operation requested. */
unsigned int duplex_lock:1;
unsigned int medialock:1; /* Do not sense media. */
unsigned int default_port:4; /* Last dev->if_port value. */
/* MII transceiver section. */
int mii_cnt; /* MII device addresses. */
u16 advertising; /* NWay media advertisement */
unsigned char phys[2]; /* MII device addresses. */
} w840private __attribute__ ((aligned (PRIV_ALIGN_BYTES)));
/* NIC specific static variables go here */
static int ioaddr;
static unsigned short eeprom [0x40];
#ifdef USE_LOWMEM_BUFFER
#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
#else
static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
#endif
static int eeprom_read(long ioaddr, int location);
static int mdio_read(int base_address, int phy_id, int location);
static void mdio_write(int base_address, int phy_id, int location, int value);
static void check_duplex(void);
static void set_rx_mode(void);
static void init_ring(void);
/*
static void wait_long_time(void)
{
printf("Paused - please read output above this line\n");
sleep(3);
}
*/
#if defined W89C840_DEBUG
static void decode_interrupt(u32 intr_status)
{
printf("Interrupt status: ");
#define TRACE_INTR(_intr_) \
if (intr_status & (_intr_)) { printf (" " #_intr_); }
TRACE_INTR(NormalIntr);
TRACE_INTR(AbnormalIntr);
TRACE_INTR(IntrPCIErr);
TRACE_INTR(TimerInt);
TRACE_INTR(IntrRxDied);
TRACE_INTR(RxNoBuf);
TRACE_INTR(IntrRxDone);
TRACE_INTR(TxFIFOUnderflow);
TRACE_INTR(RxErrIntr);
TRACE_INTR(TxIdle);
TRACE_INTR(IntrTxStopped);
TRACE_INTR(IntrTxDone);
printf("\n");
/*sleep(1);*/
}
#endif
/**************************************************************************
w89c840_reset - Reset adapter
***************************************************************************/
static void w89c840_reset(struct nic *nic)
{
int i;
/* Reset the chip to erase previous misconfiguration.
No hold time required! */
writel(0x00000001, ioaddr + PCIBusCfg);
init_ring();
writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr);
writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr);
for (i = 0; i < ETH_ALEN; i++)
writeb(nic->node_addr[i], ioaddr + StationAddr + i);
/* Initialize other registers. */
/* Configure the PCI bus bursts and FIFO thresholds.
486: Set 8 longword cache alignment, 8 longword burst.
586: Set 16 longword cache alignment, no burst limit.
Cache alignment bits 15:14 Burst length 13:8
0000 <not allowed> 0000 align to cache 0800 8 longwords
4000 8 longwords 0100 1 longword 1000 16 longwords
8000 16 longwords 0200 2 longwords 2000 32 longwords
C000 32 longwords 0400 4 longwords
Wait the specified 50 PCI cycles after a reset by initializing
Tx and Rx queues and the address filter list. */
writel(0xE010, ioaddr + PCIBusCfg);
writel(0, ioaddr + RxStartDemand);
w840private.csr6 = 0x20022002;
check_duplex();
set_rx_mode();
/* Clear and Enable interrupts by setting the interrupt mask. */
writel(0x1A0F5, ioaddr + IntrStatus);
writel(0x1A0F5, ioaddr + IntrEnable);
#if defined(W89C840_DEBUG)
printf("winbond-840 : Done reset.\n");
#endif
}
static void handle_intr(u32 intr_stat)
{
if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
/* we are polling, do not return now */
/*return 0;*/
} else {
/* Acknowledge all of the current interrupt sources ASAP. */
writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
}
if (intr_stat & AbnormalIntr) {
/* There was an abnormal interrupt */
printf("\n-=- Abnormal interrupt.\n");
#if defined (W89C840_DEBUG)
decode_interrupt(intr_stat);
#endif
if (intr_stat & RxNoBuf) {
/* There was an interrupt */
printf("-=- <=> No receive buffers available.\n");
writel(0, ioaddr + RxStartDemand);
}
}
}
/**************************************************************************
w89c840_poll - Wait for a frame
***************************************************************************/
static int w89c840_poll(struct nic *nic)
{
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
/* nic->packetlen should contain length of data */
int packet_received = 0;
u32 intr_status = readl(ioaddr + IntrStatus);
/* handle_intr(intr_status); */ /* -- handled later */
do {
/* Code from netdev_rx(dev) */
int entry = w840private.cur_rx % RX_RING_SIZE;
struct w840_rx_desc *desc = w840private.rx_head_desc;
s32 status = desc->status;
if (status & DescOwn) {
/* DescOwn bit is still set, we should wait for RX to complete */
packet_received = 0;
break;
}
if ((status & 0x38008300) != 0x0300) {
if ((status & 0x38000300) != 0x0300) {
/* Ingore earlier buffers. */
if ((status & 0xffff) != 0x7fff) {
printf("winbond-840 : Oversized Ethernet frame spanned "
"multiple buffers, entry %d status %X !\n",
w840private.cur_rx, status);
}
} else if (status & 0x8000) {
/* There was a fatal error. */
#if defined(W89C840_DEBUG)
printf("winbond-840 : Receive error, Rx status %X :", status);
if (status & 0x0890) {
printf(" RXLEN_ERROR");
}
if (status & 0x004C) {
printf(", FRAME_ERROR");
}
if (status & 0x0002) {
printf(", CRC_ERROR");
}
printf("\n");
#endif
/* Simpy do a reset now... */
w89c840_reset(nic);
packet_received = 0;
break;
}
} else {
/* Omit the four octet CRC from the length. */
int pkt_len = ((status >> 16) & 0x7ff) - 4;
#if defined(W89C840_DEBUG)
printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
#endif
nic->packetlen = pkt_len;
/* Check if the packet is long enough to accept without copying
to a minimally-sized skbuff. */
memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len);
packet_received = 1;
/* Release buffer to NIC */
w840private.rx_ring[entry].status = DescOwn;
#if defined(W89C840_DEBUG)
/* You will want this info for the initial debug. */
printf(" Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
"%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
"%hhX.%hhX.%hhX.%hhX.\n",
nic->packet[0], nic->packet[1], nic->packet[2], nic->packet[3],
nic->packet[4], nic->packet[5], nic->packet[6], nic->packet[7],
nic->packet[8], nic->packet[9], nic->packet[10],
nic->packet[11], nic->packet[12], nic->packet[13],
nic->packet[14], nic->packet[15], nic->packet[16],
nic->packet[17]);
#endif
}
entry = (++w840private.cur_rx) % RX_RING_SIZE;
w840private.rx_head_desc = &w840private.rx_ring[entry];
} while (0);
if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |TimerInt | IntrTxStopped)) {
handle_intr(intr_status);
}
return packet_received;
}
/**************************************************************************
w89c840_transmit - Transmit a frame
***************************************************************************/
static void w89c840_transmit(
struct nic *nic,
const char *d, /* Destination */
unsigned int t, /* Type */
unsigned int s, /* size */
const char *p) /* Packet */
{
/* send the packet to destination */
unsigned entry;
int transmit_status;
/* Caution: the write order is important here, set the field
with the "ownership" bits last. */
/* Fill in our transmit buffer */
entry = w840private.cur_tx % TX_RING_SIZE;
memcpy (tx_packet, d, ETH_ALEN); /* dst */
memcpy (tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/* src */
*((char *) tx_packet + 12) = t >> 8; /* type */
*((char *) tx_packet + 13) = t;
memcpy (tx_packet + ETH_HLEN, p, s);
s += ETH_HLEN;
while (s < ETH_ZLEN)
*((char *) tx_packet + ETH_HLEN + (s++)) = 0;
w840private.tx_ring[entry].buffer1 = virt_to_le32desc(tx_packet);
w840private.tx_ring[entry].length = (DescWholePkt | s);
if (entry >= TX_RING_SIZE-1) /* Wrap ring */
w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
w840private.tx_ring[entry].status = (DescOwn);
w840private.cur_tx++;
w840private.tx_q_bytes += s;
writel(0, ioaddr + TxStartDemand);
/* Work around horrible bug in the chip by marking the queue as full
when we do not have FIFO room for a maximum sized packet. */
if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) {
/* Actually this is left to help finding error tails later in debugging...
* See Linux kernel driver in winbond-840.c for details.
*/
w840private.tx_full = 1;
}
#if defined(W89C840_DEBUG)
printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
#endif
/* Now wait for TX to complete. */
transmit_status = w840private.tx_ring[entry].status;
load_timer2(TX_TIMEOUT);
{
u32 intr_stat = 0;
while (1) {
intr_stat = readl(ioaddr + IntrStatus);
#if defined(W89C840_DEBUG)
decode_interrupt(intr_stat);
#endif
if (intr_stat & (NormalIntr | IntrTxDone)) {
while ( (transmit_status & DescOwn) && timer2_running()) {
transmit_status = w840private.tx_ring[entry].status;
}
writel(intr_stat & 0x0001ffff, ioaddr + IntrStatus);
break;
}
}
}
if ((transmit_status & DescOwn) == 0) {
#if defined(W89C840_DEBUG)
printf("winbond-840 : transmission complete after %d wait loop iterations, status %X\n",
TX_LOOP_COUNT - transmit_loop_counter, w840private.tx_ring[entry].status);
#endif
return;
}
/* Transmit timed out... */
printf("winbond-840 : transmission TIMEOUT : status %X\n", w840private.tx_ring[entry].status);
return;
}
/**************************************************************************
w89c840_disable - Turn off ethernet interface
***************************************************************************/
static void w89c840_disable(struct nic *nic)
{
/* Don't know what to do to disable the board. Is this needed at all? */
/* Yes, a live NIC can corrupt the loaded memory later [Ken] */
/* Stop the chip's Tx and Rx processes. */
writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig);
}
/**************************************************************************
w89c840_probe - Look for an adapter, this routine's visible to the outside
***************************************************************************/
struct nic *w89c840_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *p)
{
u16 sum = 0;
int i, j, to;
unsigned short value;
int options;
int promisc;
if (probe_addrs == 0 || probe_addrs[0] == 0)
return 0;
ioaddr = probe_addrs[0]; /* Mask the bit that says "this is an io addr" */
#if defined(W89C840_DEBUG)
printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
#endif
ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
/* if probe_addrs is 0, then routine can use a hardwired default */
/* From Matt Hortman <mbhortman@acpthinclient.com> */
if (p->vendor == PCI_VENDOR_ID_WINBOND2
&& p->dev_id == PCI_DEVICE_ID_WINBOND2_89C840) {
/* detected "Winbond W89c840 Fast Ethernet PCI NIC" */
} else if ( p->vendor == PCI_VENDOR_ID_COMPEX
&& p->dev_id == PCI_DEVICE_ID_COMPEX_RL100ATX) {
/* detected "Compex RL100ATX Fast Ethernet PCI NIC" */
} else {
/* Gee, guess what? They missed again. */
printf("device ID : %X - is not a Compex RL100ATX NIC.\n", p->dev_id);
return 0;
}
printf(" %s\n", w89c840_version);
adjust_pci_device(p);
/* Ok. Got one. Read the eeprom. */
for (j = 0, i = 0; i < 0x40; i++) {
value = eeprom_read(ioaddr, i);
eeprom[i] = value;
sum += value;
}
for (i=0;i<ETH_ALEN;i++) {
nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
}
printf ("Ethernet addr: %!\n", nic->node_addr);
#if defined(W89C840_DEBUG)
printf("winbond-840: EEPROM checksum %hX, got eeprom", sum);
#endif
/* Reset the chip to erase previous misconfiguration.
No hold time required! */
writel(0x00000001, ioaddr + PCIBusCfg);
if (driver_flags & CanHaveMII) {
int phy, phy_idx = 0;
for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
int mii_status = mdio_read(ioaddr, phy, 1);
if (mii_status != 0xffff && mii_status != 0x0000) {
w840private.phys[phy_idx++] = phy;
w840private.advertising = mdio_read(ioaddr, phy, 4);
#if defined(W89C840_DEBUG)
printf("winbond-840 : MII PHY found at address %d, status "
"%X advertising %hX.\n", phy, mii_status, w840private.advertising);
#endif
}
}
w840private.mii_cnt = phy_idx;
if (phy_idx == 0) {
printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
}
}
/* point to NIC specific routines */
nic->reset = w89c840_reset;
nic->poll = w89c840_poll;
nic->transmit = w89c840_transmit;
nic->disable = w89c840_disable;
w89c840_reset(nic);
return nic;
}
/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. These are
often serial bit streams generated by the host processor.
The example below is for the common 93c46 EEPROM, 64 16 bit words. */
/* Delay between EEPROM clock transitions.
No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
made udelay() unreliable.
The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
depricated.
*/
#define eeprom_delay(ee_addr) readl(ee_addr)
enum EEPROM_Ctrl_Bits {
EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805,
EE_ChipSelect=0x801, EE_DataIn=0x08,
};
/* The EEPROM commands include the alway-set leading bit. */
enum EEPROM_Cmds {
EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
};
static int eeprom_read(long addr, int location)
{
int i;
int retval = 0;
int ee_addr = addr + EECtrl;
int read_cmd = location | EE_ReadCmd;
writel(EE_ChipSelect, ee_addr);
/* Shift the read command bits out. */
for (i = 10; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
writel(dataval, ee_addr);
eeprom_delay(ee_addr);
writel(dataval | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
}
writel(EE_ChipSelect, ee_addr);
for (i = 16; i > 0; i--) {
writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
eeprom_delay(ee_addr);
retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0);
writel(EE_ChipSelect, ee_addr);
eeprom_delay(ee_addr);
}
/* Terminate the EEPROM access. */
writel(0, ee_addr);
return retval;
}
/* MII transceiver control section.
Read and write the MII registers using software-generated serial
MDIO protocol. See the MII specifications or DP83840A data sheet
for details.
The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
met by back-to-back 33Mhz PCI cycles. */
#define mdio_delay(mdio_addr) readl(mdio_addr)
/* Set iff a MII transceiver on any interface requires mdio preamble.
This only set with older tranceivers, so the extra
code size of a per-interface flag is not worthwhile. */
static char mii_preamble_required = 1;
#define MDIO_WRITE0 (MDIO_EnbOutput)
#define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput)
/* Generate the preamble required for initial synchronization and
a few older transceivers. */
static void mdio_sync(long mdio_addr)
{
int bits = 32;
/* Establish sync by sending at least 32 logic ones. */
while (--bits >= 0) {
writel(MDIO_WRITE1, mdio_addr);
mdio_delay(mdio_addr);
writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
mdio_delay(mdio_addr);
}
}
static int mdio_read(int base_address, int phy_id, int location)
{
long mdio_addr = base_address + MIICtrl;
int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
int i, retval = 0;
if (mii_preamble_required)
mdio_sync(mdio_addr);
/* Shift the read command bits out. */
for (i = 15; i >= 0; i--) {
int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
writel(dataval, mdio_addr);
mdio_delay(mdio_addr);
writel(dataval | MDIO_ShiftClk, mdio_addr);
mdio_delay(mdio_addr);
}
/* Read the two transition, 16 data, and wire-idle bits. */
for (i = 20; i > 0; i--) {
writel(MDIO_EnbIn, mdio_addr);
mdio_delay(mdio_addr);
retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
mdio_delay(mdio_addr);
}
return (retval>>1) & 0xffff;
}
static void mdio_write(int base_address, int phy_id, int location, int value)
{
long mdio_addr = base_address + MIICtrl;
int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
int i;
if (location == 4 && phy_id == w840private.phys[0])
w840private.advertising = value;
if (mii_preamble_required)
mdio_sync(mdio_addr);
/* Shift the command bits out. */
for (i = 31; i >= 0; i--) {
int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
writel(dataval, mdio_addr);
mdio_delay(mdio_addr);
writel(dataval | MDIO_ShiftClk, mdio_addr);
mdio_delay(mdio_addr);
}
/* Clear out extra bits. */
for (i = 2; i > 0; i--) {
writel(MDIO_EnbIn, mdio_addr);
mdio_delay(mdio_addr);
writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
mdio_delay(mdio_addr);
}
return;
}
static void check_duplex(void)
{
int mii_reg5 = mdio_read(ioaddr, w840private.phys[0], 5);
int negotiated = mii_reg5 & w840private.advertising;
int duplex;
if (w840private.duplex_lock || mii_reg5 == 0xffff)
return;
duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
if (w840private.full_duplex != duplex) {
w840private.full_duplex = duplex;
#if defined(W89C840_DEBUG)
printf("winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n",
duplex ? "full" : "half", w840private.phys[0], negotiated);
#endif
w840private.csr6 &= ~0x200;
w840private.csr6 |= duplex ? 0x200 : 0;
}
}
static void set_rx_mode(void)
{
u32 mc_filter[2]; /* Multicast hash filter */
u32 rx_mode;
/* Accept all multicasts from now on. */
memset(mc_filter, 0xff, sizeof(mc_filter));
/*
* Actually, should work OK with multicast enabled. -- iko
*/
/*
* rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
*/
rx_mode = AcceptBroadcast | AcceptMyPhys;
writel(mc_filter[0], ioaddr + MulticastFilter0);
writel(mc_filter[1], ioaddr + MulticastFilter1);
w840private.csr6 &= ~0x00F8;
w840private.csr6 |= rx_mode;
writel(w840private.csr6, ioaddr + NetworkConfig);
#if defined(W89C840_DEBUG)
printf("winbond-840 : Done setting RX mode.\n");
#endif
}
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
static void init_ring(void)
{
int i;
char * p;
w840private.tx_full = 0;
w840private.tx_q_bytes = w840private.cur_rx = w840private.cur_tx = 0;
w840private.dirty_rx = w840private.dirty_tx = 0;
w840private.rx_buf_sz = PKT_BUF_SZ;
w840private.rx_head_desc = &w840private.rx_ring[0];
/* Initial all Rx descriptors. Fill in the Rx buffers. */
p = &rx_packet[0];
for (i = 0; i < RX_RING_SIZE; i++) {
w840private.rx_ring[i].length = w840private.rx_buf_sz;
w840private.rx_ring[i].status = 0;
w840private.rx_ring[i].next_desc = virt_to_le32desc(&w840private.rx_ring[i+1]);
w840private.rx_ring[i].buffer1 = virt_to_le32desc(p + (PKT_BUF_SZ * i));
w840private.rx_ring[i].status = DescOwn | DescIntr;
}
/* Mark the last entry as wrapping the ring. */
w840private.rx_ring[i-1].length |= DescEndRing;
w840private.rx_ring[i-1].next_desc = virt_to_le32desc(&w840private.rx_ring[0]);
w840private.dirty_rx = (unsigned int)(i - RX_RING_SIZE);
for (i = 0; i < TX_RING_SIZE; i++) {
w840private.tx_ring[i].status = 0;
}
return;
}

View file

@ -1,4 +0,0 @@
.deps
Makefile
stage1
stage1.exec

View file

@ -1,15 +0,0 @@
pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
nodist_pkglib_DATA = stage1
CLEANFILES = $(nodist_pkglib_DATA)
# We can't use builtins or standard includes.
AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
stage1_exec_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
noinst_PROGRAMS = stage1.exec
stage1_exec_SOURCES = stage1.S stage1.h
SUFFIXES = .exec
.exec:
$(OBJCOPY) -O binary $< $@

View file

@ -1,434 +0,0 @@
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 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.
@SET_MAKE@
SOURCES = $(stage1_exec_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = stage1.exec$(EXEEXT)
subdir = stage1
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_stage1_exec_OBJECTS = stage1.$(OBJEXT)
stage1_exec_OBJECTS = $(am_stage1_exec_OBJECTS)
stage1_exec_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(stage1_exec_SOURCES)
DIST_SOURCES = $(stage1_exec_SOURCES)
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(pkglibdir)"
nodist_pkglibDATA_INSTALL = $(INSTALL_DATA)
DATA = $(nodist_pkglib_DATA)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FSYS_CFLAGS = @FSYS_CFLAGS@
GRUB_CFLAGS = @GRUB_CFLAGS@
GRUB_LIBS = @GRUB_LIBS@
HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
NET_CFLAGS = @NET_CFLAGS@
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
RANLIB = @RANLIB@
SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STAGE1_CFLAGS = @STAGE1_CFLAGS@
STAGE2_CFLAGS = @STAGE2_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
nodist_pkglib_DATA = stage1
CLEANFILES = $(nodist_pkglib_DATA)
# We can't use builtins or standard includes.
AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
stage1_exec_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
stage1_exec_SOURCES = stage1.S stage1.h
SUFFIXES = .exec
all: all-am
.SUFFIXES:
.SUFFIXES: .exec .S .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu stage1/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu stage1/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
stage1.exec$(EXEEXT): $(stage1_exec_OBJECTS) $(stage1_exec_DEPENDENCIES)
@rm -f stage1.exec$(EXEEXT)
$(LINK) $(stage1_exec_LDFLAGS) $(stage1_exec_OBJECTS) $(stage1_exec_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
.S.o:
$(CCASCOMPILE) -c $<
.S.obj:
$(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
uninstall-info-am:
install-nodist_pkglibDATA: $(nodist_pkglib_DATA)
@$(NORMAL_INSTALL)
test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)"
@list='$(nodist_pkglib_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(nodist_pkglibDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \
$(nodist_pkglibDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \
done
uninstall-nodist_pkglibDATA:
@$(NORMAL_UNINSTALL)
@list='$(nodist_pkglib_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(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 -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(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 "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) $(DATA)
installdirs:
for dir in "$(DESTDIR)$(pkglibdir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am: install-nodist_pkglibDATA
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-nodist_pkglibDATA
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstPROGRAMS ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-nodist_pkglibDATA \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-nodist_pkglibDATA
.exec:
$(OBJCOPY) -O binary $< $@
# 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:

Some files were not shown because too many files have changed in this diff Show more