summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/ipxe')
-rw-r--r--src/include/ipxe/acpi.h148
-rw-r--r--src/include/ipxe/aoe.h31
-rw-r--r--src/include/ipxe/asn1.h53
-rw-r--r--src/include/ipxe/cachedhcp.h17
-rw-r--r--src/include/ipxe/certstore.h3
-rw-r--r--src/include/ipxe/dma.h480
-rw-r--r--src/include/ipxe/eap.h69
-rw-r--r--src/include/ipxe/eapol.h127
-rw-r--r--src/include/ipxe/efi/efi.h48
-rw-r--r--src/include/ipxe/efi/efi_acpi.h13
-rw-r--r--src/include/ipxe/efi/efi_autoboot.h4
-rw-r--r--src/include/ipxe/efi/efi_autoexec.h16
-rw-r--r--src/include/ipxe/efi/efi_blacklist.h13
-rw-r--r--src/include/ipxe/efi/efi_cachedhcp.h16
-rw-r--r--src/include/ipxe/efi/efi_null.h33
-rw-r--r--src/include/ipxe/efi/efi_path.h43
-rw-r--r--src/include/ipxe/efi/efi_pci.h12
-rw-r--r--src/include/ipxe/efi/efi_snp.h2
-rw-r--r--src/include/ipxe/efi/efi_usb.h10
-rw-r--r--src/include/ipxe/efi/efi_utils.h4
-rw-r--r--src/include/ipxe/efi/efi_veto.h13
-rw-r--r--src/include/ipxe/efi/efi_wrap.h1
-rw-r--r--src/include/ipxe/errfile.h13
-rw-r--r--src/include/ipxe/fcp.h8
-rw-r--r--src/include/ipxe/http.h8
-rw-r--r--src/include/ipxe/ib_srp.h35
-rw-r--r--src/include/ipxe/image.h3
-rw-r--r--src/include/ipxe/infiniband.h3
-rw-r--r--src/include/ipxe/interface.h17
-rw-r--r--src/include/ipxe/iobuf.h69
-rw-r--r--src/include/ipxe/linux/linux_acpi.h18
-rw-r--r--src/include/ipxe/linux/linux_pci.h24
-rw-r--r--src/include/ipxe/linux_api.h106
-rw-r--r--src/include/ipxe/linux_sysfs.h16
-rw-r--r--src/include/ipxe/malloc.h32
-rw-r--r--src/include/ipxe/netdevice.h6
-rw-r--r--src/include/ipxe/null_acpi.h6
-rw-r--r--src/include/ipxe/pci.h3
-rw-r--r--src/include/ipxe/pci_io.h11
-rw-r--r--src/include/ipxe/privkey.h55
-rw-r--r--src/include/ipxe/slirp.h155
-rw-r--r--src/include/ipxe/smbios.h52
-rw-r--r--src/include/ipxe/tables.h71
-rw-r--r--src/include/ipxe/tls.h16
-rw-r--r--src/include/ipxe/usb.h23
-rw-r--r--src/include/ipxe/validator.h3
-rw-r--r--src/include/ipxe/x509.h48
47 files changed, 1690 insertions, 267 deletions
diff --git a/src/include/ipxe/acpi.h b/src/include/ipxe/acpi.h
index 78f402530..81ef7ff76 100644
--- a/src/include/ipxe/acpi.h
+++ b/src/include/ipxe/acpi.h
@@ -19,6 +19,141 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/api.h>
#include <config/general.h>
+/** An ACPI small resource descriptor header */
+struct acpi_small_resource {
+ /** Tag byte */
+ uint8_t tag;
+} __attribute__ (( packed ));
+
+/** ACPI small resource length mask */
+#define ACPI_SMALL_LEN_MASK 0x03
+
+/** An ACPI end resource descriptor */
+#define ACPI_END_RESOURCE 0x78
+
+/** An ACPI end resource descriptor */
+struct acpi_end_resource {
+ /** Header */
+ struct acpi_small_resource hdr;
+ /** Checksum */
+ uint8_t checksum;
+} __attribute__ (( packed ));
+
+/** An ACPI large resource descriptor header */
+struct acpi_large_resource {
+ /** Tag byte */
+ uint8_t tag;
+ /** Length of data items */
+ uint16_t len;
+} __attribute__ (( packed ));
+
+/** ACPI large resource flag */
+#define ACPI_LARGE 0x80
+
+/** An ACPI QWORD address space resource descriptor */
+#define ACPI_QWORD_ADDRESS_SPACE_RESOURCE 0x8a
+
+/** An ACPI QWORD address space resource descriptor */
+struct acpi_qword_address_space_resource {
+ /** Header */
+ struct acpi_large_resource hdr;
+ /** Resource type */
+ uint8_t type;
+ /** General flags */
+ uint8_t general;
+ /** Type-specific flags */
+ uint8_t specific;
+ /** Granularity */
+ uint64_t granularity;
+ /** Minimum address */
+ uint64_t min;
+ /** Maximum address */
+ uint64_t max;
+ /** Translation offset */
+ uint64_t offset;
+ /** Length */
+ uint64_t len;
+} __attribute__ (( packed ));
+
+/** A memory address space type */
+#define ACPI_ADDRESS_TYPE_MEM 0x00
+
+/** A bus number address space type */
+#define ACPI_ADDRESS_TYPE_BUS 0x02
+
+/** An ACPI resource descriptor */
+union acpi_resource {
+ /** Tag byte */
+ uint8_t tag;
+ /** Small resource descriptor */
+ struct acpi_small_resource small;
+ /** End resource descriptor */
+ struct acpi_end_resource end;
+ /** Large resource descriptor */
+ struct acpi_large_resource large;
+ /** QWORD address space resource descriptor */
+ struct acpi_qword_address_space_resource qword;
+};
+
+/**
+ * Get ACPI resource tag
+ *
+ * @v res ACPI resource descriptor
+ * @ret tag Resource tag
+ */
+static inline unsigned int acpi_resource_tag ( union acpi_resource *res ) {
+
+ return ( ( res->tag & ACPI_LARGE ) ?
+ res->tag : ( res->tag & ~ACPI_SMALL_LEN_MASK ) );
+}
+
+/**
+ * Get length of ACPI small resource descriptor
+ *
+ * @v res Small resource descriptor
+ * @ret len Length of descriptor
+ */
+static inline size_t acpi_small_len ( struct acpi_small_resource *res ) {
+
+ return ( sizeof ( *res ) + ( res->tag & ACPI_SMALL_LEN_MASK ) );
+}
+
+/**
+ * Get length of ACPI large resource descriptor
+ *
+ * @v res Large resource descriptor
+ * @ret len Length of descriptor
+ */
+static inline size_t acpi_large_len ( struct acpi_large_resource *res ) {
+
+ return ( sizeof ( *res ) + le16_to_cpu ( res->len ) );
+}
+
+/**
+ * Get length of ACPI resource descriptor
+ *
+ * @v res ACPI resource descriptor
+ * @ret len Length of descriptor
+ */
+static inline size_t acpi_resource_len ( union acpi_resource *res ) {
+
+ return ( ( res->tag & ACPI_LARGE ) ?
+ acpi_large_len ( &res->large ) :
+ acpi_small_len ( &res->small ) );
+}
+
+/**
+ * Get next ACPI resource descriptor
+ *
+ * @v res ACPI resource descriptor
+ * @ret next Next ACPI resource descriptor
+ */
+static inline union acpi_resource *
+acpi_resource_next ( union acpi_resource *res ) {
+
+ return ( ( ( void * ) res ) + acpi_resource_len ( res ) );
+}
+
/**
* An ACPI description header
*
@@ -220,9 +355,12 @@ struct acpi_model {
#define PROVIDE_ACPI_INLINE( _subsys, _api_func ) \
PROVIDE_SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
+extern userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index );
+
/* Include all architecture-independent ACPI API headers */
#include <ipxe/null_acpi.h>
#include <ipxe/efi/efi_acpi.h>
+#include <ipxe/linux/linux_acpi.h>
/* Include all architecture-dependent ACPI API headers */
#include <bits/acpi.h>
@@ -234,13 +372,21 @@ struct acpi_model {
*/
userptr_t acpi_find_rsdt ( void );
+/**
+ * Locate ACPI table
+ *
+ * @v signature Requested table signature
+ * @v index Requested index of table with this signature
+ * @ret table Table, or UNULL if not found
+ */
+userptr_t acpi_find ( uint32_t signature, unsigned int index );
+
extern struct acpi_descriptor *
acpi_describe ( struct interface *interface );
#define acpi_describe_TYPE( object_type ) \
typeof ( struct acpi_descriptor * ( object_type ) )
extern void acpi_fix_checksum ( struct acpi_header *acpi );
-extern userptr_t acpi_find ( uint32_t signature, unsigned int index );
extern int acpi_sx ( uint32_t signature );
extern void acpi_add ( struct acpi_descriptor *desc );
extern void acpi_del ( struct acpi_descriptor *desc );
diff --git a/src/include/ipxe/aoe.h b/src/include/ipxe/aoe.h
index a51044d15..14d11c5cb 100644
--- a/src/include/ipxe/aoe.h
+++ b/src/include/ipxe/aoe.h
@@ -15,6 +15,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/retry.h>
#include <ipxe/ata.h>
#include <ipxe/acpi.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/interface.h>
/** An AoE config command */
struct aoecfg {
@@ -109,6 +111,35 @@ struct aoehdr {
/** Maximum number of sectors per packet */
#define AOE_MAX_COUNT 2
+/** An AoE device */
+struct aoe_device {
+ /** Reference counter */
+ struct refcnt refcnt;
+
+ /** Network device */
+ struct net_device *netdev;
+ /** ATA command issuing interface */
+ struct interface ata;
+
+ /** Major number */
+ uint16_t major;
+ /** Minor number */
+ uint8_t minor;
+ /** Target MAC address */
+ uint8_t target[MAX_LL_ADDR_LEN];
+
+ /** Saved timeout value */
+ unsigned long timeout;
+
+ /** Configuration command interface */
+ struct interface config;
+ /** Device is configued */
+ int configured;
+
+ /** ACPI descriptor */
+ struct acpi_descriptor desc;
+};
+
/** AoE boot firmware table signature */
#define ABFT_SIG ACPI_SIGNATURE ( 'a', 'B', 'F', 'T' )
diff --git a/src/include/ipxe/asn1.h b/src/include/ipxe/asn1.h
index efc66631d..fdf06f109 100644
--- a/src/include/ipxe/asn1.h
+++ b/src/include/ipxe/asn1.h
@@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdint.h>
+#include <stdarg.h>
#include <assert.h>
#include <time.h>
#include <ipxe/tables.h>
@@ -75,6 +76,9 @@ struct asn1_builder_header {
/** ASN.1 enumeration */
#define ASN1_ENUMERATED 0x0a
+/** ASN.1 UTF-8 string */
+#define ASN1_UTF8_STRING 0x0c
+
/** ASN.1 UTC time */
#define ASN1_UTC_TIME 0x17
@@ -96,6 +100,10 @@ struct asn1_builder_header {
/** ASN.1 "any tag" magic value */
#define ASN1_ANY -1U
+/** Construct a short ASN.1 value */
+#define ASN1_SHORT( tag, ... ) \
+ (tag), VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__
+
/** Initial OID byte */
#define ASN1_OID_INITIAL( first, second ) ( ( (first) * 40 ) + (second) )
@@ -288,10 +296,10 @@ struct asn1_builder_header {
ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 29 ), \
ASN1_OID_SINGLE ( 17 )
-/** Define an ASN.1 cursor containing an OID */
-#define ASN1_OID_CURSOR( oid_value ) { \
- .data = oid_value, \
- .len = sizeof ( oid_value ), \
+/** Define an ASN.1 cursor for a static value */
+#define ASN1_CURSOR( value ) { \
+ .data = value, \
+ .len = sizeof ( value ), \
}
/** An ASN.1 OID-identified algorithm */
@@ -313,22 +321,27 @@ struct asn1_algorithm {
#define __asn1_algorithm __table_entry ( ASN1_ALGORITHMS, 01 )
/* ASN.1 OID-identified algorithms */
-extern struct asn1_algorithm rsa_encryption_algorithm;
-extern struct asn1_algorithm md5_with_rsa_encryption_algorithm;
-extern struct asn1_algorithm sha1_with_rsa_encryption_algorithm;
-extern struct asn1_algorithm sha256_with_rsa_encryption_algorithm;
-extern struct asn1_algorithm sha384_with_rsa_encryption_algorithm;
-extern struct asn1_algorithm sha512_with_rsa_encryption_algorithm;
-extern struct asn1_algorithm sha224_with_rsa_encryption_algorithm;
-extern struct asn1_algorithm oid_md4_algorithm;
-extern struct asn1_algorithm oid_md5_algorithm;
-extern struct asn1_algorithm oid_sha1_algorithm;
-extern struct asn1_algorithm oid_sha256_algorithm;
-extern struct asn1_algorithm oid_sha384_algorithm;
-extern struct asn1_algorithm oid_sha512_algorithm;
-extern struct asn1_algorithm oid_sha224_algorithm;
-extern struct asn1_algorithm oid_sha512_224_algorithm;
-extern struct asn1_algorithm oid_sha512_256_algorithm;
+extern struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm;
+extern struct asn1_algorithm md5_with_rsa_encryption_algorithm __asn1_algorithm;
+extern struct asn1_algorithm
+sha1_with_rsa_encryption_algorithm __asn1_algorithm;
+extern struct asn1_algorithm
+sha256_with_rsa_encryption_algorithm __asn1_algorithm;
+extern struct asn1_algorithm
+sha384_with_rsa_encryption_algorithm __asn1_algorithm;
+extern struct asn1_algorithm
+sha512_with_rsa_encryption_algorithm __asn1_algorithm;
+extern struct asn1_algorithm
+sha224_with_rsa_encryption_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_md4_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_md5_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_sha1_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_sha256_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_sha384_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_sha512_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_sha512_224_algorithm __asn1_algorithm;
+extern struct asn1_algorithm oid_sha512_256_algorithm __asn1_algorithm;
/** An ASN.1 bit string */
struct asn1_bit_string {
diff --git a/src/include/ipxe/cachedhcp.h b/src/include/ipxe/cachedhcp.h
new file mode 100644
index 000000000..7765c6455
--- /dev/null
+++ b/src/include/ipxe/cachedhcp.h
@@ -0,0 +1,17 @@
+#ifndef _IPXE_CACHEDHCP_H
+#define _IPXE_CACHEDHCP_H
+
+/** @file
+ *
+ * Cached DHCP packet
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stddef.h>
+#include <ipxe/uaccess.h>
+
+extern int cachedhcp_record ( userptr_t data, size_t max_len );
+
+#endif /* _IPXE_CACHEDHCP_H */
diff --git a/src/include/ipxe/certstore.h b/src/include/ipxe/certstore.h
index e4c789cfd..ce96666cf 100644
--- a/src/include/ipxe/certstore.h
+++ b/src/include/ipxe/certstore.h
@@ -11,11 +11,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/asn1.h>
#include <ipxe/x509.h>
+#include <ipxe/privkey.h>
extern struct x509_chain certstore;
extern struct x509_certificate * certstore_find ( struct asn1_cursor *raw );
-extern struct x509_certificate * certstore_find_key ( struct asn1_cursor *key );
+extern struct x509_certificate * certstore_find_key ( struct private_key *key );
extern void certstore_add ( struct x509_certificate *cert );
extern void certstore_del ( struct x509_certificate *cert );
diff --git a/src/include/ipxe/dma.h b/src/include/ipxe/dma.h
new file mode 100644
index 000000000..385e4baf7
--- /dev/null
+++ b/src/include/ipxe/dma.h
@@ -0,0 +1,480 @@
+#ifndef _IPXE_DMA_H
+#define _IPXE_DMA_H
+
+/** @file
+ *
+ * DMA mappings
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/api.h>
+#include <ipxe/io.h>
+#include <ipxe/malloc.h>
+#include <ipxe/umalloc.h>
+#include <config/ioapi.h>
+
+#ifdef DMAAPI_OP
+#define DMAAPI_PREFIX_op
+#else
+#define DMAAPI_PREFIX_op __op_
+#endif
+
+#ifdef DMAAPI_FLAT
+#define DMAAPI_PREFIX_flat
+#else
+#define DMAAPI_PREFIX_flat __flat_
+#endif
+
+/** A DMA mapping */
+struct dma_mapping {
+ /** Address offset
+ *
+ * This is the value that must be added to a physical address
+ * within the mapping in order to produce the corresponding
+ * device-side DMA address.
+ */
+ physaddr_t offset;
+ /** DMA device (if unmapping is required) */
+ struct dma_device *dma;
+ /** Platform mapping token */
+ void *token;
+};
+
+/** A DMA-capable device */
+struct dma_device {
+ /** DMA operations */
+ struct dma_operations *op;
+ /** Addressable space mask */
+ physaddr_t mask;
+ /** Total number of mappings (for debugging) */
+ unsigned int mapped;
+ /** Total number of allocations (for debugging) */
+ unsigned int allocated;
+};
+
+/** DMA operations */
+struct dma_operations {
+ /**
+ * Map buffer for DMA
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v addr Buffer address
+ * @v len Length of buffer
+ * @v flags Mapping flags
+ * @ret rc Return status code
+ */
+ int ( * map ) ( struct dma_device *dma, struct dma_mapping *map,
+ physaddr_t addr, size_t len, int flags );
+ /**
+ * Unmap buffer
+ *
+ * @v dma DMA device
+ * @v map DMA mapping
+ */
+ void ( * unmap ) ( struct dma_device *dma, struct dma_mapping *map );
+ /**
+ * Allocate and map DMA-coherent buffer
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+ void * ( * alloc ) ( struct dma_device *dma, struct dma_mapping *map,
+ size_t len, size_t align );
+ /**
+ * Unmap and free DMA-coherent buffer
+ *
+ * @v dma DMA device
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+ void ( * free ) ( struct dma_device *dma, struct dma_mapping *map,
+ void *addr, size_t len );
+ /**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+ userptr_t ( * umalloc ) ( struct dma_device *dma,
+ struct dma_mapping *map,
+ size_t len, size_t align );
+ /**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+ void ( * ufree ) ( struct dma_device *dma, struct dma_mapping *map,
+ userptr_t addr, size_t len );
+ /**
+ * Set addressable space mask
+ *
+ * @v dma DMA device
+ * @v mask Addressable space mask
+ */
+ void ( * set_mask ) ( struct dma_device *dma, physaddr_t mask );
+};
+
+/** Device will read data from host memory */
+#define DMA_TX 0x01
+
+/** Device will write data to host memory */
+#define DMA_RX 0x02
+
+/** Device will both read data from and write data to host memory */
+#define DMA_BI ( DMA_TX | DMA_RX )
+
+/**
+ * Calculate static inline DMA I/O API function name
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ * @ret _subsys_func Subsystem API function
+ */
+#define DMAAPI_INLINE( _subsys, _api_func ) \
+ SINGLE_API_INLINE ( DMAAPI_PREFIX_ ## _subsys, _api_func )
+
+/**
+ * Provide a DMA I/O API implementation
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ * @v _func Implementing function
+ */
+#define PROVIDE_DMAAPI( _subsys, _api_func, _func ) \
+ PROVIDE_SINGLE_API ( DMAAPI_PREFIX_ ## _subsys, _api_func, _func )
+
+/**
+ * Provide a static inline DMA I/O API implementation
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ */
+#define PROVIDE_DMAAPI_INLINE( _subsys, _api_func ) \
+ PROVIDE_SINGLE_API_INLINE ( DMAAPI_PREFIX_ ## _subsys, _api_func )
+
+/**
+ * Map buffer for DMA
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v addr Buffer address
+ * @v len Length of buffer
+ * @v flags Mapping flags
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+DMAAPI_INLINE ( flat, dma_map ) ( struct dma_device *dma,
+ struct dma_mapping *map,
+ physaddr_t addr __unused,
+ size_t len __unused, int flags __unused ) {
+
+ /* Increment mapping count (for debugging) */
+ if ( DBG_LOG ) {
+ map->dma = dma;
+ dma->mapped++;
+ }
+
+ return 0;
+}
+
+/**
+ * Unmap buffer
+ *
+ * @v map DMA mapping
+ */
+static inline __always_inline void
+DMAAPI_INLINE ( flat, dma_unmap ) ( struct dma_mapping *map ) {
+
+ /* Decrement mapping count (for debugging) */
+ if ( DBG_LOG ) {
+ assert ( map->dma != NULL );
+ map->dma->mapped--;
+ map->dma = NULL;
+ }
+}
+
+/**
+ * Allocate and map DMA-coherent buffer
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+static inline __always_inline void *
+DMAAPI_INLINE ( flat, dma_alloc ) ( struct dma_device *dma,
+ struct dma_mapping *map,
+ size_t len, size_t align ) {
+ void *addr;
+
+ /* Allocate buffer */
+ addr = malloc_phys ( len, align );
+
+ /* Increment mapping count (for debugging) */
+ if ( DBG_LOG && addr ) {
+ map->dma = dma;
+ dma->mapped++;
+ }
+
+ return addr;
+}
+
+/**
+ * Unmap and free DMA-coherent buffer
+ *
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+static inline __always_inline void
+DMAAPI_INLINE ( flat, dma_free ) ( struct dma_mapping *map,
+ void *addr, size_t len ) {
+
+ /* Free buffer */
+ free_phys ( addr, len );
+
+ /* Decrement mapping count (for debugging) */
+ if ( DBG_LOG ) {
+ assert ( map->dma != NULL );
+ map->dma->mapped--;
+ map->dma = NULL;
+ }
+}
+
+/**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+static inline __always_inline userptr_t
+DMAAPI_INLINE ( flat, dma_umalloc ) ( struct dma_device *dma,
+ struct dma_mapping *map,
+ size_t len, size_t align __unused ) {
+ userptr_t addr;
+
+ /* Allocate buffer */
+ addr = umalloc ( len );
+
+ /* Increment mapping count (for debugging) */
+ if ( DBG_LOG && addr ) {
+ map->dma = dma;
+ dma->mapped++;
+ }
+
+ return addr;
+}
+
+/**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+static inline __always_inline void
+DMAAPI_INLINE ( flat, dma_ufree ) ( struct dma_mapping *map,
+ userptr_t addr, size_t len __unused ) {
+
+ /* Free buffer */
+ ufree ( addr );
+
+ /* Decrement mapping count (for debugging) */
+ if ( DBG_LOG ) {
+ assert ( map->dma != NULL );
+ map->dma->mapped--;
+ map->dma = NULL;
+ }
+}
+
+/**
+ * Set addressable space mask
+ *
+ * @v dma DMA device
+ * @v mask Addressable space mask
+ */
+static inline __always_inline void
+DMAAPI_INLINE ( flat, dma_set_mask ) ( struct dma_device *dma __unused,
+ physaddr_t mask __unused ) {
+
+ /* Nothing to do */
+}
+
+/**
+ * Get DMA address from physical address
+ *
+ * @v map DMA mapping
+ * @v addr Physical address within the mapped region
+ * @ret addr Device-side DMA address
+ */
+static inline __always_inline physaddr_t
+DMAAPI_INLINE ( flat, dma_phys ) ( struct dma_mapping *map __unused,
+ physaddr_t addr ) {
+
+ /* Use physical address as device address */
+ return addr;
+}
+
+/**
+ * Get DMA address from physical address
+ *
+ * @v map DMA mapping
+ * @v addr Physical address within the mapped region
+ * @ret addr Device-side DMA address
+ */
+static inline __always_inline physaddr_t
+DMAAPI_INLINE ( op, dma_phys ) ( struct dma_mapping *map, physaddr_t addr ) {
+
+ /* Adjust physical address using mapping offset */
+ return ( addr + map->offset );
+}
+
+/**
+ * Map buffer for DMA
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v addr Buffer address
+ * @v len Length of buffer
+ * @v flags Mapping flags
+ * @ret rc Return status code
+ */
+int dma_map ( struct dma_device *dma, struct dma_mapping *map,
+ physaddr_t addr, size_t len, int flags );
+
+/**
+ * Unmap buffer
+ *
+ * @v map DMA mapping
+ */
+void dma_unmap ( struct dma_mapping *map );
+
+/**
+ * Allocate and map DMA-coherent buffer
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+void * dma_alloc ( struct dma_device *dma, struct dma_mapping *map,
+ size_t len, size_t align );
+
+/**
+ * Unmap and free DMA-coherent buffer
+ *
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+void dma_free ( struct dma_mapping *map, void *addr, size_t len );
+
+/**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+userptr_t dma_umalloc ( struct dma_device *dma, struct dma_mapping *map,
+ size_t len, size_t align );
+
+/**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+void dma_ufree ( struct dma_mapping *map, userptr_t addr, size_t len );
+
+/**
+ * Set addressable space mask
+ *
+ * @v dma DMA device
+ * @v mask Addressable space mask
+ */
+void dma_set_mask ( struct dma_device *dma, physaddr_t mask );
+
+/**
+ * Get DMA address from physical address
+ *
+ * @v map DMA mapping
+ * @v addr Physical address within the mapped region
+ * @ret addr Device-side DMA address
+ */
+physaddr_t dma_phys ( struct dma_mapping *map, physaddr_t addr );
+
+/**
+ * Get DMA address from virtual address
+ *
+ * @v map DMA mapping
+ * @v addr Virtual address within the mapped region
+ * @ret addr Device-side DMA address
+ */
+static inline __always_inline physaddr_t dma ( struct dma_mapping *map,
+ void *addr ) {
+
+ /* Get DMA address from corresponding physical address */
+ return dma_phys ( map, virt_to_phys ( addr ) );
+}
+
+/**
+ * Check if DMA unmapping is required
+ *
+ * @v map DMA mapping
+ * @v unmap Unmapping is required
+ */
+static inline __always_inline int dma_mapped ( struct dma_mapping *map ) {
+
+ /* Unmapping is required if a DMA device was recorded */
+ return ( map->dma != NULL );
+}
+
+/**
+ * Initialise DMA device
+ *
+ * @v dma DMA device
+ * @v op DMA operations
+ */
+static inline __always_inline void dma_init ( struct dma_device *dma,
+ struct dma_operations *op ) {
+
+ /* Set operations table */
+ dma->op = op;
+}
+
+/**
+ * Set 64-bit addressable space mask
+ *
+ * @v dma DMA device
+ */
+static inline __always_inline void
+dma_set_mask_64bit ( struct dma_device *dma ) {
+
+ /* Set mask to maximum physical address */
+ dma_set_mask ( dma, ~( ( physaddr_t ) 0 ) );
+}
+
+#endif /* _IPXE_DMA_H */
diff --git a/src/include/ipxe/eap.h b/src/include/ipxe/eap.h
new file mode 100644
index 000000000..6fe70189b
--- /dev/null
+++ b/src/include/ipxe/eap.h
@@ -0,0 +1,69 @@
+#ifndef _IPXE_EAP_H
+#define _IPXE_EAP_H
+
+/** @file
+ *
+ * Extensible Authentication Protocol
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/timer.h>
+
+/** EAP header */
+struct eap_header {
+ /** Code */
+ uint8_t code;
+ /** Identifier */
+ uint8_t id;
+ /** Length */
+ uint16_t len;
+} __attribute__ (( packed ));
+
+/** EAP request */
+#define EAP_CODE_REQUEST 1
+
+/** EAP request */
+struct eap_request {
+ /** Header */
+ struct eap_header hdr;
+ /** Type */
+ uint8_t type;
+} __attribute__ (( packed ));
+
+/** EAP identity */
+#define EAP_TYPE_IDENTITY 1
+
+/** EAP success */
+#define EAP_CODE_SUCCESS 3
+
+/** EAP failure */
+#define EAP_CODE_FAILURE 4
+
+/** EAP packet */
+union eap_packet {
+ /** Header */
+ struct eap_header hdr;
+ /** Request */
+ struct eap_request req;
+};
+
+/** Link block timeout
+ *
+ * We mark the link as blocked upon receiving a Request-Identity, on
+ * the basis that this most likely indicates that the switch will not
+ * yet be forwarding packets.
+ *
+ * There is no way to tell how frequently the Request-Identity packet
+ * will be retransmitted by the switch. The default value for Cisco
+ * switches seems to be 30 seconds, so treat the link as blocked for
+ * 45 seconds.
+ */
+#define EAP_BLOCK_TIMEOUT ( 45 * TICKS_PER_SEC )
+
+extern int eap_rx ( struct net_device *netdev, const void *data, size_t len );
+
+#endif /* _IPXE_EAP_H */
diff --git a/src/include/ipxe/eapol.h b/src/include/ipxe/eapol.h
index 5ca9c2815..952d6c752 100644
--- a/src/include/ipxe/eapol.h
+++ b/src/include/ipxe/eapol.h
@@ -1,114 +1,61 @@
-/*
- * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
#ifndef _IPXE_EAPOL_H
#define _IPXE_EAPOL_H
/** @file
*
- * Definitions for EAPOL (Extensible Authentication Protocol over
- * LANs) frames. Definitions for the packets usually encapsulated in
- * them are elsewhere.
- */
-
-#include <ipxe/tables.h>
-#include <stdint.h>
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-
-/**
- * @defgroup eapol_type EAPOL archetype identifiers
- * @{
- */
-#define EAPOL_TYPE_EAP 0 /**< EAP authentication handshake packet */
-#define EAPOL_TYPE_START 1 /**< Request by Peer to begin (no data) */
-#define EAPOL_TYPE_LOGOFF 2 /**< Request by Peer to terminate (no data) */
-#define EAPOL_TYPE_KEY 3 /**< EAPOL-Key packet */
-/** @} */
-
-/** Expected EAPOL version field value
- *
- * Version 2 is often seen and has no format differences from version 1;
- * however, many older APs will completely drop version-2 packets, so
- * we advertise ourselves as version 1.
- */
-#define EAPOL_THIS_VERSION 1
-
-/** Length of an EAPOL frame header */
-#define EAPOL_HDR_LEN 4
-
-/** An EAPOL frame
+ * Extensible Authentication Protocol over LAN (EAPoL)
*
- * This may encapsulate an eap_pkt, an eapol_key_pkt, or a Start or
- * Logoff request with no data attached. It is transmitted directly in
- * an Ethernet frame, with no IP packet header.
*/
-struct eapol_frame
-{
- /** EAPOL version identifier, always 1 */
- u8 version;
- /** EAPOL archetype identifier indicating format of payload */
- u8 type;
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
- /** Length of payload, in network byte order */
- u16 length;
+#include <stdint.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/tables.h>
- /** Payload, if @a type is EAP or EAPOL-Key */
- u8 data[0];
+/** EAPoL header */
+struct eapol_header {
+ /** Version */
+ uint8_t version;
+ /** Type */
+ uint8_t type;
+ /** Payload length */
+ uint16_t len;
} __attribute__ (( packed ));
+/** 802.1X-2001 */
+#define EAPOL_VERSION_2001 1
-/** An EAPOL frame type handler
- *
- * Normally there will be at most two of these, one for EAP and one
- * for EAPOL-Key frames. The EAPOL interface code handles Start and
- * Logoff directly.
- */
-struct eapol_handler
-{
- /** EAPOL archetype identifier for payload this handler will handle */
- u8 type;
+/** EAPoL-encapsulated EAP packets */
+#define EAPOL_TYPE_EAP 0
- /** Receive EAPOL-encapsulated packet of specified type
- *
- * @v iob I/O buffer containing packet payload
- * @v netdev Network device from which packet was received
- * @V ll_dest Destination link-layer address
- * @v ll_source Source link-layer address
- * @ret rc Return status code
+/** EAPoL key */
+#define EAPOL_TYPE_KEY 5
+
+/** An EAPoL handler */
+struct eapol_handler {
+ /** Type */
+ uint8_t type;
+ /**
+ * Process received packet
*
- * The I/O buffer will have the EAPOL header pulled off it, so
- * @c iob->data points to the first byte of the payload.
+ * @v iobuf I/O buffer
+ * @v netdev Network device
+ * @v ll_source Link-layer source address
+ * @ret rc Return status code
*
- * This function takes ownership of the I/O buffer passed to it.
+ * This method takes ownership of the I/O buffer.
*/
- int ( * rx ) ( struct io_buffer *iob, struct net_device *netdev,
- const void *ll_dest, const void *ll_source );
+ int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev,
+ const void *ll_source );
};
-#define EAPOL_HANDLERS __table ( struct eapol_handler, "eapol_handlers" )
-#define __eapol_handler __table_entry ( EAPOL_HANDLERS, 01 )
+/** EAPoL handler table */
+#define EAPOL_HANDLERS __table ( struct eapol_handler, "eapol_handlers" )
+/** Declare an EAPoL handler */
+#define __eapol_handler __table_entry ( EAPOL_HANDLERS, 01 )
extern struct net_protocol eapol_protocol __net_protocol;
-
#endif /* _IPXE_EAPOL_H */
diff --git a/src/include/ipxe/efi/efi.h b/src/include/ipxe/efi/efi.h
index b8777ef47..a83fa0f27 100644
--- a/src/include/ipxe/efi/efi.h
+++ b/src/include/ipxe/efi/efi.h
@@ -29,11 +29,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
/* EFI headers redefine ARRAY_SIZE */
#undef ARRAY_SIZE
-/* EFI headers expect ICC to define __GNUC__ */
-#if defined ( __ICC ) && ! defined ( __GNUC__ )
-#define __GNUC__ 1
-#endif
-
/* EFI headers think your compiler uses the MS ABI by default on X64 */
#if __x86_64__
#define EFIAPI __attribute__((ms_abi))
@@ -68,6 +63,14 @@ typedef struct {} *EFI_HANDLE;
#include <ipxe/version.h>
#include <ipxe/profile.h>
+/** An EFI saved task priority level */
+struct efi_saved_tpl {
+ /** Current external TPL */
+ EFI_TPL current;
+ /** Previous external TPL */
+ EFI_TPL previous;
+};
+
/** An EFI protocol used by iPXE */
struct efi_protocol {
/** GUID */
@@ -220,9 +223,11 @@ extern EFI_HANDLE efi_image_handle;
extern EFI_LOADED_IMAGE_PROTOCOL *efi_loaded_image;
extern EFI_DEVICE_PATH_PROTOCOL *efi_loaded_image_path;
extern EFI_SYSTEM_TABLE *efi_systab;
+extern EFI_TPL efi_external_tpl;
extern int efi_shutdown_in_progress;
-extern const __attribute__ (( pure )) char * efi_guid_ntoa ( EFI_GUID *guid );
+extern const __attribute__ (( pure )) char *
+efi_guid_ntoa ( CONST EFI_GUID *guid );
extern const __attribute__ (( pure )) char *
efi_locate_search_type_name ( EFI_LOCATE_SEARCH_TYPE search_type );
extern const __attribute__ (( pure )) char *
@@ -232,9 +237,19 @@ efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path );
extern const __attribute__ (( pure )) char *
efi_handle_name ( EFI_HANDLE handle );
+extern void dbg_efi_opener ( EFI_HANDLE handle, EFI_GUID *protocol,
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *opener );
extern void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol );
extern void dbg_efi_protocols ( EFI_HANDLE handle );
+#define DBG_EFI_OPENER_IF( level, handle, protocol, \
+ opener ) do { \
+ if ( DBG_ ## level ) { \
+ dbg_efi_opener ( handle, protocol, \
+ opener ); \
+ } \
+ } while ( 0 )
+
#define DBG_EFI_OPENERS_IF( level, handle, protocol ) do { \
if ( DBG_ ## level ) { \
dbg_efi_openers ( handle, protocol ); \
@@ -247,6 +262,12 @@ extern void dbg_efi_protocols ( EFI_HANDLE handle );
} \
} while ( 0 )
+#define DBGC_EFI_OPENER_IF( level, id, ... ) do { \
+ DBG_AC_IF ( level, id ); \
+ DBG_EFI_OPENER_IF ( level, __VA_ARGS__ ); \
+ DBG_DC_IF ( level ); \
+ } while ( 0 )
+
#define DBGC_EFI_OPENERS_IF( level, id, ... ) do { \
DBG_AC_IF ( level, id ); \
DBG_EFI_OPENERS_IF ( level, __VA_ARGS__ ); \
@@ -259,21 +280,34 @@ extern void dbg_efi_protocols ( EFI_HANDLE handle );
DBG_DC_IF ( level ); \
} while ( 0 )
+#define DBGC_EFI_OPENER( ... ) \
+ DBGC_EFI_OPENER_IF ( LOG, ##__VA_ARGS__ )
#define DBGC_EFI_OPENERS( ... ) \
DBGC_EFI_OPENERS_IF ( LOG, ##__VA_ARGS__ )
#define DBGC_EFI_PROTOCOLS( ... ) \
DBGC_EFI_PROTOCOLS_IF ( LOG, ##__VA_ARGS__ )
+#define DBGC2_EFI_OPENER( ... ) \
+ DBGC_EFI_OPENER_IF ( EXTRA, ##__VA_ARGS__ )
#define DBGC2_EFI_OPENERS( ... ) \
DBGC_EFI_OPENERS_IF ( EXTRA, ##__VA_ARGS__ )
#define DBGC2_EFI_PROTOCOLS( ... ) \
DBGC_EFI_PROTOCOLS_IF ( EXTRA, ##__VA_ARGS__ )
+#define DBGCP_EFI_OPENER( ... ) \
+ DBGC_EFI_OPENER_IF ( PROFILE, ##__VA_ARGS__ )
#define DBGCP_EFI_OPENERS( ... ) \
DBGC_EFI_OPENERS_IF ( PROFILE, ##__VA_ARGS__ )
#define DBGCP_EFI_PROTOCOLS( ... ) \
DBGC_EFI_PROTOCOLS_IF ( PROFILE, ##__VA_ARGS__ )
+/* Allow for EFI-only interface operations */
+#ifdef PLATFORM_efi
+#define EFI_INTF_OP INTF_OP
+#else
+#define EFI_INTF_OP UNUSED_INTF_OP
+#endif
+
extern unsigned long __stack_chk_guard;
extern unsigned long efi_stack_cookie ( EFI_HANDLE handle );
extern void __stack_chk_fail ( void );
@@ -306,5 +340,7 @@ efi_init_stack_guard ( EFI_HANDLE handle ) {
extern EFI_STATUS efi_init ( EFI_HANDLE image_handle,
EFI_SYSTEM_TABLE *systab );
+extern void efi_raise_tpl ( struct efi_saved_tpl *tpl );
+extern void efi_restore_tpl ( struct efi_saved_tpl *tpl );
#endif /* _IPXE_EFI_H */
diff --git a/src/include/ipxe/efi/efi_acpi.h b/src/include/ipxe/efi/efi_acpi.h
index 01456f137..a698863a6 100644
--- a/src/include/ipxe/efi/efi_acpi.h
+++ b/src/include/ipxe/efi/efi_acpi.h
@@ -15,4 +15,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ACPI_PREFIX_efi __efi_
#endif
+/**
+ * Locate ACPI table
+ *
+ * @v signature Requested table signature
+ * @v index Requested index of table with this signature
+ * @ret table Table, or UNULL if not found
+ */
+static inline __attribute__ (( always_inline )) userptr_t
+ACPI_INLINE ( efi, acpi_find ) ( uint32_t signature, unsigned int index ) {
+
+ return acpi_find_via_rsdt ( signature, index );
+}
+
#endif /* _IPXE_EFI_ACPI_H */
diff --git a/src/include/ipxe/efi/efi_autoboot.h b/src/include/ipxe/efi/efi_autoboot.h
index 1d5ddc8c3..706885e28 100644
--- a/src/include/ipxe/efi/efi_autoboot.h
+++ b/src/include/ipxe/efi/efi_autoboot.h
@@ -9,6 +9,8 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-extern void efi_set_autoboot ( void );
+#include <ipxe/efi/efi.h>
+
+extern int efi_set_autoboot_ll_addr ( EFI_HANDLE device );
#endif /* _IPXE_EFI_AUTOBOOT_H */
diff --git a/src/include/ipxe/efi/efi_autoexec.h b/src/include/ipxe/efi/efi_autoexec.h
new file mode 100644
index 000000000..1f93b41cd
--- /dev/null
+++ b/src/include/ipxe/efi/efi_autoexec.h
@@ -0,0 +1,16 @@
+#ifndef _IPXE_EFI_AUTOEXEC_H
+#define _IPXE_EFI_AUTOEXEC_H
+
+/** @file
+ *
+ * EFI autoexec script
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/efi/efi.h>
+
+extern int efi_autoexec_load ( EFI_HANDLE device );
+
+#endif /* _IPXE_EFI_AUTOEXEC_H */
diff --git a/src/include/ipxe/efi/efi_blacklist.h b/src/include/ipxe/efi/efi_blacklist.h
deleted file mode 100644
index c5a5a61dc..000000000
--- a/src/include/ipxe/efi/efi_blacklist.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _IPXE_EFI_BLACKLIST_H
-#define _IPXE_EFI_BLACKLIST_H
-
-/** @file
- *
- * EFI driver blacklist
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-extern void efi_unload_blacklist ( void );
-
-#endif /* _IPXE_EFI_BLACKLIST_H */
diff --git a/src/include/ipxe/efi/efi_cachedhcp.h b/src/include/ipxe/efi/efi_cachedhcp.h
new file mode 100644
index 000000000..cd60d4095
--- /dev/null
+++ b/src/include/ipxe/efi/efi_cachedhcp.h
@@ -0,0 +1,16 @@
+#ifndef _IPXE_EFI_CACHEDHCP_H
+#define _IPXE_EFI_CACHEDHCP_H
+
+/** @file
+ *
+ * EFI cached DHCP packet
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/efi/efi.h>
+
+extern int efi_cachedhcp_record ( EFI_HANDLE device );
+
+#endif /* _IPXE_EFI_CACHEDHCP_H */
diff --git a/src/include/ipxe/efi/efi_null.h b/src/include/ipxe/efi/efi_null.h
new file mode 100644
index 000000000..297457081
--- /dev/null
+++ b/src/include/ipxe/efi/efi_null.h
@@ -0,0 +1,33 @@
+#ifndef _IPXE_EFI_NULL_H
+#define _IPXE_EFI_NULL_H
+
+/** @file
+ *
+ * EFI null interfaces
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/efi/efi.h>
+#include <ipxe/efi/Protocol/AppleNetBoot.h>
+#include <ipxe/efi/Protocol/BlockIo.h>
+#include <ipxe/efi/Protocol/ComponentName2.h>
+#include <ipxe/efi/Protocol/HiiConfigAccess.h>
+#include <ipxe/efi/Protocol/LoadFile.h>
+#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
+#include <ipxe/efi/Protocol/PxeBaseCode.h>
+#include <ipxe/efi/Protocol/SimpleNetwork.h>
+#include <ipxe/efi/Protocol/UsbIo.h>
+
+extern void efi_nullify_snp ( EFI_SIMPLE_NETWORK_PROTOCOL *snp );
+extern void efi_nullify_nii ( EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii );
+extern void efi_nullify_name2 ( EFI_COMPONENT_NAME2_PROTOCOL *name2 );
+extern void efi_nullify_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file );
+extern void efi_nullify_hii ( EFI_HII_CONFIG_ACCESS_PROTOCOL *hii );
+extern void efi_nullify_block ( EFI_BLOCK_IO_PROTOCOL *block );
+extern void efi_nullify_pxe ( EFI_PXE_BASE_CODE_PROTOCOL *pxe );
+extern void efi_nullify_apple ( EFI_APPLE_NET_BOOT_PROTOCOL *apple );
+extern void efi_nullify_usbio ( EFI_USB_IO_PROTOCOL *usbio );
+
+#endif /* _IPXE_EFI_NULL_H */
diff --git a/src/include/ipxe/efi/efi_path.h b/src/include/ipxe/efi/efi_path.h
new file mode 100644
index 000000000..76ded728c
--- /dev/null
+++ b/src/include/ipxe/efi/efi_path.h
@@ -0,0 +1,43 @@
+#ifndef _IPXE_EFI_PATH_H
+#define _IPXE_EFI_PATH_H
+
+/** @file
+ *
+ * EFI device paths
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/interface.h>
+#include <ipxe/efi/efi.h>
+#include <ipxe/efi/Protocol/DevicePath.h>
+
+struct net_device;
+struct uri;
+struct iscsi_session;
+struct aoe_device;
+struct fcp_description;
+struct ib_srp_device;
+struct usb_function;
+
+extern EFI_DEVICE_PATH_PROTOCOL *
+efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
+extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
+extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first,
+ ... );
+extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
+extern EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri );
+extern EFI_DEVICE_PATH_PROTOCOL *
+efi_iscsi_path ( struct iscsi_session *iscsi );
+extern EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev );
+extern EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path ( struct fcp_description *desc );
+extern EFI_DEVICE_PATH_PROTOCOL *
+efi_ib_srp_path ( struct ib_srp_device *ib_srp );
+extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
+
+extern EFI_DEVICE_PATH_PROTOCOL * efi_describe ( struct interface *interface );
+#define efi_describe_TYPE( object_type ) \
+ typeof ( EFI_DEVICE_PATH_PROTOCOL * ( object_type ) )
+
+#endif /* _IPXE_EFI_PATH_H */
diff --git a/src/include/ipxe/efi/efi_pci.h b/src/include/ipxe/efi/efi_pci.h
index 6dd945f05..2ea1a8f0e 100644
--- a/src/include/ipxe/efi/efi_pci.h
+++ b/src/include/ipxe/efi/efi_pci.h
@@ -17,9 +17,17 @@ static inline EFIAPI uint64_t LShiftU64 ( UINT64 value, UINTN shift ) {
return ( value << shift );
}
+/** An EFI PCI device */
+struct efi_pci_device {
+ /** PCI device */
+ struct pci_device pci;
+ /** PCI I/O protocol */
+ EFI_PCI_IO_PROTOCOL *io;
+};
+
extern int efipci_open ( EFI_HANDLE device, UINT32 attributes,
- struct pci_device *pci );
+ struct efi_pci_device *efipci );
extern void efipci_close ( EFI_HANDLE device );
-extern int efipci_info ( EFI_HANDLE device, struct pci_device *pci );
+extern int efipci_info ( EFI_HANDLE device, struct efi_pci_device *efipci );
#endif /* _IPXE_EFI_PCI_H */
diff --git a/src/include/ipxe/efi/efi_snp.h b/src/include/ipxe/efi/efi_snp.h
index 9076f1d56..c278b1d4c 100644
--- a/src/include/ipxe/efi/efi_snp.h
+++ b/src/include/ipxe/efi/efi_snp.h
@@ -76,7 +76,7 @@ struct efi_snp_device {
};
extern int efi_snp_hii_install ( struct efi_snp_device *snpdev );
-extern void efi_snp_hii_uninstall ( struct efi_snp_device *snpdev );
+extern int efi_snp_hii_uninstall ( struct efi_snp_device *snpdev );
extern struct efi_snp_device * find_snpdev ( EFI_HANDLE handle );
extern struct efi_snp_device * last_opened_snpdev ( void );
extern void efi_snp_add_claim ( int delta );
diff --git a/src/include/ipxe/efi/efi_usb.h b/src/include/ipxe/efi/efi_usb.h
index 05b4fad00..06baff529 100644
--- a/src/include/ipxe/efi/efi_usb.h
+++ b/src/include/ipxe/efi/efi_usb.h
@@ -17,14 +17,14 @@
struct efi_usb_device {
/** Name */
const char *name;
- /** The underlying USB device */
- struct usb_device *usb;
- /** The underlying EFI device */
- struct efi_device *efidev;
+ /** The underlying USB function */
+ struct usb_function *func;
/** Configuration descriptor */
struct usb_configuration_descriptor *config;
/** Supported languages */
- struct usb_descriptor_header *languages;
+ uint16_t *lang;
+ /** Length of supported languages */
+ size_t lang_len;
/** List of interfaces */
struct list_head interfaces;
};
diff --git a/src/include/ipxe/efi/efi_utils.h b/src/include/ipxe/efi/efi_utils.h
index 67acba17e..270d38dc8 100644
--- a/src/include/ipxe/efi/efi_utils.h
+++ b/src/include/ipxe/efi/efi_utils.h
@@ -9,13 +9,9 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/DevicePath.h>
struct device;
-extern EFI_DEVICE_PATH_PROTOCOL *
-efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path );
-extern size_t efi_devpath_len ( EFI_DEVICE_PATH_PROTOCOL *path );
extern int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
EFI_HANDLE *parent );
extern int efi_child_add ( EFI_HANDLE parent, EFI_HANDLE child );
diff --git a/src/include/ipxe/efi/efi_veto.h b/src/include/ipxe/efi/efi_veto.h
new file mode 100644
index 000000000..c9ecbb05c
--- /dev/null
+++ b/src/include/ipxe/efi/efi_veto.h
@@ -0,0 +1,13 @@
+#ifndef _IPXE_EFI_VETO_H
+#define _IPXE_EFI_VETO_H
+
+/** @file
+ *
+ * EFI driver vetoes
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+extern void efi_veto ( void );
+
+#endif /* _IPXE_EFI_VETO_H */
diff --git a/src/include/ipxe/efi/efi_wrap.h b/src/include/ipxe/efi/efi_wrap.h
index d8ed1a5cc..6c7ccf2e4 100644
--- a/src/include/ipxe/efi/efi_wrap.h
+++ b/src/include/ipxe/efi/efi_wrap.h
@@ -10,6 +10,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
+extern EFI_SYSTEM_TABLE * efi_wrap_systab ( void );
extern void efi_wrap ( EFI_HANDLE handle );
#endif /* _IPXE_EFI_WRAP_H */
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index 242f91f82..e3bf9f565 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -75,6 +75,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_sanboot ( ERRFILE_CORE | 0x00230000 )
#define ERRFILE_dummy_sanboot ( ERRFILE_CORE | 0x00240000 )
#define ERRFILE_fdt ( ERRFILE_CORE | 0x00250000 )
+#define ERRFILE_dma ( ERRFILE_CORE | 0x00260000 )
+#define ERRFILE_cachedhcp ( ERRFILE_CORE | 0x00270000 )
#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 )
#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )
@@ -208,6 +210,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_intelxl ( ERRFILE_DRIVER | 0x00cb0000 )
#define ERRFILE_pcimsix ( ERRFILE_DRIVER | 0x00cc0000 )
#define ERRFILE_intelxlvf ( ERRFILE_DRIVER | 0x00cd0000 )
+#define ERRFILE_usbblk ( ERRFILE_DRIVER | 0x00ce0000 )
+#define ERRFILE_iphone ( ERRFILE_DRIVER | 0x00cf0000 )
+#define ERRFILE_slirp ( ERRFILE_DRIVER | 0x00d00000 )
#define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 )
#define ERRFILE_arp ( ERRFILE_NET | 0x00010000 )
@@ -284,6 +289,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_xsigo ( ERRFILE_NET | 0x00480000 )
#define ERRFILE_ntp ( ERRFILE_NET | 0x00490000 )
#define ERRFILE_httpntlm ( ERRFILE_NET | 0x004a0000 )
+#define ERRFILE_eap ( ERRFILE_NET | 0x004b0000 )
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
@@ -378,7 +384,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_cert_cmd ( ERRFILE_OTHER | 0x004f0000 )
#define ERRFILE_acpi_settings ( ERRFILE_OTHER | 0x00500000 )
#define ERRFILE_ntlm ( ERRFILE_OTHER | 0x00510000 )
-#define ERRFILE_efi_blacklist ( ERRFILE_OTHER | 0x00520000 )
+#define ERRFILE_efi_veto ( ERRFILE_OTHER | 0x00520000 )
+#define ERRFILE_efi_autoboot ( ERRFILE_OTHER | 0x00530000 )
+#define ERRFILE_efi_autoexec ( ERRFILE_OTHER | 0x00540000 )
+#define ERRFILE_efi_cachedhcp ( ERRFILE_OTHER | 0x00550000 )
+#define ERRFILE_linux_sysfs ( ERRFILE_OTHER | 0x00560000 )
+#define ERRFILE_linux_acpi ( ERRFILE_OTHER | 0x00570000 )
/** @} */
diff --git a/src/include/ipxe/fcp.h b/src/include/ipxe/fcp.h
index 853ca13f6..d86afab42 100644
--- a/src/include/ipxe/fcp.h
+++ b/src/include/ipxe/fcp.h
@@ -163,4 +163,12 @@ struct fcp_prli_service_parameters {
/** Enhanced discovery supported */
#define FCP_PRLI_ENH_DISC 0x0800
+/** An FCP device description */
+struct fcp_description {
+ /** Fibre Channel WWN */
+ struct fc_name wwn;
+ /** SCSI LUN */
+ struct scsi_lun lun;
+};
+
#endif /* _IPXE_FCP_H */
diff --git a/src/include/ipxe/http.h b/src/include/ipxe/http.h
index 0893c9537..5a9baddcb 100644
--- a/src/include/ipxe/http.h
+++ b/src/include/ipxe/http.h
@@ -21,6 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/ntlm.h>
struct http_transaction;
+struct http_connection;
/******************************************************************************
*
@@ -43,13 +44,10 @@ struct http_scheme {
unsigned int port;
/** Transport-layer filter (if any)
*
- * @v xfer Data transfer interface
- * @v name Host name
- * @v next Next interface
+ * @v conn HTTP connection
* @ret rc Return status code
*/
- int ( * filter ) ( struct interface *xfer, const char *name,
- struct interface **next );
+ int ( * filter ) ( struct http_connection *conn );
};
/** HTTP scheme table */
diff --git a/src/include/ipxe/ib_srp.h b/src/include/ipxe/ib_srp.h
index ad407b0cf..4b6df8d3b 100644
--- a/src/include/ipxe/ib_srp.h
+++ b/src/include/ipxe/ib_srp.h
@@ -10,6 +10,8 @@
FILE_LICENCE ( BSD2 );
#include <stdint.h>
+#include <ipxe/acpi.h>
+#include <ipxe/interface.h>
#include <ipxe/infiniband.h>
#include <ipxe/srp.h>
@@ -55,4 +57,37 @@ struct sbft_ib_subtable {
uint8_t reserved[6];
} __attribute__ (( packed ));
+/**
+ * An Infiniband SRP sBFT created by iPXE
+ */
+struct ipxe_ib_sbft {
+ /** The table header */
+ struct sbft_table table;
+ /** The SCSI subtable */
+ struct sbft_scsi_subtable scsi;
+ /** The SRP subtable */
+ struct sbft_srp_subtable srp;
+ /** The Infiniband subtable */
+ struct sbft_ib_subtable ib;
+};
+
+/** An Infiniband SRP device */
+struct ib_srp_device {
+ /** Reference count */
+ struct refcnt refcnt;
+
+ /** SRP transport interface */
+ struct interface srp;
+ /** CMRC interface */
+ struct interface cmrc;
+
+ /** Infiniband device */
+ struct ib_device *ibdev;
+
+ /** ACPI descriptor */
+ struct acpi_descriptor desc;
+ /** Boot firmware table parameters */
+ struct ipxe_ib_sbft sbft;
+};
+
#endif /* _IPXE_IB_SRP_H */
diff --git a/src/include/ipxe/image.h b/src/include/ipxe/image.h
index 2e7eb4cee..4fd270081 100644
--- a/src/include/ipxe/image.h
+++ b/src/include/ipxe/image.h
@@ -175,6 +175,7 @@ extern struct image * alloc_image ( struct uri *uri );
extern int image_set_uri ( struct image *image, struct uri *uri );
extern int image_set_name ( struct image *image, const char *name );
extern int image_set_cmdline ( struct image *image, const char *cmdline );
+extern int image_set_data ( struct image *image, userptr_t data, size_t len );
extern int register_image ( struct image *image );
extern void unregister_image ( struct image *image );
struct image * find_image ( const char *name );
@@ -183,6 +184,8 @@ extern int image_replace ( struct image *replacement );
extern int image_select ( struct image *image );
extern struct image * image_find_selected ( void );
extern int image_set_trust ( int require_trusted, int permanent );
+extern struct image * image_memory ( const char *name, userptr_t data,
+ size_t len );
extern int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf );
extern int image_asn1 ( struct image *image, size_t offset,
struct asn1_cursor **cursor );
diff --git a/src/include/ipxe/infiniband.h b/src/include/ipxe/infiniband.h
index 6f4951f17..379bc109e 100644
--- a/src/include/ipxe/infiniband.h
+++ b/src/include/ipxe/infiniband.h
@@ -416,6 +416,8 @@ struct ib_device {
struct ib_device_operations *op;
/** Port number */
unsigned int port;
+ /** Total ports on device */
+ unsigned int ports;
/** Port open request counter */
unsigned int open_count;
@@ -538,7 +540,6 @@ extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
union ib_gid *gid );
extern void ib_mcast_detach ( struct ib_device *ibdev,
struct ib_queue_pair *qp, union ib_gid *gid );
-extern int ib_count_ports ( struct ib_device *ibdev );
extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad );
extern struct ib_device * alloc_ibdev ( size_t priv_size );
diff --git a/src/include/ipxe/interface.h b/src/include/ipxe/interface.h
index b65002c80..19f58a4b4 100644
--- a/src/include/ipxe/interface.h
+++ b/src/include/ipxe/interface.h
@@ -36,6 +36,21 @@ struct interface_operation {
? op_func : op_func ), \
}
+/**
+ * Define an unused object interface operation
+ *
+ * @v op_type Operation type
+ * @v object_type Implementing method's expected object type
+ * @v op_func Implementing method
+ * @ret op Object interface operation
+ */
+#define UNUSED_INTF_OP( op_type, object_type, op_func ) { \
+ .type = NULL, \
+ .func = ( ( ( ( typeof ( op_func ) * ) NULL ) == \
+ ( ( op_type ## _TYPE ( object_type ) * ) NULL ) ) \
+ ? NULL : NULL ), \
+ }
+
/** An object interface descriptor */
struct interface_descriptor {
/** Offset of interface within containing object */
@@ -154,6 +169,8 @@ extern void intfs_shutdown ( int rc, ... ) __attribute__ (( sentinel ));
extern void intf_restart ( struct interface *intf, int rc );
extern void intfs_vrestart ( va_list intfs, int rc );
extern void intfs_restart ( int rc, ... ) __attribute__ (( sentinel ));
+extern void intf_insert ( struct interface *intf, struct interface *upper,
+ struct interface *lower );
extern void intf_poke ( struct interface *intf,
void ( type ) ( struct interface *intf ) );
diff --git a/src/include/ipxe/iobuf.h b/src/include/ipxe/iobuf.h
index b40ade350..3e079c064 100644
--- a/src/include/ipxe/iobuf.h
+++ b/src/include/ipxe/iobuf.h
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <assert.h>
#include <ipxe/list.h>
+#include <ipxe/dma.h>
/**
* Minimum I/O buffer length
@@ -38,6 +39,9 @@ struct io_buffer {
*/
struct list_head list;
+ /** DMA mapping */
+ struct dma_mapping map;
+
/** Start of the buffer */
void *head;
/** Start of data */
@@ -210,10 +214,75 @@ static inline void iob_populate ( struct io_buffer *iobuf,
(iobuf) = NULL; \
__iobuf; } )
+/**
+ * Map I/O buffer for DMA
+ *
+ * @v iobuf I/O buffer
+ * @v dma DMA device
+ * @v len Length to map
+ * @v flags Mapping flags
+ * @ret rc Return status code
+ */
+static inline __always_inline int iob_map ( struct io_buffer *iobuf,
+ struct dma_device *dma,
+ size_t len, int flags ) {
+ return dma_map ( dma, &iobuf->map, virt_to_phys ( iobuf->data ),
+ len, flags );
+}
+
+/**
+ * Map I/O buffer for transmit DMA
+ *
+ * @v iobuf I/O buffer
+ * @v dma DMA device
+ * @ret rc Return status code
+ */
+static inline __always_inline int iob_map_tx ( struct io_buffer *iobuf,
+ struct dma_device *dma ) {
+ return iob_map ( iobuf, dma, iob_len ( iobuf ), DMA_TX );
+}
+
+/**
+ * Map empty I/O buffer for receive DMA
+ *
+ * @v iobuf I/O buffer
+ * @v dma DMA device
+ * @ret rc Return status code
+ */
+static inline __always_inline int iob_map_rx ( struct io_buffer *iobuf,
+ struct dma_device *dma ) {
+ assert ( iob_len ( iobuf ) == 0 );
+ return iob_map ( iobuf, dma, iob_tailroom ( iobuf ), DMA_RX );
+}
+
+/**
+ * Get I/O buffer DMA address
+ *
+ * @v iobuf I/O buffer
+ * @ret addr DMA address
+ */
+static inline __always_inline physaddr_t iob_dma ( struct io_buffer *iobuf ) {
+ return dma ( &iobuf->map, iobuf->data );
+}
+
+/**
+ * Unmap I/O buffer for DMA
+ *
+ * @v iobuf I/O buffer
+ * @v dma DMA device
+ * @ret rc Return status code
+ */
+static inline __always_inline void iob_unmap ( struct io_buffer *iobuf ) {
+ dma_unmap ( &iobuf->map );
+}
+
extern struct io_buffer * __malloc alloc_iob_raw ( size_t len, size_t align,
size_t offset );
extern struct io_buffer * __malloc alloc_iob ( size_t len );
extern void free_iob ( struct io_buffer *iobuf );
+extern struct io_buffer * __malloc alloc_rx_iob ( size_t len,
+ struct dma_device *dma );
+extern void free_rx_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 );
extern struct io_buffer * iob_concatenate ( struct list_head *list );
diff --git a/src/include/ipxe/linux/linux_acpi.h b/src/include/ipxe/linux/linux_acpi.h
new file mode 100644
index 000000000..a2c33ce2c
--- /dev/null
+++ b/src/include/ipxe/linux/linux_acpi.h
@@ -0,0 +1,18 @@
+#ifndef _IPXE_LINUX_ACPI_H
+#define _IPXE_LINUX_ACPI_H
+
+/** @file
+ *
+ * iPXE ACPI API for Linux
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#ifdef ACPI_LINUX
+#define ACPI_PREFIX_linux
+#else
+#define ACPI_PREFIX_linux __linux_
+#endif
+
+#endif /* _IPXE_LINUX_ACPI_H */
diff --git a/src/include/ipxe/linux/linux_pci.h b/src/include/ipxe/linux/linux_pci.h
index 22ae7f1bc..de42f766b 100644
--- a/src/include/ipxe/linux/linux_pci.h
+++ b/src/include/ipxe/linux/linux_pci.h
@@ -23,6 +23,17 @@ extern int linux_pci_write ( struct pci_device *pci, unsigned long where,
unsigned long value, size_t len );
/**
+ * Determine number of PCI buses within system
+ *
+ * @ret num_bus Number of buses
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( linux, pci_num_bus ) ( void ) {
+ /* Assume all buses may exist */
+ return 0x100;
+}
+
+/**
* Read byte from PCI configuration space
*
* @v pci PCI device
@@ -127,4 +138,17 @@ PCIAPI_INLINE ( linux, pci_write_config_dword ) ( struct pci_device *pci,
return linux_pci_write ( pci, where, value, sizeof ( value ) );
}
+/**
+ * Map PCI bus address as an I/O address
+ *
+ * @v bus_addr PCI bus address
+ * @v len Length of region
+ * @ret io_addr I/O address, or NULL on error
+ */
+static inline __always_inline void *
+PCIAPI_INLINE ( linux, pci_ioremap ) ( struct pci_device *pci __unused,
+ unsigned long bus_addr, size_t len ) {
+ return ioremap ( bus_addr, len );
+}
+
#endif /* _IPXE_LINUX_PCI_H */
diff --git a/src/include/ipxe/linux_api.h b/src/include/ipxe/linux_api.h
new file mode 100644
index 000000000..5b0b242d1
--- /dev/null
+++ b/src/include/ipxe/linux_api.h
@@ -0,0 +1,106 @@
+#ifndef _IPXE_LINUX_API_H
+#define _IPXE_LINUX_API_H
+
+/*
+ * Copyright (C) 2010 Piotr JaroszyƄski <p.jaroszynski@gmail.com>.
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/** @file
+ *
+ * Linux host API
+ *
+ * This file is included from both the iPXE build environment and the
+ * host build environment.
+ *
+ */
+
+#if __STDC_HOSTED__
+#define __asmcall
+#define FILE_LICENCE(x)
+#endif
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+
+#if ! __STDC_HOSTED__
+#define __KERNEL_STRICT_NAMES
+#include <linux/time.h>
+#include <linux/mman.h>
+#include <linux/fcntl.h>
+#include <linux/ioctl.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+#define MAP_FAILED ( ( void * ) -1 )
+#endif
+
+struct sockaddr;
+struct slirp_config;
+struct slirp_callbacks;
+struct Slirp;
+
+extern int linux_errno;
+extern int linux_argc;
+extern char **linux_argv;
+
+extern int __asmcall linux_open ( const char *pathname, int flags, ... );
+extern int __asmcall linux_close ( int fd );
+extern off_t __asmcall linux_lseek ( int fd, off_t offset, int whence );
+extern ssize_t __asmcall linux_read ( int fd, void *buf, size_t count );
+extern ssize_t __asmcall linux_write ( int fd, const void *buf, size_t count );
+extern int __asmcall linux_fcntl ( int fd, int cmd, ... );
+extern int __asmcall linux_ioctl ( int fd, unsigned long request, ... );
+extern int __asmcall linux_fstat_size ( int fd, size_t *size );
+extern int __asmcall linux_poll ( struct pollfd *fds, unsigned int nfds,
+ int timeout );
+extern int __asmcall linux_nanosleep ( const struct timespec *req,
+ struct timespec *rem );
+extern int __asmcall linux_usleep ( unsigned int usec );
+extern int __asmcall linux_gettimeofday ( struct timeval *tv,
+ struct timezone *tz );
+extern void * __asmcall linux_mmap ( void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset );
+extern void * __asmcall linux_mremap ( void *old_address, size_t old_size,
+ size_t new_size, int flags, ... );
+extern int __asmcall linux_munmap ( void *addr, size_t length );
+extern int __asmcall linux_socket ( int domain, int type, int protocol );
+extern int __asmcall linux_bind ( int sockfd, const struct sockaddr *addr,
+ size_t addrlen );
+extern ssize_t __asmcall linux_sendto ( int sockfd, const void *buf,
+ size_t len, int flags,
+ const struct sockaddr *dest_addr,
+ size_t addrlen );
+extern const char * __asmcall linux_strerror ( int linux_errno );
+extern struct Slirp * __asmcall
+linux_slirp_new ( const struct slirp_config *config,
+ const struct slirp_callbacks *callbacks, void *opaque );
+extern void __asmcall linux_slirp_cleanup ( struct Slirp *slirp );
+extern void __asmcall linux_slirp_input ( struct Slirp *slirp,
+ const uint8_t *pkt, int pkt_len );
+extern void __asmcall
+linux_slirp_pollfds_fill ( struct Slirp *slirp, uint32_t *timeout,
+ int ( __asmcall * add_poll ) ( int fd, int events,
+ void *opaque ),
+ void *opaque );
+extern void __asmcall
+linux_slirp_pollfds_poll ( struct Slirp *slirp, int select_error,
+ int ( __asmcall * get_revents ) ( int idx,
+ void *opaque ),
+ void *opaque );
+
+#endif /* _IPXE_LINUX_API_H */
diff --git a/src/include/ipxe/linux_sysfs.h b/src/include/ipxe/linux_sysfs.h
new file mode 100644
index 000000000..d97b649c0
--- /dev/null
+++ b/src/include/ipxe/linux_sysfs.h
@@ -0,0 +1,16 @@
+#ifndef _IPXE_LINUX_SYSFS_H
+#define _IPXE_LINUX_SYSFS_H
+
+/** @file
+ *
+ * Linux sysfs files
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <ipxe/uaccess.h>
+
+extern int linux_sysfs_read ( const char *filename, userptr_t *data );
+
+#endif /* _IPXE_LINUX_SYSFS_H */
diff --git a/src/include/ipxe/malloc.h b/src/include/ipxe/malloc.h
index 1878978fd..180ca001d 100644
--- a/src/include/ipxe/malloc.h
+++ b/src/include/ipxe/malloc.h
@@ -14,7 +14,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/*
* Prototypes for the standard functions (malloc() et al) are in
* stdlib.h. Include <ipxe/malloc.h> only if you need the
- * non-standard functions, such as malloc_dma().
+ * non-standard functions, such as malloc_phys().
*
*/
#include <stdlib.h>
@@ -32,20 +32,18 @@ extern void mpopulate ( void *start, size_t len );
extern void mdumpfree ( void );
/**
- * Allocate memory for DMA
+ * Allocate memory with specified physical alignment and offset
*
* @v size Requested size
* @v align Physical alignment
* @v offset Offset from 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_offset ( size_t size,
- size_t phys_align,
- size_t offset ) {
+static inline void * __malloc malloc_phys_offset ( size_t size,
+ size_t phys_align,
+ size_t offset ) {
void * ptr = alloc_memblock ( size, phys_align, offset );
if ( ptr && size )
VALGRIND_MALLOCLIKE_BLOCK ( ptr, size, 0, 0 );
@@ -53,32 +51,30 @@ static inline void * __malloc malloc_dma_offset ( size_t size,
}
/**
- * Allocate memory for DMA
+ * Allocate memory with specified physical alignment
*
* @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 malloc_dma_offset ( size, phys_align, 0 );
+static inline void * __malloc malloc_phys ( size_t size, size_t phys_align ) {
+ return malloc_phys_offset ( size, phys_align, 0 );
}
/**
- * Free memory allocated with malloc_dma()
+ * Free memory allocated with malloc_phys()
*
- * @v ptr Memory allocated by malloc_dma(), or NULL
- * @v size Size of memory, as passed to malloc_dma()
+ * @v ptr Memory allocated by malloc_phys(), or NULL
+ * @v size Size of memory, as passed to malloc_phys()
*
- * Memory allocated with malloc_dma() can only be freed with
- * free_dma(); it cannot be freed with the standard free().
+ * Memory allocated with malloc_phys() can only be freed with
+ * free_phys(); 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 ) {
+static inline void free_phys ( void *ptr, size_t size ) {
VALGRIND_FREELIKE_BLOCK ( ptr, 0 );
free_memblock ( ptr, size );
}
diff --git a/src/include/ipxe/netdevice.h b/src/include/ipxe/netdevice.h
index d498ab697..b9c651c71 100644
--- a/src/include/ipxe/netdevice.h
+++ b/src/include/ipxe/netdevice.h
@@ -246,6 +246,10 @@ struct net_device_operations {
*
* This method is guaranteed to be called only when the device
* is open.
+ *
+ * If the network device has an associated DMA device, then
+ * the I/O buffer will be automatically mapped for transmit
+ * DMA.
*/
int ( * transmit ) ( struct net_device *netdev,
struct io_buffer *iobuf );
@@ -358,6 +362,8 @@ struct net_device {
char name[NETDEV_NAME_LEN];
/** Underlying hardware device */
struct device *dev;
+ /** DMA device */
+ struct dma_device *dma;
/** Network device operations */
struct net_device_operations *op;
diff --git a/src/include/ipxe/null_acpi.h b/src/include/ipxe/null_acpi.h
index 1e469e33d..cedb02839 100644
--- a/src/include/ipxe/null_acpi.h
+++ b/src/include/ipxe/null_acpi.h
@@ -15,8 +15,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ACPI_PREFIX_null __null_
#endif
-static inline __always_inline userptr_t
-ACPI_INLINE ( null, acpi_find_rsdt ) ( void ) {
+static inline __attribute__ (( always_inline )) userptr_t
+ACPI_INLINE ( null, acpi_find ) ( uint32_t signature __unused,
+ unsigned int index __unused ) {
+
return UNULL;
}
diff --git a/src/include/ipxe/pci.h b/src/include/ipxe/pci.h
index 272c4c06f..6632c574d 100644
--- a/src/include/ipxe/pci.h
+++ b/src/include/ipxe/pci.h
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/device.h>
#include <ipxe/tables.h>
+#include <ipxe/dma.h>
#include <ipxe/pci_io.h>
/** PCI vendor ID */
@@ -187,6 +188,8 @@ struct pci_class_id {
struct pci_device {
/** Generic device */
struct device dev;
+ /** DMA device */
+ struct dma_device dma;
/** Memory base
*
* This is the physical address of the first valid memory BAR.
diff --git a/src/include/ipxe/pci_io.h b/src/include/ipxe/pci_io.h
index 10e69763e..2dcdd9b28 100644
--- a/src/include/ipxe/pci_io.h
+++ b/src/include/ipxe/pci_io.h
@@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/api.h>
+#include <ipxe/iomap.h>
#include <config/ioapi.h>
/**
@@ -122,4 +123,14 @@ int pci_write_config_word ( struct pci_device *pci, unsigned int where,
int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
uint32_t value );
+/**
+ * Map PCI bus address as an I/O address
+ *
+ * @v bus_addr PCI bus address
+ * @v len Length of region
+ * @ret io_addr I/O address, or NULL on error
+ */
+void * pci_ioremap ( struct pci_device *pci, unsigned long bus_addr,
+ size_t len );
+
#endif /* _IPXE_PCI_IO_H */
diff --git a/src/include/ipxe/privkey.h b/src/include/ipxe/privkey.h
index 81108b6bf..a65cf6106 100644
--- a/src/include/ipxe/privkey.h
+++ b/src/include/ipxe/privkey.h
@@ -10,7 +10,60 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/asn1.h>
+#include <ipxe/refcnt.h>
-extern struct asn1_cursor private_key;
+/** A private key */
+struct private_key {
+ /** Reference counter */
+ struct refcnt refcnt;
+ /** ASN.1 object builder */
+ struct asn1_builder builder;
+};
+
+/**
+ * Get reference to private key
+ *
+ * @v key Private key
+ * @ret key Private key
+ */
+static inline __attribute__ (( always_inline )) struct private_key *
+privkey_get ( struct private_key *key ) {
+ ref_get ( &key->refcnt );
+ return key;
+}
+
+/**
+ * Drop reference to private key
+ *
+ * @v key Private key
+ */
+static inline __attribute__ (( always_inline )) void
+privkey_put ( struct private_key *key ) {
+ ref_put ( &key->refcnt );
+}
+
+/**
+ * Get private key ASN.1 cursor
+ *
+ * @v key Private key
+ * @ret cursor ASN.1 cursor
+ */
+static inline __attribute__ (( always_inline )) struct asn1_cursor *
+privkey_cursor ( struct private_key *key ) {
+ return asn1_built ( &key->builder );
+}
+
+extern void privkey_free ( struct refcnt *refcnt );
+
+/**
+ * Initialise empty private key
+ *
+ */
+static inline __attribute__ (( always_inline )) void
+privkey_init ( struct private_key *key ) {
+ ref_init ( &key->refcnt, privkey_free );
+}
+
+extern struct private_key private_key;
#endif /* _IPXE_PRIVKEY_H */
diff --git a/src/include/ipxe/slirp.h b/src/include/ipxe/slirp.h
new file mode 100644
index 000000000..4fb13b934
--- /dev/null
+++ b/src/include/ipxe/slirp.h
@@ -0,0 +1,155 @@
+#ifndef _IPXE_SLIRP_H
+#define _IPXE_SLIRP_H
+
+/** @file
+ *
+ * Linux Slirp network driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/** Ready to be read */
+#define SLIRP_EVENT_IN 0x01
+
+/** Ready to be written */
+#define SLIRP_EVENT_OUT 0x02
+
+/** Exceptional condition */
+#define SLIRP_EVENT_PRI 0x04
+
+/** Error condition */
+#define SLIRP_EVENT_ERR 0x08
+
+/** Hang up */
+#define SLIRP_EVENT_HUP 0x10
+
+/** Slirp device configuration */
+struct slirp_config {
+ /** Configuration version */
+ uint32_t version;
+ /** Restrict to host loopback connections only */
+ int restricted;
+ /** IPv4 is enabled */
+ bool in_enabled;
+ /** IPv4 network */
+ struct in_addr vnetwork;
+ /** IPv4 netmask */
+ struct in_addr vnetmask;
+ /** IPv4 host server address */
+ struct in_addr vhost;
+ /** IPv6 is enabled */
+ bool in6_enabled;
+ /** IPv6 prefix */
+ struct in6_addr vprefix_addr6;
+ /** IPv6 prefix length */
+ uint8_t vprefix_len;
+ /** IPv6 host server address */
+ struct in6_addr vhost6;
+ /** Client hostname */
+ const char *vhostname;
+ /** TFTP server name */
+ const char *tftp_server_name;
+ /** TFTP path prefix */
+ const char *tftp_path;
+ /** Boot filename */
+ const char *bootfile;
+ /** DHCPv4 start address */
+ struct in_addr vdhcp_start;
+ /** DNS IPv4 address */
+ struct in_addr vnameserver;
+ /** DNS IPv6 address */
+ struct in_addr vnameserver6;
+ /** DNS search list */
+ const char **vdnssearch;
+ /** Domain name */
+ const char *vdomainname;
+ /** Interface MTU */
+ size_t if_mtu;
+ /** Interface MRU */
+ size_t if_mru;
+ /** Disable host loopback connections */
+ bool disable_host_loopback;
+ /** Enable emulation (apparently unsafe) */
+ bool enable_emu;
+};
+
+/** Slirp device callbacks */
+struct slirp_callbacks {
+ /**
+ * Send packet
+ *
+ * @v buf Data buffer
+ * @v len Length of data
+ * @v device Device opaque pointer
+ * @ret len Consumed length (or negative on error)
+ */
+ ssize_t ( __asmcall * send_packet ) ( const void *buf, size_t len,
+ void *device );
+ /**
+ * Print an error message
+ *
+ * @v msg Error message
+ * @v device Device opaque pointer
+ */
+ void ( __asmcall * guest_error ) ( const char *msg, void *device );
+ /**
+ * Get virtual clock
+ *
+ * @v device Device opaque pointer
+ * @ret clock_ns Clock time in nanoseconds
+ */
+ int64_t ( __asmcall * clock_get_ns ) ( void *device );
+ /**
+ * Create a new timer
+ *
+ * @v callback Timer callback
+ * @v opaque Timer opaque pointer
+ * @v device Device opaque pointer
+ * @ret timer Timer
+ */
+ void * ( __asmcall * timer_new ) ( void ( __asmcall * callback )
+ ( void *opaque ),
+ void *opaque, void *device );
+ /**
+ * Delete a timer
+ *
+ * @v timer Timer
+ * @v device Device opaque pointer
+ */
+ void ( __asmcall * timer_free ) ( void *timer, void *device );
+ /**
+ * Set timer expiry time
+ *
+ * @v timer Timer
+ * @v expire Expiry time
+ * @v device Device opaque pointer
+ */
+ void ( __asmcall * timer_mod ) ( void *timer, int64_t expire,
+ void *device );
+ /**
+ * Register file descriptor for polling
+ *
+ * @v fd File descriptor
+ * @v device Device opaque pointer
+ */
+ void ( __asmcall * register_poll_fd ) ( int fd, void *device );
+ /**
+ * Unregister file descriptor
+ *
+ * @v fd File descriptor
+ * @v device Device opaque pointer
+ */
+ void ( __asmcall * unregister_poll_fd ) ( int fd, void *device );
+ /**
+ * Notify that new events are ready
+ *
+ * @v device Device opaque pointer
+ */
+ void ( __asmcall * notify ) ( void *device );
+};
+
+#endif /* _IPXE_SLIRP_H */
diff --git a/src/include/ipxe/smbios.h b/src/include/ipxe/smbios.h
index c1d8fea3e..42278fb24 100644
--- a/src/include/ipxe/smbios.h
+++ b/src/include/ipxe/smbios.h
@@ -31,15 +31,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Include all architecture-dependent SMBIOS API headers */
#include <bits/smbios.h>
-/** Signature for SMBIOS entry point */
+/** Signature for 32-bit SMBIOS entry point */
#define SMBIOS_SIGNATURE \
( ( '_' << 0 ) + ( 'S' << 8 ) + ( 'M' << 16 ) + ( '_' << 24 ) )
+/** Signature for 64-bit SMBIOS entry point */
+#define SMBIOS3_SIGNATURE \
+ ( ( '_' << 0 ) + ( 'S' << 8 ) + ( 'M' << 16 ) + ( '3' << 24 ) )
+
/**
- * SMBIOS entry point
+ * SMBIOS 32-bit entry point
*
- * This is the single table which describes the list of SMBIOS
- * structures. It is located by scanning through the BIOS segment.
+ * This is the 32-bit version of the table which describes the list of
+ * SMBIOS structures. It may be located by scanning through the BIOS
+ * segment or via an EFI configuration table.
*/
struct smbios_entry {
/** Signature
@@ -75,6 +80,41 @@ struct smbios_entry {
uint8_t bcd_revision;
} __attribute__ (( packed ));
+/**
+ * SMBIOS 64-bit entry point
+ *
+ * This is the 64-bit version of the table which describes the list of
+ * SMBIOS structures. It may be located by scanning through the BIOS
+ * segment or via an EFI configuration table.
+ */
+struct smbios3_entry {
+ /** Signature
+ *
+ * Must be equal to SMBIOS3_SIGNATURE
+ */
+ uint32_t signature;
+ /** Signature extra byte */
+ uint8_t extra;
+ /** Checksum */
+ uint8_t checksum;
+ /** Length */
+ uint8_t len;
+ /** Major version */
+ uint8_t major;
+ /** Minor version */
+ uint8_t minor;
+ /** Documentation revision */
+ uint8_t docrev;
+ /** Entry point revision */
+ uint8_t revision;
+ /** Reserved */
+ uint8_t reserved;
+ /** Structure table length */
+ uint32_t smbios_len;
+ /** Structure table address */
+ uint64_t smbios_address;
+} __attribute__ (( packed ));
+
/** An SMBIOS structure header */
struct smbios_header {
/** Type */
@@ -155,6 +195,9 @@ struct smbios_enclosure_information {
/** SMBIOS OEM strings structure type */
#define SMBIOS_TYPE_OEM_STRINGS 11
+/** SMBIOS end of table type */
+#define SMBIOS_TYPE_END 127
+
/**
* SMBIOS entry point descriptor
*
@@ -192,5 +235,6 @@ extern int read_smbios_string ( struct smbios_structure *structure,
unsigned int index,
void *data, size_t len );
extern int smbios_version ( void );
+extern void smbios_clear ( void );
#endif /* _IPXE_SMBIOS_H */
diff --git a/src/include/ipxe/tables.h b/src/include/ipxe/tables.h
index 60f8efdea..28a87da96 100644
--- a/src/include/ipxe/tables.h
+++ b/src/include/ipxe/tables.h
@@ -444,75 +444,4 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
pointer >= table_start ( table ) ; \
pointer-- )
-/******************************************************************************
- *
- * Intel's C compiler chokes on several of the constructs used in this
- * file. The workarounds are ugly, so we use them only for an icc
- * build.
- *
- */
-#define ICC_ALIGN_HACK_FACTOR 128
-#ifdef __ICC
-
-/*
- * icc miscompiles zero-length arrays by inserting padding to a length
- * of two array elements. We therefore have to generate the
- * __table_entries() symbols by hand in asm.
- *
- */
-#undef __table_entries
-#define __table_entries( table, idx ) ( { \
- extern __table_type ( table ) \
- __table_temp_sym ( idx, __LINE__ ) [] \
- __table_entry ( table, idx ) \
- asm ( __table_entries_sym ( table, idx ) ); \
- __asm__ ( ".ifndef %c0\n\t" \
- ".section " __table_section ( table, idx ) "\n\t" \
- ".align %c1\n\t" \
- "\n%c0:\n\t" \
- ".previous\n\t" \
- ".endif\n\t" \
- : : "i" ( __table_temp_sym ( idx, __LINE__ ) ), \
- "i" ( __table_alignment ( table ) ) ); \
- __table_temp_sym ( idx, __LINE__ ); } )
-#define __table_entries_sym( table, idx ) \
- "__tbl_" __table_name ( table ) "_" #idx
-#define __table_temp_sym( a, b ) \
- ___table_temp_sym( __table_, a, _, b )
-#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
-
-/*
- * icc ignores __attribute__ (( aligned (x) )) when it is used to
- * decrease the compiler's default choice of alignment (which may be
- * higher than the alignment actually required by the structure). We
- * work around this by forcing the alignment to a large multiple of
- * the required value (so that we are never attempting to decrease the
- * default alignment) and then postprocessing the object file to
- * reduce the alignment back down to the "real" value.
- *
- */
-#undef __table_alignment
-#define __table_alignment( table ) \
- ( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
-
-/*
- * Because of the alignment hack, we must ensure that the compiler
- * never tries to place multiple objects within the same section,
- * otherwise the assembler will insert padding to the (incorrect)
- * alignment boundary. Do this by appending the line number to table
- * section names.
- *
- * Note that we don't need to worry about padding between array
- * elements, since the alignment is declared on the variable (i.e. the
- * whole array) rather than on the type (i.e. on all individual array
- * elements).
- */
-#undef __table_section
-#define __table_section( table, idx ) \
- ".tbl." __table_name ( table ) "." __table_str ( idx ) \
- "." __table_xstr ( __LINE__ )
-#define __table_xstr( x ) __table_str ( x )
-
-#endif /* __ICC */
-
#endif /* _IPXE_TABLES_H */
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index febbdc589..8b03579cc 100644
--- a/src/include/ipxe/tls.h
+++ b/src/include/ipxe/tls.h
@@ -18,6 +18,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/sha1.h>
#include <ipxe/sha256.h>
#include <ipxe/x509.h>
+#include <ipxe/privkey.h>
#include <ipxe/pending.h>
#include <ipxe/iobuf.h>
#include <ipxe/tables.h>
@@ -255,6 +256,11 @@ struct tls_session {
/** Server name */
const char *name;
+ /** Root of trust */
+ struct x509_root *root;
+ /** Private key */
+ struct private_key *key;
+
/** Session ID */
uint8_t id[32];
/** Length of session ID */
@@ -319,13 +325,17 @@ struct tls_connection {
struct digest_algorithm *handshake_digest;
/** Digest algorithm context used for handshake verification */
uint8_t *handshake_ctx;
- /** Client certificate (if used) */
- struct x509_certificate *cert;
+ /** Private key */
+ struct private_key *key;
+ /** Client certificate chain (if used) */
+ struct x509_chain *certs;
/** Secure renegotiation flag */
int secure_renegotiation;
/** Verification data */
struct tls_verify_data verify;
+ /** Root of trust */
+ struct x509_root *root;
/** Server certificate chain */
struct x509_chain *chain;
/** Certificate validator */
@@ -379,6 +389,6 @@ struct tls_connection {
#define TLS_RX_ALIGN 16
extern int add_tls ( struct interface *xfer, const char *name,
- struct interface **next );
+ struct x509_root *root, struct private_key *key );
#endif /* _IPXE_TLS_H */
diff --git a/src/include/ipxe/usb.h b/src/include/ipxe/usb.h
index 68289d26d..911247ede 100644
--- a/src/include/ipxe/usb.h
+++ b/src/include/ipxe/usb.h
@@ -580,6 +580,7 @@ usb_endpoint_described ( struct usb_endpoint *ep,
struct usb_interface_descriptor *interface,
unsigned int type, unsigned int index );
extern int usb_endpoint_open ( struct usb_endpoint *ep );
+extern int usb_endpoint_clear_halt ( struct usb_endpoint *ep );
extern void usb_endpoint_close ( struct usb_endpoint *ep );
extern int usb_message ( struct usb_endpoint *ep, unsigned int request,
unsigned int value, unsigned int index,
@@ -620,6 +621,7 @@ usb_recycle ( struct usb_endpoint *ep, struct io_buffer *iobuf ) {
}
extern int usb_prefill ( struct usb_endpoint *ep );
+extern int usb_refill_limit ( struct usb_endpoint *ep, unsigned int max );
extern int usb_refill ( struct usb_endpoint *ep );
extern void usb_flush ( struct usb_endpoint *ep );
@@ -1237,6 +1239,23 @@ usb_set_interface ( struct usb_device *usb, unsigned int interface,
NULL, 0 );
}
+/**
+ * Get USB depth
+ *
+ * @v usb USB device
+ * @ret depth Hub depth
+ */
+static inline unsigned int usb_depth ( struct usb_device *usb ) {
+ struct usb_device *parent;
+ unsigned int depth;
+
+ /* Navigate up to root hub, constructing depth as we go */
+ for ( depth = 0 ; ( parent = usb->port->hub->usb ) ; usb = parent )
+ depth++;
+
+ return depth;
+}
+
extern struct list_head usb_buses;
extern struct usb_interface_descriptor *
@@ -1272,7 +1291,6 @@ extern struct usb_bus * find_usb_bus_by_location ( unsigned int bus_type,
extern int usb_alloc_address ( struct usb_bus *bus );
extern void usb_free_address ( struct usb_bus *bus, unsigned int address );
extern unsigned int usb_route_string ( struct usb_device *usb );
-extern unsigned int usb_depth ( struct usb_device *usb );
extern struct usb_port * usb_root_hub_port ( struct usb_device *usb );
extern struct usb_port * usb_transaction_translator ( struct usb_device *usb );
@@ -1396,6 +1414,9 @@ struct usb_driver {
/** Declare a USB driver */
#define __usb_driver __table_entry ( USB_DRIVERS, 01 )
+/** Declare a USB fallback driver */
+#define __usb_fallback_driver __table_entry ( USB_DRIVERS, 02 )
+
/** USB driver scores */
enum usb_driver_score {
/** Fallback driver (has no effect on overall score) */
diff --git a/src/include/ipxe/validator.h b/src/include/ipxe/validator.h
index 0aee56eb0..367e4045d 100644
--- a/src/include/ipxe/validator.h
+++ b/src/include/ipxe/validator.h
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/interface.h>
#include <ipxe/x509.h>
-extern int create_validator ( struct interface *job, struct x509_chain *chain );
+extern int create_validator ( struct interface *job, struct x509_chain *chain,
+ struct x509_root *root );
#endif /* _IPXE_VALIDATOR_H */
diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h
index 78eeafbfb..c703c8f10 100644
--- a/src/include/ipxe/x509.h
+++ b/src/include/ipxe/x509.h
@@ -191,6 +191,8 @@ struct x509_certificate {
/** Flags */
unsigned int flags;
+ /** Root against which certificate has been validated (if any) */
+ struct x509_root *root;
/** Maximum number of subsequent certificates in chain */
unsigned int path_remaining;
@@ -218,12 +220,10 @@ struct x509_certificate {
/** X.509 certificate flags */
enum x509_flags {
- /** Certificate has been validated */
- X509_FL_VALIDATED = 0x0001,
/** Certificate was added at build time */
- X509_FL_PERMANENT = 0x0002,
+ X509_FL_PERMANENT = 0x0001,
/** Certificate was added explicitly at run time */
- X509_FL_EXPLICIT = 0x0004,
+ X509_FL_EXPLICIT = 0x0002,
};
/**
@@ -340,8 +340,10 @@ struct x509_access_method {
const struct asn1_cursor *raw );
};
-/** An X.509 root certificate store */
+/** An X.509 root certificate list */
struct x509_root {
+ /** Reference count */
+ struct refcnt refcnt;
/** Fingerprint digest algorithm */
struct digest_algorithm *digest;
/** Number of certificates */
@@ -350,11 +352,35 @@ struct x509_root {
const void *fingerprints;
};
+/**
+ * Get reference to X.509 root certificate list
+ *
+ * @v root X.509 root certificate list
+ * @ret root X.509 root certificate list
+ */
+static inline __attribute__ (( always_inline )) struct x509_root *
+x509_root_get ( struct x509_root *root ) {
+ ref_get ( &root->refcnt );
+ return root;
+}
+
+/**
+ * Drop reference to X.509 root certificate list
+ *
+ * @v root X.509 root certificate list
+ */
+static inline __attribute__ (( always_inline )) void
+x509_root_put ( struct x509_root *root ) {
+ ref_put ( &root->refcnt );
+}
+
extern const char * x509_name ( struct x509_certificate *cert );
extern int x509_parse ( struct x509_certificate *cert,
const struct asn1_cursor *raw );
extern int x509_certificate ( const void *data, size_t len,
struct x509_certificate **cert );
+extern int x509_is_valid ( struct x509_certificate *cert,
+ struct x509_root *root );
extern int x509_validate ( struct x509_certificate *cert,
struct x509_certificate *issuer,
time_t time, struct x509_root *root );
@@ -384,21 +410,13 @@ extern int x509_check_root ( struct x509_certificate *cert,
extern int x509_check_time ( struct x509_certificate *cert, time_t time );
/**
- * Check if X.509 certificate is valid
- *
- * @v cert X.509 certificate
- */
-static inline int x509_is_valid ( struct x509_certificate *cert ) {
- return ( cert->flags & X509_FL_VALIDATED );
-}
-
-/**
* Invalidate X.509 certificate
*
* @v cert X.509 certificate
*/
static inline void x509_invalidate ( struct x509_certificate *cert ) {
- cert->flags &= ~X509_FL_VALIDATED;
+ x509_root_put ( cert->root );
+ cert->root = NULL;
cert->path_remaining = 0;
}