diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/ipxe/src/arch/i386/include | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip | |
Diffstat (limited to 'roms/ipxe/src/arch/i386/include')
71 files changed, 6272 insertions, 0 deletions
| diff --git a/roms/ipxe/src/arch/i386/include/basemem.h b/roms/ipxe/src/arch/i386/include/basemem.h new file mode 100644 index 00000000..c477c7fe --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/basemem.h @@ -0,0 +1,35 @@ +#ifndef _BASEMEM_H +#define _BASEMEM_H + +/** @file + * + * Base memory allocation + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <realmode.h> +#include <bios.h> + +/** + * Read the BIOS free base memory counter + * + * @ret fbms		Free base memory counter (in kB) + */ +static inline unsigned int get_fbms ( void ) { +	uint16_t fbms; + +	get_real ( fbms, BDA_SEG, BDA_FBMS ); +	return fbms; +} + +extern void set_fbms ( unsigned int new_fbms ); + +/* Actually in hidemem.c, but putting it here avoids polluting the + * architecture-independent include/hidemem.h. + */ +extern void hide_basemem ( void ); + +#endif /* _BASEMEM_H */ diff --git a/roms/ipxe/src/arch/i386/include/basemem_packet.h b/roms/ipxe/src/arch/i386/include/basemem_packet.h new file mode 100644 index 00000000..3cb47767 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/basemem_packet.h @@ -0,0 +1,15 @@ +#ifndef BASEMEM_PACKET_H +#define BASEMEM_PACKET_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <realmode.h> + +/** Maximum length of base memory packet buffer */ +#define BASEMEM_PACKET_LEN 1514 + +/** Base memory packet buffer */ +extern char __bss16_array ( basemem_packet, [BASEMEM_PACKET_LEN] ); +#define basemem_packet __use_data16 ( basemem_packet ) + +#endif /* BASEMEM_PACKET_H */ diff --git a/roms/ipxe/src/arch/i386/include/bios.h b/roms/ipxe/src/arch/i386/include/bios.h new file mode 100644 index 00000000..0754b116 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bios.h @@ -0,0 +1,14 @@ +#ifndef BIOS_H +#define BIOS_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#define BDA_SEG 0x0040 +#define BDA_EQUIPMENT_WORD 0x0010 +#define BDA_FBMS 0x0013 +#define BDA_REBOOT 0x0072 +#define BDA_REBOOT_WARM 0x1234 +#define BDA_NUM_DRIVES 0x0075 +#define BDA_CHAR_HEIGHT 0x0085 + +#endif /* BIOS_H */ diff --git a/roms/ipxe/src/arch/i386/include/bios_disks.h b/roms/ipxe/src/arch/i386/include/bios_disks.h new file mode 100644 index 00000000..0dd7c4eb --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bios_disks.h @@ -0,0 +1,69 @@ +#ifndef BIOS_DISKS_H +#define BIOS_DISKS_H + +#include "dev.h" + +/* + * Constants + * + */ + +#define	BIOS_DISK_MAX_NAME_LEN	6 + +struct bios_disk_sector { +	char data[512]; +}; + +/* + * The location of a BIOS disk + * + */ +struct bios_disk_loc { +	uint8_t drive; +}; + +/* + * A physical BIOS disk device + * + */ +struct bios_disk_device { +	char name[BIOS_DISK_MAX_NAME_LEN]; +	uint8_t drive; +	uint8_t type; +}; + +/* + * A BIOS disk driver, with a valid device ID range and naming + * function. + * + */ +struct bios_disk_driver { +	void ( *fill_drive_name ) ( char *buf, uint8_t drive ); +	uint8_t min_drive; +	uint8_t max_drive; +}; + +/* + * Define a BIOS disk driver + * + */ +#define BIOS_DISK_DRIVER( _name, _fill_drive_name, _min_drive, _max_drive )   \ +	static struct bios_disk_driver _name = {			      \ +		.fill_drive_name = _fill_drive_name,			      \ +		.min_drive = _min_drive,				      \ +		.max_drive = _max_drive,				      \ +	} + +/* + * Functions in bios_disks.c + * + */ + + +/* + * bios_disk bus global definition + * + */ +extern struct bus_driver bios_disk_driver; + +#endif /* BIOS_DISKS_H */ diff --git a/roms/ipxe/src/arch/i386/include/biosint.h b/roms/ipxe/src/arch/i386/include/biosint.h new file mode 100644 index 00000000..ab466af3 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/biosint.h @@ -0,0 +1,33 @@ +#ifndef BIOSINT_H +#define BIOSINT_H + +/** + * @file BIOS interrupts + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <realmode.h> + +struct segoff; + +/** + * Hooked interrupt count + * + * At exit, after unhooking all possible interrupts, this counter + * should be examined.  If it is non-zero, it means that we failed to + * unhook at least one interrupt vector, and so must not free up the + * memory we are using.  (Note that this also implies that we should + * re-hook INT 15 in order to hide ourselves from the memory map). + */ +extern uint16_t __text16 ( hooked_bios_interrupts ); +#define hooked_bios_interrupts __use_text16 ( hooked_bios_interrupts ) + +extern void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler, +				  struct segoff *chain_vector ); +extern int unhook_bios_interrupt ( unsigned int interrupt, +				   unsigned int handler, +				   struct segoff *chain_vector ); + +#endif /* BIOSINT_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/byteswap.h b/roms/ipxe/src/arch/i386/include/bits/byteswap.h new file mode 100644 index 00000000..0d9cb967 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/byteswap.h @@ -0,0 +1,70 @@ +#ifndef _BITS_BYTESWAP_H +#define _BITS_BYTESWAP_H + +/** @file + * + * Byte-order swapping functions + * + */ + +#include <stdint.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +static inline __attribute__ (( always_inline, const )) uint16_t +__bswap_variable_16 ( uint16_t x ) { +	__asm__ ( "xchgb %b0,%h0" : "=q" ( x ) : "0" ( x ) ); +	return x; +} + +static inline __attribute__ (( always_inline )) void +__bswap_16s ( uint16_t *x ) { +	__asm__ ( "rorw $8, %0" : "+m" ( *x ) ); +} + +static inline __attribute__ (( always_inline, const )) uint32_t +__bswap_variable_32 ( uint32_t x ) { +	__asm__ ( "bswapl %0" : "=r" ( x ) : "0" ( x ) ); +	return x; +} + +static inline __attribute__ (( always_inline )) void +__bswap_32s ( uint32_t *x ) { +	__asm__ ( "bswapl %0" : "=r" ( *x ) : "0" ( *x ) ); +} + +static inline __attribute__ (( always_inline, const )) uint64_t +__bswap_variable_64 ( uint64_t x ) { +	uint32_t in_high = ( x >> 32 ); +	uint32_t in_low = ( x & 0xffffffffUL ); +	uint32_t out_high; +	uint32_t out_low; + +	__asm__ ( "bswapl %0\n\t" +		  "bswapl %1\n\t" +		  "xchgl %0,%1\n\t" +		  : "=r" ( out_high ), "=r" ( out_low ) +		  : "0" ( in_high ), "1" ( in_low ) ); + +	return ( ( ( ( uint64_t ) out_high ) << 32 ) | +		 ( ( uint64_t ) out_low ) ); +} + +static inline __attribute__ (( always_inline )) void +__bswap_64s ( uint64_t *x ) { +	struct { +		uint32_t __attribute__ (( may_alias )) low; +		uint32_t __attribute__ (( may_alias )) high; +	} __attribute__ (( may_alias )) *dwords = ( ( void * ) x ); +	uint32_t discard; + +	__asm__ ( "movl %0,%2\n\t" +		  "bswapl %2\n\t" +		  "xchgl %2,%1\n\t" +		  "bswapl %2\n\t" +		  "movl %2,%0\n\t" +		  : "+m" ( dwords->low ), "+m" ( dwords->high ), +		    "=r" ( discard ) ); +} + +#endif /* _BITS_BYTESWAP_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/compiler.h b/roms/ipxe/src/arch/i386/include/bits/compiler.h new file mode 100644 index 00000000..d48b4b38 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/compiler.h @@ -0,0 +1,38 @@ +#ifndef _BITS_COMPILER_H +#define _BITS_COMPILER_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifndef ASSEMBLY + +/** Declare a function with standard calling conventions */ +#define __asmcall __attribute__ (( cdecl, regparm(0) )) + +/** + * Declare a function with libgcc implicit linkage + * + * It seems as though gcc expects its implicit arithmetic functions to + * be cdecl, even if -mrtd is specified.  This is somewhat + * inconsistent; for example, if -mregparm=3 is used then the implicit + * functions do become regparm(3). + * + * The implicit calls to memcpy() and memset() which gcc can generate + * do not seem to have this inconsistency; -mregparm and -mrtd affect + * them in the same way as any other function. + * + * Update (25/4/14): it appears that more recent gcc versions do allow + * -mrtd to affect calls to the implicit arithmetic functions.  There + * is nothing obvious in the gcc changelogs to indicate precisely when + * this happened.  From experimentation with available gcc versions, + * the change occurred sometime between v4.6.3 and v4.7.2.  We assume + * that only versions up to v4.6.x require the special treatment. + */ +#if ( __GNUC__ < 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ <= 6 ) ) +#define __libgcc __attribute__ (( cdecl )) +#else +#define __libgcc +#endif + +#endif /* ASSEMBLY */ + +#endif /* _BITS_COMPILER_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/endian.h b/roms/ipxe/src/arch/i386/include/bits/endian.h new file mode 100644 index 00000000..84188542 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/endian.h @@ -0,0 +1,8 @@ +#ifndef ETHERBOOT_BITS_ENDIAN_H +#define ETHERBOOT_BITS_ENDIAN_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#define __BYTE_ORDER __LITTLE_ENDIAN + +#endif /* ETHERBOOT_BITS_ENDIAN_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/entropy.h b/roms/ipxe/src/arch/i386/include/bits/entropy.h new file mode 100644 index 00000000..6dcceec6 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/entropy.h @@ -0,0 +1,14 @@ +#ifndef _BITS_ENTROPY_H +#define _BITS_ENTROPY_H + +/** @file + * + * i386-specific entropy API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/rtc_entropy.h> + +#endif /* _BITS_ENTROPY_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/linux_api.h b/roms/ipxe/src/arch/i386/include/bits/linux_api.h new file mode 100644 index 00000000..dc6e7416 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/linux_api.h @@ -0,0 +1,6 @@ +#ifndef _I386_LINUX_API_H +#define _I386_LINUX_API_H + +#define __SYSCALL_mmap __NR_mmap2 + +#endif /* _I386_LINUX_API_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/nap.h b/roms/ipxe/src/arch/i386/include/bits/nap.h new file mode 100644 index 00000000..64066e6a --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/nap.h @@ -0,0 +1,15 @@ +#ifndef _BITS_NAP_H +#define _BITS_NAP_H + +/** @file + * + * i386-specific CPU sleeping API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/bios_nap.h> +#include <ipxe/efi/efix86_nap.h> + +#endif /* _BITS_MAP_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/profile.h b/roms/ipxe/src/arch/i386/include/bits/profile.h new file mode 100644 index 00000000..f3ee54ae --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/profile.h @@ -0,0 +1,28 @@ +#ifndef _BITS_PROFILE_H +#define _BITS_PROFILE_H + +/** @file + * + * Profiling + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> + +/** + * Get profiling timestamp + * + * @ret timestamp	Timestamp + */ +static inline __attribute__ (( always_inline )) uint64_t +profile_timestamp ( void ) { +	uint64_t tsc; + +	/* Read timestamp counter */ +	__asm__ __volatile__ ( "rdtsc" : "=A" ( tsc ) ); +	return tsc; +} + +#endif /* _BITS_PROFILE_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/reboot.h b/roms/ipxe/src/arch/i386/include/bits/reboot.h new file mode 100644 index 00000000..5b09e95f --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/reboot.h @@ -0,0 +1,14 @@ +#ifndef _BITS_REBOOT_H +#define _BITS_REBOOT_H + +/** @file + * + * i386-specific reboot API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/bios_reboot.h> + +#endif /* _BITS_REBOOT_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/sanboot.h b/roms/ipxe/src/arch/i386/include/bits/sanboot.h new file mode 100644 index 00000000..9c77a4d4 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/sanboot.h @@ -0,0 +1,14 @@ +#ifndef _BITS_SANBOOT_H +#define _BITS_SANBOOT_H + +/** @file + * + * i386-specific sanboot API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/bios_sanboot.h> + +#endif /* _BITS_SANBOOT_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/smbios.h b/roms/ipxe/src/arch/i386/include/bits/smbios.h new file mode 100644 index 00000000..cc79eec5 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/smbios.h @@ -0,0 +1,14 @@ +#ifndef _BITS_SMBIOS_H +#define _BITS_SMBIOS_H + +/** @file + * + * i386-specific SMBIOS API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/bios_smbios.h> + +#endif /* _BITS_SMBIOS_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/stdint.h b/roms/ipxe/src/arch/i386/include/bits/stdint.h new file mode 100644 index 00000000..8edf1319 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/stdint.h @@ -0,0 +1,23 @@ +#ifndef _BITS_STDINT_H +#define _BITS_STDINT_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +typedef __SIZE_TYPE__		size_t; +typedef signed long		ssize_t; +typedef signed long		off_t; + +typedef unsigned char		uint8_t; +typedef unsigned short		uint16_t; +typedef unsigned int		uint32_t; +typedef unsigned long long	uint64_t; + +typedef signed char		int8_t; +typedef signed short		int16_t; +typedef signed int		int32_t; +typedef signed long long	int64_t; + +typedef unsigned long		physaddr_t; +typedef unsigned long		intptr_t; + +#endif /* _BITS_STDINT_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/strings.h b/roms/ipxe/src/arch/i386/include/bits/strings.h new file mode 100644 index 00000000..092bcb59 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/strings.h @@ -0,0 +1,50 @@ +#ifndef _BITS_STRINGS_H +#define _BITS_STRINGS_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Find last (i.e. most significant) set bit + * + * @v value		Value + * @ret msb		Most significant bit set in value (LSB=1), or zero + */ +static inline __attribute__ (( always_inline )) int __flsl ( long value ) { +	long msb_minus_one; + +	/* If the input value is zero, the BSR instruction returns +	 * ZF=1 and leaves an undefined value in the output register. +	 * Perform this check in C rather than asm so that it can be +	 * omitted in cases where the compiler is able to prove that +	 * the input is non-zero. +	 */ +	if ( value ) { +		__asm__ ( "bsrl %1, %0" +			  : "=r" ( msb_minus_one ) +			  : "rm" ( value ) ); +		return ( msb_minus_one + 1 ); +	} else { +		return 0; +	} +} + +/** + * Find last (i.e. most significant) set bit + * + * @v value		Value + * @ret msb		Most significant bit set in value (LSB=1), or zero + */ +static inline __attribute__ (( always_inline )) int __flsll ( long long value ){ +	unsigned long high = ( value >> 32 ); +	unsigned long low = ( value >> 0 ); + +	if ( high ) { +		return ( 32 + __flsl ( high ) ); +	} else if ( low ) { +		return ( __flsl ( low ) ); +	} else { +		return 0; +	} +} + +#endif /* _BITS_STRINGS_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/time.h b/roms/ipxe/src/arch/i386/include/bits/time.h new file mode 100644 index 00000000..24dd020e --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/time.h @@ -0,0 +1,14 @@ +#ifndef _BITS_TIME_H +#define _BITS_TIME_H + +/** @file + * + * i386-specific time API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/rtc_time.h> + +#endif /* _BITS_TIME_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/timer.h b/roms/ipxe/src/arch/i386/include/bits/timer.h new file mode 100644 index 00000000..50b676b7 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/timer.h @@ -0,0 +1,15 @@ +#ifndef _BITS_TIMER_H +#define _BITS_TIMER_H + +/** @file + * + * i386-specific timer API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/bios_timer.h> +#include <ipxe/rdtsc_timer.h> + +#endif /* _BITS_TIMER_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/uaccess.h b/roms/ipxe/src/arch/i386/include/bits/uaccess.h new file mode 100644 index 00000000..2bb52e02 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/uaccess.h @@ -0,0 +1,14 @@ +#ifndef _BITS_UACCESS_H +#define _BITS_UACCESS_H + +/** @file + * + * i386-specific user access API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <librm.h> + +#endif /* _BITS_UACCESS_H */ diff --git a/roms/ipxe/src/arch/i386/include/bits/umalloc.h b/roms/ipxe/src/arch/i386/include/bits/umalloc.h new file mode 100644 index 00000000..54fb006f --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bits/umalloc.h @@ -0,0 +1,14 @@ +#ifndef _BITS_UMALLOC_H +#define _BITS_UMALLOC_H + +/** @file + * + * i386-specific user memory allocation API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/memtop_umalloc.h> + +#endif /* _BITS_UMALLOC_H */ diff --git a/roms/ipxe/src/arch/i386/include/bochs.h b/roms/ipxe/src/arch/i386/include/bochs.h new file mode 100644 index 00000000..9d090fc1 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bochs.h @@ -0,0 +1,34 @@ +#ifndef BOCHS_H +#define BOCHS_H + +/** @file + * + * bochs breakpoints + * + * This file defines @c bochsbp, the magic breakpoint instruction that + * is incredibly useful when debugging under bochs.  This file should + * never be included in production code. + * + * Use the pseudo-instruction @c bochsbp in assembly code, or the + * bochsbp() function in C code. + * + */ + +#ifdef ASSEMBLY + +/* Breakpoint for when debugging under bochs */ +#define bochsbp xchgw %bx, %bx +#define BOCHSBP bochsbp + +#else /* ASSEMBLY */ + +/** Breakpoint for when debugging under bochs */ +static inline void bochsbp ( void ) { +	__asm__ __volatile__ ( "xchgw %bx, %bx" ); +} + +#endif /* ASSEMBLY */ + +#warning "bochs.h should not be included into production code" + +#endif /* BOCHS_H */ diff --git a/roms/ipxe/src/arch/i386/include/bootsector.h b/roms/ipxe/src/arch/i386/include/bootsector.h new file mode 100644 index 00000000..8730fbfc --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bootsector.h @@ -0,0 +1,14 @@ +#ifndef _BOOTSECTOR_H +#define _BOOTSECTOR_H + +/** @file + * + * x86 bootsector image format + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +extern int call_bootsector ( unsigned int segment, unsigned int offset, +			     unsigned int drive ); + +#endif /* _BOOTSECTOR_H */ diff --git a/roms/ipxe/src/arch/i386/include/bzimage.h b/roms/ipxe/src/arch/i386/include/bzimage.h new file mode 100644 index 00000000..7e42e318 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/bzimage.h @@ -0,0 +1,142 @@ +#ifndef _BZIMAGE_H +#define _BZIMAGE_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> + +/** + * A bzImage header + * + * As documented in Documentation/i386/boot.txt + */ +struct bzimage_header { +	/** The size of the setup in sectors +	 * +	 * If this field contains 0, assume it contains 4. +	 */ +	uint8_t setup_sects; +	/** If set, the root is mounted readonly */ +	uint16_t root_flags; +	/** DO NOT USE - for bootsect.S use only */ +	uint16_t syssize; +	/** DO NOT USE - obsolete */ +	uint16_t swap_dev; +	/** DO NOT USE - for bootsect.S use only */ +	uint16_t ram_size; +	/** Video mode control */ +	uint16_t vid_mode; +	/** Default root device number */ +	uint16_t root_dev; +	/** 0xAA55 magic number */ +	uint16_t boot_flag; +	/** Jump instruction */ +	uint16_t jump; +	/** Magic signature "HdrS" */ +	uint32_t header; +	/** Boot protocol version supported */ +	uint16_t version; +	/** Boot loader hook (see below) */ +	uint32_t realmode_swtch; +	/** The load-low segment (0x1000) (obsolete) */ +	uint16_t start_sys; +	/** Pointer to kernel version string */ +	uint16_t kernel_version; +	/** Boot loader identifier */ +	uint8_t type_of_loader; +	/** Boot protocol option flags */ +	uint8_t loadflags; +	/** Move to high memory size (used with hooks) */ +	uint16_t setup_move_size; +	/** Boot loader hook (see below) */ +	uint32_t code32_start; +	/** initrd load address (set by boot loader) */ +	uint32_t ramdisk_image; +	/** initrd size (set by boot loader) */ +	uint32_t ramdisk_size; +	/** DO NOT USE - for bootsect.S use only */ +	uint32_t bootsect_kludge; +	/** Free memory after setup end */ +	uint16_t heap_end_ptr; +	/** Unused */ +	uint16_t pad1; +	/** 32-bit pointer to the kernel command line */ +	uint32_t cmd_line_ptr; +	/** Highest legal initrd address */ +	uint32_t initrd_addr_max; +	/** Physical addr alignment required for kernel	*/ +	uint32_t kernel_alignment; +	/** Whether kernel is relocatable or not */ +	uint8_t relocatable_kernel; +	/** Unused */ +	uint8_t pad2[3]; +	/** Maximum size of the kernel command line */ +	uint32_t cmdline_size; +} __attribute__ (( packed )); + +/** Offset of bzImage header within kernel image */ +#define BZI_HDR_OFFSET 0x1f1 + +/** bzImage boot flag value */ +#define BZI_BOOT_FLAG 0xaa55 + +/** bzImage magic signature value */ +#define BZI_SIGNATURE 0x53726448 + +/** bzImage boot loader identifier for Etherboot */ +#define BZI_LOADER_TYPE_ETHERBOOT 0x40 + +/** bzImage boot loader identifier for iPXE + * + * We advertise ourselves as Etherboot version 6. + */ +#define BZI_LOADER_TYPE_IPXE ( BZI_LOADER_TYPE_ETHERBOOT | 0x06 ) + +/** bzImage "load high" flag */ +#define BZI_LOAD_HIGH 0x01 + +/** Load address for high-loaded kernels */ +#define BZI_LOAD_HIGH_ADDR 0x100000 + +/** Load address for low-loaded kernels */ +#define BZI_LOAD_LOW_ADDR 0x10000 + +/** bzImage "kernel can use heap" flag */ +#define BZI_CAN_USE_HEAP 0x80 + +/** bzImage special video mode "normal" */ +#define BZI_VID_MODE_NORMAL 0xffff + +/** bzImage special video mode "ext" */ +#define BZI_VID_MODE_EXT 0xfffe + +/** bzImage special video mode "ask" */ +#define BZI_VID_MODE_ASK 0xfffd + +/** bzImage maximum initrd address for versions < 2.03 */ +#define BZI_INITRD_MAX 0x37ffffff + +/** bzImage command-line structure used by older kernels */ +struct bzimage_cmdline { +	/** Magic signature */ +	uint16_t magic; +	/** Offset to command line */ +	uint16_t offset; +} __attribute__ (( packed )); + +/** Offset of bzImage command-line structure within kernel image */ +#define BZI_CMDLINE_OFFSET 0x20 + +/** bzImage command line present magic marker value */ +#define BZI_CMDLINE_MAGIC 0xa33f + +/** Assumed size of real-mode portion (including .bss) */ +#define BZI_ASSUMED_RM_SIZE 0x8000 + +/** Amount of stack space to provide */ +#define BZI_STACK_SIZE 0x1000 + +/** Maximum size of command line */ +#define BZI_CMDLINE_SIZE 0x7ff + +#endif /* _BZIMAGE_H */ diff --git a/roms/ipxe/src/arch/i386/include/comboot.h b/roms/ipxe/src/arch/i386/include/comboot.h new file mode 100644 index 00000000..2d2f04fe --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/comboot.h @@ -0,0 +1,132 @@ +#ifndef COMBOOT_H +#define COMBOOT_H + +/** + * @file + * + * SYSLINUX COMBOOT + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <setjmp.h> +#include <ipxe/in.h> + +/** Segment used for COMBOOT PSP and image */ +#define COMBOOT_PSP_SEG 0x07C0 + +/** Entry point address of COM32 images */ +#define COM32_START_PHYS 0x101000 + +/** COM32 bounce buffer segment */ +#define COM32_BOUNCE_SEG 0x07C0 + +/** Size of SYSLINUX file block in bytes */ +#define COMBOOT_FILE_BLOCKSZ 512 + +/** COMBOOT feature flags (INT 22h AX=15h) */ +#define COMBOOT_FEATURE_LOCAL_BOOT (1 << 0) +#define COMBOOT_FEATURE_IDLE_LOOP  (1 << 1) + +/** Maximum number of shuffle descriptors for  + * shuffle and boot functions + * (INT 22h AX=0012h, 001Ah, 001Bh) + */ +#define COMBOOT_MAX_SHUFFLE_DESCRIPTORS 682 + +typedef union { +	uint32_t l; +	uint16_t w[2]; +	uint8_t  b[4]; +} com32_reg32_t; + +typedef struct { +	uint16_t gs;                /* Offset  0 */ +	uint16_t fs;                /* Offset  2 */ +	uint16_t es;                /* Offset  4 */ +	uint16_t ds;                /* Offset  6 */ + +	com32_reg32_t edi;          /* Offset  8 */ +	com32_reg32_t esi;          /* Offset 12 */ +	com32_reg32_t ebp;          /* Offset 16 */ +	com32_reg32_t _unused_esp;  /* Offset 20 */ +	com32_reg32_t ebx;          /* Offset 24 */ +	com32_reg32_t edx;          /* Offset 28 */ +	com32_reg32_t ecx;          /* Offset 32 */ +	com32_reg32_t eax;          /* Offset 36 */ + +	com32_reg32_t eflags;       /* Offset 40 */ +} com32sys_t; + +typedef struct { +	uint32_t eax;               /* Offset  0 */ +	uint32_t ecx;               /* Offset  4 */ +	uint32_t edx;               /* Offset  8 */ +	uint32_t ebx;               /* Offset 12 */ +	uint32_t esp;               /* Offset 16 */ +	uint32_t ebp;               /* Offset 20 */ +	uint32_t esi;               /* Offset 24 */ +	uint32_t edi;               /* Offset 28 */ + +	uint32_t eip;               /* Offset 32 */ +} syslinux_pm_regs; + +typedef struct { +	uint16_t es;                /* Offset  0 */ +	uint16_t _unused_cs;        /* Offset  2 */ +	uint16_t ds;                /* Offset  4 */ +	uint16_t ss;                /* Offset  6 */ +	uint16_t fs;                /* Offset  8 */ +	uint16_t gs;                /* Offset 10 */ + +	uint32_t eax;                /* Offset 12 */ +	uint32_t ecx;                /* Offset 16 */ +	uint32_t edx;                /* Offset 20 */ +	uint32_t ebx;                /* Offset 24 */ +	uint32_t esp;                /* Offset 28 */ +	uint32_t ebp;                /* Offset 32 */ +	uint32_t esi;                /* Offset 36 */ +	uint32_t edi;                /* Offset 40 */ + +	uint16_t ip;                /* Offset 44 */ +	uint16_t cs;                /* Offset 46 */ +} syslinux_rm_regs; + +typedef struct { +	uint32_t dest; +	uint32_t src; +	uint32_t len; +} comboot_shuffle_descriptor; + +extern void hook_comboot_interrupts ( ); +extern void unhook_comboot_interrupts ( ); + +/* These are not the correct prototypes, but it doens't matter,  + * as we only ever get the address of these functions; + * they are only called from COM32 code running in PHYS_CODE + */ +extern void com32_intcall_wrapper ( ); +extern void com32_farcall_wrapper ( ); +extern void com32_cfarcall_wrapper ( ); + +/* Resolve a hostname to an (IPv4) address */ +extern int comboot_resolv ( const char *name, struct in_addr *address ); + +/* setjmp/longjmp context buffer used to return after loading an image */ +extern rmjmp_buf comboot_return; + +extern void *com32_external_esp; + +#define COMBOOT_EXIT 1 +#define COMBOOT_EXIT_RUN_KERNEL 2 +#define COMBOOT_EXIT_COMMAND 3 + +extern void comboot_force_text_mode ( void ); + +#define COMBOOT_VIDEO_GRAPHICS    0x01 +#define COMBOOT_VIDEO_NONSTANDARD 0x02 +#define COMBOOT_VIDEO_VESA        0x04 +#define COMBOOT_VIDEO_NOTEXT      0x08 + +#endif diff --git a/roms/ipxe/src/arch/i386/include/efi/ipxe/dhcp_arch.h b/roms/ipxe/src/arch/i386/include/efi/ipxe/dhcp_arch.h new file mode 100644 index 00000000..18417721 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/efi/ipxe/dhcp_arch.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 VMware, Inc.  All Rights Reserved. + * + * 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 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _DHCP_ARCH_H +#define _DHCP_ARCH_H + +/** @file + * + * Architecture-specific DHCP options + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/dhcp.h> + +#define DHCP_ARCH_VENDOR_CLASS_ID \ +	DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':',      \ +		      'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '6', ':', \ +		      'U', 'N', 'D', 'I', ':', '0', '0', '3', '0', '1', '0' ) + +#define DHCP_ARCH_CLIENT_ARCHITECTURE \ +	DHCP_WORD ( DHCP_CLIENT_ARCHITECTURE_IA32 ) + +#define DHCP_ARCH_CLIENT_NDI DHCP_OPTION ( 1 /* UNDI */ , 3, 10 /* v3.10 */ ) + +#endif diff --git a/roms/ipxe/src/arch/i386/include/fakee820.h b/roms/ipxe/src/arch/i386/include/fakee820.h new file mode 100644 index 00000000..9d00fb67 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/fakee820.h @@ -0,0 +1,9 @@ +#ifndef _FAKEE820_H +#define _FAKEE820_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +extern void fake_e820 ( void ); +extern void unfake_e820 ( void ); + +#endif /* _FAKEE820_H */ diff --git a/roms/ipxe/src/arch/i386/include/gdbmach.h b/roms/ipxe/src/arch/i386/include/gdbmach.h new file mode 100644 index 00000000..416ae341 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/gdbmach.h @@ -0,0 +1,74 @@ +#ifndef GDBMACH_H +#define GDBMACH_H + +/** @file + * + * GDB architecture specifics + * + * This file declares functions for manipulating the machine state and + * debugging context. + * + */ + +#include <stdint.h> + +typedef unsigned long gdbreg_t; + +/* The register snapshot, this must be in sync with interrupt handler and the + * GDB protocol. */ +enum { +	GDBMACH_EAX, +	GDBMACH_ECX, +	GDBMACH_EDX, +	GDBMACH_EBX, +	GDBMACH_ESP, +	GDBMACH_EBP, +	GDBMACH_ESI, +	GDBMACH_EDI, +	GDBMACH_EIP, +	GDBMACH_EFLAGS, +	GDBMACH_CS, +	GDBMACH_SS, +	GDBMACH_DS, +	GDBMACH_ES, +	GDBMACH_FS, +	GDBMACH_GS, +	GDBMACH_NREGS, +	GDBMACH_SIZEOF_REGS = GDBMACH_NREGS * sizeof ( gdbreg_t ) +}; + +/* Breakpoint types */ +enum { +	GDBMACH_BPMEM, +	GDBMACH_BPHW, +	GDBMACH_WATCH, +	GDBMACH_RWATCH, +	GDBMACH_AWATCH, +}; + +/* Interrupt vectors */ +extern void gdbmach_nocode_sigfpe ( void ); +extern void gdbmach_nocode_sigtrap ( void ); +extern void gdbmach_nocode_sigstkflt ( void ); +extern void gdbmach_nocode_sigill ( void ); +extern void gdbmach_withcode_sigbus ( void ); +extern void gdbmach_withcode_sigsegv ( void ); + +static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) { +	regs [ GDBMACH_EIP ] = pc; +} + +static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) { +	regs [ GDBMACH_EFLAGS ] &= ~( 1 << 8 ); /* Trace Flag (TF) */ +	regs [ GDBMACH_EFLAGS ] |= ( step << 8 ); +} + +static inline void gdbmach_breakpoint ( void ) { +	__asm__ __volatile__ ( "int $3\n" ); +} + +extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len, int enable ); + +extern void gdbmach_init ( void ); + +#endif /* GDBMACH_H */ diff --git a/roms/ipxe/src/arch/i386/include/initrd.h b/roms/ipxe/src/arch/i386/include/initrd.h new file mode 100644 index 00000000..a5659f43 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/initrd.h @@ -0,0 +1,30 @@ +#ifndef _INITRD_H +#define _INITRD_H + +/** @file + * + * Initial ramdisk (initrd) reshuffling + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/uaccess.h> + +/** Minimum alignment for initrds + * + * Some versions of Linux complain about initrds that are not + * page-aligned. + */ +#define INITRD_ALIGN 4096 + +/** Minimum free space required to reshuffle initrds + * + * Chosen to avoid absurdly long reshuffling times + */ +#define INITRD_MIN_FREE_LEN ( 512 * 1024 ) + +extern void initrd_reshuffle ( userptr_t bottom ); +extern int initrd_reshuffle_check ( size_t len, userptr_t bottom ); + +#endif /* _INITRD_H */ diff --git a/roms/ipxe/src/arch/i386/include/int13.h b/roms/ipxe/src/arch/i386/include/int13.h new file mode 100644 index 00000000..e337ca1d --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/int13.h @@ -0,0 +1,333 @@ +#ifndef INT13_H +#define INT13_H + +/** @file + * + * INT 13 emulation + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <ipxe/list.h> +#include <ipxe/edd.h> +#include <realmode.h> + +/** + * @defgroup int13ops INT 13 operation codes + * @{ + */ + +/** Reset disk system */ +#define INT13_RESET			0x00 +/** Get status of last operation */ +#define INT13_GET_LAST_STATUS		0x01 +/** Read sectors */ +#define INT13_READ_SECTORS		0x02 +/** Write sectors */ +#define INT13_WRITE_SECTORS		0x03 +/** Get drive parameters */ +#define INT13_GET_PARAMETERS		0x08 +/** Get disk type */ +#define INT13_GET_DISK_TYPE		0x15 +/** Extensions installation check */ +#define INT13_EXTENSION_CHECK		0x41 +/** Extended read */ +#define INT13_EXTENDED_READ		0x42 +/** Extended write */ +#define INT13_EXTENDED_WRITE		0x43 +/** Verify sectors */ +#define INT13_EXTENDED_VERIFY		0x44 +/** Extended seek */ +#define INT13_EXTENDED_SEEK		0x47 +/** Get extended drive parameters */ +#define INT13_GET_EXTENDED_PARAMETERS	0x48 +/** Get CD-ROM status / terminate emulation */ +#define INT13_CDROM_STATUS_TERMINATE	0x4b +/** Read CD-ROM boot catalog */ +#define INT13_CDROM_READ_BOOT_CATALOG	0x4d + +/** @} */ + +/** + * @defgroup int13status INT 13 status codes + * @{ + */ + +/** Operation completed successfully */ +#define INT13_STATUS_SUCCESS		0x00 +/** Invalid function or parameter */ +#define INT13_STATUS_INVALID		0x01 +/** Read error */ +#define INT13_STATUS_READ_ERROR		0x04 +/** Reset failed */ +#define INT13_STATUS_RESET_FAILED	0x05 +/** Write error */ +#define INT13_STATUS_WRITE_ERROR	0xcc + +/** @} */ + +/** Block size for non-extended INT 13 calls */ +#define INT13_BLKSIZE 512 + +/** @defgroup int13fddtype INT 13 floppy disk drive types + * @{ + */ + +/** 360K */ +#define INT13_FDD_TYPE_360K		0x01 +/** 1.2M */ +#define INT13_FDD_TYPE_1M2		0x02 +/** 720K */ +#define INT13_FDD_TYPE_720K		0x03 +/** 1.44M */ +#define INT13_FDD_TYPE_1M44		0x04 + +/** An INT 13 disk address packet */ +struct int13_disk_address { +	/** Size of the packet, in bytes */ +	uint8_t bufsize; +	/** Reserved */ +	uint8_t reserved_a; +	/** Block count */ +	uint8_t count; +	/** Reserved */ +	uint8_t reserved_b; +	/** Data buffer */ +	struct segoff buffer; +	/** Starting block number */ +	uint64_t lba; +	/** Data buffer (EDD 3.0+ only) */ +	uint64_t buffer_phys; +	/** Block count (EDD 4.0+ only) */ +	uint32_t long_count; +	/** Reserved */ +	uint32_t reserved_c; +} __attribute__ (( packed )); + +/** INT 13 disk parameters */ +struct int13_disk_parameters { +	/** Size of this structure */ +	uint16_t bufsize; +	/** Flags */ +	uint16_t flags; +	/** Number of cylinders */ +	uint32_t cylinders; +	/** Number of heads */ +	uint32_t heads; +	/** Number of sectors per track */ +	uint32_t sectors_per_track; +	/** Total number of sectors on drive */ +	uint64_t sectors; +	/** Bytes per sector */ +	uint16_t sector_size; +	/** Device parameter table extension */ +	struct segoff dpte; +	/** Device path information */ +	struct edd_device_path_information dpi; +} __attribute__ (( packed )); + +/** + * @defgroup int13types INT 13 disk types + * @{ + */ + +/** No such drive */ +#define INT13_DISK_TYPE_NONE	0x00 +/** Floppy without change-line support */ +#define INT13_DISK_TYPE_FDD	0x01 +/** Floppy with change-line support */ +#define INT13_DISK_TYPE_FDD_CL	0x02 +/** Hard disk */ +#define INT13_DISK_TYPE_HDD	0x03 + +/** @} */ + +/** + * @defgroup int13flags INT 13 disk parameter flags + * @{ + */ + +/** DMA boundary errors handled transparently */ +#define INT13_FL_DMA_TRANSPARENT 0x01 +/** CHS information is valid */ +#define INT13_FL_CHS_VALID	 0x02 +/** Removable drive */ +#define INT13_FL_REMOVABLE	 0x04 +/** Write with verify supported */ +#define INT13_FL_VERIFIABLE	 0x08 +/** Has change-line supported (valid only for removable drives) */ +#define INT13_FL_CHANGE_LINE	 0x10 +/** Drive can be locked (valid only for removable drives) */ +#define INT13_FL_LOCKABLE	 0x20 +/** CHS is max possible, not current media (valid only for removable drives) */ +#define INT13_FL_CHS_MAX	 0x40 + +/** @} */ + +/** + * @defgroup int13exts INT 13 extension flags + * @{ + */ + +/** Extended disk access functions supported */ +#define INT13_EXTENSION_LINEAR		0x01 +/** Removable drive functions supported */ +#define INT13_EXTENSION_REMOVABLE	0x02 +/** EDD functions supported */ +#define INT13_EXTENSION_EDD		0x04 +/** 64-bit extensions are present */ +#define INT13_EXTENSION_64BIT		0x08 + +/** @} */ + +/** + * @defgroup int13vers INT 13 extension versions + * @{ + */ + +/** INT13 extensions version 1.x */ +#define INT13_EXTENSION_VER_1_X		0x01 +/** INT13 extensions version 2.0 (EDD-1.0) */ +#define INT13_EXTENSION_VER_2_0		0x20 +/** INT13 extensions version 2.1 (EDD-1.1) */ +#define INT13_EXTENSION_VER_2_1		0x21 +/** INT13 extensions version 3.0 (EDD-3.0) */ +#define INT13_EXTENSION_VER_3_0		0x30 + +/** @} */  + +/** Maximum number of sectors for which CHS geometry is allowed to be valid + * + * This number is taken from the EDD specification. + */ +#define INT13_MAX_CHS_SECTORS		15482880 + +/** Bootable CD-ROM specification packet */ +struct int13_cdrom_specification { +	/** Size of packet in bytes */ +	uint8_t size; +	/** Boot media type */ +	uint8_t media_type; +	/** Drive number */ +	uint8_t drive; +	/** CD-ROM controller number */ +	uint8_t controller; +	/** LBA of disk image to emulate */ +	uint32_t lba; +	/** Device specification */ +	uint16_t device; +	/** Segment of 3K buffer for caching CD-ROM reads */ +	uint16_t cache_segment; +	/** Load segment for initial boot image */ +	uint16_t load_segment; +	/** Number of 512-byte sectors to load */ +	uint16_t load_sectors; +	/** Low 8 bits of cylinder number */ +	uint8_t cyl; +	/** Sector number, plus high 2 bits of cylinder number */ +	uint8_t cyl_sector; +	/** Head number */ +	uint8_t head; +} __attribute__ (( packed )); + +/** Bootable CD-ROM boot catalog command packet */ +struct int13_cdrom_boot_catalog_command { +	/** Size of packet in bytes */ +	uint8_t size; +	/** Number of sectors of boot catalog to read */ +	uint8_t count; +	/** Buffer for boot catalog */ +	uint32_t buffer; +	/** First sector in boot catalog to transfer */ +	uint16_t start; +} __attribute__ (( packed )); + +/** A C/H/S address within a partition table entry */ +struct partition_chs { +	/** Head number */ +	uint8_t head; +	/** Sector number, plus high 2 bits of cylinder number */ +	uint8_t cyl_sector; +	/** Low 8 bits of cylinder number */ +	uint8_t cyl; +} __attribute__ (( packed )); + +#define PART_HEAD(chs) ( (chs).head ) +#define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f ) +#define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) ) + +/** A partition table entry within the MBR */ +struct partition_table_entry { +	/** Bootable flag */ +	uint8_t bootable; +	/** C/H/S start address */ +	struct partition_chs chs_start; +	/** System indicator (partition type) */ +	uint8_t type; +	/** C/H/S end address */ +	struct partition_chs chs_end; +	/** Linear start address */ +	uint32_t start; +	/** Linear length */ +	uint32_t length; +} __attribute__ (( packed )); + +/** A Master Boot Record */ +struct master_boot_record { +	/** Code area */ +	uint8_t code[440]; +	/** Disk signature */ +	uint32_t signature; +	/** Padding */ +	uint8_t pad[2]; +	/** Partition table */ +	struct partition_table_entry partitions[4]; +	/** 0x55aa MBR signature */ +	uint16_t magic; +} __attribute__ (( packed )); + +/** MBR magic signature */ +#define INT13_MBR_MAGIC 0xaa55 + +/** A floppy disk geometry */ +struct int13_fdd_geometry { +	/** Number of tracks */ +	uint8_t tracks; +	/** Number of heads and sectors per track */ +	uint8_t heads_spt; +}; + +/** Define a floppy disk geometry */ +#define INT13_FDD_GEOMETRY( cylinders, heads, sectors )			\ +	{								\ +		.tracks = (cylinders),					\ +		.heads_spt = ( ( (heads) << 6 ) | (sectors) ),		\ +	} + +/** Get floppy disk number of cylinders */ +#define INT13_FDD_CYLINDERS( geometry ) ( (geometry)->tracks ) + +/** Get floppy disk number of heads */ +#define INT13_FDD_HEADS( geometry ) ( (geometry)->heads_spt >> 6 ) + +/** Get floppy disk number of sectors per track */ +#define INT13_FDD_SECTORS( geometry ) ( (geometry)->heads_spt & 0x3f ) + +/** A floppy drive parameter table */ +struct int13_fdd_parameters { +	uint8_t step_rate__head_unload; +	uint8_t head_load__ndma; +	uint8_t motor_off_delay; +	uint8_t bytes_per_sector; +	uint8_t sectors_per_track; +	uint8_t gap_length; +	uint8_t data_length; +	uint8_t format_gap_length; +	uint8_t format_filler; +	uint8_t head_settle_time; +	uint8_t motor_start_time; +} __attribute__ (( packed )); + +#endif /* INT13_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h new file mode 100644 index 00000000..5b684c04 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_BIOS_NAP_H +#define _IPXE_BIOS_NAP_H + +/** @file + * + * BIOS CPU sleeping + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef NAP_PCBIOS +#define NAP_PREFIX_pcbios +#else +#define NAP_PREFIX_pcbios __pcbios_ +#endif + +#endif /* _IPXE_BIOS_NAP_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h new file mode 100644 index 00000000..a0845328 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_BIOS_REBOOT_H +#define _IPXE_BIOS_REBOOT_H + +/** @file + * + * Standard PC-BIOS reboot mechanism + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef REBOOT_PCBIOS +#define REBOOT_PREFIX_pcbios +#else +#define REBOOT_PREFIX_pcbios __pcbios_ +#endif + +#endif /* _IPXE_BIOS_REBOOT_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h new file mode 100644 index 00000000..689227b7 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h @@ -0,0 +1,29 @@ +#ifndef _IPXE_BIOS_SANBOOT_H +#define _IPXE_BIOS_SANBOOT_H + +/** @file + * + * Standard PC-BIOS sanboot interface + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef SANBOOT_PCBIOS +#define SANBOOT_PREFIX_pcbios +#else +#define SANBOOT_PREFIX_pcbios __pcbios_ +#endif + +/** + * Get default SAN drive number + * + * @ret drive		Default drive number + */ +static inline __always_inline unsigned int +SANBOOT_INLINE ( pcbios, san_default_drive ) ( void ) { +	/* Default to booting from first hard disk */ +	return 0x80; +} + +#endif /* _IPXE_BIOS_SANBOOT_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h new file mode 100644 index 00000000..d8c7f648 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_BIOS_SMBIOS_H +#define _IPXE_BIOS_SMBIOS_H + +/** @file + * + * Standard PC-BIOS SMBIOS interface + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef SMBIOS_PCBIOS +#define SMBIOS_PREFIX_pcbios +#else +#define SMBIOS_PREFIX_pcbios __pcbios_ +#endif + +#endif /* _IPXE_BIOS_SMBIOS_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h new file mode 100644 index 00000000..f9fc8041 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h @@ -0,0 +1,44 @@ +#ifndef _IPXE_BIOS_TIMER_H +#define _IPXE_BIOS_TIMER_H + +/** @file + * + * BIOS timer + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef TIMER_PCBIOS +#define TIMER_PREFIX_pcbios +#else +#define TIMER_PREFIX_pcbios __pcbios_ +#endif + +#include <ipxe/timer2.h> + +/** + * Delay for a fixed number of microseconds + * + * @v usecs		Number of microseconds for which to delay + */ +static inline __always_inline void +TIMER_INLINE ( pcbios, udelay ) ( unsigned long usecs ) { +	/* BIOS timer is not high-resolution enough for udelay(), so +	 * we use timer2 +	 */ +	timer2_udelay ( usecs ); +} + +/** + * Get number of ticks per second + * + * @ret ticks_per_sec	Number of ticks per second + */ +static inline __always_inline unsigned long +TIMER_INLINE ( pcbios, ticks_per_sec ) ( void ) { +	/* BIOS timer ticks over at 18.2 ticks per second */ +	return 18; +} + +#endif /* _IPXE_BIOS_TIMER_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h b/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h new file mode 100644 index 00000000..3a9eb249 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h @@ -0,0 +1,115 @@ +#ifndef _IPXE_ERRNO_PCBIOS_H +#define _IPXE_ERRNO_PCBIOS_H + +/** + * @file + * + * PC-BIOS platform error codes + * + * We use the PXE-specified error codes as the platform error codes + * for the PC-BIOS platform. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <pxe_error.h> + +/** + * Convert platform error code to platform component of iPXE error code + * + * @v platform		Platform error code + * @ret errno		Platform component of iPXE error code + */ +#define PLATFORM_TO_ERRNO( platform ) ( (platform) & 0xff ) + +/** + * Convert iPXE error code to platform error code + * + * @v errno		iPXE error code + * @ret platform	Platform error code + */ +#define ERRNO_TO_PLATFORM( errno ) ( (errno) & 0xff ) + +/* Platform-specific error codes */ +#define PLATFORM_ENOERR		PXENV_STATUS_SUCCESS +#define PLATFORM_E2BIG		PXENV_STATUS_BAD_FUNC +#define PLATFORM_EACCES		PXENV_STATUS_TFTP_ACCESS_VIOLATION +#define PLATFORM_EADDRINUSE	PXENV_STATUS_UDP_OPEN +#define PLATFORM_EADDRNOTAVAIL	PXENV_STATUS_UDP_OPEN +#define PLATFORM_EAFNOSUPPORT	PXENV_STATUS_UNSUPPORTED +#define PLATFORM_EAGAIN		PXENV_STATUS_FAILURE +#define PLATFORM_EALREADY	PXENV_STATUS_UDP_OPEN +#define PLATFORM_EBADF		PXENV_STATUS_TFTP_CLOSED +#define PLATFORM_EBADMSG	PXENV_STATUS_FAILURE +#define PLATFORM_EBUSY		PXENV_STATUS_OUT_OF_RESOURCES +#define PLATFORM_ECANCELED	PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE +#define PLATFORM_ECHILD		PXENV_STATUS_TFTP_FILE_NOT_FOUND +#define PLATFORM_ECONNABORTED	PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION +#define PLATFORM_ECONNREFUSED	PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION +#define PLATFORM_ECONNRESET	PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION +#define PLATFORM_EDEADLK	PXENV_STATUS_FAILURE +#define PLATFORM_EDESTADDRREQ	PXENV_STATUS_BAD_FUNC +#define PLATFORM_EDOM		PXENV_STATUS_FAILURE +#define PLATFORM_EDQUOT		PXENV_STATUS_FAILURE +#define PLATFORM_EEXIST		PXENV_STATUS_FAILURE +#define PLATFORM_EFAULT		PXENV_STATUS_MCOPY_PROBLEM +#define PLATFORM_EFBIG		PXENV_STATUS_MCOPY_PROBLEM +#define PLATFORM_EHOSTUNREACH	PXENV_STATUS_ARP_TIMEOUT +#define PLATFORM_EIDRM		PXENV_STATUS_FAILURE +#define PLATFORM_EILSEQ		PXENV_STATUS_FAILURE +#define PLATFORM_EINPROGRESS	PXENV_STATUS_FAILURE +#define PLATFORM_EINTR		PXENV_STATUS_FAILURE +#define PLATFORM_EINVAL		PXENV_STATUS_BAD_FUNC +#define PLATFORM_EIO		PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION +#define PLATFORM_EISCONN	PXENV_STATUS_UDP_OPEN +#define PLATFORM_EISDIR		PXENV_STATUS_FAILURE +#define PLATFORM_ELOOP		PXENV_STATUS_FAILURE +#define PLATFORM_EMFILE		PXENV_STATUS_OUT_OF_RESOURCES +#define PLATFORM_EMLINK		PXENV_STATUS_FAILURE +#define PLATFORM_EMSGSIZE	PXENV_STATUS_BAD_FUNC +#define PLATFORM_EMULTIHOP	PXENV_STATUS_FAILURE +#define PLATFORM_ENAMETOOLONG	PXENV_STATUS_FAILURE +#define PLATFORM_ENETDOWN	PXENV_STATUS_ARP_TIMEOUT +#define PLATFORM_ENETRESET	PXENV_STATUS_FAILURE +#define PLATFORM_ENETUNREACH	PXENV_STATUS_ARP_TIMEOUT +#define PLATFORM_ENFILE		PXENV_STATUS_OUT_OF_RESOURCES +#define PLATFORM_ENOBUFS	PXENV_STATUS_OUT_OF_RESOURCES +#define PLATFORM_ENODATA	PXENV_STATUS_FAILURE +#define PLATFORM_ENODEV		PXENV_STATUS_TFTP_FILE_NOT_FOUND +#define PLATFORM_ENOENT		PXENV_STATUS_TFTP_FILE_NOT_FOUND +#define PLATFORM_ENOEXEC	PXENV_STATUS_FAILURE +#define PLATFORM_ENOLCK		PXENV_STATUS_FAILURE +#define PLATFORM_ENOLINK	PXENV_STATUS_FAILURE +#define PLATFORM_ENOMEM		PXENV_STATUS_OUT_OF_RESOURCES +#define PLATFORM_ENOMSG		PXENV_STATUS_FAILURE +#define PLATFORM_ENOPROTOOPT	PXENV_STATUS_UNSUPPORTED +#define PLATFORM_ENOSPC		PXENV_STATUS_OUT_OF_RESOURCES +#define PLATFORM_ENOSR		PXENV_STATUS_OUT_OF_RESOURCES +#define PLATFORM_ENOSTR		PXENV_STATUS_FAILURE +#define PLATFORM_ENOSYS		PXENV_STATUS_UNSUPPORTED +#define PLATFORM_ENOTCONN	PXENV_STATUS_FAILURE +#define PLATFORM_ENOTDIR	PXENV_STATUS_FAILURE +#define PLATFORM_ENOTEMPTY	PXENV_STATUS_FAILURE +#define PLATFORM_ENOTSOCK	PXENV_STATUS_FAILURE +#define PLATFORM_ENOTSUP	PXENV_STATUS_UNSUPPORTED +#define PLATFORM_ENOTTY		PXENV_STATUS_FAILURE +#define PLATFORM_ENXIO		PXENV_STATUS_TFTP_FILE_NOT_FOUND +#define PLATFORM_EOPNOTSUPP	PXENV_STATUS_UNSUPPORTED +#define PLATFORM_EOVERFLOW	PXENV_STATUS_FAILURE +#define PLATFORM_EPERM		PXENV_STATUS_TFTP_ACCESS_VIOLATION +#define PLATFORM_EPIPE		PXENV_STATUS_FAILURE +#define PLATFORM_EPROTO		PXENV_STATUS_FAILURE +#define PLATFORM_EPROTONOSUPPORT PXENV_STATUS_UNSUPPORTED +#define PLATFORM_EPROTOTYPE	PXENV_STATUS_FAILURE +#define PLATFORM_ERANGE		PXENV_STATUS_FAILURE +#define PLATFORM_EROFS		PXENV_STATUS_FAILURE +#define PLATFORM_ESPIPE		PXENV_STATUS_FAILURE +#define PLATFORM_ESRCH		PXENV_STATUS_TFTP_FILE_NOT_FOUND +#define PLATFORM_ESTALE		PXENV_STATUS_FAILURE +#define PLATFORM_ETIME		PXENV_STATUS_FAILURE +#define PLATFORM_ETIMEDOUT	PXENV_STATUS_TFTP_READ_TIMEOUT +#define PLATFORM_ETXTBSY	PXENV_STATUS_FAILURE +#define PLATFORM_EWOULDBLOCK	PXENV_STATUS_TFTP_OPEN +#define PLATFORM_EXDEV		PXENV_STATUS_FAILURE + +#endif /* _IPXE_ERRNO_PCBIOS_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h b/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h new file mode 100644 index 00000000..72a0f714 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h @@ -0,0 +1,68 @@ +#ifndef _IPXE_GUESTRPC_H +#define _IPXE_GUESTRPC_H + +/** @file + * + * VMware GuestRPC mechanism + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <ipxe/vmware.h> + +/** GuestRPC magic number */ +#define GUESTRPC_MAGIC 0x49435052 /* "RPCI" */ + +/** Open RPC channel */ +#define GUESTRPC_OPEN 0x00 + +/** Open RPC channel success status */ +#define GUESTRPC_OPEN_SUCCESS 0x00010000 + +/** Send RPC command length */ +#define GUESTRPC_COMMAND_LEN 0x01 + +/** Send RPC command length success status */ +#define GUESTRPC_COMMAND_LEN_SUCCESS 0x00810000 + +/** Send RPC command data */ +#define GUESTRPC_COMMAND_DATA 0x02 + +/** Send RPC command data success status */ +#define GUESTRPC_COMMAND_DATA_SUCCESS 0x00010000 + +/** Receive RPC reply length */ +#define GUESTRPC_REPLY_LEN 0x03 + +/** Receive RPC reply length success status */ +#define GUESTRPC_REPLY_LEN_SUCCESS 0x00830000 + +/** Receive RPC reply data */ +#define GUESTRPC_REPLY_DATA 0x04 + +/** Receive RPC reply data success status */ +#define GUESTRPC_REPLY_DATA_SUCCESS 0x00010000 + +/** Finish receiving RPC reply */ +#define GUESTRPC_REPLY_FINISH 0x05 + +/** Finish receiving RPC reply success status */ +#define GUESTRPC_REPLY_FINISH_SUCCESS 0x00010000 + +/** Close RPC channel */ +#define GUESTRPC_CLOSE 0x06 + +/** Close RPC channel success status */ +#define GUESTRPC_CLOSE_SUCCESS 0x00010000 + +/** RPC command success status */ +#define GUESTRPC_SUCCESS 0x2031 /* "1 " */ + +extern int guestrpc_open ( void ); +extern void guestrpc_close ( int channel ); +extern int guestrpc_command ( int channel, const char *command, char *reply, +			      size_t reply_len ); + +#endif /* _IPXE_GUESTRPC_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h b/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h new file mode 100644 index 00000000..001648fe --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_MEMTOP_UMALLOC_H +#define _IPXE_MEMTOP_UMALLOC_H + +/** @file + * + * External memory allocation + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef UMALLOC_MEMTOP +#define UMALLOC_PREFIX_memtop +#else +#define UMALLOC_PREFIX_memtop __memtop_ +#endif + +#endif /* _IPXE_MEMTOP_UMALLOC_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/msr.h b/roms/ipxe/src/arch/i386/include/ipxe/msr.h new file mode 100644 index 00000000..c88e26a3 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/msr.h @@ -0,0 +1,38 @@ +#ifndef _IPXE_MSR_H +#define _IPXE_MSR_H + +/** @file + * + * Model-specific registers + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Read model-specific register + * + * @v msr		Model-specific register + * @ret value		Value + */ +static inline __attribute__ (( always_inline )) uint64_t +rdmsr ( unsigned int msr ) { +	uint64_t value; + +	__asm__ __volatile__ ( "rdmsr" : "=A" ( value ) : "c" ( msr ) ); +	return value; +} + +/** + * Write model-specific register + * + * @v msr		Model-specific register + * @v value		Value + */ +static inline __attribute__ (( always_inline )) void +wrmsr ( unsigned int msr, uint64_t value ) { + +	__asm__ __volatile__ ( "wrmsr" : : "c" ( msr ), "A" ( value ) ); +} + +#endif /* _IPXE_MSR_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h b/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h new file mode 100644 index 00000000..472e1400 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h @@ -0,0 +1,39 @@ +#ifndef _IPXE_RDTSC_TIMER_H +#define _IPXE_RDTSC_TIMER_H + +/** @file + * + * RDTSC timer + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef TIMER_RDTSC +#define TIMER_PREFIX_rdtsc +#else +#define TIMER_PREFIX_rdtsc __rdtsc_ +#endif + +/** + * RDTSC values can easily overflow an unsigned long.  We discard the + * low-order bits in order to obtain sensibly-scaled values. + */ +#define TSC_SHIFT 8 + +/** + * Get current system time in ticks + * + * @ret ticks		Current time, in ticks + */ +static inline __always_inline unsigned long +TIMER_INLINE ( rdtsc, currticks ) ( void ) { +	unsigned long ticks; + +	__asm__ __volatile__ ( "rdtsc\n\t" +			       "shrdl %1, %%edx, %%eax\n\t" +			       : "=a" ( ticks ) : "i" ( TSC_SHIFT ) : "edx" ); +	return ticks; +} + +#endif /* _IPXE_RDTSC_TIMER_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h b/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h new file mode 100644 index 00000000..6c3cf210 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h @@ -0,0 +1,62 @@ +#ifndef _IPXE_RTC_ENTROPY_H +#define _IPXE_RTC_ENTROPY_H + +/** @file + * + * RTC-based entropy source + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> + +#ifdef ENTROPY_RTC +#define ENTROPY_PREFIX_rtc +#else +#define ENTROPY_PREFIX_rtc __rtc_ +#endif + +/** + * min-entropy per sample + * + * @ret min_entropy	min-entropy of each sample + */ +static inline __always_inline double +ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) { + +	/* The min-entropy has been measured on several platforms +	 * using the entropy_sample test code.  Modelling the samples +	 * as independent, and using a confidence level of 99.99%, the +	 * measurements were as follows: +	 * +	 *    qemu-kvm		: 7.38 bits +	 *    VMware		: 7.46 bits +	 *    Physical hardware	: 2.67 bits +	 * +	 * We choose the lowest of these (2.67 bits) and apply a 50% +	 * safety margin to allow for some potential non-independence +	 * of samples. +	 */ +	return 1.3; +} + +extern uint8_t rtc_sample ( void ); + +/** + * Get noise sample + * + * @ret noise		Noise sample + * @ret rc		Return status code + */ +static inline __always_inline int +ENTROPY_INLINE ( rtc, get_noise ) ( noise_sample_t *noise ) { + +	/* Get sample */ +	*noise = rtc_sample(); + +	/* Always successful */ +	return 0; +} + +#endif /* _IPXE_RTC_ENTROPY_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h b/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h new file mode 100644 index 00000000..c0dfe3f8 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h @@ -0,0 +1,18 @@ +#ifndef _IPXE_RTC_TIME_H +#define _IPXE_RTC_TIME_H + +/** @file + * + * RTC-based time source + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifdef TIME_RTC +#define TIME_PREFIX_rtc +#else +#define TIME_PREFIX_rtc __rtc_ +#endif + +#endif /* _IPXE_RTC_TIME_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/timer2.h b/roms/ipxe/src/arch/i386/include/ipxe/timer2.h new file mode 100644 index 00000000..322a3ed5 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/timer2.h @@ -0,0 +1,14 @@ +#ifndef _IPXE_TIMER2_H +#define _IPXE_TIMER2_H + +/** @file + * + * Timer chip control + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +extern void timer2_udelay ( unsigned long usecs ); + +#endif /* _IPXE_TIMER2_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h b/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h new file mode 100644 index 00000000..48cd6a7b --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h @@ -0,0 +1,210 @@ +#ifndef _IPXE_VESAFB_H +#define _IPXE_VESAFB_H + +/** @file + * + * VESA frame buffer console + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <realmode.h> + +/** INT 10,4f00: return controller information */ +#define VBE_CONTROLLER_INFO 0x4f00 + +/** VBE controller information */ +struct vbe_controller_info { +	/** VBE signature */ +	uint32_t vbe_signature; +	/** VBE minor version */ +	uint8_t vbe_minor_version; +	/** VBE major version */ +	uint8_t vbe_major_version; +	/** Pointer to OEM string */ +	struct segoff oem_string_ptr; +	/** Capabilities of graphics controller */ +	uint32_t capabilities; +	/** Pointer to video mode list */ +	struct segoff video_mode_ptr; +	/** Number of 64kB memory blocks */ +	uint16_t total_memory; +	/** VBE implementation software revision */ +	uint16_t oem_software_rev; +	/** Pointer to vendor name string */ +	struct segoff oem_vendor_name_ptr; +	/** Pointer to product name string */ +	struct segoff oem_product_name_ptr; +	/** Pointer to product revision string */ +	struct segoff oem_product_rev_ptr; +	/** Reserved for VBE implementation scratch area */ +	uint8_t reserved[222]; +	/* VBE2.0 defines an additional 256-byte data area for +	 * including the OEM strings inline within the VBE information +	 * block; we omit this to reduce the amount of base memory +	 * required for VBE calls. +	 */ +} __attribute__ (( packed )); + +/** VBE controller information signature */ +#define VBE_CONTROLLER_SIGNATURE \ +	( ( 'V' << 0 ) | ( 'E' << 8 ) | ( 'S' << 16 ) | ( 'A' << 24 ) ) + +/** VBE mode list end marker */ +#define VBE_MODE_END 0xffff + +/** INT 10,4f01: return VBE mode information */ +#define VBE_MODE_INFO 0x4f01 + +/** VBE mode information */ +struct vbe_mode_info { +	/** Mode attributes */ +	uint16_t mode_attributes; +	/** Window A attributes */ +	uint8_t win_a_attributes; +	/** Window B attributes */ +	uint8_t win_b_attributes; +	/** Window granularity */ +	uint16_t win_granularity; +	/** Window size */ +	uint16_t win_size; +	/** Window A start segment */ +	uint16_t win_a_segment; +	/** Window B start segment */ +	uint16_t win_b_segment; +	/** Pointer to window function */ +	struct segoff win_func_ptr; +	/** Bytes per scan line */ +	uint16_t bytes_per_scan_line; +	/** Horizontal resolution in pixels or characters */ +	uint16_t x_resolution; +	/** Vertical resolution in pixels or characters */ +	uint16_t y_resolution; +	/** Character cell width in pixels */ +	uint8_t x_char_size; +	/** Character cell height in pixels */ +	uint8_t y_char_size; +	/** Number of memory planes */ +	uint8_t number_of_planes; +	/** Bits per pixel */ +	uint8_t bits_per_pixel; +	/** Number of banks */ +	uint8_t number_of_banks; +	/** Memory model type */ +	uint8_t memory_model; +	/** Bank size in kB */ +	uint8_t bank_size; +	/** Number of images */ +	uint8_t number_of_image_pages; +	/** Reserved for page function */ +	uint8_t reserved_1; +	/** Size of direct colour red mask in bits */ +	uint8_t red_mask_size; +	/** Bit position of LSB of red mask */ +	uint8_t red_field_position; +	/** Size of direct colour green mask in bits */ +	uint8_t green_mask_size; +	/** Bit position of LSB of green mask */ +	uint8_t green_field_position; +	/** Size of direct colour blue mask in bits */ +	uint8_t blue_mask_size; +	/** Bit position of LSB of blue mask */ +	uint8_t blue_field_position; +	/** Size of direct colour reserved mask in bits */ +	uint8_t rsvd_mask_size; +	/** Bit position of LSB of reserved mask */ +	uint8_t rsvd_field_position; +	/** Direct colour mode attributes */ +	uint8_t direct_colour_mode_info; +	/** Physical address for flat memory frame buffer */ +	uint32_t phys_base_ptr; +	/** Pointer to start of off-screen memory */ +	uint32_t off_screen_mem_offset; +	/** Amount of off-screen memory in 1kB units */ +	uint16_t off_screen_mem_size; +	/** Reserved */ +	uint8_t reserved_2[206]; +} __attribute__ (( packed )); + +/** VBE mode attributes */ +enum vbe_mode_attributes { +	/** Mode supported in hardware */ +	VBE_MODE_ATTR_SUPPORTED = 0x0001, +	/** TTY output functions supported by BIOS */ +	VBE_MODE_ATTR_TTY = 0x0004, +	/** Colour mode */ +	VBE_MODE_ATTR_COLOUR = 0x0008, +	/** Graphics mode */ +	VBE_MODE_ATTR_GRAPHICS = 0x0010, +	/** Not a VGA compatible mode */ +	VBE_MODE_ATTR_NOT_VGA = 0x0020, +	/** VGA compatible windowed memory mode is not available */ +	VBE_MODE_ATTR_NOT_WINDOWED = 0x0040, +	/** Linear frame buffer mode is available */ +	VBE_MODE_ATTR_LINEAR = 0x0080, +	/** Double scan mode is available */ +	VBE_MODE_ATTR_DOUBLE = 0x0100, +	/** Interlaced mode is available */ +	VBE_MODE_ATTR_INTERLACED = 0x0200, +	/** Hardware triple buffering support */ +	VBE_MODE_ATTR_TRIPLE_BUF = 0x0400, +	/** Hardware stereoscopic display support */ +	VBE_MODE_ATTR_STEREO = 0x0800, +	/** Dual display start address support */ +	VBE_MODE_ATTR_DUAL = 0x1000, +}; + +/** VBE mode memory models */ +enum vbe_mode_memory_model { +	/** Text mode */ +	VBE_MODE_MODEL_TEXT = 0x00, +	/** CGA graphics mode */ +	VBE_MODE_MODEL_CGA = 0x01, +	/** Hercules graphics mode */ +	VBE_MODE_MODEL_HERCULES = 0x02, +	/** Planar mode */ +	VBE_MODE_MODEL_PLANAR = 0x03, +	/** Packed pixel mode */ +	VBE_MODE_MODEL_PACKED_PIXEL = 0x04, +	/** Non-chain 4, 256 colour mode */ +	VBE_MODE_MODEL_NON_CHAIN_4 = 0x05, +	/** Direct colour mode */ +	VBE_MODE_MODEL_DIRECT_COLOUR = 0x06, +	/** YUV mode */ +	VBE_MODE_MODEL_YUV = 0x07, +}; + +/** INT 10,4f02: set VBE mode */ +#define VBE_SET_MODE 0x4f02 + +/** VBE linear frame buffer mode bit */ +#define VBE_MODE_LINEAR 0x4000 + +/** INT 10,1130: get font information */ +#define VBE_GET_FONT 0x1130 + +/** Font sets */ +enum vbe_font_set { +	/** 8x14 character font */ +	VBE_FONT_8x14 = 0x0200, +	/** 8x8 double dot font */ +	VBE_FONT_8x8_DOUBLE = 0x0300, +	/** 8x8 double dot font (high 128 characters) */ +	VBE_FONT_8x8_DOUBLE_HIGH = 0x0400, +	/** 9x14 alpha alternate font */ +	VBE_FONT_9x14_ALPHA_ALT = 0x0500, +	/** 8x16 font */ +	VBE_FONT_8x16 = 0x0600, +	/** 9x16 alternate font */ +	VBE_FONT_9x16_ALT = 0x0700, +}; + +/** INT 10,00: set VGA mode */ +#define VBE_SET_VGA_MODE 0x0000 + +/** INT 10,0f: get VGA mode */ +#define VBE_GET_VGA_MODE 0x0f00 + +#endif /* _IPXE_VESAFB_H */ diff --git a/roms/ipxe/src/arch/i386/include/ipxe/vmware.h b/roms/ipxe/src/arch/i386/include/ipxe/vmware.h new file mode 100644 index 00000000..2ac65f43 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/ipxe/vmware.h @@ -0,0 +1,81 @@ +#ifndef _IPXE_VMWARE_H +#define _IPXE_VMWARE_H + +/** @file + * + * VMware backdoor mechanism + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> + +/** VMware backdoor I/O port */ +#define VMW_PORT 0x5658 + +/** VMware backdoor magic value */ +#define VMW_MAGIC 0x564d5868 /* "VMXh" */ + +/** VMware backdoor magic instruction */ +#define VMW_BACKDOOR "inl %%dx, %%eax" + +/** Get VMware version */ +#define VMW_CMD_GET_VERSION 0x0a + +/** Issue GuestRPC command */ +#define VMW_CMD_GUESTRPC 0x1e + +/** + * Get VMware version + * + * @ret version		VMware version(?) + * @ret magic		VMware magic number, if present + * @ret product_type	VMware product type + */ +static inline __attribute__ (( always_inline )) void +vmware_cmd_get_version ( uint32_t *version, uint32_t *magic, +			 uint32_t *product_type ) { +	uint32_t discard_d; + +	/* Perform backdoor call */ +	__asm__ __volatile__ ( VMW_BACKDOOR +			       : "=a" ( *version ), "=b" ( *magic ), +				 "=c" ( *product_type ), "=d" ( discard_d ) +			       : "0" ( VMW_MAGIC ), "1" ( 0 ), +				 "2" ( VMW_CMD_GET_VERSION ), +				 "3" ( VMW_PORT ) ); +} + +/** + * Issue GuestRPC command + * + * @v channel		Channel number + * @v subcommand	GuestRPC subcommand + * @v parameter		Subcommand-specific parameter + * @ret edxhi		Subcommand-specific result + * @ret ebx		Subcommand-specific result + * @ret status		Command status + */ +static inline __attribute__ (( always_inline )) uint32_t +vmware_cmd_guestrpc ( int channel, uint16_t subcommand, uint32_t parameter, +		      uint16_t *edxhi, uint32_t *ebx ) { +	uint32_t discard_a; +	uint32_t status; +	uint32_t edx; + +	/* Perform backdoor call */ +	__asm__ __volatile__ ( VMW_BACKDOOR +			       : "=a" ( discard_a ), "=b" ( *ebx ), +				 "=c" ( status ), "=d" ( edx ) +			       : "0" ( VMW_MAGIC ), "1" ( parameter ), +				 "2" ( VMW_CMD_GUESTRPC | ( subcommand << 16 )), +				 "3" ( VMW_PORT | ( channel << 16 ) ) ); +	*edxhi = ( edx >> 16 ); + +	return status; +} + +extern int vmware_present ( void ); + +#endif /* _IPXE_VMWARE_H */ diff --git a/roms/ipxe/src/arch/i386/include/kir.h b/roms/ipxe/src/arch/i386/include/kir.h new file mode 100644 index 00000000..84633d26 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/kir.h @@ -0,0 +1,18 @@ +#ifndef KIR_H +#define KIR_H + +#ifndef KEEP_IT_REAL +#error "kir.h can be used only with -DKEEP_IT_REAL" +#endif + +#ifdef ASSEMBLY + +#define code32 code16gcc + +#else /* ASSEMBLY */ + +__asm__ ( ".code16gcc" ); + +#endif /* ASSEMBLY */ + +#endif /* KIR_H */ diff --git a/roms/ipxe/src/arch/i386/include/libkir.h b/roms/ipxe/src/arch/i386/include/libkir.h new file mode 100644 index 00000000..1f5b1350 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/libkir.h @@ -0,0 +1,233 @@ +#ifndef LIBKIR_H +#define LIBKIR_H + +#include "realmode.h" + +#ifndef ASSEMBLY + +/* + * Full API documentation for these functions is in realmode.h. + * + */ + +/* Access to variables in .data16 and .text16 in a way compatible with librm */ +#define __data16( variable ) variable +#define __data16_array( variable, array ) variable array +#define __bss16( variable ) variable +#define __bss16_array( variable, array ) variable array +#define __text16( variable ) variable +#define __text16_array( variable,array ) variable array +#define __use_data16( variable ) variable +#define __use_text16( variable ) variable +#define __from_data16( pointer ) pointer +#define __from_text16( pointer ) pointer + +/* Real-mode data and code segments */ +static inline __attribute__ (( always_inline )) unsigned int _rm_cs ( void ) { +	uint16_t cs; +	__asm__ __volatile__ ( "movw %%cs, %w0" : "=r" ( cs ) ); +	return cs; +} + +static inline __attribute__ (( always_inline )) unsigned int _rm_ds ( void ) { +	uint16_t ds; +	__asm__ __volatile__ ( "movw %%ds, %w0" : "=r" ( ds ) ); +	return ds; +} + +#define rm_cs ( _rm_cs() ) +#define rm_ds ( _rm_ds() ) + +/* Copy to/from base memory */ + +static inline void copy_to_real_libkir ( unsigned int dest_seg, +					 unsigned int dest_off, +					 const void *src, size_t n ) { +	unsigned int discard_D, discard_S, discard_c; + +	__asm__ __volatile__ ( "pushw %%es\n\t" +			       "movw %3, %%es\n\t" +			       "rep movsb\n\t" +			       "popw %%es\n\t" +			       : "=D" ( discard_D ), "=S" ( discard_S ), +			         "=c" ( discard_c ) +			       : "r" ( dest_seg ), "D" ( dest_off ), +			         "S" ( src ), +			         "c" ( n ) +			       : "memory" ); +} + +static inline void copy_from_real_libkir ( void *dest, +					   unsigned int src_seg, +					   unsigned int src_off, +					   size_t n ) { +	unsigned int discard_D, discard_S, discard_c; + +	__asm__ __volatile__ ( "pushw %%ds\n\t" +			       "movw %4, %%ds\n\t" +			       "rep movsb\n\t" +			       "popw %%ds\n\t" +			       : "=D" ( discard_D ), "=S" ( discard_S ), +			         "=c" ( discard_c ) +			       : "D" ( dest ), +			         "r" ( src_seg ), "S" ( src_off ), +			         "c" ( n ) +			       : "memory" ); +} + +#define copy_to_real copy_to_real_libkir +#define copy_from_real copy_from_real_libkir + +/* + * Transfer individual values to/from base memory.  There may well be + * a neater way to do this.  We have two versions: one for constant + * offsets (where the mov instruction must be of the form "mov + * %es:123, %xx") and one for non-constant offsets (where the mov + * instruction must be of the form "mov %es:(%xx), %yx".  If it's + * possible to incorporate both forms into one __asm__ instruction, I + * don't know how to do it. + * + * Ideally, the mov instruction should be "mov%z0"; the "%z0" is meant + * to expand to either "b", "w" or "l" depending on the size of + * operand 0.  This would remove the (minor) ambiguity in the mov + * instruction.  However, gcc on at least my system barfs with an + * "internal compiler error" when confronted with %z0. + * + */ + +#define put_real_kir_const_off( var, seg, off )		  		     \ +	__asm__ ( "movw %w1, %%es\n\t"					     \ +		  "mov %0, %%es:%c2\n\t"				     \ +		  "pushw %%ds\n\t" /* restore %es */			     \ +		  "popw %%es\n\t"					     \ +		  :							     \ +		  : "r,r" ( var ), "rm,rm" ( seg ), "i,!r" ( off )	     \ +		  ) + +#define put_real_kir_nonconst_off( var, seg, off )	  		     \ +	__asm__ ( "movw %w1, %%es\n\t"					     \ +		  "mov %0, %%es:(%2)\n\t"				     \ +		  "pushw %%ds\n\t" /* restore %es */			     \ +		  "popw %%es\n\t"					     \ +		  :							     \ +		  : "r" ( var ), "rm" ( seg ), "r" ( off )		     \ +		  ) + +#define put_real_kir( var, seg, off )					     \ +	do {								     \ +	  if ( __builtin_constant_p ( off ) )				     \ +		  put_real_kir_const_off ( var, seg, off );		     \ +	  else								     \ +		  put_real_kir_nonconst_off ( var, seg, off );		     \ +	} while ( 0 ) + +#define get_real_kir_const_off( var, seg, off )		  		     \ +	__asm__ ( "movw %w1, %%es\n\t"					     \ +		  "mov %%es:%c2, %0\n\t"				     \ +		  "pushw %%ds\n\t" /* restore %es */			     \ +		  "popw %%es\n\t"					     \ +		  : "=r,r" ( var )					     \ +		  : "rm,rm" ( seg ), "i,!r" ( off )			     \ +		  ) + +#define get_real_kir_nonconst_off( var, seg, off )			     \ +	__asm__ ( "movw %w1, %%es\n\t"					     \ +		  "mov %%es:(%2), %0\n\t"				     \ +		  "pushw %%ds\n\t" /* restore %es */			     \ +		  "popw %%es\n\t"					     \ +		  : "=r" ( var )					     \ +		  : "rm" ( seg ), "r" ( off )				     \ +		  ) + +#define get_real_kir( var, seg, off )					     \ +	do {								     \ +	  if ( __builtin_constant_p ( off ) )				     \ +		  get_real_kir_const_off ( var, seg, off );		     \ +	  else								     \ +		  get_real_kir_nonconst_off ( var, seg, off );		     \ +	} while ( 0 ) + +#define put_real put_real_kir +#define get_real get_real_kir + +/** + * A pointer to a user buffer + * + * This is actually a struct segoff, but encoded as a uint32_t to + * ensure that gcc passes it around efficiently. + */ +typedef uint32_t userptr_t; + +/** + * Copy data to user buffer + * + * @v buffer	User buffer + * @v offset	Offset within user buffer + * @v src	Source + * @v len	Length + */ +static inline __attribute__ (( always_inline )) void +copy_to_user ( userptr_t buffer, off_t offset, const void *src, size_t len ) { +	copy_to_real ( ( buffer >> 16 ), ( ( buffer & 0xffff ) + offset ), +		       src, len ); +} + +/** + * Copy data from user buffer + * + * @v dest	Destination + * @v buffer	User buffer + * @v offset	Offset within user buffer + * @v len	Length + */ +static inline __attribute__ (( always_inline )) void +copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) { +	copy_from_real ( dest, ( buffer >> 16 ), +			 ( ( buffer & 0xffff ) + offset ), len ); +} + +/** + * Convert segment:offset address to user buffer + * + * @v segment	Real-mode segment + * @v offset	Real-mode offset + * @ret buffer	User buffer + */ +static inline __attribute__ (( always_inline )) userptr_t +real_to_user ( unsigned int segment, unsigned int offset ) { +	return ( ( segment << 16 ) | offset ); +} + +/** + * Convert virtual address to user buffer + * + * @v virtual	Virtual address + * @ret buffer	User buffer + * + * This constructs a user buffer from an ordinary pointer.  Use it + * when you need to pass a pointer to an internal buffer to a function + * that expects a @c userptr_t. + */ +static inline __attribute__ (( always_inline )) userptr_t +virt_to_user ( void * virtual ) { +	return real_to_user ( rm_ds, ( intptr_t ) virtual ); +} + +/* TEXT16_CODE: declare a fragment of code that resides in .text16 */ +#define TEXT16_CODE( asm_code_str )			\ +	".section \".text16\", \"ax\", @progbits\n\t"	\ +	".code16\n\t"					\ +	".arch i386\n\t"				\ +	asm_code_str "\n\t"				\ +	".code16gcc\n\t"				\ +	".previous\n\t" + +/* REAL_CODE: declare a fragment of code that executes in real mode */ +#define REAL_CODE( asm_code_str )	\ +	".code16\n\t"			\ +	asm_code_str "\n\t"		\ +	".code16gcc\n\t" + +#endif /* ASSEMBLY */ + +#endif /* LIBKIR_H */ diff --git a/roms/ipxe/src/arch/i386/include/librm.h b/roms/ipxe/src/arch/i386/include/librm.h new file mode 100644 index 00000000..c8ba72b5 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/librm.h @@ -0,0 +1,279 @@ +#ifndef LIBRM_H +#define LIBRM_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +/* Segment selectors as used in our protected-mode GDTs. + * + * Don't change these unless you really know what you're doing. + */ + +#define VIRTUAL_CS 0x08 +#define VIRTUAL_DS 0x10 +#define PHYSICAL_CS 0x18 +#define PHYSICAL_DS 0x20 +#define REAL_CS 0x28 +#define REAL_DS 0x30 +#if 0 +#define LONG_CS 0x38 +#define LONG_DS 0x40 +#endif + +#ifndef ASSEMBLY + +#ifdef UACCESS_LIBRM +#define UACCESS_PREFIX_librm +#else +#define UACCESS_PREFIX_librm __librm_ +#endif + +/* Variables in librm.S */ +extern unsigned long virt_offset; + +/** + * Convert physical address to user pointer + * + * @v phys_addr		Physical address + * @ret userptr		User pointer + */ +static inline __always_inline userptr_t +UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) { +	return ( phys_addr - virt_offset ); +} + +/** + * Convert user buffer to physical address + * + * @v userptr		User pointer + * @v offset		Offset from user pointer + * @ret phys_addr	Physical address + */ +static inline __always_inline unsigned long +UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) { +	return ( userptr + offset + virt_offset ); +} + +static inline __always_inline userptr_t +UACCESS_INLINE ( librm, virt_to_user ) ( volatile const void *addr ) { +	return trivial_virt_to_user ( addr ); +} + +static inline __always_inline void * +UACCESS_INLINE ( librm, user_to_virt ) ( userptr_t userptr, off_t offset ) { +	return trivial_user_to_virt ( userptr, offset ); +} + +static inline __always_inline userptr_t +UACCESS_INLINE ( librm, userptr_add ) ( userptr_t userptr, off_t offset ) { +	return trivial_userptr_add ( userptr, offset ); +} + +static inline __always_inline off_t +UACCESS_INLINE ( librm, userptr_sub ) ( userptr_t userptr, +					userptr_t subtrahend ) { +	return trivial_userptr_sub ( userptr, subtrahend ); +} + +static inline __always_inline void +UACCESS_INLINE ( librm, memcpy_user ) ( userptr_t dest, off_t dest_off, +					userptr_t src, off_t src_off, +					size_t len ) { +	trivial_memcpy_user ( dest, dest_off, src, src_off, len ); +} + +static inline __always_inline void +UACCESS_INLINE ( librm, memmove_user ) ( userptr_t dest, off_t dest_off, +					 userptr_t src, off_t src_off, +					 size_t len ) { +	trivial_memmove_user ( dest, dest_off, src, src_off, len ); +} + +static inline __always_inline int +UACCESS_INLINE ( librm, memcmp_user ) ( userptr_t first, off_t first_off, +					userptr_t second, off_t second_off, +					size_t len ) { +	return trivial_memcmp_user ( first, first_off, second, second_off, len); +} + +static inline __always_inline void +UACCESS_INLINE ( librm, memset_user ) ( userptr_t buffer, off_t offset, +					int c, size_t len ) { +	trivial_memset_user ( buffer, offset, c, len ); +} + +static inline __always_inline size_t +UACCESS_INLINE ( librm, strlen_user ) ( userptr_t buffer, off_t offset ) { +	return trivial_strlen_user ( buffer, offset ); +} + +static inline __always_inline off_t +UACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset, +					int c, size_t len ) { +	return trivial_memchr_user ( buffer, offset, c, len ); +} + + +/****************************************************************************** + * + * Access to variables in .data16 and .text16 + * + */ + +extern char *data16; +extern char *text16; + +#define __data16( variable )						\ +	__attribute__ (( section ( ".data16" ) ))			\ +	_data16_ ## variable __asm__ ( #variable ) + +#define __data16_array( variable, array )				\ +	__attribute__ (( section ( ".data16" ) ))			\ +	_data16_ ## variable array __asm__ ( #variable ) + +#define __bss16( variable )						\ +	__attribute__ (( section ( ".bss16" ) ))			\ +	_data16_ ## variable __asm__ ( #variable ) + +#define __bss16_array( variable, array )				\ +	__attribute__ (( section ( ".bss16" ) ))			\ +	_data16_ ## variable array __asm__ ( #variable ) + +#define __text16( variable )						\ +	__attribute__ (( section ( ".text16.data" ) ))			\ +	_text16_ ## variable __asm__ ( #variable ) + +#define __text16_array( variable, array )				\ +	__attribute__ (( section ( ".text16.data" ) ))			\ +	_text16_ ## variable array __asm__ ( #variable ) + +#define __use_data16( variable )					\ +	( * ( ( typeof ( _data16_ ## variable ) * )			\ +	      & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) ) + +#define __use_text16( variable )					\ +	( * ( ( typeof ( _text16_ ## variable ) * )			\ +	      & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) ) + +#define __from_data16( pointer )					\ +	( ( unsigned int )						\ +	  ( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) ) + +#define __from_text16( pointer )					\ +	( ( unsigned int )						\ +	  ( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) ) + +/* Variables in librm.S, present in the normal data segment */ +extern uint16_t rm_sp; +extern uint16_t rm_ss; +extern uint16_t __text16 ( rm_cs ); +#define rm_cs __use_text16 ( rm_cs ) +extern uint16_t __text16 ( rm_ds ); +#define rm_ds __use_text16 ( rm_ds ) + +/** + * Convert segment:offset address to user buffer + * + * @v segment		Real-mode segment + * @v offset		Real-mode offset + * @ret buffer		User buffer + */ +static inline __always_inline userptr_t +real_to_user ( unsigned int segment, unsigned int offset ) { +	return ( phys_to_user ( ( segment << 4 ) + offset ) ); +} + +extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ); +extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); + +/* TEXT16_CODE: declare a fragment of code that resides in .text16 */ +#define TEXT16_CODE( asm_code_str )			\ +	".section \".text16\", \"ax\", @progbits\n\t"	\ +	".code16\n\t"					\ +	asm_code_str "\n\t"				\ +	".code32\n\t"					\ +	".previous\n\t" + +/* REAL_CODE: declare a fragment of code that executes in real mode */ +#define REAL_CODE( asm_code_str )			\ +	"pushl $1f\n\t"					\ +	"call real_call\n\t"				\ +	"addl $4, %%esp\n\t"				\ +	TEXT16_CODE ( "\n1:\n\t"			\ +		      asm_code_str			\ +		      "\n\t"				\ +		      "ret\n\t" ) + +/* PHYS_CODE: declare a fragment of code that executes in flat physical mode */ +#define PHYS_CODE( asm_code_str )			\ +	"call _virt_to_phys\n\t"			\ +	asm_code_str					\ +	"call _phys_to_virt\n\t" + +/** Number of interrupts */ +#define NUM_INT 256 + +/** An interrupt descriptor table register */ +struct idtr { +	/** Limit */ +	uint16_t limit; +	/** Base */ +	uint32_t base; +} __attribute__ (( packed )); + +/** An interrupt descriptor table entry */ +struct interrupt_descriptor { +	/** Low 16 bits of address */ +	uint16_t low; +	/** Code segment */ +	uint16_t segment; +	/** Unused */ +	uint8_t unused; +	/** Type and attributes */ +	uint8_t attr; +	/** High 16 bits of address */ +	uint16_t high; +} __attribute__ (( packed )); + +/** Interrupt descriptor is present */ +#define IDTE_PRESENT 0x80 + +/** Interrupt descriptor 32-bit interrupt gate type */ +#define IDTE_TYPE_IRQ32 0x0e + +/** An interrupt vector + * + * Each interrupt vector comprises an eight-byte fragment of code: + * + *   60			pushal + *   b0 xx		movb $INT, %al + *   e9 xx xx xx xx	jmp interrupt_wrapper + */ +struct interrupt_vector { +	/** "pushal" instruction */ +	uint8_t pushal; +	/** "movb" instruction */ +	uint8_t movb; +	/** Interrupt number */ +	uint8_t intr; +	/** "jmp" instruction */ +	uint8_t jmp; +	/** Interrupt wrapper address offset */ +	uint32_t offset; +	/** Next instruction after jump */ +	uint8_t next[0]; +} __attribute__ (( packed )); + +/** "pushal" instruction */ +#define PUSHAL_INSN 0x60 + +/** "movb" instruction */ +#define MOVB_INSN 0xb0 + +/** "jmp" instruction */ +#define JMP_INSN 0xe9 + +extern void set_interrupt_vector ( unsigned int intr, void *vector ); + +#endif /* ASSEMBLY */ + +#endif /* LIBRM_H */ diff --git a/roms/ipxe/src/arch/i386/include/limits.h b/roms/ipxe/src/arch/i386/include/limits.h new file mode 100644 index 00000000..031b6c57 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/limits.h @@ -0,0 +1,61 @@ +#ifndef LIMITS_H +#define LIMITS_H	1 + +FILE_LICENCE ( GPL2_OR_LATER ); + +/* Number of bits in a `char' */ +#define CHAR_BIT	8 + +/* Minimum and maximum values a `signed char' can hold */ +#define SCHAR_MIN	(-128) +#define SCHAR_MAX	127 + +/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ +#define UCHAR_MAX	255 + +/* Minimum and maximum values a `char' can hold */ +#define CHAR_MIN	SCHAR_MIN +#define CHAR_MAX	SCHAR_MAX + +/* Minimum and maximum values a `signed short int' can hold */ +#define SHRT_MIN	(-32768) +#define SHRT_MAX	32767 + +/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */ +#define USHRT_MAX	65535 + + +/* Minimum and maximum values a `signed int' can hold */ +#define INT_MIN		(-INT_MAX - 1) +#define INT_MAX		2147483647 + +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ +#define UINT_MAX	4294967295U + + +/* Minimum and maximum values a `signed int' can hold */ +#define INT_MAX		2147483647 +#define INT_MIN		(-INT_MAX - 1) + + +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ +#define UINT_MAX	4294967295U + + +/* Minimum and maximum values a `signed long' can hold */ +#define LONG_MAX	2147483647 +#define LONG_MIN	(-LONG_MAX - 1L) + +/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */ +#define ULONG_MAX	4294967295UL + +/* Minimum and maximum values a `signed long long' can hold */ +#define LLONG_MAX	9223372036854775807LL +#define LLONG_MIN	(-LONG_MAX - 1LL) + + +/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */ +#define ULLONG_MAX	18446744073709551615ULL + + +#endif /* LIMITS_H */ diff --git a/roms/ipxe/src/arch/i386/include/memsizes.h b/roms/ipxe/src/arch/i386/include/memsizes.h new file mode 100644 index 00000000..7b217494 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/memsizes.h @@ -0,0 +1,19 @@ +#ifndef _MEMSIZES_H +#define _MEMSIZES_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <basemem.h> + +/** + * Get size of base memory from BIOS free base memory counter + * + * @ret basemem		Base memory size, in kB + */ +static inline unsigned int basememsize ( void ) { +	return get_fbms(); +} + +extern unsigned int extmemsize ( void ); + +#endif /* _MEMSIZES_H */ diff --git a/roms/ipxe/src/arch/i386/include/multiboot.h b/roms/ipxe/src/arch/i386/include/multiboot.h new file mode 100644 index 00000000..44614c73 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/multiboot.h @@ -0,0 +1,149 @@ +#ifndef _MULTIBOOT_H +#define _MULTIBOOT_H + +/** + * @file + * + * Multiboot operating systems + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> + +/** The magic number for the Multiboot header */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/** Boot modules must be page aligned */ +#define MB_FLAG_PGALIGN 0x00000001 + +/** Memory map must be provided */ +#define MB_FLAG_MEMMAP 0x00000002 + +/** Video mode information must be provided */ +#define MB_FLAG_VIDMODE 0x00000004 + +/** Image is a raw multiboot image (not ELF) */ +#define MB_FLAG_RAW 0x00010000 + +/** + * The magic number passed by a Multiboot-compliant boot loader + * + * Must be passed in register %eax when jumping to the Multiboot OS + * image. + */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/** Multiboot information structure mem_* fields are valid */ +#define MBI_FLAG_MEM 0x00000001 + +/** Multiboot information structure boot_device field is valid */ +#define MBI_FLAG_BOOTDEV 0x00000002 + +/** Multiboot information structure cmdline field is valid */ +#define MBI_FLAG_CMDLINE 0x00000004 + +/** Multiboot information structure module fields are valid */ +#define MBI_FLAG_MODS 0x00000008 + +/** Multiboot information structure a.out symbol table is valid */ +#define MBI_FLAG_AOUT 0x00000010 + +/** Multiboot information struture ELF section header table is valid */ +#define MBI_FLAG_ELF 0x00000020 + +/** Multiboot information structure memory map is valid */ +#define MBI_FLAG_MMAP 0x00000040 + +/** Multiboot information structure drive list is valid */ +#define MBI_FLAG_DRIVES 0x00000080 + +/** Multiboot information structure ROM configuration field is valid */ +#define MBI_FLAG_CFGTBL 0x00000100 + +/** Multiboot information structure boot loader name field is valid */ +#define MBI_FLAG_LOADER 0x00000200 + +/** Multiboot information structure APM table is valid */ +#define MBI_FLAG_APM 0x00000400 + +/** Multiboot information structure video information is valid */ +#define MBI_FLAG_VBE 0x00000800 + +/** A multiboot header */ +struct multiboot_header { +	uint32_t magic; +	uint32_t flags; +	uint32_t checksum; +	uint32_t header_addr; +	uint32_t load_addr; +	uint32_t load_end_addr; +	uint32_t bss_end_addr; +	uint32_t entry_addr; +} __attribute__ (( packed, may_alias )); + +/** A multiboot a.out symbol table */ +struct multiboot_aout_symbol_table { +	uint32_t tabsize; +	uint32_t strsize; +	uint32_t addr; +	uint32_t reserved; +} __attribute__ (( packed, may_alias )); + +/** A multiboot ELF section header table */ +struct multiboot_elf_section_header_table { +	uint32_t num; +	uint32_t size; +	uint32_t addr; +	uint32_t shndx; +} __attribute__ (( packed, may_alias )); + +/** A multiboot information structure */ +struct multiboot_info { +	uint32_t flags; +	uint32_t mem_lower; +	uint32_t mem_upper; +	uint32_t boot_device; +	uint32_t cmdline; +	uint32_t mods_count; +	uint32_t mods_addr; +	union { +		struct multiboot_aout_symbol_table aout_syms; +		struct multiboot_elf_section_header_table elf_sections; +	} syms; +	uint32_t mmap_length; +	uint32_t mmap_addr; +	uint32_t drives_length; +	uint32_t drives_addr; +	uint32_t config_table; +	uint32_t boot_loader_name; +	uint32_t apm_table; +	uint32_t vbe_control_info; +	uint32_t vbe_mode_info; +	uint16_t vbe_mode; +	uint16_t vbe_interface_seg; +	uint16_t vbe_interface_off; +	uint16_t vbe_interface_len; +} __attribute__ (( packed, may_alias )); + +/** A multiboot module structure */ +struct multiboot_module { +	uint32_t mod_start; +	uint32_t mod_end; +	uint32_t string; +	uint32_t reserved; +} __attribute__ (( packed, may_alias )); + +/** A multiboot memory map entry */ +struct multiboot_memory_map { +	uint32_t size; +	uint64_t base_addr; +	uint64_t length; +	uint32_t type; +} __attribute__ (( packed, may_alias )); + +/** Usable RAM */ +#define MBMEM_RAM 1 + +#endif /* _MULTIBOOT_H */ diff --git a/roms/ipxe/src/arch/i386/include/pcbios/ipxe/dhcp_arch.h b/roms/ipxe/src/arch/i386/include/pcbios/ipxe/dhcp_arch.h new file mode 100644 index 00000000..a36d9cfa --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pcbios/ipxe/dhcp_arch.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 VMware, Inc.  All Rights Reserved. + * + * 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 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _DHCP_ARCH_H +#define _DHCP_ARCH_H + +/** @file + * + * Architecture-specific DHCP options + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/dhcp.h> + +#define DHCP_ARCH_VENDOR_CLASS_ID \ +	DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':',      \ +		      'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '0', ':', \ +		      'U', 'N', 'D', 'I', ':', '0', '0', '2', '0', '0', '1' ) + +#define DHCP_ARCH_CLIENT_ARCHITECTURE \ +	DHCP_WORD ( DHCP_CLIENT_ARCHITECTURE_X86 ) + +#define DHCP_ARCH_CLIENT_NDI DHCP_OPTION ( 1 /* UNDI */ , 2, 1 /* v2.1 */ ) + +#endif diff --git a/roms/ipxe/src/arch/i386/include/pic8259.h b/roms/ipxe/src/arch/i386/include/pic8259.h new file mode 100644 index 00000000..a07e97d3 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pic8259.h @@ -0,0 +1,73 @@ +/* + * Basic support for controlling the 8259 Programmable Interrupt Controllers. + * + * Initially written by Michael Brown (mcb30). + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifndef PIC8259_H +#define PIC8259_H + +#include <ipxe/io.h> + +/* For segoff_t */ +#include "realmode.h" + +#define IRQ_PIC_CUTOFF 8 + +/* 8259 register locations */ +#define PIC1_ICW1 0x20 +#define PIC1_OCW2 0x20 +#define PIC1_OCW3 0x20 +#define PIC1_ICR 0x20 +#define PIC1_IRR 0x20 +#define PIC1_ISR 0x20 +#define PIC1_ICW2 0x21 +#define PIC1_ICW3 0x21 +#define PIC1_ICW4 0x21 +#define PIC1_IMR 0x21 +#define PIC2_ICW1 0xa0 +#define PIC2_OCW2 0xa0 +#define PIC2_OCW3 0xa0 +#define PIC2_ICR 0xa0 +#define PIC2_IRR 0xa0 +#define PIC2_ISR 0xa0 +#define PIC2_ICW2 0xa1 +#define PIC2_ICW3 0xa1 +#define PIC2_ICW4 0xa1 +#define PIC2_IMR 0xa1 + +/* Register command values */ +#define OCW3_ID 0x08 +#define OCW3_READ_IRR 0x03 +#define OCW3_READ_ISR 0x02 +#define ICR_EOI_NON_SPECIFIC 0x20 +#define ICR_EOI_NOP 0x40 +#define ICR_EOI_SPECIFIC 0x60 +#define ICR_EOI_SET_PRIORITY 0xc0 + +/* Macros to enable/disable IRQs */ +#define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR ) +#define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) ) +#define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 ) +#define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) ) +#define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) ) + +/* Macros for acknowledging IRQs */ +#define ICR_REG( irq ) ( (irq) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR ) +#define ICR_VALUE( irq ) ( (irq) % IRQ_PIC_CUTOFF ) +#define CHAINED_IRQ 2 + +/* Utility macros to convert IRQ numbers to INT numbers and INT vectors  */ +#define IRQ_INT( irq ) ( ( ( (irq) - IRQ_PIC_CUTOFF ) ^ 0x70 ) & 0x7f ) + +/* Other constants */ +#define IRQ_MAX 15 +#define IRQ_NONE -1U + +/* Function prototypes + */ +void send_eoi ( unsigned int irq ); + +#endif /* PIC8259_H */ diff --git a/roms/ipxe/src/arch/i386/include/pnpbios.h b/roms/ipxe/src/arch/i386/include/pnpbios.h new file mode 100644 index 00000000..4c20e73e --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pnpbios.h @@ -0,0 +1,17 @@ +#ifndef _PNPBIOS_H +#define _PNPBIOS_H + +/** @file + * + * PnP BIOS + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/* BIOS segment address */ +#define BIOS_SEG 0xf000 + +extern int find_pnp_bios ( void ); + +#endif /* _PNPBIOS_H */ diff --git a/roms/ipxe/src/arch/i386/include/pxe.h b/roms/ipxe/src/arch/i386/include/pxe.h new file mode 100644 index 00000000..b95b0cce --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pxe.h @@ -0,0 +1,199 @@ +#ifndef PXE_H +#define PXE_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include "pxe_types.h" +#include "pxe_error.h" +#include "pxe_api.h" +#include <ipxe/device.h> +#include <ipxe/tables.h> + +/** PXE API invalid function code */ +#define PXENV_UNKNOWN 0xffff + +/** Parameter block for pxenv_unknown() */ +struct s_PXENV_UNKNOWN { +	PXENV_STATUS_t Status;			/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNKNOWN PXENV_UNKNOWN_t; + +/* Union used for PXE API calls; we don't know the type of the + * structure until we interpret the opcode.  Also, Status is available + * in the same location for any opcode, and it's convenient to have + * non-specific access to it. + */ +union u_PXENV_ANY { +	/* Make it easy to read status for any operation */ +	PXENV_STATUS_t				Status; +	struct s_PXENV_UNKNOWN			unknown; +	struct s_PXENV_UNLOAD_STACK		unload_stack; +	struct s_PXENV_GET_CACHED_INFO		get_cached_info; +	struct s_PXENV_TFTP_READ_FILE		restart_tftp; +	struct s_PXENV_START_UNDI		start_undi; +	struct s_PXENV_STOP_UNDI		stop_undi; +	struct s_PXENV_START_BASE		start_base; +	struct s_PXENV_STOP_BASE		stop_base; +	struct s_PXENV_TFTP_OPEN		tftp_open; +	struct s_PXENV_TFTP_CLOSE		tftp_close; +	struct s_PXENV_TFTP_READ		tftp_read; +	struct s_PXENV_TFTP_READ_FILE		tftp_read_file; +	struct s_PXENV_TFTP_GET_FSIZE		tftp_get_fsize; +	struct s_PXENV_UDP_OPEN			udp_open; +	struct s_PXENV_UDP_CLOSE		udp_close; +	struct s_PXENV_UDP_WRITE		udp_write; +	struct s_PXENV_UDP_READ			udp_read; +	struct s_PXENV_UNDI_STARTUP		undi_startup; +	struct s_PXENV_UNDI_CLEANUP		undi_cleanup; +	struct s_PXENV_UNDI_INITIALIZE		undi_initialize; +	struct s_PXENV_UNDI_RESET		undi_reset_adapter; +	struct s_PXENV_UNDI_SHUTDOWN		undi_shutdown; +	struct s_PXENV_UNDI_OPEN		undi_open; +	struct s_PXENV_UNDI_CLOSE		undi_close; +	struct s_PXENV_UNDI_TRANSMIT		undi_transmit; +	struct s_PXENV_UNDI_SET_MCAST_ADDRESS	undi_set_mcast_address; +	struct s_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address; +	struct s_PXENV_UNDI_SET_PACKET_FILTER	undi_set_packet_filter; +	struct s_PXENV_UNDI_GET_INFORMATION	undi_get_information; +	struct s_PXENV_UNDI_GET_STATISTICS	undi_get_statistics; +	struct s_PXENV_UNDI_CLEAR_STATISTICS	undi_clear_statistics; +	struct s_PXENV_UNDI_INITIATE_DIAGS	undi_initiate_diags; +	struct s_PXENV_UNDI_FORCE_INTERRUPT	undi_force_interrupt; +	struct s_PXENV_UNDI_GET_MCAST_ADDRESS	undi_get_mcast_address; +	struct s_PXENV_UNDI_GET_NIC_TYPE	undi_get_nic_type; +	struct s_PXENV_UNDI_GET_IFACE_INFO	undi_get_iface_info; +	struct s_PXENV_UNDI_GET_STATE		undi_get_state; +	struct s_PXENV_UNDI_ISR			undi_isr; +	struct s_PXENV_FILE_OPEN		file_open; +	struct s_PXENV_FILE_CLOSE		file_close; +	struct s_PXENV_FILE_SELECT		file_select; +	struct s_PXENV_FILE_READ		file_read; +	struct s_PXENV_GET_FILE_SIZE		get_file_size; +	struct s_PXENV_FILE_EXEC		file_exec; +	struct s_PXENV_FILE_API_CHECK		file_api_check; +	struct s_PXENV_FILE_EXIT_HOOK		file_exit_hook; +}; + +typedef union u_PXENV_ANY PXENV_ANY_t; + +/** A PXE API call */ +struct pxe_api_call { +	/** Entry point +	 * +	 * @v params		PXE API call parameters +	 * @ret exit		PXE API call exit code +	 */ +	PXENV_EXIT_t ( * entry ) ( union u_PXENV_ANY *params ); +	/** Length of parameters */ +	uint16_t params_len; +	/** Opcode */ +	uint16_t opcode; +}; + +/** PXE API call table */ +#define PXE_API_CALLS __table ( struct pxe_api_call, "pxe_api_calls" ) + +/** Declare a PXE API call */ +#define __pxe_api_call __table_entry ( PXE_API_CALLS, 01 ) + +/** + * Define a PXE API call + * + * @v _opcode		Opcode + * @v _entry		Entry point + * @v _params_type	Type of parameter structure + * @ret call		PXE API call + */ +#define PXE_API_CALL( _opcode, _entry, _params_type ) {			      \ +	.entry = ( ( ( ( PXENV_EXIT_t ( * ) ( _params_type *params ) ) NULL ) \ +		    == ( ( typeof ( _entry ) * ) NULL ) )		      \ +		   ? ( ( PXENV_EXIT_t ( * )				      \ +			 ( union u_PXENV_ANY *params ) ) _entry )	      \ +		   : ( ( PXENV_EXIT_t ( * )				      \ +			 ( union u_PXENV_ANY *params ) ) _entry ) ),	      \ +	.params_len = sizeof ( _params_type ),				      \ +	.opcode = _opcode,						      \ +	} + +/** An UNDI expansion ROM header */ +struct undi_rom_header { +	/** Signature +	 * +	 * Must be equal to @c ROM_SIGNATURE +	 */ +	UINT16_t Signature; +	/** ROM length in 512-byte blocks */ +	UINT8_t ROMLength; +	/** Unused */ +	UINT8_t unused[0x13]; +	/** Offset of the PXE ROM ID structure */ +	UINT16_t PXEROMID; +	/** Offset of the PCI ROM structure */ +	UINT16_t PCIRHeader; +} __attribute__ (( packed )); + +/** Signature for an expansion ROM */ +#define ROM_SIGNATURE 0xaa55 + +/** An UNDI ROM ID structure */ +struct undi_rom_id { +	/** Signature +	 * +	 * Must be equal to @c UNDI_ROM_ID_SIGNATURE +	 */ +	UINT32_t Signature; +	/** Length of structure */ +	UINT8_t StructLength; +	/** Checksum */ +	UINT8_t StructCksum; +	/** Structure revision +	 * +	 * Must be zero. +	 */ +	UINT8_t StructRev; +	/** UNDI revision +	 * +	 * Version 2.1.0 is encoded as the byte sequence 0x00, 0x01, 0x02. +	 */ +	UINT8_t UNDIRev[3]; +	/** Offset to UNDI loader */ +	UINT16_t UNDILoader; +	/** Minimum required stack segment size */ +	UINT16_t StackSize; +	/** Minimum required data segment size */ +	UINT16_t DataSize; +	/** Minimum required code segment size */ +	UINT16_t CodeSize; +} __attribute__ (( packed )); + +/** Signature for an UNDI ROM ID structure */ +#define UNDI_ROM_ID_SIGNATURE \ +	( ( 'U' << 0 ) + ( 'N' << 8 ) + ( 'D' << 16 ) + ( 'I' << 24 ) ) + +/** A PCI expansion header */ +struct pcir_header { +	/** Signature +	 * +	 * Must be equal to @c PCIR_SIGNATURE +	 */ +	uint32_t signature; +	/** PCI vendor ID */ +	uint16_t vendor_id; +	/** PCI device ID */ +	uint16_t device_id; +} __attribute__ (( packed )); + +/** Signature for an UNDI ROM ID structure */ +#define PCIR_SIGNATURE \ +	( ( 'P' << 0 ) + ( 'C' << 8 ) + ( 'I' << 16 ) + ( 'R' << 24 ) ) + +extern struct net_device *pxe_netdev; +extern const char *pxe_cmdline; + +extern void pxe_set_netdev ( struct net_device *netdev ); +extern PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE +					   *tftp_read_file ); +extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader ); + +#endif /* PXE_H */ diff --git a/roms/ipxe/src/arch/i386/include/pxe_api.h b/roms/ipxe/src/arch/i386/include/pxe_api.h new file mode 100644 index 00000000..e4396efb --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pxe_api.h @@ -0,0 +1,1819 @@ +#ifndef PXE_API_H +#define PXE_API_H + +/* + * 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 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * As an alternative, at your option, you may use this file under the + * following terms, known as the "MIT license": + * + * Copyright (c) 2005-2009 Michael Brown <mbrown@fensystems.co.uk> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** @file + * + * Preboot eXecution Environment (PXE) API + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include "pxe_types.h" + +/** @addtogroup pxe Preboot eXecution Environment (PXE) API + *  @{ + */ + +/** @defgroup pxe_api_call PXE entry points + * + * PXE entry points and calling conventions + * + *  @{ + */ + +/** The PXENV+ structure */ +struct s_PXENV { +	/** Signature +	 * +	 * Contains the bytes 'P', 'X', 'E', 'N', 'V', '+'. +	 */ +	UINT8_t		Signature[6]; +	/** PXE API version +	 * +	 * MSB is major version number, LSB is minor version number. +	 * If the API version number is 0x0201 or greater, the !PXE +	 * structure pointed to by #PXEPtr should be used instead of +	 * this data structure. +	 */ +	UINT16_t	Version; +	UINT8_t		Length;		/**< Length of this structure */ +	/** Checksum +	 * +	 * The byte checksum of this structure (using the length in +	 * #Length) must be zero. +	 */ +	UINT8_t		Checksum; +	SEGOFF16_t	RMEntry;	/**< Real-mode PXENV+ entry point */ +	/** Protected-mode PXENV+ entry point offset +	 * +	 * PXE 2.1 deprecates this entry point.  For protected-mode +	 * API calls, use the !PXE structure pointed to by #PXEPtr +	 * instead. +	 */ +	UINT32_t	PMOffset; +	/** Protected-mode PXENV+ entry point segment selector +	 * +	 * PXE 2.1 deprecates this entry point.  For protected-mode +	 * API calls, use the !PXE structure pointed to by #PXEPtr +	 * instead. +	 */ +	SEGSEL_t	PMSelector; +	SEGSEL_t	StackSeg;	/**< Stack segment selector */ +	UINT16_t	StackSize;	/**< Stack segment size */ +	SEGSEL_t	BC_CodeSeg;	/**< Base-code code segment selector */ +	UINT16_t	BC_CodeSize;	/**< Base-code code segment size */ +	SEGSEL_t	BC_DataSeg;	/**< Base-code data segment selector */ +	UINT16_t	BC_DataSize;	/**< Base-code data segment size */ +	SEGSEL_t	UNDIDataSeg;	/**< UNDI data segment selector */ +	UINT16_t	UNDIDataSize;	/**< UNDI data segment size */ +	SEGSEL_t	UNDICodeSeg;	/**< UNDI code segment selector */ +	UINT16_t	UNDICodeSize;	/**< UNDI code segment size */ +	/** Address of the !PXE structure +	 * +	 * This field is present only if #Version is 0x0201 or +	 * greater.  If present, it points to a struct s_PXE. +	 */ +	SEGOFF16_t	PXEPtr; +} __attribute__ (( packed )); + +typedef struct s_PXENV PXENV_t; + +/** The !PXE structure */ +struct s_PXE { +	/** Signature +	 * +	 * Contains the bytes '!', 'P', 'X', 'E'. +	 */ +	UINT8_t		Signature[4]; +	UINT8_t		StructLength;	/**< Length of this structure */ +	/** Checksum +	 * +	 * The byte checksum of this structure (using the length in +	 * #StructLength) must be zero. +	 */ +	UINT8_t		StructCksum; +	/** Revision of this structure +	 * +	 * For PXE version 2.1, this field must be zero. +	 */ +	UINT8_t		StructRev; +	UINT8_t		reserved_1;	/**< Must be zero */ +	/** Address of the UNDI ROM ID structure +	 * +	 * This is a pointer to a struct s_UNDI_ROM_ID. +	 */ +	SEGOFF16_t	UNDIROMID; +	/** Address of the Base Code ROM ID structure +	 * +	 * This is a pointer to a struct s_BC_ROM_ID. +	 */ +	SEGOFF16_t	BaseROMID; +	/** 16-bit !PXE entry point +	 * +	 * This is the entry point for either real mode, or protected +	 * mode with a 16-bit stack segment. +	 */ +	SEGOFF16_t	EntryPointSP; +	/** 32-bit !PXE entry point +	 * +	 * This is the entry point for protected mode with a 32-bit +	 * stack segment. +	 */ +	SEGOFF16_t	EntryPointESP; +	/** Status call-out function +	 * +	 * @v 0		(if in a time-out loop) +	 * @v n		Number of a received TFTP packet +	 * @ret 0	Continue operation +	 * @ret 1	Cancel operation +	 * +	 * This function will be called whenever the PXE stack is in +	 * protected mode, is waiting for an event (e.g. a DHCP reply) +	 * and wishes to allow the user to cancel the operation. +	 * Parameters are passed in register %ax; the return value +	 * must also be placed in register %ax.  All other registers +	 * and flags @b must be preserved. +	 * +	 * In real mode, an internal function (that checks for a +	 * keypress) will be used. +	 * +	 * If this field is set to -1, no status call-out function +	 * will be used and consequently the user will not be allowed +	 * to interrupt operations. +	 * +	 * @note The PXE specification version 2.1 defines the +	 * StatusCallout field, mentions it 11 times, but nowhere +	 * defines what it actually does or how it gets called. +	 * Fortunately, the WfM specification version 1.1a deigns to +	 * inform us of such petty details. +	 */ +	SEGOFF16_t	StatusCallout; +	UINT8_t		reserved_2;	/**< Must be zero */ +	/** Number of segment descriptors +	 * +	 * If this number is greater than 7, the remaining descriptors +	 * follow immediately after #BC_CodeWrite. +	 */ +	UINT8_t		SegDescCnt; +	/** First protected-mode selector +	 * +	 * This is the segment selector value for the first segment +	 * assigned to PXE.  Protected-mode selectors must be +	 * consecutive, according to the PXE 2.1 specification, though +	 * no reason is given.  Each #SEGDESC_t includes a field for +	 * the segment selector, so this information is entirely +	 * redundant. +	 */ +	SEGSEL_t	FirstSelector; +	/** Stack segment descriptor */ +	SEGDESC_t	Stack; +	/** UNDI data segment descriptor */ +	SEGDESC_t	UNDIData; +	/** UNDI code segment descriptor */ +	SEGDESC_t	UNDICode; +	/** UNDI writable code segment descriptor */ +	SEGDESC_t	UNDICodeWrite; +	/** Base-code data segment descriptor */ +	SEGDESC_t	BC_Data; +	/** Base-code code segment descriptor */ +	SEGDESC_t	BC_Code; +	/** Base-code writable code segment descriptor */ +	SEGDESC_t	BC_CodeWrite; +} __attribute__ (( packed )); + +typedef struct s_PXE PXE_t; + +/** @} */ /* pxe_api_call */ + +/** @defgroup pxe_preboot_api PXE Preboot API + * + * General high-level functions: #PXENV_UNLOAD_STACK, #PXENV_START_UNDI etc. + * + * @{ + */ + +/** @defgroup pxenv_unload_stack PXENV_UNLOAD_STACK + * + *  UNLOAD BASE CODE STACK + * + *  @{ + */ + +/** PXE API function code for pxenv_unload_stack() */ +#define	PXENV_UNLOAD_STACK		0x0070 + +/** Parameter block for pxenv_unload_stack() */ +struct s_PXENV_UNLOAD_STACK { +	PXENV_STATUS_t Status;			/**< PXE status code */ +	UINT8_t reserved[10];			/**< Must be zero */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNLOAD_STACK PXENV_UNLOAD_STACK_t; + +/** @} */ /* pxenv_unload_stack */ + +/** @defgroup pxenv_get_cached_info PXENV_GET_CACHED_INFO + * + *  GET CACHED INFO + * + *  @{ + */ + +/** PXE API function code for pxenv_get_cached_info() */ +#define	PXENV_GET_CACHED_INFO		0x0071 + +/** The client's DHCPDISCOVER packet */ +#define PXENV_PACKET_TYPE_DHCP_DISCOVER	1 + +/** The DHCP server's DHCPACK packet */ +#define PXENV_PACKET_TYPE_DHCP_ACK	2 + +/** The Boot Server's Discover Reply packet + * + * This packet contains DHCP option 60 set to "PXEClient", a valid + * boot file name, and may or may not contain MTFTP options. + */ +#define PXENV_PACKET_TYPE_CACHED_REPLY	3 + +/** Parameter block for pxenv_get_cached_info() */ +struct s_PXENV_GET_CACHED_INFO { +	PXENV_STATUS_t Status;			/**< PXE status code */ +	/** Packet type. +	 * +	 * Valid values are #PXENV_PACKET_TYPE_DHCP_DISCOVER, +	 * #PXENV_PACKET_TYPE_DHCP_ACK or #PXENV_PACKET_TYPE_CACHED_REPLY +	 */ +	UINT16_t PacketType; +	UINT16_t BufferSize;			/**< Buffer size */ +	SEGOFF16_t Buffer;			/**< Buffer address */ +	UINT16_t BufferLimit;			/**< Maximum buffer size */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_GET_CACHED_INFO PXENV_GET_CACHED_INFO_t; + +#define BOOTP_REQ	1	/**< A BOOTP request packet */ +#define BOOTP_REP	2	/**< A BOOTP reply packet */ + +/** DHCP broadcast flag + * + * Request a broadcast response (DHCPOFFER or DHCPACK) from the DHCP + * server. + */ +#define BOOTP_BCAST	0x8000 + +#define VM_RFC1048	0x63825363L	/**< DHCP magic cookie */ + +/** Maximum length of DHCP options */ +#define BOOTP_DHCPVEND	1024 + +/** Format of buffer filled in by pxenv_get_cached_info() + * + * This somewhat convoluted data structure simply describes the layout + * of a DHCP packet.  Refer to RFC2131 section 2 for a full + * description. + */ +struct bootph { +	/** Message opcode. +	 * +	 * Valid values are #BOOTP_REQ and #BOOTP_REP. +	 */ +	UINT8_t opcode; +	/** NIC hardware type. +	 * +	 * Valid values are as for s_PXENV_UNDI_GET_INFORMATION::HwType. +	 */ +	UINT8_t Hardware; +	UINT8_t Hardlen;		/**< MAC address length */ +	/** Gateway hops +	 * +	 * Zero in packets sent by the client.  May be non-zero in +	 * replies from the DHCP server, if the reply comes via a DHCP +	 * relay agent. +	 */ +	UINT8_t Gatehops; +	UINT32_t ident;			/**< DHCP transaction id (xid) */ +	/** Elapsed time +	 * +	 * Number of seconds since the client began the DHCP +	 * transaction. +	 */ +	UINT16_t seconds; +	/** Flags +	 * +	 * This is the bitwise-OR of any of the following values: +	 * #BOOTP_BCAST. +	 */ +	UINT16_t Flags; +	/** Client IP address +	 * +	 * Set only if the client already has an IP address. +	 */ +	IP4_t cip; +	/** Your IP address +	 * +	 * This is the IP address that the server assigns to the +	 * client. +	 */ +	IP4_t yip; +	/** Server IP address +	 * +	 * This is the IP address of the BOOTP/DHCP server. +	 */ +	IP4_t sip; +	/** Gateway IP address +	 * +	 * This is the IP address of the BOOTP/DHCP relay agent, if +	 * any.  It is @b not (necessarily) the address of the default +	 * gateway for routing purposes. +	 */ +	IP4_t gip; +	MAC_ADDR_t CAddr;		/**< Client MAC address */ +	UINT8_t Sname[64];		/**< Server host name */ +	UINT8_t bootfile[128];		/**< Boot file name */ +	/** DHCP options +	 * +	 * Don't ask.  Just laugh.  Then burn a copy of the PXE +	 * specification and send Intel an e-mail asking them if +	 * they've figured out what a "union" does in C yet. +	 */ +	union bootph_vendor { +		UINT8_t d[BOOTP_DHCPVEND]; /**< DHCP options */ +		/** DHCP options */ +		struct bootph_vendor_v { +			/** DHCP magic cookie +			 * +			 * Should have the value #VM_RFC1048. +			 */ +			UINT8_t magic[4]; +			UINT32_t flags;	/**< BOOTP flags/opcodes */ +			/** "End of BOOTP vendor extensions" +			 * +			 * Abandon hope, all ye who consider the +			 * purpose of this field. +			 */ +			UINT8_t pad[56]; +		} v; +	} vendor; +} __attribute__ (( packed )); + +typedef struct bootph BOOTPLAYER_t; + +/** @} */ /* pxenv_get_cached_info */ + +/** @defgroup pxenv_restart_tftp PXENV_RESTART_TFTP + * + *  RESTART TFTP + * + *  @{ + */ + +/** PXE API function code for pxenv_restart_tftp() */ +#define	PXENV_RESTART_TFTP		0x0073 + +/** Parameter block for pxenv_restart_tftp() */ +struct s_PXENV_TFTP_READ_FILE; + +typedef struct s_PXENV_RESTART_TFTP PXENV_RESTART_TFTP_t; + +/** @} */ /* pxenv_restart_tftp */ + +/** @defgroup pxenv_start_undi PXENV_START_UNDI + * + *  START UNDI + * + *  @{ + */ + +/** PXE API function code for pxenv_start_undi() */ +#define	PXENV_START_UNDI		0x0000 + +/** Parameter block for pxenv_start_undi() */ +struct s_PXENV_START_UNDI { +	PXENV_STATUS_t Status;			/**< PXE status code */ +	/** %ax register as passed to the Option ROM initialisation routine. +	 * +	 * For a PCI device, this should contain the bus:dev:fn value +	 * that uniquely identifies the PCI device in the system.  For +	 * a non-PCI device, this field is not defined. +	 */ +	UINT16_t AX; +	/** %bx register as passed to the Option ROM initialisation routine. +	 * +	 * For an ISAPnP device, this should contain the Card Select +	 * Number assigned to the ISAPnP card.  For non-ISAPnP +	 * devices, this should contain 0xffff. +	 */ +	UINT16_t BX; +	/** %dx register as passed to the Option ROM initialisation routine. +	 * +	 * For an ISAPnP device, this should contain the ISAPnP Read +	 * Port address as currently set in all ISAPnP cards.  If +	 * there are no ISAPnP cards, this should contain 0xffff.  (If +	 * this is a non-ISAPnP device, but there are ISAPnP cards in +	 * the system, this value is not well defined.) +	 */ +	UINT16_t DX; +	/** %di register as passed to the Option ROM initialisation routine. +	 * +	 * This contains the #OFF16_t portion of a struct #s_SEGOFF16 +	 * that points to the System BIOS Plug and Play Installation +	 * Check Structure.  (Refer to section 4.4 of the Plug and +	 * Play BIOS specification for a description of this +	 * structure.) +	 * +	 * @note The PXE specification defines the type of this field +	 * as #UINT16_t.  For x86, #OFF16_t and #UINT16_t are +	 * equivalent anyway; for other architectures #OFF16_t makes +	 * more sense. +	 */ +	OFF16_t DI; +	/** %es register as passed to the Option ROM initialisation routine. +	 * +	 * This contains the #SEGSEL_t portion of a struct #s_SEGOFF16 +	 * that points to the System BIOS Plug and Play Installation +	 * Check Structure.  (Refer to section 4.4 of the Plug and +	 * Play BIOS specification for a description of this +	 * structure.) +	 * +	 * @note The PXE specification defines the type of this field +	 * as #UINT16_t.  For x86, #SEGSEL_t and #UINT16_t are +	 * equivalent anyway; for other architectures #SEGSEL_t makes +	 * more sense. +	 */ +	SEGSEL_t ES; +} __attribute__ (( packed )); + +typedef struct s_PXENV_START_UNDI PXENV_START_UNDI_t; + +/** @} */ /* pxenv_start_undi */ + +/** @defgroup pxenv_stop_undi PXENV_STOP_UNDI + * + *  STOP UNDI + * + *  @{ + */ + +/** PXE API function code for pxenv_stop_undi() */ +#define	PXENV_STOP_UNDI			0x0015 + +/** Parameter block for pxenv_stop_undi() */ +struct s_PXENV_STOP_UNDI { +	PXENV_STATUS_t Status;			/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_STOP_UNDI PXENV_STOP_UNDI_t; + +/** @} */ /* pxenv_stop_undi */ + +/** @defgroup pxenv_start_base PXENV_START_BASE + * + *  START BASE + * + *  @{ + */ + +/** PXE API function code for pxenv_start_base() */ +#define	PXENV_START_BASE		0x0075 + +/** Parameter block for pxenv_start_base() */ +struct s_PXENV_START_BASE { +	PXENV_STATUS_t Status;			/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_START_BASE PXENV_START_BASE_t; + +/** @} */ /* pxenv_start_base */ + +/** @defgroup pxenv_stop_base PXENV_STOP_BASE + * + *  STOP BASE + * + *  @{ + */ + +/** PXE API function code for pxenv_stop_base() */ +#define	PXENV_STOP_BASE			0x0076 + +/** Parameter block for pxenv_stop_base() */ +struct s_PXENV_STOP_BASE { +	PXENV_STATUS_t Status;			/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_STOP_BASE PXENV_STOP_BASE_t; + +/** @} */ /* pxenv_stop_base */ + +/** @} */ /* pxe_preboot_api */ + +/** @defgroup pxe_tftp_api PXE TFTP API + * + * Download files via TFTP or MTFTP + * + * @{ + */ + +/** @defgroup pxenv_tftp_open PXENV_TFTP_OPEN + * + *  TFTP OPEN + * + *  @{ + */ + +/** PXE API function code for pxenv_tftp_open() */ +#define	PXENV_TFTP_OPEN			0x0020 + +/** Parameter block for pxenv_tftp_open() */ +struct s_PXENV_TFTP_OPEN { +	PXENV_STATUS_t Status;			/**< PXE status code */ +	IP4_t ServerIPAddress;			/**< TFTP server IP address */ +	IP4_t GatewayIPAddress;			/**< Relay agent IP address */ +	UINT8_t FileName[128];			/**< File name */ +	UDP_PORT_t TFTPPort;			/**< TFTP server UDP port */ +	/** Requested size of TFTP packets +	 * +	 * This is the TFTP "blksize" option.  This must be at least +	 * 512, since servers that do not support TFTP options cannot +	 * negotiate blocksizes smaller than this. +	 */ +	UINT16_t PacketSize; +} __attribute__ (( packed )); + +typedef struct s_PXENV_TFTP_OPEN PXENV_TFTP_OPEN_t; + +/** @} */ /* pxenv_tftp_open */ + +/** @defgroup pxenv_tftp_close PXENV_TFTP_CLOSE + * + *  TFTP CLOSE + * + *  @{ + */ + +/** PXE API function code for pxenv_tftp_close() */ +#define	PXENV_TFTP_CLOSE		0x0021 + +/** Parameter block for pxenv_tftp_close() */ +struct s_PXENV_TFTP_CLOSE { +	PXENV_STATUS_t Status;			/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_TFTP_CLOSE PXENV_TFTP_CLOSE_t; + +/** @} */ /* pxenv_tftp_close */ + +/** @defgroup pxenv_tftp_read PXENV_TFTP_READ + * + *  TFTP READ + * + *  @{ + */ + +/** PXE API function code for pxenv_tftp_read() */ +#define	PXENV_TFTP_READ			0x0022 + +/** Parameter block for pxenv_tftp_read() */ +struct s_PXENV_TFTP_READ { +	PXENV_STATUS_t Status;			/**< PXE status code */ +	UINT16_t PacketNumber;			/**< TFTP packet number */ +	UINT16_t BufferSize;			/**< Size of data buffer */ +	SEGOFF16_t Buffer;			/**< Address of data buffer */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_TFTP_READ PXENV_TFTP_READ_t; + +/** @} */ /* pxenv_tftp_read */ + +/** @defgroup pxenv_tftp_read_file PXENV_TFTP_READ_FILE + * + *  TFTP/MTFTP READ FILE + * + *  @{ + */ + +/** PXE API function code for pxenv_tftp_read_file() */ +#define	PXENV_TFTP_READ_FILE		0x0023 + +/** Parameter block for pxenv_tftp_read_file() */ +struct s_PXENV_TFTP_READ_FILE { +	PXENV_STATUS_t Status;			/**< PXE status code */ +	UINT8_t FileName[128];			/**< File name */ +	UINT32_t BufferSize;			/**< Size of data buffer */ +	ADDR32_t Buffer;			/**< Address of data buffer */ +	IP4_t ServerIPAddress;			/**< TFTP server IP address */ +	IP4_t GatewayIPAddress;			/**< Relay agent IP address */ +	/** File multicast IP address */ +	IP4_t McastIPAddress; +	/** Client multicast listening port */ +	UDP_PORT_t TFTPClntPort; +	/** Server multicast listening port */ +	UDP_PORT_t TFTPSrvPort; +	/** TFTP open timeout. +	 * +	 * This is the timeout for receiving the first DATA or ACK +	 * packets during the MTFTP Listen phase. +	 */ +	UINT16_t TFTPOpenTimeOut; +	/** TFTP reopen timeout. +	 * +	 * This is the timeout for receiving an ACK packet while in +	 * the MTFTP Listen phase (when at least one ACK packet has +	 * already been seen). +	 */ +	UINT16_t TFTPReopenDelay; +} __attribute__ (( packed )); + +typedef struct s_PXENV_TFTP_READ_FILE PXENV_TFTP_READ_FILE_t; + +/** @} */ /* pxenv_tftp_read_file */ + +/** @defgroup pxenv_tftp_get_fsize PXENV_TFTP_GET_FSIZE + * + *  TFTP GET FILE SIZE + * + *  @{ + */ + +/** PXE API function code for pxenv_tftp_get_fsize() */ +#define	PXENV_TFTP_GET_FSIZE		0x0025 + +/** Parameter block for pxenv_tftp_get_fsize() */ +struct s_PXENV_TFTP_GET_FSIZE { +	PXENV_STATUS_t Status;			/**< PXE status code */ +	IP4_t ServerIPAddress;			/**< TFTP server IP address */ +	IP4_t GatewayIPAddress;			/**< Relay agent IP address */ +	UINT8_t FileName[128];			/**< File name */ +	UINT32_t FileSize;			/**< Size of the file */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_TFTP_GET_FSIZE PXENV_TFTP_GET_FSIZE_t; + +/** @} */ /* pxenv_tftp_get_fsize */ + +/** @} */ /* pxe_tftp_api */ + +/** @defgroup pxe_udp_api PXE UDP API + * + * Transmit and receive UDP packets + * + * @{ + */ + +/** @defgroup pxenv_udp_open PXENV_UDP_OPEN + * + *  UDP OPEN + * + *  @{ + */ + +/** PXE API function code for pxenv_udp_open() */ +#define	PXENV_UDP_OPEN			0x0030 + +/** Parameter block for pxenv_udp_open() */ +struct s_PXENV_UDP_OPEN { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	IP4_t		src_ip;		/**< IP address of this station */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UDP_OPEN PXENV_UDP_OPEN_t; + +/** @} */ /* pxenv_udp_open */ + +/** @defgroup pxenv_udp_close PXENV_UDP_CLOSE + * + *  UDP CLOSE + * + *  @{ + */ + +/** PXE API function code for pxenv_udp_close() */ +#define	PXENV_UDP_CLOSE			0x0031 + +/** Parameter block for pxenv_udp_close() */ +struct s_PXENV_UDP_CLOSE { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UDP_CLOSE PXENV_UDP_CLOSE_t; + +/** @} */ /* pxenv_udp_close */ + +/** @defgroup pxenv_udp_write PXENV_UDP_WRITE + * + *  UDP WRITE + * + *  @{ + */ + +/** PXE API function code for pxenv_udp_write() */ +#define	PXENV_UDP_WRITE			0x0033 + +/** Parameter block for pxenv_udp_write() */ +struct s_PXENV_UDP_WRITE { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	IP4_t		ip;		/**< Destination IP address */ +	IP4_t		gw;		/**< Relay agent IP address */ +	UDP_PORT_t	src_port;	/**< Source UDP port */ +	UDP_PORT_t	dst_port;	/**< Destination UDP port */ +	UINT16_t	buffer_size;	/**< UDP payload buffer size */ +	SEGOFF16_t	buffer;		/**< UDP payload buffer address */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UDP_WRITE PXENV_UDP_WRITE_t; + +/** @} */ /* pxenv_udp_write */ + +/** @defgroup pxenv_udp_read PXENV_UDP_READ + * + *  UDP READ + * + *  @{ + */ + +/** PXE API function code for pxenv_udp_read() */ +#define	PXENV_UDP_READ			0x0032 + +/** Parameter block for pxenv_udp_read() */ +struct s_PXENV_UDP_READ { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	IP4_t		src_ip;		/**< Source IP address */ +	IP4_t		dest_ip;	/**< Destination IP address */ +	UDP_PORT_t	s_port;		/**< Source UDP port */ +	UDP_PORT_t	d_port;		/**< Destination UDP port */ +	UINT16_t	buffer_size;	/**< UDP payload buffer size */ +	SEGOFF16_t	buffer;		/**< UDP payload buffer address */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UDP_READ PXENV_UDP_READ_t; + +/** @} */ /* pxenv_udp_read */ + +/** @} */ /* pxe_udp_api */ + +/** @defgroup pxe_undi_api PXE UNDI API + * + * Direct control of the network interface card + * + * @{ + */ + +/** @defgroup pxenv_undi_startup PXENV_UNDI_STARTUP + * + *  UNDI STARTUP + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_startup() */ +#define	PXENV_UNDI_STARTUP		0x0001 + +#define PXENV_BUS_ISA		0	/**< ISA bus type */ +#define PXENV_BUS_EISA		1	/**< EISA bus type */ +#define PXENV_BUS_MCA		2	/**< MCA bus type */ +#define PXENV_BUS_PCI		3	/**< PCI bus type */ +#define PXENV_BUS_VESA		4	/**< VESA bus type */ +#define PXENV_BUS_PCMCIA	5	/**< PCMCIA bus type */ + +/** Parameter block for pxenv_undi_startup() */ +struct s_PXENV_UNDI_STARTUP { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_STARTUP PXENV_UNDI_STARTUP_t; + +/** @} */ /* pxenv_undi_startup */ + +/** @defgroup pxenv_undi_cleanup PXENV_UNDI_CLEANUP + * + *  UNDI CLEANUP + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_cleanup() */ +#define	PXENV_UNDI_CLEANUP		0x0002 + +/** Parameter block for pxenv_undi_cleanup() */ +struct s_PXENV_UNDI_CLEANUP { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_CLEANUP PXENV_UNDI_CLEANUP_t; + +/** @} */ /* pxenv_undi_cleanup */ + +/** @defgroup pxenv_undi_initialize PXENV_UNDI_INITIALIZE + * + *  UNDI INITIALIZE + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_initialize() */ +#define	PXENV_UNDI_INITIALIZE		0x0003 + +/** Parameter block for pxenv_undi_initialize() */ +struct s_PXENV_UNDI_INITIALIZE { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** NDIS 2.0 configuration information, or NULL +	 * +	 * This is a pointer to the data structure returned by the +	 * NDIS 2.0 GetProtocolManagerInfo() API call.  The data +	 * structure is documented, in a rather haphazard way, in +	 * section 4-17 of the NDIS 2.0 specification. +	 */ +	ADDR32_t ProtocolIni; +	UINT8_t reserved[8];		/**< Must be zero */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_INITIALIZE PXENV_UNDI_INITIALIZE_t; + +/** @} */ /* pxenv_undi_initialize */ + +/** @defgroup pxenv_undi_reset_adapter PXENV_UNDI_RESET_ADAPTER + * + *  UNDI RESET ADAPTER + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_reset_adapter() */ +#define	PXENV_UNDI_RESET_ADAPTER	0x0004 + +/** Maximum number of multicast MAC addresses */ +#define MAXNUM_MCADDR	8 + +/** List of multicast MAC addresses */ +struct s_PXENV_UNDI_MCAST_ADDRESS { +	/** Number of multicast MAC addresses */ +	UINT16_t MCastAddrCount; +	/** List of up to #MAXNUM_MCADDR multicast MAC addresses */ +	MAC_ADDR_t McastAddr[MAXNUM_MCADDR]; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_MCAST_ADDRESS PXENV_UNDI_MCAST_ADDRESS_t; + +/** Parameter block for pxenv_undi_reset_adapter() */ +struct s_PXENV_UNDI_RESET { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** Multicast MAC addresses */ +	struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_RESET PXENV_UNDI_RESET_t; + +/** @} */ /* pxenv_undi_reset_adapter */ + +/** @defgroup pxenv_undi_shutdown PXENV_UNDI_SHUTDOWN + * + *  UNDI SHUTDOWN + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_shutdown() */ +#define	PXENV_UNDI_SHUTDOWN		0x0005 + +/** Parameter block for pxenv_undi_shutdown() */ +struct s_PXENV_UNDI_SHUTDOWN { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_SHUTDOWN PXENV_UNDI_SHUTDOWN_t; + +/** @} */ /* pxenv_undi_shutdown */ + +/** @defgroup pxenv_undi_open PXENV_UNDI_OPEN + * + *  UNDI OPEN + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_open() */ +#define	PXENV_UNDI_OPEN			0x0006 + +/** Accept "directed" packets + * + * These are packets addresses to either this adapter's MAC address or + * to any of the configured multicast MAC addresses (see + * #s_PXENV_UNDI_MCAST_ADDRESS). + */ +#define FLTR_DIRECTED	0x0001 +/** Accept broadcast packets */ +#define FLTR_BRDCST	0x0002 +/** Accept all packets; listen in promiscuous mode */ +#define FLTR_PRMSCS	0x0004 +/** Accept source-routed packets */ +#define FLTR_SRC_RTG	0x0008 + +/** Parameter block for pxenv_undi_open() */ +struct s_PXENV_UNDI_OPEN { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** Open flags as defined in NDIS 2.0 +	 * +	 * This is the OpenOptions field as passed to the NDIS 2.0 +	 * OpenAdapter() API call.  It is defined to be "adapter +	 * specific", though 0 is guaranteed to be a valid value. +	 */ +	UINT16_t OpenFlag; +	/** Receive packet filter +	 * +	 * This is the bitwise-OR of any of the following flags: +	 * #FLTR_DIRECTED, #FLTR_BRDCST, #FLTR_PRMSCS and +	 * #FLTR_SRC_RTG. +	 */ +	UINT16_t PktFilter; +	/** Multicast MAC addresses */ +	struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_OPEN PXENV_UNDI_OPEN_t; + +/** @} */ /* pxenv_undi_open */ + +/** @defgroup pxenv_undi_close PXENV_UNDI_CLOSE + * + *  UNDI CLOSE + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_close() */ +#define	PXENV_UNDI_CLOSE		0x0007 + +/** Parameter block for pxenv_undi_close() */ +struct s_PXENV_UNDI_CLOSE { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_CLOSE PXENV_UNDI_CLOSE_t; + +/** @} */ /* pxenv_undi_close */ + +/** @defgroup pxenv_undi_transmit PXENV_UNDI_TRANSMIT + * + *  UNDI TRANSMIT PACKET + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_transmit() */ +#define	PXENV_UNDI_TRANSMIT		0x0008 + +#define P_UNKNOWN	0		/**< Media header already filled in */ +#define P_IP		1		/**< IP protocol */ +#define P_ARP		2		/**< ARP protocol */ +#define P_RARP		3		/**< RARP protocol */ +#define P_OTHER		4		/**< Other protocol */ + +#define XMT_DESTADDR	0x0000		/**< Unicast packet */ +#define XMT_BROADCAST	0x0001		/**< Broadcast packet */ + +/** Maximum number of data blocks in a transmit buffer descriptor */ +#define MAX_DATA_BLKS	8 + +/** A transmit buffer descriptor, as pointed to by s_PXENV_UNDI_TRANSMIT::TBD + */ +struct s_PXENV_UNDI_TBD { +	UINT16_t ImmedLength;		/**< Length of the transmit buffer */ +	SEGOFF16_t Xmit;		/**< Address of the transmit buffer */ +	UINT16_t DataBlkCount; +	/** Array of up to #MAX_DATA_BLKS additional transmit buffers */ +	struct DataBlk { +		/** Always 1 +		 * +		 * A value of 0 would indicate that #TDDataPtr were an +		 * #ADDR32_t rather than a #SEGOFF16_t.  The PXE +		 * specification version 2.1 explicitly states that +		 * this is not supported; #TDDataPtr will always be a +		 * #SEGOFF16_t. +		 */ +		UINT8_t TDPtrType; +		UINT8_t TDRsvdByte;	/**< Must be zero */ +		UINT16_t TDDataLen;	/**< Length of this transmit buffer */ +		SEGOFF16_t TDDataPtr;	/**< Address of this transmit buffer */ +	} DataBlock[MAX_DATA_BLKS]; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_TBD PXENV_UNDI_TBD_t; + +/** Parameter block for pxenv_undi_transmit() */ +struct s_PXENV_UNDI_TRANSMIT { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** Protocol +	 * +	 * Valid values are #P_UNKNOWN, #P_IP, #P_ARP or #P_RARP.  If +	 * the caller has already filled in the media header, this +	 * field must be set to #P_UNKNOWN. +	 */ +	UINT8_t Protocol; +	/** Unicast/broadcast flag +	 * +	 * Valid values are #XMT_DESTADDR or #XMT_BROADCAST. +	 */ +	UINT8_t XmitFlag; +	SEGOFF16_t DestAddr;		/**< Destination MAC address */ +	/** Address of the Transmit Buffer Descriptor +	 * +	 * This is a pointer to a struct s_PXENV_UNDI_TBD. +	 */ +	SEGOFF16_t TBD; +	UINT32_t Reserved[2];		/**< Must be zero */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_TRANSMIT PXENV_UNDI_TRANSMIT_t; + +/** @} */ /* pxenv_undi_transmit */ + +/** @defgroup pxenv_undi_set_mcast_address PXENV_UNDI_SET_MCAST_ADDRESS + * + *  UNDI SET MULTICAST ADDRESS + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_set_mcast_address() */ +#define	PXENV_UNDI_SET_MCAST_ADDRESS	0x0009 + +/** Parameter block for pxenv_undi_set_mcast_address() */ +struct s_PXENV_UNDI_SET_MCAST_ADDRESS { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** List of multicast addresses */ +	struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS PXENV_UNDI_SET_MCAST_ADDRESS_t; + +/** @} */ /* pxenv_undi_set_mcast_address */ + +/** @defgroup pxenv_undi_set_station_address PXENV_UNDI_SET_STATION_ADDRESS + * + *  UNDI SET STATION ADDRESS + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_set_station_address() */ +#define	PXENV_UNDI_SET_STATION_ADDRESS	0x000a + +/** Parameter block for pxenv_undi_set_station_address() */ +struct s_PXENV_UNDI_SET_STATION_ADDRESS { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	MAC_ADDR_t StationAddress;	/**< Station MAC address */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS PXENV_UNDI_SET_STATION_ADDRESS_t; + +/** @} */ /* pxenv_undi_set_station_address */ + +/** @defgroup pxenv_undi_set_packet_filter PXENV_UNDI_SET_PACKET_FILTER + * + *  UNDI SET PACKET FILTER + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_set_packet_filter() */ +#define	PXENV_UNDI_SET_PACKET_FILTER	0x000b + +/** Parameter block for pxenv_undi_set_packet_filter() */ +struct s_PXENV_UNDI_SET_PACKET_FILTER { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** Receive packet filter +	 * +	 * This field takes the same values as +	 * s_PXENV_UNDI_OPEN::PktFilter. +	 * +	 * @note Yes, this field is a different size to +	 * s_PXENV_UNDI_OPEN::PktFilter.  Blame "the managers at Intel +	 * who apparently let a consultant come up with the spec +	 * without any kind of adult supervision" (quote from hpa). +	 */ +	UINT8_t filter; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_SET_PACKET_FILTER PXENV_UNDI_SET_PACKET_FILTER_t; + +/** @} */ /* pxenv_undi_set_packet_filter */ + +/** @defgroup pxenv_undi_get_information PXENV_UNDI_GET_INFORMATION + * + *  UNDI GET INFORMATION + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_get_information() */ +#define	PXENV_UNDI_GET_INFORMATION	0x000c + +#define ETHER_TYPE		1	/**< Ethernet (10Mb) */ +#define EXP_ETHER_TYPE		2	/**< Experimental Ethernet (3Mb) */ +#define AX25_TYPE		3	/**< Amateur Radio AX.25 */ +#define TOKEN_RING_TYPE		4	/**< Proteon ProNET Token Ring */ +#define CHAOS_TYPE		5	/**< Chaos */ +#define IEEE_TYPE		6	/**< IEEE 802 Networks */ +#define ARCNET_TYPE		7	/**< ARCNET */ + +/** Parameter block for pxenv_undi_get_information() */ +struct s_PXENV_UNDI_GET_INFORMATION { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	UINT16_t BaseIo;		/**< I/O base address */ +	UINT16_t IntNumber;		/**< IRQ number */ +	UINT16_t MaxTranUnit;		/**< Adapter MTU */ +	/** Hardware type +	 * +	 * Valid values are defined in RFC1010 ("Assigned numbers"), +	 * and are #ETHER_TYPE, #EXP_ETHER_TYPE, #AX25_TYPE, +	 * #TOKEN_RING_TYPE, #CHAOS_TYPE, #IEEE_TYPE or #ARCNET_TYPE. +	 */ +	UINT16_t HwType; +	UINT16_t HwAddrLen;		/**< MAC address length */ +	MAC_ADDR_t CurrentNodeAddress;	/**< Current MAC address */ +	MAC_ADDR_t PermNodeAddress;	/**< Permanent (EEPROM) MAC address */ +	SEGSEL_t ROMAddress;		/**< Real-mode ROM segment address */ +	UINT16_t RxBufCt;		/**< Receive queue length */ +	UINT16_t TxBufCt;		/**< Transmit queue length */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_GET_INFORMATION PXENV_UNDI_GET_INFORMATION_t; + +/** @} */ /* pxenv_undi_get_information */ + +/** @defgroup pxenv_undi_get_statistics PXENV_UNDI_GET_STATISTICS + * + *  UNDI GET STATISTICS + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_get_statistics() */ +#define	PXENV_UNDI_GET_STATISTICS	0x000d + +/** Parameter block for pxenv_undi_get_statistics() */ +struct s_PXENV_UNDI_GET_STATISTICS { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	UINT32_t XmtGoodFrames;		/**< Successful transmission count */ +	UINT32_t RcvGoodFrames;		/**< Successful reception count */ +	UINT32_t RcvCRCErrors;		/**< Receive CRC error count */ +	UINT32_t RcvResourceErrors;	/**< Receive queue overflow count */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_GET_STATISTICS PXENV_UNDI_GET_STATISTICS_t; + +/** @} */ /* pxenv_undi_get_statistics */ + +/** @defgroup pxenv_undi_clear_statistics PXENV_UNDI_CLEAR_STATISTICS + * + *  UNDI CLEAR STATISTICS + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_clear_statistics() */ +#define	PXENV_UNDI_CLEAR_STATISTICS	0x000e + +/** Parameter block for pxenv_undi_clear_statistics() */ +struct s_PXENV_UNDI_CLEAR_STATISTICS { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_CLEAR_STATISTICS PXENV_UNDI_CLEAR_STATISTICS_t; + +/** @} */ /* pxenv_undi_clear_statistics */ + +/** @defgroup pxenv_undi_initiate_diags PXENV_UNDI_INITIATE_DIAGS + * + *  UNDI INITIATE DIAGS + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_initiate_diags() */ +#define	PXENV_UNDI_INITIATE_DIAGS	0x000f + +/** Parameter block for pxenv_undi_initiate_diags() */ +struct s_PXENV_UNDI_INITIATE_DIAGS { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_INITIATE_DIAGS PXENV_UNDI_INITIATE_DIAGS_t; + +/** @} */ /* pxenv_undi_initiate_diags */ + +/** @defgroup pxenv_undi_force_interrupt PXENV_UNDI_FORCE_INTERRUPT + * + *  UNDI FORCE INTERRUPT + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_force_interrupt() */ +#define	PXENV_UNDI_FORCE_INTERRUPT	0x0010 + +/** Parameter block for pxenv_undi_force_interrupt() */ +struct s_PXENV_UNDI_FORCE_INTERRUPT { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_FORCE_INTERRUPT PXENV_UNDI_FORCE_INTERRUPT_t; + +/** @} */ /* pxenv_undi_force_interrupt */ + +/** @defgroup pxenv_undi_get_mcast_address PXENV_UNDI_GET_MCAST_ADDRESS + * + *  UNDI GET MULTICAST ADDRESS + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_get_mcast_address() */ +#define	PXENV_UNDI_GET_MCAST_ADDRESS	0x0011 + +/** Parameter block for pxenv_undi_get_mcast_address() */ +struct s_PXENV_UNDI_GET_MCAST_ADDRESS { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	IP4_t InetAddr;			/**< Multicast IP address */ +	MAC_ADDR_t MediaAddr;		/**< Multicast MAC address */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS PXENV_UNDI_GET_MCAST_ADDRESS_t; + +/** @} */ /* pxenv_undi_get_mcast_address */ + +/** @defgroup pxenv_undi_get_nic_type PXENV_UNDI_GET_NIC_TYPE + * + *  UNDI GET NIC TYPE + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_get_nic_type() */ +#define	PXENV_UNDI_GET_NIC_TYPE		0x0012 + +#define PCI_NIC		2		/**< PCI network card */ +#define PnP_NIC		3		/**< ISAPnP network card */ +#define CardBus_NIC	4		/**< CardBus network card */ + +/** Information for a PCI or equivalent NIC */ +struct pci_nic_info { +	UINT16_t Vendor_ID;		/**< PCI vendor ID */ +	UINT16_t Dev_ID;		/**< PCI device ID */ +	UINT8_t Base_Class;		/**< PCI base class */ +	UINT8_t Sub_Class;		/**< PCI sub class */ +	UINT8_t Prog_Intf;		/**< PCI programming interface */ +	UINT8_t Rev;			/**< PCI revision */ +	UINT16_t BusDevFunc;		/**< PCI bus:dev:fn address */ +	UINT16_t SubVendor_ID;		/**< PCI subvendor ID */ +	UINT16_t SubDevice_ID;		/**< PCI subdevice ID */ +} __attribute__ (( packed )); +  +/** Information for an ISAPnP or equivalent NIC */ +struct pnp_nic_info { +	UINT32_t EISA_Dev_ID;		/**< EISA device ID */ +	UINT8_t Base_Class;		/**< Base class */ +	UINT8_t Sub_Class;		/**< Sub class */ +	UINT8_t Prog_Intf;		/**< Programming interface */ +	/** Card Select Number assigned to card */ +	UINT16_t CardSelNum; +} __attribute__ (( packed )); + +/** Parameter block for pxenv_undi_get_nic_type() */ +struct s_PXENV_UNDI_GET_NIC_TYPE { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** NIC type +	 * +	 * Valid values are #PCI_NIC, #PnP_NIC or #CardBus_NIC. +	 */ +	UINT8_t NicType; +	/** NIC information */ +	union nic_type_info { +		/** NIC information (if #NicType==#PCI_NIC) */ +		struct pci_nic_info pci; +		/** NIC information (if #NicType==#CardBus_NIC) */ +		struct pci_nic_info cardbus; +		/** NIC information (if #NicType==#PnP_NIC) */ +		struct pnp_nic_info pnp; +	} info; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_GET_NIC_TYPE PXENV_UNDI_GET_NIC_TYPE_t; + +/** @} */ /* pxenv_undi_get_nic_type */ + +/** @defgroup pxenv_undi_get_iface_info PXENV_UNDI_GET_IFACE_INFO + * + *  UNDI GET IFACE INFO + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_get_iface_info() */ +#define	PXENV_UNDI_GET_IFACE_INFO	0x0013 + +/** Broadcast supported */ +#define SUPPORTED_BROADCAST		0x0001 +/** Multicast supported */ +#define SUPPORTED_MULTICAST		0x0002 +/** Functional/group addressing supported */ +#define SUPPORTED_GROUP			0x0004 +/** Promiscuous mode supported */ +#define SUPPORTED_PROMISCUOUS		0x0008 +/** Software settable station address */ +#define SUPPORTED_SET_STATION_ADDRESS	0x0010 +/** InitiateDiagnostics supported */ +#define SUPPORTED_DIAGNOSTICS		0x0040 +/** Reset MAC supported */ +#define SUPPORTED_RESET			0x0400 +/** Open / Close Adapter supported */ +#define SUPPORTED_OPEN_CLOSE		0x0800 +/** Interrupt Request supported */ +#define SUPPORTED_IRQ			0x1000 + +/** Parameter block for pxenv_undi_get_iface_info() */ +struct s_PXENV_UNDI_GET_IFACE_INFO { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** Interface type +	 * +	 * This is defined in the NDIS 2.0 specification to be one of +	 * the strings "802.3", "802.4", "802.5", "802.6", "DIX", +	 * "DIX+802.3", "APPLETALK", "ARCNET", "FDDI", "SDLC", "BSC", +	 * "HDLC", or "ISDN". +	 * +	 * "Normal" Ethernet, for various historical reasons, is +	 * "DIX+802.3". +	 */ +	UINT8_t IfaceType[16]; +	UINT32_t LinkSpeed;		/**< Link speed, in bits per second */ +	/** Service flags +	 * +	 * These are the "service flags" defined in the "MAC +	 * Service-Specific Characteristics" table in the NDIS 2.0 +	 * specification.  Almost all of them are irrelevant to PXE. +	 */ +	UINT32_t ServiceFlags; +	UINT32_t Reserved[4];		/**< Must be zero */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_GET_IFACE_INFO PXENV_UNDI_GET_IFACE_INFO_t; + +/** @} */ /* pxenv_undi_get_iface_info */ + +/** @defgroup pxenv_undi_get_state PXENV_UNDI_GET_STATE + * + *  UNDI GET STATE + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_get_state() */ +#define PXENV_UNDI_GET_STATE		0x0015 + +/** pxenv_start_undi() has been called */ +#define PXE_UNDI_GET_STATE_STARTED	1 +/** pxenv_undi_initialize() has been called */ +#define PXE_UNDI_GET_STATE_INITIALIZED	2 +/** pxenv_undi_open() has been called */ +#define PXE_UNDI_GET_STATE_OPENED	3 + +/** Parameter block for pxenv_undi_get_state() */ +struct s_PXENV_UNDI_GET_STATE { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** Current state of the UNDI driver +	 * +	 * Valid values are #PXE_UNDI_GET_STATE_STARTED, +	 * #PXE_UNDI_GET_STATE_INITIALIZED or +	 * #PXE_UNDI_GET_STATE_OPENED. +	 */ +	UINT8_t UNDIstate; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_GET_STATE PXENV_UNDI_GET_STATE_t; + +/** @} */ /* pxenv_undi_get_state */ + +/** @defgroup pxenv_undi_isr PXENV_UNDI_ISR + * + *  UNDI ISR + * + *  @{ + */ + +/** PXE API function code for pxenv_undi_isr() */ +#define	PXENV_UNDI_ISR			0x0014 + +/** Determine whether or not this is our interrupt */ +#define PXENV_UNDI_ISR_IN_START		1 +/** Start processing interrupt */ +#define PXENV_UNDI_ISR_IN_PROCESS	2 +/** Continue processing interrupt */ +#define PXENV_UNDI_ISR_IN_GET_NEXT	3 +/** This interrupt was ours */ +#define PXENV_UNDI_ISR_OUT_OURS		0 +/** This interrupt was not ours */ +#define PXENV_UNDI_ISR_OUT_NOT_OURS	1 +/** Finished processing interrupt */ +#define PXENV_UNDI_ISR_OUT_DONE		0 +/** A packet transmission has completed */ +#define PXENV_UNDI_ISR_OUT_TRANSMIT	2 +/** A packet has been received */ +#define PXENV_UNDI_ISR_OUT_RECEIVE	3 +/** We are already in the middle of processing an interrupt */ +#define PXENV_UNDI_ISR_OUT_BUSY		4 + +/** Unicast packet (or packet captured in promiscuous mode) */ +#define P_DIRECTED	0 +/** Broadcast packet */ +#define P_BROADCAST	1 +/** Multicast packet */ +#define P_MULTICAST	2 + +/** Parameter block for pxenv_undi_isr() */ +struct s_PXENV_UNDI_ISR { +	PXENV_STATUS_t	Status;		/**< PXE status code */ +	/** Function flag +	 * +	 * Valid values are #PXENV_UNDI_ISR_IN_START, +	 * #PXENV_UNDI_ISR_IN_PROCESS, #PXENV_UNDI_ISR_IN_GET_NEXT, +	 * #PXENV_UNDI_ISR_OUT_OURS, #PXENV_UNDI_ISR_OUT_NOT_OURS, +	 * #PXENV_UNDI_ISR_OUT_DONE, #PXENV_UNDI_ISR_OUT_TRANSMIT, +	 * #PXENV_UNDI_ISR_OUT_RECEIVE or #PXENV_UNDI_ISR_OUT_BUSY. +	 */ +	UINT16_t FuncFlag; +	UINT16_t BufferLength;		/**< Data buffer length */ +	UINT16_t FrameLength;		/**< Total frame length */ +	UINT16_t FrameHeaderLength;	/**< Frame header length */ +	SEGOFF16_t Frame;		/**< Data buffer address */ +	/** Protocol type +	 * +	 * Valid values are #P_IP, #P_ARP, #P_RARP or #P_OTHER. +	 */ +	UINT8_t ProtType; +	/** Packet type +	 * +	 * Valid values are #P_DIRECTED, #P_BROADCAST or #P_MULTICAST. +	 */ +	UINT8_t PktType; +} __attribute__ (( packed )); + +typedef struct s_PXENV_UNDI_ISR PXENV_UNDI_ISR_t; + +/** @} */ /* pxenv_undi_isr */ + +/** @} */ /* pxe_undi_api */ + +/** @defgroup pxe_file_api PXE FILE API + * + * POSIX-like file operations + * + * @{ + */ + +/** Minimum possible opcode used within PXE FILE API */ +#define PXENV_FILE_MIN 0x00e0 + +/** Minimum possible opcode used within PXE FILE API */ +#define PXENV_FILE_MAX 0x00ef + +/** @defgroup pxenv_file_open PXENV_FILE_OPEN + * + * FILE OPEN + * + * @{ + */ + +/** PXE API function code for pxenv_file_open() */ +#define PXENV_FILE_OPEN			0x00e0 + +/** Parameter block for pxenv_file_open() */ +struct s_PXENV_FILE_OPEN { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	UINT16_t FileHandle;		/**< File handle */ +	SEGOFF16_t FileName;		/**< File URL */ +	UINT32_t Reserved;		/**< Reserved */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_OPEN PXENV_FILE_OPEN_t; + +/** @} */ /* pxenv_file_open */ + +/** @defgroup pxenv_file_close PXENV_FILE_CLOSE + * + * FILE CLOSE + * + * @{ + */ + +/** PXE API function code for pxenv_file_close() */ +#define PXENV_FILE_CLOSE		0x00e1 + +/** Parameter block for pxenv_file_close() */ +struct s_PXENV_FILE_CLOSE { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	UINT16_t FileHandle;		/**< File handle */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_CLOSE PXENV_FILE_CLOSE_t; + +/** @} */ /* pxenv_file_close */ + +/** @defgroup pxenv_file_select PXENV_FILE_SELECT + * + * FILE SELECT + * + * @{ + */ + +/** PXE API function code for pxenv_file_select() */ +#define PXENV_FILE_SELECT		0x00e2 + +/** File is ready for reading */ +#define RDY_READ			0x0001 + +/** Parameter block for pxenv_file_select() */ +struct s_PXENV_FILE_SELECT { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	UINT16_t FileHandle;		/**< File handle */ +	UINT16_t Ready;			/**< Indication of readiness */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_SELECT PXENV_FILE_SELECT_t; + +/** @} */ /* pxenv_file_select */ + +/** @defgroup pxenv_file_read PXENV_FILE_READ + * + * FILE READ + * + * @{ + */ + +/** PXE API function code for pxenv_file_read() */ +#define PXENV_FILE_READ		0x00e3 + +/** Parameter block for pxenv_file_read() */ +struct s_PXENV_FILE_READ { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	UINT16_t FileHandle;		/**< File handle */ +	UINT16_t BufferSize;		/**< Data buffer size */ +	SEGOFF16_t Buffer;		/**< Data buffer */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_READ PXENV_FILE_READ_t; + +/** @} */ /* pxenv_file_read */ + +/** @defgroup pxenv_get_file_size PXENV_GET_FILE_SIZE + * + * GET FILE SIZE + * + * @{ + */ + +/** PXE API function code for pxenv_get_file_size() */ +#define PXENV_GET_FILE_SIZE		0x00e4 + +/** Parameter block for pxenv_get_file_size() */ +struct s_PXENV_GET_FILE_SIZE { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	UINT16_t FileHandle;		/**< File handle */ +	UINT32_t FileSize;		/**< File size */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_GET_FILE_SIZE PXENV_GET_FILE_SIZE_t; + +/** @} */ /* pxenv_get_file_size */ + +/** @defgroup pxenv_file_exec PXENV_FILE_EXEC + * + * FILE EXEC + * + * @{ + */ + +/** PXE API function code for pxenv_file_exec() */ +#define PXENV_FILE_EXEC			0x00e5 + +/** Parameter block for pxenv_file_exec() */ +struct s_PXENV_FILE_EXEC { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	SEGOFF16_t Command;		/**< Command to execute */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t; + +/** @} */ /* pxenv_file_exec */ + +/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK + * + * FILE API CHECK + * + * @{ + */ + +/** PXE API function code for pxenv_file_api_check() */ +#define PXENV_FILE_API_CHECK		0x00e6 + +/** Parameter block for pxenv_file_api_check() */ +struct s_PXENV_FILE_API_CHECK { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	UINT16_t Size;			/**< Size of structure  */ +	UINT32_t Magic;			/**< Magic number */ +	UINT32_t Provider;		/**< Implementation identifier */ +	UINT32_t APIMask;		/**< Supported API functions */ +	UINT32_t Flags;			/**< Reserved for the future */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t; + +/** @} */ /* pxenv_file_api_check */ + +/** @defgroup pxenv_file_exit_hook PXENV_FILE_EXIT_HOOK + * + * FILE EXIT HOOK + * + * @{ + */ + +/** PXE API function code for pxenv_file_exit_hook() */ +#define PXENV_FILE_EXIT_HOOK			0x00e7 + +/** Parameter block for pxenv_file_exit_hook() */ +struct s_PXENV_FILE_EXIT_HOOK { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	SEGOFF16_t Hook;		/**< SEG16:OFF16 to jump to */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_EXIT_HOOK PXENV_FILE_EXIT_HOOK_t; + +/** @} */ /* pxenv_file_exit_hook */ + +/** @defgroup pxenv_file_cmdline PXENV_FILE_CMDLINE + * + * FILE CMDLINE + * + * @{ + */ + +/** PXE API function code for pxenv_file_cmdline() */ +#define PXENV_FILE_CMDLINE			0x00e8 + +/** Parameter block for pxenv_file_cmdline() */ +struct s_PXENV_FILE_CMDLINE { +	PXENV_STATUS_t Status;		/**< PXE status code */ +	UINT16_t BufferSize;		/**< Data buffer size */ +	SEGOFF16_t Buffer;		/**< Data buffer */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_CMDLINE PXENV_FILE_CMDLINE_t; + +/** @} */ /* pxe_file_cmdline */ + +/** @} */ /* pxe_file_api */ + +/** @defgroup pxe_loader_api PXE Loader API + * + * The UNDI ROM loader API + * + * @{ + */ + +/** Parameter block for undi_loader() */ +struct s_UNDI_LOADER { +	/** PXE status code */ +	PXENV_STATUS_t Status; +	/** %ax register as for PXENV_START_UNDI */ +	UINT16_t AX; +	/** %bx register as for PXENV_START_UNDI */ +	UINT16_t BX; +	/** %dx register as for PXENV_START_UNDI */ +	UINT16_t DX; +	/** %di register as for PXENV_START_UNDI */ +	OFF16_t DI; +	/** %es register as for PXENV_START_UNDI */ +	SEGSEL_t ES; +	/** UNDI data segment +	 * +	 * @note The PXE specification defines the type of this field +	 * as #UINT16_t.  For x86, #SEGSEL_t and #UINT16_t are +	 * equivalent anyway; for other architectures #SEGSEL_t makes +	 * more sense. +	 */ +	SEGSEL_t UNDI_DS; +	/** UNDI code segment +	 * +	 * @note The PXE specification defines the type of this field +	 * as #UINT16_t.  For x86, #SEGSEL_t and #UINT16_t are +	 * equivalent anyway; for other architectures #SEGSEL_t makes +	 * more sense. +	 */ +	SEGSEL_t UNDI_CS; +	/** Address of the !PXE structure (a struct s_PXE) */ +	SEGOFF16_t PXEptr; +	/** Address of the PXENV+ structure (a struct s_PXENV) */ +	SEGOFF16_t PXENVptr; +} __attribute__ (( packed )); + +typedef struct s_UNDI_LOADER UNDI_LOADER_t; + +/** @} */ /* pxe_loader_api */ + +/** @} */ /* pxe */ + +/** @page pxe_notes Etherboot PXE implementation notes + +@section pxe_routing IP routing + +Several PXE API calls (e.g. pxenv_tftp_open() and pxenv_udp_write()) +allow for the caller to specify a "relay agent IP address", often in a +field called "gateway" or similar.  The PXE specification states that +"The IP layer should provide space for a minimum of four routing +entries obtained from the default router and static route DHCP option +tags in the DHCPACK message, plus any non-zero giaddr field from the +DHCPOFFER message(s) accepted by the client". + +The DHCP static route option ("option static-routes" in dhcpd.conf) +works only for classed IP routing (i.e. it provides no way to specify +a subnet mask).  Since virtually everything now uses classless IP +routing, the DHCP static route option is almost totally useless, and +is (according to the dhcp-options man page) not implemented by any of +the popular DHCP clients. + +This leaves the caller-specified "relay agent IP address", the giaddr +field from the DHCPOFFER message(s) and the default gateway(s) +provided via the routers option ("option routers" in dhcpd.conf) in +the DHCPACK message.  Each of these is a default gateway address. +It's a fair bet that the routers option should take priority over the +giaddr field, since the routers option has to be explicitly specified +by the DHCP server operator.  Similarly, it's fair to assume that the +caller-specified "relay agent IP address", if present, should take +priority over any other routing table entries. + +@bug Etherboot currently ignores all potential sources of routing +information other than the first router provided to it by a DHCP +routers option. + +@section pxe_x86_modes x86 processor mode restrictions + +On the x86 platform, different PXE API calls have different +restrictions on the processor modes (real or protected) that can be +used.  See the individual API call descriptions for the restrictions +that apply to any particular call. + +@subsection pxe_x86_pmode16 Real mode, or protected-mode with 16-bit stack + +The PXE specification states that the API function can be called in +protected mode only if the s_PXE::StatusCallout field is set to a +non-zero value, and that the API function cannot be called with a +32-bit stack segment. + +Etherboot does not enforce either of these restrictions; they seem (as +with so much of the PXE specification) to be artifacts of the Intel +implementation. + +*/ + +#endif /* PXE_API_H */ diff --git a/roms/ipxe/src/arch/i386/include/pxe_call.h b/roms/ipxe/src/arch/i386/include/pxe_call.h new file mode 100644 index 00000000..45af4654 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pxe_call.h @@ -0,0 +1,43 @@ +#ifndef _PXE_CALL_H +#define _PXE_CALL_H + +/** @file + * + * PXE API entry point + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <pxe_api.h> +#include <realmode.h> +#include <setjmp.h> + +struct net_device; + +/** PXE load address segment */ +#define PXE_LOAD_SEGMENT 0 + +/** PXE load address offset */ +#define PXE_LOAD_OFFSET 0x7c00 + +/** PXE physical load address */ +#define PXE_LOAD_PHYS ( ( PXE_LOAD_SEGMENT << 4 ) + PXE_LOAD_OFFSET ) + +/** !PXE structure */ +extern struct s_PXE __text16 ( ppxe ); +#define ppxe __use_text16 ( ppxe ) + +/** PXENV+ structure */ +extern struct s_PXENV __text16 ( pxenv ); +#define pxenv __use_text16 ( pxenv ) + +/** PXENV_RESTART_TFTP jump buffer */ +extern rmjmp_buf pxe_restart_nbp; + +extern void pxe_activate ( struct net_device *netdev ); +extern int pxe_deactivate ( void ); +extern int pxe_start_nbp ( void ); +extern __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ); +extern int pxe_api_call_weak ( struct i386_all_regs *ix86 ); + +#endif /* _PXE_CALL_H */ diff --git a/roms/ipxe/src/arch/i386/include/pxe_error.h b/roms/ipxe/src/arch/i386/include/pxe_error.h new file mode 100644 index 00000000..a1398cbd --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pxe_error.h @@ -0,0 +1,123 @@ +#ifndef PXE_ERROR_H +#define PXE_ERROR_H + +/** @file + * + * Preboot eXecution Environment (PXE) error definitions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * @defgroup pxeerrors PXE error codes + * + * @{ + */ + +/* Generic errors */ +#define	PXENV_STATUS_SUCCESS					       0x0000 +#define	PXENV_STATUS_FAILURE					       0x0001 +#define	PXENV_STATUS_BAD_FUNC					       0x0002 +#define	PXENV_STATUS_UNSUPPORTED				       0x0003 +#define	PXENV_STATUS_KEEP_UNDI					       0x0004 +#define	PXENV_STATUS_KEEP_ALL					       0x0005 +#define	PXENV_STATUS_OUT_OF_RESOURCES				       0x0006 + +/* ARP errors (0x0010 to 0x001f) */ +#define	PXENV_STATUS_ARP_TIMEOUT				       0x0011 + +/* Base-Code state errors */ +#define	PXENV_STATUS_UDP_CLOSED					       0x0018 +#define	PXENV_STATUS_UDP_OPEN					       0x0019 +#define	PXENV_STATUS_TFTP_CLOSED				       0x001a +#define	PXENV_STATUS_TFTP_OPEN					       0x001b + +/* BIOS/system errors (0x0020 to 0x002f) */ +#define	PXENV_STATUS_MCOPY_PROBLEM				       0x0020 +#define	PXENV_STATUS_BIS_INTEGRITY_FAILURE			       0x0021 +#define	PXENV_STATUS_BIS_VALIDATE_FAILURE			       0x0022 +#define	PXENV_STATUS_BIS_INIT_FAILURE				       0x0023 +#define	PXENV_STATUS_BIS_SHUTDOWN_FAILURE			       0x0024 +#define	PXENV_STATUS_BIS_GBOA_FAILURE				       0x0025 +#define	PXENV_STATUS_BIS_FREE_FAILURE				       0x0026 +#define	PXENV_STATUS_BIS_GSI_FAILURE				       0x0027 +#define	PXENV_STATUS_BIS_BAD_CKSUM				       0x0028 + +/* TFTP/MTFTP errors (0x0030 to 0x003f) */ +#define	PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS			       0x0030 +#define	PXENV_STATUS_TFTP_OPEN_TIMEOUT				       0x0032 +#define	PXENV_STATUS_TFTP_UNKNOWN_OPCODE			       0x0033 +#define	PXENV_STATUS_TFTP_READ_TIMEOUT				       0x0035 +#define	PXENV_STATUS_TFTP_ERROR_OPCODE				       0x0036 +#define	PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION		       0x0038 +#define	PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION		       0x0039 +#define	PXENV_STATUS_TFTP_TOO_MANY_PACKAGES			       0x003a +#define	PXENV_STATUS_TFTP_FILE_NOT_FOUND			       0x003b +#define	PXENV_STATUS_TFTP_ACCESS_VIOLATION			       0x003c +#define	PXENV_STATUS_TFTP_NO_MCAST_ADDRESS			       0x003d +#define	PXENV_STATUS_TFTP_NO_FILESIZE				       0x003e +#define	PXENV_STATUS_TFTP_INVALID_PACKET_SIZE			       0x003f + +/* Reserved errors 0x0040 to 0x004f) */ + +/* DHCP/BOOTP errors (0x0050 to 0x005f) */ +#define	PXENV_STATUS_DHCP_TIMEOUT				       0x0051 +#define	PXENV_STATUS_DHCP_NO_IP_ADDRESS				       0x0052 +#define	PXENV_STATUS_DHCP_NO_BOOTFILE_NAME			       0x0053 +#define	PXENV_STATUS_DHCP_BAD_IP_ADDRESS			       0x0054 + +/* Driver errors (0x0060 to 0x006f) */ +#define	PXENV_STATUS_UNDI_INVALID_FUNCTION			       0x0060 +#define	PXENV_STATUS_UNDI_MEDIATEST_FAILED			       0x0061 +#define	PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST		       0x0062 +#define	PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC			       0x0063 +#define	PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY			       0x0064 +#define	PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA		       0x0065 +#define	PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA			       0x0066 +#define	PXENV_STATUS_UNDI_BAD_MAC_ADDRESS			       0x0067 +#define	PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM			       0x0068 +#define	PXENV_STATUS_UNDI_ERROR_SETTING_ISR			       0x0069 +#define	PXENV_STATUS_UNDI_INVALID_STATE				       0x006a +#define	PXENV_STATUS_UNDI_TRANSMIT_ERROR			       0x006b +#define	PXENV_STATUS_UNDI_INVALID_PARAMETER			       0x006c + +/* ROM and NBP bootstrap errors (0x0070 to 0x007f) */ +#define	PXENV_STATUS_BSTRAP_PROMPT_MENU				       0x0074 +#define	PXENV_STATUS_BSTRAP_MCAST_ADDR				       0x0076 +#define	PXENV_STATUS_BSTRAP_MISSING_LIST			       0x0077 +#define	PXENV_STATUS_BSTRAP_NO_RESPONSE				       0x0078 +#define	PXENV_STATUS_BSTRAP_FILE_TOO_BIG			       0x0079 + +/* Environment NBP errors (0x0080 to 0x008f) */ + +/* Reserved errors (0x0090 to 0x009f) */ + +/* Miscellaneous errors (0x00a0 to 0x00af) */ +#define	PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE			       0x00a0 +#define	PXENV_STATUS_BINL_NO_PXE_SERVER				       0x00a1 +#define	PXENV_STATUS_NOT_AVAILABLE_IN_PMODE			       0x00a2 +#define	PXENV_STATUS_NOT_AVAILABLE_IN_RMODE			       0x00a3 + +/* BUSD errors (0x00b0 to 0x00bf) */ +#define	PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED			       0x00b0 + +/* Loader errors (0x00c0 to 0x00cf) */ +#define	PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY			       0x00c0 +#define	PXENV_STATUS_LOADER_NO_BC_ROMID				       0x00c1 +#define	PXENV_STATUS_LOADER_BAD_BC_ROMID			       0x00c2 +#define	PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE		       0x00c3 +#define	PXENV_STATUS_LOADER_NO_UNDI_ROMID			       0x00c4 +#define	PXENV_STATUS_LOADER_BAD_UNDI_ROMID			       0x00c5 +#define	PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE		       0x00c6 +#define	PXENV_STATUS_LOADER_NO_PXE_STRUCT			       0x00c8 +#define	PXENV_STATUS_LOADER_NO_PXENV_STRUCT			       0x00c9 +#define	PXENV_STATUS_LOADER_UNDI_START				       0x00ca +#define	PXENV_STATUS_LOADER_BC_START				       0x00cb + +/** @} */ + +/** Derive PXENV_STATUS code from iPXE error number */ +#define PXENV_STATUS( rc ) ( (-(rc)) & 0x00ff ) + +#endif /* PXE_ERROR_H */ diff --git a/roms/ipxe/src/arch/i386/include/pxe_types.h b/roms/ipxe/src/arch/i386/include/pxe_types.h new file mode 100644 index 00000000..db821459 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pxe_types.h @@ -0,0 +1,127 @@ +#ifndef PXE_TYPES_H +#define PXE_TYPES_H + +/** @file + * + * PXE data types + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <errno.h> /* PXE status codes */ + +/** @addtogroup pxe Preboot eXecution Environment (PXE) API + *  @{ + */ + +/** @defgroup pxe_types PXE data types + * + * Basic PXE data types such as #UINT16_t, #ADDR32_t, #SEGSEL_t etc. + * + * These definitions are based on Table 1-1 ("Data Type Definitions") + * in the Intel PXE specification version 2.1.  They have been + * generalised to non-x86 architectures where possible. + * + * @{ + */ + +/** An 8-bit unsigned integer */ +typedef uint8_t UINT8_t; + +/** A 16-bit unsigned integer */ +typedef uint16_t UINT16_t; + +/** A 32-bit unsigned integer */ +typedef uint32_t UINT32_t; + +/** A PXE exit code. + * + * Permitted values are #PXENV_EXIT_SUCCESS and #PXENV_EXIT_FAILURE. + * + */ +typedef UINT16_t PXENV_EXIT_t; +#define PXENV_EXIT_SUCCESS	0x0000	/**< No error occurred */ +#define PXENV_EXIT_FAILURE	0x0001	/**< An error occurred */ + +/** A PXE status code. + * + * Status codes are defined in errno.h. + * + */ +typedef UINT16_t PXENV_STATUS_t; + +/** An IPv4 address. + * + * @note This data type is in network (big-endian) byte order. + * + */ +typedef UINT32_t IP4_t; + +/** A UDP port. + * + * @note This data type is in network (big-endian) byte order. + * + */ +typedef UINT16_t UDP_PORT_t; + +/** Maximum length of a MAC address */ +#define MAC_ADDR_LEN 16 + +/** A MAC address */ +typedef UINT8_t MAC_ADDR_t[MAC_ADDR_LEN]; + +#ifndef HAVE_ARCH_ADDR32 +/** A physical address. + * + * For x86, this is a 32-bit physical address, and is therefore + * limited to the low 4GB. + * + */ +typedef UINT32_t ADDR32_t; +#endif + +#ifndef HAVE_ARCH_SEGSEL +/** A segment selector. + * + * For x86, this is a real mode segment (0x0000-0xffff), or a + * protected-mode segment selector, such as could be loaded into a + * segment register. + * + */ +typedef UINT16_t SEGSEL_t; +#endif + +#ifndef HAVE_ARCH_OFF16 +/** An offset within a segment identified by #SEGSEL + * + * For x86, this is a 16-bit offset. + * + */ +typedef UINT16_t OFF16_t; +#endif + +/** A segment:offset address + * + * For x86, this is a 16-bit real-mode or protected-mode + * segment:offset address. + * + */ +typedef struct s_SEGOFF16 { +	OFF16_t		offset;		/**< Offset within the segment */ +	SEGSEL_t	segment;	/**< Segment selector */ +} __attribute__ (( packed )) SEGOFF16_t; + +/** A segment descriptor */ +typedef struct s_SEGDESC { +	SEGSEL_t	segment_address;	/**< Segment selector */ +	ADDR32_t	Physical_address;	/**< Segment base address */ +	OFF16_t		Seg_size;		/**< Size of the segment */ +} __attribute__ (( packed )) SEGDESC_t; + +/** @} */ /* pxe_types */ + +/** @} */ /* pxe */ + +#endif /* PXE_TYPES_H */ diff --git a/roms/ipxe/src/arch/i386/include/pxeparent.h b/roms/ipxe/src/arch/i386/include/pxeparent.h new file mode 100644 index 00000000..b31e24a7 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/pxeparent.h @@ -0,0 +1,11 @@ +#ifndef PXEPARENT_H +#define PXEPARENT_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <pxe_types.h> + +extern int pxeparent_call ( SEGOFF16_t entry, unsigned int function, +			    void *params, size_t params_len ); + +#endif diff --git a/roms/ipxe/src/arch/i386/include/realmode.h b/roms/ipxe/src/arch/i386/include/realmode.h new file mode 100644 index 00000000..dafc5a32 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/realmode.h @@ -0,0 +1,127 @@ +#ifndef REALMODE_H +#define REALMODE_H + +#include <stdint.h> +#include <registers.h> +#include <ipxe/uaccess.h> + +/* + * Data structures and type definitions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/* + * Declaration of variables in .data16 + * + * To place a variable in the .data16 segment, declare it using the + * pattern: + * + *   int __data16 ( foo ); + *   #define foo __use_data16 ( foo ); + * + *   extern uint32_t __data16 ( bar ); + *   #define bar __use_data16 ( bar ); + * + *   static long __data16 ( baz ) = 0xff000000UL; + *   #define baz __use_data16 ( baz ); + * + * i.e. take a normal declaration, add __data16() around the variable + * name, and add a line saying "#define <name> __use_data16 ( <name> ) + * + * You can then access them just like any other variable, for example + * + *   int x = foo + bar; + * + * This magic is achieved at a cost of only around 7 extra bytes per + * group of accesses to .data16 variables.  When using KEEP_IT_REAL, + * there is no extra cost. + * + * You should place variables in .data16 when they need to be accessed + * by real-mode code.  Real-mode assembly (e.g. as created by + * REAL_CODE()) can access these variables via the usual data segment. + * You can therefore write something like + * + *   static uint16_t __data16 ( foo ); + *   #define foo __use_data16 ( foo ) + * + *   int bar ( void ) { + *     __asm__ __volatile__ ( REAL_CODE ( "int $0xff\n\t" + *                                        "movw %ax, foo" ) + *                            : : ); + *     return foo; + *   } + * + * Variables may also be placed in .text16 using __text16 and + * __use_text16.  Some variables (e.g. chained interrupt vectors) fit + * most naturally in .text16; most should be in .data16. + * + * If you have only a pointer to a magic symbol within .data16 or + * .text16, rather than the symbol itself, you can attempt to extract + * the underlying symbol name using __from_data16() or + * __from_text16().  This is not for the faint-hearted; check the + * assembler output to make sure that it's doing the right thing. + */ + +/** + * Copy data to base memory + * + * @v dest_seg		Destination segment + * @v dest_off		Destination offset + * @v src		Source + * @v len		Length + */ +static inline __always_inline void +copy_to_real ( unsigned int dest_seg, unsigned int dest_off, +	       void *src, size_t n ) { +	copy_to_user ( real_to_user ( dest_seg, dest_off ), 0, src, n ); +} + +/** + * Copy data to base memory + * + * @v dest		Destination + * @v src_seg		Source segment + * @v src_off		Source offset + * @v len		Length + */ +static inline __always_inline void +copy_from_real ( void *dest, unsigned int src_seg, +		 unsigned int src_off, size_t n ) { +	copy_from_user ( dest, real_to_user ( src_seg, src_off ), 0, n ); +} + +/** + * Write a single variable to base memory + * + * @v var		Variable to write + * @v dest_seg		Destination segment + * @v dest_off		Destination offset + */ +#define put_real( var, dest_seg, dest_off ) \ +	copy_to_real ( (dest_seg), (dest_off), &(var), sizeof (var) ) + +/** + * Read a single variable from base memory + * + * @v var		Variable to read + * @v src_seg		Source segment + * @v src_off		Source offset + */ +#define get_real( var, src_seg, src_off ) \ +	copy_from_real ( &(var), (src_seg), (src_off), sizeof (var) ) + +/* + * REAL_CODE ( asm_code_str ) + * + * This can be used in inline assembly to create a fragment of code + * that will execute in real mode.  For example: to write a character + * to the BIOS console using INT 10, you would do something like: + * + *     __asm__ __volatile__ ( REAL_CODE ( "int $0x16" ) + *			      : "=a" ( character ) : "a" ( 0x0000 ) ); + * + */ + +#endif /* REALMODE_H */ diff --git a/roms/ipxe/src/arch/i386/include/registers.h b/roms/ipxe/src/arch/i386/include/registers.h new file mode 100644 index 00000000..06d23652 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/registers.h @@ -0,0 +1,198 @@ +#ifndef REGISTERS_H +#define REGISTERS_H + +/** @file + * + * i386 registers. + * + * This file defines data structures that allow easy access to i386 + * register dumps. + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> + +/** + * A 16-bit general register. + * + * This type encapsulates a 16-bit register such as %ax, %bx, %cx, + * %dx, %si, %di, %bp or %sp. + * + */ +typedef union { +	struct { +		union { +			uint8_t l; +			uint8_t byte; +		}; +		uint8_t h; +	} __attribute__ (( packed )); +	uint16_t word; +} __attribute__ (( packed )) reg16_t; + +/** + * A 32-bit general register. + * + * This type encapsulates a 32-bit register such as %eax, %ebx, %ecx, + * %edx, %esi, %edi, %ebp or %esp. + * + */ +typedef union { +	struct { +		union { +			uint8_t l; +			uint8_t byte; +		}; +		uint8_t h; +	} __attribute__ (( packed )); +	uint16_t word; +	uint32_t dword; +} __attribute__ (( packed )) reg32_t; + +/** + * A 32-bit general register dump. + * + * This is the data structure that is created on the stack by the @c + * pushal instruction, and can be read back using the @c popal + * instruction. + * + */ +struct i386_regs { +	union { +		uint16_t di; +		uint32_t edi; +	}; +	union { +		uint16_t si; +		uint32_t esi; +	}; +	union { +		uint16_t bp; +		uint32_t ebp; +	}; +	union { +		uint16_t sp; +		uint32_t esp; +	}; +	union { +		struct { +			uint8_t bl; +			uint8_t bh; +		} __attribute__ (( packed )); +		uint16_t bx; +		uint32_t ebx; +	}; +	union { +		struct { +			uint8_t dl; +			uint8_t dh; +		} __attribute__ (( packed )); +		uint16_t dx; +		uint32_t edx; +	}; +	union { +		struct { +			uint8_t cl; +			uint8_t ch; +		} __attribute__ (( packed )); +		uint16_t cx; +		uint32_t ecx; +	}; +	union { +		struct { +			uint8_t al; +			uint8_t ah; +		} __attribute__ (( packed )); +		uint16_t ax; +		uint32_t eax; +	}; +} __attribute__ (( packed )); + +/** + * A segment register dump. + * + * The i386 has no equivalent of the @c pushal or @c popal + * instructions for the segment registers.  We adopt the convention of + * always using the sequences + * + * @code + * + *   pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs + * + * @endcode + * + * and + * + * @code + * + *   addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs + * + * @endcode + * + * This is the data structure that is created and read back by these + * instruction sequences. + * + */ +struct i386_seg_regs { +	uint16_t cs; +	uint16_t ss; +	uint16_t ds; +	uint16_t es; +	uint16_t fs; +	uint16_t gs; +} __attribute__ (( packed )); + +/** + * A full register dump. + * + * This data structure is created by the instructions + * + * @code + * + *   pushfl + *   pushal + *   pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs + * + * @endcode + * + * and can be read back using the instructions + * + * @code + * + *   addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs + *   popal + *   popfl + * + * @endcode + * + * prot_call() and kir_call() create this data structure on the stack + * and pass in a pointer to this structure. + * + */ +struct i386_all_regs { +	struct i386_seg_regs segs; +	struct i386_regs regs; +	uint32_t flags; +} __attribute__ (( packed )); + +/* Flags */ +#define CF ( 1 <<  0 ) +#define PF ( 1 <<  2 ) +#define AF ( 1 <<  4 ) +#define ZF ( 1 <<  6 ) +#define SF ( 1 <<  7 ) +#define OF ( 1 << 11 ) + +/* Segment:offset structure.  Note that the order within the structure + * is offset:segment. + */ +struct segoff { +	uint16_t offset; +	uint16_t segment; +} __attribute__ (( packed )); + +typedef struct segoff segoff_t; + +#endif /* REGISTERS_H */ diff --git a/roms/ipxe/src/arch/i386/include/rtc.h b/roms/ipxe/src/arch/i386/include/rtc.h new file mode 100644 index 00000000..2a6abbae --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/rtc.h @@ -0,0 +1,83 @@ +#ifndef _RTC_H +#define _RTC_H + +/** @file + * + * CMOS Real-Time Clock (RTC) + * + * The CMOS/RTC registers are documented (with varying degrees of + * accuracy and consistency) at + * + *    http://www.nondot.org/sabre/os/files/MiscHW/RealtimeClockFAQ.txt + *    http://wiki.osdev.org/RTC + *    http://wiki.osdev.org/CMOS + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <pic8259.h> + +/** RTC IRQ */ +#define RTC_IRQ 8 + +/** RTC interrupt vector */ +#define RTC_INT IRQ_INT ( RTC_IRQ ) + +/** CMOS/RTC address (and NMI) register */ +#define CMOS_ADDRESS 0x70 + +/** NMI disable bit */ +#define CMOS_DISABLE_NMI 0x80 + +/** CMOS/RTC data register */ +#define CMOS_DATA 0x71 + +/** RTC seconds */ +#define RTC_SEC 0x00 + +/** RTC minutes */ +#define RTC_MIN 0x02 + +/** RTC hours */ +#define RTC_HOUR 0x04 + +/** RTC weekday */ +#define RTC_WDAY 0x06 + +/** RTC day of month */ +#define RTC_MDAY 0x07 + +/** RTC month */ +#define RTC_MON 0x08 + +/** RTC year */ +#define RTC_YEAR 0x09 + +/** RTC status register A */ +#define RTC_STATUS_A 0x0a + +/** RTC update in progress bit */ +#define RTC_STATUS_A_UPDATE_IN_PROGRESS 0x80 + +/** RTC status register B */ +#define RTC_STATUS_B 0x0b + +/** RTC 24 hour format bit */ +#define RTC_STATUS_B_24_HOUR 0x02 + +/** RTC binary mode bit */ +#define RTC_STATUS_B_BINARY 0x04 + +/** RTC Periodic Interrupt Enabled bit */ +#define RTC_STATUS_B_PIE 0x40 + +/** RTC status register C */ +#define RTC_STATUS_C 0x0c + +/** RTC status register D */ +#define RTC_STATUS_D 0x0d + +/** CMOS default address */ +#define CMOS_DEFAULT_ADDRESS RTC_STATUS_D + +#endif /* _RTC_H */ diff --git a/roms/ipxe/src/arch/i386/include/sdi.h b/roms/ipxe/src/arch/i386/include/sdi.h new file mode 100644 index 00000000..fc486402 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/sdi.h @@ -0,0 +1,39 @@ +#ifndef _SDI_H +#define _SDI_H + +/** @file + * + * System Deployment Image (SDI) + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** SDI image header */ +struct sdi_header { +	/** Signature */ +	uint32_t magic; +	/** Version (as an ASCII string) */ +	uint32_t version; +	/** Reserved */ +	uint8_t reserved[8]; +	/** Boot code offset */ +	uint64_t boot_offset; +	/** Boot code size */ +	uint64_t boot_size; +} __attribute__ (( packed )); + +/** SDI image signature */ +#define SDI_MAGIC \ +	( ( '$' << 0 ) | ( 'S' << 8 ) | ( 'D' << 16 ) | ( 'I' << 24 ) ) + +/** SDI boot segment */ +#define SDI_BOOT_SEG 0x0000 + +/** SDI boot offset */ +#define SDI_BOOT_OFF 0x7c00 + +/** Constant to binary-OR with physical address of SDI image */ +#define SDI_WTF 0x41 + +#endif /* _SDI_H */ diff --git a/roms/ipxe/src/arch/i386/include/setjmp.h b/roms/ipxe/src/arch/i386/include/setjmp.h new file mode 100644 index 00000000..5d3c11b6 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/setjmp.h @@ -0,0 +1,40 @@ +#ifndef ETHERBOOT_SETJMP_H +#define ETHERBOOT_SETJMP_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <realmode.h> + +/** A jump buffer */ +typedef struct { +	uint32_t retaddr; +	uint32_t ebx; +	uint32_t esp; +	uint32_t ebp; +	uint32_t esi; +	uint32_t edi; +} jmp_buf[1]; + +/** A real-mode-extended jump buffer */ +typedef struct { +	jmp_buf env; +	uint16_t rm_ss; +	uint16_t rm_sp; +} rmjmp_buf[1]; + +extern int __asmcall setjmp ( jmp_buf env ); +extern void __asmcall longjmp ( jmp_buf env, int val ); + +#define rmsetjmp( _env ) ( {			\ +	(_env)->rm_ss = rm_ss;			\ +	(_env)->rm_sp = rm_sp;			\ +	setjmp ( (_env)->env ); } )		\ + +#define rmlongjmp( _env, _val ) do {		\ +	rm_ss = (_env)->rm_ss;			\ +	rm_sp = (_env)->rm_sp;			\ +	longjmp ( (_env)->env, (_val) );	\ +	} while ( 0 ) + +#endif /* ETHERBOOT_SETJMP_H */ diff --git a/roms/ipxe/src/arch/i386/include/undi.h b/roms/ipxe/src/arch/i386/include/undi.h new file mode 100644 index 00000000..325fcbbf --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/undi.h @@ -0,0 +1,106 @@ +#ifndef _UNDI_H +#define _UNDI_H + +/** @file + * + * UNDI driver + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#ifndef ASSEMBLY + +#include <ipxe/device.h> +#include <pxe_types.h> + +/** An UNDI device + * + * This structure is used by assembly code as well as C; do not alter + * this structure without editing pxeprefix.S to match. + */ +struct undi_device { +	/** PXENV+ structure address */ +	SEGOFF16_t pxenv; +	/** !PXE structure address */ +	SEGOFF16_t ppxe; +	/** Entry point */ +	SEGOFF16_t entry; +	/** Free base memory after load */ +	UINT16_t fbms; +	/** Free base memory prior to load */ +	UINT16_t restore_fbms; +	/** PCI bus:dev.fn, or @c UNDI_NO_PCI_BUSDEVFN */ +	UINT16_t pci_busdevfn; +	/** ISAPnP card select number, or @c UNDI_NO_ISAPNP_CSN */ +	UINT16_t isapnp_csn; +	/** ISAPnP read port, or @c UNDI_NO_ISAPNP_READ_PORT */ +	UINT16_t isapnp_read_port; +	/** PCI vendor ID +	 * +	 * Filled in only for the preloaded UNDI device by pxeprefix.S +	 */ +	UINT16_t pci_vendor; +	/** PCI device ID  +	 * +	 * Filled in only for the preloaded UNDI device by pxeprefix.S +	 */ +	UINT16_t pci_device; +	/** Flags +	 * +	 * This is the bitwise OR of zero or more UNDI_FL_XXX +	 * constants. +	 */ +	UINT16_t flags; + +	/** Generic device */ +	struct device dev; +	/** Driver-private data +	 * +	 * Use undi_set_drvdata() and undi_get_drvdata() to access this +	 * field. +	 */ +	void *priv; +} __attribute__ (( packed )); + +/** + * Set UNDI driver-private data + * + * @v undi		UNDI device + * @v priv		Private data + */ +static inline void undi_set_drvdata ( struct undi_device *undi, void *priv ) { +	undi->priv = priv; +} + +/** + * Get UNDI driver-private data + * + * @v undi		UNDI device + * @ret priv		Private data + */ +static inline void * undi_get_drvdata ( struct undi_device *undi ) { +	return undi->priv; +} + +#endif /* ASSEMBLY */ + +/** PCI bus:dev.fn field is invalid */ +#define UNDI_NO_PCI_BUSDEVFN 0xffff + +/** ISAPnP card select number field is invalid */ +#define UNDI_NO_ISAPNP_CSN 0xffff + +/** ISAPnP read port field is invalid */ +#define UNDI_NO_ISAPNP_READ_PORT 0xffff + +/** UNDI flag: START_UNDI has been called */ +#define UNDI_FL_STARTED 0x0001 + +/** UNDI flag: UNDI_STARTUP and UNDI_INITIALIZE have been called */ +#define UNDI_FL_INITIALIZED 0x0002 + +/** UNDI flag: keep stack resident */ +#define UNDI_FL_KEEP_ALL 0x0004 + +#endif /* _UNDI_H */ diff --git a/roms/ipxe/src/arch/i386/include/undiload.h b/roms/ipxe/src/arch/i386/include/undiload.h new file mode 100644 index 00000000..426830e8 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/undiload.h @@ -0,0 +1,35 @@ +#ifndef _UNDILOAD_H +#define _UNDILOAD_H + +/** @file + * + * UNDI load/unload + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +struct undi_device; +struct undi_rom; + +extern int undi_load ( struct undi_device *undi, struct undi_rom *undirom ); +extern int undi_unload ( struct undi_device *undi ); + +/** + * Call UNDI loader to create a pixie + * + * @v undi		UNDI device + * @v undirom		UNDI ROM + * @v pci_busdevfn	PCI bus:dev.fn + * @ret rc		Return status code + */ +static inline int undi_load_pci ( struct undi_device *undi, +				  struct undi_rom *undirom, +				  unsigned int pci_busdevfn ) { +	undi->pci_busdevfn = pci_busdevfn; +	undi->isapnp_csn = UNDI_NO_ISAPNP_CSN; +	undi->isapnp_read_port = UNDI_NO_ISAPNP_READ_PORT; +	return undi_load ( undi, undirom ); +} + +#endif /* _UNDILOAD_H */ diff --git a/roms/ipxe/src/arch/i386/include/undinet.h b/roms/ipxe/src/arch/i386/include/undinet.h new file mode 100644 index 00000000..c3c17c11 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/undinet.h @@ -0,0 +1,17 @@ +#ifndef _UNDINET_H +#define _UNDINET_H + +/** @file + * + * UNDI network device driver + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +struct undi_device; + +extern int undinet_probe ( struct undi_device *undi ); +extern void undinet_remove ( struct undi_device *undi ); + +#endif /* _UNDINET_H */ diff --git a/roms/ipxe/src/arch/i386/include/undipreload.h b/roms/ipxe/src/arch/i386/include/undipreload.h new file mode 100644 index 00000000..de9b8fb5 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/undipreload.h @@ -0,0 +1,18 @@ +#ifndef _UNDIPRELOAD_H +#define _UNDIPRELOAD_H + +/** @file + * + * Preloaded UNDI stack + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <realmode.h> +#include <undi.h> + +extern struct undi_device __data16 ( preloaded_undi ); +#define preloaded_undi __use_data16 ( preloaded_undi ) + +#endif /* _UNDIPRELOAD_H */ diff --git a/roms/ipxe/src/arch/i386/include/undirom.h b/roms/ipxe/src/arch/i386/include/undirom.h new file mode 100644 index 00000000..86d7077b --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/undirom.h @@ -0,0 +1,53 @@ +#ifndef _UNDIROM_H +#define _UNDIROM_H + +/** @file + * + * UNDI expansion ROMs + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <pxe_types.h> + +/** An UNDI PCI device ID */ +struct undi_pci_device_id { +	/** PCI vendor ID */ +	unsigned int vendor_id; +	/** PCI device ID */ +	unsigned int device_id; +}; + +/** An UNDI device ID */ +union undi_device_id { +	/** PCI device ID */ +	struct undi_pci_device_id pci; +}; + +/** An UNDI ROM */ +struct undi_rom { +	/** List of UNDI ROMs */ +	struct list_head list; +	/** ROM segment address */ +	unsigned int rom_segment; +	/** UNDI loader entry point */ +	SEGOFF16_t loader_entry; +	/** Code segment size */ +	size_t code_size; +	/** Data segment size */ +	size_t data_size; +	/** Bus type +	 * +	 * Values are as used by @c PXENV_UNDI_GET_NIC_TYPE +	 */ +	unsigned int bus_type; +	/** Device ID */ +	union undi_device_id bus_id; +}; + +extern struct undi_rom * undirom_find_pci ( unsigned int vendor_id, +					    unsigned int device_id, +					    unsigned int rombase ); + +#endif /* _UNDIROM_H */ diff --git a/roms/ipxe/src/arch/i386/include/vga.h b/roms/ipxe/src/arch/i386/include/vga.h new file mode 100644 index 00000000..01fc39d8 --- /dev/null +++ b/roms/ipxe/src/arch/i386/include/vga.h @@ -0,0 +1,228 @@ +/* + * + * modified + * by Steve M. Gehlbach <steve@kesa.com> + * + * Originally  from linux/drivers/video/vga16.c by + * Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz> + * Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz> + * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm + * Based on VESA framebuffer (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de> + * + */  + +#ifndef VGA_H_INCL +#define VGA_H_INCL 1 + +//#include <cpu/p5/io.h> + +#define u8 unsigned char +#define u16 unsigned short +#define u32 unsigned int +#define __u32 u32 + +#define VERROR -1 +#define CHAR_HEIGHT 16 +#define LINES 25 +#define COLS 80 + +// macros for writing to vga regs +#define write_crtc(data,addr) outb(addr,CRT_IC); outb(data,CRT_DC) +#define write_att(data,addr) inb(IS1_RC); inb(0x80); outb(addr,ATT_IW); inb(0x80); outb(data,ATT_IW); inb(0x80) +#define write_seq(data,addr) outb(addr,SEQ_I); outb(data,SEQ_D) +#define write_gra(data,addr) outb(addr,GRA_I); outb(data,GRA_D) +u8 read_seq_b(u16 addr); +u8 read_gra_b(u16 addr); +u8 read_crtc_b(u16 addr); +u8 read_att_b(u16 addr); + + +#ifdef VGA_HARDWARE_FIXUP +void vga_hardware_fixup(void); +#else +#define vga_hardware_fixup() do{} while(0) +#endif + +#define SYNC_HOR_HIGH_ACT    1       /* horizontal sync high active  */ +#define SYNC_VERT_HIGH_ACT   2       /* vertical sync high active    */ +#define SYNC_EXT             4       /* external sync                */ +#define SYNC_COMP_HIGH_ACT   8       /* composite sync high active   */ +#define SYNC_BROADCAST       16      /* broadcast video timings      */ +                                        /* vtotal = 144d/288n/576i => PAL  */ +                                        /* vtotal = 121d/242n/484i => NTSC */ + +#define SYNC_ON_GREEN        32      /* sync on green */ + +#define VMODE_NONINTERLACED  0       /* non interlaced */ +#define VMODE_INTERLACED     1       /* interlaced   */ +#define VMODE_DOUBLE         2       /* double scan */ +#define VMODE_MASK           255 + +#define VMODE_YWRAP          256     /* ywrap instead of panning     */ +#define VMODE_SMOOTH_XPAN    512     /* smooth xpan possible (internally used) */ +#define VMODE_CONUPDATE      512     /* don't update x/yoffset       */ + +/* VGA data register ports */ +#define CRT_DC  0x3D5           /* CRT Controller Data Register - color emulation */ +#define CRT_DM  0x3B5           /* CRT Controller Data Register - mono emulation */ +#define ATT_R   0x3C1           /* Attribute Controller Data Read Register */ +#define GRA_D   0x3CF           /* Graphics Controller Data Register */ +#define SEQ_D   0x3C5           /* Sequencer Data Register */ + +#define MIS_R   0x3CC           // Misc Output Read Register +#define MIS_W   0x3C2           // Misc Output Write Register + +#define IS1_RC  0x3DA           /* Input Status Register 1 - color emulation */ +#define IS1_RM  0x3BA           /* Input Status Register 1 - mono emulation */ +#define PEL_D   0x3C9           /* PEL Data Register */ +#define PEL_MSK 0x3C6           /* PEL mask register */ + +/* EGA-specific registers */ +#define GRA_E0  0x3CC           /* Graphics enable processor 0 */ +#define GRA_E1  0x3CA           /* Graphics enable processor 1 */ + + +/* VGA index register ports */ +#define CRT_IC  0x3D4           /* CRT Controller Index - color emulation */ +#define CRT_IM  0x3B4           /* CRT Controller Index - mono emulation */ +#define ATT_IW  0x3C0           /* Attribute Controller Index & Data Write Register */ +#define GRA_I   0x3CE           /* Graphics Controller Index */ +#define SEQ_I   0x3C4           /* Sequencer Index */ +#define PEL_IW  0x3C8           /* PEL Write Index */ +#define PEL_IR  0x3C7           /* PEL Read Index */ + +/* standard VGA indexes max counts */ +#define CRTC_C   25              /* 25 CRT Controller Registers sequentially set*/ +								 // the remainder are not in the par array +#define ATT_C   21              /* 21 Attribute Controller Registers */ +#define GRA_C   9               /* 9  Graphics Controller Registers */ +#define SEQ_C   5               /* 5  Sequencer Registers */ +#define MIS_C   1               /* 1  Misc Output Register */ + +#define CRTC_H_TOTAL            0 +#define CRTC_H_DISP             1 +#define CRTC_H_BLANK_START      2 +#define CRTC_H_BLANK_END        3 +#define CRTC_H_SYNC_START       4 +#define CRTC_H_SYNC_END         5 +#define CRTC_V_TOTAL            6 +#define CRTC_OVERFLOW           7 +#define CRTC_PRESET_ROW         8 +#define CRTC_MAX_SCAN           9 +#define CRTC_CURSOR_START       0x0A +#define CRTC_CURSOR_END         0x0B +#define CRTC_START_HI           0x0C +#define CRTC_START_LO           0x0D +#define CRTC_CURSOR_HI          0x0E +#define CRTC_CURSOR_LO          0x0F +#define CRTC_V_SYNC_START       0x10 +#define CRTC_V_SYNC_END         0x11 +#define CRTC_V_DISP_END         0x12 +#define CRTC_OFFSET             0x13 +#define CRTC_UNDERLINE          0x14 +#define CRTC_V_BLANK_START      0x15 +#define CRTC_V_BLANK_END        0x16 +#define CRTC_MODE               0x17 +#define CRTC_LINE_COMPARE       0x18 + +#define ATC_MODE                0x10 +#define ATC_OVERSCAN            0x11 +#define ATC_PLANE_ENABLE        0x12 +#define ATC_PEL                 0x13 +#define ATC_COLOR_PAGE          0x14 + +#define SEQ_CLOCK_MODE          0x01 +#define SEQ_PLANE_WRITE         0x02 +#define SEQ_CHARACTER_MAP       0x03 +#define SEQ_MEMORY_MODE         0x04 + +#define GDC_SR_VALUE            0x00 +#define GDC_SR_ENABLE           0x01 +#define GDC_COMPARE_VALUE       0x02 +#define GDC_DATA_ROTATE         0x03 +#define GDC_PLANE_READ          0x04 +#define GDC_MODE                0x05 +#define GDC_MISC                0x06 +#define GDC_COMPARE_MASK        0x07 +#define GDC_BIT_MASK            0x08 + +// text attributes +#define VGA_ATTR_CLR_RED 0x4 +#define VGA_ATTR_CLR_GRN 0x2 +#define VGA_ATTR_CLR_BLU 0x1 +#define VGA_ATTR_CLR_YEL (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN) +#define VGA_ATTR_CLR_CYN (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) +#define VGA_ATTR_CLR_MAG (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED) +#define VGA_ATTR_CLR_BLK 0 +#define VGA_ATTR_CLR_WHT (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) +#define VGA_ATTR_BNK     0x80 +#define VGA_ATTR_ITN     0x08 + +/* + * vga register parameters + * these are copied to the  + * registers. + * + */ +struct vga_par { +        u8 crtc[CRTC_C]; +        u8 atc[ATT_C]; +        u8 gdc[GRA_C]; +        u8 seq[SEQ_C]; +        u8 misc; // the misc register, MIS_W +        u8 vss; +}; + + +/* Interpretation of offset for color fields: All offsets are from the right, + * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you + * can use the offset as right argument to <<). A pixel afterwards is a bit + * stream and is written to video memory as that unmodified. This implies + * big-endian byte order if bits_per_pixel is greater than 8. + */ +struct fb_bitfield { +        __u32 offset;                   /* beginning of bitfield        */ +        __u32 length;                   /* length of bitfield           */ +        __u32 msb_right;                /* != 0 : Most significant bit is */  +                                        /* right */  +}; + +struct screeninfo { +        __u32 xres;                     /* visible resolution           */ +        __u32 yres; +        __u32 xres_virtual;             /* virtual resolution           */ +        __u32 yres_virtual; +        __u32 xoffset;                  /* offset from virtual to visible */ +        __u32 yoffset;                  /* resolution                   */ + +        __u32 bits_per_pixel;           /* guess what                   */ +        __u32 grayscale;                /* != 0 Graylevels instead of colors */ + +        struct fb_bitfield red;         /* bitfield in fb mem if true color, */ +        struct fb_bitfield green;       /* else only length is significant */ +        struct fb_bitfield blue; +        struct fb_bitfield transp;      /* transparency                 */       + +        __u32 nonstd;                   /* != 0 Non standard pixel format */ + +        __u32 activate;                 /* see FB_ACTIVATE_*            */ + +        __u32 height;                   /* height of picture in mm    */ +        __u32 width;                    /* width of picture in mm     */ + +        __u32 accel_flags;              /* acceleration flags (hints)   */ + +        /* Timing: All values in pixclocks, except pixclock (of course) */ +        __u32 pixclock;                 /* pixel clock in ps (pico seconds) */ +        __u32 left_margin;              /* time from sync to picture    */ +        __u32 right_margin;             /* time from picture to sync    */ +        __u32 upper_margin;             /* time from sync to picture    */ +        __u32 lower_margin; +        __u32 hsync_len;                /* length of horizontal sync    */ +        __u32 vsync_len;                /* length of vertical sync      */ +        __u32 sync;                     /* sync polarity                */ +        __u32 vmode;                    /* interlaced etc				*/ +        __u32 reserved[6];              /* Reserved for future compatibility */ +}; + +#endif | 
