iPXE
pxe_api.h
Go to the documentation of this file.
00001 #ifndef PXE_API_H
00002 #define PXE_API_H
00003 
00004 /*
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License as
00007  * published by the Free Software Foundation; either version 2 of the
00008  * License, or any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018  * 02110-1301, USA.
00019  *
00020  * You can also choose to distribute this program under the terms of
00021  * the Unmodified Binary Distribution Licence (as given in the file
00022  * COPYING.UBDL), provided that you have satisfied its requirements.
00023  *
00024  * As an alternative, at your option, you may use this file under the
00025  * following terms, known as the "MIT license":
00026  *
00027  * Copyright (c) 2005-2009 Michael Brown <mbrown@fensystems.co.uk>
00028  *
00029  * Permission is hereby granted, free of charge, to any person
00030  * obtaining a copy of this software and associated documentation
00031  * files (the "Software"), to deal in the Software without
00032  * restriction, including without limitation the rights to use, copy,
00033  * modify, merge, publish, distribute, sublicense, and/or sell copies
00034  * of the Software, and to permit persons to whom the Software is
00035  * furnished to do so, subject to the following conditions:
00036  *
00037  * The above copyright notice and this permission notice shall be
00038  * included in all copies or substantial portions of the Software.
00039  *
00040  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00041  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00042  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00043  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00044  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00045  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00046  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00047  * SOFTWARE.
00048  */
00049 
00050 /** @file
00051  *
00052  * Preboot eXecution Environment (PXE) API
00053  *
00054  */
00055 
00056 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00057 
00058 #include "pxe_types.h"
00059 
00060 /** @addtogroup pxe Preboot eXecution Environment (PXE) API
00061  *  @{
00062  */
00063 
00064 /** @defgroup pxe_api_call PXE entry points
00065  *
00066  * PXE entry points and calling conventions
00067  *
00068  *  @{
00069  */
00070 
00071 /** The PXENV+ structure */
00072 struct s_PXENV {
00073         /** Signature
00074          *
00075          * Contains the bytes 'P', 'X', 'E', 'N', 'V', '+'.
00076          */
00077         UINT8_t         Signature[6];
00078         /** PXE API version
00079          *
00080          * MSB is major version number, LSB is minor version number.
00081          * If the API version number is 0x0201 or greater, the !PXE
00082          * structure pointed to by #PXEPtr should be used instead of
00083          * this data structure.
00084          */
00085         UINT16_t        Version;
00086         UINT8_t         Length;         /**< Length of this structure */
00087         /** Checksum
00088          *
00089          * The byte checksum of this structure (using the length in
00090          * #Length) must be zero.
00091          */
00092         UINT8_t         Checksum;
00093         SEGOFF16_t      RMEntry;        /**< Real-mode PXENV+ entry point */
00094         /** Protected-mode PXENV+ entry point offset
00095          *
00096          * PXE 2.1 deprecates this entry point.  For protected-mode
00097          * API calls, use the !PXE structure pointed to by #PXEPtr
00098          * instead.
00099          */
00100         UINT32_t        PMOffset;
00101         /** Protected-mode PXENV+ entry point segment selector
00102          *
00103          * PXE 2.1 deprecates this entry point.  For protected-mode
00104          * API calls, use the !PXE structure pointed to by #PXEPtr
00105          * instead.
00106          */
00107         SEGSEL_t        PMSelector;
00108         SEGSEL_t        StackSeg;       /**< Stack segment selector */
00109         UINT16_t        StackSize;      /**< Stack segment size */
00110         SEGSEL_t        BC_CodeSeg;     /**< Base-code code segment selector */
00111         UINT16_t        BC_CodeSize;    /**< Base-code code segment size */
00112         SEGSEL_t        BC_DataSeg;     /**< Base-code data segment selector */
00113         UINT16_t        BC_DataSize;    /**< Base-code data segment size */
00114         SEGSEL_t        UNDIDataSeg;    /**< UNDI data segment selector */
00115         UINT16_t        UNDIDataSize;   /**< UNDI data segment size */
00116         SEGSEL_t        UNDICodeSeg;    /**< UNDI code segment selector */
00117         UINT16_t        UNDICodeSize;   /**< UNDI code segment size */
00118         /** Address of the !PXE structure
00119          *
00120          * This field is present only if #Version is 0x0201 or
00121          * greater.  If present, it points to a struct s_PXE.
00122          */
00123         SEGOFF16_t      PXEPtr;
00124 } __attribute__ (( packed ));
00125 
00126 typedef struct s_PXENV PXENV_t;
00127 
00128 /** The !PXE structure */
00129 struct s_PXE {
00130         /** Signature
00131          *
00132          * Contains the bytes '!', 'P', 'X', 'E'.
00133          */
00134         UINT8_t         Signature[4];
00135         UINT8_t         StructLength;   /**< Length of this structure */
00136         /** Checksum
00137          *
00138          * The byte checksum of this structure (using the length in
00139          * #StructLength) must be zero.
00140          */
00141         UINT8_t         StructCksum;
00142         /** Revision of this structure
00143          *
00144          * For PXE version 2.1, this field must be zero.
00145          */
00146         UINT8_t         StructRev;
00147         UINT8_t         reserved_1;     /**< Must be zero */
00148         /** Address of the UNDI ROM ID structure
00149          *
00150          * This is a pointer to a struct s_UNDI_ROM_ID.
00151          */
00152         SEGOFF16_t      UNDIROMID;
00153         /** Address of the Base Code ROM ID structure
00154          *
00155          * This is a pointer to a struct s_BC_ROM_ID.
00156          */
00157         SEGOFF16_t      BaseROMID;
00158         /** 16-bit !PXE entry point
00159          *
00160          * This is the entry point for either real mode, or protected
00161          * mode with a 16-bit stack segment.
00162          */
00163         SEGOFF16_t      EntryPointSP;
00164         /** 32-bit !PXE entry point
00165          *
00166          * This is the entry point for protected mode with a 32-bit
00167          * stack segment.
00168          */
00169         SEGOFF16_t      EntryPointESP;
00170         /** Status call-out function
00171          *
00172          * @v 0         (if in a time-out loop)
00173          * @v n         Number of a received TFTP packet
00174          * @ret 0       Continue operation
00175          * @ret 1       Cancel operation
00176          *
00177          * This function will be called whenever the PXE stack is in
00178          * protected mode, is waiting for an event (e.g. a DHCP reply)
00179          * and wishes to allow the user to cancel the operation.
00180          * Parameters are passed in register %ax; the return value
00181          * must also be placed in register %ax.  All other registers
00182          * and flags @b must be preserved.
00183          *
00184          * In real mode, an internal function (that checks for a
00185          * keypress) will be used.
00186          *
00187          * If this field is set to -1, no status call-out function
00188          * will be used and consequently the user will not be allowed
00189          * to interrupt operations.
00190          *
00191          * @note The PXE specification version 2.1 defines the
00192          * StatusCallout field, mentions it 11 times, but nowhere
00193          * defines what it actually does or how it gets called.
00194          * Fortunately, the WfM specification version 1.1a deigns to
00195          * inform us of such petty details.
00196          */
00197         SEGOFF16_t      StatusCallout;
00198         UINT8_t         reserved_2;     /**< Must be zero */
00199         /** Number of segment descriptors
00200          *
00201          * If this number is greater than 7, the remaining descriptors
00202          * follow immediately after #BC_CodeWrite.
00203          */
00204         UINT8_t         SegDescCnt;
00205         /** First protected-mode selector
00206          *
00207          * This is the segment selector value for the first segment
00208          * assigned to PXE.  Protected-mode selectors must be
00209          * consecutive, according to the PXE 2.1 specification, though
00210          * no reason is given.  Each #SEGDESC_t includes a field for
00211          * the segment selector, so this information is entirely
00212          * redundant.
00213          */
00214         SEGSEL_t        FirstSelector;
00215         /** Stack segment descriptor */
00216         SEGDESC_t       Stack;
00217         /** UNDI data segment descriptor */
00218         SEGDESC_t       UNDIData;
00219         /** UNDI code segment descriptor */
00220         SEGDESC_t       UNDICode;
00221         /** UNDI writable code segment descriptor */
00222         SEGDESC_t       UNDICodeWrite;
00223         /** Base-code data segment descriptor */
00224         SEGDESC_t       BC_Data;
00225         /** Base-code code segment descriptor */
00226         SEGDESC_t       BC_Code;
00227         /** Base-code writable code segment descriptor */
00228         SEGDESC_t       BC_CodeWrite;
00229 } __attribute__ (( packed ));
00230 
00231 typedef struct s_PXE PXE_t;
00232 
00233 /** @} */ /* pxe_api_call */
00234 
00235 /** @defgroup pxe_preboot_api PXE Preboot API
00236  *
00237  * General high-level functions: #PXENV_UNLOAD_STACK, #PXENV_START_UNDI etc.
00238  *
00239  * @{
00240  */
00241 
00242 /** @defgroup pxenv_unload_stack PXENV_UNLOAD_STACK
00243  *
00244  *  UNLOAD BASE CODE STACK
00245  *
00246  *  @{
00247  */
00248 
00249 /** PXE API function code for pxenv_unload_stack() */
00250 #define PXENV_UNLOAD_STACK              0x0070
00251 
00252 /** Parameter block for pxenv_unload_stack() */
00253 struct s_PXENV_UNLOAD_STACK {
00254         PXENV_STATUS_t Status;                  /**< PXE status code */
00255         UINT8_t reserved[10];                   /**< Must be zero */
00256 } __attribute__ (( packed ));
00257 
00258 typedef struct s_PXENV_UNLOAD_STACK PXENV_UNLOAD_STACK_t;
00259 
00260 /** @} */ /* pxenv_unload_stack */
00261 
00262 /** @defgroup pxenv_get_cached_info PXENV_GET_CACHED_INFO
00263  *
00264  *  GET CACHED INFO
00265  *
00266  *  @{
00267  */
00268 
00269 /** PXE API function code for pxenv_get_cached_info() */
00270 #define PXENV_GET_CACHED_INFO           0x0071
00271 
00272 /** The client's DHCPDISCOVER packet */
00273 #define PXENV_PACKET_TYPE_DHCP_DISCOVER 1
00274 
00275 /** The DHCP server's DHCPACK packet */
00276 #define PXENV_PACKET_TYPE_DHCP_ACK      2
00277 
00278 /** The Boot Server's Discover Reply packet
00279  *
00280  * This packet contains DHCP option 60 set to "PXEClient", a valid
00281  * boot file name, and may or may not contain MTFTP options.
00282  */
00283 #define PXENV_PACKET_TYPE_CACHED_REPLY  3
00284 
00285 /** Parameter block for pxenv_get_cached_info() */
00286 struct s_PXENV_GET_CACHED_INFO {
00287         PXENV_STATUS_t Status;                  /**< PXE status code */
00288         /** Packet type.
00289          *
00290          * Valid values are #PXENV_PACKET_TYPE_DHCP_DISCOVER,
00291          * #PXENV_PACKET_TYPE_DHCP_ACK or #PXENV_PACKET_TYPE_CACHED_REPLY
00292          */
00293         UINT16_t PacketType;
00294         UINT16_t BufferSize;                    /**< Buffer size */
00295         SEGOFF16_t Buffer;                      /**< Buffer address */
00296         UINT16_t BufferLimit;                   /**< Maximum buffer size */
00297 } __attribute__ (( packed ));
00298 
00299 typedef struct s_PXENV_GET_CACHED_INFO PXENV_GET_CACHED_INFO_t;
00300 
00301 #define BOOTP_REQ       1       /**< A BOOTP request packet */
00302 #define BOOTP_REP       2       /**< A BOOTP reply packet */
00303 
00304 /** DHCP broadcast flag
00305  *
00306  * Request a broadcast response (DHCPOFFER or DHCPACK) from the DHCP
00307  * server.
00308  */
00309 #define BOOTP_BCAST     0x8000
00310 
00311 #define VM_RFC1048      0x63825363L     /**< DHCP magic cookie */
00312 
00313 /** Maximum length of DHCP options */
00314 #define BOOTP_DHCPVEND  1024
00315 
00316 /** Format of buffer filled in by pxenv_get_cached_info()
00317  *
00318  * This somewhat convoluted data structure simply describes the layout
00319  * of a DHCP packet.  Refer to RFC2131 section 2 for a full
00320  * description.
00321  */
00322 struct bootph {
00323         /** Message opcode.
00324          *
00325          * Valid values are #BOOTP_REQ and #BOOTP_REP.
00326          */
00327         UINT8_t opcode;
00328         /** NIC hardware type.
00329          *
00330          * Valid values are as for s_PXENV_UNDI_GET_INFORMATION::HwType.
00331          */
00332         UINT8_t Hardware;
00333         UINT8_t Hardlen;                /**< MAC address length */
00334         /** Gateway hops
00335          *
00336          * Zero in packets sent by the client.  May be non-zero in
00337          * replies from the DHCP server, if the reply comes via a DHCP
00338          * relay agent.
00339          */
00340         UINT8_t Gatehops;
00341         UINT32_t ident;                 /**< DHCP transaction id (xid) */
00342         /** Elapsed time
00343          *
00344          * Number of seconds since the client began the DHCP
00345          * transaction.
00346          */
00347         UINT16_t seconds;
00348         /** Flags
00349          *
00350          * This is the bitwise-OR of any of the following values:
00351          * #BOOTP_BCAST.
00352          */
00353         UINT16_t Flags;
00354         /** Client IP address
00355          *
00356          * Set only if the client already has an IP address.
00357          */
00358         IP4_t cip;
00359         /** Your IP address
00360          *
00361          * This is the IP address that the server assigns to the
00362          * client.
00363          */
00364         IP4_t yip;
00365         /** Server IP address
00366          *
00367          * This is the IP address of the BOOTP/DHCP server.
00368          */
00369         IP4_t sip;
00370         /** Gateway IP address
00371          *
00372          * This is the IP address of the BOOTP/DHCP relay agent, if
00373          * any.  It is @b not (necessarily) the address of the default
00374          * gateway for routing purposes.
00375          */
00376         IP4_t gip;
00377         MAC_ADDR_t CAddr;               /**< Client MAC address */
00378         UINT8_t Sname[64];              /**< Server host name */
00379         UINT8_t bootfile[128];          /**< Boot file name */
00380         /** DHCP options
00381          *
00382          * Don't ask.  Just laugh.  Then burn a copy of the PXE
00383          * specification and send Intel an e-mail asking them if
00384          * they've figured out what a "union" does in C yet.
00385          */
00386         union bootph_vendor {
00387                 UINT8_t d[BOOTP_DHCPVEND]; /**< DHCP options */
00388                 /** DHCP options */
00389                 struct bootph_vendor_v {
00390                         /** DHCP magic cookie
00391                          *
00392                          * Should have the value #VM_RFC1048.
00393                          */
00394                         UINT8_t magic[4];
00395                         UINT32_t flags; /**< BOOTP flags/opcodes */
00396                         /** "End of BOOTP vendor extensions"
00397                          *
00398                          * Abandon hope, all ye who consider the
00399                          * purpose of this field.
00400                          */
00401                         UINT8_t pad[56];
00402                 } v;
00403         } vendor;
00404 } __attribute__ (( packed ));
00405 
00406 typedef struct bootph BOOTPLAYER_t;
00407 
00408 /** @} */ /* pxenv_get_cached_info */
00409 
00410 /** @defgroup pxenv_restart_tftp PXENV_RESTART_TFTP
00411  *
00412  *  RESTART TFTP
00413  *
00414  *  @{
00415  */
00416 
00417 /** PXE API function code for pxenv_restart_tftp() */
00418 #define PXENV_RESTART_TFTP              0x0073
00419 
00420 /** Parameter block for pxenv_restart_tftp() */
00421 struct s_PXENV_TFTP_READ_FILE;
00422 
00423 typedef struct s_PXENV_RESTART_TFTP PXENV_RESTART_TFTP_t;
00424 
00425 /** @} */ /* pxenv_restart_tftp */
00426 
00427 /** @defgroup pxenv_start_undi PXENV_START_UNDI
00428  *
00429  *  START UNDI
00430  *
00431  *  @{
00432  */
00433 
00434 /** PXE API function code for pxenv_start_undi() */
00435 #define PXENV_START_UNDI                0x0000
00436 
00437 /** Parameter block for pxenv_start_undi() */
00438 struct s_PXENV_START_UNDI {
00439         PXENV_STATUS_t Status;                  /**< PXE status code */
00440         /** %ax register as passed to the Option ROM initialisation routine.
00441          *
00442          * For a PCI device, this should contain the bus:dev:fn value
00443          * that uniquely identifies the PCI device in the system.  For
00444          * a non-PCI device, this field is not defined.
00445          */
00446         UINT16_t AX;
00447         /** %bx register as passed to the Option ROM initialisation routine.
00448          *
00449          * For an ISAPnP device, this should contain the Card Select
00450          * Number assigned to the ISAPnP card.  For non-ISAPnP
00451          * devices, this should contain 0xffff.
00452          */
00453         UINT16_t BX;
00454         /** %dx register as passed to the Option ROM initialisation routine.
00455          *
00456          * For an ISAPnP device, this should contain the ISAPnP Read
00457          * Port address as currently set in all ISAPnP cards.  If
00458          * there are no ISAPnP cards, this should contain 0xffff.  (If
00459          * this is a non-ISAPnP device, but there are ISAPnP cards in
00460          * the system, this value is not well defined.)
00461          */
00462         UINT16_t DX;
00463         /** %di register as passed to the Option ROM initialisation routine.
00464          *
00465          * This contains the #OFF16_t portion of a struct #s_SEGOFF16
00466          * that points to the System BIOS Plug and Play Installation
00467          * Check Structure.  (Refer to section 4.4 of the Plug and
00468          * Play BIOS specification for a description of this
00469          * structure.)
00470          *
00471          * @note The PXE specification defines the type of this field
00472          * as #UINT16_t.  For x86, #OFF16_t and #UINT16_t are
00473          * equivalent anyway; for other architectures #OFF16_t makes
00474          * more sense.
00475          */
00476         OFF16_t DI;
00477         /** %es register as passed to the Option ROM initialisation routine.
00478          *
00479          * This contains the #SEGSEL_t portion of a struct #s_SEGOFF16
00480          * that points to the System BIOS Plug and Play Installation
00481          * Check Structure.  (Refer to section 4.4 of the Plug and
00482          * Play BIOS specification for a description of this
00483          * structure.)
00484          *
00485          * @note The PXE specification defines the type of this field
00486          * as #UINT16_t.  For x86, #SEGSEL_t and #UINT16_t are
00487          * equivalent anyway; for other architectures #SEGSEL_t makes
00488          * more sense.
00489          */
00490         SEGSEL_t ES;
00491 } __attribute__ (( packed ));
00492 
00493 typedef struct s_PXENV_START_UNDI PXENV_START_UNDI_t;
00494 
00495 /** @} */ /* pxenv_start_undi */
00496 
00497 /** @defgroup pxenv_stop_undi PXENV_STOP_UNDI
00498  *
00499  *  STOP UNDI
00500  *
00501  *  @{
00502  */
00503 
00504 /** PXE API function code for pxenv_stop_undi() */
00505 #define PXENV_STOP_UNDI                 0x0015
00506 
00507 /** Parameter block for pxenv_stop_undi() */
00508 struct s_PXENV_STOP_UNDI {
00509         PXENV_STATUS_t Status;                  /**< PXE status code */
00510 } __attribute__ (( packed ));
00511 
00512 typedef struct s_PXENV_STOP_UNDI PXENV_STOP_UNDI_t;
00513 
00514 /** @} */ /* pxenv_stop_undi */
00515 
00516 /** @defgroup pxenv_start_base PXENV_START_BASE
00517  *
00518  *  START BASE
00519  *
00520  *  @{
00521  */
00522 
00523 /** PXE API function code for pxenv_start_base() */
00524 #define PXENV_START_BASE                0x0075
00525 
00526 /** Parameter block for pxenv_start_base() */
00527 struct s_PXENV_START_BASE {
00528         PXENV_STATUS_t Status;                  /**< PXE status code */
00529 } __attribute__ (( packed ));
00530 
00531 typedef struct s_PXENV_START_BASE PXENV_START_BASE_t;
00532 
00533 /** @} */ /* pxenv_start_base */
00534 
00535 /** @defgroup pxenv_stop_base PXENV_STOP_BASE
00536  *
00537  *  STOP BASE
00538  *
00539  *  @{
00540  */
00541 
00542 /** PXE API function code for pxenv_stop_base() */
00543 #define PXENV_STOP_BASE                 0x0076
00544 
00545 /** Parameter block for pxenv_stop_base() */
00546 struct s_PXENV_STOP_BASE {
00547         PXENV_STATUS_t Status;                  /**< PXE status code */
00548 } __attribute__ (( packed ));
00549 
00550 typedef struct s_PXENV_STOP_BASE PXENV_STOP_BASE_t;
00551 
00552 /** @} */ /* pxenv_stop_base */
00553 
00554 /** @} */ /* pxe_preboot_api */
00555 
00556 /** @defgroup pxe_tftp_api PXE TFTP API
00557  *
00558  * Download files via TFTP or MTFTP
00559  *
00560  * @{
00561  */
00562 
00563 /** @defgroup pxenv_tftp_open PXENV_TFTP_OPEN
00564  *
00565  *  TFTP OPEN
00566  *
00567  *  @{
00568  */
00569 
00570 /** PXE API function code for pxenv_tftp_open() */
00571 #define PXENV_TFTP_OPEN                 0x0020
00572 
00573 /** Parameter block for pxenv_tftp_open() */
00574 struct s_PXENV_TFTP_OPEN {
00575         PXENV_STATUS_t Status;                  /**< PXE status code */
00576         IP4_t ServerIPAddress;                  /**< TFTP server IP address */
00577         IP4_t GatewayIPAddress;                 /**< Relay agent IP address */
00578         UINT8_t FileName[128];                  /**< File name */
00579         UDP_PORT_t TFTPPort;                    /**< TFTP server UDP port */
00580         /** Requested size of TFTP packets
00581          *
00582          * This is the TFTP "blksize" option.  This must be at least
00583          * 512, since servers that do not support TFTP options cannot
00584          * negotiate blocksizes smaller than this.
00585          */
00586         UINT16_t PacketSize;
00587 } __attribute__ (( packed ));
00588 
00589 typedef struct s_PXENV_TFTP_OPEN PXENV_TFTP_OPEN_t;
00590 
00591 /** @} */ /* pxenv_tftp_open */
00592 
00593 /** @defgroup pxenv_tftp_close PXENV_TFTP_CLOSE
00594  *
00595  *  TFTP CLOSE
00596  *
00597  *  @{
00598  */
00599 
00600 /** PXE API function code for pxenv_tftp_close() */
00601 #define PXENV_TFTP_CLOSE                0x0021
00602 
00603 /** Parameter block for pxenv_tftp_close() */
00604 struct s_PXENV_TFTP_CLOSE {
00605         PXENV_STATUS_t Status;                  /**< PXE status code */
00606 } __attribute__ (( packed ));
00607 
00608 typedef struct s_PXENV_TFTP_CLOSE PXENV_TFTP_CLOSE_t;
00609 
00610 /** @} */ /* pxenv_tftp_close */
00611 
00612 /** @defgroup pxenv_tftp_read PXENV_TFTP_READ
00613  *
00614  *  TFTP READ
00615  *
00616  *  @{
00617  */
00618 
00619 /** PXE API function code for pxenv_tftp_read() */
00620 #define PXENV_TFTP_READ                 0x0022
00621 
00622 /** Parameter block for pxenv_tftp_read() */
00623 struct s_PXENV_TFTP_READ {
00624         PXENV_STATUS_t Status;                  /**< PXE status code */
00625         UINT16_t PacketNumber;                  /**< TFTP packet number */
00626         UINT16_t BufferSize;                    /**< Size of data buffer */
00627         SEGOFF16_t Buffer;                      /**< Address of data buffer */
00628 } __attribute__ (( packed ));
00629 
00630 typedef struct s_PXENV_TFTP_READ PXENV_TFTP_READ_t;
00631 
00632 /** @} */ /* pxenv_tftp_read */
00633 
00634 /** @defgroup pxenv_tftp_read_file PXENV_TFTP_READ_FILE
00635  *
00636  *  TFTP/MTFTP READ FILE
00637  *
00638  *  @{
00639  */
00640 
00641 /** PXE API function code for pxenv_tftp_read_file() */
00642 #define PXENV_TFTP_READ_FILE            0x0023
00643 
00644 /** Parameter block for pxenv_tftp_read_file() */
00645 struct s_PXENV_TFTP_READ_FILE {
00646         PXENV_STATUS_t Status;                  /**< PXE status code */
00647         UINT8_t FileName[128];                  /**< File name */
00648         UINT32_t BufferSize;                    /**< Size of data buffer */
00649         ADDR32_t Buffer;                        /**< Address of data buffer */
00650         IP4_t ServerIPAddress;                  /**< TFTP server IP address */
00651         IP4_t GatewayIPAddress;                 /**< Relay agent IP address */
00652         /** File multicast IP address */
00653         IP4_t McastIPAddress;
00654         /** Client multicast listening port */
00655         UDP_PORT_t TFTPClntPort;
00656         /** Server multicast listening port */
00657         UDP_PORT_t TFTPSrvPort;
00658         /** TFTP open timeout.
00659          *
00660          * This is the timeout for receiving the first DATA or ACK
00661          * packets during the MTFTP Listen phase.
00662          */
00663         UINT16_t TFTPOpenTimeOut;
00664         /** TFTP reopen timeout.
00665          *
00666          * This is the timeout for receiving an ACK packet while in
00667          * the MTFTP Listen phase (when at least one ACK packet has
00668          * already been seen).
00669          */
00670         UINT16_t TFTPReopenDelay;
00671 } __attribute__ (( packed ));
00672 
00673 typedef struct s_PXENV_TFTP_READ_FILE PXENV_TFTP_READ_FILE_t;
00674 
00675 /** @} */ /* pxenv_tftp_read_file */
00676 
00677 /** @defgroup pxenv_tftp_get_fsize PXENV_TFTP_GET_FSIZE
00678  *
00679  *  TFTP GET FILE SIZE
00680  *
00681  *  @{
00682  */
00683 
00684 /** PXE API function code for pxenv_tftp_get_fsize() */
00685 #define PXENV_TFTP_GET_FSIZE            0x0025
00686 
00687 /** Parameter block for pxenv_tftp_get_fsize() */
00688 struct s_PXENV_TFTP_GET_FSIZE {
00689         PXENV_STATUS_t Status;                  /**< PXE status code */
00690         IP4_t ServerIPAddress;                  /**< TFTP server IP address */
00691         IP4_t GatewayIPAddress;                 /**< Relay agent IP address */
00692         UINT8_t FileName[128];                  /**< File name */
00693         UINT32_t FileSize;                      /**< Size of the file */
00694 } __attribute__ (( packed ));
00695 
00696 typedef struct s_PXENV_TFTP_GET_FSIZE PXENV_TFTP_GET_FSIZE_t;
00697 
00698 /** @} */ /* pxenv_tftp_get_fsize */
00699 
00700 /** @} */ /* pxe_tftp_api */
00701 
00702 /** @defgroup pxe_udp_api PXE UDP API
00703  *
00704  * Transmit and receive UDP packets
00705  *
00706  * @{
00707  */
00708 
00709 /** @defgroup pxenv_udp_open PXENV_UDP_OPEN
00710  *
00711  *  UDP OPEN
00712  *
00713  *  @{
00714  */
00715 
00716 /** PXE API function code for pxenv_udp_open() */
00717 #define PXENV_UDP_OPEN                  0x0030
00718 
00719 /** Parameter block for pxenv_udp_open() */
00720 struct s_PXENV_UDP_OPEN {
00721         PXENV_STATUS_t  Status;         /**< PXE status code */
00722         IP4_t           src_ip;         /**< IP address of this station */
00723 } __attribute__ (( packed ));
00724 
00725 typedef struct s_PXENV_UDP_OPEN PXENV_UDP_OPEN_t;
00726 
00727 /** @} */ /* pxenv_udp_open */
00728 
00729 /** @defgroup pxenv_udp_close PXENV_UDP_CLOSE
00730  *
00731  *  UDP CLOSE
00732  *
00733  *  @{
00734  */
00735 
00736 /** PXE API function code for pxenv_udp_close() */
00737 #define PXENV_UDP_CLOSE                 0x0031
00738 
00739 /** Parameter block for pxenv_udp_close() */
00740 struct s_PXENV_UDP_CLOSE {
00741         PXENV_STATUS_t  Status;         /**< PXE status code */
00742 } __attribute__ (( packed ));
00743 
00744 typedef struct s_PXENV_UDP_CLOSE PXENV_UDP_CLOSE_t;
00745 
00746 /** @} */ /* pxenv_udp_close */
00747 
00748 /** @defgroup pxenv_udp_write PXENV_UDP_WRITE
00749  *
00750  *  UDP WRITE
00751  *
00752  *  @{
00753  */
00754 
00755 /** PXE API function code for pxenv_udp_write() */
00756 #define PXENV_UDP_WRITE                 0x0033
00757 
00758 /** Parameter block for pxenv_udp_write() */
00759 struct s_PXENV_UDP_WRITE {
00760         PXENV_STATUS_t  Status;         /**< PXE status code */
00761         IP4_t           ip;             /**< Destination IP address */
00762         IP4_t           gw;             /**< Relay agent IP address */
00763         UDP_PORT_t      src_port;       /**< Source UDP port */
00764         UDP_PORT_t      dst_port;       /**< Destination UDP port */
00765         UINT16_t        buffer_size;    /**< UDP payload buffer size */
00766         SEGOFF16_t      buffer;         /**< UDP payload buffer address */
00767 } __attribute__ (( packed ));
00768 
00769 typedef struct s_PXENV_UDP_WRITE PXENV_UDP_WRITE_t;
00770 
00771 /** @} */ /* pxenv_udp_write */
00772 
00773 /** @defgroup pxenv_udp_read PXENV_UDP_READ
00774  *
00775  *  UDP READ
00776  *
00777  *  @{
00778  */
00779 
00780 /** PXE API function code for pxenv_udp_read() */
00781 #define PXENV_UDP_READ                  0x0032
00782 
00783 /** Parameter block for pxenv_udp_read() */
00784 struct s_PXENV_UDP_READ {
00785         PXENV_STATUS_t  Status;         /**< PXE status code */
00786         IP4_t           src_ip;         /**< Source IP address */
00787         IP4_t           dest_ip;        /**< Destination IP address */
00788         UDP_PORT_t      s_port;         /**< Source UDP port */
00789         UDP_PORT_t      d_port;         /**< Destination UDP port */
00790         UINT16_t        buffer_size;    /**< UDP payload buffer size */
00791         SEGOFF16_t      buffer;         /**< UDP payload buffer address */
00792 } __attribute__ (( packed ));
00793 
00794 typedef struct s_PXENV_UDP_READ PXENV_UDP_READ_t;
00795 
00796 /** @} */ /* pxenv_udp_read */
00797 
00798 /** @} */ /* pxe_udp_api */
00799 
00800 /** @defgroup pxe_undi_api PXE UNDI API
00801  *
00802  * Direct control of the network interface card
00803  *
00804  * @{
00805  */
00806 
00807 /** @defgroup pxenv_undi_startup PXENV_UNDI_STARTUP
00808  *
00809  *  UNDI STARTUP
00810  *
00811  *  @{
00812  */
00813 
00814 /** PXE API function code for pxenv_undi_startup() */
00815 #define PXENV_UNDI_STARTUP              0x0001
00816 
00817 #define PXENV_BUS_ISA           0       /**< ISA bus type */
00818 #define PXENV_BUS_EISA          1       /**< EISA bus type */
00819 #define PXENV_BUS_MCA           2       /**< MCA bus type */
00820 #define PXENV_BUS_PCI           3       /**< PCI bus type */
00821 #define PXENV_BUS_VESA          4       /**< VESA bus type */
00822 #define PXENV_BUS_PCMCIA        5       /**< PCMCIA bus type */
00823 
00824 /** Parameter block for pxenv_undi_startup() */
00825 struct s_PXENV_UNDI_STARTUP {
00826         PXENV_STATUS_t  Status;         /**< PXE status code */
00827 } __attribute__ (( packed ));
00828 
00829 typedef struct s_PXENV_UNDI_STARTUP PXENV_UNDI_STARTUP_t;
00830 
00831 /** @} */ /* pxenv_undi_startup */
00832 
00833 /** @defgroup pxenv_undi_cleanup PXENV_UNDI_CLEANUP
00834  *
00835  *  UNDI CLEANUP
00836  *
00837  *  @{
00838  */
00839 
00840 /** PXE API function code for pxenv_undi_cleanup() */
00841 #define PXENV_UNDI_CLEANUP              0x0002
00842 
00843 /** Parameter block for pxenv_undi_cleanup() */
00844 struct s_PXENV_UNDI_CLEANUP {
00845         PXENV_STATUS_t  Status;         /**< PXE status code */
00846 } __attribute__ (( packed ));
00847 
00848 typedef struct s_PXENV_UNDI_CLEANUP PXENV_UNDI_CLEANUP_t;
00849 
00850 /** @} */ /* pxenv_undi_cleanup */
00851 
00852 /** @defgroup pxenv_undi_initialize PXENV_UNDI_INITIALIZE
00853  *
00854  *  UNDI INITIALIZE
00855  *
00856  *  @{
00857  */
00858 
00859 /** PXE API function code for pxenv_undi_initialize() */
00860 #define PXENV_UNDI_INITIALIZE           0x0003
00861 
00862 /** Parameter block for pxenv_undi_initialize() */
00863 struct s_PXENV_UNDI_INITIALIZE {
00864         PXENV_STATUS_t  Status;         /**< PXE status code */
00865         /** NDIS 2.0 configuration information, or NULL
00866          *
00867          * This is a pointer to the data structure returned by the
00868          * NDIS 2.0 GetProtocolManagerInfo() API call.  The data
00869          * structure is documented, in a rather haphazard way, in
00870          * section 4-17 of the NDIS 2.0 specification.
00871          */
00872         ADDR32_t ProtocolIni;
00873         UINT8_t reserved[8];            /**< Must be zero */
00874 } __attribute__ (( packed ));
00875 
00876 typedef struct s_PXENV_UNDI_INITIALIZE PXENV_UNDI_INITIALIZE_t;
00877 
00878 /** @} */ /* pxenv_undi_initialize */
00879 
00880 /** @defgroup pxenv_undi_reset_adapter PXENV_UNDI_RESET_ADAPTER
00881  *
00882  *  UNDI RESET ADAPTER
00883  *
00884  *  @{
00885  */
00886 
00887 /** PXE API function code for pxenv_undi_reset_adapter() */
00888 #define PXENV_UNDI_RESET_ADAPTER        0x0004
00889 
00890 /** Maximum number of multicast MAC addresses */
00891 #define MAXNUM_MCADDR   8
00892 
00893 /** List of multicast MAC addresses */
00894 struct s_PXENV_UNDI_MCAST_ADDRESS {
00895         /** Number of multicast MAC addresses */
00896         UINT16_t MCastAddrCount;
00897         /** List of up to #MAXNUM_MCADDR multicast MAC addresses */
00898         MAC_ADDR_t McastAddr[MAXNUM_MCADDR];
00899 } __attribute__ (( packed ));
00900 
00901 typedef struct s_PXENV_UNDI_MCAST_ADDRESS PXENV_UNDI_MCAST_ADDRESS_t;
00902 
00903 /** Parameter block for pxenv_undi_reset_adapter() */
00904 struct s_PXENV_UNDI_RESET {
00905         PXENV_STATUS_t  Status;         /**< PXE status code */
00906         /** Multicast MAC addresses */
00907         struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
00908 } __attribute__ (( packed ));
00909 
00910 typedef struct s_PXENV_UNDI_RESET PXENV_UNDI_RESET_t;
00911 
00912 /** @} */ /* pxenv_undi_reset_adapter */
00913 
00914 /** @defgroup pxenv_undi_shutdown PXENV_UNDI_SHUTDOWN
00915  *
00916  *  UNDI SHUTDOWN
00917  *
00918  *  @{
00919  */
00920 
00921 /** PXE API function code for pxenv_undi_shutdown() */
00922 #define PXENV_UNDI_SHUTDOWN             0x0005
00923 
00924 /** Parameter block for pxenv_undi_shutdown() */
00925 struct s_PXENV_UNDI_SHUTDOWN {
00926         PXENV_STATUS_t  Status;         /**< PXE status code */
00927 } __attribute__ (( packed ));
00928 
00929 typedef struct s_PXENV_UNDI_SHUTDOWN PXENV_UNDI_SHUTDOWN_t;
00930 
00931 /** @} */ /* pxenv_undi_shutdown */
00932 
00933 /** @defgroup pxenv_undi_open PXENV_UNDI_OPEN
00934  *
00935  *  UNDI OPEN
00936  *
00937  *  @{
00938  */
00939 
00940 /** PXE API function code for pxenv_undi_open() */
00941 #define PXENV_UNDI_OPEN                 0x0006
00942 
00943 /** Accept "directed" packets
00944  *
00945  * These are packets addresses to either this adapter's MAC address or
00946  * to any of the configured multicast MAC addresses (see
00947  * #s_PXENV_UNDI_MCAST_ADDRESS).
00948  */
00949 #define FLTR_DIRECTED   0x0001
00950 /** Accept broadcast packets */
00951 #define FLTR_BRDCST     0x0002
00952 /** Accept all packets; listen in promiscuous mode */
00953 #define FLTR_PRMSCS     0x0004
00954 /** Accept source-routed packets */
00955 #define FLTR_SRC_RTG    0x0008
00956 
00957 /** Parameter block for pxenv_undi_open() */
00958 struct s_PXENV_UNDI_OPEN {
00959         PXENV_STATUS_t  Status;         /**< PXE status code */
00960         /** Open flags as defined in NDIS 2.0
00961          *
00962          * This is the OpenOptions field as passed to the NDIS 2.0
00963          * OpenAdapter() API call.  It is defined to be "adapter
00964          * specific", though 0 is guaranteed to be a valid value.
00965          */
00966         UINT16_t OpenFlag;
00967         /** Receive packet filter
00968          *
00969          * This is the bitwise-OR of any of the following flags:
00970          * #FLTR_DIRECTED, #FLTR_BRDCST, #FLTR_PRMSCS and
00971          * #FLTR_SRC_RTG.
00972          */
00973         UINT16_t PktFilter;
00974         /** Multicast MAC addresses */
00975         struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
00976 } __attribute__ (( packed ));
00977 
00978 typedef struct s_PXENV_UNDI_OPEN PXENV_UNDI_OPEN_t;
00979 
00980 /** @} */ /* pxenv_undi_open */
00981 
00982 /** @defgroup pxenv_undi_close PXENV_UNDI_CLOSE
00983  *
00984  *  UNDI CLOSE
00985  *
00986  *  @{
00987  */
00988 
00989 /** PXE API function code for pxenv_undi_close() */
00990 #define PXENV_UNDI_CLOSE                0x0007
00991 
00992 /** Parameter block for pxenv_undi_close() */
00993 struct s_PXENV_UNDI_CLOSE {
00994         PXENV_STATUS_t  Status;         /**< PXE status code */
00995 } __attribute__ (( packed ));
00996 
00997 typedef struct s_PXENV_UNDI_CLOSE PXENV_UNDI_CLOSE_t;
00998 
00999 /** @} */ /* pxenv_undi_close */
01000 
01001 /** @defgroup pxenv_undi_transmit PXENV_UNDI_TRANSMIT
01002  *
01003  *  UNDI TRANSMIT PACKET
01004  *
01005  *  @{
01006  */
01007 
01008 /** PXE API function code for pxenv_undi_transmit() */
01009 #define PXENV_UNDI_TRANSMIT             0x0008
01010 
01011 #define P_UNKNOWN       0               /**< Media header already filled in */
01012 #define P_IP            1               /**< IP protocol */
01013 #define P_ARP           2               /**< ARP protocol */
01014 #define P_RARP          3               /**< RARP protocol */
01015 #define P_OTHER         4               /**< Other protocol */
01016 
01017 #define XMT_DESTADDR    0x0000          /**< Unicast packet */
01018 #define XMT_BROADCAST   0x0001          /**< Broadcast packet */
01019 
01020 /** Maximum number of data blocks in a transmit buffer descriptor */
01021 #define MAX_DATA_BLKS   8
01022 
01023 /** A transmit buffer descriptor, as pointed to by s_PXENV_UNDI_TRANSMIT::TBD
01024  */
01025 struct s_PXENV_UNDI_TBD {
01026         UINT16_t ImmedLength;           /**< Length of the transmit buffer */
01027         SEGOFF16_t Xmit;                /**< Address of the transmit buffer */
01028         UINT16_t DataBlkCount;
01029         /** Array of up to #MAX_DATA_BLKS additional transmit buffers */
01030         struct DataBlk {
01031                 /** Always 1
01032                  *
01033                  * A value of 0 would indicate that #TDDataPtr were an
01034                  * #ADDR32_t rather than a #SEGOFF16_t.  The PXE
01035                  * specification version 2.1 explicitly states that
01036                  * this is not supported; #TDDataPtr will always be a
01037                  * #SEGOFF16_t.
01038                  */
01039                 UINT8_t TDPtrType;
01040                 UINT8_t TDRsvdByte;     /**< Must be zero */
01041                 UINT16_t TDDataLen;     /**< Length of this transmit buffer */
01042                 SEGOFF16_t TDDataPtr;   /**< Address of this transmit buffer */
01043         } DataBlock[MAX_DATA_BLKS];
01044 } __attribute__ (( packed ));
01045 
01046 typedef struct s_PXENV_UNDI_TBD PXENV_UNDI_TBD_t;
01047 
01048 /** Parameter block for pxenv_undi_transmit() */
01049 struct s_PXENV_UNDI_TRANSMIT {
01050         PXENV_STATUS_t  Status;         /**< PXE status code */
01051         /** Protocol
01052          *
01053          * Valid values are #P_UNKNOWN, #P_IP, #P_ARP or #P_RARP.  If
01054          * the caller has already filled in the media header, this
01055          * field must be set to #P_UNKNOWN.
01056          */
01057         UINT8_t Protocol;
01058         /** Unicast/broadcast flag
01059          *
01060          * Valid values are #XMT_DESTADDR or #XMT_BROADCAST.
01061          */
01062         UINT8_t XmitFlag;
01063         SEGOFF16_t DestAddr;            /**< Destination MAC address */
01064         /** Address of the Transmit Buffer Descriptor
01065          *
01066          * This is a pointer to a struct s_PXENV_UNDI_TBD.
01067          */
01068         SEGOFF16_t TBD;
01069         UINT32_t Reserved[2];           /**< Must be zero */
01070 } __attribute__ (( packed ));
01071 
01072 typedef struct s_PXENV_UNDI_TRANSMIT PXENV_UNDI_TRANSMIT_t;
01073 
01074 /** @} */ /* pxenv_undi_transmit */
01075 
01076 /** @defgroup pxenv_undi_set_mcast_address PXENV_UNDI_SET_MCAST_ADDRESS
01077  *
01078  *  UNDI SET MULTICAST ADDRESS
01079  *
01080  *  @{
01081  */
01082 
01083 /** PXE API function code for pxenv_undi_set_mcast_address() */
01084 #define PXENV_UNDI_SET_MCAST_ADDRESS    0x0009
01085 
01086 /** Parameter block for pxenv_undi_set_mcast_address() */
01087 struct s_PXENV_UNDI_SET_MCAST_ADDRESS {
01088         PXENV_STATUS_t  Status;         /**< PXE status code */
01089         /** List of multicast addresses */
01090         struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
01091 } __attribute__ (( packed ));
01092 
01093 typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS PXENV_UNDI_SET_MCAST_ADDRESS_t;
01094 
01095 /** @} */ /* pxenv_undi_set_mcast_address */
01096 
01097 /** @defgroup pxenv_undi_set_station_address PXENV_UNDI_SET_STATION_ADDRESS
01098  *
01099  *  UNDI SET STATION ADDRESS
01100  *
01101  *  @{
01102  */
01103 
01104 /** PXE API function code for pxenv_undi_set_station_address() */
01105 #define PXENV_UNDI_SET_STATION_ADDRESS  0x000a
01106 
01107 /** Parameter block for pxenv_undi_set_station_address() */
01108 struct s_PXENV_UNDI_SET_STATION_ADDRESS {
01109         PXENV_STATUS_t  Status;         /**< PXE status code */
01110         MAC_ADDR_t StationAddress;      /**< Station MAC address */
01111 } __attribute__ (( packed ));
01112 
01113 typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS PXENV_UNDI_SET_STATION_ADDRESS_t;
01114 
01115 /** @} */ /* pxenv_undi_set_station_address */
01116 
01117 /** @defgroup pxenv_undi_set_packet_filter PXENV_UNDI_SET_PACKET_FILTER
01118  *
01119  *  UNDI SET PACKET FILTER
01120  *
01121  *  @{
01122  */
01123 
01124 /** PXE API function code for pxenv_undi_set_packet_filter() */
01125 #define PXENV_UNDI_SET_PACKET_FILTER    0x000b
01126 
01127 /** Parameter block for pxenv_undi_set_packet_filter() */
01128 struct s_PXENV_UNDI_SET_PACKET_FILTER {
01129         PXENV_STATUS_t  Status;         /**< PXE status code */
01130         /** Receive packet filter
01131          *
01132          * This field takes the same values as
01133          * s_PXENV_UNDI_OPEN::PktFilter.
01134          *
01135          * @note Yes, this field is a different size to
01136          * s_PXENV_UNDI_OPEN::PktFilter.  Blame "the managers at Intel
01137          * who apparently let a consultant come up with the spec
01138          * without any kind of adult supervision" (quote from hpa).
01139          */
01140         UINT8_t filter;
01141 } __attribute__ (( packed ));
01142 
01143 typedef struct s_PXENV_UNDI_SET_PACKET_FILTER PXENV_UNDI_SET_PACKET_FILTER_t;
01144 
01145 /** @} */ /* pxenv_undi_set_packet_filter */
01146 
01147 /** @defgroup pxenv_undi_get_information PXENV_UNDI_GET_INFORMATION
01148  *
01149  *  UNDI GET INFORMATION
01150  *
01151  *  @{
01152  */
01153 
01154 /** PXE API function code for pxenv_undi_get_information() */
01155 #define PXENV_UNDI_GET_INFORMATION      0x000c
01156 
01157 #define ETHER_TYPE              1       /**< Ethernet (10Mb) */
01158 #define EXP_ETHER_TYPE          2       /**< Experimental Ethernet (3Mb) */
01159 #define AX25_TYPE               3       /**< Amateur Radio AX.25 */
01160 #define TOKEN_RING_TYPE         4       /**< Proteon ProNET Token Ring */
01161 #define CHAOS_TYPE              5       /**< Chaos */
01162 #define IEEE_TYPE               6       /**< IEEE 802 Networks */
01163 #define ARCNET_TYPE             7       /**< ARCNET */
01164 
01165 /** Parameter block for pxenv_undi_get_information() */
01166 struct s_PXENV_UNDI_GET_INFORMATION {
01167         PXENV_STATUS_t  Status;         /**< PXE status code */
01168         UINT16_t BaseIo;                /**< I/O base address */
01169         UINT16_t IntNumber;             /**< IRQ number */
01170         UINT16_t MaxTranUnit;           /**< Adapter MTU */
01171         /** Hardware type
01172          *
01173          * Valid values are defined in RFC1010 ("Assigned numbers"),
01174          * and are #ETHER_TYPE, #EXP_ETHER_TYPE, #AX25_TYPE,
01175          * #TOKEN_RING_TYPE, #CHAOS_TYPE, #IEEE_TYPE or #ARCNET_TYPE.
01176          */
01177         UINT16_t HwType;
01178         UINT16_t HwAddrLen;             /**< MAC address length */
01179         MAC_ADDR_t CurrentNodeAddress;  /**< Current MAC address */
01180         MAC_ADDR_t PermNodeAddress;     /**< Permanent (EEPROM) MAC address */
01181         SEGSEL_t ROMAddress;            /**< Real-mode ROM segment address */
01182         UINT16_t RxBufCt;               /**< Receive queue length */
01183         UINT16_t TxBufCt;               /**< Transmit queue length */
01184 } __attribute__ (( packed ));
01185 
01186 typedef struct s_PXENV_UNDI_GET_INFORMATION PXENV_UNDI_GET_INFORMATION_t;
01187 
01188 /** @} */ /* pxenv_undi_get_information */
01189 
01190 /** @defgroup pxenv_undi_get_statistics PXENV_UNDI_GET_STATISTICS
01191  *
01192  *  UNDI GET STATISTICS
01193  *
01194  *  @{
01195  */
01196 
01197 /** PXE API function code for pxenv_undi_get_statistics() */
01198 #define PXENV_UNDI_GET_STATISTICS       0x000d
01199 
01200 /** Parameter block for pxenv_undi_get_statistics() */
01201 struct s_PXENV_UNDI_GET_STATISTICS {
01202         PXENV_STATUS_t  Status;         /**< PXE status code */
01203         UINT32_t XmtGoodFrames;         /**< Successful transmission count */
01204         UINT32_t RcvGoodFrames;         /**< Successful reception count */
01205         UINT32_t RcvCRCErrors;          /**< Receive CRC error count */
01206         UINT32_t RcvResourceErrors;     /**< Receive queue overflow count */
01207 } __attribute__ (( packed ));
01208 
01209 typedef struct s_PXENV_UNDI_GET_STATISTICS PXENV_UNDI_GET_STATISTICS_t;
01210 
01211 /** @} */ /* pxenv_undi_get_statistics */
01212 
01213 /** @defgroup pxenv_undi_clear_statistics PXENV_UNDI_CLEAR_STATISTICS
01214  *
01215  *  UNDI CLEAR STATISTICS
01216  *
01217  *  @{
01218  */
01219 
01220 /** PXE API function code for pxenv_undi_clear_statistics() */
01221 #define PXENV_UNDI_CLEAR_STATISTICS     0x000e
01222 
01223 /** Parameter block for pxenv_undi_clear_statistics() */
01224 struct s_PXENV_UNDI_CLEAR_STATISTICS {
01225         PXENV_STATUS_t  Status;         /**< PXE status code */
01226 } __attribute__ (( packed ));
01227 
01228 typedef struct s_PXENV_UNDI_CLEAR_STATISTICS PXENV_UNDI_CLEAR_STATISTICS_t;
01229 
01230 /** @} */ /* pxenv_undi_clear_statistics */
01231 
01232 /** @defgroup pxenv_undi_initiate_diags PXENV_UNDI_INITIATE_DIAGS
01233  *
01234  *  UNDI INITIATE DIAGS
01235  *
01236  *  @{
01237  */
01238 
01239 /** PXE API function code for pxenv_undi_initiate_diags() */
01240 #define PXENV_UNDI_INITIATE_DIAGS       0x000f
01241 
01242 /** Parameter block for pxenv_undi_initiate_diags() */
01243 struct s_PXENV_UNDI_INITIATE_DIAGS {
01244         PXENV_STATUS_t  Status;         /**< PXE status code */
01245 } __attribute__ (( packed ));
01246 
01247 typedef struct s_PXENV_UNDI_INITIATE_DIAGS PXENV_UNDI_INITIATE_DIAGS_t;
01248 
01249 /** @} */ /* pxenv_undi_initiate_diags */
01250 
01251 /** @defgroup pxenv_undi_force_interrupt PXENV_UNDI_FORCE_INTERRUPT
01252  *
01253  *  UNDI FORCE INTERRUPT
01254  *
01255  *  @{
01256  */
01257 
01258 /** PXE API function code for pxenv_undi_force_interrupt() */
01259 #define PXENV_UNDI_FORCE_INTERRUPT      0x0010
01260 
01261 /** Parameter block for pxenv_undi_force_interrupt() */
01262 struct s_PXENV_UNDI_FORCE_INTERRUPT {
01263         PXENV_STATUS_t  Status;         /**< PXE status code */
01264 } __attribute__ (( packed ));
01265 
01266 typedef struct s_PXENV_UNDI_FORCE_INTERRUPT PXENV_UNDI_FORCE_INTERRUPT_t;
01267 
01268 /** @} */ /* pxenv_undi_force_interrupt */
01269 
01270 /** @defgroup pxenv_undi_get_mcast_address PXENV_UNDI_GET_MCAST_ADDRESS
01271  *
01272  *  UNDI GET MULTICAST ADDRESS
01273  *
01274  *  @{
01275  */
01276 
01277 /** PXE API function code for pxenv_undi_get_mcast_address() */
01278 #define PXENV_UNDI_GET_MCAST_ADDRESS    0x0011
01279 
01280 /** Parameter block for pxenv_undi_get_mcast_address() */
01281 struct s_PXENV_UNDI_GET_MCAST_ADDRESS {
01282         PXENV_STATUS_t  Status;         /**< PXE status code */
01283         IP4_t InetAddr;                 /**< Multicast IP address */
01284         MAC_ADDR_t MediaAddr;           /**< Multicast MAC address */
01285 } __attribute__ (( packed ));
01286 
01287 typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS PXENV_UNDI_GET_MCAST_ADDRESS_t;
01288 
01289 /** @} */ /* pxenv_undi_get_mcast_address */
01290 
01291 /** @defgroup pxenv_undi_get_nic_type PXENV_UNDI_GET_NIC_TYPE
01292  *
01293  *  UNDI GET NIC TYPE
01294  *
01295  *  @{
01296  */
01297 
01298 /** PXE API function code for pxenv_undi_get_nic_type() */
01299 #define PXENV_UNDI_GET_NIC_TYPE         0x0012
01300 
01301 #define PCI_NIC         2               /**< PCI network card */
01302 #define PnP_NIC         3               /**< ISAPnP network card */
01303 #define CardBus_NIC     4               /**< CardBus network card */
01304 
01305 /** Information for a PCI or equivalent NIC */
01306 struct pci_nic_info {
01307         UINT16_t Vendor_ID;             /**< PCI vendor ID */
01308         UINT16_t Dev_ID;                /**< PCI device ID */
01309         UINT8_t Base_Class;             /**< PCI base class */
01310         UINT8_t Sub_Class;              /**< PCI sub class */
01311         UINT8_t Prog_Intf;              /**< PCI programming interface */
01312         UINT8_t Rev;                    /**< PCI revision */
01313         UINT16_t BusDevFunc;            /**< PCI bus:dev:fn address */
01314         UINT16_t SubVendor_ID;          /**< PCI subvendor ID */
01315         UINT16_t SubDevice_ID;          /**< PCI subdevice ID */
01316 } __attribute__ (( packed ));
01317  
01318 /** Information for an ISAPnP or equivalent NIC */
01319 struct pnp_nic_info {
01320         UINT32_t EISA_Dev_ID;           /**< EISA device ID */
01321         UINT8_t Base_Class;             /**< Base class */
01322         UINT8_t Sub_Class;              /**< Sub class */
01323         UINT8_t Prog_Intf;              /**< Programming interface */
01324         /** Card Select Number assigned to card */
01325         UINT16_t CardSelNum;
01326 } __attribute__ (( packed ));
01327 
01328 /** Parameter block for pxenv_undi_get_nic_type() */
01329 struct s_PXENV_UNDI_GET_NIC_TYPE {
01330         PXENV_STATUS_t  Status;         /**< PXE status code */
01331         /** NIC type
01332          *
01333          * Valid values are #PCI_NIC, #PnP_NIC or #CardBus_NIC.
01334          */
01335         UINT8_t NicType;
01336         /** NIC information */
01337         union nic_type_info {
01338                 /** NIC information (if #NicType==#PCI_NIC) */
01339                 struct pci_nic_info pci;
01340                 /** NIC information (if #NicType==#CardBus_NIC) */
01341                 struct pci_nic_info cardbus;
01342                 /** NIC information (if #NicType==#PnP_NIC) */
01343                 struct pnp_nic_info pnp;
01344         } info;
01345 } __attribute__ (( packed ));
01346 
01347 typedef struct s_PXENV_UNDI_GET_NIC_TYPE PXENV_UNDI_GET_NIC_TYPE_t;
01348 
01349 /** @} */ /* pxenv_undi_get_nic_type */
01350 
01351 /** @defgroup pxenv_undi_get_iface_info PXENV_UNDI_GET_IFACE_INFO
01352  *
01353  *  UNDI GET IFACE INFO
01354  *
01355  *  @{
01356  */
01357 
01358 /** PXE API function code for pxenv_undi_get_iface_info() */
01359 #define PXENV_UNDI_GET_IFACE_INFO       0x0013
01360 
01361 /** Broadcast supported */
01362 #define SUPPORTED_BROADCAST             0x0001
01363 /** Multicast supported */
01364 #define SUPPORTED_MULTICAST             0x0002
01365 /** Functional/group addressing supported */
01366 #define SUPPORTED_GROUP                 0x0004
01367 /** Promiscuous mode supported */
01368 #define SUPPORTED_PROMISCUOUS           0x0008
01369 /** Software settable station address */
01370 #define SUPPORTED_SET_STATION_ADDRESS   0x0010
01371 /** InitiateDiagnostics supported */
01372 #define SUPPORTED_DIAGNOSTICS           0x0040
01373 /** Reset MAC supported */
01374 #define SUPPORTED_RESET                 0x0400
01375 /** Open / Close Adapter supported */
01376 #define SUPPORTED_OPEN_CLOSE            0x0800
01377 /** Interrupt Request supported */
01378 #define SUPPORTED_IRQ                   0x1000
01379 
01380 /** Parameter block for pxenv_undi_get_iface_info() */
01381 struct s_PXENV_UNDI_GET_IFACE_INFO {
01382         PXENV_STATUS_t  Status;         /**< PXE status code */
01383         /** Interface type
01384          *
01385          * This is defined in the NDIS 2.0 specification to be one of
01386          * the strings "802.3", "802.4", "802.5", "802.6", "DIX",
01387          * "DIX+802.3", "APPLETALK", "ARCNET", "FDDI", "SDLC", "BSC",
01388          * "HDLC", or "ISDN".
01389          *
01390          * "Normal" Ethernet, for various historical reasons, is
01391          * "DIX+802.3".
01392          */
01393         UINT8_t IfaceType[16];
01394         UINT32_t LinkSpeed;             /**< Link speed, in bits per second */
01395         /** Service flags
01396          *
01397          * These are the "service flags" defined in the "MAC
01398          * Service-Specific Characteristics" table in the NDIS 2.0
01399          * specification.  Almost all of them are irrelevant to PXE.
01400          */
01401         UINT32_t ServiceFlags;
01402         UINT32_t Reserved[4];           /**< Must be zero */
01403 } __attribute__ (( packed ));
01404 
01405 typedef struct s_PXENV_UNDI_GET_IFACE_INFO PXENV_UNDI_GET_IFACE_INFO_t;
01406 
01407 /** @} */ /* pxenv_undi_get_iface_info */
01408 
01409 /** @defgroup pxenv_undi_get_state PXENV_UNDI_GET_STATE
01410  *
01411  *  UNDI GET STATE
01412  *
01413  *  @{
01414  */
01415 
01416 /** PXE API function code for pxenv_undi_get_state() */
01417 #define PXENV_UNDI_GET_STATE            0x0015
01418 
01419 /** pxenv_start_undi() has been called */
01420 #define PXE_UNDI_GET_STATE_STARTED      1
01421 /** pxenv_undi_initialize() has been called */
01422 #define PXE_UNDI_GET_STATE_INITIALIZED  2
01423 /** pxenv_undi_open() has been called */
01424 #define PXE_UNDI_GET_STATE_OPENED       3
01425 
01426 /** Parameter block for pxenv_undi_get_state() */
01427 struct s_PXENV_UNDI_GET_STATE {
01428         PXENV_STATUS_t  Status;         /**< PXE status code */
01429         /** Current state of the UNDI driver
01430          *
01431          * Valid values are #PXE_UNDI_GET_STATE_STARTED,
01432          * #PXE_UNDI_GET_STATE_INITIALIZED or
01433          * #PXE_UNDI_GET_STATE_OPENED.
01434          */
01435         UINT8_t UNDIstate;
01436 } __attribute__ (( packed ));
01437 
01438 typedef struct s_PXENV_UNDI_GET_STATE PXENV_UNDI_GET_STATE_t;
01439 
01440 /** @} */ /* pxenv_undi_get_state */
01441 
01442 /** @defgroup pxenv_undi_isr PXENV_UNDI_ISR
01443  *
01444  *  UNDI ISR
01445  *
01446  *  @{
01447  */
01448 
01449 /** PXE API function code for pxenv_undi_isr() */
01450 #define PXENV_UNDI_ISR                  0x0014
01451 
01452 /** Determine whether or not this is our interrupt */
01453 #define PXENV_UNDI_ISR_IN_START         1
01454 /** Start processing interrupt */
01455 #define PXENV_UNDI_ISR_IN_PROCESS       2
01456 /** Continue processing interrupt */
01457 #define PXENV_UNDI_ISR_IN_GET_NEXT      3
01458 /** This interrupt was ours */
01459 #define PXENV_UNDI_ISR_OUT_OURS         0
01460 /** This interrupt was not ours */
01461 #define PXENV_UNDI_ISR_OUT_NOT_OURS     1
01462 /** Finished processing interrupt */
01463 #define PXENV_UNDI_ISR_OUT_DONE         0
01464 /** A packet transmission has completed */
01465 #define PXENV_UNDI_ISR_OUT_TRANSMIT     2
01466 /** A packet has been received */
01467 #define PXENV_UNDI_ISR_OUT_RECEIVE      3
01468 /** We are already in the middle of processing an interrupt */
01469 #define PXENV_UNDI_ISR_OUT_BUSY         4
01470 
01471 /** Unicast packet (or packet captured in promiscuous mode) */
01472 #define P_DIRECTED      0
01473 /** Broadcast packet */
01474 #define P_BROADCAST     1
01475 /** Multicast packet */
01476 #define P_MULTICAST     2
01477 
01478 /** Parameter block for pxenv_undi_isr() */
01479 struct s_PXENV_UNDI_ISR {
01480         PXENV_STATUS_t  Status;         /**< PXE status code */
01481         /** Function flag
01482          *
01483          * Valid values are #PXENV_UNDI_ISR_IN_START,
01484          * #PXENV_UNDI_ISR_IN_PROCESS, #PXENV_UNDI_ISR_IN_GET_NEXT,
01485          * #PXENV_UNDI_ISR_OUT_OURS, #PXENV_UNDI_ISR_OUT_NOT_OURS,
01486          * #PXENV_UNDI_ISR_OUT_DONE, #PXENV_UNDI_ISR_OUT_TRANSMIT,
01487          * #PXENV_UNDI_ISR_OUT_RECEIVE or #PXENV_UNDI_ISR_OUT_BUSY.
01488          */
01489         UINT16_t FuncFlag;
01490         UINT16_t BufferLength;          /**< Data buffer length */
01491         UINT16_t FrameLength;           /**< Total frame length */
01492         UINT16_t FrameHeaderLength;     /**< Frame header length */
01493         SEGOFF16_t Frame;               /**< Data buffer address */
01494         /** Protocol type
01495          *
01496          * Valid values are #P_IP, #P_ARP, #P_RARP or #P_OTHER.
01497          */
01498         UINT8_t ProtType;
01499         /** Packet type
01500          *
01501          * Valid values are #P_DIRECTED, #P_BROADCAST or #P_MULTICAST.
01502          */
01503         UINT8_t PktType;
01504 } __attribute__ (( packed ));
01505 
01506 typedef struct s_PXENV_UNDI_ISR PXENV_UNDI_ISR_t;
01507 
01508 /** @} */ /* pxenv_undi_isr */
01509 
01510 /** @} */ /* pxe_undi_api */
01511 
01512 /** @defgroup pxe_file_api PXE FILE API
01513  *
01514  * POSIX-like file operations
01515  *
01516  * @{
01517  */
01518 
01519 /** Minimum possible opcode used within PXE FILE API */
01520 #define PXENV_FILE_MIN 0x00e0
01521 
01522 /** Minimum possible opcode used within PXE FILE API */
01523 #define PXENV_FILE_MAX 0x00ef
01524 
01525 /** @defgroup pxenv_file_open PXENV_FILE_OPEN
01526  *
01527  * FILE OPEN
01528  *
01529  * @{
01530  */
01531 
01532 /** PXE API function code for pxenv_file_open() */
01533 #define PXENV_FILE_OPEN                 0x00e0
01534 
01535 /** Parameter block for pxenv_file_open() */
01536 struct s_PXENV_FILE_OPEN {
01537         PXENV_STATUS_t Status;          /**< PXE status code */
01538         UINT16_t FileHandle;            /**< File handle */
01539         SEGOFF16_t FileName;            /**< File URL */
01540         UINT32_t Reserved;              /**< Reserved */
01541 } __attribute__ (( packed ));
01542 
01543 typedef struct s_PXENV_FILE_OPEN PXENV_FILE_OPEN_t;
01544 
01545 /** @} */ /* pxenv_file_open */
01546 
01547 /** @defgroup pxenv_file_close PXENV_FILE_CLOSE
01548  *
01549  * FILE CLOSE
01550  *
01551  * @{
01552  */
01553 
01554 /** PXE API function code for pxenv_file_close() */
01555 #define PXENV_FILE_CLOSE                0x00e1
01556 
01557 /** Parameter block for pxenv_file_close() */
01558 struct s_PXENV_FILE_CLOSE {
01559         PXENV_STATUS_t Status;          /**< PXE status code */
01560         UINT16_t FileHandle;            /**< File handle */
01561 } __attribute__ (( packed ));
01562 
01563 typedef struct s_PXENV_FILE_CLOSE PXENV_FILE_CLOSE_t;
01564 
01565 /** @} */ /* pxenv_file_close */
01566 
01567 /** @defgroup pxenv_file_select PXENV_FILE_SELECT
01568  *
01569  * FILE SELECT
01570  *
01571  * @{
01572  */
01573 
01574 /** PXE API function code for pxenv_file_select() */
01575 #define PXENV_FILE_SELECT               0x00e2
01576 
01577 /** File is ready for reading */
01578 #define RDY_READ                        0x0001
01579 
01580 /** Parameter block for pxenv_file_select() */
01581 struct s_PXENV_FILE_SELECT {
01582         PXENV_STATUS_t Status;          /**< PXE status code */
01583         UINT16_t FileHandle;            /**< File handle */
01584         UINT16_t Ready;                 /**< Indication of readiness */
01585 } __attribute__ (( packed ));
01586 
01587 typedef struct s_PXENV_FILE_SELECT PXENV_FILE_SELECT_t;
01588 
01589 /** @} */ /* pxenv_file_select */
01590 
01591 /** @defgroup pxenv_file_read PXENV_FILE_READ
01592  *
01593  * FILE READ
01594  *
01595  * @{
01596  */
01597 
01598 /** PXE API function code for pxenv_file_read() */
01599 #define PXENV_FILE_READ         0x00e3
01600 
01601 /** Parameter block for pxenv_file_read() */
01602 struct s_PXENV_FILE_READ {
01603         PXENV_STATUS_t Status;          /**< PXE status code */
01604         UINT16_t FileHandle;            /**< File handle */
01605         UINT16_t BufferSize;            /**< Data buffer size */
01606         SEGOFF16_t Buffer;              /**< Data buffer */
01607 } __attribute__ (( packed ));
01608 
01609 typedef struct s_PXENV_FILE_READ PXENV_FILE_READ_t;
01610 
01611 /** @} */ /* pxenv_file_read */
01612 
01613 /** @defgroup pxenv_get_file_size PXENV_GET_FILE_SIZE
01614  *
01615  * GET FILE SIZE
01616  *
01617  * @{
01618  */
01619 
01620 /** PXE API function code for pxenv_get_file_size() */
01621 #define PXENV_GET_FILE_SIZE             0x00e4
01622 
01623 /** Parameter block for pxenv_get_file_size() */
01624 struct s_PXENV_GET_FILE_SIZE {
01625         PXENV_STATUS_t Status;          /**< PXE status code */
01626         UINT16_t FileHandle;            /**< File handle */
01627         UINT32_t FileSize;              /**< File size */
01628 } __attribute__ (( packed ));
01629 
01630 typedef struct s_PXENV_GET_FILE_SIZE PXENV_GET_FILE_SIZE_t;
01631 
01632 /** @} */ /* pxenv_get_file_size */
01633 
01634 /** @defgroup pxenv_file_exec PXENV_FILE_EXEC
01635  *
01636  * FILE EXEC
01637  *
01638  * @{
01639  */
01640 
01641 /** PXE API function code for pxenv_file_exec() */
01642 #define PXENV_FILE_EXEC                 0x00e5
01643 
01644 /** Parameter block for pxenv_file_exec() */
01645 struct s_PXENV_FILE_EXEC {
01646         PXENV_STATUS_t Status;          /**< PXE status code */
01647         SEGOFF16_t Command;             /**< Command to execute */
01648 } __attribute__ (( packed ));
01649 
01650 typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
01651 
01652 /** @} */ /* pxenv_file_exec */
01653 
01654 /** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK
01655  *
01656  * FILE API CHECK
01657  *
01658  * @{
01659  */
01660 
01661 /** PXE API function code for pxenv_file_api_check() */
01662 #define PXENV_FILE_API_CHECK            0x00e6
01663 
01664 /** Parameter block for pxenv_file_api_check() */
01665 struct s_PXENV_FILE_API_CHECK {
01666         PXENV_STATUS_t Status;          /**< PXE status code */
01667         UINT16_t Size;                  /**< Size of structure  */
01668         UINT32_t Magic;                 /**< Magic number */
01669         UINT32_t Provider;              /**< Implementation identifier */
01670         UINT32_t APIMask;               /**< Supported API functions */
01671         UINT32_t Flags;                 /**< Reserved for the future */
01672 } __attribute__ (( packed ));
01673 
01674 typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t;
01675 
01676 /** @} */ /* pxenv_file_api_check */
01677 
01678 /** @defgroup pxenv_file_exit_hook PXENV_FILE_EXIT_HOOK
01679  *
01680  * FILE EXIT HOOK
01681  *
01682  * @{
01683  */
01684 
01685 /** PXE API function code for pxenv_file_exit_hook() */
01686 #define PXENV_FILE_EXIT_HOOK                    0x00e7
01687 
01688 /** Parameter block for pxenv_file_exit_hook() */
01689 struct s_PXENV_FILE_EXIT_HOOK {
01690         PXENV_STATUS_t Status;          /**< PXE status code */
01691         SEGOFF16_t Hook;                /**< SEG16:OFF16 to jump to */
01692 } __attribute__ (( packed ));
01693 
01694 typedef struct s_PXENV_FILE_EXIT_HOOK PXENV_FILE_EXIT_HOOK_t;
01695 
01696 /** @} */ /* pxenv_file_exit_hook */
01697 
01698 /** @defgroup pxenv_file_cmdline PXENV_FILE_CMDLINE
01699  *
01700  * FILE CMDLINE
01701  *
01702  * @{
01703  */
01704 
01705 /** PXE API function code for pxenv_file_cmdline() */
01706 #define PXENV_FILE_CMDLINE                      0x00e8
01707 
01708 /** Parameter block for pxenv_file_cmdline() */
01709 struct s_PXENV_FILE_CMDLINE {
01710         PXENV_STATUS_t Status;          /**< PXE status code */
01711         UINT16_t BufferSize;            /**< Data buffer size */
01712         SEGOFF16_t Buffer;              /**< Data buffer */
01713 } __attribute__ (( packed ));
01714 
01715 typedef struct s_PXENV_FILE_CMDLINE PXENV_FILE_CMDLINE_t;
01716 
01717 /** @} */ /* pxe_file_cmdline */
01718 
01719 /** @} */ /* pxe_file_api */
01720 
01721 /** @defgroup pxe_loader_api PXE Loader API
01722  *
01723  * The UNDI ROM loader API
01724  *
01725  * @{
01726  */
01727 
01728 /** Parameter block for undi_loader() */
01729 struct s_UNDI_LOADER {
01730         /** PXE status code */
01731         PXENV_STATUS_t Status;
01732         /** %ax register as for PXENV_START_UNDI */
01733         UINT16_t AX;
01734         /** %bx register as for PXENV_START_UNDI */
01735         UINT16_t BX;
01736         /** %dx register as for PXENV_START_UNDI */
01737         UINT16_t DX;
01738         /** %di register as for PXENV_START_UNDI */
01739         OFF16_t DI;
01740         /** %es register as for PXENV_START_UNDI */
01741         SEGSEL_t ES;
01742         /** UNDI data segment
01743          *
01744          * @note The PXE specification defines the type of this field
01745          * as #UINT16_t.  For x86, #SEGSEL_t and #UINT16_t are
01746          * equivalent anyway; for other architectures #SEGSEL_t makes
01747          * more sense.
01748          */
01749         SEGSEL_t UNDI_DS;
01750         /** UNDI code segment
01751          *
01752          * @note The PXE specification defines the type of this field
01753          * as #UINT16_t.  For x86, #SEGSEL_t and #UINT16_t are
01754          * equivalent anyway; for other architectures #SEGSEL_t makes
01755          * more sense.
01756          */
01757         SEGSEL_t UNDI_CS;
01758         /** Address of the !PXE structure (a struct s_PXE) */
01759         SEGOFF16_t PXEptr;
01760         /** Address of the PXENV+ structure (a struct s_PXENV) */
01761         SEGOFF16_t PXENVptr;
01762 } __attribute__ (( packed ));
01763 
01764 typedef struct s_UNDI_LOADER UNDI_LOADER_t;
01765 
01766 /** @} */ /* pxe_loader_api */
01767 
01768 /** @} */ /* pxe */
01769 
01770 /** @page pxe_notes Etherboot PXE implementation notes
01771 
01772 @section pxe_routing IP routing
01773 
01774 Several PXE API calls (e.g. pxenv_tftp_open() and pxenv_udp_write())
01775 allow for the caller to specify a "relay agent IP address", often in a
01776 field called "gateway" or similar.  The PXE specification states that
01777 "The IP layer should provide space for a minimum of four routing
01778 entries obtained from the default router and static route DHCP option
01779 tags in the DHCPACK message, plus any non-zero giaddr field from the
01780 DHCPOFFER message(s) accepted by the client".
01781 
01782 The DHCP static route option ("option static-routes" in dhcpd.conf)
01783 works only for classed IP routing (i.e. it provides no way to specify
01784 a subnet mask).  Since virtually everything now uses classless IP
01785 routing, the DHCP static route option is almost totally useless, and
01786 is (according to the dhcp-options man page) not implemented by any of
01787 the popular DHCP clients.
01788 
01789 This leaves the caller-specified "relay agent IP address", the giaddr
01790 field from the DHCPOFFER message(s) and the default gateway(s)
01791 provided via the routers option ("option routers" in dhcpd.conf) in
01792 the DHCPACK message.  Each of these is a default gateway address.
01793 It's a fair bet that the routers option should take priority over the
01794 giaddr field, since the routers option has to be explicitly specified
01795 by the DHCP server operator.  Similarly, it's fair to assume that the
01796 caller-specified "relay agent IP address", if present, should take
01797 priority over any other routing table entries.
01798 
01799 @bug Etherboot currently ignores all potential sources of routing
01800 information other than the first router provided to it by a DHCP
01801 routers option.
01802 
01803 @section pxe_x86_modes x86 processor mode restrictions
01804 
01805 On the x86 platform, different PXE API calls have different
01806 restrictions on the processor modes (real or protected) that can be
01807 used.  See the individual API call descriptions for the restrictions
01808 that apply to any particular call.
01809 
01810 @subsection pxe_x86_pmode16 Real mode, or protected-mode with 16-bit stack
01811 
01812 The PXE specification states that the API function can be called in
01813 protected mode only if the s_PXE::StatusCallout field is set to a
01814 non-zero value, and that the API function cannot be called with a
01815 32-bit stack segment.
01816 
01817 Etherboot does not enforce either of these restrictions; they seem (as
01818 with so much of the PXE specification) to be artifacts of the Intel
01819 implementation.
01820 
01821 */
01822 
01823 #endif /* PXE_API_H */