OpenSolaris_b135/grub/grub-0.97/netboot/undi.h

Compare this file to the similar file:
Show the results in this format:

/**************************************************************************
Etherboot -  BOOTP/TFTP Bootstrap Program
UNDI NIC driver for Etherboot - header file

This file Copyright (C) 2003 Michael Brown <mbrown@fensystems.co.uk>
of Fen Systems Ltd. (http://www.fensystems.co.uk/).  All rights
reserved.

$Id: undi.h,v 1.5 2003/10/24 10:05:06 mcb30 Exp $
***************************************************************************/

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2, or (at
 * your option) any later version.
 */

/* Include pxe.h from FreeBSD.
 * pxe.h defines PACKED, which etherboot.h has already defined.
 */

#undef PACKED
#include "pxe.h"
#include "pic8259.h"

/* __undi_call is the assembler wrapper to the real-mode UNDI calls.
 * Pass it the real-mode segment:offset address of an undi_call_info_t
 * structure.  The parameters are only uint16_t, but GCC will push
 * them on the stack as uint32_t anyway for the sake of alignment.  We
 * specify them here as uint32_t to remove ambiguity.
 */

typedef struct undi_call_info {
	SEGOFF16_t	routine;
	uint16_t	stack[3];
} undi_call_info_t;

typedef uint16_t PXENV_EXIT_t;
#define PXENV_EXIT_SUCCESS 0x0000
#define PXENV_EXIT_FAILURE 0x0001
PXENV_EXIT_t __undi_call ( uint32_t, uint32_t );

/* The UNDI loader parameter structure is not defined in pxe.h
 */

typedef struct undi_loader {
	PXENV_STATUS_t	status;
	uint16_t	ax;
	uint16_t	bx;
	uint16_t	dx;
	uint16_t	di;
	uint16_t	es;
	uint16_t	undi_ds;
	uint16_t	undi_cs;
	uint16_t	pxe_off;
	uint16_t	pxenv_off;
} undi_loader_t;

/* A union that can function as the parameter block for any UNDI API call.
 */

typedef union pxenv_structure {
	PXENV_STATUS_t			Status; /* Make it easy to read status
						   for any operation */
	undi_loader_t			loader;
	t_PXENV_START_UNDI		start_undi;
	t_PXENV_UNDI_STARTUP		undi_startup;
	t_PXENV_UNDI_CLEANUP		undi_cleanup;
	t_PXENV_UNDI_INITIALIZE		undi_initialize;
	t_PXENV_UNDI_SHUTDOWN		undi_shutdown;
	t_PXENV_UNDI_OPEN		undi_open;
	t_PXENV_UNDI_CLOSE		undi_close;
	t_PXENV_UNDI_TRANSMIT		undi_transmit;
	t_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address;
	t_PXENV_UNDI_GET_INFORMATION	undi_get_information;
	t_PXENV_UNDI_GET_IFACE_INFO	undi_get_iface_info;
	t_PXENV_UNDI_ISR		undi_isr;
	t_PXENV_STOP_UNDI		stop_undi;
	t_PXENV_UNLOAD_STACK		unload_stack;
	t_PXENV_GET_CACHED_INFO		get_cached_info;
	t_PXENV_UDP_OPEN		udp_open;
	t_PXENV_UDP_CLOSE		udp_close;
	t_PXENV_UDP_READ		udp_read;
	t_PXENV_UDP_WRITE		udp_write;
	t_PXENV_TFTP_OPEN		tftp_open;
	t_PXENV_TFTP_CLOSE		tftp_close;
	t_PXENV_TFTP_READ		tftp_read;
	t_PXENV_TFTP_GET_FSIZE		tftp_get_fsize;
} pxenv_structure_t;

/* UNDI status codes
 */

#define PXENV_STATUS_SUCCESS			0x0000
#define PXENV_STATUS_FAILURE			0x0001
#define PXENV_STATUS_KEEP_UNDI			0x0004
#define PXENV_STATUS_KEEP_ALL			0x0005
#define PXENV_STATUS_UNDI_MEDIATEST_FAILED	0x0061

/* BIOS PnP parameter block.  We scan for this so that we can pass it
 * to the UNDI driver.
 */

#define PNP_BIOS_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) )
typedef struct pnp_bios {
	uint32_t	signature;
	uint8_t		version;
	uint8_t		length;
	uint16_t	control;
	uint8_t		checksum;
	uint8_t		dontcare[24];
} PACKED pnp_bios_t;

/* Structures within the PXE ROM.
 */

#define ROM_SIGNATURE 0xaa55
typedef struct rom {
	uint16_t	signature;
	uint8_t		unused[0x14];
	uint16_t	undi_rom_id_off;
	uint16_t	pcir_off;
	uint16_t	pnp_off;
} PACKED rom_t;	

#define PCIR_SIGNATURE ( ('P'<<0) + ('C'<<8) + ('I'<<16) + ('R'<<24) )
typedef struct pcir_header {
	uint32_t	signature;
	uint16_t	vendor_id;
	uint16_t	device_id;
} PACKED pcir_header_t;

#define PNP_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) )
typedef struct pnp_header {
	uint32_t	signature;
	uint8_t		struct_revision;
	uint8_t		length;
	uint16_t	next;
	uint8_t		reserved;
	uint8_t		checksum;
	uint16_t	id[2];
	uint16_t	manuf_str_off;
	uint16_t	product_str_off;
	uint8_t		base_type;
	uint8_t		sub_type;
	uint8_t		interface_type;
	uint8_t		indicator;
	uint16_t	boot_connect_off;
	uint16_t	disconnect_off;
	uint16_t	initialise_off;
	uint16_t	reserved2;
	uint16_t	info;
} PACKED pnp_header_t;

#define UNDI_SIGNATURE ( ('U'<<0) + ('N'<<8) + ('D'<<16) + ('I'<<24) )
typedef struct undi_rom_id {
	uint32_t	signature;
	uint8_t		struct_length;
	uint8_t		struct_cksum;
	uint8_t		struct_rev;
	uint8_t		undi_rev[3];
	uint16_t	undi_loader_off;
	uint16_t	stack_size;
	uint16_t	data_size;
	uint16_t	code_size;
} PACKED undi_rom_id_t;

/* Storage buffers that we need in base memory.  We collect these into
 * a single structure to make allocation simpler.
 */

typedef struct undi_base_mem_xmit_data {
	MAC_ADDR		destaddr;
	t_PXENV_UNDI_TBD	tbd;
} undi_base_mem_xmit_data_t;

typedef struct undi_base_mem_data {
	undi_call_info_t	undi_call_info;
	pxenv_structure_t	pxs;
	undi_base_mem_xmit_data_t xmit_data;
	char			xmit_buffer[ETH_FRAME_LEN];
	char			irq_handler[0]; /* Must be last in structure */
} undi_base_mem_data_t;

/* Macros and data structures used when freeing bits of base memory
 * used by the UNDI driver.
 */

#define FIRING_SQUAD_TARGET_SIZE 8
#define FIRING_SQUAD_TARGET_INDEX(x) ( (x) / FIRING_SQUAD_TARGET_SIZE )
#define FIRING_SQUAD_TARGET_BIT(x) ( (x) % FIRING_SQUAD_TARGET_SIZE )
typedef struct firing_squad_lineup {
	uint8_t targets[ 640 / FIRING_SQUAD_TARGET_SIZE ];
} firing_squad_lineup_t;
typedef enum firing_squad_shoot {
	DONTSHOOT = 0,
	SHOOT = 1
} firing_squad_shoot_t;

/* Driver private data structure.
 */

typedef struct undi {
	/* Pointers to various data structures */
	pnp_bios_t		*pnp_bios;
	rom_t			*rom;
	undi_rom_id_t		*undi_rom_id;
	pxe_t			*pxe;
	undi_call_info_t	*undi_call_info;
	pxenv_structure_t	*pxs;
	undi_base_mem_xmit_data_t *xmit_data;
	/* Pointers and sizes to keep track of allocated base memory */
	undi_base_mem_data_t	*base_mem_data;
	void			*driver_code;
	size_t			driver_code_size;
	void			*driver_data;
	size_t			driver_data_size;
	char			*xmit_buffer;
	/* Flags.  We keep our own instead of trusting the UNDI driver
	 * to have implemented PXENV_UNDI_GET_STATE correctly.  Plus
	 * there's the small issue of PXENV_UNDI_GET_STATE being the
	 * same API call as PXENV_STOP_UNDI...
	 */
	uint8_t prestarted;	/* pxenv_start_undi() has been called */
	uint8_t started;	/* pxenv_undi_startup() has been called */
	uint8_t	initialized;	/* pxenv_undi_initialize() has been called */
	uint8_t opened;		/* pxenv_undi_open() has been called */
	/* Parameters that we need to store for future reference
	 */
	struct pci_device	pci;
	irq_t			irq;
} undi_t;

/* Constants
 */

#define HUNT_FOR_PIXIES 0
#define HUNT_FOR_UNDI_ROMS 1