diff options
| author | Simon Rettberg | 2021-03-08 15:55:33 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2021-03-08 15:55:33 +0100 |
| commit | 6707d9218c8e6e760e53068d5f41ceb31fac6ea0 (patch) | |
| tree | 88e8fc84ede2a0ed2c1cec3a6109beb9fb53abf5 /src/include/ipxe | |
| parent | Merge branch 'master' into openslx (diff) | |
| parent | [linux] Do not assume that stat() works on sysfs files (diff) | |
| download | ipxe-6707d9218c8e6e760e53068d5f41ceb31fac6ea0.tar.gz ipxe-6707d9218c8e6e760e53068d5f41ceb31fac6ea0.tar.xz ipxe-6707d9218c8e6e760e53068d5f41ceb31fac6ea0.zip | |
Merge branch 'master' into openslx
Diffstat (limited to 'src/include/ipxe')
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; } |
