summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/background.h52
-rw-r--r--src/include/buffer.h96
-rw-r--r--src/include/compiler.h127
-rw-r--r--src/include/console.h83
-rw-r--r--src/include/dns.h4
-rw-r--r--src/include/errno.h141
-rw-r--r--src/include/etherboot.h59
-rw-r--r--src/include/igmp.h33
-rw-r--r--src/include/nmb.h2
-rw-r--r--src/include/pci_ids.h1
-rw-r--r--src/include/pxe.h956
-rw-r--r--src/include/pxe_api.h1696
-rw-r--r--src/include/pxe_export.h61
-rw-r--r--src/include/pxe_types.h126
-rw-r--r--src/include/tables.h214
-rw-r--r--src/include/tftp.h169
-rw-r--r--src/include/tftpcore.h33
-rw-r--r--src/include/vsprintf.h44
18 files changed, 2784 insertions, 1113 deletions
diff --git a/src/include/background.h b/src/include/background.h
new file mode 100644
index 000000000..24cb3201f
--- /dev/null
+++ b/src/include/background.h
@@ -0,0 +1,52 @@
+#ifndef BACKGROUND_H
+#define BACKGROUND_H
+
+/** @file
+ *
+ * Background protocols
+ *
+ * Some protocols (e.g. ARP, IGMP) operate in the background; the
+ * upper layers are not aware of their operation. When an ARP query
+ * for the local station's IP address arrives, Etherboot must reply to
+ * it regardless of what other operations are currently in progress.
+ *
+ * Background protocols are called in two circumstances: when
+ * Etherboot is about to poll for a packet, and when Etherboot has
+ * received a packet that the upper layer (whatever that may currently
+ * be) isn't interested in.
+ *
+ */
+
+#include "tables.h"
+#include "ip.h"
+
+/** A background protocol */
+struct background {
+ /** Send method
+ *
+ * This method will be called whenever Etherboot is about to
+ * poll for a packet. The background protocol should use this
+ * method to send out any periodic transmissions that it may
+ * require.
+ */
+ void ( *send ) ( unsigned long timestamp );
+ /** Process method
+ *
+ * This method will be called whenever Etherboot has received
+ * a packet and doesn't know what to do with it.
+ */
+ void ( *process ) ( unsigned long timestamp, unsigned short ptype,
+ struct iphdr *ip );
+};
+
+/** A member of the background protocols table */
+#define __background __table ( background, 01 )
+
+/* Functions in background.c */
+
+extern void background_send ( unsigned long timestamp );
+
+extern void background_process ( unsigned long timestamp, unsigned short ptype,
+ struct iphdr *ip );
+
+#endif /* BACKGROUND_H */
diff --git a/src/include/buffer.h b/src/include/buffer.h
index 0085c7d16..ac4c31481 100644
--- a/src/include/buffer.h
+++ b/src/include/buffer.h
@@ -1,41 +1,93 @@
#ifndef BUFFER_H
#define BUFFER_H
+#include "compiler.h" /* for doxygen */
#include "stdint.h"
-/*
- * "start" and "end" denote the real boundaries of the buffer. "fill"
- * denotes the offset to the first free block in the buffer. (If the
- * buffer is full, "fill" will equal ( end - start ) ).
+/** @file
+ *
+ * Buffers for loading files.
+ *
+ * This file provides routines for filling a buffer with data received
+ * piecemeal, where the size of the data is not necessarily known in
+ * advance.
+ *
+ * Some protocols do not provide a mechanism for us to know the size
+ * of the file before we happen to receive a particular block
+ * (e.g. the final block in an MTFTP transfer). In addition, some
+ * protocols (all the multicast protocols plus any TCP-based protocol)
+ * can, in theory, provide the data in any order.
+ *
+ * Rather than requiring each protocol to implement its own equivalent
+ * of "dd" to arrange the data into well-sized pieces before handing
+ * off to the image loader, we provide these generic buffer functions
+ * which assemble a file into a single contiguous block. The whole
+ * block is then passed to the image loader.
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ * struct buffer my_buffer;
+ * void *data;
+ * off_t offset;
+ * size_t len;
+ *
+ * // We have an area of memory [buf_start,buf_end) into which we want
+ * // to load a file, where buf_start and buf_end are physical addresses.
+ * buffer->start = buf_start;
+ * buffer->end = buf_end;
+ * init_buffer ( &buffer );
+ * ...
+ * while ( get_file_block ( ... ) ) {
+ * // Downloaded block is stored in [data,data+len), and represents
+ * // the portion of the file at offsets [offset,offset+len)
+ * if ( ! fill_buffer ( &buffer, data, offset, len ) ) {
+ * // An error occurred
+ * return 0;
+ * }
+ * ...
+ * }
+ * ...
+ * // The whole file is now present at [buf_start,buf_start+filesize),
+ * // where buf_start is a physical address. The struct buffer can simply
+ * // be discarded; there is no done_buffer() call.
+ *
+ * @endcode
+ *
+ * For a description of the internal operation, see buffer.c.
+ *
+ */
+
+/**
+ * A buffer
+ *
+ * #start and #end denote the real boundaries of the buffer, and are
+ * physical addresses. #fill denotes the offset to the first free
+ * block in the buffer. (If the buffer is full, #fill will equal
+ * #end-#start.)
*
*/
struct buffer {
- physaddr_t start;
- physaddr_t end;
- off_t fill;
+ physaddr_t start; /**< Start of buffer in memory */
+ physaddr_t end; /**< End of buffer in memory */
+ off_t fill; /**< Offset to first gap in buffer */
};
-/*
- * Free blocks in the buffer start with a "tail byte". If non-zero,
- * this byte indicates that the free block is the tail of the buffer,
- * i.e. occupies all the remaining space up to the end of the buffer.
- * When the tail byte is non-zero, it indicates that the remainder of
- * the descriptor (the struct buffer_free_block) follows the tail
- * byte.
+/**
+ * A free block descriptor.
*
- * This scheme is necessary because we may end up with a tail that is
- * smaller than a struct buffer_free_block.
+ * See buffer.c for a full description of the fields.
*
*/
struct buffer_free_block {
- char tail;
- physaddr_t next_free;
- physaddr_t end;
+ char tail; /**< Tail byte marker */
+ char reserved[3]; /**< Padding */
+ physaddr_t start; /**< Address of this free block */
+ physaddr_t next; /**< Address of next free block */
+ physaddr_t end; /**< End of this block */
} __attribute__ (( packed ));
-/* This must be provided by the architecture-dependent load_buffer.c */
-extern struct buffer load_buffer;
-
/* Functions in buffer.c */
extern void init_buffer ( struct buffer *buffer );
diff --git a/src/include/compiler.h b/src/include/compiler.h
index 4a7c48a1c..79781bc72 100644
--- a/src/include/compiler.h
+++ b/src/include/compiler.h
@@ -1,11 +1,30 @@
#ifndef COMPILER_H
#define COMPILER_H
-/* We export the symbol obj_OBJECT (OBJECT is defined on command-line)
- * as a global symbol, so that the linker can drag in selected object
- * files from the library using -u obj_OBJECT.
+/*
+ * Doxygen can't cope with some of the more esoteric areas of C, so we
+ * make its life simpler.
+ *
+ */
+#ifdef DOXYGEN
+#define __attribute__(x)
+#endif
+
+/** @file
+ *
+ * Global compiler definitions.
+ *
+ * This file is implicitly included by every @c .c file in Etherboot.
+ * It defines global macros such as DBG() and ASSERT().
*
- * Not quite sure why cpp requires two levels of macro call in order
+ * We arrange for each object to export the symbol @c obj_OBJECT
+ * (where @c OBJECT is the object name, e.g. @c rtl8139) as a global
+ * symbol, so that the linker can drag in selected object files from
+ * the library using <tt> -u obj_OBJECT </tt>.
+ *
+ */
+
+/* Not quite sure why cpp requires two levels of macro call in order
* to actually expand OBJECT...
*/
#undef _H1
@@ -30,7 +49,9 @@
__asm__ ( ".globl\t" OBJECT_SYMBOL_STR );
__asm__ ( ".equ\t" OBJECT_SYMBOL_STR ", 0" );
-/*
+/**
+ * Drag in an object by object name.
+ *
* Macro to allow objects to explicitly drag in other objects by
* object name. Used by config.c.
*
@@ -38,6 +59,56 @@ __asm__ ( ".equ\t" OBJECT_SYMBOL_STR ", 0" );
#define REQUIRE_OBJECT(object) \
__asm__ ( ".equ\tneed_" #object ", obj_" #object );
+/** @def DBG
+ *
+ * Print a debugging message.
+ *
+ * The debug level is set at build time by specifying the @c DEBUG=
+ * parameter on the @c make command line. For example, to enable
+ * debugging for the PCI bus functions (in pci.c) in a @c .dsk image
+ * for the @c rtl8139 card, you could use the command line
+ *
+ * @code
+ *
+ * make bin/rtl8139.dsk DEBUG=pci
+ *
+ * @endcode
+ *
+ * This will enable the debugging statements (DBG()) in pci.c. If
+ * debugging is not enabled, DBG() statements will be ignored.
+ *
+ * You can enable debugging in several objects simultaneously by
+ * separating them with commas, as in
+ *
+ * @code
+ *
+ * make bin/rtl8139.dsk DEBUG=pci,buffer,heap
+ *
+ * @endcode
+ *
+ * You can increase the debugging level for an object by specifying it
+ * with @c :N, where @c N is the level, as in
+ *
+ * @code
+ *
+ * make bin/rtl8139.dsk DEBUG=pci,buffer:2,heap
+ *
+ * @endcode
+ *
+ * which would enable debugging for the PCI, buffer-handling and
+ * heap-allocation code, with the buffer-handling code at level 2.
+ *
+ */
+
+/** @def DBG2
+ *
+ * Print a level 2 debugging message.
+ *
+ * As for DBG(). DBG2() takes effect only when the debugging level is
+ * 2 or greater.
+ *
+ */
+
/*
* If debug_OBJECT is set to a true value, the macro DBG(...) will
* expand to printf(...) when compiling OBJECT, and the symbol
@@ -67,8 +138,12 @@ __asm__ ( ".equ\tDEBUG_LEVEL, " DEBUG_SYMBOL_STR );
#define DBG2 DBG_PRINT
#endif
-/*
- * ASSERT() macros
+/**
+ * Assert a condition.
+ *
+ * If the condition is not true, a debug message will be printed.
+ * Assertions only take effect if the debug level is non-zero (see
+ * DBG()).
*
*/
#define ASSERT(x)
@@ -84,20 +159,35 @@ __asm__ ( ".equ\tDEBUG_LEVEL, " DEBUG_SYMBOL_STR );
} while (0)
#endif
-/*
- * Commonly-used attributes.
+/** Declare a data structure as packed. */
+#define PACKED __attribute__ (( packed ))
+
+/**
+ * Declare a variable or data structure as unused.
*
- * Note that __used can be used only for functions. If you have a
- * static variable declaration that you want to force to be included,
- * use __unused.
+ * Note that using #__unused on a static global variable (such as a
+ * table structure as mentioned in tables.h) is necessary in order to
+ * inhibit compiler warnings.
*
*/
-#define PACKED __attribute__ (( packed ))
#define __unused __attribute__ (( unused ))
+
+/**
+ * Declare a function as used.
+ *
+ * Necessary only if the function is called only from assembler code.
+ * You cannot use this attribute for static global variables; use
+ * #__unused instead.
+ *
+ */
#define __used __attribute__ (( used ))
+
+/** Declare a data structure to be aligned with 16-byte alignment */
#define __aligned __attribute__ (( aligned ( 16 ) ))
-/*
+/**
+ * Shared data.
+ *
* To save space in the binary when multiple-driver images are
* compiled, uninitialised data areas can be shared between drivers.
* This will typically be used to share statically-allocated receive
@@ -105,13 +195,16 @@ __asm__ ( ".equ\tDEBUG_LEVEL, " DEBUG_SYMBOL_STR );
*
* Use as e.g.
*
- * struct {
+ * @code
+ *
+ * struct {
* char rx_buf[NUM_RX_BUF][RX_BUF_SIZE];
* char tx_buf[TX_BUF_SIZE];
- * } my_static_data __shared;
+ * } my_static_data __shared;
+ *
+ * @endcode
*
*/
-
#define __shared __asm__ ( "_shared_bss" )
#endif /* ASSEMBLY */
diff --git a/src/include/console.h b/src/include/console.h
index 1decb9c3b..9e13293ae 100644
--- a/src/include/console.h
+++ b/src/include/console.h
@@ -5,19 +5,94 @@
#include "vsprintf.h"
#include "tables.h"
-/*
- * Consoles that cannot be used before their INIT_FN() has completed
- * should set disabled = 1 initially. This allows other console
- * devices to still be used to print out early debugging messages.
+/** @file
+ *
+ * User interaction.
+ *
+ * Various console devices can be selected via the build options
+ * CONSOLE_FIRMWARE, CONSOLE_SERIAL etc. The console functions
+ * putchar(), getchar() and iskey() delegate to the individual console
+ * drivers.
+ *
*/
+/**
+ * A console driver
+ *
+ * Defines the functions that implement a particular console type.
+ * Must be made part of the console drivers table by using
+ * #__console_driver.
+ *
+ * @note Consoles that cannot be used before their INIT_FN() has
+ * completed should set #disabled=1 initially. This allows other
+ * console devices to still be used to print out early debugging
+ * messages.
+ *
+ */
struct console_driver {
+ /** Console is disabled.
+ *
+ * The console's putchar(), getchar() and iskey() methods will
+ * not be called while #disabled==1. Typically the
+ * console's initialisation functions (called via INIT_FN())
+ * will set #disabled=0 upon completion.
+ *
+ */
int disabled;
+
+ /** Write a character to the console.
+ *
+ * @v character Character to be written
+ * @ret None -
+ * @err None -
+ *
+ */
void ( *putchar ) ( int character );
+
+ /** Read a character from the console.
+ *
+ * @v None -
+ * @ret character Character read
+ * @err None -
+ *
+ * If no character is available to be read, this method will
+ * block. The character read should not be echoed back to the
+ * console.
+ *
+ */
int ( *getchar ) ( void );
+
+ /** Check for available input.
+ *
+ * @v None -
+ * @ret True Input is available
+ * @ret False Input is not available
+ * @err None -
+ *
+ * This should return True if a subsequent call to getchar()
+ * will not block.
+ *
+ */
int ( *iskey ) ( void );
};
+/**
+ * Mark a <tt> struct console_driver </tt> as being part of the
+ * console drivers table.
+ *
+ * Use as e.g.
+ *
+ * @code
+ *
+ * struct console_driver my_console __console_driver = {
+ * .putchar = my_putchar,
+ * .getchar = my_getchar,
+ * .iskey = my_iskey,
+ * };
+ *
+ * @endcode
+ *
+ */
#define __console_driver __table ( console, 01 )
/* Function prototypes */
diff --git a/src/include/dns.h b/src/include/dns.h
index 5b8b81f13..33ee73fe5 100644
--- a/src/include/dns.h
+++ b/src/include/dns.h
@@ -70,12 +70,12 @@ struct dns_rr_info {
} __attribute__ (( packed ));
struct dns_rr_info_a {
- struct dns_rr_info;
+ struct dns_rr_info info;
struct in_addr in_addr;
} __attribute__ (( packed ));
struct dns_rr_info_cname {
- struct dns_rr_info;
+ struct dns_rr_info info;
char cname[0];
} __attribute__ (( packed ));
diff --git a/src/include/errno.h b/src/include/errno.h
new file mode 100644
index 000000000..e122d9c39
--- /dev/null
+++ b/src/include/errno.h
@@ -0,0 +1,141 @@
+#ifndef ERRNO_H
+#define ERRNO_H
+
+/** @file
+ *
+ * Error codes
+ *
+ */
+
+/* PXE error codes are determined by the PXE specification */
+
+/* Generic errors */
+#define PXENV_STATUS_SUCCESS 0x00
+#define PXENV_STATUS_FAILURE 0x01
+#define PXENV_STATUS_BAD_FUNC 0x02
+#define PXENV_STATUS_UNSUPPORTED 0x03
+#define PXENV_STATUS_KEEP_UNDI 0x04
+#define PXENV_STATUS_KEEP_ALL 0x05
+#define PXENV_STATUS_OUT_OF_RESOURCES 0x06
+
+/* ARP errors (0x10 to 0x1f) */
+#define PXENV_STATUS_ARP_TIMEOUT 0x11
+
+/* Base-Code state errors */
+#define PXENV_STATUS_UDP_CLOSED 0x18
+#define PXENV_STATUS_UDP_OPEN 0x19
+#define PXENV_STATUS_TFTP_CLOSED 0x1a
+#define PXENV_STATUS_TFTP_OPEN 0x1b
+
+/* BIOS/system errors (0x20 to 0x2f) */
+#define PXENV_STATUS_MCOPY_PROBLEM 0x20
+#define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21
+#define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22
+#define PXENV_STATUS_BIS_INIT_FAILURE 0x23
+#define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24
+#define PXENV_STATUS_BIS_GBOA_FAILURE 0x25
+#define PXENV_STATUS_BIS_FREE_FAILURE 0x26
+#define PXENV_STATUS_BIS_GSI_FAILURE 0x27
+#define PXENV_STATUS_BIS_BAD_CKSUM 0x28
+
+/* TFTP/MTFTP errors (0x30 to 0x3f) */
+#define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30
+#define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32
+#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33
+#define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35
+#define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36
+#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38
+#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39
+#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3a
+#define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3b
+#define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3c
+#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3d
+#define PXENV_STATUS_TFTP_NO_FILESIZE 0x3e
+#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3f
+
+/* Reserved errors 0x40 to 0x4f) */
+
+/* DHCP/BOOTP errors (0x50 to 0x5f) */
+#define PXENV_STATUS_DHCP_TIMEOUT 0x51
+#define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52
+#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53
+#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54
+
+/* Driver errors (0x60 to 0x6f) */
+#define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60
+#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61
+#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62
+#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63
+#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64
+#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65
+#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66
+#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67
+#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68
+#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69
+#define PXENV_STATUS_UNDI_INVALID_STATE 0x6a
+#define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6b
+#define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6c
+
+/* ROM and NBP bootstrap errors (0x70 to 0x7f) */
+#define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74
+#define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76
+#define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77
+#define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78
+#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79
+
+/* Environment NBP errors (0x80 to 0x8f) */
+
+/* Reserved errors (0x90 to 0x9f) */
+
+/* Miscellaneous errors (0xa0 to 0xaf) */
+#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xa0
+#define PXENV_STATUS_BINL_NO_PXE_SERVER 0xa1
+#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xa2
+#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xa3
+
+/* BUSD errors (0xb0 to 0xbf) */
+#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xb0
+
+/* Loader errors (0xc0 to 0xcf) */
+#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xc0
+#define PXENV_STATUS_LOADER_NO_BC_ROMID 0xc1
+#define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xc2
+#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xc3
+#define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xc4
+#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xc5
+#define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xc6
+#define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xc8
+#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xc9
+#define PXENV_STATUS_LOADER_UNDI_START 0xca
+#define PXENV_STATUS_LOADER_BC_START 0xcb
+
+/*
+ * The range 0xd0 to 0xff is defined as "Vendor errors" by the PXE
+ * spec. We place all our Etherboot-specific errors in this range.
+ * We also define some generic errors as aliases to the PXE errors.
+ *
+ */
+
+#define ENOERR 0x00
+#define ENOMEM PXENV_STATUS_OUT_OF_RESOURCES
+#define EBADIMG 0xd0
+#define EIMGRET 0xd1
+#define ETIMEDOUT 0xd2
+#define EINVAL 0xd3
+
+/* Data structures and declarations */
+
+#include "tables.h"
+
+extern int errno;
+
+extern const char * strerror ( int errno );
+
+struct errortab {
+ int errno;
+ const char *text;
+};
+
+#define __errortab __table(errortab,01)
+
+#endif /* ERRNO_H */
diff --git a/src/include/etherboot.h b/src/include/etherboot.h
index e61a711ff..b9546c043 100644
--- a/src/include/etherboot.h
+++ b/src/include/etherboot.h
@@ -1,6 +1,26 @@
#ifndef ETHERBOOT_H
#define ETHERBOOT_H
+/*
+ * Standard includes that we always want
+ *
+ */
+
+#include "compiler.h"
+#include "stddef.h"
+#include "stdint.h"
+
+
+/*
+ * IMPORTANT!!!!!!!!!!!!!!
+ *
+ * Everything below this point is cruft left over from older versions
+ * of Etherboot. Do not add *anything* below this point. Things are
+ * gradually being moved to individual header files.
+ *
+ */
+
+
#include <stdarg.h>
#include "osdep.h"
@@ -110,16 +130,11 @@ enum {
MAX_ARP
};
-#define IGMP_SERVER 0
-#define MAX_IGMP IGMP_SERVER+1
-
#define RARP_REQUEST 3
#define RARP_REPLY 4
#include "in.h"
-#define MULTICAST_MASK 0xF0000000
-#define MULTICAST_NETWORK 0xE0000000
/* Helper macros used to identify when DHCP options are valid/invalid in/outside of encapsulation */
#define NON_ENCAP_OPT in_encapsulated_options == 0 &&
@@ -134,7 +149,6 @@ enum {
#include "udp.h"
#include "tcp.h"
#include "bootp.h"
-#include "tftp.h"
#include "igmp.h"
#include "nfs.h"
#include "console.h"
@@ -145,12 +159,7 @@ struct arptable_t {
uint8_t node[6];
} PACKED;
-struct igmptable_t {
- in_addr group;
- unsigned long time;
-} PACKED;
-
-#define KERNEL_BUF (BOOTP_DATA_ADDR->bootp_reply.bp_file)
+#define KERNEL_BUF (bootp_data.bootp_reply.bp_file)
#define FLOPPY_BOOT_LOCATION 0x7c00
@@ -195,19 +204,13 @@ int tcp_reset(struct iphdr *ip);
typedef int (*reply_t)(int ival, void *ptr, unsigned short ptype, struct iphdr *ip, struct udphdr *udp, struct tcphdr *tcp);
extern int await_reply P((reply_t reply, int ival, void *ptr, long timeout));
extern int decode_rfc1533 P((unsigned char *, unsigned int, unsigned int, int));
-extern void join_group(int slot, unsigned long group);
-extern void leave_group(int slot);
#define RAND_MAX 2147483647L
extern uint16_t ipchksum P((const void *ip, unsigned long len));
extern uint16_t add_ipchksums P((unsigned long offset, uint16_t sum, uint16_t new));
extern int32_t random P((void));
extern long rfc2131_sleep_interval P((long base, int exp));
-extern long rfc1112_sleep_interval P((long base, int exp));
extern void cleanup P((void));
-/* config.c */
-extern void print_config(void);
-
/* osloader.c */
/* Be careful with sector_t it is an unsigned long long on x86 */
typedef uint64_t sector_t;
@@ -271,15 +274,6 @@ extern int elf_start(unsigned long machine, unsigned long entry, unsigned long p
extern unsigned long currticks P((void));
extern void exit P((int status));
-/* serial.c */
-extern int serial_getc P((void));
-extern void serial_putc P((int));
-extern int serial_ischar P((void));
-extern int serial_init P((void));
-extern void serial_fini P((void));
-
-/* floppy.c */
-extern int bootdisk P((int dev,int part));
/***************************************************************************
External variables
@@ -288,10 +282,11 @@ External variables
extern struct rom_info rom;
extern char *hostname;
extern int hostnamelen;
+extern unsigned char *addparam;
+extern int addparamlen;
extern jmp_buf restart_etherboot;
extern int url_port;
extern struct arptable_t arptable[MAX_ARP];
-extern struct igmptable_t igmptable[MAX_IGMP];
#ifdef IMAGE_MENU
extern int menutmo,menudefault;
extern unsigned char *defparams;
@@ -309,14 +304,6 @@ extern int freebsd_howto;
extern char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];
#endif
-/* bootmenu.c */
-
-/* osloader.c */
-
-/* created by linker */
-extern char _virt_start[], _text[], _etext[], _text16[], _etext16[];
-extern char _data[], _edata[], _bss[], _ebss[], _end[];
-
/*
* Local variables:
diff --git a/src/include/igmp.h b/src/include/igmp.h
index 2235d6c66..48753eab5 100644
--- a/src/include/igmp.h
+++ b/src/include/igmp.h
@@ -1,5 +1,8 @@
-#ifndef _IGMP_H
-#define _IGMP_H
+#ifndef IGMP_H
+#define IGMP_H
+
+#include "stdint.h"
+#include "in.h"
#define IGMP_QUERY 0x11
#define IGMPv1_REPORT 0x12
@@ -7,11 +10,19 @@
#define IGMP_LEAVE 0x17
#define GROUP_ALL_HOSTS 0xe0000001 /* 224.0.0.1 Host byte order */
+#define MULTICAST_MASK 0xf0000000
+#define MULTICAST_NETWORK 0xe0000000
+
+enum {
+ IGMP_SERVER,
+ MAX_IGMP
+};
+
struct igmp {
- uint8_t type;
- uint8_t response_time;
- uint16_t chksum;
- in_addr group;
+ uint8_t type;
+ uint8_t response_time;
+ uint16_t chksum;
+ struct in_addr group;
} PACKED;
struct igmp_ip_t { /* Format of an igmp ip packet */
@@ -20,4 +31,12 @@ struct igmp_ip_t { /* Format of an igmp ip packet */
struct igmp igmp;
} PACKED;
-#endif /* _IGMP_H */
+struct igmptable_t {
+ struct in_addr group;
+ unsigned long time;
+} PACKED;
+
+extern void join_group ( int slot, unsigned long group );
+extern void leave_group ( int slot );
+
+#endif /* IGMP_H */
diff --git a/src/include/nmb.h b/src/include/nmb.h
index 695f8e08f..7948d9e48 100644
--- a/src/include/nmb.h
+++ b/src/include/nmb.h
@@ -14,7 +14,7 @@
#define NBNS_UDP_PORT 137
struct dns_rr_info_nb {
- struct dns_rr_info;
+ struct dns_rr_info info;
uint16_t nb_flags;
struct in_addr nb_address;
} __attribute__ (( packed ));
diff --git a/src/include/pci_ids.h b/src/include/pci_ids.h
index bcf4c3cd8..a853d4dcb 100644
--- a/src/include/pci_ids.h
+++ b/src/include/pci_ids.h
@@ -319,6 +319,7 @@
#define PCI_VENDOR_ID_MORETON 0x15aa
#define PCI_VENDOR_ID_ZOLTRIX 0x15b0
#define PCI_VENDOR_ID_PDC 0x15e9
+#define PCI_VENDOR_ID_FSC 0x1734
#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_VENDOR_ID_3DLABS 0x3d3d
diff --git a/src/include/pxe.h b/src/include/pxe.h
index 48f555094..f8e2de79b 100644
--- a/src/include/pxe.h
+++ b/src/include/pxe.h
@@ -1,895 +1,59 @@
-/*
- * pxe.h for Etherboot.
- *
- * PXE is technically specified only for i386, but there's no reason
- * why we shouldn't make the API available for other architectures,
- * provided that someone wants to write the shim that allows an
- * external program to call pxe_api_call().
- *
- * We stick with Intel's data structure definitions as far as possible
- * on other architectures. Generally the only i386-specific stuff is
- * related to addressing: real-mode segment:offset addresses, segment
- * selectors, segment descriptors etc. We allow an architecture-
- * specific header to define these types, then build the PXE
- * structures. Note that we retain the names from the PXE
- * specification document (e.g. SEGOFF16_t) even if the architecture
- * in question doesn't represent a SEGOFF16_t as anything resembling a
- * 16-bit segment:offset address. This is done in order to keep the
- * structure definitions as close as possible to those in the spec, to
- * minimise confusion.
- *
- * This file derives from several originals. One is pxe.h from
- * FreeBSD. Another is general.h86 from netboot. The original
- * copyright notices are reproduced below. This entire file is
- * licensed under the GPL; the netboot code is GPL anyway and the
- * FreeBSD code allows us to relicense under the GPL provided that we
- * retain the FreeBSD copyright notice. This is my understanding,
- * anyway. Other portions are my own and therefore Copyright (C) 2004
- * Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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 any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
#ifndef PXE_H
#define PXE_H
-/* Include architecture-specific PXE data types
- *
- * May define SEGOFF16_t, SEGDESC_t and SEGSEL_t. These should be
- * #defines to underlying * types. May also define
- * IS_NULL_SEGOFF16(segoff16), SEGOFF16_TO_PTR(segoff16) and
- * PTR_TO_SEGOFF16(ptr,segoff16)
- */
-#ifndef PXE_TYPES_H
-#include <pxe_types.h>
-#endif
-
-/* Defaults in case pxe_types.h did not define a type. These are
- * placeholder structures just to make the code compile.
- */
-#ifndef SEGOFF16_t
-#define SEGOFF16_t void*
-#endif
-
-#ifndef IS_NULL_SEGOFF16
-#define IS_NULL_SEGOFF16(segoff16) ( (segoff16) == NULL )
-#endif
-
-#ifndef SEGOFF16_TO_PTR
-#define SEGOFF16_TO_PTR(segoff16) (segoff16)
-#endif
-
-#ifndef PTR_TO_SEGOFF16
-#define PTR_TO_SEGOFF16(ptr,segoff16) (segoff16) = (ptr);
-#endif
-
-#ifndef SEGDESC_t
-#define SEGDESC_t void
-#endif
-
-#ifndef SEGSEL_t
-#define SEGSEL_t void
-#endif
-
-/*****************************************************************************
- * The following portion of this file is derived from FreeBSD's pxe.h.
- * Do not remove the copyright notice below.
- *****************************************************************************
- */
-
-/*
- * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
- * All rights reserved.
- * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
- * All rights reserved.
- * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/boot/i386/libi386/pxe.h,v 1.4.2.2 2000/09/10 02:52:18 ps Exp $
- */
-
-/*
- * The typedefs and structures declared in this file
- * clearly violate style(9), the reason for this is to conform to the
- * typedefs/structure-names used in the Intel literature to avoid confusion.
- *
- * It's for your own good. :)
- */
-
-/* It seems that intel didn't think about ABI,
- * either that or 16bit ABI != 32bit ABI (which seems reasonable)
- * I have to thank Intel for the hair loss I incurred trying to figure
- * out why PXE was mis-reading structures I was passing it (at least
- * from my point of view)
- *
- * Solution: use gcc's '__attribute__ ((packed))' to correctly align
- * structures passed into PXE
- * Question: does this really work for PXE's expected ABI?
- */
-#ifndef PACKED
-#define PACKED __attribute__ ((packed))
-#endif
-
-#define S_SIZE(s) s, sizeof(s) - 1
-
-#define IP_STR "%d.%d.%d.%d"
-#define IP_ARGS(ip) \
- (int)(ip >> 24) & 0xff, (int)(ip >> 16) & 0xff, \
- (int)(ip >> 8) & 0xff, (int)ip & 0xff
-
-#define MAC_STR "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARGS(mac) \
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
-
-typedef uint16_t PXENV_EXIT_t;
-typedef uint16_t PXENV_STATUS_t;
-typedef uint32_t IP4_t;
-typedef uint32_t ADDR32_t;
-/* It seems as though UDP_PORT_t is in network order, although I can't
- * find anything in the spec to back this up. (Michael Brown)
- */
-typedef uint16_t UDP_PORT_t;
-
-#define MAC_ADDR_LEN 16
-typedef uint8_t MAC_ADDR[MAC_ADDR_LEN];
-
-/* PXENV+ */
-typedef struct {
- uint8_t Signature[6]; /* 'PXENV+' */
- uint16_t Version; /* MSB = major, LSB = minor */
- uint8_t Length; /* structure length */
- uint8_t Checksum; /* checksum pad */
- SEGOFF16_t RMEntry; /* SEG:OFF to PXE entry point */
- /* don't use PMOffset and PMSelector (from the 2.1 PXE manual) */
- uint32_t PMOffset; /* Protected mode entry */
- SEGSEL_t PMSelector; /* Protected mode selector */
- SEGSEL_t StackSeg; /* Stack segment address */
- uint16_t StackSize; /* Stack segment size (bytes) */
- SEGSEL_t BC_CodeSeg; /* BC Code segment address */
- uint16_t BC_CodeSize; /* BC Code segment size (bytes) */
- SEGSEL_t BC_DataSeg; /* BC Data segment address */
- uint16_t BC_DataSize; /* BC Data segment size (bytes) */
- SEGSEL_t UNDIDataSeg; /* UNDI Data segment address */
- uint16_t UNDIDataSize; /* UNDI Data segment size (bytes) */
- SEGSEL_t UNDICodeSeg; /* UNDI Code segment address */
- uint16_t UNDICodeSize; /* UNDI Code segment size (bytes) */
- SEGOFF16_t PXEPtr; /* SEG:OFF to !PXE struct,
- only present when Version > 2.1 */
-} PACKED pxenv_t;
-
-/* !PXE */
-typedef struct {
- uint8_t Signature[4];
- uint8_t StructLength;
- uint8_t StructCksum;
- uint8_t StructRev;
- uint8_t reserved_1;
- SEGOFF16_t UNDIROMID;
- SEGOFF16_t BaseROMID;
- SEGOFF16_t EntryPointSP;
- SEGOFF16_t EntryPointESP;
- SEGOFF16_t StatusCallout;
- uint8_t reserved_2;
- uint8_t SegDescCn;
- SEGSEL_t FirstSelector;
- SEGDESC_t Stack;
- SEGDESC_t UNDIData;
- SEGDESC_t UNDICode;
- SEGDESC_t UNDICodeWrite;
- SEGDESC_t BC_Data;
- SEGDESC_t BC_Code;
- SEGDESC_t BC_CodeWrite;
-} PACKED pxe_t;
-
-#define PXENV_START_UNDI 0x0000
-typedef struct {
- PXENV_STATUS_t Status;
- uint16_t ax;
- uint16_t bx;
- uint16_t dx;
- uint16_t di;
- uint16_t es;
-} PACKED t_PXENV_START_UNDI;
-
-#define PXENV_UNDI_STARTUP 0x0001
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UNDI_STARTUP;
-
-#define PXENV_UNDI_CLEANUP 0x0002
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UNDI_CLEANUP;
-
-#define PXENV_UNDI_INITIALIZE 0x0003
-typedef struct {
- PXENV_STATUS_t Status;
- ADDR32_t ProtocolIni; /* Phys addr of a copy of the driver module */
- uint8_t reserved[8];
-} PACKED t_PXENV_UNDI_INITIALIZE;
-
-
-#define MAXNUM_MCADDR 8
-typedef struct {
- uint16_t MCastAddrCount;
- MAC_ADDR McastAddr[MAXNUM_MCADDR];
-} PACKED t_PXENV_UNDI_MCAST_ADDRESS;
-
-#define PXENV_UNDI_RESET_ADAPTER 0x0004
-typedef struct {
- PXENV_STATUS_t Status;
- t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
-} PACKED t_PXENV_UNDI_RESET_ADAPTER;
-
-#define PXENV_UNDI_SHUTDOWN 0x0005
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UNDI_SHUTDOWN;
-
-#define PXENV_UNDI_OPEN 0x0006
-typedef struct {
- PXENV_STATUS_t Status;
- uint16_t OpenFlag;
- uint16_t PktFilter;
-# define FLTR_DIRECTED 0x0001
-# define FLTR_BRDCST 0x0002
-# define FLTR_PRMSCS 0x0003
-# define FLTR_SRC_RTG 0x0004
-
- t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
-} PACKED t_PXENV_UNDI_OPEN;
-
-#define PXENV_UNDI_CLOSE 0x0007
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UNDI_CLOSE;
-
-#define PXENV_UNDI_TRANSMIT 0x0008
-typedef struct {
- PXENV_STATUS_t Status;
- uint8_t Protocol;
-# define P_UNKNOWN 0
-# define P_IP 1
-# define P_ARP 2
-# define P_RARP 3
-
- uint8_t XmitFlag;
-# define XMT_DESTADDR 0x0000
-# define XMT_BROADCAST 0x0001
-
- SEGOFF16_t DestAddr;
- SEGOFF16_t TBD;
- uint32_t Reserved[2];
-} PACKED t_PXENV_UNDI_TRANSMIT;
-
-#define MAX_DATA_BLKS 8
-typedef struct {
- uint16_t ImmedLength;
- SEGOFF16_t Xmit;
- uint16_t DataBlkCount;
- struct DataBlk {
- uint8_t TDPtrType;
- uint8_t TDRsvdByte;
- uint16_t TDDataLen;
- SEGOFF16_t TDDataPtr;
- } DataBlock[MAX_DATA_BLKS];
-} PACKED t_PXENV_UNDI_TBD;
-
-#define PXENV_UNDI_SET_MCAST_ADDRESS 0x0009
-typedef struct {
- PXENV_STATUS_t Status;
- t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
-} PACKED t_PXENV_UNDI_SET_MCAST_ADDRESS;
-
-#define PXENV_UNDI_SET_STATION_ADDRESS 0x000A
-typedef struct {
- PXENV_STATUS_t Status;
- MAC_ADDR StationAddress; /* Temp MAC addres to use */
-} PACKED t_PXENV_UNDI_SET_STATION_ADDRESS;
-
-#define PXENV_UNDI_SET_PACKET_FILTER 0x000B
-typedef struct {
- PXENV_STATUS_t Status;
- uint8_t filter; /* see UNDI_OPEN (0x0006) */
-} PACKED t_PXENV_UNDI_SET_PACKET_FILTER;
-
-#define PXENV_UNDI_GET_INFORMATION 0x000C
-typedef struct {
- PXENV_STATUS_t Status;
- uint16_t BaseIo; /* Adapter base I/O address */
- uint16_t IntNumber; /* Adapter IRQ number */
- uint16_t MaxTranUnit; /* Adapter maximum transmit unit */
- uint16_t HwType; /* Type of protocol at the hardware addr */
-# define ETHER_TYPE 1
-# define EXP_ETHER_TYPE 2
-# define IEEE_TYPE 6
-# define ARCNET_TYPE 7
-
- uint16_t HwAddrLen; /* Length of hardware address */
- MAC_ADDR CurrentNodeAddress; /* Current hardware address */
- MAC_ADDR PermNodeAddress; /* Permanent hardware address */
- SEGSEL_t ROMAddress; /* Real mode ROM segment address */
- uint16_t RxBufCt; /* Receive queue length */
- uint16_t TxBufCt; /* Transmit queue length */
-} PACKED t_PXENV_UNDI_GET_INFORMATION;
-
-#define PXENV_UNDI_GET_STATISTICS 0x000D
-typedef struct {
- PXENV_STATUS_t Status;
- uint32_t XmitGoodFrames; /* Number of successful transmissions */
- uint32_t RcvGoodFrames; /* Number of good frames received */
- uint32_t RcvCRCErrors; /* Number of frames with CRC errors */
- uint32_t RcvResourceErrors; /* Number of frames dropped */
-} PACKED t_PXENV_UNDI_GET_STATISTICS;
-
-#define PXENV_UNDI_CLEAR_STATISTICS 0x000E
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UNDI_CLEAR_STATISTICS;
-
-#define PXENV_UNDI_INITIATE_DIAGS 0x000F
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UNDI_INITIATE_DIAGS;
-
-#define PXENV_UNDI_FORCE_INTERRUPT 0x0010
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UNDI_FORCE_INTERRUPT;
-
-#define PXENV_UNDI_GET_MCAST_ADDRESS 0x0011
-typedef struct {
- PXENV_STATUS_t Status;
- IP4_t InetAddr; /* IP mulicast address */
- MAC_ADDR MediaAddr; /* MAC multicast address */
-} PACKED t_PXENV_UNDI_GET_MCAST_ADDRESS;
-
-#define PXENV_UNDI_GET_NIC_TYPE 0x0012
-typedef struct {
- PXENV_STATUS_t Status;
- uint8_t NicType; /* Type of NIC */
-# define PCI_NIC 2
-# define PnP_NIC 3
-# define CardBus_NIC 4
-
- union {
- struct {
- uint16_t Vendor_ID;
- uint16_t Dev_ID;
- uint8_t Base_Class;
- uint8_t Sub_Class;
- uint8_t Prog_Intf;
- uint8_t Rev;
- uint16_t BusDevFunc;
- uint16_t SubVendor_ID;
- uint16_t SubDevice_ID;
- } pci, cardbus;
- struct {
- uint32_t EISA_Dev_ID;
- uint8_t Base_Class;
- uint8_t Sub_Class;
- uint8_t Prog_Intf;
- uint16_t CardSelNum;
- } pnp;
- } info;
-} PACKED t_PXENV_UNDI_GET_NIC_TYPE;
-
-#define PXENV_UNDI_GET_IFACE_INFO 0x0013
-typedef struct {
- PXENV_STATUS_t Status;
- uint8_t IfaceType[16]; /* Name of MAC type in ASCII. */
- uint32_t LinkSpeed; /* Defined in NDIS 2.0 spec */
- uint32_t ServiceFlags; /* Defined in NDIS 2.0 spec */
- uint32_t Reserved[4]; /* must be 0 */
-} PACKED t_PXENV_UNDI_GET_IFACE_INFO;
-
-#define PXENV_UNDI_ISR 0x0014
-typedef struct {
- PXENV_STATUS_t Status;
- uint16_t FuncFlag; /* PXENV_UNDI_ISR_OUT_xxx */
- uint16_t BufferLength; /* Length of Frame */
- uint16_t FrameLength; /* Total length of reciever frame */
- uint16_t FrameHeaderLength; /* Length of the media header in Frame */
- SEGOFF16_t Frame; /* receive buffer */
- uint8_t ProtType; /* Protocol type */
- uint8_t PktType; /* Packet Type */
-# define PXENV_UNDI_ISR_IN_START 1
-# define PXENV_UNDI_ISR_IN_PROCESS 2
-# define PXENV_UNDI_ISR_IN_GET_NEXT 3
-
- /* one of these will be returned for PXENV_UNDI_ISR_IN_START */
-# define PXENV_UNDI_ISR_OUT_OURS 0
-# define PXENV_UNDI_ISR_OUT_NOT_OURS 1
-
- /*
- * one of these will bre returnd for PXEND_UNDI_ISR_IN_PROCESS
- * and PXENV_UNDI_ISR_IN_GET_NEXT
- */
-# define PXENV_UNDI_ISR_OUT_DONE 0
-# define PXENV_UNDI_ISR_OUT_TRANSMIT 2
-# define PXENV_UNDI_ISR_OUT_RECEIVE 3
-# define PXENV_UNDI_ISR_OUT_BUSY 4
-} PACKED t_PXENV_UNDI_ISR;
-
-#define PXENV_STOP_UNDI 0x0015
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_STOP_UNDI;
-
-#define PXENV_TFTP_OPEN 0x0020
-typedef struct {
- PXENV_STATUS_t Status;
- IP4_t ServerIPAddress;
- IP4_t GatewayIPAddress;
- uint8_t FileName[128];
- UDP_PORT_t TFTPPort;
- uint16_t PacketSize;
-} PACKED t_PXENV_TFTP_OPEN;
-
-#define PXENV_TFTP_CLOSE 0x0021
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_TFTP_CLOSE;
-
-#define PXENV_TFTP_READ 0x0022
-typedef struct {
- PXENV_STATUS_t Status;
- uint16_t PacketNumber;
- uint16_t BufferSize;
- SEGOFF16_t Buffer;
-} PACKED t_PXENV_TFTP_READ;
-
-#define PXENV_TFTP_READ_FILE 0x0023
-typedef struct {
- PXENV_STATUS_t Status;
- uint8_t FileName[128];
- uint32_t BufferSize;
- ADDR32_t Buffer;
- IP4_t ServerIPAddress;
- IP4_t GatewayIPAdress;
- IP4_t McastIPAdress;
- UDP_PORT_t TFTPClntPort;
- UDP_PORT_t TFTPSrvPort;
- uint16_t TFTPOpenTimeOut;
- uint16_t TFTPReopenDelay;
-} PACKED t_PXENV_TFTP_READ_FILE;
-
-#define PXENV_TFTP_GET_FSIZE 0x0025
-typedef struct {
- PXENV_STATUS_t Status;
- IP4_t ServerIPAddress;
- IP4_t GatewayIPAdress;
- uint8_t FileName[128];
- uint32_t FileSize;
-} PACKED t_PXENV_TFTP_GET_FSIZE;
-
-#define PXENV_UDP_OPEN 0x0030
-typedef struct {
- PXENV_STATUS_t Status;
- IP4_t src_ip; /* IP address of this station */
-} PACKED t_PXENV_UDP_OPEN;
-
-#define PXENV_UDP_CLOSE 0x0031
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_UDP_CLOSE;
-
-#define PXENV_UDP_READ 0x0032
-typedef struct {
- PXENV_STATUS_t Status;
- IP4_t src_ip; /* IP of sender */
- IP4_t dest_ip; /* Only accept packets sent to this IP */
- UDP_PORT_t s_port; /* UDP source port of sender */
- UDP_PORT_t d_port; /* Only accept packets sent to this port */
- uint16_t buffer_size; /* Size of the packet buffer */
- SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
-} PACKED t_PXENV_UDP_READ;
-
-#define PXENV_UDP_WRITE 0x0033
-typedef struct {
- PXENV_STATUS_t Status;
- IP4_t ip; /* dest ip addr */
- IP4_t gw; /* ip gateway */
- UDP_PORT_t src_port; /* source udp port */
- UDP_PORT_t dst_port; /* destination udp port */
- uint16_t buffer_size; /* Size of the packet buffer */
- SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
-} PACKED t_PXENV_UDP_WRITE;
-
-#define PXENV_UNLOAD_STACK 0x0070
-typedef struct {
- PXENV_STATUS_t Status;
- uint8_t reserved[10];
-} PACKED t_PXENV_UNLOAD_STACK;
-
-
-#define PXENV_GET_CACHED_INFO 0x0071
-typedef struct {
- PXENV_STATUS_t Status;
- uint16_t PacketType; /* type (defined right here) */
-# define PXENV_PACKET_TYPE_DHCP_DISCOVER 1
-# define PXENV_PACKET_TYPE_DHCP_ACK 2
-# define PXENV_PACKET_TYPE_BINL_REPLY 3
- uint16_t BufferSize; /* max to copy, leave at 0 for pointer */
- SEGOFF16_t Buffer; /* copy to, leave at 0 for pointer */
- uint16_t BufferLimit; /* max size of buffer in BC dataseg ? */
-} PACKED t_PXENV_GET_CACHED_INFO;
-
-
-/* structure filled in by PXENV_GET_CACHED_INFO
- * (how we determine which IP we downloaded the initial bootstrap from)
- * words can't describe...
- */
-typedef struct {
- uint8_t opcode;
-# define BOOTP_REQ 1
-# define BOOTP_REP 2
- uint8_t Hardware; /* hardware type */
- uint8_t Hardlen; /* hardware addr len */
- uint8_t Gatehops; /* zero it */
- uint32_t ident; /* random number chosen by client */
- uint16_t seconds; /* seconds since did initial bootstrap */
- uint16_t Flags; /* seconds since did initial bootstrap */
-# define BOOTP_BCAST 0x8000 /* ? */
- IP4_t cip; /* Client IP */
- IP4_t yip; /* Your IP */
- IP4_t sip; /* IP to use for next boot stage */
- IP4_t gip; /* Relay IP ? */
- MAC_ADDR CAddr; /* Client hardware address */
- uint8_t Sname[64]; /* Server's hostname (Optional) */
- uint8_t bootfile[128]; /* boot filename */
- union {
-# if 1
-# define BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size */
-# else
-# define BOOTP_DHCPVEND 312 /* DHCP standard vendor field size */
-# endif
- uint8_t d[BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options */
- struct {
- uint8_t magic[4]; /* DHCP magic cookie */
-# ifndef VM_RFC1048
-# define VM_RFC1048 0x63825363L /* ? */
-# endif
- uint32_t flags; /* bootp flags/opcodes */
- uint8_t pad[56]; /* I don't think intel knows what a
- union does... */
- } v;
- } vendor;
-} PACKED BOOTPLAYER;
-
-#define PXENV_RESTART_TFTP 0x0073
-#define t_PXENV_RESTART_TFTP t_PXENV_TFTP_READ_FILE
-
-#define PXENV_START_BASE 0x0075
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_START_BASE;
-
-#define PXENV_STOP_BASE 0x0076
-typedef struct {
- PXENV_STATUS_t Status;
-} PACKED t_PXENV_STOP_BASE;
-
-/*****************************************************************************
- * The following portion of this file is derived from netboot's
- * general.h86. Do not remove the copyright notice below.
- *****************************************************************************
- */
-
-/*
- * general.h86 - Common PXE definitions
- *
- * Copyright (C) 2003 Gero Kuhlmann <gero@gkminix.han.de>
- *
- * 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
- * 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.
- *
- * $Id$
- */
-
-/*
- **************************************************************************
- *
- * This file contains the Preboot API common definitions as
- * per Intels PXE specification version 2.0.
- *
- * Updated to comply with PXE specification version 2.1 by Michael Brown.
- *
- **************************************************************************
- *
- * Result codes returned in AX by a PXENV API service:
- */
-#define PXENV_EXIT_SUCCESS 0x0000
-#define PXENV_EXIT_FAILURE 0x0001
-
-
-
-/*
- **************************************************************************
- *
- * CPU types (defined in WfM 1.1):
- */
-#define PXENV_CPU_X86 0
-#define PXENV_CPU_ALPHA 1
-#define PXENV_CPU_PPC 2
-
-
-
-/*
- **************************************************************************
- *
- * Bus types (defined in WfM 1.1):
- */
-#define PXENV_BUS_ISA 0
-#define PXENV_BUS_EISA 1
-#define PXENV_BUS_MCA 2
-#define PXENV_BUS_PCI 3
-#define PXENV_BUS_VESA 4
-#define PXENV_BUS_PCMCIA 5
-
-
-
-/*
- **************************************************************************
- *
- * Status codes returned in the status word of the PXENV API parameter
- * structure. Some of these codes are also used to return status
- * information from a boot image loader back to the bootrom.
- */
-
-/* Generic API errors that are reported by the loader */
-#define PXENV_STATUS_SUCCESS 0x00
-#define PXENV_STATUS_FAILURE 0x01 /* general failure */
-#define PXENV_STATUS_BAD_FUNC 0x02 /* invalid function number */
-#define PXENV_STATUS_UNSUPPORTED 0x03 /* not yet supported */
-#define PXENV_STATUS_KEEP_UNDI 0x04 /* keep UNDI in memory */
-#define PXENV_STATUS_KEEP_ALL 0x05 /* keep everything in memory */
-#define PXENV_STATUS_OUT_OF_RESOURCES 0x06 /* also keep everything */
-
-/* ARP/UDP errors (0x10 to 0x1F) */
-#define PXENV_STATUS_ARP_CANCELED 0x10 /* ARP canceled by keystroke */
-#define PXENV_STATUS_ARP_TIMEOUT 0x11 /* ARP timeout */
-#define PXENV_STATUS_UDP_CLOSED 0x18 /* UDP closed */
-#define PXENV_STATUS_UDP_OPEN 0x19 /* UDP already open */
-#define PXENV_STATUS_TFTP_CLOSED 0x1A /* TFTP closed */
-#define PXENV_STATUS_TFTP_OPEN 0x1B /* TFTP already opened */
-
-/* BIOS/system errors (0x20 to 0x2F) */
-#define PXENV_STATUS_MCOPY_PROBLEM 0x20 /* can't copy into memory */
-
-/* TFP errors (0x30 to 0x3F) */
-#define PXENV_STATUS_TFTP_CANNOT_ARP 0x30 /* TFTP ARP problem */
-#define PXENV_STATUS_TFTP_OPEN_CANCELED 0x31 /* TFTP open canceled by key */
-#define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32 /* timeout during TFTP open */
-#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 /* unknown TFTP opcode */
-#define PXENV_STATUS_TFTP_READ_CANCELED 0x34 /* TFTP read canceled by key */
-#define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 /* timeout during TFTP read */
-#define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 /* bad TFTP opcode */
-#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION \
- 0x38 /* error during TFTP open */
-#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION \
- 0x39 /* error during TFTP read */
-#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES \
- 0x3A /* too many packages */
-#define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B /* file not found */
-#define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C /* access violation */
-#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D /* no multicast address */
-#define PXENV_STATUS_TFTP_NO_FILESIZE 0x3E /* unable to get file size */
-#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE \
- 0x3F /* invalid packet size */
-
-/* BOOTP errors (0x40 to 0x4F) */
-#define PXENV_STATUS_BOOTP_CANCELED 0x40 /* BOOTP canceled by key */
-#define PXENV_STATUS_BOOTP_TIMEOUT 0x41 /* timeout during BOOTP */
-#define PXENV_STATUS_BOOTP_NO_FILE 0x42 /* missing bootfile name */
-
-/* DHCP errors (0x50 to 0x5F) */
-#define PXENV_STATUS_DHCP_CANCELED 0x50 /* DHCP canceled by key */
-#define PXENV_STATUS_DHCP_TIMEOUT 0x51 /* timeout during DHCP */
-#define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 /* missing IP address */
-#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 /* missing bootfile name */
-#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54 /* invalid IP address */
-
-/* Driver errors (0x60 to 0x6F) */
-#define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 /* invalid UNDI function */
-#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 /* media test failed */
-#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST \
- 0x62 /* cannot init for multicast */
-#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC \
- 0x63 /* cannot init NIC */
-#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY \
- 0x64 /* cannot init hardware */
-#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA \
- 0x65 /* cannot read config data */
-#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA \
- 0x66 /* cannot read init data */
-#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 /* invalid hardware address */
-#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM \
- 0x68 /* invalid EEPROM checksum */
-#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69
-#define PXENV_STATUS_UNDI_INVALID_STATE 0x6a /* invalid UNDI state */
-#define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6b /* transmit error */
-#define PXENV_STATUS_UNDI_INVALID_PARAMETER \
- 0x6c /* almost anything */
-
-/* Bootstrap (.1) errors (0x70 to 0x7F) */
-#define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 /* invalid bootstrap menu */
-#define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 /* missing multicast address */
-#define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 /* missing file list */
-#define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 /* no response from server */
-#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79 /* next file too big */
-
-/* Environment (.2) errors (0x80 to 0x8F) */
-
-/* MTFTP errors (0x90 to 0x9F) */
-#define PXENV_STATUS_MTFTP_OPEN_CANCEL 0x91 /* MTFTP open canceled by key */
-#define PXENV_STATUS_MTFTP_OPEN_TIMEOUT 0x92 /* timeout during MTFTP open */
-#define PXENV_STATUS_MTFTP_UNKNOWN_OP 0x93 /* unknown TFTP opcode */
-#define PXENV_STATUS_MTFTP_READ_CANCEL 0x94 /* MTFTP read canceled by key */
-#define PXENV_STATUS_MTFTP_READ_TIMEOUT 0x95 /* timeout during MTFTP read */
-#define PXENV_STATUS_MTFTP_ERROR_OP 0x96 /* bad TFTP opcode */
-#define PXENV_STATUS_MTFTP_CANNOT_OPEN 0x98 /* error during MTFTP open */
-#define PXENV_STATUS_MTFTP_CANNOT_READ 0x99 /* error during MTFTP read */
-#define PXENV_STATUS_MTFTP_TOO_MANY 0x9A /* too many packages */
-#define PXENV_STATUS_MTFTP_PACK_SIZE 0x9B /* invalid package size */
-
-/* Misc. errors (0xA0 to 0xAF) */
-#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE \
- 0xA0 /* BINL canceled by key */
-#define PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1 /* no BINL server found */
-#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE \
- 0xA2 /* not avail. in prot mode */
-#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE \
- 0xA3 /* not avail. in real mode */
-
-/* BUSD errors (0xB0 to 0xBF) */
-#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED \
- 0xB0 /* BUSD services not enabled */
-#define PXENV_STATUS_BUSD_DEV_ENABLE 0xB1 /* BUSD device not enabled */
-
-/* Loader errors (0xC0 to 0xCF) */
-#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY \
- 0xC0 /* no free base memory */
-#define PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1 /* no base code rom ID */
-#define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2 /* bad base code rom ID */
-#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE \
- 0xC3 /* bad base code image */
-#define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4 /* no UNDI rom ID */
-#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5 /* bad UNDI rom ID */
-#define PXENV_STATUS_LOADER_UNDI_DRIVER_IMAGE \
- 0xC6 /* bad UNDI runtime image */
-#define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8 /* missing !PXE struct */
-#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT \
- 0xC9 /* missing PXENV+ struct */
-#define PXENV_STATUS_LOADER_UNDI_START 0xCA /* UNDI not started */
-#define PXENV_STATUS_LOADER_BC_START 0xCB /* base code not started */
-
-/* Reserved errors (0xD0 to 0xFF) */
-#define PXENV_STATUS_IMAGE_INVALID 0xD0 /* invalid boot image */
-#define PXENV_STATUS_STOP_BASE 0xD1 /* error stopping base code */
-#define PXENV_STATUS_UNLOAD_BASE 0xD2 /* error unloading base code */
-#define PXENV_STATUS_STOP_UNDI 0xD3 /* error stopping UNDI */
-#define PXENV_STATUS_CLEANUP_UNDI 0xD4 /* error cleaning up UNDI */
-
-
-/*****************************************************************************
- * The remainder of this file is original to Etherboot.
- *****************************************************************************
- */
-
-/* Dummy PXE opcode for the loader routine. We do this to make the
- * API simpler
- */
-#define PXENV_UNDI_LOADER 0x104d /* 'load' */
-
-typedef struct undi_loader {
- union {
- struct {
- PXENV_STATUS_t Status;
- uint16_t ax;
- uint16_t bx;
- uint16_t dx;
- uint16_t di;
- uint16_t es;
- };
- t_PXENV_START_UNDI start_undi;
- };
- uint16_t undi_ds;
- uint16_t undi_cs;
- SEGOFF16_t pxe_ptr;
- SEGOFF16_t pxenv_ptr;
-} PACKED undi_loader_t;
+#include "pxe_types.h"
+#include "pxe_api.h"
+#include "etherboot.h"
+#include "tftp.h"
/* Union used for PXE API calls; we don't know the type of the
* structure until we interpret the opcode. Also, Status is available
* in the same location for any opcode, and it's convenient to have
* non-specific access to it.
*/
-typedef union {
- PXENV_STATUS_t Status; /* Make it easy to read status
- for any operation */
- t_PXENV_START_UNDI start_undi;
- t_PXENV_UNDI_STARTUP undi_startup;
- t_PXENV_UNDI_CLEANUP undi_cleanup;
- t_PXENV_UNDI_INITIALIZE undi_initialize;
- t_PXENV_UNDI_RESET_ADAPTER undi_reset_adapter;
- t_PXENV_UNDI_SHUTDOWN undi_shutdown;
- t_PXENV_UNDI_OPEN undi_open;
- t_PXENV_UNDI_CLOSE undi_close;
- t_PXENV_UNDI_TRANSMIT undi_transmit;
- t_PXENV_UNDI_SET_MCAST_ADDRESS undi_set_mcast_address;
- t_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address;
- t_PXENV_UNDI_SET_PACKET_FILTER undi_set_packet_filter;
- t_PXENV_UNDI_GET_INFORMATION undi_get_information;
- t_PXENV_UNDI_GET_STATISTICS undi_get_statistics;
- t_PXENV_UNDI_CLEAR_STATISTICS undi_clear_statistics;
- t_PXENV_UNDI_INITIATE_DIAGS undi_initiate_diags;
- t_PXENV_UNDI_FORCE_INTERRUPT undi_force_interrupt;
- t_PXENV_UNDI_GET_MCAST_ADDRESS undi_get_mcast_address;
- t_PXENV_UNDI_GET_NIC_TYPE undi_get_nic_type;
- t_PXENV_UNDI_GET_IFACE_INFO undi_get_iface_info;
- t_PXENV_UNDI_ISR undi_isr;
- t_PXENV_STOP_UNDI stop_undi;
- t_PXENV_TFTP_OPEN tftp_open;
- t_PXENV_TFTP_CLOSE tftp_close;
- t_PXENV_TFTP_READ tftp_read;
- t_PXENV_TFTP_READ_FILE tftp_read_file;
- t_PXENV_TFTP_GET_FSIZE tftp_get_fsize;
- t_PXENV_UDP_OPEN udp_open;
- t_PXENV_UDP_CLOSE udp_close;
- t_PXENV_UDP_READ udp_read;
- t_PXENV_UDP_WRITE udp_write;
- t_PXENV_UNLOAD_STACK unload_stack;
- t_PXENV_GET_CACHED_INFO get_cached_info;
- t_PXENV_RESTART_TFTP restart_tftp;
- t_PXENV_START_BASE start_base;
- t_PXENV_STOP_BASE stop_base;
- undi_loader_t loader;
-} t_PXENV_ANY;
+union u_PXENV_ANY {
+ /* Make it easy to read status for any operation */
+ PXENV_STATUS_t Status;
+ struct s_PXENV_UNLOAD_STACK unload_stack;
+ struct s_PXENV_GET_CACHED_INFO get_cached_info;
+ struct s_PXENV_TFTP_READ_FILE restart_tftp;
+ struct s_PXENV_START_UNDI start_undi;
+ struct s_PXENV_STOP_UNDI stop_undi;
+ struct s_PXENV_START_BASE start_base;
+ struct s_PXENV_STOP_BASE stop_base;
+ struct s_PXENV_TFTP_OPEN tftp_open;
+ struct s_PXENV_TFTP_CLOSE tftp_close;
+ struct s_PXENV_TFTP_READ tftp_read;
+ struct s_PXENV_TFTP_READ_FILE tftp_read_file;
+ struct s_PXENV_TFTP_GET_FSIZE tftp_get_fsize;
+ struct s_PXENV_UDP_OPEN udp_open;
+ struct s_PXENV_UDP_CLOSE udp_close;
+ struct s_PXENV_UDP_WRITE udp_write;
+ struct s_PXENV_UDP_READ udp_read;
+ struct s_PXENV_UNDI_STARTUP undi_startup;
+ struct s_PXENV_UNDI_CLEANUP undi_cleanup;
+ struct s_PXENV_UNDI_INITIALIZE undi_initialize;
+ struct s_PXENV_UNDI_RESET undi_reset_adapter;
+ struct s_PXENV_UNDI_SHUTDOWN undi_shutdown;
+ struct s_PXENV_UNDI_OPEN undi_open;
+ struct s_PXENV_UNDI_CLOSE undi_close;
+ struct s_PXENV_UNDI_TRANSMIT undi_transmit;
+ struct s_PXENV_UNDI_SET_MCAST_ADDRESS undi_set_mcast_address;
+ struct s_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address;
+ struct s_PXENV_UNDI_SET_PACKET_FILTER undi_set_packet_filter;
+ struct s_PXENV_UNDI_GET_INFORMATION undi_get_information;
+ struct s_PXENV_UNDI_GET_STATISTICS undi_get_statistics;
+ struct s_PXENV_UNDI_CLEAR_STATISTICS undi_clear_statistics;
+ struct s_PXENV_UNDI_INITIATE_DIAGS undi_initiate_diags;
+ struct s_PXENV_UNDI_FORCE_INTERRUPT undi_force_interrupt;
+ struct s_PXENV_UNDI_GET_MCAST_ADDRESS undi_get_mcast_address;
+ struct s_PXENV_UNDI_GET_NIC_TYPE undi_get_nic_type;
+ struct s_PXENV_UNDI_GET_IFACE_INFO undi_get_iface_info;
+ struct s_PXENV_UNDI_GET_STATE undi_get_state;
+ struct s_PXENV_UNDI_ISR undi_isr;
+};
+
+typedef union u_PXENV_ANY PXENV_ANY_t;
/* PXE stack status indicator. See pxe_export.c for further
* explanation.
@@ -900,22 +64,32 @@ typedef enum {
READY
} pxe_stack_state_t;
+#define ENSURE_CAN_UNLOAD(structure) if ( ! ensure_pxe_state(CAN_UNLOAD) ) { \
+ structure->Status = PXENV_STATUS_UNDI_INVALID_STATE; \
+ return PXENV_EXIT_FAILURE; }
+#define ENSURE_MIDWAY(structure) if ( ! ensure_pxe_state(MIDWAY) ) { \
+ structure->Status = PXENV_STATUS_UNDI_INVALID_STATE; \
+ return PXENV_EXIT_FAILURE; }
+#define ENSURE_READY(structure) if ( ! ensure_pxe_state(READY) ) { \
+ structure->Status = PXENV_STATUS_UNDI_INVALID_STATE; \
+ return PXENV_EXIT_FAILURE; }
+
/* Data structures installed as part of a PXE stack. Architectures
* will have extra information to append to the end of this.
*/
#define PXE_TFTP_MAGIC_COOKIE ( ( 'P'<<24 ) | ( 'x'<<16 ) | ( 'T'<<8 ) | 'f' )
-typedef struct {
- pxe_t pxe __attribute__ ((aligned(16)));
- pxenv_t pxenv __attribute__ ((aligned(16)));
+typedef struct pxe_stack {
+ struct s_PXE pxe __attribute__ ((aligned(16)));
+ struct s_PXENV pxenv __attribute__ ((aligned(16)));
pxe_stack_state_t state;
union {
- BOOTPLAYER cached_info;
+ BOOTPLAYER_t cached_info;
char packet[ETH_FRAME_LEN];
struct {
uint32_t magic_cookie;
unsigned int len;
int eof;
- char data[TFTP_MAX_PACKET];
+ char data[TFTP_MAX_BLKSIZE];
} tftpdata;
struct {
char *buffer;
@@ -926,4 +100,10 @@ typedef struct {
struct {} arch_data __attribute__ ((aligned(16)));
} pxe_stack_t;
+extern int ensure_pxe_state ( pxe_stack_state_t wanted );
+
+extern pxe_stack_t *pxe_stack;
+
+extern PXENV_EXIT_t pxe_api_call ( int opcode, union u_PXENV_ANY *any );
+
#endif /* PXE_H */
diff --git a/src/include/pxe_api.h b/src/include/pxe_api.h
new file mode 100644
index 000000000..7256c57e5
--- /dev/null
+++ b/src/include/pxe_api.h
@@ -0,0 +1,1696 @@
+#ifndef PXE_API_H
+#define PXE_API_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or 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.
+ */
+
+/** @file
+ *
+ * Preboot eXecution Environment (PXE) API
+ *
+ */
+
+#include "pxe_types.h"
+
+/** @addtogroup pxe Preboot eXecution Environment (PXE) API
+ * @{
+ */
+
+/** @defgroup pxe_api_call PXE entry points
+ *
+ * PXE entry points and calling conventions
+ *
+ * @{
+ */
+
+/** The PXENV+ structure */
+struct s_PXENV {
+ /** Signature
+ *
+ * Contains the bytes 'P', 'X', 'E', 'N', 'V', '+'.
+ */
+ UINT8_t Signature[6];
+ /** PXE API version
+ *
+ * MSB is major version number, LSB is minor version number.
+ * If the API version number is 0x0201 or greater, the !PXE
+ * structure pointed to by #PXEPtr should be used instead of
+ * this data structure.
+ */
+ UINT16_t Version;
+ UINT8_t Length; /**< Length of this structure */
+ /** Checksum
+ *
+ * The byte checksum of this structure (using the length in
+ * #Length) must be zero.
+ */
+ UINT8_t Checksum;
+ SEGOFF16_t RMEntry; /**< Real-mode PXENV+ entry point */
+ /** Protected-mode PXENV+ entry point offset
+ *
+ * PXE 2.1 deprecates this entry point. For protected-mode
+ * API calls, use the !PXE structure pointed to by #PXEPtr
+ * instead.
+ */
+ UINT32_t PMOffset;
+ /** Protected-mode PXENV+ entry point segment selector
+ *
+ * PXE 2.1 deprecates this entry point. For protected-mode
+ * API calls, use the !PXE structure pointed to by #PXEPtr
+ * instead.
+ */
+ SEGSEL_t PMSelector;
+ SEGSEL_t StackSeg; /**< Stack segment selector */
+ UINT16_t StackSize; /**< Stack segment size */
+ SEGSEL_t BC_CodeSeg; /**< Base-code code segment selector */
+ UINT16_t BC_CodeSize; /**< Base-code code segment size */
+ SEGSEL_t BC_DataSeg; /**< Base-code data segment selector */
+ UINT16_t BC_DataSize; /**< Base-code data segment size */
+ SEGSEL_t UNDIDataSeg; /**< UNDI data segment selector */
+ UINT16_t UNDIDataSize; /**< UNDI data segment size */
+ SEGSEL_t UNDICodeSeg; /**< UNDI code segment selector */
+ UINT16_t UNDICodeSize; /**< UNDI code segment size */
+ /** Address of the !PXE structure
+ *
+ * This field is present only if #Version is 0x0201 or
+ * greater. If present, it points to a struct s_PXE.
+ */
+ SEGOFF16_t PXEPtr;
+} PACKED;
+
+typedef struct s_PXENV PXENV_t;
+
+/** The !PXE structure */
+struct s_PXE {
+ /** Signature
+ *
+ * Contains the bytes '!', 'P', 'X', 'E'.
+ */
+ UINT8_t Signature[4];
+ UINT8_t StructLength; /**< Length of this structure */
+ /** Checksum
+ *
+ * The byte checksum of this structure (using the length in
+ * #StructLength) must be zero.
+ */
+ UINT8_t StructCksum;
+ /** Revision of this structure
+ *
+ * For PXE version 2.1, this field must be zero.
+ */
+ UINT8_t StructRev;
+ UINT8_t reserved_1; /**< Must be zero */
+ /** Address of the UNDI ROM ID structure
+ *
+ * This is a pointer to a struct s_UNDI_ROM_ID.
+ */
+ SEGOFF16_t UNDIROMID;
+ /** Address of the Base Code ROM ID structure
+ *
+ * This is a pointer to a struct s_BC_ROM_ID.
+ */
+ SEGOFF16_t BaseROMID;
+ /** 16-bit !PXE entry point
+ *
+ * This is the entry point for either real mode, or protected
+ * mode with a 16-bit stack segment.
+ */
+ SEGOFF16_t EntryPointSP;
+ /** 32-bit !PXE entry point
+ *
+ * This is the entry point for protected mode with a 32-bit
+ * stack segment.
+ */
+ SEGOFF16_t EntryPointESP;
+ /** Status call-out function
+ *
+ * @v 0 (if in a time-out loop)
+ * @v n Number of a received TFTP packet
+ * @ret 0 Continue operation
+ * @ret 1 Cancel operation
+ *
+ * This function will be called whenever the PXE stack is in
+ * protected mode, is waiting for an event (e.g. a DHCP reply)
+ * and wishes to allow the user to cancel the operation.
+ * Parameters are passed in register %ax; the return value
+ * must also be placed in register %ax. All other registers
+ * and flags @b must be preserved.
+ *
+ * In real mode, an internal function (that checks for a
+ * keypress) will be used.
+ *
+ * If this field is set to -1, no status call-out function
+ * will be used and consequently the user will not be allowed
+ * to interrupt operations.
+ *
+ * @note The PXE specification version 2.1 defines the
+ * StatusCallout field, mentions it 11 times, but nowhere
+ * defines what it actually does or how it gets called.
+ * Fortunately, the WfM specification version 1.1a deigns to
+ * inform us of such petty details.
+ */
+ SEGOFF16_t StatusCallout;
+ UINT8_t reserved_2; /**< Must be zero */
+ /** Number of segment descriptors
+ *
+ * If this number is greater than 7, the remaining descriptors
+ * follow immediately after #BC_CodeWrite.
+ */
+ UINT8_t SegDescCnt;
+ /** First protected-mode selector
+ *
+ * This is the segment selector value for the first segment
+ * assigned to PXE. Protected-mode selectors must be
+ * consecutive, according to the PXE 2.1 specification, though
+ * no reason is given. Each #SEGDESC_t includes a field for
+ * the segment selector, so this information is entirely
+ * redundant.
+ */
+ SEGSEL_t FirstSelector;
+ /** Stack segment descriptor */
+ SEGDESC_t Stack;
+ /** UNDI data segment descriptor */
+ SEGDESC_t UNDIData;
+ /** UNDI code segment descriptor */
+ SEGDESC_t UNDICode;
+ /** UNDI writable code segment descriptor */
+ SEGDESC_t UNDICodeWrite;
+ /** Base-code data segment descriptor */
+ SEGDESC_t BC_Data;
+ /** Base-code code segment descriptor */
+ SEGDESC_t BC_Code;
+ /** Base-code writable code segment descriptor */
+ SEGDESC_t BC_CodeWrite;
+} PACKED;
+
+typedef struct s_PXE PXE_t;
+
+/** @} */ /* pxe_api_call */
+
+/** @defgroup pxe_preboot_api PXE Preboot API
+ *
+ * General high-level functions: #PXENV_UNLOAD_STACK, #PXENV_START_UNDI etc.
+ *
+ * @{
+ */
+
+/** @defgroup pxenv_unload_stack PXENV_UNLOAD_STACK
+ *
+ * UNLOAD BASE CODE STACK
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_unload_stack() */
+#define PXENV_UNLOAD_STACK 0x0070
+
+/** Parameter block for pxenv_unload_stack() */
+struct s_PXENV_UNLOAD_STACK {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ UINT8_t reserved[10]; /**< Must be zero */
+} PACKED;
+
+typedef struct s_PXENV_UNLOAD_STACK PXENV_UNLOAD_STACK_t;
+
+extern PXENV_EXIT_t pxenv_unload_stack ( struct s_PXENV_UNLOAD_STACK
+ *unload_stack );
+
+/** @} */ /* pxenv_unload_stack */
+
+/** @defgroup pxenv_get_cached_info PXENV_GET_CACHED_INFO
+ *
+ * GET CACHED INFO
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_get_cached_info() */
+#define PXENV_GET_CACHED_INFO 0x0071
+
+/** The client's DHCPDISCOVER packet */
+#define PXENV_PACKET_TYPE_DHCP_DISCOVER 1
+
+/** The DHCP server's DHCPACK packet */
+#define PXENV_PACKET_TYPE_DHCP_ACK 2
+
+/** The Boot Server's Discover Reply packet
+ *
+ * This packet contains DHCP option 60 set to "PXEClient", a valid
+ * boot file name, and may or may not contain MTFTP options.
+ */
+#define PXENV_PACKET_TYPE_CACHED_REPLY 3
+
+/** Parameter block for pxenv_get_cached_info() */
+struct s_PXENV_GET_CACHED_INFO {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Packet type.
+ *
+ * Valid values are #PXENV_PACKET_TYPE_DHCP_DISCOVER,
+ * #PXENV_PACKET_TYPE_DHCP_ACK or #PXENV_PACKET_TYPE_CACHED_REPLY
+ */
+ UINT16_t PacketType;
+ UINT16_t BufferSize; /**< Buffer size */
+ SEGOFF16_t Buffer; /**< Buffer address */
+ UINT16_t BufferLimit; /**< Maximum buffer size */
+} PACKED;
+
+typedef struct s_PXENV_GET_CACHED_INFO PXENV_GET_CACHED_INFO_t;
+
+#define BOOTP_REQ 1 /**< A BOOTP request packet */
+#define BOOTP_REP 2 /**< A BOOTP reply packet */
+
+/** DHCP broadcast flag
+ *
+ * Request a broadcast response (DHCPOFFER or DHCPACK) from the DHCP
+ * server.
+ */
+#define BOOTP_BCAST 0x8000
+
+#define VM_RFC1048 0x63825363L /**< DHCP magic cookie */
+
+/** Maximum length of DHCP options */
+#define BOOTP_DHCPVEND 1024
+
+/** Format of buffer filled in by pxenv_get_cached_info()
+ *
+ * This somewhat convoluted data structure simply describes the layout
+ * of a DHCP packet. Refer to RFC2131 section 2 for a full
+ * description.
+ */
+struct bootph {
+ /** Message opcode.
+ *
+ * Valid values are #BOOTP_REQ and #BOOTP_REP.
+ */
+ UINT8_t opcode;
+ /** NIC hardware type.
+ *
+ * Valid values are as for s_PXENV_UNDI_GET_INFORMATION::HwType.
+ */
+ UINT8_t Hardware;
+ UINT8_t Hardlen; /**< MAC address length */
+ /** Gateway hops
+ *
+ * Zero in packets sent by the client. May be non-zero in
+ * replies from the DHCP server, if the reply comes via a DHCP
+ * relay agent.
+ */
+ UINT8_t Gatehops;
+ UINT32_t ident; /**< DHCP transaction id (xid) */
+ /** Elapsed time
+ *
+ * Number of seconds since the client began the DHCP
+ * transaction.
+ */
+ UINT16_t seconds;
+ /** Flags
+ *
+ * This is the bitwise-OR of any of the following values:
+ * #BOOTP_BCAST.
+ */
+ UINT16_t Flags;
+ /** Client IP address
+ *
+ * Set only if the client already has an IP address.
+ */
+ IP4_t cip;
+ /** Your IP address
+ *
+ * This is the IP address that the server assigns to the
+ * client.
+ */
+ IP4_t yip;
+ /** Server IP address
+ *
+ * This is the IP address of the BOOTP/DHCP server.
+ */
+ IP4_t sip;
+ /** Gateway IP address
+ *
+ * This is the IP address of the BOOTP/DHCP relay agent, if
+ * any. It is @b not (necessarily) the address of the default
+ * gateway for routing purposes.
+ */
+ IP4_t gip;
+ MAC_ADDR_t CAddr; /**< Client MAC address */
+ UINT8_t Sname[64]; /**< Server host name */
+ UINT8_t bootfile[128]; /**< Boot file name */
+ /** DHCP options
+ *
+ * Don't ask. Just laugh. Then burn a copy of the PXE
+ * specification and send Intel an e-mail asking them if
+ * they've figured out what a "union" does in C yet.
+ */
+ union bootph_vendor {
+ UINT8_t d[BOOTP_DHCPVEND]; /**< DHCP options */
+ /** DHCP options */
+ struct bootph_vendor_v {
+ /** DHCP magic cookie
+ *
+ * Should have the value #VM_RFC1048.
+ */
+ UINT8_t magic[4];
+ UINT32_t flags; /**< BOOTP flags/opcodes */
+ /** "End of BOOTP vendor extensions"
+ *
+ * Abandon hope, all ye who consider the
+ * purpose of this field.
+ */
+ UINT8_t pad[56];
+ } v;
+ } vendor;
+} PACKED;
+
+typedef struct bootph BOOTPLAYER_t;
+
+extern PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
+ *get_cached_info );
+
+/** @} */ /* pxenv_get_cached_info */
+
+/** @defgroup pxenv_restart_tftp PXENV_RESTART_TFTP
+ *
+ * RESTART TFTP
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_restart_tftp() */
+#define PXENV_RESTART_TFTP 0x0073
+
+/** Parameter block for pxenv_restart_tftp() */
+struct s_PXENV_TFTP_READ_FILE;
+
+typedef struct s_PXENV_RESTART_TFTP PXENV_RESTART_TFTP_t;
+
+extern PXENV_EXIT_t pxenv_restart_tftp ( struct s_PXENV_TFTP_READ_FILE
+ *restart_tftp );
+
+/** @} */ /* pxenv_restart_tftp */
+
+/** @defgroup pxenv_start_undi PXENV_START_UNDI
+ *
+ * START UNDI
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_start_undi() */
+#define PXENV_START_UNDI 0x0000
+
+/** Parameter block for pxenv_start_undi() */
+struct s_PXENV_START_UNDI {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** %ax register as passed to the Option ROM initialisation routine.
+ *
+ * For a PCI device, this should contain the bus:dev:fn value
+ * that uniquely identifies the PCI device in the system. For
+ * a non-PCI device, this field is not defined.
+ */
+ UINT16_t AX;
+ /** %bx register as passed to the Option ROM initialisation routine.
+ *
+ * For an ISAPnP device, this should contain the Card Select
+ * Number assigned to the ISAPnP card. For non-ISAPnP
+ * devices, this should contain 0xffff.
+ */
+ UINT16_t BX;
+ /** %dx register as passed to the Option ROM initialisation routine.
+ *
+ * For an ISAPnP device, this should contain the ISAPnP Read
+ * Port address as currently set in all ISAPnP cards. If
+ * there are no ISAPnP cards, this should contain 0xffff. (If
+ * this is a non-ISAPnP device, but there are ISAPnP cards in
+ * the system, this value is not well defined.)
+ */
+ UINT16_t DX;
+ /** %di register as passed to the Option ROM initialisation routine.
+ *
+ * This contains the #OFF16_t portion of a struct #s_SEGOFF16
+ * that points to the System BIOS Plug and Play Installation
+ * Check Structure. (Refer to section 4.4 of the Plug and
+ * Play BIOS specification for a description of this
+ * structure.)
+ *
+ * @note The PXE specification defines the type of this field
+ * as #UINT16_t. For x86, #OFF16_t and #UINT16_t are
+ * equivalent anyway; for other architectures #OFF16_t makes
+ * more sense.
+ */
+ OFF16_t DI;
+ /** %es register as passed to the Option ROM initialisation routine.
+ *
+ * This contains the #SEGSEL_t portion of a struct #s_SEGOFF16
+ * that points to the System BIOS Plug and Play Installation
+ * Check Structure. (Refer to section 4.4 of the Plug and
+ * Play BIOS specification for a description of this
+ * structure.)
+ *
+ * @note The PXE specification defines the type of this field
+ * as #UINT16_t. For x86, #SEGSEL_t and #UINT16_t are
+ * equivalent anyway; for other architectures #SEGSEL_t makes
+ * more sense.
+ */
+ SEGSEL_t ES;
+} PACKED;
+
+typedef struct s_PXENV_START_UNDI PXENV_START_UNDI_t;
+
+extern PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi );
+
+/** @} */ /* pxenv_start_undi */
+
+/** @defgroup pxenv_stop_undi PXENV_STOP_UNDI
+ *
+ * STOP UNDI
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_stop_undi() */
+#define PXENV_STOP_UNDI 0x0015
+
+/** Parameter block for pxenv_stop_undi() */
+struct s_PXENV_STOP_UNDI {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_STOP_UNDI PXENV_STOP_UNDI_t;
+
+extern PXENV_EXIT_t pxenv_stop_undi ( struct s_PXENV_STOP_UNDI *stop_undi );
+
+/** @} */ /* pxenv_stop_undi */
+
+/** @defgroup pxenv_start_base PXENV_START_BASE
+ *
+ * START BASE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_start_base() */
+#define PXENV_START_BASE 0x0075
+
+/** Parameter block for pxenv_start_base() */
+struct s_PXENV_START_BASE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_START_BASE PXENV_START_BASE_t;
+
+extern PXENV_EXIT_t pxenv_start_base ( struct s_PXENV_START_BASE *start_base );
+
+/** @} */ /* pxenv_start_base */
+
+/** @defgroup pxenv_stop_base PXENV_STOP_BASE
+ *
+ * STOP BASE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_stop_base() */
+#define PXENV_STOP_BASE 0x0076
+
+/** Parameter block for pxenv_stop_base() */
+struct s_PXENV_STOP_BASE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_STOP_BASE PXENV_STOP_BASE_t;
+
+extern PXENV_EXIT_t pxenv_stop_base ( struct s_PXENV_STOP_BASE *stop_base );
+
+/** @} */ /* pxenv_stop_base */
+
+/** @} */ /* pxe_preboot_api */
+
+/** @defgroup pxe_tftp_api PXE TFTP API
+ *
+ * Download files via TFTP or MTFTP
+ *
+ * @{
+ */
+
+/** @defgroup pxenv_tftp_open PXENV_TFTP_OPEN
+ *
+ * TFTP OPEN
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_tftp_open() */
+#define PXENV_TFTP_OPEN 0x0020
+
+/** Parameter block for pxenv_tftp_open() */
+struct s_PXENV_TFTP_OPEN {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ IP4_t ServerIPAddress; /**< TFTP server IP address */
+ IP4_t GatewayIPAddress; /**< Relay agent IP address */
+ UINT8_t FileName[128]; /**< File name */
+ UDP_PORT_t TFTPPort; /**< TFTP server UDP port */
+ /** Requested size of TFTP packets
+ *
+ * This is the TFTP "blksize" option. This must be at least
+ * 512, since servers that do not support TFTP options cannot
+ * negotiate blocksizes smaller than this.
+ */
+ UINT16_t PacketSize;
+} PACKED;
+
+typedef struct s_PXENV_TFTP_OPEN PXENV_TFTP_OPEN_t;
+
+extern PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open );
+
+/** @} */ /* pxenv_tftp_open */
+
+/** @defgroup pxenv_tftp_close PXENV_TFTP_CLOSE
+ *
+ * TFTP CLOSE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_tftp_close() */
+#define PXENV_TFTP_CLOSE 0x0021
+
+/** Parameter block for pxenv_tftp_close() */
+struct s_PXENV_TFTP_CLOSE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_TFTP_CLOSE PXENV_TFTP_CLOSE_t;
+
+extern PXENV_EXIT_t pxenv_tftp_close ( struct s_PXENV_TFTP_CLOSE *tftp_close );
+
+/** @} */ /* pxenv_tftp_close */
+
+/** @defgroup pxenv_tftp_read PXENV_TFTP_READ
+ *
+ * TFTP READ
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_tftp_read() */
+#define PXENV_TFTP_READ 0x0022
+
+/** Parameter block for pxenv_tftp_read() */
+struct s_PXENV_TFTP_READ {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ UINT16_t PacketNumber; /**< TFTP packet number */
+ UINT16_t BufferSize; /**< Size of data buffer */
+ SEGOFF16_t Buffer; /**< Address of data buffer */
+} PACKED;
+
+typedef struct s_PXENV_TFTP_READ PXENV_TFTP_READ_t;
+
+extern PXENV_EXIT_t pxenv_tftp_read ( struct s_PXENV_TFTP_READ *tftp_read );
+
+/** @} */ /* pxenv_tftp_read */
+
+/** @defgroup pxenv_tftp_read_file PXENV_TFTP_READ_FILE
+ *
+ * TFTP/MTFTP READ FILE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_tftp_read_file() */
+#define PXENV_TFTP_READ_FILE 0x0023
+
+/** Parameter block for pxenv_tftp_read_file() */
+struct s_PXENV_TFTP_READ_FILE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ UINT8_t FileName[128]; /**< File name */
+ UINT32_t BufferSize; /**< Size of data buffer */
+ ADDR32_t Buffer; /**< Address of data buffer */
+ IP4_t ServerIPAddress; /**< TFTP server IP address */
+ IP4_t GatewayIPAddress; /**< Relay agent IP address */
+ /** File multicast IP address */
+ IP4_t McastIPAddress;
+ /** Client multicast listening port */
+ UDP_PORT_t TFTPClntPort;
+ /** Server multicast listening port */
+ UDP_PORT_t TFTPSrvPort;
+ /** TFTP open timeout.
+ *
+ * This is the timeout for receiving the first DATA or ACK
+ * packets during the MTFTP Listen phase.
+ */
+ UINT16_t TFTPOpenTimeOut;
+ /** TFTP reopen timeout.
+ *
+ * This is the timeout for receiving an ACK packet while in
+ * the MTFTP Listen phase (when at least one ACK packet has
+ * already been seen).
+ */
+ UINT16_t TFTPReopenDelay;
+} PACKED;
+
+typedef struct s_PXENV_TFTP_READ_FILE PXENV_TFTP_READ_FILE_t;
+
+extern PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE
+ *tftp_read_file );
+
+/** @} */ /* pxenv_tftp_read_file */
+
+/** @defgroup pxenv_tftp_get_fsize PXENV_TFTP_GET_FSIZE
+ *
+ * TFTP GET FILE SIZE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_tftp_get_fsize() */
+#define PXENV_TFTP_GET_FSIZE 0x0025
+
+/** Parameter block for pxenv_tftp_get_fsize() */
+struct s_PXENV_TFTP_GET_FSIZE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ IP4_t ServerIPAddress; /**< TFTP server IP address */
+ IP4_t GatewayIPAddress; /**< Relay agent IP address */
+ UINT8_t FileName[128]; /**< File name */
+ UINT32_t FileSize; /**< Size of the file */
+} PACKED;
+
+typedef struct s_PXENV_TFTP_GET_FSIZE PXENV_TFTP_GET_FSIZE_t;
+
+extern PXENV_EXIT_t pxenv_tftp_get_fsize ( struct s_PXENV_TFTP_GET_FSIZE
+ *get_fsize );
+
+/** @} */ /* pxenv_tftp_get_fsize */
+
+/** @} */ /* pxe_tftp_api */
+
+/** @defgroup pxe_udp_api PXE UDP API
+ *
+ * Transmit and receive UDP packets
+ *
+ * @{
+ */
+
+/** @defgroup pxenv_udp_open PXENV_UDP_OPEN
+ *
+ * UDP OPEN
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_udp_open() */
+#define PXENV_UDP_OPEN 0x0030
+
+/** Parameter block for pxenv_udp_open() */
+struct s_PXENV_UDP_OPEN {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ IP4_t src_ip; /**< IP address of this station */
+} PACKED;
+
+typedef struct s_PXENV_UDP_OPEN PXENV_UDP_OPEN_t;
+
+extern PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open );
+
+/** @} */ /* pxenv_udp_open */
+
+/** @defgroup pxenv_udp_close PXENV_UDP_CLOSE
+ *
+ * UDP CLOSE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_udp_close() */
+#define PXENV_UDP_CLOSE 0x0031
+
+/** Parameter block for pxenv_udp_close() */
+struct s_PXENV_UDP_CLOSE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UDP_CLOSE PXENV_UDP_CLOSE_t;
+
+extern PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close );
+
+/** @} */ /* pxenv_udp_close */
+
+/** @defgroup pxenv_udp_write PXENV_UDP_WRITE
+ *
+ * UDP WRITE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_udp_write() */
+#define PXENV_UDP_WRITE 0x0033
+
+/** Parameter block for pxenv_udp_write() */
+struct s_PXENV_UDP_WRITE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ IP4_t ip; /**< Destination IP address */
+ IP4_t gw; /**< Relay agent IP address */
+ UDP_PORT_t src_port; /**< Source UDP port */
+ UDP_PORT_t dst_port; /**< Destination UDP port */
+ UINT16_t buffer_size; /**< UDP payload buffer size */
+ SEGOFF16_t buffer; /**< UDP payload buffer address */
+} PACKED;
+
+typedef struct s_PXENV_UDP_WRITE PXENV_UDP_WRITE_t;
+
+extern PXENV_EXIT_t pxenv_udp_write ( struct s_PXENV_UDP_WRITE *udp_write );
+
+/** @} */ /* pxenv_udp_write */
+
+/** @defgroup pxenv_udp_read PXENV_UDP_READ
+ *
+ * UDP READ
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_udp_read() */
+#define PXENV_UDP_READ 0x0032
+
+/** Parameter block for pxenv_udp_read() */
+struct s_PXENV_UDP_READ {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ IP4_t src_ip; /**< Source IP address */
+ IP4_t dest_ip; /**< Destination IP address */
+ UDP_PORT_t s_port; /**< Source UDP port */
+ UDP_PORT_t d_port; /**< Destination UDP port */
+ UINT16_t buffer_size; /**< UDP payload buffer size */
+ SEGOFF16_t buffer; /**< UDP payload buffer address */
+} PACKED;
+
+typedef struct s_PXENV_UDP_READ PXENV_UDP_READ_t;
+
+extern PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *udp_read );
+
+/** @} */ /* pxenv_udp_read */
+
+/** @} */ /* pxe_udp_api */
+
+/** @defgroup pxe_undi_api PXE UNDI API
+ *
+ * Direct control of the network interface card
+ *
+ * @{
+ */
+
+/** @defgroup pxenv_undi_startup PXENV_UNDI_STARTUP
+ *
+ * UNDI STARTUP
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_startup() */
+#define PXENV_UNDI_STARTUP 0x0001
+
+#define PXENV_BUS_ISA 0 /**< ISA bus type */
+#define PXENV_BUS_EISA 1 /**< EISA bus type */
+#define PXENV_BUS_MCA 2 /**< MCA bus type */
+#define PXENV_BUS_PCI 3 /**< PCI bus type */
+#define PXENV_BUS_VESA 4 /**< VESA bus type */
+#define PXENV_BUS_PCMCIA 5 /**< PCMCIA bus type */
+
+/** Parameter block for pxenv_undi_startup() */
+struct s_PXENV_UNDI_STARTUP {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_STARTUP PXENV_UNDI_STARTUP_t;
+
+extern PXENV_EXIT_t pxenv_undi_startup ( struct s_PXENV_UNDI_STARTUP
+ *undi_startup );
+
+/** @} */ /* pxenv_undi_startup */
+
+/** @defgroup pxenv_undi_cleanup PXENV_UNDI_CLEANUP
+ *
+ * UNDI CLEANUP
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_cleanup() */
+#define PXENV_UNDI_CLEANUP 0x0002
+
+/** Parameter block for pxenv_undi_cleanup() */
+struct s_PXENV_UNDI_CLEANUP {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_CLEANUP PXENV_UNDI_CLEANUP_t;
+
+extern PXENV_EXIT_t pxenv_undi_cleanup ( struct s_PXENV_UNDI_CLEANUP
+ *undi_cleanup );
+
+/** @} */ /* pxenv_undi_cleanup */
+
+/** @defgroup pxenv_undi_initialize PXENV_UNDI_INITIALIZE
+ *
+ * UNDI INITIALIZE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_initialize() */
+#define PXENV_UNDI_INITIALIZE 0x0003
+
+/** Parameter block for pxenv_undi_initialize() */
+struct s_PXENV_UNDI_INITIALIZE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** NDIS 2.0 configuration information, or NULL
+ *
+ * This is a pointer to the data structure returned by the
+ * NDIS 2.0 GetProtocolManagerInfo() API call. The data
+ * structure is documented, in a rather haphazard way, in
+ * section 4-17 of the NDIS 2.0 specification.
+ */
+ ADDR32_t ProtocolIni;
+ UINT8_t reserved[8]; /**< Must be zero */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_INITIALIZE PXENV_UNDI_INITIALIZE_t;
+
+extern PXENV_EXIT_t pxenv_undi_initialize ( struct s_PXENV_UNDI_INITIALIZE
+ *undi_initialize );
+
+/** @} */ /* pxenv_undi_initialize */
+
+/** @defgroup pxenv_undi_reset_adapter PXENV_UNDI_RESET_ADAPTER
+ *
+ * UNDI RESET ADAPTER
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_reset_adapter() */
+#define PXENV_UNDI_RESET_ADAPTER 0x0004
+
+/** Maximum number of multicast MAC addresses */
+#define MAXNUM_MCADDR 8
+
+/** List of multicast MAC addresses */
+struct s_PXENV_UNDI_MCAST_ADDRESS {
+ /** Number of multicast MAC addresses */
+ UINT16_t MCastAddrCount;
+ /** List of up to #MAXNUM_MCADDR multicast MAC addresses */
+ MAC_ADDR_t McastAddr[MAXNUM_MCADDR];
+} PACKED;
+
+typedef struct s_PXENV_UNDI_MCAST_ADDRESS PXENV_UNDI_MCAST_ADDRESS_t;
+
+/** Parameter block for pxenv_undi_reset_adapter() */
+struct s_PXENV_UNDI_RESET {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Multicast MAC addresses */
+ struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} PACKED;
+
+typedef struct s_PXENV_UNDI_RESET PXENV_UNDI_RESET_t;
+
+extern PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
+ *undi_reset_adapter );
+
+/** @} */ /* pxenv_undi_reset_adapter */
+
+/** @defgroup pxenv_undi_shutdown PXENV_UNDI_SHUTDOWN
+ *
+ * UNDI SHUTDOWN
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_shutdown() */
+#define PXENV_UNDI_SHUTDOWN 0x0005
+
+/** Parameter block for pxenv_undi_shutdown() */
+struct s_PXENV_UNDI_SHUTDOWN {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_SHUTDOWN PXENV_UNDI_SHUTDOWN_t;
+
+extern PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
+ *undi_shutdown );
+
+/** @} */ /* pxenv_undi_shutdown */
+
+/** @defgroup pxenv_undi_open PXENV_UNDI_OPEN
+ *
+ * UNDI OPEN
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_open() */
+#define PXENV_UNDI_OPEN 0x0006
+
+/** Accept "directed" packets
+ *
+ * These are packets addresses to either this adapter's MAC address or
+ * to any of the configured multicast MAC addresses (see
+ * #s_PXENV_UNDI_MCAST_ADDRESS).
+ */
+#define FLTR_DIRECTED 0x0001
+/** Accept broadcast packets */
+#define FLTR_BRDCST 0x0002
+/** Accept all packets; listen in promiscuous mode */
+#define FLTR_PRMSCS 0x0004
+/** Accept source-routed packets */
+#define FLTR_SRC_RTG 0x0008
+
+/** Parameter block for pxenv_undi_open() */
+struct s_PXENV_UNDI_OPEN {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Open flags as defined in NDIS 2.0
+ *
+ * This is the OpenOptions field as passed to the NDIS 2.0
+ * OpenAdapter() API call. It is defined to be "adapter
+ * specific", though 0 is guaranteed to be a valid value.
+ */
+ UINT16_t OpenFlag;
+ /** Receive packet filter
+ *
+ * This is the bitwise-OR of any of the following flags:
+ * #FLTR_DIRECTED, #FLTR_BRDCST, #FLTR_PRMSCS and
+ * #FLTR_SRC_RTG.
+ */
+ UINT16_t PktFilter;
+ /** Multicast MAC addresses */
+ struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} PACKED;
+
+typedef struct s_PXENV_UNDI_OPEN PXENV_UNDI_OPEN_t;
+
+extern PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open );
+
+/** @} */ /* pxenv_undi_open */
+
+/** @defgroup pxenv_undi_close PXENV_UNDI_CLOSE
+ *
+ * UNDI CLOSE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_close() */
+#define PXENV_UNDI_CLOSE 0x0007
+
+/** Parameter block for pxenv_undi_close() */
+struct s_PXENV_UNDI_CLOSE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_CLOSE PXENV_UNDI_CLOSE_t;
+
+extern PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close );
+
+/** @} */ /* pxenv_undi_close */
+
+/** @defgroup pxenv_undi_transmit PXENV_UNDI_TRANSMIT
+ *
+ * UNDI TRANSMIT PACKET
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_transmit() */
+#define PXENV_UNDI_TRANSMIT 0x0008
+
+#define P_UNKNOWN 0 /**< Media header already filled in */
+#define P_IP 1 /**< IP protocol */
+#define P_ARP 2 /**< ARP protocol */
+#define P_RARP 3 /**< RARP protocol */
+#define P_OTHER 4 /**< Other protocol */
+
+#define XMT_DESTADDR 0x0000 /**< Unicast packet */
+#define XMT_BROADCAST 0x0001 /**< Broadcast packet */
+
+/** Maximum number of data blocks in a transmit buffer descriptor */
+#define MAX_DATA_BLKS 8
+
+/** A transmit buffer descriptor, as pointed to by s_PXENV_UNDI_TRANSMIT::TBD
+ */
+struct s_PXENV_UNDI_TBD {
+ UINT16_t ImmedLength; /**< Length of the transmit buffer */
+ SEGOFF16_t Xmit; /**< Address of the transmit buffer */
+ UINT16_t DataBlkCount;
+ /** Array of up to #MAX_DATA_BLKS additional transmit buffers */
+ struct DataBlk {
+ /** Always 1
+ *
+ * A value of 0 would indicate that #TDDataPtr were an
+ * #ADDR32_t rather than a #SEGOFF16_t. The PXE
+ * specification version 2.1 explicitly states that
+ * this is not supported; #TDDataPtr will always be a
+ * #SEGOFF16_t.
+ */
+ UINT8_t TDPtrType;
+ UINT8_t TDRsvdByte; /**< Must be zero */
+ UINT16_t TDDataLen; /**< Length of this transmit buffer */
+ SEGOFF16_t TDDataPtr; /**< Address of this transmit buffer */
+ } DataBlock[MAX_DATA_BLKS];
+} PACKED;
+
+typedef struct s_PXENV_UNDI_TBD PXENV_UNDI_TBD_t;
+
+/** Parameter block for pxenv_undi_transmit() */
+struct s_PXENV_UNDI_TRANSMIT {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Protocol
+ *
+ * Valid values are #P_UNKNOWN, #P_IP, #P_ARP or #P_RARP. If
+ * the caller has already filled in the media header, this
+ * field must be set to #P_UNKNOWN.
+ */
+ UINT8_t Protocol;
+ /** Unicast/broadcast flag
+ *
+ * Valid values are #XMT_DESTADDR or #XMT_BROADCAST.
+ */
+ UINT8_t XmitFlag;
+ SEGOFF16_t DestAddr; /**< Destination MAC address */
+ /** Address of the Transmit Buffer Descriptor
+ *
+ * This is a pointer to a struct s_PXENV_UNDI_TBD.
+ */
+ SEGOFF16_t TBD;
+ UINT32_t Reserved[2]; /**< Must be zero */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_TRANSMIT PXENV_UNDI_TRANSMIT_t;
+
+extern PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
+ *undi_transmit );
+
+/** @} */ /* pxenv_undi_transmit */
+
+/** @defgroup pxenv_undi_set_mcast_address PXENV_UNDI_SET_MCAST_ADDRESS
+ *
+ * UNDI SET MULTICAST ADDRESS
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_set_mcast_address() */
+#define PXENV_UNDI_SET_MCAST_ADDRESS 0x0009
+
+/** Parameter block for pxenv_undi_set_mcast_address() */
+struct s_PXENV_UNDI_SET_MCAST_ADDRESS {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** List of multicast addresses */
+ struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} PACKED;
+
+typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS PXENV_UNDI_SET_MCAST_ADDRESS_t;
+
+extern PXENV_EXIT_t pxenv_undi_set_mcast_address (
+ struct s_PXENV_UNDI_SET_MCAST_ADDRESS *undi_set_mcast_address );
+
+/** @} */ /* pxenv_undi_set_mcast_address */
+
+/** @defgroup pxenv_undi_set_station_address PXENV_UNDI_SET_STATION_ADDRESS
+ *
+ * UNDI SET STATION ADDRESS
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_set_station_address() */
+#define PXENV_UNDI_SET_STATION_ADDRESS 0x000a
+
+/** Parameter block for pxenv_undi_set_station_address() */
+struct s_PXENV_UNDI_SET_STATION_ADDRESS {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ MAC_ADDR_t StationAddress; /**< Station MAC address */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS PXENV_UNDI_SET_STATION_ADDRESS_t;
+
+extern PXENV_EXIT_t pxenv_undi_set_station_address (
+ struct s_PXENV_UNDI_SET_STATION_ADDRESS *undi_set_station_address );
+
+/** @} */ /* pxenv_undi_set_station_address */
+
+/** @defgroup pxenv_undi_set_packet_filter PXENV_UNDI_SET_PACKET_FILTER
+ *
+ * UNDI SET PACKET FILTER
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_set_packet_filter() */
+#define PXENV_UNDI_SET_PACKET_FILTER 0x000b
+
+/** Parameter block for pxenv_undi_set_packet_filter() */
+struct s_PXENV_UNDI_SET_PACKET_FILTER {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Receive packet filter
+ *
+ * This field takes the same values as
+ * s_PXENV_UNDI_OPEN::PktFilter.
+ *
+ * @note Yes, this field is a different size to
+ * s_PXENV_UNDI_OPEN::PktFilter. Blame "the managers at Intel
+ * who apparently let a consultant come up with the spec
+ * without any kind of adult supervision" (quote from hpa).
+ */
+ UINT8_t filter;
+} PACKED;
+
+typedef struct s_PXENV_UNDI_SET_PACKET_FILTER PXENV_UNDI_SET_PACKET_FILTER_t;
+
+extern PXENV_EXIT_t pxenv_undi_set_packet_filter (
+ struct s_PXENV_UNDI_SET_PACKET_FILTER *undi_set_packet_filter );
+
+/** @} */ /* pxenv_undi_set_packet_filter */
+
+/** @defgroup pxenv_undi_get_information PXENV_UNDI_GET_INFORMATION
+ *
+ * UNDI GET INFORMATION
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_get_information() */
+#define PXENV_UNDI_GET_INFORMATION 0x000c
+
+#define ETHER_TYPE 1 /**< Ethernet (10Mb) */
+#define EXP_ETHER_TYPE 2 /**< Experimental Ethernet (3Mb) */
+#define AX25_TYPE 3 /**< Amateur Radio AX.25 */
+#define TOKEN_RING_TYPE 4 /**< Proteon ProNET Token Ring */
+#define CHAOS_TYPE 5 /**< Chaos */
+#define IEEE_TYPE 6 /**< IEEE 802 Networks */
+#define ARCNET_TYPE 7 /**< ARCNET */
+
+/** Parameter block for pxenv_undi_get_information() */
+struct s_PXENV_UNDI_GET_INFORMATION {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ UINT16_t BaseIo; /**< I/O base address */
+ UINT16_t IntNumber; /**< IRQ number */
+ UINT16_t MaxTranUnit; /**< Adapter MTU */
+ /** Hardware type
+ *
+ * Valid values are defined in RFC1010 ("Assigned numbers"),
+ * and are #ETHER_TYPE, #EXP_ETHER_TYPE, #AX25_TYPE,
+ * #TOKEN_RING_TYPE, #CHAOS_TYPE, #IEEE_TYPE or #ARCNET_TYPE.
+ */
+ UINT16_t HwType;
+ UINT16_t HwAddrLen; /**< MAC address length */
+ MAC_ADDR_t CurrentNodeAddress; /**< Current MAC address */
+ MAC_ADDR_t PermNodeAddress; /**< Permanent (EEPROM) MAC address */
+ SEGSEL_t ROMAddress; /**< Real-mode ROM segment address */
+ UINT16_t RxBufCt; /**< Receive queue length */
+ UINT16_t TxBufCt; /**< Transmit queue length */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_GET_INFORMATION PXENV_UNDI_GET_INFORMATION_t;
+
+extern PXENV_EXIT_t pxenv_undi_get_information (
+ struct s_PXENV_UNDI_GET_INFORMATION *undi_get_information );
+
+/** @} */ /* pxenv_undi_get_information */
+
+/** @defgroup pxenv_undi_get_statistics PXENV_UNDI_GET_STATISTICS
+ *
+ * UNDI GET STATISTICS
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_get_statistics() */
+#define PXENV_UNDI_GET_STATISTICS 0x000d
+
+/** Parameter block for pxenv_undi_get_statistics() */
+struct s_PXENV_UNDI_GET_STATISTICS {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ UINT32_t XmtGoodFrames; /**< Successful transmission count */
+ UINT32_t RcvGoodFrames; /**< Successful reception count */
+ UINT32_t RcvCRCErrors; /**< Receive CRC error count */
+ UINT32_t RcvResourceErrors; /**< Receive queue overflow count */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_GET_STATISTICS PXENV_UNDI_GET_STATISTICS_t;
+
+extern PXENV_EXIT_t pxenv_undi_get_statistics (
+ struct s_PXENV_UNDI_GET_STATISTICS *undi_get_statistics );
+
+/** @} */ /* pxenv_undi_get_statistics */
+
+/** @defgroup pxenv_undi_clear_statistics PXENV_UNDI_CLEAR_STATISTICS
+ *
+ * UNDI CLEAR STATISTICS
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_clear_statistics() */
+#define PXENV_UNDI_CLEAR_STATISTICS 0x000e
+
+/** Parameter block for pxenv_undi_clear_statistics() */
+struct s_PXENV_UNDI_CLEAR_STATISTICS {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_CLEAR_STATISTICS PXENV_UNDI_CLEAR_STATISTICS_t;
+
+extern PXENV_EXIT_t pxenv_undi_clear_statistics (
+ struct s_PXENV_UNDI_CLEAR_STATISTICS *undi_clear_statistics );
+
+/** @} */ /* pxenv_undi_clear_statistics */
+
+/** @defgroup pxenv_undi_initiate_diags PXENV_UNDI_INITIATE_DIAGS
+ *
+ * UNDI INITIATE DIAGS
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_initiate_diags() */
+#define PXENV_UNDI_INITIATE_DIAGS 0x000f
+
+/** Parameter block for pxenv_undi_initiate_diags() */
+struct s_PXENV_UNDI_INITIATE_DIAGS {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_INITIATE_DIAGS PXENV_UNDI_INITIATE_DIAGS_t;
+
+extern PXENV_EXIT_t pxenv_undi_initiate_diags (
+ struct s_PXENV_UNDI_INITIATE_DIAGS *undi_initiate_diags );
+
+/** @} */ /* pxenv_undi_initiate_diags */
+
+/** @defgroup pxenv_undi_force_interrupt PXENV_UNDI_FORCE_INTERRUPT
+ *
+ * UNDI FORCE INTERRUPT
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_force_interrupt() */
+#define PXENV_UNDI_FORCE_INTERRUPT 0x0010
+
+/** Parameter block for pxenv_undi_force_interrupt() */
+struct s_PXENV_UNDI_FORCE_INTERRUPT {
+ PXENV_STATUS_t Status; /**< PXE status code */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_FORCE_INTERRUPT PXENV_UNDI_FORCE_INTERRUPT_t;
+
+extern PXENV_EXIT_t pxenv_undi_force_interrupt (
+ struct s_PXENV_UNDI_FORCE_INTERRUPT *undi_force_interrupt );
+
+/** @} */ /* pxenv_undi_force_interrupt */
+
+/** @defgroup pxenv_undi_get_mcast_address PXENV_UNDI_GET_MCAST_ADDRESS
+ *
+ * UNDI GET MULTICAST ADDRESS
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_get_mcast_address() */
+#define PXENV_UNDI_GET_MCAST_ADDRESS 0x0011
+
+/** Parameter block for pxenv_undi_get_mcast_address() */
+struct s_PXENV_UNDI_GET_MCAST_ADDRESS {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ IP4_t InetAddr; /**< Multicast IP address */
+ MAC_ADDR_t MediaAddr; /**< Multicast MAC address */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS PXENV_UNDI_GET_MCAST_ADDRESS_t;
+
+extern PXENV_EXIT_t pxenv_undi_get_mcast_address (
+ struct s_PXENV_UNDI_GET_MCAST_ADDRESS *undi_get_mcast_address );
+
+/** @} */ /* pxenv_undi_get_mcast_address */
+
+/** @defgroup pxenv_undi_get_nic_type PXENV_UNDI_GET_NIC_TYPE
+ *
+ * UNDI GET NIC TYPE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_get_nic_type() */
+#define PXENV_UNDI_GET_NIC_TYPE 0x0012
+
+#define PCI_NIC 2 /**< PCI network card */
+#define PnP_NIC 3 /**< ISAPnP network card */
+#define CardBus_NIC 4 /**< CardBus network card */
+
+/** Information for a PCI or equivalent NIC */
+struct pci_nic_info {
+ UINT16_t Vendor_ID; /**< PCI vendor ID */
+ UINT16_t Dev_ID; /**< PCI device ID */
+ UINT8_t Base_Class; /**< PCI base class */
+ UINT8_t Sub_Class; /**< PCI sub class */
+ UINT8_t Prog_Intf; /**< PCI programming interface */
+ UINT8_t Rev; /**< PCI revision */
+ UINT16_t BusDevFunc; /**< PCI bus:dev:fn address */
+ UINT16_t SubVendor_ID; /**< PCI subvendor ID */
+ UINT16_t SubDevice_ID; /**< PCI subdevice ID */
+} PACKED;
+
+/** Information for an ISAPnP or equivalent NIC */
+struct pnp_nic_info {
+ UINT32_t EISA_Dev_ID; /**< EISA device ID */
+ UINT8_t Base_Class; /**< Base class */
+ UINT8_t Sub_Class; /**< Sub class */
+ UINT8_t Prog_Intf; /**< Programming interface */
+ /** Card Select Number assigned to card */
+ UINT16_t CardSelNum;
+} PACKED;
+
+/** Parameter block for pxenv_undi_get_nic_type() */
+struct s_PXENV_UNDI_GET_NIC_TYPE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** NIC type
+ *
+ * Valid values are #PCI_NIC, #PnP_NIC or #CardBus_NIC.
+ */
+ UINT8_t NicType;
+ /** NIC information */
+ union nic_type_info {
+ /** NIC information (if #NicType==#PCI_NIC) */
+ struct pci_nic_info pci;
+ /** NIC information (if #NicType==#CardBus_NIC) */
+ struct pci_nic_info cardbus;
+ /** NIC information (if #NicType==#PnP_NIC) */
+ struct pnp_nic_info pnp;
+ } info;
+} PACKED;
+
+typedef struct s_PXENV_UNDI_GET_NIC_TYPE PXENV_UNDI_GET_NIC_TYPE_t;
+
+extern PXENV_EXIT_t pxenv_undi_get_nic_type (
+ struct s_PXENV_UNDI_GET_NIC_TYPE *undi_get_nic_type );
+
+/** @} */ /* pxenv_undi_get_nic_type */
+
+/** @defgroup pxenv_undi_get_iface_info PXENV_UNDI_GET_IFACE_INFO
+ *
+ * UNDI GET IFACE INFO
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_get_iface_info() */
+#define PXENV_UNDI_GET_IFACE_INFO 0x0013
+
+/** Parameter block for pxenv_undi_get_iface_info() */
+struct s_PXENV_UNDI_GET_IFACE_INFO {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Interface type
+ *
+ * This is defined in the NDIS 2.0 specification to be one of
+ * the strings "802.3", "802.4", "802.5", "802.6", "DIX",
+ * "DIX+802.3", "APPLETALK", "ARCNET", "FDDI", "SDLC", "BSC",
+ * "HDLC", or "ISDN".
+ *
+ * "Normal" Ethernet, for various historical reasons, is
+ * "DIX+802.3".
+ */
+ UINT8_t IfaceType[16];
+ UINT32_t LinkSpeed; /**< Link speed, in bits per second */
+ /** Service flags
+ *
+ * These are the "service flags" defined in the "MAC
+ * Service-Specific Characteristics" table in the NDIS 2.0
+ * specification. Almost all of them are irrelevant to PXE.
+ */
+ UINT32_t ServiceFlags;
+ UINT32_t Reserved[4]; /**< Must be zero */
+} PACKED;
+
+typedef struct s_PXENV_UNDI_GET_IFACE_INFO PXENV_UNDI_GET_IFACE_INFO_t;
+
+extern PXENV_EXIT_t pxenv_undi_get_iface_info (
+ struct s_PXENV_UNDI_GET_IFACE_INFO *undi_get_iface_info );
+
+/** @} */ /* pxenv_undi_get_iface_info */
+
+/** @defgroup pxenv_undi_get_state PXENV_UNDI_GET_STATE
+ *
+ * UNDI GET STATE
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_get_state() */
+#define PXENV_UNDI_GET_STATE 0x0015
+
+/** pxenv_start_undi() has been called */
+#define PXE_UNDI_GET_STATE_STARTED 1
+/** pxenv_undi_initialize() has been called */
+#define PXE_UNDI_GET_STATE_INITIALIZED 2
+/** pxenv_undi_open() has been called */
+#define PXE_UNDI_GET_STATE_OPENED 3
+
+/** Parameter block for pxenv_undi_get_state() */
+struct s_PXENV_UNDI_GET_STATE {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Current state of the UNDI driver
+ *
+ * Valid values are #PXE_UNDI_GET_STATE_STARTED,
+ * #PXE_UNDI_GET_STATE_INITIALIZED or
+ * #PXE_UNDI_GET_STATE_OPENED.
+ */
+ UINT8_t UNDIstate;
+} PACKED;
+
+typedef struct s_PXENV_UNDI_GET_STATE PXENV_UNDI_GET_STATE_t;
+
+extern PXENV_EXIT_t pxenv_undi_get_state ( struct s_PXENV_UNDI_GET_STATE
+ *undi_get_state );
+
+/** @} */ /* pxenv_undi_get_state */
+
+/** @defgroup pxenv_undi_isr PXENV_UNDI_ISR
+ *
+ * UNDI ISR
+ *
+ * @{
+ */
+
+/** PXE API function code for pxenv_undi_isr() */
+#define PXENV_UNDI_ISR 0x0014
+
+/** Determine whether or not this is our interrupt */
+#define PXENV_UNDI_ISR_IN_START 1
+/** Start processing interrupt */
+#define PXENV_UNDI_ISR_IN_PROCESS 2
+/** Continue processing interrupt */
+#define PXENV_UNDI_ISR_IN_GET_NEXT 3
+/** This interrupt was ours */
+#define PXENV_UNDI_ISR_OUT_OURS 0
+/** This interrupt was not ours */
+#define PXENV_UNDI_ISR_OUT_NOT_OURS 1
+/** Finished processing interrupt */
+#define PXENV_UNDI_ISR_OUT_DONE 0
+/** A packet transmission has completed */
+#define PXENV_UNDI_ISR_OUT_TRANSMIT 2
+/** A packet has been received */
+#define PXENV_UNDI_ISR_OUT_RECEIVE 3
+/** We are already in the middle of processing an interrupt */
+#define PXENV_UNDI_ISR_OUT_BUSY 4
+
+/** Unicast packet (or packet captured in promiscuous mode) */
+#define P_DIRECTED 0
+/** Broadcast packet */
+#define P_BROADCAST 1
+/** Multicast packet */
+#define P_MULTICAST 2
+
+/** Parameter block for pxenv_undi_isr() */
+struct s_PXENV_UNDI_ISR {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Function flag
+ *
+ * Valid values are #PXENV_UNDI_ISR_IN_START,
+ * #PXENV_UNDI_ISR_IN_PROCESS, #PXENV_UNDI_ISR_IN_GET_NEXT,
+ * #PXENV_UNDI_ISR_OUT_OURS, #PXENV_UNDI_ISR_OUT_NOT_OURS,
+ * #PXENV_UNDI_ISR_OUT_DONE, #PXENV_UNDI_ISR_OUT_TRANSMIT,
+ * #PXENV_UNDI_ISR_OUT_RECEIVE or #PXENV_UNDI_ISR_OUT_BUSY.
+ */
+ UINT16_t FuncFlag;
+ UINT16_t BufferLength; /**< Data buffer length */
+ UINT16_t FrameLength; /**< Total frame length */
+ UINT16_t FrameHeaderLength; /**< Frame header length */
+ SEGOFF16_t Frame; /**< Data buffer address */
+ /** Protocol type
+ *
+ * Valid values are #P_IP, #P_ARP, #P_RARP or #P_OTHER.
+ */
+ UINT8_t ProtType;
+ /** Packet type
+ *
+ * Valid values are #P_DIRECTED, #P_BROADCAST or #P_MULTICAST.
+ */
+ UINT8_t PktType;
+} PACKED;
+
+typedef struct s_PXENV_UNDI_ISR PXENV_UNDI_ISR_t;
+
+extern PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr );
+
+/** @} */ /* pxenv_undi_isr */
+
+/** @} */ /* pxe_undi_api */
+
+/** @defgroup pxe_loader_api PXE Loader API
+ *
+ * The UNDI ROM loader API
+ *
+ * @{
+ */
+
+/** The UNDI ROM ID structure */
+struct s_UNDI_ROM_ID {
+ /** Signature
+ *
+ * Contains the bytes 'U', 'N', 'D', 'I'.
+ */
+ UINT32_t Signature;
+ UINT8_t StructLength; /**< Length of this structure */
+ /** Checksum
+ *
+ * The byte checksum of this structure (using the length in
+ * #StructLength) must be zero.
+ */
+ UINT8_t StructCksum;
+ /** Revision of this structure
+ *
+ * For PXE version 2.1, this field must be zero.
+ */
+ UINT8_t StructRev;
+ /** UNDI revision
+ *
+ * UNDI revision, least significant byte first. For UNDI
+ * version 2.1.0, this field will contain { 0x00, 0x01, 0x02 }.
+ */
+ UINT8_t UNDIRev[3];
+ /** UNDI loader routine entry point
+ *
+ * This is the entry point for calling undi_loader().
+ */
+ UINT16_t UNDILoader;
+ /** Minimum required stack segment size */
+ UINT16_t StackSize;
+ /** Minimum required data segment size */
+ UINT16_t DataSize;
+ /** Minimum required code segment size */
+ UINT16_t CodeSize;
+} PACKED;
+
+typedef struct s_UNDI_ROM_ID UNDI_ROM_ID_t;
+
+/** Parameter block for undi_loader() */
+struct s_UNDI_LOADER {
+ /** struct s_UNDI_LOADER starts with a struct s_PXENV_START_UNDI */
+ union undi_loader_start_undi {
+ PXENV_STATUS_t Status; /**< PXE status code */
+ /** Parameters to pass to pxenv_start_undi() */
+ struct s_PXENV_START_UNDI start_undi;
+ } u;
+ /** UNDI data segment
+ *
+ * @note The PXE specification defines the type of this field
+ * as #UINT16_t. For x86, #SEGSEL_t and #UINT16_t are
+ * equivalent anyway; for other architectures #SEGSEL_t makes
+ * more sense.
+ */
+ SEGSEL_t undi_ds;
+ /** UNDI code segment
+ *
+ * @note The PXE specification defines the type of this field
+ * as #UINT16_t. For x86, #SEGSEL_t and #UINT16_t are
+ * equivalent anyway; for other architectures #SEGSEL_t makes
+ * more sense.
+ */
+ SEGSEL_t undi_cs;
+ /** Address of the !PXE structure (a struct s_PXE) */
+ SEGOFF16_t pxe_ptr;
+ /** Address of the PXENV+ structure (a struct s_PXENV) */
+ SEGOFF16_t pxenv_ptr;
+} PACKED;
+
+typedef struct s_UNDI_LOADER UNDI_LOADER_t;
+
+extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader );
+
+/** @} */ /* pxe_loader_api */
+
+/** @} */ /* pxe */
+
+/** @page pxe_notes Etherboot PXE implementation notes
+
+@section pxe_routing IP routing
+
+Several PXE API calls (e.g. pxenv_tftp_open() and pxenv_udp_write())
+allow for the caller to specify a "relay agent IP address", often in a
+field called "gateway" or similar. The PXE specification states that
+"The IP layer should provide space for a minimum of four routing
+entries obtained from the default router and static route DHCP option
+tags in the DHCPACK message, plus any non-zero giaddr field from the
+DHCPOFFER message(s) accepted by the client".
+
+The DHCP static route option ("option static-routes" in dhcpd.conf)
+works only for classed IP routing (i.e. it provides no way to specify
+a subnet mask). Since virtually everything now uses classless IP
+routing, the DHCP static route option is almost totally useless, and
+is (according to the dhcp-options man page) not implemented by any of
+the popular DHCP clients.
+
+This leaves the caller-specified "relay agent IP address", the giaddr
+field from the DHCPOFFER message(s) and the default gateway(s)
+provided via the routers option ("option routers" in dhcpd.conf) in
+the DHCPACK message. Each of these is a default gateway address.
+It's a fair bet that the routers option should take priority over the
+giaddr field, since the routers option has to be explicitly specified
+by the DHCP server operator. Similarly, it's fair to assume that the
+caller-specified "relay agent IP address", if present, should take
+priority over any other routing table entries.
+
+@bug Etherboot currently ignores all potential sources of routing
+information other than the first router provided to it by a DHCP
+routers option.
+
+@section pxe_x86_modes x86 processor mode restrictions
+
+On the x86 platform, different PXE API calls have different
+restrictions on the processor modes (real or protected) that can be
+used. See the individual API call descriptions for the restrictions
+that apply to any particular call.
+
+@subsection pxe_x86_pmode16 Real mode, or protected-mode with 16-bit stack
+
+The PXE specification states that the API function can be called in
+protected mode only if the s_PXE::StatusCallout field is set to a
+non-zero value, and that the API function cannot be called with a
+32-bit stack segment.
+
+Etherboot does not enforce either of these restrictions; they seem (as
+with so much of the PXE specification) to be artifacts of the Intel
+implementation.
+
+*/
+
+#endif /* PXE_API_H */
diff --git a/src/include/pxe_export.h b/src/include/pxe_export.h
deleted file mode 100644
index 3d39e73cf..000000000
--- a/src/include/pxe_export.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Header for pxe_export.c
- */
-
-#ifndef PXE_EXPORT_H
-#define PXE_EXPORT_H
-
-#include "pxe.h"
-
-/* Function prototypes */
-extern int ensure_pxe_state ( pxe_stack_state_t wanted );
-
-extern PXENV_EXIT_t pxenv_start_undi ( t_PXENV_START_UNDI * );
-extern PXENV_EXIT_t pxenv_undi_startup ( t_PXENV_UNDI_STARTUP * );
-extern PXENV_EXIT_t pxenv_undi_cleanup ( t_PXENV_UNDI_CLEANUP * );
-extern PXENV_EXIT_t pxenv_undi_initialize ( t_PXENV_UNDI_INITIALIZE * );
-extern PXENV_EXIT_t pxenv_undi_reset_adapter ( t_PXENV_UNDI_RESET_ADAPTER * );
-extern PXENV_EXIT_t pxenv_undi_shutdown ( t_PXENV_UNDI_SHUTDOWN * );
-extern PXENV_EXIT_t pxenv_undi_open ( t_PXENV_UNDI_OPEN * );
-extern PXENV_EXIT_t pxenv_undi_close ( t_PXENV_UNDI_CLOSE * );
-extern PXENV_EXIT_t pxenv_undi_transmit ( t_PXENV_UNDI_TRANSMIT * );
-extern PXENV_EXIT_t pxenv_undi_set_mcast_address (
- t_PXENV_UNDI_SET_MCAST_ADDRESS * );
-extern PXENV_EXIT_t pxenv_undi_set_station_address (
- t_PXENV_UNDI_SET_STATION_ADDRESS * );
-extern PXENV_EXIT_t pxenv_undi_set_packet_filter (
- t_PXENV_UNDI_SET_PACKET_FILTER * );
-extern PXENV_EXIT_t pxenv_undi_get_information (
- t_PXENV_UNDI_GET_INFORMATION * );
-extern PXENV_EXIT_t pxenv_undi_get_statistics ( t_PXENV_UNDI_GET_STATISTICS* );
-extern PXENV_EXIT_t pxenv_undi_clear_statistics (
- t_PXENV_UNDI_CLEAR_STATISTICS * );
-extern PXENV_EXIT_t pxenv_undi_initiate_diags ( t_PXENV_UNDI_INITIATE_DIAGS* );
-extern PXENV_EXIT_t pxenv_undi_force_interrupt (
- t_PXENV_UNDI_FORCE_INTERRUPT * );
-extern PXENV_EXIT_t pxenv_undi_get_mcast_address (
- t_PXENV_UNDI_GET_MCAST_ADDRESS * );
-extern PXENV_EXIT_t pxenv_undi_get_nic_type ( t_PXENV_UNDI_GET_NIC_TYPE * );
-extern PXENV_EXIT_t pxenv_undi_get_iface_info ( t_PXENV_UNDI_GET_IFACE_INFO *);
-extern PXENV_EXIT_t pxenv_undi_isr ( t_PXENV_UNDI_ISR * );
-extern PXENV_EXIT_t pxenv_stop_undi ( t_PXENV_STOP_UNDI * );
-extern PXENV_EXIT_t pxenv_tftp_open ( t_PXENV_TFTP_OPEN * );
-extern PXENV_EXIT_t pxenv_tftp_close ( t_PXENV_TFTP_CLOSE * );
-extern PXENV_EXIT_t pxenv_tftp_read ( t_PXENV_TFTP_READ * );
-extern PXENV_EXIT_t pxenv_tftp_read_file ( t_PXENV_TFTP_READ_FILE * );
-extern PXENV_EXIT_t pxenv_tftp_get_fsize ( t_PXENV_TFTP_GET_FSIZE * );
-extern PXENV_EXIT_t pxenv_udp_open ( t_PXENV_UDP_OPEN * );
-extern PXENV_EXIT_t pxenv_udp_close ( t_PXENV_UDP_CLOSE * );
-extern PXENV_EXIT_t pxenv_udp_read ( t_PXENV_UDP_READ * );
-extern PXENV_EXIT_t pxenv_udp_write ( t_PXENV_UDP_WRITE * );
-extern PXENV_EXIT_t pxenv_unload_stack ( t_PXENV_UNLOAD_STACK * );
-extern PXENV_EXIT_t pxenv_get_cached_info ( t_PXENV_GET_CACHED_INFO * );
-extern PXENV_EXIT_t pxenv_restart_tftp ( t_PXENV_RESTART_TFTP * );
-extern PXENV_EXIT_t pxenv_start_base ( t_PXENV_START_BASE * );
-extern PXENV_EXIT_t pxenv_stop_base ( t_PXENV_STOP_BASE * );
-
-extern PXENV_EXIT_t pxe_api_call ( int opcode, t_PXENV_ANY *params );
-
-/* Static variables */
-extern pxe_stack_t *pxe_stack;
-
-#endif /* PXE_EXPORT_H */
diff --git a/src/include/pxe_types.h b/src/include/pxe_types.h
new file mode 100644
index 000000000..80e6aa17c
--- /dev/null
+++ b/src/include/pxe_types.h
@@ -0,0 +1,126 @@
+#ifndef PXE_TYPES_H
+#define PXE_TYPES_H
+
+/** @file
+ *
+ * PXE data types
+ *
+ */
+
+#include "stdint.h"
+#include "pxe_addr.h" /* Architecture-specific PXE definitions */
+#include "errno.h" /* PXE status codes */
+
+/** @addtogroup pxe Preboot eXecution Environment (PXE) API
+ * @{
+ */
+
+/** @defgroup pxe_types PXE data types
+ *
+ * Basic PXE data types such as #UINT16_t, #ADDR32_t, #SEGSEL_t etc.
+ *
+ * These definitions are based on Table 1-1 ("Data Type Definitions")
+ * in the Intel PXE specification version 2.1. They have been
+ * generalised to non-x86 architectures where possible.
+ *
+ * @{
+ */
+
+/** An 8-bit unsigned integer */
+typedef uint8_t UINT8_t;
+
+/** A 16-bit unsigned integer */
+typedef uint16_t UINT16_t;
+
+/** A 32-bit unsigned integer */
+typedef uint32_t UINT32_t;
+
+/** A PXE exit code.
+ *
+ * Permitted values are #PXENV_EXIT_SUCCESS and #PXENV_EXIT_FAILURE.
+ *
+ */
+typedef UINT16_t PXENV_EXIT_t;
+#define PXENV_EXIT_SUCCESS 0x0000 /**< No error occurred */
+#define PXENV_EXIT_FAILURE 0x0001 /**< An error occurred */
+
+/** A PXE status code.
+ *
+ * Status codes are defined in errno.h.
+ *
+ */
+typedef UINT16_t PXENV_STATUS_t;
+
+/** An IPv4 address.
+ *
+ * @note This data type is in network (big-endian) byte order.
+ *
+ */
+typedef UINT32_t IP4_t;
+
+/** A UDP port.
+ *
+ * @note This data type is in network (big-endian) byte order.
+ *
+ */
+typedef UINT16_t UDP_PORT_t;
+
+/** Maximum length of a MAC address */
+#define MAC_ADDR_LEN 16
+
+/** A MAC address */
+typedef UINT8_t MAC_ADDR_t[MAC_ADDR_LEN];
+
+#ifndef HAVE_ARCH_ADDR32
+/** A physical address.
+ *
+ * For x86, this is a 32-bit physical address, and is therefore
+ * limited to the low 4GB.
+ *
+ */
+typedef UINT32_t ADDR32_t;
+#endif
+
+#ifndef HAVE_ARCH_SEGSEL
+/** A segment selector.
+ *
+ * For x86, this is a real mode segment (0x0000-0xffff), or a
+ * protected-mode segment selector, such as could be loaded into a
+ * segment register.
+ *
+ */
+typedef UINT16_t SEGSEL_t;
+#endif
+
+#ifndef HAVE_ARCH_OFF16
+/** An offset within a segment identified by #SEGSEL
+ *
+ * For x86, this is a 16-bit offset.
+ *
+ */
+typedef UINT16_t OFF16_t;
+#endif
+
+/** A segment:offset address
+ *
+ * For x86, this is a 16-bit real-mode or protected-mode
+ * segment:offset address.
+ *
+ */
+typedef struct s_SEGOFF16 {
+ OFF16_t offset; /**< Offset within the segment */
+ SEGSEL_t segment; /**< Segment selector */
+} PACKED SEGOFF16_t;
+
+/** A segment descriptor */
+typedef struct s_SEGDESC {
+ SEGSEL_t segment_address; /**< Segment selector */
+ ADDR32_t physical_address; /**< Segment base address */
+ OFF16_t seg_size; /**< Size of the segment */
+} PACKED SEGDESC_t;
+
+/** @} */ /* pxe_types */
+
+/** @} */ /* pxe */
+
+#endif /* PXE_TYPES_H */
diff --git a/src/include/tables.h b/src/include/tables.h
index 26ad61db7..c3e05e55e 100644
--- a/src/include/tables.h
+++ b/src/include/tables.h
@@ -1,47 +1,171 @@
#ifndef TABLES_H
#define TABLES_H
-/*
- * Macros for dealing with linker-generated tables of fixed-size
- * symbols. We make fairly extensive use of these in order to avoid
- * ifdef spaghetti and/or linker symbol pollution. For example,
- * instead of having code such as
+/** @page ifdef_harmful #ifdef considered harmful
+ *
+ * Overuse of @c #ifdef has long been a problem in Etherboot.
+ * Etherboot provides a rich array of features, but all these features
+ * take up valuable space in a ROM image. The traditional solution to
+ * this problem has been for each feature to have its own @c #ifdef
+ * option, allowing the feature to be compiled in only if desired.
+ *
+ * The problem with this is that it becomes impossible to compile, let
+ * alone test, all possible versions of Etherboot. Code that is not
+ * typically used tends to suffer from bit-rot over time. It becomes
+ * extremely difficult to predict which combinations of compile-time
+ * options will result in code that can even compile and link
+ * correctly.
+ *
+ * To solve this problem, we have adopted a new approach from
+ * Etherboot 5.5 onwards. @c #ifdef is now "considered harmful", and
+ * its use should be minimised. Separate features should be
+ * implemented in separate @c .c files, and should \b always be
+ * compiled (i.e. they should \b not be guarded with a @c #ifdef @c
+ * MY_PET_FEATURE statement). By making (almost) all code always
+ * compile, we avoid the problem of bit-rot in rarely-used code.
+ *
+ * The file config.h, in combination with the @c make command line,
+ * specifies the objects that will be included in any particular build
+ * of Etherboot. For example, suppose that config.h includes the line
+ *
+ * @code
+ *
+ * #define CONSOLE_SERIAL
+ * #define DOWNLOAD_PROTO_TFTP
+ *
+ * @endcode
+ *
+ * When a particular Etherboot image (e.g. @c bin/rtl8139.zdsk) is
+ * built, the options specified in config.h are used to drag in the
+ * relevant objects at link-time. For the above example, serial.o and
+ * tftp.o would be linked in.
+ *
+ * There remains one problem to solve: how do these objects get used?
+ * Traditionally, we had code such as
+ *
+ * @code
+ *
+ * #ifdef CONSOLE_SERIAL
+ * serial_init();
+ * #endif
+ *
+ * @endcode
+ *
+ * in main.c, but this reintroduces @c #ifdef and so is a Bad Idea.
+ * We cannot simply remove the @c #ifdef and make it
+ *
+ * @code
*
- * #ifdef CONSOLE_SERIAL
* serial_init();
- * #endif
+ *
+ * @endcode
+ *
+ * because then serial.o would end up always being linked in.
+ *
+ * The solution is to use @link tables.h linker tables @endlink.
+ *
+ */
+
+/** @file
+ *
+ * Linker tables
+ *
+ * Read @ref ifdef_harmful first for some background on the motivation
+ * for using linker tables.
+ *
+ * This file provides macros for dealing with linker-generated tables
+ * of fixed-size symbols. We make fairly extensive use of these in
+ * order to avoid @c #ifdef spaghetti and/or linker symbol pollution.
+ * For example, instead of having code such as
+ *
+ * @code
+ *
+ * #ifdef CONSOLE_SERIAL
+ * serial_init();
+ * #endif
+ *
+ * @endcode
*
* we make serial.c generate an entry in the initialisation function
* table, and then have a function call_init_fns() that simply calls
* all functions present in this table. If and only if serial.o gets
* linked in, then its initialisation function will be called. We
* avoid linker symbol pollution (i.e. always dragging in serial.o
- * just because of a call to serial_init()) and we also avoid ifdef
- * spaghetti (having to conditionalise every reference to functions in
- * serial.c).
+ * just because of a call to serial_init()) and we also avoid @c
+ * #ifdef spaghetti (having to conditionalise every reference to
+ * functions in serial.c).
*
* The linker script takes care of assembling the tables for us. All
- * our table sections have names of the format ".tbl.NAME.NN" where
- * NAME designates the data structure stored in the table
- * (e.g. "init_fn") and NN is a two-digit decimal number used to
- * impose an ordering upon the tables if required. NN=00 is reserved
- * for the symbol indicating "table start", and NN=99 is reserved for
- * the symbol indicating "table end".
+ * our table sections have names of the format @c .tbl.NAME.NN where
+ * @c NAME designates the data structure stored in the table (e.g. @c
+ * init_fn) and @c NN is a two-digit decimal number used to impose an
+ * ordering upon the tables if required. @c NN=00 is reserved for the
+ * symbol indicating "table start", and @c NN=99 is reserved for the
+ * symbol indicating "table end".
+ *
+ * As an example, suppose that we want to create a "frobnicator"
+ * feature framework, and allow for several independent modules to
+ * provide frobnicating services. Then we would create a frob.h
+ * header file containing e.g.
+ *
+ * @code
+ *
+ * struct frobnicator {
+ * const char *name; // Name of the frobnicator
+ * void ( *frob ) ( void ); // The frobnicating function itself
+ * };
+ *
+ * #define __frobnicator __table ( frobnicators, 01 )
+ *
+ * @endcode
*
- * To define an entry in the "xxx" table:
+ * Any module providing frobnicating services would look something
+ * like
*
- * static struct xxx my_xxx __table(xxx,01) = { ... };
+ * @code
*
- * To access start and end markers for the "xxx" table:
+ * #include "frob.h"
*
- * static struct xxx xxx_start[0] __table_start(xxx);
- * static struct xxx xxx_end[0] __table_end(xxx);
+ * static void my_frob ( void ) {
+ * // Do my frobnicating
+ * ...
+ * }
*
- * See init.h and init.c for an example of how these macros are used
- * in practice.
+ * static struct frob my_frobnicator __frobnicator = {
+ * .name = "my_frob",
+ * .frob = my_frob,
+ * };
+ *
+ * @endcode
+ *
+ * The central frobnicator code (frob.c) would use the frobnicating
+ * modules as follows
+ *
+ * @code
+ *
+ * #include "frob.h"
+ *
+ * static struct frob frob_start[0] __table_start ( frobnicators );
+ * static struct frob frob_end[0] __table_end ( frobnicators );
+ *
+ * // Call all linked-in frobnicators
+ * void frob_all ( void ) {
+ * struct frob *frob;
+ *
+ * for ( frob = frob_start ; frob < frob_end ; frob++ ) {
+ * printf ( "Calling frobnicator \"%s\"\n", frob->name );
+ * frob->frob ();
+ * }
+ * }
+ *
+ * @endcode
+ *
+ * See init.h and init.c for a real-life example.
*
*/
+#include "compiler.h" /* for doxygen */
+
#define __table_str(x) #x
#define __table_section(table,idx) \
__section__ ( ".tbl." __table_str(table) "." __table_str(idx) )
@@ -49,10 +173,54 @@
#define __table_section_start(table) __table_section(table,00)
#define __table_section_end(table) __table_section(table,99)
+
+/**
+ * Linker table entry.
+ *
+ * Declares a data structure to be part of a linker table. Use as
+ * e.g.
+ *
+ * @code
+ *
+ * static struct my_foo __table ( foo, 01 ) = {
+ * ...
+ * };
+ *
+ * @endcode
+ *
+ */
#define __table(table,idx) \
__attribute__ (( unused, __table_section(table,idx) ))
+
+/**
+ * Linker table start marker.
+ *
+ * Declares a data structure (usually an empty data structure) to be
+ * the start of a linker table. Use as e.g.
+ *
+ * @code
+ *
+ * static struct foo_start[0] __table_start ( foo );
+ *
+ * @endcode
+ *
+ */
#define __table_start(table) \
__attribute__ (( unused, __table_section_start(table) ))
+
+/**
+ * Linker table end marker.
+ *
+ * Declares a data structure (usually an empty data structure) to be
+ * the end of a linker table. Use as e.g.
+ *
+ * @code
+ *
+ * static struct foo_end[0] __table_end ( foo );
+ *
+ * @endcode
+ *
+ */
#define __table_end(table) \
__attribute__ (( unused, __table_section_end(table) ))
diff --git a/src/include/tftp.h b/src/include/tftp.h
index 70192067c..2a086eb2b 100644
--- a/src/include/tftp.h
+++ b/src/include/tftp.h
@@ -1,13 +1,17 @@
#ifndef TFTP_H
#define TFTP_H
+/** @file */
+
#include "in.h"
#include "buffer.h"
#include "nic.h"
+#include "ip.h"
+#include "udp.h"
-#define TFTP_PORT 69
-#define TFTP_DEFAULTSIZE_PACKET 512
-#define TFTP_MAX_PACKET 1432 /* 512 */
+#define TFTP_PORT 69 /**< Default TFTP server port */
+#define TFTP_DEFAULT_BLKSIZE 512
+#define TFTP_MAX_BLKSIZE 1432 /* 512 */
#define TFTP_RRQ 1
#define TFTP_WRQ 2
@@ -16,53 +20,131 @@
#define TFTP_ERROR 5
#define TFTP_OACK 6
-#define TFTP_CODE_EOF 1
-#define TFTP_CODE_MORE 2
-#define TFTP_CODE_ERROR 3
-#define TFTP_CODE_BOOT 4
-#define TFTP_CODE_CFG 5
+#define TFTP_ERR_FILE_NOT_FOUND 1 /**< File not found */
+#define TFTP_ERR_ACCESS_DENIED 2 /**< Access violation */
+#define TFTP_ERR_DISK_FULL 3 /**< Disk full or allocation exceeded */
+#define TFTP_ERR_ILLEGAL_OP 4 /**< Illegal TFTP operation */
+#define TFTP_ERR_UNKNOWN_TID 5 /**< Unknown transfer ID */
+#define TFTP_ERR_FILE_EXISTS 6 /**< File already exists */
+#define TFTP_ERR_UNKNOWN_USER 7 /**< No such user */
+#define TFTP_ERR_BAD_OPTS 8 /**< Option negotiation failed */
+
+/** A TFTP request (RRQ) packet */
+struct tftp_rrq {
+ struct iphdr ip;
+ struct udphdr udp;
+ uint16_t opcode;
+ char data[TFTP_DEFAULT_BLKSIZE];
+} PACKED;
+
+/** A TFTP data (DATA) packet */
+struct tftp_data {
+ struct iphdr ip;
+ struct udphdr udp;
+ uint16_t opcode;
+ uint16_t block;
+ uint8_t data[TFTP_MAX_BLKSIZE];
+} PACKED;
+
+/** A TFTP acknowledgement (ACK) packet */
+struct tftp_ack {
+ struct iphdr ip;
+ struct udphdr udp;
+ uint16_t opcode;
+ uint16_t block;
+} PACKED;
+
+/** A TFTP error (ERROR) packet */
+struct tftp_error {
+ struct iphdr ip;
+ struct udphdr udp;
+ uint16_t opcode;
+ uint16_t errcode;
+ char errmsg[TFTP_DEFAULT_BLKSIZE];
+} PACKED;
-struct tftp_t {
+/** A TFTP options acknowledgement (OACK) packet */
+struct tftp_oack {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
- union {
- uint8_t rrq[TFTP_DEFAULTSIZE_PACKET];
- struct {
- uint16_t block;
- uint8_t download[TFTP_MAX_PACKET];
- } data;
- struct {
- uint16_t block;
- } ack;
- struct {
- uint16_t errcode;
- uint8_t errmsg[TFTP_DEFAULTSIZE_PACKET];
- } err;
- struct {
- uint8_t data[TFTP_DEFAULTSIZE_PACKET+2];
- } oack;
- } u;
+ uint8_t data[TFTP_DEFAULT_BLKSIZE];
} PACKED;
-/* define a smaller tftp packet solely for making requests to conserve stack
- 512 bytes should be enough */
-struct tftpreq_t {
+/** The common header of all TFTP packets */
+struct tftp_common {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
- union {
- uint8_t rrq[512];
- struct {
- uint16_t block;
- } ack;
- struct {
- uint16_t errcode;
- uint8_t errmsg[512-2];
- } err;
- } u;
} PACKED;
+/** A union encapsulating all TFTP packet types */
+union tftp_any {
+ struct tftp_common common;
+ struct tftp_rrq rrq;
+ struct tftp_data data;
+ struct tftp_ack ack;
+ struct tftp_error error;
+ struct tftp_oack oack;
+};
+
+/**
+ * TFTP state
+ *
+ * This data structure holds the state for an ongoing TFTP transfer.
+ */
+struct tftp_state {
+ /** TFTP server address
+ *
+ * This is the IP address and UDP port from which data packets
+ * will be sent, and to which ACK packets should be sent.
+ */
+ struct sockaddr_in server;
+ /** TFTP client port
+ *
+ * This is the UDP port from which the open request will be
+ * sent, and to which any unicast data packets will be sent.
+ */
+ in_port_t lport;
+ /** TFTP multicast address
+ *
+ * This is the IP address and UDP port to which multicast data
+ * packets, if any, will be sent.
+ */
+ struct sockaddr_in multicast;
+ /** Master client
+ *
+ * This will be true if the client is the master client for a
+ * multicast protocol (i.e. MTFTP or TFTM). (It will always
+ * be true for a non-multicast protocol, i.e. plain old TFTP).
+ */
+ int master;
+ /** Data block size
+ *
+ * This is the "blksize" option negotiated with the TFTP
+ * server. (If the TFTP server does not support TFTP options,
+ * this will default to 512).
+ */
+ unsigned int blksize;
+ /** File size
+ *
+ * This is the value returned in the "tsize" option from the
+ * TFTP server. If the TFTP server does not support the
+ * "tsize" option, this value will be zero.
+ */
+ off_t tsize;
+ /** Last received block
+ *
+ * The block number of the most recent block received from the
+ * TFTP server. Note that the first data block is block 1; a
+ * value of 0 indicates that no data blocks have yet been
+ * received.
+ */
+ unsigned int block;
+};
+
+
+
struct tftpreq_info_t {
struct sockaddr_in *server;
const char *name;
@@ -78,13 +160,4 @@ struct tftpblk_info_t {
#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
-/*
- * Functions in tftp.c. Needed for pxe_export.c
- *
- */
-extern int tftp_block ( struct tftpreq_info_t *request,
- struct tftpblk_info_t *block );
-extern int tftp ( char *url, struct sockaddr_in *server, char *file,
- struct buffer *buffer );
-
#endif /* TFTP_H */
diff --git a/src/include/tftpcore.h b/src/include/tftpcore.h
new file mode 100644
index 000000000..52f63bd9c
--- /dev/null
+++ b/src/include/tftpcore.h
@@ -0,0 +1,33 @@
+#ifndef TFTPCORE_H
+#define TFTPCORE_H
+
+/** @file
+ *
+ * TFTP core functions
+ *
+ * This file provides functions that are common to the TFTP (rfc1350),
+ * TFTM (rfc2090) and MTFTP (PXE) protocols.
+ *
+ */
+
+#include "tftp.h"
+
+extern int tftp_open ( struct tftp_state *state, const char *filename,
+ union tftp_any **reply, int multicast );
+
+extern int tftp_process_opts ( struct tftp_state *state,
+ struct tftp_oack *oack );
+
+extern int tftp_ack_nowait ( struct tftp_state *state );
+
+extern int tftp_get ( struct tftp_state *state, long timeout,
+ union tftp_any **reply );
+
+extern int tftp_ack ( struct tftp_state *state, union tftp_any **reply );
+
+extern int tftp_error ( struct tftp_state *state, int errcode,
+ const char *errmsg );
+
+extern void tftp_set_errno ( struct tftp_error *error );
+
+#endif /* TFTPCORE_H */
diff --git a/src/include/vsprintf.h b/src/include/vsprintf.h
index 2bf200852..553ebeb55 100644
--- a/src/include/vsprintf.h
+++ b/src/include/vsprintf.h
@@ -1,10 +1,46 @@
#ifndef VSPRINTF_H
#define VSPRINTF_H
-/*
- * Note that we cannot use __attribute__ (( format ( printf, ... ) ))
- * to get automatic type checking on arguments, because we use
- * non-standard format characters such as "%!" and "%@".
+/** @file
+ *
+ * printf and friends.
+ *
+ * Etherboot's printf() functions understand the following format
+ * specifiers:
+ *
+ * - Hexadecimal integers
+ * - @c %[#]x - 4 bytes int (8 hex digits, lower case)
+ * - @c %[#]X - 4 bytes int (8 hex digits, upper case)
+ * - @c %[#]lx - 8 bytes long (16 hex digits, lower case)
+ * - @c %[#]lX - 8 bytes long (16 hex digits, upper case)
+ * - @c %[#]hx - 2 bytes int (4 hex digits, lower case)
+ * - @c %[#]hX - 2 bytes int (4 hex digits, upper case)
+ * - @c %[#]hhx - 1 byte int (2 hex digits, lower case)
+ * - @c %[#]hhX - 1 byte int (2 hex digits, upper case)
+ * .
+ * If the optional # prefix is specified, the output will
+ * be prefixed with 0x (or 0X).
+ *
+ * - Other integers
+ * - @c %d - decimal int
+ * .
+ * Note that any width specification (e.g. the @c 02 in @c %02x)
+ * will be accepted but ignored.
+ *
+ * - Strings and characters
+ * - @c %c - char
+ * - @c %s - string
+ * - @c %m - error message text (i.e. strerror(errno))
+ *
+ * - Etherboot-specific specifiers
+ * - @c %@ - IP address in ddd.ddd.ddd.ddd notation
+ * - @c %! - MAC address in xx:xx:xx:xx:xx:xx notation
+ *
+ *
+ * @note Unfortunately, we cannot use <tt> __attribute__ (( format (
+ * printf, ... ) )) </tt> to get automatic type checking on arguments,
+ * because we use non-standard format characters such as @c %! and
+ * @c %@.
*
*/