heavily rewrite the netboot support.

This commit is contained in:
okuji 2000-02-07 06:26:45 +00:00
parent a2018f29ff
commit 9fe0449a36
36 changed files with 5132 additions and 2080 deletions

147
ChangeLog
View file

@ -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

View file

@ -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@

604
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -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
View file

@ -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@

View file

@ -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@

View file

@ -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@

View file

@ -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@

View file

@ -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;
/* variables for 3C509 */
#ifdef INCLUDE_3C529
struct el3_mca_adapters_struct *mcafound = NULL;
int mca_pos4 = 0, mca_pos5 = 0, mca_irq = 0;
#endif
t509_disable(nic); /* in case board was active */
/* note that nic is not used */
for (failcount=0; failcount<4000; failcount++) {
int data, j, io_base, id_port = 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
if(eth_nic_base >= EP_EISA_START) {
printf("3C5x9 board on EISA at 0x%x - ",eth_nic_base);
#ifdef INCLUDE_3C529
if (mcafound) {
printf("%s board found on MCA at 0x%x IRQ %d -",
mcafound->name, eth_nic_base, mca_irq);
} else {
printf("3C5x9 board on ISA at 0x%x - ",eth_nic_base);
#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:
*/

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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.

View file

@ -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"},
#endif
{ 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_3C59X
extern struct nic *VX_probe(struct nic *, unsigned short *);
#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 *,
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);

View file

@ -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:
*/

View file

@ -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;
@ -568,17 +573,42 @@ struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs)
eeprom[i] = value;
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 */

View file

@ -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:

View file

@ -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
#include <etherboot.h>
#include <nic.h>
#include <netboot_config.h>
/* use GRUB's file system buffer */
#define BUFSIZE (32*1024)
#define buf ((char *)(FSYS_BUF))
static int retry;
static unsigned short isocket = 2000;
static unsigned short osocket;
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;
#endif
static int buf_read = 0, buf_eof = 0;
static unsigned long buf_fileoff;
static int retry;
static unsigned short isocket = 2000;
static unsigned short osocket;
static unsigned short len, block, prevblock;
static struct tftp_t *tr;
static struct tftp_t tp;
static int packetsize = TFTP_DEFAULTSIZE_PACKET;
static int buf_fill(int abort);
int tftp_mount(void)
/* 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 (! 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 (!ip_init())
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;
return 0;
/* 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;
if (buf_eof && (filepos + size >= buf_fileoff + buf_read))
break; /* end of file */
continue;
/* 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;
/* Move the unused data forwards. */
grub_memmove (buf, buf + amt, buf_read - amt);
buf_read -= amt;
}
else if ((filepos == buf_fileoff + buf_read) && buf_eof)
break; /* end of file */
if (buf_eof) /* filepos beyond end of file */
else
{
/* Reset the reading offset. */
saved_filepos += buf_read;
buf_read = 0;
}
/* 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)
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 ())
{
printf(" TFTP doesn't support listing the directory; Sorry!\n");
return 1;
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 */
return 1;
}
void tftp_close(void)
{
buf_read = 0;
buf_fill (1); /* abort. */
}
static int buf_fill(int abort)
{
while (!buf_eof && (buf_read + packetsize <= BUFSIZE))
if (filemax == -1)
{
/* read a packet from the network */
if (!await_reply(AWAIT_TFTP, isocket, NULL))
{
if (ip_abort)
return 0;
/* The server doesn't support the "tsize" option, so we must read
the file twice... */
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;
/* 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;
}
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 */
while (! buf_eof);
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;
/* 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;
}
/* Close the file. */
void
tftp_close (void)
{
buf_read = 0;
buf_fill (1);
}

View file

@ -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 */
}

View file

@ -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);

View file

@ -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 */

View file

@ -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
View 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
View 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
View 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:
*/

File diff suppressed because it is too large Load diff

View file

@ -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
View 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:
*/

View file

@ -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,59 +350,86 @@ 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;
for (devfn = 0; devfn < 0xff; ++devfn) {
if (PCI_FUNC(devfn) == 0) {
pcibios_read_config_byte(0, devfn,
PCI_HEADER_TYPE, &hdr_type);
} else if (!(hdr_type & 0x80)) {
/* not a multi-function device */
continue;
}
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(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
else if (!(hdr_type & 0x80)) /* not a multi-function device */
continue;
pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l);
/* some broken boards return 0 if a slot is empty: */
if (l == 0xffffffff || l == 0x00000000) {
hdr_type = 0;
continue;
}
vendor = l & 0xffff;
device = (l >> 16) & 0xffff;
pcibios_read_config_dword(0, devfn,
PCI_VENDOR_ID, &l);
/* some broken boards return 0 if a slot is empty: */
if (l == 0xffffffff || l == 0x00000000) {
hdr_type = 0;
continue;
}
vendor = l & 0xffff;
device = (l >> 16) & 0xffff;
#if DEBUG
printf("bus 0, function %x, vendor %x, device %x\r\n",
devfn, vendor, device);
#endif
for (i = 0; pcidev[i].vendor != 0; i++) {
if (vendor == pcidev[i].vendor
&& device == pcidev[i].dev_id) {
pcibios_read_config_dword(0, devfn,
PCI_BASE_ADDRESS_0, &pci_ioaddr);
/* Strip the I/O address out of the
* returned value */
pci_ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
printf("Found %s at 0x%x\r\n",
pcidev[i].name, pci_ioaddr);
/* 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)
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 */
}

View file

@ -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 */
#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
#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);

View file

@ -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@

View file

@ -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@

View file

@ -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 *

View file

@ -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,8 +307,7 @@ gunzip_test_header (void)
gzip_data_offset = filepos;
if (! is_tftp)
filepos = filemax - 8;
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;
}
gzip_crc = *((unsigned long *) buf);
gzip_fsmax = gzip_filemax = *((unsigned long *) (buf + 4));
initialize_tables ();

View file

@ -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);

View file

@ -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@