diff options
Diffstat (limited to 'gpxe/src/include')
166 files changed, 17970 insertions, 0 deletions
diff --git a/gpxe/src/include/.gitignore b/gpxe/src/include/.gitignore new file mode 100644 index 00000000..de1598ef --- /dev/null +++ b/gpxe/src/include/.gitignore @@ -0,0 +1 @@ +.buildserial.h diff --git a/gpxe/src/include/alloca.h b/gpxe/src/include/alloca.h new file mode 100644 index 00000000..08398fb3 --- /dev/null +++ b/gpxe/src/include/alloca.h @@ -0,0 +1,25 @@ +#ifndef _ALLOCA_H +#define _ALLOCA_H + +/** + * @file + * + * Temporary memory allocation + * + */ + +#include <stdint.h> + +/** + * Allocate temporary memory from the stack + * + * @v size Size to allocate + * @ret ptr Allocated memory + * + * This memory will be freed automatically when the containing + * function returns. There are several caveats regarding use of + * alloca(); use it only if you already know what they are. + */ +#define alloca(size) __builtin_alloca ( size ) + +#endif /* _ALLOCA_H */ diff --git a/gpxe/src/include/assert.h b/gpxe/src/include/assert.h new file mode 100644 index 00000000..93750a1e --- /dev/null +++ b/gpxe/src/include/assert.h @@ -0,0 +1,65 @@ +#ifndef _ASSERT_H +#define _ASSERT_H + +/** @file + * + * Assertions + * + * This file provides two assertion macros: assert() (for run-time + * assertions) and linker_assert() (for link-time assertions). + * + */ + +#ifdef NDEBUG +#define ASSERTING 0 +#else +#define ASSERTING 1 +#endif + +/** printf() for assertions + * + * This function exists so that the assert() macro can expand to + * printf() calls without dragging the printf() prototype into scope. + * + * As far as the compiler is concerned, assert_printf() and printf() are + * completely unrelated calls; it's only at the assembly stage that + * references to the assert_printf symbol are collapsed into references + * to the printf symbol. + */ +extern int __attribute__ (( format ( printf, 1, 2 ) )) +assert_printf ( const char *fmt, ... ) asm ( "printf" ); + +/** + * Assert a condition at run-time. + * + * If the condition is not true, a debug message will be printed. + * Assertions only take effect in debug-enabled builds (see DBG()). + * + * @todo Make an assertion failure abort the program + * + */ +#define assert( condition ) \ + do { \ + if ( ASSERTING && ! (condition) ) { \ + assert_printf ( "assert(%s) failed at %s line %d\n", \ + #condition, __FILE__, __LINE__ ); \ + } \ + } while ( 0 ) + +/** + * Assert a condition at link-time. + * + * If the condition is not true, the link will fail with an unresolved + * symbol (error_symbol). + * + * This macro is gPXE-specific. Do not use this macro in code + * intended to be portable. + * + */ +#define linker_assert( condition, error_symbol ) \ + if ( ! (condition) ) { \ + extern void error_symbol ( void ); \ + error_symbol(); \ + } + +#endif /* _ASSERT_H */ diff --git a/gpxe/src/include/big_bswap.h b/gpxe/src/include/big_bswap.h new file mode 100644 index 00000000..3775fac1 --- /dev/null +++ b/gpxe/src/include/big_bswap.h @@ -0,0 +1,33 @@ +#ifndef ETHERBOOT_BIG_BSWAP_H +#define ETHERBOOT_BIG_BSWAP_H + +#define ntohl(x) (x) +#define htonl(x) (x) +#define ntohs(x) (x) +#define htons(x) (x) +#define cpu_to_le64(x) __bswap_64(x) +#define cpu_to_le32(x) __bswap_32(x) +#define cpu_to_le16(x) __bswap_16(x) +#define cpu_to_be64(x) (x) +#define cpu_to_be32(x) (x) +#define cpu_to_be16(x) (x) +#define le64_to_cpu(x) __bswap_64(x) +#define le32_to_cpu(x) __bswap_32(x) +#define le16_to_cpu(x) __bswap_16(x) +#define be64_to_cpu(x) (x) +#define be32_to_cpu(x) (x) +#define be16_to_cpu(x) (x) +#define cpu_to_le64s(x) __bswap_64s(x) +#define cpu_to_le32s(x) __bswap_32s(x) +#define cpu_to_le16s(x) __bswap_16s(x) +#define cpu_to_be64s(x) do {} while (0) +#define cpu_to_be32s(x) do {} while (0) +#define cpu_to_be16s(x) do {} while (0) +#define le64_to_cpus(x) __bswap_64s(x) +#define le32_to_cpus(x) __bswap_32s(x) +#define le16_to_cpus(x) __bswap_16s(x) +#define be64_to_cpus(x) do {} while (0) +#define be32_to_cpus(x) do {} while (0) +#define be16_to_cpus(x) do {} while (0) + +#endif /* ETHERBOOT_BIG_BSWAP_H */ diff --git a/gpxe/src/include/bootp.h b/gpxe/src/include/bootp.h new file mode 100644 index 00000000..0e65477a --- /dev/null +++ b/gpxe/src/include/bootp.h @@ -0,0 +1,230 @@ +#ifndef _BOOTP_H +#define _BOOTP_H + +#ifdef ALTERNATE_DHCP_PORTS_1067_1068 +#undef NON_STANDARD_BOOTP_SERVER +#define NON_STANDARD_BOOTP_SERVER 1067 +#undef NON_STANDARD_BOOTP_CLIENT +#define NON_STANDARD_BOOTP_CLIENT 1068 +#endif + +#ifdef NON_STANDARD_BOOTP_SERVER +#define BOOTP_SERVER NON_STANDARD_BOOTP_SERVER +#else +#define BOOTP_SERVER 67 +#endif +#ifdef NON_STANDARD_BOOTP_CLIENT +#define BOOTP_CLIENT NON_STANDARD_BOOTP_CLIENT +#else +#define BOOTP_CLIENT 68 +#endif +#define PROXYDHCP_SERVER 4011 /* For PXE */ + +#define BOOTP_REQUEST 1 +#define BOOTP_REPLY 2 + +#define TAG_LEN(p) (*((p)+1)) +#define RFC1533_COOKIE 99, 130, 83, 99 +#define RFC1533_PAD 0 +#define RFC1533_NETMASK 1 +#define RFC1533_TIMEOFFSET 2 +#define RFC1533_GATEWAY 3 +#define RFC1533_TIMESERVER 4 +#define RFC1533_IEN116NS 5 +#define RFC1533_DNS 6 +#define RFC1533_LOGSERVER 7 +#define RFC1533_COOKIESERVER 8 +#define RFC1533_LPRSERVER 9 +#define RFC1533_IMPRESSSERVER 10 +#define RFC1533_RESOURCESERVER 11 +#define RFC1533_HOSTNAME 12 +#define RFC1533_BOOTFILESIZE 13 +#define RFC1533_MERITDUMPFILE 14 +#define RFC1533_DOMAINNAME 15 +#define RFC1533_SWAPSERVER 16 +#define RFC1533_ROOTPATH 17 +#define RFC1533_EXTENSIONPATH 18 +#define RFC1533_IPFORWARDING 19 +#define RFC1533_IPSOURCEROUTING 20 +#define RFC1533_IPPOLICYFILTER 21 +#define RFC1533_IPMAXREASSEMBLY 22 +#define RFC1533_IPTTL 23 +#define RFC1533_IPMTU 24 +#define RFC1533_IPMTUPLATEAU 25 +#define RFC1533_INTMTU 26 +#define RFC1533_INTLOCALSUBNETS 27 +#define RFC1533_INTBROADCAST 28 +#define RFC1533_INTICMPDISCOVER 29 +#define RFC1533_INTICMPRESPOND 30 +#define RFC1533_INTROUTEDISCOVER 31 +#define RFC1533_INTROUTESOLICIT 32 +#define RFC1533_INTSTATICROUTES 33 +#define RFC1533_LLTRAILERENCAP 34 +#define RFC1533_LLARPCACHETMO 35 +#define RFC1533_LLETHERNETENCAP 36 +#define RFC1533_TCPTTL 37 +#define RFC1533_TCPKEEPALIVETMO 38 +#define RFC1533_TCPKEEPALIVEGB 39 +#define RFC1533_NISDOMAIN 40 +#define RFC1533_NISSERVER 41 +#define RFC1533_NTPSERVER 42 +#define RFC1533_VENDOR 43 +#define RFC1533_NBNS 44 +#define RFC1533_NBDD 45 +#define RFC1533_NBNT 46 +#define RFC1533_NBSCOPE 47 +#define RFC1533_XFS 48 +#define RFC1533_XDM 49 +#ifndef NO_DHCP_SUPPORT +#define RFC2132_REQ_ADDR 50 +#define RFC2132_MSG_TYPE 53 +#define RFC2132_SRV_ID 54 +#define RFC2132_PARAM_LIST 55 +#define RFC2132_MAX_SIZE 57 +#define RFC2132_VENDOR_CLASS_ID 60 +#define RFC2132_CLIENT_ID 61 +#define RFC2132_TFTP_SERVER_NAME 66 +#define RFC2132_BOOTFILE_NAME 67 +#define RFC3004_USER_CLASS 77 + +#ifdef PXE_DHCP_STRICT +/* + * The following options are acknowledged in RFC3679 because they are + * widely used by PXE implementations, but have never been properly + * allocated. Despite other PXE options being correctly packed in a + * vendor encapsulated field, these are exposed. Sigh. Note that the + * client UUID (option 97) is also noted in the PXE spec as using + * option 61. + */ +#define RFC3679_PXE_CLIENT_ARCH 93 +#define RFC3679_PXE_CLIENT_NDI 94 +#define RFC3679_PXE_CLIENT_UUID 97 + +/* The lengths are fixed. */ +#define RFC3679_PXE_CLIENT_ARCH_LENGTH 2 +#define RFC3679_PXE_CLIENT_NDI_LENGTH 3 +#define RFC3679_PXE_CLIENT_UUID_LENGTH 17 + +/* + * Values of RFC3679_PXE_CLIENT_ARCH can apparently be one of the + * following, according to the PXE spec. The spec only actually + * described the 2nd octet, not the first. Duh... assume 0. + */ +#define RFC3679_PXE_CLIENT_ARCH_IAX86PC 0,0 +#define RFC3679_PXE_CLIENT_ARCH_NECPC98 0,1 +#define RFC3679_PXE_CLIENT_ARCH_IA64PC 0,2 +#define RFC3679_PXE_CLIENT_ARCH_DECALPHA 0,3 +#define RFC3679_PXE_CLIENT_ARCH_ARCX86 0,4 +#define RFC3679_PXE_CLIENT_ARCH_INTELLEAN 0,5 + +/* + * Only one valid value of NDI type (must be 1) and UNDI version (must + * be 2.1) + */ +#define RFC3679_PXE_CLIENT_NDI_21 1,2,1 + +/* + * UUID - type must be 1 and then 16 octets of UID, as with the client ID. + * The value is a default for testing only + */ +#define RFC3679_PXE_CLIENT_UUID_TYPE 0 +#warning "UUID is a default for testing ONLY!" +#define RFC3679_PXE_CLIENT_UUID_DEFAULT \ + RFC3679_PXE_CLIENT_UUID_TYPE, \ + 0xDE,0xAD,0xBE,0xEF, \ + 0xDE,0xAD,0xBE,0xEF, \ + 0xDE,0xAD,0xBE,0xEF, \ + 0xDE,0xAD,0xBE,0xEF +/* + * The Vendor Class ID. Note that the Arch and UNDI version numbers + * are fixed and must be same as the ARCH and NDI above. + */ +#define RFC2132_VENDOR_CLASS_ID_PXE_LENGTH 32 +#define RFC2132_VENDOR_CLASS_ID_PXE \ + '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' + +/* + * The following vendor options are required in the PXE spec to pull + * options for the *next* image. The PXE spec doesn't help us with + * this (like explaining why). + */ +#define RFC1533_VENDOR_PXE_OPT128 128 +#define RFC1533_VENDOR_PXE_OPT129 129 +#define RFC1533_VENDOR_PXE_OPT130 130 +#define RFC1533_VENDOR_PXE_OPT131 131 +#define RFC1533_VENDOR_PXE_OPT132 132 +#define RFC1533_VENDOR_PXE_OPT133 133 +#define RFC1533_VENDOR_PXE_OPT134 134 +#define RFC1533_VENDOR_PXE_OPT135 135 + +#endif /* PXE_DHCP_STRICT */ + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPACK 5 +#endif /* NO_DHCP_SUPPORT */ + +#define RFC1533_VENDOR_MAJOR 0 +#define RFC1533_VENDOR_MINOR 0 + +#define RFC1533_VENDOR_MAGIC 128 +#define RFC1533_VENDOR_ADDPARM 129 +#define RFC1533_VENDOR_ETHDEV 130 +/* We should really apply for an official Etherboot encap option */ +#define RFC1533_VENDOR_ETHERBOOT_ENCAP 150 +/* I'll leave it to FREEBSD to decide if they want to renumber */ +#ifdef IMAGE_FREEBSD +#define RFC1533_VENDOR_HOWTO 132 +#define RFC1533_VENDOR_KERNEL_ENV 133 +#endif +#define RFC1533_VENDOR_NIC_DEV_ID 175 +#define RFC1533_VENDOR_ARCH 177 + +#define RFC1533_END 255 + +#define BOOTP_VENDOR_LEN 64 +#ifndef NO_DHCP_SUPPORT +#define DHCP_OPT_LEN 312 +#endif /* NO_DHCP_SUPPORT */ + +/* Format of a bootp packet */ +struct bootp_t { + uint8_t bp_op; + uint8_t bp_htype; + uint8_t bp_hlen; + uint8_t bp_hops; + uint32_t bp_xid; + uint16_t bp_secs; + uint16_t unused; + in_addr bp_ciaddr; + in_addr bp_yiaddr; + in_addr bp_siaddr; + in_addr bp_giaddr; + uint8_t bp_hwaddr[16]; + uint8_t bp_sname[64]; + char bp_file[128]; +#ifdef NO_DHCP_SUPPORT + uint8_t bp_vend[BOOTP_VENDOR_LEN]; +#else + uint8_t bp_vend[DHCP_OPT_LEN]; +#endif /* NO_DHCP_SUPPORT */ +}; + +/* Format of a bootp IP packet */ +struct bootpip_t +{ + struct iphdr ip; + struct udphdr udp; + struct bootp_t bp; +}; + +/* Format of bootp packet with extensions */ +struct bootpd_t { + struct bootp_t bootp_reply; + uint8_t bootp_extension[MAX_BOOTP_EXTLEN]; +}; + +#endif /* _BOOTP_H */ diff --git a/gpxe/src/include/btext.h b/gpxe/src/include/btext.h new file mode 100644 index 00000000..1d3f9e59 --- /dev/null +++ b/gpxe/src/include/btext.h @@ -0,0 +1,62 @@ +/* + * This file describes the structure passed from the BootX application + * (for MacOS) when it is used to boot Linux. + * + * Written by Benjamin Herrenschmidt. + * + * Move to LinuxBIOS by LYH yhlu@tyan.com + * + */ + + +#ifndef _BTEXT_H__ +#define _BTEXT_H__ + +#if 1 +#define u32 unsigned int +#define u16 unsigned short +#define u8 unsigned char +#endif + +/* Here are the boot informations that are passed to the bootstrap + * Note that the kernel arguments and the device tree are appended + * at the end of this structure. */ +typedef struct boot_infos +{ + + /* NEW (vers. 2) this holds the current _logical_ base addr of + the frame buffer (for use by early boot message) */ + u8* logicalDisplayBase; + + + /* Some infos about the current MacOS display */ + u32 dispDeviceRect[4]; /* left,top,right,bottom */ + u32 dispDeviceDepth; /* (8, 16 or 32) */ + u32 dispDeviceBase; /* base address (physical) */ + u32 dispDeviceRowBytes; /* rowbytes (in bytes) */ + u32 dispDeviceColorsOffset; /* Colormap (8 bits only) or 0 (*) */ + + + /* The framebuffer size (optional, currently 0) */ + u32 frameBufferSize; /* Represents a max size, can be 0. */ + + +} boot_infos_t; + +/* (*) The format of the colormap is 256 * 3 * 2 bytes. Each color index is represented + * by 3 short words containing a 16 bits (unsigned) color component. + * Later versions may contain the gamma table for direct-color devices here. + */ +#define BOOTX_COLORTABLE_SIZE (256UL*3UL*2UL) + + +/* + * Definitions for using the procedures in btext.c. + * + * Benjamin Herrenschmidt <benh@kernel.crashing.org> + */ + +extern boot_infos_t disp_bi; +extern u32 boot_text_mapped; + +#endif /* _BTEXT_H */ diff --git a/gpxe/src/include/byteswap.h b/gpxe/src/include/byteswap.h new file mode 100644 index 00000000..72b5a01d --- /dev/null +++ b/gpxe/src/include/byteswap.h @@ -0,0 +1,22 @@ +#ifndef ETHERBOOT_BYTESWAP_H +#define ETHERBOOT_BYTESWAP_H + +#include "endian.h" +#include "bits/byteswap.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#include "little_bswap.h" +#endif +#if __BYTE_ORDER == __BIG_ENDIAN +#include "big_bswap.h" +#endif + +/* Make routines available to all */ +#define swap64(x) __bswap_64(x) +#define swap32(x) __bswap_32(x) +#define swap16(x) __bswap_16(x) +#define bswap_64(x) __bswap_64(x) +#define bswap_32(x) __bswap_32(x) +#define bswap_16(x) __bswap_16(x) + +#endif /* ETHERBOOT_BYTESWAP_H */ diff --git a/gpxe/src/include/cmdline.h b/gpxe/src/include/cmdline.h new file mode 100644 index 00000000..9ab29c53 --- /dev/null +++ b/gpxe/src/include/cmdline.h @@ -0,0 +1,8 @@ +#ifndef CMDLINE_H +#define CMDLINE_H + +/* Command line external functions */ + +void cmdl_start(); + +#endif diff --git a/gpxe/src/include/cmdlinelib.h b/gpxe/src/include/cmdlinelib.h new file mode 100644 index 00000000..1eb68994 --- /dev/null +++ b/gpxe/src/include/cmdlinelib.h @@ -0,0 +1,99 @@ +/* Command line library */ +#ifndef CMDLINELIB_H +#define CMDLINELIB_H + +#define CMDL_BUFFER_SIZE 256 +//#define CMDL_OUTPUT_SIZE 256 +#define CMDL_PROMPT_SIZE 8 +#define CMDL_MAX_TAB_COMPLETE_RESULT 256 + +typedef int (*cmdl_putchar_t)(int); +typedef int (*cmdl_printf_t)( const char *format, ... ); +typedef int (*cmdl_getchar_t)(); + +#ifndef NULL +#define NULL ((void *)0) +#endif + +enum{ + CMDL_LEFT, + CMDL_RIGHT +}; + +enum{ + CMDLK_FW=6, + CMDLK_BW=2, + CMDLK_BS=8, + CMDLK_HOME=2, + CMDLK_END=5, + CMDLK_DELTOEND=11, + CMDLK_DELARG=23, + CMDLK_ENTER=0x0d, + CMDLK_RETURN=0x0a, + CMDLK_TAB=9 +}; + +typedef struct{ + + // buffers + + //char* output; + char* buffer; + char* prompt; + + // options and values + + int cursor; + //int has_output; + int exit; + int refresh; + int tabstate; + int insert; + + // callbacks + + cmdl_putchar_t putchar; + cmdl_getchar_t getchar; + cmdl_printf_t printf; + +}cmd_line; + +typedef struct{ + int argc; + char **argv; +}cmdl_param_list; + +void cmdl_setputchar(cmd_line* cmd, cmdl_putchar_t in); +void cmdl_setgetchar(cmd_line* cmd, cmdl_getchar_t in); +void cmdl_setprintf(cmd_line* cmd, cmdl_printf_t in); + +//void cmdl_builtin_help(cmd_line* cmd, char* command); + +void cmdl_parsechar(cmd_line* cmd, char in); + +void cmdl_addreplace(cmd_line* cmd, char in); +void cmdl_addinsert(cmd_line* cmd, char in); +void cmdl_enterloop(cmd_line* cmd); +void cmdl_exec(cmd_line* cmd); +void cmdl_setexit(cmd_line* cmd, int exit); +int cmdl_getexit(cmd_line* cmd); +void cmdl_clearoutput(cmd_line* cmd); +void cmdl_clearbuffer(cmd_line* cmd); +int cmdl_printf(cmd_line* cmd, const char *format, ...); +char* cmdl_getoutput(cmd_line* cmd); +//void cmdl_addoutput_str(cmd_line* cmd, char output[CMDL_OUTPUT_SIZE]); +void cmdl_addstr(cmd_line* cmd, char* str); +int cmdl_movecursor(cmd_line* cmd, int direction); +char* cmdl_getbuffer(cmd_line* cmd); +void cmdl_addchar(cmd_line* cmd, char in); +int cmdl_check(cmd_line* cmd); +void cmdl_del(cmd_line* cmd); +cmd_line* cmdl_create(); +void cmdl_free(cmd_line* cmd); +char *cmdl_getprompt(cmd_line* cmd); +void cmdl_setpropmt(cmd_line* cmd, char prompt[CMDL_PROMPT_SIZE]); +cmdl_param_list* cmdl_getparams(const char* command); +void cmdl_tabcomplete(cmd_line *cmd); + +#endif + diff --git a/gpxe/src/include/cmdlist.h b/gpxe/src/include/cmdlist.h new file mode 100644 index 00000000..33cd349b --- /dev/null +++ b/gpxe/src/include/cmdlist.h @@ -0,0 +1,18 @@ +#ifndef COMMANDLIST_H +#define COMMANDLIST_H + +void test_req(); +void test2_req(); +void help_req(); +void nvo_cmd_req(); + +void commandlist() +{ + // test_req(); + // test2_req(); + help_req(); + nvo_cmd_req(); +} + +#endif + diff --git a/gpxe/src/include/coff.h b/gpxe/src/include/coff.h new file mode 100644 index 00000000..a73fda52 --- /dev/null +++ b/gpxe/src/include/coff.h @@ -0,0 +1,73 @@ +#ifndef COFF_H +#define COFF_H +/* Based on the elf.h file + * Changed accordingly to support COFF file support + */ + + +/* Values for f_flags. */ +#define F_RELFLG 0x0001 /* If set, not reloc. info. Clear for executables */ +#define F_EXEC 0x0002 /* No unresolved symbols. Executable file ! */ +#define F_LNNO 0x0004 /* If set, line information numbers removed */ +#define F_LSYMS 0x0008 /* If set, local symbols removed */ +#define F_AR32WR 0x0100 /* Indicates little endian file */ + +/* Values for e_machine (architecute). */ +#define EM_E1 0x17a /* Magic number for Hyperstone. Big endian format */ + +/* Values for f_flags. */ +#define O_MAGIC 0x017c /* Optional's header magic number for Hyperstone */ + +/* Values for s_flags. */ +#define S_TYPE_TEXT 0x0020 /* If set, the section contains only executable */ +#define S_TYPE_DATA 0x0040 /* If set, the section contains only initialized data */ +#define S_TYPE_BSS 0x0080 /* If set, the section is BSS no data stored */ + + +typedef struct +{ + unsigned short f_magic; /* magic number */ + unsigned short f_nscns; /* number of sections */ + unsigned long f_timdat; /* time & date stamp */ + unsigned long f_symptr; /* file pointer to symtab */ + unsigned long f_nsyms; /* number of symtab entries */ + unsigned short f_opthdr; /* sizeof(optional hdr) */ + unsigned short f_flags; /* flags */ +} +COFF_filehdr; + +/* + * Optional header. + */ +typedef struct +{ + unsigned short magic; /* type of file */ + unsigned short vstamp; /* version stamp */ + unsigned long tsize; /* text size in bytes, padded to FW bdry*/ + unsigned long dsize; /* initialized data " " */ + unsigned long bsize; /* uninitialized data " " */ + unsigned long entry; /* entry pt. */ + unsigned long text_start; /* base of text used for this file */ + unsigned long data_start; /* base of data used for this file */ +} +COFF_opthdr; + +/* + * Section header. + */ +typedef struct +{ + char s_name[8]; /* section name */ + unsigned long s_paddr; /* physical address, aliased s_nlib */ + unsigned long s_vaddr; /* virtual address */ + unsigned long s_size; /* section size */ + unsigned long s_scnptr; /* file ptr to raw data for section */ + unsigned long s_relptr; /* file ptr to relocation */ + unsigned long s_lnnoptr; /* file ptr to line numbers */ + unsigned short s_nreloc; /* number of relocation entries */ + unsigned short s_nlnno; /* number of line number entries*/ + unsigned long s_flags; /* flags */ +} +COFF_scnhdr; + +#endif /* COFF_H */ diff --git a/gpxe/src/include/compiler.h b/gpxe/src/include/compiler.h new file mode 100644 index 00000000..1d4312a6 --- /dev/null +++ b/gpxe/src/include/compiler.h @@ -0,0 +1,357 @@ +#ifndef COMPILER_H +#define COMPILER_H + +/* + * Doxygen can't cope with some of the more esoteric areas of C, so we + * make its life simpler. + * + */ +#ifdef DOXYGEN +#define __attribute__(x) +#endif + +/** @file + * + * Global compiler definitions. + * + * This file is implicitly included by every @c .c file in Etherboot. + * It defines global macros such as DBG(). + * + * We arrange for each object to export the symbol @c obj_OBJECT + * (where @c OBJECT is the object name, e.g. @c rtl8139) as a global + * symbol, so that the linker can drag in selected object files from + * the library using <tt> -u obj_OBJECT </tt>. + * + */ + +/* Not quite sure why cpp requires two levels of macro call in order + * to actually expand OBJECT... + */ +#undef _H1 +#define _H1( x, y ) x ## y +#undef _H2 +#define _H2( x, y ) _H1 ( x, y ) +#define PREFIX_OBJECT(prefix) _H2 ( prefix, OBJECT ) +#define OBJECT_SYMBOL PREFIX_OBJECT(obj_) +#undef _STR +#define _STR(s) #s +#undef _XSTR +#define _XSTR(s) _STR(s) +#define OBJECT_SYMBOL_STR _XSTR ( OBJECT_SYMBOL ) + +#ifdef ASSEMBLY + + .globl OBJECT_SYMBOL + .equ OBJECT_SYMBOL, 0 + +#else /* ASSEMBLY */ + +__asm__ ( ".globl\t" OBJECT_SYMBOL_STR ); +__asm__ ( ".equ\t" OBJECT_SYMBOL_STR ", 0" ); + +/** + * Drag in an object by object name. + * + * Macro to allow objects to explicitly drag in other objects by + * object name. Used by config.c. + * + */ +#define REQUIRE_OBJECT(object) \ + __asm__ ( ".equ\tneed_" #object ", obj_" #object ); + +/** @def DBG + * + * Print a debugging message. + * + * The debug level is set at build time by specifying the @c DEBUG= + * parameter on the @c make command line. For example, to enable + * debugging for the PCI bus functions (in pci.c) in a @c .dsk image + * for the @c rtl8139 card, you could use the command line + * + * @code + * + * make bin/rtl8139.dsk DEBUG=pci + * + * @endcode + * + * This will enable the debugging statements (DBG()) in pci.c. If + * debugging is not enabled, DBG() statements will be ignored. + * + * You can enable debugging in several objects simultaneously by + * separating them with commas, as in + * + * @code + * + * make bin/rtl8139.dsk DEBUG=pci,buffer,heap + * + * @endcode + * + * You can increase the debugging level for an object by specifying it + * with @c :N, where @c N is the level, as in + * + * @code + * + * make bin/rtl8139.dsk DEBUG=pci,buffer:2,heap + * + * @endcode + * + * which would enable debugging for the PCI, buffer-handling and + * heap-allocation code, with the buffer-handling code at level 2. + * + */ + +/* + * If debug_OBJECT is set to a true value, the macro DBG(...) will + * expand to printf(...) when compiling OBJECT, and the symbol + * DEBUG_LEVEL will be inserted into the object file. + * + */ +#define DEBUG_SYMBOL PREFIX_OBJECT(debug_) + +#if DEBUG_SYMBOL +#define DEBUG_SYMBOL_STR _XSTR ( DEBUG_SYMBOL ) +__asm__ ( ".equ\tDBGLVL, " DEBUG_SYMBOL_STR ); +#endif + +/** printf() for debugging + * + * This function exists so that the DBG() macros can expand to + * printf() calls without dragging the printf() prototype into scope. + * + * As far as the compiler is concerned, dbg_printf() and printf() are + * completely unrelated calls; it's only at the assembly stage that + * references to the dbg_printf symbol are collapsed into references + * to the printf symbol. + */ +extern int __attribute__ (( format ( printf, 1, 2 ) )) +dbg_printf ( const char *fmt, ... ) asm ( "printf" ); + +extern void dbg_autocolourise ( unsigned long id ); +extern void dbg_decolourise ( void ); +extern void dbg_hex_dump_da ( unsigned long dispaddr, + const void *data, unsigned long len ); + +/* Compatibility with existing Makefile */ +#if DEBUG_SYMBOL +#define DBGLVL DEBUG_SYMBOL +#else +#define DBGLVL 0 +#endif + +#define DBGLVL_LOG 1 +#define DBG_LOG ( DBGLVL & DBGLVL_LOG ) +#define DBGLVL_EXTRA 2 +#define DBG_EXTRA ( DBGLVL & DBGLVL_EXTRA ) +#define DBGLVL_PROFILE 4 +#define DBG_PROFILE ( DBGLVL & DBGLVL_PROFILE ) +#define DBGLVL_IO 8 +#define DBG_IO ( DBGLVL & DBGLVL_IO ) + +/** + * Print debugging message if we are at a certain debug level + * + * @v level Debug level + * @v ... printf() argument list + */ +#define DBG_IF( level, ... ) do { \ + if ( DBG_ ## level ) { \ + dbg_printf ( __VA_ARGS__ ); \ + } \ + } while ( 0 ) + +/** + * Print a hex dump if we are at a certain debug level + * + * @v level Debug level + * @v dispaddr Display address + * @v data Data to print + * @v len Length of data + */ +#define DBG_HDA_IF( level, dispaddr, data, len ) do { \ + if ( DBG_ ## level ) { \ + union { \ + unsigned long ul; \ + typeof ( dispaddr ) raw; \ + } da; \ + da.raw = dispaddr; \ + dbg_hex_dump_da ( da.ul, data, len ); \ + } \ + } while ( 0 ) + +/** + * Print a hex dump if we are at a certain debug level + * + * @v level Debug level + * @v data Data to print + * @v len Length of data + */ +#define DBG_HD_IF( level, data, len ) do { \ + DBG_HDA_IF ( level, data, data, len ); \ + } while ( 0 ) + +/** + * Select colour for debug messages if we are at a certain debug level + * + * @v level Debug level + * @v id Message stream ID + */ +#define DBG_AC_IF( level, id ) do { \ + if ( DBG_ ## level ) { \ + union { \ + unsigned long ul; \ + typeof ( id ) raw; \ + } dbg_stream; \ + dbg_stream.raw = id; \ + dbg_autocolourise ( dbg_stream.ul ); \ + } \ + } while ( 0 ) + +/** + * Revert colour for debug messages if we are at a certain debug level + * + * @v level Debug level + */ +#define DBG_DC_IF( level ) do { \ + if ( DBG_ ## level ) { \ + dbg_decolourise(); \ + } \ + } while ( 0 ) + +/* Autocolourising versions of the DBGxxx_IF() macros */ + +#define DBGC_IF( level, id, ... ) do { \ + DBG_AC_IF ( level, id ); \ + DBG_IF ( level, __VA_ARGS__ ); \ + DBG_DC_IF ( level ); \ + } while ( 0 ) + +#define DBGC_HDA_IF( level, id, ... ) do { \ + DBG_AC_IF ( level, id ); \ + DBG_HDA_IF ( level, __VA_ARGS__ ); \ + DBG_DC_IF ( level ); \ + } while ( 0 ) + +#define DBGC_HD_IF( level, id, ... ) do { \ + DBG_AC_IF ( level, id ); \ + DBG_HD_IF ( level, __VA_ARGS__ ); \ + DBG_DC_IF ( level ); \ + } while ( 0 ) + +/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( LOG, ... )*/ + +#define DBG( ... ) DBG_IF ( LOG, __VA_ARGS__ ) +#define DBG_HDA( ... ) DBG_HDA_IF ( LOG, __VA_ARGS__ ) +#define DBG_HD( ... ) DBG_HD_IF ( LOG, __VA_ARGS__ ) +#define DBGC( ... ) DBGC_IF ( LOG, __VA_ARGS__ ) +#define DBGC_HDA( ... ) DBGC_HDA_IF ( LOG, __VA_ARGS__ ) +#define DBGC_HD( ... ) DBGC_HD_IF ( LOG, __VA_ARGS__ ) + +/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( EXTRA, ... )*/ + +#define DBG2( ... ) DBG_IF ( EXTRA, __VA_ARGS__ ) +#define DBG2_HDA( ... ) DBG_HDA_IF ( EXTRA, __VA_ARGS__ ) +#define DBG2_HD( ... ) DBG_HD_IF ( EXTRA, __VA_ARGS__ ) +#define DBGC2( ... ) DBGC_IF ( EXTRA, __VA_ARGS__ ) +#define DBGC2_HDA( ... ) DBGC_HDA_IF ( EXTRA, __VA_ARGS__ ) +#define DBGC2_HD( ... ) DBGC_HD_IF ( EXTRA, __VA_ARGS__ ) + +/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( PROFILE, ... )*/ + +#define DBGP( ... ) DBG_IF ( PROFILE, __VA_ARGS__ ) +#define DBGP_HDA( ... ) DBG_HDA_IF ( PROFILE, __VA_ARGS__ ) +#define DBGP_HD( ... ) DBG_HD_IF ( PROFILE, __VA_ARGS__ ) +#define DBGCP( ... ) DBGC_IF ( PROFILE, __VA_ARGS__ ) +#define DBGCP_HDA( ... ) DBGC_HDA_IF ( PROFILE, __VA_ARGS__ ) +#define DBGCP_HD( ... ) DBGC_HD_IF ( PROFILE, __VA_ARGS__ ) + +/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( IO, ... )*/ + +#define DBGIO( ... ) DBG_IF ( IO, __VA_ARGS__ ) +#define DBGIO_HDA( ... ) DBG_HDA_IF ( IO, __VA_ARGS__ ) +#define DBGIO_HD( ... ) DBG_HD_IF ( IO, __VA_ARGS__ ) +#define DBGCIO( ... ) DBGC_IF ( IO, __VA_ARGS__ ) +#define DBGCIO_HDA( ... ) DBGC_HDA_IF ( IO, __VA_ARGS__ ) +#define DBGCIO_HD( ... ) DBGC_HD_IF ( IO, __VA_ARGS__ ) + + +#if DEBUG_SYMBOL == 0 +#define NDEBUG +#endif + +/** Select file identifier for errno.h (if used) */ +#define ERRFILE PREFIX_OBJECT ( ERRFILE_ ) + +/** Declare a data structure as packed. */ +#define PACKED __attribute__ (( packed )) + +/** Declare a variable or data structure as unused. */ +#define __unused __attribute__ (( unused )) + +/** Apply standard C calling conventions */ +#define __cdecl __attribute__ (( cdecl , regparm(0) )) + +/** + * Declare a function as pure - i.e. without side effects + */ +#define __pure __attribute__ (( pure )) + +/** + * Declare a function as const - i.e. it does not access global memory + * (including dereferencing pointers passed to it) at all. + * Must also not call any non-const functions. + */ +#define __const __attribute__ (( const )) + +/** + * Declare a function's pointer parameters as non-null - i.e. force + * compiler to check pointers at compile time and enable possible + * optimizations based on that fact + */ +#define __nonnull __attribute__ (( nonnull )) + +/** + * Declare a pointer returned by a function as a unique memory address + * as returned by malloc-type functions. + */ +#define __malloc __attribute__ (( malloc )) + +/** + * Declare a function as used. + * + * Necessary only if the function is called only from assembler code. + */ +#define __used __attribute__ (( used )) + +/** Declare a data structure to be aligned with 16-byte alignment */ +#define __aligned __attribute__ (( aligned ( 16 ) )) + +/** + * Shared data. + * + * To save space in the binary when multiple-driver images are + * compiled, uninitialised data areas can be shared between drivers. + * This will typically be used to share statically-allocated receive + * and transmit buffers between drivers. + * + * Use as e.g. + * + * @code + * + * struct { + * char rx_buf[NUM_RX_BUF][RX_BUF_SIZE]; + * char tx_buf[TX_BUF_SIZE]; + * } my_static_data __shared; + * + * @endcode + * + */ +#define __shared __asm__ ( "_shared_bss" ) + +/** + * Optimisation barrier + */ +#define barrier() __asm__ __volatile__ ( "" : : : "memory" ) + +#endif /* ASSEMBLY */ + +#endif /* COMPILER_H */ diff --git a/gpxe/src/include/console.h b/gpxe/src/include/console.h new file mode 100644 index 00000000..9addd526 --- /dev/null +++ b/gpxe/src/include/console.h @@ -0,0 +1,114 @@ +#ifndef CONSOLE_H +#define CONSOLE_H + +#include <gpxe/tables.h> + +/** @file + * + * User interaction. + * + * Various console devices can be selected via the build options + * CONSOLE_FIRMWARE, CONSOLE_SERIAL etc. The console functions + * putchar(), getchar() and iskey() delegate to the individual console + * drivers. + * + */ + +/** + * A console driver + * + * Defines the functions that implement a particular console type. + * Must be made part of the console drivers table by using + * #__console_driver. + * + * @note Consoles that cannot be used before their initialisation + * function has completed should set #disabled=1 initially. This + * allows other console devices to still be used to print out early + * debugging messages. + * + */ +struct console_driver { + /** Console is disabled. + * + * The console's putchar(), putline(), getchar() and iskey() + * methods will not be called while #disabled==1. Typically + * the console's initialisation functions will set #disabled=0 + * upon completion. + * + */ + int disabled; + + /** Write a character to the console. + * + * @v character Character to be written + * @ret None - + * @err None - + * + */ + void ( *putchar ) ( int character ); + + /** Write an entire line to the console. + * This is intended to be used by line-oriented output media, + * like system logging facilities or line printers. + * Line output will not contain non-printable characters. + * + * @v linebuffer Pointer to the \0-terminated line + * @ret None - + * @err None - + */ + void ( * putline ) ( unsigned char * linebuffer ); + + /** Read a character from the console. + * + * @v None - + * @ret character Character read + * @err None - + * + * If no character is available to be read, this method will + * block. The character read should not be echoed back to the + * console. + * + */ + int ( *getchar ) ( void ); + + /** Check for available input. + * + * @v None - + * @ret True Input is available + * @ret False Input is not available + * @err None - + * + * This should return True if a subsequent call to getchar() + * will not block. + * + */ + int ( *iskey ) ( void ); +}; + +/** + * Mark a <tt> struct console_driver </tt> as being part of the + * console drivers table. + * + * Use as e.g. + * + * @code + * + * struct console_driver my_console __console_driver = { + * .putchar = my_putchar, + * .getchar = my_getchar, + * .iskey = my_iskey, + * }; + * + * @endcode + * + */ +#define __console_driver __table ( struct console_driver, console, 01 ) + +/* Function prototypes */ + +extern void putchar ( int character ); +extern int getchar ( void ); +extern int iskey ( void ); +extern int getkey ( void ); + +#endif /* CONSOLE_H */ diff --git a/gpxe/src/include/cpu.h b/gpxe/src/include/cpu.h new file mode 100644 index 00000000..b2c428f7 --- /dev/null +++ b/gpxe/src/include/cpu.h @@ -0,0 +1,6 @@ +#ifndef CPU_H +#define CPU_H + +#include "bits/cpu.h" + +#endif /* CPU_H */ diff --git a/gpxe/src/include/ctype.h b/gpxe/src/include/ctype.h new file mode 100644 index 00000000..a79395d2 --- /dev/null +++ b/gpxe/src/include/ctype.h @@ -0,0 +1,28 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +/** @file + * + * Character types + */ + +#define isdigit(c) ((c & 0x04) != 0) +#define islower(c) ((c & 0x02) != 0) +//#define isspace(c) ((c & 0x20) != 0) +#define isupper(c) ((c & 0x01) != 0) + +static inline unsigned char tolower(unsigned char c) +{ + if (isupper(c)) + c -= 'A'-'a'; + return c; +} + +static inline unsigned char toupper(unsigned char c) +{ + if (islower(c)) + c -= 'a'-'A'; + return c; +} + +#endif /* _CTYPE_H */ diff --git a/gpxe/src/include/curses.h b/gpxe/src/include/curses.h new file mode 100644 index 00000000..6b1c42d8 --- /dev/null +++ b/gpxe/src/include/curses.h @@ -0,0 +1,753 @@ +#ifndef CURSES_H +#define CURSES_H + +#include <stdint.h> +#include <stdarg.h> + +/** @file + * + * MuCurses header file + * + */ + +#undef ERR +#define ERR (-1) + +#undef FALSE +#define FALSE (0) + +#undef OK +#define OK (0) + +#undef TRUE +#define TRUE (1) + +typedef int bool; +typedef uint32_t chtype; +typedef uint32_t attr_t; + +/** Curses SCREEN object */ +typedef struct _curses_screen { + /** Current cursor position */ + unsigned int curs_x, curs_y; + /** Current attribute */ + attr_t attrs; + + void ( *init ) ( struct _curses_screen *scr ); + void ( *exit ) ( struct _curses_screen *scr ); + /** + * Move cursor to position specified by x,y coords + * + * @v scr screen on which to operate + * @v y Y position + * @v x X position + */ + void ( * movetoyx ) ( struct _curses_screen *scr, + unsigned int y, unsigned int x ); + /** + * Write character to current cursor position + * + * @v scr screen on which to operate + * @v c character to be written + */ + void ( * putc ) ( struct _curses_screen *scr, chtype c ); + /** + * Pop a character from the keyboard input stream + * + * @v scr screen on which to operate + * @ret c popped character + */ + int ( * getc ) ( struct _curses_screen *scr ); + /** + * Checks to see whether a character is waiting in the input stream + * + * @v scr screen on which to operate + * @ret TRUE character waiting in stream + * @ret FALSE no character waiting in stream + */ + bool ( *peek ) ( struct _curses_screen *scr ); +} SCREEN; + +/** Curses Window struct */ +typedef struct _curses_window { + /** screen with which window associates */ + SCREEN *scr; + /** window attributes */ + attr_t attrs; + /** window origin coordinates */ + unsigned int ori_x, ori_y; + /** window cursor position */ + unsigned int curs_x, curs_y; + /** window dimensions */ + unsigned int width, height; + /** parent window */ + struct _curses_window *parent; + /** windows that share the same parent as this one */ + //struct list_head siblings; + /** windows der'd or sub'd from this one */ + //struct list_head children; +} WINDOW; + +extern WINDOW _stdscr; +extern unsigned short _COLS; +extern unsigned short _LINES; + +#define stdscr ( &_stdscr ) +#define COLS _COLS +#define LINES _LINES + +#define MUCURSES_BITS( mask, shift ) (( mask ) << (shift)) +#define CPAIR_SHIFT 8 +#define ATTRS_SHIFT 16 + +#define WA_DEFAULT ( 0x0000 << ATTRS_SHIFT ) +#define WA_ALTCHARSET ( 0x0001 << ATTRS_SHIFT ) +#define WA_BLINK ( 0x0002 << ATTRS_SHIFT ) +#define WA_BOLD ( 0x0004 << ATTRS_SHIFT ) +#define WA_DIM ( 0x0008 << ATTRS_SHIFT ) +#define WA_INVIS ( 0x0010 << ATTRS_SHIFT ) +#define WA_PROTECT ( 0x0020 << ATTRS_SHIFT ) +#define WA_REVERSE ( 0x0040 << ATTRS_SHIFT ) +#define WA_STANDOUT ( 0x0080 << ATTRS_SHIFT ) +#define WA_UNDERLINE ( 0x0100 << ATTRS_SHIFT ) +#define WA_HORIZONTAL ( 0x0200 << ATTRS_SHIFT ) +#define WA_VERTICAL ( 0x0400 << ATTRS_SHIFT ) +#define WA_LEFT ( 0x0800 << ATTRS_SHIFT ) +#define WA_RIGHT ( 0x1000 << ATTRS_SHIFT ) +#define WA_LOW ( 0x2000 << ATTRS_SHIFT ) +#define WA_TOP ( 0x4000 << ATTRS_SHIFT ) + +#define A_DEFAULT WA_DEFAULT +#define A_ALTCHARSET WA_ALTCHARSET +#define A_BLINK WA_BLINK +#define A_BOLD WA_BOLD +#define A_DIM WA_DIM +#define A_INVIS WA_INVIS +#define A_PROTECT WA_PROTECT +#define A_REVERSE WA_REVERSE +#define A_STANDOUT WA_STANDOUT +#define A_UNDERLINE WA_UNDERLINE + +#define A_ATTRIBUTES ( 0xffff << ATTRS_SHIFT ) +#define A_CHARTEXT ( 0xff ) +#define A_COLOUR ( 0xff << CPAIR_SHIFT ) +#define A_COLOR A_COLOUR + +#define COLOUR_PAIR(n) ( (n) << CPAIR_SHIFT ) +#define COLOR_PAIR(n) COLOUR_PAIR(n) +#define PAIR_NUMBER(attrs) ( ( (attrs) & A_COLOUR ) >> CPAIR_SHIFT ) + +#define COLOUR_PAIRS 8 /* Arbitrary limit */ +#define COLOR_PAIRS COLOUR_PAIRS + +#define ACS_ULCORNER '+' +#define ACS_LLCORNER '+' +#define ACS_URCORNER '+' +#define ACS_LRCORNER '+' +#define ACS_RTEE '+' +#define ACS_LTEE '+' +#define ACS_BTEE '+' +#define ACS_TTEE '+' +#define ACS_HLINE '-' +#define ACS_VLINE '|' +#define ACS_PLUS '+' +#define ACS_S1 '-' +#define ACS_S9 '_' +#define ACS_DIAMOND '+' +#define ACS_CKBOARD ':' +#define ACS_DEGREE '\'' +#define ACS_PLMINUS '#' +#define ACS_BULLET 'o' +#define ACS_LARROW '<' +#define ACS_RARROW '>' +#define ACS_DARROW 'v' +#define ACS_UARROW '^' +#define ACS_BOARD '#' +#define ACS_LANTERN '#' +#define ACS_BLOCK '#' + +#define COLOUR_BLACK 0 +#define COLOUR_RED 1 +#define COLOUR_GREEN 2 +#define COLOUR_YELLOW 3 +#define COLOUR_BLUE 4 +#define COLOUR_MAGENTA 5 +#define COLOUR_CYAN 6 +#define COLOUR_WHITE 7 +#define COLOURS 7 + +#define COLOUR_FG 30 +#define COLOUR_BG 40 +#define COLOR_FG COLOUR_FG +#define COLOR_BG COLOUR_BG + +#define COLOR_BLACK COLOUR_BLACK +#define COLOR_BLUE COLOUR_BLUE +#define COLOR_GREEN COLOUR_GREEN +#define COLOR_CYAN COLOUR_CYAN +#define COLOR_RED COLOUR_RED +#define COLOR_MAGENTA COLOUR_MAGENTA +#define COLOR_YELLOW COLOUR_YELLOW +#define COLOR_WHITE COLOUR_WHITE +#define COLORS COLOURS + +/* + * KEY code constants are define in gpxe/keys.h + */ +#include <gpxe/keys.h> + +//extern int addch ( const chtype * ); +//extern int addchnstr ( const chtype *, int ); +//extern int addchstr ( const chtype * ); +//extern int addnstr ( const char *, int ); +//extern int addstr ( const char * ); +//extern int attroff ( int ); +//extern int attron ( int ); +//extern int attrset ( int ); +//extern int attr_get ( attr_t *, short *, void * ); +//extern int attr_off ( attr_t, void * ); +//extern int attr_on ( attr_t, void * ); +//extern int attr_set ( attr_t, short, void * ); +extern int baudrate ( void ); +extern int beep ( void ); +//extern void bkgdset ( chtype ); +/*extern int border ( chtype, chtype, chtype, chtype, chtype, chtype, chtype, + chtype );*/ +extern int box ( WINDOW *, chtype, chtype ) __nonnull; +//extern bool can_change_colour ( void ); +#define can_change_color() can_change_colour() +extern int cbreak ( void ); +//extern int clrtobot ( void ); +//extern int clrtoeol ( void ); +extern int colour_content ( short, short *, short *, short * ) __nonnull; +#define color_content( c, r, g, b ) colour_content( (c), (r), (g), (b) ) +//extern int colour_set ( short, void * ); +#define color_set( cpno, opts ) colour_set( (cpno), (opts) ) +extern int copywin ( const WINDOW *, WINDOW *, int, int, int, + int, int, int, int ); +extern int curs_set ( int ); +extern int def_prog_mode ( void ); +extern int def_shell_mode ( void ); +extern int delay_output ( int ); +//extern int delch ( void ); +//extern int deleteln ( void ); +extern void delscreen ( SCREEN * ); +extern int delwin ( WINDOW * ) __nonnull; +extern WINDOW *derwin ( WINDOW *, int, int, int, int ) __nonnull; +//extern int doupdate ( void ); +extern WINDOW *dupwin ( WINDOW * ) __nonnull; +extern int echo ( void ); +extern int echochar ( const chtype ); +extern int endwin ( void ); +extern char erasechar ( void ); +//extern int erase ( void ); +extern void filter ( void ); +extern int flash ( void ); +extern int flushinp ( void ); +extern __pure chtype getbkgd ( WINDOW * ) __nonnull; +//extern int getch ( void ); +//extern int getnstr ( char *, int ); +//extern int getstr ( char * ); +extern int halfdelay ( int ); +//extern bool has_colors ( void ); +extern bool has_ic ( void ); +extern bool has_il ( void ); +//extern int hline ( chtype, int ); +extern void idcok ( WINDOW *, bool ); +extern int idlok ( WINDOW *, bool ); +//extern void immedok ( WINDOW *, bool ); +//extern chtype inch ( void ); +//extern int inchnstr ( chtype *, int ); +//extern int inchstr ( chtype * ); +extern WINDOW *initscr ( void ); +extern int init_colour ( short, short, short, short ); +#define init_color ( c, r, g, b ) init_colour ( (c), (r), (g), (b) ) +extern int init_pair ( short, short, short ); +//extern int innstr ( char *, int ); +//extern int insch ( chtype ); +//extern int insnstr ( const char *, int ); +//extern int insstr ( const char * ); +//extern int instr ( char * ); +extern int intrflush ( WINDOW *, bool ); +extern bool isendwin ( void ); +//extern bool is_linetouched ( WINDOW *, int ); +//extern bool is_wintouched ( WINDOW * ); +extern char *keyname ( int ); +extern int keypad ( WINDOW *, bool ); +extern char killchar ( void ); +extern int leaveok ( WINDOW *, bool ); +extern char *longname ( void ); +extern int meta ( WINDOW *, bool ); +//extern int move ( int, int ); +//extern int mvaddch ( int, int, const chtype ); +//extern int mvaddchnstr ( int, int, const chtype *, int ); +//extern int mvaddchstr ( int, int, const chtype * ); +//extern int mvaddnstr ( int, int, const char *, int ); +//extern int mvaddstr ( int, int, const char * ); +extern int mvcur ( int, int, int, int ); +//extern int mvdelch ( int, int ); +extern int mvderwin ( WINDOW *, int, int ); +//extern int mvgetch ( int, int ); +//extern int mvgetnstr ( int, int, char *, int ); +//extern int mvgetstr ( int, int, char * ); +//extern int mvhline ( int, int, chtype, int ); +//extern chtype mvinch ( int, int ); +//extern int mvinchnstr ( int, int, chtype *, int ); +//extern int mvinchstr ( int, int, chtype * ); +//extern int mvinnstr ( int, int, char *, int ); +//extern int mvinsch ( int, int, chtype ); +//extern int mvinsnstr ( int, int, const char *, int ); +//extern int mvinsstr ( int, int, const char * ); +//extern int mvinstr ( int, int, char * ); +//extern int mvprintw ( int, int, char *, ... ); +//extern int mvscanw ( int, int, char *, ... ); +//extern int mvvline ( int, int, chtype, int ); +//extern int mvwaddch ( WINDOW *, int, int, const chtype ); +//extern int mvwaddchnstr ( WINDOW *, int, int, const chtype *, int ); +//extern int mvwaddchstr ( WINDOW *, int, int, const chtype * ); +//extern int mvwaddnstr ( WINDOW *, int, int, const char *, int ); +//extern int mvwaddstr ( WINDOW *, int, int, const char * ); +//extern int mvwdelch ( WINDOW *, int, int ); +//extern int mvwgetch ( WINDOW *, int, int ); +//extern int mvwgetnstr ( WINDOW *, int, int, char *, int ); +//extern int mvwgetstr ( WINDOW *, int, int, char * ); +//extern int mvwhline ( WINDOW *, int, int, chtype, int ); +extern int mvwin ( WINDOW *, int, int ) __nonnull; +//extern chtype mvwinch ( WINDOW *, int, int ); +//extern int mvwinchnstr ( WINDOW *, int, int, chtype *, int ); +//extern int mvwinchstr ( WINDOW *, int, int, chtype * ); +//extern int mvwinnstr ( WINDOW *, int, int, char *, int ); +//extern int mvwinsch ( WINDOW *, int, int, chtype ); +//extern int mvwinsnstr ( WINDOW *, int, int, const char *, int ); +//extern int mvwinsstr ( WINDOW *, int, int, const char * ); +//extern int mvwinstr ( WINDOW *, int, int, char * ); +//extern int mvwprintw ( WINDOW *, int, int, char *, ... ); +//extern int mvwscanw ( WINDOW *, int, int, char *, ... ); +//extern int mvwvline ( WINDOW *, int, int, chtype, int ); +extern int napms ( int ); +//extern WINDOW *newpad ( int, int ); +extern WINDOW *newwin ( int, int, int, int ); +extern int nl ( void ); +extern int nocbreak ( void ); +extern int nodelay ( WINDOW *, bool ); +extern int noecho ( void ); +extern int nonl ( void ); +extern void noqiflush ( void ); +extern int noraw ( void ); +extern int notimeout ( WINDOW *, bool ); +extern int overlay ( const WINDOW *, WINDOW * ); +extern int overwrite ( const WINDOW *, WINDOW * ); +extern int pair_content ( short, short *, short * ) __nonnull; +//extern int pechochar ( WINDOW *, chtype ); +//extern int pnoutrefresh ( WINDOW *, int, int, int, int, int, int ); +//extern int prefresh ( WINDOW *, int, int, int, int, int, int ); +extern int printw ( char *, ... ); +extern int putp ( const char * ); +extern void qiflush ( void ); +extern int raw ( void ); +//extern int redrawwin ( WINDOW * ); +//extern int refresh ( void ); +extern int reset_prog_mode ( void ); +extern int reset_shell_mode ( void ); +extern int resetty ( void ); +extern int ripoffline ( int, int (*) ( WINDOW *, int) ); +extern int savetty ( void ); +//extern int scanw ( char *, ... ); +//extern int scrl ( int ); +//extern int scroll ( WINDOW * ); +//extern int scrollok ( WINDOW *, bool ); +//extern int setscrreg ( int, int ); +extern SCREEN *set_term ( SCREEN * ); +extern int setupterm ( char *, int, int * ); +extern int slk_attr_off ( const attr_t, void * ); +extern int slk_attroff ( const chtype ); +extern int slk_attr_on ( const attr_t, void * ); +extern int slk_attron ( const chtype ); +extern int slk_attr_set ( const attr_t, short, void * ); +extern int slk_attrset ( const chtype ); +extern int slk_clear ( void ); +extern int slk_colour ( short ); +#define slk_color( c ) slk_colour( (c) ) +extern int slk_init ( int ); +extern char *slk_label ( int ); +extern int slk_noutrefresh ( void ); +//extern int slk_refresh ( void ); +extern int slk_restore ( void ); +extern int slk_set ( int, const char *, int ) __nonnull; +extern int slk_touch ( void ); +extern int standend ( void ); +extern int standout ( void ); +//extern int start_colour ( void ); +#define start_color() start_colour() +//extern WINDOW *subpad ( WINDOW *, int, int, int, int ); +extern WINDOW *subwin ( WINDOW *, int, int, int, int ) __nonnull; +extern int syncok ( WINDOW *, bool ); +extern chtype termattrs ( void ); +extern attr_t term_attrs ( void ); +extern char *termname ( void ); +extern int tigetflag ( char * ); +extern int tigetnum ( char * ); +extern char *tigetstr ( char * ); +extern void timeout ( int ); +//extern int touchline ( WINDOW *, int, int ); +//extern int touchwin ( WINDOW * ); +extern char *tparm ( char *, long, long, long, long, long, long, long, long, + long ); +extern int typeahead ( int ); +//extern int ungetch ( int ); +//extern int untouchwin ( WINDOW * ); +extern void use_env ( bool ); +extern int vid_attr ( attr_t, short, void * ); +extern int vidattr ( chtype ); +extern int vid_puts ( attr_t, short, void *, int ( *) ( int) ); +extern int vidputs ( chtype, int ( *) ( int) ); +//extern int vline ( chtype, int ); +//extern int vwprintw ( WINDOW *, const char *, va_list ); +extern int vw_printw ( WINDOW *, const char *, va_list ) __nonnull; +//extern int vwscanw ( WINDOW *, char *, va_list ); +//extern int vw_scanw ( WINDOW *, char *, va_list ); +extern int waddch ( WINDOW *, const chtype ) __nonnull; +extern int waddchnstr ( WINDOW *, const chtype *, int ) __nonnull; +//extern int waddchstr ( WINDOW *, const chtype * ); +extern int waddnstr ( WINDOW *, const char *, int ) __nonnull; +//extern int waddstr ( WINDOW *, const char * ); +extern int wattroff ( WINDOW *, int ) __nonnull; +extern int wattron ( WINDOW *, int ) __nonnull; +extern int wattrset ( WINDOW *, int ) __nonnull; +extern int wattr_get ( WINDOW *, attr_t *, short *, void * ) + __attribute__ (( nonnull (1, 2, 3))); +extern int wattr_off ( WINDOW *, attr_t, void * ) + __attribute__ (( nonnull (1))); +extern int wattr_on ( WINDOW *, attr_t, void * ) + __attribute__ (( nonnull (1))); +extern int wattr_set ( WINDOW *, attr_t, short, void * ) + __attribute__ (( nonnull (1))); +//extern void wbkgdset ( WINDOW *, chtype ); +extern int wborder ( WINDOW *, chtype, chtype, chtype, chtype, chtype, chtype, + chtype, chtype ) __nonnull; +extern int wclrtobot ( WINDOW * ) __nonnull; +extern int wclrtoeol ( WINDOW * ) __nonnull; +extern void wcursyncup ( WINDOW * ); +extern int wcolour_set ( WINDOW *, short, void * ) __nonnull; +#define wcolor_set(w,s,v) wcolour_set((w),(s),(v)) +extern int wdelch ( WINDOW * ) __nonnull; +extern int wdeleteln ( WINDOW * ) __nonnull; +extern int wechochar ( WINDOW *, const chtype ); +extern int werase ( WINDOW * ) __nonnull; +extern int wgetch ( WINDOW * ); +extern int wgetnstr ( WINDOW *, char *, int ); +//extern int wgetstr ( WINDOW *, char * ); +extern int whline ( WINDOW *, chtype, int ) __nonnull; +//extern chtype winch ( WINDOW * ); +//extern int winchnstr ( WINDOW *, chtype *, int ); +//extern int winchstr ( WINDOW *, chtype * ); +//extern int winnstr ( WINDOW *, char *, int ); +//extern int winsch ( WINDOW *, chtype ); +//extern int winsnstr ( WINDOW *, const char *, int ); +//extern int winsstr ( WINDOW *, const char * ); +//extern int winstr ( WINDOW *, char * ); +extern int wmove ( WINDOW *, int, int ); +//extern int wnoutrefresh ( WINDOW * ); +extern int wprintw ( WINDOW *, const char *, ... ) __nonnull; +//extern int wredrawln ( WINDOW *, int, int ); +//extern int wrefresh ( WINDOW * ); +//extern int wscanw ( WINDOW *, char *, ... ); +//extern int wscrl ( WINDOW *, int ); +//extern int wsetscrreg ( WINDOW *, int, int ); +//extern int wstandend ( WINDOW * ); +//extern int wstandout ( WINDOW * ); +extern void wsyncup ( WINDOW * ); +extern void wsyncdown ( WINDOW * ); +extern void wtimeout ( WINDOW *, int ); +//extern int wtouchln ( WINDOW *, int, int, int ); +extern int wvline ( WINDOW *, chtype, int ) __nonnull; + +/* + * There is frankly a ridiculous amount of redundancy within the + * curses API - ncurses decided to get around this by using #define + * macros, but I've decided to be type-safe and implement them all as + * static inlines instead... + */ + +static inline int addch ( const chtype ch ) { + return waddch( stdscr, ch ); +} + +static inline int addchnstr ( const chtype *chstr, int n ) { + return waddchnstr ( stdscr, chstr, n ); +} + +static inline int addchstr ( const chtype *chstr ) { + return waddchnstr ( stdscr, chstr, -1 ); +} + +static inline int addnstr ( const char *str, int n ) { + return waddnstr ( stdscr, str, n ); +} + +static inline int addstr ( const char *str ) { + return waddnstr ( stdscr, str, -1 ); +} + +static inline int attroff ( int attrs ) { + return wattroff ( stdscr, attrs ); +} + +static inline int attron ( int attrs ) { + return wattron ( stdscr, attrs ); +} + +static inline int attrset ( int attrs ) { + return wattrset ( stdscr, attrs ); +} + +static inline int attr_get ( attr_t *attrs, short *pair, void *opts ) { + return wattr_get ( stdscr, attrs, pair, opts ); +} + +static inline int attr_off ( attr_t attrs, void *opts ) { + return wattr_off ( stdscr, attrs, opts ); +} + +static inline int attr_on ( attr_t attrs, void *opts ) { + return wattr_on ( stdscr, attrs, opts ); +} + +static inline int attr_set ( attr_t attrs, short cpair, void *opts ) { + return wattr_set ( stdscr, attrs, cpair, opts ); +} + +static inline void bkgdset ( chtype ch ) { + wattrset ( stdscr, ch ); +} + +static inline int border ( chtype ls, chtype rs, chtype ts, chtype bs, + chtype tl, chtype tr, chtype bl, chtype br ) { + return wborder ( stdscr, ls, rs, ts, bs, tl, tr, bl, br ); +} + +static inline bool can_change_colour ( void ) { + return FALSE; +} + +static inline int clrtobot ( void ) { + return wclrtobot( stdscr ); +} + +static inline int clrtoeol ( void ) { + return wclrtoeol( stdscr ); +} + +static inline int colour_set ( short colour_pair_number, void *opts ) { + return wcolour_set ( stdscr, colour_pair_number, opts ); +} + +static inline int delch ( void ) { + return wdelch ( stdscr ); +} + +static inline int deleteln ( void ) { + return wdeleteln( stdscr ); +} + +static inline int erase ( void ) { + return werase ( stdscr ); +} + +static inline int getch ( void ) { + return wgetch ( stdscr ); +} + +static inline int getnstr ( char *str, int n ) { + return wgetnstr ( stdscr, str, n ); +} + +static inline int getstr ( char *str ) { + return wgetnstr ( stdscr, str, -1 ); +} + +static inline bool has_colors ( void ) { + return TRUE; +} + +static inline int has_key ( int kc __unused ) { + return TRUE; +} + +static inline int hline ( chtype ch, int n ) { + return whline ( stdscr, ch, n ); +} + +static inline int move ( int y, int x ) { + return wmove ( stdscr, y, x ); +} + +static inline int mvaddch ( int y, int x, const chtype ch ) { + return ( wmove ( stdscr, y, x ) == OK + ? waddch( stdscr, ch ) : ERR ); +} + +static inline int mvaddchnstr ( int y, int x, const chtype *chstr, int n ) { + return ( wmove ( stdscr, y, x ) == OK + ? waddchnstr ( stdscr, chstr, n ) : ERR ); +} + +static inline int mvaddchstr ( int y, int x, const chtype *chstr ) { + return ( wmove ( stdscr, y, x ) == OK + ? waddchnstr ( stdscr, chstr, -1 ) : ERR ); +} + +static inline int mvaddnstr ( int y, int x, const char *str, int n ) { + return ( wmove ( stdscr, y, x ) == OK + ? waddnstr ( stdscr, str, n ) : ERR ); +} + +static inline int mvaddstr ( int y, int x, const char *str ) { + return ( wmove ( stdscr, y, x ) == OK + ? waddnstr ( stdscr, str, -1 ) : ERR ); +} + +static inline int mvdelch ( int y, int x ) { + return ( wmove ( stdscr, y, x ) == OK + ? wdelch ( stdscr ) : ERR ); +} + +static inline int mvgetch ( int y, int x ) { + return ( wmove ( stdscr, y, x ) == OK + ? wgetch ( stdscr ) : ERR ); +} + +static inline int mvgetnstr ( int y, int x, char *str, int n ) { + return ( wmove ( stdscr, y, x ) == OK + ? wgetnstr ( stdscr, str, n ) : ERR ); +} + +static inline int mvgetstr ( int y, int x, char *str ) { + return ( wmove ( stdscr, y, x ) == OK + ? wgetnstr ( stdscr, str, -1 ) : ERR ); +} + +static inline int mvhline ( int y, int x, chtype ch, int n ) { + return ( wmove ( stdscr, y, x ) == OK + ? whline ( stdscr, ch, n ) : ERR ); +} + +// OK, so maybe a few I did with macros... +#define mvprintw( y, x, fmt, ... ) \ + ( wmove(stdscr,(y),(x)) == OK \ + ? wprintw( stdscr,(fmt), ## __VA_ARGS__ ) : ERR ) + +static inline int mvvline ( int y, int x, chtype ch, int n ) { + return ( wmove ( stdscr, y, x ) == OK + ? wvline ( stdscr, ch, n ) : ERR ); +} + +static inline int mvwaddch ( WINDOW *win, int y, int x, const chtype ch ) { + return ( wmove( win, y, x ) == OK + ? waddch ( win, ch ) : ERR ); +} + +static inline int mvwaddchnstr ( WINDOW *win, int y, int x, const chtype *chstr, int n ) { + return ( wmove ( win, y, x ) == OK + ? waddchnstr ( win, chstr, n ) : ERR ); +} + +static inline int mvwaddchstr ( WINDOW *win, int y, int x, const chtype *chstr ) { + return ( wmove ( win, y, x ) == OK + ? waddchnstr ( win, chstr, -1 ) : ERR ); +} + +static inline int mvwaddnstr ( WINDOW *win, int y, int x, const char *str, int n ) { + return ( wmove ( win, y, x ) == OK + ? waddnstr ( win, str, n ) : ERR ); +} + +static inline int mvwaddstr ( WINDOW *win, int y, int x, const char *str ) { + return ( wmove ( win, y, x ) == OK + ? waddnstr ( win, str, -1 ) : ERR ); +} + +static inline int mvwdelch ( WINDOW *win, int y, int x ) { + return ( wmove ( win, y, x ) == OK + ? wdelch ( win ) : ERR ); +} + +static inline int mvwgetch ( WINDOW *win, int y, int x ) { + return ( wmove ( win, y, x ) == OK + ? wgetch ( win ) : ERR ); +} + +static inline int mvwgetnstr ( WINDOW *win, int y, int x, char *str, int n ) { + return ( wmove ( win, y, x ) == OK + ? wgetnstr ( win, str, n ) : ERR ); +} + +static inline int mvwgetstr ( WINDOW *win, int y, int x, char *str ) { + return ( wmove ( win, y, x ) == OK + ? wgetnstr ( win, str, -1 ) : ERR ); +} + +static inline int mvwhline ( WINDOW *win, int y, int x, chtype ch, int n ) { + return ( wmove ( win, y, x ) == OK + ? whline ( win, ch, n ) : ERR ); +} + +#define mvwprintw( win, y, x, fmt, ... ) \ + ( wmove((win),(y),(x)) == OK \ + ? wprintw((win),(fmt), ## __VA_ARGS__) : ERR ) + +static inline int mvwvline ( WINDOW *win, int y, int x, chtype ch, int n ) { + return ( wmove ( win, y, x ) == OK + ? wvline ( win, ch, n ) : ERR ); +} + +#define printw( fmt, ... ) wprintw(stdscr,(fmt), ## __VA_ARGS__ ) + +static inline int slk_refresh ( void ) { + if ( slk_clear() == OK ) + return slk_restore(); + else + return ERR; +} + +#define standend() wstandend( stdscr ) +#define standout() wstandout( stdscr ) + +static inline int start_colour ( void ) { + return OK; +} + +static inline int vline ( chtype ch, int n ) { + return wvline ( stdscr, ch, n ); +} + +// marked for removal +static inline int vwprintw ( WINDOW *win, const char *fmt, va_list varglist ) { + return vw_printw ( win, fmt, varglist ); +} + +static inline int waddchstr ( WINDOW *win, const chtype *chstr ) { + return waddchnstr ( win, chstr, -1 ); +} + +static inline int waddstr ( WINDOW *win, const char *str ) { + return waddnstr ( win, str, -1 ); +} + +static inline int wbkgdset ( WINDOW *win, chtype ch ) { + return wattrset( win, ch ); +} + +static inline int wgetstr ( WINDOW *win, char *str ) { + return wgetnstr ( win, str, -1 ); +} + +static inline int wstandend ( WINDOW *win ) { + return wattrset ( win, A_DEFAULT ); +} + +static inline int wstandout ( WINDOW *win ) { + return wattrset ( win, A_STANDOUT ); +} + +#endif /* CURSES_H */ diff --git a/gpxe/src/include/debug.h b/gpxe/src/include/debug.h new file mode 100644 index 00000000..bb5d33f3 --- /dev/null +++ b/gpxe/src/include/debug.h @@ -0,0 +1,28 @@ +#ifndef DEBUG_H +#define DEBUG_H + +//#include <lib.h> +extern int last_putchar; + +/* Defining DEBUG_THIS before including this file enables debug() macro + * for the file. DEBUG_ALL is for global control. */ + +#if DEBUG_THIS || DEBUG_ALL +#define DEBUG 1 +#else +#undef DEBUG +#endif + +#if DEBUG +# define debug(...) \ + ((last_putchar=='\n' ? printf("%s: ", __FUNCTION__) : 0), \ + printf(__VA_ARGS__)) +# define debug_hexdump hexdump +#else +# define debug(...) /* nothing */ +# define debug_hexdump(...) /* nothing */ +#endif + +#define debugx debug + +#endif /* DEBUG_H */ diff --git a/gpxe/src/include/dhcp.h b/gpxe/src/include/dhcp.h new file mode 100644 index 00000000..deba219b --- /dev/null +++ b/gpxe/src/include/dhcp.h @@ -0,0 +1,12 @@ +#ifndef DHCP_H +#define DHCP_H + +#include "stdint.h" + +struct dhcp_dev_id { + uint8_t bus_type; + uint16_t vendor_id; + uint16_t device_id; +} __attribute__ (( packed )); + +#endif /* DHCP_H */ diff --git a/gpxe/src/include/elf.h b/gpxe/src/include/elf.h new file mode 100644 index 00000000..a6eb5d9c --- /dev/null +++ b/gpxe/src/include/elf.h @@ -0,0 +1,236 @@ +#ifndef ELF_H +#define ELF_H + +#define EI_NIDENT 16 /* Size of e_ident array. */ + +/* Values for e_type. */ +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ + +/* Values for e_machine (architecute). */ +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386+ */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_486 6 /* Perhaps disused */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ + +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_AT19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_NUM 95 + +/* Values for p_type. */ +#define PT_NULL 0 /* Unused entry. */ +#define PT_LOAD 1 /* Loadable segment. */ +#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ +#define PT_INTERP 3 /* Pathname of interpreter. */ +#define PT_NOTE 4 /* Auxiliary information. */ +#define PT_SHLIB 5 /* Reserved (not used). */ +#define PT_PHDR 6 /* Location of program header itself. */ + +/* Values for p_flags. */ +#define PF_X 0x1 /* Executable. */ +#define PF_W 0x2 /* Writable. */ +#define PF_R 0x4 /* Readable. */ + + +#define ELF_PROGRAM_RETURNS_BIT 0x8000000 /* e_flags bit 31 */ + +#define EI_MAG0 0 +#define ELFMAG0 0x7f + +#define EI_MAG1 1 +#define ELFMAG1 'E' + +#define EI_MAG2 2 +#define ELFMAG2 'L' + +#define EI_MAG3 3 +#define ELFMAG3 'F' + +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ + +#define EI_DATA 5 /* Data encodeing byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement little endian */ +#define ELFDATA2MSB 2 /* 2's complement big endian */ + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EV_NONE 0 /* Invalid ELF Version */ +#define EV_CURRENT 1 /* Current version */ + +#define ELF32_PHDR_SIZE (8*4) /* Size of an elf program header */ + +#ifndef ASSEMBLY + +#include <stdint.h> + +/* + * ELF definitions common to all 32-bit architectures. + */ + +typedef uint32_t Elf32_Addr; +typedef uint16_t Elf32_Half; +typedef uint32_t Elf32_Off; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf32_Word; +typedef uint32_t Elf32_Size; + +typedef uint64_t Elf64_Addr; +typedef uint16_t Elf64_Half; +typedef uint64_t Elf64_Off; +typedef int32_t Elf64_Sword; +typedef uint32_t Elf64_Word; +typedef uint64_t Elf64_Size; + +/* + * ELF header. + */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* File identification. */ + Elf32_Half e_type; /* File type. */ + Elf32_Half e_machine; /* Machine architecture. */ + Elf32_Word e_version; /* ELF format version. */ + Elf32_Addr e_entry; /* Entry point. */ + Elf32_Off e_phoff; /* Program header file offset. */ + Elf32_Off e_shoff; /* Section header file offset. */ + Elf32_Word e_flags; /* Architecture-specific flags. */ + Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ + Elf32_Half e_phentsize; /* Size of program header entry. */ + Elf32_Half e_phnum; /* Number of program header entries. */ + Elf32_Half e_shentsize; /* Size of section header entry. */ + Elf32_Half e_shnum; /* Number of section header entries. */ + Elf32_Half e_shstrndx; /* Section name strings section. */ +} Elf32_Ehdr; + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* File identification. */ + Elf64_Half e_type; /* File type. */ + Elf64_Half e_machine; /* Machine architecture. */ + Elf64_Word e_version; /* ELF format version. */ + Elf64_Addr e_entry; /* Entry point. */ + Elf64_Off e_phoff; /* Program header file offset. */ + Elf64_Off e_shoff; /* Section header file offset. */ + Elf64_Word e_flags; /* Architecture-specific flags. */ + Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ + Elf64_Half e_phentsize; /* Size of program header entry. */ + Elf64_Half e_phnum; /* Number of program header entries. */ + Elf64_Half e_shentsize; /* Size of section header entry. */ + Elf64_Half e_shnum; /* Number of section header entries. */ + Elf64_Half e_shstrndx; /* Section name strings section. */ +} Elf64_Ehdr; + +/* + * Program header. + */ +typedef struct { + Elf32_Word p_type; /* Entry type. */ + Elf32_Off p_offset; /* File offset of contents. */ + Elf32_Addr p_vaddr; /* Virtual address (not used). */ + Elf32_Addr p_paddr; /* Physical address. */ + Elf32_Size p_filesz; /* Size of contents in file. */ + Elf32_Size p_memsz; /* Size of contents in memory. */ + Elf32_Word p_flags; /* Access permission flags. */ + Elf32_Size p_align; /* Alignment in memory and file. */ +} Elf32_Phdr; + +typedef struct { + Elf64_Word p_type; /* Entry type. */ + Elf64_Word p_flags; /* Access permission flags. */ + Elf64_Off p_offset; /* File offset of contents. */ + Elf64_Addr p_vaddr; /* Virtual address (not used). */ + Elf64_Addr p_paddr; /* Physical address. */ + Elf64_Size p_filesz; /* Size of contents in file. */ + Elf64_Size p_memsz; /* Size of contents in memory. */ + Elf64_Size p_align; /* Alignment in memory and file. */ +} Elf64_Phdr; + +/* Standardized Elf image notes for booting... The name for all of these is ELFBoot */ + + +/* ELF Defines for the current architecture */ +#include "bits/elf.h" + +#endif /* ASSEMBLY */ + +#endif /* ELF_H */ diff --git a/gpxe/src/include/endian.h b/gpxe/src/include/endian.h new file mode 100644 index 00000000..32006224 --- /dev/null +++ b/gpxe/src/include/endian.h @@ -0,0 +1,19 @@ +#ifndef ETHERBOOT_ENDIAN_H +#define ETHERBOOT_ENDIAN_H + +/* Definitions for byte order, according to significance of bytes, + from low addresses to high addresses. The value is what you get by + putting '4' in the most significant byte, '3' in the second most + significant byte, '2' in the second least significant byte, and '1' + in the least significant byte, and then writing down one digit for + each byte, starting with the byte at the lowest address at the left, + and proceeding to the byte with the highest address at the right. */ + +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __PDP_ENDIAN 3412 + +#include "bits/endian.h" + + +#endif /* ETHERBOOT_ENDIAN_H */ diff --git a/gpxe/src/include/errno.h b/gpxe/src/include/errno.h new file mode 100644 index 00000000..58dff1fd --- /dev/null +++ b/gpxe/src/include/errno.h @@ -0,0 +1,508 @@ +#ifndef ERRNO_H +#define ERRNO_H + +/** @file + * + * Error codes + * + * Return status codes as used within gPXE are designed to allow for + * maximum visibility into the source of an error even in an end-user + * build with no debugging. They are constructed as follows: + * + * Bits 7-0 : PXE error code + * + * This is the closest equivalent PXE error code + * (e.g. PXENV_STATUS_OUT_OF_RESOURCES), and is the only part of the + * error that will be returned via the PXE API, since PXE has + * predefined error codes. + * + * Bits 12-8 : Per-file disambiguator + * + * When the same error number can be generated from multiple points + * within a file, this field can be used to identify the unique + * instance. + * + * Bits 23-13 : File identifier + * + * This is a unique identifier for the file generating the error + * (e.g. ERRFILE_tcp for tcp.c). + * + * Bits 30-24 : POSIX error code + * + * This is the closest equivalent POSIX error code (e.g. ENOMEM). + * + * Bit 31 : Reserved + * + * Errors are usually return as negative error numbers (e.g. -EINVAL); + * bit 31 is therefore unusable. + * + * + * The convention within the code is that errors are negative and + * expressed using the POSIX error code and (optionally) a per-file + * disambiguator, e.g. + * + * return -EINVAL; + * + * or + * + * #define ETCP_BAD_CHECKSUM EUNIQ_02 + * return -( EINVAL | ETCP_BAD_CHECKSUM ) + * + * By various bits of preprocessor magic, the PXE error code and file + * identifier are already incorporated into the definition of the + * POSIX error code, which keeps the code relatively clean. + * + * + * Functions that wish to return failures should be declared as + * returning an integer @c rc "Return status code". A return value of + * zero indicates success, a non-zero value indicates failure. The + * return value can be passed directly to strerror() in order to + * generate a human-readable error message, e.g. + * + * if ( ( rc = some_function ( ... ) ) != 0 ) { + * DBG ( "Whatever I was trying to do failed: %s\n", strerror ( rc ) ); + * return rc; + * } + * + * As illustrated in the above example, error returns should generally + * be directly propagated upward to the calling function. + * + */ + +/* Get definitions for file identifiers */ +#include <gpxe/errfile.h> + +/* If we do not have a valid file identifier, generate a compiler + * warning upon usage of any error codes. (Don't just use a #warning, + * because some files include errno.h but don't ever actually use any + * error codes.) + */ +#if ! ERRFILE +extern char missing_errfile_declaration[] __attribute__ (( deprecated )); +#undef ERRFILE +#define ERRFILE ( 0 * ( ( int ) missing_errfile_declaration ) ) +#endif + +/** Derive PXENV_STATUS code from gPXE error number */ +#define PXENV_STATUS( rc ) ( (-(rc)) & 0x00ff ) + +/** + * @defgroup pxeerrors PXE error codes + * + * The names, meanings and values of these error codes are defined by + * the PXE specification. + * + * @{ + */ + +/* 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 + +/** @} */ + +/** + * @defgroup posixerrors POSIX error codes + * + * The names and meanings (but not the values) of these error codes + * are defined by POSIX. We choose to assign unique values which + * incorporate the closest equivalent PXE error code, so that code may + * simply use ENOMEM, rather than having to use the cumbersome + * (ENOMEM|PXENV_STATUS_OUT_OF_RESOURCES). + * + * @{ + */ + +/** Operation completed successfully */ +#define ENOERR ( ERRFILE | PXENV_STATUS_SUCCESS | 0x00000000 ) + +/** Arg list too long */ +#define E2BIG ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x01000000 ) + +/** Permission denied */ +#define EACCES ( ERRFILE | PXENV_STATUS_TFTP_ACCESS_VIOLATION | 0x02000000 ) + +/** Address in use */ +#define EADDRINUSE ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x03000000 ) + +/** Address not available */ +#define EADDRNOTAVAIL ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x04000000 ) + +/** Address family not supported */ +#define EAFNOSUPPORT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x05000000 ) + +/** Resource temporarily unavailable */ +#define EAGAIN ( ERRFILE | PXENV_STATUS_FAILURE | 0x06000000 ) + +/** Connection already in progress */ +#define EALREADY ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x07000000 ) + +/** Bad file descriptor */ +#define EBADF ( ERRFILE | PXENV_STATUS_TFTP_CLOSED | 0x08000000 ) + +/** Bad message */ +#define EBADMSG ( ERRFILE | PXENV_STATUS_FAILURE | 0x09000000 ) + +/** Resource busy */ +#define EBUSY ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x0a000000 ) + +/** Operation canceled */ +#define ECANCELED \ + ( ERRFILE | PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE | 0x0b000000 ) + +/** No child processes */ +#define ECHILD ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x0c000000 ) + +/** Connection aborted */ +#define ECONNABORTED \ + ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x0d000000 ) + +/** Connection refused */ +#define ECONNREFUSED \ + ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION | 0x0e000000 ) + +/** Connection reset */ +#define ECONNRESET \ + ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x0f000000 ) + +/** Resource deadlock avoided */ +#define EDEADLK ( ERRFILE | PXENV_STATUS_FAILURE | 0x10000000 ) + +/** Destination address required */ +#define EDESTADDRREQ ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x11000000 ) + +/** Domain error */ +#define EDOM ( ERRFILE | PXENV_STATUS_FAILURE | 0x12000000 ) + +/** Reserved */ +#define EDQUOT ( ERRFILE | PXENV_STATUS_FAILURE | 0x13000000 ) + +/** File exists */ +#define EEXIST ( ERRFILE | PXENV_STATUS_FAILURE | 0x14000000 ) + +/** Bad address */ +#define EFAULT ( ERRFILE | PXENV_STATUS_MCOPY_PROBLEM | 0x15000000 ) + +/** File too large */ +#define EFBIG ( ERRFILE | PXENV_STATUS_MCOPY_PROBLEM | 0x16000000 ) + +/** Host is unreachable */ +#define EHOSTUNREACH ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x17000000 ) + +/** Identifier removed */ +#define EIDRM ( ERRFILE | PXENV_STATUS_FAILURE | 0x18000000 ) + +/** Illegal byte sequence */ +#define EILSEQ ( ERRFILE | PXENV_STATUS_FAILURE | 0x19000000 ) + +/** Operation in progress */ +#define EINPROGRESS ( ERRFILE | PXENV_STATUS_FAILURE | 0x1a000000 ) + +/** Interrupted function call */ +#define EINTR ( ERRFILE | PXENV_STATUS_FAILURE | 0x1b000000 ) + +/** Invalid argument */ +#define EINVAL ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x1c000000 ) + +/** Input/output error */ +#define EIO \ + ( ERRFILE | PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION | 0x1d000000 ) + +/** Socket is connected */ +#define EISCONN ( ERRFILE | PXENV_STATUS_UDP_OPEN | 0x1e000000 ) + +/** Is a directory */ +#define EISDIR ( ERRFILE | PXENV_STATUS_FAILURE | 0x1f000000 ) + +/** Too many levels of symbolic links */ +#define ELOOP ( ERRFILE | PXENV_STATUS_FAILURE | 0x20000000 ) + +/** Too many open files */ +#define EMFILE ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x21000000 ) + +/** Too many links */ +#define EMLINK ( ERRFILE | PXENV_STATUS_FAILURE | 0x22000000 ) + +/** Inappropriate message buffer length */ +#define EMSGSIZE ( ERRFILE | PXENV_STATUS_BAD_FUNC | 0x23000000 ) + +/** Reserved */ +#define EMULTIHOP ( ERRFILE | PXENV_STATUS_FAILURE | 0x24000000 ) + +/** Filename too long */ +#define ENAMETOOLONG ( ERRFILE | PXENV_STATUS_FAILURE | 0x25000000 ) + +/** Network is down */ +#define ENETDOWN ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x26000000 ) + +/** Connection aborted by network */ +#define ENETRESET ( ERRFILE | PXENV_STATUS_FAILURE | 0x27000000 ) + +/** Network unreachable */ +#define ENETUNREACH ( ERRFILE | PXENV_STATUS_ARP_TIMEOUT | 0x28000000 ) + +/** Too many open files in system */ +#define ENFILE ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x29000000 ) + +/** No buffer space available */ +#define ENOBUFS ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x2a000000 ) + +/** No message is available on the STREAM head read queue */ +#define ENODATA ( ERRFILE | PXENV_STATUS_FAILURE | 0x2b000000 ) + +/** No such device */ +#define ENODEV ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x2c000000 ) + +/** No such file or directory */ +#define ENOENT ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x2d000000 ) + +/** Exec format error */ +#define ENOEXEC ( ERRFILE | PXENV_STATUS_FAILURE | 0x2e000000 ) + +/** No locks available */ +#define ENOLCK ( ERRFILE | PXENV_STATUS_FAILURE | 0x2f000000 ) + +/** Reserved */ +#define ENOLINK ( ERRFILE | PXENV_STATUS_FAILURE | 0x30000000 ) + +/** Not enough space */ +#define ENOMEM ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x31000000 ) + +/** No message of the desired type */ +#define ENOMSG ( ERRFILE | PXENV_STATUS_FAILURE | 0x32000000 ) + +/** Protocol not available */ +#define ENOPROTOOPT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x33000000 ) + +/** No space left on device */ +#define ENOSPC ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x34000000 ) + +/** No STREAM resources */ +#define ENOSR ( ERRFILE | PXENV_STATUS_OUT_OF_RESOURCES | 0x35000000 ) + +/** Not a STREAM */ +#define ENOSTR ( ERRFILE | PXENV_STATUS_FAILURE | 0x36000000 ) + +/** Function not implemented */ +#define ENOSYS ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x37000000 ) + +/** The socket is not connected */ +#define ENOTCONN ( ERRFILE | PXENV_STATUS_FAILURE | 0x38000000 ) + +/** Not a directory */ +#define ENOTDIR ( ERRFILE | PXENV_STATUS_FAILURE | 0x39000000 ) + +/** Directory not empty */ +#define ENOTEMPTY ( ERRFILE | PXENV_STATUS_FAILURE | 0x3a000000 ) + +/** Not a socket */ +#define ENOTSOCK ( ERRFILE | PXENV_STATUS_FAILURE | 0x3b000000 ) + +/** Not supported */ +#define ENOTSUP ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x3c000000 ) + +/** Inappropriate I/O control operation */ +#define ENOTTY ( ERRFILE | PXENV_STATUS_FAILURE | 0x3d000000 ) + +/** No such device or address */ +#define ENXIO ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x3e000000 ) + +/** Operation not supported on socket */ +#define EOPNOTSUPP ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x3f000000 ) + +/** Value too large to be stored in data type */ +#define EOVERFLOW ( ERRFILE | PXENV_STATUS_FAILURE | 0x40000000 ) + +/** Operation not permitted */ +#define EPERM ( ERRFILE | PXENV_STATUS_TFTP_ACCESS_VIOLATION | 0x41000000 ) + +/** Broken pipe */ +#define EPIPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x42000000 ) + +/** Protocol error */ +#define EPROTO ( ERRFILE | PXENV_STATUS_FAILURE | 0x43000000 ) + +/** Protocol not supported */ +#define EPROTONOSUPPORT ( ERRFILE | PXENV_STATUS_UNSUPPORTED | 0x44000000 ) + +/** Protocol wrong type for socket */ +#define EPROTOTYPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x45000000 ) + +/** Result too large */ +#define ERANGE ( ERRFILE | PXENV_STATUS_FAILURE | 0x46000000 ) + +/** Read-only file system */ +#define EROFS ( ERRFILE | PXENV_STATUS_FAILURE | 0x47000000 ) + +/** Invalid seek */ +#define ESPIPE ( ERRFILE | PXENV_STATUS_FAILURE | 0x48000000 ) + +/** No such process */ +#define ESRCH ( ERRFILE | PXENV_STATUS_TFTP_FILE_NOT_FOUND | 0x49000000 ) + +/** Stale file handle */ +#define ESTALE ( ERRFILE | PXENV_STATUS_FAILURE | 0x4a000000 ) + +/** STREAM ioctl() timeout */ +#define ETIME ( ERRFILE | PXENV_STATUS_FAILURE | 0x4b000000 ) + +/** Operation timed out */ +#define ETIMEDOUT ( ERRFILE | PXENV_STATUS_TFTP_READ_TIMEOUT | 0x4c000000 ) + +/** Text file busy */ +#define ETXTBSY ( ERRFILE | PXENV_STATUS_FAILURE | 0x4d000000 ) + +/** Operation would block (different from EAGAIN!) */ +#define EWOULDBLOCK ( ERRFILE | PXENV_STATUS_TFTP_OPEN | 0x4e000000 ) + +/** Improper link */ +#define EXDEV ( ERRFILE | PXENV_STATUS_FAILURE | 0x4f000000 ) + +/** @} */ + +/** + * @defgroup euniq Per-file error disambiguators + * + * Files which use the same error number multiple times should + * probably define their own error subspace using these + * disambiguators. For example: + * + * #define ETCP_HEADER_TOO_SHORT EUNIQ_01 + * #define ETCP_BAD_CHECKSUM EUNIQ_02 + * + * @{ + */ + +#define EUNIQ_01 0x00000100 +#define EUNIQ_02 0x00000200 +#define EUNIQ_03 0x00000300 +#define EUNIQ_04 0x00000400 +#define EUNIQ_05 0x00000500 +#define EUNIQ_06 0x00000600 +#define EUNIQ_07 0x00000700 +#define EUNIQ_08 0x00000800 +#define EUNIQ_09 0x00000900 +#define EUNIQ_0A 0x00000a00 +#define EUNIQ_0B 0x00000b00 +#define EUNIQ_0C 0x00000c00 +#define EUNIQ_0D 0x00000d00 +#define EUNIQ_0E 0x00000e00 +#define EUNIQ_0F 0x00000f00 +#define EUNIQ_10 0x00001000 +#define EUNIQ_11 0x00001100 +#define EUNIQ_12 0x00001200 +#define EUNIQ_13 0x00001300 +#define EUNIQ_14 0x00001400 +#define EUNIQ_15 0x00001500 +#define EUNIQ_16 0x00001600 +#define EUNIQ_17 0x00001700 +#define EUNIQ_18 0x00001800 +#define EUNIQ_19 0x00001900 +#define EUNIQ_1A 0x00001a00 +#define EUNIQ_1B 0x00001b00 +#define EUNIQ_1C 0x00001c00 +#define EUNIQ_1D 0x00001d00 +#define EUNIQ_1E 0x00001e00 +#define EUNIQ_1F 0x00001f00 + +/** @} */ + +extern int errno; + +#endif /* ERRNO_H */ diff --git a/gpxe/src/include/etherboot.h b/gpxe/src/include/etherboot.h new file mode 100644 index 00000000..2a465954 --- /dev/null +++ b/gpxe/src/include/etherboot.h @@ -0,0 +1,42 @@ +#ifndef ETHERBOOT_H +#define ETHERBOOT_H + +/* + * Standard includes that we always want + * + */ + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <strings.h> +#include <console.h> +#include <gpxe/timer.h> +#include <gpxe/if_arp.h> +#include <gpxe/if_ether.h> + +typedef unsigned long Address; + +/* + * IMPORTANT!!!!!!!!!!!!!! + * + * Everything below this point is cruft left over from older versions + * of Etherboot. Do not add *anything* below this point. Things are + * gradually being moved to individual header files. + * + */ + +/* Link configuration time in tenths of a second */ +#ifndef VALID_LINK_TIMEOUT +#define VALID_LINK_TIMEOUT 100 /* 10.0 seconds */ +#endif + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ + +#endif /* ETHERBOOT_H */ diff --git a/gpxe/src/include/fs.h b/gpxe/src/include/fs.h new file mode 100644 index 00000000..1dfe8fd9 --- /dev/null +++ b/gpxe/src/include/fs.h @@ -0,0 +1,41 @@ +#ifndef FS_H +#define FS_H + +#include <stdint.h> + +//typedef uint64_t sector_t; + +#ifdef IDE_DISK +int ide_probe(int drive); +int ide_read(int drive, sector_t sector, void *buffer); +#endif + +#ifdef USB_DISK +int usb_probe(int drive); +int usb_read(int drive, sector_t sector, void *buffer); +#endif + +#define DISK_IDE 1 +#define DISK_MEM 2 +#define DISK_USB 3 + +int devopen(const char *name, int *reopen); +int devread(unsigned long sector, unsigned long byte_offset, + unsigned long byte_len, void *buf); + +int file_open(const char *filename); +int file_read(void *buf, unsigned long len); +int file_seek(unsigned long offset); +unsigned long file_size(void); + +#define PARTITION_UNKNOWN 0xbad6a7 + +#ifdef ELTORITO +int open_eltorito_image(int part, unsigned long *start, unsigned long *length); +#else +# define open_eltorito_image(x,y,z) PARTITION_UNKNOWN +#endif + +extern int using_devsize; + +#endif /* FS_H */ diff --git a/gpxe/src/include/getopt.h b/gpxe/src/include/getopt.h new file mode 100644 index 00000000..2505223e --- /dev/null +++ b/gpxe/src/include/getopt.h @@ -0,0 +1,92 @@ +#ifndef _GETOPT_H +#define _GETOPT_H + +/** @file + * + * Parse command-line options + * + */ + +#include <stddef.h> + +enum getopt_argument_requirement { + /** Option does not take an argument */ + no_argument = 0, + /** Option requires an argument */ + required_argument = 1, + /** Option may have an argument */ + optional_argument = 2, +}; + +/** A long option, as used for getopt_long() */ +struct option { + /** Long name of this option */ + const char *name; + /** Option takes an argument + * + * Must be one of @c no_argument, @c required_argument, or @c + * optional_argument. + */ + int has_arg; + /** Location into which to store @c val, or NULL. + * + * See the description for @c val for more details. + */ + int *flag; + /** Value to return + * + * If @c flag is NULL, then this is the value that will be + * returned by getopt_long() when this option is found, and + * should therefore be set to the equivalent short option + * character. + * + * If @c flag is non-NULL, then this value will be written to + * the location pointed to by @flag, and getopt_long() will + * return 0. + */ + int val; +}; + +extern char *optarg; +extern int optind; +extern int nextchar; +extern int optopt; + +extern int getopt_long ( int argc, char * const argv[], const char *optstring, + const struct option *longopts, int *longindex ); + +/** + * Parse command-line options + * + * @v argv Argument count + * @v argv Argument list + * @v optstring Option specification string + * @ret option Option found, or -1 for no more options + * + * See getopt_long() for full details. + */ +static inline int getopt ( int argc, char * const argv[], + const char *optstring ) { + static const struct option no_options[] = { + { NULL, 0, NULL, 0 } + }; + return getopt_long ( argc, argv, optstring, no_options, NULL ); +} + +/** + * Reset getopt() internal state + * + * Due to a limitation of the POSIX getopt() API, it is necessary to + * add a call to reset_getopt() before each set of calls to getopt() + * or getopt_long(). This arises because POSIX assumes that each + * process will parse command line arguments no more than once; this + * assumption is not valid within Etherboot. We work around the + * limitation by arranging for execv() to call reset_getopt() before + * executing the command. + */ +static inline void reset_getopt ( void ) { + optind = 1; + nextchar = 0; +} + +#endif /* _GETOPT_H */ diff --git a/gpxe/src/include/gpxe/abft.h b/gpxe/src/include/gpxe/abft.h new file mode 100644 index 00000000..1c651ef1 --- /dev/null +++ b/gpxe/src/include/gpxe/abft.h @@ -0,0 +1,35 @@ +#ifndef _GPXE_ABFT_H +#define _GPXE_ABFT_H + +/** @file + * + * AoE boot firmware table + * + */ + +#include <stdint.h> +#include <gpxe/acpi.h> +#include <gpxe/if_ether.h> + +/** AoE boot firmware table signature */ +#define ABFT_SIG "aBFT" + +/** + * AoE Boot Firmware Table (aBFT) + */ +struct abft_table { + /** ACPI header */ + struct acpi_description_header acpi; + /** AoE shelf */ + uint16_t shelf; + /** AoE slot */ + uint8_t slot; + /** Reserved */ + uint8_t reserved_a; + /** MAC address */ + uint8_t mac[ETH_ALEN]; +} __attribute__ (( packed )); + +extern void abft_fill_data ( struct aoe_session *aoe ); + +#endif /* _GPXE_ABFT_H */ diff --git a/gpxe/src/include/gpxe/acpi.h b/gpxe/src/include/gpxe/acpi.h new file mode 100644 index 00000000..33b1b2b7 --- /dev/null +++ b/gpxe/src/include/gpxe/acpi.h @@ -0,0 +1,41 @@ +#ifndef _GPXE_ACPI_H +#define _GPXE_ACPI_H + +/** @file + * + * ACPI data structures + * + */ + +#include <stdint.h> + +/** + * An ACPI description header + * + * This is the structure common to the start of all ACPI system + * description tables. + */ +struct acpi_description_header { + /** ACPI signature (4 ASCII characters) */ + char signature[4]; + /** Length of table, in bytes, including header */ + uint32_t length; + /** ACPI Specification minor version number */ + uint8_t revision; + /** To make sum of entire table == 0 */ + uint8_t checksum; + /** OEM identification */ + char oem_id[6]; + /** OEM table identification */ + char oem_table_id[8]; + /** OEM revision number */ + uint32_t oem_revision; + /** ASL compiler vendor ID */ + char asl_compiler_id[4]; + /** ASL compiler revision number */ + uint32_t asl_compiler_revision; +} __attribute__ (( packed )); + +extern void acpi_fix_checksum ( struct acpi_description_header *acpi ); + +#endif /* _GPXE_ACPI_H */ diff --git a/gpxe/src/include/gpxe/aes.h b/gpxe/src/include/gpxe/aes.h new file mode 100644 index 00000000..75cb4c44 --- /dev/null +++ b/gpxe/src/include/gpxe/aes.h @@ -0,0 +1,8 @@ +#ifndef _GPXE_AES_H +#define _GPXE_AES_H + +struct crypto_algorithm; + +extern struct crypto_algorithm aes_algorithm; + +#endif /* _GPXE_AES_H */ diff --git a/gpxe/src/include/gpxe/ansiesc.h b/gpxe/src/include/gpxe/ansiesc.h new file mode 100644 index 00000000..ccc4ca65 --- /dev/null +++ b/gpxe/src/include/gpxe/ansiesc.h @@ -0,0 +1,118 @@ +#ifndef _GPXE_ANSIESC_H +#define _GPXE_ANSIESC_H + +/** @file + * + * ANSI escape sequences + * + * ANSI X3.64 (aka ECMA-48 or ISO/IEC 6429, available from + * http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf) + * defines escape sequences consisting of: + * + * A Control Sequence Introducer (CSI) + * + * Zero or more Parameter Bytes (P) + * + * Zero or more Intermediate Bytes (I) + * + * A Final Byte (F) + * + * The CSI consists of ESC (0x1b) followed by "[" (0x5b). The + * Parameter Bytes, for a standardised (i.e. not private or + * experimental) sequence, consist of a list of ASCII decimal integers + * separated by semicolons. The Intermediate Bytes (in the range 0x20 + * to 0x2f) and the Final Byte (in the range 0x40 to 0x4f) determine + * the control function. + * + */ + +/** A handler for an escape sequence */ +struct ansiesc_handler { + /** The control function identifier + * + * The control function identifier consists of the + * Intermediate Bytes (if any) and the Final Byte. In + * practice, no more than one immediate byte is ever used, so + * the byte combination can be efficiently expressed as a + * single integer, in the obvious way (with the Final Byte + * being the least significant byte). + */ + unsigned int function; + /** Handle escape sequence + * + * @v count Parameter count + * @v params Parameter list + * + * A negative parameter value indicates that the parameter was + * omitted and that the default value for this control + * function should be used. + * + * Since all parameters are optional, there is no way to + * distinguish between "zero parameters" and "single parameter + * omitted". Consequently, the parameter list will always + * contain at least one item. + */ + void ( * handle ) ( unsigned int count, int params[] ); +}; + +/** Maximum number of parameters within a single escape sequence */ +#define ANSIESC_MAX_PARAMS 4 + +/** + * ANSI escape sequence context + * + * This provides temporary storage for processing escape sequences, + * and points to the list of escape sequence handlers. + */ +struct ansiesc_context { + /** Array of handlers + * + * Must be terminated by a handler with @c function set to + * zero. + */ + struct ansiesc_handler *handlers; + /** Parameter count + * + * Will be zero when not currently in an escape sequence. + */ + unsigned int count; + /** Parameter list */ + int params[ANSIESC_MAX_PARAMS]; + /** Control function identifier */ + unsigned int function; +}; + +/** Escape character */ +#define ESC 0x1b + +/** Control Sequence Introducer */ +#define CSI "\033[" + +/** + * @defgroup ansifuncs ANSI escape sequence function identifiers + * @{ + */ + +/** Cursor position */ +#define ANSIESC_CUP 'H' + +/** Erase in page */ +#define ANSIESC_ED 'J' + +/** Erase from cursor to end of page */ +#define ANSIESC_ED_TO_END 0 + +/** Erase from start of page to cursor */ +#define ANSIESC_ED_FROM_START 1 + +/** Erase whole page */ +#define ANSIESC_ED_ALL 2 + +/** Select graphic rendition */ +#define ANSIESC_SGR 'm' + +/** @} */ + +extern int ansiesc_process ( struct ansiesc_context *ctx, int c ); + +#endif /* _GPXE_ANSIESC_H */ diff --git a/gpxe/src/include/gpxe/aoe.h b/gpxe/src/include/gpxe/aoe.h new file mode 100644 index 00000000..85683384 --- /dev/null +++ b/gpxe/src/include/gpxe/aoe.h @@ -0,0 +1,126 @@ +#ifndef _GPXE_AOE_H +#define _GPXE_AOE_H + +/** @file + * + * AoE protocol + * + */ + +#include <stdint.h> +#include <gpxe/list.h> +#include <gpxe/if_ether.h> +#include <gpxe/retry.h> +#include <gpxe/async.h> +#include <gpxe/ata.h> + +/** An AoE ATA command */ +struct aoecmd { + /** AoE command flags */ + uint8_t aflags; + /** ATA error/feature register */ + uint8_t err_feat; + /** ATA sector count register */ + uint8_t count; + /** ATA command/status register */ + uint8_t cmd_stat; + /** Logical block address, in little-endian order */ + union { + uint64_t u64; + uint8_t bytes[6]; + } lba; + /** Data payload */ + uint8_t data[0]; +} __attribute__ (( packed )); + +#define AOE_FL_EXTENDED 0x40 /**< LBA48 extended addressing */ +#define AOE_FL_DEV_HEAD 0x10 /**< Device/head flag */ +#define AOE_FL_ASYNC 0x02 /**< Asynchronous write */ +#define AOE_FL_WRITE 0x01 /**< Write command */ + +/** An AoE header */ +struct aoehdr { + /** Protocol version number and flags */ + uint8_t ver_flags; + /** Error code */ + uint8_t error; + /** Major device number, in network byte order */ + uint16_t major; + /** Minor device number */ + uint8_t minor; + /** Command number */ + uint8_t command; + /** Tag, in network byte order */ + uint32_t tag; + /** Payload */ + union { + /** ATA command */ + struct aoecmd command[0]; + } arg; +} __attribute__ (( packed )); + +#define AOE_VERSION 0x10 /**< Version 1 */ +#define AOE_VERSION_MASK 0xf0 /**< Version part of ver_flags field */ + +#define AOE_FL_RESPONSE 0x08 /**< Message is a response */ +#define AOE_FL_ERROR 0x04 /**< Command generated an error */ + +#define AOE_MAJOR_BROADCAST 0xffff +#define AOE_MINOR_BROADCAST 0xff + +#define AOE_CMD_ATA 0x00 /**< Issue ATA command */ +#define AOE_CMD_CONFIG 0x01 /**< Query Config Information */ + +#define AOE_TAG_MAGIC 0xebeb0000 + +#define AOE_ERR_BAD_COMMAND 1 /**< Unrecognised command code */ +#define AOE_ERR_BAD_PARAMETER 2 /**< Bad argument parameter */ +#define AOE_ERR_UNAVAILABLE 3 /**< Device unavailable */ +#define AOE_ERR_CONFIG_EXISTS 4 /**< Config string present */ +#define AOE_ERR_BAD_VERSION 5 /**< Unsupported version */ + +/** An AoE session */ +struct aoe_session { + /** Reference counter */ + struct refcnt refcnt; + + /** List of all AoE sessions */ + struct list_head list; + + /** Network device */ + struct net_device *netdev; + + /** Major number */ + uint16_t major; + /** Minor number */ + uint8_t minor; + /** Target MAC address */ + uint8_t target[ETH_ALEN]; + + /** Tag for current AoE command */ + uint32_t tag; + + /** Current ATA command */ + struct ata_command *command; + /** Overall status of current ATA command */ + unsigned int status; + /** Byte offset within command's data buffer */ + unsigned int command_offset; + /** Return status code for command */ + int rc; + + /** Retransmission timer */ + struct retry_timer timer; +}; + +#define AOE_STATUS_ERR_MASK 0x0f /**< Error portion of status code */ +#define AOE_STATUS_PENDING 0x80 /**< Command pending */ + +/** Maximum number of sectors per packet */ +#define AOE_MAX_COUNT 2 + +extern void aoe_detach ( struct ata_device *ata ); +extern int aoe_attach ( struct ata_device *ata, struct net_device *netdev, + const char *root_path ); + +#endif /* _GPXE_AOE_H */ diff --git a/gpxe/src/include/gpxe/arp.h b/gpxe/src/include/gpxe/arp.h new file mode 100644 index 00000000..6464ce0c --- /dev/null +++ b/gpxe/src/include/gpxe/arp.h @@ -0,0 +1,41 @@ +#ifndef _GPXE_ARP_H +#define _GPXE_ARP_H + +/** @file + * + * Address Resolution Protocol + * + */ + +#include <gpxe/tables.h> + +struct net_device; +struct net_protocol; + +/** A network-layer protocol that relies upon ARP */ +struct arp_net_protocol { + /** Network-layer protocol */ + struct net_protocol *net_protocol; + /** Check existence of address + * + * @v netdev Network device + * @v net_addr Network-layer address + * @ret rc Return status code + */ + int ( * check ) ( struct net_device *netdev, + const void *net_addr ); +}; + +/** Declare an ARP protocol */ +#define __arp_net_protocol \ + __table ( struct arp_net_protocol, arp_net_protocols, 01 ) + +extern struct net_protocol arp_protocol; + +extern int arp_resolve ( struct net_device *netdev, + struct net_protocol *net_protocol, + const void *dest_net_addr, + const void *source_net_addr, + void *dest_ll_addr ); + +#endif /* _GPXE_ARP_H */ diff --git a/gpxe/src/include/gpxe/asn1.h b/gpxe/src/include/gpxe/asn1.h new file mode 100644 index 00000000..1ad90050 --- /dev/null +++ b/gpxe/src/include/gpxe/asn1.h @@ -0,0 +1,32 @@ +#ifndef _GPXE_ASN1_H +#define _GPXE_ASN1_H + +/** @file + * + * ASN.1 encoding + * + */ + +#define ASN1_INTEGER 0x02 +#define ASN1_BIT_STRING 0x03 +#define ASN1_OCTET_STRING 0x04 +#define ASN1_NULL 0x05 +#define ASN1_OID 0x06 +#define ASN1_SEQUENCE 0x30 +#define ASN1_IP_ADDRESS 0x40 +#define ASN1_EXPLICIT_TAG 0xa0 + +/** + * A DER-encoded ASN.1 object cursor + */ +struct asn1_cursor { + /** Start of data */ + uint8_t *data; + /** Length of data */ + size_t len; +}; + +extern int asn1_enter_object ( struct asn1_cursor *cursor, unsigned int type ); +extern int asn1_skip_object ( struct asn1_cursor *cursor, unsigned int type ); + +#endif /* _GPXE_ASN1_H */ diff --git a/gpxe/src/include/gpxe/async.h b/gpxe/src/include/gpxe/async.h new file mode 100644 index 00000000..2d1d31a4 --- /dev/null +++ b/gpxe/src/include/gpxe/async.h @@ -0,0 +1,228 @@ +#ifndef _GPXE_ASYNC_H +#define _GPXE_ASYNC_H + +/** @file + * + * Asynchronous operations + * + */ + +#include <gpxe/list.h> + +struct async; + +/** An asynchronous operation ID + * + * Only positive identifiers are valid; negative values are used to + * indicate errors. + */ +typedef long aid_t; + +/** Signals that can be delivered to asynchronous operations */ +enum signal { + /** A child asynchronous operation has completed + * + * The parent should call async_wait() to reap the completed + * child. async_wait() will return the exit status and + * operation identifier of the child. + * + * The handler for this signal can be set to @c NULL; if it + * is, then the children will accumulate as zombies until + * async_wait() is called. + * + * The handler for this signal can also be set to @c SIG_IGN; + * if it is, then the children will automatically be reaped. + * Note that if you use @c SIG_IGN then you will not be able + * to retrieve the return status of the children; the call to + * async_wait() will simply return -ECHILD. + */ + SIGCHLD = 0, + /** Cancel asynchronous operation + * + * This signal should trigger the asynchronous operation to + * cancel itself (including killing all its own children, if + * any), and then call async_done(). The asynchronous + * operation is allowed to not complete immediately. + * + * The handler for this signal can be set to @c NULL; if it + * is, then attempts to cancel the asynchronous operation will + * fail and the operation will complete normally. Anything + * waiting for the operation to cancel will block. + */ + SIGKILL, + /** Update progress of asynchronous operation + * + * This signal should cause the asynchronous operation to + * immediately update the @c completed and @c total fields. + * + * The handler for this signal can be set to @c NULL; if it + * is, then the asynchronous operation is expected to keep its + * @c completed and @c total fields up to date at all times. + */ + SIGUPDATE, + SIGMAX +}; + +/** + * A signal handler + * + * @v async Asynchronous operation + * @v signal Signal received + */ +typedef void ( * signal_handler_t ) ( struct async *async, + enum signal signal ); + +/** Asynchronous operation operations */ +struct async_operations { + /** Reap asynchronous operation + * + * @v async Asynchronous operation + * + * Release all resources associated with the asynchronous + * operation. This will be called only after the asynchronous + * operation itself calls async_done(), so the only remaining + * resources will probably be the memory used by the struct + * async itself. + * + * This method can be set to @c NULL; if it is, then no + * resources will be freed. This may be suitable for + * asynchronous operations that consume no dynamically + * allocated memory. + */ + void ( * reap ) ( struct async *async ); + /** Handle signals */ + signal_handler_t signal[SIGMAX]; +}; + +/** An asynchronous operation */ +struct async { + /** Other asynchronous operations with the same parent */ + struct list_head siblings; + /** Child asynchronous operations */ + struct list_head children; + /** Parent asynchronous operation + * + * This field is optional; if left to NULL then the owner must + * never call async_done(). + */ + struct async *parent; + /** Asynchronous operation ID */ + aid_t aid; + /** Final return status code */ + int rc; + + /** Amount of operation completed so far + * + * The units for this quantity are arbitrary. @c completed + * divded by @total should give something which approximately + * represents the progress through the operation. For a + * download operation, using byte counts would make sense. + * + * This progress indicator should also incorporate the status + * of any child asynchronous operations. + */ + unsigned long completed; + /** Total operation size + * + * See @c completed. A zero value means "total size unknown" + * and is explcitly permitted; users should take this into + * account before calculating @c completed/total. + */ + unsigned long total; + + struct async_operations *aop; +}; + +extern struct async_operations default_async_operations; +extern struct async_operations orphan_async_operations; + +extern aid_t async_init ( struct async *async, struct async_operations *aop, + struct async *parent ); +extern void async_uninit ( struct async *async ); +extern void async_ignore_signal ( struct async *async, enum signal signal ); +extern void async_signal ( struct async *async, enum signal signal ); +extern void async_signal_children ( struct async *async, enum signal signal ); +extern void async_done ( struct async *async, int rc ); +extern aid_t async_wait ( struct async *async, int *rc, int block ); + +/** Default signal handler */ +#define SIG_DFL NULL + +/** Ignore signal */ +#define SIG_IGN async_ignore_signal + +/** + * Initialise orphan asynchronous operation + * + * @v async Asynchronous operation + * @ret aid Asynchronous operation ID + * + * An orphan asynchronous operation can act as a context for child + * operations. However, you must not call async_done() on such an + * operation, since this would attempt to send a signal to its + * (non-existent) parent. Instead, simply free the structure (after + * calling async_wait() to ensure that any child operations have + * completed). + */ +static inline aid_t async_init_orphan ( struct async *async ) { + return async_init ( async, &orphan_async_operations, NULL ); +} + +/** + * Execute and block on an asynchronous operation + * + * @v async_temp Temporary asynchronous operation structure to use + * @v START Code used to start the asynchronous operation + * @ret rc Return status code + * + * This is a notational shorthand for writing + * + * async_init_orphan ( &async_temp ); + * if ( ( rc = START ) == 0 ) + * async_wait ( &async_temp ); + * if ( rc != 0 ) { + * ...handle failure... + * } + * + * and allows you instead to write + * + * if ( ( rc = async_block ( &async_temp, START ) ) != 0 ) { + * ...handle failure... + * } + * + * The argument START is a code snippet; it should initiate an + * asynchronous operation as a child of @c async_temp and return an + * error status code if it failed to do so (e.g. due to malloc() + * failure). + */ +#define async_block( async_temp, START ) ( { \ + int rc; \ + \ + async_init_orphan ( async_temp ); \ + if ( ( rc = START ) == 0 ) \ + async_wait ( async_temp, &rc, 1 ); \ + rc; \ + } ) + +/** + * Execute and block on an asynchronous operation, with progress indicator + * + * @v async_temp Temporary asynchronous operation structure to use + * @v START Code used to start the asynchronous operation + * @ret rc Return status code + * + * As for async_block(), the argument START is a code snippet; it + * should initiate an asynchronous operation as a child of @c + * async_temp and return an error status code if it failed to do so + * (e.g. due to malloc() failure). + */ +#define async_block_progress( async_temp, START ) ( { \ + int rc; \ + \ + async_init_orphan ( async_temp ); \ + if ( ( rc = START ) == 0 ) \ + async_wait_progress ( async_temp, &rc );\ + rc; \ + } ) + +#endif /* _GPXE_ASYNC_H */ diff --git a/gpxe/src/include/gpxe/ata.h b/gpxe/src/include/gpxe/ata.h new file mode 100644 index 00000000..b6da3930 --- /dev/null +++ b/gpxe/src/include/gpxe/ata.h @@ -0,0 +1,205 @@ +#ifndef _GPXE_ATA_H +#define _GPXE_ATA_H + +#include <stdint.h> +#include <gpxe/blockdev.h> +#include <gpxe/uaccess.h> +#include <gpxe/refcnt.h> + +/** @file + * + * ATA devices + * + */ + +/** + * An ATA Logical Block Address + * + * ATA controllers have three byte-wide registers for specifying the + * block address: LBA Low, LBA Mid and LBA High. This allows for a + * 24-bit address. Some devices support the "48-bit address feature + * set" (LBA48), in which case each of these byte-wide registers is + * actually a two-entry FIFO, and the "previous" byte pushed into the + * FIFO is used as the corresponding high-order byte. So, to set up + * the 48-bit address 0x123456abcdef, you would issue + * + * 0x56 -> LBA Low register + * 0xef -> LBA Low register + * 0x34 -> LBA Mid register + * 0xcd -> LBA Mid register + * 0x12 -> LBA High register + * 0xab -> LBA High register + * + * This structure encapsulates this information by providing a single + * 64-bit integer in native byte order, unioned with bytes named so + * that the sequence becomes + * + * low_prev -> LBA Low register + * low_cur -> LBA Low register + * mid_prev -> LBA Mid register + * mid_cur -> LBA Mid register + * high_prev -> LBA High register + * high_cur -> LBA High register + * + * Just to complicate matters further, in non-LBA48 mode it is + * possible to have a 28-bit address, in which case bits 27:24 must be + * written into the low four bits of the Device register. + */ +union ata_lba { + /** LBA as a 64-bit integer in native-endian order */ + uint64_t native; + /** ATA registers */ + struct { +#if __BYTE_ORDER == __LITTLE_ENDIAN + uint8_t low_cur; + uint8_t mid_cur; + uint8_t high_cur; + uint8_t low_prev; + uint8_t mid_prev; + uint8_t high_prev; + uint16_t pad; +#elif __BYTE_ORDER == __BIG_ENDIAN + uint16_t pad; + uint8_t high_prev; + uint8_t mid_prev; + uint8_t low_prev; + uint8_t high_cur; + uint8_t mid_cur; + uint8_t low_cur; +#else +#error "I need a byte order" +#endif + } bytes; +}; + +/** An ATA 2-byte FIFO register */ +union ata_fifo { + /** Value in native-endian order */ + uint16_t native; + /** ATA registers */ + struct { +#if __BYTE_ORDER == __LITTLE_ENDIAN + uint8_t cur; + uint8_t prev; +#elif __BYTE_ORDER == __BIG_ENDIAN + uint8_t prev; + uint8_t cur; +#else +#error "I need a byte order" +#endif + } bytes; +}; + +/** ATA command block */ +struct ata_cb { + /** Logical block address */ + union ata_lba lba; + /** Sector count */ + union ata_fifo count; + /** Error/feature register */ + union ata_fifo err_feat; + /** Device register */ + uint8_t device; + /** Command/status register */ + uint8_t cmd_stat; + /** LBA48 addressing flag */ + int lba48; +}; + +/** Obsolete bits in the ATA device register */ +#define ATA_DEV_OBSOLETE 0xa0 + +/** LBA flag in the ATA device register */ +#define ATA_DEV_LBA 0x40 + +/** Slave ("device 1") flag in the ATA device register */ +#define ATA_DEV_SLAVE 0x10 + +/** Master ("device 0") flag in the ATA device register */ +#define ATA_DEV_MASTER 0x00 + +/** Mask of non-LBA portion of device register */ +#define ATA_DEV_MASK 0xf0 + +/** "Read sectors" command */ +#define ATA_CMD_READ 0x20 + +/** "Read sectors (ext)" command */ +#define ATA_CMD_READ_EXT 0x24 + +/** "Write sectors" command */ +#define ATA_CMD_WRITE 0x30 + +/** "Write sectors (ext)" command */ +#define ATA_CMD_WRITE_EXT 0x34 + +/** "Identify" command */ +#define ATA_CMD_IDENTIFY 0xec + +/** An ATA command */ +struct ata_command { + /** ATA command block */ + struct ata_cb cb; + /** Data-out buffer (may be NULL) + * + * If non-NULL, this buffer must be ata_command::cb::count + * sectors in size. + */ + userptr_t data_out; + /** Data-in buffer (may be NULL) + * + * If non-NULL, this buffer must be ata_command::cb::count + * sectors in size. + */ + userptr_t data_in; +}; + +/** + * Structure returned by ATA IDENTIFY command + * + * This is a huge structure with many fields that we don't care about, + * so we implement only a few fields. + */ +struct ata_identity { + uint16_t ignore_a[60]; /* words 0-59 */ + uint32_t lba_sectors; /* words 60-61 */ + uint16_t ignore_b[21]; /* words 62-82 */ + uint16_t supports_lba48; /* word 83 */ + uint16_t ignore_c[16]; /* words 84-99 */ + uint64_t lba48_sectors; /* words 100-103 */ + uint16_t ignore_d[152]; /* words 104-255 */ +}; + +/** Supports LBA48 flag */ +#define ATA_SUPPORTS_LBA48 ( 1 << 10 ) + +/** ATA sector size */ +#define ATA_SECTOR_SIZE 512 + +/** An ATA device */ +struct ata_device { + /** Block device interface */ + struct block_device blockdev; + /** Device number + * + * Must be ATA_DEV_MASTER or ATA_DEV_SLAVE. + */ + int device; + /** LBA48 extended addressing */ + int lba48; + /** + * Issue ATA command + * + * @v ata ATA device + * @v command ATA command + * @ret rc Return status code + */ + int ( * command ) ( struct ata_device *ata, + struct ata_command *command ); + /** Backing device */ + struct refcnt *backend; +}; + +extern int init_atadev ( struct ata_device *ata ); + +#endif /* _GPXE_ATA_H */ diff --git a/gpxe/src/include/gpxe/bitbash.h b/gpxe/src/include/gpxe/bitbash.h new file mode 100644 index 00000000..62bdce00 --- /dev/null +++ b/gpxe/src/include/gpxe/bitbash.h @@ -0,0 +1,50 @@ +#ifndef _GPXE_BITBASH_H +#define _GPXE_BITBASH_H + +/** @file + * + * Bit-bashing interfaces + * + */ + +struct bit_basher; + +/** Bit-bashing operations */ +struct bit_basher_operations { + /** + * Set/clear output bit + * + * @v basher Bit-bashing interface + * @v bit_id Bit number + * @v data Value to write + * + * @c data will be 0 if a logic 0 should be written (i.e. the + * bit should be cleared), or -1UL if a logic 1 should be + * written (i.e. the bit should be set). This is done so that + * the method may simply binary-AND @c data with the + * appropriate bit mask. + */ + void ( * write ) ( struct bit_basher *basher, unsigned int bit_id, + unsigned long data ); + /** + * Read input bit + * + * @v basher Bit-bashing interface + * @v bit_id Bit number + * @ret zero Input is a logic 0 + * @ret non-zero Input is a logic 1 + */ + int ( * read ) ( struct bit_basher *basher, unsigned int bit_id ); +}; + +/** A bit-bashing interface */ +struct bit_basher { + /** Bit-bashing operations */ + struct bit_basher_operations *op; +}; + +extern void write_bit ( struct bit_basher *basher, unsigned int bit_id, + unsigned long data ); +extern int read_bit ( struct bit_basher *basher, unsigned int bit_id ); + +#endif /* _GPXE_BITBASH_H */ diff --git a/gpxe/src/include/gpxe/bitmap.h b/gpxe/src/include/gpxe/bitmap.h new file mode 100644 index 00000000..0c2f53c8 --- /dev/null +++ b/gpxe/src/include/gpxe/bitmap.h @@ -0,0 +1,83 @@ +#ifndef _GPXE_BITMAP_H +#define _GPXE_BITMAP_H + +/** @file + * + * Bitmaps for multicast downloads + * + */ + +#include <stdint.h> +#include <stddef.h> +#include <stdlib.h> + +/** A single block of bits within a bitmap */ +typedef unsigned long bitmap_block_t; + +/** Size of a block of bits (in bits) */ +#define BITMAP_BLKSIZE ( sizeof ( bitmap_block_t ) * 8 ) + +/** + * Block index within bitmap + * + * @v bit Bit index + * @ret index Block index + */ +#define BITMAP_INDEX( bit ) ( (bit) / BITMAP_BLKSIZE ) + +/** + * Block mask within bitmap + * + * @v bit Bit index + * @ret mask Block mask + */ +#define BITMAP_MASK( bit ) ( 1 << ( (bit) % BITMAP_BLKSIZE ) ) + +/** A bitmap */ +struct bitmap { + /** Bitmap data */ + bitmap_block_t *blocks; + /** Length of the bitmap, in bits */ + unsigned int length; + /** Index of first gap in the bitmap */ + unsigned int first_gap; +}; + +extern int bitmap_resize ( struct bitmap *bitmap, unsigned int new_length ); +extern int bitmap_test ( struct bitmap *bitmap, unsigned int bit ); +extern void bitmap_set ( struct bitmap *bitmap, unsigned int bit ); + +/** + * Free bitmap resources + * + * @v bitmap Bitmap + */ +static inline void bitmap_free ( struct bitmap *bitmap ) { + free ( bitmap->blocks ); +} + +/** + * Get first gap within bitmap + * + * @v bitmap Bitmap + * @ret first_gap First gap + * + * The first gap is the first unset bit within the bitmap. + */ +static inline unsigned int bitmap_first_gap ( struct bitmap *bitmap ) { + return bitmap->first_gap; +} + +/** + * Check to see if bitmap is full + * + * @v bitmap Bitmap + * @ret is_full Bitmap is full + * + * The bitmap is full if it has no gaps (i.e. no unset bits). + */ +static inline int bitmap_full ( struct bitmap *bitmap ) { + return ( bitmap->first_gap == bitmap->length ); +} + +#endif /* _GPXE_BITMAP_H */ diff --git a/gpxe/src/include/gpxe/bitops.h b/gpxe/src/include/gpxe/bitops.h new file mode 100644 index 00000000..f95af7d3 --- /dev/null +++ b/gpxe/src/include/gpxe/bitops.h @@ -0,0 +1,27 @@ +#ifndef _GPXE_BITOPS_H +#define _GPXE_BITOPS_H + +/** @file + * + * Bit operations + */ + +#include <stdint.h> + +static inline uint32_t rol32 ( uint32_t data, unsigned int rotation ) { + return ( ( data << rotation ) | ( data >> ( 32 - rotation ) ) ); +} + +static inline uint32_t ror32 ( uint32_t data, unsigned int rotation ) { + return ( ( data >> rotation ) | ( data << ( 32 - rotation ) ) ); +} + +static inline uint64_t rol64 ( uint64_t data, unsigned int rotation ) { + return ( ( data << rotation ) | ( data >> ( 64 - rotation ) ) ); +} + +static inline uint64_t ror64 ( uint64_t data, unsigned int rotation ) { + return ( ( data >> rotation ) | ( data << ( 64 - rotation ) ) ); +} + +#endif /* _GPXE_BITOPS_H */ diff --git a/gpxe/src/include/gpxe/blockdev.h b/gpxe/src/include/gpxe/blockdev.h new file mode 100644 index 00000000..467ed1d9 --- /dev/null +++ b/gpxe/src/include/gpxe/blockdev.h @@ -0,0 +1,43 @@ +#ifndef _GPXE_BLOCKDEV_H +#define _GPXE_BLOCKDEV_H + +/** + * @file + * + * Block devices + * + */ + +#include <gpxe/uaccess.h> + +/** A block device */ +struct block_device { + /** Block size */ + size_t blksize; + /** Total number of blocks */ + uint64_t blocks; + /** + * Read block + * + * @v blockdev Block device + * @v block Block number + * @v count Block count + * @v buffer Data buffer + * @ret rc Return status code + */ + int ( * read ) ( struct block_device *blockdev, uint64_t block, + unsigned long count, userptr_t buffer ); + /** + * Write block + * + * @v blockdev Block device + * @v block Block number + * @v count Block count + * @v buffer Data buffer + * @ret rc Return status code + */ + int ( * write ) ( struct block_device *blockdev, uint64_t block, + unsigned long count, userptr_t buffer ); +}; + +#endif /* _GPXE_BLOCKDEV_H */ diff --git a/gpxe/src/include/gpxe/chap.h b/gpxe/src/include/gpxe/chap.h new file mode 100644 index 00000000..0ea7ac5c --- /dev/null +++ b/gpxe/src/include/gpxe/chap.h @@ -0,0 +1,51 @@ +#ifndef _GPXE_CHAP_H +#define _GPXE_CHAP_H + +/** @file + * + * CHAP protocol + * + */ + +#include <stdint.h> +#include <gpxe/md5.h> + +struct crypto_algorithm; + +/** A CHAP challenge/response */ +struct chap_challenge { + /** Digest algorithm used for the response */ + struct crypto_algorithm *digest; + /** Context used by the digest algorithm */ + uint8_t *digest_context; + /** CHAP response */ + uint8_t *response; + /** Length of CHAP response */ + size_t response_len; +}; + +extern int chap_init ( struct chap_challenge *chap, + struct crypto_algorithm *digest ); +extern void chap_update ( struct chap_challenge *chap, const void *data, + size_t len ); +extern void chap_respond ( struct chap_challenge *chap ); +extern void chap_finish ( struct chap_challenge *chap ); + +/** + * Add identifier data to the CHAP challenge + * + * @v chap CHAP challenge/response + * @v identifier CHAP identifier + * + * The CHAP identifier is the first byte of the CHAP challenge. This + * function is a notational convenience for calling chap_update() for + * the identifier byte. + */ +static inline void chap_set_identifier ( struct chap_challenge *chap, + unsigned int identifier ) { + uint8_t ident_byte = identifier; + + chap_update ( chap, &ident_byte, sizeof ( ident_byte ) ); +} + +#endif /* _GPXE_CHAP_H */ diff --git a/gpxe/src/include/gpxe/command.h b/gpxe/src/include/gpxe/command.h new file mode 100644 index 00000000..5d8057ab --- /dev/null +++ b/gpxe/src/include/gpxe/command.h @@ -0,0 +1,22 @@ +#ifndef _GPXE_COMMAND_H +#define _GPXE_COMMAND_H + +#include <gpxe/tables.h> + +/** A command-line command */ +struct command { + /** Name of the command */ + const char *name; + /** + * Function implementing the command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ + int ( * exec ) ( int argc, char **argv ); +}; + +#define __command __table ( struct command, commands, 01 ) + +#endif /* _GPXE_COMMAND_H */ diff --git a/gpxe/src/include/gpxe/cpio.h b/gpxe/src/include/gpxe/cpio.h new file mode 100644 index 00000000..ba6f844a --- /dev/null +++ b/gpxe/src/include/gpxe/cpio.h @@ -0,0 +1,51 @@ +#ifndef _GPXE_CPIO_H +#define _GPXE_CPIO_H + +/** @file + * + * CPIO archives + * + */ + +/** A CPIO archive header + * + * All field are hexadecimal ASCII numbers padded with '0' on the + * left to the full width of the field. + */ +struct cpio_header { + /** The string "070701" or "070702" */ + char c_magic[6]; + /** File inode number */ + char c_ino[8]; + /** File mode and permissions */ + char c_mode[8]; + /** File uid */ + char c_uid[8]; + /** File gid */ + char c_gid[8]; + /** Number of links */ + char c_nlink[8]; + /** Modification time */ + char c_mtime[8]; + /** Size of data field */ + char c_filesize[8]; + /** Major part of file device number */ + char c_maj[8]; + /** Minor part of file device number */ + char c_min[8]; + /** Major part of device node reference */ + char c_rmaj[8]; + /** Minor part of device node reference */ + char c_rmin[8]; + /** Length of filename, including final NUL */ + char c_namesize[8]; + /** Checksum of data field if c_magic is 070702, othersize zero */ + char c_chksum[8]; +} __attribute__ (( packed )); + +/** CPIO magic */ +#define CPIO_MAGIC "070701" + +extern void cpio_set_field ( char *field, unsigned long value ); + +#endif /* _GPXE_CPIO_H */ diff --git a/gpxe/src/include/gpxe/crypto.h b/gpxe/src/include/gpxe/crypto.h new file mode 100644 index 00000000..95665acc --- /dev/null +++ b/gpxe/src/include/gpxe/crypto.h @@ -0,0 +1,116 @@ +#ifndef _GPXE_CRYPTO_H +#define _GPXE_CRYPTO_H + +/** @file + * + * Cryptographic API + * + */ + +#include <stdint.h> +#include <stddef.h> + +/** A cryptographic algorithm */ +struct crypto_algorithm { + /** Algorithm name */ + const char *name; + /** Context size */ + size_t ctxsize; + /** Block size */ + size_t blocksize; + /** Final output size */ + size_t digestsize; + /** Initialise algorithm + * + * @v ctx Context + */ + void ( * init ) ( void *ctx ); + /** Set key + * + * @v ctx Context + * @v key Key + * @v keylen Key length + * @ret rc Return status code + */ + int ( * setkey ) ( void *ctx, const void *key, size_t keylen ); + /** Set initialisation vector + * + * @v ctx Context + * @v iv Initialisation vector + */ + void ( *setiv ) ( void *ctx, const void *iv ); + /** Encode data + * + * @v ctx Context + * @v src Data to encode + * @v dst Encoded data, or NULL + * @v len Length of data + * @ret rc Return status code + * + * For a cipher algorithm, the enciphered data should be + * placed in @c dst. For a digest algorithm, only the digest + * state should be updated, and @c dst will be NULL. + * + * @v len is guaranteed to be a multiple of @c blocksize. + */ + void ( * encode ) ( void *ctx, const void *src, void *dst, + size_t len ); + /** Decode data + * + * @v ctx Context + * @v src Data to decode + * @v dst Decoded data + * @v len Length of data + * @ret rc Return status code + * + * @v len is guaranteed to be a multiple of @c blocksize. + */ + void ( * decode ) ( void *ctx, const void *src, void *dst, + size_t len ); + /** Finalise algorithm + * + * @v ctx Context + * @v out Algorithm final output + */ + void ( * final ) ( void *ctx, void *out ); +}; + +static inline void digest_init ( struct crypto_algorithm *crypto, + void *ctx ) { + crypto->init ( ctx ); +} + +static inline void digest_update ( struct crypto_algorithm *crypto, + void *ctx, const void *data, size_t len ) { + crypto->encode ( ctx, data, NULL, len ); +} + +static inline void digest_final ( struct crypto_algorithm *crypto, + void *ctx, void *out ) { + crypto->final ( ctx, out ); +} + +static inline void cipher_setiv ( struct crypto_algorithm *crypto, + void *ctx, const void *iv ) { + crypto->setiv ( ctx, iv ); +} + +static inline int cipher_setkey ( struct crypto_algorithm *crypto, + void *ctx, const void *key, size_t keylen ) { + return crypto->setkey ( ctx, key, keylen ); +} + +static inline int is_stream_cipher ( struct crypto_algorithm *crypto ) { + return ( crypto->blocksize == 1 ); +} + +extern struct crypto_algorithm crypto_null; + +extern int cipher_encrypt ( struct crypto_algorithm *crypto, + void *ctx, const void *src, void *dst, + size_t len ); +extern int cipher_decrypt ( struct crypto_algorithm *crypto, + void *ctx, const void *src, void *dst, + size_t len ); + +#endif /* _GPXE_CRYPTO_H */ diff --git a/gpxe/src/include/gpxe/device.h b/gpxe/src/include/gpxe/device.h new file mode 100644 index 00000000..caabdae5 --- /dev/null +++ b/gpxe/src/include/gpxe/device.h @@ -0,0 +1,111 @@ +#ifndef _GPXE_DEVICE_H +#define _GPXE_DEVICE_H + +/** + * @file + * + * Device model + * + */ + +#include <gpxe/list.h> +#include <gpxe/tables.h> + +/** A hardware device description */ +struct device_description { + /** Bus type + * + * This must be a BUS_TYPE_XXX constant. + */ + unsigned int bus_type; + /** Location + * + * The interpretation of this field is bus-type-specific. + */ + unsigned int location; + /** Vendor ID */ + unsigned int vendor; + /** Device ID */ + unsigned int device; + /** Device class */ + unsigned long class; + /** I/O address */ + unsigned long ioaddr; + /** IRQ */ + unsigned int irq; +}; + +/** PCI bus type */ +#define BUS_TYPE_PCI 1 + +/** ISAPnP bus type */ +#define BUS_TYPE_ISAPNP 2 + +/** EISA bus type */ +#define BUS_TYPE_EISA 3 + +/** MCA bus type */ +#define BUS_TYPE_MCA 4 + +/** ISA bus type */ +#define BUS_TYPE_ISA 5 + +/** A hardware device */ +struct device { + /** Name */ + char name[16]; + /** Device description */ + struct device_description desc; + /** Devices on the same bus */ + struct list_head siblings; + /** Devices attached to this device */ + struct list_head children; + /** Bus device */ + struct device *parent; +}; + +/** + * A root device + * + * Root devices are system buses such as PCI, EISA, etc. + * + */ +struct root_device { + /** Device chain + * + * A root device has a NULL parent field. + */ + struct device dev; + /** Root device driver */ + struct root_driver *driver; +}; + +/** A root device driver */ +struct root_driver { + /** + * Add root device + * + * @v rootdev Root device + * @ret rc Return status code + * + * Called from probe_devices() for all root devices in the build. + */ + int ( * probe ) ( struct root_device *rootdev ); + /** + * Remove root device + * + * @v rootdev Root device + * + * Called from remove_device() for all successfully-probed + * root devices. + */ + void ( * remove ) ( struct root_device *rootdev ); +}; + +/** Declare a root device */ +#define __root_device __table ( struct root_device, root_devices, 01 ) + +extern int probe_devices ( void ); +extern void remove_devices ( void ); + +#endif /* _GPXE_DEVICE_H */ diff --git a/gpxe/src/include/gpxe/dhcp.h b/gpxe/src/include/gpxe/dhcp.h new file mode 100644 index 00000000..94cc2010 --- /dev/null +++ b/gpxe/src/include/gpxe/dhcp.h @@ -0,0 +1,455 @@ +#ifndef _GPXE_DHCP_H +#define _GPXE_DHCP_H + +/** @file + * + * Dynamic Host Configuration Protocol + * + */ + +#include <stdint.h> +#include <gpxe/in.h> +#include <gpxe/list.h> +#include <gpxe/refcnt.h> +#include <gpxe/tables.h> + +struct net_device; +struct job_interface; +struct dhcp_options; +struct dhcp_packet; + +/** BOOTP/DHCP server port */ +#define BOOTPS_PORT 67 + +/** BOOTP/DHCP client port */ +#define BOOTPC_PORT 68 + +/** Construct a tag value for an encapsulated option + * + * This tag value can be passed to Etherboot functions when searching + * for DHCP options in order to search for a tag within an + * encapsulated options block. + */ +#define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \ + ( ( (encapsulator) << 8 ) | (encapsulated) ) +/** Extract encapsulating option block tag from encapsulated tag value */ +#define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 ) +/** Extract encapsulated option tag from encapsulated tag value */ +#define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff ) +/** Option is encapsulated */ +#define DHCP_IS_ENCAP_OPT( opt ) DHCP_ENCAPSULATOR( opt ) + +/** + * @defgroup dhcpopts DHCP option tags + * @{ + */ + +/** Padding + * + * This tag does not have a length field; it is always only a single + * byte in length. + */ +#define DHCP_PAD 0 + +/** Minimum normal DHCP option */ +#define DHCP_MIN_OPTION 1 + +/** Subnet mask */ +#define DHCP_SUBNET_MASK 1 + +/** Routers */ +#define DHCP_ROUTERS 3 + +/** DNS servers */ +#define DHCP_DNS_SERVERS 6 + +/** Syslog servers */ +#define DHCP_LOG_SERVERS 7 + +/** Host name */ +#define DHCP_HOST_NAME 12 + +/** Domain name */ +#define DHCP_DOMAIN_NAME 15 + +/** Root path */ +#define DHCP_ROOT_PATH 17 + +/** Vendor encapsulated options */ +#define DHCP_VENDOR_ENCAP 43 + +/** Requested IP address */ +#define DHCP_REQUESTED_ADDRESS 50 + +/** Lease time */ +#define DHCP_LEASE_TIME 51 + +/** Option overloading + * + * The value of this option is the bitwise-OR of zero or more + * DHCP_OPTION_OVERLOAD_XXX constants. + */ +#define DHCP_OPTION_OVERLOAD 52 + +/** The "file" field is overloaded to contain extra DHCP options */ +#define DHCP_OPTION_OVERLOAD_FILE 1 + +/** The "sname" field is overloaded to contain extra DHCP options */ +#define DHCP_OPTION_OVERLOAD_SNAME 2 + +/** DHCP message type */ +#define DHCP_MESSAGE_TYPE 53 +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 +#define DHCPINFORM 8 + +/** DHCP server identifier */ +#define DHCP_SERVER_IDENTIFIER 54 + +/** Parameter request list */ +#define DHCP_PARAMETER_REQUEST_LIST 55 + +/** Maximum DHCP message size */ +#define DHCP_MAX_MESSAGE_SIZE 57 + +/** Vendor class identifier */ +#define DHCP_VENDOR_CLASS_ID 60 + +/** Client identifier */ +#define DHCP_CLIENT_ID 61 + +/** TFTP server name + * + * This option replaces the fixed "sname" field, when that field is + * used to contain overloaded options. + */ +#define DHCP_TFTP_SERVER_NAME 66 + +/** Bootfile name + * + * This option replaces the fixed "file" field, when that field is + * used to contain overloaded options. + */ +#define DHCP_BOOTFILE_NAME 67 + +/** Client system architecture */ +#define DHCP_CLIENT_ARCHITECTURE 93 + +/** Client network device interface */ +#define DHCP_CLIENT_NDI 94 + +/** UUID client identifier */ +#define DHCP_CLIENT_UUID 97 + +/** Etherboot-specific encapsulated options + * + * This encapsulated options field is used to contain all options + * specific to Etherboot (i.e. not assigned by IANA or other standards + * bodies). + */ +#define DHCP_EB_ENCAP 175 + +/** Priority of this options block + * + * This is a signed 8-bit integer field indicating the priority of + * this block of options. It can be used to specify the relative + * priority of multiple option blocks (e.g. options from non-volatile + * storage versus options from a DHCP server). + */ +#define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 1 ) + +/** "Your" IP address + * + * This option is used internally to contain the value of the "yiaddr" + * field, in order to provide a consistent approach to storing and + * processing options. It should never be present in a DHCP packet. + */ +#define DHCP_EB_YIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 2 ) + +/** "Server" IP address + * + * This option is used internally to contain the value of the "siaddr" + * field, in order to provide a consistent approach to storing and + * processing options. It should never be present in a DHCP packet. + */ +#define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 ) + +/* + * Tags in the range 0x10-0x7f are reserved for feature markers + * + */ + +/** Ignore ProxyDHCP + * + * If set to a non-zero value, gPXE will not wait for ProxyDHCP offers + * and will ignore any ProxyDHCP offers that it receives. + */ +#define DHCP_EB_NO_PROXYDHCP DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb0 ) + +/** Network device descriptor + * + * Byte 0 is the bus type ID; remaining bytes depend on the bus type. + * + * PCI devices: + * Byte 0 : 1 (PCI) + * Byte 1 : PCI vendor ID MSB + * Byte 2 : PCI vendor ID LSB + * Byte 3 : PCI device ID MSB + * Byte 4 : PCI device ID LSB + */ +#define DHCP_EB_BUS_ID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb1 ) + +/** BIOS drive number + * + * This is the drive number for a drive emulated via INT 13. 0x80 is + * the first hard disk, 0x81 is the second hard disk, etc. + */ +#define DHCP_EB_BIOS_DRIVE DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd ) + +/** Username + * + * This will be used as the username for any required authentication. + * It is expected that this option's value will be held in + * non-volatile storage, rather than transmitted as part of a DHCP + * packet. + */ +#define DHCP_EB_USERNAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbe ) + +/** Password + * + * This will be used as the password for any required authentication. + * It is expected that this option's value will be held in + * non-volatile storage, rather than transmitted as part of a DHCP + * packet. + */ +#define DHCP_EB_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbf ) + +/** iSCSI primary target IQN */ +#define DHCP_ISCSI_PRIMARY_TARGET_IQN 201 + +/** iSCSI secondary target IQN */ +#define DHCP_ISCSI_SECONDARY_TARGET_IQN 202 + +/** iSCSI initiator IQN */ +#define DHCP_ISCSI_INITIATOR_IQN 203 + +/** Maximum normal DHCP option */ +#define DHCP_MAX_OPTION 254 + +/** End of options + * + * This tag does not have a length field; it is always only a single + * byte in length. + */ +#define DHCP_END 255 + +/** @} */ + +/** + * Count number of arguments to a variadic macro + * + * This rather neat, non-iterative solution is courtesy of Laurent + * Deniau. + * + */ +#define _VA_ARG_COUNT( _1, _2, _3, _4, _5, _6, _7, _8, \ + _9, _10, _11, _12, _13, _14, _15, _16, \ + _17, _18, _19, _20, _21, _22, _23, _24, \ + _25, _26, _27, _28, _29, _30, _31, _32, \ + _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, \ + _49, _50, _51, _52, _53, _54, _55, _56, \ + _57, _58, _59, _60, _61, _62, _63, N, ... ) N +#define VA_ARG_COUNT( ... ) \ + _VA_ARG_COUNT ( __VA_ARGS__, \ + 63, 62, 61, 60, 59, 58, 57, 56, \ + 55, 54, 53, 52, 51, 50, 49, 48, \ + 47, 46, 45, 44, 43, 42, 41, 40, \ + 39, 38, 37, 36, 35, 34, 33, 32, \ + 31, 30, 29, 28, 27, 26, 25, 24, \ + 23, 22, 21, 20, 19, 18, 17, 16, \ + 15, 14, 13, 12, 11, 10, 9, 8, \ + 7, 6, 5, 4, 3, 2, 1, 0 ) + +/** Construct a DHCP option from a list of bytes */ +#define DHCP_OPTION( ... ) VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__ + +/** Construct a DHCP option from a list of characters */ +#define DHCP_STRING( ... ) DHCP_OPTION ( __VA_ARGS__ ) + +/** Construct a byte-valued DHCP option */ +#define DHCP_BYTE( value ) DHCP_OPTION ( value ) + +/** Construct a word-valued DHCP option */ +#define DHCP_WORD( value ) DHCP_OPTION ( ( ( (value) >> 8 ) & 0xff ), \ + ( ( (value) >> 0 ) & 0xff ) ) + +/** Construct a dword-valued DHCP option */ +#define DHCP_DWORD( value ) DHCP_OPTION ( ( ( (value) >> 24 ) & 0xff ), \ + ( ( (value) >> 16 ) & 0xff ), \ + ( ( (value) >> 8 ) & 0xff ), \ + ( ( (value) >> 0 ) & 0xff ) ) + +/** Construct a DHCP encapsulated options field */ +#define DHCP_ENCAP( ... ) DHCP_OPTION ( __VA_ARGS__, DHCP_END ) + +/** + * A DHCP option + * + * DHCP options consist of a mandatory tag, a length field that is + * mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a + * payload. + */ +struct dhcp_option { + /** Tag + * + * Must be a @c DHCP_XXX value. + */ + uint8_t tag; + /** Length + * + * This is the length of the data field (i.e. excluding the + * tag and length fields). For the two tags @c DHCP_PAD and + * @c DHCP_END, the length field is implicitly zero and is + * also missing, i.e. these DHCP options are only a single + * byte in length. + */ + uint8_t len; + /** Option data */ + uint8_t data[0]; +} __attribute__ (( packed )); + +/** + * Length of a DHCP option header + * + * The header is the portion excluding the data, i.e. the tag and the + * length. + */ +#define DHCP_OPTION_HEADER_LEN ( offsetof ( struct dhcp_option, data ) ) + +/** Maximum length for a single DHCP option */ +#define DHCP_MAX_LEN 0xff + +/** + * A DHCP header + * + */ +struct dhcphdr { + /** Operation + * + * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY. + */ + uint8_t op; + /** Hardware address type + * + * This is an ARPHRD_XXX constant. Note that ARPHRD_XXX + * constants are nominally 16 bits wide; this could be + * considered to be a bug in the BOOTP/DHCP specification. + */ + uint8_t htype; + /** Hardware address length */ + uint8_t hlen; + /** Number of hops from server */ + uint8_t hops; + /** Transaction ID */ + uint32_t xid; + /** Seconds since start of acquisition */ + uint16_t secs; + /** Flags */ + uint16_t flags; + /** "Client" IP address + * + * This is filled in if the client already has an IP address + * assigned and can respond to ARP requests. + */ + struct in_addr ciaddr; + /** "Your" IP address + * + * This is the IP address assigned by the server to the client. + */ + struct in_addr yiaddr; + /** "Server" IP address + * + * This is the IP address of the next server to be used in the + * boot process. + */ + struct in_addr siaddr; + /** "Gateway" IP address + * + * This is the IP address of the DHCP relay agent, if any. + */ + struct in_addr giaddr; + /** Client hardware address */ + uint8_t chaddr[16]; + /** Server host name (null terminated) + * + * This field may be overridden and contain DHCP options + */ + char sname[64]; + /** Boot file name (null terminated) + * + * This field may be overridden and contain DHCP options + */ + char file[128]; + /** DHCP magic cookie + * + * Must have the value @c DHCP_MAGIC_COOKIE. + */ + uint32_t magic; + /** DHCP options + * + * Variable length; extends to the end of the packet. Minimum + * length (for the sake of sanity) is 1, to allow for a single + * @c DHCP_END tag. + */ + uint8_t options[0]; +}; + +/** Opcode for a request from client to server */ +#define BOOTP_REQUEST 1 + +/** Opcode for a reply from server to client */ +#define BOOTP_REPLY 2 + +/** BOOTP reply must be broadcast + * + * Clients that cannot accept unicast BOOTP replies must set this + * flag. + */ +#define BOOTP_FL_BROADCAST 0x8000 + +/** DHCP magic cookie */ +#define DHCP_MAGIC_COOKIE 0x63825363UL + +/** DHCP minimum packet length + * + * This is the mandated minimum packet length that a DHCP participant + * must be prepared to receive. + */ +#define DHCP_MIN_LEN 552 + +/** Maximum time that we will wait for ProxyDHCP offers */ +#define PROXYDHCP_WAIT_TIME ( TICKS_PER_SEC * 1 ) + +/** Settings block name used for DHCP responses */ +#define DHCP_SETTINGS_NAME "dhcp" + +/** Settings block name used for ProxyDHCP responses */ +#define PROXYDHCP_SETTINGS_NAME "proxydhcp" + +extern int create_dhcp_packet ( struct dhcp_packet *dhcppkt, + struct net_device *netdev, uint8_t msgtype, + struct dhcp_options *options, + void *data, size_t max_len ); +extern int create_dhcp_request ( struct dhcp_packet *dhcppkt, + struct net_device *netdev, + struct dhcp_packet *dhcpoffer, + void *data, size_t max_len ); +extern int start_dhcp ( struct job_interface *job, struct net_device *netdev ); + +#endif /* _GPXE_DHCP_H */ diff --git a/gpxe/src/include/gpxe/dhcpopts.h b/gpxe/src/include/gpxe/dhcpopts.h new file mode 100644 index 00000000..8391a9d4 --- /dev/null +++ b/gpxe/src/include/gpxe/dhcpopts.h @@ -0,0 +1,32 @@ +#ifndef _GPXE_DHCPOPTS_H +#define _GPXE_DHCPOPTS_H + +/** @file + * + * DHCP options + * + */ + +#include <stdint.h> + +/** A DHCP options block */ +struct dhcp_options { + /** Option block raw data */ + void *data; + /** Option block length */ + size_t len; + /** Option block maximum length */ + size_t max_len; +}; + +extern int dhcpopt_store ( struct dhcp_options *options, unsigned int tag, + const void *data, size_t len ); +extern int dhcpopt_extensible_store ( struct dhcp_options *options, + unsigned int tag, + const void *data, size_t len ); +extern int dhcpopt_fetch ( struct dhcp_options *options, unsigned int tag, + void *data, size_t len ); +extern void dhcpopt_init ( struct dhcp_options *options, + void *data, size_t max_len ); + +#endif /* _GPXE_DHCPOPTS_H */ diff --git a/gpxe/src/include/gpxe/dhcppkt.h b/gpxe/src/include/gpxe/dhcppkt.h new file mode 100644 index 00000000..179be2f8 --- /dev/null +++ b/gpxe/src/include/gpxe/dhcppkt.h @@ -0,0 +1,35 @@ +#ifndef _GPXE_DHCPPKT_H +#define _GPXE_DHCPPKT_H + +/** @file + * + * DHCP packets + * + */ + +#include <gpxe/dhcp.h> +#include <gpxe/dhcpopts.h> + +/** + * A DHCP packet + * + */ +struct dhcp_packet { + /** The DHCP packet contents */ + struct dhcphdr *dhcphdr; + /** Maximum length of the DHCP packet buffer */ + size_t max_len; + /** Used length of the DHCP packet buffer */ + size_t len; + /** DHCP option blocks */ + struct dhcp_options options; +}; + +extern int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag, + const void *data, size_t len ); +extern int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag, + void *data, size_t len ); +extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, + void *data, size_t len ); + +#endif /* _GPXE_DHCPPKT_H */ diff --git a/gpxe/src/include/gpxe/dns.h b/gpxe/src/include/gpxe/dns.h new file mode 100644 index 00000000..3e3cff1b --- /dev/null +++ b/gpxe/src/include/gpxe/dns.h @@ -0,0 +1,90 @@ +#ifndef _GPXE_DNS_H +#define _GPXE_DNS_H + +/** @file + * + * DNS protocol + * + */ + +#include <stdint.h> +#include <gpxe/in.h> + +/* + * Constants + * + */ + +#define DNS_TYPE_A 1 +#define DNS_TYPE_CNAME 5 +#define DNS_TYPE_ANY 255 + +#define DNS_CLASS_IN 1 +#define DNS_CLASS_CS 2 +#define DNS_CLASS_CH 3 +#define DNS_CLASS_HS 4 + +#define DNS_FLAG_QUERY ( 0x00 << 15 ) +#define DNS_FLAG_RESPONSE ( 0x01 << 15 ) +#define DNS_FLAG_QR(flags) ( (flags) & ( 0x01 << 15 ) ) +#define DNS_FLAG_OPCODE_QUERY ( 0x00 << 11 ) +#define DNS_FLAG_OPCODE_IQUERY ( 0x01 << 11 ) +#define DNS_FLAG_OPCODE_STATUS ( 0x02 << 11 ) +#define DNS_FLAG_OPCODE(flags) ( (flags) & ( 0x0f << 11 ) ) +#define DNS_FLAG_RD ( 0x01 << 8 ) +#define DNS_FLAG_RA ( 0x01 << 7 ) +#define DNS_FLAG_RCODE_OK ( 0x00 << 0 ) +#define DNS_FLAG_RCODE_NX ( 0x03 << 0 ) +#define DNS_FLAG_RCODE(flags) ( (flags) & ( 0x0f << 0 ) ) + +#define DNS_PORT 53 +#define DNS_MAX_RETRIES 3 +#define DNS_MAX_CNAME_RECURSION 0x30 + +/* + * DNS protocol structures + * + */ +struct dns_header { + uint16_t id; + uint16_t flags; + uint16_t qdcount; + uint16_t ancount; + uint16_t nscount; + uint16_t arcount; +} __attribute__ (( packed )); + +struct dns_query_info { + uint16_t qtype; + uint16_t qclass; +} __attribute__ (( packed )); + +struct dns_query { + struct dns_header dns; + char payload[ 256 + sizeof ( struct dns_query_info ) ]; +} __attribute__ (( packed )); + +struct dns_rr_info_common { + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t rdlength; +} __attribute__ (( packed )); + +struct dns_rr_info_a { + struct dns_rr_info_common common; + struct in_addr in_addr; +} __attribute__ (( packed )); + +struct dns_rr_info_cname { + struct dns_rr_info_common common; + char cname[0]; +} __attribute__ (( packed )); + +union dns_rr_info { + struct dns_rr_info_common common; + struct dns_rr_info_a a; + struct dns_rr_info_cname cname; +}; + +#endif /* _GPXE_DNS_H */ diff --git a/gpxe/src/include/gpxe/downloader.h b/gpxe/src/include/gpxe/downloader.h new file mode 100644 index 00000000..33aa7692 --- /dev/null +++ b/gpxe/src/include/gpxe/downloader.h @@ -0,0 +1,17 @@ +#ifndef _GPXE_DOWNLOADER_H +#define _GPXE_DOWNLOADER_H + +/** @file + * + * Image downloader + * + */ + +struct job_interface; +struct image; + +extern int create_downloader ( struct job_interface *job, struct image *image, + int ( * register_image ) ( struct image *image ), + int type, ... ); + +#endif /* _GPXE_DOWNLOADER_H */ diff --git a/gpxe/src/include/gpxe/editbox.h b/gpxe/src/include/gpxe/editbox.h new file mode 100644 index 00000000..47b07c25 --- /dev/null +++ b/gpxe/src/include/gpxe/editbox.h @@ -0,0 +1,51 @@ +#ifndef _GPXE_EDITBOX_H +#define _GPXE_EDITBOX_H + +/** @file + * + * Editable text box widget + * + */ + +#include <curses.h> +#include <gpxe/editstring.h> + +/** An editable text box widget */ +struct edit_box { + /** Editable string */ + struct edit_string string; + /** Containing window */ + WINDOW *win; + /** Row */ + unsigned int row; + /** Starting column */ + unsigned int col; + /** Width */ + unsigned int width; + /** First displayed character */ + unsigned int first; +}; + +extern void init_editbox ( struct edit_box *box, char *buf, size_t len, + WINDOW *win, unsigned int row, unsigned int col, + unsigned int width ) + __attribute__ (( nonnull (1, 2) )); +extern void draw_editbox ( struct edit_box *box ) __nonnull; +static inline int __pure edit_editbox ( struct edit_box *box, int key ) __nonnull; + +/** + * Edit text box widget + * + * @v box Editable text box widget + * @v key Key pressed by user + * @ret key Key returned to application, or zero + * + * You must call draw_editbox() to update the display after calling + * edit_editbox(). + * + */ +static inline int edit_editbox ( struct edit_box *box, int key ) { + return edit_string ( &box->string, key ); +} + +#endif /* _GPXE_EDITBOX_H */ diff --git a/gpxe/src/include/gpxe/editstring.h b/gpxe/src/include/gpxe/editstring.h new file mode 100644 index 00000000..fad8bd5a --- /dev/null +++ b/gpxe/src/include/gpxe/editstring.h @@ -0,0 +1,31 @@ +#ifndef _GPXE_EDITSTRING_H +#define _GPXE_EDITSTRING_H + +/** @file + * + * Editable strings + * + */ + +/** An editable string */ +struct edit_string { + /** Buffer for string */ + char *buf; + /** Size of buffer (including terminating NUL) */ + size_t len; + /** Cursor position */ + unsigned int cursor; + + /* The following items are the edit history */ + + /** Last cursor position */ + unsigned int last_cursor; + /** Start of modified portion of string */ + unsigned int mod_start; + /** End of modified portion of string */ + unsigned int mod_end; +}; + +extern int edit_string ( struct edit_string *string, int key ) __nonnull; + +#endif /* _GPXE_EDITSTRING_H */ diff --git a/gpxe/src/include/gpxe/eisa.h b/gpxe/src/include/gpxe/eisa.h new file mode 100644 index 00000000..e9d890e1 --- /dev/null +++ b/gpxe/src/include/gpxe/eisa.h @@ -0,0 +1,125 @@ +#ifndef EISA_H +#define EISA_H + +#include <stdint.h> +#include <gpxe/isa_ids.h> +#include <gpxe/device.h> +#include <gpxe/tables.h> + +/* + * EISA constants + * + */ + +#define EISA_MIN_SLOT (0x1) +#define EISA_MAX_SLOT (0xf) /* Must be 2^n - 1 */ +#define EISA_SLOT_BASE( n ) ( 0x1000 * (n) ) + +#define EISA_VENDOR_ID ( 0xc80 ) +#define EISA_PROD_ID ( 0xc82 ) +#define EISA_GLOBAL_CONFIG ( 0xc84 ) + +#define EISA_CMD_RESET ( 1 << 2 ) +#define EISA_CMD_ENABLE ( 1 << 0 ) + +/** An EISA device ID list entry */ +struct eisa_device_id { + /** Name */ + const char *name; + /** Manufacturer ID */ + uint16_t vendor_id; + /** Product ID */ + uint16_t prod_id; +}; + +/** An EISA device */ +struct eisa_device { + /** Generic device */ + struct device dev; + /** Slot number */ + unsigned int slot; + /** I/O address */ + uint16_t ioaddr; + /** Manufacturer ID */ + uint16_t vendor_id; + /** Product ID */ + uint16_t prod_id; + /** Driver for this device */ + struct eisa_driver *driver; + /** Driver-private data + * + * Use eisa_set_drvdata() and eisa_get_drvdata() to access + * this field. + */ + void *priv; + /** Driver name */ + const char *driver_name; +}; + +/** An EISA driver */ +struct eisa_driver { + /** EISA ID table */ + struct eisa_device_id *ids; + /** Number of entries in EISA ID table */ + unsigned int id_count; + /** + * Probe device + * + * @v eisa EISA device + * @v id Matching entry in ID table + * @ret rc Return status code + */ + int ( * probe ) ( struct eisa_device *eisa, + const struct eisa_device_id *id ); + /** + * Remove device + * + * @v eisa EISA device + */ + void ( * remove ) ( struct eisa_device *eisa ); +}; + +/** Declare an EISA driver */ +#define __eisa_driver __table ( struct eisa_driver, eisa_drivers, 01 ) + +extern void eisa_device_enabled ( struct eisa_device *eisa, int enabled ); + +/** + * Enable EISA device + * + * @v eisa EISA device + */ +static inline void enable_eisa_device ( struct eisa_device *eisa ) { + eisa_device_enabled ( eisa, 1 ); +} + +/** + * Disable EISA device + * + * @v eisa EISA device + */ +static inline void disable_eisa_device ( struct eisa_device *eisa ) { + eisa_device_enabled ( eisa, 0 ); +} + +/** + * Set EISA driver-private data + * + * @v eisa EISA device + * @v priv Private data + */ +static inline void eisa_set_drvdata ( struct eisa_device *eisa, void *priv ) { + eisa->priv = priv; +} + +/** + * Get EISA driver-private data + * + * @v eisa EISA device + * @ret priv Private data + */ +static inline void * eisa_get_drvdata ( struct eisa_device *eisa ) { + return eisa->priv; +} + +#endif /* EISA_H */ diff --git a/gpxe/src/include/gpxe/elf.h b/gpxe/src/include/gpxe/elf.h new file mode 100644 index 00000000..db28a60a --- /dev/null +++ b/gpxe/src/include/gpxe/elf.h @@ -0,0 +1,15 @@ +#ifndef _GPXE_ELF_H +#define _GPXE_ELF_H + +/** + * @file + * + * ELF image format + * + */ + +#include <elf.h> + +extern int elf_load ( struct image *image ); + +#endif /* _GPXE_ELF_H */ diff --git a/gpxe/src/include/gpxe/embedded.h b/gpxe/src/include/gpxe/embedded.h new file mode 100644 index 00000000..ec457055 --- /dev/null +++ b/gpxe/src/include/gpxe/embedded.h @@ -0,0 +1,9 @@ +#ifndef _GPXE_EMBEDDED_H +#define _GPXE_EMBEDDED_H + +#include <gpxe/image.h> + +struct image *embedded_image(void); + +#endif + diff --git a/gpxe/src/include/gpxe/errfile.h b/gpxe/src/include/gpxe/errfile.h new file mode 100644 index 00000000..ae8b1480 --- /dev/null +++ b/gpxe/src/include/gpxe/errfile.h @@ -0,0 +1,157 @@ +#ifndef _GPXE_ERRFILE_H +#define _GPXE_ERRFILE_H + +/** @file + * + * Error file identifiers + * + */ + +#include <bits/errfile.h> + +/** + * @defgroup errfilecat Error file identifier categories + * + * @{ + */ + +#define ERRFILE_CORE 0x00002000 /**< Core code */ +#define ERRFILE_DRIVER 0x00004000 /**< Driver code */ +#define ERRFILE_NET 0x00006000 /**< Networking code */ +#define ERRFILE_IMAGE 0x00008000 /**< Image code */ +#define ERRFILE_OTHER 0x0000e000 /**< Any other code */ + +/** @} */ + +/** Flag for architecture-dependent error files */ +#define ERRFILE_ARCH 0x00800000 + +/** + * @defgroup errfile Error file identifiers + * + * These values are automatically incorporated into the definitions + * for error numbers such as EINVAL. + * + * @{ + */ + +#define ERRFILE_asprintf ( ERRFILE_CORE | 0x00000000 ) +#define ERRFILE_downloader ( ERRFILE_CORE | 0x00010000 ) +#define ERRFILE_exec ( ERRFILE_CORE | 0x00020000 ) +#define ERRFILE_hw ( ERRFILE_CORE | 0x00030000 ) +#define ERRFILE_iobuf ( ERRFILE_CORE | 0x00040000 ) +#define ERRFILE_job ( ERRFILE_CORE | 0x00050000 ) +#define ERRFILE_linebuf ( ERRFILE_CORE | 0x00060000 ) +#define ERRFILE_monojob ( ERRFILE_CORE | 0x00070000 ) +#define ERRFILE_nvo ( ERRFILE_CORE | 0x00080000 ) +#define ERRFILE_open ( ERRFILE_CORE | 0x00090000 ) +#define ERRFILE_posix_io ( ERRFILE_CORE | 0x000a0000 ) +#define ERRFILE_resolv ( ERRFILE_CORE | 0x000b0000 ) +#define ERRFILE_settings ( ERRFILE_CORE | 0x000c0000 ) +#define ERRFILE_vsprintf ( ERRFILE_CORE | 0x000d0000 ) +#define ERRFILE_xfer ( ERRFILE_CORE | 0x000e0000 ) +#define ERRFILE_bitmap ( ERRFILE_CORE | 0x000f0000 ) + +#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 ) +#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 ) +#define ERRFILE_isapnp ( ERRFILE_DRIVER | 0x00020000 ) +#define ERRFILE_mca ( ERRFILE_DRIVER | 0x00030000 ) +#define ERRFILE_pci ( ERRFILE_DRIVER | 0x00040000 ) + +#define ERRFILE_nvs ( ERRFILE_DRIVER | 0x00100000 ) +#define ERRFILE_spi ( ERRFILE_DRIVER | 0x00110000 ) +#define ERRFILE_i2c_bit ( ERRFILE_DRIVER | 0x00120000 ) +#define ERRFILE_spi_bit ( ERRFILE_DRIVER | 0x00130000 ) + +#define ERRFILE_3c509 ( ERRFILE_DRIVER | 0x00200000 ) +#define ERRFILE_bnx2 ( ERRFILE_DRIVER | 0x00210000 ) +#define ERRFILE_cs89x0 ( ERRFILE_DRIVER | 0x00220000 ) +#define ERRFILE_eepro ( ERRFILE_DRIVER | 0x00230000 ) +#define ERRFILE_etherfabric ( ERRFILE_DRIVER | 0x00240000 ) +#define ERRFILE_legacy ( ERRFILE_DRIVER | 0x00250000 ) +#define ERRFILE_natsemi ( ERRFILE_DRIVER | 0x00260000 ) +#define ERRFILE_pnic ( ERRFILE_DRIVER | 0x00270000 ) +#define ERRFILE_prism2_pci ( ERRFILE_DRIVER | 0x00280000 ) +#define ERRFILE_prism2_plx ( ERRFILE_DRIVER | 0x00290000 ) +#define ERRFILE_rtl8139 ( ERRFILE_DRIVER | 0x002a0000 ) +#define ERRFILE_smc9000 ( ERRFILE_DRIVER | 0x002b0000 ) +#define ERRFILE_tg3 ( ERRFILE_DRIVER | 0x002c0000 ) +#define ERRFILE_3c509_eisa ( ERRFILE_DRIVER | 0x002d0000 ) +#define ERRFILE_3c515 ( ERRFILE_DRIVER | 0x002e0000 ) +#define ERRFILE_3c529 ( ERRFILE_DRIVER | 0x002f0000 ) +#define ERRFILE_3c595 ( ERRFILE_DRIVER | 0x00300000 ) +#define ERRFILE_3c5x9 ( ERRFILE_DRIVER | 0x00310000 ) +#define ERRFILE_3c90x ( ERRFILE_DRIVER | 0x00320000 ) +#define ERRFILE_amd8111e ( ERRFILE_DRIVER | 0x00330000 ) +#define ERRFILE_davicom ( ERRFILE_DRIVER | 0x00340000 ) +#define ERRFILE_depca ( ERRFILE_DRIVER | 0x00350000 ) +#define ERRFILE_dmfe ( ERRFILE_DRIVER | 0x00360000 ) +#define ERRFILE_eepro100 ( ERRFILE_DRIVER | 0x00380000 ) +#define ERRFILE_epic100 ( ERRFILE_DRIVER | 0x00390000 ) +#define ERRFILE_forcedeth ( ERRFILE_DRIVER | 0x003a0000 ) +#define ERRFILE_mtd80x ( ERRFILE_DRIVER | 0x003b0000 ) +#define ERRFILE_ns83820 ( ERRFILE_DRIVER | 0x003c0000 ) +#define ERRFILE_ns8390 ( ERRFILE_DRIVER | 0x003d0000 ) +#define ERRFILE_pcnet32 ( ERRFILE_DRIVER | 0x003e0000 ) +#define ERRFILE_r8169 ( ERRFILE_DRIVER | 0x003f0000 ) +#define ERRFILE_sis900 ( ERRFILE_DRIVER | 0x00400000 ) +#define ERRFILE_sundance ( ERRFILE_DRIVER | 0x00410000 ) +#define ERRFILE_tlan ( ERRFILE_DRIVER | 0x00420000 ) +#define ERRFILE_tulip ( ERRFILE_DRIVER | 0x00430000 ) +#define ERRFILE_via_rhine ( ERRFILE_DRIVER | 0x00440000 ) +#define ERRFILE_via_velocity ( ERRFILE_DRIVER | 0x00450000 ) +#define ERRFILE_w89c840 ( ERRFILE_DRIVER | 0x00460000 ) +#define ERRFILE_ipoib ( ERRFILE_DRIVER | 0x00470000 ) +#define ERRFILE_e1000 ( ERRFILE_DRIVER | 0x00480000 ) +#define ERRFILE_e1000_hw ( ERRFILE_DRIVER | 0x00490000 ) + +#define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 ) +#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 ) +#define ERRFILE_hermon ( ERRFILE_DRIVER | 0x00720000 ) + +#define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 ) +#define ERRFILE_arp ( ERRFILE_NET | 0x00010000 ) +#define ERRFILE_dhcpopts ( ERRFILE_NET | 0x00020000 ) +#define ERRFILE_ethernet ( ERRFILE_NET | 0x00030000 ) +#define ERRFILE_icmpv6 ( ERRFILE_NET | 0x00040000 ) +#define ERRFILE_ipv4 ( ERRFILE_NET | 0x00050000 ) +#define ERRFILE_ipv6 ( ERRFILE_NET | 0x00060000 ) +#define ERRFILE_ndp ( ERRFILE_NET | 0x00070000 ) +#define ERRFILE_netdevice ( ERRFILE_NET | 0x00080000 ) +#define ERRFILE_nullnet ( ERRFILE_NET | 0x00090000 ) +#define ERRFILE_tcp ( ERRFILE_NET | 0x000a0000 ) +#define ERRFILE_ftp ( ERRFILE_NET | 0x000b0000 ) +#define ERRFILE_http ( ERRFILE_NET | 0x000c0000 ) +#define ERRFILE_iscsi ( ERRFILE_NET | 0x000d0000 ) +#define ERRFILE_tcpip ( ERRFILE_NET | 0x000e0000 ) +#define ERRFILE_udp ( ERRFILE_NET | 0x000f0000 ) +#define ERRFILE_dhcp ( ERRFILE_NET | 0x00100000 ) +#define ERRFILE_dns ( ERRFILE_NET | 0x00110000 ) +#define ERRFILE_tftp ( ERRFILE_NET | 0x00120000 ) +#define ERRFILE_infiniband ( ERRFILE_NET | 0x00130000 ) +#define ERRFILE_netdev_settings ( ERRFILE_NET | 0x00140000 ) +#define ERRFILE_dhcppkt ( ERRFILE_NET | 0x00150000 ) + +#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) +#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) +#define ERRFILE_script ( ERRFILE_IMAGE | 0x00020000 ) +#define ERRFILE_segment ( ERRFILE_IMAGE | 0x00030000 ) + +#define ERRFILE_asn1 ( ERRFILE_OTHER | 0x00000000 ) +#define ERRFILE_chap ( ERRFILE_OTHER | 0x00010000 ) +#define ERRFILE_aoeboot ( ERRFILE_OTHER | 0x00020000 ) +#define ERRFILE_autoboot ( ERRFILE_OTHER | 0x00030000 ) +#define ERRFILE_dhcpmgmt ( ERRFILE_OTHER | 0x00040000 ) +#define ERRFILE_imgmgmt ( ERRFILE_OTHER | 0x00050000 ) +#define ERRFILE_pxe_tftp ( ERRFILE_OTHER | 0x00060000 ) +#define ERRFILE_pxe_udp ( ERRFILE_OTHER | 0x00070000 ) +#define ERRFILE_axtls_aes ( ERRFILE_OTHER | 0x00080000 ) +#define ERRFILE_cipher ( ERRFILE_OTHER | 0x00090000 ) +#define ERRFILE_image_cmd ( ERRFILE_OTHER | 0x000a0000 ) +#define ERRFILE_uri_test ( ERRFILE_OTHER | 0x000b0000 ) +#define ERRFILE_ibft ( ERRFILE_OTHER | 0x000c0000 ) +#define ERRFILE_tls ( ERRFILE_OTHER | 0x000d0000 ) + +/** @} */ + +#endif /* _GPXE_ERRFILE_H */ diff --git a/gpxe/src/include/gpxe/errortab.h b/gpxe/src/include/gpxe/errortab.h new file mode 100644 index 00000000..e9a56768 --- /dev/null +++ b/gpxe/src/include/gpxe/errortab.h @@ -0,0 +1,19 @@ +#ifndef _GPXE_ERRORTAB_H +#define _GPXE_ERRORTAB_H + +/** @file + * + * Error message tables + * + */ + +#include <gpxe/tables.h> + +struct errortab { + int errno; + const char *text; +}; + +#define __errortab __table ( struct errortab, errortab, 01 ) + +#endif /* _GPXE_ERRORTAB_H */ diff --git a/gpxe/src/include/gpxe/ethernet.h b/gpxe/src/include/gpxe/ethernet.h new file mode 100644 index 00000000..158fe066 --- /dev/null +++ b/gpxe/src/include/gpxe/ethernet.h @@ -0,0 +1,33 @@ +#ifndef _GPXE_ETHERNET_H +#define _GPXE_ETHERNET_H + +/** @file + * + * Ethernet protocol + * + */ + +#include <stdint.h> +#include <gpxe/netdevice.h> + +extern struct ll_protocol ethernet_protocol; + +extern const char * eth_ntoa ( const void *ll_addr ); + +/** + * Allocate Ethernet device + * + * @v priv_size Size of driver private data + * @ret netdev Network device, or NULL + */ +static inline struct net_device * alloc_etherdev ( size_t priv_size ) { + struct net_device *netdev; + + netdev = alloc_netdev ( priv_size ); + if ( netdev ) { + netdev->ll_protocol = ðernet_protocol; + } + return netdev; +} + +#endif /* _GPXE_ETHERNET_H */ diff --git a/gpxe/src/include/gpxe/fakedhcp.h b/gpxe/src/include/gpxe/fakedhcp.h new file mode 100644 index 00000000..990b56af --- /dev/null +++ b/gpxe/src/include/gpxe/fakedhcp.h @@ -0,0 +1,21 @@ +#ifndef _GPXE_FAKEDHCP_H +#define _GPXE_FAKEDHCP_H + +/** @file + * + * Fake DHCP packets + * + */ + +#include <stdint.h> + +struct net_device; + +extern int create_fakedhcpdiscover ( struct net_device *netdev, + void *data, size_t max_len ); +extern int create_fakedhcpack ( struct net_device *netdev, + void *data, size_t max_len ); +extern int create_fakeproxydhcpack ( struct net_device *netdev, + void *data, size_t max_len ); + +#endif /* _GPXE_FAKEDHCP_H */ diff --git a/gpxe/src/include/gpxe/features.h b/gpxe/src/include/gpxe/features.h new file mode 100644 index 00000000..a520131f --- /dev/null +++ b/gpxe/src/include/gpxe/features.h @@ -0,0 +1,88 @@ +#ifndef _GPXE_FEATURES_H +#define _GPXE_FEATURES_H + +#include <stdint.h> +#include <gpxe/tables.h> +#include <gpxe/dhcp.h> + +/** @file + * + * Feature list + * + */ + +/** + * @defgroup featurecat Feature categories + * @{ + */ + +#define FEATURE_PROTOCOL 01 /**< Network protocols */ +#define FEATURE_IMAGE 02 /**< Image formats */ +#define FEATURE_MISC 03 /**< Miscellaneous */ + +/** @} */ + +/** + * @defgroup dhcpfeatures DHCP feature option tags + * + * DHCP feature option tags are Etherboot encapsulated options in the + * range 0x10-0x7f. + * + * @{ + */ + +#define DHCP_EB_FEATURE_PXE_EXT 0x10 /**< PXE API extensions */ +#define DHCP_EB_FEATURE_ISCSI 0x11 /**< iSCSI protocol */ +#define DHCP_EB_FEATURE_AOE 0x12 /**< AoE protocol */ +#define DHCP_EB_FEATURE_HTTP 0x13 /**< HTTP protocol */ +#define DHCP_EB_FEATURE_HTTPS 0x14 /**< HTTPS protocol */ +#define DHCP_EB_FEATURE_TFTP 0x15 /**< TFTP protocol */ +#define DHCP_EB_FEATURE_FTP 0x16 /**< FTP protocol */ +#define DHCP_EB_FEATURE_DNS 0x17 /**< DNS protocol */ +#define DHCP_EB_FEATURE_BZIMAGE 0x18 /**< bzImage format */ +#define DHCP_EB_FEATURE_MULTIBOOT 0x19 /**< Multiboot format */ +#define DHCP_EB_FEATURE_NBI 0x20 /**< NBI format */ +#define DHCP_EB_FEATURE_PXE 0x21 /**< PXE format */ + +/** @} */ + +/** Declare a feature code for DHCP */ +#define __dhcp_feature( category ) \ + __table ( uint8_t, dhcp_features, category ) + +/** Construct a DHCP feature table entry */ +#define DHCP_FEATURE( category, feature_opt, version ) \ + _DHCP_FEATURE ( category, OBJECT, feature_opt, version ) +#define _DHCP_FEATURE( category, _name, feature_opt, version ) \ + __DHCP_FEATURE ( category, _name, feature_opt, version ) +#define __DHCP_FEATURE( category, _name, feature_opt, version ) \ + uint8_t __dhcp_feature_ ## _name [] __dhcp_feature ( category ) = { \ + feature_opt, DHCP_BYTE ( version ) \ + }; + +/** A named feature */ +struct feature { + /** Feature name */ + char *name; +}; + +/** Declare a named feature */ +#define __feature_name( category ) \ + __table ( struct feature, features, category ) + +/** Construct a named feature */ +#define FEATURE_NAME( category, text ) \ + _FEATURE_NAME ( category, OBJECT, text ) +#define _FEATURE_NAME( category, _name, text ) \ + __FEATURE_NAME ( category, _name, text ) +#define __FEATURE_NAME( category, _name, text ) \ + struct feature __feature_ ## _name __feature_name ( category ) = { \ + .name = text, \ + }; + +/** Declare a feature */ +#define FEATURE( category, text, feature_opt, version ) \ + FEATURE_NAME ( category, text ); \ + DHCP_FEATURE ( category, feature_opt, version ); + +#endif /* _GPXE_FEATURES_H */ diff --git a/gpxe/src/include/gpxe/filter.h b/gpxe/src/include/gpxe/filter.h new file mode 100644 index 00000000..126f6347 --- /dev/null +++ b/gpxe/src/include/gpxe/filter.h @@ -0,0 +1,73 @@ +#ifndef _GPXE_FILTER_H +#define _GPXE_FILTER_H + +/** @file + * + * Data transfer filters + * + */ + +#include <stddef.h> +#include <gpxe/xfer.h> + +/** + * Half of a data transfer filter + * + * Embed two of these structures within a structure implementing a + * data transfer filter, and intialise with filter_init(). You can + * then use the filter_xxx() methods as the data transfer interface + * methods as required. + */ +struct xfer_filter_half { + /** Data transfer interface */ + struct xfer_interface xfer; + /** Other half of the data transfer filter */ + struct xfer_filter_half *other; +}; + +/** + * Get data transfer interface for the other half of a data transfer filter + * + * @v xfer Data transfer interface + * @ret other Other half's data transfer interface + */ +static inline __attribute__ (( always_inline )) struct xfer_interface * +filter_other_half ( struct xfer_interface *xfer ) { + struct xfer_filter_half *half = + container_of ( xfer, struct xfer_filter_half, xfer ); + return &half->other->xfer; +} + +extern void filter_close ( struct xfer_interface *xfer, int rc ); +extern int filter_vredirect ( struct xfer_interface *xfer, int type, + va_list args ); +extern size_t filter_window ( struct xfer_interface *xfer ); +extern struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer, + size_t len ); +extern int filter_deliver_iob ( struct xfer_interface *xfer, + struct io_buffer *iobuf, + struct xfer_metadata *meta ); +extern int filter_deliver_raw ( struct xfer_interface *xfer, const void *data, + size_t len ); + +/** + * Initialise a data transfer filter + * + * @v left "Left" half of the filter + * @v left_op Data transfer interface operations for "left" half + * @v right "Right" half of the filter + * @v right_op Data transfer interface operations for "right" half + * @v refcnt Containing object reference counter, or NULL + */ +static inline void filter_init ( struct xfer_filter_half *left, + struct xfer_interface_operations *left_op, + struct xfer_filter_half *right, + struct xfer_interface_operations *right_op, + struct refcnt *refcnt ) { + xfer_init ( &left->xfer, left_op, refcnt ); + xfer_init ( &right->xfer, right_op, refcnt ); + left->other = right; + right->other = left; +} + +#endif /* _GPXE_FILTER_H */ diff --git a/gpxe/src/include/gpxe/ftp.h b/gpxe/src/include/gpxe/ftp.h new file mode 100644 index 00000000..370285c6 --- /dev/null +++ b/gpxe/src/include/gpxe/ftp.h @@ -0,0 +1,13 @@ +#ifndef _GPXE_FTP_H +#define _GPXE_FTP_H + +/** @file + * + * File transfer protocol + * + */ + +/** FTP default port */ +#define FTP_PORT 21 + +#endif /* _GPXE_FTP_H */ diff --git a/gpxe/src/include/gpxe/hidemem.h b/gpxe/src/include/gpxe/hidemem.h new file mode 100644 index 00000000..547f8881 --- /dev/null +++ b/gpxe/src/include/gpxe/hidemem.h @@ -0,0 +1,23 @@ +#ifndef _GPXE_HIDEMEM_H +#define _GPXE_HIDEMEM_H + +/** + * @file + * + * Hidden memory regions + * + */ + +/** + * Unique IDs for hidden regions + */ +enum hidemem_region_id { + TEXT = 0, + BASEMEM, + EXTMEM, +}; + +extern void hide_region ( unsigned int region_id, physaddr_t start, + physaddr_t end ); + +#endif /* _GPXE_HIDEMEM_H */ diff --git a/gpxe/src/include/gpxe/hmac.h b/gpxe/src/include/gpxe/hmac.h new file mode 100644 index 00000000..fd34db04 --- /dev/null +++ b/gpxe/src/include/gpxe/hmac.h @@ -0,0 +1,30 @@ +#ifndef _GPXE_HMAC_H +#define _GPXE_HMAC_H + +/** @file + * + * Keyed-Hashing for Message Authentication + */ + +#include <gpxe/crypto.h> + +/** + * Update HMAC + * + * @v digest Digest algorithm to use + * @v digest_ctx Digest context + * @v data Data + * @v len Length of data + */ +static inline void hmac_update ( struct crypto_algorithm *digest, + void *digest_ctx, const void *data, + size_t len ) { + digest_update ( digest, digest_ctx, data, len ); +} + +extern void hmac_init ( struct crypto_algorithm *digest, void *digest_ctx, + void *key, size_t *key_len ); +extern void hmac_final ( struct crypto_algorithm *digest, void *digest_ctx, + void *key, size_t *key_len, void *hmac ); + +#endif /* _GPXE_HMAC_H */ diff --git a/gpxe/src/include/gpxe/http.h b/gpxe/src/include/gpxe/http.h new file mode 100644 index 00000000..fa92a950 --- /dev/null +++ b/gpxe/src/include/gpxe/http.h @@ -0,0 +1,21 @@ +#ifndef _GPXE_HTTP_H +#define _GPXE_HTTP_H + +/** @file + * + * Hyper Text Transport Protocol + * + */ + +/** HTTP default port */ +#define HTTP_PORT 80 + +/** HTTPS default port */ +#define HTTPS_PORT 443 + +extern int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, + unsigned int default_port, + int ( * filter ) ( struct xfer_interface *, + struct xfer_interface ** ) ); + +#endif /* _GPXE_HTTP_H */ diff --git a/gpxe/src/include/gpxe/i2c.h b/gpxe/src/include/gpxe/i2c.h new file mode 100644 index 00000000..bfaee8fb --- /dev/null +++ b/gpxe/src/include/gpxe/i2c.h @@ -0,0 +1,111 @@ +#ifndef _GPXE_I2C_H +#define _GPXE_I2C_H + +/** @file + * + * I2C interface + * + */ + +#include <stdint.h> + +/** An I2C device + * + * An I2C device represents a specific slave device on an I2C bus. It + * is accessed via an I2C interface. + */ +struct i2c_device { + /** Address of this device */ + unsigned int address; + /** Flag indicating a ten-bit address format */ + int tenbit; +}; + +/** An I2C interface + * + * An I2C interface provides access to an I2C bus, via which I2C + * devices may be reached. + */ +struct i2c_interface { + /** + * Read data from I2C device + * + * @v i2c I2C interface + * @v i2cdev I2C device + * @v offset Starting offset within the device + * @v data Data buffer + * @v len Length of data buffer + * @ret rc Return status code + */ + int ( * read ) ( struct i2c_interface *i2c, struct i2c_device *i2cdev, + unsigned int offset, uint8_t *data, + unsigned int len ); + /** + * Write data to I2C device + * + * @v i2c I2C interface + * @v i2cdev I2C device + * @v offset Starting offset within the device + * @v data Data buffer + * @v len Length of data buffer + * @ret rc Return status code + */ + int ( * write ) ( struct i2c_interface *i2c, struct i2c_device *i2cdev, + unsigned int offset, const uint8_t *data, + unsigned int len ); +}; + +/** A bit-bashing I2C interface + * + * This provides a standardised way to construct I2C buses via a + * bit-bashing interface. + */ +struct i2c_bit_basher { + /** I2C interface */ + struct i2c_interface i2c; + /** Bit-bashing interface */ + struct bit_basher basher; +}; + +/** Ten-bit address marker + * + * This value is ORed with the I2C device address to indicate a + * ten-bit address format on the bus. + */ +#define I2C_TENBIT_ADDRESS 0x7800 + +/** An I2C write command */ +#define I2C_WRITE 0 + +/** An I2C read command */ +#define I2C_READ 1 + +/** Bit indices used for I2C bit-bashing interface */ +enum { + /** Serial clock */ + I2C_BIT_SCL = 0, + /** Serial data */ + I2C_BIT_SDA, +}; + +/** Delay required for bit-bashing operation */ +#define I2C_UDELAY 5 + +/** + * Check presence of I2C device + * + * @v i2c I2C interface + * @v i2cdev I2C device + * @ret rc Return status code + * + * Checks for the presence of the device on the I2C bus by attempting + * a zero-length write. + */ +static inline int i2c_check_presence ( struct i2c_interface *i2c, + struct i2c_device *i2cdev ) { + return i2c->write ( i2c, i2cdev, 0, NULL, 0 ); +} + +extern void init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit ); + +#endif /* _GPXE_I2C_H */ diff --git a/gpxe/src/include/gpxe/ibft.h b/gpxe/src/include/gpxe/ibft.h new file mode 100644 index 00000000..5eef547b --- /dev/null +++ b/gpxe/src/include/gpxe/ibft.h @@ -0,0 +1,300 @@ +#ifndef _GPXE_IBFT_H +#define _GPXE_IBFT_H + +/* + * Copyright Fen Systems Ltd. 2007. Portions of this code are derived + * from IBM Corporation Sample Programs. Copyright IBM Corporation + * 2004, 2007. All rights reserved. + * + * 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 + * + * iSCSI boot firmware table + * + * The information in this file is derived from the document "iSCSI + * Boot Firmware Table (iBFT)" as published by IBM at + * + * ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_iscsi_boot_firmware_table_v1.02.pdf + * + */ + +#include <stdint.h> +#include <gpxe/acpi.h> +#include <gpxe/in.h> + +/** iSCSI Boot Firmware Table signature */ +#define IBFT_SIG "iBFT" + +/** An offset from the start of the iBFT */ +typedef uint16_t ibft_off_t; + +/** Length of a string within the iBFT (excluding terminating NUL) */ +typedef uint16_t ibft_size_t; + +/** A string within the iBFT */ +struct ibft_string { + /** Length of string */ + ibft_size_t length; + /** Offset to string */ + ibft_off_t offset; +} __attribute__ (( packed )); + +/** An IP address within the iBFT */ +struct ibft_ipaddr { + /** Reserved; must be zero */ + uint16_t zeroes[5]; + /** Must be 0xffff if IPv4 address is present, otherwise zero */ + uint16_t ones; + /** The IPv4 address, or zero if not present */ + struct in_addr in; +} __attribute__ (( packed )); + +/** + * iBFT structure header + * + * This structure is common to several sections within the iBFT. + */ +struct ibft_header { + /** Structure ID + * + * This is an IBFT_STRUCTURE_ID_XXX constant + */ + uint8_t structure_id; + /** Version (always 1) */ + uint8_t version; + /** Length, including this header */ + uint16_t length; + /** Index + * + * This is the number of the NIC or Target, when applicable. + */ + uint8_t index; + /** Flags */ + uint8_t flags; +} __attribute__ (( packed )); + +/** + * iBFT Control structure + * + */ +struct ibft_control { + /** Common header */ + struct ibft_header header; + /** Extensions */ + uint16_t extensions; + /** Offset to Initiator structure */ + ibft_off_t initiator; + /** Offset to NIC structure for NIC 0 */ + ibft_off_t nic_0; + /** Offset to Target structure for target 0 */ + ibft_off_t target_0; + /** Offset to NIC structure for NIC 1 */ + ibft_off_t nic_1; + /** Offset to Target structure for target 1 */ + ibft_off_t target_1; +} __attribute__ (( packed )); + +/** Structure ID for Control section */ +#define IBFT_STRUCTURE_ID_CONTROL 0x01 + +/** Attempt login only to specified target + * + * If this flag is not set, all targets will be logged in to. + */ +#define IBFT_FL_CONTROL_SINGLE_LOGIN_ONLY 0x01 + +/** + * iBFT Initiator structure + * + */ +struct ibft_initiator { + /** Common header */ + struct ibft_header header; + /** iSNS server */ + struct ibft_ipaddr isns_server; + /** SLP server */ + struct ibft_ipaddr slp_server; + /** Primary and secondary Radius servers */ + struct ibft_ipaddr radius[2]; + /** Initiator name */ + struct ibft_string initiator_name; +} __attribute__ (( packed )); + +/** Structure ID for Initiator section */ +#define IBFT_STRUCTURE_ID_INITIATOR 0x02 + +/** Initiator block valid */ +#define IBFT_FL_INITIATOR_BLOCK_VALID 0x01 + +/** Initiator firmware boot selected */ +#define IBFT_FL_INITIATOR_FIRMWARE_BOOT_SELECTED 0x02 + +/** + * iBFT NIC structure + * + */ +struct ibft_nic { + /** Common header */ + struct ibft_header header; + /** IP address */ + struct ibft_ipaddr ip_address; + /** Subnet mask + * + * This is the length of the subnet mask in bits (e.g. /24). + */ + uint8_t subnet_mask_prefix; + /** Origin */ + uint8_t origin; + /** Default gateway */ + struct ibft_ipaddr gateway; + /** Primary and secondary DNS servers */ + struct ibft_ipaddr dns[2]; + /** DHCP server */ + struct ibft_ipaddr dhcp; + /** VLAN tag */ + uint16_t vlan; + /** MAC address */ + uint8_t mac_address[6]; + /** PCI bus:dev:fn */ + uint16_t pci_bus_dev_func; + /** Hostname */ + struct ibft_string hostname; +} __attribute__ (( packed )); + +/** Structure ID for NIC section */ +#define IBFT_STRUCTURE_ID_NIC 0x03 + +/** NIC block valid */ +#define IBFT_FL_NIC_BLOCK_VALID 0x01 + +/** NIC firmware boot selected */ +#define IBFT_FL_NIC_FIRMWARE_BOOT_SELECTED 0x02 + +/** NIC global / link local */ +#define IBFT_FL_NIC_GLOBAL 0x04 + +/** + * iBFT Target structure + * + */ +struct ibft_target { + /** Common header */ + struct ibft_header header; + /** IP address */ + struct ibft_ipaddr ip_address; + /** TCP port */ + uint16_t socket; + /** Boot LUN */ + uint64_t boot_lun; + /** CHAP type + * + * This is an IBFT_CHAP_XXX constant. + */ + uint8_t chap_type; + /** NIC association */ + uint8_t nic_association; + /** Target name */ + struct ibft_string target_name; + /** CHAP name */ + struct ibft_string chap_name; + /** CHAP secret */ + struct ibft_string chap_secret; + /** Reverse CHAP name */ + struct ibft_string reverse_chap_name; + /** Reverse CHAP secret */ + struct ibft_string reverse_chap_secret; +} __attribute__ (( packed )); + +/** Structure ID for Target section */ +#define IBFT_STRUCTURE_ID_TARGET 0x04 + +/** Target block valid */ +#define IBFT_FL_TARGET_BLOCK_VALID 0x01 + +/** Target firmware boot selected */ +#define IBFT_FL_TARGET_FIRMWARE_BOOT_SELECTED 0x02 + +/** Target use Radius CHAP */ +#define IBFT_FL_TARGET_USE_CHAP 0x04 + +/** Target use Radius rCHAP */ +#define IBFT_FL_TARGET_USE_RCHAP 0x08 + +/* Values for chap_type */ +#define IBFT_CHAP_NONE 0 /**< No CHAP authentication */ +#define IBFT_CHAP_ONE_WAY 1 /**< One-way CHAP */ +#define IBFT_CHAP_MUTUAL 2 /**< Mutual CHAP */ + +/** + * iSCSI Boot Firmware Table (iBFT) + */ +struct ibft_table { + /** ACPI header */ + struct acpi_description_header acpi; + /** Reserved */ + uint8_t reserved[12]; + /** Control structure */ + struct ibft_control control; +} __attribute__ (( packed )); + +/** + * iSCSI string block descriptor + * + * This is an internal structure that we use to keep track of the + * allocation of string data. + */ +struct ibft_string_block { + /** The iBFT containing these strings */ + struct ibft_table *table; + /** Offset of first free byte within iBFT */ + unsigned int offset; +}; + +/** Amount of space reserved for strings in a gPXE iBFT */ +#define IBFT_STRINGS_SIZE 384 + +/** + * An iBFT created by gPXE + * + */ +struct gpxe_ibft { + /** The fixed section */ + struct ibft_table table; + /** The Initiator section */ + struct ibft_initiator initiator __attribute__ (( aligned ( 16 ) )); + /** The NIC section */ + struct ibft_nic nic __attribute__ (( aligned ( 16 ) )); + /** The Target section */ + struct ibft_target target __attribute__ (( aligned ( 16 ) )); + /** Strings block */ + char strings[IBFT_STRINGS_SIZE]; +} __attribute__ (( packed, aligned ( 16 ) )); + +struct net_device; +struct iscsi_session; + +extern int ibft_fill_data ( struct net_device *netdev, + struct iscsi_session *iscsi ); + +#endif /* _GPXE_IBFT_H */ diff --git a/gpxe/src/include/gpxe/icmp6.h b/gpxe/src/include/gpxe/icmp6.h new file mode 100644 index 00000000..34093616 --- /dev/null +++ b/gpxe/src/include/gpxe/icmp6.h @@ -0,0 +1,57 @@ +#ifndef _GPXE_ICMP6_H +#define _GPXE_ICMP6_H + +/** @file + * + * ICMP6 protocol + * + */ + +#include <gpxe/ip6.h> +#include <gpxe/ndp.h> + +#define ICMP6_NSOLICIT 135 +#define ICMP6_NADVERT 136 + +extern struct tcpip_protocol icmp6_protocol; + +struct icmp6_header { + uint8_t type; + uint8_t code; + uint16_t csum; + /* Message body */ +}; + +struct neighbour_solicit { + uint8_t type; + uint8_t code; + uint16_t csum; + uint32_t reserved; + struct in6_addr target; + /* "Compulsory" options */ + uint8_t opt_type; + uint8_t opt_len; + /* FIXME: hack alert */ + uint8_t opt_ll_addr[6]; +}; + +struct neighbour_advert { + uint8_t type; + uint8_t code; + uint16_t csum; + uint8_t flags; + uint8_t reserved; + struct in6_addr target; + uint8_t opt_type; + uint8_t opt_len; + /* FIXME: hack alert */ + uint8_t opt_ll_addr[6]; +}; + +#define ICMP6_FLAGS_ROUTER 0x80 +#define ICMP6_FLAGS_SOLICITED 0x40 +#define ICMP6_FLAGS_OVERRIDE 0x20 + +int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest ); + +#endif /* _GPXE_ICMP6_H */ diff --git a/gpxe/src/include/gpxe/if_arp.h b/gpxe/src/include/gpxe/if_arp.h new file mode 100644 index 00000000..5b250337 --- /dev/null +++ b/gpxe/src/include/gpxe/if_arp.h @@ -0,0 +1,100 @@ +#ifndef _GPXE_IF_ARP_H +#define _GPXE_IF_ARP_H + +/** @file + * + * Address Resolution Protocol constants and types + * + */ + +#include <stdint.h> + +/* ARP protocol HARDWARE identifiers. */ +#define ARPHRD_NETROM 0 /**< from KA9Q: NET/ROM pseudo */ +#define ARPHRD_ETHER 1 /**< Ethernet 10Mbps */ +#define ARPHRD_EETHER 2 /**< Experimental Ethernet */ +#define ARPHRD_AX25 3 /**< AX.25 Level 2 */ +#define ARPHRD_PRONET 4 /**< PROnet token ring */ +#define ARPHRD_CHAOS 5 /**< Chaosnet */ +#define ARPHRD_IEEE802 6 /**< IEEE 802.2 Ethernet/TR/TB */ +#define ARPHRD_ARCNET 7 /**< ARCnet */ +#define ARPHRD_APPLETLK 8 /**< APPLEtalk */ +#define ARPHRD_DLCI 15 /**< Frame Relay DLCI */ +#define ARPHRD_ATM 19 /**< ATM */ +#define ARPHRD_METRICOM 23 /**< Metricom STRIP (new IANA id) */ +#define ARPHRD_IEEE1394 24 /**< IEEE 1394 IPv4 - RFC 2734 */ +#define ARPHRD_EUI64 27 /**< EUI-64 */ +#define ARPHRD_INFINIBAND 32 /**< InfiniBand */ + +/* ARP protocol opcodes. */ +#define ARPOP_REQUEST 1 /**< ARP request */ +#define ARPOP_REPLY 2 /**< ARP reply */ +#define ARPOP_RREQUEST 3 /**< RARP request */ +#define ARPOP_RREPLY 4 /**< RARP reply */ +#define ARPOP_InREQUEST 8 /**< InARP request */ +#define ARPOP_InREPLY 9 /**< InARP reply */ +#define ARPOP_NAK 10 /**< (ATM)ARP NAK */ + +/** + * An ARP header + * + * This contains only the fixed-size portions of an ARP header; for + * other fields use the arp_{sender,target}_{ha,pa} family of + * functions. + */ +struct arphdr { + /** Link-layer protocol + * + * This is an ARPHRD_XXX constant + */ + uint16_t ar_hrd; + /** Network-layer protocol + * + * This is, for Ethernet, an ETH_P_XXX constant. + */ + uint16_t ar_pro; + /** Link-layer address length */ + uint8_t ar_hln; + /** Network-layer address length */ + uint8_t ar_pln; + /** ARP opcode */ + uint16_t ar_op; +} __attribute__ (( packed )); + +/** ARP packet sender hardware address + * + * @v arphdr ARP header + * @ret ar_sha Sender hardware address + */ +static inline void * arp_sender_ha ( struct arphdr *arphdr ) { + return ( ( ( void * ) arphdr ) + sizeof ( *arphdr ) ); +} + +/** ARP packet sender protocol address + * + * @v arphdr ARP header + * @ret ar_spa Sender protocol address + */ +static inline void * arp_sender_pa ( struct arphdr *arphdr ) { + return ( arp_sender_ha ( arphdr ) + arphdr->ar_hln ); +} + +/** ARP packet target hardware address + * + * @v arphdr ARP header + * @ret ar_tha Target hardware address + */ +static inline void * arp_target_ha ( struct arphdr *arphdr ) { + return ( arp_sender_pa ( arphdr ) + arphdr->ar_pln ); +} + +/** ARP packet target protocol address + * + * @v arphdr ARP header + * @ret ar_tpa Target protocol address + */ +static inline void * arp_target_pa ( struct arphdr *arphdr ) { + return ( arp_target_ha ( arphdr ) + arphdr->ar_hln ); +} + +#endif /* _GPXE_IF_ARP_H */ diff --git a/gpxe/src/include/gpxe/if_ether.h b/gpxe/src/include/gpxe/if_ether.h new file mode 100644 index 00000000..2f3f33d4 --- /dev/null +++ b/gpxe/src/include/gpxe/if_ether.h @@ -0,0 +1,33 @@ +#ifndef _GPXE_IF_ETHER_H +#define _GPXE_IF_ETHER_H + +#include <stdint.h> + +#define ETH_ALEN 6 /* Size of Ethernet address */ +#define ETH_HLEN 14 /* Size of ethernet header */ +#define ETH_ZLEN 60 /* Minimum packet */ +#define ETH_FRAME_LEN 1514 /* Maximum packet */ +#define ETH_DATA_ALIGN 2 /* Amount needed to align the data after an ethernet header */ +#ifndef ETH_MAX_MTU +#define ETH_MAX_MTU (ETH_FRAME_LEN-ETH_HLEN) +#endif + +#define ETH_P_RAW 0x0000 /* Raw packet */ +#define ETH_P_IP 0x0800 /* Internet Protocl Packet */ +#define ETH_P_ARP 0x0806 /* Address Resolution Protocol */ +#define ETH_P_RARP 0x8035 /* Reverse Address resolution Protocol */ +#define ETH_P_IPV6 0x86DD /* IPv6 over blueblook */ +#define ETH_P_SLOW 0x8809 /* Ethernet slow protocols */ +#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ + +/** An Ethernet link-layer header */ +struct ethhdr { + /** Destination MAC address */ + uint8_t h_dest[ETH_ALEN]; + /** Source MAC address */ + uint8_t h_source[ETH_ALEN]; + /** Protocol ID */ + uint16_t h_protocol; +} __attribute__ ((packed)); + +#endif /* _GPXE_IF_ETHER_H */ diff --git a/gpxe/src/include/gpxe/image.h b/gpxe/src/include/gpxe/image.h new file mode 100644 index 00000000..76dc3b8f --- /dev/null +++ b/gpxe/src/include/gpxe/image.h @@ -0,0 +1,162 @@ +#ifndef _GPXE_IMAGE_H +#define _GPXE_IMAGE_H + +/** + * @file + * + * Executable/loadable images + * + */ + +#include <gpxe/tables.h> +#include <gpxe/list.h> +#include <gpxe/uaccess.h> +#include <gpxe/refcnt.h> + +struct uri; +struct image_type; + +/** An executable or loadable image */ +struct image { + /** Reference count */ + struct refcnt refcnt; + + /** List of registered images */ + struct list_head list; + + /** URI of image */ + struct uri *uri; + /** Name */ + char name[16]; + /** Flags */ + unsigned int flags; + + /** Command line to pass to image */ + char *cmdline; + /** Raw file image */ + userptr_t data; + /** Length of raw file image */ + size_t len; + + /** Image type, if known */ + struct image_type *type; + /** Image type private data */ + union { + physaddr_t phys; + userptr_t user; + unsigned long ul; + } priv; +}; + +/** Image is loaded */ +#define IMAGE_LOADED 0x0001 + +/** An executable or loadable image type */ +struct image_type { + /** Name of this image type */ + char *name; + /** + * Load image into memory + * + * @v image Executable/loadable image + * @ret rc Return status code + * + * Load the image into memory at the correct location as + * determined by the file format. + * + * If the file image is in the correct format, the method must + * update @c image->type to point to its own type (unless @c + * image->type is already set). This allows the autoloading + * code to disambiguate between "this is not my image format" + * and "there is something wrong with this image". In + * particular, setting @c image->type and then returning an + * error will cause image_autoload() to abort and return an + * error, rather than continuing to the next image type. + */ + int ( * load ) ( struct image *image ); + /** + * Execute loaded image + * + * @v image Loaded image + * @ret rc Return status code + */ + int ( * exec ) ( struct image *image ); +}; + +/** + * Multiboot image probe priority + * + * Multiboot images are also valid executables in another format + * (e.g. ELF), so we must perform the multiboot probe first. + */ +#define PROBE_MULTIBOOT 01 + +/** + * Normal image probe priority + */ +#define PROBE_NORMAL 02 + +/** + * PXE image probe priority + * + * PXE images have no signature checks, so will claim all image files. + * They must therefore be tried last in the probe order list. + */ +#define PROBE_PXE 03 + +/** An executable or loadable image type */ +#define __image_type( probe_order ) \ + __table ( struct image_type, image_types, probe_order ) + +extern struct list_head images; + +/** Iterate over all registered images */ +#define for_each_image( image ) \ + list_for_each_entry ( (image), &images, list ) + +extern struct image * alloc_image ( void ); +extern int image_set_uri ( struct image *image, struct uri *uri ); +extern int image_set_cmdline ( struct image *image, const char *cmdline ); +extern int register_image ( struct image *image ); +extern void unregister_image ( struct image *image ); +extern void promote_image ( struct image *image ); +struct image * find_image ( const char *name ); +extern int image_load ( struct image *image ); +extern int image_autoload ( struct image *image ); +extern int image_exec ( struct image *image ); +extern int register_and_autoload_image ( struct image *image ); +extern int register_and_autoexec_image ( struct image *image ); + +/** + * Increment reference count on an image + * + * @v image Image + * @ret image Image + */ +static inline struct image * image_get ( struct image *image ) { + ref_get ( &image->refcnt ); + return image; +} + +/** + * Decrement reference count on an image + * + * @v image Image + */ +static inline void image_put ( struct image *image ) { + ref_put ( &image->refcnt ); +} + +/** + * Set image name + * + * @v image Image + * @v name New image name + * @ret rc Return status code + */ +static inline int image_set_name ( struct image *image, const char *name ) { + strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) ); + return 0; +} + +#endif /* _GPXE_IMAGE_H */ diff --git a/gpxe/src/include/gpxe/in.h b/gpxe/src/include/gpxe/in.h new file mode 100644 index 00000000..89530a55 --- /dev/null +++ b/gpxe/src/include/gpxe/in.h @@ -0,0 +1,94 @@ +#ifndef _GPXE_IN_H +#define _GPXE_IN_H + +#include <stdint.h> +#include <gpxe/socket.h> + +/* Protocol numbers */ + +#define IP_ICMP 1 +#define IP_IGMP 2 +#define IP_TCP 6 +#define IP_UDP 17 +#define IP_ICMP6 58 + +/* IP address constants */ + +#define INADDR_NONE 0xffffffff + +#define INADDR_BROADCAST 0xffffffff + +#define IN_CLASSA(addr) ( ( (addr) & 0x80000000 ) == 0x00000000 ) +#define IN_CLASSA_NET 0xff000000 +#define IN_CLASSB(addr) ( ( (addr) & 0xc0000000 ) == 0x80000000 ) +#define IN_CLASSB_NET 0xffff0000 +#define IN_CLASSC(addr) ( ( (addr) & 0xe0000000 ) == 0xc0000000 ) +#define IN_CLASSC_NET 0xffffff00 +#define IN_MULTICAST(addr) ( ( (addr) & 0xf0000000 ) == 0xe0000000 ) + +/** + * IP address structure + */ +struct in_addr { + uint32_t s_addr; +}; + +typedef struct in_addr in_addr; + +/** + * IP6 address structure + */ +struct in6_addr { + union { + uint8_t u6_addr8[16]; + uint16_t u6_addr16[8]; + uint32_t u6_addr32[4]; + } in6_u; +#define s6_addr in6_u.u6_addr8 +#define s6_addr16 in6_u.u6_addr16 +#define s6_addr32 in6_u.u6_addr32 +}; + +/** + * IPv4 socket address + */ +struct sockaddr_in { + /** Socket address family (part of struct @c sockaddr) + * + * Always set to @c AF_INET for IPv4 addresses + */ + sa_family_t sin_family; + /** TCP/IP port (part of struct @c sockaddr_tcpip) */ + uint16_t sin_port; + /** IPv4 address */ + struct in_addr sin_addr; +}; + +/** + * IPv6 socket address + */ +struct sockaddr_in6 { + /** Socket address family (part of struct @c sockaddr) + * + * Always set to @c AF_INET6 for IPv6 addresses + */ + sa_family_t sin_family; + /** TCP/IP port (part of struct @c sockaddr_tcpip) */ + uint16_t sin_port; + uint32_t sin6_flowinfo; /* Flow number */ + struct in6_addr sin6_addr; /* 128-bit destination address */ + uint32_t sin6_scope_id; /* Scope ID */ +}; + +extern int inet_aton ( const char *cp, struct in_addr *inp ); +extern char * inet_ntoa ( struct in_addr in ); + +/* Adding the following for IP6 support + * + +extern int inet6_aton ( const char *cp, struct in6_addr *inp ); +extern char * inet6_ntoa ( struct in_addr in ); + + */ + +#endif /* _GPXE_IN_H */ diff --git a/gpxe/src/include/gpxe/infiniband.h b/gpxe/src/include/gpxe/infiniband.h new file mode 100644 index 00000000..354dc579 --- /dev/null +++ b/gpxe/src/include/gpxe/infiniband.h @@ -0,0 +1,751 @@ +#ifndef _GPXE_INFINIBAND_H +#define _GPXE_INFINIBAND_H + +/** @file + * + * Infiniband protocol + * + */ + +#include <stdint.h> +#include <gpxe/device.h> + +/** Subnet administrator QPN */ +#define IB_SA_QPN 1 + +/** Broadcast QPN */ +#define IB_BROADCAST_QPN 0xffffffUL + +/** Subnet administrator queue key */ +#define IB_GLOBAL_QKEY 0x80010000UL + +/** An Infiniband Global Identifier */ +struct ib_gid { + union { + uint8_t bytes[16]; + uint16_t words[8]; + uint32_t dwords[4]; + } u; +}; + +/** An Infiniband Global Route Header */ +struct ib_global_route_header { + /** IP version, traffic class, and flow label + * + * 4 bits : Version of the GRH + * 8 bits : Traffic class + * 20 bits : Flow label + */ + uint32_t ipver_tclass_flowlabel; + /** Payload length */ + uint16_t paylen; + /** Next header */ + uint8_t nxthdr; + /** Hop limit */ + uint8_t hoplmt; + /** Source GID */ + struct ib_gid sgid; + /** Destiniation GID */ + struct ib_gid dgid; +} __attribute__ (( packed )); + +struct ib_device; +struct ib_queue_pair; +struct ib_completion_queue; + +/** An Infiniband Work Queue */ +struct ib_work_queue { + /** Containing queue pair */ + struct ib_queue_pair *qp; + /** "Is a send queue" flag */ + int is_send; + /** Associated completion queue */ + struct ib_completion_queue *cq; + /** List of work queues on this completion queue */ + struct list_head list; + /** Number of work queue entries */ + unsigned int num_wqes; + /** Next work queue entry index + * + * This is the index of the next entry to be filled (i.e. the + * first empty entry). This value is not bounded by num_wqes; + * users must logical-AND with (num_wqes-1) to generate an + * array index. + */ + unsigned long next_idx; + /** I/O buffers assigned to work queue */ + struct io_buffer **iobufs; + /** Driver private data */ + void *drv_priv; +}; + +/** An Infiniband Queue Pair */ +struct ib_queue_pair { + /** Queue Pair Number */ + unsigned long qpn; + /** Queue key */ + unsigned long qkey; + /** Send queue */ + struct ib_work_queue send; + /** Receive queue */ + struct ib_work_queue recv; + /** Driver private data */ + void *drv_priv; + /** Queue owner private data */ + void *owner_priv; +}; + +/** An Infiniband Completion Queue */ +struct ib_completion_queue { + /** Completion queue number */ + unsigned long cqn; + /** Number of completion queue entries */ + unsigned int num_cqes; + /** Next completion queue entry index + * + * This is the index of the next entry to be filled (i.e. the + * first empty entry). This value is not bounded by num_wqes; + * users must logical-AND with (num_wqes-1) to generate an + * array index. + */ + unsigned long next_idx; + /** List of work queues completing to this queue */ + struct list_head work_queues; + /** Driver private data */ + void *drv_priv; +}; + +/** An Infiniband completion */ +struct ib_completion { + /** Syndrome + * + * If non-zero, then the completion is in error. + */ + unsigned int syndrome; + /** Length */ + size_t len; +}; + +/** An Infiniband completion handler + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v completion Completion + * @v iobuf I/O buffer + */ +typedef void ( * ib_completer_t ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp, + struct ib_completion *completion, + struct io_buffer *iobuf ); + +/** An Infiniband Address Vector */ +struct ib_address_vector { + /** Destination Queue Pair */ + unsigned int dest_qp; + /** Queue key */ + unsigned long qkey; + /** Destination Local ID */ + unsigned int dlid; + /** Rate */ + unsigned int rate; + /** Service level */ + unsigned int sl; + /** GID is present */ + unsigned int gid_present; + /** GID */ + struct ib_gid gid; +}; + +struct ib_mad_hdr; + +/** + * Infiniband device operations + * + * These represent a subset of the Infiniband Verbs. + */ +struct ib_device_operations { + /** Create completion queue + * + * @v ibdev Infiniband device + * @v cq Completion queue + * @ret rc Return status code + */ + int ( * create_cq ) ( struct ib_device *ibdev, + struct ib_completion_queue *cq ); + /** Destroy completion queue + * + * @v ibdev Infiniband device + * @v cq Completion queue + */ + void ( * destroy_cq ) ( struct ib_device *ibdev, + struct ib_completion_queue *cq ); + /** Create queue pair + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @ret rc Return status code + */ + int ( * create_qp ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp ); + /** Destroy queue pair + * + * @v ibdev Infiniband device + * @v qp Queue pair + */ + void ( * destroy_qp ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp ); + /** Post send work queue entry + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v av Address vector + * @v iobuf I/O buffer + * @ret rc Return status code + * + * If this method returns success, the I/O buffer remains + * owned by the queue pair. If this method returns failure, + * the I/O buffer is immediately released; the failure is + * interpreted as "failure to enqueue buffer". + */ + int ( * post_send ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp, + struct ib_address_vector *av, + struct io_buffer *iobuf ); + /** Post receive work queue entry + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v iobuf I/O buffer + * @ret rc Return status code + * + * If this method returns success, the I/O buffer remains + * owned by the queue pair. If this method returns failure, + * the I/O buffer is immediately released; the failure is + * interpreted as "failure to enqueue buffer". + */ + int ( * post_recv ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp, + struct io_buffer *iobuf ); + /** Poll completion queue + * + * @v ibdev Infiniband device + * @v cq Completion queue + * @v complete_send Send completion handler + * @v complete_recv Receive completion handler + * + * The completion handler takes ownership of the I/O buffer. + */ + void ( * poll_cq ) ( struct ib_device *ibdev, + struct ib_completion_queue *cq, + ib_completer_t complete_send, + ib_completer_t complete_recv ); + /** + * Open port + * + * @v ibdev Infiniband device + * @ret rc Return status code + */ + int ( * open ) ( struct ib_device *ibdev ); + /** + * Close port + * + * @v ibdev Infiniband device + */ + void ( * close ) ( struct ib_device *ibdev ); + /** Attach to multicast group + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v gid Multicast GID + * @ret rc Return status code + */ + int ( * mcast_attach ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp, + struct ib_gid *gid ); + /** Detach from multicast group + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v gid Multicast GID + */ + void ( * mcast_detach ) ( struct ib_device *ibdev, + struct ib_queue_pair *qp, + struct ib_gid *gid ); + /** + * Issue management datagram + * + * @v ibdev Infiniband device + * @v mad Management datagram + * @v len Length of management datagram + * @ret rc Return status code + */ + int ( * mad ) ( struct ib_device *ibdev, struct ib_mad_hdr *mad, + size_t len ); +}; + +/** An Infiniband device */ +struct ib_device { + /** Underlying device */ + struct device *dev; + /** Infiniband operations */ + struct ib_device_operations *op; + /** Port number */ + unsigned int port; + /** Port GID */ + struct ib_gid port_gid; + /** Subnet manager LID */ + unsigned long sm_lid; + /** Partition key */ + unsigned int pkey; + /** Driver private data */ + void *drv_priv; + /** Owner private data */ + void *owner_priv; +}; + +extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev, + unsigned int num_cqes ); +extern void ib_destroy_cq ( struct ib_device *ibdev, + struct ib_completion_queue *cq ); +extern struct ib_queue_pair * +ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes, + struct ib_completion_queue *send_cq, unsigned int num_recv_wqes, + struct ib_completion_queue *recv_cq, unsigned long qkey ); +extern void ib_destroy_qp ( struct ib_device *ibdev, + struct ib_queue_pair *qp ); +extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq, + unsigned long qpn, int is_send ); +extern struct ib_device * alloc_ibdev ( size_t priv_size ); +extern int register_ibdev ( struct ib_device *ibdev ); +extern void unregister_ibdev ( struct ib_device *ibdev ); +extern void free_ibdev ( struct ib_device *ibdev ); + +/** + * Post send work queue entry + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v av Address vector + * @v iobuf I/O buffer + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) int +ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp, + struct ib_address_vector *av, struct io_buffer *iobuf ) { + return ibdev->op->post_send ( ibdev, qp, av, iobuf ); +} + +/** + * Post receive work queue entry + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v iobuf I/O buffer + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) int +ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp, + struct io_buffer *iobuf ) { + return ibdev->op->post_recv ( ibdev, qp, iobuf ); +} + +/** + * Poll completion queue + * + * @v ibdev Infiniband device + * @v cq Completion queue + * @v complete_send Send completion handler + * @v complete_recv Receive completion handler + */ +static inline __attribute__ (( always_inline )) void +ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq, + ib_completer_t complete_send, ib_completer_t complete_recv ) { + ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv ); +} + +/** + * Open port + * + * @v ibdev Infiniband device + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) int +ib_open ( struct ib_device *ibdev ) { + return ibdev->op->open ( ibdev ); +} + +/** + * Close port + * + * @v ibdev Infiniband device + */ +static inline __attribute__ (( always_inline )) void +ib_close ( struct ib_device *ibdev ) { + ibdev->op->close ( ibdev ); +} + +/** + * Attach to multicast group + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v gid Multicast GID + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) int +ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp, + struct ib_gid *gid ) { + return ibdev->op->mcast_attach ( ibdev, qp, gid ); +} + +/** + * Detach from multicast group + * + * @v ibdev Infiniband device + * @v qp Queue pair + * @v gid Multicast GID + */ +static inline __attribute__ (( always_inline )) void +ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp, + struct ib_gid *gid ) { + ibdev->op->mcast_detach ( ibdev, qp, gid ); +} + +/** + * Issue management datagram + * + * @v ibdev Infiniband device + * @v mad Management datagram + * @v len Length of management datagram + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) int +ib_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad, size_t len ) { + return ibdev->op->mad ( ibdev, mad, len ); +} + +/** + * Set Infiniband work queue driver-private data + * + * @v wq Work queue + * @v priv Private data + */ +static inline __attribute__ (( always_inline )) void +ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) { + wq->drv_priv = priv; +} + +/** + * Get Infiniband work queue driver-private data + * + * @v wq Work queue + * @ret priv Private data + */ +static inline __attribute__ (( always_inline )) void * +ib_wq_get_drvdata ( struct ib_work_queue *wq ) { + return wq->drv_priv; +} + +/** + * Set Infiniband queue pair driver-private data + * + * @v qp Queue pair + * @v priv Private data + */ +static inline __attribute__ (( always_inline )) void +ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) { + qp->drv_priv = priv; +} + +/** + * Get Infiniband queue pair driver-private data + * + * @v qp Queue pair + * @ret priv Private data + */ +static inline __attribute__ (( always_inline )) void * +ib_qp_get_drvdata ( struct ib_queue_pair *qp ) { + return qp->drv_priv; +} + +/** + * Set Infiniband queue pair owner-private data + * + * @v qp Queue pair + * @v priv Private data + */ +static inline __attribute__ (( always_inline )) void +ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) { + qp->owner_priv = priv; +} + +/** + * Get Infiniband queue pair owner-private data + * + * @v qp Queue pair + * @ret priv Private data + */ +static inline __attribute__ (( always_inline )) void * +ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) { + return qp->owner_priv; +} + +/** + * Set Infiniband completion queue driver-private data + * + * @v cq Completion queue + * @v priv Private data + */ +static inline __attribute__ (( always_inline )) void +ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) { + cq->drv_priv = priv; +} + +/** + * Get Infiniband completion queue driver-private data + * + * @v cq Completion queue + * @ret priv Private data + */ +static inline __attribute__ (( always_inline )) void * +ib_cq_get_drvdata ( struct ib_completion_queue *cq ) { + return cq->drv_priv; +} + +/** + * Set Infiniband device driver-private data + * + * @v ibdev Infiniband device + * @v priv Private data + */ +static inline __attribute__ (( always_inline )) void +ib_set_drvdata ( struct ib_device *ibdev, void *priv ) { + ibdev->drv_priv = priv; +} + +/** + * Get Infiniband device driver-private data + * + * @v ibdev Infiniband device + * @ret priv Private data + */ +static inline __attribute__ (( always_inline )) void * +ib_get_drvdata ( struct ib_device *ibdev ) { + return ibdev->drv_priv; +} + +/** + * Set Infiniband device owner-private data + * + * @v ibdev Infiniband device + * @v priv Private data + */ +static inline __attribute__ (( always_inline )) void +ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) { + ibdev->owner_priv = priv; +} + +/** + * Get Infiniband device owner-private data + * + * @v ibdev Infiniband device + * @ret priv Private data + */ +static inline __attribute__ (( always_inline )) void * +ib_get_ownerdata ( struct ib_device *ibdev ) { + return ibdev->owner_priv; +} + +/***************************************************************************** + * + * Management datagrams + * + * Portions Copyright (c) 2004 Mellanox Technologies Ltd. All rights + * reserved. + * + */ + +/* Management base version */ +#define IB_MGMT_BASE_VERSION 1 + +/* Management classes */ +#define IB_MGMT_CLASS_SUBN_LID_ROUTED 0x01 +#define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE 0x81 +#define IB_MGMT_CLASS_SUBN_ADM 0x03 +#define IB_MGMT_CLASS_PERF_MGMT 0x04 +#define IB_MGMT_CLASS_BM 0x05 +#define IB_MGMT_CLASS_DEVICE_MGMT 0x06 +#define IB_MGMT_CLASS_CM 0x07 +#define IB_MGMT_CLASS_SNMP 0x08 +#define IB_MGMT_CLASS_VENDOR_RANGE2_START 0x30 +#define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4F + +/* Management methods */ +#define IB_MGMT_METHOD_GET 0x01 +#define IB_MGMT_METHOD_SET 0x02 +#define IB_MGMT_METHOD_GET_RESP 0x81 +#define IB_MGMT_METHOD_SEND 0x03 +#define IB_MGMT_METHOD_TRAP 0x05 +#define IB_MGMT_METHOD_REPORT 0x06 +#define IB_MGMT_METHOD_REPORT_RESP 0x86 +#define IB_MGMT_METHOD_TRAP_REPRESS 0x07 +#define IB_MGMT_METHOD_DELETE 0x15 +#define IB_MGMT_METHOD_RESP 0x80 + +/* Subnet management attributes */ +#define IB_SMP_ATTR_NOTICE 0x0002 +#define IB_SMP_ATTR_NODE_DESC 0x0010 +#define IB_SMP_ATTR_NODE_INFO 0x0011 +#define IB_SMP_ATTR_SWITCH_INFO 0x0012 +#define IB_SMP_ATTR_GUID_INFO 0x0014 +#define IB_SMP_ATTR_PORT_INFO 0x0015 +#define IB_SMP_ATTR_PKEY_TABLE 0x0016 +#define IB_SMP_ATTR_SL_TO_VL_TABLE 0x0017 +#define IB_SMP_ATTR_VL_ARB_TABLE 0x0018 +#define IB_SMP_ATTR_LINEAR_FORWARD_TABLE 0x0019 +#define IB_SMP_ATTR_RANDOM_FORWARD_TABLE 0x001A +#define IB_SMP_ATTR_MCAST_FORWARD_TABLE 0x001B +#define IB_SMP_ATTR_SM_INFO 0x0020 +#define IB_SMP_ATTR_VENDOR_DIAG 0x0030 +#define IB_SMP_ATTR_LED_INFO 0x0031 +#define IB_SMP_ATTR_VENDOR_MASK 0xFF00 + +#define IB_SA_ATTR_MC_MEMBER_REC 0x38 +#define IB_SA_ATTR_PATH_REC 0x35 + +#define IB_SA_MCMEMBER_REC_MGID (1<<0) +#define IB_SA_MCMEMBER_REC_PORT_GID (1<<1) +#define IB_SA_MCMEMBER_REC_QKEY (1<<2) +#define IB_SA_MCMEMBER_REC_MLID (1<<3) +#define IB_SA_MCMEMBER_REC_MTU_SELECTOR (1<<4) +#define IB_SA_MCMEMBER_REC_MTU (1<<5) +#define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS (1<<6) +#define IB_SA_MCMEMBER_REC_PKEY (1<<7) +#define IB_SA_MCMEMBER_REC_RATE_SELECTOR (1<<8) +#define IB_SA_MCMEMBER_REC_RATE (1<<9) +#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR (1<<10) +#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME (1<<11) +#define IB_SA_MCMEMBER_REC_SL (1<<12) +#define IB_SA_MCMEMBER_REC_FLOW_LABEL (1<<13) +#define IB_SA_MCMEMBER_REC_HOP_LIMIT (1<<14) +#define IB_SA_MCMEMBER_REC_SCOPE (1<<15) +#define IB_SA_MCMEMBER_REC_JOIN_STATE (1<<16) +#define IB_SA_MCMEMBER_REC_PROXY_JOIN (1<<17) + +#define IB_SA_PATH_REC_DGID (1<<2) +#define IB_SA_PATH_REC_SGID (1<<3) + +struct ib_mad_hdr { + uint8_t base_version; + uint8_t mgmt_class; + uint8_t class_version; + uint8_t method; + uint16_t status; + uint16_t class_specific; + uint32_t tid[2]; + uint16_t attr_id; + uint16_t resv; + uint32_t attr_mod; +} __attribute__ (( packed )); + +struct ib_sa_hdr { + uint32_t sm_key[2]; + uint16_t reserved; + uint16_t attrib_offset; + uint32_t comp_mask[2]; +} __attribute__ (( packed )); + +struct ib_rmpp_hdr { + uint32_t raw[3]; +} __attribute__ (( packed )); + +struct ib_mad_data { + struct ib_mad_hdr mad_hdr; + uint8_t data[232]; +} __attribute__ (( packed )); + +struct ib_mad_guid_info { + struct ib_mad_hdr mad_hdr; + uint32_t mkey[2]; + uint32_t reserved[8]; + uint8_t gid_local[8]; +} __attribute__ (( packed )); + +struct ib_mad_port_info { + struct ib_mad_hdr mad_hdr; + uint32_t mkey[2]; + uint32_t reserved[8]; + uint32_t mkey2[2]; + uint8_t gid_prefix[8]; + uint16_t lid; + uint16_t mastersm_lid; + uint32_t cap_mask; + uint16_t diag_code; + uint16_t mkey_lease_period; + uint8_t local_port_num; + uint8_t link_width_enabled; + uint8_t link_width_supported; + uint8_t link_width_active; + uint8_t port_state__link_speed_supported; + uint8_t link_down_def_state__port_phys_state; + uint8_t lmc__r1__mkey_prot_bits; + uint8_t link_speed_enabled__link_speed_active; +} __attribute__ (( packed )); + +struct ib_mad_pkey_table { + struct ib_mad_hdr mad_hdr; + uint32_t mkey[2]; + uint32_t reserved[8]; + uint16_t pkey[16][2]; +} __attribute__ (( packed )); + +struct ib_mad_path_record { + struct ib_mad_hdr mad_hdr; + struct ib_rmpp_hdr rmpp_hdr; + struct ib_sa_hdr sa_hdr; + uint32_t reserved0[2]; + struct ib_gid dgid; + struct ib_gid sgid; + uint16_t dlid; + uint16_t slid; + uint32_t hop_limit__flow_label__raw_traffic; + uint32_t pkey__numb_path__reversible__tclass; + uint8_t reserved1; + uint8_t reserved__sl; + uint8_t mtu_selector__mtu; + uint8_t rate_selector__rate; + uint32_t preference__packet_lifetime__packet_lifetime_selector; + uint32_t reserved2[35]; +} __attribute__ (( packed )); + +struct ib_mad_mc_member_record { + struct ib_mad_hdr mad_hdr; + struct ib_rmpp_hdr rmpp_hdr; + struct ib_sa_hdr sa_hdr; + struct ib_gid mgid; + struct ib_gid port_gid; + uint32_t qkey; + uint16_t mlid; + uint8_t mtu_selector__mtu; + uint8_t tclass; + uint16_t pkey; + uint8_t rate_selector__rate; + uint8_t packet_lifetime_selector__packet_lifetime; + uint32_t sl__flow_label__hop_limit; + uint8_t scope__join_state; + uint8_t proxy_join__reserved; + uint16_t reserved0; + uint32_t reserved1[37]; +} __attribute__ (( packed )); + +union ib_mad { + struct ib_mad_hdr mad_hdr; + struct ib_mad_data data; + struct ib_mad_guid_info guid_info; + struct ib_mad_port_info port_info; + struct ib_mad_pkey_table pkey_table; + struct ib_mad_path_record path_record; + struct ib_mad_mc_member_record mc_member_record; +} __attribute__ (( packed )); + +#endif /* _GPXE_INFINIBAND_H */ diff --git a/gpxe/src/include/gpxe/init.h b/gpxe/src/include/gpxe/init.h new file mode 100644 index 00000000..d83aa5e5 --- /dev/null +++ b/gpxe/src/include/gpxe/init.h @@ -0,0 +1,62 @@ +#ifndef _GPXE_INIT_H +#define _GPXE_INIT_H + +#include <gpxe/tables.h> + +/** + * An initialisation function + * + * Initialisation functions are called exactly once, as part of the + * call to initialise(). + */ +struct init_fn { + void ( * initialise ) ( void ); +}; + +/** Declare an initialisation functon */ +#define __init_fn( init_order ) \ + __table ( struct init_fn, init_fns, init_order ) + +/** @defgroup initfn_order Initialisation function ordering + * @{ + */ + +#define INIT_EARLY 01 /**< Early initialisation */ +#define INIT_CONSOLE 02 /**< Console initialisation */ +#define INIT_NORMAL 03 /**< Normal initialisation */ + +/** @} */ + +/** + * A startup/shutdown function + * + * Startup and shutdown functions may be called multiple times, as + * part of the calls to startup() and shutdown(). + */ +struct startup_fn { + void ( * startup ) ( void ); + void ( * shutdown ) ( void ); +}; + +/** Declare a startup/shutdown function */ +#define __startup_fn( startup_order ) \ + __table ( struct startup_fn, startup_fns, startup_order ) + +/** @defgroup startfn_order Startup/shutdown function ordering + * + * Shutdown functions are called in the reverse order to startup + * functions. + * + * @{ + */ + +#define STARTUP_EARLY 01 /**< Early startup */ +#define STARTUP_NORMAL 02 /**< Normal startup */ + +/** @} */ + +extern void initialise ( void ); +extern void startup ( void ); +extern void shutdown ( void ); + +#endif /* _GPXE_INIT_H */ diff --git a/gpxe/src/include/gpxe/initrd.h b/gpxe/src/include/gpxe/initrd.h new file mode 100644 index 00000000..1871bf78 --- /dev/null +++ b/gpxe/src/include/gpxe/initrd.h @@ -0,0 +1,14 @@ +#ifndef _GPXE_INITRD_H +#define _GPXE_INITRD_H + +/** + * @file + * + * Linux initrd image format + * + */ + +#include <gpxe/image.h> +extern struct image_type initrd_image_type __image_type ( PROBE_NORMAL ); + +#endif /* _GPXE_INITRD_H */ diff --git a/gpxe/src/include/gpxe/interface.h b/gpxe/src/include/gpxe/interface.h new file mode 100644 index 00000000..94c711a9 --- /dev/null +++ b/gpxe/src/include/gpxe/interface.h @@ -0,0 +1,56 @@ +#ifndef _GPXE_INTERFACE_H +#define _GPXE_INTERFACE_H + +/** @file + * + * Object communication interfaces + * + */ + +#include <gpxe/refcnt.h> + +/** An object communication interface */ +struct interface { + /** Destination interface + * + * When messages are sent via this interface, they will be + * delivered to the destination interface. + * + * This pointer may never be NULL. When the interface is + * unplugged, it should point to a null interface. + */ + struct interface *dest; + /** Reference counter + * + * If this interface is not part of a reference-counted + * object, this field may be NULL. + */ + struct refcnt *refcnt; +}; + +/** + * Increment reference count on an interface + * + * @v intf Interface + * @ret intf Interface + */ +static inline __attribute__ (( always_inline )) struct interface * +intf_get ( struct interface *intf ) { + ref_get ( intf->refcnt ); + return intf; +} + +/** + * Decrement reference count on an interface + * + * @v intf Interface + */ +static inline __attribute__ (( always_inline )) void +intf_put ( struct interface *intf ) { + ref_put ( intf->refcnt ); +} + +extern void plug ( struct interface *intf, struct interface *dest ); +extern void plug_plug ( struct interface *a, struct interface *b ); + +#endif /* _GPXE_INTERFACE_H */ diff --git a/gpxe/src/include/gpxe/iobuf.h b/gpxe/src/include/gpxe/iobuf.h new file mode 100644 index 00000000..ff787754 --- /dev/null +++ b/gpxe/src/include/gpxe/iobuf.h @@ -0,0 +1,189 @@ +#ifndef _GPXE_IOBUF_H +#define _GPXE_IOBUF_H + +/** @file + * + * I/O buffers + * + */ + +#include <stdint.h> +#include <assert.h> +#include <gpxe/list.h> + +/** + * I/O buffer alignment + * + * I/O buffers allocated via alloc_iob() are guaranteed to be + * physically aligned to this boundary. Some cards cannot DMA across + * a 4kB boundary. With a standard Ethernet MTU, aligning to a 2kB + * boundary is sufficient to guarantee no 4kB boundary crossings. For + * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway. + */ +#define IOB_ALIGN 2048 + +/** + * Minimum I/O buffer length + * + * alloc_iob() will round up the allocated length to this size if + * necessary. This is used on behalf of hardware that is not capable + * of auto-padding. + */ +#define IOB_ZLEN 64 + +/** + * A persistent I/O buffer + * + * This data structure encapsulates a long-lived I/O buffer. The + * buffer may be passed between multiple owners, queued for possible + * retransmission, etc. + */ +struct io_buffer { + /** List of which this buffer is a member + * + * The list must belong to the current owner of the buffer. + * Different owners may maintain different lists (e.g. a + * retransmission list for TCP). + */ + struct list_head list; + + /** Start of the buffer */ + void *head; + /** Start of data */ + void *data; + /** End of data */ + void *tail; + /** End of the buffer */ + void *end; +}; + +/** + * Reserve space at start of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to reserve + * @ret data Pointer to new start of buffer + */ +static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) { + iobuf->data += len; + iobuf->tail += len; + return iobuf->data; +} +#define iob_reserve( iobuf, len ) ( { \ + void *__result; \ + __result = iob_reserve ( (iobuf), (len) ); \ + assert ( (iobuf)->tail <= (iobuf)->end ); \ + __result; } ) + +/** + * Add data to start of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to add + * @ret data Pointer to new start of buffer + */ +static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) { + iobuf->data -= len; + return iobuf->data; +} +#define iob_push( iobuf, len ) ( { \ + void *__result; \ + __result = iob_push ( (iobuf), (len) ); \ + assert ( (iobuf)->data >= (iobuf)->head ); \ + __result; } ) + +/** + * Remove data from start of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to remove + * @ret data Pointer to new start of buffer + */ +static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) { + iobuf->data += len; + assert ( iobuf->data <= iobuf->tail ); + return iobuf->data; +} +#define iob_pull( iobuf, len ) ( { \ + void *__result; \ + __result = iob_pull ( (iobuf), (len) ); \ + assert ( (iobuf)->data <= (iobuf)->tail ); \ + __result; } ) + +/** + * Add data to end of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to add + * @ret data Pointer to newly added space + */ +static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) { + void *old_tail = iobuf->tail; + iobuf->tail += len; + return old_tail; +} +#define iob_put( iobuf, len ) ( { \ + void *__result; \ + __result = iob_put ( (iobuf), (len) ); \ + assert ( (iobuf)->tail <= (iobuf)->end ); \ + __result; } ) + +/** + * Remove data from end of I/O buffer + * + * @v iobuf I/O buffer + * @v len Length to remove + */ +static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) { + iobuf->tail -= len; +} +#define iob_unput( iobuf, len ) do { \ + iob_unput ( (iobuf), (len) ); \ + assert ( (iobuf)->tail >= (iobuf)->data ); \ + } while ( 0 ) + +/** + * Empty an I/O buffer + * + * @v iobuf I/O buffer + */ +static inline void iob_empty ( struct io_buffer *iobuf ) { + iobuf->tail = iobuf->data; +} + +/** + * Calculate length of data in an I/O buffer + * + * @v iobuf I/O buffer + * @ret len Length of data in buffer + */ +static inline size_t iob_len ( struct io_buffer *iobuf ) { + return ( iobuf->tail - iobuf->data ); +} + +/** + * Calculate available space at start of an I/O buffer + * + * @v iobuf I/O buffer + * @ret len Length of data available at start of buffer + */ +static inline size_t iob_headroom ( struct io_buffer *iobuf ) { + return ( iobuf->data - iobuf->head ); +} + +/** + * Calculate available space at end of an I/O buffer + * + * @v iobuf I/O buffer + * @ret len Length of data available at end of buffer + */ +static inline size_t iob_tailroom ( struct io_buffer *iobuf ) { + return ( iobuf->end - iobuf->tail ); +} + +extern struct io_buffer * __malloc alloc_iob ( size_t len ); +extern void free_iob ( struct io_buffer *iobuf ); +extern void iob_pad ( struct io_buffer *iobuf, size_t min_len ); +extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len ); + +#endif /* _GPXE_IOBUF_H */ diff --git a/gpxe/src/include/gpxe/ip.h b/gpxe/src/include/gpxe/ip.h new file mode 100644 index 00000000..b1b0c48c --- /dev/null +++ b/gpxe/src/include/gpxe/ip.h @@ -0,0 +1,95 @@ +#ifndef _GPXE_IP_H +#define _GPXE_IP_H + +/** @file + * + * IP protocol + * + */ + +#include <stdint.h> +#include <gpxe/in.h> +#include <gpxe/list.h> +#include <gpxe/retry.h> + +struct io_buffer; +struct net_device; +struct net_protocol; + +/* IP constants */ + +#define IP_VER 0x40U +#define IP_MASK_VER 0xf0U +#define IP_MASK_HLEN 0x0fU +#define IP_MASK_OFFSET 0x1fffU +#define IP_MASK_DONOTFRAG 0x4000U +#define IP_MASK_MOREFRAGS 0x2000U +#define IP_PSHLEN 12 + +/* IP header defaults */ +#define IP_TOS 0 +#define IP_TTL 64 + +#define IP_FRAG_IOB_SIZE 1500 +#define IP_FRAG_TIMEOUT 50 + +/** An IPv4 packet header */ +struct iphdr { + uint8_t verhdrlen; + uint8_t service; + uint16_t len; + uint16_t ident; + uint16_t frags; + uint8_t ttl; + uint8_t protocol; + uint16_t chksum; + struct in_addr src; + struct in_addr dest; +} __attribute__ (( packed )); + +/** An IPv4 pseudo header */ +struct ipv4_pseudo_header { + struct in_addr src; + struct in_addr dest; + uint8_t zero_padding; + uint8_t protocol; + uint16_t len; +}; + +/** An IPv4 address/routing table entry */ +struct ipv4_miniroute { + /** List of miniroutes */ + struct list_head list; + + /** Network device */ + struct net_device *netdev; + + /** IPv4 address */ + struct in_addr address; + /** Subnet mask */ + struct in_addr netmask; + /** Gateway address */ + struct in_addr gateway; +}; + +/* Fragment reassembly buffer */ +struct frag_buffer { + /* Identification number */ + uint16_t ident; + /* Source network address */ + struct in_addr src; + /* Destination network address */ + struct in_addr dest; + /* Reassembled I/O buffer */ + struct io_buffer *frag_iob; + /* Reassembly timer */ + struct retry_timer frag_timer; + /* List of fragment reassembly buffers */ + struct list_head list; +}; + +extern struct list_head ipv4_miniroutes; + +extern struct net_protocol ipv4_protocol; + +#endif /* _GPXE_IP_H */ diff --git a/gpxe/src/include/gpxe/ip6.h b/gpxe/src/include/gpxe/ip6.h new file mode 100644 index 00000000..dc0ae31f --- /dev/null +++ b/gpxe/src/include/gpxe/ip6.h @@ -0,0 +1,78 @@ +#ifndef _GPXE_IP6_H +#define _GPXE_IP6_H + +/** @file + * + * IP6 protocol + * + */ + +#include <stdint.h> +#include <gpxe/in.h> + +/* IP6 constants */ + +#define IP6_VERSION 0x6 +#define IP6_HOP_LIMIT 255 + +/** + * I/O buffer contents + * This is duplicated in tcp.h and here. Ideally it should go into iobuf.h + */ +#define MAX_HDR_LEN 100 +#define MAX_IOB_LEN 1500 +#define MIN_IOB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */ + +#define IP6_EQUAL( in6_addr1, in6_addr2 ) \ + ( memcmp ( ( char* ) &( in6_addr1 ), ( char* ) &( in6_addr2 ),\ + sizeof ( struct in6_addr ) ) == 0 ) + +#define IS_UNSPECIFIED( addr ) \ + ( ( (addr).in6_u.u6_addr32[0] == 0x00000000 ) && \ + ( (addr).in6_u.u6_addr32[1] == 0x00000000 ) && \ + ( (addr).in6_u.u6_addr32[2] == 0x00000000 ) && \ + ( (addr).in6_u.u6_addr32[3] == 0x00000000 ) ) +/* IP6 header */ +struct ip6_header { + uint32_t ver_traffic_class_flow_label; + uint16_t payload_len; + uint8_t nxt_hdr; + uint8_t hop_limit; + struct in6_addr src; + struct in6_addr dest; +}; + +/* IP6 pseudo header */ +struct ipv6_pseudo_header { + struct in6_addr src; + struct in6_addr dest; + uint8_t zero_padding; + uint8_t nxt_hdr; + uint16_t len; +}; + +/* Next header numbers */ +#define IP6_HOPBYHOP 0x00 +#define IP6_ROUTING 0x43 +#define IP6_FRAGMENT 0x44 +#define IP6_AUTHENTICATION 0x51 +#define IP6_DEST_OPTS 0x60 +#define IP6_ESP 0x50 +#define IP6_ICMP6 0x58 +#define IP6_NO_HEADER 0x59 + +struct io_buffer; +struct net_device; +struct net_protocol; + +extern struct net_protocol ipv6_protocol; +extern struct tcpip_net_protocol ipv6_tcpip_protocol; +extern char * inet6_ntoa ( struct in6_addr in6 ); + +extern int add_ipv6_address ( struct net_device *netdev, + struct in6_addr prefix, int prefix_len, + struct in6_addr address, + struct in6_addr gateway ); +extern void del_ipv6_address ( struct net_device *netdev ); + +#endif /* _GPXE_IP6_H */ diff --git a/gpxe/src/include/gpxe/ipoib.h b/gpxe/src/include/gpxe/ipoib.h new file mode 100644 index 00000000..0551687d --- /dev/null +++ b/gpxe/src/include/gpxe/ipoib.h @@ -0,0 +1,78 @@ +#ifndef _GPXE_IPOIB_H +#define _GPXE_IPOIB_H + +/** @file + * + * IP over Infiniband + */ + +#include <gpxe/infiniband.h> + +/** IPoIB MAC address length */ +#define IPOIB_ALEN 20 + +/** An IPoIB MAC address */ +struct ipoib_mac { + /** Queue pair number + * + * MSB must be zero; QPNs are only 24-bit. + */ + uint32_t qpn; + /** Port GID */ + struct ib_gid gid; +} __attribute__ (( packed )); + +/** IPoIB link-layer header length */ +#define IPOIB_HLEN 24 + +/** + * IPoIB link-layer header pseudo portion + * + * This part doesn't actually exist on the wire, but it provides a + * convenient way to fit into the typical network device model. + */ +struct ipoib_pseudo_hdr { + /** Peer address */ + struct ipoib_mac peer; +} __attribute__ (( packed )); + +/** IPoIB link-layer header real portion */ +struct ipoib_real_hdr { + /** Network-layer protocol */ + uint16_t proto; + /** Reserved, must be zero */ + uint16_t reserved; +} __attribute__ (( packed )); + +/** An IPoIB link-layer header */ +struct ipoib_hdr { + /** Pseudo portion */ + struct ipoib_pseudo_hdr pseudo; + /** Real portion */ + struct ipoib_real_hdr real; +} __attribute__ (( packed )); + +extern struct ll_protocol ipoib_protocol; + +extern const char * ipoib_ntoa ( const void *ll_addr ); + +/** + * Allocate IPoIB device + * + * @v priv_size Size of driver private data + * @ret netdev Network device, or NULL + */ +static inline struct net_device * alloc_ipoibdev ( size_t priv_size ) { + struct net_device *netdev; + + netdev = alloc_netdev ( priv_size ); + if ( netdev ) { + netdev->ll_protocol = &ipoib_protocol; + } + return netdev; +} + +extern int ipoib_probe ( struct ib_device *ibdev ); +extern void ipoib_remove ( struct ib_device *ibdev ); + +#endif /* _GPXE_IPOIB_H */ diff --git a/gpxe/src/include/gpxe/isa.h b/gpxe/src/include/gpxe/isa.h new file mode 100644 index 00000000..bb25dbce --- /dev/null +++ b/gpxe/src/include/gpxe/isa.h @@ -0,0 +1,92 @@ +#ifndef ISA_H +#define ISA_H + +#include <stdint.h> +#include <gpxe/isa_ids.h> +#include <gpxe/device.h> +#include <gpxe/tables.h> + +/** An ISA device */ +struct isa_device { + /** Generic device */ + struct device dev; + /** I/O address */ + uint16_t ioaddr; + /** Driver for this device */ + struct isa_driver *driver; + /** Driver-private data + * + * Use isa_set_drvdata() and isa_get_drvdata() to access + * this field. + */ + void *priv; + /** Driver name */ + const char *driver_name; +}; + +/* + * An individual ISA device, identified by probe address + * + */ +typedef uint16_t isa_probe_addr_t; + +/** An ISA driver */ +struct isa_driver { + /** Name */ + const char *name; + /** Probe address list */ + isa_probe_addr_t *probe_addrs; + /** Number of entries in probe address list */ + unsigned int addr_count; + /** Manufacturer ID to be assumed for this device */ + uint16_t vendor_id; + /** Product ID to be assumed for this device */ + uint16_t prod_id; + /** + * Probe device + * + * @v isa ISA device + * @v id Matching entry in ID table + * @ret rc Return status code + */ + int ( * probe ) ( struct isa_device *isa ); + /** + * Remove device + * + * @v isa ISA device + */ + void ( * remove ) ( struct isa_device *isa ); +}; + +/** Declare an ISA driver */ +#define __isa_driver __table ( struct isa_driver, isa_drivers, 01 ) + +/** + * Set ISA driver-private data + * + * @v isa ISA device + * @v priv Private data + */ +static inline void isa_set_drvdata ( struct isa_device *isa, void *priv ) { + isa->priv = priv; +} + +/** + * Get ISA driver-private data + * + * @v isa ISA device + * @ret priv Private data + */ +static inline void * isa_get_drvdata ( struct isa_device *isa ) { + return isa->priv; +} + +/* + * ISA_ROM is parsed by parserom.pl to generate Makefile rules and + * files for rom-o-matic. + * + */ +#define ISA_ROM( IMAGE, DESCRIPTION ) + +#endif /* ISA_H */ + diff --git a/gpxe/src/include/gpxe/isa_ids.h b/gpxe/src/include/gpxe/isa_ids.h new file mode 100644 index 00000000..bf3f1015 --- /dev/null +++ b/gpxe/src/include/gpxe/isa_ids.h @@ -0,0 +1,49 @@ +#ifndef ISA_IDS_H +#define ISA_IDS_H + +/* + * This file defines IDs as used by ISAPnP and EISA devices. These + * IDs have the format: + * + * vendor byte 0 bit 7 must be zero + * bits 6-2 first vendor char in compressed ASCII + * bits 1-0 second vendor char in compressed ASCII (bits 4-3) + * byte 1 bits 7-5 second vendor char in compressed ASCII (bits 2-0) + * bits 4-0 third vendor char in compressed ASCII + * product byte 0 bits 7-4 first hex digit of product number + * bits 3-0 second hex digit of product number + * byte 1 bits 7-4 third hex digit of product number + * bits 3-0 hex digit of revision level + * + * ISA IDs are always expressed in little-endian order, even though + * the underlying "meaning" is big-endian. + */ + +#include <byteswap.h> + +/* + * Construct a vendor ID from three ASCII characters + * + */ +#define ISA_VENDOR( a, b, c ) \ + bswap_16 ( ( ( ( (a) - 'A' + 1 ) & 0x1f ) << 10 ) | \ + ( ( ( (b) - 'A' + 1 ) & 0x1f ) << 5 ) | \ + ( ( ( (c) - 'A' + 1 ) & 0x1f ) << 0 ) ) + +#define ISAPNP_VENDOR( a, b, c ) ISA_VENDOR ( a, b, c ) +#define EISA_VENDOR( a, b, c ) ISA_VENDOR ( a, b, c ) + +#define GENERIC_ISAPNP_VENDOR ISAPNP_VENDOR ( 'P','N','P' ) + +/* + * Extract product ID and revision from combined product field + * + */ +#define ISA_PROD_ID_MASK ( 0xf0ff ) +#define ISA_PROD_ID(product) ( (product) & ISA_PROD_ID_MASK ) +#define ISA_PROD_REV(product) ( ( (product) & ~ISA_PROD_ID_MASK ) >> 8 ) + +/* Functions in isa_ids.c */ +extern char * isa_id_string ( unsigned int vendor, unsigned int product ); + +#endif /* ISA_IDS_H */ diff --git a/gpxe/src/include/gpxe/isapnp.h b/gpxe/src/include/gpxe/isapnp.h new file mode 100644 index 00000000..07797a99 --- /dev/null +++ b/gpxe/src/include/gpxe/isapnp.h @@ -0,0 +1,273 @@ +/************************************************************************** +* +* isapnp.h -- Etherboot isapnp support for the 3Com 3c515 +* Written 2002-2003 by Timothy Legge <tlegge@rogers.com> +* +* 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 +* (at your option) 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +* Portions of this code: +* Copyright (C) 2001 P.J.H.Fox (fox@roestock.demon.co.uk) +* +* +* +* REVISION HISTORY: +* ================ +* Version 0.1 April 26, 2002 TJL +* Version 0.2 01/08/2003 TJL Renamed from 3c515_isapnp.h +* +* +* Generalised into an ISAPnP bus that can be used by more than just +* the 3c515 by Michael Brown <mbrown@fensystems.co.uk> +* +***************************************************************************/ + +#ifndef ISAPNP_H +#define ISAPNP_H + +#include <stdint.h> +#include <gpxe/isa_ids.h> +#include <gpxe/device.h> +#include <gpxe/tables.h> + +/* + * ISAPnP constants + * + */ + +/* Port addresses */ +#define ISAPNP_ADDRESS 0x279 +#define ISAPNP_WRITE_DATA 0xa79 +#define ISAPNP_READ_PORT_MIN 0x203 +#define ISAPNP_READ_PORT_START 0x213 /* ISAPnP spec says 0x203, but + * Linux ISAPnP starts at + * 0x213 with no explanatory + * comment. 0x203 probably + * clashes with something. */ +#define ISAPNP_READ_PORT_MAX 0x3ff +#define ISAPNP_READ_PORT_STEP 0x10 /* Can be any multiple of 4 + * according to the spec, but + * since ISA I/O addresses are + * allocated in blocks of 16, + * it makes no sense to use + * any value less than 16. + */ + +/* Card select numbers */ +#define ISAPNP_CSN_MIN 0x01 +#define ISAPNP_CSN_MAX 0x0f + +/* Registers */ +#define ISAPNP_READPORT 0x00 +#define ISAPNP_SERIALISOLATION 0x01 +#define ISAPNP_CONFIGCONTROL 0x02 +#define ISAPNP_WAKE 0x03 +#define ISAPNP_RESOURCEDATA 0x04 +#define ISAPNP_STATUS 0x05 +#define ISAPNP_CARDSELECTNUMBER 0x06 +#define ISAPNP_LOGICALDEVICENUMBER 0x07 +#define ISAPNP_ACTIVATE 0x30 +#define ISAPNP_IORANGECHECK 0x31 +#define ISAPNP_IOBASE(n) ( 0x60 + ( (n) * 2 ) ) +#define ISAPNP_IRQNO(n) ( 0x70 + ( (n) * 2 ) ) +#define ISAPNP_IRQTYPE(n) ( 0x71 + ( (n) * 2 ) ) + +/* Bits in the CONFIGCONTROL register */ +#define ISAPNP_CONFIG_RESET ( 1 << 0 ) +#define ISAPNP_CONFIG_WAIT_FOR_KEY ( 1 << 1 ) +#define ISAPNP_CONFIG_RESET_CSN ( 1 << 2 ) +#define ISAPNP_CONFIG_RESET_DRV ( ISAPNP_CONFIG_RESET | \ + ISAPNP_CONFIG_WAIT_FOR_KEY | \ + ISAPNP_CONFIG_RESET_CSN ) + +/* The LFSR used for the initiation key and for checksumming */ +#define ISAPNP_LFSR_SEED 0x6a + +/* Small tags */ +#define ISAPNP_IS_SMALL_TAG(tag) ( ! ( (tag) & 0x80 ) ) +#define ISAPNP_SMALL_TAG_NAME(tag) ( ( (tag) >> 3 ) & 0xf ) +#define ISAPNP_SMALL_TAG_LEN(tag) ( ( (tag) & 0x7 ) ) +#define ISAPNP_TAG_PNPVERNO 0x01 +#define ISAPNP_TAG_LOGDEVID 0x02 +#define ISAPNP_TAG_COMPATDEVID 0x03 +#define ISAPNP_TAG_IRQ 0x04 +#define ISAPNP_TAG_DMA 0x05 +#define ISAPNP_TAG_STARTDEP 0x06 +#define ISAPNP_TAG_ENDDEP 0x07 +#define ISAPNP_TAG_IOPORT 0x08 +#define ISAPNP_TAG_FIXEDIO 0x09 +#define ISAPNP_TAG_RSVDSHORTA 0x0A +#define ISAPNP_TAG_RSVDSHORTB 0x0B +#define ISAPNP_TAG_RSVDSHORTC 0x0C +#define ISAPNP_TAG_RSVDSHORTD 0x0D +#define ISAPNP_TAG_VENDORSHORT 0x0E +#define ISAPNP_TAG_END 0x0F +/* Large tags */ +#define ISAPNP_IS_LARGE_TAG(tag) ( ( (tag) & 0x80 ) ) +#define ISAPNP_LARGE_TAG_NAME(tag) (tag) +#define ISAPNP_TAG_MEMRANGE 0x81 +#define ISAPNP_TAG_ANSISTR 0x82 +#define ISAPNP_TAG_UNICODESTR 0x83 +#define ISAPNP_TAG_VENDORLONG 0x84 +#define ISAPNP_TAG_MEM32RANGE 0x85 +#define ISAPNP_TAG_FIXEDMEM32RANGE 0x86 +#define ISAPNP_TAG_RSVDLONG0 0xF0 +#define ISAPNP_TAG_RSVDLONG1 0xF1 +#define ISAPNP_TAG_RSVDLONG2 0xF2 +#define ISAPNP_TAG_RSVDLONG3 0xF3 +#define ISAPNP_TAG_RSVDLONG4 0xF4 +#define ISAPNP_TAG_RSVDLONG5 0xF5 +#define ISAPNP_TAG_RSVDLONG6 0xF6 +#define ISAPNP_TAG_RSVDLONG7 0xF7 +#define ISAPNP_TAG_RSVDLONG8 0xF8 +#define ISAPNP_TAG_RSVDLONG9 0xF9 +#define ISAPNP_TAG_RSVDLONGA 0xFA +#define ISAPNP_TAG_RSVDLONGB 0xFB +#define ISAPNP_TAG_RSVDLONGC 0xFC +#define ISAPNP_TAG_RSVDLONGD 0xFD +#define ISAPNP_TAG_RSVDLONGE 0xFE +#define ISAPNP_TAG_RSVDLONGF 0xFF +#define ISAPNP_TAG_PSEUDO_NEWBOARD 0x100 + +/** An ISAPnP serial identifier */ +struct isapnp_identifier { + /** Vendor ID */ + uint16_t vendor_id; + /** Product ID */ + uint16_t prod_id; + /** Serial number */ + uint32_t serial; + /** Checksum */ + uint8_t checksum; +} __attribute__ (( packed )); + +/** An ISAPnP logical device ID structure */ +struct isapnp_logdevid { + /** Vendor ID */ + uint16_t vendor_id; + /** Product ID */ + uint16_t prod_id; + /** Flags */ + uint16_t flags; +} __attribute__ (( packed )); + +/** An ISAPnP device ID list entry */ +struct isapnp_device_id { + /** Name */ + const char *name; + /** Vendor ID */ + uint16_t vendor_id; + /** Product ID */ + uint16_t prod_id; +}; + +/** An ISAPnP device */ +struct isapnp_device { + /** Generic device */ + struct device dev; + /** Vendor ID */ + uint16_t vendor_id; + /** Product ID */ + uint16_t prod_id; + /** I/O address */ + uint16_t ioaddr; + /** Interrupt number */ + uint8_t irqno; + /** Card Select Number */ + uint8_t csn; + /** Logical Device ID */ + uint8_t logdev; + /** Driver for this device */ + struct isapnp_driver *driver; + /** Driver-private data + * + * Use isapnp_set_drvdata() and isapnp_get_drvdata() to access + * this field. + */ + void *priv; + /** Driver name */ + const char *driver_name; +}; + +/** An ISAPnP driver */ +struct isapnp_driver { + /** ISAPnP ID table */ + struct isapnp_device_id *ids; + /** Number of entries in ISAPnP ID table */ + unsigned int id_count; + /** + * Probe device + * + * @v isapnp ISAPnP device + * @v id Matching entry in ID table + * @ret rc Return status code + */ + int ( * probe ) ( struct isapnp_device *isapnp, + const struct isapnp_device_id *id ); + /** + * Remove device + * + * @v isapnp ISAPnP device + */ + void ( * remove ) ( struct isapnp_device *isapnp ); +}; + +/** Declare an ISAPnP driver */ +#define __isapnp_driver __table ( struct isapnp_driver, isapnp_drivers, 01 ) + +extern uint16_t isapnp_read_port; + +extern void isapnp_device_activation ( struct isapnp_device *isapnp, + int activation ); + +/** + * Activate ISAPnP device + * + * @v isapnp ISAPnP device + */ +static inline void activate_isapnp_device ( struct isapnp_device *isapnp ) { + isapnp_device_activation ( isapnp, 1 ); +} + +/** + * Deactivate ISAPnP device + * + * @v isapnp ISAPnP device + */ +static inline void deactivate_isapnp_device ( struct isapnp_device *isapnp ) { + isapnp_device_activation ( isapnp, 0 ); +} + +/** + * Set ISAPnP driver-private data + * + * @v isapnp ISAPnP device + * @v priv Private data + */ +static inline void isapnp_set_drvdata ( struct isapnp_device *isapnp, + void *priv ) { + isapnp->priv = priv; +} + +/** + * Get ISAPnP driver-private data + * + * @v isapnp ISAPnP device + * @ret priv Private data + */ +static inline void * isapnp_get_drvdata ( struct isapnp_device *isapnp ) { + return isapnp->priv; +} + +#endif /* ISAPNP_H */ diff --git a/gpxe/src/include/gpxe/iscsi.h b/gpxe/src/include/gpxe/iscsi.h new file mode 100644 index 00000000..e4df6849 --- /dev/null +++ b/gpxe/src/include/gpxe/iscsi.h @@ -0,0 +1,654 @@ +#ifndef _GPXE_ISCSI_H +#define _GPXE_ISCSI_H + +/** @file + * + * iSCSI protocol + * + */ + +#include <stdint.h> +#include <gpxe/socket.h> +#include <gpxe/scsi.h> +#include <gpxe/chap.h> +#include <gpxe/refcnt.h> +#include <gpxe/xfer.h> +#include <gpxe/process.h> + +/** Default iSCSI port */ +#define ISCSI_PORT 3260 + +/** + * iSCSI segment lengths + * + * iSCSI uses an icky structure with one one-byte field (a dword + * count) and one three-byte field (a byte count). This structure, + * and the accompanying macros, relieve some of the pain. + */ +union iscsi_segment_lengths { + struct { + /** The AHS length (measured in dwords) */ + uint8_t ahs_len; + /** The data length (measured in bytes), in network + * byte order + */ + uint8_t data_len[3]; + } bytes; + /** Ths data length (measured in bytes), in network byte + * order, with ahs_len as the first byte. + */ + uint32_t ahs_and_data_len; +}; + +/** The length of the additional header segment, in dwords */ +#define ISCSI_AHS_LEN( segment_lengths ) \ + ( (segment_lengths).bytes.ahs_len ) + +/** The length of the data segment, in bytes, excluding any padding */ +#define ISCSI_DATA_LEN( segment_lengths ) \ + ( ntohl ( (segment_lengths).ahs_and_data_len ) & 0xffffff ) + +/** The padding of the data segment, in bytes */ +#define ISCSI_DATA_PAD_LEN( segment_lengths ) \ + ( ( 0 - (segment_lengths).bytes.data_len[2] ) & 0x03 ) + +/** Set additional header and data segment lengths */ +#define ISCSI_SET_LENGTHS( segment_lengths, ahs_len, data_len ) do { \ + (segment_lengths).ahs_and_data_len = \ + htonl ( data_len | ( ahs_len << 24 ) ); \ + } while ( 0 ) + +/** + * iSCSI basic header segment common fields + * + */ +struct iscsi_bhs_common { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Fields specific to the PDU type */ + uint8_t other_a[2]; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Fields specific to the PDU type */ + uint8_t other_b[8]; + /** Initiator Task Tag */ + uint32_t itt; + /** Fields specific to the PDU type */ + uint8_t other_c[28]; +}; + +/** Opcode mask */ +#define ISCSI_OPCODE_MASK 0x3f + +/** Immediate delivery */ +#define ISCSI_FLAG_IMMEDIATE 0x40 + +/** Final PDU of a sequence */ +#define ISCSI_FLAG_FINAL 0x80 + +/** + * iSCSI basic header segment common request fields + * + */ +struct iscsi_bhs_common_response { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Fields specific to the PDU type */ + uint8_t other_a[2]; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Fields specific to the PDU type */ + uint8_t other_b[8]; + /** Initiator Task Tag */ + uint32_t itt; + /** Fields specific to the PDU type */ + uint8_t other_c[4]; + /** Status sequence number */ + uint32_t statsn; + /** Expected command sequence number */ + uint32_t expcmdsn; + /** Fields specific to the PDU type */ + uint8_t other_d[16]; +}; + +/** + * iSCSI login request basic header segment + * + */ +struct iscsi_bhs_login_request { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Maximum supported version number */ + uint8_t version_max; + /** Minimum supported version number */ + uint8_t version_min; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Initiator session ID (IANA format) enterprise number and flags */ + uint32_t isid_iana_en; + /** Initiator session ID (IANA format) qualifier */ + uint16_t isid_iana_qual; + /** Target session identifying handle */ + uint16_t tsih; + /** Initiator Task Tag */ + uint32_t itt; + /** Connection ID */ + uint16_t cid; + /** Reserved */ + uint16_t reserved_a; + /** Command sequence number */ + uint32_t cmdsn; + /** Expected status sequence number */ + uint32_t expstatsn; + /** Reserved */ + uint8_t reserved_b[16]; +}; + +/** Login request opcode */ +#define ISCSI_OPCODE_LOGIN_REQUEST 0x03 + +/** Willingness to transition to next stage */ +#define ISCSI_LOGIN_FLAG_TRANSITION 0x80 + +/** Key=value pairs continued in subsequent request */ +#define ISCSI_LOGIN_FLAG_CONTINUE 0x40 + +/* Current stage values and mask */ +#define ISCSI_LOGIN_CSG_MASK 0x0c +#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION 0x00 +#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION 0x04 +#define ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE 0x0c + +/* Next stage values and mask */ +#define ISCSI_LOGIN_NSG_MASK 0x03 +#define ISCSI_LOGIN_NSG_SECURITY_NEGOTIATION 0x00 +#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01 +#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03 + +/** ISID IANA format marker */ +#define ISCSI_ISID_IANA 0x40000000 + +/** Fen Systems Ltd. IANA enterprise number + * + * Permission is hereby granted to use Fen Systems Ltd.'s IANA + * enterprise number with this iSCSI implementation. + */ +#define IANA_EN_FEN_SYSTEMS 10019 + +/** + * iSCSI login response basic header segment + * + */ +struct iscsi_bhs_login_response { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Maximum supported version number */ + uint8_t version_max; + /** Minimum supported version number */ + uint8_t version_min; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Initiator session ID (IANA format) enterprise number and flags */ + uint32_t isid_iana_en; + /** Initiator session ID (IANA format) qualifier */ + uint16_t isid_iana_qual; + /** Target session identifying handle */ + uint16_t tsih; + /** Initiator Task Tag */ + uint32_t itt; + /** Reserved */ + uint32_t reserved_a; + /** Status sequence number */ + uint32_t statsn; + /** Expected command sequence number */ + uint32_t expcmdsn; + /** Maximum command sequence number */ + uint32_t maxcmdsn; + /** Status class */ + uint8_t status_class; + /** Status detail */ + uint8_t status_detail; + /** Reserved */ + uint8_t reserved_b[10]; +}; + +/** Login response opcode */ +#define ISCSI_OPCODE_LOGIN_RESPONSE 0x23 + +/* Login response status codes */ +#define ISCSI_STATUS_SUCCESS 0x00 +#define ISCSI_STATUS_REDIRECT 0x01 +#define ISCSI_STATUS_INITIATOR_ERROR 0x02 +#define ISCSI_STATUS_TARGET_ERROR 0x03 + +/** + * iSCSI SCSI command basic header segment + * + */ +struct iscsi_bhs_scsi_command { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Reserved */ + uint16_t reserved_a; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** SCSI Logical Unit Number */ + uint64_t lun; + /** Initiator Task Tag */ + uint32_t itt; + /** Expected data transfer length */ + uint32_t exp_len; + /** Command sequence number */ + uint32_t cmdsn; + /** Expected status sequence number */ + uint32_t expstatsn; + /** SCSI Command Descriptor Block (CDB) */ + union scsi_cdb cdb; +}; + +/** SCSI command opcode */ +#define ISCSI_OPCODE_SCSI_COMMAND 0x01 + +/** Command will read data */ +#define ISCSI_COMMAND_FLAG_READ 0x40 + +/** Command will write data */ +#define ISCSI_COMMAND_FLAG_WRITE 0x20 + +/* Task attributes */ +#define ISCSI_COMMAND_ATTR_UNTAGGED 0x00 +#define ISCSI_COMMAND_ATTR_SIMPLE 0x01 +#define ISCSI_COMMAND_ATTR_ORDERED 0x02 +#define ISCSI_COMMAND_ATTR_HEAD_OF_QUEUE 0x03 +#define ISCSI_COMMAND_ATTR_ACA 0x04 + +/** + * iSCSI SCSI response basic header segment + * + */ +struct iscsi_bhs_scsi_response { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Response code */ + uint8_t response; + /** SCSI status code */ + uint8_t status; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Reserved */ + uint8_t reserved_a[8]; + /** Initiator Task Tag */ + uint32_t itt; + /** SNACK tag */ + uint32_t snack; + /** Status sequence number */ + uint32_t statsn; + /** Expected command sequence number */ + uint32_t expcmdsn; + /** Maximum command sequence number */ + uint32_t maxcmdsn; + /** Expected data sequence number */ + uint32_t expdatasn; + /** Reserved */ + uint8_t reserved_b[8]; +}; + +/** SCSI response opcode */ +#define ISCSI_OPCODE_SCSI_RESPONSE 0x21 + +/** SCSI command completed at target */ +#define ISCSI_RESPONSE_COMMAND_COMPLETE 0x00 + +/** SCSI target failure */ +#define ISCSI_RESPONSE_TARGET_FAILURE 0x01 + +/** SCSI sense response code offset + * + * The SCSI response may contain unsolicited sense data in the data + * segment. If it does, this is the offset to the sense response code + * byte, which is the only byte we care about. + */ +#define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2 + +/** + * iSCSI data-in basic header segment + * + */ +struct iscsi_bhs_data_in { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Reserved */ + uint8_t reserved_a; + /** SCSI status code */ + uint8_t status; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Logical Unit Number */ + uint64_t lun; + /** Initiator Task Tag */ + uint32_t itt; + /** Target Transfer Tag */ + uint32_t ttt; + /** Status sequence number */ + uint32_t statsn; + /** Expected command sequence number */ + uint32_t expcmdsn; + /** Maximum command sequence number */ + uint32_t maxcmdsn; + /** Data sequence number */ + uint32_t datasn; + /** Buffer offset */ + uint32_t offset; + /** Residual count */ + uint32_t residual_count; +}; + +/** Data-in opcode */ +#define ISCSI_OPCODE_DATA_IN 0x25 + +/** Data requires acknowledgement */ +#define ISCSI_DATA_FLAG_ACKNOWLEDGE 0x40 + +/** Data overflow occurred */ +#define ISCSI_DATA_FLAG_OVERFLOW 0x04 + +/** Data underflow occurred */ +#define ISCSI_DATA_FLAG_UNDERFLOW 0x02 + +/** SCSI status code and overflow/underflow flags are valid */ +#define ISCSI_DATA_FLAG_STATUS 0x01 + +/** + * iSCSI data-out basic header segment + * + */ +struct iscsi_bhs_data_out { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Reserved */ + uint16_t reserved_a; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Logical Unit Number */ + uint64_t lun; + /** Initiator Task Tag */ + uint32_t itt; + /** Target Transfer Tag */ + uint32_t ttt; + /** Reserved */ + uint32_t reserved_b; + /** Expected status sequence number */ + uint32_t expstatsn; + /** Reserved */ + uint32_t reserved_c; + /** Data sequence number */ + uint32_t datasn; + /** Buffer offset */ + uint32_t offset; + /** Reserved */ + uint32_t reserved_d; +}; + +/** Data-out opcode */ +#define ISCSI_OPCODE_DATA_OUT 0x05 + +/** + * iSCSI request to transfer basic header segment + * + */ +struct iscsi_bhs_r2t { + /** Opcode */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Reserved */ + uint16_t reserved_a; + /** Segment lengths */ + union iscsi_segment_lengths lengths; + /** Logical Unit Number */ + uint64_t lun; + /** Initiator Task Tag */ + uint32_t itt; + /** Target Transfer Tag */ + uint32_t ttt; + /** Status sequence number */ + uint32_t statsn; + /** Expected command sequence number */ + uint32_t expcmdsn; + /** Maximum command sequence number */ + uint32_t maxcmdsn; + /** R2T sequence number */ + uint32_t r2tsn; + /** Buffer offset */ + uint32_t offset; + /** Desired data transfer length */ + uint32_t len; +}; + +/** R2T opcode */ +#define ISCSI_OPCODE_R2T 0x31 + +/** + * An iSCSI basic header segment + */ +union iscsi_bhs { + struct iscsi_bhs_common common; + struct iscsi_bhs_common_response common_response; + struct iscsi_bhs_login_request login_request; + struct iscsi_bhs_login_response login_response; + struct iscsi_bhs_scsi_command scsi_command; + struct iscsi_bhs_scsi_response scsi_response; + struct iscsi_bhs_data_in data_in; + struct iscsi_bhs_data_out data_out; + struct iscsi_bhs_r2t r2t; + unsigned char bytes[ sizeof ( struct iscsi_bhs_common ) ]; +}; + +/** State of an iSCSI TX engine */ +enum iscsi_tx_state { + /** Nothing to send */ + ISCSI_TX_IDLE = 0, + /** Sending the basic header segment */ + ISCSI_TX_BHS, + /** Sending the additional header segment */ + ISCSI_TX_AHS, + /** Sending the data segment */ + ISCSI_TX_DATA, + /** Sending the data segment padding */ + ISCSI_TX_DATA_PADDING, +}; + +/** State of an iSCSI RX engine */ +enum iscsi_rx_state { + /** Receiving the basic header segment */ + ISCSI_RX_BHS = 0, + /** Receiving the additional header segment */ + ISCSI_RX_AHS, + /** Receiving the data segment */ + ISCSI_RX_DATA, + /** Receiving the data segment padding */ + ISCSI_RX_DATA_PADDING, +}; + +/** An iSCSI session */ +struct iscsi_session { + /** Reference counter */ + struct refcnt refcnt; + + /** Transport-layer socket */ + struct xfer_interface socket; + + /** Target address */ + char *target_address; + /** Target port */ + unsigned int target_port; + /** Target IQN */ + char *target_iqn; + /** Logical Unit Number (LUN) */ + uint64_t lun; + /** Target socket address (recorded only for iBFT) */ + struct sockaddr target_sockaddr; + + /** Session status + * + * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX + * constants. + */ + int status; + /** Retry count + * + * Number of times that the connection has been retried. + * Reset upon a successful connection. + */ + int retry_count; + + /** Username (if any) */ + char *username; + /** Password (if any) */ + char *password; + /** CHAP challenge/response */ + struct chap_challenge chap; + + /** Target session identifying handle + * + * This is assigned by the target when we first log in, and + * must be reused on subsequent login attempts. + */ + uint16_t tsih; + /** Initiator task tag + * + * This is the tag of the current command. It is incremented + * whenever a new command is started. + */ + uint32_t itt; + /** Target transfer tag + * + * This is the tag attached to a sequence of data-out PDUs in + * response to an R2T. + */ + uint32_t ttt; + /** + * Transfer offset + * + * This is the offset for an in-progress sequence of data-out + * PDUs in response to an R2T. + */ + uint32_t transfer_offset; + /** + * Transfer length + * + * This is the length for an in-progress sequence of data-out + * PDUs in response to an R2T. + */ + uint32_t transfer_len; + /** Command sequence number + * + * This is the sequence number of the current command, used to + * fill out the CmdSN field in iSCSI request PDUs. It is + * updated with the value of the ExpCmdSN field whenever we + * receive an iSCSI response PDU containing such a field. + */ + uint32_t cmdsn; + /** Status sequence number + * + * This is the most recent status sequence number present in + * the StatSN field of an iSCSI response PDU containing such a + * field. Whenever we send an iSCSI request PDU, we fill out + * the ExpStatSN field with this value plus one. + */ + uint32_t statsn; + + /** Basic header segment for current TX PDU */ + union iscsi_bhs tx_bhs; + /** State of the TX engine */ + enum iscsi_tx_state tx_state; + /** TX process */ + struct process process; + + /** Basic header segment for current RX PDU */ + union iscsi_bhs rx_bhs; + /** State of the RX engine */ + enum iscsi_rx_state rx_state; + /** Byte offset within the current RX state */ + size_t rx_offset; + /** Length of the current RX state */ + size_t rx_len; + /** Buffer for received data (not always used) */ + void *rx_buffer; + + /** Current SCSI command + * + * Set to NULL when command is complete. + */ + struct scsi_command *command; + /** SCSI command return code + * + * Set to -EINPROGRESS while command is processing. + */ + int rc; + /** Instant return code + * + * Set to a non-zero value if all requests should return + * immediately. This can be used to e.g. avoid retrying + * logins that are doomed to fail authentication. + */ + int instant_rc; +}; + +/** iSCSI session is currently in the security negotiation phase */ +#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE \ + ( ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION | \ + ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION ) + +/** iSCSI session is currently in the operational parameter + * negotiation phase + */ +#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE \ + ( ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION | \ + ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE ) + +/** iSCSI session is currently in the full feature phase */ +#define ISCSI_STATUS_FULL_FEATURE_PHASE ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE + +/** Mask for all iSCSI session phases */ +#define ISCSI_STATUS_PHASE_MASK ( ISCSI_LOGIN_CSG_MASK | ISCSI_LOGIN_NSG_MASK ) + +/** iSCSI session needs to send the initial security negotiation strings */ +#define ISCSI_STATUS_STRINGS_SECURITY 0x0100 + +/** iSCSI session needs to send the CHAP_A string */ +#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM 0x0200 + +/** iSCSI session needs to send the CHAP response */ +#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE 0x0400 + +/** iSCSI session needs to send the operational negotiation strings */ +#define ISCSI_STATUS_STRINGS_OPERATIONAL 0x0800 + +/** Mask for all iSCSI "needs to send" flags */ +#define ISCSI_STATUS_STRINGS_MASK 0xff00 + +/** Maximum number of retries at connecting */ +#define ISCSI_MAX_RETRIES 2 + +extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path ); +extern void iscsi_detach ( struct scsi_device *scsi ); +extern const char * iscsi_initiator_iqn ( void ); + +#endif /* _GPXE_ISCSI_H */ diff --git a/gpxe/src/include/gpxe/job.h b/gpxe/src/include/gpxe/job.h new file mode 100644 index 00000000..8e11aa33 --- /dev/null +++ b/gpxe/src/include/gpxe/job.h @@ -0,0 +1,165 @@ +#ifndef _GPXE_JOB_H +#define _GPXE_JOB_H + +/** @file + * + * Job control interfaces + * + */ + +#include <stddef.h> +#include <gpxe/interface.h> + +/** Job progress */ +struct job_progress { + /** Amount of operation completed so far + * + * The units for this quantity are arbitrary. @c completed + * divded by @total should give something which approximately + * represents the progress through the operation. For a + * download operation, using byte counts would make sense. + */ + unsigned long completed; + /** Total operation size + * + * See @c completed. A zero value means "total size unknown" + * and is explcitly permitted; users should take this into + * account before calculating @c completed/total. + */ + unsigned long total; +}; + +struct job_interface; + +/** Job control interface operations */ +struct job_interface_operations { + /** Job completed + * + * @v job Job control interface + * @v rc Overall job status code + */ + void ( * done ) ( struct job_interface *job, int rc ); + /** Abort job + * + * @v job Job control interface + */ + void ( * kill ) ( struct job_interface *job ); + /** Get job progress + * + * @v job Job control interface + * @v progress Progress data to fill in + */ + void ( * progress ) ( struct job_interface *job, + struct job_progress *progress ); +}; + +/** A job control interface */ +struct job_interface { + /** Generic object communication interface */ + struct interface intf; + /** Operations for received messages */ + struct job_interface_operations *op; +}; + +extern struct job_interface null_job; +extern struct job_interface_operations null_job_ops; + +extern void job_done ( struct job_interface *job, int rc ); +extern void job_kill ( struct job_interface *job ); + +extern void ignore_job_done ( struct job_interface *job, int rc ); +extern void ignore_job_kill ( struct job_interface *job ); +extern void ignore_job_progress ( struct job_interface *job, + struct job_progress *progress ); + +/** + * Initialise a job control interface + * + * @v job Job control interface + * @v op Job control interface operations + * @v refcnt Containing object reference counter, or NULL + */ +static inline void job_init ( struct job_interface *job, + struct job_interface_operations *op, + struct refcnt *refcnt ) { + job->intf.dest = &null_job.intf; + job->intf.refcnt = refcnt; + job->op = op; +} + +/** + * Get job control interface from generic object communication interface + * + * @v intf Generic object communication interface + * @ret job Job control interface + */ +static inline __attribute__ (( always_inline )) struct job_interface * +intf_to_job ( struct interface *intf ) { + return container_of ( intf, struct job_interface, intf ); +} + +/** + * Get reference to destination job control interface + * + * @v job Job control interface + * @ret dest Destination interface + */ +static inline __attribute__ (( always_inline )) struct job_interface * +job_get_dest ( struct job_interface *job ) { + return intf_to_job ( intf_get ( job->intf.dest ) ); +} + +/** + * Drop reference to job control interface + * + * @v job Job control interface + */ +static inline __attribute__ (( always_inline )) void +job_put ( struct job_interface *job ) { + intf_put ( &job->intf ); +} + +/** + * Plug a job control interface into a new destination interface + * + * @v job Job control interface + * @v dest New destination interface + */ +static inline void job_plug ( struct job_interface *job, + struct job_interface *dest ) { + plug ( &job->intf, &dest->intf ); +} + +/** + * Plug two job control interfaces together + * + * @v a Job control interface A + * @v b Job control interface B + */ +static inline void job_plug_plug ( struct job_interface *a, + struct job_interface *b ) { + plug_plug ( &a->intf, &b->intf ); +} + +/** + * Unplug a job control interface + * + * @v job Job control interface + */ +static inline void job_unplug ( struct job_interface *job ) { + plug ( &job->intf, &null_job.intf ); +} + +/** + * Stop using a job control interface + * + * @v job Job control interface + * + * After calling this method, no further messages will be received via + * the interface. + */ +static inline void job_nullify ( struct job_interface *job ) { + job->op = &null_job_ops; +}; + +#endif /* _GPXE_JOB_H */ diff --git a/gpxe/src/include/gpxe/keys.h b/gpxe/src/include/gpxe/keys.h new file mode 100644 index 00000000..7a0b5101 --- /dev/null +++ b/gpxe/src/include/gpxe/keys.h @@ -0,0 +1,82 @@ +#ifndef _GPXE_KEYS_H +#define _GPXE_KEYS_H + +/** @file + * + * Key definitions + * + */ + +/* + * Symbolic names for some standard ASCII characters + * + */ + +#define NUL 0x00 +#define CTRL_A 0x01 +#define CTRL_B 0x02 +#define CTRL_C 0x03 +#define CTRL_D 0x04 +#define CTRL_E 0x05 +#define CTRL_F 0x06 +#define CTRL_G 0x07 +#define CTRL_H 0x08 +#define CTRL_I 0x09 +#define CTRL_J 0x0a +#define CTRL_K 0x0b +#define CTRL_L 0x0c +#define CTRL_M 0x0d +#define CTRL_N 0x0e +#define CTRL_O 0x0f +#define CTRL_P 0x10 +#define CTRL_Q 0x11 +#define CTRL_R 0x12 +#define CTRL_S 0x13 +#define CTRL_T 0x14 +#define CTRL_U 0x15 +#define CTRL_V 0x16 +#define CTRL_W 0x17 +#define CTRL_X 0x18 +#define CTRL_Y 0x19 +#define CTRL_Z 0x1a + +#define BACKSPACE CTRL_H +#define TAB CTRL_I +#define LF CTRL_J +#define CR CTRL_M +#define ESC 0x1b + +/* + * Special keys outside the normal ASCII range + * + * + * The names are chosen to match those used by curses. The values are + * chosen to facilitate easy conversion from a received ANSI escape + * sequence to a KEY_XXX constant. The KEY_XXX constant is simply + * 0x100 plus the first byte following CSI in the ANSI escape + * sequence. For example, KEY_LEFT is 0x144, since a left cursor key + * is transmitted as the ANSI sequence "^[[D". + */ + +#define KEY_ANSI( character ) ( 0x100 + (character) ) + +#define KEY_MIN 0x101 +#define KEY_UP KEY_ANSI ( 'A' ) /**< Up arrow */ +#define KEY_DOWN KEY_ANSI ( 'B' ) /**< Down arrow */ +#define KEY_RIGHT KEY_ANSI ( 'C' ) /**< Right arrow */ +#define KEY_LEFT KEY_ANSI ( 'D' ) /**< Left arrow */ +#define KEY_END KEY_ANSI ( 'F' ) /**< End */ +#define KEY_HOME KEY_ANSI ( 'H' ) /**< Home */ +#define KEY_IC KEY_ANSI ( '2' ) /**< Insert */ +#define KEY_DC KEY_ANSI ( '3' ) /**< Delete */ +#define KEY_PPAGE KEY_ANSI ( '5' ) /**< Page up */ +#define KEY_NPAGE KEY_ANSI ( '6' ) /**< Page down */ +#define KEY_MAX 0x1ff + +/* Not in the [KEY_MIN,KEY_MAX] range; terminals seem to send these as + * normal ASCII values. + */ +#define KEY_BACKSPACE BACKSPACE +#define KEY_ENTER LF + +#endif /* _GPXE_KEYS_H */ diff --git a/gpxe/src/include/gpxe/linebuf.h b/gpxe/src/include/gpxe/linebuf.h new file mode 100644 index 00000000..676731a9 --- /dev/null +++ b/gpxe/src/include/gpxe/linebuf.h @@ -0,0 +1,28 @@ +#ifndef _GPXE_LINEBUF_H +#define _GPXE_LINEBUF_H + +/** @file + * + * Line buffering + * + */ + +#include <stdint.h> +#include <stddef.h> + +/** A line buffer */ +struct line_buffer { + /** Current string in the buffer */ + char *data; + /** Length of current string, excluding the terminating NUL */ + size_t len; + /** String is ready to read */ + int ready; +}; + +extern char * buffered_line ( struct line_buffer *linebuf ); +extern ssize_t line_buffer ( struct line_buffer *linebuf, + const char *data, size_t len ); +extern void empty_line_buffer ( struct line_buffer *linebuf ); + +#endif /* _GPXE_LINEBUF_H */ diff --git a/gpxe/src/include/gpxe/linux_compat.h b/gpxe/src/include/gpxe/linux_compat.h new file mode 100644 index 00000000..2c3cbbde --- /dev/null +++ b/gpxe/src/include/gpxe/linux_compat.h @@ -0,0 +1,25 @@ +#ifndef _GPXE_LINUX_COMPAT_H +#define _GPXE_LINUX_COMPAT_H + +/** @file + * + * Linux code compatibility + * + * This file exists to ease the building of Linux source code within + * gPXE. This is intended to facilitate quick testing; it is not + * intended to be a substitute for proper porting. + */ + +#include <stdint.h> +#include <errno.h> +#include <stdio.h> +#include <byteswap.h> +#include <gpxe/bitops.h> + +#define __init +#define __exit +#define __initdata +#define __exitdata +#define printk printf + +#endif /* _GPXE_LINUX_COMPAT_H */ diff --git a/gpxe/src/include/gpxe/list.h b/gpxe/src/include/gpxe/list.h new file mode 100644 index 00000000..602382be --- /dev/null +++ b/gpxe/src/include/gpxe/list.h @@ -0,0 +1,178 @@ +#ifndef _GPXE_LIST_H +#define _GPXE_LIST_H + +/** @file + * + * Linked lists + * + * This linked list handling code is based on the Linux kernel's + * list.h. + */ + +#include <stddef.h> +#include <assert.h> + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next; + struct list_head *prev; +}; + +#define LIST_HEAD_INIT( name ) { &(name), &(name) } + +#define LIST_HEAD( name ) \ + struct list_head name = LIST_HEAD_INIT ( name ) + +#define INIT_LIST_HEAD( ptr ) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while ( 0 ) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add ( struct list_head *new, + struct list_head *prev, + struct list_head *next ) { + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * Add a new entry to the head of a list + * + * @v new New entry to be added + * @v head List head to add it after + * + * Insert a new entry after the specified head. This is good for + * implementing stacks. + */ +static inline void list_add ( struct list_head *new, struct list_head *head ) { + __list_add ( new, head, head->next ); +} +#define list_add( new, head ) do { \ + assert ( (head)->next->prev == (head) ); \ + assert ( (head)->prev->next == (head) ); \ + list_add ( (new), (head) ); \ + } while ( 0 ) + +/** + * Add a new entry to the tail of a list + * + * @v new New entry to be added + * @v head List head to add it before + * + * Insert a new entry before the specified head. This is useful for + * implementing queues. + */ +static inline void list_add_tail ( struct list_head *new, + struct list_head *head ) { + __list_add ( new, head->prev, head ); +} +#define list_add_tail( new, head ) do { \ + assert ( (head)->next->prev == (head) ); \ + assert ( (head)->prev->next == (head) ); \ + list_add_tail ( (new), (head) ); \ + } while ( 0 ) + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del ( struct list_head * prev, + struct list_head * next ) { + next->prev = prev; + prev->next = next; +} + +/** + * Delete an entry from a list + * + * @v entry Element to delete from the list + * + * Note that list_empty() on entry does not return true after this; + * the entry is in an undefined state. + */ +static inline void list_del ( struct list_head *entry ) { + __list_del ( entry->prev, entry->next ); +} +#define list_del( entry ) do { \ + assert ( (entry)->prev != NULL ); \ + assert ( (entry)->next != NULL ); \ + assert ( (entry)->next->prev == (entry) ); \ + assert ( (entry)->prev->next == (entry) ); \ + list_del ( (entry) ); \ + } while ( 0 ) + +/** + * Test whether a list is empty + * + * @v head List to test. + */ +static inline int list_empty ( const struct list_head *head ) { + return head->next == head; +} + +/** + * Get the containing struct for this entry + * + * @v ptr The struct list_head pointer + * @v type The type of the struct this is embedded in + * @v member The name of the list_struct within the struct + */ +#define list_entry( ptr, type, member ) \ + container_of ( ptr, type, member ) + +/** + * Iterate over a list + * + * @v pos The &struct list_head to use as a loop counter + * @v head The head for your list + */ +#define list_for_each( pos, head ) \ + for ( pos = (head)->next; pos != (head); pos = pos->next ) + +/** + * Iterate over entries in a list + * + * @v pos The type * to use as a loop counter + * @v head The head for your list + * @v member The name of the list_struct within the struct + */ +#define list_for_each_entry( pos, head, member ) \ + for ( pos = list_entry ( (head)->next, typeof ( *pos ), member ); \ + &pos->member != (head); \ + pos = list_entry ( pos->member.next, typeof ( *pos ), member ) ) + +/** + * Iterate over entries in a list, safe against deletion of entries + * + * @v pos The type * to use as a loop counter + * @v tmp Another type * to use for temporary storage + * @v head The head for your list + * @v member The name of the list_struct within the struct + */ +#define list_for_each_entry_safe( pos, tmp, head, member ) \ + for ( pos = list_entry ( (head)->next, typeof ( *pos ), member ), \ + tmp = list_entry ( pos->member.next, typeof ( *tmp ), member ); \ + &pos->member != (head); \ + pos = tmp, \ + tmp = list_entry ( tmp->member.next, typeof ( *tmp ), member ) ) + +#endif /* _GPXE_LIST_H */ diff --git a/gpxe/src/include/gpxe/malloc.h b/gpxe/src/include/gpxe/malloc.h new file mode 100644 index 00000000..cce5d1d3 --- /dev/null +++ b/gpxe/src/include/gpxe/malloc.h @@ -0,0 +1,57 @@ +#ifndef _GPXE_MALLOC_H +#define _GPXE_MALLOC_H + +#include <stdint.h> + +/** @file + * + * Dynamic memory allocation + * + */ + +/* + * Prototypes for the standard functions (malloc() et al) are in + * stdlib.h. Include <gpxe/malloc.h> only if you need the + * non-standard functions, such as malloc_dma(). + * + */ +#include <stdlib.h> + +extern size_t freemem; + +extern void * __malloc alloc_memblock ( size_t size, size_t align ); +extern void free_memblock ( void *ptr, size_t size ); +extern void mpopulate ( void *start, size_t len ); +extern void mdumpfree ( void ); + +/** + * Allocate memory for DMA + * + * @v size Requested size + * @v align Physical alignment + * @ret ptr Memory, or NULL + * + * Allocates physically-aligned memory for DMA. + * + * @c align must be a power of two. @c size may not be zero. + */ +static inline void * __malloc malloc_dma ( size_t size, size_t phys_align ) { + return alloc_memblock ( size, phys_align ); +} + +/** + * Free memory allocated with malloc_dma() + * + * @v ptr Memory allocated by malloc_dma(), or NULL + * @v size Size of memory, as passed to malloc_dma() + * + * Memory allocated with malloc_dma() can only be freed with + * free_dma(); it cannot be freed with the standard free(). + * + * If @c ptr is NULL, no action is taken. + */ +static inline void free_dma ( void *ptr, size_t size ) { + free_memblock ( ptr, size ); +} + +#endif /* _GPXE_MALLOC_H */ diff --git a/gpxe/src/include/gpxe/mca.h b/gpxe/src/include/gpxe/mca.h new file mode 100644 index 00000000..21f9e74d --- /dev/null +++ b/gpxe/src/include/gpxe/mca.h @@ -0,0 +1,103 @@ +/* + * MCA bus driver code + * + * Abstracted from 3c509.c. + * + */ + +#ifndef MCA_H +#define MCA_H + +#include <gpxe/isa_ids.h> +#include <gpxe/device.h> +#include <gpxe/tables.h> + +/* + * MCA constants + * + */ +#define MCA_MOTHERBOARD_SETUP_REG 0x94 +#define MCA_ADAPTER_SETUP_REG 0x96 +#define MCA_MAX_SLOT_NR 0x07 /* Must be 2^n - 1 */ +#define MCA_POS_REG(n) (0x100+(n)) + +/* Is there a standard that would define this? */ +#define GENERIC_MCA_VENDOR ISA_VENDOR ( 'M', 'C', 'A' ) + +/** An MCA device ID list entry */ +struct mca_device_id { + /** Name */ + const char *name; + /** Device ID */ + uint16_t id; +}; + +/** An MCA device */ +struct mca_device { + /** Generic device */ + struct device dev; + /** Slot number */ + unsigned int slot; + /** POS register values */ + unsigned char pos[8]; + /** Driver for this device */ + struct mca_driver *driver; + /** Driver-private data + * + * Use mca_set_drvdata() and mca_get_drvdata() to access + * this field. + */ + void *priv; + /** Driver name */ + const char *driver_name; +}; + +#define MCA_ID(mca) ( ( (mca)->pos[1] << 8 ) + (mca)->pos[0] ) + +/** An MCA driver */ +struct mca_driver { + /** MCA ID table */ + struct mca_device_id *ids; + /** Number of entries in MCA ID table */ + unsigned int id_count; + /** + * Probe device + * + * @v mca MCA device + * @v id Matching entry in ID table + * @ret rc Return status code + */ + int ( * probe ) ( struct mca_device *mca, + const struct mca_device_id *id ); + /** + * Remove device + * + * @v mca MCA device + */ + void ( * remove ) ( struct mca_device *mca ); +}; + +/** Declare an MCA driver */ +#define __mca_driver __table ( struct mca_driver, mca_drivers, 01 ) + +/** + * Set MCA driver-private data + * + * @v mca MCA device + * @v priv Private data + */ +static inline void mca_set_drvdata ( struct mca_device *mca, void *priv ) { + mca->priv = priv; +} + +/** + * Get MCA driver-private data + * + * @v mca MCA device + * @ret priv Private data + */ +static inline void * mca_get_drvdata ( struct mca_device *mca ) { + return mca->priv; +} + +#endif diff --git a/gpxe/src/include/gpxe/md5.h b/gpxe/src/include/gpxe/md5.h new file mode 100644 index 00000000..304a0e64 --- /dev/null +++ b/gpxe/src/include/gpxe/md5.h @@ -0,0 +1,22 @@ +#ifndef _GPXE_MD5_H +#define _GPXE_MD5_H + +struct crypto_algorithm; + +#include <stdint.h> + +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_WORDS 16 +#define MD5_HASH_WORDS 4 + +struct md5_ctx { + u32 hash[MD5_HASH_WORDS]; + u32 block[MD5_BLOCK_WORDS]; + u64 byte_count; +}; + +#define MD5_CTX_SIZE sizeof ( struct md5_ctx ) + +extern struct crypto_algorithm md5_algorithm; + +#endif /* _GPXE_MD5_H */ diff --git a/gpxe/src/include/gpxe/memmap.h b/gpxe/src/include/gpxe/memmap.h new file mode 100644 index 00000000..836a1b92 --- /dev/null +++ b/gpxe/src/include/gpxe/memmap.h @@ -0,0 +1,34 @@ +#ifndef _GPXE_MEMMAP_H +#define _GPXE_MEMMAP_H + +#include <stdint.h> + +/** + * @file + * + * Memory mapping + * + */ + +/** A usable memory region */ +struct memory_region { + /** Physical start address */ + uint64_t start; + /** Physical end address */ + uint64_t end; +}; + +/** Maximum number of memory regions we expect to encounter */ +#define MAX_MEMORY_REGIONS 8 + +/** A memory map */ +struct memory_map { + /** Memory regions */ + struct memory_region regions[MAX_MEMORY_REGIONS]; + /** Number of used regions */ + unsigned int count; +}; + +extern void get_memmap ( struct memory_map *memmap ); + +#endif /* _GPXE_MEMMAP_H */ diff --git a/gpxe/src/include/gpxe/monojob.h b/gpxe/src/include/gpxe/monojob.h new file mode 100644 index 00000000..aaa38d03 --- /dev/null +++ b/gpxe/src/include/gpxe/monojob.h @@ -0,0 +1,15 @@ +#ifndef _GPXE_MONOJOB_H +#define _GPXE_MONOJOB_H + +/** @file + * + * Single foreground job + * + */ + +struct job_interface; + +extern struct job_interface monojob; +extern int monojob_wait ( const char *string ); + +#endif /* _GPXE_MONOJOB_H */ diff --git a/gpxe/src/include/gpxe/ndp.h b/gpxe/src/include/gpxe/ndp.h new file mode 100644 index 00000000..db32b0c8 --- /dev/null +++ b/gpxe/src/include/gpxe/ndp.h @@ -0,0 +1,21 @@ +#include <stdint.h> +#include <byteswap.h> +#include <string.h> +#include <gpxe/icmp6.h> +#include <gpxe/ip6.h> +#include <gpxe/in.h> +#include <gpxe/netdevice.h> +#include <gpxe/iobuf.h> +#include <gpxe/tcpip.h> + +#define NDP_STATE_INVALID 0 +#define NDP_STATE_INCOMPLETE 1 +#define NDP_STATE_REACHABLE 2 +#define NDP_STATE_DELAY 3 +#define NDP_STATE_PROBE 4 +#define NDP_STATE_STALE 5 + +int ndp_resolve ( struct net_device *netdev, struct in6_addr *src, + struct in6_addr *dest, void *dest_ll_addr ); +int ndp_process_advert ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, + struct sockaddr_tcpip *st_dest ); diff --git a/gpxe/src/include/gpxe/netdevice.h b/gpxe/src/include/gpxe/netdevice.h new file mode 100644 index 00000000..d8cb84d0 --- /dev/null +++ b/gpxe/src/include/gpxe/netdevice.h @@ -0,0 +1,404 @@ +#ifndef _GPXE_NETDEVICE_H +#define _GPXE_NETDEVICE_H + +/** @file + * + * Network device management + * + */ + +#include <stdint.h> +#include <gpxe/list.h> +#include <gpxe/tables.h> +#include <gpxe/refcnt.h> +#include <gpxe/settings.h> + +struct io_buffer; +struct net_device; +struct net_protocol; +struct ll_protocol; +struct device; + +/** Maximum length of a link-layer address */ +#define MAX_LL_ADDR_LEN 20 + +/** Maximum length of a link-layer header */ +#define MAX_LL_HEADER_LEN 32 + +/** Maximum length of a network-layer address */ +#define MAX_NET_ADDR_LEN 4 + +/** + * A network-layer protocol + * + */ +struct net_protocol { + /** Protocol name */ + const char *name; + /** + * Process received packet + * + * @v iobuf I/O buffer + * @v netdev Network device + * @v ll_source Link-layer source address + * + * This method takes ownership of the I/O buffer. + */ + int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev, + const void *ll_source ); + /** + * Transcribe network-layer address + * + * @v net_addr Network-layer address + * @ret string Human-readable transcription of address + * + * This method should convert the network-layer address into a + * human-readable format (e.g. dotted quad notation for IPv4). + * + * The buffer used to hold the transcription is statically + * allocated. + */ + const char * ( *ntoa ) ( const void * net_addr ); + /** Network-layer protocol + * + * This is an ETH_P_XXX constant, in network-byte order + */ + uint16_t net_proto; + /** Network-layer address length */ + uint8_t net_addr_len; +}; + +/** + * A link-layer protocol + * + */ +struct ll_protocol { + /** Protocol name */ + const char *name; + /** + * Transmit network-layer packet via network device + * + * @v iobuf I/O buffer + * @v netdev Network device + * @v net_protocol Network-layer protocol + * @v ll_dest Link-layer destination address + * @ret rc Return status code + * + * This method should prepend in the link-layer header + * (e.g. the Ethernet DIX header) and transmit the packet. + * This method takes ownership of the I/O buffer. + */ + int ( * tx ) ( struct io_buffer *iobuf, struct net_device *netdev, + struct net_protocol *net_protocol, + const void *ll_dest ); + /** + * Handle received packet + * + * @v iobuf I/O buffer + * @v netdev Network device + * + * This method should strip off the link-layer header + * (e.g. the Ethernet DIX header) and pass the packet to + * net_rx(). This method takes ownership of the packet + * buffer. + */ + int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev ); + /** + * Transcribe link-layer address + * + * @v ll_addr Link-layer address + * @ret string Human-readable transcription of address + * + * This method should convert the link-layer address into a + * human-readable format. + * + * The buffer used to hold the transcription is statically + * allocated. + */ + const char * ( * ntoa ) ( const void * ll_addr ); + /** Link-layer protocol + * + * This is an ARPHRD_XXX constant, in network byte order. + */ + uint16_t ll_proto; + /** Link-layer address length */ + uint8_t ll_addr_len; + /** Link-layer header length */ + uint8_t ll_header_len; + /** Link-layer broadcast address */ + const uint8_t *ll_broadcast; +}; + +/** Network device operations */ +struct net_device_operations { + /** Open network device + * + * @v netdev Network device + * @ret rc Return status code + * + * This method should allocate RX I/O buffers and enable + * the hardware to start transmitting and receiving packets. + */ + int ( * open ) ( struct net_device *netdev ); + /** Close network device + * + * @v netdev Network device + * + * This method should stop the flow of packets, and free up + * any packets that are currently in the device's TX queue. + */ + void ( * close ) ( struct net_device *netdev ); + /** Transmit packet + * + * @v netdev Network device + * @v iobuf I/O buffer + * @ret rc Return status code + * + * This method should cause the hardware to initiate + * transmission of the I/O buffer. + * + * If this method returns success, the I/O buffer remains + * owned by the net device's TX queue, and the net device must + * eventually call netdev_tx_complete() to free the buffer. + * If this method returns failure, the I/O buffer is + * immediately released; the failure is interpreted as + * "failure to enqueue buffer". + * + * This method is guaranteed to be called only when the device + * is open. + */ + int ( * transmit ) ( struct net_device *netdev, + struct io_buffer *iobuf ); + /** Poll for completed and received packets + * + * @v netdev Network device + * + * This method should cause the hardware to check for + * completed transmissions and received packets. Any received + * packets should be delivered via netdev_rx(). + * + * This method is guaranteed to be called only when the device + * is open. + */ + void ( * poll ) ( struct net_device *netdev ); + /** Enable or disable interrupts + * + * @v netdev Network device + * @v enable Interrupts should be enabled + */ + void ( * irq ) ( struct net_device *netdev, int enable ); +}; + +/** Network device statistics */ +struct net_device_stats { + /** Count of successfully completed transmissions */ + unsigned int tx_ok; + /** Count of transmission errors */ + unsigned int tx_err; + /** Count of successfully received packets */ + unsigned int rx_ok; + /** Count of reception errors */ + unsigned int rx_err; +}; + +/** + * A network device + * + * This structure represents a piece of networking hardware. It has + * properties such as a link-layer address and methods for + * transmitting and receiving raw packets. + * + * Note that this structure must represent a generic network device, + * not just an Ethernet device. + */ +struct net_device { + /** Reference counter */ + struct refcnt refcnt; + /** List of network devices */ + struct list_head list; + /** Name of this network device */ + char name[8]; + /** Underlying hardware device */ + struct device *dev; + + /** Network device operations */ + struct net_device_operations *op; + + /** Link-layer protocol */ + struct ll_protocol *ll_protocol; + /** Link-layer address + * + * For Ethernet, this is the MAC address. + */ + uint8_t ll_addr[MAX_LL_ADDR_LEN]; + + /** Current device state + * + * This is the bitwise-OR of zero or more NETDEV_XXX constants. + */ + unsigned int state; + /** TX packet queue */ + struct list_head tx_queue; + /** RX packet queue */ + struct list_head rx_queue; + /** Device statistics */ + struct net_device_stats stats; + + /** Configuration settings applicable to this device */ + struct simple_settings settings; + + /** Driver private data */ + void *priv; +}; + +/** Network device is open */ +#define NETDEV_OPEN 0x0001 + +/** Declare a link-layer protocol */ +#define __ll_protocol __table ( struct ll_protocol, ll_protocols, 01 ) + +/** Declare a network-layer protocol */ +#define __net_protocol __table ( struct net_protocol, net_protocols, 01 ) + +extern struct list_head net_devices; +extern struct net_device_operations null_netdev_operations; + +/** + * Initialise a network device + * + * @v netdev Network device + * @v op Network device operations + */ +static inline void netdev_init ( struct net_device *netdev, + struct net_device_operations *op ) { + netdev->op = op; +} + +/** + * Stop using a network device + * + * @v netdev Network device + * + * Drivers should call this method immediately before the final call + * to netdev_put(). + */ +static inline void netdev_nullify ( struct net_device *netdev ) { + netdev->op = &null_netdev_operations; +} + +/** + * Get printable network device hardware address + * + * @v netdev Network device + * @ret name Hardware address + */ +static inline const char * netdev_hwaddr ( struct net_device *netdev ) { + return netdev->ll_protocol->ntoa ( netdev->ll_addr ); +} + +/** Iterate over all network devices */ +#define for_each_netdev( netdev ) \ + list_for_each_entry ( (netdev), &net_devices, list ) + +/** There exist some network devices + * + * @ret existence Existence of network devices + */ +static inline int have_netdevs ( void ) { + return ( ! list_empty ( &net_devices ) ); +} + +/** + * Get reference to network device + * + * @v netdev Network device + * @ret netdev Network device + */ +static inline __attribute__ (( always_inline )) struct net_device * +netdev_get ( struct net_device *netdev ) { + ref_get ( &netdev->refcnt ); + return netdev; +} + +/** + * Drop reference to network device + * + * @v netdev Network device + */ +static inline __attribute__ (( always_inline )) void +netdev_put ( struct net_device *netdev ) { + ref_put ( &netdev->refcnt ); +} + +/** + * Get driver private area for this network device + * + * @v netdev Network device + * @ret priv Driver private area for this network device + */ +static inline __attribute__ (( always_inline )) void * +netdev_priv ( struct net_device *netdev ) { + return netdev->priv; +} + +/** + * Get per-netdevice configuration settings block + * + * @v netdev Network device + * @ret settings Settings block + */ +static inline __attribute__ (( always_inline )) struct settings * +netdev_settings ( struct net_device *netdev ) { + return &netdev->settings.settings; +} + +extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ); +extern void netdev_tx_complete_err ( struct net_device *netdev, + struct io_buffer *iobuf, int rc ); +extern void netdev_tx_complete_next_err ( struct net_device *netdev, int rc ); +extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ); +extern void netdev_rx_err ( struct net_device *netdev, + struct io_buffer *iobuf, int rc ); +extern void netdev_poll ( struct net_device *netdev ); +extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ); +extern struct net_device * alloc_netdev ( size_t priv_size ); +extern int register_netdev ( struct net_device *netdev ); +extern int netdev_open ( struct net_device *netdev ); +extern void netdev_close ( struct net_device *netdev ); +extern void unregister_netdev ( struct net_device *netdev ); +extern void netdev_irq ( struct net_device *netdev, int enable ); +extern struct net_device * find_netdev ( const char *name ); +extern struct net_device * find_netdev_by_location ( unsigned int bus_type, + unsigned int location ); +extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev, + struct net_protocol *net_protocol, const void *ll_dest ); +extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev, + uint16_t net_proto, const void *ll_source ); + +extern struct settings_operations netdev_settings_operations; + +/** + * Complete network transmission + * + * @v netdev Network device + * @v iobuf I/O buffer + * + * The packet must currently be in the network device's TX queue. + */ +static inline void netdev_tx_complete ( struct net_device *netdev, + struct io_buffer *iobuf ) { + netdev_tx_complete_err ( netdev, iobuf, 0 ); +} + +/** + * Complete network transmission + * + * @v netdev Network device + * + * Completes the oldest outstanding packet in the TX queue. + */ +static inline void netdev_tx_complete_next ( struct net_device *netdev ) { + netdev_tx_complete_next_err ( netdev, 0 ); +} + +#endif /* _GPXE_NETDEVICE_H */ diff --git a/gpxe/src/include/gpxe/nvo.h b/gpxe/src/include/gpxe/nvo.h new file mode 100644 index 00000000..28068f4b --- /dev/null +++ b/gpxe/src/include/gpxe/nvo.h @@ -0,0 +1,53 @@ +#ifndef _GPXE_NVO_H +#define _GPXE_NVO_H + +/** @file + * + * Non-volatile stored options + * + */ + +#include <stdint.h> +#include <gpxe/dhcpopts.h> +#include <gpxe/settings.h> + +struct nvs_device; +struct refcnt; + +/** + * A fragment of a non-volatile storage device used for stored options + */ +struct nvo_fragment { + /** Starting address of fragment within NVS device */ + unsigned int address; + /** Length of fragment */ + size_t len; +}; + +/** + * A block of non-volatile stored options + */ +struct nvo_block { + /** Settings block */ + struct settings settings; + /** Underlying non-volatile storage device */ + struct nvs_device *nvs; + /** List of option-containing fragments + * + * The list is terminated by a fragment with a length of zero. + */ + struct nvo_fragment *fragments; + /** Total length of option-containing fragments */ + size_t total_len; + /** Option-containing data */ + void *data; + /** DHCP options block */ + struct dhcp_options dhcpopts; +}; + +extern void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs, + struct nvo_fragment *fragments, struct refcnt *refcnt ); +extern int register_nvo ( struct nvo_block *nvo, struct settings *parent ); +extern void unregister_nvo ( struct nvo_block *nvo ); + +#endif /* _GPXE_NVO_H */ diff --git a/gpxe/src/include/gpxe/nvs.h b/gpxe/src/include/gpxe/nvs.h new file mode 100644 index 00000000..b026dd46 --- /dev/null +++ b/gpxe/src/include/gpxe/nvs.h @@ -0,0 +1,66 @@ +#ifndef _GPXE_NVS_H +#define _GPXE_NVS_H + +/** @file + * + * Non-volatile storage + * + */ + +#include <stdint.h> + +/** A non-volatile storage device */ +struct nvs_device { + /** Word length + * + * This is expressed as the base-2 logarithm of the word + * length in bytes. A value of 0 therefore translates as + * 8-bit words, and a value of 1 translates as 16-bit words. + */ + unsigned int word_len_log2; + /** Device size (in words) */ + unsigned int size; + /** Data block size (in words) + * + * This is the block size used by the device. It must be a + * power of two. Data reads and writes must not cross a block + * boundary. + * + * Many devices allow reads to cross a block boundary, and + * restrict only writes. For the sake of simplicity, we + * assume that the same restriction applies to both reads and + * writes. + */ + unsigned int block_size; + /** Read data from device + * + * @v nvs NVS device + * @v address Address from which to read + * @v data Data buffer + * @v len Length of data buffer + * @ret rc Return status code + * + * Reads may not cross a block boundary. + */ + int ( * read ) ( struct nvs_device *nvs, unsigned int address, + void *data, size_t len ); + /** Write data to device + * + * @v nvs NVS device + * @v address Address to which to write + * @v data Data buffer + * @v len Length of data buffer + * @ret rc Return status code + * + * Writes may not cross a block boundary. + */ + int ( * write ) ( struct nvs_device *nvs, unsigned int address, + const void *data, size_t len ); +}; + +extern int nvs_read ( struct nvs_device *nvs, unsigned int address, + void *data, size_t len ); +extern int nvs_write ( struct nvs_device *nvs, unsigned int address, + const void *data, size_t len ); + +#endif /* _GPXE_NVS_H */ diff --git a/gpxe/src/include/gpxe/open.h b/gpxe/src/include/gpxe/open.h new file mode 100644 index 00000000..beab0a1f --- /dev/null +++ b/gpxe/src/include/gpxe/open.h @@ -0,0 +1,95 @@ +#ifndef _GPXE_OPEN_H +#define _GPXE_OPEN_H + +/** @file + * + * Data transfer interface opening + * + */ + +#include <stdarg.h> +#include <gpxe/tables.h> + +struct xfer_interface; +struct uri; +struct sockaddr; + +/** Location types */ +enum { + /** Location is a URI + * + * Parameter list for open() is: + * + * struct uri *uri; + */ + LOCATION_URI = 1, + /** Location is a URI string + * + * Parameter list for open() is: + * + * const char *uri_string; + */ + LOCATION_URI_STRING, + /** Location is a socket + * + * Parameter list for open() is: + * + * int semantics; + * struct sockaddr *peer; + * struct sockaddr *local; + */ + LOCATION_SOCKET, +}; + +/** A URI opener */ +struct uri_opener { + /** URI protocol name + * + * This is the "scheme" portion of the URI, e.g. "http" or + * "file". + */ + const char *scheme; + /** Open URI + * + * @v xfer Data transfer interface + * @v uri URI + * @ret rc Return status code + */ + int ( * open ) ( struct xfer_interface *xfer, struct uri *uri ); +}; + +/** Register a URI opener */ +#define __uri_opener __table ( struct uri_opener, uri_openers, 01 ) + +/** A socket opener */ +struct socket_opener { + /** Communication semantics (e.g. SOCK_STREAM) */ + int semantics; + /** Address family (e.g. AF_INET) */ + int family; + /** Open socket + * + * @v xfer Data transfer interface + * @v peer Peer socket address + * @v local Local socket address, or NULL + * @ret rc Return status code + */ + int ( * open ) ( struct xfer_interface *xfer, struct sockaddr *peer, + struct sockaddr *local ); +}; + +/** Register a socket opener */ +#define __socket_opener __table ( struct socket_opener, socket_openers, 01 ) + +extern int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ); +extern int xfer_open_uri_string ( struct xfer_interface *xfer, + const char *uri_string ); +extern int xfer_open_named_socket ( struct xfer_interface *xfer, + int semantics, struct sockaddr *peer, + const char *name, struct sockaddr *local ); +extern int xfer_open_socket ( struct xfer_interface *xfer, int semantics, + struct sockaddr *peer, struct sockaddr *local ); +extern int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ); +extern int xfer_open ( struct xfer_interface *xfer, int type, ... ); + +#endif /* _GPXE_OPEN_H */ diff --git a/gpxe/src/include/gpxe/pci.h b/gpxe/src/include/gpxe/pci.h new file mode 100644 index 00000000..b5c417c9 --- /dev/null +++ b/gpxe/src/include/gpxe/pci.h @@ -0,0 +1,356 @@ +#ifndef _GPXE_PCI_H +#define _GPXE_PCI_H + +/* + * Support for NE2000 PCI clones added David Monro June 1997 + * Generalised for other PCI NICs by Ken Yap July 1997 + * PCI support rewritten by Michael Brown 2006 + * + * Most of this is taken from /usr/src/linux/include/linux/pci.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, or (at + * your option) any later version. + */ + +#include <stdint.h> +#include <gpxe/device.h> +#include <gpxe/tables.h> +#include <pci_io.h> +#include "pci_ids.h" + +/* + * PCI constants + * + */ + +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ +#define PCI_COMMAND_MEM 0x2 /* Enable response in mem space */ +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_LATENCY_TIMER 0x0d /* 8 bits */ +#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ +#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ +#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ +#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ +#define PCI_COMMAND_SERR 0x100 /* Enable SERR */ +#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ + + +#define PCI_VENDOR_ID 0x00 /* 16 bits */ +#define PCI_DEVICE_ID 0x02 /* 16 bits */ +#define PCI_COMMAND 0x04 /* 16 bits */ + +#define PCI_STATUS 0x06 /* 16 bits */ +#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */ +#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ +#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */ +#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ +#define PCI_STATUS_PARITY 0x100 /* Detected parity error */ +#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */ +#define PCI_STATUS_DEVSEL_FAST 0x000 +#define PCI_STATUS_DEVSEL_MEDIUM 0x200 +#define PCI_STATUS_DEVSEL_SLOW 0x400 +#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */ +#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */ +#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */ +#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */ +#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */ + +#define PCI_REVISION 0x08 /* 8 bits */ +#define PCI_REVISION_ID 0x08 /* 8 bits */ +#define PCI_CLASS_REVISION 0x08 /* 32 bits */ +#define PCI_CLASS_CODE 0x0b /* 8 bits */ +#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */ +#define PCI_HEADER_TYPE 0x0e /* 8 bits */ +#define PCI_HEADER_TYPE_NORMAL 0 +#define PCI_HEADER_TYPE_BRIDGE 1 +#define PCI_HEADER_TYPE_CARDBUS 2 + + +/* Header type 0 (normal devices) */ +#define PCI_CARDBUS_CIS 0x28 +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c +#define PCI_SUBSYSTEM_ID 0x2e + +#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ +#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */ +#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */ +#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ +#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */ +#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */ + +#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */ +#define PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 + +#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */ +#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ +#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0f) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03) +#define PCI_ROM_ADDRESS 0x30 /* 32 bits */ +#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM, + bits 31..11 are address, + 10..2 are reserved */ + +#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */ + +#define PCI_INTERRUPT_LINE 0x3c /* IRQ number (0-15) */ +#define PCI_INTERRUPT_PIN 0x3d /* IRQ pin on PCI bus (A-D) */ + +/* Header type 1 (PCI-to-PCI bridges) */ +#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ +#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */ +#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */ +#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */ +#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */ +#define PCI_IO_RANGE_TYPE_16 0x00 +#define PCI_IO_RANGE_TYPE_32 0x01 +#define PCI_IO_RANGE_MASK ~0x0f +#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */ +#define PCI_MEMORY_BASE 0x20 /* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 +#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f +#define PCI_MEMORY_RANGE_MASK ~0x0f +#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ +#define PCI_PREF_MEMORY_LIMIT 0x26 +#define PCI_PREF_RANGE_TYPE_MASK 0x0f +#define PCI_PREF_RANGE_TYPE_32 0x00 +#define PCI_PREF_RANGE_TYPE_64 0x01 +#define PCI_PREF_RANGE_MASK ~0x0f +#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ +#define PCI_PREF_LIMIT_UPPER32 0x2c +#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ +#define PCI_IO_LIMIT_UPPER16 0x32 +/* 0x34 same as for htype 0 */ +/* 0x35-0x3b is reserved */ +#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */ +/* 0x3c-0x3d are same as for htype 0 */ +#define PCI_BRIDGE_CONTROL 0x3e +#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */ +#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */ +#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */ +#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */ +#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */ +#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */ +#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */ + +#define PCI_CB_CAPABILITY_LIST 0x14 + +/* Capability lists */ + +#define PCI_CAP_LIST_ID 0 /* Capability ID */ +#define PCI_CAP_ID_PM 0x01 /* Power Management */ +#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */ +#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */ +#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */ +#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ +#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ +#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ +#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ +#define PCI_CAP_SIZEOF 4 + +/* Power Management Registers */ + +#define PCI_PM_PMC 2 /* PM Capabilities Register */ +#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */ +#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */ +#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */ +#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */ +#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */ +#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */ +#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */ +#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */ +#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */ +#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */ +#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */ +#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */ +#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */ +#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */ +#define PCI_PM_CTRL 4 /* PM control and status register */ +#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ +#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */ +#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */ +#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */ +#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */ +#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */ +#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */ +#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */ +#define PCI_PM_DATA_REGISTER 7 /* (??) */ +#define PCI_PM_SIZEOF 8 + +/* AGP registers */ + +#define PCI_AGP_VERSION 2 /* BCD version number */ +#define PCI_AGP_RFU 3 /* Rest of capability flags */ +#define PCI_AGP_STATUS 4 /* Status register */ +#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */ +#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */ +#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */ +#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */ +#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */ +#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */ +#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */ +#define PCI_AGP_COMMAND 8 /* Control register */ +#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */ +#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */ +#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */ +#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */ +#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */ +#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */ +#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */ +#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */ +#define PCI_AGP_SIZEOF 12 + +/* Slot Identification */ + +#define PCI_SID_ESR 2 /* Expansion Slot Register */ +#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */ +#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */ +#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */ + +/* Message Signalled Interrupts registers */ + +#define PCI_MSI_FLAGS 2 /* Various flags */ +#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */ +#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */ +#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */ +#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */ +#define PCI_MSI_RFU 3 /* Rest of capability flags */ +#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */ +#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ +#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ +#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ + +/** A PCI device ID list entry */ +struct pci_device_id { + /** Name */ + const char *name; + /** PCI vendor ID */ + uint16_t vendor; + /** PCI device ID */ + uint16_t device; +}; + +/** Match-anything ID */ +#define PCI_ANY_ID 0xffff + +/** A PCI device */ +struct pci_device { + /** Generic device */ + struct device dev; + /** Memory base + * + * This is the physical address of the first valid memory BAR. + */ + unsigned long membase; + /** + * I/O address + * + * This is the physical address of the first valid I/O BAR. + */ + unsigned long ioaddr; + /** Vendor ID */ + uint16_t vendor; + /** Device ID */ + uint16_t device; + /** Device class */ + uint32_t class; + /** Interrupt number */ + uint8_t irq; + /** Bus number */ + uint8_t bus; + /** Device and function number */ + uint8_t devfn; + /** Driver for this device */ + struct pci_driver *driver; + /** Driver-private data + * + * Use pci_set_drvdata() and pci_get_drvdata() to access this + * field. + */ + void *priv; + /** Driver name */ + const char *driver_name; +}; + +/** A PCI driver */ +struct pci_driver { + /** PCI ID table */ + struct pci_device_id *ids; + /** Number of entries in PCI ID table */ + unsigned int id_count; + /** + * Probe device + * + * @v pci PCI device + * @v id Matching entry in ID table + * @ret rc Return status code + */ + int ( * probe ) ( struct pci_device *pci, + const struct pci_device_id *id ); + /** + * Remove device + * + * @v pci PCI device + */ + void ( * remove ) ( struct pci_device *pci ); +}; + +/** Declare a PCI driver */ +#define __pci_driver __table ( struct pci_driver, pci_drivers, 01 ) + +#define PCI_DEVFN( slot, func ) ( ( (slot) << 3 ) | (func) ) +#define PCI_SLOT( devfn ) ( ( (devfn) >> 3 ) & 0x1f ) +#define PCI_FUNC( devfn ) ( (devfn) & 0x07 ) +#define PCI_BUSDEVFN( bus, devfn ) ( ( (bus) << 8 ) | (devfn) ) + +#define PCI_BASE_CLASS( class ) ( (class) >> 16 ) +#define PCI_SUB_CLASS( class ) ( ( (class) >> 8 ) & 0xff ) +#define PCI_PROG_INTF( class ) ( (class) & 0xff ) + +/* + * PCI_ROM is used to build up entries in a struct pci_id array. It + * is also parsed by parserom.pl to generate Makefile rules and files + * for rom-o-matic. + */ +#define PCI_ROM( _vendor, _device, _name, _description ) { \ + .vendor = _vendor, \ + .device = _device, \ + .name = _name, \ +} + +extern void adjust_pci_device ( struct pci_device *pci ); +extern unsigned long pci_bar_start ( struct pci_device *pci, + unsigned int reg ); +extern int pci_find_capability ( struct pci_device *pci, int capability ); +extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ); + +/** + * Set PCI driver-private data + * + * @v pci PCI device + * @v priv Private data + */ +static inline void pci_set_drvdata ( struct pci_device *pci, void *priv ) { + pci->priv = priv; +} + +/** + * Get PCI driver-private data + * + * @v pci PCI device + * @ret priv Private data + */ +static inline void * pci_get_drvdata ( struct pci_device *pci ) { + return pci->priv; +} + +#endif /* _GPXE_PCI_H */ diff --git a/gpxe/src/include/gpxe/pci_ids.h b/gpxe/src/include/gpxe/pci_ids.h new file mode 100644 index 00000000..075ff96b --- /dev/null +++ b/gpxe/src/include/gpxe/pci_ids.h @@ -0,0 +1,348 @@ +#ifndef _GPXE_PCI_IDS_H +#define _GPXE_PCI_IDS_H + +/* + * PCI Class, Vendor and Device IDs + * + * Please keep sorted. + */ + +/* Device classes and subclasses */ + +#define PCI_CLASS_NOT_DEFINED 0x0000 +#define PCI_CLASS_NOT_DEFINED_VGA 0x0001 + +#define PCI_BASE_CLASS_STORAGE 0x01 +#define PCI_CLASS_STORAGE_SCSI 0x0100 +#define PCI_CLASS_STORAGE_IDE 0x0101 +#define PCI_CLASS_STORAGE_FLOPPY 0x0102 +#define PCI_CLASS_STORAGE_IPI 0x0103 +#define PCI_CLASS_STORAGE_RAID 0x0104 +#define PCI_CLASS_STORAGE_OTHER 0x0180 + +#define PCI_BASE_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x0200 +#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201 +#define PCI_CLASS_NETWORK_FDDI 0x0202 +#define PCI_CLASS_NETWORK_ATM 0x0203 +#define PCI_CLASS_NETWORK_OTHER 0x0280 + +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_VGA 0x0300 +#define PCI_CLASS_DISPLAY_XGA 0x0301 +#define PCI_CLASS_DISPLAY_3D 0x0302 +#define PCI_CLASS_DISPLAY_OTHER 0x0380 + +#define PCI_BASE_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400 +#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 +#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402 +#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 + +#define PCI_BASE_CLASS_MEMORY 0x05 +#define PCI_CLASS_MEMORY_RAM 0x0500 +#define PCI_CLASS_MEMORY_FLASH 0x0501 +#define PCI_CLASS_MEMORY_OTHER 0x0580 + +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_HOST 0x0600 +#define PCI_CLASS_BRIDGE_ISA 0x0601 +#define PCI_CLASS_BRIDGE_EISA 0x0602 +#define PCI_CLASS_BRIDGE_MC 0x0603 +#define PCI_CLASS_BRIDGE_PCI 0x0604 +#define PCI_CLASS_BRIDGE_PCMCIA 0x0605 +#define PCI_CLASS_BRIDGE_NUBUS 0x0606 +#define PCI_CLASS_BRIDGE_CARDBUS 0x0607 +#define PCI_CLASS_BRIDGE_RACEWAY 0x0608 +#define PCI_CLASS_BRIDGE_OTHER 0x0680 + +#define PCI_BASE_CLASS_COMMUNICATION 0x07 +#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701 +#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702 +#define PCI_CLASS_COMMUNICATION_MODEM 0x0703 +#define PCI_CLASS_COMMUNICATION_OTHER 0x0780 + +#define PCI_BASE_CLASS_SYSTEM 0x08 +#define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_DMA 0x0801 +#define PCI_CLASS_SYSTEM_TIMER 0x0802 +#define PCI_CLASS_SYSTEM_RTC 0x0803 +#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804 +#define PCI_CLASS_SYSTEM_OTHER 0x0880 + +#define PCI_BASE_CLASS_INPUT 0x09 +#define PCI_CLASS_INPUT_KEYBOARD 0x0900 +#define PCI_CLASS_INPUT_PEN 0x0901 +#define PCI_CLASS_INPUT_MOUSE 0x0902 +#define PCI_CLASS_INPUT_SCANNER 0x0903 +#define PCI_CLASS_INPUT_GAMEPORT 0x0904 +#define PCI_CLASS_INPUT_OTHER 0x0980 + +#define PCI_BASE_CLASS_DOCKING 0x0a +#define PCI_CLASS_DOCKING_GENERIC 0x0a00 +#define PCI_CLASS_DOCKING_OTHER 0x0a80 + +#define PCI_BASE_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_PROCESSOR_386 0x0b00 +#define PCI_CLASS_PROCESSOR_486 0x0b01 +#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02 +#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20 +#define PCI_CLASS_PROCESSOR_MIPS 0x0b30 +#define PCI_CLASS_PROCESSOR_CO 0x0b40 + +#define PCI_BASE_CLASS_SERIAL 0x0c +#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00 +#define PCI_CLASS_SERIAL_ACCESS 0x0c01 +#define PCI_CLASS_SERIAL_SSA 0x0c02 +#define PCI_CLASS_SERIAL_USB 0x0c03 +#define PCI_CLASS_SERIAL_FIBER 0x0c04 +#define PCI_CLASS_SERIAL_SMBUS 0x0c05 + +#define PCI_BASE_CLASS_INTELLIGENT 0x0e +#define PCI_CLASS_INTELLIGENT_I2O 0x0e00 + +#define PCI_BASE_CLASS_SATELLITE 0x0f +#define PCI_CLASS_SATELLITE_TV 0x0f00 +#define PCI_CLASS_SATELLITE_AUDIO 0x0f01 +#define PCI_CLASS_SATELLITE_VOICE 0x0f03 +#define PCI_CLASS_SATELLITE_DATA 0x0f04 + +#define PCI_BASE_CLASS_CRYPT 0x10 +#define PCI_CLASS_CRYPT_NETWORK 0x1000 +#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001 +#define PCI_CLASS_CRYPT_OTHER 0x1080 + +#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11 +#define PCI_CLASS_SP_DPIO 0x1100 +#define PCI_CLASS_SP_OTHER 0x1180 + +#define PCI_CLASS_OTHERS 0xff + +/* Vendors */ + +#define PCI_VENDOR_ID_DYNALINK 0x0675 +#define PCI_VENDOR_ID_BERKOM 0x0871 +#define PCI_VENDOR_ID_COMPAQ 0x0e11 +#define PCI_VENDOR_ID_NCR 0x1000 +#define PCI_VENDOR_ID_LSI_LOGIC 0x1000 +#define PCI_VENDOR_ID_ATI 0x1002 +#define PCI_VENDOR_ID_VLSI 0x1004 +#define PCI_VENDOR_ID_ADL 0x1005 +#define PCI_VENDOR_ID_NS 0x100b +#define PCI_VENDOR_ID_TSENG 0x100c +#define PCI_VENDOR_ID_WEITEK 0x100e +#define PCI_VENDOR_ID_DEC 0x1011 +#define PCI_VENDOR_ID_CIRRUS 0x1013 +#define PCI_VENDOR_ID_IBM 0x1014 +#define PCI_VENDOR_ID_COMPEX2 0x101a +/* pci.ids says "AT&T GIS (NCR)" */ +#define PCI_VENDOR_ID_WD 0x101c +#define PCI_VENDOR_ID_AMI 0x101e +#define PCI_VENDOR_ID_AMD 0x1022 +#define PCI_VENDOR_ID_TRIDENT 0x1023 +#define PCI_VENDOR_ID_AI 0x1025 +#define PCI_VENDOR_ID_DELL 0x1028 +#define PCI_VENDOR_ID_MATROX 0x102B +#define PCI_VENDOR_ID_CT 0x102c +#define PCI_VENDOR_ID_MIRO 0x1031 +#define PCI_VENDOR_ID_NEC 0x1033 +#define PCI_VENDOR_ID_FD 0x1036 +#define PCI_VENDOR_ID_SIS 0x1039 +#define PCI_VENDOR_ID_SI 0x1039 +#define PCI_VENDOR_ID_HP 0x103c +#define PCI_VENDOR_ID_PCTECH 0x1042 +#define PCI_VENDOR_ID_ASUSTEK 0x1043 +#define PCI_VENDOR_ID_DPT 0x1044 +#define PCI_VENDOR_ID_OPTI 0x1045 +#define PCI_VENDOR_ID_ELSA 0x1048 +#define PCI_VENDOR_ID_ELSA 0x1048 +#define PCI_VENDOR_ID_SGS 0x104a +#define PCI_VENDOR_ID_BUSLOGIC 0x104B +#define PCI_VENDOR_ID_TI 0x104c +#define PCI_VENDOR_ID_SONY 0x104d +#define PCI_VENDOR_ID_OAK 0x104e +/* Winbond have two vendor IDs! See 0x10ad as well */ +#define PCI_VENDOR_ID_WINBOND2 0x1050 +#define PCI_VENDOR_ID_ANIGMA 0x1051 +#define PCI_VENDOR_ID_EFAR 0x1055 +#define PCI_VENDOR_ID_MOTOROLA 0x1057 +#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507 +#define PCI_VENDOR_ID_PROMISE 0x105a +#define PCI_VENDOR_ID_N9 0x105d +#define PCI_VENDOR_ID_UMC 0x1060 +#define PCI_VENDOR_ID_X 0x1061 +#define PCI_VENDOR_ID_MYLEX 0x1069 +#define PCI_VENDOR_ID_PICOP 0x1066 +#define PCI_VENDOR_ID_APPLE 0x106b +#define PCI_VENDOR_ID_YAMAHA 0x1073 +#define PCI_VENDOR_ID_NEXGEN 0x1074 +#define PCI_VENDOR_ID_QLOGIC 0x1077 +#define PCI_VENDOR_ID_CYRIX 0x1078 +#define PCI_VENDOR_ID_LEADTEK 0x107d +#define PCI_VENDOR_ID_INTERPHASE 0x107e +#define PCI_VENDOR_ID_CONTAQ 0x1080 +#define PCI_VENDOR_ID_FOREX 0x1083 +#define PCI_VENDOR_ID_OLICOM 0x108d +#define PCI_VENDOR_ID_SUN 0x108e +#define PCI_VENDOR_ID_CMD 0x1095 +#define PCI_VENDOR_ID_VISION 0x1098 +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#define PCI_VENDOR_ID_SIERRA 0x10a8 +#define PCI_VENDOR_ID_SGI 0x10a9 +#define PCI_VENDOR_ID_ACC 0x10aa +#define PCI_VENDOR_ID_WINBOND 0x10ad +#define PCI_VENDOR_ID_DATABOOK 0x10b3 +#define PCI_VENDOR_ID_PLX 0x10b5 +#define PCI_VENDOR_ID_MADGE 0x10b6 +#define PCI_VENDOR_ID_3COM 0x10b7 +#define PCI_VENDOR_ID_SMC 0x10b8 +#define PCI_VENDOR_ID_SUNDANCE 0x13F0 +#define PCI_VENDOR_ID_AL 0x10b9 +#define PCI_VENDOR_ID_MITSUBISHI 0x10ba +#define PCI_VENDOR_ID_SURECOM 0x10bd +#define PCI_VENDOR_ID_NEOMAGIC 0x10c8 +#define PCI_VENDOR_ID_ASP 0x10cd +#define PCI_VENDOR_ID_MACRONIX 0x10d9 +#define PCI_VENDOR_ID_TCONRAD 0x10da +#define PCI_VENDOR_ID_CERN 0x10dc +#define PCI_VENDOR_ID_NVIDIA 0x10de +#define PCI_VENDOR_ID_IMS 0x10e0 +#define PCI_VENDOR_ID_TEKRAM2 0x10e1 +#define PCI_VENDOR_ID_TUNDRA 0x10e3 +#define PCI_VENDOR_ID_AMCC 0x10e8 +#define PCI_VENDOR_ID_INTERG 0x10ea +#define PCI_VENDOR_ID_REALTEK 0x10ec +#define PCI_VENDOR_ID_XILINX 0x10ee +#define PCI_VENDOR_ID_TRUEVISION 0x10fa +#define PCI_VENDOR_ID_INIT 0x1101 +#define PCI_VENDOR_ID_CREATIVE 0x1102 +/* duplicate: ECTIVA */ +#define PCI_VENDOR_ID_ECTIVA 0x1102 +/* duplicate: CREATIVE */ +#define PCI_VENDOR_ID_TTI 0x1103 +#define PCI_VENDOR_ID_VIA 0x1106 +#define PCI_VENDOR_ID_VIATEC 0x1106 +#define PCI_VENDOR_ID_SIEMENS 0x110A +#define PCI_VENDOR_ID_SMC2 0x1113 +#define PCI_VENDOR_ID_VORTEX 0x1119 +#define PCI_VENDOR_ID_EF 0x111a +#define PCI_VENDOR_ID_IDT 0x111d +#define PCI_VENDOR_ID_FORE 0x1127 +#define PCI_VENDOR_ID_IMAGINGTECH 0x112f +#define PCI_VENDOR_ID_PHILIPS 0x1131 +#define PCI_VENDOR_ID_EICON 0x1133 +#define PCI_VENDOR_ID_CYCLONE 0x113c +#define PCI_VENDOR_ID_ALLIANCE 0x1142 +#define PCI_VENDOR_ID_SYSKONNECT 0x1148 +#define PCI_VENDOR_ID_VMIC 0x114a +#define PCI_VENDOR_ID_DIGI 0x114f +#define PCI_VENDOR_ID_MUTECH 0x1159 +#define PCI_VENDOR_ID_XIRCOM 0x115d +#define PCI_VENDOR_ID_RENDITION 0x1163 +#define PCI_VENDOR_ID_SERVERWORKS 0x1166 +#define PCI_VENDOR_ID_SBE 0x1176 +#define PCI_VENDOR_ID_TOSHIBA 0x1179 +#define PCI_VENDOR_ID_RICOH 0x1180 +#define PCI_VENDOR_ID_DLINK 0x1186 +#define PCI_VENDOR_ID_ARTOP 0x1191 +#define PCI_VENDOR_ID_ZEITNET 0x1193 +#define PCI_VENDOR_ID_OMEGA 0x119b +#define PCI_VENDOR_ID_FUJITSU_ME 0x119e +#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9 +#define PCI_VENDOR_ID_GALILEO 0x11ab +#define PCI_VENDOR_ID_LINKSYS 0x11ad +#define PCI_VENDOR_ID_LITEON 0x11ad +#define PCI_VENDOR_ID_V3 0x11b0 +#define PCI_VENDOR_ID_NP 0x11bc +#define PCI_VENDOR_ID_ATT 0x11c1 +#define PCI_VENDOR_ID_SPECIALIX 0x11cb +#define PCI_VENDOR_ID_AURAVISION 0x11d1 +#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4 +#define PCI_VENDOR_ID_IKON 0x11d5 +#define PCI_VENDOR_ID_ZORAN 0x11de +#define PCI_VENDOR_ID_KINETIC 0x11f4 +#define PCI_VENDOR_ID_COMPEX 0x11f6 +#define PCI_VENDOR_ID_RP 0x11fe +#define PCI_VENDOR_ID_CYCLADES 0x120e +#define PCI_VENDOR_ID_ESSENTIAL 0x120f +#define PCI_VENDOR_ID_O2 0x1217 +#define PCI_VENDOR_ID_3DFX 0x121a +#define PCI_VENDOR_ID_SIGMADES 0x1236 +#define PCI_VENDOR_ID_CCUBE 0x123f +#define PCI_VENDOR_ID_AVM 0x1244 +#define PCI_VENDOR_ID_DIPIX 0x1246 +#define PCI_VENDOR_ID_STALLION 0x124d +#define PCI_VENDOR_ID_OPTIBASE 0x1255 +#define PCI_VENDOR_ID_ESS 0x125d +#define PCI_VENDOR_ID_HARRIS 0x1260 +#define PCI_VENDOR_ID_SATSAGEM 0x1267 +#define PCI_VENDOR_ID_HUGHES 0x1273 +#define PCI_VENDOR_ID_ENSONIQ 0x1274 +#define PCI_VENDOR_ID_ROCKWELL 0x127A +#define PCI_VENDOR_ID_DAVICOM 0x1282 +#define PCI_VENDOR_ID_ITE 0x1283 +/* formerly Platform Tech */ +#define PCI_VENDOR_ID_ESS_OLD 0x1285 +#define PCI_VENDOR_ID_ALTEON 0x12ae +#define PCI_VENDOR_ID_USR 0x12B9 +#define PCI_VENDOR_ID_HOLTEK 0x12c3 +#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4 +#define PCI_VENDOR_ID_PICTUREL 0x12c5 +#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 +#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0 +#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D +#define PCI_VENDOR_ID_AUREAL 0x12eb +#define PCI_VENDOR_ID_CBOARDS 0x1307 +#define PCI_VENDOR_ID_SIIG 0x131f +#define PCI_VENDOR_ID_ADMTEK 0x1317 +#define PCI_VENDOR_ID_DOMEX 0x134a +#define PCI_VENDOR_ID_QUATECH 0x135C +#define PCI_VENDOR_ID_SEALEVEL 0x135e +#define PCI_VENDOR_ID_HYPERCOPE 0x1365 +#define PCI_VENDOR_ID_KAWASAKI 0x136b +#define PCI_VENDOR_ID_LMC 0x1376 +#define PCI_VENDOR_ID_NETGEAR 0x1385 +#define PCI_VENDOR_ID_APPLICOM 0x1389 +#define PCI_VENDOR_ID_MOXA 0x1393 +#define PCI_VENDOR_ID_CCD 0x1397 +#define PCI_VENDOR_ID_MICROGATE 0x13c0 +#define PCI_VENDOR_ID_3WARE 0x13C1 +#define PCI_VENDOR_ID_ABOCOM 0x13D1 +#define PCI_VENDOR_ID_CMEDIA 0x13f6 +#define PCI_VENDOR_ID_LAVA 0x1407 +#define PCI_VENDOR_ID_TIMEDIA 0x1409 +#define PCI_VENDOR_ID_OXSEMI 0x1415 +#define PCI_VENDOR_ID_AIRONET 0x14b9 +#define PCI_VENDOR_ID_TITAN 0x14D2 +#define PCI_VENDOR_ID_PANACOM 0x14d4 +#define PCI_VENDOR_ID_BROADCOM 0x14e4 +#define PCI_VENDOR_ID_SYBA 0x1592 +#define PCI_VENDOR_ID_MORETON 0x15aa +#define PCI_VENDOR_ID_ZOLTRIX 0x15b0 +#define PCI_VENDOR_ID_PDC 0x15e9 +#define PCI_VENDOR_ID_FSC 0x1734 +#define PCI_VENDOR_ID_SYMPHONY 0x1c1c +#define PCI_VENDOR_ID_TEKRAM 0x1de1 +#define PCI_VENDOR_ID_3DLABS 0x3d3d +#define PCI_VENDOR_ID_AVANCE 0x4005 +#define PCI_VENDOR_ID_AKS 0x416c +#define PCI_VENDOR_ID_NETVIN 0x4a14 +#define PCI_VENDOR_ID_S3 0x5333 +#define PCI_VENDOR_ID_DCI 0x6666 +#define PCI_VENDOR_ID_GENROCO 0x5555 +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_VENDOR_ID_COMPUTONE 0x8e0e +#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e +#define PCI_VENDOR_ID_KTI 0x8e2e +#define PCI_VENDOR_ID_ADAPTEC 0x9004 +#define PCI_VENDOR_ID_ADAPTEC2 0x9005 +#define PCI_VENDOR_ID_ATRONICS 0x907f +#define PCI_VENDOR_ID_HOLTEK2 0x9412 +#define PCI_VENDOR_ID_NETMOS 0x9710 +#define PCI_SUBVENDOR_ID_EXSYS 0xd84d +#define PCI_VENDOR_ID_TIGERJET 0xe159 +#define PCI_VENDOR_ID_ARK 0xedd8 + +#endif /* _GPXE_PCI_IDS_H */ diff --git a/gpxe/src/include/gpxe/posix_io.h b/gpxe/src/include/gpxe/posix_io.h new file mode 100644 index 00000000..9984db00 --- /dev/null +++ b/gpxe/src/include/gpxe/posix_io.h @@ -0,0 +1,85 @@ +#ifndef _GPXE_POSIX_IO_H +#define _GPXE_POSIX_IO_H + +/** @file + * + * POSIX-like I/O + * + */ + +#include <stdint.h> +#include <gpxe/uaccess.h> + +/** Minimum file descriptor that will ever be allocated */ +#define POSIX_FD_MIN ( 1 ) + +/** Maximum file descriptor that will ever be allocated */ +#define POSIX_FD_MAX ( 31 ) + +/** File descriptor set as used for select() */ +typedef uint32_t fd_set; + +extern int open ( const char *uri_string ); +extern ssize_t read_user ( int fd, userptr_t buffer, + off_t offset, size_t len ); +extern int select ( fd_set *readfds, int wait ); +extern ssize_t fsize ( int fd ); +extern int close ( int fd ); + +/** + * Zero a file descriptor set + * + * @v set File descriptor set + */ +static inline __attribute__ (( always_inline )) void +FD_ZERO ( fd_set *set ) { + *set = 0; +} + +/** + * Set a bit within a file descriptor set + * + * @v fd File descriptor + * @v set File descriptor set + */ +static inline __attribute__ (( always_inline )) void +FD_SET ( int fd, fd_set *set ) { + *set |= ( 1 << fd ); +} + +/** + * Clear a bit within a file descriptor set + * + * @v fd File descriptor + * @v set File descriptor set + */ +static inline __attribute__ (( always_inline )) void +FD_CLR ( int fd, fd_set *set ) { + *set &= ~( 1 << fd ); +} + +/** + * Test a bit within a file descriptor set + * + * @v fd File descriptor + * @v set File descriptor set + * @ret is_set Corresponding bit is set + */ +static inline __attribute__ (( always_inline )) int +FD_ISSET ( int fd, fd_set *set ) { + return ( *set & ( 1 << fd ) ); +} + +/** + * Read data from file + * + * @v fd File descriptor + * @v buf Data buffer + * @v len Maximum length to read + * @ret len Actual length read, or negative error number + */ +static inline ssize_t read ( int fd, void *buf, size_t len ) { + return read_user ( fd, virt_to_user ( buf ), 0, len ); +} + +#endif /* _GPXE_POSIX_IO_H */ diff --git a/gpxe/src/include/gpxe/process.h b/gpxe/src/include/gpxe/process.h new file mode 100644 index 00000000..8d9b109a --- /dev/null +++ b/gpxe/src/include/gpxe/process.h @@ -0,0 +1,75 @@ +#ifndef _GPXE_PROCESS_H +#define _GPXE_PROCESS_H + +/** @file + * + * Processes + * + */ + +#include <gpxe/list.h> +#include <gpxe/refcnt.h> +#include <gpxe/tables.h> + +/** A process */ +struct process { + /** List of processes */ + struct list_head list; + /** + * Single-step the process + * + * This method should execute a single step of the process. + * Returning from this method is isomorphic to yielding the + * CPU to another process. + */ + void ( * step ) ( struct process *process ); + /** Reference counter + * + * If this interface is not part of a reference-counted + * object, this field may be NULL. + */ + struct refcnt *refcnt; +}; + +extern void process_add ( struct process *process ); +extern void process_del ( struct process *process ); +extern void step ( void ); + +/** + * Initialise process without adding to process list + * + * @v process Process + * @v step Process' step() method + */ +static inline __attribute__ (( always_inline )) void +process_init_stopped ( struct process *process, + void ( * step ) ( struct process *process ), + struct refcnt *refcnt ) { + process->step = step; + process->refcnt = refcnt; +} + +/** + * Initialise process and add to process list + * + * @v process Process + * @v step Process' step() method + */ +static inline __attribute__ (( always_inline )) void +process_init ( struct process *process, + void ( * step ) ( struct process *process ), + struct refcnt *refcnt ) { + process_init_stopped ( process, step, refcnt ); + process_add ( process ); +} + +/** + * Declare a permanent process + * + * Permanent processes will be automatically added to the process list + * at initialisation time. + */ +#define __permanent_process \ + __table ( struct process, processes, 01 ) + +#endif /* _GPXE_PROCESS_H */ diff --git a/gpxe/src/include/gpxe/profile.h b/gpxe/src/include/gpxe/profile.h new file mode 100644 index 00000000..d46ca05a --- /dev/null +++ b/gpxe/src/include/gpxe/profile.h @@ -0,0 +1,78 @@ +#ifndef _GPXE_PROFILE_H +#define _GPXE_PROFILE_H + +/** @file + * + * Profiling + * + */ + +#include <stdint.h> + +/** + * A data structure for storing profiling information + */ +union profiler { + /** Timestamp (in CPU-specific "ticks") */ + uint64_t timestamp; + /** Registers returned by rdtsc. + * + * This part should really be architecture-specific code. + */ + struct { + uint32_t eax; + uint32_t edx; + } rdtsc; +}; + +/** + * Static per-object profiler, for use with simple_profile() + */ +static union profiler simple_profiler; + +/** + * Perform profiling + * + * @v profiler Profiler data structure + * @ret delta Elapsed ticks since last call to profile(). + * + * Call profile() both before and after the code you wish to measure. + * The "after" call will return the measurement. For example: + * + * @code + * + * profile ( &profiler ); + * ... do something here ... + * printf ( "It took %ld ticks to execute\n", profile ( &profiler ) ); + * + * @endcode + */ +static inline __attribute__ (( always_inline )) unsigned long +profile ( union profiler *profiler ) { + uint64_t last_timestamp = profiler->timestamp; + + __asm__ __volatile__ ( "rdtsc" : + "=a" ( profiler->rdtsc.eax ), + "=d" ( profiler->rdtsc.edx ) ); + return ( profiler->timestamp - last_timestamp ); +} + +/** + * Perform profiling + * + * @ret delta Elapsed ticks since last call to profile(). + * + * When you only need one profiler, you can avoid the hassle of + * creating your own @c profiler data structure by using + * simple_profile() instead. + * + * simple_profile() is equivalent to profile(&simple_profiler), where + * @c simple_profiler is a @c profiler data structure that is static + * to each object which includes @c profile.h. + */ +static inline __attribute__ (( always_inline )) unsigned long +simple_profile ( void ) { + return profile ( &simple_profiler ); +} + +#endif /* _GPXE_PROFILE_H */ diff --git a/gpxe/src/include/gpxe/ramdisk.h b/gpxe/src/include/gpxe/ramdisk.h new file mode 100644 index 00000000..4a77f05e --- /dev/null +++ b/gpxe/src/include/gpxe/ramdisk.h @@ -0,0 +1,22 @@ +#ifndef _GPXE_RAMDISK_H +#define _GPXE_RAMDISK_H + +/** + * @file + * + * RAM disks + * + */ + +#include <gpxe/uaccess.h> +#include <gpxe/blockdev.h> + +struct ramdisk { + struct block_device blockdev; + userptr_t data; +}; + +extern int init_ramdisk ( struct ramdisk *ramdisk, userptr_t data, size_t len, + unsigned int blksize ); + +#endif /* _GPXE_RAMDISK_H */ diff --git a/gpxe/src/include/gpxe/rarp.h b/gpxe/src/include/gpxe/rarp.h new file mode 100644 index 00000000..81e03bde --- /dev/null +++ b/gpxe/src/include/gpxe/rarp.h @@ -0,0 +1,14 @@ +#ifndef _GPXE_RARP_H +#define _GPXE_RARP_H + +/** @file + * + * Reverse Address Resolution Protocol + * + */ + +struct net_protocol; + +extern struct net_protocol rarp_protocol; + +#endif /* _GPXE_RARP_H */ diff --git a/gpxe/src/include/gpxe/refcnt.h b/gpxe/src/include/gpxe/refcnt.h new file mode 100644 index 00000000..68e0fd4b --- /dev/null +++ b/gpxe/src/include/gpxe/refcnt.h @@ -0,0 +1,44 @@ +#ifndef _GPXE_REFCNT_H +#define _GPXE_REFCNT_H + +/** @file + * + * Reference counting + * + */ + +/** + * A reference counter + * + * This data structure is designed to be embedded within a + * reference-counted object. + * + * Reference-counted objects are freed when their reference count + * drops below zero. This means that a freshly allocated-and-zeroed + * reference-counted object will be freed on the first call to + * ref_put(). + */ +struct refcnt { + /** Current reference count + * + * When this count is decremented below zero, the free() + * method will be called. + */ + int refcnt; + /** Free containing object + * + * This method is called when the reference count is + * decremented below zero. + * + * If this method is left NULL, the standard library free() + * function will be called. The upshot of this is that you + * may omit the free() method if the @c refcnt object is the + * first element of your reference-counted struct. + */ + void ( * free ) ( struct refcnt *refcnt ); +}; + +extern struct refcnt * ref_get ( struct refcnt *refcnt ); +extern void ref_put ( struct refcnt *refcnt ); + +#endif /* _GPXE_REFCNT_H */ diff --git a/gpxe/src/include/gpxe/resolv.h b/gpxe/src/include/gpxe/resolv.h new file mode 100644 index 00000000..7c1ee6e2 --- /dev/null +++ b/gpxe/src/include/gpxe/resolv.h @@ -0,0 +1,166 @@ +#ifndef _GPXE_RESOLV_H +#define _GPXE_RESOLV_H + +/** @file + * + * Name resolution + * + */ + +#include <gpxe/refcnt.h> +#include <gpxe/interface.h> +#include <gpxe/tables.h> + +struct sockaddr; +struct resolv_interface; + +/** Name resolution interface operations */ +struct resolv_interface_operations { + /** Name resolution completed + * + * @v resolv Name resolution interface + * @v sa Completed socket address (if successful) + * @v rc Final status code + */ + void ( * done ) ( struct resolv_interface *resolv, + struct sockaddr *sa, int rc ); +}; + +/** A name resolution interface */ +struct resolv_interface { + /** Generic object communication interface */ + struct interface intf; + /** Operations for received messages */ + struct resolv_interface_operations *op; +}; + +extern struct resolv_interface null_resolv; +extern struct resolv_interface_operations null_resolv_ops; + +/** + * Initialise a name resolution interface + * + * @v resolv Name resolution interface + * @v op Name resolution interface operations + * @v refcnt Containing object reference counter, or NULL + */ +static inline void resolv_init ( struct resolv_interface *resolv, + struct resolv_interface_operations *op, + struct refcnt *refcnt ) { + resolv->intf.dest = &null_resolv.intf; + resolv->intf.refcnt = refcnt; + resolv->op = op; +} + +/** + * Get name resolution interface from generic object communication interface + * + * @v intf Generic object communication interface + * @ret resolv Name resolution interface + */ +static inline __attribute__ (( always_inline )) struct resolv_interface * +intf_to_resolv ( struct interface *intf ) { + return container_of ( intf, struct resolv_interface, intf ); +} + +/** + * Get reference to destination name resolution interface + * + * @v resolv Name resolution interface + * @ret dest Destination interface + */ +static inline __attribute__ (( always_inline )) struct resolv_interface * +resolv_get_dest ( struct resolv_interface *resolv ) { + return intf_to_resolv ( intf_get ( resolv->intf.dest ) ); +} + +/** + * Drop reference to name resolution interface + * + * @v resolv name resolution interface + */ +static inline __attribute__ (( always_inline )) void +resolv_put ( struct resolv_interface *resolv ) { + intf_put ( &resolv->intf ); +} + +/** + * Plug a name resolution interface into a new destination interface + * + * @v resolv Name resolution interface + * @v dest New destination interface + */ +static inline __attribute__ (( always_inline )) void +resolv_plug ( struct resolv_interface *resolv, struct resolv_interface *dest ) { + plug ( &resolv->intf, &dest->intf ); +} + +/** + * Plug two name resolution interfaces together + * + * @v a Name resolution interface A + * @v b Name resolution interface B + */ +static inline __attribute__ (( always_inline )) void +resolv_plug_plug ( struct resolv_interface *a, struct resolv_interface *b ) { + plug_plug ( &a->intf, &b->intf ); +} + +/** + * Unplug a name resolution interface + * + * @v resolv Name resolution interface + */ +static inline __attribute__ (( always_inline )) void +resolv_unplug ( struct resolv_interface *resolv ) { + plug ( &resolv->intf, &null_resolv.intf ); +} + +/** + * Stop using a name resolution interface + * + * @v resolv Name resolution interface + * + * After calling this method, no further messages will be received via + * the interface. + */ +static inline void resolv_nullify ( struct resolv_interface *resolv ) { + resolv->op = &null_resolv_ops; +}; + +/** A name resolver */ +struct resolver { + /** Name of this resolver (e.g. "DNS") */ + const char *name; + /** Start name resolution + * + * @v resolv Name resolution interface + * @v name Name to resolve + * @v sa Socket address to complete + * @ret rc Return status code + */ + int ( * resolv ) ( struct resolv_interface *resolv, const char *name, + struct sockaddr *sa ); +}; + +/** Numeric resolver priority */ +#define RESOLV_NUMERIC 01 + +/** Normal resolver priority */ +#define RESOLV_NORMAL 02 + +/** Register as a name resolver */ +#define __resolver( resolv_order ) \ + __table ( struct resolver, resolvers, resolv_order ) + +extern void resolv_done ( struct resolv_interface *resolv, + struct sockaddr *sa, int rc ); +extern void ignore_resolv_done ( struct resolv_interface *resolv, + struct sockaddr *sa, int rc ); +extern struct resolv_interface_operations null_resolv_ops; +extern struct resolv_interface null_resolv; + +extern int resolv ( struct resolv_interface *resolv, const char *name, + struct sockaddr *sa ); + +#endif /* _GPXE_RESOLV_H */ diff --git a/gpxe/src/include/gpxe/retry.h b/gpxe/src/include/gpxe/retry.h new file mode 100644 index 00000000..e71e7b3b --- /dev/null +++ b/gpxe/src/include/gpxe/retry.h @@ -0,0 +1,52 @@ +#ifndef _GPXE_RETRY_H +#define _GPXE_RETRY_H + +/** @file + * + * Retry timers + * + */ + +#include <gpxe/list.h> + +/** A retry timer */ +struct retry_timer { + /** List of active timers */ + struct list_head list; + /** Timeout value (in ticks) */ + unsigned long timeout; + /** Start time (in ticks) + * + * A start time of zero indicates a stopped timer. + */ + unsigned long start; + /** Retry count */ + unsigned int count; + /** Timer expired callback + * + * @v timer Retry timer + * @v fail Failure indicator + * + * The timer will already be stopped when this method is + * called. The failure indicator will be True if the retry + * timeout has already exceeded @c MAX_TIMEOUT. + */ + void ( * expired ) ( struct retry_timer *timer, int over ); +}; + +extern void start_timer ( struct retry_timer *timer ); +extern void start_timer_nodelay ( struct retry_timer *timer ); +extern void stop_timer ( struct retry_timer *timer ); + +/** + * Test to see if timer is currently running + * + * @v timer Retry timer + * @ret running Non-zero if timer is running + */ +static inline __attribute__ (( always_inline )) unsigned long +timer_running ( struct retry_timer *timer ) { + return ( timer->start ); +} + +#endif /* _GPXE_RETRY_H */ diff --git a/gpxe/src/include/gpxe/rsa.h b/gpxe/src/include/gpxe/rsa.h new file mode 100644 index 00000000..ce15cfa0 --- /dev/null +++ b/gpxe/src/include/gpxe/rsa.h @@ -0,0 +1,10 @@ +#ifndef _GPXE_RSA_H +#define _GPXE_RSA_H + +struct crypto_algorithm; + +extern struct crypto_algorithm rsa_algorithm; + +#include "crypto/axtls/crypto.h" + +#endif /* _GPXE_RSA_H */ diff --git a/gpxe/src/include/gpxe/scsi.h b/gpxe/src/include/gpxe/scsi.h new file mode 100644 index 00000000..e820117b --- /dev/null +++ b/gpxe/src/include/gpxe/scsi.h @@ -0,0 +1,270 @@ +#ifndef _GPXE_SCSI_H +#define _GPXE_SCSI_H + +#include <stdint.h> +#include <gpxe/blockdev.h> +#include <gpxe/uaccess.h> +#include <gpxe/refcnt.h> + +/** @file + * + * SCSI devices + * + */ + +/** + * @defgroup scsiops SCSI operation codes + * @{ + */ + +#define SCSI_OPCODE_READ_10 0x28 /**< READ (10) */ +#define SCSI_OPCODE_READ_16 0x88 /**< READ (16) */ +#define SCSI_OPCODE_WRITE_10 0x2a /**< WRITE (10) */ +#define SCSI_OPCODE_WRITE_16 0x8a /**< WRITE (16) */ +#define SCSI_OPCODE_READ_CAPACITY_10 0x25 /**< READ CAPACITY (10) */ +#define SCSI_OPCODE_SERVICE_ACTION_IN 0x9e /**< SERVICE ACTION IN */ +#define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */ + +/** @} */ + +/** + * @defgroup scsiflags SCSI flags + * @{ + */ + +#define SCSI_FL_FUA_NV 0x02 /**< Force unit access to NVS */ +#define SCSI_FL_FUA 0x08 /**< Force unit access */ +#define SCSI_FL_DPO 0x10 /**< Disable cache page out */ + +/** @} */ + +/** + * @defgroup scsicdbs SCSI command data blocks + * @{ + */ + +/** A SCSI "READ (10)" CDB */ +struct scsi_cdb_read_10 { + /** Opcode (0x28) */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Start address + * + * This is a logical block number, in big-endian order. + */ + uint32_t lba; + /** Group number */ + uint8_t group; + /** Transfer length + * + * This is a logical block count, in big-endian order. + */ + uint16_t len; + /** Control byte */ + uint8_t control; +} __attribute__ (( packed )); + +/** A SCSI "READ (16)" CDB */ +struct scsi_cdb_read_16 { + /** Opcode (0x88) */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Start address + * + * This is a logical block number, in big-endian order. + */ + uint64_t lba; + /** Transfer length + * + * This is a logical block count, in big-endian order. + */ + uint32_t len; + /** Group number */ + uint8_t group; + /** Control byte */ + uint8_t control; +} __attribute__ (( packed )); + +/** A SCSI "WRITE (10)" CDB */ +struct scsi_cdb_write_10 { + /** Opcode (0x2a) */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Start address + * + * This is a logical block number, in big-endian order. + */ + uint32_t lba; + /** Group number */ + uint8_t group; + /** Transfer length + * + * This is a logical block count, in big-endian order. + */ + uint16_t len; + /** Control byte */ + uint8_t control; +} __attribute__ (( packed )); + +/** A SCSI "WRITE (16)" CDB */ +struct scsi_cdb_write_16 { + /** Opcode (0x8a) */ + uint8_t opcode; + /** Flags */ + uint8_t flags; + /** Start address + * + * This is a logical block number, in big-endian order. + */ + uint64_t lba; + /** Transfer length + * + * This is a logical block count, in big-endian order. + */ + uint32_t len; + /** Group number */ + uint8_t group; + /** Control byte */ + uint8_t control; +} __attribute__ (( packed )); + +/** A SCSI "READ CAPACITY (10)" CDB */ +struct scsi_cdb_read_capacity_10 { + /** Opcode (0x25) */ + uint8_t opcode; + /** Reserved */ + uint8_t reserved_a; + /** Logical block address + * + * Applicable only if the PMI bit is set. + */ + uint32_t lba; + /** Reserved */ + uint8_t reserved_b[3]; + /** Control byte */ + uint8_t control; +} __attribute__ (( packed )); + +/** SCSI "READ CAPACITY (10)" parameter data */ +struct scsi_capacity_10 { + /** Maximum logical block number */ + uint32_t lba; + /** Block length in bytes */ + uint32_t blksize; +} __attribute__ (( packed )); + +/** A SCSI "READ CAPACITY (16)" CDB */ +struct scsi_cdb_read_capacity_16 { + /** Opcode (0x9e) */ + uint8_t opcode; + /** Service action */ + uint8_t service_action; + /** Logical block address + * + * Applicable only if the PMI bit is set. + */ + uint64_t lba; + /** Transfer length + * + * This is the size of the data-in buffer, in bytes. + */ + uint32_t len; + /** Reserved */ + uint8_t reserved; + /** Control byte */ + uint8_t control; +} __attribute__ (( packed )); + +/** SCSI "READ CAPACITY (16)" parameter data */ +struct scsi_capacity_16 { + /** Maximum logical block number */ + uint64_t lba; + /** Block length in bytes */ + uint32_t blksize; + /** Reserved */ + uint8_t reserved[20]; +} __attribute__ (( packed )); + +/** A SCSI Command Data Block */ +union scsi_cdb { + struct scsi_cdb_read_10 read10; + struct scsi_cdb_read_16 read16; + struct scsi_cdb_write_10 write10; + struct scsi_cdb_write_16 write16; + struct scsi_cdb_read_capacity_10 readcap10; + struct scsi_cdb_read_capacity_16 readcap16; + unsigned char bytes[16]; +}; + +/** printf() format for dumping a scsi_cdb */ +#define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \ + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" + +/** printf() parameters for dumping a scsi_cdb */ +#define SCSI_CDB_DATA(cdb) \ + (cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3], \ + (cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7], \ + (cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \ + (cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15] + +/** @} */ + +/** A SCSI command */ +struct scsi_command { + /** CDB for this command */ + union scsi_cdb cdb; + /** Data-out buffer (may be NULL) */ + userptr_t data_out; + /** Data-out buffer length + * + * Must be zero if @c data_out is NULL + */ + size_t data_out_len; + /** Data-in buffer (may be NULL) */ + userptr_t data_in; + /** Data-in buffer length + * + * Must be zero if @c data_in is NULL + */ + size_t data_in_len; + /** SCSI status code */ + uint8_t status; + /** SCSI sense response code */ + uint8_t sense_response; +}; + +/** A SCSI device */ +struct scsi_device { + /** Block device interface */ + struct block_device blockdev; + /** Logical unit number (LUN) + * + * This is a four-level LUN as specified by SAM-2, in + * big-endian order. + */ + uint64_t lun; + /** + * Issue SCSI command + * + * @v scsi SCSI device + * @v command SCSI command + * @ret rc Return status code + * + * Note that a successful return status code indicates only + * that the SCSI command completed. The caller must check the + * status field in the command structure to see if, for + * example, the device returned CHECK CONDITION or some other + * non-success status code. + */ + int ( * command ) ( struct scsi_device *scsi, + struct scsi_command *command ); + /** Backing device */ + struct refcnt *backend; +}; + +extern int init_scsidev ( struct scsi_device *scsi ); + +#endif /* _GPXE_SCSI_H */ diff --git a/gpxe/src/include/gpxe/segment.h b/gpxe/src/include/gpxe/segment.h new file mode 100644 index 00000000..5ab91699 --- /dev/null +++ b/gpxe/src/include/gpxe/segment.h @@ -0,0 +1,15 @@ +#ifndef _GPXE_SEGMENT_H +#define _GPXE_SEGMENT_H + +/** + * @file + * + * Executable image segments + * + */ + +#include <gpxe/uaccess.h> + +extern int prep_segment ( userptr_t segment, size_t filesz, size_t memsz ); + +#endif /* _GPXE_SEGMENT_H */ diff --git a/gpxe/src/include/gpxe/settings.h b/gpxe/src/include/gpxe/settings.h new file mode 100644 index 00000000..40825698 --- /dev/null +++ b/gpxe/src/include/gpxe/settings.h @@ -0,0 +1,285 @@ +#ifndef _GPXE_SETTINGS_H +#define _GPXE_SETTINGS_H + +/** @file + * + * Configuration settings + * + */ + +#include <stdint.h> +#include <gpxe/tables.h> +#include <gpxe/list.h> +#include <gpxe/refcnt.h> +#include <gpxe/dhcpopts.h> + +struct settings; +struct in_addr; + +/** A setting */ +struct setting { + /** Name + * + * This is the human-readable name for the setting. + */ + const char *name; + /** Description */ + const char *description; + /** Setting type + * + * This identifies the type of setting (e.g. string, IPv4 + * address, etc.). + */ + struct setting_type *type; + /** DHCP option number, if applicable */ + unsigned int tag; +}; + +/** Declare a configuration setting */ +#define __setting __table ( struct setting, settings, 01 ) + +/** Settings block operations */ +struct settings_operations { + /** Store value of setting + * + * @v settings Settings block + * @v setting Setting to store + * @v data Setting data, or NULL to clear setting + * @v len Length of setting data + * @ret rc Return status code + */ + int ( * store ) ( struct settings *settings, struct setting *setting, + const void *data, size_t len ); + /** Fetch value of setting + * + * @v settings Settings block + * @v setting Setting to fetch + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @ret len Length of setting data, or negative error + * + * The actual length of the setting will be returned even if + * the buffer was too small. + */ + int ( * fetch ) ( struct settings *settings, struct setting *setting, + void *data, size_t len ); +}; + +/** A settings block */ +struct settings { + /** Reference counter */ + struct refcnt *refcnt; + /** Name */ + const char *name; + /** Parent settings block */ + struct settings *parent; + /** Sibling settings blocks */ + struct list_head siblings; + /** Child settings blocks */ + struct list_head children; + /** Settings block operations */ + struct settings_operations *op; +}; + +/** + * A setting type + * + * This represents a type of setting (e.g. string, IPv4 address, + * etc.). + */ +struct setting_type { + /** Name + * + * This is the name exposed to the user (e.g. "string"). + */ + const char *name; + /** Parse and set value of setting + * + * @v settings Settings block + * @v setting Setting to store + * @v value Formatted setting data + * @ret rc Return status code + */ + int ( * storef ) ( struct settings *settings, struct setting *setting, + const char *value ); + /** Fetch and format value of setting + * + * @v settings Settings block + * @v setting Setting to fetch + * @v buf Buffer to contain formatted value + * @v len Length of buffer + * @ret len Length of formatted value, or negative error + */ + int ( * fetchf ) ( struct settings *settings, struct setting *setting, + char *buf, size_t len ); +}; + +/** Declare a configuration setting type */ +#define __setting_type \ + __table ( struct setting_type, setting_types, 01 ) + +/** + * A settings applicator + * + */ +struct settings_applicator { + /** Apply updated settings + * + * @ret rc Return status code + */ + int ( * apply ) ( void ); +}; + +/** Declare a settings applicator */ +#define __settings_applicator \ + __table ( struct settings_applicator, settings_applicators, 01 ) + +/** + * A simple settings block + * + */ +struct simple_settings { + /** Settings block */ + struct settings settings; + /** DHCP options */ + struct dhcp_options dhcpopts; +}; + +extern struct settings_operations simple_settings_operations; +extern int simple_settings_store ( struct settings *settings, + struct setting *setting, + const void *data, size_t len ); +extern int simple_settings_fetch ( struct settings *settings, + struct setting *setting, + void *data, size_t len ); + +extern int register_settings ( struct settings *settings, + struct settings *parent ); +extern void unregister_settings ( struct settings *settings ); + +extern int store_setting ( struct settings *settings, struct setting *setting, + const void *data, size_t len ); +extern int fetch_setting ( struct settings *settings, struct setting *setting, + void *data, size_t len ); +extern int fetch_setting_len ( struct settings *settings, + struct setting *setting ); +extern int fetch_string_setting ( struct settings *settings, + struct setting *setting, + char *data, size_t len ); +extern int fetch_ipv4_setting ( struct settings *settings, + struct setting *setting, struct in_addr *inp ); +extern int fetch_int_setting ( struct settings *settings, + struct setting *setting, long *value ); +extern int fetch_uint_setting ( struct settings *settings, + struct setting *setting, + unsigned long *value ); +extern long fetch_intz_setting ( struct settings *settings, + struct setting *setting ); +extern unsigned long fetch_uintz_setting ( struct settings *settings, + struct setting *setting ); +extern int setting_cmp ( struct setting *a, struct setting *b ); + +extern struct settings * find_child_settings ( struct settings *parent, + const char *name ); +extern struct settings * find_settings ( const char *name ); + +extern int storef_setting ( struct settings *settings, + struct setting *setting, + const char *value ); +extern int storef_named_setting ( const char *name, const char *value ); +extern int fetchf_named_setting ( const char *name, char *buf, size_t len ); + +extern struct setting_type setting_type_string __setting_type; +extern struct setting_type setting_type_ipv4 __setting_type; +extern struct setting_type setting_type_int8 __setting_type; +extern struct setting_type setting_type_int16 __setting_type; +extern struct setting_type setting_type_int32 __setting_type; +extern struct setting_type setting_type_uint8 __setting_type; +extern struct setting_type setting_type_uint16 __setting_type; +extern struct setting_type setting_type_uint32 __setting_type; +extern struct setting_type setting_type_hex __setting_type; + +extern struct setting ip_setting __setting; +extern struct setting netmask_setting __setting; +extern struct setting gateway_setting __setting; +extern struct setting dns_setting __setting; +extern struct setting hostname_setting __setting; +extern struct setting filename_setting __setting; +extern struct setting root_path_setting __setting; +extern struct setting username_setting __setting; +extern struct setting password_setting __setting; +extern struct setting priority_setting __setting; +extern struct setting bios_drive_setting __setting; + +/** + * Initialise a settings block + * + * @v settings Settings block + * @v op Settings block operations + * @v refcnt Containing object reference counter, or NULL + * @v name Settings block name + */ +static inline void settings_init ( struct settings *settings, + struct settings_operations *op, + struct refcnt *refcnt, + const char *name ) { + INIT_LIST_HEAD ( &settings->siblings ); + INIT_LIST_HEAD ( &settings->children ); + settings->op = op; + settings->refcnt = refcnt; + settings->name = name; +} + +/** + * Initialise a settings block + * + * @v simple Simple settings block + * @v refcnt Containing object reference counter, or NULL + * @v name Settings block name + */ +static inline void simple_settings_init ( struct simple_settings *simple, + struct refcnt *refcnt, + const char *name ) { + settings_init ( &simple->settings, &simple_settings_operations, + refcnt, name ); +} + +/** + * Delete setting + * + * @v settings Settings block + * @v setting Setting to delete + * @ret rc Return status code + */ +static inline int delete_setting ( struct settings *settings, + struct setting *setting ) { + return store_setting ( settings, setting, NULL, 0 ); +} + +/** + * Fetch and format value of setting + * + * @v settings Settings block, or NULL to search all blocks + * @v setting Setting to fetch + * @v type Settings type + * @v buf Buffer to contain formatted value + * @v len Length of buffer + * @ret len Length of formatted value, or negative error + */ +static inline int fetchf_setting ( struct settings *settings, + struct setting *setting, + char *buf, size_t len ) { + return setting->type->fetchf ( settings, setting, buf, len ); +} + +/** + * Delete named setting + * + * @v name Name of setting + * @ret rc Return status code + */ +static inline int delete_named_setting ( const char *name ) { + return storef_named_setting ( name, NULL ); +} + +#endif /* _GPXE_SETTINGS_H */ diff --git a/gpxe/src/include/gpxe/settings_ui.h b/gpxe/src/include/gpxe/settings_ui.h new file mode 100644 index 00000000..48548fd5 --- /dev/null +++ b/gpxe/src/include/gpxe/settings_ui.h @@ -0,0 +1,14 @@ +#ifndef _GPXE_SETTINGS_UI_H +#define _GPXE_SETTINGS_UI_H + +/** @file + * + * Option configuration console + * + */ + +struct settings; + +extern int settings_ui ( struct settings *settings ) __nonnull; + +#endif /* _GPXE_SETTINGS_UI_H */ diff --git a/gpxe/src/include/gpxe/sha1.h b/gpxe/src/include/gpxe/sha1.h new file mode 100644 index 00000000..2d6e90dd --- /dev/null +++ b/gpxe/src/include/gpxe/sha1.h @@ -0,0 +1,13 @@ +#ifndef _GPXE_SHA1_H +#define _GPXE_SHA1_H + +#include "crypto/axtls/crypto.h" + +struct crypto_algorithm; + +#define SHA1_CTX_SIZE sizeof ( SHA1_CTX ) +#define SHA1_DIGEST_SIZE SHA1_SIZE + +extern struct crypto_algorithm sha1_algorithm; + +#endif /* _GPXE_SHA1_H */ diff --git a/gpxe/src/include/gpxe/shell.h b/gpxe/src/include/gpxe/shell.h new file mode 100644 index 00000000..c353fc4d --- /dev/null +++ b/gpxe/src/include/gpxe/shell.h @@ -0,0 +1,12 @@ +#ifndef _GPXE_SHELL_H +#define _GPXE_SHELL_H + +/** @file + * + * Minimal command shell + * + */ + +extern void shell ( void ); + +#endif /* _GPXE_SHELL_H */ diff --git a/gpxe/src/include/gpxe/shell_banner.h b/gpxe/src/include/gpxe/shell_banner.h new file mode 100644 index 00000000..f8e92a4d --- /dev/null +++ b/gpxe/src/include/gpxe/shell_banner.h @@ -0,0 +1,12 @@ +#ifndef _GPXE_SHELL_BANNER_H +#define _GPXE_SHELL_BANNER_H + +/** @file + * + * Shell startup banner + * + */ + +extern int shell_banner ( void ); + +#endif /* _GPXE_SHELL_BANNER_H */ diff --git a/gpxe/src/include/gpxe/socket.h b/gpxe/src/include/gpxe/socket.h new file mode 100644 index 00000000..9c7afb87 --- /dev/null +++ b/gpxe/src/include/gpxe/socket.h @@ -0,0 +1,95 @@ +#ifndef _GPXE_SOCKET_H +#define _GPXE_SOCKET_H + +/** @file + * + * Socket addresses + * + */ + +/** + * @defgroup commtypes Communication semantics + * + * @{ + */ + +/** Connection-based, reliable streams */ +#define SOCK_STREAM ( ( int ) TCP_SOCK_STREAM ) +extern char TCP_SOCK_STREAM[]; + +/** Connectionless, unreliable streams */ +#define SOCK_DGRAM ( ( int ) UDP_SOCK_DGRAM ) +extern char UDP_SOCK_DGRAM[]; + +/** @} */ + +/** + * Name communication semantics + * + * @v semantics Communication semantics (e.g. SOCK_STREAM) + * @ret name Name of communication semantics + */ +static inline __attribute__ (( always_inline )) const char * +socket_semantics_name ( int semantics ) { + /* Cannot use a switch() because of the {TCP_UDP}_SOCK_XXX hack */ + if ( semantics == SOCK_STREAM ) { + return "SOCK_STREAM"; + } else if ( semantics == SOCK_DGRAM ) { + return "SOCK_DGRAM"; + } else { + return "SOCK_UNKNOWN"; + } +} + +/** + * @defgroup addrfam Address families + * + * @{ + */ +#define AF_INET 1 /**< IPv4 Internet addresses */ +#define AF_INET6 2 /**< IPv6 Internet addresses */ +/** @} */ + +/** + * Name address family + * + * @v family Address family (e.g. AF_INET) + * @ret name Name of address family + */ +static inline __attribute__ (( always_inline )) const char * +socket_family_name ( int family ) { + switch ( family ) { + case AF_INET: return "AF_INET"; + case AF_INET6: return "AF_INET6"; + default: return "AF_UNKNOWN"; + } +} + +/** A socket address family */ +typedef uint16_t sa_family_t; + +/** Length of a @c struct @c sockaddr */ +#define SA_LEN 32 + +/** + * Generalized socket address structure + * + * This contains the fields common to socket addresses for all address + * families. + */ +struct sockaddr { + /** Socket address family + * + * This is an AF_XXX constant. + */ + sa_family_t sa_family; + /** Padding + * + * This ensures that a struct @c sockaddr_tcpip is large + * enough to hold a socket address for any TCP/IP address + * family. + */ + char pad[ SA_LEN - sizeof ( sa_family_t ) ]; +}; + +#endif /* _GPXE_SOCKET_H */ diff --git a/gpxe/src/include/gpxe/spi.h b/gpxe/src/include/gpxe/spi.h new file mode 100644 index 00000000..fe38cb6b --- /dev/null +++ b/gpxe/src/include/gpxe/spi.h @@ -0,0 +1,239 @@ +#ifndef _GPXE_SPI_H +#define _GPXE_SPI_H + +/** @file + * + * SPI interface + * + */ + +#include <gpxe/nvs.h> + +/** + * @defgroup spicmds SPI commands + * @{ + */ + +/** Write status register */ +#define SPI_WRSR 0x01 + +/** Write data to memory array */ +#define SPI_WRITE 0x02 + +/** Read data from memory array */ +#define SPI_READ 0x03 + +/** Reset write enable latch */ +#define SPI_WRDI 0x04 + +/** Read status register */ +#define SPI_RDSR 0x05 + +/** Set write enable latch */ +#define SPI_WREN 0x06 + +/** + * @defgroup atmelcmds Atmel-specific SPI commands + * @{ + */ + +/** Erase one sector in memory array (Not supported on all devices) */ +#define ATMEL_SECTOR_ERASE 0x52 + +/** Erase all sections in memory array (Not supported on all devices) */ +#define ATMEL_CHIP_ERASE 0x62 + +/** Read manufacturer and product ID (Not supported on all devices) */ +#define ATMEL_RDID 0x15 + +/** @} */ + +/** @} */ + +/** + * @defgroup spistatus SPI status register bits (not present on all devices) + * @{ + */ + +/** Write-protect pin enabled */ +#define SPI_STATUS_WPEN 0x80 + +/** Block protection bit 2 */ +#define SPI_STATUS_BP2 0x10 + +/** Block protection bit 1 */ +#define SPI_STATUS_BP1 0x08 + +/** Block protection bit 0 */ +#define SPI_STATUS_BP0 0x04 + +/** State of the write enable latch */ +#define SPI_STATUS_WEN 0x02 + +/** Device busy flag */ +#define SPI_STATUS_NRDY 0x01 + +/** @} */ + +/** + * An SPI device + * + * This data structure represents a physical SPI device attached to an + * SPI bus. + */ +struct spi_device { + /** NVS device */ + struct nvs_device nvs; + /** SPI bus to which device is attached */ + struct spi_bus *bus; + /** Slave number */ + unsigned int slave; + /** Command length, in bits */ + unsigned int command_len; + /** Address length, in bits */ + unsigned int address_len; + /** Address is munged + * + * Some devices with 9-bit addresses (e.g. AT25040A EEPROM) + * use bit 3 of the command byte as address bit A8, rather + * than having a two-byte address. If this flag is set, then + * commands should be munged in this way. + */ + unsigned int munge_address : 1; +}; + +static inline __attribute__ (( always_inline )) struct spi_device * +nvs_to_spi ( struct nvs_device *nvs ) { + return container_of ( nvs, struct spi_device, nvs ); +} + +/** + * An SPI bus + * + * This data structure represents an SPI bus controller capable of + * issuing commands to attached SPI devices. + */ +struct spi_bus { + /** SPI interface mode + * + * This is the bitwise OR of zero or more of @c SPI_MODE_CPHA + * and @c SPI_MODE_CPOL. It is also the number conventionally + * used to describe the SPI interface mode. For example, SPI + * mode 1 is the mode in which CPOL=0 and CPHA=1, which + * therefore corresponds to a mode value of (0|SPI_MODE_CPHA) + * which, happily, equals 1. + */ + unsigned int mode; + /** + * Read/write data via SPI bus + * + * @v bus SPI bus + * @v device SPI device + * @v command Command + * @v address Address to read/write (<0 for no address) + * @v data_out TX data buffer (or NULL) + * @v data_in RX data buffer (or NULL) + * @v len Length of data buffer(s) + * + * This issues the specified command and optional address to + * the SPI device, then reads and/or writes data to/from the + * data buffers. + */ + int ( * rw ) ( struct spi_bus *bus, struct spi_device *device, + unsigned int command, int address, + const void *data_out, void *data_in, size_t len ); +}; + +/** Clock phase (CPHA) mode bit + * + * Phase 0 is sample on rising edge, shift data on falling edge. + * + * Phase 1 is shift data on rising edge, sample data on falling edge. + */ +#define SPI_MODE_CPHA 0x01 + +/** Clock polarity (CPOL) mode bit + * + * This bit reflects the idle state of the clock line (SCLK). + */ +#define SPI_MODE_CPOL 0x02 + +/** Slave select polarity mode bit + * + * This bit reflects that active state of the slave select lines. It + * is not part of the normal SPI mode number (which covers only @c + * SPI_MODE_CPOL and @c SPI_MODE_CPHA), but is included here for + * convenience. + */ +#define SPI_MODE_SSPOL 0x10 + +/** Microwire-compatible mode + * + * This is SPI mode 1 (i.e. CPOL=0, CPHA=1), and is compatible with + * the original Microwire protocol. + */ +#define SPI_MODE_MICROWIRE 1 + +/** Microwire/Plus-compatible mode + * + * This is SPI mode 0 (i.e. CPOL=0, CPHA=0), and is compatible with + * the Microwire/Plus protocol + */ +#define SPI_MODE_MICROWIRE_PLUS 0 + +/** Threewire-compatible mode + * + * This mode is compatible with Atmel's series of "three-wire" + * interfaces. + */ +#define SPI_MODE_THREEWIRE ( SPI_MODE_MICROWIRE_PLUS | SPI_MODE_SSPOL ) + +extern int spi_read ( struct nvs_device *nvs, unsigned int address, + void *data, size_t len ); +extern int spi_write ( struct nvs_device *nvs, unsigned int address, + const void *data, size_t len ); + +/** + * @defgroup spidevs SPI device types + * @{ + */ + +static inline __attribute__ (( always_inline )) void +init_spi ( struct spi_device *device ) { + device->nvs.word_len_log2 = 0; + device->command_len = 8, + device->nvs.read = spi_read; + device->nvs.write = spi_write; +} + +/** Atmel AT25F1024 serial flash */ +static inline __attribute__ (( always_inline )) void +init_at25f1024 ( struct spi_device *device ) { + device->address_len = 24; + device->nvs.size = ( 128 * 1024 ); + device->nvs.block_size = 256; + init_spi ( device ); +} + +/** Atmel 25040 serial EEPROM */ +static inline __attribute__ (( always_inline )) void +init_at25040 ( struct spi_device *device ) { + device->address_len = 8; + device->munge_address = 1; + device->nvs.size = 512; + device->nvs.block_size = 8; + init_spi ( device ); +} + +/** Microchip 25XX640 serial EEPROM */ +static inline __attribute__ (( always_inline )) void +init_mc25xx640 ( struct spi_device *device ) { + device->address_len = 16; + device->nvs.size = ( 8 * 1024 ); + device->nvs.block_size = 32; + init_spi ( device ); +} + +/** @} */ + +#endif /* _GPXE_SPI_H */ diff --git a/gpxe/src/include/gpxe/spi_bit.h b/gpxe/src/include/gpxe/spi_bit.h new file mode 100644 index 00000000..ced85ceb --- /dev/null +++ b/gpxe/src/include/gpxe/spi_bit.h @@ -0,0 +1,61 @@ +#ifndef _GPXE_SPI_BIT_H +#define _GPXE_SPI_BIT_H + +/** @file + * + * SPI bit-bashing interface + * + */ + +#include <gpxe/spi.h> +#include <gpxe/bitbash.h> + +/** A bit-bashing SPI bus */ +struct spi_bit_basher { + /** SPI bus */ + struct spi_bus bus; + /** Bit-bashing interface */ + struct bit_basher basher; + /** Endianness of data + * + * SPI commands and addresses are always big-endian (i.e. MSB + * transmitted first on the wire), but some cards + * (e.g. natsemi) choose to regard the data stored in the + * EEPROM as little-endian (i.e. LSB transmitted first on the + * wire). + */ + int endianness; +}; + +/** Bit indices used for SPI bit-bashing interface */ +enum { + /** Serial clock */ + SPI_BIT_SCLK = 0, + /** Master Out Slave In */ + SPI_BIT_MOSI, + /** Master In Slave Out */ + SPI_BIT_MISO, + /** Slave 0 select */ + SPI_BIT_SS0, +}; + +/** + * Determine bit index for a particular slave + * + * @v slave Slave number + * @ret index Bit index (i.e. SPI_BIT_SSN, where N=slave) + */ +#define SPI_BIT_SS( slave ) ( SPI_BIT_SS0 + (slave) ) + +/** Delay between SCLK transitions */ +#define SPI_BIT_UDELAY 1 + +/** SPI bit basher treats data as big-endian */ +#define SPI_BIT_BIG_ENDIAN 0 + +/** SPI bit basher treats data as little-endian */ +#define SPI_BIT_LITTLE_ENDIAN 1 + +extern void init_spi_bit_basher ( struct spi_bit_basher *spibit ); + +#endif /* _GPXE_SPI_BIT_H */ diff --git a/gpxe/src/include/gpxe/tables.h b/gpxe/src/include/gpxe/tables.h new file mode 100644 index 00000000..b2c56ab6 --- /dev/null +++ b/gpxe/src/include/gpxe/tables.h @@ -0,0 +1,229 @@ +#ifndef _GPXE_TABLES_H +#define _GPXE_TABLES_H + +/** @page ifdef_harmful #ifdef considered harmful + * + * Overuse of @c #ifdef has long been a problem in Etherboot. + * Etherboot provides a rich array of features, but all these features + * take up valuable space in a ROM image. The traditional solution to + * this problem has been for each feature to have its own @c #ifdef + * option, allowing the feature to be compiled in only if desired. + * + * The problem with this is that it becomes impossible to compile, let + * alone test, all possible versions of Etherboot. Code that is not + * typically used tends to suffer from bit-rot over time. It becomes + * extremely difficult to predict which combinations of compile-time + * options will result in code that can even compile and link + * correctly. + * + * To solve this problem, we have adopted a new approach from + * Etherboot 5.5 onwards. @c #ifdef is now "considered harmful", and + * its use should be minimised. Separate features should be + * implemented in separate @c .c files, and should \b always be + * compiled (i.e. they should \b not be guarded with a @c #ifdef @c + * MY_PET_FEATURE statement). By making (almost) all code always + * compile, we avoid the problem of bit-rot in rarely-used code. + * + * The file config.h, in combination with the @c make command line, + * specifies the objects that will be included in any particular build + * of Etherboot. For example, suppose that config.h includes the line + * + * @code + * + * #define CONSOLE_SERIAL + * #define DOWNLOAD_PROTO_TFTP + * + * @endcode + * + * When a particular Etherboot image (e.g. @c bin/rtl8139.zdsk) is + * built, the options specified in config.h are used to drag in the + * relevant objects at link-time. For the above example, serial.o and + * tftp.o would be linked in. + * + * There remains one problem to solve: how do these objects get used? + * Traditionally, we had code such as + * + * @code + * + * #ifdef CONSOLE_SERIAL + * serial_init(); + * #endif + * + * @endcode + * + * in main.c, but this reintroduces @c #ifdef and so is a Bad Idea. + * We cannot simply remove the @c #ifdef and make it + * + * @code + * + * serial_init(); + * + * @endcode + * + * because then serial.o would end up always being linked in. + * + * The solution is to use @link tables.h linker tables @endlink. + * + */ + +/** @file + * + * Linker tables + * + * Read @ref ifdef_harmful first for some background on the motivation + * for using linker tables. + * + * This file provides macros for dealing with linker-generated tables + * of fixed-size symbols. We make fairly extensive use of these in + * order to avoid @c #ifdef spaghetti and/or linker symbol pollution. + * For example, instead of having code such as + * + * @code + * + * #ifdef CONSOLE_SERIAL + * serial_init(); + * #endif + * + * @endcode + * + * we make serial.c generate an entry in the initialisation function + * table, and then have a function call_init_fns() that simply calls + * all functions present in this table. If and only if serial.o gets + * linked in, then its initialisation function will be called. We + * avoid linker symbol pollution (i.e. always dragging in serial.o + * just because of a call to serial_init()) and we also avoid @c + * #ifdef spaghetti (having to conditionalise every reference to + * functions in serial.c). + * + * The linker script takes care of assembling the tables for us. All + * our table sections have names of the format @c .tbl.NAME.NN where + * @c NAME designates the data structure stored in the table (e.g. @c + * init_fn) and @c NN is a two-digit decimal number used to impose an + * ordering upon the tables if required. @c NN=00 is reserved for the + * symbol indicating "table start", and @c NN=99 is reserved for the + * symbol indicating "table end". + * + * As an example, suppose that we want to create a "frobnicator" + * feature framework, and allow for several independent modules to + * provide frobnicating services. Then we would create a frob.h + * header file containing e.g. + * + * @code + * + * struct frobnicator { + * const char *name; // Name of the frobnicator + * void ( *frob ) ( void ); // The frobnicating function itself + * }; + * + * #define __frobnicator __table ( frobnicators, 01 ) + * + * @endcode + * + * Any module providing frobnicating services would look something + * like + * + * @code + * + * #include "frob.h" + * + * static void my_frob ( void ) { + * // Do my frobnicating + * ... + * } + * + * struct frob my_frobnicator __frobnicator = { + * .name = "my_frob", + * .frob = my_frob, + * }; + * + * @endcode + * + * The central frobnicator code (frob.c) would use the frobnicating + * modules as follows + * + * @code + * + * #include "frob.h" + * + * static struct frob frob_start[0] __table_start ( frobnicators ); + * static struct frob frob_end[0] __table_end ( frobnicators ); + * + * // Call all linked-in frobnicators + * void frob_all ( void ) { + * struct frob *frob; + * + * for ( frob = frob_start ; frob < frob_end ; frob++ ) { + * printf ( "Calling frobnicator \"%s\"\n", frob->name ); + * frob->frob (); + * } + * } + * + * @endcode + * + * See init.h and init.c for a real-life example. + * + */ + +#ifdef DOXYGEN +#define __attribute__( x ) +#endif + +#define __table_str( x ) #x +#define __table_section( table, idx ) \ + __section__ ( ".tbl." __table_str ( table ) "." __table_str ( idx ) ) + +#define __table_section_start( table ) __table_section ( table, 00 ) +#define __table_section_end( table ) __table_section ( table, 99 ) + +#define __natural_alignment( type ) __aligned__ ( __alignof__ ( type ) ) + +/** + * Linker table entry. + * + * Declares a data structure to be part of a linker table. Use as + * e.g. + * + * @code + * + * struct my_foo __table ( foo, 01 ) = { + * ... + * }; + * + * @endcode + * + */ +#define __table( type, table, idx ) \ + __attribute__ (( __table_section ( table, idx ), \ + __natural_alignment ( type ) )) + +/** + * Linker table start marker. + * + * Declares a data structure (usually an empty data structure) to be + * the start of a linker table. Use as e.g. + * + * @code + * + * static struct foo_start[0] __table_start ( foo ); + * + * @endcode + * + */ +#define __table_start( type, table ) __table ( type, table, 00 ) + +/** + * Linker table end marker. + * + * Declares a data structure (usually an empty data structure) to be + * the end of a linker table. Use as e.g. + * + * @code + * + * static struct foo_end[0] __table_end ( foo ); + * + * @endcode + * + */ +#define __table_end( type, table ) __table ( type, table, 99 ) + +#endif /* _GPXE_TABLES_H */ diff --git a/gpxe/src/include/gpxe/tcp.h b/gpxe/src/include/gpxe/tcp.h new file mode 100644 index 00000000..264ec29b --- /dev/null +++ b/gpxe/src/include/gpxe/tcp.h @@ -0,0 +1,306 @@ +#ifndef _GPXE_TCP_H +#define _GPXE_TCP_H + +/** @file + * + * TCP protocol + * + * This file defines the gPXE TCP API. + * + */ + +#include <gpxe/tcpip.h> + +/** + * A TCP header + */ +struct tcp_header { + uint16_t src; /* Source port */ + uint16_t dest; /* Destination port */ + uint32_t seq; /* Sequence number */ + uint32_t ack; /* Acknowledgement number */ + uint8_t hlen; /* Header length (4), Reserved (4) */ + uint8_t flags; /* Reserved (2), Flags (6) */ + uint16_t win; /* Advertised window */ + uint16_t csum; /* Checksum */ + uint16_t urg; /* Urgent pointer */ +}; + +/** @defgroup tcpopts TCP options + * @{ + */ + +/** End of TCP options list */ +#define TCP_OPTION_END 0 + +/** TCP option pad */ +#define TCP_OPTION_NOP 1 + +/** Generic TCP option */ +struct tcp_option { + uint8_t kind; + uint8_t length; +} __attribute__ (( packed )); + +/** TCP MSS option */ +struct tcp_mss_option { + uint8_t kind; + uint8_t length; + uint16_t mss; +} __attribute__ (( packed )); + +/** Code for the TCP MSS option */ +#define TCP_OPTION_MSS 2 + +/** TCP timestamp option */ +struct tcp_timestamp_option { + uint8_t kind; + uint8_t length; + uint32_t tsval; + uint32_t tsecr; +} __attribute__ (( packed )); + +/** Padded TCP timestamp option (used for sending) */ +struct tcp_timestamp_padded_option { + uint8_t nop[2]; + struct tcp_timestamp_option tsopt; +} __attribute__ (( packed )); + +/** Code for the TCP timestamp option */ +#define TCP_OPTION_TS 8 + +/** Parsed TCP options */ +struct tcp_options { + /** MSS option, if present */ + const struct tcp_mss_option *mssopt; + /** Timestampe option, if present */ + const struct tcp_timestamp_option *tsopt; +}; + +/** @} */ + +/* + * TCP flags + */ +#define TCP_CWR 0x80 +#define TCP_ECE 0x40 +#define TCP_URG 0x20 +#define TCP_ACK 0x10 +#define TCP_PSH 0x08 +#define TCP_RST 0x04 +#define TCP_SYN 0x02 +#define TCP_FIN 0x01 + +/** +* @defgroup tcpstates TCP states +* +* The TCP state is defined by a combination of the flags that have +* been sent to the peer, the flags that have been acknowledged by the +* peer, and the flags that have been received from the peer. +* +* @{ +*/ + +/** TCP flags that have been sent in outgoing packets */ +#define TCP_STATE_SENT(flags) ( (flags) << 0 ) +#define TCP_FLAGS_SENT(state) ( ( (state) >> 0 ) & 0xff ) + +/** TCP flags that have been acknowledged by the peer + * + * Note that this applies only to SYN and FIN. + */ +#define TCP_STATE_ACKED(flags) ( (flags) << 8 ) +#define TCP_FLAGS_ACKED(state) ( ( (state) >> 8 ) & 0xff ) + +/** TCP flags that have been received from the peer + * + * Note that this applies only to SYN and FIN, and that once SYN has + * been received, we should always be sending ACK. + */ +#define TCP_STATE_RCVD(flags) ( (flags) << 16 ) +#define TCP_FLAGS_RCVD(state) ( ( (state) >> 16 ) & 0xff ) + +/** TCP flags that are currently being sent in outgoing packets */ +#define TCP_FLAGS_SENDING(state) \ + ( TCP_FLAGS_SENT ( state ) & ~TCP_FLAGS_ACKED ( state ) ) + +/** CLOSED + * + * The connection has not yet been used for anything. + */ +#define TCP_CLOSED TCP_RST + +/** LISTEN + * + * Not currently used as a state; we have no support for listening + * connections. Given a unique value to avoid compiler warnings. + */ +#define TCP_LISTEN 0 + +/** SYN_SENT + * + * SYN has been sent, nothing has yet been received or acknowledged. + */ +#define TCP_SYN_SENT ( TCP_STATE_SENT ( TCP_SYN ) ) + +/** SYN_RCVD + * + * SYN has been sent but not acknowledged, SYN has been received. + */ +#define TCP_SYN_RCVD ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) | \ + TCP_STATE_RCVD ( TCP_SYN ) ) + +/** ESTABLISHED + * + * SYN has been sent and acknowledged, SYN has been received. + */ +#define TCP_ESTABLISHED ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) | \ + TCP_STATE_ACKED ( TCP_SYN ) | \ + TCP_STATE_RCVD ( TCP_SYN ) ) + +/** FIN_WAIT_1 + * + * SYN has been sent and acknowledged, SYN has been received, FIN has + * been sent but not acknowledged, FIN has not been received. + * + * RFC 793 shows that we can enter FIN_WAIT_1 without have had SYN + * acknowledged, i.e. if the application closes the connection after + * sending and receiving SYN, but before having had SYN acknowledged. + * However, we have to *pretend* that SYN has been acknowledged + * anyway, otherwise we end up sending SYN and FIN in the same + * sequence number slot. Therefore, when we transition from SYN_RCVD + * to FIN_WAIT_1, we have to remember to set TCP_STATE_ACKED(TCP_SYN) + * and increment our sequence number. + */ +#define TCP_FIN_WAIT_1 ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ + TCP_STATE_ACKED ( TCP_SYN ) | \ + TCP_STATE_RCVD ( TCP_SYN ) ) + +/** FIN_WAIT_2 + * + * SYN has been sent and acknowledged, SYN has been received, FIN has + * been sent and acknowledged, FIN ha not been received. + */ +#define TCP_FIN_WAIT_2 ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ + TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) | \ + TCP_STATE_RCVD ( TCP_SYN ) ) + +/** CLOSING / LAST_ACK + * + * SYN has been sent and acknowledged, SYN has been received, FIN has + * been sent but not acknowledged, FIN has been received. + * + * This state actually encompasses both CLOSING and LAST_ACK; they are + * identical with the definition of state that we use. I don't + * *believe* that they need to be distinguished. + */ +#define TCP_CLOSING_OR_LAST_ACK \ + ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ + TCP_STATE_ACKED ( TCP_SYN ) | \ + TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) ) + +/** TIME_WAIT + * + * SYN has been sent and acknowledged, SYN has been received, FIN has + * been sent and acknowledged, FIN has been received. + */ +#define TCP_TIME_WAIT ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) | \ + TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) | \ + TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) ) + +/** CLOSE_WAIT + * + * SYN has been sent and acknowledged, SYN has been received, FIN has + * been received. + */ +#define TCP_CLOSE_WAIT ( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) | \ + TCP_STATE_ACKED ( TCP_SYN ) | \ + TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) ) + +/** Can send data in current state + * + * We can send data if and only if we have had our SYN acked and we + * have not yet sent our FIN. + */ +#define TCP_CAN_SEND_DATA(state) \ + ( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN ) | \ + TCP_STATE_SENT ( TCP_FIN ) ) ) \ + == TCP_STATE_ACKED ( TCP_SYN ) ) + +/** Have closed gracefully + * + * We have closed gracefully if we have both received a FIN and had + * our own FIN acked. + */ +#define TCP_CLOSED_GRACEFULLY(state) \ + ( ( (state) & ( TCP_STATE_ACKED ( TCP_FIN ) | \ + TCP_STATE_RCVD ( TCP_FIN ) ) ) \ + == ( TCP_STATE_ACKED ( TCP_FIN ) | TCP_STATE_RCVD ( TCP_FIN ) ) ) + +/** @} */ + +/** Mask for TCP header length field */ +#define TCP_MASK_HLEN 0xf0 + +/** Smallest port number on which a TCP connection can listen */ +#define TCP_MIN_PORT 1 + +/* Some IOB constants */ +#define MAX_HDR_LEN 100 +#define MAX_IOB_LEN 1500 +#define MIN_IOB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */ + +/** + * Maxmimum advertised TCP window size + * + * We estimate the TCP window size as the amount of free memory we + * have. This is not strictly accurate (since it ignores any space + * already allocated as RX buffers), but it will do for now. + * + * Since we don't store out-of-order received packets, the + * retransmission penalty is that the whole window contents must be + * resent. This suggests keeping the window size small, but bear in + * mind that the maximum bandwidth on any link is limited to + * + * max_bandwidth = ( tcp_window / round_trip_time ) + * + * With a 48kB window, which probably accurately reflects our amount + * of free memory, and a WAN RTT of say 200ms, this gives a maximum + * bandwidth of 240kB/s. This is sufficiently close to realistic that + * we will need to be careful that our advertised window doesn't end + * up limiting WAN download speeds. + * + * Finally, since the window goes into a 16-bit field and we cannot + * actually use 65536, we use a window size of (65536-4) to ensure + * that payloads remain dword-aligned. + */ +//#define TCP_MAX_WINDOW_SIZE ( 65536 - 4 ) +#define TCP_MAX_WINDOW_SIZE 4096 + +/** + * Path MTU + * + * We really ought to implement Path MTU discovery. Until we do, + * anything with a path MTU greater than this may fail. + */ +#define TCP_PATH_MTU 1460 + +/** + * Advertised TCP MSS + * + * We currently hardcode this to a reasonable value and hope that the + * sender uses path MTU discovery. The alternative is breaking the + * abstraction layer so that we can find out the MTU from the IP layer + * (which would have to find out from the net device layer). + */ +#define TCP_MSS 1460 + +/** TCP maximum segment lifetime + * + * Currently set to 2 minutes, as per RFC 793. + */ +#define TCP_MSL ( 2 * 60 * TICKS_PER_SEC ) + +extern struct tcpip_protocol tcp_protocol; + +#endif /* _GPXE_TCP_H */ diff --git a/gpxe/src/include/gpxe/tcpip.h b/gpxe/src/include/gpxe/tcpip.h new file mode 100644 index 00000000..c0fadd23 --- /dev/null +++ b/gpxe/src/include/gpxe/tcpip.h @@ -0,0 +1,118 @@ +#ifndef _GPXE_TCPIP_H +#define _GPXE_TCPIP_H + +/** @file + * + * Transport-network layer interface + * + */ + +#include <stdint.h> +#include <gpxe/socket.h> +#include <gpxe/in.h> +#include <gpxe/tables.h> + +struct io_buffer; +struct net_device; + +/** Empty checksum value + * + * This is the TCP/IP checksum over a zero-length block of data. + */ +#define TCPIP_EMPTY_CSUM 0xffff + +/** + * TCP/IP socket address + * + * This contains the fields common to socket addresses for all TCP/IP + * address families. + */ +struct sockaddr_tcpip { + /** Socket address family (part of struct @c sockaddr) */ + sa_family_t st_family; + /** TCP/IP port */ + uint16_t st_port; + /** Padding + * + * This ensures that a struct @c sockaddr_tcpip is large + * enough to hold a socket address for any TCP/IP address + * family. + */ + char pad[ sizeof ( struct sockaddr ) - + ( sizeof ( sa_family_t ) + sizeof ( uint16_t ) ) ]; +}; + +/** + * A transport-layer protocol of the TCP/IP stack (eg. UDP, TCP, etc) + */ +struct tcpip_protocol { + /** Protocol name */ + const char *name; + /** + * Process received packet + * + * @v iobuf I/O buffer + * @v st_src Partially-filled source address + * @v st_dest Partially-filled destination address + * @v pshdr_csum Pseudo-header checksum + * @ret rc Return status code + * + * This method takes ownership of the I/O buffer. + */ + int ( * rx ) ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, + struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ); + /** + * Transport-layer protocol number + * + * This is a constant of the type IP_XXX + */ + uint8_t tcpip_proto; +}; + +/** + * A network-layer protocol of the TCP/IP stack (eg. IPV4, IPv6, etc) + */ +struct tcpip_net_protocol { + /** Protocol name */ + const char *name; + /** Network address family */ + sa_family_t sa_family; + /** + * Transmit packet + * + * @v iobuf I/O buffer + * @v tcpip_protocol Transport-layer protocol + * @v st_dest Destination address + * @v netdev Network device (or NULL to route automatically) + * @v trans_csum Transport-layer checksum to complete, or NULL + * @ret rc Return status code + * + * This function takes ownership of the I/O buffer. + */ + int ( * tx ) ( struct io_buffer *iobuf, + struct tcpip_protocol *tcpip_protocol, + struct sockaddr_tcpip *st_dest, + struct net_device *netdev, + uint16_t *trans_csum ); +}; + +/** Declare a TCP/IP transport-layer protocol */ +#define __tcpip_protocol \ + __table ( struct tcpip_protocol, tcpip_protocols, 01 ) + +/** Declare a TCP/IP network-layer protocol */ +#define __tcpip_net_protocol \ + __table ( struct tcpip_net_protocol, tcpip_net_protocols, 01 ) + +extern int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto, + struct sockaddr_tcpip *st_src, + struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ); +extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip, + struct sockaddr_tcpip *st_dest, + struct net_device *netdev, + uint16_t *trans_csum ); +extern uint16_t tcpip_continue_chksum ( uint16_t partial, + const void *data, size_t len ); +extern uint16_t tcpip_chksum ( const void *data, size_t len ); + +#endif /* _GPXE_TCPIP_H */ diff --git a/gpxe/src/include/gpxe/tftp.h b/gpxe/src/include/gpxe/tftp.h new file mode 100644 index 00000000..0177a95a --- /dev/null +++ b/gpxe/src/include/gpxe/tftp.h @@ -0,0 +1,83 @@ +#ifndef _GPXE_TFTP_H +#define _GPXE_TFTP_H + +/** @file + * + * TFTP protocol + * + */ + +#include <stdint.h> + +#define TFTP_PORT 69 /**< Default TFTP server port */ +#define TFTP_DEFAULT_BLKSIZE 512 /**< Default TFTP data block size */ +#define TFTP_MAX_BLKSIZE 1432 + +#define TFTP_RRQ 1 /**< Read request opcode */ +#define TFTP_WRQ 2 /**< Write request opcode */ +#define TFTP_DATA 3 /**< Data block opcode */ +#define TFTP_ACK 4 /**< Data block acknowledgement opcode */ +#define TFTP_ERROR 5 /**< Error opcode */ +#define TFTP_OACK 6 /**< Options acknowledgement opcode */ + +#define TFTP_ERR_FILE_NOT_FOUND 1 /**< File not found */ +#define TFTP_ERR_ACCESS_DENIED 2 /**< Access violation */ +#define TFTP_ERR_DISK_FULL 3 /**< Disk full or allocation exceeded */ +#define TFTP_ERR_ILLEGAL_OP 4 /**< Illegal TFTP operation */ +#define TFTP_ERR_UNKNOWN_TID 5 /**< Unknown transfer ID */ +#define TFTP_ERR_FILE_EXISTS 6 /**< File already exists */ +#define TFTP_ERR_UNKNOWN_USER 7 /**< No such user */ +#define TFTP_ERR_BAD_OPTS 8 /**< Option negotiation failed */ + +#define MTFTP_PORT 1759 /**< Default MTFTP server port */ + +/** A TFTP read request (RRQ) packet */ +struct tftp_rrq { + uint16_t opcode; + char data[0]; +} __attribute__ (( packed )); + +/** A TFTP data (DATA) packet */ +struct tftp_data { + uint16_t opcode; + uint16_t block; + uint8_t data[0]; +} __attribute__ (( packed )); + +/** A TFTP acknowledgement (ACK) packet */ +struct tftp_ack { + uint16_t opcode; + uint16_t block; +} __attribute__ (( packed )); + +/** A TFTP error (ERROR) packet */ +struct tftp_error { + uint16_t opcode; + uint16_t errcode; + char errmsg[0]; +} __attribute__ (( packed )); + +/** A TFTP options acknowledgement (OACK) packet */ +struct tftp_oack { + uint16_t opcode; + char data[0]; +} __attribute__ (( packed )); + +/** The common header of all TFTP packets */ +struct tftp_common { + uint16_t opcode; +} __attribute__ (( packed )); + +/** A union encapsulating all TFTP packet types */ +union tftp_any { + struct tftp_common common; + struct tftp_rrq rrq; + struct tftp_data data; + struct tftp_ack ack; + struct tftp_error error; + struct tftp_oack oack; +}; + +extern void tftp_set_request_blksize ( unsigned int blksize ); + +#endif /* _GPXE_TFTP_H */ diff --git a/gpxe/src/include/gpxe/threewire.h b/gpxe/src/include/gpxe/threewire.h new file mode 100644 index 00000000..865fc25d --- /dev/null +++ b/gpxe/src/include/gpxe/threewire.h @@ -0,0 +1,89 @@ +#ifndef _GPXE_THREEWIRE_H +#define _GPXE_THREEWIRE_H + +/** @file + * + * Three-wire serial interface + * + * The Atmel three-wire interface is a subset of the (newer) SPI + * interface, and is implemented here as a layer on top of the SPI + * support. + */ + +#include <gpxe/spi.h> +#include <limits.h> + +/** + * @defgroup tcmds Three-wire commands + * @{ + */ + +/** Read data from memory array */ +#define THREEWIRE_READ 0x6 + +/** Write data to memory array */ +#define THREEWIRE_WRITE 0x5 + +/** Write enable */ +#define THREEWIRE_EWEN 0x4 + +/** Address to be used for write enable command */ +#define THREEWIRE_EWEN_ADDRESS INT_MAX + +/** Time to wait for write cycles to complete + * + * This is sufficient for AT93C46/AT93C56 devices, but may need to be + * increased in future when other devices are added. + */ +#define THREEWIRE_WRITE_MDELAY 10 + +/** @} */ + +extern int threewire_read ( struct nvs_device *nvs, unsigned int address, + void *data, size_t len ); +extern int threewire_write ( struct nvs_device *nvs, unsigned int address, + const void *data, size_t len ); + +/** + * @defgroup tdevs Three-wire device types + * @{ + */ + +static inline __attribute__ (( always_inline )) void +init_at93cx6 ( struct spi_device *device, unsigned int organisation ) { + device->nvs.word_len_log2 = ( ( organisation == 8 ) ? 0 : 1 ); + device->nvs.block_size = 1; + device->command_len = 3, + device->nvs.read = threewire_read; + device->nvs.write = threewire_write; +} + +/** + * Initialise Atmel AT93C46 serial EEPROM + * + * @v device SPI device + * @v organisation Word organisation (8 or 16) + */ +static inline __attribute__ (( always_inline )) void +init_at93c46 ( struct spi_device *device, unsigned int organisation ) { + device->nvs.size = ( 1024 / organisation ); + device->address_len = ( ( organisation == 8 ) ? 7 : 6 ); + init_at93cx6 ( device, organisation ); +} + +/** + * Initialise Atmel AT93C56 serial EEPROM + * + * @v device SPI device + * @v organisation Word organisation (8 or 16) + */ +static inline __attribute__ (( always_inline )) void +init_at93c56 ( struct spi_device *device, unsigned int organisation ) { + device->nvs.size = ( 2048 / organisation ); + device->address_len = ( ( organisation == 8 ) ? 9 : 8 ); + init_at93cx6 ( device, organisation ); +} + +/** @} */ + +#endif /* _GPXE_THREEWIRE_H */ diff --git a/gpxe/src/include/gpxe/timer.h b/gpxe/src/include/gpxe/timer.h new file mode 100644 index 00000000..b7057225 --- /dev/null +++ b/gpxe/src/include/gpxe/timer.h @@ -0,0 +1,41 @@ +#ifndef GPXE_TIMER_H +#define GPXE_TIMER_H + +#include <stddef.h> +#include <gpxe/tables.h> + +typedef unsigned long tick_t; + +#define MSECS_IN_SEC (1000) +#define USECS_IN_SEC (1000*1000) +#define USECS_IN_MSEC (1000) + +#define TICKS_PER_SEC USECS_IN_SEC + +extern tick_t currticks ( void ); + +extern void generic_currticks_udelay ( unsigned int usecs ); + +/** A timer */ +struct timer { + /** Initialise timer + * + * @ret rc Return status code + */ + int ( * init ) ( void ); + /** Read current time + * + * @ret ticks Current time, in ticks + */ + tick_t ( * currticks ) ( void ); + /** Delay + * + * @v usecs Time to delay, in microseconds + */ + void ( * udelay ) ( unsigned int usecs ); +}; + +#define __timer( order ) __table ( struct timer, timers, order ) + +#endif /* GPXE_TIMER_H */ + diff --git a/gpxe/src/include/gpxe/tls.h b/gpxe/src/include/gpxe/tls.h new file mode 100644 index 00000000..a8cf16ef --- /dev/null +++ b/gpxe/src/include/gpxe/tls.h @@ -0,0 +1,171 @@ +#ifndef _GPXE_TLS_H +#define _GPXE_TLS_H + +/** + * @file + * + * Transport Layer Security Protocol + */ + +#include <stdint.h> +#include <gpxe/refcnt.h> +#include <gpxe/filter.h> +#include <gpxe/process.h> +#include <gpxe/crypto.h> +#include <gpxe/md5.h> +#include <gpxe/sha1.h> + +/** A TLS header */ +struct tls_header { + /** Content type + * + * This is a TLS_TYPE_XXX constant + */ + uint8_t type; + /** Protocol version + * + * This is a TLS_VERSION_XXX constant + */ + uint16_t version; + /** Length of payload */ + uint16_t length; +} __attribute__ (( packed )); + +/** TLS version 1.0 */ +#define TLS_VERSION_TLS_1_0 0x0301 + +/** TLS version 1.1 */ +#define TLS_VERSION_TLS_1_1 0x0302 + +/** Change cipher content type */ +#define TLS_TYPE_CHANGE_CIPHER 20 + +/** Alert content type */ +#define TLS_TYPE_ALERT 21 + +/** Handshake content type */ +#define TLS_TYPE_HANDSHAKE 22 + +/** Application data content type */ +#define TLS_TYPE_DATA 23 + +/* Handshake message types */ +#define TLS_HELLO_REQUEST 0 +#define TLS_CLIENT_HELLO 1 +#define TLS_SERVER_HELLO 2 +#define TLS_CERTIFICATE 11 +#define TLS_SERVER_KEY_EXCHANGE 12 +#define TLS_CERTIFICATE_REQUEST 13 +#define TLS_SERVER_HELLO_DONE 14 +#define TLS_CERTIFICATE_VERIFY 15 +#define TLS_CLIENT_KEY_EXCHANGE 16 +#define TLS_FINISHED 20 + +/* TLS alert levels */ +#define TLS_ALERT_WARNING 1 +#define TLS_ALERT_FATAL 2 + +/* TLS cipher specifications */ +#define TLS_RSA_WITH_NULL_MD5 0x0001 +#define TLS_RSA_WITH_NULL_SHA 0x0002 +#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f +#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 + +/** TLS RX state machine state */ +enum tls_rx_state { + TLS_RX_HEADER = 0, + TLS_RX_DATA, +}; + +/** TLS TX state machine state */ +enum tls_tx_state { + TLS_TX_NONE = 0, + TLS_TX_CLIENT_HELLO, + TLS_TX_CLIENT_KEY_EXCHANGE, + TLS_TX_CHANGE_CIPHER, + TLS_TX_FINISHED, + TLS_TX_DATA +}; + +/** A TLS cipher specification */ +struct tls_cipherspec { + /** Public-key encryption algorithm */ + struct crypto_algorithm *pubkey; + /** Bulk encryption cipher algorithm */ + struct crypto_algorithm *cipher; + /** MAC digest algorithm */ + struct crypto_algorithm *digest; + /** Key length */ + size_t key_len; + /** Dynamically-allocated storage */ + void *dynamic; + /** Public key encryption context */ + void *pubkey_ctx; + /** Bulk encryption cipher context */ + void *cipher_ctx; + /** Next bulk encryption cipher context (TX only) */ + void *cipher_next_ctx; + /** MAC secret */ + void *mac_secret; +}; + +/** A TLS session */ +struct tls_session { + /** Reference counter */ + struct refcnt refcnt; + + /** Plaintext stream */ + struct xfer_filter_half plainstream; + /** Ciphertext stream */ + struct xfer_filter_half cipherstream; + + /** Current TX cipher specification */ + struct tls_cipherspec tx_cipherspec; + /** Next TX cipher specification */ + struct tls_cipherspec tx_cipherspec_pending; + /** Current RX cipher specification */ + struct tls_cipherspec rx_cipherspec; + /** Next RX cipher specification */ + struct tls_cipherspec rx_cipherspec_pending; + /** Premaster secret */ + uint8_t pre_master_secret[48]; + /** Master secret */ + uint8_t master_secret[48]; + /** Server random bytes */ + uint8_t server_random[32]; + /** Client random bytes */ + uint8_t client_random[32]; + /** MD5 context for handshake verification */ + uint8_t handshake_md5_ctx[MD5_CTX_SIZE]; + /** SHA1 context for handshake verification */ + uint8_t handshake_sha1_ctx[SHA1_CTX_SIZE]; + + /** Hack: server RSA public key */ + uint8_t *rsa_mod; + size_t rsa_mod_len; + uint8_t *rsa_pub_exp; + size_t rsa_pub_exp_len; + + /** TX sequence number */ + uint64_t tx_seq; + /** TX state */ + enum tls_tx_state tx_state; + /** TX process */ + struct process process; + + /** RX sequence number */ + uint64_t rx_seq; + /** RX state */ + enum tls_rx_state rx_state; + /** Offset within current RX state */ + size_t rx_rcvd; + /** Current received record header */ + struct tls_header rx_header; + /** Current received raw data buffer */ + void *rx_data; +}; + +extern int add_tls ( struct xfer_interface *xfer, + struct xfer_interface **next ); + +#endif /* _GPXE_TLS_H */ diff --git a/gpxe/src/include/gpxe/uaccess.h b/gpxe/src/include/gpxe/uaccess.h new file mode 100644 index 00000000..05f89e03 --- /dev/null +++ b/gpxe/src/include/gpxe/uaccess.h @@ -0,0 +1,27 @@ +#ifndef _GPXE_UACCESS_H +#define _GPXE_UACCESS_H + +/** + * @file + * + * Access to external ("user") memory + * + * gPXE often needs to transfer data between internal and external + * buffers. On i386, the external buffers may require access via a + * different segment, and the buffer address cannot be encoded into a + * simple void * pointer. The @c userptr_t type encapsulates the + * information needed to identify an external buffer, and the + * copy_to_user() and copy_from_user() functions provide methods for + * transferring data between internal and external buffers. + * + * Note that userptr_t is an opaque type; in particular, performing + * arithmetic upon a userptr_t is not allowed. + * + */ + +#include <bits/uaccess.h> + +/** Equivalent of NULL for user pointers */ +#define UNULL ( ( userptr_t ) 0 ) + +#endif /* _GPXE_UACCESS_H */ diff --git a/gpxe/src/include/gpxe/udp.h b/gpxe/src/include/gpxe/udp.h new file mode 100644 index 00000000..cb0e44eb --- /dev/null +++ b/gpxe/src/include/gpxe/udp.h @@ -0,0 +1,47 @@ +#ifndef _GPXE_UDP_H +#define _GPXE_UDP_H + +/** @file + * + * UDP protocol + * + * This file defines the gPXE UDP API. + * + */ + +#include <stddef.h> +#include <gpxe/iobuf.h> +#include <gpxe/tcpip.h> +#include <gpxe/if_ether.h> + +struct xfer_interface; +struct sockaddr; + +/** + * UDP constants + */ + +#define UDP_MAX_HLEN 72 +#define UDP_MAX_TXIOB ETH_MAX_MTU +#define UDP_MIN_TXIOB ETH_ZLEN + +/** + * A UDP header + */ +struct udp_header { + /** Source port */ + uint16_t src; + /** Destination port */ + uint16_t dest; + /** Length */ + uint16_t len; + /** Checksum */ + uint16_t chksum; +}; + +extern int udp_open_promisc ( struct xfer_interface *xfer ); +extern int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer, + struct sockaddr *local ); + +#endif /* _GPXE_UDP_H */ + diff --git a/gpxe/src/include/gpxe/umalloc.h b/gpxe/src/include/gpxe/umalloc.h new file mode 100644 index 00000000..49ec22b4 --- /dev/null +++ b/gpxe/src/include/gpxe/umalloc.h @@ -0,0 +1,17 @@ +#ifndef _GPXE_UMALLOC_H +#define _GPXE_UMALLOC_H + +/** + * @file + * + * User memory allocation + * + */ + +#include <gpxe/uaccess.h> + +extern userptr_t umalloc ( size_t size ); +extern userptr_t urealloc ( userptr_t ptr, size_t new_size ); +extern void ufree ( userptr_t ptr ); + +#endif /* _GPXE_UMALLOC_H */ diff --git a/gpxe/src/include/gpxe/uri.h b/gpxe/src/include/gpxe/uri.h new file mode 100644 index 00000000..514bc479 --- /dev/null +++ b/gpxe/src/include/gpxe/uri.h @@ -0,0 +1,139 @@ +#ifndef _GPXE_URI_H +#define _GPXE_URI_H + +/** @file + * + * Uniform Resource Identifiers + * + */ + +#include <stdlib.h> +#include <gpxe/refcnt.h> + +/** A Uniform Resource Identifier + * + * Terminology for this data structure is as per uri(7), except that + * "path" is defined to include the leading '/' for an absolute path. + * + * Note that all fields within a URI are optional and may be NULL. + * + * Some examples are probably helpful: + * + * http://www.etherboot.org/wiki : + * + * scheme = "http", host = "www.etherboot.org", path = "/wiki" + * + * /var/lib/tftpboot : + * + * path = "/var/lib/tftpboot" + * + * mailto:bob@nowhere.com : + * + * scheme = "mailto", opaque = "bob@nowhere.com" + * + * ftp://joe:secret@insecure.org:8081/hidden/path/to?what=is#this + * + * scheme = "ftp", user = "joe", password = "secret", + * host = "insecure.org", port = "8081", path = "/hidden/path/to", + * query = "what=is", fragment = "this" + */ +struct uri { + /** Reference count */ + struct refcnt refcnt; + /** Scheme */ + const char *scheme; + /** Opaque part */ + const char *opaque; + /** User name */ + const char *user; + /** Password */ + const char *password; + /** Host name */ + const char *host; + /** Port number */ + const char *port; + /** Path */ + const char *path; + /** Query */ + const char *query; + /** Fragment */ + const char *fragment; +}; + +/** + * URI is an absolute URI + * + * @v uri URI + * @ret is_absolute URI is absolute + * + * An absolute URI begins with a scheme, e.g. "http:" or "mailto:". + * Note that this is a separate concept from a URI with an absolute + * path. + */ +static inline int uri_is_absolute ( struct uri *uri ) { + return ( uri->scheme != NULL ); +} + +/** + * URI has an absolute path + * + * @v uri URI + * @ret has_absolute_path URI has an absolute path + * + * An absolute path begins with a '/'. Note that this is a separate + * concept from an absolute URI. Note also that a URI may not have a + * path at all. + */ +static inline int uri_has_absolute_path ( struct uri *uri ) { + return ( uri->path && ( uri->path[0] == '/' ) ); +} + +/** + * URI has a relative path + * + * @v uri URI + * @ret has_relative_path URI has a relative path + * + * A relative path begins with something other than a '/'. Note that + * this is a separate concept from a relative URI. Note also that a + * URI may not have a path at all. + */ +static inline int uri_has_relative_path ( struct uri *uri ) { + return ( uri->path && ( uri->path[0] != '/' ) ); +} + +/** + * Increment URI reference count + * + * @v uri URI, or NULL + * @ret uri URI as passed in + */ +static inline __attribute__ (( always_inline )) struct uri * +uri_get ( struct uri *uri ) { + ref_get ( &uri->refcnt ); + return uri; +} + +/** + * Decrement URI reference count + * + * @v uri URI, or NULL + */ +static inline __attribute__ (( always_inline )) void +uri_put ( struct uri *uri ) { + ref_put ( &uri->refcnt ); +} + +extern struct uri *cwuri; + +extern struct uri * parse_uri ( const char *uri_string ); +extern unsigned int uri_port ( struct uri *uri, unsigned int default_port ); +extern int unparse_uri ( char *buf, size_t size, struct uri *uri ); +extern struct uri * uri_dup ( struct uri *uri ); +extern char * resolve_path ( const char *base_path, + const char *relative_path ); +extern struct uri * resolve_uri ( struct uri *base_uri, + struct uri *relative_uri ); +extern void churi ( struct uri *uri ); + +#endif /* _GPXE_URI_H */ diff --git a/gpxe/src/include/gpxe/uuid.h b/gpxe/src/include/gpxe/uuid.h new file mode 100644 index 00000000..a62735c9 --- /dev/null +++ b/gpxe/src/include/gpxe/uuid.h @@ -0,0 +1,34 @@ +#ifndef _GPXE_UUID_H +#define _GPXE_UUID_H + +/** @file + * + * Universally unique IDs + */ + +#include <stdint.h> + +union uuid; +#include <bits/uuid.h> + +/** A universally unique ID */ +union uuid { + /** Canonical form (00000000-0000-0000-0000-000000000000) */ + struct { + /** 8 hex digits, little-endian */ + uint32_t a; + /** 2 hex digits, little-endian */ + uint16_t b; + /** 2 hex digits, little-endian */ + uint16_t c; + /** 2 hex digits, big-endian */ + uint16_t d; + /** 12 hex digits, big-endian */ + uint8_t e[6]; + } canonical; + uint8_t raw[16]; +}; + +extern char * uuid_ntoa ( union uuid *uuid ); + +#endif /* _GPXE_UUID_H */ diff --git a/gpxe/src/include/gpxe/vsprintf.h b/gpxe/src/include/gpxe/vsprintf.h new file mode 100644 index 00000000..9360f29b --- /dev/null +++ b/gpxe/src/include/gpxe/vsprintf.h @@ -0,0 +1,71 @@ +#ifndef _GPXE_VSPRINTF_H +#define _GPXE_VSPRINTF_H + +/** @file + * + * printf() and friends + * + * Etherboot's printf() functions understand the following subset of + * the standard C printf()'s format specifiers: + * + * - Flag characters + * - '#' - Alternate form (i.e. "0x" prefix) + * - '0' - Zero-pad + * - Field widths + * - Length modifiers + * - 'hh' - Signed / unsigned char + * - 'h' - Signed / unsigned short + * - 'l' - Signed / unsigned long + * - 'll' - Signed / unsigned long long + * - 'z' - Signed / unsigned size_t + * - Conversion specifiers + * - 'd' - Signed decimal + * - 'x','X' - Unsigned hexadecimal + * - 'c' - Character + * - 's' - String + * - 'p' - Pointer + * + * Hexadecimal numbers are always zero-padded to the specified field + * width (if any); decimal numbers are always space-padded. Decimal + * long longs are not supported. + * + */ + +#include <stdint.h> +#include <stdarg.h> +#include <stdio.h> + +/** + * A printf context + * + * Contexts are used in order to be able to share code between + * vprintf() and vsnprintf(), without requiring the allocation of a + * buffer for vprintf(). + */ +struct printf_context { + /** + * Character handler + * + * @v ctx Context + * @v c Character + * + * This method is called for each character written to the + * formatted string. + */ + void ( * handler ) ( struct printf_context *ctx, unsigned int c ); + /** Length of formatted string + * + * When handler() is called, @len will be set to the number of + * characters written so far (i.e. zero for the first call to + * handler()). + */ + size_t len; +}; + +extern size_t vcprintf ( struct printf_context *ctx, const char *fmt, + va_list args ); +extern int vssnprintf ( char *buf, ssize_t ssize, const char *fmt, + va_list args ); +extern int ssnprintf ( char *buf, ssize_t ssize, const char *fmt, ... ); + +#endif /* _GPXE_VSPRINTF_H */ diff --git a/gpxe/src/include/gpxe/xfer.h b/gpxe/src/include/gpxe/xfer.h new file mode 100644 index 00000000..9575bf69 --- /dev/null +++ b/gpxe/src/include/gpxe/xfer.h @@ -0,0 +1,275 @@ +#ifndef _GPXE_XFER_H +#define _GPXE_XFER_H + +/** @file + * + * Data transfer interfaces + * + */ + +#include <stddef.h> +#include <stdarg.h> +#include <gpxe/interface.h> +#include <gpxe/iobuf.h> + +struct xfer_interface; +struct xfer_metadata; + +/** Data transfer interface operations */ +struct xfer_interface_operations { + /** Close interface + * + * @v xfer Data transfer interface + * @v rc Reason for close + */ + void ( * close ) ( struct xfer_interface *xfer, int rc ); + /** Redirect to new location + * + * @v xfer Data transfer interface + * @v type New location type + * @v args Remaining arguments depend upon location type + * @ret rc Return status code + */ + int ( * vredirect ) ( struct xfer_interface *xfer, int type, + va_list args ); + /** Check flow control window + * + * @v xfer Data transfer interface + * @ret len Length of window + * + * Flow control is regarded as advisory but not mandatory. + * Users who have control over their own rate of data + * generation should perform a flow control check before + * generating new data. Users who have no control (such as + * NIC drivers or filter layers) are not obliged to check. + * + * Data transfer interfaces must be prepared to accept + * datagrams even if they are advertising a window of zero + * bytes. + */ + size_t ( * window ) ( struct xfer_interface *xfer ); + /** Allocate I/O buffer + * + * @v xfer Data transfer interface + * @v len I/O buffer payload length + * @ret iobuf I/O buffer + */ + struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer, + size_t len ); + /** Deliver datagram as I/O buffer with metadata + * + * @v xfer Data transfer interface + * @v iobuf Datagram I/O buffer + * @v meta Data transfer metadata + * @ret rc Return status code + * + * A data transfer interface that wishes to support only raw + * data delivery should set this method to + * xfer_deliver_as_raw(). + */ + int ( * deliver_iob ) ( struct xfer_interface *xfer, + struct io_buffer *iobuf, + struct xfer_metadata *meta ); + /** Deliver datagram as raw data + * + * @v xfer Data transfer interface + * @v data Data buffer + * @v len Length of data buffer + * @ret rc Return status code + * + * A data transfer interface that wishes to support only I/O + * buffer delivery should set this method to + * xfer_deliver_as_iob(). + */ + int ( * deliver_raw ) ( struct xfer_interface *xfer, + const void *data, size_t len ); +}; + +/** A data transfer interface */ +struct xfer_interface { + /** Generic object communication interface */ + struct interface intf; + /** Operations for received messages */ + struct xfer_interface_operations *op; +}; + +/** Basis positions for seek() events */ +enum seek_whence { + SEEK_CUR = 0, + SEEK_SET, +}; + +/** Data transfer metadata */ +struct xfer_metadata { + /** Position of data within stream */ + off_t offset; + /** Basis for data position + * + * Must be one of @c SEEK_CUR or @c SEEK_SET. + */ + int whence; + /** Source socket address, or NULL */ + struct sockaddr *src; + /** Destination socket address, or NULL */ + struct sockaddr *dest; + /** Network device, or NULL */ + struct net_device *netdev; +}; + +/** + * Describe seek basis + * + * @v whence Basis for new position + */ +static inline __attribute__ (( always_inline )) const char * +whence_text ( int whence ) { + switch ( whence ) { + case SEEK_CUR: return "CUR"; + case SEEK_SET: return "SET"; + default: return "INVALID"; + } +} + +extern struct xfer_interface null_xfer; +extern struct xfer_interface_operations null_xfer_ops; + +extern void xfer_close ( struct xfer_interface *xfer, int rc ); +extern int xfer_vredirect ( struct xfer_interface *xfer, int type, + va_list args ); +extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... ); +extern size_t xfer_window ( struct xfer_interface *xfer ); +extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, + size_t len ); +extern int xfer_deliver_iob ( struct xfer_interface *xfer, + struct io_buffer *iobuf ); +extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer, + struct io_buffer *iobuf, + struct xfer_metadata *meta ); +extern int xfer_deliver_raw ( struct xfer_interface *xfer, + const void *data, size_t len ); +extern int xfer_vprintf ( struct xfer_interface *xfer, + const char *format, va_list args ); +extern int xfer_printf ( struct xfer_interface *xfer, + const char *format, ... ); +extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ); + +extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc ); +extern int ignore_xfer_vredirect ( struct xfer_interface *xfer, + int type, va_list args ); +extern size_t unlimited_xfer_window ( struct xfer_interface *xfer ); +extern size_t no_xfer_window ( struct xfer_interface *xfer ); +extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer, + size_t len ); +extern int xfer_deliver_as_raw ( struct xfer_interface *xfer, + struct io_buffer *iobuf, + struct xfer_metadata *meta ); +extern int xfer_deliver_as_iob ( struct xfer_interface *xfer, + const void *data, size_t len ); +extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, + const void *data __unused, size_t len ); + +/** + * Initialise a data transfer interface + * + * @v xfer Data transfer interface + * @v op Data transfer interface operations + * @v refcnt Containing object reference counter, or NULL + */ +static inline void xfer_init ( struct xfer_interface *xfer, + struct xfer_interface_operations *op, + struct refcnt *refcnt ) { + xfer->intf.dest = &null_xfer.intf; + xfer->intf.refcnt = refcnt; + xfer->op = op; +} + +/** + * Initialise a static data transfer interface + * + * @v operations Data transfer interface operations + */ +#define XFER_INIT( operations ) { \ + .intf = { \ + .dest = &null_xfer.intf, \ + .refcnt = NULL, \ + }, \ + .op = operations, \ + } + +/** + * Get data transfer interface from generic object communication interface + * + * @v intf Generic object communication interface + * @ret xfer Data transfer interface + */ +static inline __attribute__ (( always_inline )) struct xfer_interface * +intf_to_xfer ( struct interface *intf ) { + return container_of ( intf, struct xfer_interface, intf ); +} + +/** + * Get reference to destination data transfer interface + * + * @v xfer Data transfer interface + * @ret dest Destination interface + */ +static inline __attribute__ (( always_inline )) struct xfer_interface * +xfer_get_dest ( struct xfer_interface *xfer ) { + return intf_to_xfer ( intf_get ( xfer->intf.dest ) ); +} + +/** + * Drop reference to data transfer interface + * + * @v xfer Data transfer interface + */ +static inline __attribute__ (( always_inline )) void +xfer_put ( struct xfer_interface *xfer ) { + intf_put ( &xfer->intf ); +} + +/** + * Plug a data transfer interface into a new destination interface + * + * @v xfer Data transfer interface + * @v dest New destination interface + */ +static inline __attribute__ (( always_inline )) void +xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) { + plug ( &xfer->intf, &dest->intf ); +} + +/** + * Plug two data transfer interfaces together + * + * @v a Data transfer interface A + * @v b Data transfer interface B + */ +static inline __attribute__ (( always_inline )) void +xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) { + plug_plug ( &a->intf, &b->intf ); +} + +/** + * Unplug a data transfer interface + * + * @v xfer Data transfer interface + */ +static inline __attribute__ (( always_inline )) void +xfer_unplug ( struct xfer_interface *xfer ) { + plug ( &xfer->intf, &null_xfer.intf ); +} + +/** + * Stop using a data transfer interface + * + * @v xfer Data transfer interface + * + * After calling this method, no further messages will be received via + * the interface. + */ +static inline void xfer_nullify ( struct xfer_interface *xfer ) { + xfer->op = &null_xfer_ops; +}; + +#endif /* _GPXE_XFER_H */ diff --git a/gpxe/src/include/i82365.h b/gpxe/src/include/i82365.h new file mode 100644 index 00000000..3b0e00ca --- /dev/null +++ b/gpxe/src/include/i82365.h @@ -0,0 +1,450 @@ +/* + * i82365.h 1.15 1999/10/25 20:03:34 + * + * The contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"). + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + */ + +#ifndef _LINUX_I82365_H +#define _LINUX_I82365_H + +/* register definitions for the Intel 82365SL PCMCIA controller */ + +/* Offsets for PCIC registers */ +#define I365_IDENT 0x00 /* Identification and revision */ +#define I365_STATUS 0x01 /* Interface status */ +#define I365_POWER 0x02 /* Power and RESETDRV control */ +#define I365_INTCTL 0x03 /* Interrupt and general control */ +#define I365_CSC 0x04 /* Card status change */ +#define I365_CSCINT 0x05 /* Card status change interrupt control */ +#define I365_ADDRWIN 0x06 /* Address window enable */ +#define I365_IOCTL 0x07 /* I/O control */ +#define I365_GENCTL 0x16 /* Card detect and general control */ +#define I365_GBLCTL 0x1E /* Global control register */ + +/* Offsets for I/O and memory window registers */ +#define I365_IO(map) (0x08+((map)<<2)) +#define I365_MEM(map) (0x10+((map)<<3)) +#define I365_W_START 0 +#define I365_W_STOP 2 +#define I365_W_OFF 4 + +/* Flags for I365_STATUS */ +#define I365_CS_BVD1 0x01 +#define I365_CS_STSCHG 0x01 +#define I365_CS_BVD2 0x02 +#define I365_CS_SPKR 0x02 +#define I365_CS_DETECT 0x0C +#define I365_CS_WRPROT 0x10 +#define I365_CS_READY 0x20 /* Inverted */ +#define I365_CS_POWERON 0x40 +#define I365_CS_GPI 0x80 + +/* Flags for I365_POWER */ +#define I365_PWR_OFF 0x00 /* Turn off the socket */ +#define I365_PWR_OUT 0x80 /* Output enable */ +#define I365_PWR_NORESET 0x40 /* Disable RESETDRV on resume */ +#define I365_PWR_AUTO 0x20 /* Auto pwr switch enable */ +#define I365_VCC_MASK 0x18 /* Mask for turning off Vcc */ +/* There are different layouts for B-step and DF-step chips: the B + step has independent Vpp1/Vpp2 control, and the DF step has only + Vpp1 control, plus 3V control */ +#define I365_VCC_5V 0x10 /* Vcc = 5.0v */ +#define I365_VCC_3V 0x18 /* Vcc = 3.3v */ +#define I365_VPP2_MASK 0x0c /* Mask for turning off Vpp2 */ +#define I365_VPP2_5V 0x04 /* Vpp2 = 5.0v */ +#define I365_VPP2_12V 0x08 /* Vpp2 = 12.0v */ +#define I365_VPP1_MASK 0x03 /* Mask for turning off Vpp1 */ +#define I365_VPP1_5V 0x01 /* Vpp2 = 5.0v */ +#define I365_VPP1_12V 0x02 /* Vpp2 = 12.0v */ + +/* Flags for I365_INTCTL */ +#define I365_RING_ENA 0x80 +#define I365_PC_RESET 0x40 +#define I365_PC_IOCARD 0x20 +#define I365_INTR_ENA 0x10 +#define I365_IRQ_MASK 0x0F + +/* Flags for I365_CSC and I365_CSCINT*/ +#define I365_CSC_BVD1 0x01 +#define I365_CSC_STSCHG 0x01 +#define I365_CSC_BVD2 0x02 +#define I365_CSC_READY 0x04 +#define I365_CSC_DETECT 0x08 +#define I365_CSC_ANY 0x0F +#define I365_CSC_GPI 0x10 + +/* Flags for I365_ADDRWIN */ +#define I365_ENA_IO(map) (0x40 << (map)) +#define I365_ENA_MEM(map) (0x01 << (map)) + +/* Flags for I365_IOCTL */ +#define I365_IOCTL_MASK(map) (0x0F << (map<<2)) +#define I365_IOCTL_WAIT(map) (0x08 << (map<<2)) +#define I365_IOCTL_0WS(map) (0x04 << (map<<2)) +#define I365_IOCTL_IOCS16(map) (0x02 << (map<<2)) +#define I365_IOCTL_16BIT(map) (0x01 << (map<<2)) + +/* Flags for I365_GENCTL */ +#define I365_CTL_16DELAY 0x01 +#define I365_CTL_RESET 0x02 +#define I365_CTL_GPI_ENA 0x04 +#define I365_CTL_GPI_CTL 0x08 +#define I365_CTL_RESUME 0x10 +#define I365_CTL_SW_IRQ 0x20 + +/* Flags for I365_GBLCTL */ +#define I365_GBL_PWRDOWN 0x01 +#define I365_GBL_CSC_LEV 0x02 +#define I365_GBL_WRBACK 0x04 +#define I365_GBL_IRQ_0_LEV 0x08 +#define I365_GBL_IRQ_1_LEV 0x10 + +/* Flags for memory window registers */ +#define I365_MEM_16BIT 0x8000 /* In memory start high byte */ +#define I365_MEM_0WS 0x4000 +#define I365_MEM_WS1 0x8000 /* In memory stop high byte */ +#define I365_MEM_WS0 0x4000 +#define I365_MEM_WRPROT 0x8000 /* In offset high byte */ +#define I365_MEM_REG 0x4000 + +#define I365_REG(slot, reg) (((slot) << 6) + reg) + +#endif /* _LINUX_I82365_H */ + +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +// Beginning vg468.h (for VADEM chipset) + +#ifndef _LINUX_VG468_H +#define _LINUX_VG468_H + +/* Special bit in I365_IDENT used for Vadem chip detection */ +#define I365_IDENT_VADEM 0x08 + +/* Special definitions in I365_POWER */ +#define VG468_VPP2_MASK 0x0c +#define VG468_VPP2_5V 0x04 +#define VG468_VPP2_12V 0x08 + +/* Unique Vadem registers */ +#define VG469_VSENSE 0x1f /* Card voltage sense */ +#define VG469_VSELECT 0x2f /* Card voltage select */ +#define VG468_CTL 0x38 /* Control register */ +#define VG468_TIMER 0x39 /* Timer control */ +#define VG468_MISC 0x3a /* Miscellaneous */ +#define VG468_GPIO_CFG 0x3b /* GPIO configuration */ +#define VG469_EXT_MODE 0x3c /* Extended mode register */ +#define VG468_SELECT 0x3d /* Programmable chip select */ +#define VG468_SELECT_CFG 0x3e /* Chip select configuration */ +#define VG468_ATA 0x3f /* ATA control */ + +/* Flags for VG469_VSENSE */ +#define VG469_VSENSE_A_VS1 0x01 +#define VG469_VSENSE_A_VS2 0x02 +#define VG469_VSENSE_B_VS1 0x04 +#define VG469_VSENSE_B_VS2 0x08 + +/* Flags for VG469_VSELECT */ +#define VG469_VSEL_VCC 0x03 +#define VG469_VSEL_5V 0x00 +#define VG469_VSEL_3V 0x03 +#define VG469_VSEL_MAX 0x0c +#define VG469_VSEL_EXT_STAT 0x10 +#define VG469_VSEL_EXT_BUS 0x20 +#define VG469_VSEL_MIXED 0x40 +#define VG469_VSEL_ISA 0x80 + +/* Flags for VG468_CTL */ +#define VG468_CTL_SLOW 0x01 /* 600ns memory timing */ +#define VG468_CTL_ASYNC 0x02 /* Asynchronous bus clocking */ +#define VG468_CTL_TSSI 0x08 /* Tri-state some outputs */ +#define VG468_CTL_DELAY 0x10 /* Card detect debounce */ +#define VG468_CTL_INPACK 0x20 /* Obey INPACK signal? */ +#define VG468_CTL_POLARITY 0x40 /* VCCEN polarity */ +#define VG468_CTL_COMPAT 0x80 /* Compatibility stuff */ + +#define VG469_CTL_WS_COMPAT 0x04 /* Wait state compatibility */ +#define VG469_CTL_STRETCH 0x10 /* LED stretch */ + +/* Flags for VG468_TIMER */ +#define VG468_TIMER_ZEROPWR 0x10 /* Zero power control */ +#define VG468_TIMER_SIGEN 0x20 /* Power up */ +#define VG468_TIMER_STATUS 0x40 /* Activity timer status */ +#define VG468_TIMER_RES 0x80 /* Timer resolution */ +#define VG468_TIMER_MASK 0x0f /* Activity timer timeout */ + +/* Flags for VG468_MISC */ +#define VG468_MISC_GPIO 0x04 /* General-purpose IO */ +#define VG468_MISC_DMAWSB 0x08 /* DMA wait state control */ +#define VG469_MISC_LEDENA 0x10 /* LED enable */ +#define VG468_MISC_VADEMREV 0x40 /* Vadem revision control */ +#define VG468_MISC_UNLOCK 0x80 /* Unique register lock */ + +/* Flags for VG469_EXT_MODE_A */ +#define VG469_MODE_VPPST 0x03 /* Vpp steering control */ +#define VG469_MODE_INT_SENSE 0x04 /* Internal voltage sense */ +#define VG469_MODE_CABLE 0x08 +#define VG469_MODE_COMPAT 0x10 /* i82365sl B or DF step */ +#define VG469_MODE_TEST 0x20 +#define VG469_MODE_RIO 0x40 /* Steer RIO to INTR? */ + +/* Flags for VG469_EXT_MODE_B */ +#define VG469_MODE_B_3V 0x01 /* 3.3v for socket B */ + +#endif /* _LINUX_VG468_H */ + + +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +// Beginning ricoh.h (RICOH chipsets) + +#ifndef _LINUX_RICOH_H +#define _LINUX_RICOH_H + + +#define RF5C_MODE_CTL 0x1f /* Mode control */ +#define RF5C_PWR_CTL 0x2f /* Mixed voltage control */ +#define RF5C_CHIP_ID 0x3a /* Chip identification */ +#define RF5C_MODE_CTL_3 0x3b /* Mode control 3 */ + +/* I/O window address offset */ +#define RF5C_IO_OFF(w) (0x36+((w)<<1)) + +/* Flags for RF5C_MODE_CTL */ +#define RF5C_MODE_ATA 0x01 /* ATA mode */ +#define RF5C_MODE_LED_ENA 0x02 /* IRQ 12 is LED */ +#define RF5C_MODE_CA21 0x04 +#define RF5C_MODE_CA22 0x08 +#define RF5C_MODE_CA23 0x10 +#define RF5C_MODE_CA24 0x20 +#define RF5C_MODE_CA25 0x40 +#define RF5C_MODE_3STATE_BIT7 0x80 + +/* Flags for RF5C_PWR_CTL */ +#define RF5C_PWR_VCC_3V 0x01 +#define RF5C_PWR_IREQ_HIGH 0x02 +#define RF5C_PWR_INPACK_ENA 0x04 +#define RF5C_PWR_5V_DET 0x08 +#define RF5C_PWR_TC_SEL 0x10 /* Terminal Count: irq 11 or 15 */ +#define RF5C_PWR_DREQ_LOW 0x20 +#define RF5C_PWR_DREQ_OFF 0x00 /* DREQ steering control */ +#define RF5C_PWR_DREQ_INPACK 0x40 +#define RF5C_PWR_DREQ_SPKR 0x80 +#define RF5C_PWR_DREQ_IOIS16 0xc0 + +/* Values for RF5C_CHIP_ID */ +#define RF5C_CHIP_RF5C296 0x32 +#define RF5C_CHIP_RF5C396 0xb2 + +/* Flags for RF5C_MODE_CTL_3 */ +#define RF5C_MCTL3_DISABLE 0x01 /* Disable PCMCIA interface */ +#define RF5C_MCTL3_DMA_ENA 0x02 + +/* Register definitions for Ricoh PCI-to-CardBus bridges */ + +/* Extra bits in CB_BRIDGE_CONTROL */ +#define RL5C46X_BCR_3E0_ENA 0x0800 +#define RL5C46X_BCR_3E2_ENA 0x1000 + +/* Bridge Configuration Register */ +#define RL5C4XX_CONFIG 0x80 /* 16 bit */ +#define RL5C4XX_CONFIG_IO_1_MODE 0x0200 +#define RL5C4XX_CONFIG_IO_0_MODE 0x0100 +#define RL5C4XX_CONFIG_PREFETCH 0x0001 + + +/* Misc Control Register */ +#define RL5C4XX_MISC 0x0082 /* 16 bit */ +#define RL5C4XX_MISC_HW_SUSPEND_ENA 0x0002 +#define RL5C4XX_MISC_VCCEN_POL 0x0100 +#define RL5C4XX_MISC_VPPEN_POL 0x0200 +#define RL5C46X_MISC_SUSPEND 0x0001 +#define RL5C46X_MISC_PWR_SAVE_2 0x0004 +#define RL5C46X_MISC_IFACE_BUSY 0x0008 +#define RL5C46X_MISC_B_LOCK 0x0010 +#define RL5C46X_MISC_A_LOCK 0x0020 +#define RL5C46X_MISC_PCI_LOCK 0x0040 +#define RL5C47X_MISC_IFACE_BUSY 0x0004 +#define RL5C47X_MISC_PCI_INT_MASK 0x0018 +#define RL5C47X_MISC_PCI_INT_DIS 0x0020 +#define RL5C47X_MISC_SUBSYS_WR 0x0040 +#define RL5C47X_MISC_SRIRQ_ENA 0x0080 +#define RL5C47X_MISC_5V_DISABLE 0x0400 +#define RL5C47X_MISC_LED_POL 0x0800 + +/* 16-bit Interface Control Register */ +#define RL5C4XX_16BIT_CTL 0x0084 /* 16 bit */ +#define RL5C4XX_16CTL_IO_TIMING 0x0100 +#define RL5C4XX_16CTL_MEM_TIMING 0x0200 +#define RL5C46X_16CTL_LEVEL_1 0x0010 +#define RL5C46X_16CTL_LEVEL_2 0x0020 + +/* 16-bit IO and memory timing registers */ +#define RL5C4XX_16BIT_IO_0 0x0088 /* 16 bit */ +#define RL5C4XX_16BIT_MEM_0 0x0088 /* 16 bit */ +#define RL5C4XX_SETUP_MASK 0x0007 +#define RL5C4XX_SETUP_SHIFT 0 +#define RL5C4XX_CMD_MASK 0x01f0 +#define RL5C4XX_CMD_SHIFT 4 +#define RL5C4XX_HOLD_MASK 0x1c00 +#define RL5C4XX_HOLD_SHIFT 10 +#define RL5C4XX_MISC_CONTROL 0x2F /* 8 bit */ +#define RL5C4XX_ZV_ENABLE 0x08 + +#endif /* _LINUX_RICOH_H */ + + +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +//***************************************************************************** +// Beginning cirrus.h (CIRRUS chipsets) + +#ifndef _LINUX_CIRRUS_H +#define _LINUX_CIRRUS_H + +#ifndef PCI_VENDOR_ID_CIRRUS +#define PCI_VENDOR_ID_CIRRUS 0x1013 +#endif +#ifndef PCI_DEVICE_ID_CIRRUS_6729 +#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 +#endif +#ifndef PCI_DEVICE_ID_CIRRUS_6832 +#define PCI_DEVICE_ID_CIRRUS_6832 0x1110 +#endif + +#define PD67_MISC_CTL_1 0x16 /* Misc control 1 */ +#define PD67_FIFO_CTL 0x17 /* FIFO control */ +#define PD67_MISC_CTL_2 0x1E /* Misc control 2 */ +#define PD67_CHIP_INFO 0x1f /* Chip information */ +#define PD67_ATA_CTL 0x026 /* 6730: ATA control */ +#define PD67_EXT_INDEX 0x2e /* Extension index */ +#define PD67_EXT_DATA 0x2f /* Extension data */ + +/* PD6722 extension registers -- indexed in PD67_EXT_INDEX */ +#define PD67_DATA_MASK0 0x01 /* Data mask 0 */ +#define PD67_DATA_MASK1 0x02 /* Data mask 1 */ +#define PD67_DMA_CTL 0x03 /* DMA control */ + +/* PD6730 extension registers -- indexed in PD67_EXT_INDEX */ +#define PD67_EXT_CTL_1 0x03 /* Extension control 1 */ +#define PD67_MEM_PAGE(n) ((n)+5) /* PCI window bits 31:24 */ +#define PD67_EXTERN_DATA 0x0a +#define PD67_MISC_CTL_3 0x25 +#define PD67_SMB_PWR_CTL 0x26 + +/* I/O window address offset */ +#define PD67_IO_OFF(w) (0x36+((w)<<1)) + +/* Timing register sets */ +#define PD67_TIME_SETUP(n) (0x3a + 3*(n)) +#define PD67_TIME_CMD(n) (0x3b + 3*(n)) +#define PD67_TIME_RECOV(n) (0x3c + 3*(n)) + +/* Flags for PD67_MISC_CTL_1 */ +#define PD67_MC1_5V_DET 0x01 /* 5v detect */ +#define PD67_MC1_MEDIA_ENA 0x01 /* 6730: Multimedia enable */ +#define PD67_MC1_VCC_3V 0x02 /* 3.3v Vcc */ +#define PD67_MC1_PULSE_MGMT 0x04 +#define PD67_MC1_PULSE_IRQ 0x08 +#define PD67_MC1_SPKR_ENA 0x10 +#define PD67_MC1_INPACK_ENA 0x80 + +/* Flags for PD67_FIFO_CTL */ +#define PD67_FIFO_EMPTY 0x80 + +/* Flags for PD67_MISC_CTL_2 */ +#define PD67_MC2_FREQ_BYPASS 0x01 +#define PD67_MC2_DYNAMIC_MODE 0x02 +#define PD67_MC2_SUSPEND 0x04 +#define PD67_MC2_5V_CORE 0x08 +#define PD67_MC2_LED_ENA 0x10 /* IRQ 12 is LED enable */ +#define PD67_MC2_FAST_PCI 0x10 /* 6729: PCI bus > 25 MHz */ +#define PD67_MC2_3STATE_BIT7 0x20 /* Floppy change bit */ +#define PD67_MC2_DMA_MODE 0x40 +#define PD67_MC2_IRQ15_RI 0x80 /* IRQ 15 is ring enable */ + +/* Flags for PD67_CHIP_INFO */ +#define PD67_INFO_SLOTS 0x20 /* 0 = 1 slot, 1 = 2 slots */ +#define PD67_INFO_CHIP_ID 0xc0 +#define PD67_INFO_REV 0x1c + +/* Fields in PD67_TIME_* registers */ +#define PD67_TIME_SCALE 0xc0 +#define PD67_TIME_SCALE_1 0x00 +#define PD67_TIME_SCALE_16 0x40 +#define PD67_TIME_SCALE_256 0x80 +#define PD67_TIME_SCALE_4096 0xc0 +#define PD67_TIME_MULT 0x3f + +/* Fields in PD67_DMA_CTL */ +#define PD67_DMA_MODE 0xc0 +#define PD67_DMA_OFF 0x00 +#define PD67_DMA_DREQ_INPACK 0x40 +#define PD67_DMA_DREQ_WP 0x80 +#define PD67_DMA_DREQ_BVD2 0xc0 +#define PD67_DMA_PULLUP 0x20 /* Disable socket pullups? */ + +/* Fields in PD67_EXT_CTL_1 */ +#define PD67_EC1_VCC_PWR_LOCK 0x01 +#define PD67_EC1_AUTO_PWR_CLEAR 0x02 +#define PD67_EC1_LED_ENA 0x04 +#define PD67_EC1_INV_CARD_IRQ 0x08 +#define PD67_EC1_INV_MGMT_IRQ 0x10 +#define PD67_EC1_PULLUP_CTL 0x20 + +/* Fields in PD67_MISC_CTL_3 */ +#define PD67_MC3_IRQ_MASK 0x03 +#define PD67_MC3_IRQ_PCPCI 0x00 +#define PD67_MC3_IRQ_EXTERN 0x01 +#define PD67_MC3_IRQ_PCIWAY 0x02 +#define PD67_MC3_IRQ_PCI 0x03 +#define PD67_MC3_PWR_MASK 0x0c +#define PD67_MC3_PWR_SERIAL 0x00 +#define PD67_MC3_PWR_TI2202 0x08 +#define PD67_MC3_PWR_SMB 0x0c + +/* Register definitions for Cirrus PD6832 PCI-to-CardBus bridge */ + +/* PD6832 extension registers -- indexed in PD67_EXT_INDEX */ +#define PD68_EXT_CTL_2 0x0b +#define PD68_PCI_SPACE 0x22 +#define PD68_PCCARD_SPACE 0x23 +#define PD68_WINDOW_TYPE 0x24 +#define PD68_EXT_CSC 0x2e +#define PD68_MISC_CTL_4 0x2f +#define PD68_MISC_CTL_5 0x30 +#define PD68_MISC_CTL_6 0x31 + +/* Extra flags in PD67_MISC_CTL_3 */ +#define PD68_MC3_HW_SUSP 0x10 +#define PD68_MC3_MM_EXPAND 0x40 +#define PD68_MC3_MM_ARM 0x80 + +/* Bridge Control Register */ +#define PD6832_BCR_MGMT_IRQ_ENA 0x0800 + +/* Socket Number Register */ +#define PD6832_SOCKET_NUMBER 0x004c /* 8 bit */ + +#endif /* _LINUX_CIRRUS_H */ + + + diff --git a/gpxe/src/include/igmp.h b/gpxe/src/include/igmp.h new file mode 100644 index 00000000..8b3292f2 --- /dev/null +++ b/gpxe/src/include/igmp.h @@ -0,0 +1,42 @@ +#ifndef IGMP_H +#define IGMP_H + +#include "stdint.h" +#include <gpxe/in.h> + +#define IGMP_QUERY 0x11 +#define IGMPv1_REPORT 0x12 +#define IGMPv2_REPORT 0x16 +#define IGMP_LEAVE 0x17 +#define GROUP_ALL_HOSTS 0xe0000001 /* 224.0.0.1 Host byte order */ + +#define MULTICAST_MASK 0xf0000000 +#define MULTICAST_NETWORK 0xe0000000 + +enum { + IGMP_SERVER, + MAX_IGMP +}; + +struct igmp { + uint8_t type; + uint8_t response_time; + uint16_t chksum; + struct in_addr group; +} PACKED; + +struct igmp_ip_t { /* Format of an igmp ip packet */ + struct iphdr ip; + uint8_t router_alert[4]; /* Router alert option */ + struct igmp igmp; +} PACKED; + +struct igmptable_t { + struct in_addr group; + unsigned long time; +} PACKED; + +extern void join_group ( int slot, unsigned long group ); +extern void leave_group ( int slot ); + +#endif /* IGMP_H */ diff --git a/gpxe/src/include/lib.h b/gpxe/src/include/lib.h new file mode 100644 index 00000000..400ea468 --- /dev/null +++ b/gpxe/src/include/lib.h @@ -0,0 +1,42 @@ +#ifndef LIB_H +#define LIB_H + +#include <stdint.h> + +int getline(char *buf, int max); + +extern struct pci_device *dev_list; +extern int n_devs; + +extern void pci_init(void); +extern struct pci_device *pci_find_device(int vendor, int device, int devclass, +int prog_if, int index); + +void *calloc(size_t nmemb, size_t size); +void *realloc(void *ptr, size_t size); + +char *strdup(const char *s); + +int isspace(int c); + +unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base); +unsigned long long strtoull_with_suffix(const char *cp,char **endp,unsigned int base); + +unsigned int get_le32(const unsigned char *); +unsigned int get_le16(const unsigned char *); +void hexdump(const void *p, unsigned int len); + +long long simple_strtoll(const char *cp,char **endp,unsigned int base); + +#define LOADER_NOT_SUPPORT 0xbadf11e + +struct sys_info; +int elf_load(struct sys_info *, const char *filename, const char *cmdline); + +#if LINUX_LOADER +int linux_load(struct sys_info *, const char *filename, const char *cmdline); +#else +#define linux_load(x,y,z) LOADER_NOT_SUPPORT /* nop */ +#endif + +#endif /* LIB_H */ diff --git a/gpxe/src/include/libgen.h b/gpxe/src/include/libgen.h new file mode 100644 index 00000000..56a2f760 --- /dev/null +++ b/gpxe/src/include/libgen.h @@ -0,0 +1,7 @@ +#ifndef _LIBGEN_H +#define _LIBGEN_H + +extern char * basename ( char *path ); +extern char * dirname ( char *path ); + +#endif /* _LIBGEN_H */ diff --git a/gpxe/src/include/little_bswap.h b/gpxe/src/include/little_bswap.h new file mode 100644 index 00000000..e4f83753 --- /dev/null +++ b/gpxe/src/include/little_bswap.h @@ -0,0 +1,33 @@ +#ifndef ETHERBOOT_LITTLE_BSWAP_H +#define ETHERBOOT_LITTLE_BSWAP_H + +#define ntohl(x) __bswap_32(x) +#define htonl(x) __bswap_32(x) +#define ntohs(x) __bswap_16(x) +#define htons(x) __bswap_16(x) +#define cpu_to_le64(x) (x) +#define cpu_to_le32(x) (x) +#define cpu_to_le16(x) (x) +#define cpu_to_be64(x) __bswap_64(x) +#define cpu_to_be32(x) __bswap_32(x) +#define cpu_to_be16(x) __bswap_16(x) +#define le64_to_cpu(x) (x) +#define le32_to_cpu(x) (x) +#define le16_to_cpu(x) (x) +#define be64_to_cpu(x) __bswap_64(x) +#define be32_to_cpu(x) __bswap_32(x) +#define be16_to_cpu(x) __bswap_16(x) +#define cpu_to_le64s(x) do {} while (0) +#define cpu_to_le32s(x) do {} while (0) +#define cpu_to_le16s(x) do {} while (0) +#define cpu_to_be64s(x) __bswap_64s(x) +#define cpu_to_be32s(x) __bswap_32s(x) +#define cpu_to_be16s(x) __bswap_16s(x) +#define le64_to_cpus(x) do {} while (0) +#define le32_to_cpus(x) do {} while (0) +#define le16_to_cpus(x) do {} while (0) +#define be64_to_cpus(x) __bswap_64s(x) +#define be32_to_cpus(x) __bswap_32s(x) +#define be16_to_cpus(x) __bswap_16s(x) + +#endif /* ETHERBOOT_LITTLE_BSWAP_H */ diff --git a/gpxe/src/include/mii.h b/gpxe/src/include/mii.h new file mode 100644 index 00000000..34c1ca9b --- /dev/null +++ b/gpxe/src/include/mii.h @@ -0,0 +1,105 @@ +/* + * linux/mii.h: definitions for MII-compatible transceivers + * Originally drivers/net/sunhme.h. + * + * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com) + * + * Copied Form Linux 2.4.25 an unneeded items removed by: + * Timothy Legge (timlegge at etherboot dot org) + * + * 03/26/2004 + */ + +/* Generic MII registers. */ + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x07c0 /* Unused... */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_RESV 0x1c00 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ + ADVERTISE_CSMA) +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* Link partner ability register. */ +#define LPA_SLCT 0x001f /* Same as advertise selector */ +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ +#define LPA_RESV 0x1c00 /* Unused... */ +#define LPA_RFAULT 0x2000 /* Link partner faulted */ +#define LPA_LPACK 0x4000 /* Link partner acked us */ +#define LPA_NPAGE 0x8000 /* Next page bit */ + +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) + +/* Expansion register for auto-negotiation. */ +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */ +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */ +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */ +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ +#define EXPANSION_RESV 0xffe0 /* Unused... */ + +/* N-way test register. */ +#define NWAYTEST_RESV1 0x00ff /* Unused... */ +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ +#define NWAYTEST_RESV2 0xfe00 /* Unused... */ + diff --git a/gpxe/src/include/nfs.h b/gpxe/src/include/nfs.h new file mode 100644 index 00000000..0877bb66 --- /dev/null +++ b/gpxe/src/include/nfs.h @@ -0,0 +1,63 @@ +#ifndef _NFS_H +#define _NFS_H + +#define SUNRPC_PORT 111 + +#define PROG_PORTMAP 100000 +#define PROG_NFS 100003 +#define PROG_MOUNT 100005 + +#define MSG_CALL 0 +#define MSG_REPLY 1 + +#define PORTMAP_GETPORT 3 + +#define MOUNT_ADDENTRY 1 +#define MOUNT_UMOUNTALL 4 + +#define NFS_LOOKUP 4 +#define NFS_READLINK 5 +#define NFS_READ 6 + +#define NFS_FHSIZE 32 + +#define NFSERR_PERM 1 +#define NFSERR_NOENT 2 +#define NFSERR_ACCES 13 +#define NFSERR_ISDIR 21 +#define NFSERR_INVAL 22 + +/* Block size used for NFS read accesses. A RPC reply packet (including all + * headers) must fit within a single Ethernet frame to avoid fragmentation. + * Chosen to be a power of two, as most NFS servers are optimized for this. */ +#define NFS_READ_SIZE 1024 + +#define NFS_MAXLINKDEPTH 16 + +struct rpc_t { + struct iphdr ip; + struct udphdr udp; + union { + uint8_t data[300]; /* longest RPC call must fit!!!! */ + struct { + uint32_t id; + uint32_t type; + uint32_t rpcvers; + uint32_t prog; + uint32_t vers; + uint32_t proc; + uint32_t data[1]; + } call; + struct { + uint32_t id; + uint32_t type; + uint32_t rstatus; + uint32_t verifier; + uint32_t v2; + uint32_t astatus; + uint32_t data[1]; + } reply; + } u; +} PACKED; + +#endif /* _NFS_H */ diff --git a/gpxe/src/include/nic.h b/gpxe/src/include/nic.h new file mode 100644 index 00000000..65e4be71 --- /dev/null +++ b/gpxe/src/include/nic.h @@ -0,0 +1,272 @@ + /* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + +#ifndef NIC_H +#define NIC_H + +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <byteswap.h> +#include <gpxe/pci.h> +#include <gpxe/isapnp.h> +#include <gpxe/isa.h> +#include <gpxe/eisa.h> +#include <gpxe/mca.h> +#include "dhcp.h" + +typedef enum { + DISABLE = 0, + ENABLE, + FORCE +} irq_action_t; + +typedef enum duplex { + HALF_DUPLEX = 1, + FULL_DUPLEX +} duplex_t; + +/* + * Structure returned from eth_probe and passed to other driver + * functions. + */ +struct nic { + struct nic_operations *nic_op; + int flags; /* driver specific flags */ + unsigned char *node_addr; + unsigned char *packet; + unsigned int packetlen; + unsigned int ioaddr; + unsigned char irqno; + unsigned int mbps; + duplex_t duplex; + struct dhcp_dev_id dhcp_dev_id; + void *priv_data; /* driver private data */ +}; + +struct nic_operations { + int ( *connect ) ( struct nic * ); + int ( *poll ) ( struct nic *, int retrieve ); + void ( *transmit ) ( struct nic *, const char *, + unsigned int, unsigned int, const char * ); + void ( *irq ) ( struct nic *, irq_action_t ); +}; + +extern struct nic nic; + +static inline int eth_poll ( int retrieve ) { + return nic.nic_op->poll ( &nic, retrieve ); +} + +static inline void eth_transmit ( const char *dest, unsigned int type, + unsigned int size, const void *packet ) { + nic.nic_op->transmit ( &nic, dest, type, size, packet ); +} + +/* + * Function prototypes + * + */ +extern int dummy_connect ( struct nic *nic ); +extern void dummy_irq ( struct nic *nic, irq_action_t irq_action ); +extern int legacy_probe ( void *hwdev, + void ( * set_drvdata ) ( void *hwdev, void *priv ), + struct device *dev, + int ( * probe ) ( struct nic *nic, void *hwdev ), + void ( * disable ) ( struct nic *nic, void *hwdev )); +void legacy_remove ( void *hwdev, + void * ( * get_drvdata ) ( void *hwdev ), + void ( * disable ) ( struct nic *nic, void *hwdev ) ); + +#define PCI_DRIVER(_name,_ids,_class) \ + static inline int \ + _name ## _pci_legacy_probe ( struct pci_device *pci, \ + const struct pci_device_id *id ); \ + static inline void \ + _name ## _pci_legacy_remove ( struct pci_device *pci ); \ + struct pci_driver _name __pci_driver = { \ + .ids = _ids, \ + .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ + .probe = _name ## _pci_legacy_probe, \ + .remove = _name ## _pci_legacy_remove, \ + }; \ + REQUIRE_OBJECT ( pci ); + +static inline void legacy_pci_set_drvdata ( void *hwdev, void *priv ) { + pci_set_drvdata ( hwdev, priv ); +} +static inline void * legacy_pci_get_drvdata ( void *hwdev ) { + return pci_get_drvdata ( hwdev ); +} + +#define ISAPNP_DRIVER(_name,_ids) \ + static inline int \ + _name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp, \ + const struct isapnp_device_id *id ); \ + static inline void \ + _name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ); \ + struct isapnp_driver _name __isapnp_driver = { \ + .ids = _ids, \ + .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ + .probe = _name ## _isapnp_legacy_probe, \ + .remove = _name ## _isapnp_legacy_remove, \ + }; \ + REQUIRE_OBJECT ( isapnp ); + +static inline void legacy_isapnp_set_drvdata ( void *hwdev, void *priv ) { + isapnp_set_drvdata ( hwdev, priv ); +} +static inline void * legacy_isapnp_get_drvdata ( void *hwdev ) { + return isapnp_get_drvdata ( hwdev ); +} + +#define EISA_DRIVER(_name,_ids) \ + static inline int \ + _name ## _eisa_legacy_probe ( struct eisa_device *eisa, \ + const struct eisa_device_id *id ); \ + static inline void \ + _name ## _eisa_legacy_remove ( struct eisa_device *eisa ); \ + struct eisa_driver _name __eisa_driver = { \ + .ids = _ids, \ + .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ + .probe = _name ## _eisa_legacy_probe, \ + .remove = _name ## _eisa_legacy_remove, \ + }; \ + REQUIRE_OBJECT ( eisa ); + +static inline void legacy_eisa_set_drvdata ( void *hwdev, void *priv ) { + eisa_set_drvdata ( hwdev, priv ); +} +static inline void * legacy_eisa_get_drvdata ( void *hwdev ) { + return eisa_get_drvdata ( hwdev ); +} + +#define MCA_DRIVER(_name,_ids) \ + static inline int \ + _name ## _mca_legacy_probe ( struct mca_device *mca, \ + const struct mca_device_id *id ); \ + static inline void \ + _name ## _mca_legacy_remove ( struct mca_device *mca ); \ + struct mca_driver _name __mca_driver = { \ + .ids = _ids, \ + .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \ + .probe = _name ## _mca_legacy_probe, \ + .remove = _name ## _mca_legacy_remove, \ + }; \ + REQUIRE_OBJECT ( mca ); + +static inline void legacy_mca_set_drvdata ( void *hwdev, void *priv ) { + mca_set_drvdata ( hwdev, priv ); +} +static inline void * legacy_mca_get_drvdata ( void *hwdev ) { + return mca_get_drvdata ( hwdev ); +} + +#define ISA_DRIVER(_name,_probe_addrs,_probe_addr,_vendor_id,_prod_id) \ + static inline int \ + _name ## _isa_legacy_probe ( struct isa_device *isa ); \ + static inline int \ + _name ## _isa_legacy_probe_at_addr ( struct isa_device *isa ) { \ + if ( ! _probe_addr ( isa->ioaddr ) ) \ + return -ENODEV; \ + return _name ## _isa_legacy_probe ( isa ); \ + } \ + static inline void \ + _name ## _isa_legacy_remove ( struct isa_device *isa ); \ + static const char _name ## _text[]; \ + struct isa_driver _name __isa_driver = { \ + .name = _name ## _text, \ + .probe_addrs = _probe_addrs, \ + .addr_count = ( sizeof ( _probe_addrs ) / \ + sizeof ( _probe_addrs[0] ) ), \ + .vendor_id = _vendor_id, \ + .prod_id = _prod_id, \ + .probe = _name ## _isa_legacy_probe_at_addr, \ + .remove = _name ## _isa_legacy_remove, \ + }; \ + REQUIRE_OBJECT ( isa ); + +static inline void legacy_isa_set_drvdata ( void *hwdev, void *priv ) { + isa_set_drvdata ( hwdev, priv ); +} +static inline void * legacy_isa_get_drvdata ( void *hwdev ) { + return isa_get_drvdata ( hwdev ); +} + +#undef DRIVER +#define DRIVER(_name_text,_unused2,_unused3,_name,_probe,_disable) \ + static const char _name ## _text[] = _name_text; \ + static inline int \ + _name ## _probe ( struct nic *nic, void *hwdev ) { \ + return _probe ( nic, hwdev ); \ + } \ + static inline void \ + _name ## _disable ( struct nic *nic, void *hwdev ) { \ + void ( * _unsafe_disable ) () = _disable; \ + _unsafe_disable ( nic, hwdev ); \ + } \ + static inline int \ + _name ## _pci_legacy_probe ( struct pci_device *pci, \ + const struct pci_device_id *id __unused ) { \ + return legacy_probe ( pci, legacy_pci_set_drvdata, \ + &pci->dev, _name ## _probe, \ + _name ## _disable ); \ + } \ + static inline void \ + _name ## _pci_legacy_remove ( struct pci_device *pci ) { \ + return legacy_remove ( pci, legacy_pci_get_drvdata, \ + _name ## _disable ); \ + } \ + static inline int \ + _name ## _isapnp_legacy_probe ( struct isapnp_device *isapnp, \ + const struct isapnp_device_id *id __unused ) { \ + return legacy_probe ( isapnp, legacy_isapnp_set_drvdata, \ + &isapnp->dev, _name ## _probe, \ + _name ## _disable ); \ + } \ + static inline void \ + _name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ) { \ + return legacy_remove ( isapnp, legacy_isapnp_get_drvdata, \ + _name ## _disable ); \ + } \ + static inline int \ + _name ## _eisa_legacy_probe ( struct eisa_device *eisa, \ + const struct eisa_device_id *id __unused ) { \ + return legacy_probe ( eisa, legacy_eisa_set_drvdata, \ + &eisa->dev, _name ## _probe, \ + _name ## _disable ); \ + } \ + static inline void \ + _name ## _eisa_legacy_remove ( struct eisa_device *eisa ) { \ + return legacy_remove ( eisa, legacy_eisa_get_drvdata, \ + _name ## _disable ); \ + } \ + static inline int \ + _name ## _mca_legacy_probe ( struct mca_device *mca, \ + const struct mca_device_id *id __unused ) { \ + return legacy_probe ( mca, legacy_mca_set_drvdata, \ + &mca->dev, _name ## _probe, \ + _name ## _disable ); \ + } \ + static inline void \ + _name ## _mca_legacy_remove ( struct mca_device *mca ) { \ + return legacy_remove ( mca, legacy_mca_get_drvdata, \ + _name ## _disable ); \ + } \ + static inline int \ + _name ## _isa_legacy_probe ( struct isa_device *isa ) { \ + return legacy_probe ( isa, legacy_isa_set_drvdata, \ + &isa->dev, _name ## _probe, \ + _name ## _disable ); \ + } \ + static inline void \ + _name ## _isa_legacy_remove ( struct isa_device *isa ) { \ + return legacy_remove ( isa, legacy_isa_get_drvdata, \ + _name ## _disable ); \ + } + +#endif /* NIC_H */ diff --git a/gpxe/src/include/nmb.h b/gpxe/src/include/nmb.h new file mode 100644 index 00000000..3e551ffd --- /dev/null +++ b/gpxe/src/include/nmb.h @@ -0,0 +1,22 @@ +#ifndef NMB_H +#define NMB_H + +#include <gpxe/dns.h> + +/* + * NetBIOS name query packets are basically the same as DNS packets, + * though the resource record format is different. + * + */ + +#define DNS_TYPE_NB 0x20 +#define DNS_FLAG_BROADCAST ( 0x01 << 4 ) +#define NBNS_UDP_PORT 137 + +struct dns_rr_info_nb { + struct dns_rr_info info; + uint16_t nb_flags; + struct in_addr nb_address; +} __attribute__ (( packed )); + +#endif /* NMB_H */ diff --git a/gpxe/src/include/old_tcp.h b/gpxe/src/include/old_tcp.h new file mode 100644 index 00000000..93e1485e --- /dev/null +++ b/gpxe/src/include/old_tcp.h @@ -0,0 +1,37 @@ +#ifndef _TCP_H +#define _TCP_H + +#define TCP_INITIAL_TIMEOUT (3*TICKS_PER_SEC) +#define TCP_MAX_TIMEOUT (60*TICKS_PER_SEC) +#define TCP_MIN_TIMEOUT (TICKS_PER_SEC) +#define TCP_MAX_RETRY 10 +#define TCP_MAX_HEADER ((int)sizeof(struct iphdr)+64) +#define TCP_MIN_WINDOW (1500-TCP_MAX_HEADER) +#define TCP_MAX_WINDOW (65535-TCP_MAX_HEADER) + +#define FIN 1 +#define SYN 2 +#define RST 4 +#define PSH 8 +#define ACK 16 +#define URG 32 + + +struct tcphdr { + uint16_t src; + uint16_t dst; + int32_t seq; + int32_t ack; + uint16_t ctrl; + uint16_t window; + uint16_t chksum; + uint16_t urgent; +}; + +extern int tcp_transaction ( unsigned long destip, unsigned int destsock, + void *ptr, + int (*send)(int len, void *buf, void *ptr), + int (*recv)(int len, const void *buf, void *ptr)); + + +#endif /* _TCP_H */ diff --git a/gpxe/src/include/pc_kbd.h b/gpxe/src/include/pc_kbd.h new file mode 100644 index 00000000..c125efa0 --- /dev/null +++ b/gpxe/src/include/pc_kbd.h @@ -0,0 +1,7 @@ +#ifndef _PC_KBD_H +#define _PC_KBD_H + +int kbd_ischar(void); + +int kbd_getc(void); +#endif diff --git a/gpxe/src/include/pcmcia-opts.h b/gpxe/src/include/pcmcia-opts.h new file mode 100644 index 00000000..70dc0921 --- /dev/null +++ b/gpxe/src/include/pcmcia-opts.h @@ -0,0 +1,23 @@ +// pcmcia-opts.h +// special options file for development time. Later this could end in Config(?) +#ifndef __pcmciaopts +#define __pcmciaopts + + #define _yes_ 1 + #define _no_ 0 + + #define SUPPORT_I82365 (_yes_) +// #define SUPPORT_YENTA (_no_) +// #define SUPPORT_SOME_DRIVER (_no_) + + #define PCMCIA_SHUTDOWN (_yes_) + #define MAP_ATTRMEM_TO 0xd0000 + #define MAP_ATTRMEM_LEN 0x02000 + + #define PDEBUG 3 + // The higher the more output you get, 0..3 + // Not fully implemented though, but for the future... + + #undef _yes_ + #undef _no_ +#endif diff --git a/gpxe/src/include/pcmcia.h b/gpxe/src/include/pcmcia.h new file mode 100644 index 00000000..d528bea5 --- /dev/null +++ b/gpxe/src/include/pcmcia.h @@ -0,0 +1,156 @@ +// pcmcia.h - Header file for PCMCIA support + +#ifndef PCMCIA_H +#define PCMCIA_H + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +typedef u_short ioaddr_t; +extern int sockets; + +#define MAXPCCSOCKS 8 +#define MAXPCCCONFIGS 8 + +typedef enum ebpdriver_t { I82365, SOMEDRIVER } ebpdriver_t; +typedef enum interface_func_t { INIT, SHUTDOWN, MAPATTRMEM, UNMAPATTRMEM, SELECTCONFIG } interface_func_t; +typedef enum ebpstatus_t { EMPTY, HASCARD, INITIALIZED, SUSPENDED, OTHERDEVICE, UNKNOWN } ebpstatus_t; + +struct driver_interact_t { + ebpdriver_t id; + int (*f)(interface_func_t,int,int,int,int); + char *name; +}; +struct pccsock_t { + ebpdriver_t device; + int drivernum; + ebpstatus_t status; + // Internal usage of the drivers: + int internalid; + int flags; + int ioaddr; + int type; + int configoffset; + int possibleconfignum; + int stringoffset; + u_int stringlength; + int rmask0; +}; + +extern struct pccsock_t pccsock[MAXPCCSOCKS]; +extern u_int pccsocks; + +struct pcc_config_t { + u_char index; + u_char irq; + int iowin; + int iolen; +}; + + +int i82365_interfacer(interface_func_t,int,int,int,void *); +void sleepticks(int); + +#define EINVAL 22 + + +//*********************************************************** cc.h: +/* Definitions for card status flags for GetStatus */ +#define SS_WRPROT 0x0001 +#define SS_CARDLOCK 0x0002 +#define SS_EJECTION 0x0004 +#define SS_INSERTION 0x0008 +#define SS_BATDEAD 0x0010 +#define SS_BATWARN 0x0020 +#define SS_READY 0x0040 +#define SS_DETECT 0x0080 +#define SS_POWERON 0x0100 +#define SS_GPI 0x0200 +#define SS_STSCHG 0x0400 +#define SS_CARDBUS 0x0800 +#define SS_3VCARD 0x1000 +#define SS_XVCARD 0x2000 +#define SS_PENDING 0x4000 + +/* cc.h: for InquireSocket */ +typedef struct socket_cap_t { + u_int features; + u_int irq_mask; + u_int map_size; + ioaddr_t io_offset; + u_char pci_irq; + //struct pci_dev *cb_dev; + //struct bus_operations *bus; + void *cb_dev; + void *bus; +} socket_cap_t; +/* InquireSocket capabilities */ +#define SS_CAP_PAGE_REGS 0x0001 +#define SS_CAP_VIRTUAL_BUS 0x0002 +#define SS_CAP_MEM_ALIGN 0x0004 +#define SS_CAP_STATIC_MAP 0x0008 +#define SS_CAP_PCCARD 0x4000 +#define SS_CAP_CARDBUS 0x8000 + +/* for GetSocket, SetSocket */ +typedef struct socket_state_t { + u_int flags; + u_int csc_mask; + u_char Vcc, Vpp; + u_char io_irq; +} socket_state_t; + +extern socket_state_t dead_socket; + +/* Socket configuration flags */ +#define SS_PWR_AUTO 0x0010 +#define SS_IOCARD 0x0020 +#define SS_RESET 0x0040 +#define SS_DMA_MODE 0x0080 +#define SS_SPKR_ENA 0x0100 +#define SS_OUTPUT_ENA 0x0200 +#define SS_DEBOUNCED 0x0400 /* Tell driver that the debounce delay has ended */ +#define SS_ZVCARD 0x0800 + +/* Flags for I/O port and memory windows */ +#define MAP_ACTIVE 0x01 +#define MAP_16BIT 0x02 +#define MAP_AUTOSZ 0x04 +#define MAP_0WS 0x08 +#define MAP_WRPROT 0x10 +#define MAP_ATTRIB 0x20 +#define MAP_USE_WAIT 0x40 +#define MAP_PREFETCH 0x80 + +/* Use this just for bridge windows */ +#define MAP_IOSPACE 0x20 + +typedef struct pccard_io_map { + u_char map; + u_char flags; + u_short speed; + ioaddr_t start, stop; +} pccard_io_map; + + +typedef struct pccard_mem_map { + u_char map; + u_char flags; + u_short speed; + u_long sys_start, sys_stop; + u_int card_start; +} pccard_mem_map; + +typedef struct cb_bridge_map { + u_char map; + u_char flags; + u_int start, stop; +} cb_bridge_map; +// need the global function pointer struct? *TODO* +//************************************* end cc.h + + + +#endif /* PCMCIA_H */ diff --git a/gpxe/src/include/pxe.h b/gpxe/src/include/pxe.h new file mode 100644 index 00000000..6d332ac7 --- /dev/null +++ b/gpxe/src/include/pxe.h @@ -0,0 +1,151 @@ +#ifndef PXE_H +#define PXE_H + +#include "pxe_types.h" +#include "pxe_api.h" +#include <gpxe/device.h> + +/* Parameter block for pxenv_unknown() */ +struct s_PXENV_UNKNOWN { + PXENV_STATUS_t Status; /**< PXE status code */ +} 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; +}; + +typedef union u_PXENV_ANY PXENV_ANY_t; + +/** 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; +} 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; +} 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; +} 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 void pxe_set_netdev ( struct net_device *netdev ); + +extern void pxe_set_cached_filename ( const unsigned char *filename ); + +#endif /* PXE_H */ diff --git a/gpxe/src/include/pxe_api.h b/gpxe/src/include/pxe_api.h new file mode 100644 index 00000000..b3d4bca8 --- /dev/null +++ b/gpxe/src/include/pxe_api.h @@ -0,0 +1,1841 @@ +#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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/** @file + * + * Preboot eXecution Environment (PXE) API + * + */ + +#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; +} 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; +} 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 */ +} PACKED; + +typedef struct s_PXENV_UNLOAD_STACK PXENV_UNLOAD_STACK_t; + +extern PXENV_EXIT_t pxenv_unload_stack ( struct s_PXENV_UNLOAD_STACK + *unload_stack ); + +/** @} */ /* 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 */ +} 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; +} PACKED; + +typedef struct bootph BOOTPLAYER_t; + +extern PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO + *get_cached_info ); + +/** @} */ /* 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; + +extern PXENV_EXIT_t pxenv_restart_tftp ( struct s_PXENV_TFTP_READ_FILE + *restart_tftp ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_START_UNDI PXENV_START_UNDI_t; + +extern PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_STOP_UNDI PXENV_STOP_UNDI_t; + +extern PXENV_EXIT_t pxenv_stop_undi ( struct s_PXENV_STOP_UNDI *stop_undi ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_START_BASE PXENV_START_BASE_t; + +extern PXENV_EXIT_t pxenv_start_base ( struct s_PXENV_START_BASE *start_base ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_STOP_BASE PXENV_STOP_BASE_t; + +extern PXENV_EXIT_t pxenv_stop_base ( struct s_PXENV_STOP_BASE *stop_base ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_TFTP_OPEN PXENV_TFTP_OPEN_t; + +extern PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_TFTP_CLOSE PXENV_TFTP_CLOSE_t; + +extern PXENV_EXIT_t pxenv_tftp_close ( struct s_PXENV_TFTP_CLOSE *tftp_close ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_TFTP_READ PXENV_TFTP_READ_t; + +extern PXENV_EXIT_t pxenv_tftp_read ( struct s_PXENV_TFTP_READ *tftp_read ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_TFTP_READ_FILE PXENV_TFTP_READ_FILE_t; + +extern PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE + *tftp_read_file ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_TFTP_GET_FSIZE PXENV_TFTP_GET_FSIZE_t; + +extern PXENV_EXIT_t pxenv_tftp_get_fsize ( struct s_PXENV_TFTP_GET_FSIZE + *get_fsize ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UDP_OPEN PXENV_UDP_OPEN_t; + +extern PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *udp_open ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UDP_CLOSE PXENV_UDP_CLOSE_t; + +extern PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *udp_close ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UDP_WRITE PXENV_UDP_WRITE_t; + +extern PXENV_EXIT_t pxenv_udp_write ( struct s_PXENV_UDP_WRITE *udp_write ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UDP_READ PXENV_UDP_READ_t; + +extern PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *udp_read ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_STARTUP PXENV_UNDI_STARTUP_t; + +extern PXENV_EXIT_t pxenv_undi_startup ( struct s_PXENV_UNDI_STARTUP + *undi_startup ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_CLEANUP PXENV_UNDI_CLEANUP_t; + +extern PXENV_EXIT_t pxenv_undi_cleanup ( struct s_PXENV_UNDI_CLEANUP + *undi_cleanup ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_INITIALIZE PXENV_UNDI_INITIALIZE_t; + +extern PXENV_EXIT_t pxenv_undi_initialize ( struct s_PXENV_UNDI_INITIALIZE + *undi_initialize ); + +/** @} */ /* 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]; +} 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; +} PACKED; + +typedef struct s_PXENV_UNDI_RESET PXENV_UNDI_RESET_t; + +extern PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET + *undi_reset_adapter ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_SHUTDOWN PXENV_UNDI_SHUTDOWN_t; + +extern PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN + *undi_shutdown ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_UNDI_OPEN PXENV_UNDI_OPEN_t; + +extern PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_CLOSE PXENV_UNDI_CLOSE_t; + +extern PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close ); + +/** @} */ /* 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]; +} 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_TRANSMIT PXENV_UNDI_TRANSMIT_t; + +extern PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT + *undi_transmit ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS PXENV_UNDI_SET_MCAST_ADDRESS_t; + +extern PXENV_EXIT_t pxenv_undi_set_mcast_address ( + struct s_PXENV_UNDI_SET_MCAST_ADDRESS *undi_set_mcast_address ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS PXENV_UNDI_SET_STATION_ADDRESS_t; + +extern PXENV_EXIT_t pxenv_undi_set_station_address ( + struct s_PXENV_UNDI_SET_STATION_ADDRESS *undi_set_station_address ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_UNDI_SET_PACKET_FILTER PXENV_UNDI_SET_PACKET_FILTER_t; + +extern PXENV_EXIT_t pxenv_undi_set_packet_filter ( + struct s_PXENV_UNDI_SET_PACKET_FILTER *undi_set_packet_filter ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_GET_INFORMATION PXENV_UNDI_GET_INFORMATION_t; + +extern PXENV_EXIT_t pxenv_undi_get_information ( + struct s_PXENV_UNDI_GET_INFORMATION *undi_get_information ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_GET_STATISTICS PXENV_UNDI_GET_STATISTICS_t; + +extern PXENV_EXIT_t pxenv_undi_get_statistics ( + struct s_PXENV_UNDI_GET_STATISTICS *undi_get_statistics ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_CLEAR_STATISTICS PXENV_UNDI_CLEAR_STATISTICS_t; + +extern PXENV_EXIT_t pxenv_undi_clear_statistics ( + struct s_PXENV_UNDI_CLEAR_STATISTICS *undi_clear_statistics ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_INITIATE_DIAGS PXENV_UNDI_INITIATE_DIAGS_t; + +extern PXENV_EXIT_t pxenv_undi_initiate_diags ( + struct s_PXENV_UNDI_INITIATE_DIAGS *undi_initiate_diags ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_FORCE_INTERRUPT PXENV_UNDI_FORCE_INTERRUPT_t; + +extern PXENV_EXIT_t pxenv_undi_force_interrupt ( + struct s_PXENV_UNDI_FORCE_INTERRUPT *undi_force_interrupt ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS PXENV_UNDI_GET_MCAST_ADDRESS_t; + +extern PXENV_EXIT_t pxenv_undi_get_mcast_address ( + struct s_PXENV_UNDI_GET_MCAST_ADDRESS *undi_get_mcast_address ); + +/** @} */ /* 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 */ +} 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; +} 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; +} PACKED; + +typedef struct s_PXENV_UNDI_GET_NIC_TYPE PXENV_UNDI_GET_NIC_TYPE_t; + +extern PXENV_EXIT_t pxenv_undi_get_nic_type ( + struct s_PXENV_UNDI_GET_NIC_TYPE *undi_get_nic_type ); + +/** @} */ /* 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 + +/** 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 */ +} PACKED; + +typedef struct s_PXENV_UNDI_GET_IFACE_INFO PXENV_UNDI_GET_IFACE_INFO_t; + +extern PXENV_EXIT_t pxenv_undi_get_iface_info ( + struct s_PXENV_UNDI_GET_IFACE_INFO *undi_get_iface_info ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_UNDI_GET_STATE PXENV_UNDI_GET_STATE_t; + +extern PXENV_EXIT_t pxenv_undi_get_state ( struct s_PXENV_UNDI_GET_STATE + *undi_get_state ); + +/** @} */ /* 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; +} PACKED; + +typedef struct s_PXENV_UNDI_ISR PXENV_UNDI_ISR_t; + +extern PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ); + +/** @} */ /* pxenv_undi_isr */ + +/** @} */ /* pxe_undi_api */ + +/** @defgroup pxe_file_api PXE FILE API + * + * POSIX-like file operations + * + * @{ + */ + +/** @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 */ +} PACKED; + +typedef struct s_PXENV_FILE_OPEN PXENV_FILE_OPEN_t; + +extern PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_FILE_CLOSE PXENV_FILE_CLOSE_t; + +extern PXENV_EXIT_t pxenv_file_close ( struct s_PXENV_FILE_CLOSE + *file_close ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_FILE_SELECT PXENV_FILE_SELECT_t; + +extern PXENV_EXIT_t pxenv_file_select ( struct s_PXENV_FILE_SELECT + *file_select ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_FILE_READ PXENV_FILE_READ_t; + +extern PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_GET_FILE_SIZE PXENV_GET_FILE_SIZE_t; + +extern PXENV_EXIT_t pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE + *get_file_size ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t; + +extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ); + +/** @} */ /* 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 */ +} PACKED; + +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t; + +extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ); + +/** @} */ /* pxenv_file_api_check */ + +/** @} */ /* 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; +} PACKED; + +typedef struct s_UNDI_LOADER UNDI_LOADER_t; + +extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader ); + +/** @} */ /* 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/gpxe/src/include/pxe_types.h b/gpxe/src/include/pxe_types.h new file mode 100644 index 00000000..e31af062 --- /dev/null +++ b/gpxe/src/include/pxe_types.h @@ -0,0 +1,126 @@ +#ifndef PXE_TYPES_H +#define PXE_TYPES_H + +/** @file + * + * PXE data types + * + */ + +#include "stdint.h" +#include "pxe_addr.h" /* Architecture-specific PXE definitions */ +#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 */ +} 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 */ +} PACKED SEGDESC_t; + +/** @} */ /* pxe_types */ + +/** @} */ /* pxe */ + +#endif /* PXE_TYPES_H */ diff --git a/gpxe/src/include/readline/readline.h b/gpxe/src/include/readline/readline.h new file mode 100644 index 00000000..1a03b483 --- /dev/null +++ b/gpxe/src/include/readline/readline.h @@ -0,0 +1,12 @@ +#ifndef _READLINE_H +#define _READLINE_H + +/** @file + * + * Minmal readline + * + */ + +extern char * __malloc readline ( const char *prompt ); + +#endif /* _READLINE_H */ diff --git a/gpxe/src/include/stdarg.h b/gpxe/src/include/stdarg.h new file mode 100644 index 00000000..a4eb711d --- /dev/null +++ b/gpxe/src/include/stdarg.h @@ -0,0 +1,10 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef __builtin_va_list va_list; +#define va_start( ap, last ) __builtin_va_start ( ap, last ) +#define va_arg( ap, type ) __builtin_va_arg ( ap, type ) +#define va_end( ap ) __builtin_va_end ( ap ) +#define va_copy( dest, src ) __builtin_va_copy ( dest, src ) + +#endif /* _STDARG_H */ diff --git a/gpxe/src/include/stddef.h b/gpxe/src/include/stddef.h new file mode 100644 index 00000000..6f91d219 --- /dev/null +++ b/gpxe/src/include/stddef.h @@ -0,0 +1,18 @@ +#ifndef STDDEF_H +#define STDDEF_H + +/* for size_t */ +#include <stdint.h> + +#undef NULL +#define NULL ((void *)0) + +#undef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +#undef container_of +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#endif /* STDDEF_H */ diff --git a/gpxe/src/include/stdint.h b/gpxe/src/include/stdint.h new file mode 100644 index 00000000..4b0e44f2 --- /dev/null +++ b/gpxe/src/include/stdint.h @@ -0,0 +1,24 @@ +#ifndef _STDINT_H +#define _STDINT_H + +#include <bits/stdint.h> + +typedef int8_t s8; +typedef uint8_t u8; +typedef int16_t s16; +typedef uint16_t u16; +typedef int32_t s32; +typedef uint32_t u32; +typedef int64_t s64; +typedef uint64_t u64; + +typedef int8_t int8; +typedef uint8_t uint8; +typedef int16_t int16; +typedef uint16_t uint16; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; + +#endif /* _STDINT_H */ diff --git a/gpxe/src/include/stdio.h b/gpxe/src/include/stdio.h new file mode 100644 index 00000000..82077e20 --- /dev/null +++ b/gpxe/src/include/stdio.h @@ -0,0 +1,45 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#include <stdint.h> +#include <stdarg.h> + +extern int __attribute__ (( format ( printf, 1, 2 ) )) +printf ( const char *fmt, ... ); + +extern int __attribute__ (( format ( printf, 3, 4 ) )) +snprintf ( char *buf, size_t size, const char *fmt, ... ); + +extern int __attribute__ (( format ( printf, 2, 3 ) )) +asprintf ( char **strp, const char *fmt, ... ); + +extern int vprintf ( const char *fmt, va_list args ); + +extern int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args ); + +extern int vasprintf ( char **strp, const char *fmt, va_list args ); + +/** + * Write a formatted string to a buffer + * + * @v buf Buffer into which to write the string + * @v fmt Format string + * @v ... Arguments corresponding to the format string + * @ret len Length of formatted string + */ +#define sprintf( buf, fmt, ... ) \ + snprintf ( (buf), ~( ( size_t ) 0 ), (fmt), ## __VA_ARGS__ ) + +/** + * Write a formatted string to a buffer + * + * @v buf Buffer into which to write the string + * @v fmt Format string + * @v args Arguments corresponding to the format string + * @ret len Length of formatted string + */ +static inline int vsprintf ( char *buf, const char *fmt, va_list args ) { + return vsnprintf ( buf, ~( ( size_t ) 0 ), fmt, args ); +} + +#endif /* _STDIO_H */ diff --git a/gpxe/src/include/stdlib.h b/gpxe/src/include/stdlib.h new file mode 100644 index 00000000..ae996962 --- /dev/null +++ b/gpxe/src/include/stdlib.h @@ -0,0 +1,72 @@ +#ifndef STDLIB_H +#define STDLIB_H + +#include <stdint.h> +#include <assert.h> + +/***************************************************************************** + * + * Numeric parsing + * + **************************************************************************** + */ + +extern unsigned long strtoul ( const char *p, char **endp, int base ); + +/***************************************************************************** + * + * Memory allocation + * + **************************************************************************** + */ + +extern void * __malloc malloc ( size_t size ); +extern void * realloc ( void *old_ptr, size_t new_size ); +extern void free ( void *ptr ); +extern void * __malloc zalloc ( size_t len ); + +/** + * Allocate cleared memory + * + * @v nmemb Number of members + * @v size Size of each member + * @ret ptr Allocated memory + * + * Allocate memory as per malloc(), and zero it. + * + * This is implemented as a static inline, with the body of the + * function in zalloc(), since in most cases @c nmemb will be 1 and + * doing the multiply is just wasteful. + */ +static inline void * __malloc calloc ( size_t nmemb, size_t size ) { + return zalloc ( nmemb * size ); +} + +/***************************************************************************** + * + * Random number generation + * + **************************************************************************** + */ + +extern long int random ( void ); +extern void srandom ( unsigned int seed ); + +static inline int rand ( void ) { + return random(); +} + +static inline void srand ( unsigned int seed ) { + srandom ( seed ); +} + +/***************************************************************************** + * + * Miscellaneous + * + **************************************************************************** + */ + +extern int system ( const char *command ); + +#endif /* STDLIB_H */ diff --git a/gpxe/src/include/string.h b/gpxe/src/include/string.h new file mode 100644 index 00000000..a2894a3a --- /dev/null +++ b/gpxe/src/include/string.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 2004 Tobias Lorenz + * + * string handling functions + * based on linux/include/linux/ctype.h + * and linux/include/linux/string.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef ETHERBOOT_STRING_H +#define ETHERBOOT_STRING_H + +#include <stddef.h> +#include <bits/string.h> + +int __pure strnicmp(const char *s1, const char *s2, size_t len) __nonnull; +char * strcpy(char * dest,const char *src) __nonnull; +char * strncpy(char * dest,const char *src,size_t count) __nonnull; +char * strcat(char * dest, const char * src) __nonnull; +char * strncat(char *dest, const char *src, size_t count) __nonnull; +int __pure strcmp(const char * cs,const char * ct) __nonnull; +int __pure strncmp(const char * cs,const char * ct, + size_t count) __nonnull; +char * __pure strchr(const char * s, int c) __nonnull; +char * __pure strrchr(const char * s, int c) __nonnull; +size_t __pure strlen(const char * s) __nonnull; +size_t __pure strnlen(const char * s, size_t count) __nonnull; +size_t __pure strspn(const char *s, const char *accept) __nonnull; +size_t __pure strcspn(const char *s, const char *reject) __nonnull; +char * __pure strpbrk(const char * cs,const char * ct) __nonnull; +char * strtok(char * s,const char * ct) __nonnull; +char * strsep(char **s, const char *ct) __nonnull; +void * memset(void * s,int c,size_t count) __nonnull; +void * memmove(void * dest,const void *src,size_t count) __nonnull; +int __pure memcmp(const void * cs,const void * ct, + size_t count) __nonnull; +void * __pure memscan(const void * addr, int c, size_t size) __nonnull; +char * __pure strstr(const char * s1,const char * s2) __nonnull; +void * __pure memchr(const void *s, int c, size_t n) __nonnull; +char * __malloc strdup(const char *s) __nonnull; +char * __malloc strndup(const char *s, size_t n) __nonnull; + +extern const char * __pure strerror ( int errno ); + +#endif /* ETHERBOOT_STRING */ diff --git a/gpxe/src/include/strings.h b/gpxe/src/include/strings.h new file mode 100644 index 00000000..968a7c11 --- /dev/null +++ b/gpxe/src/include/strings.h @@ -0,0 +1,63 @@ +#ifndef _STRINGS_H +#define _STRINGS_H + +#include <limits.h> +#include <string.h> + +static inline __attribute__ (( always_inline )) int +__constant_flsl ( unsigned long x ) { + int r = 0; + +#if ULONG_MAX > 0xffffffff + if ( x & 0xffffffff00000000UL ) { + x >>= 32; + r += 32; + } +#endif + if ( x & 0xffff0000UL ) { + x >>= 16; + r += 16; + } + if ( x & 0xff00 ) { + x >>= 8; + r += 8; + } + if ( x & 0xf0 ) { + x >>= 4; + r += 4; + } + if ( x & 0xc ) { + x >>= 2; + r += 2; + } + if ( x & 0x2 ) { + x >>= 1; + r += 1; + } + if ( x & 0x1 ) { + r += 1; + } + return r; +} + +/* We don't actually have these functions yet */ +extern int __flsl ( long x ); + +#define flsl( x ) \ + ( __builtin_constant_p ( x ) ? __constant_flsl ( x ) : __flsl ( x ) ) + +#define fls( x ) flsl ( x ) + +extern int strcasecmp ( const char *s1, const char *s2 ); + +static inline __attribute__ (( always_inline )) void +bcopy ( const void *src, void *dest, size_t n ) { + memmove ( dest, src, n ); +} + +static inline __attribute__ (( always_inline )) void +bzero ( void *s, size_t n ) { + memset ( s, 0, n ); +} + +#endif /* _STRINGS_H */ diff --git a/gpxe/src/include/sys/time.h b/gpxe/src/include/sys/time.h new file mode 100644 index 00000000..21fb7e99 --- /dev/null +++ b/gpxe/src/include/sys/time.h @@ -0,0 +1,20 @@ +#ifndef _SYS_TIME_H +#define _SYS_TIME_H + +#include <time.h> + +typedef unsigned long suseconds_t; + +struct timeval { + time_t tv_sec; /* seconds */ + suseconds_t tv_usec; /* microseconds */ +}; + +struct timezone { + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +extern int gettimeofday ( struct timeval *tv, struct timezone *tz ); + +#endif /* _SYS_TIME_H */ diff --git a/gpxe/src/include/sys_info.h b/gpxe/src/include/sys_info.h new file mode 100644 index 00000000..7127c643 --- /dev/null +++ b/gpxe/src/include/sys_info.h @@ -0,0 +1,33 @@ +#ifndef SYS_INFO_H +#define SYS_INFO_H + +/* Information collected from firmware/bootloader */ + +struct sys_info { + /* Values passed by bootloader */ + unsigned long boot_type; + unsigned long boot_data; + unsigned long boot_arg; + + char *firmware; /* "PCBIOS", "LinuxBIOS", etc. */ + char *command_line; /* command line given to us */ +#if 0 +//By LYH +//Will use meminfo in Etherboot + /* memory map */ + int n_memranges; + struct memrange { + unsigned long long base; + unsigned long long size; + } *memrange; +#endif +}; + +void collect_sys_info(struct sys_info *info); +void collect_elfboot_info(struct sys_info *info); +void collect_linuxbios_info(struct sys_info *info); + +/* Our name and version. I want to see single instance of these in the image */ +extern const char *program_name, *program_version; + +#endif /* SYS_INFO_H */ diff --git a/gpxe/src/include/time.h b/gpxe/src/include/time.h new file mode 100644 index 00000000..6ea927c3 --- /dev/null +++ b/gpxe/src/include/time.h @@ -0,0 +1,22 @@ +#ifndef _TIME_H +#define _TIME_H + +typedef unsigned long time_t; + +struct tm { + int tm_sec; /* seconds */ + int tm_min; /* minutes */ + int tm_hour; /* hours */ + int tm_mday; /* day of the month */ + int tm_mon; /* month */ + int tm_year; /* year */ + int tm_wday; /* day of the week */ + int tm_yday; /* day in the year */ + int tm_isdst; /* daylight saving time */ +}; + +extern time_t time ( time_t *t ); + +extern time_t mktime ( struct tm *tm ); + +#endif /* _TIME_H */ diff --git a/gpxe/src/include/unistd.h b/gpxe/src/include/unistd.h new file mode 100644 index 00000000..7c44a0ce --- /dev/null +++ b/gpxe/src/include/unistd.h @@ -0,0 +1,31 @@ +#ifndef _UNISTD_H +#define _UNISTD_H + +#include <stddef.h> +#include <stdarg.h> + +unsigned int sleep ( unsigned int seconds ); +extern int execv ( const char *command, char * const argv[] ); + +/** + * Execute command + * + * @v command Command name + * @v arg ... Argument list (starting with argv[0]) + * @ret rc Command exit status + * + * This is a front end to execv(). + */ +#define execl( command, arg, ... ) ( { \ + char * const argv[] = { (arg), ## __VA_ARGS__ }; \ + int rc = execv ( (command), argv ); \ + rc; \ + } ) + +void udelay(unsigned int usecs); +void mdelay(unsigned int msecs); + +#define usleep(x) udelay(x) + + +#endif /* _UNISTD_H */ diff --git a/gpxe/src/include/usr/aoeboot.h b/gpxe/src/include/usr/aoeboot.h new file mode 100644 index 00000000..0421ebcc --- /dev/null +++ b/gpxe/src/include/usr/aoeboot.h @@ -0,0 +1,6 @@ +#ifndef _USR_AOEBOOT_H +#define _USR_AOEBOOT_H + +extern int aoeboot ( const char *root_path ); + +#endif /* _USR_AOEBOOT_H */ diff --git a/gpxe/src/include/usr/autoboot.h b/gpxe/src/include/usr/autoboot.h new file mode 100644 index 00000000..b451a8c1 --- /dev/null +++ b/gpxe/src/include/usr/autoboot.h @@ -0,0 +1,13 @@ +#ifndef _USR_AUTOBOOT_H +#define _USR_AUTOBOOT_H + +/** @file + * + * Automatic booting + * + */ + +extern void autoboot ( void ); +extern int boot_root_path ( const char *root_path ); + +#endif /* _USR_AUTOBOOT_H */ diff --git a/gpxe/src/include/usr/dhcpmgmt.h b/gpxe/src/include/usr/dhcpmgmt.h new file mode 100644 index 00000000..2757a1c1 --- /dev/null +++ b/gpxe/src/include/usr/dhcpmgmt.h @@ -0,0 +1,14 @@ +#ifndef _USR_DHCPMGMT_H +#define _USR_DHCPMGMT_H + +/** @file + * + * DHCP management + * + */ + +struct net_device; + +int dhcp ( struct net_device *netdev ); + +#endif /* _USR_DHCPMGMT_H */ diff --git a/gpxe/src/include/usr/ifmgmt.h b/gpxe/src/include/usr/ifmgmt.h new file mode 100644 index 00000000..c7d35da8 --- /dev/null +++ b/gpxe/src/include/usr/ifmgmt.h @@ -0,0 +1,16 @@ +#ifndef _USR_IFMGMT_H +#define _USR_IFMGMT_H + +/** @file + * + * Network interface management + * + */ + +struct net_device; + +extern int ifopen ( struct net_device *netdev ); +extern void ifclose ( struct net_device *netdev ); +extern void ifstat ( struct net_device *netdev ); + +#endif /* _USR_IFMGMT_H */ diff --git a/gpxe/src/include/usr/imgmgmt.h b/gpxe/src/include/usr/imgmgmt.h new file mode 100644 index 00000000..438af003 --- /dev/null +++ b/gpxe/src/include/usr/imgmgmt.h @@ -0,0 +1,20 @@ +#ifndef _USR_IMGMGMT_H +#define _USR_IMGMGMT_H + +/** @file + * + * Image management + * + */ + +struct image; + +extern int imgfetch ( struct image *image, const char *uri_string, + int ( * image_register ) ( struct image *image ) ); +extern int imgload ( struct image *image ); +extern int imgexec ( struct image *image ); +extern struct image * imgautoselect ( void ); +extern void imgstat ( struct image *image ); +extern void imgfree ( struct image *image ); + +#endif /* _USR_IMGMGMT_H */ diff --git a/gpxe/src/include/usr/iscsiboot.h b/gpxe/src/include/usr/iscsiboot.h new file mode 100644 index 00000000..b17951d5 --- /dev/null +++ b/gpxe/src/include/usr/iscsiboot.h @@ -0,0 +1,6 @@ +#ifndef _USR_ISCSIBOOT_H +#define _USR_ISCSIBOOT_H + +extern int iscsiboot ( const char *root_path ); + +#endif /* _USR_ISCSIBOOT_H */ diff --git a/gpxe/src/include/usr/route.h b/gpxe/src/include/usr/route.h new file mode 100644 index 00000000..fc855892 --- /dev/null +++ b/gpxe/src/include/usr/route.h @@ -0,0 +1,12 @@ +#ifndef _USR_ROUTE_H +#define _USR_ROUTE_H + +/** @file + * + * Routing table management + * + */ + +extern void route ( void ); + +#endif /* _USR_ROUTE_H */ |