1 /************************************************************************** 2 Etherboot - BOOTP/TFTP Bootstrap Program 3 UNDI NIC driver for Etherboot - header file 4 5 This file Copyright (C) 2003 Michael Brown <mbrown@fensystems.co.uk> 6 of Fen Systems Ltd. (http://www.fensystems.co.uk/). All rights 7 reserved. 8 9 $Id: undi.h,v 1.5 2003/10/24 10:05:06 mcb30 Exp $ 10 ***************************************************************************/ 11 12 /* 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License as 15 * published by the Free Software Foundation; either version 2, or (at 16 * your option) any later version. 17 */ 18 19 /* Include pxe.h from FreeBSD. 20 * pxe.h defines PACKED, which etherboot.h has already defined. 21 */ 22 23 #undef PACKED 24 #include "pxe.h" 25 #include "pic8259.h" 26 27 /* __undi_call is the assembler wrapper to the real-mode UNDI calls. 28 * Pass it the real-mode segment:offset address of an undi_call_info_t 29 * structure. The parameters are only uint16_t, but GCC will push 30 * them on the stack as uint32_t anyway for the sake of alignment. We 31 * specify them here as uint32_t to remove ambiguity. 32 */ 33 34 typedef struct undi_call_info { 35 SEGOFF16_t routine; 36 uint16_t stack[3]; 37 } undi_call_info_t; 38 39 typedef uint16_t PXENV_EXIT_t; 40 #define PXENV_EXIT_SUCCESS 0x0000 41 #define PXENV_EXIT_FAILURE 0x0001 42 PXENV_EXIT_t __undi_call ( uint32_t, uint32_t ); 43 44 /* The UNDI loader parameter structure is not defined in pxe.h 45 */ 46 47 typedef struct undi_loader { 48 PXENV_STATUS_t status; 49 uint16_t ax; 50 uint16_t bx; 51 uint16_t dx; 52 uint16_t di; 53 uint16_t es; 54 uint16_t undi_ds; 55 uint16_t undi_cs; 56 uint16_t pxe_off; 57 uint16_t pxenv_off; 58 } undi_loader_t; 59 60 /* A union that can function as the parameter block for any UNDI API call. 61 */ 62 63 typedef union pxenv_structure { 64 PXENV_STATUS_t Status; /* Make it easy to read status 65 for any operation */ 66 undi_loader_t loader; 67 t_PXENV_START_UNDI start_undi; 68 t_PXENV_UNDI_STARTUP undi_startup; 69 t_PXENV_UNDI_CLEANUP undi_cleanup; 70 t_PXENV_UNDI_INITIALIZE undi_initialize; 71 t_PXENV_UNDI_SHUTDOWN undi_shutdown; 72 t_PXENV_UNDI_OPEN undi_open; 73 t_PXENV_UNDI_CLOSE undi_close; 74 t_PXENV_UNDI_TRANSMIT undi_transmit; 75 t_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address; 76 t_PXENV_UNDI_GET_INFORMATION undi_get_information; 77 t_PXENV_UNDI_GET_IFACE_INFO undi_get_iface_info; 78 t_PXENV_UNDI_ISR undi_isr; 79 t_PXENV_STOP_UNDI stop_undi; 80 t_PXENV_UNLOAD_STACK unload_stack; 81 t_PXENV_GET_CACHED_INFO get_cached_info; 82 t_PXENV_UDP_OPEN udp_open; 83 t_PXENV_UDP_CLOSE udp_close; 84 t_PXENV_UDP_READ udp_read; 85 t_PXENV_UDP_WRITE udp_write; 86 t_PXENV_TFTP_OPEN tftp_open; 87 t_PXENV_TFTP_CLOSE tftp_close; 88 t_PXENV_TFTP_READ tftp_read; 89 t_PXENV_TFTP_GET_FSIZE tftp_get_fsize; 90 } pxenv_structure_t; 91 92 /* UNDI status codes 93 */ 94 95 #define PXENV_STATUS_SUCCESS 0x0000 96 #define PXENV_STATUS_FAILURE 0x0001 97 #define PXENV_STATUS_KEEP_UNDI 0x0004 98 #define PXENV_STATUS_KEEP_ALL 0x0005 99 #define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x0061 100 101 /* BIOS PnP parameter block. We scan for this so that we can pass it 102 * to the UNDI driver. 103 */ 104 105 #define PNP_BIOS_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) ) 106 typedef struct pnp_bios { 107 uint32_t signature; 108 uint8_t version; 109 uint8_t length; 110 uint16_t control; 111 uint8_t checksum; 112 uint8_t dontcare[24]; 113 } PACKED pnp_bios_t; 114 115 /* Structures within the PXE ROM. 116 */ 117 118 #define ROM_SIGNATURE 0xaa55 119 typedef struct rom { 120 uint16_t signature; 121 uint8_t unused[0x14]; 122 uint16_t undi_rom_id_off; 123 uint16_t pcir_off; 124 uint16_t pnp_off; 125 } PACKED rom_t; 126 127 #define PCIR_SIGNATURE ( ('P'<<0) + ('C'<<8) + ('I'<<16) + ('R'<<24) ) 128 typedef struct pcir_header { 129 uint32_t signature; 130 uint16_t vendor_id; 131 uint16_t device_id; 132 } PACKED pcir_header_t; 133 134 #define PNP_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) ) 135 typedef struct pnp_header { 136 uint32_t signature; 137 uint8_t struct_revision; 138 uint8_t length; 139 uint16_t next; 140 uint8_t reserved; 141 uint8_t checksum; 142 uint16_t id[2]; 143 uint16_t manuf_str_off; 144 uint16_t product_str_off; 145 uint8_t base_type; 146 uint8_t sub_type; 147 uint8_t interface_type; 148 uint8_t indicator; 149 uint16_t boot_connect_off; 150 uint16_t disconnect_off; 151 uint16_t initialise_off; 152 uint16_t reserved2; 153 uint16_t info; 154 } PACKED pnp_header_t; 155 156 #define UNDI_SIGNATURE ( ('U'<<0) + ('N'<<8) + ('D'<<16) + ('I'<<24) ) 157 typedef struct undi_rom_id { 158 uint32_t signature; 159 uint8_t struct_length; 160 uint8_t struct_cksum; 161 uint8_t struct_rev; 162 uint8_t undi_rev[3]; 163 uint16_t undi_loader_off; 164 uint16_t stack_size; 165 uint16_t data_size; 166 uint16_t code_size; 167 } PACKED undi_rom_id_t; 168 169 /* Storage buffers that we need in base memory. We collect these into 170 * a single structure to make allocation simpler. 171 */ 172 173 typedef struct undi_base_mem_xmit_data { 174 MAC_ADDR destaddr; 175 t_PXENV_UNDI_TBD tbd; 176 } undi_base_mem_xmit_data_t; 177 178 typedef struct undi_base_mem_data { 179 undi_call_info_t undi_call_info; 180 pxenv_structure_t pxs; 181 undi_base_mem_xmit_data_t xmit_data; 182 char xmit_buffer[ETH_FRAME_LEN]; 183 char irq_handler[0]; /* Must be last in structure */ 184 } undi_base_mem_data_t; 185 186 /* Macros and data structures used when freeing bits of base memory 187 * used by the UNDI driver. 188 */ 189 190 #define FIRING_SQUAD_TARGET_SIZE 8 191 #define FIRING_SQUAD_TARGET_INDEX(x) ( (x) / FIRING_SQUAD_TARGET_SIZE ) 192 #define FIRING_SQUAD_TARGET_BIT(x) ( (x) % FIRING_SQUAD_TARGET_SIZE ) 193 typedef struct firing_squad_lineup { 194 uint8_t targets[ 640 / FIRING_SQUAD_TARGET_SIZE ]; 195 } firing_squad_lineup_t; 196 typedef enum firing_squad_shoot { 197 DONTSHOOT = 0, 198 SHOOT = 1 199 } firing_squad_shoot_t; 200 201 /* Driver private data structure. 202 */ 203 204 typedef struct undi { 205 /* Pointers to various data structures */ 206 pnp_bios_t *pnp_bios; 207 rom_t *rom; 208 undi_rom_id_t *undi_rom_id; 209 pxe_t *pxe; 210 undi_call_info_t *undi_call_info; 211 pxenv_structure_t *pxs; 212 undi_base_mem_xmit_data_t *xmit_data; 213 /* Pointers and sizes to keep track of allocated base memory */ 214 undi_base_mem_data_t *base_mem_data; 215 void *driver_code; 216 size_t driver_code_size; 217 void *driver_data; 218 size_t driver_data_size; 219 char *xmit_buffer; 220 /* Flags. We keep our own instead of trusting the UNDI driver 221 * to have implemented PXENV_UNDI_GET_STATE correctly. Plus 222 * there's the small issue of PXENV_UNDI_GET_STATE being the 223 * same API call as PXENV_STOP_UNDI... 224 */ 225 uint8_t prestarted; /* pxenv_start_undi() has been called */ 226 uint8_t started; /* pxenv_undi_startup() has been called */ 227 uint8_t initialized; /* pxenv_undi_initialize() has been called */ 228 uint8_t opened; /* pxenv_undi_open() has been called */ 229 /* Parameters that we need to store for future reference 230 */ 231 struct pci_device pci; 232 irq_t irq; 233 } undi_t; 234 235 /* Constants 236 */ 237 238 #define HUNT_FOR_PIXIES 0 239 #define HUNT_FOR_UNDI_ROMS 1 240