#
# Makefile for Etherboot
#
# Most of the time you should edit Config
#
# Common options:
#	VERSION_*=v	- Set the major and minor version numbers
#
# NS8390 options:
#	-DINCLUDE_NE	- Include NE1000/NE2000 support
#	-DNE_SCAN=list	- Probe for NE base address using list of
#			  comma separated hex addresses
#	-DINCLUDE_3C503 - Include 3c503 support
#	  -DT503_SHMEM	- Use 3c503 shared memory mode (off by default)
#	-DINCLUDE_WD	- Include Western Digital/SMC support
#	-DWD_DEFAULT_MEM- Default memory location for WD/SMC cards
#	-DWD_790_PIO    - Read/write to WD/SMC 790 cards in PIO mode (default
#			  is to use shared memory) Try this if you get "Bogus
#			  packet, ignoring" messages, common on ISA/PCI hybrid
#			  systems.
#	-DCOMPEX_RL2000_FIX
#
#	If you have a Compex RL2000 PCI 32-bit (11F6:1401),
#	and the bootrom hangs in "Probing...[NE*000/PCI]",
#	try enabling this fix... it worked for me :).
#	In the first packet write somehow it somehow doesn't
#	get back the expected data so it is stuck in a loop.
#	I didn't bother to investigate what or why because it works
#	when I interrupt the loop if it takes more then COMPEX_RL2000_TRIES.
#	The code will notify if it does a abort.
#	SomniOne - somnione@gmx.net
#
# 3C509 option:
#	-DINCLUDE_3C509	- Include 3c509 support
#
# 3C90X options:
#	-DINCLUDE_3C90X	- Include 3c90x support
#
#	Warning Warning Warning
#	If you use any of the XCVR options below, please do not complain about
#	the behaviour with Linux drivers to the kernel developers. You are
#	on your own if you do this. Please read 3c90x.txt to understand
#	what they do. If you don't understand them, ask for help on the
#	Etherboot mailing list. And please document what you did to the NIC
#	on the NIC so that people after you won't get nasty surprises.
#
#	-DCFG_3C90X_PRESERVE_XCVR - Reset the transceiver type to the value it
#			  had initially just before the loaded code is started.
#	-DCFG_3C90X_XCVR - Hardcode the tranceiver type Etherboot uses.
#	-DCFG_3C90X_BOOTROM_FIX - If you have a 3c905B with buggy ROM
#			  interface, setting this option might "fix" it.  Use
#			  with caution and read the docs in 3c90x.txt!
#
#	See the documentation file 3c90x.txt for more details.
#
# CS89X0 (optional) options:
#	-DINCLUDE_CS89X0- Include CS89x0 support
#	-DCS_SCAN=list	- Probe for CS89x0 base address using list of
#			  comma separated hex addresses; increasing the
#			  address by one (0x300 -> 0x301) will force a
#			  more aggressive probing algorithm. This might
#			  be neccessary after a soft-reset of the NIC.
#
# LANCE options:
#	-DINCLUDE_NE2100- Include NE2100 support
#	-DINCLUDE_NI6510- Include NI6510 support
#
# SK_G16 options:
#	-DINCLUDE_SK_G16- Include SK_G16 support
#
# I82586 options:
#	-DINCLUDE_3C507	- Include 3c507 support
#	-DINCLUDE_NI5210- Include NI5210 support
#	-DINCLUDE_EXOS205-Include EXOS205 support
#
# SMC9000 options:
#       -DINCLUDE_SMC9000   - Include SMC9000 driver
#       -DSMC9000_SCAN=list - List of I/O addresses to probe
#
# TIARA (Fujitsu Etherstar) options:
#	-DINCLUDE_TIARA	- Include Tiara support
#
# NI5010 options:
#	-DINCLUDE_NI5010 - Include NI5010 support
#
# TULIP options:
#	-DINCLUDE_TULIP	- Include Tulip support
#
# RTL8139 options:
#	-DINCLUDE_RTL8139 - Include RTL8139 support
#
# SIS900 options:
#	-DINCLUDE_SIS900 - Include SIS900 support
#
# NATSEMI options:
#	-DINCLUDE_NATSEMI - Include NATSEMI support
#

include Config

GCC=		gcc
CPP=		gcc -E -Wp,-Wall
STRIP=		strip
OBJCOPY=	objcopy
# MAKEROM=	bin/makerom
MAKEROM=	./makerom.pl
VERSION_MAJOR=	5
VERSION_MINOR=	0
VERSION_PATCH=	10
EXTRAVERSION=
VERSION=	$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)$(EXTRAVERSION)
CFLAGS32+=	-DVERSION_MAJOR=$(VERSION_MAJOR) \
		-DVERSION_MINOR=$(VERSION_MINOR) \
		-DVERSION=\"$(VERSION)\" -DRELOC=$(RELOCADDR) $(OLDGAS)
ifeq "$(shell uname -s)" "FreeBSD"
CFLAGS32+=	-DIMAGE_FREEBSD -DELF_IMAGE -DAOUT_IMAGE
endif
LCONFIG+=	-DRELOC=$(RELOCADDR)

IDENT32=	'$(@F) $(VERSION) Etherboot (GPL)'

# Find out if we're using binutils 2.9.1 which uses a different syntax in some
# places (most prominently in the opcode prefix area).
OLDGAS:=	$(shell $(AS32) --version | grep -q '2\.9\.1' && echo -DGAS291)

BUILD_LIBS=	$(BLIB32)
BUILD_BINS=	$(BINS32)

3C503FLAGS=	-DINCLUDE_3C503 # -DT503_SHMEM
# Note that the suffix to MAKEROM_ is the (mixed case) basename of the ROM file
MAKEROM_3c503=	-3
3C507FLAGS=	-DINCLUDE_3C507
3C509FLAGS=	-DINCLUDE_3C509
3C529FLAGS=	-DINCLUDE_3C529
3C595FLAGS=	-DINCLUDE_3C595
3C90XFLAGS=	-DINCLUDE_3C90X
CS89X0FLAGS=	-DINCLUDE_CS89X0
EEPROFLAGS=	-DINCLUDE_EEPRO
EEPRO100FLAGS=	-DINCLUDE_EEPRO100
E1000FLAGS=	-DINCLUDE_E1000
EPIC100FLAGS=	-DINCLUDE_EPIC100
EXOS205FLAGS=	-DINCLUDE_EXOS205
LANCEFLAGS=	-DINCLUDE_LANCE		# Lance/PCI!
NE2100FLAGS=	-DINCLUDE_NE2100
NEFLAGS=	-DINCLUDE_NE -DNE_SCAN=0x300,0x280,0x320,0x340,0x380
NS8390FLAGS=	-DINCLUDE_NS8390	# NE2000/PCI!
NI5010FLAGS=	-DINCLUDE_NI5010
NI5210FLAGS=	-DINCLUDE_NI5210
NI6510FLAGS=	-DINCLUDE_NI6510
RTL8139FLAGS=	-DINCLUDE_RTL8139
SK_G16FLAGS=	-DINCLUDE_SK_G16
SIS900FLAGS=   	-DINCLUDE_SIS900
NATSEMIFLAGS=  	-DINCLUDE_NATSEMI
SMC9000FLAGS=   -DINCLUDE_SMC9000
SUNDANCEFLAGS=	-DINCLUDE_SUNDANCE
TIARAFLAGS=	-DINCLUDE_TIARA
DEPCAFLAGS=	-DINCLUDE_DEPCA	# -DDEPCA_MODEL=DEPCA -DDEPCA_RAM_BASE=0xd0000
TULIPFLAGS=	-DINCLUDE_TULIP
OTULIPFLAGS=	-DINCLUDE_OTULIP
VIA_RHINEFLAGS=	-DINCLUDE_VIA_RHINE
WDFLAGS=	-DINCLUDE_WD -DWD_DEFAULT_MEM=0xCC000
W89C840FLAGS=	-DINCLUDE_W89C840

SRCS=	boot1a.s comprefix.S liloprefix.S loader.S start32.S memsizes.c serial.c
SRCS+=	main.c pci.c osloader.c nfs.c misc.c ansiesc.c bootmenu.c config.c
SRCS+=	md5.c floppy.c isapnp.c

# ROM loaders: LZ version (prefix Z), PCI header version (prefix P)
RLOADER=	bin/rloader.bin
PXELOADER=	bin/pxeloader.bin
PXEZLOADER=	bin/pxezloader.bin
PRLOADER=	bin/prloader.bin
RZLOADER=	bin/rzloader.bin
PRZLOADER=	bin/przloader.bin
DISKLOADER=	bin/boot1a.bin
COMPREFIX=	bin/comprefix.bin
LILOPREFIX=	bin/liloprefix.bin

START32=	bin32/start32.o bin32/pcbios.o bin32/memsizes.o
ELF_START32=	bin32/start32.o bin32/linuxbios.o

BOBJS32=	bin32/main.o bin32/osloader.o bin32/nfs.o bin32/misc.o
BOBJS32+=	bin32/ansiesc.o bin32/bootmenu.o bin32/md5.o bin32/floppy.o
BOBJS32+=	bin32/serial.o bin32/timer.o bin32/isapnp.o
BLIB32=		bin32/bootlib.a
LIBS32=		$(BLIB32) $(LIBC32)
UTILS+=		bin/makerom bin/lzhuf
STDDEPS32=	$(START32) $(BLIB32) $(UTILS)
ELF_DEPS32=	$(ELF_START32) $(BLIB32)
# MAKEDEPS is the one target that is depended by all ROMs, so we check gcc here
# If you are confident that gcc 2.96 works for you, you can delete gcccheck
# from the next line
MAKEDEPS=	Makefile Config Roms gcccheck

CHECKSIZE=	{ read d1; read d1 d2 d3 size d4; [ $$size -gt $(ROMLIMIT) ] &&\
	{ $(RM) $@; echo "ERROR: code size exceeds limit!"; exit 1; }; exit 0; }

# Make sure that the relocation address is acceptable for all ROM sizes.
# Setting it to 0x94000 leaves about 45kB of space for the Etherboot program.
# The check is done based running 'size' on the binary, not ROM size, but
# roughly this means a ROM of 16kB or a partially used ROM of 32kB,
# remembering to take compressed ROM images into account.
#
# You may also set RELOCADDR to 0x84000 to avoid using 0x94000
# because of other drivers (e.g. Disk On Chip). In that case, you may
# only load 512kB of OS, or load in memory above 1MB.
# This is only the beginning of what you need to do, you also have to
# use a Linux kernel that has moved segments out of the 0x9xxxx space,
# notably the boot block and parameter area.
# Please consult the kernel experts re booting from DOC on this.
# Please send feedback if you get this to work, I have not tried it.
#
ifndef RELOCADDR
RELOCADDR=0x94000
endif

# Evaluate ROMLIMIT only once - it is constant during the make run.
# Note that the 3K safety margin below is for the 1K extended BIOS data area
# and for the Etherboot runtime stack.  Under normal situations, 2K of stack
# are rarely needed.  If you experience strange behaviour in functions that use
# many local variables or that call functions that do, check for stack overrun!
# Make sure that the normal case needs no Perl interpreter - if someone uses a
# different RELOCADDR, then he has Perl installed anyways (the shell cannot
# deal with hex numbers, as test/eval don't support non-decimal integers).
ifeq ($(RELOCADDR),0x94000)
ROMLIMIT=46080
else
ROMLIMIT:=$(shell perl -e 'print 0x10000 - 3072 - ($(RELOCADDR) & 0xFFFF), "\n";')
endif

# Start of targets

all:	$(UTILS) $(BUILD_LIBS) allbins

gcccheck:	Makefile Config
	@if $(CC32) -v 2>&1 | grep -is 'gcc version 2\.96' > /dev/null; \
	then \
		echo 'gcc 2.96 is unsuitable for compiling Etherboot'; \
		echo 'Use gcc 2.95 or gcc 3.x instead'; \
		exit 1; \
	else \
		touch gcccheck; \
	fi

include Roms

# We need allbins because $(BINS32) is not defined until
# the Makefile fragment "Roms" is read.

allbins:	$(BUILD_BINS)

# Common files

$(BLIB32):	$(BOBJS32)
	$(AR32) rv $@ $(BOBJS32)
	$(RANLIB32) $@

bin32/main.o:		main.c etherboot.h osdep.h nic.h

bin32/osloader.o:	osloader.c etherboot.h osdep.h

bin32/nfs.o:		nfs.c etherboot.h osdep.h nic.h

bin32/misc.o:		misc.c etherboot.h osdep.h

bin32/ansiesc.o:	ansiesc.c etherboot.h osdep.h

bin32/bootmenu.o:	bootmenu.c etherboot.h osdep.h

bin32/md5.o:		md5.c etherboot.h osdep.h

bin32/floppy.o:		floppy.c etherboot.h osdep.h

bin32/timer.o:		timer.c timer.h etherboot.h osdep.h

# ISAPNP Support Code

bin32/isapnp.o:		isapnp.c isapnp.h

# PCI support code (common to all PCI drivers)

bin32/pci.o:	pci.c pci.h

# Do not add driver specific dependencies here unless it's something the
# genrules.pl script *can't* deal with, i.e. if it is not C code.

# Prepended loaders

bin/rloader.s:	loader.S $(MAKEDEPS)
	$(CPP) $(LCONFIG) -o $@ $<

bin/rzloader.s:	loader.S $(MAKEDEPS)
	$(CPP) $(LCONFIG) -DZLOADER -o $@ $<

bin/pxeloader.s:	loader.S $(MAKEDEPS)
	$(CPP) $(LCONFIG) -DPXELOADER -o $@ $<

bin/pxezloader.s:	loader.S $(MAKEDEPS)
	$(CPP) $(LCONFIG) -DPXELOADER -DZLOADER -o $@ $<

bin/prloader.s:	loader.S $(MAKEDEPS)
	$(CPP) $(LCONFIG) -DPCI_PNP_HEADER -o $@ $<

bin/przloader.s:	loader.S $(MAKEDEPS)
	$(CPP) $(LCONFIG) -DPCI_PNP_HEADER -DZLOADER -o $@ $<

# Old floppy loader, may be required for non-1.44 MB floppies

bin/floppyload.s:	floppyload.S $(MAKEDEPS)
	$(CPP) -o $@ $<

# New floppy / hard disk loader

bin/boot1a.bin: boot1a.s
	as --defsym FLAGS=0x80 boot1a.s -o boot1a.o
	ld -nostdlib -static -N -e start -Ttext 0x7c00 -o boot1a.out boot1a.o
	objcopy -S -O binary boot1a.out bin/boot1a.bin
	$(RM) boot1a.o boot1a.out

# COM loader

bin/comprefix.s:	comprefix.S $(MAKEDEPS)
	$(CPP) -o $@ $<

# LILO prefix:

bin/liloprefix.s:	liloprefix.S $(MAKEDEPS)
	$(CPP) -o $@ $<

# Utilities

bin/makerom: makerom.c
	$(GCC) -O2 -o $@ makerom.c

bin/lzhuf:	lzhuf.c
	$(GCC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -o $@ $<

# Roms file

Roms:	NIC genrules.pl
	@chmod +x genrules.pl
	./genrules.pl NIC > $@

# Pattern Rules

# general rules for compiling/assembling source files
bin32/%.o:	%.c $(MAKEDEPS)
	$(CC32) $(CFLAGS32) -o $@ -c $<

bin32/%.o:	%.S $(MAKEDEPS)
	$(CPP) $(CFLAGS32) $< | $(AS32) $(ASFLAGS32) -o $@

# general rule for .bin (plain binary loader code), may be overridden
bin/%.bin:	bin/%.s
	$(AS32) $(ASFLAGS32) -o bin/$*.tmp $<
	$(OBJCOPY) -O binary bin/$*.tmp $@
	$(RM) bin/$*.tmp

# general rule for .huf (compressed binary code), may be overridden
%.huf:	%.img
	bin/lzhuf e $< $@

# general rules for normal/compressed ROM images, may be overridden
bin32/%.rom:	bin32/%.img $(RLOADER)
	cat $(RLOADER) $< > $@
	$(MAKEROM) $(MAKEROM_$*) -i$(IDENT32) $@

bin32/%.lzrom:	bin32/%.huf $(RZLOADER)
	cat $(RZLOADER) $< > $@
	$(MAKEROM) $(MAKEROM_$*) -i$(IDENT32) $@

# general rules for normal/compressed PXE images, may be overridden
bin32/%.pxe:	bin32/%.img $(PXELOADER)
	cat $(PXELOADER) $< > $@
	$(MAKEROM) -x $@

bin32/%.lzpxe:	bin32/%.huf $(PXEZLOADER)
	cat $(PXEZLOADER) $< > $@
	$(MAKEROM) -x $@


# rules to write the .rom/.lzrom image onto a blank floppy
# You must give the directory name, e.g. use bin32/rtl8139.lzfd0 as the target.
%.fd0:	%.rom $(DISKLOADER)
	cat $(DISKLOADER) $< > /dev/fd0

%.lzfd0:	%.lzrom $(DISKLOADER)
	cat $(DISKLOADER) $< > /dev/fd0

# rules to generate a .com executable
# You must give the directory name, e.g. use bin32/rtl8139.com as the target.
%.com:	%.lzrom $(COMPREFIX)
	cat $(COMPREFIX) $< > $@

# rules to make a disk image (padding to fill an even number of cylinders).
# VMware reports disk image read errors if it cannot read ahead 36 sectors,
# probably because the floppyload.S code reads up to that number of sectors in
# a single request.  Not that 18k matters much these days...
# Probably not required now that boot1a.s is in use, but shouldn't hurt.
# You must give the directory name, e.g. use bin32/rtl8139.dsk as the target.
%.dsk:	%.rom $(DISKLOADER)
	cat $(DISKLOADER) $< > $@.x
	dd if=$@.x of=$@ bs=36k conv=sync 2> /dev/null
	$(RM) $@.x

%.lzdsk:	%.lzrom $(DISKLOADER)
	cat $(DISKLOADER) $< > $@.x
	dd if=$@.x of=$@ bs=36k conv=sync 2> /dev/null
	$(RM) $@.x

# rules to make a LILO-bootable image
%.lilo:		%.rom $(LILOPREFIX)
	cat $(LILOPREFIX) $< /dev/zero | head -c 64k > $@

%.lzlilo:	%.lzrom $(LILOPREFIX)
	cat $(LILOPREFIX) $< /dev/zero | head -c 64k > $@

# Housekeeping

clean:
	$(RM) $(UTILS) bin/*.s bin/*.bin Roms
	$(RM) $(BLIB32)
	$(RM) bin32/*.o bin32/*.tmp
	$(RM) bin32/*.img bin32/*.huf
	$(RM) bin32/*.rom bin32/*.lzrom
	$(RM) bin32/*.com
	$(RM) bin32/*.dsk bin32/*.lzdsk
	$(RM) bin32/*.lilo bin32/*.lzlilo
	$(RM) bin32/*.pxe bin32/*.lzpxe
	$(RM) bin32/*.elf bin32/*.ebi
	$(RM) gcccheck

../index.html:	../index.xhtml
	(cd ..; m4 -P -DHOSTSITE=SOURCEFORGE index.xhtml > index.html)

../index-berlios.html:	../index.xhtml
	(cd ..; m4 -P -DHOSTSITE=BERLIOS index.xhtml > index-berlios.html)

tarball: ../index.html ../index-berlios.html
	(echo -n $(VERSION) ''; date -u +'%Y-%m-%d') > ../VERSION
	(cd ../..; tar cf /tmp/etherboot-$(VERSION).tar --exclude CVS etherboot-$(VERSION))
	bzip2 -9 < /tmp/etherboot-$(VERSION).tar > /tmp/etherboot-$(VERSION).tar.bz2
	gzip -9 < /tmp/etherboot-$(VERSION).tar > /tmp/etherboot-$(VERSION).tar.gz

version:
	@echo $(VERSION)
