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