17c478bd9Sstevel@tonic-gate /************************************************************************** 27c478bd9Sstevel@tonic-gate Etherboot - BOOTP/TFTP Bootstrap Program 37c478bd9Sstevel@tonic-gate UNDI NIC driver for Etherboot - header file 47c478bd9Sstevel@tonic-gate 57c478bd9Sstevel@tonic-gate This file Copyright (C) 2003 Michael Brown <mbrown@fensystems.co.uk> 67c478bd9Sstevel@tonic-gate of Fen Systems Ltd. (http://www.fensystems.co.uk/). All rights 77c478bd9Sstevel@tonic-gate reserved. 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate $Id: undi.h,v 1.5 2003/10/24 10:05:06 mcb30 Exp $ 107c478bd9Sstevel@tonic-gate ***************************************************************************/ 117c478bd9Sstevel@tonic-gate 127c478bd9Sstevel@tonic-gate /* 137c478bd9Sstevel@tonic-gate * This program is free software; you can redistribute it and/or 147c478bd9Sstevel@tonic-gate * modify it under the terms of the GNU General Public License as 157c478bd9Sstevel@tonic-gate * published by the Free Software Foundation; either version 2, or (at 167c478bd9Sstevel@tonic-gate * your option) any later version. 177c478bd9Sstevel@tonic-gate */ 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate /* Include pxe.h from FreeBSD. 207c478bd9Sstevel@tonic-gate * pxe.h defines PACKED, which etherboot.h has already defined. 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate #undef PACKED 247c478bd9Sstevel@tonic-gate #include "pxe.h" 257c478bd9Sstevel@tonic-gate #include "pic8259.h" 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* __undi_call is the assembler wrapper to the real-mode UNDI calls. 287c478bd9Sstevel@tonic-gate * Pass it the real-mode segment:offset address of an undi_call_info_t 297c478bd9Sstevel@tonic-gate * structure. The parameters are only uint16_t, but GCC will push 307c478bd9Sstevel@tonic-gate * them on the stack as uint32_t anyway for the sake of alignment. We 317c478bd9Sstevel@tonic-gate * specify them here as uint32_t to remove ambiguity. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate typedef struct undi_call_info { 357c478bd9Sstevel@tonic-gate SEGOFF16_t routine; 367c478bd9Sstevel@tonic-gate uint16_t stack[3]; 377c478bd9Sstevel@tonic-gate } undi_call_info_t; 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate typedef uint16_t PXENV_EXIT_t; 407c478bd9Sstevel@tonic-gate #define PXENV_EXIT_SUCCESS 0x0000 417c478bd9Sstevel@tonic-gate #define PXENV_EXIT_FAILURE 0x0001 427c478bd9Sstevel@tonic-gate PXENV_EXIT_t __undi_call ( uint32_t, uint32_t ); 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* The UNDI loader parameter structure is not defined in pxe.h 457c478bd9Sstevel@tonic-gate */ 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate typedef struct undi_loader { 487c478bd9Sstevel@tonic-gate PXENV_STATUS_t status; 497c478bd9Sstevel@tonic-gate uint16_t ax; 507c478bd9Sstevel@tonic-gate uint16_t bx; 517c478bd9Sstevel@tonic-gate uint16_t dx; 527c478bd9Sstevel@tonic-gate uint16_t di; 537c478bd9Sstevel@tonic-gate uint16_t es; 547c478bd9Sstevel@tonic-gate uint16_t undi_ds; 557c478bd9Sstevel@tonic-gate uint16_t undi_cs; 567c478bd9Sstevel@tonic-gate uint16_t pxe_off; 577c478bd9Sstevel@tonic-gate uint16_t pxenv_off; 587c478bd9Sstevel@tonic-gate } undi_loader_t; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* A union that can function as the parameter block for any UNDI API call. 617c478bd9Sstevel@tonic-gate */ 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate typedef union pxenv_structure { 647c478bd9Sstevel@tonic-gate PXENV_STATUS_t Status; /* Make it easy to read status 657c478bd9Sstevel@tonic-gate for any operation */ 667c478bd9Sstevel@tonic-gate undi_loader_t loader; 677c478bd9Sstevel@tonic-gate t_PXENV_START_UNDI start_undi; 687c478bd9Sstevel@tonic-gate t_PXENV_UNDI_STARTUP undi_startup; 697c478bd9Sstevel@tonic-gate t_PXENV_UNDI_CLEANUP undi_cleanup; 707c478bd9Sstevel@tonic-gate t_PXENV_UNDI_INITIALIZE undi_initialize; 717c478bd9Sstevel@tonic-gate t_PXENV_UNDI_SHUTDOWN undi_shutdown; 727c478bd9Sstevel@tonic-gate t_PXENV_UNDI_OPEN undi_open; 737c478bd9Sstevel@tonic-gate t_PXENV_UNDI_CLOSE undi_close; 747c478bd9Sstevel@tonic-gate t_PXENV_UNDI_TRANSMIT undi_transmit; 757c478bd9Sstevel@tonic-gate t_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address; 767c478bd9Sstevel@tonic-gate t_PXENV_UNDI_GET_INFORMATION undi_get_information; 777c478bd9Sstevel@tonic-gate t_PXENV_UNDI_GET_IFACE_INFO undi_get_iface_info; 787c478bd9Sstevel@tonic-gate t_PXENV_UNDI_ISR undi_isr; 797c478bd9Sstevel@tonic-gate t_PXENV_STOP_UNDI stop_undi; 807c478bd9Sstevel@tonic-gate t_PXENV_UNLOAD_STACK unload_stack; 8199ed6083Sszhou t_PXENV_GET_CACHED_INFO get_cached_info; 8299ed6083Sszhou t_PXENV_UDP_OPEN udp_open; 8399ed6083Sszhou t_PXENV_UDP_CLOSE udp_close; 8499ed6083Sszhou t_PXENV_UDP_READ udp_read; 8599ed6083Sszhou t_PXENV_UDP_WRITE udp_write; 8699ed6083Sszhou t_PXENV_TFTP_OPEN tftp_open; 8799ed6083Sszhou t_PXENV_TFTP_CLOSE tftp_close; 8899ed6083Sszhou t_PXENV_TFTP_READ tftp_read; 8999ed6083Sszhou t_PXENV_TFTP_GET_FSIZE tftp_get_fsize; 907c478bd9Sstevel@tonic-gate } pxenv_structure_t; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate /* UNDI status codes 937c478bd9Sstevel@tonic-gate */ 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate #define PXENV_STATUS_SUCCESS 0x0000 967c478bd9Sstevel@tonic-gate #define PXENV_STATUS_FAILURE 0x0001 977c478bd9Sstevel@tonic-gate #define PXENV_STATUS_KEEP_UNDI 0x0004 987c478bd9Sstevel@tonic-gate #define PXENV_STATUS_KEEP_ALL 0x0005 997c478bd9Sstevel@tonic-gate #define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x0061 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /* BIOS PnP parameter block. We scan for this so that we can pass it 1027c478bd9Sstevel@tonic-gate * to the UNDI driver. 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate #define PNP_BIOS_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) ) 1067c478bd9Sstevel@tonic-gate typedef struct pnp_bios { 1077c478bd9Sstevel@tonic-gate uint32_t signature; 1087c478bd9Sstevel@tonic-gate uint8_t version; 1097c478bd9Sstevel@tonic-gate uint8_t length; 1107c478bd9Sstevel@tonic-gate uint16_t control; 1117c478bd9Sstevel@tonic-gate uint8_t checksum; 1127c478bd9Sstevel@tonic-gate uint8_t dontcare[24]; 1137c478bd9Sstevel@tonic-gate } PACKED pnp_bios_t; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate /* Structures within the PXE ROM. 1167c478bd9Sstevel@tonic-gate */ 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate #define ROM_SIGNATURE 0xaa55 1197c478bd9Sstevel@tonic-gate typedef struct rom { 1207c478bd9Sstevel@tonic-gate uint16_t signature; 1217c478bd9Sstevel@tonic-gate uint8_t unused[0x14]; 1227c478bd9Sstevel@tonic-gate uint16_t undi_rom_id_off; 1237c478bd9Sstevel@tonic-gate uint16_t pcir_off; 1247c478bd9Sstevel@tonic-gate uint16_t pnp_off; 1257c478bd9Sstevel@tonic-gate } PACKED rom_t; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate #define PCIR_SIGNATURE ( ('P'<<0) + ('C'<<8) + ('I'<<16) + ('R'<<24) ) 1287c478bd9Sstevel@tonic-gate typedef struct pcir_header { 1297c478bd9Sstevel@tonic-gate uint32_t signature; 1307c478bd9Sstevel@tonic-gate uint16_t vendor_id; 1317c478bd9Sstevel@tonic-gate uint16_t device_id; 1327c478bd9Sstevel@tonic-gate } PACKED pcir_header_t; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate #define PNP_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) ) 1357c478bd9Sstevel@tonic-gate typedef struct pnp_header { 1367c478bd9Sstevel@tonic-gate uint32_t signature; 1377c478bd9Sstevel@tonic-gate uint8_t struct_revision; 1387c478bd9Sstevel@tonic-gate uint8_t length; 1397c478bd9Sstevel@tonic-gate uint16_t next; 1407c478bd9Sstevel@tonic-gate uint8_t reserved; 1417c478bd9Sstevel@tonic-gate uint8_t checksum; 1427c478bd9Sstevel@tonic-gate uint16_t id[2]; 1437c478bd9Sstevel@tonic-gate uint16_t manuf_str_off; 1447c478bd9Sstevel@tonic-gate uint16_t product_str_off; 1457c478bd9Sstevel@tonic-gate uint8_t base_type; 1467c478bd9Sstevel@tonic-gate uint8_t sub_type; 1477c478bd9Sstevel@tonic-gate uint8_t interface_type; 1487c478bd9Sstevel@tonic-gate uint8_t indicator; 1497c478bd9Sstevel@tonic-gate uint16_t boot_connect_off; 1507c478bd9Sstevel@tonic-gate uint16_t disconnect_off; 1517c478bd9Sstevel@tonic-gate uint16_t initialise_off; 1527c478bd9Sstevel@tonic-gate uint16_t reserved2; 1537c478bd9Sstevel@tonic-gate uint16_t info; 1547c478bd9Sstevel@tonic-gate } PACKED pnp_header_t; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate #define UNDI_SIGNATURE ( ('U'<<0) + ('N'<<8) + ('D'<<16) + ('I'<<24) ) 1577c478bd9Sstevel@tonic-gate typedef struct undi_rom_id { 1587c478bd9Sstevel@tonic-gate uint32_t signature; 1597c478bd9Sstevel@tonic-gate uint8_t struct_length; 1607c478bd9Sstevel@tonic-gate uint8_t struct_cksum; 1617c478bd9Sstevel@tonic-gate uint8_t struct_rev; 1627c478bd9Sstevel@tonic-gate uint8_t undi_rev[3]; 1637c478bd9Sstevel@tonic-gate uint16_t undi_loader_off; 1647c478bd9Sstevel@tonic-gate uint16_t stack_size; 1657c478bd9Sstevel@tonic-gate uint16_t data_size; 1667c478bd9Sstevel@tonic-gate uint16_t code_size; 1677c478bd9Sstevel@tonic-gate } PACKED undi_rom_id_t; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* Storage buffers that we need in base memory. We collect these into 1707c478bd9Sstevel@tonic-gate * a single structure to make allocation simpler. 1717c478bd9Sstevel@tonic-gate */ 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate typedef struct undi_base_mem_xmit_data { 1747c478bd9Sstevel@tonic-gate MAC_ADDR destaddr; 1757c478bd9Sstevel@tonic-gate t_PXENV_UNDI_TBD tbd; 1767c478bd9Sstevel@tonic-gate } undi_base_mem_xmit_data_t; 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate typedef struct undi_base_mem_data { 1797c478bd9Sstevel@tonic-gate undi_call_info_t undi_call_info; 1807c478bd9Sstevel@tonic-gate pxenv_structure_t pxs; 1817c478bd9Sstevel@tonic-gate undi_base_mem_xmit_data_t xmit_data; 1827c478bd9Sstevel@tonic-gate char xmit_buffer[ETH_FRAME_LEN]; 1837c478bd9Sstevel@tonic-gate char irq_handler[0]; /* Must be last in structure */ 1847c478bd9Sstevel@tonic-gate } undi_base_mem_data_t; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate /* Macros and data structures used when freeing bits of base memory 1877c478bd9Sstevel@tonic-gate * used by the UNDI driver. 1887c478bd9Sstevel@tonic-gate */ 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate #define FIRING_SQUAD_TARGET_SIZE 8 1917c478bd9Sstevel@tonic-gate #define FIRING_SQUAD_TARGET_INDEX(x) ( (x) / FIRING_SQUAD_TARGET_SIZE ) 1927c478bd9Sstevel@tonic-gate #define FIRING_SQUAD_TARGET_BIT(x) ( (x) % FIRING_SQUAD_TARGET_SIZE ) 1937c478bd9Sstevel@tonic-gate typedef struct firing_squad_lineup { 1947c478bd9Sstevel@tonic-gate uint8_t targets[ 640 / FIRING_SQUAD_TARGET_SIZE ]; 1957c478bd9Sstevel@tonic-gate } firing_squad_lineup_t; 1967c478bd9Sstevel@tonic-gate typedef enum firing_squad_shoot { 1977c478bd9Sstevel@tonic-gate DONTSHOOT = 0, 1987c478bd9Sstevel@tonic-gate SHOOT = 1 1997c478bd9Sstevel@tonic-gate } firing_squad_shoot_t; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* Driver private data structure. 2027c478bd9Sstevel@tonic-gate */ 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate typedef struct undi { 2057c478bd9Sstevel@tonic-gate /* Pointers to various data structures */ 2067c478bd9Sstevel@tonic-gate pnp_bios_t *pnp_bios; 2077c478bd9Sstevel@tonic-gate rom_t *rom; 2087c478bd9Sstevel@tonic-gate undi_rom_id_t *undi_rom_id; 2097c478bd9Sstevel@tonic-gate pxe_t *pxe; 2107c478bd9Sstevel@tonic-gate undi_call_info_t *undi_call_info; 2117c478bd9Sstevel@tonic-gate pxenv_structure_t *pxs; 2127c478bd9Sstevel@tonic-gate undi_base_mem_xmit_data_t *xmit_data; 2137c478bd9Sstevel@tonic-gate /* Pointers and sizes to keep track of allocated base memory */ 2147c478bd9Sstevel@tonic-gate undi_base_mem_data_t *base_mem_data; 2157c478bd9Sstevel@tonic-gate void *driver_code; 2167c478bd9Sstevel@tonic-gate size_t driver_code_size; 2177c478bd9Sstevel@tonic-gate void *driver_data; 2187c478bd9Sstevel@tonic-gate size_t driver_data_size; 2197c478bd9Sstevel@tonic-gate char *xmit_buffer; 2207c478bd9Sstevel@tonic-gate /* Flags. We keep our own instead of trusting the UNDI driver 2217c478bd9Sstevel@tonic-gate * to have implemented PXENV_UNDI_GET_STATE correctly. Plus 2227c478bd9Sstevel@tonic-gate * there's the small issue of PXENV_UNDI_GET_STATE being the 2237c478bd9Sstevel@tonic-gate * same API call as PXENV_STOP_UNDI... 2247c478bd9Sstevel@tonic-gate */ 2257c478bd9Sstevel@tonic-gate uint8_t prestarted; /* pxenv_start_undi() has been called */ 2267c478bd9Sstevel@tonic-gate uint8_t started; /* pxenv_undi_startup() has been called */ 2277c478bd9Sstevel@tonic-gate uint8_t initialized; /* pxenv_undi_initialize() has been called */ 2287c478bd9Sstevel@tonic-gate uint8_t opened; /* pxenv_undi_open() has been called */ 2297c478bd9Sstevel@tonic-gate /* Parameters that we need to store for future reference 2307c478bd9Sstevel@tonic-gate */ 2317c478bd9Sstevel@tonic-gate struct pci_device pci; 2327c478bd9Sstevel@tonic-gate irq_t irq; 2337c478bd9Sstevel@tonic-gate } undi_t; 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate /* Constants 2367c478bd9Sstevel@tonic-gate */ 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate #define HUNT_FOR_PIXIES 0 2397c478bd9Sstevel@tonic-gate #define HUNT_FOR_UNDI_ROMS 1 240