heavily rewrite the netboot support.
This commit is contained in:
parent
a2018f29ff
commit
9fe0449a36
36 changed files with 5132 additions and 2080 deletions
147
ChangeLog
147
ChangeLog
|
@ -1,3 +1,150 @@
|
|||
2000-02-07 OKUJI Yoshinori <okuji@gnu.org>
|
||||
|
||||
The netboot support is heavily rewritten, based on
|
||||
Etherboot-4.4.2. The current one doesn't work yet, so check out
|
||||
GRUB with the tag "dresden_netboot_code" if you need working
|
||||
one.
|
||||
|
||||
* configure.in (--enable-tftp): Deleted.
|
||||
(FSYS_CFLAGS): `AC_SUBST'ed right before AC_OUTPUT.
|
||||
(NETBOOT_DRIVERS): New variable. AC_SUBST this after examining
|
||||
the driver options.
|
||||
(--enable-packet-retransmission): New option.
|
||||
(--enable-pci-direct): Likewise.
|
||||
(--enable-3c509): Likewise.
|
||||
(--enable-3c529): Likewise.
|
||||
(--enable-3c90x): Likewise.
|
||||
(--enable-cs89x0): Likewise.
|
||||
(--enable-epic100): Likewise.
|
||||
(--enable-3c507): Likewise.
|
||||
(--enable-exos205): Likewise.
|
||||
(--enable-ni5210): Likewise.
|
||||
(--enable-lancepci): Likewise.
|
||||
(--enable-ne2100): Likewise.
|
||||
(--enable-ni6510): Likewise.
|
||||
(--enable-3c503): Likewise.
|
||||
(--enable-ntulip): Likewise.
|
||||
(--enable-rtl8139): Likewise.
|
||||
(--enable-sk-g16): Likewise.
|
||||
(--enable-smc9000): Likewise.
|
||||
(--enable-tiara): Likewise.
|
||||
(--enable-tulip): Likewise.
|
||||
(--enable-via-rhine): Likewise.
|
||||
(--enable-3c503-shmem): Likewise.
|
||||
(--enable-3c503-aui): Likewise.
|
||||
(--enable-3c509-hack): Likewise.
|
||||
(--enable-compex-rl2000-fix): Likewise.
|
||||
(--enable-smc9000-scan): Likewise.
|
||||
(--enable-t503): Deleted.
|
||||
(--enable-lance): Likewise.
|
||||
(--enable-cs): Likewise.
|
||||
|
||||
* netboot/main.c: New file. Copied and modified.
|
||||
* netboot/linux-asm-io.h: Likewise.
|
||||
* netboot/etherboot.h: Likewise.
|
||||
* netboot/misc.c: Likewise.
|
||||
* netboot/via-rhine.c: Likewise.
|
||||
* netboot/3c90x.c: Likewise.
|
||||
* netboot/3c90x.txt: Likewise.
|
||||
* netboot/epic100.c: Likewise.
|
||||
* netboot/epic100.h: Likewise.
|
||||
* netboot/i82586.c: Likewise.
|
||||
* netboot/linux-asm-string.h: Likewise.
|
||||
* netboot/ntulip.c: Likewise.
|
||||
* netboot/ntulip.txt: Likewise.
|
||||
* netboot/osdep.h: Likewise.
|
||||
* netboot/rtl8139.c: Likewise.
|
||||
* netboot/sk_g16.c: Likewise.
|
||||
* netboot/sk_g16.h: Likewise.
|
||||
* netboot/smc9000.c: Likewise.
|
||||
* netboot/smc9000.h: Likewise.
|
||||
* netboot/tiara.c: Likewise.
|
||||
* netboot/tulip.c: Likewise.
|
||||
* netboot/tulip.h: Likewise.
|
||||
* netboot/README.netboot: New file. Most information is stolen
|
||||
from Makefile and Config.32 in Etherboot.
|
||||
* netboot/3c509.c: Copied from Etherboot. The original is
|
||||
removed.
|
||||
* netboot/3c509.h: Likewise.
|
||||
* netboot/cs89x0.c: Likewise.
|
||||
* netboot/eepro100.c: Likewise.
|
||||
* netboot/lance.c: Likewise.
|
||||
* netboot/ns8390.c: Likewise.
|
||||
* netboot/ns8390.h: Likewise.
|
||||
* netboot/pci.c: Likewise.
|
||||
|
||||
* netboot/3c59x.c: Include etherboot.h instead netboot.h.
|
||||
* netboot/config.c: Copied from Etherboot and added the 3c59x
|
||||
entries.
|
||||
* netboot/pci.h: Likewise.
|
||||
* netboot/fsys_tftp.c: Entirely rewritten based on main.c in
|
||||
Etherboot.
|
||||
|
||||
* netboot/io.h: Removed.
|
||||
* netboot/ip.h: Likewise.
|
||||
* netboot/ip.c: Likewise.
|
||||
* netboot/netboot.h: Likewise.
|
||||
|
||||
* netboot/Makefile.am (INCLUDES): Added -I$(top_srcdir)/stage2.
|
||||
(DRIVERS): Removed.
|
||||
(libdrivers_a_SOURCES): Added etherboot.h, linux-asm-io.h,
|
||||
linux-asm-string.h, main.c, misc.c and osdep.h. Deleted io.h,
|
||||
ip.h, ip.c, netboot.h and $(DRIVERS).
|
||||
(EXTRA_libdrivers_a_SOURCES): New variable.
|
||||
(libdrivers_a_LIBADD): Set to @NETBOOT_DRIVERS@.
|
||||
(libdrivers_a_DEPENDENCIES): New variable.
|
||||
(EXTRA_DIST): Likewise.
|
||||
(3c509_drivers): New variable. Define a new rule for the value.
|
||||
(3c59x_drivers): Likewise.
|
||||
(3c90x_drivers): Likewise.
|
||||
(cs89x0_drivers): Likewise.
|
||||
(eepro100_drivers): Likewise.
|
||||
(epic100_drivers): Likewise.
|
||||
(i82586_drivers): Likewise.
|
||||
(lance_drivers): Likewise.
|
||||
(ns8390_drivers): Likewise.
|
||||
(ntulip_drivers): Likewise.
|
||||
(rtl8139_drivers): Likewise.
|
||||
(sk_g16_drivers): Likewise.
|
||||
(smc9000_drivers): Likewise.
|
||||
(tiara_drivers): Likewise.
|
||||
(tulip_drivers): Likewise.
|
||||
(via_rhine_drivers): Likewise.
|
||||
(t503_o_CFLAGS): Removed.
|
||||
(nepci_o_CFLAGS): Set to -DINCLUDE_NEPCI=1.
|
||||
(ne_o_CFLAGS): Set to -DINCLUDE_NE=1.
|
||||
(wd_o_CFLAGS): Set to -DINCLUDE_WD=1.
|
||||
(3c509_o_CFLAGS): Likewise.
|
||||
(3c529_o_CFLAGS): Likewise.
|
||||
(3c59x_o_CFLAGS): Likewise.
|
||||
(3c90x_o_CFLAGS): Likewise.
|
||||
(cs89x0_o_CFLAGS): Likewise.
|
||||
(eepro100_o_CFLAGS): Likewise.
|
||||
(epic100_o_CFLAGS): Likewise.
|
||||
(3c507_o_CFLAGS): Likewise.
|
||||
(exos205_o_CFLAGS): Likewise.
|
||||
(ni5210_o_CFLAGS): Likewise.
|
||||
(lancepci_o_CFLAGS): Likewise.
|
||||
(ne2100_o_CFLAGS): Likewise.
|
||||
(ni6510_o_CFLAGS): Likewise.
|
||||
(3c503_o_CFLAGS): Likewise.
|
||||
(ntulip_o_CFLAGS): Likewise.
|
||||
(rtl8139_o_CFLAGS): Likewise.
|
||||
(sk_g16_o_CFLAGS): Likewise.
|
||||
(smc9000_o_CFLAGS): Likewise.
|
||||
(tiara_o_CFLAGS): Likewise.
|
||||
(tulip_o_CFLAGS): Likewise.
|
||||
(via_rhine_o_CFLAGS): Likewise.
|
||||
|
||||
* stage2/char_io.c (nul_terminate): Changed the type of the
|
||||
return value to int. Return the original character changed to
|
||||
NUL.
|
||||
* stage2/shared.h (NETWORK_DRIVE): New macro.
|
||||
(nul_terminate): Adjusted to the definition.
|
||||
* stage2/gunzip.c (gunzip_test_header): Removed the TFTP check
|
||||
entirely. It is no longer necessary because we now can obtain
|
||||
the correct size of a file even for TFTP.
|
||||
|
||||
2000-02-07 OKUJI Yoshinori <okuji@gnu.org>
|
||||
|
||||
* stage2/asm.S: Undo the previous changes. Is
|
||||
|
|
|
@ -68,6 +68,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
282
configure.in
282
configure.in
|
@ -190,12 +190,12 @@ if test x"$enable_minix" != xno; then
|
|||
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_MINIX=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(tftp,
|
||||
[ --enable-tftp enable TFTP support in Stage 2])
|
||||
|
||||
if test x"$enable_tftp" = xyes; then
|
||||
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
|
||||
fi
|
||||
dnl AC_ARG_ENABLE(tftp,
|
||||
dnl [ --enable-tftp enable TFTP support in Stage 2])
|
||||
dnl
|
||||
dnl #if test x"$enable_tftp" = xyes; then
|
||||
dnl FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
|
||||
dnl fi
|
||||
|
||||
AC_ARG_ENABLE(gunzip,
|
||||
[ --disable-gunzip disable decompression in Stage 2])
|
||||
|
@ -204,93 +204,251 @@ if test x"$enable_gunzip" = xno; then
|
|||
FSYS_CFLAGS="$FSYS_CFLAGS -DNO_DECOMPRESSION=1"
|
||||
fi
|
||||
|
||||
AC_SUBST(FSYS_CFLAGS)
|
||||
|
||||
AC_ARG_ENABLE(ne,
|
||||
[ --enable-ne enable NE1000/2000 network driver in Stage 2])
|
||||
|
||||
if test x"$enable_ne" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
|
||||
dnl The netboot support.
|
||||
dnl General options.
|
||||
AC_ARG_ENABLE(packet-retransmission,
|
||||
[ --enable-packet-retransmission
|
||||
turn on packet retransmission])
|
||||
if test "x$enable_packet_retransmission" = xyes; then
|
||||
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(nepci,
|
||||
[ --enable-nepci enable PCI NE2000 network driver in Stage 2])
|
||||
|
||||
if test x"$enable_nepci" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NEPCI=1"
|
||||
AC_ARG_ENABLE(pci-direct,
|
||||
[ --enable-pci-direct access PCI directly instead of using BIOS])
|
||||
if test "x$enable_pci_direct" = xyes; then
|
||||
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONFIG_PCI_DIRECT=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(wd,
|
||||
[ --enable-wd enable WD/SMC network driver in Stage 2])
|
||||
|
||||
if test x"$enable_wd" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
|
||||
dnl Device drivers.
|
||||
AC_ARG_ENABLE(3c509,
|
||||
[ --enable-3c509 enable 3Com509 driver])
|
||||
if test "x$enable_3c509" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C509"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c509.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(t503,
|
||||
[ --enable-t503 enable 3C503 network driver in Stage 2])
|
||||
|
||||
if test x"$enable_t503" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_T503=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(t509,
|
||||
[ --enable-t509 enable 3C509 network driver in Stage 2])
|
||||
|
||||
if test x"$enable_t509" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_T509=1"
|
||||
AC_ARG_ENABLE(3c529,
|
||||
[ --enable-3c529 enable 3Com529 driver])
|
||||
if test "x$enable_3c529" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C529=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c529.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(3c59x,
|
||||
[ --enable-3c59x enable 3C59x network driver in Stage 2])
|
||||
|
||||
if test x"$enable_3c59x" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C59X=1"
|
||||
[ --enable-3c59x enable 3Com59x driver])
|
||||
if test "x$enable_3c59x" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C59x=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c59x.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(lance,
|
||||
[ --enable-lance enable LANCE network driver in Stage 2])
|
||||
|
||||
if test x"$enable_lance" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
|
||||
AC_ARG_ENABLE(3c90x,
|
||||
[ --enable-3c90x enable 3Com90x driver])
|
||||
if test "x$enable_3c90x" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C90x=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c90x.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(cs,
|
||||
[ --enable-cs enable CS89*0 network driver in Stage 2])
|
||||
|
||||
if test x"$enable_cs" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS=1"
|
||||
AC_ARG_ENABLE(cs89x0,
|
||||
[ --enable-cs89x0 enable CS89x0 driver])
|
||||
if test "x$enable_cs89x0" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS89X0=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS cs89x0.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(eepro100,
|
||||
[ --enable-eepro100 enable EtherExpress100 network driver in Stage 2])
|
||||
|
||||
if test x"$enable_eepro100" = xyes; then
|
||||
[ --enable-eepro100 enable Etherexpress Pro/100 driver])
|
||||
if test "x$enable_eepro100" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO100=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS eepro100.o"
|
||||
fi
|
||||
|
||||
AC_SUBST(NET_CFLAGS)
|
||||
AM_CONDITIONAL(NETBOOT_SUPPORT, test ! -z "$NET_CFLAGS")
|
||||
AC_ARG_ENABLE(epic100,
|
||||
[ --enable-epic100 enable SMC 83c170 EPIC/100 driver])
|
||||
if test "x$enable_epic100" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EPIC100=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS epic100.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(3c507,
|
||||
[ --enable-3c507 enable 3Com507 driver])
|
||||
if test "x$enable_3c507" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C507=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c507.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(exos205,
|
||||
[ --enable-exos205 enable EXOS205 driver])
|
||||
if test "x$enable_exos205" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EXOS205=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS exos205.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(ni5210,
|
||||
[ --enable-ni5210 enable Racal-Interlan NI5210 driver])
|
||||
if test "x$enable_ni5210" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5210=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5210.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(lancepci,
|
||||
[ --enable-lancepci enable Lance PCI PCNet/32 driver])
|
||||
if test "x$enable_lancepci" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCEPCI=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS lancepci.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(ne2100,
|
||||
[ --enable-ne2100 enable Novell NE2100 driver])
|
||||
if test "x$enable_ne2100" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE2100=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne2100.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(ni6510,
|
||||
[ --enable-ni6510 enable Racal-Interlan NI6510 driver])
|
||||
if test "x$enable_ni6510" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI6510=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni6510.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(3c503,
|
||||
[ --enable-3c503 enable 3Com503 driver])
|
||||
if test "x$enable_3c503" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C503=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c503.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(ne,
|
||||
[ --enable-ne enable NE1000/2000 ISA driver])
|
||||
if test "x$enable_ne" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(nepci,
|
||||
[ --enable-nepci enable NE2000 PCI driver])
|
||||
if test "x$enable_nepci" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NEPCI=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS nepci.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(wd,
|
||||
[ --enable-wd enable WD8003/8013, SMC8216/8416 driver])
|
||||
if test "x$enable_wd" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS wd.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(ntulip,
|
||||
[ --enable-ntulip enable Tulip driver])
|
||||
if test "x$enable_ntulip" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NTULIP=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS ntulip.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(rtl8139,
|
||||
[ --enable-rtl8139 enable Realtek 8139 driver])
|
||||
if test "x$enable_rtl8139" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_RTL8139=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS rtl8139.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(sk-g16,
|
||||
[ --enable-sk-g16 enable Schneider and Koch G16 driver])
|
||||
if test "x$enable_sk_g16" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SK_G16=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS sk_g16.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(smc9000,
|
||||
[ --enable-smc9000 enable SMC9000 driver])
|
||||
if test "x$enable_smc9000" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SMC9000=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS smc9000.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(tiara,
|
||||
[ --enable-tiara enable Tiara driver])
|
||||
if test "x$enable_tiara" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TIARA=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS tiara.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(tulip,
|
||||
[ --enable-tulip enable old Tulip driver])
|
||||
if test "x$enable_tulip" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TULIP=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS tulip.o"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(via-rhine,
|
||||
[ --enable-via-rhine enable Rhine-I/II driver])
|
||||
if test "x$enable_via_rhine" = xyes; then
|
||||
NET_CFLAGS="$NET_CFLAGS -DINCLUDE_VIA_RHINE=1"
|
||||
NETBOOT_DRIVERS="$NETBOOT_DRIVERS via_rhine.o"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(NETBOOT_SUPPORT, test "x$NET_CFLAGS" != x)
|
||||
if test "x$NET_CFLAGS" != x; then
|
||||
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
|
||||
fi
|
||||
|
||||
dnl Extra options.
|
||||
AC_ARG_ENABLE(3c503-shmem,
|
||||
[ --enable-3c503-shmem use 3c503 shared memory mode])
|
||||
if test "x$enable_3c503_shmem" = xyes; then
|
||||
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_SHMEM=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(3c503-aui,
|
||||
[ --enable-3c503-aui use AUI by default on 3c503 cards])
|
||||
if test "x$enable_3c503_aui" = xyes; then
|
||||
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_AUI=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(3c509-hack,
|
||||
[ --enable-3c509-hack make a 3c509 do bootp quicker])
|
||||
if test "x$enable_3c509_hack" = xyes; then
|
||||
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT509HACK=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(compex-rl2000-fix,
|
||||
[ --enable-compex-rl2000-fix
|
||||
specify this if you have a Compex RL2000 PCI])
|
||||
if test "x$enable_compex_rl2000_fix" = xyes; then
|
||||
NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCOMPEX_RL2000_FIX=1"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(smc9000,
|
||||
[ --enable-smc9000-scan=LIST
|
||||
probe for SMC9000 I/O addresses using LIST],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DSMC9000_SCAN=$enable_smc9000_scan"])
|
||||
|
||||
AC_ARG_ENABLE(ne-scan,
|
||||
[ --enable-ne-scan set the parameter for NE network driver],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=$enable_ne_scan"],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=0x280,0x300,0x320,0x340"])
|
||||
[ --enable-ne-scan=LIST probe for NE base address using LIST],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=$enable_ne_scan"],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=0x280,0x300,0x320,0x340"])
|
||||
|
||||
AC_ARG_ENABLE(wd-default-mem,
|
||||
[ --enable-wd-default-mem set the parameter for WD network driver],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=$enable_wd_default_mem"],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"])
|
||||
[ --enable-wd-default-mem=MEM
|
||||
set the default memory location for WD/SMC],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=$enable_wd_default_mem"],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"])
|
||||
|
||||
AC_ARG_ENABLE(cs-scan,
|
||||
[ --enable-cs-scan set the parameter for CS network driver],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"])
|
||||
[ --enable-cs-scan=LIST probe for CS89x0 base address using LIST],
|
||||
[NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"])
|
||||
|
||||
|
||||
dnl Now substitute the variables.
|
||||
AC_SUBST(FSYS_CFLAGS)
|
||||
AC_SUBST(NET_CFLAGS)
|
||||
AC_SUBST(NET_EXTRAFLAGS)
|
||||
AC_SUBST(NETBOOT_DRIVERS)
|
||||
|
||||
|
||||
# Output.
|
||||
dnl Output.
|
||||
AC_OUTPUT([Makefile stage1/Makefile stage2/Makefile docs/Makefile \
|
||||
debian/Makefile lib/Makefile util/Makefile grub/Makefile \
|
||||
netboot/Makefile util/grub-install])
|
||||
|
|
1
debian/Makefile.in
vendored
1
debian/Makefile.in
vendored
|
@ -68,6 +68,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
|
@ -68,6 +68,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
|
@ -68,6 +68,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
|
@ -68,6 +68,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
259
netboot/3c509.c
259
netboot/3c509.c
|
@ -1,5 +1,5 @@
|
|||
/**************************************************************************
|
||||
NETBOOT - BOOTP/TFTP Bootstrap Program
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters.
|
||||
Date: Mar 22 1995
|
||||
|
@ -22,11 +22,9 @@ $Id$
|
|||
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_T509
|
||||
|
||||
/* #define EDEBUG */
|
||||
|
||||
#include "netboot.h"
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "3c509.h"
|
||||
|
||||
|
@ -34,6 +32,28 @@ static unsigned char eth_vendor, eth_flags, eth_laar;
|
|||
static unsigned short eth_nic_base, eth_asic_base;
|
||||
static char bnc=0, utp=0; /* for 3C509 */
|
||||
|
||||
#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 {
|
||||
char* name;
|
||||
int id;
|
||||
};
|
||||
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
|
||||
|
||||
static void safetwiddle()
|
||||
{
|
||||
static int count=0;
|
||||
|
@ -78,17 +98,17 @@ static void t509_reset(struct nic *nic)
|
|||
return;
|
||||
|
||||
/* stop card */
|
||||
outw(BASE + EP_COMMAND, RX_DISABLE);
|
||||
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||
outw(RX_DISABLE, BASE + EP_COMMAND);
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
|
||||
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
|
||||
outw(BASE + EP_COMMAND, TX_DISABLE);
|
||||
outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
|
||||
outw(BASE + EP_COMMAND, RX_RESET);
|
||||
outw(BASE + EP_COMMAND, TX_RESET);
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
outw(BASE + EP_COMMAND, SET_RD_0_MASK);
|
||||
outw(BASE + EP_COMMAND, SET_INTR_MASK);
|
||||
outw(BASE + EP_COMMAND, SET_RX_FILTER);
|
||||
outw(TX_DISABLE, BASE + EP_COMMAND);
|
||||
outw(STOP_TRANSCEIVER, BASE + EP_COMMAND);
|
||||
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
|
||||
|
@ -98,22 +118,22 @@ static void t509_reset(struct nic *nic)
|
|||
GO_WINDOW(0);
|
||||
|
||||
/* Disable the card */
|
||||
outw(BASE + EP_W0_CONFIG_CTRL, 0);
|
||||
outw(0, BASE + EP_W0_CONFIG_CTRL);
|
||||
|
||||
/* Configure IRQ to none */
|
||||
outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(0));
|
||||
outw(SET_IRQ(0), BASE + EP_W0_RESOURCE_CFG);
|
||||
|
||||
/* Enable the card */
|
||||
outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
|
||||
outw(ENABLE_DRQ_IRQ, BASE + EP_W0_CONFIG_CTRL);
|
||||
|
||||
GO_WINDOW(2);
|
||||
|
||||
/* Reload the ether_addr. */
|
||||
for (i = 0; i < ETHER_ADDR_SIZE; i++)
|
||||
outb(BASE + EP_W2_ADDR_0 + i, nic->node_addr[i]);
|
||||
outb(nic->node_addr[i], BASE + EP_W2_ADDR_0 + i);
|
||||
|
||||
outw(BASE + EP_COMMAND, RX_RESET);
|
||||
outw(BASE + EP_COMMAND, TX_RESET);
|
||||
outw(RX_RESET, BASE + EP_COMMAND);
|
||||
outw(TX_RESET, BASE + EP_COMMAND);
|
||||
|
||||
/* Window 1 is operating window */
|
||||
GO_WINDOW(1);
|
||||
|
@ -121,35 +141,35 @@ static void t509_reset(struct nic *nic)
|
|||
inb(BASE + EP_W1_TX_STATUS);
|
||||
|
||||
/* get rid of stray intr's */
|
||||
outw(BASE + EP_COMMAND, ACK_INTR | 0xff);
|
||||
outw(ACK_INTR | 0xff, BASE + EP_COMMAND);
|
||||
|
||||
outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
|
||||
outw(SET_RD_0_MASK | S_5_INTS, BASE + EP_COMMAND);
|
||||
|
||||
outw(BASE + EP_COMMAND, SET_INTR_MASK);
|
||||
outw(SET_INTR_MASK, BASE + EP_COMMAND);
|
||||
|
||||
outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
|
||||
FIL_BRDCST);
|
||||
outw(SET_RX_FILTER | FIL_INDIVIDUAL |
|
||||
FIL_BRDCST, BASE + EP_COMMAND);
|
||||
|
||||
/* configure BNC */
|
||||
if (bnc) {
|
||||
outw(BASE + EP_COMMAND, START_TRANSCEIVER);
|
||||
SAFEDELAY(1000);
|
||||
outw(START_TRANSCEIVER, BASE + EP_COMMAND);
|
||||
SAFEDELAY(10000);
|
||||
}
|
||||
/* configure UTP */
|
||||
if (utp) {
|
||||
GO_WINDOW(4);
|
||||
outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
|
||||
outw(ENABLE_UTP, BASE + EP_W4_MEDIA_TYPE);
|
||||
GO_WINDOW(1);
|
||||
}
|
||||
|
||||
/* start tranciever and receiver */
|
||||
outw(BASE + EP_COMMAND, RX_ENABLE);
|
||||
outw(BASE + EP_COMMAND, TX_ENABLE);
|
||||
outw(RX_ENABLE, BASE + EP_COMMAND);
|
||||
outw(TX_ENABLE, BASE + EP_COMMAND);
|
||||
|
||||
/* set early threshold for minimal packet length */
|
||||
outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | ETH_MIN_PACKET);
|
||||
outw(SET_RX_EARLY_THRESH | ETH_MIN_PACKET, BASE + EP_COMMAND);
|
||||
|
||||
outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);
|
||||
outw(SET_TX_START_THRESH | 16, BASE + EP_COMMAND);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -165,7 +185,7 @@ unsigned int t, /* Type */
|
|||
unsigned int s, /* size */
|
||||
char *p) /* Packet */
|
||||
{
|
||||
register u_int len;
|
||||
register unsigned int len;
|
||||
int pad;
|
||||
int status;
|
||||
|
||||
|
@ -194,30 +214,30 @@ char *p) /* Packet */
|
|||
/* drop acknowledgements */
|
||||
while(( status=inb(BASE + EP_W1_TX_STATUS) )& TXS_COMPLETE ) {
|
||||
if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
|
||||
outw(BASE + EP_COMMAND, TX_RESET);
|
||||
outw(BASE + EP_COMMAND, TX_ENABLE);
|
||||
outw(TX_RESET, BASE + EP_COMMAND);
|
||||
outw(TX_ENABLE, BASE + EP_COMMAND);
|
||||
}
|
||||
|
||||
outb(BASE + EP_W1_TX_STATUS, 0x0);
|
||||
outb(0x0, BASE + EP_W1_TX_STATUS);
|
||||
}
|
||||
|
||||
while (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
|
||||
/* no room in FIFO */
|
||||
}
|
||||
|
||||
outw(BASE + EP_W1_TX_PIO_WR_1, len);
|
||||
outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
|
||||
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, ETHER_ADDR_SIZE/2);
|
||||
outsw(BASE + EP_W1_TX_PIO_WR_1, nic->node_addr, ETHER_ADDR_SIZE/2);
|
||||
outw(BASE + EP_W1_TX_PIO_WR_1, t);
|
||||
outw(t, BASE + EP_W1_TX_PIO_WR_1);
|
||||
outsw(BASE + EP_W1_TX_PIO_WR_1, p, s / 2);
|
||||
if (s & 1)
|
||||
outb(BASE + EP_W1_TX_PIO_WR_1, *(p+s - 1));
|
||||
outb(*(p+s - 1), BASE + EP_W1_TX_PIO_WR_1);
|
||||
|
||||
while (pad--)
|
||||
outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */
|
||||
outb(0, BASE + EP_W1_TX_PIO_WR_1); /* Padding */
|
||||
|
||||
/* timeout after sending */
|
||||
DELAY(1000);
|
||||
|
@ -246,8 +266,8 @@ static int t509_poll(struct nic *nic)
|
|||
|
||||
if( (cst & S_RX_COMPLETE)==0 ) {
|
||||
/* acknowledge everything */
|
||||
outw(BASE + EP_COMMAND, ACK_INTR| (cst & S_5_INTS));
|
||||
outw(BASE + EP_COMMAND, C_INTR_LATCH);
|
||||
outw(ACK_INTR| (cst & S_5_INTS), BASE + EP_COMMAND);
|
||||
outw(C_INTR_LATCH, BASE + EP_COMMAND);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,7 +278,7 @@ static int t509_poll(struct nic *nic)
|
|||
#endif
|
||||
|
||||
if (status & ERR_RX) {
|
||||
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||
outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -303,7 +323,7 @@ static int t509_poll(struct nic *nic)
|
|||
}
|
||||
|
||||
/* acknowledge reception of packet */
|
||||
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||
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];
|
||||
|
@ -328,8 +348,8 @@ eeprom_rdy()
|
|||
|
||||
for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);
|
||||
if (i >= MAX_EEPROMBUSY) {
|
||||
/* printf("3c509: eeprom failed to come ready.\r\n"); */
|
||||
printf("3c509: eeprom is busy.\r\n"); /* memory in EPROM is tight */
|
||||
/* printf("3c509: eeprom failed to come ready.\n"); */
|
||||
printf("3c509: eeprom is busy.\n"); /* memory in EPROM is tight */
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
|
@ -345,7 +365,7 @@ int offset;
|
|||
{
|
||||
if (!eeprom_rdy())
|
||||
return (0xffff);
|
||||
outw(IS_BASE + EP_W0_EEPROM_COMMAND, EEPROM_CMD_RD | offset);
|
||||
outw(EEPROM_CMD_RD | offset, IS_BASE + EP_W0_EEPROM_COMMAND);
|
||||
if (!eeprom_rdy())
|
||||
return (0xffff);
|
||||
return (inw(IS_BASE + EP_W0_EEPROM_DATA));
|
||||
|
@ -358,7 +378,7 @@ int port;
|
|||
int cx, al;
|
||||
|
||||
for (al = 0xff, cx = 0; cx < 255; cx++) {
|
||||
outb(port, al);
|
||||
outb(al, port);
|
||||
al <<= 1;
|
||||
if (al & 0x100)
|
||||
al ^= 0xcf;
|
||||
|
@ -385,8 +405,8 @@ int id_port;
|
|||
int offset;
|
||||
{
|
||||
int i, data = 0;
|
||||
outb(id_port, 0x80 + offset);
|
||||
DELAY(1000);
|
||||
outb(0x80 + offset, id_port);
|
||||
DELAY(10000);
|
||||
for (i = 0; i < 16; i++)
|
||||
data = (data << 1) | (inw(id_port) & 1);
|
||||
return (data);
|
||||
|
@ -394,26 +414,38 @@ int offset;
|
|||
|
||||
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
|
||||
|
||||
/* variables for 3C509 */
|
||||
|
||||
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 = EP_ID_PORT;
|
||||
u_short k;
|
||||
unsigned short k;
|
||||
int ep_current_tag = EP_LAST_TAG + 1;
|
||||
short *p;
|
||||
#ifdef INCLUDE_3C529
|
||||
int curboard;
|
||||
#endif
|
||||
|
||||
id_port = EP_ID_PORT;
|
||||
ep_current_tag = EP_LAST_TAG + 1;
|
||||
|
@ -422,7 +454,59 @@ struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
/*********************************************************
|
||||
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_vendor = VENDOR_3C509;
|
||||
|
||||
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 && eth_vendor==VENDOR_NONE ; j++) {
|
||||
|
@ -435,9 +519,9 @@ struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
continue;
|
||||
|
||||
/* Reset and Enable the card */
|
||||
outb(io_base + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER);
|
||||
SAFEDELAY(1000); /* we must wait at least 1 ms */
|
||||
outb(io_base + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER);
|
||||
outb(W0_P4_CMD_RESET_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
|
||||
SAFEDELAY(10000); /* we must wait at least 10 ms */
|
||||
outb(W0_P4_CMD_ENABLE_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
|
||||
|
||||
/*
|
||||
* Once activated, all the registers are mapped in the range
|
||||
|
@ -450,11 +534,11 @@ struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
|
||||
/* Look for the ISA boards. Init and leave them actived */
|
||||
/* search for the first card, ignore all others */
|
||||
outb(id_port, 0xc0); /* Global reset */
|
||||
SAFEDELAY(1000);
|
||||
outb(0xc0, id_port); /* Global reset */
|
||||
SAFEDELAY(10000);
|
||||
for (i = 0; i < EP_MAX_BOARDS && eth_vendor==VENDOR_NONE; i++) {
|
||||
outb(id_port, 0);
|
||||
outb(id_port, 0);
|
||||
outb(0, id_port);
|
||||
outb(0, id_port);
|
||||
send_ID_sequence(id_port);
|
||||
|
||||
data = get_eeprom_data(id_port, EEPROM_MFG_ID);
|
||||
|
@ -467,8 +551,8 @@ struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
|
||||
eth_nic_base =
|
||||
(get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
|
||||
outb(id_port, ep_current_tag); /* tags board */
|
||||
outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG);
|
||||
outb(ep_current_tag, id_port); /* tags board */
|
||||
outb(ACTIVATE_ADAPTER_TO_CONFIG, id_port);
|
||||
eth_vendor = VENDOR_3C509;
|
||||
ep_current_tag--;
|
||||
}
|
||||
|
@ -482,27 +566,51 @@ struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
*/
|
||||
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! (%x != %x)\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 0x%x IRQ %d -",
|
||||
mcafound->name, eth_nic_base, mca_irq);
|
||||
} else {
|
||||
#endif
|
||||
if(eth_nic_base >= EP_EISA_START) {
|
||||
printf("3C5x9 board on EISA at 0x%x - ",eth_nic_base);
|
||||
} else {
|
||||
printf("3C5x9 board on ISA at 0x%x - ",eth_nic_base);
|
||||
}
|
||||
#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;
|
||||
j = (inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14) & 0x3;
|
||||
|
||||
switch(j) {
|
||||
case 0:
|
||||
if(i & IS_UTP) {
|
||||
printf("10baseT\r\n");
|
||||
printf("10baseT\n");
|
||||
utp=1;
|
||||
}
|
||||
else {
|
||||
printf("10baseT not present\r\n");
|
||||
printf("10baseT not present\n");
|
||||
eth_vendor=VENDOR_NONE;
|
||||
goto no3c509;
|
||||
}
|
||||
|
@ -510,9 +618,9 @@ struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
break;
|
||||
case 1:
|
||||
if(i & IS_AUI)
|
||||
printf("10base5\r\n");
|
||||
printf("10base5\n");
|
||||
else {
|
||||
printf("10base5 not present\r\n");
|
||||
printf("10base5 not present\n");
|
||||
eth_vendor=VENDOR_NONE;
|
||||
goto no3c509;
|
||||
}
|
||||
|
@ -520,37 +628,37 @@ struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
break;
|
||||
case 3:
|
||||
if(i & IS_BNC) {
|
||||
printf("10base2\r\n");
|
||||
printf("10base2\n");
|
||||
bnc=1;
|
||||
}
|
||||
else {
|
||||
printf("10base2 not present\r\n");
|
||||
printf("10base2 not present\n");
|
||||
eth_vendor=VENDOR_NONE;
|
||||
goto no3c509;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
printf("unknown connector\r\n");
|
||||
printf("unknown connector\n");
|
||||
eth_vendor=VENDOR_NONE;
|
||||
goto no3c509;
|
||||
}
|
||||
/*
|
||||
* Read the station address from the eeprom
|
||||
*/
|
||||
p = (u_short *) nic->node_addr;
|
||||
p = (unsigned short *) nic->node_addr;
|
||||
for (i = 0; i < 3; i++) {
|
||||
GO_WINDOW(0);
|
||||
p[i] = htons(get_e(i));
|
||||
GO_WINDOW(2);
|
||||
outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
|
||||
outw(ntohs(p[i]), BASE + EP_W2_ADDR_0 + (i * 2));
|
||||
}
|
||||
|
||||
printf("Ethernet address: ");
|
||||
for(i=0; i<5; i++) {
|
||||
printf("%b:",nic->node_addr[i]);
|
||||
}
|
||||
printf("%b\r\n",nic->node_addr[i]);
|
||||
printf("%b\n",nic->node_addr[i]);
|
||||
|
||||
t509_reset(nic);
|
||||
nic->reset = t509_reset;
|
||||
|
@ -565,10 +673,9 @@ no3c509:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_T509 */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
|
|
115
netboot/3c509.h
115
netboot/3c509.h
|
@ -73,7 +73,7 @@
|
|||
* Some short functions, worth to let them be a macro
|
||||
*/
|
||||
#define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
|
||||
#define GO_WINDOW(x) outw(BASE+EP_COMMAND, WINDOW_SELECT|(x))
|
||||
#define GO_WINDOW(x) outw(WINDOW_SELECT|(x), BASE+EP_COMMAND)
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
|
@ -205,50 +205,50 @@
|
|||
* 10-0: 11-bit arg if any. For commands with no args;
|
||||
* this can be set to anything.
|
||||
*/
|
||||
#define GLOBAL_RESET (u_short) 0x0000 /* Wait at least 1ms
|
||||
#define GLOBAL_RESET (unsigned short) 0x0000 /* Wait at least 1ms
|
||||
* after issuing */
|
||||
#define WINDOW_SELECT (u_short) (0x1<<11)
|
||||
#define START_TRANSCEIVER (u_short) (0x2<<11) /* Read ADDR_CFG reg to
|
||||
#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 (u_short) (0x3<<11) /* state disabled on
|
||||
#define RX_DISABLE (unsigned short) (0x3<<11) /* state disabled on
|
||||
* power-up */
|
||||
#define RX_ENABLE (u_short) (0x4<<11)
|
||||
#define RX_RESET (u_short) (0x5<<11)
|
||||
#define RX_DISCARD_TOP_PACK (u_short) (0x8<<11)
|
||||
#define TX_ENABLE (u_short) (0x9<<11)
|
||||
#define TX_DISABLE (u_short) (0xa<<11)
|
||||
#define TX_RESET (u_short) (0xb<<11)
|
||||
#define REQ_INTR (u_short) (0xc<<11)
|
||||
#define SET_INTR_MASK (u_short) (0xe<<11)
|
||||
#define SET_RD_0_MASK (u_short) (0xf<<11)
|
||||
#define SET_RX_FILTER (u_short) (0x10<<11)
|
||||
#define FIL_INDIVIDUAL (u_short) (0x1)
|
||||
#define FIL_GROUP (u_short) (0x2)
|
||||
#define FIL_BRDCST (u_short) (0x4)
|
||||
#define FIL_ALL (u_short) (0x8)
|
||||
#define SET_RX_EARLY_THRESH (u_short) (0x11<<11)
|
||||
#define SET_TX_AVAIL_THRESH (u_short) (0x12<<11)
|
||||
#define SET_TX_START_THRESH (u_short) (0x13<<11)
|
||||
#define STATS_ENABLE (u_short) (0x15<<11)
|
||||
#define STATS_DISABLE (u_short) (0x16<<11)
|
||||
#define STOP_TRANSCEIVER (u_short) (0x17<<11)
|
||||
#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 (u_short) (0x6800)
|
||||
#define C_INTR_LATCH (u_short) (ACK_INTR|0x1)
|
||||
#define C_CARD_FAILURE (u_short) (ACK_INTR|0x2)
|
||||
#define C_TX_COMPLETE (u_short) (ACK_INTR|0x4)
|
||||
#define C_TX_AVAIL (u_short) (ACK_INTR|0x8)
|
||||
#define C_RX_COMPLETE (u_short) (ACK_INTR|0x10)
|
||||
#define C_RX_EARLY (u_short) (ACK_INTR|0x20)
|
||||
#define C_INT_RQD (u_short) (ACK_INTR|0x40)
|
||||
#define C_UPD_STATS (u_short) (ACK_INTR|0x80)
|
||||
#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.
|
||||
|
@ -268,17 +268,17 @@
|
|||
* 1: Adapter Failure.
|
||||
* 0: Interrupt Latch.
|
||||
*/
|
||||
#define S_INTR_LATCH (u_short) (0x1)
|
||||
#define S_CARD_FAILURE (u_short) (0x2)
|
||||
#define S_TX_COMPLETE (u_short) (0x4)
|
||||
#define S_TX_AVAIL (u_short) (0x8)
|
||||
#define S_RX_COMPLETE (u_short) (0x10)
|
||||
#define S_RX_EARLY (u_short) (0x20)
|
||||
#define S_INT_RQD (u_short) (0x40)
|
||||
#define S_UPD_STATS (u_short) (0x80)
|
||||
#define S_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 (u_short) (0x1000)
|
||||
#define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000)
|
||||
|
||||
/*
|
||||
* FIFO Registers.
|
||||
|
@ -297,14 +297,14 @@
|
|||
*
|
||||
* 10-0: RX Bytes (0-1514)
|
||||
*/
|
||||
#define ERR_RX_INCOMPLETE (u_short) (0x1<<15)
|
||||
#define ERR_RX (u_short) (0x1<<14)
|
||||
#define ERR_RX_OVERRUN (u_short) (0x8<<11)
|
||||
#define ERR_RX_RUN_PKT (u_short) (0xb<<11)
|
||||
#define ERR_RX_ALIGN (u_short) (0xc<<11)
|
||||
#define ERR_RX_CRC (u_short) (0xd<<11)
|
||||
#define ERR_RX_OVERSIZE (u_short) (0x9<<11)
|
||||
#define ERR_RX_DRIBBLE (u_short) (0x2<<11)
|
||||
#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.
|
||||
|
@ -360,7 +360,7 @@
|
|||
* Receive status register
|
||||
*/
|
||||
|
||||
#define RX_BYTES_MASK (u_short) (0x07ff)
|
||||
#define RX_BYTES_MASK (unsigned short) (0x07ff)
|
||||
#define RX_ERROR 0x4000
|
||||
#define RX_INCOMPLETE 0x8000
|
||||
|
||||
|
@ -376,11 +376,20 @@
|
|||
#define BNC 0x2
|
||||
#define UTP 0x4
|
||||
|
||||
#define RX_BYTES_MASK (u_short) (0x07ff)
|
||||
#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
|
||||
|
|
|
@ -51,7 +51,7 @@ static char *version = "3c59x.c:v0.30-all 12/23/96 becker@cesdis.gsfc.nasa.gov\n
|
|||
#define NO_VORTEX_BUS_MASTER
|
||||
|
||||
|
||||
#include "netboot.h"
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "3c509.h"
|
||||
#include "pci.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# For <shared.h> and <stage1.h>.
|
||||
INCLUDES = -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1
|
||||
|
||||
# For <stage1.h>.
|
||||
INCLUDES = -I$(top_srcdir)/stage1
|
||||
|
||||
# Don't build the netboot support by default.
|
||||
if NETBOOT_SUPPORT
|
||||
LIBDRIVERS = libdrivers.a
|
||||
else
|
||||
|
@ -10,26 +10,147 @@ endif
|
|||
|
||||
noinst_LIBRARIES = $(LIBDRIVERS)
|
||||
|
||||
DRIVERS = 3c509.c 3c509.h 3c59x.c cs89x0.c cs89x0.h eepro100.c \
|
||||
lance.c
|
||||
|
||||
libdrivers_a_SOURCES = byteorder.h config.c netboot_config.h \
|
||||
fsys_tftp.c if.h io.h ip.c ip.h netboot.h netdevice.h nic.h \
|
||||
pci.c pci.h $(DRIVERS)
|
||||
libdrivers_a_SOURCES = byteorder.h config.c etherboot.h \
|
||||
fsys_tftp.c if.h linux-asm-io.h linux-asm-string.h \
|
||||
main.c misc.c netboot_config.h netdevice.h nic.h osdep.h \
|
||||
pci.c pci.h
|
||||
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c59x.c 3c90x.c cs89x0.c \
|
||||
3c89x0.h eepro100.c epic100.c epic100.h i82586.c lance.c \
|
||||
ns8390.c ns8390.h ntulip.c rtl8139.c sk_g16.c sk_g16.h \
|
||||
smc9000.c smc9000.h tiara.c tulip.c tulip.h via-rhine.c
|
||||
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
-DFSYS_TFTP $(NET_CFLAGS) $(NET_EXTRAFLAGS)
|
||||
# Filled by configure.
|
||||
libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
|
||||
libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
|
||||
|
||||
libdrivers_a_LIBADD = nepci.o ne.o wd.o t503.o
|
||||
EXTRA_DIST = README.netboot 3c90x.txt ntulip.txt
|
||||
|
||||
$(libdrivers_a_LIBADD): ns8390.c ns8390.h
|
||||
$(libdrivers_a_LIBADD): %.o: ns8390.c
|
||||
$(COMPILE) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
# These below are several special rules for the device drivers.
|
||||
# We cannot use a simple rule for them...
|
||||
|
||||
nepci_o_CFLAGS = $(filter-out -DINCLUDE_T503=1 -DINCLUDE_NE=1 \
|
||||
-DINCLUDE_WD=1, $(libdrivers_a_CFLAGS))
|
||||
ne_o_CFLAGS = $(filter-out -DINCLUDE_T503=1 -DINCLUDE_NEPCI=1 \
|
||||
-DINCLUDE_WD=1, $(libdrivers_a_CFLAGS))
|
||||
wd_o_CFLAGS = $(filter-out -DINCLUDE_T503=1 -DINCLUDE_NE=1 \
|
||||
-DINCLUDE_NEPCI=1, $(libdrivers_a_CFLAGS))
|
||||
t503_o_CFLAGS = $(filter-out -DINCLUDE_NE=1 -DINCLUDE_NEPCI=1 \
|
||||
-DINCLUDE_WD=1, $(libdrivers_a_CFLAGS))
|
||||
# What objects are derived from a driver?
|
||||
3c509_drivers = 3c509.o 3c529.o
|
||||
3c59x_drivers = 3c59x.o
|
||||
3c90x_drivers = 3c90x.o
|
||||
cs89x0_drivers = cs89x0.o
|
||||
eepro100_drivers = eepro100.o
|
||||
epic100_drivers = epic100.o
|
||||
i82586_drivers = 3c507.o exos205.o ni5210.o
|
||||
lance_drivers = lancepci.o ne2100.o ni6510.o
|
||||
ns8390_drivers = 3c503.o ne.o nepci.o wd.o
|
||||
ntulip_drivers = ntulip.o
|
||||
rtl8139_drivers = rtl8139.o
|
||||
sk_g16_drivers = sk_g16.o
|
||||
smc9000_drivers = smc9000.o
|
||||
tiara_drivers = tiara.o
|
||||
tulip_drivers = tulip.o
|
||||
via_rhine_drivers = via_rhine.o
|
||||
|
||||
# Is it really necessary to specify dependecies explicitly?
|
||||
$(ns8390_drivers): ns8390.c ns8390.h
|
||||
$(ns8390_drivers): %.o: ns8390.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 $<
|
||||
|
||||
$(3c509_drivers): 3c509.c 3c509.h
|
||||
$(3c509_drivers): %.o: 3c509.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(3c59x_drivers): 3c59x.c 3c509.h
|
||||
$(3c59x_drivers): %.o: 3c59x.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 $<
|
||||
|
||||
$(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 $<
|
||||
|
||||
$(lance_drivers): lance.c
|
||||
$(lance_drivers): %.o: lance.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(ntulip_drivers): ntulip.c
|
||||
$(ntulip_drivers): %.o: ntulip.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 $<
|
||||
|
||||
$(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 $<
|
||||
|
||||
$(tulip_drivers): tulip.c tulip.h
|
||||
$(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 $<
|
||||
|
||||
|
||||
# Per-object flags.
|
||||
3c509_o_CFLAGS = -DINCLUDE_3C509=1
|
||||
3c529_o_CFLAGS = -DINCLUDE_3C529=1
|
||||
3c59x_o_CFLAGS = -DINCLUDE_3C59X=1
|
||||
3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
|
||||
cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
|
||||
eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
|
||||
epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
|
||||
3c507_o_CFLAGS = -DINCLUDE_3C507=1
|
||||
exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
|
||||
ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
|
||||
lancepci_o_CFLAGS = -DINCLUDE_LANCEPCI=1
|
||||
ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
|
||||
ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
|
||||
3c503_o_CFLAGS = -DINCLUDE_3C503=1
|
||||
ne_o_CFLAGS = -DINCLUDE_NE=1
|
||||
nepci_o_CFLAGS = -DINCLUDE_NEPCI=1
|
||||
wd_o_CFLAGS = -DINCLUDE_WD=1
|
||||
ntulip_o_CFLAGS = -DINCLUDE_NTULIP=1
|
||||
rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
|
||||
sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
|
||||
smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
|
||||
tiara_o_CFLAGS = -DINCLUDE_TIARA=1
|
||||
tulip_o_CFLAGS = -DINCLUDE_TULIP=1
|
||||
via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
|
||||
|
|
|
@ -68,6 +68,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
@ -81,41 +82,80 @@ host_cpu = @host_cpu@
|
|||
host_vendor = @host_vendor@
|
||||
install_sh = @install_sh@
|
||||
|
||||
# For <stage1.h>.
|
||||
# For <shared.h> and <stage1.h>.
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/stage1
|
||||
INCLUDES = -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1
|
||||
@NETBOOT_SUPPORT_TRUE@LIBDRIVERS = @NETBOOT_SUPPORT_TRUE@libdrivers.a
|
||||
@NETBOOT_SUPPORT_FALSE@LIBDRIVERS =
|
||||
|
||||
noinst_LIBRARIES = $(LIBDRIVERS)
|
||||
|
||||
DRIVERS = 3c509.c 3c509.h 3c59x.c cs89x0.c cs89x0.h eepro100.c \
|
||||
lance.c
|
||||
libdrivers_a_SOURCES = byteorder.h config.c etherboot.h \
|
||||
fsys_tftp.c if.h linux-asm-io.h linux-asm-string.h \
|
||||
main.c misc.c netboot_config.h netdevice.h nic.h osdep.h \
|
||||
pci.c pci.h
|
||||
|
||||
|
||||
libdrivers_a_SOURCES = byteorder.h config.c netboot_config.h \
|
||||
fsys_tftp.c if.h io.h ip.c ip.h netboot.h netdevice.h nic.h \
|
||||
pci.c pci.h $(DRIVERS)
|
||||
EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c59x.c 3c90x.c cs89x0.c \
|
||||
3c89x0.h eepro100.c epic100.c epic100.h i82586.c lance.c \
|
||||
ns8390.c ns8390.h ntulip.c rtl8139.c sk_g16.c sk_g16.h \
|
||||
smc9000.c smc9000.h tiara.c tulip.c tulip.h via-rhine.c
|
||||
|
||||
libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
-DFSYS_TFTP $(NET_CFLAGS) $(NET_EXTRAFLAGS)
|
||||
|
||||
# Filled by configure.
|
||||
libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
|
||||
libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
|
||||
|
||||
libdrivers_a_LIBADD = nepci.o ne.o wd.o t503.o
|
||||
EXTRA_DIST = README.netboot 3c90x.txt ntulip.txt
|
||||
|
||||
nepci_o_CFLAGS = $(filter-out -DINCLUDE_T503=1 -DINCLUDE_NE=1 \
|
||||
-DINCLUDE_WD=1, $(libdrivers_a_CFLAGS))
|
||||
# These below are several special rules for the device drivers.
|
||||
# We cannot use a simple rule for them...
|
||||
|
||||
ne_o_CFLAGS = $(filter-out -DINCLUDE_T503=1 -DINCLUDE_NEPCI=1 \
|
||||
-DINCLUDE_WD=1, $(libdrivers_a_CFLAGS))
|
||||
|
||||
wd_o_CFLAGS = $(filter-out -DINCLUDE_T503=1 -DINCLUDE_NE=1 \
|
||||
-DINCLUDE_NEPCI=1, $(libdrivers_a_CFLAGS))
|
||||
|
||||
t503_o_CFLAGS = $(filter-out -DINCLUDE_NE=1 -DINCLUDE_NEPCI=1 \
|
||||
-DINCLUDE_WD=1, $(libdrivers_a_CFLAGS))
|
||||
# What objects are derived from a driver?
|
||||
3c509_drivers = 3c509.o 3c529.o
|
||||
3c59x_drivers = 3c59x.o
|
||||
3c90x_drivers = 3c90x.o
|
||||
cs89x0_drivers = cs89x0.o
|
||||
eepro100_drivers = eepro100.o
|
||||
epic100_drivers = epic100.o
|
||||
i82586_drivers = 3c507.o exos205.o ni5210.o
|
||||
lance_drivers = lancepci.o ne2100.o ni6510.o
|
||||
ns8390_drivers = 3c503.o ne.o nepci.o wd.o
|
||||
ntulip_drivers = ntulip.o
|
||||
rtl8139_drivers = rtl8139.o
|
||||
sk_g16_drivers = sk_g16.o
|
||||
smc9000_drivers = smc9000.o
|
||||
tiara_drivers = tiara.o
|
||||
tulip_drivers = tulip.o
|
||||
via_rhine_drivers = via_rhine.o
|
||||
|
||||
# Per-object flags.
|
||||
3c509_o_CFLAGS = -DINCLUDE_3C509=1
|
||||
3c529_o_CFLAGS = -DINCLUDE_3C529=1
|
||||
3c59x_o_CFLAGS = -DINCLUDE_3C59X=1
|
||||
3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
|
||||
cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
|
||||
eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
|
||||
epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
|
||||
3c507_o_CFLAGS = -DINCLUDE_3C507=1
|
||||
exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
|
||||
ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
|
||||
lancepci_o_CFLAGS = -DINCLUDE_LANCEPCI=1
|
||||
ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
|
||||
ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
|
||||
3c503_o_CFLAGS = -DINCLUDE_3C503=1
|
||||
ne_o_CFLAGS = -DINCLUDE_NE=1
|
||||
nepci_o_CFLAGS = -DINCLUDE_NEPCI=1
|
||||
wd_o_CFLAGS = -DINCLUDE_WD=1
|
||||
ntulip_o_CFLAGS = -DINCLUDE_NTULIP=1
|
||||
rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
|
||||
sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
|
||||
smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
|
||||
tiara_o_CFLAGS = -DINCLUDE_TIARA=1
|
||||
tulip_o_CFLAGS = -DINCLUDE_TULIP=1
|
||||
via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
|
||||
subdir = netboot
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
|
@ -128,27 +168,28 @@ CPPFLAGS = @CPPFLAGS@
|
|||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
libdrivers_a_AR = $(AR) cru
|
||||
libdrivers_a_DEPENDENCIES = nepci.o ne.o wd.o t503.o
|
||||
am_libdrivers_a_OBJECTS = libdrivers_a-config.o \
|
||||
libdrivers_a-fsys_tftp.o libdrivers_a-ip.o libdrivers_a-pci.o \
|
||||
libdrivers_a-3c509.o libdrivers_a-3c59x.o libdrivers_a-cs89x0.o \
|
||||
libdrivers_a-eepro100.o libdrivers_a-lance.o
|
||||
libdrivers_a-fsys_tftp.o libdrivers_a-main.o libdrivers_a-misc.o \
|
||||
libdrivers_a-pci.o
|
||||
libdrivers_a_OBJECTS = $(am_libdrivers_a_OBJECTS)
|
||||
AR = ar
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CFLAGS = @CFLAGS@
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DIST_SOURCES = $(libdrivers_a_SOURCES)
|
||||
DIST_SOURCES = $(libdrivers_a_SOURCES) $(EXTRA_libdrivers_a_SOURCES)
|
||||
DIST_COMMON = Makefile.am Makefile.in compile
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
GZIP_ENV = --best
|
||||
DEP_FILES = .deps/3c509.P .deps/3c59x.P .deps/config.P .deps/cs89x0.P \
|
||||
.deps/eepro100.P .deps/fsys_tftp.P .deps/ip.P .deps/lance.P .deps/pci.P
|
||||
SOURCES = $(libdrivers_a_SOURCES)
|
||||
DEP_FILES = .deps/3c509.P .deps/3c59x.P .deps/3c90x.P .deps/config.P \
|
||||
.deps/cs89x0.P .deps/eepro100.P .deps/epic100.P .deps/fsys_tftp.P \
|
||||
.deps/i82586.P .deps/lance.P .deps/main.P .deps/misc.P .deps/ns8390.P \
|
||||
.deps/ntulip.P .deps/pci.P .deps/rtl8139.P .deps/sk_g16.P \
|
||||
.deps/smc9000.P .deps/tiara.P .deps/tulip.P .deps/via-rhine.P
|
||||
SOURCES = $(libdrivers_a_SOURCES) $(EXTRA_libdrivers_a_SOURCES)
|
||||
OBJECTS = $(am_libdrivers_a_OBJECTS)
|
||||
|
||||
all: all-redirect
|
||||
|
@ -182,13 +223,25 @@ distclean-compile:
|
|||
maintainer-clean-compile:
|
||||
libdrivers_a-config.o: config.c
|
||||
libdrivers_a-fsys_tftp.o: fsys_tftp.c
|
||||
libdrivers_a-ip.o: ip.c
|
||||
libdrivers_a-main.o: main.c
|
||||
libdrivers_a-misc.o: misc.c
|
||||
libdrivers_a-pci.o: pci.c
|
||||
libdrivers_a-3c509.o: 3c509.c
|
||||
libdrivers_a-3c59x.o: 3c59x.c
|
||||
libdrivers_a-3c90x.o: 3c90x.c
|
||||
libdrivers_a-cs89x0.o: cs89x0.c
|
||||
libdrivers_a-eepro100.o: eepro100.c
|
||||
libdrivers_a-epic100.o: epic100.c
|
||||
libdrivers_a-i82586.o: i82586.c
|
||||
libdrivers_a-lance.o: lance.c
|
||||
libdrivers_a-ns8390.o: ns8390.c
|
||||
libdrivers_a-ntulip.o: ntulip.c
|
||||
libdrivers_a-rtl8139.o: rtl8139.c
|
||||
libdrivers_a-sk_g16.o: sk_g16.c
|
||||
libdrivers_a-smc9000.o: smc9000.c
|
||||
libdrivers_a-tiara.o: tiara.c
|
||||
libdrivers_a-tulip.o: tulip.c
|
||||
libdrivers_a-via-rhine.o: via-rhine.c
|
||||
|
||||
libdrivers.a: $(libdrivers_a_OBJECTS) $(libdrivers_a_DEPENDENCIES)
|
||||
-rm -f libdrivers.a
|
||||
|
@ -319,7 +372,7 @@ libdrivers_a-fsys_tftp.lo: fsys_tftp.c
|
|||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-ip.o: ip.c
|
||||
libdrivers_a-main.o: main.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
|
@ -328,7 +381,26 @@ libdrivers_a-ip.o: ip.c
|
|||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-ip.lo: ip.c
|
||||
libdrivers_a-main.lo: main.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-misc.o: misc.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-misc.lo: misc.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
|
@ -395,6 +467,25 @@ libdrivers_a-3c59x.lo: 3c59x.c
|
|||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-3c90x.o: 3c90x.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-3c90x.lo: 3c90x.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-cs89x0.o: cs89x0.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
|
@ -433,6 +524,44 @@ libdrivers_a-eepro100.lo: eepro100.c
|
|||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-epic100.o: epic100.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-epic100.lo: epic100.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-i82586.o: i82586.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-i82586.lo: i82586.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-lance.o: lance.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
|
@ -451,6 +580,158 @@ libdrivers_a-lance.lo: lance.c
|
|||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-ns8390.o: ns8390.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-ns8390.lo: ns8390.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-ntulip.o: ntulip.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-ntulip.lo: ntulip.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-rtl8139.o: rtl8139.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-rtl8139.lo: rtl8139.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-sk_g16.o: sk_g16.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-sk_g16.lo: sk_g16.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-smc9000.o: smc9000.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-smc9000.lo: smc9000.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-tiara.o: tiara.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-tiara.lo: tiara.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-tulip.o: tulip.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-tulip.lo: tulip.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-via-rhine.o: via-rhine.c
|
||||
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm .deps/$(*D)/$(*F).pp
|
||||
|
||||
libdrivers_a-via-rhine.lo: via-rhine.c
|
||||
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
|
||||
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
|
||||
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
|
||||
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
|
||||
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
|
||||
>> .deps/$(*D)/$(*F).P; \
|
||||
rm -f .deps/$(*D)/$(*F).pp
|
||||
info-am:
|
||||
info: info-am
|
||||
dvi-am:
|
||||
|
@ -524,9 +805,86 @@ installdirs mostlyclean-generic distclean-generic clean-generic \
|
|||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
$(libdrivers_a_LIBADD): ns8390.c ns8390.h
|
||||
$(libdrivers_a_LIBADD): %.o: ns8390.c
|
||||
$(COMPILE) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
# Is it really necessary to specify dependecies explicitly?
|
||||
$(ns8390_drivers): ns8390.c ns8390.h
|
||||
$(ns8390_drivers): %.o: ns8390.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 $<
|
||||
|
||||
$(3c509_drivers): 3c509.c 3c509.h
|
||||
$(3c509_drivers): %.o: 3c509.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(3c59x_drivers): 3c59x.c 3c509.h
|
||||
$(3c59x_drivers): %.o: 3c59x.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 $<
|
||||
|
||||
$(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 $<
|
||||
|
||||
$(lance_drivers): lance.c
|
||||
$(lance_drivers): %.o: lance.c
|
||||
$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
|
||||
$(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(ntulip_drivers): ntulip.c
|
||||
$(ntulip_drivers): %.o: ntulip.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 $<
|
||||
|
||||
$(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 $<
|
||||
|
||||
$(tulip_drivers): tulip.c tulip.h
|
||||
$(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 $<
|
||||
|
||||
# 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.
|
||||
|
|
383
netboot/config.c
383
netboot/config.c
|
@ -1,93 +1,283 @@
|
|||
#include "netboot.h"
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000 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-4.4.2. Some parts are stolen
|
||||
from "include/linux/pci.h" in linux-2.2.14. */
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
|
||||
#include "netboot_config.h"
|
||||
|
||||
#undef INCLUDE_PCI
|
||||
#if defined(INCLUDE_NEPCI) || defined(INCLUDE_EEPRO100) || defined (INCLUDE_3C59X)
|
||||
/* || others later */
|
||||
#if defined(NETBOOT32) /* only for 32 bit machines */
|
||||
#define INCLUDE_PCI
|
||||
/* #include <linux/pci.h> */
|
||||
#include "pci.h"
|
||||
static unsigned short pci_addrs[16];
|
||||
struct pci_device; /* for the probe prototype */
|
||||
|
||||
struct pci_device pci_nic_list[] = {
|
||||
#undef INCLUDE_PCI
|
||||
#if defined(INCLUDE_NEPCI) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCEPCI) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_NTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE)
|
||||
/* || others later */
|
||||
#if defined(ETHERBOOT32) /* only for 32 bit machines */
|
||||
#define INCLUDE_PCI
|
||||
/*#include <linux/pci.h>*/
|
||||
#include "pci.h"
|
||||
static unsigned short pci_ioaddrs[16];
|
||||
|
||||
static struct pci_device pci_nic_list[] = {
|
||||
#ifdef INCLUDE_NEPCI
|
||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029,
|
||||
"Realtek 8029"},
|
||||
"Realtek 8029", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940,
|
||||
"Winbond NE2000-PCI"}, /* "Winbond 89C940" */
|
||||
"Winbond NE2000-PCI", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000,
|
||||
"Compex ReadyLink 2000"},
|
||||
"Compex ReadyLink 2000", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2,
|
||||
"KTI ET32P2"},
|
||||
{PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC,
|
||||
"NetVin NV5000"},
|
||||
{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C926,
|
||||
"VIA 82C926 Amazon"},
|
||||
{PCI_VENDOR_ID_SURECOM, PCI_DEVICE_ID_SURECOM_NE34,
|
||||
"SureCom NE34"},
|
||||
"KTI ET32P2", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC,
|
||||
"NetVin NV5000SC", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_3C90X
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
|
||||
"3Com900-TPO", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
|
||||
"3Com900-Combo", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX,
|
||||
"3Com905-TX", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4,
|
||||
"3Com905-T4", 0, 0, 0},
|
||||
|
||||
{ PCI_VENDOR_ID_3COM, 0x9004,
|
||||
"3Com900B-TPO", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9005,
|
||||
"3Com900B-Combo", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9006,
|
||||
"3Com900B-2/T", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x900A,
|
||||
"3Com900B-FL", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905B_TX,
|
||||
"3Com905B-TX", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x9056,
|
||||
"3Com905B-T4", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, 0x905A,
|
||||
"3Com905B-FL", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C_TXM,
|
||||
"3Com905C-TXM", 0, 0, 0},
|
||||
|
||||
#endif
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,
|
||||
"Intel EtherExpressPro100"},
|
||||
"Intel EtherExpressPro100", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_EPIC100
|
||||
{ PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100,
|
||||
"SMC EtherPowerII", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_LANCEPCI
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
|
||||
"AMD Lance/PCI", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_RTL8139
|
||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
|
||||
"Realtek 8139", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211,
|
||||
"SMC EZ10/100", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_TULIP
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
|
||||
"Digital Tulip", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
|
||||
"Digital Tulip Fast", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
|
||||
"Digital Tulip+", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
|
||||
"Digital Tulip 21142", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_NTULIP
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
|
||||
"Digital Tulip", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
|
||||
"Digital Tulip Fast", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
|
||||
"Digital Tulip+", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
|
||||
"Digital Tulip 21142", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5,
|
||||
"Macronix MX987x5", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LC82C115,
|
||||
"LinkSys LNE100TX", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_DEC_TULIP,
|
||||
"Netgear FA310TX", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_VIA_RHINE
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_RHINE_I,
|
||||
"VIA 3043", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A,
|
||||
"VIA 86C100A", 0, 0, 0},
|
||||
#endif
|
||||
#ifdef INCLUDE_3C59X
|
||||
{PCI_VENDOR_ID_VORTEX, PCI_DEVICE_ID_VORTEX_3c595, "3c595"},
|
||||
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590,
|
||||
"3c590 Vortex 10Mbps", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595TX,
|
||||
"3c595 Vortex 100baseTX", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595T4,
|
||||
"3c595 Vortex 100baseT4", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVIVE_ID_3COM_3C595MII,
|
||||
"3c595 Vortex 100base-MII", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
|
||||
"3c900 Boomerang 10baseT", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
|
||||
"3c900 Boomerang 10Mbps/Combo", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX,
|
||||
"3c905 Boomerang 100baseTx", 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4,
|
||||
"3c905 Boomerang 100baseT4", 0, 0, 0},
|
||||
#endif
|
||||
|
||||
/* other PCI NICs go here */
|
||||
{0,}
|
||||
};
|
||||
#endif /* NETBOOT32 */
|
||||
#endif /* ETHERBOOT32 */
|
||||
#endif /* INCLUDE_*PCI */
|
||||
|
||||
struct dispatch_table
|
||||
{
|
||||
char *nic_name;
|
||||
struct nic *(*eth_probe)(struct nic *, unsigned short *);
|
||||
unsigned short *probe_addrs; /* for probe overrides */
|
||||
struct nic *(*eth_probe)(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
unsigned short *probe_ioaddrs; /* for probe overrides */
|
||||
};
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
extern struct nic *wd_probe(struct nic *, unsigned short *);
|
||||
extern struct nic *wd_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_T503
|
||||
extern struct nic *t503_probe(struct nic *, unsigned short *);
|
||||
#ifdef INCLUDE_3C503
|
||||
extern struct nic *t503_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_NE)
|
||||
extern struct nic *ne_probe(struct nic *, unsigned short *);
|
||||
#ifdef INCLUDE_VIA_RHINE
|
||||
extern struct nic *rhine_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_NEPCI)
|
||||
extern struct nic *nepci_probe(struct nic *, unsigned short *);
|
||||
#ifdef INCLUDE_NE
|
||||
extern struct nic *ne_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_T509
|
||||
extern struct nic *t509_probe(struct nic *, unsigned short *);
|
||||
#ifdef INCLUDE_NEPCI
|
||||
extern struct nic *nepci_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C509
|
||||
extern struct nic *t509_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C529
|
||||
extern struct nic *t529_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C90X
|
||||
extern struct nic *a3c90x_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
extern struct nic *eepro100_probe(struct nic *, unsigned short *);
|
||||
extern struct nic *eepro100_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_CS
|
||||
extern struct nic *cs89x0_probe(struct nic *, unsigned short *);
|
||||
#ifdef INCLUDE_EPIC100
|
||||
extern struct nic *epic100_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_TULIP
|
||||
extern struct nic *tulip_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NTULIP
|
||||
extern struct nic *ntulip_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_CS89x0
|
||||
extern struct nic *cs89x0_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_LANCEPCI
|
||||
extern struct nic *lancepci_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NE2100
|
||||
extern struct nic *ne2100_probe(struct nic *, unsigned short *);
|
||||
extern struct nic *ne2100_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NI6510
|
||||
extern struct nic *ni6510_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_SK_G16
|
||||
extern struct nic *SK_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C507
|
||||
extern struct nic *t507_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NI5210
|
||||
extern struct nic *ni5210_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EXOS205
|
||||
extern struct nic *exos205_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_SMC9000
|
||||
extern struct nic *smc9000_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_TIARA
|
||||
extern struct nic *tiara_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_RTL8139
|
||||
extern struct nic *rtl8139_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C59X
|
||||
extern struct nic *VX_probe(struct nic *, unsigned short *);
|
||||
extern struct nic *VX_probe(struct nic *, unsigned short *,
|
||||
struct pci_device *);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* NIC probing is in order of appearance in this table.
|
||||
* If for some reason you want to change the order,
|
||||
|
@ -95,35 +285,78 @@ extern struct nic *VX_probe(struct nic *, unsigned short *);
|
|||
*/
|
||||
static struct dispatch_table NIC[] =
|
||||
{
|
||||
#ifdef INCLUDE_RTL8139
|
||||
{ "RTL8139", rtl8139_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_WD
|
||||
{ "WD", wd_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_T503
|
||||
#ifdef INCLUDE_3C503
|
||||
{ "3C503", t503_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_NE
|
||||
{ "NE*000", ne_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_T509
|
||||
#ifdef INCLUDE_3C509
|
||||
{ "3C5x9", t509_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
{ "EEPRO100", eepro100_probe, 0 },
|
||||
#ifdef INCLUDE_3C529
|
||||
{ "3C5x9", t529_probe, 0 },
|
||||
#endif
|
||||
#ifdef INCLUDE_CS
|
||||
#ifdef INCLUDE_3C90X
|
||||
{ "3C90X", a3c90x_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
{ "EEPRO100", eepro100_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_EPIC100
|
||||
{ "EPIC100", epic100_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_TULIP
|
||||
{ "Tulip", tulip_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_NTULIP
|
||||
{ "NTulip", ntulip_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_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_NEPCI
|
||||
{ "NE*000/PCI", nepci_probe, pci_addrs },
|
||||
{ "NE2000/PCI", nepci_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_LANCEPCI
|
||||
{ "LANCE/PCI", lancepci_probe, pci_ioaddrs },
|
||||
#endif
|
||||
#ifdef INCLUDE_VIA_RHINE
|
||||
{ "VIA 86C100", rhine_probe, pci_ioaddrs },
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_3C59X
|
||||
{"VorTex/PCI", VX_probe, pci_addrs},
|
||||
{ "VorTex/PCI", VX_probe, pci_ioaddrs },
|
||||
#endif
|
||||
|
||||
/* this entry must always be last to mark the end of list */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
@ -139,7 +372,7 @@ char packet[ETH_MAX_PACKET];
|
|||
|
||||
struct nic nic =
|
||||
{
|
||||
#ifdef NETBOOT32
|
||||
#ifdef ETHERBOOT32
|
||||
(void (*)(struct nic *))eth_dummy, /* reset */
|
||||
eth_dummy, /* poll */
|
||||
(void (*)(struct nic *, char *,
|
||||
|
@ -148,13 +381,17 @@ struct nic nic =
|
|||
(void (*)(struct nic *))eth_dummy, /* disable */
|
||||
#endif
|
||||
/* bcc has problems with complicated casts */
|
||||
#ifdef NETBOOT16
|
||||
#ifdef ETHERBOOT16
|
||||
eth_dummy,
|
||||
eth_dummy,
|
||||
eth_dummy,
|
||||
eth_dummy,
|
||||
#endif
|
||||
#ifdef T503_AUI
|
||||
1, /* aui */
|
||||
#else
|
||||
0, /* no aui */
|
||||
#endif
|
||||
arptable[ARP_CLIENT].node, /* node_addr */
|
||||
packet, /* packet */
|
||||
0, /* packetlen */
|
||||
|
@ -166,21 +403,16 @@ void print_config(void)
|
|||
{
|
||||
struct dispatch_table *t;
|
||||
|
||||
#ifdef NETBOOT32
|
||||
printf("Etherboot/32 version " VERSION
|
||||
#ifdef NFS_BOOT
|
||||
" ESC for menu"
|
||||
#ifdef ETHERBOOT32
|
||||
printf("Etherboot/32 version " VERSION " (GPL) for ");
|
||||
#endif
|
||||
" for ");
|
||||
#endif
|
||||
#ifdef NETBOOT16
|
||||
/* you need to edit the version manually because bcc doesn't
|
||||
do string literal concatenation yet */
|
||||
printf("Etherboot/16 version 3.2 for ");
|
||||
#ifdef ETHERBOOT16
|
||||
/* Must be all on line or bcc can't handle concatenation */
|
||||
printf("Etherboot/16 version " VERSION " (GPL) for ");
|
||||
#endif
|
||||
for (t = NIC; t->nic_name != 0; ++t)
|
||||
printf("[%s]", t->nic_name);
|
||||
printf("\r\n");
|
||||
putchar('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -191,18 +423,31 @@ void eth_reset(void)
|
|||
|
||||
int eth_probe(void)
|
||||
{
|
||||
struct pci_device *p;
|
||||
struct dispatch_table *t;
|
||||
|
||||
p = 0;
|
||||
#ifdef INCLUDE_PCI
|
||||
pci_addrs[0] = 0;
|
||||
eth_pci_init(pci_nic_list, pci_addrs);
|
||||
pci_addrs[1] = 0;
|
||||
/* 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
|
||||
printf("Probing...");
|
||||
for (t = NIC; t->nic_name != 0; ++t)
|
||||
{
|
||||
printf("[%s]", t->nic_name);
|
||||
if ((*t->eth_probe)(&nic, t->probe_addrs))
|
||||
if ((*t->eth_probe)(&nic, t->probe_ioaddrs, p))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
|
106
netboot/cs89x0.c
106
netboot/cs89x0.c
|
@ -72,15 +72,13 @@
|
|||
have no way of testing whether it actually works.
|
||||
|
||||
* I did not (yet) bother to make the code 16bit aware, so for
|
||||
the time being, it will only work for netboot-32.
|
||||
the time being, it will only work for Etherboot/32.
|
||||
|
||||
* 12
|
||||
|
||||
*/
|
||||
|
||||
#ifdef INCLUDE_CS
|
||||
|
||||
#include "netboot.h"
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "cs89x0.h"
|
||||
|
||||
|
@ -100,7 +98,7 @@ static unsigned char eth_vendor;
|
|||
static int inline readreg(portno)
|
||||
int portno;
|
||||
{
|
||||
outw(eth_nic_base + ADD_PORT, portno);
|
||||
outw(portno, eth_nic_base + ADD_PORT);
|
||||
return inw(eth_nic_base + DATA_PORT);
|
||||
}
|
||||
|
||||
|
@ -108,8 +106,8 @@ static void inline writereg(portno,value)
|
|||
int portno;
|
||||
int value;
|
||||
{
|
||||
outw(eth_nic_base + ADD_PORT, portno);
|
||||
outw(eth_nic_base + DATA_PORT, value);
|
||||
outw(portno, eth_nic_base + ADD_PORT);
|
||||
outw(value, eth_nic_base + DATA_PORT);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -119,7 +117,7 @@ EEPROM access
|
|||
|
||||
static int wait_eeprom_ready()
|
||||
{
|
||||
long tmo = currticks() + 4*18L;
|
||||
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
|
||||
|
@ -138,7 +136,7 @@ static int get_eeprom_data(off,len,buffer)
|
|||
int i;
|
||||
|
||||
#if defined(EDEBUG)
|
||||
printf("\r\ncs: EEPROM data from %x for %x:",off,len);
|
||||
printf("\ncs: EEPROM data from %x for %x:",off,len);
|
||||
#endif
|
||||
for (i = 0; i < len; i++) {
|
||||
if (wait_eeprom_ready() < 0)
|
||||
|
@ -151,12 +149,12 @@ static int get_eeprom_data(off,len,buffer)
|
|||
buffer[i] = readreg(PP_EEData);
|
||||
#if defined(EDEBUG)
|
||||
if (!(i%10))
|
||||
printf("\r\ncs: ");
|
||||
printf("\ncs: ");
|
||||
printf("%x ", buffer[i]);
|
||||
#endif
|
||||
}
|
||||
#if defined(EDEBUG)
|
||||
printf("\r\n");
|
||||
putchar('\n');
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
|
@ -196,7 +194,7 @@ static void control_dc_dc(on_not_off)
|
|||
int on_not_off;
|
||||
{
|
||||
unsigned int selfcontrol;
|
||||
long tmo = currticks() + 18;
|
||||
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 */
|
||||
|
@ -243,7 +241,7 @@ static int detect_tp()
|
|||
if ((eth_auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
|
||||
printf(" negotiating duplex... ");
|
||||
while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
|
||||
if (currticks() - tmo > 40*18) {
|
||||
if (currticks() - tmo > 40*TICKS_PER_SEC) {
|
||||
printf("time out ");
|
||||
break;
|
||||
}
|
||||
|
@ -269,12 +267,11 @@ static int send_test_pkt(struct nic *nic)
|
|||
|
||||
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
|
||||
|
||||
bcopy(nic->node_addr,testpacket,ETHER_ADDR_SIZE);
|
||||
bcopy(nic->node_addr,testpacket+ETHER_ADDR_SIZE,
|
||||
ETHER_ADDR_SIZE);
|
||||
memcpy(testpacket, nic->node_addr, ETHER_ADDR_SIZE);
|
||||
memcpy(testpacket+ETHER_ADDR_SIZE, nic->node_addr, ETHER_ADDR_SIZE);
|
||||
|
||||
outw(eth_nic_base + TX_CMD_PORT, TX_AFTER_ALL);
|
||||
outw(eth_nic_base + TX_LEN_PORT, ETH_MIN_PACKET);
|
||||
outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
|
||||
outw(ETH_MIN_PACKET, eth_nic_base + TX_LEN_PORT);
|
||||
|
||||
/* Test to see if the chip has allocated memory for the packet */
|
||||
for (tmo = currticks() + 2;
|
||||
|
@ -347,14 +344,14 @@ void cs89x0_reset(struct nic *nic)
|
|||
/* Hardware problem requires PNP registers to be reconfigured
|
||||
after a reset */
|
||||
if (eth_irq != 0xFFFF) {
|
||||
outw(eth_nic_base + ADD_PORT, PP_CS8920_ISAINT);
|
||||
outb(eth_nic_base + DATA_PORT, eth_irq);
|
||||
outb(eth_nic_base + DATA_PORT + 1, 0); }
|
||||
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(eth_nic_base + ADD_PORT, PP_CS8920_ISAMemB);
|
||||
outb(eth_nic_base + DATA_PORT, (eth_mem_start >> 8) & 0xff);
|
||||
outb(eth_nic_base + DATA_PORT + 1, (eth_mem_start >> 24) & 0xff); } }
|
||||
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;
|
||||
|
@ -383,7 +380,7 @@ void cs89x0_reset(struct nic *nic)
|
|||
writereg(PP_BufCFG, 0);
|
||||
|
||||
/* reset address port, so that autoprobing will keep working */
|
||||
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -412,14 +409,14 @@ static void cs89x0_transmit(
|
|||
|
||||
retry:
|
||||
/* initiate a transmit sequence */
|
||||
outw(eth_nic_base + TX_CMD_PORT, TX_AFTER_ALL);
|
||||
outw(eth_nic_base + TX_LEN_PORT, sr);
|
||||
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...\r\n");
|
||||
for (tmo = currticks() + 5*18; currticks() - tmo < 0; );
|
||||
printf("cs: unable to send packet; retrying...\n");
|
||||
for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() - tmo < 0; );
|
||||
cs89x0_reset(nic);
|
||||
goto retry; }
|
||||
|
||||
|
@ -427,17 +424,17 @@ retry:
|
|||
outsw(eth_nic_base + TX_FRAME_PORT, d, ETHER_ADDR_SIZE/2);
|
||||
outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
|
||||
ETHER_ADDR_SIZE/2);
|
||||
outw(eth_nic_base + TX_FRAME_PORT, ((t >> 8)&0xFF)|(t << 8));
|
||||
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 - ETHER_ADDR_SIZE - 1; sr-- > 0;
|
||||
outw(eth_nic_base + TX_FRAME_PORT, 0));
|
||||
outw(0, eth_nic_base + TX_FRAME_PORT));
|
||||
|
||||
/* wait for transfer to succeed */
|
||||
for (tmo = currticks()+5*18;
|
||||
for (tmo = currticks()+5*TICKS_PER_SEC;
|
||||
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() - tmo < 0;
|
||||
twiddle());
|
||||
if ((s & TX_SEND_OK_BITS) != TX_OK) {
|
||||
printf("\r\ntransmission error 0x%x\r\n", s);
|
||||
printf("\ntransmission error 0x%x\n", s);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -504,7 +501,7 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
ioaddr &= ~1;
|
||||
if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
|
||||
continue;
|
||||
outw(ioaddr + ADD_PORT, PP_ChipID);
|
||||
outw(PP_ChipID, ioaddr + ADD_PORT);
|
||||
}
|
||||
|
||||
if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
|
||||
|
@ -516,7 +513,7 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
eth_cs_type = rev_type &~ REVISON_BITS;
|
||||
cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
|
||||
|
||||
printf("\r\ncs: cs89%c0%s rev %c, base 0x%x",
|
||||
printf("\ncs: cs89%c0%s rev %c, base 0x%x",
|
||||
eth_cs_type==CS8900?'0':'2',
|
||||
eth_cs_type==CS8920M?"M":"",
|
||||
cs_revision,
|
||||
|
@ -524,18 +521,18 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
|
||||
/* First check to see if an EEPROM is attached*/
|
||||
if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
|
||||
printf("\r\ncs: no EEPROM...\r\n");
|
||||
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||
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("\r\ncs: EEPROM read failed...\r\n");
|
||||
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||
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("\r\ncs: EEPROM checksum bad...\r\n");
|
||||
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||
printf("\ncs: EEPROM checksum bad...\n");
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
continue; }
|
||||
|
||||
/* get transmission control word but keep the
|
||||
|
@ -572,14 +569,14 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
write_irq, which is the reverse
|
||||
mapping of the table below. */
|
||||
if (i < 4) i = "\012\013\014\005"[i];
|
||||
else printf("\r\ncs: BUG: isa_config is %d\r\n", i); }
|
||||
else printf("\ncs: BUG: isa_config is %d\n", i); }
|
||||
eth_irq = i; }
|
||||
|
||||
/* Retrieve and print the ethernet address. */
|
||||
for (i=0; i<ETHER_ADDR_SIZE; i++) {
|
||||
printf("%b%s",(int)(nic->node_addr[i] =
|
||||
((unsigned char *)eeprom_buff)[i]),
|
||||
i < ETHER_ADDR_SIZE-1 ? ":" : "\r\n"); }
|
||||
i < ETHER_ADDR_SIZE-1 ? ":" : "\n"); }
|
||||
|
||||
/* Set the LineCTL quintuplet based on adapter
|
||||
configuration read from EEPROM */
|
||||
|
@ -602,11 +599,11 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
A_CNF_10B_2);
|
||||
}
|
||||
if (!result) {
|
||||
printf("cs: EEPROM is configured for unavailable media\r\n");
|
||||
printf("cs: EEPROM is configured for unavailable media\n");
|
||||
error:
|
||||
writereg(PP_LineCTL, readreg(PP_LineCTL) &
|
||||
~(SERIAL_TX_ON | SERIAL_RX_ON));
|
||||
outw(eth_nic_base + ADD_PORT, PP_ChipID);
|
||||
outw(PP_ChipID, eth_nic_base + ADD_PORT);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -622,7 +619,7 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
if (!result) {
|
||||
clrline();
|
||||
printf("10Base-T (RJ-45%s",
|
||||
") has no cable\r\n"); }
|
||||
") 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 */
|
||||
|
@ -633,7 +630,7 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
if (!result) {
|
||||
clrline();
|
||||
printf("10Base-5 (AUI%s",
|
||||
") has no cable\r\n"); }
|
||||
") 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 */
|
||||
|
@ -644,7 +641,7 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
if (!result) {
|
||||
clrline();
|
||||
printf("10Base-2 (BNC%s",
|
||||
") has no cable\r\n"); }
|
||||
") 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 */
|
||||
|
@ -661,18 +658,18 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
if (eth_adapter_cnf & A_CNF_10B_2)
|
||||
if ((result = detect_bnc(nic)) != 0)
|
||||
break;
|
||||
clrline(); printf("no media detected\r\n");
|
||||
clrline(); printf("no media detected\n");
|
||||
goto error;
|
||||
}
|
||||
clrline();
|
||||
switch(result) {
|
||||
case 0: printf("no network cable attached to configured media\r\n");
|
||||
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)\r\n");
|
||||
case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
|
||||
break;
|
||||
case A_CNF_MEDIA_AUI: printf("using 10Base-5 (AUI)\r\n");
|
||||
case A_CNF_MEDIA_AUI: printf("using 10Base-5 (AUI)\n");
|
||||
break;
|
||||
case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\r\n");
|
||||
case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -690,10 +687,9 @@ struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
return nic;
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_CS */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
||||
|
|
|
@ -95,18 +95,18 @@
|
|||
* the packet buffers)
|
||||
* */
|
||||
|
||||
#ifdef INCLUDE_EEPRO100
|
||||
|
||||
|
||||
/* The etherboot authors seem to dislike the argument ordering in
|
||||
* outb macros that Linux uses. I disklike the confusion that this
|
||||
* has caused even more.... This file uses the Linux argument ordering. */
|
||||
#define LINUX_OUT_MACROS
|
||||
/* Sorry not us. It's inherted code from FreeBSD. [The authors] */
|
||||
|
||||
#include "netboot.h"
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include <linux/bios32.h>
|
||||
#include <linux/pci.h>
|
||||
#include "pci.h"
|
||||
|
||||
#undef virt_to_bus
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
|
||||
static int ioaddr;
|
||||
|
||||
|
@ -398,7 +398,7 @@ static int read_eeprom(int ioaddr, int location)
|
|||
static void inline whereami (char *str)
|
||||
{
|
||||
#if 0
|
||||
printf ("%s\r\n", str);
|
||||
printf ("%s\n", str);
|
||||
sleep (2);
|
||||
#endif
|
||||
}
|
||||
|
@ -451,13 +451,13 @@ static void eepro100_transmit(struct nic *nic, char *d, unsigned int t, unsigned
|
|||
outw(status & 0xfc00, ioaddr + SCBStatus);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("transmitting type %x packet (%d bytes). status = %x, cmd=%x\r\n",
|
||||
printf ("transmitting type %x packet (%d bytes). status = %x, cmd=%x\n",
|
||||
t, s, status, inw (ioaddr + SCBCmd));
|
||||
#endif
|
||||
|
||||
|
||||
memcpy (&hdr.dst_addr, d, 6);
|
||||
memcpy (&hdr.src_addr, &arptable[ARP_CLIENT].node, 6);
|
||||
memcpy (&hdr.src_addr, nic->node_addr, 6);
|
||||
|
||||
hdr.type = htons (t);
|
||||
|
||||
|
@ -474,7 +474,7 @@ static void eepro100_transmit(struct nic *nic, char *d, unsigned int t, unsigned
|
|||
txfd.tx_buf_size1 = s;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("txfd: \r\n");
|
||||
printf ("txfd: \n");
|
||||
hd (&txfd, sizeof (txfd));
|
||||
#endif
|
||||
|
||||
|
@ -489,8 +489,8 @@ static void eepro100_transmit(struct nic *nic, char *d, unsigned int t, unsigned
|
|||
s2 = inw (ioaddr + SCBStatus);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Tx: Loop executed %d times.\r\n", TIME_OUT-to);
|
||||
printf ("s1 = %x, s2 = %x.\r\n", s1, s2);
|
||||
printf ("Tx: Loop executed %d times.\n", TIME_OUT-to);
|
||||
printf ("s1 = %x, s2 = %x.\n", s1, s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -524,10 +524,10 @@ static int eepro100_poll(struct nic *nic)
|
|||
|
||||
if (to) {
|
||||
#ifdef DEBUG
|
||||
printf ("Got a packet: Len = %d.\r\n", rxfd.count & 0x3fff);
|
||||
printf ("Got a packet: Len = %d.\n", rxfd.count & 0x3fff);
|
||||
#endif
|
||||
nic->packetlen = rxfd.count & 0x3fff;
|
||||
bcopy (rxfd.packet, nic->packet, sizeof (rxfd.packet));
|
||||
memcpy (nic->packet, rxfd.packet, sizeof (rxfd.packet));
|
||||
#ifdef DEBUG
|
||||
hd (nic->packet, 0x30);
|
||||
#endif
|
||||
|
@ -548,7 +548,7 @@ static void eepro100_disable(struct nic *nic)
|
|||
* leaves the 82557 initialized, and ready to recieve packets.
|
||||
*/
|
||||
|
||||
struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
|
||||
struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *p)
|
||||
{
|
||||
int pci_index;
|
||||
u16 sum = 0;
|
||||
|
@ -557,6 +557,11 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
|
|||
int options;
|
||||
int promisc;
|
||||
|
||||
unsigned char pci_bus = 0;
|
||||
unsigned short pci_command;
|
||||
unsigned short new_command;
|
||||
unsigned char pci_latency;
|
||||
|
||||
if (probeaddrs == 0 || probeaddrs[0] == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -569,16 +574,41 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
|
|||
sum += value;
|
||||
}
|
||||
|
||||
/* From Matt Hortman <mbhortman@acpthinclient.com> */
|
||||
if (p->dev_id == PCI_DEVICE_ID_INTEL_82557 ){
|
||||
/*
|
||||
* check to make sure the bios properly set the
|
||||
* 82557 (or 82558) to be bus master
|
||||
*
|
||||
* from eepro100.c in 2.2.9 kernel source
|
||||
*/
|
||||
|
||||
pcibios_read_config_word(pci_bus, p->devfn, PCI_COMMAND, &pci_command);
|
||||
new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
|
||||
|
||||
if (pci_command != new_command) {
|
||||
printf("\nThe PCI BIOS has not enabled this device!\nUpdating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",
|
||||
pci_command, new_command, pci_bus, p->devfn);
|
||||
pcibios_write_config_word(pci_bus, p->devfn, PCI_COMMAND, new_command);
|
||||
}
|
||||
|
||||
pcibios_read_config_byte(pci_bus, p->devfn, PCI_LATENCY_TIMER, &pci_latency);
|
||||
if (pci_latency < 32) {
|
||||
printf("\nPCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n", pci_latency);
|
||||
pcibios_write_config_byte(pci_bus, p->devfn, PCI_LATENCY_TIMER, 32);
|
||||
}
|
||||
}
|
||||
|
||||
printf ("Ethernet addr: ");
|
||||
for (i=0;i<6;i++) {
|
||||
arptable[ARP_CLIENT].node[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
|
||||
printf ("%b%c", arptable[ARP_CLIENT].node[i] , i < 5?':':' ');
|
||||
nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
|
||||
printf ("%b%c", nic->node_addr[i] , i < 5?':':' ');
|
||||
}
|
||||
printf ("\r\n");
|
||||
printf ("\n");
|
||||
|
||||
if (sum != 0xBABA)
|
||||
printf("eepro100: Invalid EEPROM checksum %#4.4x, "
|
||||
"check settings before activating this device!\r\n", sum);
|
||||
"check settings before activating this device!\n", sum);
|
||||
outl(0, ioaddr + SCBPort);
|
||||
udelay (10);
|
||||
|
||||
|
@ -635,11 +665,11 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
|
|||
char *p = (char *)&txfd.tx_desc_addr;
|
||||
|
||||
for (i=0;i<6;i++)
|
||||
p[i] = arptable[ARP_CLIENT].node[i];
|
||||
p[i] = nic->node_addr[i];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Setup_eaddr:\r\n");
|
||||
printf ("Setup_eaddr:\n");
|
||||
hd (&txfd, 0x20);
|
||||
#endif
|
||||
/* options = 0x40; */ /* 10mbps half duplex... */
|
||||
|
@ -647,13 +677,13 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
|
|||
|
||||
promisc = 0;
|
||||
|
||||
printf ("eeprom[6] = %x \r\n", eeprom[6]);
|
||||
printf ("eeprom[6] = %x \n", eeprom[6]);
|
||||
if ( ((eeprom[6]>>8) & 0x3f) == DP83840
|
||||
|| ((eeprom[6]>>8) & 0x3f) == DP83840A) {
|
||||
int mdi_reg23 = mdio_read(ioaddr, eeprom[6] & 0x1f, 23) | 0x0422;
|
||||
if (congenb)
|
||||
mdi_reg23 |= 0x0100;
|
||||
printf(" DP83840 specific setup, setting register 23 to %x.\r\n",
|
||||
printf(" DP83840 specific setup, setting register 23 to %x.\n",
|
||||
mdi_reg23);
|
||||
mdio_write(ioaddr, eeprom[6] & 0x1f, 23, mdi_reg23);
|
||||
}
|
||||
|
@ -686,7 +716,7 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
|
|||
/* Wait */;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("\r\nLoop executed %d times.\r\n", TIME_OUT-to);
|
||||
printf ("\nLoop executed %d times.\n", TIME_OUT-to);
|
||||
#endif
|
||||
nic->reset = eepro100_reset;
|
||||
nic->poll = eepro100_poll;
|
||||
|
@ -790,11 +820,10 @@ void hd (void *where, int n)
|
|||
printf ("%X ", where);
|
||||
for (i=0;i < ( (n>16)?16:n);i++)
|
||||
printf (" %b", ((char *)where)[i]);
|
||||
printf ("\n\r");
|
||||
printf ("\n");
|
||||
n -= 16;
|
||||
where += 16;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDE_EEPRO100 */
|
||||
|
|
|
@ -1,59 +1,38 @@
|
|||
/**************************************************************************
|
||||
NETBOOT - BOOTP/TFTP Bootstrap Program
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters
|
||||
Date: Dec/93
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#define NETBOOT32
|
||||
/* Include GRUB-specific macros and prototypes here. */
|
||||
#include <shared.h>
|
||||
|
||||
#include "../stage2/shared.h"
|
||||
/* FIXME: For now, disable the DHCP support. Perhaps I should segregate
|
||||
the DHCP support from the BOOTP support, and permit both to
|
||||
co-exist. */
|
||||
#define NO_DHCP_SUPPORT 1
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "io.h"
|
||||
#include "osdep.h"
|
||||
|
||||
typedef unsigned long Address;
|
||||
|
||||
extern int _pending_key;
|
||||
extern inline int getchar(void);
|
||||
extern inline int getchar(void) {
|
||||
int foo;
|
||||
|
||||
if (_pending_key == -1)
|
||||
return getkey();
|
||||
foo = _pending_key;
|
||||
_pending_key = -1;
|
||||
return foo;
|
||||
}
|
||||
extern inline int iskey(void);
|
||||
extern inline int iskey(void) {
|
||||
return _pending_key != -1 ? 1 : ((_pending_key = checkkey()) != -1);
|
||||
}
|
||||
|
||||
#if 0 /*Edmund*/
|
||||
#define bcmp __builtin_memcmp
|
||||
#define memcpy(d,s,sz) bcopy((s),(d),(sz))
|
||||
#else
|
||||
#define bcopy(src, dest, n) memcpy(dest, src, n)
|
||||
#define bzero(s, n) memset(s, 0, n)
|
||||
#define bcmp(s1, s2, n) memcmp(s1, s2, n)
|
||||
/* These could be customised for different languages perhaps */
|
||||
#define ASK_PROMPT "Boot from (N)etwork or from (L)ocal? "
|
||||
#define ANS_NETWORK 'N'
|
||||
#define ANS_LOCAL 'L'
|
||||
#ifndef ANS_DEFAULT /* in case left out in Makefile */
|
||||
#define ANS_DEFAULT ANS_NETWORK
|
||||
#endif
|
||||
|
||||
/* ANSI prototyping macro */
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
|
||||
|
||||
|
||||
#define TAGGED_IMAGE /* eventually optional */
|
||||
#if !defined(TAGGED_IMAGE) && !defined(AOUT_IMAGE) && !defined(ELF_IMAGE)
|
||||
#define TAGGED_IMAGE /* choose at least one */
|
||||
#endif
|
||||
|
||||
#define ESC 0x1B
|
||||
|
||||
#ifndef DEFAULT_BOOTFILE
|
||||
#define DEFAULT_BOOTFILE "/kernel"
|
||||
#define DEFAULT_BOOTFILE "/tftpboot/kernel"
|
||||
#endif
|
||||
|
||||
#ifndef MAX_TFTP_RETRIES
|
||||
|
@ -65,7 +44,11 @@ extern inline int iskey(void) {
|
|||
#endif
|
||||
|
||||
#ifndef MAX_BOOTP_EXTLEN
|
||||
#if defined(INTERNAL_BOOTP_DATA) || (RELOC >= 0x94200)
|
||||
#define MAX_BOOTP_EXTLEN 1024
|
||||
#else
|
||||
#define MAX_BOOTP_EXTLEN (1024-sizeof(struct bootp_t))
|
||||
#endif /* INTERNAL_BOOTP_DATA || RELOC > 0x94200 */
|
||||
#endif
|
||||
|
||||
#ifndef MAX_ARP_RETRIES
|
||||
|
@ -76,9 +59,16 @@ extern inline int iskey(void) {
|
|||
#define MAX_RPC_RETRIES 20
|
||||
#endif
|
||||
|
||||
#ifndef TIMEOUT /* Inter-packet retry in ticks 18/sec */
|
||||
#define TIMEOUT 180
|
||||
#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)
|
||||
|
@ -110,17 +100,19 @@ extern inline int iskey(void) {
|
|||
#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 69
|
||||
#define SUNRPC 111
|
||||
|
||||
#define RPC_SOCKET 620 /* Arbitrary */
|
||||
|
||||
#define IP_UDP 17
|
||||
/* Same after going through htonl */
|
||||
#define IP_BROADCAST 0xFFFFFFFF
|
||||
|
||||
#define ARP_REQUEST 1
|
||||
|
@ -181,12 +173,25 @@ extern inline int iskey(void) {
|
|||
#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 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_HOWTO 132 /* used by FreeBSD */
|
||||
#define RFC1533_VENDOR_MNUOPTS 160
|
||||
#define RFC1533_VENDOR_SELECTION 176
|
||||
#define RFC1533_VENDOR_MOTD 184
|
||||
|
@ -196,6 +201,9 @@ extern inline int iskey(void) {
|
|||
|
||||
#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 */
|
||||
|
@ -213,33 +221,24 @@ extern inline int iskey(void) {
|
|||
#define TFTP_CODE_BOOT 4
|
||||
#define TFTP_CODE_CFG 5
|
||||
|
||||
#define PROG_PORTMAP 100000
|
||||
#define PROG_NFS 100003
|
||||
#define PROG_MOUNT 100005
|
||||
|
||||
#define MSG_CALL 0
|
||||
#define MSG_REPLY 1
|
||||
|
||||
#define PORTMAP_LOOKUP 3
|
||||
|
||||
#define MOUNT_ADDENTRY 1
|
||||
#define MOUNT_UMNTALL 4
|
||||
#define NFS_LOOKUP 4
|
||||
#define NFS_READ 6
|
||||
|
||||
#define NFS_READ_SIZE 1024
|
||||
|
||||
|
||||
#define AWAIT_ARP 0
|
||||
#define AWAIT_BOOTP 1
|
||||
#define AWAIT_TFTP 2
|
||||
#define AWAIT_RPC 3
|
||||
#define AWAIT_RARP 3
|
||||
|
||||
typedef struct {
|
||||
unsigned long s_addr;
|
||||
} in_addr;
|
||||
|
||||
struct arptable_t {
|
||||
unsigned long ipaddr;
|
||||
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;
|
||||
|
@ -261,8 +260,8 @@ struct iphdr {
|
|||
char ttl;
|
||||
char protocol;
|
||||
unsigned short chksum;
|
||||
char src[4];
|
||||
char dest[4];
|
||||
in_addr src;
|
||||
in_addr dest;
|
||||
};
|
||||
|
||||
struct udphdr {
|
||||
|
@ -282,14 +281,18 @@ struct bootp_t {
|
|||
unsigned long bp_xid;
|
||||
unsigned short bp_secs;
|
||||
unsigned short unused;
|
||||
char bp_ciaddr[4];
|
||||
char bp_yiaddr[4];
|
||||
char bp_siaddr[4];
|
||||
char bp_giaddr[4];
|
||||
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 */
|
||||
};
|
||||
|
||||
struct bootpd_t {
|
||||
|
@ -297,7 +300,6 @@ struct bootpd_t {
|
|||
unsigned char bootp_extension[MAX_BOOTP_EXTLEN];
|
||||
};
|
||||
|
||||
|
||||
struct tftp_t {
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
|
@ -321,108 +323,91 @@ struct tftp_t {
|
|||
} u;
|
||||
};
|
||||
|
||||
struct rpc_t {
|
||||
struct iphdr ip;
|
||||
struct udphdr udp;
|
||||
union {
|
||||
char data[1400];
|
||||
struct {
|
||||
long id;
|
||||
long type;
|
||||
long rstatus;
|
||||
long verifier;
|
||||
long v2;
|
||||
long astatus;
|
||||
long data[1];
|
||||
} reply;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
|
||||
|
||||
/***************************************************************************
|
||||
RPC Functions
|
||||
***************************************************************************/
|
||||
#define PUTLONG(val) {\
|
||||
register int lval = val; \
|
||||
*(rpcptr++) = ((lval) >> 24); \
|
||||
*(rpcptr++) = ((lval) >> 16); \
|
||||
*(rpcptr++) = ((lval) >> 8); \
|
||||
*(rpcptr++) = (lval); \
|
||||
rpclen+=4; }
|
||||
#define ROM_INFO_LOCATION 0x7dfa
|
||||
/* at end of floppy boot block */
|
||||
|
||||
#if 0 /* XXX */
|
||||
struct rom_info {
|
||||
unsigned short rom_segment;
|
||||
unsigned short rom_length;
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
extern int rarp P((void));
|
||||
External prototypes
|
||||
***************************************************************************/
|
||||
/* main.c */
|
||||
#if 0
|
||||
extern void print_bytes P((unsigned char *bytes, int len));
|
||||
extern void load P((void));
|
||||
extern int load_linux P((int root_mount_port,int swap_mount_port,
|
||||
int root_nfs_port,char *kernel_handle));
|
||||
extern int linux_tftp P((unsigned int block,unsigned char *data,int len));
|
||||
extern int tftpkernel P((unsigned char *, int, int, int));
|
||||
extern int tftp P((char *name, int (*)(unsigned char *, int, int, int)));
|
||||
#endif
|
||||
extern int bootp P((void));
|
||||
extern int rarp P((void));
|
||||
extern int udp_transmit P((unsigned long destip, unsigned int srcsock,
|
||||
unsigned int destsock, int len, char *buf));
|
||||
extern int await_reply P((int type, int ival, char *ptr));
|
||||
extern void default_netmask P((void));
|
||||
extern int await_reply P((int type, int ival, char *ptr, int timeout));
|
||||
extern int decode_rfc1533 P((unsigned char *, int, int, int));
|
||||
extern unsigned short ipchksum P((unsigned short *, int len));
|
||||
extern void convert_ipaddr P((char *, char *));
|
||||
extern void rfc951_sleep P((int));
|
||||
|
||||
#if 0
|
||||
/* bootmenu.c */
|
||||
extern int execute P((char *string));
|
||||
extern void bootmenu P((void));
|
||||
extern void bootmenu P((int));
|
||||
extern void show_motd P((void));
|
||||
extern void parse_menuopts P((char *,int));
|
||||
extern int getoptvalue P((char **, int *, int *));
|
||||
extern void selectImage P((char **, char *, struct arptable_t *));
|
||||
extern void selectImage P((char **));
|
||||
|
||||
/* linuxloader.c */
|
||||
extern char *linux_add_cmdline P((char *string));
|
||||
|
||||
/* rpc.c */
|
||||
extern int rpclookup P((int addr, int prog, int ver));
|
||||
extern int nfs_mount P((int server, int port, char *path, char *fh));
|
||||
extern int nfs_umountall P((int server, int port));
|
||||
extern int nfs_lookup P((int server, int port, char *fh, char *path, char *file_fh));
|
||||
extern int nfs_read P((int server, int port, char *fh, int offset, int len, char *buffer));
|
||||
extern void rpc_err P((struct rpc_t *rpc));
|
||||
extern void nfs_err P((int err));
|
||||
/* osloader.c */
|
||||
#if defined(AOUT_IMAGE) || defined(ELF_IMAGE)
|
||||
extern int howto;
|
||||
#endif
|
||||
extern int os_tftp P((unsigned int block,unsigned char *data,int len));
|
||||
#endif
|
||||
|
||||
/* misc.c */
|
||||
#if 0 /*Edmund*/
|
||||
extern void bcopy P((void *src, void *dst, int cnt));
|
||||
extern void bzero P((void *dst, int cnt));
|
||||
extern int bcmp P((void *src, void *dst, int cnt));
|
||||
#endif
|
||||
extern void twiddle P((void));
|
||||
extern void sleep P((int secs));
|
||||
#if 0
|
||||
extern int strcasecmp P((char *a, char *b));
|
||||
extern char *substr P((char *a, char *b));
|
||||
#endif
|
||||
extern int getdec P((char **));
|
||||
extern void twiddle P((void));
|
||||
#if 0
|
||||
extern void printf(); /* old style to avoid varargs */
|
||||
extern char *sprintf();
|
||||
extern int setip P((char *p, unsigned long *i));
|
||||
extern int inet_ntoa P((char *p, in_addr *i));
|
||||
extern void gateA20 P((void));
|
||||
extern void putchar P((int));
|
||||
extern int getchar ();
|
||||
extern int iskey P((void));
|
||||
|
||||
/* start*.S */
|
||||
extern int getchar P((void));
|
||||
extern void putchar P((int));
|
||||
extern int iskey P((void));
|
||||
extern int getc P((void));
|
||||
extern void putc P((int));
|
||||
extern int ischar P((void));
|
||||
extern int getshift P((void));
|
||||
extern unsigned short memsize P((void));
|
||||
extern void disk_init P((void));
|
||||
extern short disk_read P((int drv,int c,int h,int s,char *buf));
|
||||
extern void start_linux P((void));
|
||||
extern void xstart P((unsigned long, unsigned long, unsigned long));
|
||||
extern unsigned int disk_read P((int drv,int c,int h,int s,char *buf));
|
||||
extern void xstart P((unsigned long, unsigned long, char *));
|
||||
extern long currticks P((void));
|
||||
extern int setjmp P((void *jmpbuf));
|
||||
extern void longjmp P((void *jmpbuf, int where));
|
||||
extern void exit P((int status));
|
||||
|
||||
/* serial.S */
|
||||
extern int serial_getc P((void));
|
||||
extern void serial_putc P((int));
|
||||
extern int serial_ischar P((void));
|
||||
extern void serial_init P((void));
|
||||
|
||||
/* ansiesc.c */
|
||||
extern void ansi_reset P((void));
|
||||
extern void enable_cursor P((int));
|
||||
|
@ -433,36 +418,53 @@ extern void md5_done P((unsigned char *buf));
|
|||
|
||||
/* floppy.c */
|
||||
extern int bootdisk P((int dev,int part));
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
External variables
|
||||
***************************************************************************/
|
||||
/* main.c */
|
||||
extern int ip_abort;
|
||||
extern int network_ready;
|
||||
#if 0
|
||||
extern char *kernel;
|
||||
extern char kernel_buf[];
|
||||
extern struct nfs_diskless nfsdiskless;
|
||||
#endif
|
||||
extern struct rom_info rom;
|
||||
#if 0
|
||||
extern int hostnamelen;
|
||||
extern unsigned long netmask;
|
||||
extern int jmp_bootmenu[10];
|
||||
extern char kernel_buf[128];
|
||||
extern struct bootpd_t bootp_data;
|
||||
#endif
|
||||
extern struct arptable_t arptable[MAX_ARP];
|
||||
#if 0
|
||||
extern char *imagelist[RFC1533_VENDOR_NUMOFIMG];
|
||||
extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
|
||||
extern int menutmo,menudefault;
|
||||
extern struct bootpd_t bootp_data;
|
||||
#endif
|
||||
#ifdef ETHERBOOT32
|
||||
#define INTERNAL_BOOTP_DATA 1
|
||||
#ifdef INTERNAL_BOOTP_DATA
|
||||
#define BOOTP_DATA_ADDR (&bootp_data)
|
||||
#else
|
||||
#define BOOTP_DATA_ADDR ((struct bootpd_t *)0x93C00)
|
||||
#endif /* INTERNAL_BOOTP_DATA */
|
||||
#endif
|
||||
#ifdef ETHERBOOT16
|
||||
#define BOOTP_DATA_ADDR (&bootp_data)
|
||||
#endif
|
||||
extern unsigned char *end_of_rfc1533;
|
||||
|
||||
/* bootmenu.c */
|
||||
|
||||
/* linuxloader.c */
|
||||
|
||||
/* rpc.c */
|
||||
extern int rpc_id;
|
||||
/* osloader.c */
|
||||
|
||||
#if 0
|
||||
/* created by linker */
|
||||
extern char _edata[], _end[];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
|
@ -1,94 +1,308 @@
|
|||
#include "../stage2/filesys.h"
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000 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.
|
||||
*/
|
||||
|
||||
#include "netboot.h"
|
||||
#include "netboot_config.h"
|
||||
#include "nic.h"
|
||||
/* Based on "src/main.c" in etherboot-4.4.2. */
|
||||
/**************************************************************************
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
#include "ip.h"
|
||||
Author: Martin Renters
|
||||
Date: Dec/93
|
||||
|
||||
#if 0
|
||||
**************************************************************************/
|
||||
|
||||
#define BUFSIZE (20*TFTP_DEFAULTSIZE_PACKET)
|
||||
static char buf[BUFSIZE];
|
||||
#include <filesys.h>
|
||||
|
||||
#else
|
||||
|
||||
/* use GRUB's file system buffer */
|
||||
#define BUFSIZE (32*1024)
|
||||
#define buf ((char *)(FSYS_BUF))
|
||||
|
||||
#endif
|
||||
|
||||
static int buf_read = 0, buf_eof = 0;
|
||||
static unsigned long buf_fileoff;
|
||||
#include <etherboot.h>
|
||||
#include <nic.h>
|
||||
#include <netboot_config.h>
|
||||
|
||||
static int retry;
|
||||
static unsigned short isocket = 2000;
|
||||
static unsigned short osocket;
|
||||
static unsigned short len, block, prevblock;
|
||||
static struct tftp_t *tr;
|
||||
static struct tftp_t tp;
|
||||
static int packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||
static unsigned short block, prevblock;
|
||||
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;
|
||||
|
||||
static int buf_fill(int abort);
|
||||
|
||||
int tftp_mount(void)
|
||||
/* Fill the buffer by receiving the data via the TFTP protocol. */
|
||||
static int
|
||||
buf_fill (int abort)
|
||||
{
|
||||
if (current_drive != 0x20) /* only mount network drives */
|
||||
while (! buf_eof && (buf_read + packetsize <= FSYS_BUFLEN))
|
||||
{
|
||||
struct tftp_t *tr;
|
||||
|
||||
#ifdef CONGESTED
|
||||
if (! await_reply (AWAIT_TFTP, isocket, NULL, block ? TFTP_REXMT : 0))
|
||||
#else
|
||||
if (! await_reply (AWAIT_TFTP, isocket, NULL, 0))
|
||||
#endif
|
||||
{
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
|
||||
if (!ip_init())
|
||||
if (! block && retry++ < MAX_TFTP_RETRIES)
|
||||
{
|
||||
/* Maybe initial request was lost. */
|
||||
rfc951_sleep(retry);
|
||||
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
++isocket, TFTP, len, (char *) &tp))
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef CONGESTED
|
||||
if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
|
||||
{
|
||||
/* We resend our last ack. */
|
||||
# ifdef MDEBUG
|
||||
grub_printf ("<REXMT>\n");
|
||||
# endif
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
isocket, osocket,
|
||||
TFTP_MIN_PACKET, (char *) &tp);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* Timeout. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
tr = (struct tftp_t *) &nic.packet[ETHER_HDR_SIZE];
|
||||
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;
|
||||
|
||||
/* Shouldn't happen. */
|
||||
if (prevblock)
|
||||
/* Ignore it. */
|
||||
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;
|
||||
}
|
||||
else if (! grub_strcmp ("tsize", p))
|
||||
{
|
||||
p += 6;
|
||||
if ((filemax = getdec (&p)) < 0)
|
||||
{
|
||||
filemax = -1;
|
||||
goto noak;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
noak:
|
||||
tp.opcode = htons (TFTP_ERROR);
|
||||
tp.u.err.errcode = 8;
|
||||
len = (grub_sprintf ((char *) tp.u.err.errmsg,
|
||||
"RFC1782 error")
|
||||
+ TFTP_MIN_PACKET + 1);
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
isocket, ntohs (tr->udp.src),
|
||||
len, (char *) &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))
|
||||
{
|
||||
len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4;
|
||||
|
||||
/* Shouldn't happen. */
|
||||
if (len > packetsize)
|
||||
/* Ignore it. */
|
||||
continue;
|
||||
|
||||
block = ntohs (tp.u.ack.block = tr->u.data.block);
|
||||
}
|
||||
else
|
||||
/* Neither TFTP_OACK nor TFTP_DATA. */
|
||||
break;
|
||||
|
||||
/* Block order. */
|
||||
if (block && (block != prevblock + 1))
|
||||
tp.u.ack.block = htons (block = prevblock);
|
||||
|
||||
/* Should be continuous. */
|
||||
tp.opcode = abort ? htons (TFTP_ERROR) : htons (TFTP_ACK);
|
||||
osocket = ntohs (tr->udp.src);
|
||||
|
||||
/* Ack. */
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, isocket,
|
||||
osocket, TFTP_MIN_PACKET, (char *) &tp);
|
||||
|
||||
if (abort)
|
||||
{
|
||||
buf_eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Retransmission or OACK. */
|
||||
if (block <= prevblock)
|
||||
/* Don't process. */
|
||||
continue;
|
||||
|
||||
prevblock = block;
|
||||
/* Is it the right place to zero the timer? */
|
||||
retry = 0;
|
||||
|
||||
/* 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;
|
||||
|
||||
buf = (char *) FSYS_BUF;
|
||||
buf_eof = 0;
|
||||
buf_read = 0;
|
||||
saved_filepos = 0;
|
||||
|
||||
/* Send the packet. */
|
||||
return udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++isocket, TFTP,
|
||||
len, (char *) &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 "size" bytes from file position "filepos" to "addr" */
|
||||
int tftp_read(char *addr, int size)
|
||||
/* Read up to SIZE bytes, returned in ADDR. */
|
||||
int
|
||||
tftp_read (char *addr, int size)
|
||||
{
|
||||
/* How many bytes is read? */
|
||||
int ret = 0;
|
||||
|
||||
if (filepos < buf_fileoff)
|
||||
if (filepos < saved_filepos)
|
||||
{
|
||||
printf("tftp_read: can't read from filepos=%d, buf_fileoff=%d\n",
|
||||
filepos, buf_fileoff);
|
||||
errnum = ERR_BOOT_FAILURE;
|
||||
/* Uggh.. FILEPOS has been moved backwards. So reopen the file. */
|
||||
tp = saved_tp;
|
||||
len = saved_len;
|
||||
if (! send_rrq ())
|
||||
{
|
||||
errnum = ERR_READ;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
if (filepos < buf_fileoff + buf_read)
|
||||
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)
|
||||
{
|
||||
/* can copy stuff from buffer */
|
||||
int tocopy = buf_fileoff + buf_read - filepos;
|
||||
if (tocopy > size) tocopy = size;
|
||||
bcopy(buf + (filepos - buf_fileoff), (void*) addr, tocopy);
|
||||
size -= tocopy;
|
||||
addr += tocopy;
|
||||
filepos += tocopy;
|
||||
ret += tocopy;
|
||||
/* Copy the buffer to the supplied memory space. */
|
||||
grub_memmove (addr, buf + filepos - saved_filepos, amt);
|
||||
size -= amt;
|
||||
addr += amt;
|
||||
filepos += amt;
|
||||
saved_filepos = filepos;
|
||||
ret += amt;
|
||||
|
||||
if (buf_eof && (filepos + size >= buf_fileoff + buf_read))
|
||||
break; /* end of file */
|
||||
|
||||
continue;
|
||||
/* Move the unused data forwards. */
|
||||
grub_memmove (buf, buf + amt, buf_read - amt);
|
||||
buf_read -= amt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset the reading offset. */
|
||||
saved_filepos += buf_read;
|
||||
buf_read = 0;
|
||||
}
|
||||
else if ((filepos == buf_fileoff + buf_read) && buf_eof)
|
||||
break; /* end of file */
|
||||
|
||||
if (buf_eof) /* filepos beyond end of file */
|
||||
/* Read the data. */
|
||||
if (! buf_fill (0))
|
||||
{
|
||||
errnum = ERR_READ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* move buffer contents forward by 1/2 buffer size */
|
||||
bcopy(buf + BUFSIZE/2, buf, BUFSIZE/2);
|
||||
buf_fileoff += BUFSIZE/2;
|
||||
buf_read -= BUFSIZE/2;
|
||||
|
||||
if (! buf_fill(0)) /* read more data */
|
||||
if (size > 0 && buf_eof)
|
||||
{
|
||||
errnum = ERR_READ;
|
||||
return 0;
|
||||
|
@ -98,128 +312,82 @@ int tftp_read(char *addr, int size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int tftp_dir(char *dirname)
|
||||
/* Check if the file DIRNAME really exists. Get the size and save it in
|
||||
FILEMAX. */
|
||||
int
|
||||
tftp_dir (char *dirname)
|
||||
{
|
||||
char name[100], *np;
|
||||
int ch;
|
||||
|
||||
/* In TFTP, there is no way to know what files exis. */
|
||||
if (print_possibilities)
|
||||
{
|
||||
printf(" TFTP doesn't support listing the directory; Sorry!\n");
|
||||
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)
|
||||
+ TFTP_MIN_PACKET + 1);
|
||||
/* Restore the original DIRNAME. */
|
||||
dirname[grub_strlen (dirname)] = ch;
|
||||
if (! send_rrq ())
|
||||
{
|
||||
errnum = ERR_READ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* open the file */
|
||||
np = name;
|
||||
while (dirname && *dirname && !isspace(*dirname))
|
||||
*np++ = *dirname++;
|
||||
*np = 0;
|
||||
|
||||
buf_eof = buf_read = buf_fileoff = 0;
|
||||
|
||||
retry = 0;
|
||||
block = 0;
|
||||
prevblock = 0;
|
||||
packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||
|
||||
/* send tftp read request */
|
||||
tp.opcode = htons(TFTP_RRQ);
|
||||
len = 30 + sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
|
||||
name, 0, 0, 0, TFTP_MAX_PACKET) + 1;
|
||||
|
||||
if (!udp_transmit(arptable[ARP_SERVER].ipaddr, ++isocket, TFTP,
|
||||
len, (char *)&tp))
|
||||
/* Read the data. */
|
||||
if (! buf_fill (0))
|
||||
{
|
||||
printf("tftp_dir: can't transmit TFTP read request\n");
|
||||
errnum = ERR_BOOT_FAILURE;
|
||||
return (0);
|
||||
}
|
||||
if (! buf_fill(0))
|
||||
{
|
||||
printf("tftp_dir: can't read from file\n");
|
||||
errnum = ERR_FILE_NOT_FOUND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* filemax = 234620; */
|
||||
filemax = 16L*1024*1024; /* XXX 16MB is max filesize */
|
||||
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);
|
||||
|
||||
/* Retry the open instruction. */
|
||||
goto reopen;
|
||||
}
|
||||
|
||||
/* Save the TFTP packet so that we can reopen the file later. */
|
||||
saved_tp = tp;
|
||||
saved_len = len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void tftp_close(void)
|
||||
/* Close the file. */
|
||||
void
|
||||
tftp_close (void)
|
||||
{
|
||||
buf_read = 0;
|
||||
buf_fill (1); /* abort. */
|
||||
}
|
||||
|
||||
static int buf_fill(int abort)
|
||||
{
|
||||
while (!buf_eof && (buf_read + packetsize <= BUFSIZE))
|
||||
{
|
||||
/* read a packet from the network */
|
||||
if (!await_reply(AWAIT_TFTP, isocket, NULL))
|
||||
{
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
|
||||
if (prevblock == 0 && retry++ < MAX_TFTP_RETRIES)
|
||||
{ /* maybe initial request was lost */
|
||||
rfc951_sleep(retry);
|
||||
if (!udp_transmit(arptable[ARP_SERVER].ipaddr,
|
||||
++isocket, TFTP, len, (char *)&tp))
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
return 0; /* timeout on other blocks */
|
||||
}
|
||||
|
||||
/* we got a packet */
|
||||
|
||||
tr = (struct tftp_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||
|
||||
if (tr->opcode == ntohs(TFTP_ERROR)) /* error? */
|
||||
{
|
||||
printf("TFTP error %d (%s)\r\n",
|
||||
ntohs(tr->u.err.errcode),
|
||||
tr->u.err.errmsg);
|
||||
return 0;
|
||||
}
|
||||
else if (tr->opcode == ntohs(TFTP_OACK))
|
||||
{
|
||||
continue; /* ignore */
|
||||
}
|
||||
else if (tr->opcode == ntohs(TFTP_DATA))
|
||||
{
|
||||
retry = MAX_TFTP_RETRIES; /*no more retries! */
|
||||
len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
|
||||
if (len > packetsize) /* shouldn't happen */
|
||||
continue; /* ignore it */
|
||||
block = ntohs(tp.u.ack.block = tr->u.data.block);
|
||||
}
|
||||
else /* neither TFTP_OACK nor TFTP_DATA */
|
||||
return 0;
|
||||
|
||||
tp.opcode = abort ? htons(TFTP_ERROR) : htons(TFTP_ACK);
|
||||
osocket = ntohs(tr->udp.src);
|
||||
udp_transmit(arptable[ARP_SERVER].ipaddr, isocket,
|
||||
osocket, TFTP_MIN_PACKET, (char *)&tp); /* ack */
|
||||
|
||||
if (abort)
|
||||
{
|
||||
buf_eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (block <= prevblock) /* retransmission or OACK */
|
||||
continue; /* don't process */
|
||||
prevblock = block;
|
||||
|
||||
bcopy(tr->u.data.download, buf + buf_read, len);
|
||||
buf_read += len;
|
||||
|
||||
if (len < packetsize) /* End of data */
|
||||
buf_eof = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
buf_fill (1);
|
||||
}
|
||||
|
|
645
netboot/ip.c
645
netboot/ip.c
|
@ -1,645 +0,0 @@
|
|||
#include "netboot.h"
|
||||
#include "netboot_config.h"
|
||||
#include "nic.h"
|
||||
|
||||
#include "ip.h"
|
||||
|
||||
|
||||
struct arptable_t arptable[MAX_ARP];
|
||||
int _pending_key;
|
||||
|
||||
static unsigned long netmask;
|
||||
static char rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };
|
||||
static char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
static char *kernel;
|
||||
static char kernel_buf[128];
|
||||
static struct bootpd_t bootp_data;
|
||||
static int vendorext_isvalid;
|
||||
static unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* äEth */
|
||||
static unsigned char *end_of_rfc1533 = NULL;
|
||||
|
||||
int ip_abort = 0;
|
||||
|
||||
static int bootp(void);
|
||||
static void default_netmask(void);
|
||||
static void convert_ipaddr(register char *d, register char *s);
|
||||
static int decode_rfc1533(register unsigned char *p, int block, int len,
|
||||
int eof);
|
||||
|
||||
|
||||
int ip_init(void)
|
||||
{
|
||||
static int bootp_completed = 0,
|
||||
probe_completed = 0;
|
||||
|
||||
if (!probe_completed && !eth_probe())
|
||||
{
|
||||
printf("No ethernet adapter found\n");
|
||||
return 0;
|
||||
}
|
||||
probe_completed = 1;
|
||||
|
||||
#if 1
|
||||
if ((!bootp_completed ||
|
||||
!arptable[ARP_CLIENT].ipaddr || !arptable[ARP_SERVER].ipaddr))
|
||||
{
|
||||
#endif
|
||||
if (!bootp())
|
||||
{
|
||||
printf("No BOOTP server found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("My IP 0x%x, Server IP 0x%x, GW IP 0x%x\n",
|
||||
arptable[ARP_CLIENT].ipaddr,
|
||||
arptable[ARP_SERVER].ipaddr,
|
||||
arptable[ARP_GATEWAY].ipaddr);
|
||||
#ifdef CONFIG_FILE_EXT
|
||||
{
|
||||
char *ext = &config_file;
|
||||
|
||||
/* seek to end of config file name */
|
||||
while(*ext)
|
||||
ext++;
|
||||
|
||||
sprintf(ext, ".%d", arptable[ARP_CLIENT].ipaddr & 0xff);
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
}
|
||||
bootp_completed = 1;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
UDP_TRANSMIT - Send a UDP datagram
|
||||
**************************************************************************/
|
||||
int udp_transmit(destip, srcsock, destsock, len, buf)
|
||||
unsigned long destip;
|
||||
unsigned int srcsock, destsock;
|
||||
int len;
|
||||
char *buf;
|
||||
{
|
||||
struct iphdr *ip;
|
||||
struct udphdr *udp;
|
||||
struct arprequest arpreq;
|
||||
int arpentry, i;
|
||||
int retry;
|
||||
|
||||
ip = (struct iphdr *)buf;
|
||||
udp = (struct udphdr *)(buf + sizeof(struct iphdr));
|
||||
ip->verhdrlen = 0x45;
|
||||
ip->service = 0;
|
||||
ip->len = htons(len);
|
||||
ip->ident = 0;
|
||||
ip->frags = 0;
|
||||
ip->ttl = 60;
|
||||
ip->protocol = IP_UDP;
|
||||
ip->chksum = 0;
|
||||
convert_ipaddr(ip->src, (char *)&arptable[ARP_CLIENT].ipaddr);
|
||||
convert_ipaddr(ip->dest, (char *)&destip);
|
||||
ip->chksum = ipchksum((unsigned short *)buf, sizeof(struct iphdr));
|
||||
udp->src = htons(srcsock);
|
||||
udp->dest = htons(destsock);
|
||||
udp->len = htons(len - sizeof(struct iphdr));
|
||||
udp->chksum = 0;
|
||||
if (destip == IP_BROADCAST) {
|
||||
eth_transmit(broadcast, IP, len, buf);
|
||||
} else {
|
||||
long h_netmask = ntohl(netmask);
|
||||
/* Check to see if we need gateway */
|
||||
if (((destip & h_netmask) !=
|
||||
(arptable[ARP_CLIENT].ipaddr & h_netmask)) &&
|
||||
arptable[ARP_GATEWAY].ipaddr)
|
||||
destip = arptable[ARP_GATEWAY].ipaddr;
|
||||
for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
|
||||
if (arptable[arpentry].ipaddr == destip) break;
|
||||
if (arpentry == MAX_ARP) {
|
||||
printf("%I is not in my arp table!\r\n", destip);
|
||||
return(0);
|
||||
}
|
||||
for (i = 0; i<ETHER_ADDR_SIZE; i++)
|
||||
if (arptable[arpentry].node[i]) break;
|
||||
if (i == ETHER_ADDR_SIZE) { /* Need to do arp request */
|
||||
arpreq.hwtype = htons(1);
|
||||
arpreq.protocol = htons(IP);
|
||||
arpreq.hwlen = ETHER_ADDR_SIZE;
|
||||
arpreq.protolen = 4;
|
||||
arpreq.opcode = htons(ARP_REQUEST);
|
||||
bcopy(arptable[ARP_CLIENT].node, arpreq.shwaddr,
|
||||
ETHER_ADDR_SIZE);
|
||||
convert_ipaddr(arpreq.sipaddr,
|
||||
(char *)&arptable[ARP_CLIENT].ipaddr);
|
||||
bzero(arpreq.thwaddr, ETHER_ADDR_SIZE);
|
||||
convert_ipaddr(arpreq.tipaddr, (char *)&destip);
|
||||
for (retry = 0; retry < MAX_ARP_RETRIES;
|
||||
rfc951_sleep(++retry)) {
|
||||
eth_transmit(broadcast, ARP, sizeof(arpreq),
|
||||
(char *)&arpreq);
|
||||
if (await_reply(AWAIT_ARP, arpentry,
|
||||
arpreq.tipaddr)) goto xmit;
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
xmit: eth_transmit(arptable[arpentry].node, IP, len, buf);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
AWAIT_REPLY - Wait until we get a response for our request
|
||||
**************************************************************************/
|
||||
int await_reply(type, ival, ptr)
|
||||
int type, ival;
|
||||
char *ptr;
|
||||
{
|
||||
unsigned long time;
|
||||
struct iphdr *ip;
|
||||
struct udphdr *udp;
|
||||
struct arprequest *arpreply;
|
||||
struct bootp_t *bootpreply;
|
||||
struct rpc_t *rpc;
|
||||
|
||||
int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +
|
||||
sizeof(struct udphdr);
|
||||
|
||||
ip_abort = 0;
|
||||
|
||||
time = currticks() + TIMEOUT;
|
||||
while(time > currticks()) {
|
||||
#if 0
|
||||
if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1);
|
||||
#else
|
||||
if (iskey() && (getchar() == ESC))
|
||||
{
|
||||
ip_abort = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (eth_poll())
|
||||
{ /* We have something! */
|
||||
/* Check for ARP - No IP hdr */
|
||||
if ((nic.packetlen >= ETHER_HDR_SIZE +
|
||||
sizeof(struct arprequest)) &&
|
||||
(((nic.packet[12] << 8) | nic.packet[13]) == ARP))
|
||||
{
|
||||
unsigned long target_ip;
|
||||
|
||||
arpreply = (struct arprequest *)
|
||||
&nic.packet[ETHER_HDR_SIZE];
|
||||
|
||||
if (arpreply->opcode == ntohs(ARP_REQUEST)
|
||||
&& (convert_ipaddr(&target_ip,
|
||||
&arpreply->tipaddr),
|
||||
arptable[ARP_CLIENT].ipaddr == target_ip))
|
||||
{
|
||||
/* request for our ether address -- send a reply */
|
||||
|
||||
unsigned long my_ip_net
|
||||
= *(unsigned long*)(arpreply->tipaddr);
|
||||
|
||||
bcopy(arpreply->shwaddr, arpreply->thwaddr, 10);
|
||||
bcopy(arptable[ARP_CLIENT].node,
|
||||
arpreply->shwaddr, ETHER_ADDR_SIZE);
|
||||
*(unsigned long*)(arpreply->sipaddr) = my_ip_net;
|
||||
arpreply->opcode = htons(ARP_REPLY);
|
||||
eth_transmit(arpreply->thwaddr, ARP,
|
||||
sizeof(struct arprequest),
|
||||
(char *) arpreply);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (type == AWAIT_ARP &&
|
||||
(arpreply->opcode == ntohs(ARP_REPLY)) &&
|
||||
!bcmp(arpreply->sipaddr, ptr, 4)) {
|
||||
bcopy(arpreply->shwaddr,
|
||||
arptable[ival].node,
|
||||
ETHER_ADDR_SIZE);
|
||||
return(1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Anything else has IP header */
|
||||
if ((nic.packetlen < protohdrlen) ||
|
||||
(((nic.packet[12] << 8) | nic.packet[13]) != IP)) continue;
|
||||
ip = (struct iphdr *)&nic.packet[ETHER_HDR_SIZE];
|
||||
if ((ip->verhdrlen != 0x45) ||
|
||||
ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
|
||||
(ip->protocol != IP_UDP)) continue;
|
||||
udp = (struct udphdr *)&nic.packet[ETHER_HDR_SIZE +
|
||||
sizeof(struct iphdr)];
|
||||
|
||||
/* BOOTP ? */
|
||||
bootpreply = (struct bootp_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||
if ((type == AWAIT_BOOTP) &&
|
||||
(nic.packetlen >= (ETHER_HDR_SIZE +
|
||||
sizeof(struct bootp_t))) &&
|
||||
(ntohs(udp->dest) == BOOTP_CLIENT) &&
|
||||
(bootpreply->bp_op == BOOTP_REPLY)) {
|
||||
convert_ipaddr((char *)&arptable[ARP_CLIENT].ipaddr,
|
||||
bootpreply->bp_yiaddr);
|
||||
default_netmask();
|
||||
convert_ipaddr((char *)&arptable[ARP_SERVER].ipaddr,
|
||||
bootpreply->bp_siaddr);
|
||||
bzero(arptable[ARP_SERVER].node,
|
||||
ETHER_ADDR_SIZE); /* Kill arp */
|
||||
convert_ipaddr((char *)&arptable[ARP_GATEWAY].ipaddr,
|
||||
bootpreply->bp_giaddr);
|
||||
bzero(arptable[ARP_GATEWAY].node,
|
||||
ETHER_ADDR_SIZE); /* Kill arp */
|
||||
if (bootpreply->bp_file[0]) {
|
||||
bcopy(bootpreply->bp_file,
|
||||
kernel_buf, 128);
|
||||
kernel = kernel_buf;
|
||||
}
|
||||
bcopy((char *)bootpreply,
|
||||
(char *)&bootp_data,
|
||||
sizeof(struct bootp_t));
|
||||
decode_rfc1533(bootp_data.bootp_reply.bp_vend,
|
||||
0, BOOTP_VENDOR_LEN, 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* TFTP ? */
|
||||
if ((type == AWAIT_TFTP) &&
|
||||
(ntohs(udp->dest) == ival)) return(1);
|
||||
|
||||
/* RPC */
|
||||
rpc = (struct rpc_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||
#ifdef NFS_BOOT
|
||||
if ((type == AWAIT_RPC) &&
|
||||
(ntohs(udp->dest) == RPC_SOCKET) &&
|
||||
(ntohl(rpc->u.reply.id) == ival) &&
|
||||
(ntohl(rpc->u.reply.type) == MSG_REPLY)) {
|
||||
rpc_id++;
|
||||
return(1);
|
||||
}
|
||||
#endif /* NFS_BOOT */
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
IPCHKSUM - Checksum IP Header
|
||||
**************************************************************************/
|
||||
unsigned short ipchksum(ip, len)
|
||||
register unsigned short *ip;
|
||||
register int len;
|
||||
{
|
||||
unsigned long sum = 0;
|
||||
len >>= 1;
|
||||
while (len--) {
|
||||
sum += *(ip++);
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
}
|
||||
return((~sum) & 0x0000FFFF);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TFTP - Download extended BOOTP data, configuration file or kernel image
|
||||
**************************************************************************/
|
||||
int tftp(name,fnc)
|
||||
char *name;
|
||||
int (*fnc)(unsigned char *, int, int, int);
|
||||
{
|
||||
int retry = 0;
|
||||
static unsigned short isocket = 2000;
|
||||
unsigned short osocket;
|
||||
unsigned short len, block = 0, prevblock = 0;
|
||||
struct tftp_t *tr;
|
||||
struct tftp_t tp;
|
||||
int rc;
|
||||
int packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||
|
||||
tp.opcode = htons(TFTP_RRQ);
|
||||
len = 30 + sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
|
||||
name, 0, 0, 0, TFTP_MAX_PACKET) + 1;
|
||||
if (!udp_transmit(arptable[ARP_SERVER].ipaddr, ++isocket, TFTP,
|
||||
len, (char *)&tp))
|
||||
return (0);
|
||||
for (;;)
|
||||
{
|
||||
if (!await_reply(AWAIT_TFTP, isocket, NULL))
|
||||
{
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
if (prevblock == 0 && retry++ < MAX_TFTP_RETRIES)
|
||||
{ /* maybe initial request was lost */
|
||||
rfc951_sleep(retry);
|
||||
if (!udp_transmit(arptable[ARP_SERVER].ipaddr,
|
||||
++isocket, TFTP, len, (char *)&tp))
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
break; /* timeout on other blocks */
|
||||
}
|
||||
tr = (struct tftp_t *)&nic.packet[ETHER_HDR_SIZE];
|
||||
if (tr->opcode == ntohs(TFTP_ERROR))
|
||||
{
|
||||
printf("TFTP error %d (%s)\r\n",
|
||||
ntohs(tr->u.err.errcode),
|
||||
tr->u.err.errmsg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tr->opcode == ntohs(TFTP_OACK)) {
|
||||
#if 0
|
||||
char *p = tr->u.oack.data, *e;
|
||||
|
||||
retry = MAX_TFTP_RETRIES;/*no more retries! */
|
||||
if (prevblock) /* shouldn't happen */
|
||||
continue; /* ignore it */
|
||||
len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 2;
|
||||
if (len > TFTP_MAX_PACKET)
|
||||
goto noak;
|
||||
e = p + len;
|
||||
while (*p != '\000' && p < e) {
|
||||
if (!strcasecmp("blksize", p)) {
|
||||
p += 8;
|
||||
if ((packetsize = getdec(&p)) <
|
||||
TFTP_DEFAULTSIZE_PACKET)
|
||||
goto noak;
|
||||
while (p < e && *p) p++;
|
||||
if (p < e)
|
||||
p++;
|
||||
}
|
||||
else {
|
||||
noak:
|
||||
tp.opcode = htons(TFTP_ERROR);
|
||||
tp.u.err.errcode = 8;
|
||||
len = 30 + sprintf((char *)tp.u.err.errmsg,
|
||||
"RFC1782 error")+ 1;
|
||||
udp_transmit(arptable[ARP_SERVER].
|
||||
ipaddr, isocket,
|
||||
ntohs(tr->udp.src),
|
||||
len, (char *)&tp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (p > e)
|
||||
goto noak;
|
||||
block = tp.u.ack.block = 0; /* this ensures, that */
|
||||
/* the packet does not get */
|
||||
/* processed as data! */
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
else if (tr->opcode == ntohs(TFTP_DATA)) {
|
||||
retry = MAX_TFTP_RETRIES;/*no more retries! */
|
||||
len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
|
||||
if (len > packetsize) /* shouldn't happen */
|
||||
continue; /* ignore it */
|
||||
block = ntohs(tp.u.ack.block = tr->u.data.block); }
|
||||
else /* neither TFTP_OACK nor TFTP_DATA */
|
||||
break;
|
||||
|
||||
tp.opcode = htons(TFTP_ACK);
|
||||
osocket = ntohs(tr->udp.src);
|
||||
udp_transmit(arptable[ARP_SERVER].ipaddr, isocket,
|
||||
osocket, TFTP_MIN_PACKET, (char *)&tp); /* ack */
|
||||
if (block <= prevblock) /* retransmission or OACK */
|
||||
continue; /* don't process */
|
||||
prevblock = block;
|
||||
if ((rc = fnc(tr->u.data.download,
|
||||
block, len, len < packetsize)) >= 0)
|
||||
return(rc);
|
||||
if (len < packetsize) /* End of data */
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
CONVERT_IPADDR - Convert IP address from net to machine order
|
||||
**************************************************************************/
|
||||
static void convert_ipaddr(d, s)
|
||||
register char *d,*s;
|
||||
{
|
||||
d[3] = s[0];
|
||||
d[2] = s[1];
|
||||
d[1] = s[2];
|
||||
d[0] = s[3];
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
RFC951_SLEEP - sleep for expotentially longer times
|
||||
**************************************************************************/
|
||||
void rfc951_sleep(exp)
|
||||
int exp;
|
||||
{
|
||||
static long seed = 0;
|
||||
long q,z,tmo;
|
||||
|
||||
if (!seed) /* Initialize linear congruential generator */
|
||||
seed = currticks() + *(long *)&arptable[ARP_CLIENT].node
|
||||
+ ((short *)arptable[ARP_CLIENT].node)[2];
|
||||
/* simplified version of the LCG given in Bruce Scheier's
|
||||
"Applied Cryptography" */
|
||||
q = seed/53668;
|
||||
if ((seed = 40014*(seed-53668*q) - 12211*q) < 0) seed += 2147483563l;
|
||||
/* compute mask */
|
||||
for (tmo = 63; tmo <= 60*18 && --exp > 0; tmo = 2*tmo+1);
|
||||
/* sleep */
|
||||
printf("<sleep>\r\n");
|
||||
for (tmo = (tmo&seed)+currticks(); currticks() < tmo; )
|
||||
/* if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1) */ ;
|
||||
eth_reset();
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TWIDDLE
|
||||
**************************************************************************/
|
||||
void twiddle()
|
||||
{
|
||||
static unsigned long lastticks = 0;
|
||||
static int count=0;
|
||||
static char tiddles[]="-\\|/";
|
||||
unsigned long ticks;
|
||||
if ((ticks = currticks()) < lastticks)
|
||||
return;
|
||||
lastticks = ticks+1;
|
||||
putchar(tiddles[(count++)&3]);
|
||||
putchar('\b');
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
BOOTP - Get my IP address and load information
|
||||
**************************************************************************/
|
||||
static int bootp()
|
||||
{
|
||||
int retry;
|
||||
struct bootp_t bp;
|
||||
unsigned long starttime;
|
||||
#ifdef T509HACK
|
||||
int flag;
|
||||
|
||||
flag = 1;
|
||||
#endif
|
||||
bzero(&bp, sizeof(struct bootp_t));
|
||||
bp.bp_op = BOOTP_REQUEST;
|
||||
bp.bp_htype = 1;
|
||||
bp.bp_hlen = ETHER_ADDR_SIZE;
|
||||
bp.bp_xid = starttime = currticks();
|
||||
bcopy(arptable[ARP_CLIENT].node, bp.bp_hwaddr, ETHER_ADDR_SIZE);
|
||||
bcopy(rfc1533_cookie, bp.bp_vend, 5); /* request RFC-style options */
|
||||
|
||||
for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
|
||||
udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
|
||||
sizeof(struct bootp_t), (char *)&bp);
|
||||
#ifdef T509HACK
|
||||
if (flag) {
|
||||
flag--;
|
||||
} else {
|
||||
if (await_reply(AWAIT_BOOTP, 0, NULL))
|
||||
return(1);
|
||||
if (ip_abort) /* hohmuth */
|
||||
return 0;
|
||||
rfc951_sleep(++retry);
|
||||
|
||||
}
|
||||
#else
|
||||
if (await_reply(AWAIT_BOOTP, 0, NULL))
|
||||
return(1);
|
||||
if (ip_abort) /* hohmuth */
|
||||
return 0;
|
||||
rfc951_sleep(++retry);
|
||||
#endif
|
||||
bp.bp_secs = htons((currticks()-starttime)/20);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DEFAULT_NETMASK - Set a default netmask for IP address
|
||||
**************************************************************************/
|
||||
static void default_netmask()
|
||||
{
|
||||
int net = arptable[ARP_CLIENT].ipaddr >> 24;
|
||||
if (net <= 127)
|
||||
netmask = htonl(0xff000000);
|
||||
else if (net < 192)
|
||||
netmask = htonl(0xffff0000);
|
||||
else
|
||||
netmask = htonl(0xffffff00);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DECODE_RFC1533 - Decodes RFC1533 header
|
||||
**************************************************************************/
|
||||
static int decode_rfc1533(p, block, len, eof)
|
||||
register unsigned char *p;
|
||||
int block, len, eof;
|
||||
{
|
||||
static unsigned char *extdata = NULL, *extend = NULL;
|
||||
unsigned char *extpath = NULL;
|
||||
unsigned char *end, *q;
|
||||
|
||||
if (block == 0) {
|
||||
#ifdef IMAGE_MENU
|
||||
bzero(imagelist, sizeof(imagelist));
|
||||
menudefault = useimagemenu = 0;
|
||||
menutmo = -1;
|
||||
#endif
|
||||
#ifdef MOTD
|
||||
bzero(motd, sizeof(motd));
|
||||
#endif
|
||||
end_of_rfc1533 = NULL;
|
||||
vendorext_isvalid = 0;
|
||||
if (bcmp(p, rfc1533_cookie, 4))
|
||||
return(0); /* no RFC 1533 header found */
|
||||
p += 4;
|
||||
end = p + len; }
|
||||
else {
|
||||
if (block == 1) {
|
||||
if (bcmp(p, rfc1533_cookie, 4))
|
||||
return(0); /* no RFC 1533 header found */
|
||||
p += 4;
|
||||
len -= 4; }
|
||||
if (extend + len <= (unsigned char *)(&bootp_data+1)) {
|
||||
bcopy(p, extend, len);
|
||||
extend += len;
|
||||
} else {
|
||||
printf("Overflow in vendor data buffer! Aborting...\r\n");
|
||||
*extdata = RFC1533_END;
|
||||
return(0);
|
||||
}
|
||||
p = extdata; end = extend;
|
||||
}
|
||||
if (eof) {
|
||||
while(p < end) {
|
||||
unsigned char c = *p;
|
||||
if (c == RFC1533_PAD) {p++; continue;}
|
||||
else if (c == RFC1533_END) {
|
||||
end_of_rfc1533 = end = p; continue; }
|
||||
else if (c == RFC1533_NETMASK) {bcopy(p+2,&netmask,4);}
|
||||
#ifdef NFS_BOOT
|
||||
else if (c == RFC1533_HOSTNAME) {
|
||||
if (TAG_LEN(p) < (MNAMELEN&~3)-1) {
|
||||
bcopy(p+2,&nfsdiskless.my_hostnam,TAG_LEN(p));
|
||||
nfsdiskless.my_hostnam[TAG_LEN(p)] = '\000';
|
||||
hostnamelen = (TAG_LEN(p)+3)&~3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (c == RFC1533_GATEWAY) {
|
||||
/* This is a little simplistic, but it will
|
||||
usually be sufficient; look into the gate-
|
||||
way list, only if there has been no BOOTP
|
||||
gateway. Take only the first entry */
|
||||
if (TAG_LEN(p) >= 4 &&
|
||||
arptable[ARP_GATEWAY].ipaddr == 0)
|
||||
convert_ipaddr((char *)&arptable[ARP_GATEWAY].ipaddr,
|
||||
p+2);
|
||||
}
|
||||
else if (c == RFC1533_EXTENSIONPATH)
|
||||
extpath = p;
|
||||
else if (c == RFC1533_VENDOR_MAGIC &&
|
||||
TAG_LEN(p) >= 6 &&
|
||||
!bcmp(p+2,vendorext_magic,4) &&
|
||||
p[6] == RFC1533_VENDOR_MAJOR)
|
||||
vendorext_isvalid++;
|
||||
#ifdef IMAGE_MENU
|
||||
else if (c == RFC1533_VENDOR_MNUOPTS) {
|
||||
parse_menuopts(p+2, TAG_LEN(p));
|
||||
}
|
||||
else if (c >= RFC1533_VENDOR_IMG &&
|
||||
c<RFC1533_VENDOR_IMG+RFC1533_VENDOR_NUMOFIMG){
|
||||
imagelist[c - RFC1533_VENDOR_IMG] = p;
|
||||
useimagemenu++;
|
||||
}
|
||||
#endif
|
||||
#ifdef MOTD
|
||||
else if (c >= RFC1533_VENDOR_MOTD &&
|
||||
c < RFC1533_VENDOR_MOTD +
|
||||
RFC1533_VENDOR_NUMOFMOTD)
|
||||
motd[c - RFC1533_VENDOR_MOTD] = p;
|
||||
#endif
|
||||
else {
|
||||
/* printf("Unknown RFC1533-tag ");
|
||||
for(q=p;q<p+2+TAG_LEN(p);q++)
|
||||
printf("%x ",*q);
|
||||
printf("\n\r"); */ }
|
||||
p += TAG_LEN(p) + 2;
|
||||
}
|
||||
extdata = extend = end;
|
||||
if (block == 0 && extpath != NULL) {
|
||||
char fname[64];
|
||||
bcopy(extpath+2,fname,TAG_LEN(extpath));
|
||||
fname[(int)TAG_LEN(extpath)] = '\000';
|
||||
printf("Loading BOOTP-extension file: %s\r\n",fname);
|
||||
tftp(fname,decode_rfc1533);
|
||||
}
|
||||
}
|
||||
return(-1); /* proceed with next block */
|
||||
}
|
15
netboot/ip.h
15
netboot/ip.h
|
@ -1,15 +0,0 @@
|
|||
int ip_init(void);
|
||||
int tftp(char *name, int (*fnc)(unsigned char *, int, int, int));
|
||||
|
||||
extern int ip_abort;
|
||||
|
||||
extern int udp_transmit (unsigned long destip, unsigned int srcsock,
|
||||
unsigned int destsock, int len, char *buf);
|
||||
|
||||
extern int await_reply (int type, int ival, char *ptr);
|
||||
|
||||
extern unsigned short ipchksum (unsigned short *, int len);
|
||||
|
||||
extern void rfc951_sleep (int);
|
||||
|
||||
extern void twiddle (void);
|
143
netboot/lance.c
143
netboot/lance.c
|
@ -5,19 +5,28 @@ Large portions borrowed from the Linux LANCE driver by Donald Becker
|
|||
Ken Yap, July 1997
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_NE2100
|
||||
|
||||
/* to get some global routines like printf */
|
||||
#include "netboot.h"
|
||||
#include "etherboot.h"
|
||||
/* to get the interface to the body of the program */
|
||||
#include "nic.h"
|
||||
|
||||
/* Offsets from base I/O address */
|
||||
#if defined(INCLUDE_NE2100) || defined(INCLUDE_LANCEPCI)
|
||||
#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
|
||||
|
||||
struct lance_init_block
|
||||
{
|
||||
|
@ -97,10 +106,13 @@ static struct lance_chip_type
|
|||
};
|
||||
|
||||
/* Define a macro for converting program addresses to real addresses */
|
||||
/* Linux already defines it in asm/io.h */
|
||||
#ifdef NETBOOT16
|
||||
#ifdef ETHERBOOT32
|
||||
#undef virt_to_bus
|
||||
#define virt_to_bus(x) ((unsigned long)x)
|
||||
#endif
|
||||
#ifdef ETHERBOOT16
|
||||
#define virt_to_bus(x) (((Address)x)+RELOC)
|
||||
#endif /* NETBOOT16 */
|
||||
#endif /* ETHERBOOT16 */
|
||||
|
||||
static int chip_version;
|
||||
static unsigned short ioaddr;
|
||||
|
@ -109,10 +121,6 @@ static struct lance_interface *lp;
|
|||
/* additional 8 bytes for 8-byte alignment space */
|
||||
static char lance[sizeof(struct lance_interface)+8];
|
||||
|
||||
#if defined(INCLUDE_NE2100)
|
||||
#define lance_probe ne2100_probe
|
||||
#endif
|
||||
|
||||
/* DMA defines and helper routines */
|
||||
|
||||
/* DMA controller registers */
|
||||
|
@ -147,26 +155,26 @@ static char lance[sizeof(struct lance_interface)+8];
|
|||
static void enable_dma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr <= 3)
|
||||
outb_p(DMA1_MASK_REG, dmanr);
|
||||
outb_p(dmanr, DMA1_MASK_REG);
|
||||
else
|
||||
outb_p(DMA2_MASK_REG, dmanr & 3);
|
||||
outb_p(dmanr & 3, DMA2_MASK_REG);
|
||||
}
|
||||
|
||||
static void disable_dma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr <= 3)
|
||||
outb_p(DMA1_MASK_REG, dmanr | 4);
|
||||
outb_p(dmanr | 4, DMA1_MASK_REG);
|
||||
else
|
||||
outb_p(DMA2_MASK_REG, (dmanr & 3) | 4);
|
||||
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(DMA1_MODE_REG, mode | dmanr);
|
||||
outb_p(mode | dmanr, DMA1_MODE_REG);
|
||||
else
|
||||
outb_p(DMA2_MODE_REG, mode | (dmanr&3));
|
||||
outb_p(mode | (dmanr&3), DMA2_MODE_REG);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -181,13 +189,13 @@ static void lance_reset(struct nic *nic)
|
|||
(void)inw(ioaddr+LANCE_RESET);
|
||||
/* Un-Reset the LANCE, needed only for the NE2100 */
|
||||
if (chip_table[chip_version].flags & LANCE_MUST_UNRESET)
|
||||
outw(ioaddr+LANCE_RESET, 0);
|
||||
outw(0, ioaddr+LANCE_RESET);
|
||||
if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT)
|
||||
{
|
||||
/* This is 79C960 specific; Turn on auto-select of media
|
||||
(AUI, BNC). */
|
||||
outw(ioaddr+LANCE_ADDR, 0x2);
|
||||
outw(ioaddr+LANCE_BUS_IF, 0x2);
|
||||
outw(0x2, ioaddr+LANCE_ADDR);
|
||||
outw(0x2, ioaddr+LANCE_BUS_IF);
|
||||
}
|
||||
/* Re-initialise the LANCE, and start it when done. */
|
||||
/* Set station address */
|
||||
|
@ -201,25 +209,25 @@ static void lance_reset(struct nic *nic)
|
|||
lp->rx_ring.u.addr[3] = 0x80;
|
||||
lp->init_block.mode = 0x0; /* enable Rx and Tx */
|
||||
l = (Address)virt_to_bus(&lp->init_block);
|
||||
outw(ioaddr+LANCE_ADDR, 0x1);
|
||||
outw(0x1, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, (short)l);
|
||||
outw(ioaddr+LANCE_ADDR, 0x2);
|
||||
outw((short)l, ioaddr+LANCE_DATA);
|
||||
outw(0x2, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, (short)(l >> 16));
|
||||
outw(ioaddr+LANCE_ADDR, 0x4);
|
||||
outw((short)(l >> 16), ioaddr+LANCE_DATA);
|
||||
outw(0x4, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, 0x915);
|
||||
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||
outw(0x915, ioaddr+LANCE_DATA);
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, 0x4); /* stop */
|
||||
outw(ioaddr+LANCE_DATA, 0x1); /* init */
|
||||
outw(0x4, ioaddr+LANCE_DATA); /* stop */
|
||||
outw(0x1, ioaddr+LANCE_DATA); /* init */
|
||||
for (i = 100; i > 0; --i)
|
||||
if (inw(ioaddr+LANCE_DATA) & 0x100)
|
||||
break;
|
||||
/* Apparently clearing the InitDone bit here triggers a bug
|
||||
in the '974. (Mark Stockton) */
|
||||
outw(ioaddr+LANCE_DATA, 0x2); /* start */
|
||||
outw(0x2, ioaddr+LANCE_DATA); /* start */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -233,19 +241,19 @@ static int lance_poll(struct nic *nic)
|
|||
if (status & 0x80)
|
||||
return (0);
|
||||
#ifdef DEBUG
|
||||
printf("LANCE packet received rx_ring.u.base %X mcnt %x csr0 %x\r\n",
|
||||
printf("LANCE packet received rx_ring.u.base %X mcnt %x csr0 %x\n",
|
||||
lp->rx_ring.u.base, lp->rx_ring.msg_length,
|
||||
inw(ioaddr+LANCE_DATA));
|
||||
#endif
|
||||
if (status == 0x3)
|
||||
bcopy(lp->rbuf, nic->packet, nic->packetlen = lp->rx_ring.msg_length);
|
||||
memcpy(nic->packet, lp->rbuf, nic->packetlen = lp->rx_ring.msg_length);
|
||||
/* Andrew Boyd of QNX reports that some revs of the 79C765
|
||||
clear the buffer length */
|
||||
lp->rx_ring.buf_length = -ETH_MAX_PACKET;
|
||||
lp->rx_ring.u.addr[3] |= 0x80; /* prime for next receive */
|
||||
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, 0x500); /* clear receive + InitDone */
|
||||
outw(0x500, ioaddr+LANCE_DATA); /* clear receive + InitDone */
|
||||
return (status == 0x3);
|
||||
}
|
||||
|
||||
|
@ -262,11 +270,11 @@ static void lance_transmit(
|
|||
unsigned long time;
|
||||
|
||||
/* copy the packet to ring buffer */
|
||||
bcopy(d, lp->tbuf, ETHER_ADDR_SIZE); /* dst */
|
||||
bcopy(nic->node_addr, &lp->tbuf[ETHER_ADDR_SIZE], ETHER_ADDR_SIZE); /* src */
|
||||
memcpy(lp->tbuf, d, ETHER_ADDR_SIZE); /* dst */
|
||||
memcpy(&lp->tbuf[ETHER_ADDR_SIZE], nic->node_addr, ETHER_ADDR_SIZE); /* src */
|
||||
lp->tbuf[ETHER_ADDR_SIZE+ETHER_ADDR_SIZE] = t >> 8; /* type */
|
||||
lp->tbuf[ETHER_ADDR_SIZE+ETHER_ADDR_SIZE+1] = t; /* type */
|
||||
bcopy(p, &lp->tbuf[ETHER_HDR_SIZE], s);
|
||||
memcpy(&lp->tbuf[ETHER_HDR_SIZE], p, s);
|
||||
s += ETHER_HDR_SIZE;
|
||||
if (chip_table[chip_version].flags & LANCE_MUST_PAD)
|
||||
while (s < ETH_MIN_PACKET) /* pad to min length */
|
||||
|
@ -278,18 +286,18 @@ static void lance_transmit(
|
|||
/* we set the top byte as the very last thing */
|
||||
lp->tx_ring.u.addr[3] = 0x83;
|
||||
/* Trigger an immediate send poll */
|
||||
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||
outw(ioaddr+LANCE_DATA, 0x48);
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
outw(0x48, ioaddr+LANCE_DATA);
|
||||
/* wait for transmit complete */
|
||||
time = currticks() + 18; /* wait one second */
|
||||
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\r\n");
|
||||
printf("LANCE timed out on transmit\n");
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, 0x200); /* clear transmit + InitDone */
|
||||
outw(0x200, ioaddr+LANCE_DATA); /* clear transmit + InitDone */
|
||||
#ifdef DEBUG
|
||||
printf("tx_ring.u.base %X tx_ring.buf_length %x tx_ring.misc %x csr0 %x\r\n",
|
||||
printf("tx_ring.u.base %X tx_ring.buf_length %x tx_ring.misc %x csr0 %x\n",
|
||||
lp->tx_ring.u.base, lp->tx_ring.buf_length, lp->tx_ring.misc,
|
||||
inw(ioaddr+LANCE_DATA));
|
||||
#endif
|
||||
|
@ -308,16 +316,18 @@ static int lance_probe1(struct nic *nic)
|
|||
static char dmas[] = { 5, 6, 7, 3 };
|
||||
|
||||
reset_val = inw(ioaddr+LANCE_RESET);
|
||||
outw(ioaddr+LANCE_ADDR, 0x0); /* Switch to window 0 */
|
||||
#ifdef INCLUDE_NE2100
|
||||
outw(0x0, ioaddr+LANCE_ADDR); /* Switch to window 0 */
|
||||
if (inw(ioaddr+LANCE_DATA) != 0x4)
|
||||
return (-1);
|
||||
outw(ioaddr+LANCE_ADDR, 88); /* Get the version of the chip */
|
||||
#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(ioaddr+LANCE_ADDR, 89);
|
||||
outw(89, ioaddr+LANCE_ADDR);
|
||||
chip_version |= inw(ioaddr+LANCE_DATA) << 16;
|
||||
if ((chip_version & 0xfff) != 0x3)
|
||||
return (-1);
|
||||
|
@ -335,16 +345,16 @@ static int lance_probe1(struct nic *nic)
|
|||
lp->init_block.rx_ring = virt_to_bus(&lp->rx_ring) & 0xffffff;
|
||||
lp->init_block.tx_ring = virt_to_bus(&lp->tx_ring) & 0xffffff;
|
||||
l = virt_to_bus(&lp->init_block);
|
||||
outw(ioaddr+LANCE_ADDR, 0x1);
|
||||
outw(0x1, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, (unsigned short)l);
|
||||
outw(ioaddr+LANCE_ADDR, 0x2);
|
||||
outw((unsigned short)l, ioaddr+LANCE_DATA);
|
||||
outw(0x2, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, (unsigned short)(l >> 16));
|
||||
outw(ioaddr+LANCE_ADDR, 0x4);
|
||||
outw((unsigned short)(l >> 16), ioaddr+LANCE_DATA);
|
||||
outw(0x4, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
outw(ioaddr+LANCE_DATA, 0x915);
|
||||
outw(ioaddr+LANCE_ADDR, 0x0);
|
||||
outw(0x915, ioaddr+LANCE_DATA);
|
||||
outw(0x0, ioaddr+LANCE_ADDR);
|
||||
(void)inw(ioaddr+LANCE_ADDR);
|
||||
/* now probe for DMA channel */
|
||||
dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0xf) |
|
||||
|
@ -359,10 +369,10 @@ static int lance_probe1(struct nic *nic)
|
|||
or the machine will hang */
|
||||
if (dma_channels & (1 << dma))
|
||||
continue;
|
||||
outw(ioaddr+LANCE_DATA, 0x7f04); /* clear memory error bits */
|
||||
outw(0x7f04, ioaddr+LANCE_DATA); /* clear memory error bits */
|
||||
set_dma_mode(dma, DMA_MODE_CASCADE);
|
||||
enable_dma(dma);
|
||||
outw(ioaddr+LANCE_DATA, 0x1); /* init */
|
||||
outw(0x1, ioaddr+LANCE_DATA); /* init */
|
||||
for (j = 100; j > 0; --j)
|
||||
if (inw(ioaddr+LANCE_DATA) & 0x900)
|
||||
break;
|
||||
|
@ -373,23 +383,32 @@ static int lance_probe1(struct nic *nic)
|
|||
}
|
||||
if (i >= (sizeof(dmas)/sizeof(dmas[0])))
|
||||
dma = 0;
|
||||
printf("\r\n%s base 0x%x, DMA %d, addr ",
|
||||
printf("\n%s base 0x%x, DMA %d, addr ",
|
||||
chip_table[lance_version].name, ioaddr, dma);
|
||||
/* Get station address */
|
||||
for (i = 0; i < ETHER_ADDR_SIZE; ++i)
|
||||
{
|
||||
printf("%b", nic->node_addr[i] = inb(ioaddr+i));
|
||||
printf("%b", nic->node_addr[i] = inb(ioaddr+LANCE_ETH_ADDR+i));
|
||||
if (i < ETHER_ADDR_SIZE -1)
|
||||
printf(":");
|
||||
}
|
||||
printf("\r\n");
|
||||
putchar('\n');
|
||||
return (lance_version);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
***************************************************************************/
|
||||
struct nic *lance_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
|
||||
#ifdef INCLUDE_LANCEPCI
|
||||
struct nic *lancepci_probe(struct nic *nic, unsigned short *probe_addrs)
|
||||
#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;
|
||||
static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x360, 0 };
|
||||
|
@ -401,8 +420,14 @@ struct nic *lance_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
{
|
||||
char offset15, offset14 = inb(ioaddr + 14);
|
||||
|
||||
#ifdef INCLUDE_NE2100
|
||||
if ((offset14 == 0x52 || offset14 == 0x57) &&
|
||||
((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
|
||||
#endif
|
||||
#ifdef INCLUDE_NI6510
|
||||
if ((offset14 == 0x00 || offset14 == 0x52) &&
|
||||
((offset15 = inb(ioaddr + 15)) == 0x55 || offset15 == 0x44))
|
||||
#endif
|
||||
if (lance_probe1(nic) >= 0)
|
||||
break;
|
||||
}
|
||||
|
@ -422,5 +447,3 @@ struct nic *lance_probe(struct nic *nic, unsigned short *probe_addrs)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_NE2100 */
|
||||
|
|
|
@ -2,11 +2,92 @@
|
|||
#define _ASM_IO_H
|
||||
|
||||
/*
|
||||
* This file contains parts of Linux's /usr/include/asm/io.h, but
|
||||
* with the argument order reversed for outb, outb_p, outw, outw_p.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Change virtual addresses to physical addresses and vv.
|
||||
* These are trivial on the 1:1 Linux/i386 mapping (but if we ever
|
||||
* make the kernel segment mapped at 0, we need to do translation
|
||||
* on the i386 as well)
|
||||
*/
|
||||
extern inline unsigned long virt_to_phys(volatile void * address);
|
||||
extern inline unsigned long virt_to_phys(volatile void * address)
|
||||
{
|
||||
return (unsigned long) address;
|
||||
}
|
||||
|
||||
extern inline void * phys_to_virt(unsigned long address);
|
||||
extern inline void * phys_to_virt(unsigned long address)
|
||||
{
|
||||
return (void *) address;
|
||||
}
|
||||
|
||||
/*
|
||||
* IO bus memory addresses are also 1:1 with the physical address
|
||||
*/
|
||||
#define virt_to_bus virt_to_phys
|
||||
#define bus_to_virt phys_to_virt
|
||||
|
||||
/*
|
||||
* 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 inline void __out##s(unsigned x value, unsigned short port); \
|
||||
|
@ -70,7 +151,12 @@ __OUTS(b)
|
|||
__OUTS(w)
|
||||
__OUTS(l)
|
||||
|
||||
#define outb(port,val) \
|
||||
/*
|
||||
* 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)))
|
||||
|
@ -80,7 +166,7 @@ __OUTS(l)
|
|||
__inbc(port) : \
|
||||
__inb(port))
|
||||
|
||||
#define outb_p(port,val) \
|
||||
#define outb_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outbc_p((val),(port)) : \
|
||||
__outb_p((val),(port)))
|
||||
|
@ -90,7 +176,7 @@ __OUTS(l)
|
|||
__inbc_p(port) : \
|
||||
__inb_p(port))
|
||||
|
||||
#define outw(port,val) \
|
||||
#define outw(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outwc((val),(port)) : \
|
||||
__outw((val),(port)))
|
||||
|
@ -100,7 +186,7 @@ __OUTS(l)
|
|||
__inwc(port) : \
|
||||
__inw(port))
|
||||
|
||||
#define outw_p(port,val) \
|
||||
#define outw_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outwc_p((val),(port)) : \
|
||||
__outw_p((val),(port)))
|
||||
|
@ -110,7 +196,7 @@ __OUTS(l)
|
|||
__inwc_p(port) : \
|
||||
__inw_p(port))
|
||||
|
||||
#define outl(port,val) \
|
||||
#define outl(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outlc((val),(port)) : \
|
||||
__outl((val),(port)))
|
||||
|
@ -120,7 +206,7 @@ __OUTS(l)
|
|||
__inlc(port) : \
|
||||
__inl(port))
|
||||
|
||||
#define outl_p(port,val) \
|
||||
#define outl_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outlc_p((val),(port)) : \
|
||||
__outl_p((val),(port)))
|
246
netboot/linux-asm-string.h
Normal file
246
netboot/linux-asm-string.h
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Taken from Linux /usr/include/asm/string.h
|
||||
* All except memcpy, 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 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) ? \
|
||||
__memset((s),(c),(count)) : \
|
||||
__memset((s),(c),(count)))
|
||||
|
||||
#endif
|
956
netboot/main.c
Normal file
956
netboot/main.c
Normal file
|
@ -0,0 +1,956 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000 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.4.2. */
|
||||
|
||||
/**************************************************************************
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters
|
||||
Date: Dec/93
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/* #define MDEBUG */
|
||||
|
||||
#include <etherboot.h>
|
||||
#include <nic.h>
|
||||
|
||||
#include <netboot_config.h>
|
||||
|
||||
struct arptable_t arptable[MAX_ARP];
|
||||
int ip_abort = 0;
|
||||
int network_ready = 0;
|
||||
struct rom_info rom;
|
||||
|
||||
static int vendorext_isvalid;
|
||||
static unsigned long netmask;
|
||||
static struct bootpd_t bootp_data;
|
||||
static unsigned long xid;
|
||||
static unsigned char *end_of_rfc1533 = NULL;
|
||||
|
||||
#ifndef NO_DHCP_SUPPORT
|
||||
static int dhcp_reply;
|
||||
static in_addr dhcp_server = {0L};
|
||||
static in_addr dhcp_addr = {0L};
|
||||
#endif /* NO_DHCP_SUPPORT */
|
||||
|
||||
/* äEth */
|
||||
static unsigned char vendorext_magic[] = {0xE4, 0x45, 0x74, 0x68};
|
||||
|
||||
#ifdef NO_DHCP_SUPPORT
|
||||
|
||||
static char rfc1533_cookie[5] = {RFC1533_COOKIE, RFC1533_END};
|
||||
|
||||
#else /* ! NO_DHCP_SUPPORT */
|
||||
|
||||
static char rfc1533_cookie[] = {RFC1533_COOKIE};
|
||||
static char rfc1533_end[] = {RFC1533_END};
|
||||
|
||||
static char dhcpdiscover[] =
|
||||
{
|
||||
RFC2132_MSG_TYPE, 1, DHCPDISCOVER,
|
||||
RFC2132_MAX_SIZE, 2, 2, 64,
|
||||
RFC2132_PARAM_LIST, 4, RFC1533_NETMASK, RFC1533_GATEWAY,
|
||||
RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH
|
||||
};
|
||||
|
||||
static char dhcprequest[] =
|
||||
{
|
||||
RFC2132_MSG_TYPE, 1, DHCPREQUEST,
|
||||
RFC2132_SRV_ID, 4, 0, 0, 0, 0,
|
||||
RFC2132_REQ_ADDR, 4, 0, 0, 0, 0,
|
||||
RFC2132_MAX_SIZE, 2, 2, 64,
|
||||
/* request parameters */
|
||||
RFC2132_PARAM_LIST,
|
||||
/* 4 standard + 4 vendortags + 8 motd + 16 menu items */
|
||||
4 + 4 + 8 + 16,
|
||||
/* Standard parameters */
|
||||
RFC1533_NETMASK, RFC1533_GATEWAY,
|
||||
RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
|
||||
/* Etherboot vendortags */
|
||||
RFC1533_VENDOR_MAGIC, RFC1533_VENDOR_HOWTO,
|
||||
RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
|
||||
/* 8 MOTD entries */
|
||||
RFC1533_VENDOR_MOTD,
|
||||
RFC1533_VENDOR_MOTD + 1,
|
||||
RFC1533_VENDOR_MOTD + 2,
|
||||
RFC1533_VENDOR_MOTD + 3,
|
||||
RFC1533_VENDOR_MOTD + 4,
|
||||
RFC1533_VENDOR_MOTD + 5,
|
||||
RFC1533_VENDOR_MOTD + 6,
|
||||
RFC1533_VENDOR_MOTD + 7,
|
||||
/* 16 image entries */
|
||||
RFC1533_VENDOR_IMG,
|
||||
RFC1533_VENDOR_IMG + 1,
|
||||
RFC1533_VENDOR_IMG + 2,
|
||||
RFC1533_VENDOR_IMG + 3,
|
||||
RFC1533_VENDOR_IMG + 4,
|
||||
RFC1533_VENDOR_IMG + 5,
|
||||
RFC1533_VENDOR_IMG + 6,
|
||||
RFC1533_VENDOR_IMG + 7,
|
||||
RFC1533_VENDOR_IMG + 8,
|
||||
RFC1533_VENDOR_IMG + 9,
|
||||
RFC1533_VENDOR_IMG + 10,
|
||||
RFC1533_VENDOR_IMG + 11,
|
||||
RFC1533_VENDOR_IMG + 12,
|
||||
RFC1533_VENDOR_IMG + 13,
|
||||
RFC1533_VENDOR_IMG + 14,
|
||||
RFC1533_VENDOR_IMG + 15,
|
||||
};
|
||||
|
||||
#endif /* ! NO_DHCP_SUPPORT */
|
||||
|
||||
static char broadcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
/**************************************************************************
|
||||
DEFAULT_NETMASK - Return default netmask for IP address
|
||||
**************************************************************************/
|
||||
static inline unsigned long
|
||||
default_netmask (void)
|
||||
{
|
||||
int net = ntohl (arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
|
||||
if (net <= 127)
|
||||
return (htonl (0xff000000));
|
||||
else if (net < 192)
|
||||
return (htonl (0xffff0000));
|
||||
else
|
||||
return (htonl (0xffffff00));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
UDP_TRANSMIT - Send a UDP datagram
|
||||
**************************************************************************/
|
||||
int
|
||||
udp_transmit (unsigned long destip, unsigned srcsock, unsigned destsock,
|
||||
int len, char *buf)
|
||||
{
|
||||
struct iphdr *ip;
|
||||
struct udphdr *udp;
|
||||
struct arprequest arpreq;
|
||||
int arpentry, i;
|
||||
int retry;
|
||||
|
||||
ip = (struct iphdr *) buf;
|
||||
udp = (struct udphdr *) (buf + sizeof (struct iphdr));
|
||||
ip->verhdrlen = 0x45;
|
||||
ip->service = 0;
|
||||
ip->len = htons (len);
|
||||
ip->ident = 0;
|
||||
ip->frags = 0;
|
||||
ip->ttl = 60;
|
||||
ip->protocol = IP_UDP;
|
||||
ip->chksum = 0;
|
||||
ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
|
||||
ip->dest.s_addr = destip;
|
||||
ip->chksum = ipchksum ((unsigned short *) buf, sizeof (struct iphdr));
|
||||
udp->src = htons (srcsock);
|
||||
udp->dest = htons (destsock);
|
||||
udp->len = htons (len - sizeof (struct iphdr));
|
||||
udp->chksum = 0;
|
||||
|
||||
if (destip == IP_BROADCAST)
|
||||
{
|
||||
eth_transmit (broadcast, IP, len, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((destip & netmask)
|
||||
!= (arptable[ARP_CLIENT].ipaddr.s_addr & netmask))
|
||||
&& arptable[ARP_GATEWAY].ipaddr.s_addr)
|
||||
destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
|
||||
|
||||
for (arpentry = 0; arpentry < MAX_ARP; arpentry++)
|
||||
if (arptable[arpentry].ipaddr.s_addr == destip)
|
||||
break;
|
||||
|
||||
if (arpentry == MAX_ARP)
|
||||
{
|
||||
grub_printf ("%x is not in my arp table!\n", destip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ETHER_ADDR_SIZE; i++)
|
||||
if (arptable[arpentry].node[i])
|
||||
break;
|
||||
|
||||
if (i == ETHER_ADDR_SIZE)
|
||||
{
|
||||
/* Need to do arp request. */
|
||||
arpreq.hwtype = htons (1);
|
||||
arpreq.protocol = htons (IP);
|
||||
arpreq.hwlen = ETHER_ADDR_SIZE;
|
||||
arpreq.protolen = 4;
|
||||
arpreq.opcode = htons (ARP_REQUEST);
|
||||
grub_memmove (arpreq.shwaddr, arptable[ARP_CLIENT].node,
|
||||
ETHER_ADDR_SIZE);
|
||||
grub_memmove (arpreq.sipaddr, (char *) &arptable[ARP_CLIENT].ipaddr,
|
||||
sizeof (in_addr));
|
||||
grub_memset (arpreq.thwaddr, 0, ETHER_ADDR_SIZE);
|
||||
grub_memmove (arpreq.tipaddr, (char *) &destip, sizeof (in_addr));
|
||||
|
||||
for (retry = 0; retry < MAX_ARP_RETRIES; rfc951_sleep (++retry))
|
||||
{
|
||||
eth_transmit (broadcast, ARP, sizeof (arpreq), (char *) &arpreq);
|
||||
if (await_reply (AWAIT_ARP, arpentry, arpreq.tipaddr, 0))
|
||||
goto xmit;
|
||||
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmit:
|
||||
eth_transmit (arptable[arpentry].node, IP, len, buf);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TFTP - Download extended BOOTP data, or kernel image
|
||||
**************************************************************************/
|
||||
static int
|
||||
tftp (char *name, int (*fnc) (unsigned char *, int, int, int))
|
||||
{
|
||||
int retry = 0;
|
||||
static unsigned short isocket = 2000;
|
||||
unsigned short osocket;
|
||||
unsigned short len, block = 0, prevblock = 0;
|
||||
struct tftp_t *tr;
|
||||
struct tftp_t tp;
|
||||
int rc;
|
||||
int packetsize = TFTP_DEFAULTSIZE_PACKET;
|
||||
|
||||
tp.opcode = htons (TFTP_RRQ);
|
||||
len = (grub_sprintf ((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
|
||||
name, 0, 0, 0, TFTP_MAX_PACKET)
|
||||
+ TFTP_MIN_PACKET + 1);
|
||||
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++isocket, TFTP,
|
||||
len, (char *) &tp))
|
||||
return 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#ifdef CONGESTED
|
||||
if (! await_reply (AWAIT_TFTP, isocket, NULL, (block ? TFTP_REXMT : 0)))
|
||||
#else
|
||||
if (! await_reply (AWAIT_TFTP, isocket, NULL, 0))
|
||||
#endif
|
||||
{
|
||||
if (! block && retry++ < MAX_TFTP_RETRIES)
|
||||
{
|
||||
/* Maybe initial request was lost. */
|
||||
rfc951_sleep (retry);
|
||||
if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
++isocket, TFTP, len, (char *) &tp))
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef CONGESTED
|
||||
if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
|
||||
{
|
||||
/* We resend our last ack. */
|
||||
#ifdef MDEBUG
|
||||
grub_printf ("<REXMT>\n");
|
||||
#endif
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
isocket, osocket,
|
||||
TFTP_MIN_PACKET, (char *)&tp);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* Timeout. */
|
||||
break;
|
||||
}
|
||||
|
||||
tr = (struct tftp_t *) &nic.packet[ETHER_HDR_SIZE];
|
||||
if (tr->opcode == ntohs (TFTP_ERROR))
|
||||
{
|
||||
grub_printf ("TFTP error %d (%s)\n",
|
||||
ntohs (tr->u.err.errcode),
|
||||
tr->u.err.errmsg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tr->opcode == ntohs (TFTP_OACK))
|
||||
{
|
||||
char *p = tr->u.oack.data, *e;
|
||||
|
||||
/* Shouldn't happen. */
|
||||
if (prevblock)
|
||||
/* Ignore it. */
|
||||
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;
|
||||
|
||||
while (p < e && *p)
|
||||
p++;
|
||||
|
||||
if (p < e)
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
noak:
|
||||
tp.opcode = htons (TFTP_ERROR);
|
||||
tp.u.err.errcode = 8;
|
||||
len = (grub_sprintf ((char *) tp.u.err.errmsg,
|
||||
"RFC1782 error")
|
||||
+ TFTP_MIN_PACKET + 1);
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
|
||||
isocket, ntohs (tr->udp.src),
|
||||
len, (char *) &tp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4;
|
||||
/* Shouldn't happen. */
|
||||
if (len > packetsize)
|
||||
/* Ignore it. */
|
||||
continue;
|
||||
|
||||
block = ntohs (tp.u.ack.block = tr->u.data.block);
|
||||
}
|
||||
else
|
||||
/* Neither TFTP_OACK nor TFTP_DATA. */
|
||||
break;
|
||||
|
||||
if (block && (block != prevblock+1))
|
||||
/* Block order. */
|
||||
tp.u.ack.block = htons (block = prevblock);
|
||||
|
||||
/* Should be continuous. */
|
||||
tp.opcode = htons (TFTP_ACK);
|
||||
osocket = ntohs (tr->udp.src);
|
||||
/* Ack. */
|
||||
udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, isocket,
|
||||
osocket, TFTP_MIN_PACKET, (char *) &tp);
|
||||
|
||||
/* Retransmission or OACK. */
|
||||
if (block <= prevblock)
|
||||
/* Don't process. */
|
||||
continue;
|
||||
|
||||
prevblock = block;
|
||||
/* Is it the right place to zero the timer? */
|
||||
retry = 0;
|
||||
|
||||
if ((rc = fnc (tr->u.data.download, block, len, len < packetsize)) >= 0)
|
||||
return rc;
|
||||
|
||||
/* End of data. */
|
||||
if (len < packetsize)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
RARP - Get my IP address and load information
|
||||
**************************************************************************/
|
||||
int
|
||||
rarp (void)
|
||||
{
|
||||
int retry;
|
||||
|
||||
/* arp and rarp requests share the same packet structure. */
|
||||
struct arprequest rarpreq;
|
||||
|
||||
memset (&rarpreq, 0, sizeof (rarpreq));
|
||||
|
||||
rarpreq.hwtype = htons (1);
|
||||
rarpreq.protocol = htons (IP);
|
||||
rarpreq.hwlen = ETHER_ADDR_SIZE;
|
||||
rarpreq.protolen = 4;
|
||||
rarpreq.opcode = htons (RARP_REQUEST);
|
||||
grub_memmove ((char *) &rarpreq.shwaddr, arptable[ARP_CLIENT].node,
|
||||
ETHER_ADDR_SIZE);
|
||||
/* sipaddr is already zeroed out */
|
||||
grub_memmove ((char *) &rarpreq.thwaddr, arptable[ARP_CLIENT].node,
|
||||
ETHER_ADDR_SIZE);
|
||||
/* tipaddr is already zeroed out */
|
||||
|
||||
for (retry = 0; retry < MAX_ARP_RETRIES; rfc951_sleep (++retry))
|
||||
{
|
||||
eth_transmit (broadcast, RARP, sizeof (rarpreq), (char *) &rarpreq);
|
||||
|
||||
if (await_reply (AWAIT_RARP, 0, rarpreq.shwaddr, 0))
|
||||
break;
|
||||
|
||||
if (ip_abort)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (retry < MAX_ARP_RETRIES)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
BOOTP - Get my IP address and load information
|
||||
**************************************************************************/
|
||||
int
|
||||
bootp (void)
|
||||
{
|
||||
int retry;
|
||||
#ifndef NO_DHCP_SUPPORT
|
||||
int retry1;
|
||||
#endif /* ! NO_DHCP_SUPPORT */
|
||||
struct bootp_t bp;
|
||||
unsigned long starttime;
|
||||
#ifdef T509HACK
|
||||
int flag;
|
||||
|
||||
flag = 1;
|
||||
#endif
|
||||
grub_memset (&bp, 0, sizeof (struct bootp_t));
|
||||
bp.bp_op = BOOTP_REQUEST;
|
||||
bp.bp_htype = 1;
|
||||
bp.bp_hlen = ETHER_ADDR_SIZE;
|
||||
bp.bp_xid = xid = starttime = currticks ();
|
||||
grub_memmove (bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
|
||||
#ifdef NO_DHCP_SUPPORT
|
||||
/* Request RFC-style options. */
|
||||
grub_memmove (bp.bp_vend, rfc1533_cookie, 5);
|
||||
#else
|
||||
/* Request RFC-style options. */
|
||||
grub_memmove (bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
|
||||
grub_memmove (bp.bp_vend + sizeof rfc1533_cookie, dhcpdiscover,
|
||||
sizeof dhcpdiscover);
|
||||
grub_memmove (bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcpdiscover,
|
||||
rfc1533_end, sizeof rfc1533_end);
|
||||
#endif /* ! NO_DHCP_SUPPORT */
|
||||
|
||||
for (retry = 0; retry < MAX_BOOTP_RETRIES;)
|
||||
{
|
||||
/*
|
||||
* Discard all received packets - we have no requests
|
||||
* outstanding. It happened too often that the reply sent
|
||||
* by the BOOTP server caused a RX buffer overrun (which for
|
||||
* most cards - especially the cheap ones with a small
|
||||
* receive buffer - is handled by discarding the whole
|
||||
* receive buffer contents). An even cruder way to solve
|
||||
* the problem would be to discard all packets while in
|
||||
* rfc951_sleep(), but this may have affected future changes
|
||||
* to the etherboot implementation.
|
||||
*/
|
||||
while (eth_poll ())
|
||||
/* Nothing */
|
||||
;
|
||||
|
||||
udp_transmit (IP_BROADCAST, 0, BOOTP_SERVER,
|
||||
sizeof (struct bootp_t), (char *) &bp);
|
||||
#ifdef T509HACK
|
||||
if (flag)
|
||||
{
|
||||
flag--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await_reply (AWAIT_BOOTP, 0, NULL, 0))
|
||||
return 1;
|
||||
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
|
||||
rfc951_sleep (++retry);
|
||||
}
|
||||
#else /* ! T509HACK */
|
||||
|
||||
# ifdef NO_DHCP_SUPPORT
|
||||
if (await_reply (AWAIT_BOOTP, 0, NULL, 0))
|
||||
# else
|
||||
if (await_reply (AWAIT_BOOTP, 0, NULL, 0))
|
||||
{
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
|
||||
if (dhcp_reply == DHCPOFFER)
|
||||
{
|
||||
dhcp_reply = 0;
|
||||
grub_memmove (bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
|
||||
grub_memmove (bp.bp_vend + sizeof rfc1533_cookie,
|
||||
dhcprequest, sizeof dhcprequest);
|
||||
grub_memmove (bp.bp_vend + sizeof rfc1533_cookie
|
||||
+ sizeof dhcprequest,
|
||||
rfc1533_end, sizeof rfc1533_end);
|
||||
grub_memmove (bp.bp_vend + 9, &dhcp_server, sizeof (in_addr));
|
||||
grub_memmove (bp.bp_vend + 15, &dhcp_addr, sizeof (in_addr));
|
||||
for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;)
|
||||
{
|
||||
udp_transmit (IP_BROADCAST, 0, BOOTP_SERVER,
|
||||
sizeof (struct bootp_t), (char *) &bp);
|
||||
dhcp_reply = 0;
|
||||
if (await_reply (AWAIT_BOOTP, 0, NULL, 0))
|
||||
if (dhcp_reply == DHCPACK)
|
||||
return 1;
|
||||
|
||||
if (ip_abort)
|
||||
return 0;
|
||||
|
||||
rfc951_sleep (++retry1);
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif /* ! NO_DHCP_SUPPORT */
|
||||
return 1;
|
||||
# ifndef NO_DHCP_SUPPORT
|
||||
}
|
||||
rfc951_sleep (++retry);
|
||||
|
||||
# endif /* ! NO_DHCP_SUPPORT */
|
||||
#endif /* ! T509HACK */
|
||||
|
||||
bp.bp_secs = htons ((currticks () - starttime) / 20);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
AWAIT_REPLY - Wait until we get a response for our request
|
||||
**************************************************************************/
|
||||
int
|
||||
await_reply (int type, int ival, char *ptr, int timeout)
|
||||
{
|
||||
unsigned long time;
|
||||
struct iphdr *ip;
|
||||
struct udphdr *udp;
|
||||
struct arprequest *arpreply;
|
||||
struct bootp_t *bootpreply;
|
||||
struct rpc_t *rpc;
|
||||
unsigned short ptype;
|
||||
int protohdrlen = (ETHER_HDR_SIZE + sizeof (struct iphdr)
|
||||
+ sizeof (struct udphdr));
|
||||
|
||||
ip_abort = 0;
|
||||
|
||||
#ifdef CONGESTED
|
||||
time = currticks () + (timeout ? timeout : TIMEOUT);
|
||||
#else
|
||||
time = currticks () + TIMEOUT;
|
||||
#endif
|
||||
while (time > currticks ())
|
||||
{
|
||||
if (checkkey () != -1 && getkey () == ESC)
|
||||
{
|
||||
ip_abort = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eth_poll ())
|
||||
{
|
||||
/* We have something! */
|
||||
|
||||
/* Check for ARP - No IP hdr. */
|
||||
if (nic.packetlen >= ETHER_HDR_SIZE)
|
||||
{
|
||||
ptype = (((unsigned short) nic.packet[12]) << 8
|
||||
| ((unsigned short) nic.packet[13]));
|
||||
}
|
||||
else
|
||||
/* What else could we do with it? */
|
||||
continue;
|
||||
|
||||
if (nic.packetlen >= ETHER_HDR_SIZE + sizeof (struct arprequest)
|
||||
&& ptype == ARP)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
arpreply = (struct arprequest *) &nic.packet[ETHER_HDR_SIZE];
|
||||
|
||||
if (arpreply->opcode == ntohs (ARP_REPLY)
|
||||
&& ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr))
|
||||
&& type == AWAIT_ARP)
|
||||
{
|
||||
grub_memmove ((char *) arptable[ival].node,
|
||||
arpreply->shwaddr,
|
||||
ETHER_ADDR_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
grub_memmove ((char *) &tmp, arpreply->tipaddr,
|
||||
sizeof (in_addr));
|
||||
|
||||
if (arpreply->opcode == ntohs (ARP_REQUEST)
|
||||
&& tmp == arptable[ARP_CLIENT].ipaddr.s_addr)
|
||||
{
|
||||
arpreply->opcode = htons (ARP_REPLY);
|
||||
grub_memmove (arpreply->tipaddr, arpreply->sipaddr,
|
||||
sizeof (in_addr));
|
||||
grub_memmove (arpreply->thwaddr, (char *) arpreply->shwaddr,
|
||||
ETHER_ADDR_SIZE);
|
||||
grub_memmove (arpreply->sipaddr,
|
||||
(char *) &arptable[ARP_CLIENT].ipaddr,
|
||||
sizeof (in_addr));
|
||||
grub_memmove (arpreply->shwaddr,
|
||||
arptable[ARP_CLIENT].node,
|
||||
ETHER_ADDR_SIZE);
|
||||
eth_transmit (arpreply->thwaddr, ARP,
|
||||
sizeof (struct arprequest),
|
||||
(char *) arpreply);
|
||||
#ifdef MDEBUG
|
||||
grub_memmove (&tmp, arpreply->tipaddr, sizeof (in_addr));
|
||||
grub_printf ("Sent ARP reply to: %x\n", tmp);
|
||||
#endif /* MDEBUG */
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for RARP - No IP hdr. */
|
||||
if (type == AWAIT_RARP
|
||||
&& nic.packetlen >= ETHER_HDR_SIZE + sizeof (struct arprequest)
|
||||
&& ptype == RARP)
|
||||
{
|
||||
arpreply = (struct arprequest *) &nic.packet[ETHER_HDR_SIZE];
|
||||
|
||||
if (arpreply->opcode == ntohs (RARP_REPLY)
|
||||
&& ! grub_memcmp (arpreply->thwaddr, ptr, ETHER_ADDR_SIZE))
|
||||
{
|
||||
grub_memmove ((char *) arptable[ARP_SERVER].node,
|
||||
arpreply->shwaddr, ETHER_ADDR_SIZE);
|
||||
grub_memmove ((char *) &arptable[ARP_SERVER].ipaddr,
|
||||
arpreply->sipaddr, sizeof (in_addr));
|
||||
grub_memmove ((char *) &arptable[ARP_CLIENT].ipaddr,
|
||||
arpreply->tipaddr, sizeof (in_addr));
|
||||
return 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Anything else has IP header. */
|
||||
if (nic.packetlen < protohdrlen || ptype != IP)
|
||||
continue;
|
||||
|
||||
ip = (struct iphdr *) &nic.packet[ETHER_HDR_SIZE];
|
||||
if (ip->verhdrlen != 0x45
|
||||
|| ipchksum ((unsigned short *) ip, sizeof (struct iphdr))
|
||||
|| ip->protocol != IP_UDP)
|
||||
continue;
|
||||
|
||||
udp = (struct udphdr *)
|
||||
&nic.packet[ETHER_HDR_SIZE + sizeof (struct iphdr)];
|
||||
|
||||
/* BOOTP ? */
|
||||
bootpreply = (struct bootp_t *) &nic.packet[ETHER_HDR_SIZE];
|
||||
if (type == AWAIT_BOOTP
|
||||
#ifdef NO_DHCP_SUPPORT
|
||||
&& (nic.packetlen
|
||||
>= (ETHER_HDR_SIZE + sizeof (struct bootp_t)))
|
||||
#else
|
||||
&& (nic.packetlen
|
||||
>= (ETHER_HDR_SIZE + sizeof (struct bootp_t)) - DHCP_OPT_LEN)
|
||||
#endif /* ! NO_DHCP_SUPPORT */
|
||||
&& ntohs (udp->dest) == BOOTP_CLIENT
|
||||
&& bootpreply->bp_op == BOOTP_REPLY
|
||||
&& bootpreply->bp_xid == xid)
|
||||
{
|
||||
arptable[ARP_CLIENT].ipaddr.s_addr
|
||||
= bootpreply->bp_yiaddr.s_addr;
|
||||
#ifndef NO_DHCP_SUPPORT
|
||||
dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
|
||||
#endif /* ! NO_DHCP_SUPPORT */
|
||||
netmask = default_netmask ();
|
||||
arptable[ARP_SERVER].ipaddr.s_addr
|
||||
= bootpreply->bp_siaddr.s_addr;
|
||||
/* Kill arp. */
|
||||
grub_memset (arptable[ARP_SERVER].node, 0, ETHER_ADDR_SIZE);
|
||||
arptable[ARP_GATEWAY].ipaddr.s_addr
|
||||
= bootpreply->bp_giaddr.s_addr;
|
||||
/* Kill arp. */
|
||||
grub_memset (arptable[ARP_GATEWAY].node, 0, ETHER_ADDR_SIZE);
|
||||
|
||||
/* GRUB doesn't autoload any kernel image. */
|
||||
#if 0
|
||||
if (bootpreply->bp_file[0])
|
||||
{
|
||||
grub_memmove (kernel_buf, bootpreply->bp_file, 128);
|
||||
kernel = kernel_buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
grub_memmove ((char *) BOOTP_DATA_ADDR, (char *) bootpreply,
|
||||
sizeof (struct bootpd_t));
|
||||
#ifdef NO_DHCP_SUPPORT
|
||||
decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,
|
||||
0, BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 1);
|
||||
#else
|
||||
decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,
|
||||
0, DHCP_OPT_LEN, 1);
|
||||
#endif /* ! NO_DHCP_SUPPORT */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TFTP ? */
|
||||
if (type == AWAIT_TFTP && ntohs (udp->dest) == ival)
|
||||
return 1;
|
||||
|
||||
/* RPC */
|
||||
rpc = (struct rpc_t *) &nic.packet[ETHER_HDR_SIZE];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DECODE_RFC1533 - Decodes RFC1533 header
|
||||
**************************************************************************/
|
||||
int
|
||||
decode_rfc1533 (unsigned char *p, int block, int len, int eof)
|
||||
{
|
||||
static unsigned char *extdata = NULL, *extend = NULL;
|
||||
unsigned char *extpath = NULL;
|
||||
unsigned char *end;
|
||||
|
||||
if (block == 0)
|
||||
{
|
||||
#ifdef IMAGE_MENU
|
||||
memset (imagelist, 0, sizeof (imagelist));
|
||||
menudefault = useimagemenu = 0;
|
||||
menutmo = -1;
|
||||
#endif
|
||||
#ifdef MOTD
|
||||
memset (motd, 0, sizeof (motd));
|
||||
#endif
|
||||
|
||||
end_of_rfc1533 = NULL;
|
||||
vendorext_isvalid = 0;
|
||||
|
||||
if (grub_memcmp (p, rfc1533_cookie, 4))
|
||||
/* no RFC 1533 header found */
|
||||
return 0;
|
||||
|
||||
p += 4;
|
||||
end = p + len;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (block == 1)
|
||||
{
|
||||
if (grub_memcmp (p, rfc1533_cookie, 4))
|
||||
/* no RFC 1533 header found */
|
||||
return 0;
|
||||
|
||||
p += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
if (extend + len
|
||||
<= ((unsigned char *)
|
||||
&(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])))
|
||||
{
|
||||
grub_memmove (extend, p, len);
|
||||
extend += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf ("Overflow in vendor data buffer! Aborting...\n");
|
||||
*extdata = RFC1533_END;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = extdata;
|
||||
end = extend;
|
||||
}
|
||||
|
||||
if (eof)
|
||||
{
|
||||
while (p < end)
|
||||
{
|
||||
unsigned char c = *p;
|
||||
|
||||
if (c == RFC1533_PAD)
|
||||
{
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
else if (c == RFC1533_END)
|
||||
{
|
||||
end_of_rfc1533 = end = p;
|
||||
continue;
|
||||
}
|
||||
else if (c == RFC1533_NETMASK)
|
||||
{
|
||||
grub_memmove ((char *) &netmask, p + 2, sizeof (in_addr));
|
||||
}
|
||||
else if (c == RFC1533_GATEWAY)
|
||||
{
|
||||
/* This is a little simplistic, but it will
|
||||
usually be sufficient.
|
||||
Take only the first entry. */
|
||||
if (TAG_LEN (p) >= sizeof (in_addr))
|
||||
grub_memmove ((char *) &arptable[ARP_GATEWAY].ipaddr, p + 2,
|
||||
sizeof (in_addr));
|
||||
}
|
||||
else if (c == RFC1533_EXTENSIONPATH)
|
||||
extpath = p;
|
||||
#ifndef NO_DHCP_SUPPORT
|
||||
else if (c == RFC2132_MSG_TYPE)
|
||||
{
|
||||
dhcp_reply = *(p + 2);
|
||||
}
|
||||
else if (c == RFC2132_SRV_ID)
|
||||
{
|
||||
grub_memmove (&dhcp_server, p + 2, sizeof (in_addr));
|
||||
}
|
||||
#endif /* ! NO_DHCP_SUPPORT */
|
||||
|
||||
/* GRUB needs not to use any vendor-specific extension. */
|
||||
#if 0
|
||||
else if (c == RFC1533_VENDOR_MAGIC
|
||||
# if !defined(AOUT_IMAGE) && !defined(ELF_IMAGE) /* since FreeBSD uses tag 128 for swap definition */
|
||||
&& TAG_LEN (p) >= 6 &&
|
||||
!memcmp (p + 2, vendorext_magic, 4) &&
|
||||
p[6] == RFC1533_VENDOR_MAJOR
|
||||
# endif
|
||||
)
|
||||
vendorext_isvalid++;
|
||||
# if defined(AOUT_IMAGE) || defined(ELF_IMAGE)
|
||||
else if (c == RFC1533_VENDOR_HOWTO)
|
||||
{
|
||||
howto = ((p[2] * 256 + p[3]) * 256 + p[4]) * 256 + p[5];
|
||||
/*
|
||||
printf("Howto %X %d,%x %x %x %x\n",howto,TAGLEN(p),p[2],p[3],p[4],p[5]);
|
||||
*/
|
||||
}
|
||||
# endif
|
||||
# ifdef IMAGE_MENU
|
||||
else if (c == RFC1533_VENDOR_MNUOPTS)
|
||||
{
|
||||
parse_menuopts (p + 2, TAG_LEN (p));
|
||||
}
|
||||
else if (c >= RFC1533_VENDOR_IMG &&
|
||||
c < RFC1533_VENDOR_IMG + RFC1533_VENDOR_NUMOFIMG)
|
||||
{
|
||||
imagelist[c - RFC1533_VENDOR_IMG] = p;
|
||||
useimagemenu++;
|
||||
}
|
||||
# endif
|
||||
# ifdef MOTD
|
||||
else if (c >= RFC1533_VENDOR_MOTD &&
|
||||
c < RFC1533_VENDOR_MOTD +
|
||||
RFC1533_VENDOR_NUMOFMOTD)
|
||||
motd[c - RFC1533_VENDOR_MOTD] = p;
|
||||
# endif
|
||||
else
|
||||
{
|
||||
/* printf("Unknown RFC1533-tag ");
|
||||
for(q=p;q<p+2+TAG_LEN(p);q++)
|
||||
printf("%x ",*q);
|
||||
putchar('\n'); */
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
p += TAG_LEN (p) + 2;
|
||||
}
|
||||
|
||||
extdata = extend = end;
|
||||
|
||||
if (block == 0 && extpath != NULL)
|
||||
{
|
||||
char fname[64];
|
||||
grub_memmove (fname, extpath + 2, TAG_LEN (extpath));
|
||||
fname[(int) TAG_LEN (extpath)] = '\000';
|
||||
grub_printf ("Loading BOOTP-extension file: %s\n", fname);
|
||||
tftp (fname, decode_rfc1533);
|
||||
}
|
||||
}
|
||||
|
||||
/* Proceed with next block. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
IPCHKSUM - Checksum IP Header
|
||||
**************************************************************************/
|
||||
unsigned short
|
||||
ipchksum (unsigned short *ip, int len)
|
||||
{
|
||||
unsigned long sum = 0;
|
||||
len >>= 1;
|
||||
while (len--)
|
||||
{
|
||||
sum += *(ip++);
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
}
|
||||
return (~sum) & 0x0000FFFF;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
RFC951_SLEEP - sleep for expotentially longer times
|
||||
**************************************************************************/
|
||||
void
|
||||
rfc951_sleep (int exp)
|
||||
{
|
||||
static long seed = 0;
|
||||
long q, tmo;
|
||||
|
||||
if (! seed)
|
||||
/* Initialize linear congruential generator. */
|
||||
seed = (currticks () + *(long *) &arptable[ARP_CLIENT].node
|
||||
+ ((short *) arptable[ARP_CLIENT].node)[2]);
|
||||
|
||||
/* Simplified version of the LCG given in Bruce Scheier's
|
||||
"Applied Cryptography". */
|
||||
q = seed / 53668;
|
||||
if ((seed = 40014 * (seed - 53668 * q) - 12211 * q) < 0)
|
||||
seed += 2147483563l;
|
||||
|
||||
/* Compute mask. */
|
||||
for (tmo = 63; tmo <= 60 * TICKS_PER_SEC && --exp > 0; tmo = 2 * tmo + 1)
|
||||
;
|
||||
|
||||
/* Sleep. */
|
||||
grub_printf ("<sleep>\n");
|
||||
|
||||
for (tmo = (tmo & seed) + currticks (); currticks () < tmo;)
|
||||
;
|
||||
}
|
328
netboot/misc.c
Normal file
328
netboot/misc.c
Normal file
|
@ -0,0 +1,328 @@
|
|||
/**************************************************************************
|
||||
MISC Support Routines
|
||||
**************************************************************************/
|
||||
|
||||
#include "etherboot.h"
|
||||
|
||||
/**************************************************************************
|
||||
SLEEP
|
||||
**************************************************************************/
|
||||
void sleep(int secs)
|
||||
{
|
||||
long tmo;
|
||||
|
||||
for (tmo = currticks()+secs*TICKS_PER_SEC; currticks() < tmo; )
|
||||
/* Nothing */;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
TWIDDLE
|
||||
**************************************************************************/
|
||||
void twiddle()
|
||||
{
|
||||
static unsigned long lastticks = 0;
|
||||
static int count=0;
|
||||
static char tiddles[]="-\\|/";
|
||||
unsigned long ticks;
|
||||
if ((ticks = currticks()) < lastticks)
|
||||
return;
|
||||
lastticks = ticks+1;
|
||||
putchar(tiddles[(count++)&3]);
|
||||
putchar('\b');
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef ETHERBOOT32
|
||||
/**************************************************************************
|
||||
STRCASECMP (not entirely correct, but this will do for our purposes)
|
||||
**************************************************************************/
|
||||
int strcasecmp(a,b)
|
||||
char *a, *b;
|
||||
{
|
||||
while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; }
|
||||
return((*a & ~0x20) - (*b & ~0x20));
|
||||
}
|
||||
#endif /* ETHERBOOT32 */
|
||||
|
||||
/**************************************************************************
|
||||
PRINTF and friends
|
||||
|
||||
Formats:
|
||||
%X - 4 byte ASCII (8 hex digits)
|
||||
%x - 2 byte ASCII (4 hex digits)
|
||||
%b - 1 byte ASCII (2 hex digits)
|
||||
%d - decimal (also %i)
|
||||
%c - ASCII char
|
||||
%s - ASCII string
|
||||
%I - Internet address in x.x.x.x notation
|
||||
**************************************************************************/
|
||||
static char hex[]="0123456789ABCDEF";
|
||||
char *do_printf(buf, fmt, dp)
|
||||
char *buf, *fmt;
|
||||
int *dp;
|
||||
{
|
||||
register char *p;
|
||||
char tmp[16];
|
||||
while (*fmt) {
|
||||
if (*fmt == '%') { /* switch() uses more space */
|
||||
fmt++;
|
||||
|
||||
if (*fmt == 'X') {
|
||||
long *lp = (long *)dp;
|
||||
register long h = *lp++;
|
||||
dp = (int *)lp;
|
||||
*(buf++) = hex[(h>>28)& 0x0F];
|
||||
*(buf++) = hex[(h>>24)& 0x0F];
|
||||
*(buf++) = hex[(h>>20)& 0x0F];
|
||||
*(buf++) = hex[(h>>16)& 0x0F];
|
||||
*(buf++) = hex[(h>>12)& 0x0F];
|
||||
*(buf++) = hex[(h>>8)& 0x0F];
|
||||
*(buf++) = hex[(h>>4)& 0x0F];
|
||||
*(buf++) = hex[h& 0x0F];
|
||||
}
|
||||
if (*fmt == 'x') {
|
||||
register int h = *(dp++);
|
||||
*(buf++) = hex[(h>>12)& 0x0F];
|
||||
*(buf++) = hex[(h>>8)& 0x0F];
|
||||
*(buf++) = hex[(h>>4)& 0x0F];
|
||||
*(buf++) = hex[h& 0x0F];
|
||||
}
|
||||
if (*fmt == 'b') {
|
||||
register int h = *(dp++);
|
||||
*(buf++) = hex[(h>>4)& 0x0F];
|
||||
*(buf++) = hex[h& 0x0F];
|
||||
}
|
||||
if ((*fmt == 'd') || (*fmt == 'i')) {
|
||||
register int dec = *(dp++);
|
||||
p = tmp;
|
||||
if (dec < 0) {
|
||||
*(buf++) = '-';
|
||||
dec = -dec;
|
||||
}
|
||||
do {
|
||||
*(p++) = '0' + (dec%10);
|
||||
dec = dec/10;
|
||||
} while(dec);
|
||||
while ((--p) >= tmp) *(buf++) = *p;
|
||||
}
|
||||
if (*fmt == 'I') {
|
||||
union {
|
||||
long l;
|
||||
unsigned char c[4];
|
||||
} u;
|
||||
long *lp = (long *)dp;
|
||||
u.l = *lp++;
|
||||
dp = (int *)lp;
|
||||
buf = sprintf(buf,"%d.%d.%d.%d",
|
||||
u.c[0], u.c[1], u.c[2], u.c[3]);
|
||||
}
|
||||
if (*fmt == 'c')
|
||||
*(buf++) = *(dp++);
|
||||
if (*fmt == 's') {
|
||||
p = (char *)*dp++;
|
||||
while (*p) *(buf++) = *p++;
|
||||
}
|
||||
} else *(buf++) = *fmt;
|
||||
fmt++;
|
||||
}
|
||||
*buf = 0;
|
||||
return(buf);
|
||||
}
|
||||
|
||||
char *sprintf(buf, fmt, data)
|
||||
char *fmt, *buf;
|
||||
int data;
|
||||
{
|
||||
return(do_printf(buf,fmt, &data));
|
||||
}
|
||||
|
||||
void printf(fmt,data)
|
||||
char *fmt;
|
||||
int data;
|
||||
{
|
||||
char buf[120],*p;
|
||||
p = buf;
|
||||
do_printf(buf,fmt,&data);
|
||||
while (*p) putchar(*p++);
|
||||
}
|
||||
|
||||
#ifdef IMAGE_MENU
|
||||
/**************************************************************************
|
||||
INET_NTOA - Convert an ascii x.x.x.x to binary form
|
||||
**************************************************************************/
|
||||
int inet_ntoa(p, i)
|
||||
char *p;
|
||||
in_addr *i;
|
||||
{
|
||||
unsigned long ip = 0;
|
||||
int val;
|
||||
if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
|
||||
if (*p != '.') return(0);
|
||||
p++;
|
||||
ip = val;
|
||||
if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
|
||||
if (*p != '.') return(0);
|
||||
p++;
|
||||
ip = (ip << 8) | val;
|
||||
if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
|
||||
if (*p != '.') return(0);
|
||||
p++;
|
||||
ip = (ip << 8) | val;
|
||||
if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
|
||||
i->s_addr = htonl((ip << 8) | val);
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* IMAGE_MENU */
|
||||
#endif /* 0 */
|
||||
|
||||
int getdec(ptr)
|
||||
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);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
|
||||
#define K_STATUS 0x64 /* keyboard status */
|
||||
#define K_CMD 0x64 /* keybd ctlr command (write-only) */
|
||||
|
||||
#define K_OBUF_FUL 0x01 /* output buffer full */
|
||||
#define K_IBUF_FUL 0x02 /* input buffer full */
|
||||
|
||||
#define KC_CMD_WIN 0xd0 /* read output port */
|
||||
#define KC_CMD_WOUT 0xd1 /* write output port */
|
||||
#define KB_A20 0xdf /* enable A20,
|
||||
enable output buffer full interrupt
|
||||
enable data line
|
||||
disable clock line */
|
||||
#ifndef IBM_L40
|
||||
|
||||
static void empty_8042(void)
|
||||
{
|
||||
extern void slowdownio();
|
||||
unsigned long time;
|
||||
char st;
|
||||
|
||||
slowdownio();
|
||||
time = currticks() + TICKS_PER_SEC; /* max wait of 1 second */
|
||||
while ((((st = inb(K_CMD)) & K_OBUF_FUL) ||
|
||||
(st & K_IBUF_FUL)) &&
|
||||
currticks() < time)
|
||||
inb(K_RDWR);
|
||||
}
|
||||
#endif IBM_L40
|
||||
|
||||
/*
|
||||
* Gate A20 for high memory
|
||||
*/
|
||||
void gateA20()
|
||||
{
|
||||
#ifdef IBM_L40
|
||||
outb(0x2, 0x92);
|
||||
#else IBM_L40
|
||||
empty_8042();
|
||||
outb(KC_CMD_WOUT, K_CMD);
|
||||
empty_8042();
|
||||
outb(KB_A20, K_RDWR);
|
||||
empty_8042();
|
||||
#endif IBM_L40
|
||||
}
|
||||
|
||||
#ifdef ETHERBOOT32
|
||||
/* Serial console is only implemented in ETHERBOOT32 for now */
|
||||
void
|
||||
putchar(int c)
|
||||
{
|
||||
#ifdef ANSIESC
|
||||
handleansi(c);
|
||||
return;
|
||||
#endif
|
||||
if (c == '\n')
|
||||
putchar('\r');
|
||||
#ifdef SERIAL_CONSOLE
|
||||
#if SERIAL_CONSOLE == DUAL
|
||||
putc(c);
|
||||
#endif /* SERIAL_CONSOLE == DUAL */
|
||||
serial_putc(c);
|
||||
#else
|
||||
putc(c);
|
||||
#endif /* SERIAL_CONSOLE */
|
||||
}
|
||||
|
||||
int
|
||||
getchar(int in_buf)
|
||||
{
|
||||
int c=256;
|
||||
|
||||
loop:
|
||||
#ifdef SERIAL_CONSOLE
|
||||
#if SERIAL_CONSOLE == DUAL
|
||||
if (ischar())
|
||||
c = getc();
|
||||
#endif
|
||||
if (serial_ischar())
|
||||
c = serial_getc();
|
||||
#else
|
||||
if (ischar())
|
||||
c = getc();
|
||||
#endif
|
||||
|
||||
if (c==256){
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
if (c == '\b') {
|
||||
if (in_buf != 0) {
|
||||
putchar('\b');
|
||||
putchar(' ');
|
||||
} else {
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
putchar(c);
|
||||
return(c);
|
||||
}
|
||||
|
||||
int
|
||||
iskey(void)
|
||||
{
|
||||
int isc;
|
||||
|
||||
/*
|
||||
* Checking the keyboard has the side effect of enabling clock
|
||||
* interrupts so that bios_tick works. Check the keyboard to
|
||||
* get this side effect even if we only want the serial status.
|
||||
*/
|
||||
|
||||
#ifdef SERIAL_CONSOLE
|
||||
#if SERIAL_CONSOLE == DUAL
|
||||
if (ischar())
|
||||
return 1;
|
||||
#endif
|
||||
if (serial_ischar())
|
||||
return 1;
|
||||
#else
|
||||
if (ischar())
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif /* ETHERBOOT32 */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
712
netboot/ns8390.c
712
netboot/ns8390.c
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/**************************************************************************
|
||||
NETBOOT - BOOTP/TFTP Bootstrap Program
|
||||
ETHERBOOT - BOOTP/TFTP Bootstrap Program
|
||||
|
||||
Author: Martin Renters
|
||||
Date: Jun/94
|
||||
|
@ -63,31 +63,6 @@ Western Digital/SMC Board Types
|
|||
#define TYPE_SMC8416C 0x00 /* the same codes as the 8216. */
|
||||
#define TYPE_SMC8013EBP 0x2c
|
||||
|
||||
#ifdef INCLUDE_WD
|
||||
struct wd_board {
|
||||
char *name;
|
||||
char id;
|
||||
char flags;
|
||||
char memsize;
|
||||
} wd_boards[] = {
|
||||
{"WD8003S", TYPE_WD8003S, 0, MEM_8192},
|
||||
{"WD8003E", TYPE_WD8003E, 0, MEM_8192},
|
||||
{"WD8013EBT", TYPE_WD8013EBT, FLAG_16BIT, MEM_16384},
|
||||
{"WD8003W", TYPE_WD8003W, 0, MEM_8192},
|
||||
{"WD8003EB", TYPE_WD8003EB, 0, MEM_8192},
|
||||
{"WD8013W", TYPE_WD8013W, FLAG_16BIT, MEM_16384},
|
||||
{"WD8003EP/WD8013EP",
|
||||
TYPE_WD8013EP, 0, MEM_8192},
|
||||
{"WD8013WC", TYPE_WD8013WC, FLAG_16BIT, MEM_16384},
|
||||
{"WD8013EPC", TYPE_WD8013EPC, FLAG_16BIT, MEM_16384},
|
||||
{"SMC8216T", TYPE_SMC8216T, FLAG_16BIT | FLAG_790, MEM_16384},
|
||||
{"SMC8216C", TYPE_SMC8216C, FLAG_16BIT | FLAG_790, MEM_16384},
|
||||
{"SMC8416T", TYPE_SMC8416T, FLAG_16BIT | FLAG_790, MEM_8192},
|
||||
{"SMC8416C/BT", TYPE_SMC8416C, FLAG_16BIT | FLAG_790, MEM_8192},
|
||||
{"SMC8013EBP", TYPE_SMC8013EBP,FLAG_16BIT, MEM_16384},
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
#endif
|
||||
/**************************************************************************
|
||||
3com 3c503 definitions
|
||||
**************************************************************************/
|
||||
|
@ -116,6 +91,7 @@ struct wd_board {
|
|||
#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
|
||||
|
@ -173,6 +149,8 @@ NE1000/2000 definitions
|
|||
#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
|
||||
**************************************************************************/
|
||||
|
@ -232,7 +210,7 @@ NE1000/2000 definitions
|
|||
#define D8390_RSTAT_PRX 0x01 /* successful recv */
|
||||
#define D8390_RSTAT_CRC 0x02 /* CRC error */
|
||||
#define D8390_RSTAT_FAE 0x04 /* Frame alignment error */
|
||||
#define D8390_RSTAT_OVER 0x08 /* overflow */
|
||||
#define D8390_RSTAT_OVER 0x08 /* FIFO overrun */
|
||||
|
||||
#define D8390_TXBUF_SIZE 6
|
||||
#define D8390_RXBUF_END 32
|
||||
|
|
69
netboot/osdep.h
Normal file
69
netboot/osdep.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef __OSDEP_H__
|
||||
#define __OSDEP_H__
|
||||
|
||||
#if 1
|
||||
# define ETHERBOOT32
|
||||
# include <byteorder.h>
|
||||
# if 0
|
||||
# include <linux-asm-string.h>
|
||||
# endif
|
||||
# include <linux-asm-io.h>
|
||||
#else
|
||||
#ifdef __linux__
|
||||
#define ETHERBOOT32
|
||||
#include <asm/byteorder.h>
|
||||
#include "linux-asm-string.h"
|
||||
#include "linux-asm-io.h"
|
||||
#define _edata edata /* ELF does not prepend a _ */
|
||||
#define _end end
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define ETHERBOOT32
|
||||
#include <sys/types.h>
|
||||
#include "linux-asm-string.h"
|
||||
#include "linux-asm-io.h"
|
||||
#define _edata edata /* ELF does not prepend a _ */
|
||||
#define _end end
|
||||
#endif
|
||||
|
||||
#ifdef __BCC__
|
||||
#define ETHERBOOT16
|
||||
#define inline
|
||||
#define const
|
||||
#define volatile
|
||||
#define setjmp _setjmp /* they are that way in libc.a */
|
||||
#define longjmp _longjmp
|
||||
|
||||
/* BCC include files are missing these. */
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned short u_short;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned long u_long;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ETHERBOOT16) && !defined(ETHERBOOT32)
|
||||
Error, neither ETHERBOOT16 nor ETHERBOOT32 defined
|
||||
#endif
|
||||
|
||||
#if defined(ETHERBOOT16) && defined(ETHERBOOT32)
|
||||
Error, both ETHERBOOT16 and ETHERBOOT32 defined
|
||||
#endif
|
||||
|
||||
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:
|
||||
*/
|
256
netboot/pci.c
256
netboot/pci.c
|
@ -14,13 +14,72 @@
|
|||
** a multi-pcibus machine will have something better than an ne2000)
|
||||
*/
|
||||
|
||||
#include "netboot.h"
|
||||
#include "etherboot.h"
|
||||
#include "pci.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
/*#define DEBUG 1*/
|
||||
static unsigned int pci_ioaddr = 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 char bus, unsigned char device_fn,
|
||||
unsigned char 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 char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned short *value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
*value = inw(0xCFC + (where&2));
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
|
||||
unsigned char where, unsigned int *value)
|
||||
{
|
||||
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
|
||||
*value = inl(0xCFC);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
|
||||
unsigned char 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 char bus, unsigned char device_fn,
|
||||
unsigned char 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 char bus, unsigned char device_fn, unsigned char 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 unsigned long bios32_entry = 0;
|
||||
static struct {
|
||||
unsigned long address;
|
||||
|
@ -56,16 +115,16 @@ static unsigned long bios32_service(unsigned long service)
|
|||
case 0:
|
||||
return address + entry;
|
||||
case 0x80: /* Not present */
|
||||
printf("bios32_service(%d) : not present\r\n", service);
|
||||
printf("bios32_service(%d) : not present\n", service);
|
||||
return 0;
|
||||
default: /* Shouldn't happen */
|
||||
printf("bios32_service(%d) : returned 0x%x, mail drew@colorado.edu\r\n",
|
||||
printf("bios32_service(%d) : returned 0x%x, mail drew@colorado.edu\n",
|
||||
service, return_code);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int pcibios_read_config_byte(unsigned char bus,
|
||||
int pcibios_read_config_byte(unsigned char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned char *value)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
@ -87,7 +146,29 @@ static int pcibios_read_config_byte(unsigned char bus,
|
|||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
static int pcibios_read_config_dword (unsigned char bus,
|
||||
int pcibios_read_config_word(unsigned char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned short *value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags);
|
||||
__asm__("lcall (%%esi)\n\t"
|
||||
"jc 1f\n\t"
|
||||
"xor %%ah, %%ah\n"
|
||||
"1:"
|
||||
: "=c" (*value),
|
||||
"=a" (ret)
|
||||
: "1" (PCIBIOS_READ_CONFIG_WORD),
|
||||
"b" (bx),
|
||||
"D" ((long) where),
|
||||
"S" (&pci_indirect));
|
||||
restore_flags(flags);
|
||||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
static int pcibios_read_config_dword(unsigned char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned int *value)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
@ -109,6 +190,72 @@ static int pcibios_read_config_dword (unsigned char bus,
|
|||
return (int) (ret & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
int pcibios_write_config_byte (unsigned char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned char value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags); cli();
|
||||
__asm__("lcall (%%esi)\n\t"
|
||||
"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 char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned short value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags); cli();
|
||||
__asm__("lcall (%%esi)\n\t"
|
||||
"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 char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned int value)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long bx = (bus << 8) | device_fn;
|
||||
unsigned long flags;
|
||||
|
||||
save_flags(flags); cli();
|
||||
__asm__("lcall (%%esi)\n\t"
|
||||
"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;
|
||||
|
@ -139,13 +286,13 @@ static void check_pcibios(void)
|
|||
minor_revision = pack & 0xff;
|
||||
if (present_status || (signature != PCI_SIGNATURE)) {
|
||||
printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
|
||||
"BIOS????\r\n");
|
||||
"BIOS????\n");
|
||||
pcibios_entry = 0;
|
||||
}
|
||||
#if DEBUG
|
||||
if (pcibios_entry) {
|
||||
printf ("pcibios_init : PCI BIOS revision %b.%b"
|
||||
" entry at 0x%X\r\n", major_revision,
|
||||
" entry at 0x%X\n", major_revision,
|
||||
minor_revision, pcibios_entry);
|
||||
}
|
||||
#endif
|
||||
|
@ -177,24 +324,24 @@ static void pcibios_init(void)
|
|||
if (sum != 0)
|
||||
continue;
|
||||
if (check->fields.revision != 0) {
|
||||
printf("pcibios_init : unsupported revision %d at 0x%X, mail drew@colorado.edu\r\n",
|
||||
printf("pcibios_init : unsupported revision %d at 0x%X, mail drew@colorado.edu\n",
|
||||
check->fields.revision, check);
|
||||
continue;
|
||||
}
|
||||
#if DEBUG
|
||||
printf("pcibios_init : BIOS32 Service Directory "
|
||||
"structure at 0x%X\r\n", check);
|
||||
"structure at 0x%X\n", check);
|
||||
#endif
|
||||
if (!bios32_entry) {
|
||||
if (check->fields.entry >= 0x100000) {
|
||||
printf("pcibios_init: entry in high "
|
||||
"memory, giving up\r\n");
|
||||
"memory, giving up\n");
|
||||
return;
|
||||
} else {
|
||||
bios32_entry = check->fields.entry;
|
||||
#if DEBUG
|
||||
printf("pcibios_init : BIOS32 Service Directory"
|
||||
" entry at 0x%X\r\n", bios32_entry);
|
||||
" entry at 0x%X\n", bios32_entry);
|
||||
#endif
|
||||
bios32_indirect.address = bios32_entry;
|
||||
}
|
||||
|
@ -203,25 +350,26 @@ static void pcibios_init(void)
|
|||
if (bios32_entry)
|
||||
check_pcibios();
|
||||
}
|
||||
#endif /* CONFIG_PCI_DIRECT not defined*/
|
||||
|
||||
static void scan_bus(struct pci_device *pcidev)
|
||||
{
|
||||
unsigned int devfn, l;
|
||||
unsigned int devfn, l, bus, buses;
|
||||
unsigned char hdr_type = 0;
|
||||
unsigned short vendor, device;
|
||||
int i;
|
||||
unsigned int membase, ioaddr, romaddr;
|
||||
unsigned char class, subclass;
|
||||
int i, reg;
|
||||
|
||||
pci_ioaddr = 0;
|
||||
buses=1;
|
||||
for (bus = 0; bus < buses; ++bus) {
|
||||
for (devfn = 0; devfn < 0xff; ++devfn) {
|
||||
if (PCI_FUNC(devfn) == 0) {
|
||||
pcibios_read_config_byte(0, devfn,
|
||||
PCI_HEADER_TYPE, &hdr_type);
|
||||
} else if (!(hdr_type & 0x80)) {
|
||||
/* not a multi-function device */
|
||||
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(0, devfn,
|
||||
PCI_VENDOR_ID, &l);
|
||||
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;
|
||||
|
@ -229,33 +377,59 @@ static void scan_bus(struct pci_device *pcidev)
|
|||
}
|
||||
vendor = l & 0xffff;
|
||||
device = (l >> 16) & 0xffff;
|
||||
#if DEBUG
|
||||
printf("bus 0, function %x, vendor %x, device %x\r\n",
|
||||
devfn, vendor, device);
|
||||
#endif
|
||||
|
||||
/* check for pci-pci bridge devices!! - more buses when found */
|
||||
pcibios_read_config_byte(bus, devfn, PCI_CLASS_CODE, &class);
|
||||
pcibios_read_config_byte(bus, devfn, PCI_SUBCLASS_CODE, &subclass);
|
||||
if (class == 0x06 && subclass == 0x04)
|
||||
buses++;
|
||||
|
||||
#if DEBUG
|
||||
printf("bus %x, function %x, vendor %x, device %x\n",
|
||||
bus, devfn, vendor, device);
|
||||
#endif
|
||||
for (i = 0; pcidev[i].vendor != 0; i++) {
|
||||
if (vendor == pcidev[i].vendor
|
||||
&& device == pcidev[i].dev_id) {
|
||||
pcibios_read_config_dword(0, devfn,
|
||||
PCI_BASE_ADDRESS_0, &pci_ioaddr);
|
||||
/* Strip the I/O address out of the
|
||||
* returned value */
|
||||
pci_ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
|
||||
printf("Found %s at 0x%x\r\n",
|
||||
pcidev[i].name, pci_ioaddr);
|
||||
if (vendor != pcidev[i].vendor
|
||||
|| device != pcidev[i].dev_id)
|
||||
continue;
|
||||
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 0x%x, ROM address 0x%X\n",
|
||||
pcidev[i].name, ioaddr, romaddr);
|
||||
/* Take the first one or the one that matches in boot ROM address */
|
||||
if (pci_ioaddr == 0 || romaddr == ((long) rom.rom_segment >> 4)) {
|
||||
pcidev[i].membase = membase;
|
||||
pcidev[i].ioaddr = ioaddr;
|
||||
pcidev[i].devfn = devfn;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eth_pci_init(struct pci_device *pcidev, unsigned short *ioaddr)
|
||||
void eth_pci_init(struct pci_device *pcidev)
|
||||
{
|
||||
#ifndef CONFIG_PCI_DIRECT
|
||||
pcibios_init();
|
||||
if (!pcibios_entry) {
|
||||
printf("pci_init: no BIOS32 detected\r\n");
|
||||
printf("pci_init: no BIOS32 detected\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
scan_bus(pcidev);
|
||||
/* we only return one address at the moment, maybe more later? */
|
||||
*ioaddr = pci_ioaddr;
|
||||
/* return values are in pcidev structures */
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
** /usr/src/linux/drivers/net/ne.c
|
||||
*/
|
||||
|
||||
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O 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
|
||||
|
@ -27,11 +31,25 @@
|
|||
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
||||
#define PCI_COMMAND 0x04 /* 16 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)
|
||||
|
||||
|
@ -61,31 +79,71 @@ union bios32 {
|
|||
#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_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_VENDOR_ID_COMPEX 0x11f6
|
||||
#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
|
||||
#define PCI_VENDOR_ID_KTI 0x8e2e
|
||||
#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
|
||||
#define PCI_VENDOR_ID_INTEL 0x8086
|
||||
#define PCI_DEVICE_ID_INTEL_82557 0x1229
|
||||
#define PCI_VENDOR_ID_NETVIN 0x4a14
|
||||
#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
|
||||
#define PCI_VENDOR_ID_VIA 0x1106
|
||||
#define PCI_DEVICE_ID_VIA_82C926 0x0926
|
||||
#define PCI_VENDOR_ID_SURECOM 0x10bd
|
||||
#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34
|
||||
#define PCI_VENDOR_ID_VORTEX 0x1119
|
||||
#define PCI_DEVICE_ID_VORTEX_3c595 0x1234 /* Correct value unknown */
|
||||
#define PCI_VENDOR_ID_3COM 0x10b7
|
||||
#define PCI_DEVICE_ID_3COM_3C985 0x0001
|
||||
#define PCI_DEVICE_ID_3COM_3C339 0x3390
|
||||
#define PCI_DEVICE_ID_3COM_3C590 0x5900
|
||||
#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
|
||||
#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
|
||||
#define PCI_DEVICE_ID_3COM_3C595MII 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_VENDOR_ID_AMD 0x1022
|
||||
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
|
||||
#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_86C100A 0x6100
|
||||
|
||||
struct pci_device {
|
||||
unsigned short vendor, dev_id;
|
||||
char *name;
|
||||
unsigned int membase;
|
||||
unsigned short ioaddr;
|
||||
unsigned short devfn;
|
||||
};
|
||||
|
||||
extern void eth_pci_init(struct pci_device *, unsigned short *);
|
||||
extern void eth_pci_init(struct pci_device *);
|
||||
|
||||
extern int pcibios_read_config_byte(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char *value);
|
||||
extern int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char value);
|
||||
extern int pcibios_read_config_word(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short *value);
|
||||
extern int pcibios_write_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short value);
|
||||
extern int pcibios_write_config_dword(unsigned char bus,
|
||||
unsigned char device_fn, unsigned char where, unsigned int value);
|
||||
|
|
|
@ -66,6 +66,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
|
@ -66,6 +66,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
|
@ -756,14 +756,17 @@ substring (char *s1, char *s2)
|
|||
|
||||
#ifndef STAGE1_5
|
||||
/* Terminate the string STR with NUL. */
|
||||
char *
|
||||
int
|
||||
nul_terminate (char *str)
|
||||
{
|
||||
int ch;
|
||||
|
||||
while (*str && ! grub_isspace (*str))
|
||||
str++;
|
||||
|
||||
*str++ = 0;
|
||||
return str;
|
||||
ch = *str;
|
||||
*str = 0;
|
||||
return ch;
|
||||
}
|
||||
|
||||
char *
|
||||
|
|
|
@ -269,12 +269,6 @@ int
|
|||
gunzip_test_header (void)
|
||||
{
|
||||
unsigned char buf[10];
|
||||
int is_tftp = 0;
|
||||
|
||||
/* XXX: currently, if CURRENT_DRIVE is a network device, we use only
|
||||
tftp. */
|
||||
if (current_drive == 0x20)
|
||||
is_tftp = 1;
|
||||
|
||||
/* "compressed_file" is already reset to zero by this point */
|
||||
|
||||
|
@ -313,7 +307,6 @@ gunzip_test_header (void)
|
|||
|
||||
gzip_data_offset = filepos;
|
||||
|
||||
if (! is_tftp)
|
||||
filepos = filemax - 8;
|
||||
|
||||
if (grub_read (buf, 8) != 8)
|
||||
|
@ -324,17 +317,8 @@ gunzip_test_header (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (! is_tftp)
|
||||
{
|
||||
gzip_crc = *((unsigned long *) buf);
|
||||
gzip_fsmax = gzip_filemax = *((unsigned long *) (buf + 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't have gzip_crc. */
|
||||
gzip_fsmax = gzip_filemax = 16 * 1024 * 1024;
|
||||
filepos = filemax;
|
||||
}
|
||||
|
||||
initialize_tables ();
|
||||
|
||||
|
|
|
@ -176,6 +176,9 @@ extern char *grub_scratch_mem;
|
|||
#define BOOTSEC_SIG_OFFSET 0x1FE
|
||||
#define BOOTSEC_LISTSIZE 8
|
||||
|
||||
/* Not bad, perhaps. */
|
||||
#define NETWORK_DRIVE 0x20
|
||||
|
||||
/*
|
||||
* GRUB specific information
|
||||
* (in LSB order)
|
||||
|
@ -710,7 +713,7 @@ char *convert_to_ascii (char *buf, int c, ...);
|
|||
int get_cmdline (char *prompt, char *cmdline, int maxlen,
|
||||
int echo_char, int history);
|
||||
int substring (char *s1, char *s2);
|
||||
char *nul_terminate (char *str);
|
||||
int nul_terminate (char *str);
|
||||
int get_based_digit (int c, int base);
|
||||
int safe_parse_maxint (char **str_ptr, int *myint_ptr);
|
||||
int memcheck (int start, int len);
|
||||
|
|
|
@ -68,6 +68,7 @@ GRUB_CFLAGS = @GRUB_CFLAGS@
|
|||
GRUB_LIBS = @GRUB_LIBS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
|
||||
NET_CFLAGS = @NET_CFLAGS@
|
||||
NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
|
||||
OBJCOPY = @OBJCOPY@
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue