Merge branch 'master' into respect_cc_v4

pull/723/head
David Yeske 2023-02-02 11:23:32 -05:00 committed by GitHub
commit 3c301c6cf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
277 changed files with 23823 additions and 17529 deletions

View File

@ -369,7 +369,6 @@ endif
# Include architecture-specific include path
ifdef ARCH
INCDIRS += arch/$(ARCH)/include
INCDIRS += arch/$(ARCH)/include/$(PLATFORM)
endif
###############################################################################
@ -462,7 +461,9 @@ ifeq ($(CCTYPE),gcc)
CFLAGS += -ffreestanding
CFLAGS += -fcommon
CFLAGS += -Wall -W -Wformat-nonliteral
CFLAGS += -Wno-array-bounds -Wno-dangling-pointer
HOST_CFLAGS += -Wall -W -Wformat-nonliteral
HOST_CFLAGS += -Wno-array-bounds -Wno-dangling-pointer
endif
CFLAGS += $(WORKAROUND_CFLAGS) $(EXTRA_CFLAGS)
ASFLAGS += $(WORKAROUND_ASFLAGS) $(EXTRA_ASFLAGS)
@ -510,6 +511,10 @@ CFLAGS += -include include/compiler.h
#
CFLAGS += -DASM_TCHAR='$(ASM_TCHAR)' -DASM_TCHAR_OPS='$(ASM_TCHAR_OPS)'
# Inhibit the default -Dlinux
#
CFLAGS += -Ulinux
# CFLAGS for specific object types
#
CFLAGS_c +=

View File

@ -8,6 +8,10 @@ SYMBOL_PREFIX = _ipxe__
#
CFLAGS += -UNVALGRIND
# The Linux linker script
#
LDSCRIPT = scripts/linux.lds
# Use a two-stage link
#
LDFLAGS += -r -d

View File

@ -0,0 +1,6 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Include generic Linux Makefile
#
MAKEDEPS += Makefile.linux
include Makefile.linux

View File

@ -5,7 +5,7 @@ SRCDIRS += arch/arm32/libgcc
# ARM32-specific flags
#
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs -mfloat-abi=soft
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs
CFLAGS += -mword-relocations
ASFLAGS += -mthumb -mcpu=cortex-a15
@ -13,6 +13,11 @@ ASFLAGS += -mthumb -mcpu=cortex-a15
#
CFLAGS += -fshort-wchar
# EFI requires that enums are always 32 bits, and nothing else
# currently cares
#
CFLAGS += -fno-short-enums
# Include common ARM Makefile
MAKEDEPS += arch/arm/Makefile
include arch/arm/Makefile

View File

@ -1,8 +1,8 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# UEFI requires that enums are always 32 bits
# EFI uses the soft float ABI
#
CFLAGS += -fno-short-enums
CFLAGS += -mfloat-abi=soft
# Specify EFI image builder
#

View File

@ -1,5 +1,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.section ".note.GNU-stack", "", %progbits
.text
.arm

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM32
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,5 +1,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.section ".note.GNU-stack", "", %progbits
.text
.thumb

View File

@ -1,5 +1,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.section ".note.GNU-stack", "", %progbits
.text
.arm

View File

@ -0,0 +1,10 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Starting virtual address
#
LDFLAGS += -Ttext=0x400000
# Include generic Linux Makefile
#
MAKEDEPS += arch/arm/Makefile.linux
include arch/arm/Makefile.linux

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2015 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 (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM64
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM64
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,8 +1,8 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Linker script
# Starting virtual address
#
LDSCRIPT = arch/i386/scripts/linux.lds
LDFLAGS += -Ttext=0x08048000
# Compiler flags for building host API wrapper
#

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_IA32
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_IA32
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
#endif

View File

@ -22,9 +22,6 @@ SRCDIRS += arch/x86/drivers/xen
SRCDIRS += arch/x86/drivers/hyperv
SRCDIRS += arch/x86/transitions
# breaks building some of the linux-related objects
CFLAGS += -Ulinux
# disable valgrind
CFLAGS += -DNVALGRIND

View File

@ -1,9 +1,5 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Include x86 Linux headers
#
INCDIRS += arch/x86/include/linux
# Include generic Linux Makefile
#
MAKEDEPS += Makefile.linux

View File

@ -45,7 +45,7 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) {
PCIDIRECT_CONFIG_ADDRESS );
}
PROVIDE_PCIAPI_INLINE ( direct, pci_num_bus );
PROVIDE_PCIAPI_INLINE ( direct, pci_discover );
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte );
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
@ -53,3 +53,5 @@ PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
struct pci_api pcidirect_api = PCIAPI_RUNTIME ( direct );

View File

@ -252,13 +252,17 @@ static void bzimage_update_header ( struct image *image,
*/
static int bzimage_parse_cmdline ( struct image *image,
struct bzimage_context *bzimg,
const char *cmdline ) {
char *cmdline ) {
char *sep;
char *vga;
char *mem;
/* Look for "vga=" */
if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
vga += 4;
sep = strchr ( vga, ' ' );
if ( sep )
*sep = '\0';
if ( strcmp ( vga, "normal" ) == 0 ) {
bzimg->vid_mode = BZI_VID_MODE_NORMAL;
} else if ( strcmp ( vga, "ext" ) == 0 ) {
@ -267,11 +271,13 @@ static int bzimage_parse_cmdline ( struct image *image,
bzimg->vid_mode = BZI_VID_MODE_ASK;
} else {
bzimg->vid_mode = strtoul ( vga, &vga, 0 );
if ( *vga && ( *vga != ' ' ) ) {
DBGC ( image, "bzImage %p strange \"vga=\""
if ( *vga ) {
DBGC ( image, "bzImage %p strange \"vga=\" "
"terminator '%c'\n", image, *vga );
}
}
if ( sep )
*sep = ' ';
}
/* Look for "mem=" */
@ -522,7 +528,7 @@ static void bzimage_load_initrds ( struct image *image,
*/
static int bzimage_exec ( struct image *image ) {
struct bzimage_context bzimg;
const char *cmdline = ( image->cmdline ? image->cmdline : "" );
char *cmdline = ( image->cmdline ? image->cmdline : "" );
int rc;
/* Read and parse header from image */

View File

@ -11,5 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/pcibios.h>
#include <ipxe/pcidirect.h>
#include <ipxe/pcicloud.h>
#endif /* _BITS_PCI_IO_H */

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_PCBIOS_DHCPARCH_H
#define _IPXE_PCBIOS_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
#endif /* _IPXE_PCBIOS_DHCPARCH_H */

View File

@ -145,4 +145,6 @@ PCIAPI_INLINE ( pcbios, pci_ioremap ) ( struct pci_device *pci __unused,
return ioremap ( bus_addr, len );
}
extern struct pci_api pcibios_api;
#endif /* _IPXE_PCIBIOS_H */

View File

@ -0,0 +1,18 @@
#ifndef _IPXE_PCICLOUD_H
#define _IPXE_PCICLOUD_H
/** @file
*
* Cloud VM PCI configuration space access
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef PCIAPI_CLOUD
#define PCIAPI_PREFIX_cloud
#else
#define PCIAPI_PREFIX_cloud __cloud_
#endif
#endif /* _IPXE_PCICLOUD_H */

View File

@ -26,14 +26,18 @@ struct pci_device;
extern void pcidirect_prepare ( struct pci_device *pci, int where );
/**
* Determine number of PCI buses within system
* Find next PCI bus:dev.fn address range in system
*
* @ret num_bus Number of buses
* @v busdevfn Starting PCI bus:dev.fn address
* @v range PCI bus:dev.fn address range to fill in
*/
static inline __always_inline int
PCIAPI_INLINE ( direct, pci_num_bus ) ( void ) {
static inline __always_inline void
PCIAPI_INLINE ( direct, pci_discover ) ( uint32_t busdevfn __unused,
struct pci_range *range ) {
/* Scan first bus and rely on bridge detection to find higher buses */
return 1;
range->start = PCI_BUSDEVFN ( 0, 0, 0, 0 );
range->count = PCI_BUSDEVFN ( 0, 1, 0, 0 );
}
/**
@ -151,4 +155,6 @@ PCIAPI_INLINE ( direct, pci_ioremap ) ( struct pci_device *pci __unused,
return ioremap ( bus_addr, len );
}
extern struct pci_api pcidirect_api;
#endif /* _PCIDIRECT_H */

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _LINUX_DHCP_ARCH_H
#define _LINUX_DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL);
#include <ipxe/dhcp.h>
// Emulate one of the supported arch-platforms
#include <arch/i386/include/pcbios/ipxe/dhcp_arch.h>
//#include <arch/i386/include/efi/ipxe/dhcp_arch.h>
//#include <arch/x86_64/include/efi/ipxe/dhcp_arch.h>
#endif

View File

@ -59,7 +59,7 @@ static void cachedhcp_init ( void ) {
}
/* Record cached DHCPACK */
if ( ( rc = cachedhcp_record ( &cached_dhcpack,
if ( ( rc = cachedhcp_record ( &cached_dhcpack, 0,
phys_to_user ( cached_dhcpack_phys ),
sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n",

View File

@ -34,13 +34,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*/
/**
* Determine number of PCI buses within system
* Find next PCI bus:dev.fn address range in system
*
* @ret num_bus Number of buses
* @v busdevfn Starting PCI bus:dev.fn address
* @v range PCI bus:dev.fn address range to fill in
*/
static int pcibios_num_bus ( void ) {
static void pcibios_discover ( uint32_t busdevfn __unused,
struct pci_range *range ) {
int discard_a, discard_D;
uint8_t max_bus;
uint16_t num_bus;
/* We issue this call using flat real mode, to work around a
* bug in some HP BIOSes.
@ -48,16 +50,20 @@ static int pcibios_num_bus ( void ) {
__asm__ __volatile__ ( REAL_CODE ( "call flatten_real_mode\n\t"
"stc\n\t"
"int $0x1a\n\t"
"movzbw %%cl, %%cx\n\t"
"incw %%cx\n\t"
"jnc 1f\n\t"
"xorw %%cx, %%cx\n\t"
"\n1:\n\t" )
: "=c" ( max_bus ), "=a" ( discard_a ),
: "=c" ( num_bus ), "=a" ( discard_a ),
"=D" ( discard_D )
: "a" ( PCIBIOS_INSTALLATION_CHECK >> 16 ),
"D" ( 0 )
: "ebx", "edx" );
return ( max_bus + 1 );
/* Populate range */
range->start = PCI_BUSDEVFN ( 0, 0, 0, 0 );
range->count = PCI_BUSDEVFN ( 0, num_bus, 0, 0 );
}
/**
@ -114,7 +120,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
return ( status >> 8 );
}
PROVIDE_PCIAPI ( pcbios, pci_num_bus, pcibios_num_bus );
PROVIDE_PCIAPI ( pcbios, pci_discover, pcibios_discover );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_dword );
@ -122,3 +128,5 @@ PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_ioremap );
struct pci_api pcibios_api = PCIAPI_RUNTIME ( pcbios );

View File

@ -0,0 +1,191 @@
/*
* Copyright (C) 2022 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 (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/init.h>
#include <ipxe/pci.h>
#include <ipxe/ecam.h>
#include <ipxe/pcibios.h>
#include <ipxe/pcidirect.h>
#include <ipxe/pcicloud.h>
/** @file
*
* Cloud VM PCI configuration space access
*
*/
/** Selected PCI configuration space access API */
static struct pci_api *pcicloud = &ecam_api;
/**
* Find next PCI bus:dev.fn address range in system
*
* @v busdevfn Starting PCI bus:dev.fn address
* @v range PCI bus:dev.fn address range to fill in
*/
static void pcicloud_discover ( uint32_t busdevfn, struct pci_range *range ) {
pcicloud->pci_discover ( busdevfn, range );
}
/**
* Read byte from PCI configuration space
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value read
* @ret rc Return status code
*/
static int pcicloud_read_config_byte ( struct pci_device *pci,
unsigned int where, uint8_t *value ) {
return pcicloud->pci_read_config_byte ( pci, where, value );
}
/**
* Read 16-bit word from PCI configuration space
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value read
* @ret rc Return status code
*/
static int pcicloud_read_config_word ( struct pci_device *pci,
unsigned int where, uint16_t *value ) {
return pcicloud->pci_read_config_word ( pci, where, value );
}
/**
* Read 32-bit dword from PCI configuration space
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value read
* @ret rc Return status code
*/
static int pcicloud_read_config_dword ( struct pci_device *pci,
unsigned int where, uint32_t *value ) {
return pcicloud->pci_read_config_dword ( pci, where, value );
}
/**
* Write byte to PCI configuration space
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value to be written
* @ret rc Return status code
*/
static int pcicloud_write_config_byte ( struct pci_device *pci,
unsigned int where, uint8_t value ) {
return pcicloud->pci_write_config_byte ( pci, where, value );
}
/**
* Write 16-bit word to PCI configuration space
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value to be written
* @ret rc Return status code
*/
static int pcicloud_write_config_word ( struct pci_device *pci,
unsigned int where, uint16_t value ) {
return pcicloud->pci_write_config_word ( pci, where, value );
}
/**
* Write 32-bit dword to PCI configuration space
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value to be written
* @ret rc Return status code
*/
static int pcicloud_write_config_dword ( struct pci_device *pci,
unsigned int where, uint32_t value ) {
return pcicloud->pci_write_config_dword ( pci, where, 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 void * pcicloud_ioremap ( struct pci_device *pci,
unsigned long bus_addr, size_t len ) {
return pcicloud->pci_ioremap ( pci, bus_addr, len );
}
PROVIDE_PCIAPI ( cloud, pci_discover, pcicloud_discover );
PROVIDE_PCIAPI ( cloud, pci_read_config_byte, pcicloud_read_config_byte );
PROVIDE_PCIAPI ( cloud, pci_read_config_word, pcicloud_read_config_word );
PROVIDE_PCIAPI ( cloud, pci_read_config_dword, pcicloud_read_config_dword );
PROVIDE_PCIAPI ( cloud, pci_write_config_byte, pcicloud_write_config_byte );
PROVIDE_PCIAPI ( cloud, pci_write_config_word, pcicloud_write_config_word );
PROVIDE_PCIAPI ( cloud, pci_write_config_dword, pcicloud_write_config_dword );
PROVIDE_PCIAPI ( cloud, pci_ioremap, pcicloud_ioremap );
/**
* Initialise cloud VM PCI configuration space access
*
*/
static void pcicloud_init ( void ) {
static struct pci_api *apis[] = {
&ecam_api, &pcibios_api, &pcidirect_api
};
struct pci_range range;
unsigned int i;
/* Select first API that successfully discovers an address range */
for ( i = 0 ; i < ( sizeof ( apis ) / sizeof ( apis[0] ) ) ; i++ ) {
pcicloud = apis[i];
pcicloud_discover ( 0, &range );
if ( range.count != 0 ) {
DBGC ( pcicloud, "PCICLOUD selected %s API\n",
pcicloud->name );
break;
}
}
/* The PCI direct API can never fail discovery since the range
* is hardcoded.
*/
assert ( range.count != 0 );
}
/** Cloud VM PCI configuration space access initialisation function */
struct init_fn pcicloud_init_fn __init_fn ( INIT_EARLY ) = {
.initialise = pcicloud_init,
};

View File

@ -12,6 +12,7 @@
#include <ipxe/uaccess.h>
#include <ipxe/process.h>
#include <ipxe/netdevice.h>
#include <ipxe/malloc.h>
#include <realmode.h>
#include <pxe.h>
@ -482,3 +483,28 @@ struct pxe_api_call pxe_udp_api[] __pxe_api_call = {
PXE_API_CALL ( PXENV_UDP_READ, pxenv_udp_read,
struct s_PXENV_UDP_READ ),
};
/**
* Discard some cached PXE UDP data
*
* @ret discarded Number of cached items discarded
*/
static unsigned int pxe_udp_discard ( void ) {
struct io_buffer *iobuf;
unsigned int discarded = 0;
/* Try to discard the oldest received UDP packet */
iobuf = list_first_entry ( &pxe_udp.list, struct io_buffer, list );
if ( iobuf ) {
list_del ( &iobuf->list );
free_iob ( iobuf );
discarded++;
}
return discarded;
}
/** PXE UDP cache discarder */
struct cache_discarder pxe_udp_discarder __cache_discarder ( CACHE_NORMAL ) = {
.discard = pxe_udp_discard,
};

View File

@ -1,8 +1,8 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Linker script
# Starting virtual address
#
LDSCRIPT = arch/x86_64/scripts/linux.lds
LDFLAGS += -Ttext=0x400000
# Include generic Linux Makefile
#

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86_64
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86_64
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
#endif

View File

@ -1,106 +0,0 @@
/* -*- sh -*- */
/*
* Linker script for x86_64 Linux images
*
*/
OUTPUT_FORMAT ( "elf64-x86-64", "elf64-x86-64", "elf64-x86-64" )
OUTPUT_ARCH ( i386:x86-64 )
SECTIONS {
_max_align = 32;
. = 0x400000;
/*
* The text section
*
*/
. = ALIGN ( _max_align );
.text : {
_text = .;
*(.text)
*(.text.*)
_etext = .;
}
/*
* The rodata section
*
*/
. = ALIGN ( _max_align );
.rodata : {
_rodata = .;
*(.rodata)
*(.rodata.*)
_erodata = .;
}
/*
* The data section
*
* Adjust the address for the data segment. We want to adjust up to
* the same address within the page on the next page up.
*/
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1));
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
.data : {
_data = .;
*(.data)
*(.data.*)
KEEP(*(SORT(.tbl.*)))
KEEP(*(.provided))
KEEP(*(.provided.*))
_edata = .;
}
/*
* The bss section
*
*/
. = ALIGN ( _max_align );
.bss : {
_bss = .;
*(.bss)
*(.bss.*)
*(COMMON)
_ebss = .;
}
/*
* Weak symbols that need zero values if not otherwise defined
*
*/
.weak 0x0 : {
_weak = .;
*(.weak)
*(.weak.*)
_eweak = .;
}
_assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" );
/*
* Dispose of the comment and note sections to make the link map
* easier to read
*
*/
/DISCARD/ : {
*(.comment)
*(.comment.*)
*(.note)
*(.note.*)
*(.rel)
*(.rel.*)
*(.discard)
*(.discard.*)
*(.sbat)
*(.sbat.*)
}
}

View File

@ -3,5 +3,5 @@
*/
#ifdef PLATFORM_pcbios
#undef PCIAPI_PCBIOS
#define PCIAPI_DIRECT
#define PCIAPI_CLOUD
#endif

View File

@ -124,3 +124,15 @@ REQUIRE_OBJECT ( rsa_aes_cbc_sha1 );
defined ( CRYPTO_DIGEST_SHA256 )
REQUIRE_OBJECT ( rsa_aes_cbc_sha256 );
#endif
/* RSA, AES-GCM, and SHA-256 */
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_GCM ) && \
defined ( CRYPTO_DIGEST_SHA256 )
REQUIRE_OBJECT ( rsa_aes_gcm_sha256 );
#endif
/* RSA, AES-GCM, and SHA-384 */
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_GCM ) && \
defined ( CRYPTO_DIGEST_SHA384 )
REQUIRE_OBJECT ( rsa_aes_gcm_sha384 );
#endif

View File

@ -18,6 +18,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** AES-CBC block cipher */
#define CRYPTO_CIPHER_AES_CBC
/** AES-GCM block cipher */
#define CRYPTO_CIPHER_AES_GCM
/** MD4 digest algorithm */
//#define CRYPTO_DIGEST_MD4

View File

@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcppkt.h>
#include <ipxe/init.h>
#include <ipxe/netdevice.h>
#include <ipxe/vlan.h>
#include <ipxe/cachedhcp.h>
/** @file
@ -43,6 +44,8 @@ struct cached_dhcp_packet {
const char *name;
/** DHCP packet (if any) */
struct dhcp_packet *dhcppkt;
/** VLAN tag (if applicable) */
unsigned int vlan;
};
/** Cached DHCPACK */
@ -136,15 +139,26 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
* matches this network device.
*/
if ( memcmp ( ll_addr, chaddr, ll_addr_len ) != 0 ) {
DBGC ( colour, "CACHEDHCP %s does not match %s\n",
cache->name, netdev->name );
DBGC ( colour, "CACHEDHCP %s %s does not match %s\n",
cache->name, ll_protocol->ntoa ( chaddr ),
netdev->name );
return 0;
}
/* Do nothing unless cached packet's VLAN tag matches
* this network device.
*/
if ( vlan_tag ( netdev ) != cache->vlan ) {
DBGC ( colour, "CACHEDHCP %s VLAN %d does not match "
"%s\n", cache->name, cache->vlan,
netdev->name );
return 0;
}
DBGC ( colour, "CACHEDHCP %s is for %s\n",
cache->name, netdev->name );
/* Use network device's settings block */
settings = netdev_settings ( netdev );
DBGC ( colour, "CACHEDHCP %s is for %s\n",
cache->name, netdev->name );
}
/* Register settings */
@ -165,12 +179,13 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
* Record cached DHCP packet
*
* @v cache Cached DHCP packet
* @v vlan VLAN tag, if any
* @v data DHCPACK packet buffer
* @v max_len Maximum possible length
* @ret rc Return status code
*/
int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
size_t max_len ) {
int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan,
userptr_t data, size_t max_len ) {
struct dhcp_packet *dhcppkt;
struct dhcp_packet *tmp;
struct dhcphdr *dhcphdr;
@ -225,36 +240,55 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name,
user_to_phys ( data, 0 ), len, max_len );
cache->dhcppkt = dhcppkt;
cache->vlan = vlan;
return 0;
}
/**
* Cached DHCPACK startup function
* Cached DHCP packet startup function
*
*/
static void cachedhcp_startup ( void ) {
/* Apply cached ProxyDHCPOFFER, if any */
cachedhcp_apply ( &cached_proxydhcp, NULL );
cachedhcp_free ( &cached_proxydhcp );
/* Apply cached PXEBSACK, if any */
cachedhcp_apply ( &cached_pxebs, NULL );
cachedhcp_free ( &cached_pxebs );
/* Free any remaining cached packets */
/* Report unclaimed DHCPACK, if any. Do not free yet, since
* it may still be claimed by a dynamically created device
* such as a VLAN device.
*/
if ( cached_dhcpack.dhcppkt ) {
DBGC ( colour, "CACHEDHCP %s unclaimed\n",
cached_dhcpack.name );
}
}
/**
* Cached DHCP packet shutdown function
*
* @v booting System is shutting down for OS boot
*/
static void cachedhcp_shutdown ( int booting __unused ) {
/* Free cached DHCPACK, if any */
if ( cached_dhcpack.dhcppkt ) {
DBGC ( colour, "CACHEDHCP %s never claimed\n",
cached_dhcpack.name );
}
cachedhcp_free ( &cached_dhcpack );
cachedhcp_free ( &cached_proxydhcp );
cachedhcp_free ( &cached_pxebs );
}
/** Cached DHCPACK startup function */
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
.name = "cachedhcp",
.startup = cachedhcp_startup,
.shutdown = cachedhcp_shutdown,
};
/**

View File

@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/crypto.h>
#include <ipxe/ecb.h>
#include <ipxe/cbc.h>
#include <ipxe/gcm.h>
#include <ipxe/aes.h>
/** AES strides
@ -778,25 +779,18 @@ static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
return 0;
}
/**
* Set initialisation vector
*
* @v ctx Context
* @v iv Initialisation vector
*/
static void aes_setiv ( void *ctx __unused, const void *iv __unused ) {
/* Nothing to do */
}
/** Basic AES algorithm */
struct cipher_algorithm aes_algorithm = {
.name = "aes",
.ctxsize = sizeof ( struct aes_context ),
.blocksize = AES_BLOCKSIZE,
.alignsize = 0,
.authsize = 0,
.setkey = aes_setkey,
.setiv = aes_setiv,
.setiv = cipher_null_setiv,
.encrypt = aes_encrypt,
.decrypt = aes_decrypt,
.auth = cipher_null_auth,
};
/* AES in Electronic Codebook mode */
@ -806,3 +800,7 @@ ECB_CIPHER ( aes_ecb, aes_ecb_algorithm,
/* AES in Cipher Block Chaining mode */
CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
aes_algorithm, struct aes_context, AES_BLOCKSIZE );
/* AES in Galois/Counter mode */
GCM_CIPHER ( aes_gcm, aes_gcm_algorithm,
aes_algorithm, struct aes_context, AES_BLOCKSIZE );

View File

@ -96,12 +96,6 @@ static void arc4_xor ( void *ctxv, const void *srcv, void *dstv,
ctx->j = j;
}
static void arc4_setiv ( void *ctx __unused, const void *iv __unused )
{
/* ARC4 does not use a fixed-length IV */
}
/**
* Perform ARC4 encryption or decryption, skipping initial keystream bytes
*
@ -125,8 +119,11 @@ struct cipher_algorithm arc4_algorithm = {
.name = "ARC4",
.ctxsize = ARC4_CTX_SIZE,
.blocksize = 1,
.alignsize = 1,
.authsize = 0,
.setkey = arc4_setkey,
.setiv = arc4_setiv,
.setiv = cipher_null_setiv,
.encrypt = arc4_xor,
.decrypt = arc4_xor,
.auth = cipher_null_auth,
};

View File

@ -32,16 +32,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <ipxe/crypto.h>
static void digest_null_init ( void *ctx __unused ) {
void digest_null_init ( void *ctx __unused ) {
/* Do nothing */
}
static void digest_null_update ( void *ctx __unused, const void *src __unused,
size_t len __unused ) {
void digest_null_update ( void *ctx __unused, const void *src __unused,
size_t len __unused ) {
/* Do nothing */
}
static void digest_null_final ( void *ctx __unused, void *out __unused ) {
void digest_null_final ( void *ctx __unused, void *out __unused ) {
/* Do nothing */
}
@ -55,76 +55,80 @@ struct digest_algorithm digest_null = {
.final = digest_null_final,
};
static int cipher_null_setkey ( void *ctx __unused, const void *key __unused,
size_t keylen __unused ) {
int cipher_null_setkey ( void *ctx __unused, const void *key __unused,
size_t keylen __unused ) {
/* Do nothing */
return 0;
}
static void cipher_null_setiv ( void *ctx __unused,
const void *iv __unused ) {
void cipher_null_setiv ( void *ctx __unused, const void *iv __unused,
size_t ivlen __unused ) {
/* Do nothing */
}
static void cipher_null_encrypt ( void *ctx __unused, const void *src,
void *dst, size_t len ) {
void cipher_null_encrypt ( void *ctx __unused, const void *src, void *dst,
size_t len ) {
memcpy ( dst, src, len );
}
static void cipher_null_decrypt ( void *ctx __unused, const void *src,
void *dst, size_t len ) {
void cipher_null_decrypt ( void *ctx __unused, const void *src, void *dst,
size_t len ) {
memcpy ( dst, src, len );
}
void cipher_null_auth ( void *ctx __unused, void *auth __unused ) {
/* Do nothing */
}
struct cipher_algorithm cipher_null = {
.name = "null",
.ctxsize = 0,
.blocksize = 1,
.alignsize = 1,
.authsize = 0,
.setkey = cipher_null_setkey,
.setiv = cipher_null_setiv,
.encrypt = cipher_null_encrypt,
.decrypt = cipher_null_decrypt,
.auth = cipher_null_auth,
};
static int pubkey_null_init ( void *ctx __unused, const void *key __unused,
size_t key_len __unused ) {
int pubkey_null_init ( void *ctx __unused, const void *key __unused,
size_t key_len __unused ) {
return 0;
}
static size_t pubkey_null_max_len ( void *ctx __unused ) {
size_t pubkey_null_max_len ( void *ctx __unused ) {
return 0;
}
static int pubkey_null_encrypt ( void *ctx __unused,
const void *plaintext __unused,
size_t plaintext_len __unused,
void *ciphertext __unused ) {
int pubkey_null_encrypt ( void *ctx __unused, const void *plaintext __unused,
size_t plaintext_len __unused,
void *ciphertext __unused ) {
return 0;
}
static int pubkey_null_decrypt ( void *ctx __unused,
const void *ciphertext __unused,
size_t ciphertext_len __unused,
void *plaintext __unused ) {
int pubkey_null_decrypt ( void *ctx __unused, const void *ciphertext __unused,
size_t ciphertext_len __unused,
void *plaintext __unused ) {
return 0;
}
static int pubkey_null_sign ( void *ctx __unused,
struct digest_algorithm *digest __unused,
const void *value __unused,
void *signature __unused ) {
int pubkey_null_sign ( void *ctx __unused,
struct digest_algorithm *digest __unused,
const void *value __unused, void *signature __unused ) {
return 0;
}
static int pubkey_null_verify ( void *ctx __unused,
struct digest_algorithm *digest __unused,
const void *value __unused,
const void *signature __unused ,
size_t signature_len __unused ) {
int pubkey_null_verify ( void *ctx __unused,
struct digest_algorithm *digest __unused,
const void *value __unused,
const void *signature __unused ,
size_t signature_len __unused ) {
return 0;
}
static void pubkey_null_final ( void *ctx __unused ) {
void pubkey_null_final ( void *ctx __unused ) {
/* Do nothing */
}

133
src/crypto/dhe.c 100644
View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2022 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 Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
* Ephemeral Diffie-Hellman key exchange
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <ipxe/bigint.h>
#include <ipxe/dhe.h>
/**
* Calculate Diffie-Hellman key
*
* @v modulus Prime modulus
* @v len Length of prime modulus
* @v generator Generator
* @v generator_len Length of generator
* @v partner Partner public key
* @v partner_len Length of partner public key
* @v private Private key
* @v private_len Length of private key
* @ret public Public key (length equal to prime modulus)
* @ret shared Shared secret (length equal to prime modulus)
* @ret rc Return status code
*/
int dhe_key ( const void *modulus, size_t len, const void *generator,
size_t generator_len, const void *partner, size_t partner_len,
const void *private, size_t private_len, void *public,
void *shared ) {
unsigned int size = bigint_required_size ( len );
unsigned int private_size = bigint_required_size ( private_len );
bigint_t ( size ) *mod;
bigint_t ( private_size ) *exp;
size_t tmp_len = bigint_mod_exp_tmp_len ( mod, exp );
struct {
bigint_t ( size ) modulus;
bigint_t ( size ) generator;
bigint_t ( size ) partner;
bigint_t ( private_size ) private;
bigint_t ( size ) result;
uint8_t tmp[tmp_len];
} __attribute__ (( packed )) *ctx;
int rc;
DBGC2 ( modulus, "DHE %p modulus:\n", modulus );
DBGC2_HDA ( modulus, 0, modulus, len );
DBGC2 ( modulus, "DHE %p generator:\n", modulus );
DBGC2_HDA ( modulus, 0, generator, generator_len );
DBGC2 ( modulus, "DHE %p partner public key:\n", modulus );
DBGC2_HDA ( modulus, 0, partner, partner_len );
DBGC2 ( modulus, "DHE %p private key:\n", modulus );
DBGC2_HDA ( modulus, 0, private, private_len );
/* Sanity checks */
if ( generator_len > len ) {
DBGC ( modulus, "DHE %p overlength generator\n", modulus );
rc = -EINVAL;
goto err_sanity;
}
if ( partner_len > len ) {
DBGC ( modulus, "DHE %p overlength partner public key\n",
modulus );
rc = -EINVAL;
goto err_sanity;
}
if ( private_len > len ) {
DBGC ( modulus, "DHE %p overlength private key\n", modulus );
rc = -EINVAL;
goto err_sanity;
}
/* Allocate context */
ctx = malloc ( sizeof ( *ctx ) );
if ( ! ctx ) {
rc = -ENOMEM;
goto err_alloc;
}
/* Initialise context */
bigint_init ( &ctx->modulus, modulus, len );
bigint_init ( &ctx->generator, generator, generator_len );
bigint_init ( &ctx->partner, partner, partner_len );
bigint_init ( &ctx->private, private, private_len );
/* Calculate public key */
bigint_mod_exp ( &ctx->generator, &ctx->modulus, &ctx->private,
&ctx->result, ctx->tmp );
bigint_done ( &ctx->result, public, len );
DBGC2 ( modulus, "DHE %p public key:\n", modulus );
DBGC2_HDA ( modulus, 0, public, len );
/* Calculate shared secret */
bigint_mod_exp ( &ctx->partner, &ctx->modulus, &ctx->private,
&ctx->result, ctx->tmp );
bigint_done ( &ctx->result, shared, len );
DBGC2 ( modulus, "DHE %p shared secret:\n", modulus );
DBGC2_HDA ( modulus, 0, shared, len );
/* Success */
rc = 0;
free ( ctx );
err_alloc:
err_sanity:
return rc;
}

535
src/crypto/gcm.c 100644
View File

@ -0,0 +1,535 @@
/*
* Copyright (C) 2022 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 Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
* Galois/Counter Mode (GCM)
*
* The GCM algorithm is specified in
*
* https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
* https://csrc.nist.rip/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
*
*/
#include <stdint.h>
#include <string.h>
#include <byteswap.h>
#include <ipxe/crypto.h>
#include <ipxe/gcm.h>
/**
* Perform encryption
*
* This value is chosen to allow for ANDing with a fragment length.
*/
#define GCM_FL_ENCRYPT 0x00ff
/**
* Calculate hash over an initialisation vector value
*
* The hash calculation for a non 96-bit initialisation vector is
* identical to the calculation used for additional data, except that
* the non-additional data length counter is used.
*/
#define GCM_FL_IV 0x0100
/**
* GCM field polynomial
*
* GCM treats 128-bit blocks as polynomials in GF(2^128) with the
* field polynomial f(x) = 1 + x + x^2 + x^7 + x^128.
*
* In a somewhat bloody-minded interpretation of "big-endian", the
* constant term (with degree zero) is arbitrarily placed in the
* leftmost bit of the big-endian binary representation (i.e. the most
* significant bit of byte 0), thereby failing to correspond to the
* bit ordering in any CPU architecture in existence. This
* necessitates some wholly gratuitous byte reversals when
* constructing the multiplication tables, since all CPUs will treat
* bit 0 as being the least significant bit within a byte.
*
* The field polynomial maps to the 128-bit constant
* 0xe1000000000000000000000000000000 (with the x^128 term outside the
* 128-bit range), and can therefore be treated as a single-byte
* value.
*/
#define GCM_POLY 0xe1
/**
* Hash key for which multiplication tables are cached
*
* GCM operates much more efficiently with a cached multiplication
* table, which costs 4kB per hash key. Since this exceeds the
* available stack space, we place a single 4kB cache in .bss and
* recalculate the cached values as required. In the common case of a
* single HTTPS connection being used to download a (relatively) large
* file, the same key will be used repeatedly for almost all GCM
* operations, and so the overhead of recalculation is negligible.
*/
static const union gcm_block *gcm_cached_key;
/**
* Cached multiplication table (M0) for Shoup's method
*
* Each entry within this table represents the result of multiplying
* the cached hash key by an arbitrary 8-bit polynomial.
*/
static union gcm_block gcm_cached_mult[256];
/**
* Cached reduction table (R) for Shoup's method
*
* Each entry within this table represents the result of multiplying
* the fixed polynomial x^128 by an arbitrary 8-bit polynomial. Only
* the leftmost 16 bits are stored, since all other bits within the
* result will always be zero.
*/
static uint16_t gcm_cached_reduce[256];
/**
* Reverse bits in a byte
*
* @v byte Byte
* @ret etyb Bit-reversed byte
*/
static inline __attribute__ (( always_inline )) uint8_t
gcm_reverse ( const uint8_t byte ) {
uint8_t etyb = etyb;
uint8_t mask;
for ( mask = 1 ; mask ; mask <<= 1 ) {
etyb <<= 1;
if ( byte & mask )
etyb |= 1;
}
return etyb;
}
/**
* Update GCM counter
*
* @v ctr Counter
* @v delta Amount to add to counter
*/
static inline __attribute__ (( always_inline )) void
gcm_count ( union gcm_block *ctr, uint32_t delta ) {
uint32_t *value = &ctr->ctr.value;
/* Update counter modulo 2^32 */
*value = cpu_to_be32 ( be32_to_cpu ( *value ) + delta );
}
/**
* XOR partial data block
*
* @v src1 Source buffer 1
* @v src2 Source buffer 2
* @v dst Destination buffer
* @v len Length
*/
static inline void gcm_xor ( const void *src1, const void *src2, void *dst,
size_t len ) {
uint8_t *dst_bytes = dst;
const uint8_t *src1_bytes = src1;
const uint8_t *src2_bytes = src2;
/* XOR one byte at a time */
while ( len-- )
*(dst_bytes++) = ( *(src1_bytes++) ^ *(src2_bytes++) );
}
/**
* XOR whole data block in situ
*
* @v src Source block
* @v dst Destination block
*/
static inline void gcm_xor_block ( const union gcm_block *src,
union gcm_block *dst ) {
/* XOR whole dwords */
dst->dword[0] ^= src->dword[0];
dst->dword[1] ^= src->dword[1];
dst->dword[2] ^= src->dword[2];
dst->dword[3] ^= src->dword[3];
}
/**
* Multiply polynomial by (x)
*
* @v mult Multiplicand
* @v res Result
*/
static void gcm_multiply_x ( const union gcm_block *mult,
union gcm_block *res ) {
unsigned int i;
uint8_t byte;
uint8_t carry;
/* Multiply by (x) by shifting all bits rightward */
for ( i = 0, carry = 0 ; i < sizeof ( res->byte ) ; i++ ) {
byte = mult->byte[i];
res->byte[i] = ( ( carry << 7 ) | ( byte >> 1 ) );
carry = ( byte & 0x01 );
}
/* If result overflows, reduce modulo the field polynomial */
if ( carry )
res->byte[0] ^= GCM_POLY;
}
/**
* Construct cached tables
*
* @v key Hash key
* @v context Context
*/
static void gcm_cache ( const union gcm_block *key ) {
union gcm_block *mult;
uint16_t reduce;
unsigned int this;
unsigned int other;
unsigned int i;
/* Calculate M0[1..255] and R[1..255]
*
* The R[] values are independent of the key, but the overhead
* of recalculating them here is negligible and saves on
* overall code size since the calculations are related.
*/
for ( i = 1 ; i < 256 ; i++ ) {
/* Reverse bit order to compensate for poor life choices */
this = gcm_reverse ( i );
/* Construct entries */
mult = &gcm_cached_mult[this];
if ( this & 0x80 ) {
/* Odd number: entry[i] = entry[i - 1] + poly */
other = ( this & 0x7f ); /* bit-reversed (i - 1) */
gcm_xor ( key, &gcm_cached_mult[other], mult,
sizeof ( *mult ) );
reduce = gcm_cached_reduce[other];
reduce ^= be16_to_cpu ( GCM_POLY << 8 );
gcm_cached_reduce[this] = reduce;
} else {
/* Even number: entry[i] = entry[i/2] * (x) */
other = ( this << 1 ); /* bit-reversed (i / 2) */
gcm_multiply_x ( &gcm_cached_mult[other], mult );
reduce = be16_to_cpu ( gcm_cached_reduce[other] );
reduce >>= 1;
gcm_cached_reduce[this] = cpu_to_be16 ( reduce );
}
}
/* Record cached key */
gcm_cached_key = key;
}
/**
* Multiply polynomial by (x^8) in situ
*
* @v poly Multiplicand and result
*/
static void gcm_multiply_x_8 ( union gcm_block *poly ) {
uint8_t *byte;
uint8_t msb;
/* Reduction table must already have been calculated */
assert ( gcm_cached_key != NULL );
/* Record most significant byte */
byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
msb = *byte;
/* Multiply least significant bytes by shifting */
for ( ; byte > &poly->byte[0] ; byte-- )
*byte = *( byte - 1 );
*byte = 0;
/* Multiply most significant byte via reduction table */
poly->word[0] ^= gcm_cached_reduce[msb];
}
/**
* Multiply polynomial by hash key in situ
*
* @v key Hash key
* @v poly Multiplicand and result
*/
static void gcm_multiply_key ( const union gcm_block *key,
union gcm_block *poly ) {
union gcm_block res;
uint8_t *byte;
/* Construct tables, if necessary */
if ( gcm_cached_key != key )
gcm_cache ( key );
/* Multiply using Shoup's algorithm */
byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
memcpy ( &res, &gcm_cached_mult[ *byte ], sizeof ( res ) );
for ( byte-- ; byte >= &poly->byte[0] ; byte-- ) {
gcm_multiply_x_8 ( &res );
gcm_xor_block ( &gcm_cached_mult[ *byte ], &res );
}
/* Overwrite result */
memcpy ( poly, &res, sizeof ( *poly ) );
}
/**
* Encrypt/decrypt/authenticate data
*
* @v context Context
* @v src Input data
* @v dst Output data, or NULL to process additional data
* @v len Length of data
* @v flags Operation flags
*/
static void gcm_process ( struct gcm_context *context, const void *src,
void *dst, size_t len, unsigned int flags ) {
union gcm_block tmp;
uint64_t *total;
size_t frag_len;
unsigned int block;
/* Calculate block number (for debugging) */
block = ( ( ( context->len.len.add + 8 * sizeof ( tmp ) - 1 ) /
( 8 * sizeof ( tmp ) ) ) +
( ( context->len.len.data + 8 * sizeof ( tmp ) - 1 ) /
( 8 * sizeof ( tmp ) ) ) + 1 );
/* Update total length (in bits) */
total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
&context->len.len.data : &context->len.len.add );
*total += ( len * 8 );
/* Process data */
for ( ; len ; src += frag_len, len -= frag_len, block++ ) {
/* Calculate fragment length */
frag_len = len;
if ( frag_len > sizeof ( tmp ) )
frag_len = sizeof ( tmp );
/* Update hash with input data */
gcm_xor ( src, &context->hash, &context->hash, frag_len );
/* Encrypt/decrypt block, if applicable */
if ( dst ) {
/* Increment counter */
gcm_count ( &context->ctr, 1 );
/* Encrypt counter */
DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
DBGC2_HDA ( context, 0, &context->ctr,
sizeof ( context->ctr ) );
cipher_encrypt ( context->raw_cipher, &context->raw_ctx,
&context->ctr, &tmp, sizeof ( tmp ) );
DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
context, block );
DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
/* Encrypt/decrypt data */
gcm_xor ( src, &tmp, dst, frag_len );
dst += frag_len;
/* Update hash with encrypted data, if applicable */
gcm_xor ( &tmp, &context->hash, &context->hash,
( frag_len & flags ) );
}
/* Update hash */
gcm_multiply_key ( &context->key, &context->hash );
DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
DBGC2_HDA ( context, 0, &context->hash,
sizeof ( context->hash ) );
}
}
/**
* Construct hash
*
* @v context Context
* @v hash Hash to fill in
*/
static void gcm_hash ( struct gcm_context *context, union gcm_block *hash ) {
/* Construct big-endian lengths block */
hash->len.add = cpu_to_be64 ( context->len.len.add );
hash->len.data = cpu_to_be64 ( context->len.len.data );
DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
/* Update hash */
gcm_xor_block ( &context->hash, hash );
gcm_multiply_key ( &context->key, hash );
DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
}
/**
* Construct tag
*
* @v context Context
* @v tag Tag
*/
void gcm_tag ( struct gcm_context *context, union gcm_block *tag ) {
union gcm_block tmp;
uint32_t offset;
/* Construct hash */
gcm_hash ( context, tag );
/* Construct encrypted initial counter value */
memcpy ( &tmp, &context->ctr, sizeof ( tmp ) );
offset = ( ( -context->len.len.data ) / ( 8 * sizeof ( tmp ) ) );
gcm_count ( &tmp, offset );
cipher_encrypt ( context->raw_cipher, &context->raw_ctx, &tmp,
&tmp, sizeof ( tmp ) );
DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
/* Construct tag */
gcm_xor_block ( &tmp, tag );
DBGC2 ( context, "GCM %p T:\n", context );
DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
}
/**
* Set key
*
* @v context Context
* @v key Key
* @v keylen Key length
* @v raw_cipher Underlying cipher
* @ret rc Return status code
*/
int gcm_setkey ( struct gcm_context *context, const void *key, size_t keylen,
struct cipher_algorithm *raw_cipher ) {
int rc;
/* Initialise GCM context */
memset ( context, 0, sizeof ( *context ) );
context->raw_cipher = raw_cipher;
/* Set underlying block cipher key */
if ( ( rc = cipher_setkey ( raw_cipher, context->raw_ctx, key,
keylen ) ) != 0 )
return rc;
/* Construct GCM hash key */
cipher_encrypt ( raw_cipher, context->raw_ctx, &context->ctr,
&context->key, sizeof ( context->key ) );
DBGC2 ( context, "GCM %p H:\n", context );
DBGC2_HDA ( context, 0, &context->key, sizeof ( context->key ) );
/* Reset counter */
context->ctr.ctr.value = cpu_to_be32 ( 1 );
/* Construct cached tables */
gcm_cache ( &context->key );
return 0;
}
/**
* Set initialisation vector
*
* @v ctx Context
* @v iv Initialisation vector
* @v ivlen Initialisation vector length
*/
void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) {
union gcm_block *check = ( ( void * ) context );
/* Sanity checks */
linker_assert ( &context->hash == check, gcm_bad_layout );
linker_assert ( &context->len == check + 1, gcm_bad_layout );
linker_assert ( &context->ctr == check + 2, gcm_bad_layout );
linker_assert ( &context->key == check + 3, gcm_bad_layout );
/* Reset non-key state */
memset ( context, 0, offsetof ( typeof ( *context ), key ) );
/* Reset counter */
context->ctr.ctr.value = cpu_to_be32 ( 1 );
/* Process initialisation vector */
if ( ivlen == sizeof ( context->ctr.ctr.iv ) ) {
/* Initialisation vector is exactly 96 bits, use it as-is */
memcpy ( context->ctr.ctr.iv, iv, ivlen );
} else {
/* Calculate hash over initialisation vector */
gcm_process ( context, iv, NULL, ivlen, GCM_FL_IV );
gcm_hash ( context, &context->ctr );
assert ( context->len.len.add == 0 );
/* Reset non-key, non-counter state */
memset ( context, 0, offsetof ( typeof ( *context ), ctr ) );
}
DBGC2 ( context, "GCM %p Y[0]:\n", context );
DBGC2_HDA ( context, 0, &context->ctr, sizeof ( context->ctr ) );
}
/**
* Encrypt data
*
* @v context Context
* @v src Data to encrypt
* @v dst Buffer for encrypted data, or NULL for additional data
* @v len Length of data
*/
void gcm_encrypt ( struct gcm_context *context, const void *src, void *dst,
size_t len ) {
/* Process data */
gcm_process ( context, src, dst, len, GCM_FL_ENCRYPT );
}
/**
* Decrypt data
*
* @v context Context
* @v src Data to decrypt
* @v dst Buffer for decrypted data, or NULL for additional data
* @v len Length of data
*/
void gcm_decrypt ( struct gcm_context *context, const void *src, void *dst,
size_t len ) {
/* Process data */
gcm_process ( context, src, dst, len, 0 );
}

View File

@ -46,94 +46,62 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/crypto.h>
#include <ipxe/hmac.h>
/**
* Reduce HMAC key length
*
* @v digest Digest algorithm to use
* @v digest_ctx Digest context
* @v key Key
* @v key_len Length of key
*/
static void hmac_reduce_key ( struct digest_algorithm *digest,
void *key, size_t *key_len ) {
uint8_t digest_ctx[digest->ctxsize];
digest_init ( digest, digest_ctx );
digest_update ( digest, digest_ctx, key, *key_len );
digest_final ( digest, digest_ctx, key );
*key_len = digest->digestsize;
}
/**
* Initialise HMAC
*
* @v digest Digest algorithm to use
* @v digest_ctx Digest context
* @v ctx HMAC context
* @v key Key
* @v key_len Length of key
*
* The length of the key should be less than the block size of the
* digest algorithm being used. (If the key length is greater, it
* will be replaced with its own digest, and key_len will be updated
* accordingly).
*/
void hmac_init ( struct digest_algorithm *digest, void *digest_ctx,
void *key, size_t *key_len ) {
unsigned char k_ipad[digest->blocksize];
void hmac_init ( struct digest_algorithm *digest, void *ctx, const void *key,
size_t key_len ) {
hmac_context_t ( digest ) *hctx = ctx;
unsigned int i;
/* Reduce key if necessary */
if ( *key_len > sizeof ( k_ipad ) )
hmac_reduce_key ( digest, key, key_len );
/* Construct input pad */
memset ( k_ipad, 0, sizeof ( k_ipad ) );
memcpy ( k_ipad, key, *key_len );
for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) {
k_ipad[i] ^= 0x36;
memset ( hctx->pad, 0, sizeof ( hctx->pad ) );
if ( key_len <= sizeof ( hctx->pad ) ) {
memcpy ( hctx->pad, key, key_len );
} else {
digest_init ( digest, hctx->ctx );
digest_update ( digest, hctx->ctx, key, key_len );
digest_final ( digest, hctx->ctx, hctx->pad );
}
for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) {
hctx->pad[i] ^= 0x36;
}
/* Start inner hash */
digest_init ( digest, digest_ctx );
digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) );
digest_init ( digest, hctx->ctx );
digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
}
/**
* Finalise HMAC
*
* @v digest Digest algorithm to use
* @v digest_ctx Digest context
* @v key Key
* @v key_len Length of key
* @v ctx HMAC context
* @v hmac HMAC digest to fill in
*
* The length of the key should be less than the block size of the
* digest algorithm being used. (If the key length is greater, it
* will be replaced with its own digest, and key_len will be updated
* accordingly).
*/
void hmac_final ( struct digest_algorithm *digest, void *digest_ctx,
void *key, size_t *key_len, void *hmac ) {
unsigned char k_opad[digest->blocksize];
void hmac_final ( struct digest_algorithm *digest, void *ctx, void *hmac ) {
hmac_context_t ( digest ) *hctx = ctx;
unsigned int i;
/* Reduce key if necessary */
if ( *key_len > sizeof ( k_opad ) )
hmac_reduce_key ( digest, key, key_len );
/* Construct output pad */
memset ( k_opad, 0, sizeof ( k_opad ) );
memcpy ( k_opad, key, *key_len );
for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) {
k_opad[i] ^= 0x5c;
/* Construct output pad from input pad */
for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) {
hctx->pad[i] ^= 0x6a;
}
/* Finish inner hash */
digest_final ( digest, digest_ctx, hmac );
digest_final ( digest, hctx->ctx, hmac );
/* Perform outer hash */
digest_init ( digest, digest_ctx );
digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) );
digest_update ( digest, digest_ctx, hmac, digest->digestsize );
digest_final ( digest, digest_ctx, hmac );
digest_init ( digest, hctx->ctx );
digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
digest_update ( digest, hctx->ctx, hmac, digest->digestsize );
digest_final ( digest, hctx->ctx, hmac );
/* Erase output pad (from which the key may be derivable) */
memset ( hctx->pad, 0, sizeof ( hctx->pad ) );
}

View File

@ -79,7 +79,7 @@ static void hmac_drbg_update_key ( struct digest_algorithm *hash,
struct hmac_drbg_state *state,
const void *data, size_t len,
const uint8_t single ) {
uint8_t context[ hash->ctxsize ];
uint8_t context[ hmac_ctxsize ( hash ) ];
size_t out_len = hash->digestsize;
DBGC ( state, "HMAC_DRBG_%s %p provided data :\n", hash->name, state );
@ -92,13 +92,11 @@ static void hmac_drbg_update_key ( struct digest_algorithm *hash,
assert ( ( single == 0x00 ) || ( single == 0x01 ) );
/* K = HMAC ( K, V || single || provided_data ) */
hmac_init ( hash, context, state->key, &out_len );
assert ( out_len == hash->digestsize );
hmac_init ( hash, context, state->key, out_len );
hmac_update ( hash, context, state->value, out_len );
hmac_update ( hash, context, &single, sizeof ( single ) );
hmac_update ( hash, context, data, len );
hmac_final ( hash, context, state->key, &out_len, state->key );
assert ( out_len == hash->digestsize );
hmac_final ( hash, context, state->key );
DBGC ( state, "HMAC_DRBG_%s %p K = HMAC ( K, V || %#02x || "
"provided_data ) :\n", hash->name, state, single );
@ -122,7 +120,7 @@ static void hmac_drbg_update_key ( struct digest_algorithm *hash,
*/
static void hmac_drbg_update_value ( struct digest_algorithm *hash,
struct hmac_drbg_state *state ) {
uint8_t context[ hash->ctxsize ];
uint8_t context[ hmac_ctxsize ( hash ) ];
size_t out_len = hash->digestsize;
/* Sanity checks */
@ -130,11 +128,9 @@ static void hmac_drbg_update_value ( struct digest_algorithm *hash,
assert ( state != NULL );
/* V = HMAC ( K, V ) */
hmac_init ( hash, context, state->key, &out_len );
assert ( out_len == hash->digestsize );
hmac_init ( hash, context, state->key, out_len );
hmac_update ( hash, context, state->value, out_len );
hmac_final ( hash, context, state->key, &out_len, state->value );
assert ( out_len == hash->digestsize );
hmac_final ( hash, context, state->value );
DBGC ( state, "HMAC_DRBG_%s %p V = HMAC ( K, V ) :\n",
hash->name, state );

View File

@ -27,22 +27,65 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/rsa.h>
#include <ipxe/aes.h>
#include <ipxe/sha1.h>
#include <ipxe/sha256.h>
#include <ipxe/tls.h>
/** TLS_RSA_WITH_AES_128_CBC_SHA cipher suite */
struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite (03) = {
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ),
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA cipher suite */
struct tls_cipher_suite
tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 05 ) = {
.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA ),
.key_len = ( 128 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA1_DIGEST_SIZE,
.exchange = &tls_dhe_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha1_algorithm,
.handshake = &sha256_algorithm,
};
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA cipher suite */
struct tls_cipher_suite
tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 06 ) = {
.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA ),
.key_len = ( 256 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA1_DIGEST_SIZE,
.exchange = &tls_dhe_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha1_algorithm,
.handshake = &sha256_algorithm,
};
/** TLS_RSA_WITH_AES_128_CBC_SHA cipher suite */
struct tls_cipher_suite
tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 15 ) = {
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ),
.key_len = ( 128 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA1_DIGEST_SIZE,
.exchange = &tls_pubkey_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha1_algorithm,
.handshake = &sha256_algorithm,
};
/** TLS_RSA_WITH_AES_256_CBC_SHA cipher suite */
struct tls_cipher_suite tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite (04) = {
struct tls_cipher_suite
tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 16 ) = {
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ),
.key_len = ( 256 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA1_DIGEST_SIZE,
.exchange = &tls_pubkey_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha1_algorithm,
.handshake = &sha256_algorithm,
};

View File

@ -29,20 +29,62 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/sha256.h>
#include <ipxe/tls.h>
/** TLS_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite(01)={
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ),
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
struct tls_cipher_suite
tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 03 ) = {
.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ),
.key_len = ( 128 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA256_DIGEST_SIZE,
.exchange = &tls_dhe_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha256_algorithm,
.handshake = &sha256_algorithm,
};
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
struct tls_cipher_suite
tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 04 ) = {
.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ),
.key_len = ( 256 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA256_DIGEST_SIZE,
.exchange = &tls_dhe_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha256_algorithm,
.handshake = &sha256_algorithm,
};
/** TLS_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
struct tls_cipher_suite
tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 13 ) = {
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ),
.key_len = ( 128 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA256_DIGEST_SIZE,
.exchange = &tls_pubkey_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha256_algorithm,
.handshake = &sha256_algorithm,
};
/** TLS_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
struct tls_cipher_suite tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite(02)={
struct tls_cipher_suite
tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 14 ) = {
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ),
.key_len = ( 256 / 8 ),
.fixed_iv_len = 0,
.record_iv_len = AES_BLOCKSIZE,
.mac_len = SHA256_DIGEST_SIZE,
.exchange = &tls_pubkey_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_cbc_algorithm,
.digest = &sha256_algorithm,
.handshake = &sha256_algorithm,
};

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2022 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 (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <byteswap.h>
#include <ipxe/rsa.h>
#include <ipxe/aes.h>
#include <ipxe/sha256.h>
#include <ipxe/tls.h>
/** TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite */
struct tls_cipher_suite
tls_dhe_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 01 ) = {
.code = htons ( TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ),
.key_len = ( 128 / 8 ),
.fixed_iv_len = 4,
.record_iv_len = 8,
.mac_len = 0,
.exchange = &tls_dhe_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_gcm_algorithm,
.digest = &sha256_algorithm,
.handshake = &sha256_algorithm,
};
/** TLS_RSA_WITH_AES_128_GCM_SHA256 cipher suite */
struct tls_cipher_suite
tls_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 11 ) = {
.code = htons ( TLS_RSA_WITH_AES_128_GCM_SHA256 ),
.key_len = ( 128 / 8 ),
.fixed_iv_len = 4,
.record_iv_len = 8,
.mac_len = 0,
.exchange = &tls_pubkey_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_gcm_algorithm,
.digest = &sha256_algorithm,
.handshake = &sha256_algorithm,
};

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2022 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 (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <byteswap.h>
#include <ipxe/rsa.h>
#include <ipxe/aes.h>
#include <ipxe/sha512.h>
#include <ipxe/tls.h>
/** TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite */
struct tls_cipher_suite
tls_dhe_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 02 ) = {
.code = htons ( TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ),
.key_len = ( 256 / 8 ),
.fixed_iv_len = 4,
.record_iv_len = 8,
.mac_len = 0,
.exchange = &tls_dhe_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_gcm_algorithm,
.digest = &sha384_algorithm,
.handshake = &sha384_algorithm,
};
/** TLS_RSA_WITH_AES_256_GCM_SHA384 cipher suite */
struct tls_cipher_suite
tls_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 12 ) = {
.code = htons ( TLS_RSA_WITH_AES_256_GCM_SHA384 ),
.key_len = ( 256 / 8 ),
.fixed_iv_len = 4,
.record_iv_len = 8,
.mac_len = 0,
.exchange = &tls_pubkey_exchange_algorithm,
.pubkey = &rsa_algorithm,
.cipher = &aes_gcm_algorithm,
.digest = &sha384_algorithm,
.handshake = &sha384_algorithm,
};

View File

@ -117,10 +117,9 @@ void ntlm_key ( const char *domain, const char *username,
struct digest_algorithm *md5 = &md5_algorithm;
union {
uint8_t md4[MD4_CTX_SIZE];
uint8_t md5[MD5_CTX_SIZE];
uint8_t md5[ MD5_CTX_SIZE + MD5_BLOCK_SIZE ];
} ctx;
uint8_t digest[MD4_DIGEST_SIZE];
size_t digest_len;
uint8_t c;
uint16_t wc;
@ -141,8 +140,7 @@ void ntlm_key ( const char *domain, const char *username,
digest_final ( md4, ctx.md4, digest );
/* Construct HMAC-MD5 of (Unicode) upper-case username */
digest_len = sizeof ( digest );
hmac_init ( md5, ctx.md5, digest, &digest_len );
hmac_init ( md5, ctx.md5, digest, sizeof ( digest ) );
while ( ( c = *(username++) ) ) {
wc = cpu_to_le16 ( toupper ( c ) );
hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
@ -151,7 +149,7 @@ void ntlm_key ( const char *domain, const char *username,
wc = cpu_to_le16 ( c );
hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
}
hmac_final ( md5, ctx.md5, digest, &digest_len, key->raw );
hmac_final ( md5, ctx.md5, key->raw );
DBGC ( key, "NTLM key:\n" );
DBGC_HDA ( key, 0, key, sizeof ( *key ) );
}
@ -170,8 +168,7 @@ void ntlm_response ( struct ntlm_challenge_info *info, struct ntlm_key *key,
struct ntlm_nt_response *nt ) {
struct digest_algorithm *md5 = &md5_algorithm;
struct ntlm_nonce tmp_nonce;
uint8_t ctx[MD5_CTX_SIZE];
size_t key_len = sizeof ( *key );
uint8_t ctx[ MD5_CTX_SIZE + MD5_BLOCK_SIZE ];
unsigned int i;
/* Generate random nonce, if needed */
@ -183,10 +180,10 @@ void ntlm_response ( struct ntlm_challenge_info *info, struct ntlm_key *key,
/* Construct LAN Manager response */
memcpy ( &lm->nonce, nonce, sizeof ( lm->nonce ) );
hmac_init ( md5, ctx, key->raw, &key_len );
hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
hmac_update ( md5, ctx, &lm->nonce, sizeof ( lm->nonce ) );
hmac_final ( md5, ctx, key->raw, &key_len, lm->digest );
hmac_final ( md5, ctx, lm->digest );
DBGC ( key, "NTLM LAN Manager response:\n" );
DBGC_HDA ( key, 0, lm, sizeof ( *lm ) );
@ -195,14 +192,14 @@ void ntlm_response ( struct ntlm_challenge_info *info, struct ntlm_key *key,
nt->version = NTLM_VERSION_NTLMV2;
nt->high = NTLM_VERSION_NTLMV2;
memcpy ( &nt->nonce, nonce, sizeof ( nt->nonce ) );
hmac_init ( md5, ctx, key->raw, &key_len );
hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
hmac_update ( md5, ctx, &nt->version,
( sizeof ( *nt ) -
offsetof ( typeof ( *nt ), version ) ) );
hmac_update ( md5, ctx, info->target, info->len );
hmac_update ( md5, ctx, &nt->zero, sizeof ( nt->zero ) );
hmac_final ( md5, ctx, key->raw, &key_len, nt->digest );
hmac_final ( md5, ctx, nt->digest );
DBGC ( key, "NTLM NT response prefix:\n" );
DBGC_HDA ( key, 0, nt, sizeof ( *nt ) );
}

View File

@ -49,7 +49,7 @@ void prf_sha1 ( const void *key, size_t key_len, const char *label,
u8 in[strlen ( label ) + 1 + data_len + 1]; /* message to HMAC */
u8 *in_blknr; /* pointer to last byte of in, block number */
u8 out[SHA1_DIGEST_SIZE]; /* HMAC-SHA1 result */
u8 sha1_ctx[SHA1_CTX_SIZE]; /* SHA1 context */
u8 ctx[SHA1_CTX_SIZE + SHA1_BLOCK_SIZE]; /* HMAC-SHA1 context */
const size_t label_len = strlen ( label );
/* The HMAC-SHA-1 is calculated using the given key on the
@ -65,9 +65,9 @@ void prf_sha1 ( const void *key, size_t key_len, const char *label,
for ( blk = 0 ;; blk++ ) {
*in_blknr = blk;
hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len );
hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) );
hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out );
hmac_init ( &sha1_algorithm, ctx, keym, key_len );
hmac_update ( &sha1_algorithm, ctx, in, sizeof ( in ) );
hmac_final ( &sha1_algorithm, ctx, out );
if ( prf_len <= sizeof ( out ) ) {
memcpy ( prf, out, prf_len );
@ -100,7 +100,7 @@ static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
u8 pass[pass_len]; /* modifiable passphrase */
u8 in[salt_len + 4]; /* input buffer to first round */
u8 last[SHA1_DIGEST_SIZE]; /* output of round N, input of N+1 */
u8 sha1_ctx[SHA1_CTX_SIZE];
u8 ctx[SHA1_CTX_SIZE + SHA1_BLOCK_SIZE];
u8 *next_in = in; /* changed to `last' after first round */
int next_size = sizeof ( in );
int i;
@ -114,9 +114,9 @@ static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
memset ( block, 0, sizeof ( last ) );
for ( i = 0; i < iterations; i++ ) {
hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len );
hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size );
hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last );
hmac_init ( &sha1_algorithm, ctx, pass, pass_len );
hmac_update ( &sha1_algorithm, ctx, next_in, next_size );
hmac_final ( &sha1_algorithm, ctx, last );
for ( j = 0; j < sizeof ( last ); j++ ) {
block[j] ^= last[j];

View File

@ -0,0 +1,267 @@
/*
* Copyright (C) 2022 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 (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/uaccess.h>
#include <ipxe/ecam.h>
/** @file
*
* PCI Enhanced Configuration Access Mechanism (ECAM)
*
*/
/** Cached mapped ECAM allocation */
static struct ecam_mapping ecam;
/**
* Find lowest ECAM allocation not below a given PCI bus:dev.fn address
*
* @v busdevfn PCI bus:dev.fn address
* @v range PCI device address range to fill in
* @v alloc ECAM allocation to fill in, or NULL
* @ret rc Return status code
*/
static int ecam_find ( uint32_t busdevfn, struct pci_range *range,
struct ecam_allocation *alloc ) {
struct ecam_allocation tmp;
unsigned int best = 0;
unsigned int offset;
unsigned int count;
unsigned int index;
userptr_t mcfg;
uint32_t length;
uint32_t start;
/* Return empty range on error */
range->count = 0;
/* Locate MCFG table */
mcfg = acpi_table ( ECAM_SIGNATURE, 0 );
if ( ! mcfg ) {
DBGC ( &ecam, "ECAM found no MCFG table\n" );
return -ENOTSUP;
}
/* Get length of table */
copy_from_user ( &length, mcfg,
offsetof ( struct ecam_table, acpi.length ),
sizeof ( length ) );
/* Iterate over allocations */
for ( offset = offsetof ( struct ecam_table, alloc ) ;
( offset + sizeof ( tmp ) ) <= le32_to_cpu ( length ) ;
offset += sizeof ( tmp ) ) {
/* Read allocation */
copy_from_user ( &tmp, mcfg, offset, sizeof ( tmp ) );
DBGC2 ( &ecam, "ECAM %04x:[%02x-%02x] has base %08llx\n",
le16_to_cpu ( tmp.segment ), tmp.start, tmp.end,
( ( unsigned long long ) le64_to_cpu ( tmp.base ) ) );
start = PCI_BUSDEVFN ( le16_to_cpu ( tmp.segment ),
tmp.start, 0, 0 );
count = PCI_BUSDEVFN ( 0, ( tmp.end - tmp.start + 1 ), 0, 0 );
/* Check for a matching or new closest allocation */
index = ( busdevfn - start );
if ( ( index < count ) || ( index > best ) ) {
if ( alloc )
memcpy ( alloc, &tmp, sizeof ( *alloc ) );
range->start = start;
range->count = count;
best = index;
}
/* Stop if this range contains the target bus:dev.fn address */
if ( index < count )
return 0;
}
return ( best ? 0 : -ENOENT );
}
/**
* Find next PCI bus:dev.fn address range in system
*
* @v busdevfn Starting PCI bus:dev.fn address
* @v range PCI bus:dev.fn address range to fill in
*/
static void ecam_discover ( uint32_t busdevfn, struct pci_range *range ) {
/* Find new range, if any */
ecam_find ( busdevfn, range, NULL );
}
/**
* Access configuration space for PCI device
*
* @v pci PCI device
* @ret rc Return status code
*/
static int ecam_access ( struct pci_device *pci ) {
uint64_t base;
size_t len;
int rc;
/* Reuse mapping if possible */
if ( ( pci->busdevfn - ecam.range.start ) < ecam.range.count )
return 0;
/* Clear any existing mapping */
if ( ecam.regs ) {
iounmap ( ecam.regs );
ecam.regs = NULL;
}
/* Find allocation for this PCI device */
if ( ( rc = ecam_find ( pci->busdevfn, &ecam.range,
&ecam.alloc ) ) != 0 ) {
DBGC ( &ecam, "ECAM found no allocation for " PCI_FMT ": %s\n",
PCI_ARGS ( pci ), strerror ( rc ) );
goto err_find;
}
if ( ecam.range.start > pci->busdevfn ) {
DBGC ( &ecam, "ECAM found no allocation for " PCI_FMT "\n",
PCI_ARGS ( pci ) );
goto err_find;
}
/* Map configuration space for this allocation */
base = le64_to_cpu ( ecam.alloc.base );
len = ( ecam.range.count * ECAM_SIZE );
ecam.regs = ioremap ( base, len );
if ( ! ecam.regs ) {
DBGC ( &ecam, "ECAM %04x:[%02x-%02x] could not map "
"[%08llx,%08llx)\n", le16_to_cpu ( ecam.alloc.segment ),
ecam.alloc.start, ecam.alloc.end, base, ( base + len ) );
rc = -ENODEV;
goto err_ioremap;
}
/* Populate cached mapping */
DBGC ( &ecam, "ECAM %04x:[%02x-%02x] mapped [%08llx,%08llx) -> %p\n",
le16_to_cpu ( ecam.alloc.segment ), ecam.alloc.start,
ecam.alloc.end, base, ( base + len ), ecam.regs );
return 0;
iounmap ( ecam.regs );
err_ioremap:
err_find:
ecam.range.count = 0;
return rc;
}
/**
* Read from PCI configuration space
*
* @v pci PCI device
* @v location Offset and length within PCI configuration space
* @v value Value read
* @ret rc Return status code
*/
int ecam_read ( struct pci_device *pci, unsigned int location, void *value ) {
unsigned int where = ECAM_WHERE ( location );
unsigned int len = ECAM_LEN ( location );
unsigned int index;
void *addr;
int rc;
/* Return all-ones on error */
memset ( value, 0xff, len );
/* Access configuration space */
if ( ( rc = ecam_access ( pci ) ) != 0 )
return rc;
/* Read from address */
index = ( pci->busdevfn - ecam.range.start );
addr = ( ecam.regs + ( index * ECAM_SIZE ) + where );
switch ( len ) {
case 4:
*( ( uint32_t *) value ) = readl ( addr );
break;
case 2:
*( ( uint16_t *) value ) = readw ( addr );
break;
case 1:
*( ( uint8_t *) value ) = readb ( addr );
break;
default:
assert ( 0 );
}
return 0;
}
/**
* Write to PCI configuration space
*
* @v pci PCI device
* @v location Offset and length within PCI configuration space
* @v value Value to write
* @ret rc Return status code
*/
int ecam_write ( struct pci_device *pci, unsigned int location,
unsigned long value ) {
unsigned int where = ECAM_WHERE ( location );
unsigned int len = ECAM_LEN ( location );
unsigned int index;
void *addr;
int rc;
/* Access configuration space */
if ( ( rc = ecam_access ( pci ) ) != 0 )
return rc;
/* Read from address */
index = ( pci->busdevfn - ecam.range.start );
addr = ( ecam.regs + ( index * ECAM_SIZE ) + where );
switch ( len ) {
case 4:
writel ( value, addr );
break;
case 2:
writew ( value, addr );
break;
case 1:
writeb ( value, addr );
break;
default:
assert ( 0 );
}
return 0;
}
PROVIDE_PCIAPI ( ecam, pci_discover, ecam_discover );
PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_byte );
PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_word );
PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_dword );
PROVIDE_PCIAPI_INLINE ( ecam, pci_write_config_byte );
PROVIDE_PCIAPI_INLINE ( ecam, pci_write_config_word );
PROVIDE_PCIAPI_INLINE ( ecam, pci_write_config_dword );
PROVIDE_PCIAPI_INLINE ( ecam, pci_ioremap );
struct pci_api ecam_api = PCIAPI_RUNTIME ( ecam );

View File

@ -229,46 +229,55 @@ int pci_read_config ( struct pci_device *pci ) {
*
* @v pci PCI device to fill in
* @v busdevfn Starting bus:dev.fn address
* @ret busdevfn Bus:dev.fn address of next PCI device, or negative error
* @ret busdevfn Bus:dev.fn address of next PCI device
* @ret rc Return status code
*/
int pci_find_next ( struct pci_device *pci, unsigned int busdevfn ) {
static unsigned int end;
unsigned int sub_end;
int pci_find_next ( struct pci_device *pci, uint32_t *busdevfn ) {
static struct pci_range range;
uint8_t hdrtype;
uint8_t sub;
uint32_t end;
unsigned int count;
int rc;
/* Determine number of PCI buses */
if ( ! end )
end = PCI_BUSDEVFN ( 0, pci_num_bus(), 0, 0 );
/* Find next PCI device, if any */
for ( ; busdevfn < end ; busdevfn++ ) {
do {
/* Find next PCI bus:dev.fn address range, if necessary */
if ( ( *busdevfn - range.start ) >= range.count ) {
pci_discover ( *busdevfn, &range );
if ( *busdevfn < range.start )
*busdevfn = range.start;
if ( ( *busdevfn - range.start ) >= range.count )
break;
}
/* Check for PCI device existence */
memset ( pci, 0, sizeof ( *pci ) );
pci_init ( pci, busdevfn );
pci_init ( pci, *busdevfn );
if ( ( rc = pci_read_config ( pci ) ) != 0 )
continue;
/* If device is a bridge, expand the number of PCI
* buses as needed.
/* If device is a bridge, expand the PCI bus:dev.fn
* address range as needed.
*/
pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
hdrtype &= PCI_HEADER_TYPE_MASK;
if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
sub_end = PCI_BUSDEVFN ( 0, ( sub + 1 ), 0, 0 );
if ( end < sub_end ) {
end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
( sub + 1 ), 0, 0 );
count = ( end - range.start );
if ( count > range.count ) {
DBGC ( pci, PCI_FMT " found subordinate bus "
"%#02x\n", PCI_ARGS ( pci ), sub );
end = sub_end;
range.count = count;
}
}
/* Return this device */
return busdevfn;
}
return 0;
} while ( ++(*busdevfn) );
return -ENODEV;
}
@ -348,11 +357,10 @@ void pci_remove ( struct pci_device *pci ) {
*/
static int pcibus_probe ( struct root_device *rootdev ) {
struct pci_device *pci = NULL;
int busdevfn = 0;
uint32_t busdevfn = 0;
int rc;
for ( busdevfn = 0 ; 1 ; busdevfn++ ) {
do {
/* Allocate struct pci_device */
if ( ! pci )
pci = malloc ( sizeof ( *pci ) );
@ -362,8 +370,7 @@ static int pcibus_probe ( struct root_device *rootdev ) {
}
/* Find next PCI device, if any */
busdevfn = pci_find_next ( pci, busdevfn );
if ( busdevfn < 0 )
if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
break;
/* Look for a driver */
@ -386,7 +393,8 @@ static int pcibus_probe ( struct root_device *rootdev ) {
/* Not registered; re-use struct pci_device */
list_del ( &pci->dev.siblings );
}
}
} while ( ++busdevfn );
free ( pci );
return 0;

View File

@ -61,14 +61,15 @@ pci_backup_excluded ( struct pci_device *pci, unsigned int offset,
*
* @v pci PCI device
* @v backup PCI configuration space backup
* @v limit Maximum offset in PCI configuration space
* @v exclude PCI configuration space backup exclusion list, or NULL
*/
void pci_backup ( struct pci_device *pci, struct pci_config_backup *backup,
const uint8_t *exclude ) {
unsigned int limit, const uint8_t *exclude ) {
unsigned int offset;
uint32_t *dword;
for ( offset = 0, dword = backup->dwords ; offset < 0x100 ;
for ( offset = 0, dword = backup->dwords ; offset < limit ;
offset += sizeof ( *dword ) , dword++ ) {
if ( ! pci_backup_excluded ( pci, offset, exclude ) )
pci_read_config_dword ( pci, offset, dword );
@ -80,14 +81,15 @@ void pci_backup ( struct pci_device *pci, struct pci_config_backup *backup,
*
* @v pci PCI device
* @v backup PCI configuration space backup
* @v limit Maximum offset in PCI configuration space
* @v exclude PCI configuration space backup exclusion list, or NULL
*/
void pci_restore ( struct pci_device *pci, struct pci_config_backup *backup,
const uint8_t *exclude ) {
unsigned int limit, const uint8_t *exclude ) {
unsigned int offset;
uint32_t *dword;
for ( offset = 0, dword = backup->dwords ; offset < 0x100 ;
for ( offset = 0, dword = backup->dwords ; offset < limit ;
offset += sizeof ( *dword ) , dword++ ) {
if ( ! pci_backup_excluded ( pci, offset, exclude ) )
pci_write_config_dword ( pci, offset, *dword );

View File

@ -0,0 +1,132 @@
/*
* Copyright (C) 2022 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 (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/pci.h>
#include <ipxe/pcibridge.h>
/** @file
*
* PCI-to-PCI bridge
*
*/
/** List of all PCI bridges */
static LIST_HEAD ( pcibridges );
/**
* Find bridge attached to a PCI device
*
* @v pci PCI device
* @ret bridge PCI bridge, or NULL
*/
struct pci_bridge * pcibridge_find ( struct pci_device *pci ) {
unsigned int bus = PCI_BUS ( pci->busdevfn );
struct pci_bridge *bridge;
/* Find matching bridge */
list_for_each_entry ( bridge, &pcibridges, list ) {
if ( bus == bridge->secondary )
return bridge;
}
return NULL;
}
/**
* Probe PCI device
*
* @v pci PCI device
* @ret rc Return status code
*/
static int pcibridge_probe ( struct pci_device *pci ) {
struct pci_bridge *bridge;
uint16_t base;
uint16_t limit;
int rc;
/* Allocate and initialise structure */
bridge = zalloc ( sizeof ( *bridge ) );
if ( ! bridge ) {
rc = -ENOMEM;
goto err_alloc;
}
bridge->pci = pci;
/* Read configuration */
pci_read_config_dword ( pci, PCI_PRIMARY, &bridge->buses );
cpu_to_le32s ( &buses );
pci_read_config_word ( pci, PCI_MEM_BASE, &base );
bridge->membase = ( ( base & ~PCI_MEM_MASK ) << 16 );
pci_read_config_word ( pci, PCI_MEM_LIMIT, &limit );
bridge->memlimit = ( ( ( ( limit | PCI_MEM_MASK ) + 1 ) << 16 ) - 1 );
DBGC ( bridge, "BRIDGE " PCI_FMT " bus %02x to [%02x,%02x) mem "
"[%08x,%08x)\n", PCI_ARGS ( pci ), bridge->primary,
bridge->secondary, bridge->subordinate, bridge->membase,
bridge->memlimit );
/* Add to list of PCI bridges */
list_add ( &bridge->list, &pcibridges );
pci_set_drvdata ( pci, bridge );
return 0;
free ( bridge );
err_alloc:
return rc;
}
/**
* Remove PCI device
*
* @v pci PCI device
*/
static void pcibridge_remove ( struct pci_device *pci ) {
struct pci_bridge *bridge = pci_get_drvdata ( pci );
/* Remove from list of bridges */
list_del ( &bridge->list );
/* Free device */
free ( bridge );
}
/** Bridge PCI device IDs */
static struct pci_device_id pcibridge_ids[] = {
PCI_ROM ( 0xffff, 0xffff, "bridge", "Bridge", 0 ),
};
/** Bridge PCI driver */
struct pci_driver pcibridge_driver __pci_driver = {
.ids = pcibridge_ids,
.id_count = ( sizeof ( pcibridge_ids ) / sizeof ( pcibridge_ids[0] ) ),
.class = PCI_CLASS_ID ( PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_PCI,
PCI_ANY_ID ),
.probe = pcibridge_probe,
.remove = pcibridge_remove,
};

View File

@ -3,6 +3,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/timer.h>
#include <ipxe/pci.h>
#include <ipxe/pcibackup.h>
static int pci_find_capability_common ( struct pci_device *pci,
uint8_t pos, int cap ) {
@ -121,8 +122,12 @@ unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) {
* @v exp PCI Express Capability address
*/
void pci_reset ( struct pci_device *pci, unsigned int exp ) {
struct pci_config_backup backup;
uint16_t control;
/* Back up configuration space */
pci_backup ( pci, &backup, PCI_CONFIG_BACKUP_STANDARD, NULL );
/* Perform a PCIe function-level reset */
pci_read_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), &control );
control |= PCI_EXP_DEVCTL_FLR;
@ -131,6 +136,6 @@ void pci_reset ( struct pci_device *pci, unsigned int exp ) {
/* Allow time for reset to complete */
mdelay ( PCI_EXP_FLR_DELAY_MS );
/* Re-enable device */
adjust_pci_device ( pci );
/* Restore configuration */
pci_restore ( pci, &backup, PCI_CONFIG_BACKUP_STANDARD, NULL );
}

View File

@ -2561,7 +2561,7 @@ static void arbel_reset ( struct arbel *arbel ) {
unsigned int i;
/* Perform device reset and preserve PCI configuration */
pci_backup ( pci, &backup, backup_exclude );
pci_backup ( pci, &backup, PCI_CONFIG_BACKUP_ALL, backup_exclude );
writel ( ARBEL_RESET_MAGIC,
( arbel->config + ARBEL_RESET_OFFSET ) );
for ( i = 0 ; i < ARBEL_RESET_WAIT_TIME_MS ; i++ ) {
@ -2570,7 +2570,7 @@ static void arbel_reset ( struct arbel *arbel ) {
if ( vendor != 0xffff )
break;
}
pci_restore ( pci, &backup, backup_exclude );
pci_restore ( pci, &backup, PCI_CONFIG_BACKUP_ALL, backup_exclude );
}
/**

View File

@ -2647,6 +2647,7 @@ static struct pci_device_id golan_nics[] = {
PCI_ROM ( 0x15b3, 0x1021, "ConnectX-7", "ConnectX-7 HCA driver, DevID 4129", 0 ),
PCI_ROM ( 0x15b3, 0xa2d2, "BlueField", "BlueField integrated ConnectX-5 network controller HCA driver, DevID 41682", 0 ),
PCI_ROM ( 0x15b3, 0xa2d6, "BlueField-2", "BlueField-2 network controller HCA driver, DevID 41686", 0 ),
PCI_ROM ( 0x15b3, 0xa2dc, "BlueField-3", "BlueField-3 network controller HCA driver, DevID 41692", 0 ),
};
struct pci_driver golan_driver __pci_driver = {

View File

@ -2840,7 +2840,7 @@ static int hermon_reset ( struct hermon *hermon ) {
hermon->toggle = 0;
/* Perform device reset and preserve PCI configuration */
pci_backup ( pci, &backup, backup_exclude );
pci_backup ( pci, &backup, PCI_CONFIG_BACKUP_ALL, backup_exclude );
writel ( HERMON_RESET_MAGIC,
( hermon->config + HERMON_RESET_OFFSET ) );
@ -2852,7 +2852,8 @@ static int hermon_reset ( struct hermon *hermon ) {
if ( vendor == pci->vendor ) {
/* Restore PCI configuration */
pci_restore ( pci, &backup, backup_exclude );
pci_restore ( pci, &backup, PCI_CONFIG_BACKUP_ALL,
backup_exclude );
DBGC ( hermon, "Hermon %p reset after %dms\n",
hermon, i );

View File

@ -2256,7 +2256,7 @@ static void qib7322_reset ( struct qib7322 *qib7322, struct pci_device *pci ) {
struct pci_config_backup backup;
/* Back up PCI configuration space */
pci_backup ( pci, &backup, NULL );
pci_backup ( pci, &backup, PCI_CONFIG_BACKUP_ALL, NULL );
/* Assert reset */
memset ( &control, 0, sizeof ( control ) );
@ -2267,7 +2267,7 @@ static void qib7322_reset ( struct qib7322 *qib7322, struct pci_device *pci ) {
mdelay ( 1000 );
/* Restore PCI configuration space */
pci_restore ( pci, &backup, NULL );
pci_restore ( pci, &backup, PCI_CONFIG_BACKUP_ALL, NULL );
}
/**

View File

@ -121,10 +121,9 @@ int ecm_fetch_mac ( struct usb_function *func,
}
/* Apply system-specific MAC address as current link-layer
* address, if present and not already used.
* address, if present.
*/
if ( ( ( rc = acpi_mac ( amac ) ) == 0 ) &&
! find_netdev_by_ll_addr ( &ethernet_protocol, amac ) ) {
if ( ( rc = acpi_mac ( amac ) ) == 0 ) {
memcpy ( netdev->ll_addr, amac, ETH_ALEN );
DBGC ( usb, "USB %s using system-specific MAC %s\n",
func->name, eth_ntoa ( netdev->ll_addr ) );

View File

@ -222,7 +222,7 @@ static int nii_pci_open ( struct nii_nic *nii ) {
/* Locate PCI I/O protocol */
if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
&pci_device ) ) != 0 ) {
&pci_device, 0 ) ) != 0 ) {
DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
nii->dev.name, strerror ( rc ) );
goto err_locate;
@ -921,18 +921,17 @@ static int nii_set_station_address ( struct nii_nic *nii,
* Set receive filters
*
* @v nii NII NIC
* @v flags Flags
* @ret rc Return status code
*/
static int nii_set_rx_filters ( struct nii_nic *nii ) {
static int nii_set_rx_filters ( struct nii_nic *nii, unsigned int flags ) {
uint32_t implementation = nii->undi->Implementation;
unsigned int flags;
unsigned int op;
int stat;
int rc;
/* Construct receive filter set */
flags = ( PXE_OPFLAGS_RECEIVE_FILTER_ENABLE |
PXE_OPFLAGS_RECEIVE_FILTER_UNICAST );
flags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
if ( implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED )
flags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED )
@ -944,14 +943,40 @@ static int nii_set_rx_filters ( struct nii_nic *nii ) {
op = NII_OP ( PXE_OPCODE_RECEIVE_FILTERS, flags );
if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
rc = -EIO_STAT ( stat );
DBGC ( nii, "NII %s could not set receive filters %#04x: %s\n",
nii->dev.name, flags, strerror ( rc ) );
DBGC ( nii, "NII %s could not %s%sable receive filters "
"%#04x: %s\n", nii->dev.name,
( ( flags & PXE_OPFLAGS_RECEIVE_FILTER_ENABLE ) ?
"en" : "" ),
( ( flags & PXE_OPFLAGS_RECEIVE_FILTER_DISABLE ) ?
"dis" : "" ), flags, strerror ( rc ) );
return rc;
}
return 0;
}
/**
* Enable receive filters
*
* @v nii NII NIC
* @ret rc Return status code
*/
static int nii_enable_rx_filters ( struct nii_nic *nii ) {
return nii_set_rx_filters ( nii, PXE_OPFLAGS_RECEIVE_FILTER_ENABLE );
}
/**
* Disable receive filters
*
* @v nii NII NIC
* @ret rc Return status code
*/
static int nii_disable_rx_filters ( struct nii_nic *nii ) {
return nii_set_rx_filters ( nii, PXE_OPFLAGS_RECEIVE_FILTER_DISABLE );
}
/**
* Transmit packet
*
@ -1175,13 +1200,25 @@ static int nii_open ( struct net_device *netdev ) {
/* Treat as non-fatal */
}
/* Set receive filters */
if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
goto err_set_rx_filters;
/* Disable receive filters
*
* We have no reason to disable receive filters here (or
* anywhere), but some NII drivers have a bug which prevents
* packets from being received unless we attempt to disable
* the receive filters.
*
* Ignore any failures, since we genuinely don't care if the
* NII driver cannot disable the filters.
*/
nii_disable_rx_filters ( nii );
/* Enable receive filters */
if ( ( rc = nii_enable_rx_filters ( nii ) ) != 0 )
goto err_enable_rx_filters;
return 0;
err_set_rx_filters:
err_enable_rx_filters:
nii_shutdown ( nii );
err_initialise:
return rc;

View File

@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_utils.h>
#include "snpnet.h"
#include "nii.h"
@ -40,34 +41,60 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* Check to see if driver supports a device
*
* @v device EFI device handle
* @v protocol Protocol GUID
* @ret rc Return status code
*/
static int snp_supported ( EFI_HANDLE device ) {
static int snp_nii_supported ( EFI_HANDLE device, EFI_GUID *protocol ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_HANDLE parent;
EFI_STATUS efirc;
int rc;
/* Check that this is not a device we are providing ourselves */
if ( find_snpdev ( device ) != NULL ) {
DBGCP ( device, "SNP %s is provided by this binary\n",
DBGCP ( device, "HANDLE %s is provided by this binary\n",
efi_handle_name ( device ) );
return -ENOTTY;
}
/* Test for presence of simple network protocol */
if ( ( efirc = bs->OpenProtocol ( device,
&efi_simple_network_protocol_guid,
/* Test for presence of protocol */
if ( ( efirc = bs->OpenProtocol ( device, protocol,
NULL, efi_image_handle, device,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
DBGCP ( device, "SNP %s is not an SNP device\n",
efi_handle_name ( device ) );
DBGCP ( device, "HANDLE %s is not a %s device\n",
efi_handle_name ( device ),
efi_guid_ntoa ( protocol ) );
return -EEFI ( efirc );
}
DBGC ( device, "SNP %s is an SNP device\n",
efi_handle_name ( device ) );
/* Check that there are no instances of this protocol further
* up this device path.
*/
if ( ( rc = efi_locate_device ( device, protocol,
&parent, 1 ) ) == 0 ) {
DBGC2 ( device, "HANDLE %s has %s-supporting parent ",
efi_handle_name ( device ),
efi_guid_ntoa ( protocol ) );
DBGC2 ( device, "%s\n", efi_handle_name ( parent ) );
return -ENOTTY;
}
DBGC ( device, "HANDLE %s is a %s device\n",
efi_handle_name ( device ), efi_guid_ntoa ( protocol ) );
return 0;
}
/**
* Check to see if driver supports a device
*
* @v device EFI device handle
* @ret rc Return status code
*/
static int snp_supported ( EFI_HANDLE device ) {
return snp_nii_supported ( device, &efi_simple_network_protocol_guid );
}
/**
* Check to see if driver supports a device
*
@ -75,29 +102,8 @@ static int snp_supported ( EFI_HANDLE device ) {
* @ret rc Return status code
*/
static int nii_supported ( EFI_HANDLE device ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_STATUS efirc;
/* Check that this is not a device we are providing ourselves */
if ( find_snpdev ( device ) != NULL ) {
DBGCP ( device, "NII %s is provided by this binary\n",
efi_handle_name ( device ) );
return -ENOTTY;
}
/* Test for presence of NII protocol */
if ( ( efirc = bs->OpenProtocol ( device,
&efi_nii31_protocol_guid,
NULL, efi_image_handle, device,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
DBGCP ( device, "NII %s is not an NII device\n",
efi_handle_name ( device ) );
return -EEFI ( efirc );
}
DBGC ( device, "NII %s is an NII device\n",
efi_handle_name ( device ) );
return 0;
return snp_nii_supported ( device, &efi_nii31_protocol_guid );
}
/** EFI SNP driver */

View File

@ -80,7 +80,7 @@ static int chained_locate ( struct chained_protocol *chained ) {
/* Locate handle supporting this protocol */
if ( ( rc = efi_locate_device ( device, chained->protocol,
&parent ) ) != 0 ) {
&parent, 0 ) ) != 0 ) {
DBGC ( device, "CHAINED %s does not support %s: %s\n",
efi_handle_name ( device ),
efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );

View File

@ -24,6 +24,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
@ -34,6 +35,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/iobuf.h>
#include <ipxe/malloc.h>
#include <ipxe/pci.h>
#include <ipxe/pcibridge.h>
#include <ipxe/version.h>
#include "ena.h"
/** @file
@ -347,6 +350,90 @@ static int ena_admin ( struct ena_nic *ena, union ena_aq_req *req,
return rc;
}
/**
* Set async event notification queue config
*
* @v ena ENA device
* @v enabled Bitmask of the groups to enable
* @ret rc Return status code
*/
static int ena_set_aenq_config ( struct ena_nic *ena, uint32_t enabled ) {
union ena_aq_req *req;
union ena_acq_rsp *rsp;
union ena_feature *feature;
int rc;
/* Construct request */
req = ena_admin_req ( ena );
req->header.opcode = ENA_SET_FEATURE;
req->set_feature.id = ENA_AENQ_CONFIG;
feature = &req->set_feature.feature;
feature->aenq.enabled = cpu_to_le32 ( enabled );
/* Issue request */
if ( ( rc = ena_admin ( ena, req, &rsp ) ) != 0 )
return rc;
return 0;
}
/**
* Create async event notification queue
*
* @v ena ENA device
* @ret rc Return status code
*/
static int ena_create_async ( struct ena_nic *ena ) {
size_t aenq_len = ( ENA_AENQ_COUNT * sizeof ( ena->aenq.evt[0] ) );
int rc;
/* Allocate async event notification queue */
ena->aenq.evt = malloc_phys ( aenq_len, aenq_len );
if ( ! ena->aenq.evt ) {
rc = -ENOMEM;
goto err_alloc_aenq;
}
memset ( ena->aenq.evt, 0, aenq_len );
/* Program queue address and capabilities */
ena_set_base ( ena, ENA_AENQ_BASE, ena->aenq.evt );
ena_set_caps ( ena, ENA_AENQ_CAPS, ENA_AENQ_COUNT,
sizeof ( ena->aenq.evt[0] ) );
DBGC ( ena, "ENA %p AENQ [%08lx,%08lx)\n",
ena, virt_to_phys ( ena->aenq.evt ),
( virt_to_phys ( ena->aenq.evt ) + aenq_len ) );
/* Disable all events */
if ( ( rc = ena_set_aenq_config ( ena, 0 ) ) != 0 )
goto err_set_aenq_config;
return 0;
err_set_aenq_config:
ena_clear_caps ( ena, ENA_AENQ_CAPS );
free_phys ( ena->aenq.evt, aenq_len );
err_alloc_aenq:
return rc;
}
/**
* Destroy async event notification queue
*
* @v ena ENA device
*/
static void ena_destroy_async ( struct ena_nic *ena ) {
size_t aenq_len = ( ENA_AENQ_COUNT * sizeof ( ena->aenq.evt[0] ) );
/* Clear queue capabilities */
ena_clear_caps ( ena, ENA_AENQ_CAPS );
wmb();
/* Free queue */
free_phys ( ena->aenq.evt, aenq_len );
DBGC ( ena, "ENA %p AENQ destroyed\n", ena );
}
/**
* Create submission queue
*
@ -359,6 +446,7 @@ static int ena_create_sq ( struct ena_nic *ena, struct ena_sq *sq,
struct ena_cq *cq ) {
union ena_aq_req *req;
union ena_acq_rsp *rsp;
unsigned int i;
int rc;
/* Allocate submission queue entries */
@ -391,11 +479,20 @@ static int ena_create_sq ( struct ena_nic *ena, struct ena_sq *sq,
sq->prod = 0;
sq->phase = ENA_SQE_PHASE;
DBGC ( ena, "ENA %p %s SQ%d at [%08lx,%08lx) db +%04x CQ%d\n",
/* Calculate fill level */
sq->fill = sq->max;
if ( sq->fill > cq->actual )
sq->fill = cq->actual;
/* Initialise buffer ID ring */
for ( i = 0 ; i < sq->count ; i++ )
sq->ids[i] = i;
DBGC ( ena, "ENA %p %s SQ%d at [%08lx,%08lx) fill %d db +%04x CQ%d\n",
ena, ena_direction ( sq->direction ), sq->id,
virt_to_phys ( sq->sqe.raw ),
( virt_to_phys ( sq->sqe.raw ) + sq->len ),
sq->doorbell, cq->id );
sq->fill, sq->doorbell, cq->id );
return 0;
err_admin:
@ -459,6 +556,7 @@ static int ena_create_cq ( struct ena_nic *ena, struct ena_cq *cq ) {
req->header.opcode = ENA_CREATE_CQ;
req->create_cq.size = cq->size;
req->create_cq.count = cpu_to_le16 ( cq->requested );
req->create_cq.vector = cpu_to_le32 ( ENA_MSIX_NONE );
req->create_cq.address = cpu_to_le64 ( virt_to_bus ( cq->cqe.raw ) );
/* Issue request */
@ -596,6 +694,32 @@ static int ena_get_device_attributes ( struct net_device *netdev ) {
return 0;
}
/**
* Set host attributes
*
* @v ena ENA device
* @ret rc Return status code
*/
static int ena_set_host_attributes ( struct ena_nic *ena ) {
union ena_aq_req *req;
union ena_acq_rsp *rsp;
union ena_feature *feature;
int rc;
/* Construct request */
req = ena_admin_req ( ena );
req->header.opcode = ENA_SET_FEATURE;
req->set_feature.id = ENA_HOST_ATTRIBUTES;
feature = &req->set_feature.feature;
feature->host.info = cpu_to_le64 ( virt_to_bus ( ena->info ) );
/* Issue request */
if ( ( rc = ena_admin ( ena, req, &rsp ) ) != 0 )
return rc;
return 0;
}
/**
* Get statistics (for debugging)
*
@ -652,13 +776,14 @@ static void ena_refill_rx ( struct net_device *netdev ) {
struct ena_nic *ena = netdev->priv;
struct io_buffer *iobuf;
struct ena_rx_sqe *sqe;
unsigned int index;
physaddr_t address;
size_t len = netdev->max_pkt_len;
unsigned int refilled = 0;
unsigned int index;
unsigned int id;
/* Refill queue */
while ( ( ena->rx.sq.prod - ena->rx.cq.cons ) < ENA_RX_COUNT ) {
while ( ( ena->rx.sq.prod - ena->rx.cq.cons ) < ena->rx.sq.fill ) {
/* Allocate I/O buffer */
iobuf = alloc_iob ( len );
@ -667,14 +792,15 @@ static void ena_refill_rx ( struct net_device *netdev ) {
break;
}
/* Get next submission queue entry */
/* Get next submission queue entry and buffer ID */
index = ( ena->rx.sq.prod % ENA_RX_COUNT );
sqe = &ena->rx.sq.sqe.rx[index];
id = ena->rx_ids[index];
/* Construct submission queue entry */
address = virt_to_bus ( iobuf->data );
sqe->len = cpu_to_le16 ( len );
sqe->id = cpu_to_le16 ( ena->rx.sq.prod );
sqe->id = cpu_to_le16 ( id );
sqe->address = cpu_to_le64 ( address );
wmb();
sqe->flags = ( ENA_SQE_FIRST | ENA_SQE_LAST | ENA_SQE_CPL |
@ -686,10 +812,10 @@ static void ena_refill_rx ( struct net_device *netdev ) {
ena->rx.sq.phase ^= ENA_SQE_PHASE;
/* Record I/O buffer */
assert ( ena->rx_iobuf[index] == NULL );
ena->rx_iobuf[index] = iobuf;
assert ( ena->rx_iobuf[id] == NULL );
ena->rx_iobuf[id] = iobuf;
DBGC2 ( ena, "ENA %p RX %d at [%08llx,%08llx)\n", ena, sqe->id,
DBGC2 ( ena, "ENA %p RX %d at [%08llx,%08llx)\n", ena, id,
( ( unsigned long long ) address ),
( ( unsigned long long ) address + len ) );
refilled++;
@ -778,23 +904,25 @@ static void ena_close ( struct net_device *netdev ) {
static int ena_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
struct ena_nic *ena = netdev->priv;
struct ena_tx_sqe *sqe;
unsigned int index;
physaddr_t address;
unsigned int index;
unsigned int id;
size_t len;
/* Get next submission queue entry */
if ( ( ena->tx.sq.prod - ena->tx.cq.cons ) >= ENA_TX_COUNT ) {
if ( ( ena->tx.sq.prod - ena->tx.cq.cons ) >= ena->tx.sq.fill ) {
DBGC ( ena, "ENA %p out of transmit descriptors\n", ena );
return -ENOBUFS;
}
index = ( ena->tx.sq.prod % ENA_TX_COUNT );
sqe = &ena->tx.sq.sqe.tx[index];
id = ena->tx_ids[index];
/* Construct submission queue entry */
address = virt_to_bus ( iobuf->data );
len = iob_len ( iobuf );
sqe->len = cpu_to_le16 ( len );
sqe->id = ena->tx.sq.prod;
sqe->id = cpu_to_le16 ( id );
sqe->address = cpu_to_le64 ( address );
wmb();
sqe->flags = ( ENA_SQE_FIRST | ENA_SQE_LAST | ENA_SQE_CPL |
@ -806,10 +934,14 @@ static int ena_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
if ( ( ena->tx.sq.prod % ENA_TX_COUNT ) == 0 )
ena->tx.sq.phase ^= ENA_SQE_PHASE;
/* Record I/O buffer */
assert ( ena->tx_iobuf[id] == NULL );
ena->tx_iobuf[id] = iobuf;
/* Ring doorbell */
writel ( ena->tx.sq.prod, ( ena->regs + ena->tx.sq.doorbell ) );
DBGC2 ( ena, "ENA %p TX %d at [%08llx,%08llx)\n", ena, sqe->id,
DBGC2 ( ena, "ENA %p TX %d at [%08llx,%08llx)\n", ena, id,
( ( unsigned long long ) address ),
( ( unsigned long long ) address + len ) );
return 0;
@ -823,7 +955,9 @@ static int ena_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
static void ena_poll_tx ( struct net_device *netdev ) {
struct ena_nic *ena = netdev->priv;
struct ena_tx_cqe *cqe;
struct io_buffer *iobuf;
unsigned int index;
unsigned int id;
/* Check for completed packets */
while ( ena->tx.cq.cons != ena->tx.sq.prod ) {
@ -835,16 +969,24 @@ static void ena_poll_tx ( struct net_device *netdev ) {
/* Stop if completion queue entry is empty */
if ( ( cqe->flags ^ ena->tx.cq.phase ) & ENA_CQE_PHASE )
return;
DBGC2 ( ena, "ENA %p TX %d complete\n", ena,
( le16_to_cpu ( cqe->id ) >> 2 /* Don't ask */ ) );
/* Increment consumer counter */
ena->tx.cq.cons++;
if ( ! ( ena->tx.cq.cons & ena->tx.cq.mask ) )
ena->tx.cq.phase ^= ENA_CQE_PHASE;
/* Identify and free buffer ID */
id = ENA_TX_CQE_ID ( le16_to_cpu ( cqe->id ) );
ena->tx_ids[index] = id;
/* Identify I/O buffer */
iobuf = ena->tx_iobuf[id];
assert ( iobuf != NULL );
ena->tx_iobuf[id] = NULL;
/* Complete transmit */
netdev_tx_complete_next ( netdev );
DBGC2 ( ena, "ENA %p TX %d complete\n", ena, id );
netdev_tx_complete ( netdev, iobuf );
}
}
@ -858,13 +1000,14 @@ static void ena_poll_rx ( struct net_device *netdev ) {
struct ena_rx_cqe *cqe;
struct io_buffer *iobuf;
unsigned int index;
unsigned int id;
size_t len;
/* Check for received packets */
while ( ena->rx.cq.cons != ena->rx.sq.prod ) {
/* Get next completion queue entry */
index = ( ena->rx.cq.cons % ENA_RX_COUNT );
index = ( ena->rx.cq.cons & ena->rx.cq.mask );
cqe = &ena->rx.cq.cqe.rx[index];
/* Stop if completion queue entry is empty */
@ -876,15 +1019,20 @@ static void ena_poll_rx ( struct net_device *netdev ) {
if ( ! ( ena->rx.cq.cons & ena->rx.cq.mask ) )
ena->rx.cq.phase ^= ENA_CQE_PHASE;
/* Identify and free buffer ID */
id = le16_to_cpu ( cqe->id );
ena->rx_ids[index] = id;
/* Populate I/O buffer */
iobuf = ena->rx_iobuf[index];
ena->rx_iobuf[index] = NULL;
iobuf = ena->rx_iobuf[id];
assert ( iobuf != NULL );
ena->rx_iobuf[id] = NULL;
len = le16_to_cpu ( cqe->len );
iob_put ( iobuf, len );
/* Hand off to network stack */
DBGC2 ( ena, "ENA %p RX %d complete (length %zd)\n",
ena, le16_to_cpu ( cqe->id ), len );
ena, id, len );
netdev_rx ( netdev, iobuf );
}
}
@ -921,6 +1069,45 @@ static struct net_device_operations ena_operations = {
******************************************************************************
*/
/**
* Assign memory BAR
*
* @v ena ENA device
* @v pci PCI device
* @ret rc Return status code
*
* Some BIOSes in AWS EC2 are observed to fail to assign a base
* address to the ENA device. The device is the only device behind
* its bridge, and the BIOS does assign a memory window to the bridge.
* We therefore place the device at the start of the memory window.
*/
static int ena_membase ( struct ena_nic *ena, struct pci_device *pci ) {
struct pci_bridge *bridge;
/* Locate PCI bridge */
bridge = pcibridge_find ( pci );
if ( ! bridge ) {
DBGC ( ena, "ENA %p found no PCI bridge\n", ena );
return -ENOTCONN;
}
/* Sanity check */
if ( PCI_SLOT ( pci->busdevfn ) || PCI_FUNC ( pci->busdevfn ) ) {
DBGC ( ena, "ENA %p at " PCI_FMT " may not be only device "
"on bus\n", ena, PCI_ARGS ( pci ) );
return -ENOTSUP;
}
/* Place device at start of memory window */
pci_write_config_dword ( pci, PCI_BASE_ADDRESS_0, bridge->membase );
pci->membase = bridge->membase;
DBGC ( ena, "ENA %p at " PCI_FMT " claiming bridge " PCI_FMT " mem "
"%08x\n", ena, PCI_ARGS ( pci ), PCI_ARGS ( bridge->pci ),
bridge->membase );
return 0;
}
/**
* Probe PCI device
*
@ -930,6 +1117,7 @@ static struct net_device_operations ena_operations = {
static int ena_probe ( struct pci_device *pci ) {
struct net_device *netdev;
struct ena_nic *ena;
struct ena_host_info *info;
int rc;
/* Allocate and initialise net device */
@ -946,16 +1134,20 @@ static int ena_probe ( struct pci_device *pci ) {
ena->acq.phase = ENA_ACQ_PHASE;
ena_cq_init ( &ena->tx.cq, ENA_TX_COUNT,
sizeof ( ena->tx.cq.cqe.tx[0] ) );
ena_sq_init ( &ena->tx.sq, ENA_SQ_TX, ENA_TX_COUNT,
sizeof ( ena->tx.sq.sqe.tx[0] ) );
ena_sq_init ( &ena->tx.sq, ENA_SQ_TX, ENA_TX_COUNT, ENA_TX_COUNT,
sizeof ( ena->tx.sq.sqe.tx[0] ), ena->tx_ids );
ena_cq_init ( &ena->rx.cq, ENA_RX_COUNT,
sizeof ( ena->rx.cq.cqe.rx[0] ) );
ena_sq_init ( &ena->rx.sq, ENA_SQ_RX, ENA_RX_COUNT,
sizeof ( ena->rx.sq.sqe.rx[0] ) );
ena_sq_init ( &ena->rx.sq, ENA_SQ_RX, ENA_RX_COUNT, ENA_RX_FILL,
sizeof ( ena->rx.sq.sqe.rx[0] ), ena->rx_ids );
/* Fix up PCI device */
adjust_pci_device ( pci );
/* Fix up PCI BAR if left unassigned by BIOS */
if ( ( ! pci->membase ) && ( ( rc = ena_membase ( ena, pci ) ) != 0 ) )
goto err_membase;
/* Map registers */
ena->regs = pci_ioremap ( pci, pci->membase, ENA_BAR_SIZE );
if ( ! ena->regs ) {
@ -963,6 +1155,25 @@ static int ena_probe ( struct pci_device *pci ) {
goto err_ioremap;
}
/* Allocate and initialise host info */
info = malloc_phys ( PAGE_SIZE, PAGE_SIZE );
if ( ! info ) {
rc = -ENOMEM;
goto err_info;
}
ena->info = info;
memset ( info, 0, PAGE_SIZE );
info->type = cpu_to_le32 ( ENA_HOST_INFO_TYPE_LINUX );
snprintf ( info->dist_str, sizeof ( info->dist_str ), "%s",
( product_name[0] ? product_name : product_short_name ) );
snprintf ( info->kernel_str, sizeof ( info->kernel_str ), "%s",
product_version );
info->version = cpu_to_le32 ( ENA_HOST_INFO_VERSION_WTF );
info->spec = cpu_to_le16 ( ENA_HOST_INFO_SPEC_2_0 );
info->busdevfn = cpu_to_le16 ( pci->busdevfn );
DBGC2 ( ena, "ENA %p host info:\n", ena );
DBGC2_HDA ( ena, virt_to_phys ( info ), info, sizeof ( *info ) );
/* Reset the NIC */
if ( ( rc = ena_reset ( ena ) ) != 0 )
goto err_reset;
@ -971,6 +1182,14 @@ static int ena_probe ( struct pci_device *pci ) {
if ( ( rc = ena_create_admin ( ena ) ) != 0 )
goto err_create_admin;
/* Create async event notification queue */
if ( ( rc = ena_create_async ( ena ) ) != 0 )
goto err_create_async;
/* Set host attributes */
if ( ( rc = ena_set_host_attributes ( ena ) ) != 0 )
goto err_set_host_attributes;
/* Fetch MAC address */
if ( ( rc = ena_get_device_attributes ( netdev ) ) != 0 )
goto err_get_device_attributes;
@ -989,12 +1208,18 @@ static int ena_probe ( struct pci_device *pci ) {
unregister_netdev ( netdev );
err_register_netdev:
err_get_device_attributes:
err_set_host_attributes:
ena_destroy_async ( ena );
err_create_async:
ena_destroy_admin ( ena );
err_create_admin:
ena_reset ( ena );
err_reset:
free_phys ( ena->info, PAGE_SIZE );
err_info:
iounmap ( ena->regs );
err_ioremap:
err_membase:
netdev_nullify ( netdev );
netdev_put ( netdev );
err_alloc:
@ -1013,12 +1238,18 @@ static void ena_remove ( struct pci_device *pci ) {
/* Unregister network device */
unregister_netdev ( netdev );
/* Destroy async event notification queue */
ena_destroy_async ( ena );
/* Destroy admin queues */
ena_destroy_admin ( ena );
/* Reset card */
ena_reset ( ena );
/* Free host info */
free_phys ( ena->info, PAGE_SIZE );
/* Free network device */
iounmap ( ena->regs );
netdev_nullify ( netdev );

View File

@ -24,11 +24,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Number of admin completion queue entries */
#define ENA_ACQ_COUNT 2
/** Number of async event notification queue entries */
#define ENA_AENQ_COUNT 2
/** Number of transmit queue entries */
#define ENA_TX_COUNT 16
/** Number of receive queue entries */
#define ENA_RX_COUNT 16
#define ENA_RX_COUNT 128
/** Receive queue maximum fill level */
#define ENA_RX_FILL 16
/** Base address low register offset */
#define ENA_BASE_LO 0x0
@ -57,6 +63,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Maximum time to wait for admin requests */
#define ENA_ADMIN_MAX_WAIT_MS 5000
/** Async event notification queue capabilities register */
#define ENA_AENQ_CAPS 0x34
/** Async event notification queue base address register */
#define ENA_AENQ_BASE 0x38
/** Device control register */
#define ENA_CTRL 0x54
#define ENA_CTRL_RESET 0x00000001UL /**< Reset */
@ -127,10 +139,99 @@ struct ena_device_attributes {
uint32_t mtu;
} __attribute__ (( packed ));
/** Async event notification queue config */
#define ENA_AENQ_CONFIG 26
/** Async event notification queue config */
struct ena_aenq_config {
/** Bitmask of supported AENQ groups (device -> host) */
uint32_t supported;
/** Bitmask of enabled AENQ groups (host -> device) */
uint32_t enabled;
} __attribute__ (( packed ));
/** Host attributes */
#define ENA_HOST_ATTRIBUTES 28
/** Host attributes */
struct ena_host_attributes {
/** Host info base address */
uint64_t info;
/** Debug area base address */
uint64_t debug;
/** Debug area size */
uint32_t debug_len;
} __attribute__ (( packed ));
/** Host information */
struct ena_host_info {
/** Operating system type */
uint32_t type;
/** Operating system distribution (string) */
char dist_str[128];
/** Operating system distribution (numeric) */
uint32_t dist;
/** Kernel version (string) */
char kernel_str[32];
/** Kernel version (numeric) */
uint32_t kernel;
/** Driver version */
uint32_t version;
/** Linux network device features */
uint64_t linux_features;
/** ENA specification version */
uint16_t spec;
/** PCI bus:dev.fn address */
uint16_t busdevfn;
/** Number of CPUs */
uint16_t cpus;
/** Reserved */
uint8_t reserved_a[2];
/** Supported features */
uint32_t features;
} __attribute__ (( packed ));
/** Linux operating system type
*
* There is a defined "iPXE" operating system type (with value 5).
* However, some very broken versions of the ENA firmware will refuse
* to allow a completion queue to be created if the "iPXE" type is
* used.
*/
#define ENA_HOST_INFO_TYPE_LINUX 1
/** Driver version
*
* The driver version field is nominally used to report a version
* number outside of the VM for consumption by humans (and potentially
* by automated monitoring tools that could e.g. check for outdated
* versions with known security flaws).
*
* However, at some point in the development of the ENA firmware, some
* unknown person at AWS thought it would be sensible to apply a
* machine interpretation to this field and adjust the behaviour of
* the firmware based on its value, thereby creating a maintenance and
* debugging nightmare for all existing and future drivers.
*
* Hint to engineers: if you ever find yourself writing code of the
* form "if (version == SOME_MAGIC_NUMBER)" then something has gone
* very, very wrong. This *always* indicates that something is
* broken, either in your own code or in the code with which you are
* forced to interact.
*/
#define ENA_HOST_INFO_VERSION_WTF 0x00000002UL
/** ENA specification version */
#define ENA_HOST_INFO_SPEC_2_0 0x0200
/** Feature */
union ena_feature {
/** Device attributes */
struct ena_device_attributes device;
/** Async event notification queue config */
struct ena_aenq_config aenq;
/** Host attributes */
struct ena_host_attributes host;
};
/** Submission queue direction */
@ -230,6 +331,14 @@ struct ena_create_cq_req {
uint64_t address;
} __attribute__ (( packed ));
/** Empty MSI-X vector
*
* Some versions of the ENA firmware will complain if the completion
* queue's MSI-X vector field is left empty, even though the queue
* configuration specifies that interrupts are not used.
*/
#define ENA_MSIX_NONE 0xffffffffUL
/** Create completion queue response */
struct ena_create_cq_rsp {
/** Header */
@ -292,6 +401,27 @@ struct ena_get_feature_rsp {
union ena_feature feature;
} __attribute__ (( packed ));
/** Set feature */
#define ENA_SET_FEATURE 9
/** Set feature request */
struct ena_set_feature_req {
/** Header */
struct ena_aq_header header;
/** Length */
uint32_t len;
/** Address */
uint64_t address;
/** Flags */
uint8_t flags;
/** Feature identifier */
uint8_t id;
/** Reserved */
uint8_t reserved[2];
/** Feature */
union ena_feature feature;
} __attribute__ (( packed ));
/** Get statistics */
#define ENA_GET_STATS 11
@ -352,6 +482,8 @@ union ena_aq_req {
struct ena_destroy_cq_req destroy_cq;
/** Get feature */
struct ena_get_feature_req get_feature;
/** Set feature */
struct ena_set_feature_req set_feature;
/** Get statistics */
struct ena_get_stats_req get_stats;
/** Padding */
@ -396,6 +528,28 @@ struct ena_acq {
unsigned int phase;
};
/** Async event notification queue event */
struct ena_aenq_event {
/** Type of event */
uint16_t group;
/** ID of event */
uint16_t syndrome;
/** Phase */
uint8_t flags;
/** Reserved */
uint8_t reserved[3];
/** Timestamp */
uint64_t timestamp;
/** Additional event data */
uint8_t data[48];
} __attribute__ (( packed ));
/** Async event notification queue */
struct ena_aenq {
/** Events */
struct ena_aenq_event *evt;
};
/** Transmit submission queue entry */
struct ena_tx_sqe {
/** Length */
@ -454,6 +608,9 @@ struct ena_tx_cqe {
uint16_t cons;
} __attribute__ (( packed ));
/** Transmit completion request identifier */
#define ENA_TX_CQE_ID(id) ( (id) >> 2 )
/** Receive completion queue entry */
struct ena_rx_cqe {
/** Reserved */
@ -482,6 +639,8 @@ struct ena_sq {
/** Raw data */
void *raw;
} sqe;
/** Buffer IDs */
uint8_t *ids;
/** Doorbell register offset */
unsigned int doorbell;
/** Total length of entries */
@ -496,6 +655,10 @@ struct ena_sq {
uint8_t direction;
/** Number of entries */
uint8_t count;
/** Maximum fill level */
uint8_t max;
/** Fill level (limited to completion queue size) */
uint8_t fill;
};
/**
@ -504,15 +667,19 @@ struct ena_sq {
* @v sq Submission queue
* @v direction Direction
* @v count Number of entries
* @v max Maximum fill level
* @v size Size of each entry
* @v ids Buffer IDs
*/
static inline __attribute__ (( always_inline )) void
ena_sq_init ( struct ena_sq *sq, unsigned int direction, unsigned int count,
size_t size ) {
unsigned int max, size_t size, uint8_t *ids ) {
sq->len = ( count * size );
sq->direction = direction;
sq->count = count;
sq->max = max;
sq->ids = ids;
}
/** Completion queue */
@ -573,15 +740,25 @@ struct ena_qp {
struct ena_nic {
/** Registers */
void *regs;
/** Host info */
struct ena_host_info *info;
/** Admin queue */
struct ena_aq aq;
/** Admin completion queue */
struct ena_acq acq;
/** Async event notification queue */
struct ena_aenq aenq;
/** Transmit queue */
struct ena_qp tx;
/** Receive queue */
struct ena_qp rx;
/** Receive I/O buffers */
/** Transmit buffer IDs */
uint8_t tx_ids[ENA_TX_COUNT];
/** Transmit I/O buffers, indexed by buffer ID */
struct io_buffer *tx_iobuf[ENA_TX_COUNT];
/** Receive buffer IDs */
uint8_t rx_ids[ENA_RX_COUNT];
/** Receive I/O buffers, indexed by buffer ID */
struct io_buffer *rx_iobuf[ENA_RX_COUNT];
};

View File

@ -1173,6 +1173,10 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x15fa, "i219v-14", "I219-V (14)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x15fb, "i219lm-13", "I219-LM (13)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x15fc, "i219v-13", "I219-V (13)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x1a1c, "i219lm-17", "I219-LM (17)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x1a1d, "i219v-17", "I219-V (17)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x1a1e, "i219lm-16", "I219-LM (16)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x1a1f, "i219v-16", "I219-V (16)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x1f41, "i354", "I354", INTEL_NO_ASDE ),
PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),

View File

@ -59,6 +59,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
EUNIQ ( EINFO_EIO, ( -(status) & 0x1f ), \
EIO_NETIF_RSP_ERROR, EIO_NETIF_RSP_DROPPED )
/** List of netfront devices */
static LIST_HEAD ( netfront_devices );
/******************************************************************************
*
* XenStore interface
@ -952,6 +955,7 @@ static int netfront_probe ( struct xen_device *xendev ) {
netdev->dev = &xendev->dev;
netfront = netdev->priv;
netfront->xendev = xendev;
netfront->netdev = netdev;
INIT_LIST_HEAD ( &netfront->rx_partial );
DBGC ( netfront, "NETFRONT %s backend=\"%s\" in domain %ld\n",
xendev->key, xendev->backend, xendev->backend_id );
@ -991,9 +995,13 @@ static int netfront_probe ( struct xen_device *xendev ) {
/* Set initial link state */
netdev_link_down ( netdev );
/* Add to list of netfront devices */
list_add_tail ( &netfront->list, &netfront_devices );
xen_set_drvdata ( xendev, netdev );
return 0;
list_del ( &netfront->list );
unregister_netdev ( netdev );
err_register_netdev:
err_read_mac:
@ -1015,6 +1023,9 @@ static void netfront_remove ( struct xen_device *xendev ) {
struct netfront_nic *netfront = netdev->priv;
struct xen_hypervisor *xen = xendev->xen;
/* Remove from list of netfront devices */
list_del ( &netfront->list );
/* Unregister network device */
unregister_netdev ( netdev );
@ -1033,3 +1044,41 @@ struct xen_driver netfront_driver __xen_driver = {
.probe = netfront_probe,
.remove = netfront_remove,
};
/******************************************************************************
*
* Emulated PCI device inhibitor
*
******************************************************************************
*/
/**
* Inhibit emulated PCI devices
*
* @v netdev Network device
* @ret rc Return status code
*/
static int netfront_net_probe ( struct net_device *netdev ) {
struct netfront_nic *netfront;
/* Inhibit emulated PCI devices matching an existing netfront device */
list_for_each_entry ( netfront, &netfront_devices, list ) {
if ( ( netdev->dev != netfront->netdev->dev ) &&
( netdev->ll_protocol->ll_addr_len == ETH_ALEN ) &&
( memcmp ( netdev->hw_addr, netfront->netdev->hw_addr,
ETH_ALEN ) == 0 ) ) {
DBGC ( netfront, "NETFRONT %s inhibiting emulated %s "
"%s\n", netfront->xendev->key,
netdev->dev->driver_name, netdev->dev->name );
return -EEXIST;
}
}
return 0;
}
/** Emulated PCI device inhibitor driver */
struct net_driver netfront_net_driver __net_driver = {
.name = "netfront",
.probe = netfront_net_probe,
};

View File

@ -159,6 +159,11 @@ struct netfront_nic {
/** Grant references */
grant_ref_t refs[NETFRONT_REF_COUNT];
/** Network device */
struct net_device *netdev;
/** List of netfront NICs */
struct list_head list;
/** Transmit ring */
struct netfront_ring tx;
/** Transmit front ring */

View File

@ -1067,11 +1067,15 @@ static void realtek_detect ( struct realtek_nic *rtl ) {
* Note that enabling DAC seems to cause bizarre behaviour
* (lockups, garbage data on the wire) on some systems, even
* if only 32-bit addresses are used.
*
* Disable VLAN offload, since some cards seem to have it
* enabled by default.
*/
cpcr = readw ( rtl->regs + RTL_CPCR );
cpcr |= ( RTL_CPCR_MULRW | RTL_CPCR_CPRX | RTL_CPCR_CPTX );
if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
cpcr |= RTL_CPCR_DAC;
cpcr &= ~RTL_CPCR_VLAN;
writew ( cpcr, rtl->regs + RTL_CPCR );
check_cpcr = readw ( rtl->regs + RTL_CPCR );

View File

@ -228,8 +228,9 @@ enum realtek_legacy_status {
/** C+ Command Register (word) */
#define RTL_CPCR 0xe0
#define RTL_CPCR_DAC 0x0010 /**< PCI Dual Address Cycle Enable */
#define RTL_CPCR_MULRW 0x0008 /**< PCI Multiple Read/Write Enable */
#define RTL_CPCR_VLAN 0x0040 /**< VLAN tag stripping enable */
#define RTL_CPCR_DAC 0x0010 /**< PCI Dual Address Cycle enable */
#define RTL_CPCR_MULRW 0x0008 /**< PCI Multiple Read/Write enable */
#define RTL_CPCR_CPRX 0x0002 /**< C+ receive enable */
#define RTL_CPCR_CPTX 0x0001 /**< C+ transmit enable */

View File

@ -22,6 +22,7 @@
*/
#include <stdio.h>
#include <errno.h>
#include <getopt.h>
#include <ipxe/pci.h>
#include <ipxe/command.h>
@ -58,7 +59,7 @@ static int pciscan_exec ( int argc, char **argv ) {
struct named_setting setting;
struct pci_device pci;
unsigned long prev;
int next;
uint32_t busdevfn;
int len;
int rc;
@ -75,17 +76,19 @@ static int pciscan_exec ( int argc, char **argv ) {
if ( ( len = fetchn_setting ( setting.settings, &setting.setting,
NULL, &setting.setting, &prev ) ) < 0 ) {
/* Setting not yet defined: start searching from 00:00.0 */
prev = 0;
busdevfn = 0;
} else {
/* Setting is defined: start searching from next location */
prev++;
busdevfn = ( prev + 1 );
if ( ! busdevfn ) {
rc = -ENOENT;
goto err_end;
}
}
/* Find next existent PCI device */
if ( ( next = pci_find_next ( &pci, prev ) ) < 0 ) {
rc = next;
if ( ( rc = pci_find_next ( &pci, &busdevfn ) ) != 0 )
goto err_find_next;
}
/* Apply default type if necessary. Use ":uint16" rather than
* ":busdevfn" to allow for easy inclusion within a
@ -96,13 +99,14 @@ static int pciscan_exec ( int argc, char **argv ) {
/* Store setting */
if ( ( rc = storen_setting ( setting.settings, &setting.setting,
next ) ) != 0 ) {
busdevfn ) ) != 0 ) {
printf ( "Could not store \"%s\": %s\n",
setting.setting.name, strerror ( rc ) );
goto err_store;
}
err_store:
err_end:
err_find_next:
err_parse_setting:
err_parse_options:

View File

@ -96,9 +96,7 @@ efi_image_path ( struct image *image, EFI_DEVICE_PATH_PROTOCOL *parent ) {
efi_snprintf ( filepath->PathName, ( name_len + 1 /* NUL */ ),
"%s", image->name );
end = ( ( ( void * ) filepath ) + filepath_len );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
return path;
}

View File

@ -755,6 +755,53 @@ char __debug_disable(OBJECT) = ( DBGLVL_MAX & ~DBGLVL_DFLT );
#define FILE_LICENCE_BSD2 \
PROVIDE_SYMBOL ( PREFIX_OBJECT ( __licence__bsd2__ ) )
/** Declare a file as being under the two-clause BSD plus patent licence
*
* This licence declaration is applicable when a file states itself to
* be licensed under terms allowing redistribution in source and
* binary forms (with or without modification) provided that:
*
* redistributions of source code retain the copyright notice,
* list of conditions and any attached disclaimers
*
* redistributions in binary form reproduce the copyright notice,
* list of conditions and any attached disclaimers in the
* documentation and/or other materials provided with the
* distribution
*
* and in addition states that
*
* Subject to the terms and conditions of this license, each
* copyright holder and contributor hereby grants to those
* receiving rights under this license a perpetual, worldwide,
* non-exclusive, no-charge, royalty-free, irrevocable (except for
* failure to satisfy the conditions of this license) patent
* license to make, have made, use, offer to sell, sell, import,
* and otherwise transfer this software, where such license
* applies only to those patent claims, already acquired or
* hereafter acquired, licensable by such copyright holder or
* contributor that are necessarily infringed by:
*
* their Contribution(s) (the licensed copyrights of copyright
* holders and non-copyrightable additions of contributors, in
* source or binary form) alone; or
*
* combination of their Contribution(s) with the work of
* authorship to which such Contribution(s) was added by such
* copyright holder or contributor, if, at the time the
* Contribution is added, such addition causes such combination
* to be necessarily infringed. The patent license shall not
* apply to any other combinations which include the
* Contribution.
*
* It is not necessary for the file to explicitly state that it is
* under a "BSD" licence; only that the licensing terms be
* functionally equivalent to the standard two-clause BSD licence with
* patent grant.
*/
#define FILE_LICENCE_BSD2_PATENT \
PROVIDE_SYMBOL ( PREFIX_OBJECT ( __licence__bsd2_patent__ ) )
/** Declare a file as being under the one-clause MIT-style licence
*
* This licence declaration is applicable when a file states itself to

View File

@ -47,6 +47,7 @@ struct aes_context {
extern struct cipher_algorithm aes_algorithm;
extern struct cipher_algorithm aes_ecb_algorithm;
extern struct cipher_algorithm aes_cbc_algorithm;
extern struct cipher_algorithm aes_gcm_algorithm;
int aes_wrap ( const void *kek, const void *src, void *dest, int nblk );
int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk );

View File

@ -18,7 +18,8 @@ extern struct cached_dhcp_packet cached_dhcpack;
extern struct cached_dhcp_packet cached_proxydhcp;
extern struct cached_dhcp_packet cached_pxebs;
extern int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
extern int cachedhcp_record ( struct cached_dhcp_packet *cache,
unsigned int vlan, userptr_t data,
size_t max_len );
#endif /* _IPXE_CACHEDHCP_H */

View File

@ -33,12 +33,15 @@ static inline int cbc_setkey ( void *ctx, const void *key, size_t keylen,
*
* @v ctx Context
* @v iv Initialisation vector
* @v ivlen Initialisation vector length
* @v raw_cipher Underlying cipher algorithm
* @v cbc_ctx CBC context
*/
static inline void cbc_setiv ( void *ctx __unused, const void *iv,
static inline void cbc_setiv ( void *ctx __unused,
const void *iv, size_t ivlen,
struct cipher_algorithm *raw_cipher,
void *cbc_ctx ) {
assert ( ivlen == raw_cipher->blocksize );
memcpy ( cbc_ctx, iv, raw_cipher->blocksize );
}
@ -70,9 +73,10 @@ static int _cbc_name ## _setkey ( void *ctx, const void *key, \
return cbc_setkey ( &_cbc_name ## _ctx->raw_ctx, key, keylen, \
&_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );\
} \
static void _cbc_name ## _setiv ( void *ctx, const void *iv ) { \
static void _cbc_name ## _setiv ( void *ctx, const void *iv, \
size_t ivlen ) { \
struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \
cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, \
cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, ivlen, \
&_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \
} \
static void _cbc_name ## _encrypt ( void *ctx, const void *src, \
@ -91,10 +95,13 @@ struct cipher_algorithm _cbc_cipher = { \
.name = #_cbc_name, \
.ctxsize = sizeof ( struct _cbc_name ## _context ), \
.blocksize = _blocksize, \
.alignsize = _blocksize, \
.authsize = 0, \
.setkey = _cbc_name ## _setkey, \
.setiv = _cbc_name ## _setiv, \
.encrypt = _cbc_name ## _encrypt, \
.decrypt = _cbc_name ## _decrypt, \
.auth = cipher_null_auth, \
};
#endif /* _IPXE_CBC_H */

View File

@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
/** A message digest algorithm */
struct digest_algorithm {
@ -50,28 +51,47 @@ struct cipher_algorithm {
const char *name;
/** Context size */
size_t ctxsize;
/** Block size */
/** Block size
*
* Every call to encrypt() or decrypt() must be for a multiple
* of this size.
*/
size_t blocksize;
/** Alignment size
*
* Every call to encrypt() or decrypt() must begin at a
* multiple of this offset from the start of the stream.
* (Equivalently: all but the last call to encrypt() or
* decrypt() must be for a multiple of this size.)
*
* For ciphers supporting additional data, the main data
* stream and additional data stream are both considered to
* begin at offset zero.
*/
size_t alignsize;
/** Authentication tag size */
size_t authsize;
/** Set key
*
* @v ctx Context
* @v key Key
* @v keylen Key length
* @ret rc Return status code
* @v ctx Context
* @v key Key
* @v keylen Key length
* @ret rc Return status code
*/
int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
/** Set initialisation vector
*
* @v ctx Context
* @v iv Initialisation vector
* @v ctx Context
* @v iv Initialisation vector
* @v ivlen Initialisation vector length
*/
void ( * setiv ) ( void *ctx, const void *iv );
void ( * setiv ) ( void *ctx, const void *iv, size_t ivlen );
/** Encrypt data
*
* @v ctx Context
* @v src Data to encrypt
* @v dst Buffer for encrypted data
* @v len Length of data
* @v ctx Context
* @v src Data to encrypt
* @v dst Buffer for encrypted data, or NULL for additional data
* @v len Length of data
*
* @v len is guaranteed to be a multiple of @c blocksize.
*/
@ -79,15 +99,21 @@ struct cipher_algorithm {
size_t len );
/** Decrypt data
*
* @v ctx Context
* @v src Data to decrypt
* @v dst Buffer for decrypted data
* @v len Length of data
* @v ctx Context
* @v src Data to decrypt
* @v dst Buffer for decrypted data, or NULL for additional data
* @v len Length of data
*
* @v len is guaranteed to be a multiple of @c blocksize.
*/
void ( * decrypt ) ( void *ctx, const void *src, void *dst,
size_t len );
/** Generate authentication tag
*
* @v ctx Context
* @v auth Authentication tag
*/
void ( * auth ) ( void *ctx, void *auth );
};
/** A public key algorithm */
@ -190,8 +216,8 @@ static inline int cipher_setkey ( struct cipher_algorithm *cipher,
}
static inline void cipher_setiv ( struct cipher_algorithm *cipher,
void *ctx, const void *iv ) {
cipher->setiv ( ctx, iv );
void *ctx, const void *iv, size_t ivlen ) {
cipher->setiv ( ctx, iv, ivlen );
}
static inline void cipher_encrypt ( struct cipher_algorithm *cipher,
@ -214,10 +240,23 @@ static inline void cipher_decrypt ( struct cipher_algorithm *cipher,
cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) ); \
} while ( 0 )
static inline void cipher_auth ( struct cipher_algorithm *cipher, void *ctx,
void *auth ) {
cipher->auth ( ctx, auth );
}
static inline int is_stream_cipher ( struct cipher_algorithm *cipher ) {
return ( cipher->blocksize == 1 );
}
static inline int is_block_cipher ( struct cipher_algorithm *cipher ) {
return ( cipher->blocksize > 1 );
}
static inline int is_auth_cipher ( struct cipher_algorithm *cipher ) {
return cipher->authsize;
}
static inline int pubkey_init ( struct pubkey_algorithm *pubkey, void *ctx,
const void *key, size_t key_len ) {
return pubkey->init ( ctx, key, key_len );
@ -263,6 +302,30 @@ static inline int pubkey_match ( struct pubkey_algorithm *pubkey,
public_key_len );
}
extern void digest_null_init ( void *ctx );
extern void digest_null_update ( void *ctx, const void *src, size_t len );
extern void digest_null_final ( void *ctx, void *out );
extern int cipher_null_setkey ( void *ctx, const void *key, size_t keylen );
extern void cipher_null_setiv ( void *ctx, const void *iv, size_t ivlen );
extern void cipher_null_encrypt ( void *ctx, const void *src, void *dst,
size_t len );
extern void cipher_null_decrypt ( void *ctx, const void *src, void *dst,
size_t len );
extern void cipher_null_auth ( void *ctx, void *auth );
extern int pubkey_null_init ( void *ctx, const void *key, size_t key_len );
extern size_t pubkey_null_max_len ( void *ctx );
extern int pubkey_null_encrypt ( void *ctx, const void *plaintext,
size_t plaintext_len, void *ciphertext );
extern int pubkey_null_decrypt ( void *ctx, const void *ciphertext,
size_t ciphertext_len, void *plaintext );
extern int pubkey_null_sign ( void *ctx, struct digest_algorithm *digest,
const void *value, void *signature );
extern int pubkey_null_verify ( void *ctx, struct digest_algorithm *digest,
const void *value, const void *signature ,
size_t signature_len );
extern struct digest_algorithm digest_null;
extern struct cipher_algorithm cipher_null;
extern struct pubkey_algorithm pubkey_null;

View File

@ -274,8 +274,9 @@ struct dhcp_client_architecture {
/** DHCP client architecture values
*
* These are defined by the PXE specification and redefined by
* RFC4578.
* These are originally defined by the PXE specification, redefined by
* RFC4578, redefined again by RFC5970, and now maintained in the IANA
* DHCPv6 parameters registry.
*/
enum dhcp_client_architecture_values {
/** Intel x86 PC */
@ -302,6 +303,24 @@ enum dhcp_client_architecture_values {
DHCP_CLIENT_ARCHITECTURE_ARM32 = 0x000a,
/** EFI 64-bit ARM */
DHCP_CLIENT_ARCHITECTURE_ARM64 = 0x000b,
/** EFI 32-bit RISC-V */
DHCP_CLIENT_ARCHITECTURE_RISCV32 = 0x0019,
/** EFI 64-bit RISC-V */
DHCP_CLIENT_ARCHITECTURE_RISCV64 = 0x001b,
/** EFI 128-bit RISC-V */
DHCP_CLIENT_ARCHITECTURE_RISCV128 = 0x001d,
/** EFI 32-bit MIPS */
DHCP_CLIENT_ARCHITECTURE_MIPS32 = 0x0021,
/** EFI 64-bit MIPS */
DHCP_CLIENT_ARCHITECTURE_MIPS64 = 0x0022,
/** EFI 32-bit Sunway */
DHCP_CLIENT_ARCHITECTURE_SUNWAY32 = 0x0023,
/** EFI 64-bit Sunway */
DHCP_CLIENT_ARCHITECTURE_SUNWAY64 = 0x0024,
/** EFI 32-bit LoongArch */
DHCP_CLIENT_ARCHITECTURE_LOONG32 = 0x0025,
/** EFI 64-bit LoongArch */
DHCP_CLIENT_ARCHITECTURE_LOONG64 = 0x0027,
};
/** Client network device interface */

View File

@ -0,0 +1,16 @@
#ifndef _IPXE_DHCPARCH_H
#define _IPXE_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Include platform-specific client architecture definitions */
#define PLATFORM_DHCPARCH(_platform) <ipxe/_platform/dhcparch.h>
#include PLATFORM_DHCPARCH(PLATFORM)
#endif /* _IPXE_DHCPARCH_H */

View File

@ -0,0 +1,19 @@
#ifndef _IPXE_DHE_H
#define _IPXE_DHE_H
/** @file
*
* Ephemeral Diffie-Hellman key exchange
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
extern int dhe_key ( const void *modulus, size_t len, const void *generator,
size_t generator_len, const void *partner,
size_t partner_len, const void *private,
size_t private_len, void *public, void *shared );
#endif /* _IPXE_DHE_H */

View File

@ -0,0 +1,57 @@
#ifndef _IPXE_ECAM_H
#define _IPXE_ECAM_H
/** @file
*
* PCI I/O API for Enhanced Configuration Access Mechanism (ECAM)
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/acpi.h>
#include <ipxe/pci.h>
/** Enhanced Configuration Access Mechanism per-device size */
#define ECAM_SIZE 4096
/** Enhanced Configuration Access Mechanism table signature */
#define ECAM_SIGNATURE ACPI_SIGNATURE ( 'M', 'C', 'F', 'G' )
/** An Enhanced Configuration Access Mechanism allocation */
struct ecam_allocation {
/** Base address */
uint64_t base;
/** PCI segment number */
uint16_t segment;
/** Start PCI bus number */
uint8_t start;
/** End PCI bus number */
uint8_t end;
/** Reserved */
uint8_t reserved[4];
} __attribute__ (( packed ));
/** An Enhanced Configuration Access Mechanism table */
struct ecam_table {
/** ACPI header */
struct acpi_header acpi;
/** Reserved */
uint8_t reserved[8];
/** Allocation structures */
struct ecam_allocation alloc[0];
} __attribute__ (( packed ));
/** A mapped Enhanced Configuration Access Mechanism allocation */
struct ecam_mapping {
/** Allocation */
struct ecam_allocation alloc;
/** PCI bus:dev.fn address range */
struct pci_range range;
/** MMIO base address */
void *regs;
};
extern struct pci_api ecam_api;
#endif /* _IPXE_ECAM_H */

View File

@ -0,0 +1,139 @@
#ifndef _IPXE_ECAM_IO_H
#define _IPXE_ECAM_IO_H
/** @file
*
* PCI I/O API for Enhanced Configuration Access Mechanism (ECAM)
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#ifdef PCIAPI_ECAM
#define PCIAPI_PREFIX_ecam
#else
#define PCIAPI_PREFIX_ecam __ecam_
#endif
struct pci_device;
/** Construct ECAM location */
#define ECAM_LOC( where, len ) ( ( (len) << 16 ) | where )
/** Extract offset from ECAM location */
#define ECAM_WHERE( location ) ( (location) & 0xffff )
/** Extract length from ECAM location */
#define ECAM_LEN( location ) ( (location) >> 16 )
extern int ecam_read ( struct pci_device *pci, unsigned int location,
void *value );
extern int ecam_write ( struct pci_device *pci, unsigned int location,
unsigned long value );
/**
* Read byte from PCI configuration space via ECAM
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value read
* @ret rc Return status code
*/
static inline __always_inline int
PCIAPI_INLINE ( ecam, pci_read_config_byte ) ( struct pci_device *pci,
unsigned int where,
uint8_t *value ) {
return ecam_read ( pci, ECAM_LOC ( where, sizeof ( *value ) ), value );
}
/**
* Read word from PCI configuration space via ECAM
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value read
* @ret rc Return status code
*/
static inline __always_inline int
PCIAPI_INLINE ( ecam, pci_read_config_word ) ( struct pci_device *pci,
unsigned int where,
uint16_t *value ) {
return ecam_read ( pci, ECAM_LOC ( where, sizeof ( *value ) ), value );
}
/**
* Read dword from PCI configuration space via ECAM
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value read
* @ret rc Return status code
*/
static inline __always_inline int
PCIAPI_INLINE ( ecam, pci_read_config_dword ) ( struct pci_device *pci,
unsigned int where,
uint32_t *value ) {
return ecam_read ( pci, ECAM_LOC ( where, sizeof ( *value ) ), value );
}
/**
* Write byte to PCI configuration space via ECAM
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value to be written
* @ret rc Return status code
*/
static inline __always_inline int
PCIAPI_INLINE ( ecam, pci_write_config_byte ) ( struct pci_device *pci,
unsigned int where,
uint8_t value ) {
return ecam_write ( pci, ECAM_LOC ( where, sizeof ( value ) ), value );
}
/**
* Write word to PCI configuration space via ECAM
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value to be written
* @ret rc Return status code
*/
static inline __always_inline int
PCIAPI_INLINE ( ecam, pci_write_config_word ) ( struct pci_device *pci,
unsigned int where,
uint16_t value ) {
return ecam_write ( pci, ECAM_LOC ( where, sizeof ( value ) ), value );
}
/**
* Write dword to PCI configuration space via ECAM
*
* @v pci PCI device
* @v where Location within PCI configuration space
* @v value Value to be written
* @ret rc Return status code
*/
static inline __always_inline int
PCIAPI_INLINE ( ecam, pci_write_config_dword ) ( struct pci_device *pci,
unsigned int where,
uint32_t value ) {
return ecam_write ( pci, ECAM_LOC ( where, sizeof ( value ) ), 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 ( ecam, pci_ioremap ) ( struct pci_device *pci __unused,
unsigned long bus_addr, size_t len ) {
return ioremap ( bus_addr, len );
}
#endif /* _IPXE_ECAM_IO_H */

View File

@ -31,8 +31,9 @@ static int _ecb_name ## _setkey ( void *ctx, const void *key, \
size_t keylen ) { \
return cipher_setkey ( &_raw_cipher, ctx, key, keylen ); \
} \
static void _ecb_name ## _setiv ( void *ctx, const void *iv ) { \
cipher_setiv ( &_raw_cipher, ctx, iv ); \
static void _ecb_name ## _setiv ( void *ctx, const void *iv, \
size_t ivlen ) { \
cipher_setiv ( &_raw_cipher, ctx, iv, ivlen ); \
} \
static void _ecb_name ## _encrypt ( void *ctx, const void *src, \
void *dst, size_t len ) { \
@ -46,10 +47,13 @@ struct cipher_algorithm _ecb_cipher = { \
.name = #_ecb_name, \
.ctxsize = sizeof ( _raw_context ), \
.blocksize = _blocksize, \
.alignsize = _blocksize, \
.authsize = 0, \
.setkey = _ecb_name ## _setkey, \
.setiv = _ecb_name ## _setiv, \
.encrypt = _ecb_name ## _encrypt, \
.decrypt = _ecb_name ## _decrypt, \
.auth = cipher_null_auth, \
};
#endif /* _IPXE_ECB_H */

View File

@ -1,24 +1,18 @@
/** @file
Processor or Compiler specific defines and types for AArch64.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __PROCESSOR_BIND_H__
#define __PROCESSOR_BIND_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
///
/// Define the processor type so other code can make processor based choices
@ -28,53 +22,102 @@ FILE_LICENCE ( BSD3 );
//
// Make sure we are using the correct packing rules per EFI specification
//
#ifndef __GNUC__
#pragma pack()
#if !defined (__GNUC__) && !defined (__ASSEMBLER__)
#pragma pack()
#endif
#if _MSC_EXTENSIONS
//
// use Microsoft* C compiler dependent integer width types
//
typedef unsigned __int64 UINT64;
typedef __int64 INT64;
typedef unsigned __int32 UINT32;
typedef __int32 INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
#if defined (_MSC_EXTENSIONS)
//
// Disable some level 4 compilation warnings (same as IA32 and X64)
//
//
// Disabling bitfield type checking warnings.
//
#pragma warning ( disable : 4214 )
//
// Disabling the unreferenced formal parameter warnings.
//
#pragma warning ( disable : 4100 )
//
// Disable slightly different base types warning as CHAR8 * can not be set
// to a constant string.
//
#pragma warning ( disable : 4057 )
//
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
//
#pragma warning ( disable : 4127 )
//
// This warning is caused by functions defined but not used. For precompiled header only.
//
#pragma warning ( disable : 4505 )
//
// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
//
#pragma warning ( disable : 4206 )
//
// Disable 'potentially uninitialized local variable X used' warnings
//
#pragma warning ( disable : 4701 )
//
// Disable 'potentially uninitialized local pointer variable X used' warnings
//
#pragma warning ( disable : 4703 )
//
// use Microsoft* C compiler dependent integer width types
//
typedef unsigned __int64 UINT64;
typedef __int64 INT64;
typedef unsigned __int32 UINT32;
typedef __int32 INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
#else
//
// Assume standard AARCH64 alignment.
//
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned int UINT32;
typedef int INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
//
// Assume standard AARCH64 alignment.
//
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned int UINT32;
typedef int INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
#endif
///
/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions,
/// 8 bytes on supported 64-bit processor instructions)
///
typedef UINT64 UINTN;
typedef UINT64 UINTN;
///
/// Signed value of native width. (4 bytes on supported 32-bit processor instructions,
/// 8 bytes on supported 64-bit processor instructions)
///
typedef INT64 INTN;
typedef INT64 INTN;
//
// Processor specific defines
@ -83,7 +126,7 @@ typedef INT64 INTN;
///
/// A value of native width with the highest bit set.
///
#define MAX_BIT 0x8000000000000000ULL
#define MAX_BIT 0x8000000000000000ULL
///
/// A value of native width with the two highest bits set.
@ -93,7 +136,12 @@ typedef INT64 INTN;
///
/// Maximum legal AARCH64 address
///
#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFFULL
#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFFULL
///
/// Maximum usable address at boot time (48 bits using 4 KB pages)
///
#define MAX_ALLOC_ADDRESS 0xFFFFFFFFFFFFULL
///
/// Maximum legal AArch64 INTN and UINTN values.
@ -101,6 +149,11 @@ typedef INT64 INTN;
#define MAX_INTN ((INTN)0x7FFFFFFFFFFFFFFFULL)
#define MAX_UINTN ((UINTN)0xFFFFFFFFFFFFFFFFULL)
///
/// Minimum legal AArch64 INTN value.
///
#define MIN_INTN (((INTN)-9223372036854775807LL) - 1)
///
/// The stack alignment required for AARCH64
///
@ -109,8 +162,8 @@ typedef INT64 INTN;
///
/// Page allocation granularity for AARCH64
///
#define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x10000)
#define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x10000)
//
// Modifier to ensure that all protocol member functions and EFI intrinsics
@ -121,18 +174,18 @@ typedef INT64 INTN;
// When compiling with Clang, we still use GNU as for the assembler, so we still
// need to define the GCC_ASM* macros.
#if defined(__GNUC__) || defined(__clang__)
///
/// For GNU assembly code, .global or .globl can declare global symbols.
/// Define this macro to unify the usage.
///
#define ASM_GLOBAL .globl
#if defined (__GNUC__) || defined (__clang__)
///
/// For GNU assembly code, .global or .globl can declare global symbols.
/// Define this macro to unify the usage.
///
#define ASM_GLOBAL .globl
#define GCC_ASM_EXPORT(func__) \
#define GCC_ASM_EXPORT(func__) \
.global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
.type ASM_PFX(func__), %function
#define GCC_ASM_IMPORT(func__) \
#define GCC_ASM_IMPORT(func__) \
.extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
#endif
@ -147,7 +200,7 @@ typedef INT64 INTN;
@return The pointer to the first instruction of a function given a function pointer.
**/
#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__

View File

@ -1,22 +1,16 @@
/** @file
Processor or Compiler specific defines and types for ARM.
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __PROCESSOR_BIND_H__
#define __PROCESSOR_BIND_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
///
/// Define the processor type so other code can make processor based choices
@ -26,61 +20,110 @@ FILE_LICENCE ( BSD3 );
//
// Make sure we are using the correct packing rules per EFI specification
//
#ifndef __GNUC__
#pragma pack()
#if !defined (__GNUC__) && !defined (__ASSEMBLER__)
#pragma pack()
#endif
#if defined (_MSC_EXTENSIONS)
//
// Disable some level 4 compilation warnings (same as IA32 and X64)
//
//
// Disabling bitfield type checking warnings.
//
#pragma warning ( disable : 4214 )
//
// Disabling the unreferenced formal parameter warnings.
//
#pragma warning ( disable : 4100 )
//
// Disable slightly different base types warning as CHAR8 * can not be set
// to a constant string.
//
#pragma warning ( disable : 4057 )
//
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
//
#pragma warning ( disable : 4127 )
//
// This warning is caused by functions defined but not used. For precompiled header only.
//
#pragma warning ( disable : 4505 )
//
// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
//
#pragma warning ( disable : 4206 )
//
// Disable 'potentially uninitialized local variable X used' warnings
//
#pragma warning ( disable : 4701 )
//
// Disable 'potentially uninitialized local pointer variable X used' warnings
//
#pragma warning ( disable : 4703 )
#endif
//
// RVCT does not support the __builtin_unreachable() macro
// MSFT doesn't support the __builtin_unreachable() macro
//
#ifdef __ARMCC_VERSION
#if defined (_MSC_EXTENSIONS)
#define UNREACHABLE()
#endif
#if _MSC_EXTENSIONS
//
// use Microsoft* C compiler dependent integer width types
//
typedef unsigned __int64 UINT64;
typedef __int64 INT64;
typedef unsigned __int32 UINT32;
typedef __int32 INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
#if defined (_MSC_EXTENSIONS)
//
// use Microsoft* C compiler dependent integer width types
//
typedef unsigned __int64 UINT64;
typedef __int64 INT64;
typedef unsigned __int32 UINT32;
typedef __int32 INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
#else
//
// Assume standard ARM alignment.
// Need to check portability of long long
//
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned int UINT32;
typedef int INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
//
// Assume standard ARM alignment.
// Need to check portability of long long
//
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned int UINT32;
typedef int INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
#endif
///
/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions,
/// 8 bytes on supported 64-bit processor instructions)
///
typedef UINT32 UINTN;
typedef UINT32 UINTN;
///
/// Signed value of native width. (4 bytes on supported 32-bit processor instructions,
/// 8 bytes on supported 64-bit processor instructions)
///
typedef INT32 INTN;
typedef INT32 INTN;
//
// Processor specific defines
@ -89,24 +132,34 @@ typedef INT32 INTN;
///
/// A value of native width with the highest bit set.
///
#define MAX_BIT 0x80000000
#define MAX_BIT 0x80000000
///
/// A value of native width with the two highest bits set.
///
#define MAX_2_BITS 0xC0000000
#define MAX_2_BITS 0xC0000000
///
/// Maximum legal ARM address
///
#define MAX_ADDRESS 0xFFFFFFFF
///
/// Maximum usable address at boot time
///
#define MAX_ALLOC_ADDRESS MAX_ADDRESS
///
/// Maximum legal ARM INTN and UINTN values.
///
#define MAX_INTN ((INTN)0x7FFFFFFF)
#define MAX_UINTN ((UINTN)0xFFFFFFFF)
///
/// Minimum legal ARM INTN value.
///
#define MIN_INTN (((INTN)-2147483647) - 1)
///
/// The stack alignment required for ARM
///
@ -115,8 +168,8 @@ typedef INT32 INTN;
///
/// Page allocation granularity for ARM
///
#define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x1000)
//
// Modifier to ensure that all protocol member functions and EFI intrinsics
@ -127,40 +180,45 @@ typedef INT32 INTN;
// When compiling with Clang, we still use GNU as for the assembler, so we still
// need to define the GCC_ASM* macros.
#if defined(__GNUC__) || defined(__clang__)
///
/// For GNU assembly code, .global or .globl can declare global symbols.
/// Define this macro to unify the usage.
///
#define ASM_GLOBAL .globl
#if defined (__GNUC__) || defined (__clang__)
///
/// For GNU assembly code, .global or .globl can declare global symbols.
/// Define this macro to unify the usage.
///
#define ASM_GLOBAL .globl
#if !defined(__APPLE__)
///
/// ARM EABI defines that the linker should not manipulate call relocations
/// (do bl/blx conversion) unless the target symbol has function type.
/// CodeSourcery 2010.09 started requiring the .type to function properly
///
#define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function
#if !defined (__APPLE__)
///
/// ARM EABI defines that the linker should not manipulate call relocations
/// (do bl/blx conversion) unless the target symbol has function type.
/// CodeSourcery 2010.09 started requiring the .type to function properly
///
#define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function
#define GCC_ASM_EXPORT(func__) \
#define GCC_ASM_EXPORT(func__) \
.global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
.type ASM_PFX(func__), %function
#define GCC_ASM_IMPORT(func__) \
#define GCC_ASM_IMPORT(func__) \
.extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
#else
//
// .type not supported by Apple Xcode tools
//
#define INTERWORK_FUNC(func__)
//
// .type not supported by Apple Xcode tools
//
#define INTERWORK_FUNC(func__)
#define GCC_ASM_EXPORT(func__) \
#define GCC_ASM_EXPORT(func__) \
.globl _CONCATENATE (__USER_LABEL_PREFIX__, func__) \
#define GCC_ASM_IMPORT(name)
#define GCC_ASM_IMPORT(name)
#endif
#elif defined (_MSC_EXTENSIONS)
//
// PRESERVE8 is not supported by the MSFT assembler.
//
#define PRESERVE8
#endif
/**
@ -173,12 +231,10 @@ typedef INT32 INTN;
@return The pointer to the first instruction of a function given a function pointer.
**/
#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -5,14 +5,8 @@
ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the
ACPI 2.0 Table GUID and ACPI Table GUID.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
GUIDs defined in UEFI 2.0 spec.
@ -22,7 +16,7 @@
#ifndef __ACPI_GUID_H__
#define __ACPI_GUID_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define ACPI_TABLE_GUID \
{ \
@ -34,15 +28,15 @@ FILE_LICENCE ( BSD3 );
0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
}
#define ACPI_10_TABLE_GUID ACPI_TABLE_GUID
#define ACPI_10_TABLE_GUID ACPI_TABLE_GUID
//
// ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID.
//
#define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID
#define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID
extern EFI_GUID gEfiAcpiTableGuid;
extern EFI_GUID gEfiAcpi10TableGuid;
extern EFI_GUID gEfiAcpi20TableGuid;
extern EFI_GUID gEfiAcpiTableGuid;
extern EFI_GUID gEfiAcpi10TableGuid;
extern EFI_GUID gEfiAcpi20TableGuid;
#endif

View File

@ -3,21 +3,15 @@
and EFI_FILE_PROTOCOL.GetInfo() to set or get generic file information.
This GUID is defined in UEFI specification.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __FILE_INFO_H__
#define __FILE_INFO_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define EFI_FILE_INFO_ID \
{ \
@ -28,35 +22,35 @@ typedef struct {
///
/// The size of the EFI_FILE_INFO structure, including the Null-terminated FileName string.
///
UINT64 Size;
UINT64 Size;
///
/// The size of the file in bytes.
///
UINT64 FileSize;
UINT64 FileSize;
///
/// PhysicalSize The amount of physical space the file consumes on the file system volume.
///
UINT64 PhysicalSize;
UINT64 PhysicalSize;
///
/// The time the file was created.
///
EFI_TIME CreateTime;
EFI_TIME CreateTime;
///
/// The time when the file was last accessed.
///
EFI_TIME LastAccessTime;
EFI_TIME LastAccessTime;
///
/// The time when the file's contents were last modified.
///
EFI_TIME ModificationTime;
EFI_TIME ModificationTime;
///
/// The attribute bits for the file.
///
UINT64 Attribute;
UINT64 Attribute;
///
/// The Null-terminated name of the file.
///
CHAR16 FileName[1];
CHAR16 FileName[1];
} EFI_FILE_INFO;
///
@ -66,8 +60,8 @@ typedef struct {
/// computes this size correctly no matter how big the FileName array is declared.
/// This is required to make the EFI_FILE_INFO data structure ANSI compilant.
///
#define SIZE_OF_EFI_FILE_INFO OFFSET_OF (EFI_FILE_INFO, FileName)
#define SIZE_OF_EFI_FILE_INFO OFFSET_OF (EFI_FILE_INFO, FileName)
extern EFI_GUID gEfiFileInfoGuid;
extern EFI_GUID gEfiFileInfoGuid;
#endif

View File

@ -3,21 +3,15 @@
or EFI_FILE_PROTOCOL.SetInfo() to get or set information about the system's volume.
This GUID is defined in UEFI specification.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __FILE_SYSTEM_INFO_H__
#define __FILE_SYSTEM_INFO_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define EFI_FILE_SYSTEM_INFO_ID \
{ \
@ -28,27 +22,27 @@ typedef struct {
///
/// The size of the EFI_FILE_SYSTEM_INFO structure, including the Null-terminated VolumeLabel string.
///
UINT64 Size;
UINT64 Size;
///
/// TRUE if the volume only supports read access.
///
BOOLEAN ReadOnly;
BOOLEAN ReadOnly;
///
/// The number of bytes managed by the file system.
///
UINT64 VolumeSize;
UINT64 VolumeSize;
///
/// The number of available bytes for use by the file system.
///
UINT64 FreeSpace;
UINT64 FreeSpace;
///
/// The nominal block size by which files are typically grown.
///
UINT32 BlockSize;
UINT32 BlockSize;
///
/// The Null-terminated string that is the volume's label.
///
CHAR16 VolumeLabel[1];
CHAR16 VolumeLabel[1];
} EFI_FILE_SYSTEM_INFO;
///
@ -60,6 +54,6 @@ typedef struct {
///
#define SIZE_OF_EFI_FILE_SYSTEM_INFO OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)
extern EFI_GUID gEfiFileSystemInfoGuid;
extern EFI_GUID gEfiFileSystemInfoGuid;
#endif

View File

@ -1,14 +1,8 @@
/** @file
Guid used to identify HII FormMap configuration method.
Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
GUID defined in UEFI 2.2 spec.
@ -17,11 +11,11 @@
#ifndef __EFI_HII_FORMMAP_GUID_H__
#define __EFI_HII_FORMMAP_GUID_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define EFI_HII_STANDARD_FORM_GUID \
{ 0x3bd2f4ec, 0xe524, 0x46e4, { 0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62 } }
extern EFI_GUID gEfiHiiStandardFormGuid;
extern EFI_GUID gEfiHiiStandardFormGuid;
#endif

View File

@ -2,14 +2,8 @@
GUID indicates that the form set contains forms designed to be used
for platform configuration and this form set will be displayed.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
GUID defined in UEFI 2.1.
@ -19,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef __HII_PLATFORM_SETUP_FORMSET_GUID_H__
#define __HII_PLATFORM_SETUP_FORMSET_GUID_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \
{ 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } }
@ -30,8 +24,12 @@ FILE_LICENCE ( BSD3 );
#define EFI_HII_USER_CREDENTIAL_FORMSET_GUID \
{ 0x337f4407, 0x5aee, 0x4b83, { 0xb2, 0xa7, 0x4e, 0xad, 0xca, 0x30, 0x88, 0xcd } }
extern EFI_GUID gEfiHiiPlatformSetupFormsetGuid;
extern EFI_GUID gEfiHiiDriverHealthFormsetGuid;
extern EFI_GUID gEfiHiiUserCredentialFormsetGuid;
#define EFI_HII_REST_STYLE_FORMSET_GUID \
{ 0x790217bd, 0xbecf, 0x485b, { 0x91, 0x70, 0x5f, 0xf7, 0x11, 0x31, 0x8b, 0x27 } }
extern EFI_GUID gEfiHiiPlatformSetupFormsetGuid;
extern EFI_GUID gEfiHiiDriverHealthFormsetGuid;
extern EFI_GUID gEfiHiiUserCredentialFormsetGuid;
extern EFI_GUID gEfiHiiRestStyleFormsetGuid;
#endif

View File

@ -1,25 +1,19 @@
/** @file
EDKII extented HII IFR guid opcodes.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __MDEMODULE_HII_H__
#define __MDEMODULE_HII_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define NARROW_CHAR 0xFFF0
#define WIDE_CHAR 0xFFF1
#define NON_BREAKING_CHAR 0xFFF2
#define NARROW_CHAR 0xFFF0
#define WIDE_CHAR 0xFFF1
#define NON_BREAKING_CHAR 0xFFF2
///
/// State defined for password statemachine .
@ -38,91 +32,91 @@ FILE_LICENCE ( BSD3 );
///
/// EDKII implementation extension opcodes, new extension can be added here later.
///
#define EFI_IFR_EXTEND_OP_LABEL 0x0
#define EFI_IFR_EXTEND_OP_BANNER 0x1
#define EFI_IFR_EXTEND_OP_TIMEOUT 0x2
#define EFI_IFR_EXTEND_OP_CLASS 0x3
#define EFI_IFR_EXTEND_OP_SUBCLASS 0x4
#define EFI_IFR_EXTEND_OP_LABEL 0x0
#define EFI_IFR_EXTEND_OP_BANNER 0x1
#define EFI_IFR_EXTEND_OP_TIMEOUT 0x2
#define EFI_IFR_EXTEND_OP_CLASS 0x3
#define EFI_IFR_EXTEND_OP_SUBCLASS 0x4
///
/// Label opcode.
///
typedef struct _EFI_IFR_GUID_LABEL {
EFI_IFR_OP_HEADER Header;
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_TIANO_GUID.
///
EFI_GUID Guid;
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_LABEL.
///
UINT8 ExtendOpCode;
UINT8 ExtendOpCode;
///
/// Label Number.
///
UINT16 Number;
UINT16 Number;
} EFI_IFR_GUID_LABEL;
#define EFI_IFR_BANNER_ALIGN_LEFT 0
#define EFI_IFR_BANNER_ALIGN_CENTER 1
#define EFI_IFR_BANNER_ALIGN_RIGHT 2
#define EFI_IFR_BANNER_ALIGN_LEFT 0
#define EFI_IFR_BANNER_ALIGN_CENTER 1
#define EFI_IFR_BANNER_ALIGN_RIGHT 2
///
/// Banner opcode.
///
typedef struct _EFI_IFR_GUID_BANNER {
EFI_IFR_OP_HEADER Header;
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_TIANO_GUID.
///
EFI_GUID Guid;
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_BANNER
///
UINT8 ExtendOpCode;
EFI_STRING_ID Title; ///< The string token for the banner title.
UINT16 LineNumber; ///< 1-based line number.
UINT8 Alignment; ///< left, center, or right-aligned.
UINT8 ExtendOpCode;
EFI_STRING_ID Title; ///< The string token for the banner title.
UINT16 LineNumber; ///< 1-based line number.
UINT8 Alignment; ///< left, center, or right-aligned.
} EFI_IFR_GUID_BANNER;
///
/// Timeout opcode.
///
typedef struct _EFI_IFR_GUID_TIMEOUT {
EFI_IFR_OP_HEADER Header;
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_TIANO_GUID.
///
EFI_GUID Guid;
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_TIMEOUT.
///
UINT8 ExtendOpCode;
UINT16 TimeOut; ///< TimeOut Value.
UINT8 ExtendOpCode;
UINT16 TimeOut; ///< TimeOut Value.
} EFI_IFR_GUID_TIMEOUT;
#define EFI_NON_DEVICE_CLASS 0x00
#define EFI_DISK_DEVICE_CLASS 0x01
#define EFI_VIDEO_DEVICE_CLASS 0x02
#define EFI_NETWORK_DEVICE_CLASS 0x04
#define EFI_INPUT_DEVICE_CLASS 0x08
#define EFI_ON_BOARD_DEVICE_CLASS 0x10
#define EFI_OTHER_DEVICE_CLASS 0x20
#define EFI_NON_DEVICE_CLASS 0x00
#define EFI_DISK_DEVICE_CLASS 0x01
#define EFI_VIDEO_DEVICE_CLASS 0x02
#define EFI_NETWORK_DEVICE_CLASS 0x04
#define EFI_INPUT_DEVICE_CLASS 0x08
#define EFI_ON_BOARD_DEVICE_CLASS 0x10
#define EFI_OTHER_DEVICE_CLASS 0x20
///
/// Device Class opcode.
///
typedef struct _EFI_IFR_GUID_CLASS {
EFI_IFR_OP_HEADER Header;
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_TIANO_GUID.
///
EFI_GUID Guid;
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_CLASS.
///
UINT8 ExtendOpCode;
UINT16 Class; ///< Device Class from the above.
UINT8 ExtendOpCode;
UINT16 Class; ///< Device Class from the above.
} EFI_IFR_GUID_CLASS;
#define EFI_SETUP_APPLICATION_SUBCLASS 0x00
@ -134,16 +128,16 @@ typedef struct _EFI_IFR_GUID_CLASS {
/// SubClass opcode
///
typedef struct _EFI_IFR_GUID_SUBCLASS {
EFI_IFR_OP_HEADER Header;
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_TIANO_GUID.
///
EFI_GUID Guid;
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_SUBCLASS.
///
UINT8 ExtendOpCode;
UINT16 SubClass; ///< Sub Class type from the above.
UINT8 ExtendOpCode;
UINT16 SubClass; ///< Sub Class type from the above.
} EFI_IFR_GUID_SUBCLASS;
///
@ -157,66 +151,83 @@ typedef struct _EFI_IFR_GUID_SUBCLASS {
/// One is for framework OneOf question Option Key value;
/// another is for framework vareqval.
///
#define EFI_IFR_EXTEND_OP_OPTIONKEY 0x0
#define EFI_IFR_EXTEND_OP_VAREQNAME 0x1
#define EFI_IFR_EXTEND_OP_OPTIONKEY 0x0
#define EFI_IFR_EXTEND_OP_VAREQNAME 0x1
///
/// Store the framework vfr option key value.
///
typedef struct _EFI_IFR_GUID_OPTIONKEY {
EFI_IFR_OP_HEADER Header;
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_FRAMEWORK_GUID.
///
EFI_GUID Guid;
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_OPTIONKEY.
///
UINT8 ExtendOpCode;
UINT8 ExtendOpCode;
///
/// OneOf Questiond ID binded by OneOf Option.
///
EFI_QUESTION_ID QuestionId;
EFI_QUESTION_ID QuestionId;
///
/// The OneOf Option Value.
///
EFI_IFR_TYPE_VALUE OptionValue;
EFI_IFR_TYPE_VALUE OptionValue;
///
/// The Framework OneOf Option Key Value.
///
UINT16 KeyValue;
UINT16 KeyValue;
} EFI_IFR_GUID_OPTIONKEY;
///
/// Store the framework vfr vareqval name number.
///
typedef struct _EFI_IFR_GUID_VAREQNAME {
EFI_IFR_OP_HEADER Header;
EFI_IFR_OP_HEADER Header;
///
/// EFI_IFR_FRAMEWORK_GUID.
///
EFI_GUID Guid;
EFI_GUID Guid;
///
/// EFI_IFR_EXTEND_OP_VAREQNAME.
///
UINT8 ExtendOpCode;
UINT8 ExtendOpCode;
///
/// Question ID of the Numeric Opcode created.
///
EFI_QUESTION_ID QuestionId;
EFI_QUESTION_ID QuestionId;
///
/// For vareqval (0x100), NameId is 0x100.
/// This value will convert to a Unicode String following this rule;
/// sprintf(StringBuffer, "%d", NameId) .
/// The the Unicode String will be used as a EFI Variable Name.
///
UINT16 NameId;
UINT16 NameId;
} EFI_IFR_GUID_VAREQNAME;
///
/// EDKII implementation extension GUID, used to indaicate there are bit fields in the varstore.
///
#define EDKII_IFR_BIT_VARSTORE_GUID \
{0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60,0xA7, 0x1D}}
///
/// EDKII implementation extension flags, used to indaicate the disply style and bit width for bit filed storage.
/// Two high bits for display style and the low six bits for bit width.
///
#define EDKII_IFR_DISPLAY_BIT 0xC0
#define EDKII_IFR_DISPLAY_INT_DEC_BIT 0x00
#define EDKII_IFR_DISPLAY_UINT_DEC_BIT 0x40
#define EDKII_IFR_DISPLAY_UINT_HEX_BIT 0x80
#define EDKII_IFR_NUMERIC_SIZE_BIT 0x3F
#pragma pack()
extern EFI_GUID gEfiIfrTianoGuid;
extern EFI_GUID gEfiIfrFrameworkGuid;
extern EFI_GUID gEfiIfrTianoGuid;
extern EFI_GUID gEfiIfrFrameworkGuid;
extern EFI_GUID gEdkiiIfrBitVarstoreGuid;
#endif

View File

@ -1,14 +1,8 @@
/** @file
Terminal Device Path Vendor Guid.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
GUIDs defined in UEFI 2.0 spec.
@ -18,7 +12,7 @@
#ifndef __PC_ANSI_H__
#define __PC_ANSI_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define EFI_PC_ANSI_GUID \
{ \
@ -50,11 +44,11 @@ FILE_LICENCE ( BSD3 );
0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \
}
extern EFI_GUID gEfiPcAnsiGuid;
extern EFI_GUID gEfiVT100Guid;
extern EFI_GUID gEfiVT100PlusGuid;
extern EFI_GUID gEfiVTUTF8Guid;
extern EFI_GUID gEfiUartDevicePathGuid;
extern EFI_GUID gEfiSasDevicePathGuid;
extern EFI_GUID gEfiPcAnsiGuid;
extern EFI_GUID gEfiVT100Guid;
extern EFI_GUID gEfiVT100PlusGuid;
extern EFI_GUID gEfiVTUTF8Guid;
extern EFI_GUID gEfiUartDevicePathGuid;
extern EFI_GUID gEfiSasDevicePathGuid;
#endif

View File

@ -5,14 +5,8 @@
locate the SMBIOS tables. Do not search the 0xF0000 segment to find SMBIOS
tables.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
GUIDs defined in UEFI 2.5 spec.
@ -22,7 +16,7 @@
#ifndef __SMBIOS_GUID_H__
#define __SMBIOS_GUID_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#define SMBIOS_TABLE_GUID \
{ \
@ -34,7 +28,7 @@ FILE_LICENCE ( BSD3 );
0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } \
}
extern EFI_GUID gEfiSmbiosTableGuid;
extern EFI_GUID gEfiSmbios3TableGuid;
extern EFI_GUID gEfiSmbiosTableGuid;
extern EFI_GUID gEfiSmbios3TableGuid;
#endif

View File

@ -2,13 +2,7 @@
GUID for UEFI WIN_CERTIFICATE structure.
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Revision Reference:
GUID defined in UEFI 2.0 spec.
@ -17,14 +11,14 @@
#ifndef __EFI_WIN_CERTIFICATE_H__
#define __EFI_WIN_CERTIFICATE_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
//
// _WIN_CERTIFICATE.wCertificateType
//
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
#define WIN_CERT_TYPE_EFI_PKCS115 0x0EF0
#define WIN_CERT_TYPE_EFI_GUID 0x0EF1
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
#define WIN_CERT_TYPE_EFI_PKCS115 0x0EF0
#define WIN_CERT_TYPE_EFI_GUID 0x0EF1
///
/// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
@ -34,18 +28,18 @@ typedef struct {
/// The length of the entire certificate,
/// including the length of the header, in bytes.
///
UINT32 dwLength;
UINT32 dwLength;
///
/// The revision level of the WIN_CERTIFICATE
/// structure. The current revision level is 0x0200.
///
UINT16 wRevision;
UINT16 wRevision;
///
/// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI
/// certificate types. The UEFI specification reserves the range of
/// certificate type values from 0x0EF0 to 0x0EFF.
///
UINT16 wCertificateType;
UINT16 wCertificateType;
///
/// The following is the actual certificate. The format of
/// the certificate depends on wCertificateType.
@ -64,12 +58,11 @@ typedef struct {
/// WIN_CERTIFICATE_UEFI_GUID.CertData
///
typedef struct {
EFI_GUID HashType;
UINT8 PublicKey[256];
UINT8 Signature[256];
EFI_GUID HashType;
UINT8 PublicKey[256];
UINT8 Signature[256];
} EFI_CERT_BLOCK_RSA_2048_SHA256;
///
/// Certificate which encapsulates a GUID-specific digital signature
///
@ -78,22 +71,21 @@ typedef struct {
/// This is the standard WIN_CERTIFICATE header, where
/// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.
///
WIN_CERTIFICATE Hdr;
WIN_CERTIFICATE Hdr;
///
/// This is the unique id which determines the
/// format of the CertData. .
///
EFI_GUID CertType;
EFI_GUID CertType;
///
/// The following is the certificate data. The format of
/// the data is determined by the CertType.
/// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
/// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
///
UINT8 CertData[1];
UINT8 CertData[1];
} WIN_CERTIFICATE_UEFI_GUID;
///
/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
///
@ -107,12 +99,12 @@ typedef struct {
/// This is the standard WIN_CERTIFICATE header, where
/// wCertificateType is set to WIN_CERT_TYPE_UEFI_PKCS1_15.
///
WIN_CERTIFICATE Hdr;
WIN_CERTIFICATE Hdr;
///
/// This is the hashing algorithm which was performed on the
/// UEFI executable when creating the digital signature.
///
EFI_GUID HashAlgorithm;
EFI_GUID HashAlgorithm;
///
/// The following is the actual digital signature. The
/// size of the signature is the same size as the key
@ -125,6 +117,6 @@ typedef struct {
///
} WIN_CERTIFICATE_EFI_PKCS1_15;
extern EFI_GUID gEfiCertTypeRsa2048Sha256Guid;
extern EFI_GUID gEfiCertTypeRsa2048Sha256Guid;
#endif

View File

@ -1,21 +1,15 @@
/** @file
Processor or Compiler specific defines and types for IA-32 architecture.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __PROCESSOR_BIND_H__
#define __PROCESSOR_BIND_H__
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
///
/// Define the processor type so other code can make processor based choices.
@ -25,39 +19,38 @@ FILE_LICENCE ( BSD3 );
//
// Make sure we are using the correct packing rules per EFI specification
//
#if !defined(__GNUC__)
#pragma pack()
#if !defined (__GNUC__)
#pragma pack()
#endif
#if defined(__INTEL_COMPILER)
#if defined (__INTEL_COMPILER)
//
// Disable ICC's remark #869: "Parameter" was never referenced warning.
// This is legal ANSI C code so we disable the remark that is turned on with -Wall
//
#pragma warning ( disable : 869 )
#pragma warning ( disable : 869 )
//
// Disable ICC's remark #1418: external function definition with no prior declaration.
// This is legal ANSI C code so we disable the remark that is turned on with /W4
//
#pragma warning ( disable : 1418 )
#pragma warning ( disable : 1418 )
//
// Disable ICC's remark #1419: external declaration in primary source file
// This is legal ANSI C code so we disable the remark that is turned on with /W4
//
#pragma warning ( disable : 1419 )
#pragma warning ( disable : 1419 )
//
// Disable ICC's remark #593: "Variable" was set but never used.
// This is legal ANSI C code so we disable the remark that is turned on with /W4
//
#pragma warning ( disable : 593 )
#pragma warning ( disable : 593 )
#endif
#if defined(_MSC_EXTENSIONS)
#if defined (_MSC_EXTENSIONS)
//
// Disable warning that make it impossible to compile at /W4
@ -67,35 +60,35 @@ FILE_LICENCE ( BSD3 );
//
// Disabling bitfield type checking warnings.
//
#pragma warning ( disable : 4214 )
#pragma warning ( disable : 4214 )
//
// Disabling the unreferenced formal parameter warnings.
//
#pragma warning ( disable : 4100 )
#pragma warning ( disable : 4100 )
//
// Disable slightly different base types warning as CHAR8 * can not be set
// to a constant string.
//
#pragma warning ( disable : 4057 )
#pragma warning ( disable : 4057 )
//
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
//
#pragma warning ( disable : 4127 )
#pragma warning ( disable : 4127 )
//
// This warning is caused by functions defined but not used. For precompiled header only.
//
#pragma warning ( disable : 4505 )
#pragma warning ( disable : 4505 )
//
// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
//
#pragma warning ( disable : 4206 )
#pragma warning ( disable : 4206 )
#if _MSC_VER == 1800 || _MSC_VER == 1900
#if defined (_MSC_VER) && _MSC_VER >= 1800
//
// Disable these warnings for VS2013.
@ -105,130 +98,129 @@ FILE_LICENCE ( BSD3 );
// This warning is for potentially uninitialized local variable, and it may cause false
// positive issues in VS2013 and VS2015 build
//
#pragma warning ( disable : 4701 )
#pragma warning ( disable : 4701 )
//
// This warning is for potentially uninitialized local pointer variable, and it may cause
// false positive issues in VS2013 and VS2015 build
//
#pragma warning ( disable : 4703 )
#pragma warning ( disable : 4703 )
#endif
#endif
#endif
#if defined (_MSC_EXTENSIONS)
//
// use Microsoft C compiler dependent integer width types
//
#if defined(_MSC_EXTENSIONS)
//
// use Microsoft C compiler dependent integer width types
//
///
/// 8-byte unsigned value.
///
typedef unsigned __int64 UINT64;
///
/// 8-byte signed value.
///
typedef __int64 INT64;
///
/// 4-byte unsigned value.
///
typedef unsigned __int32 UINT32;
///
/// 4-byte signed value.
///
typedef __int32 INT32;
///
/// 2-byte unsigned value.
///
typedef unsigned short UINT16;
///
/// 2-byte Character. Unless otherwise specified all strings are stored in the
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
///
typedef unsigned short CHAR16;
///
/// 2-byte signed value.
///
typedef short INT16;
///
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
/// values are undefined.
///
typedef unsigned char BOOLEAN;
///
/// 1-byte unsigned value.
///
typedef unsigned char UINT8;
///
/// 1-byte Character.
///
typedef char CHAR8;
///
/// 1-byte signed value.
///
typedef signed char INT8;
///
/// 8-byte unsigned value.
///
typedef unsigned __int64 UINT64;
///
/// 8-byte signed value.
///
typedef __int64 INT64;
///
/// 4-byte unsigned value.
///
typedef unsigned __int32 UINT32;
///
/// 4-byte signed value.
///
typedef __int32 INT32;
///
/// 2-byte unsigned value.
///
typedef unsigned short UINT16;
///
/// 2-byte Character. Unless otherwise specified all strings are stored in the
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
///
typedef unsigned short CHAR16;
///
/// 2-byte signed value.
///
typedef short INT16;
///
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
/// values are undefined.
///
typedef unsigned char BOOLEAN;
///
/// 1-byte unsigned value.
///
typedef unsigned char UINT8;
///
/// 1-byte Character.
///
typedef char CHAR8;
///
/// 1-byte signed value.
///
typedef signed char INT8;
#else
///
/// 8-byte unsigned value.
///
typedef unsigned long long UINT64;
///
/// 8-byte signed value.
///
typedef long long INT64;
///
/// 4-byte unsigned value.
///
typedef unsigned int UINT32;
///
/// 4-byte signed value.
///
typedef int INT32;
///
/// 2-byte unsigned value.
///
typedef unsigned short UINT16;
///
/// 2-byte Character. Unless otherwise specified all strings are stored in the
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
///
typedef unsigned short CHAR16;
///
/// 2-byte signed value.
///
typedef short INT16;
///
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
/// values are undefined.
///
typedef unsigned char BOOLEAN;
///
/// 1-byte unsigned value.
///
typedef unsigned char UINT8;
///
/// 1-byte Character
///
typedef char CHAR8;
///
/// 1-byte signed value
///
typedef signed char INT8;
///
/// 8-byte unsigned value.
///
typedef unsigned long long UINT64;
///
/// 8-byte signed value.
///
typedef long long INT64;
///
/// 4-byte unsigned value.
///
typedef unsigned int UINT32;
///
/// 4-byte signed value.
///
typedef int INT32;
///
/// 2-byte unsigned value.
///
typedef unsigned short UINT16;
///
/// 2-byte Character. Unless otherwise specified all strings are stored in the
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
///
typedef unsigned short CHAR16;
///
/// 2-byte signed value.
///
typedef short INT16;
///
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
/// values are undefined.
///
typedef unsigned char BOOLEAN;
///
/// 1-byte unsigned value.
///
typedef unsigned char UINT8;
///
/// 1-byte Character
///
typedef char CHAR8;
///
/// 1-byte signed value
///
typedef signed char INT8;
#endif
///
/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions;
/// 8 bytes on supported 64-bit processor instructions.)
///
typedef UINT32 UINTN;
typedef UINT32 UINTN;
///
/// Signed value of native width. (4 bytes on supported 32-bit processor instructions;
/// 8 bytes on supported 64-bit processor instructions.)
///
typedef INT32 INTN;
typedef INT32 INTN;
//
// Processor specific defines
@ -237,7 +229,7 @@ typedef INT32 INTN;
///
/// A value of native width with the highest bit set.
///
#define MAX_BIT 0x80000000
#define MAX_BIT 0x80000000
///
/// A value of native width with the two highest bits set.
///
@ -246,7 +238,12 @@ typedef INT32 INTN;
///
/// Maximum legal IA-32 address.
///
#define MAX_ADDRESS 0xFFFFFFFF
#define MAX_ADDRESS 0xFFFFFFFF
///
/// Maximum usable address at boot time
///
#define MAX_ALLOC_ADDRESS MAX_ADDRESS
///
/// Maximum legal IA-32 INTN and UINTN values.
@ -254,16 +251,21 @@ typedef INT32 INTN;
#define MAX_INTN ((INTN)0x7FFFFFFF)
#define MAX_UINTN ((UINTN)0xFFFFFFFF)
///
/// Minimum legal IA-32 INTN value.
///
#define MIN_INTN (((INTN)-2147483647) - 1)
///
/// The stack alignment required for IA-32.
///
#define CPU_STACK_ALIGNMENT sizeof(UINTN)
#define CPU_STACK_ALIGNMENT sizeof(UINTN)
///
/// Page allocation granularity for IA-32.
///
#define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000)
#define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x1000)
//
// Modifier to ensure that all protocol member functions and EFI intrinsics
@ -271,33 +273,33 @@ typedef INT32 INTN;
// EFI intrinsics are required to modify their member functions with EFIAPI.
//
#ifdef EFIAPI
///
/// If EFIAPI is already defined, then we use that definition.
///
#elif defined(_MSC_EXTENSIONS)
///
/// Microsoft* compiler specific method for EFIAPI calling convention.
///
#define EFIAPI __cdecl
#elif defined(__GNUC__)
///
/// GCC specific method for EFIAPI calling convention.
///
#define EFIAPI __attribute__((cdecl))
///
/// If EFIAPI is already defined, then we use that definition.
///
#elif defined (_MSC_EXTENSIONS)
///
/// Microsoft* compiler specific method for EFIAPI calling convention.
///
#define EFIAPI __cdecl
#elif defined (__GNUC__) || defined (__clang__)
///
/// GCC specific method for EFIAPI calling convention.
///
#define EFIAPI __attribute__((cdecl))
#else
///
/// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI
/// is the standard.
///
#define EFIAPI
///
/// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI
/// is the standard.
///
#define EFIAPI
#endif
#if defined(__GNUC__)
///
/// For GNU assembly code, .global or .globl can declare global symbols.
/// Define this macro to unify the usage.
///
#define ASM_GLOBAL .globl
#if defined (__GNUC__) || defined (__clang__)
///
/// For GNU assembly code, .global or .globl can declare global symbols.
/// Define this macro to unify the usage.
///
#define ASM_GLOBAL .globl
#endif
/**
@ -310,11 +312,10 @@ typedef INT32 INTN;
@return The pointer to the first instruction of a function given a function pointer.
**/
#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#define __USER_LABEL_PREFIX__ _
#endif
#endif

View File

@ -1,20 +1,15 @@
/** @file
ACPI 1.0b definitions from the ACPI Specification, revision 1.0b
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _ACPI_1_0_H_
#define _ACPI_1_0_H_
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#include <ipxe/efi/IndustryStandard/AcpiAml.h>
@ -23,8 +18,8 @@ FILE_LICENCE ( BSD3 );
/// excluding the RSD PTR structure.
///
typedef struct {
UINT32 Signature;
UINT32 Length;
UINT32 Signature;
UINT32 Length;
} EFI_ACPI_COMMON_HEADER;
#pragma pack(1)
@ -32,84 +27,84 @@ typedef struct {
/// The common ACPI description table header. This structure prefaces most ACPI tables.
///
typedef struct {
UINT32 Signature;
UINT32 Length;
UINT8 Revision;
UINT8 Checksum;
UINT8 OemId[6];
UINT64 OemTableId;
UINT32 OemRevision;
UINT32 CreatorId;
UINT32 CreatorRevision;
UINT32 Signature;
UINT32 Length;
UINT8 Revision;
UINT8 Checksum;
UINT8 OemId[6];
UINT64 OemTableId;
UINT32 OemRevision;
UINT32 CreatorId;
UINT32 CreatorRevision;
} EFI_ACPI_DESCRIPTION_HEADER;
#pragma pack()
//
// Define for Desriptor
// Define for Descriptor
//
#define ACPI_SMALL_ITEM_FLAG 0x00
#define ACPI_LARGE_ITEM_FLAG 0x01
#define ACPI_SMALL_ITEM_FLAG 0x00
#define ACPI_LARGE_ITEM_FLAG 0x01
//
// Small Item Descriptor Name
//
#define ACPI_SMALL_IRQ_DESCRIPTOR_NAME 0x04
#define ACPI_SMALL_DMA_DESCRIPTOR_NAME 0x05
#define ACPI_SMALL_START_DEPENDENT_DESCRIPTOR_NAME 0x06
#define ACPI_SMALL_END_DEPENDENT_DESCRIPTOR_NAME 0x07
#define ACPI_SMALL_IO_PORT_DESCRIPTOR_NAME 0x08
#define ACPI_SMALL_FIXED_IO_PORT_DESCRIPTOR_NAME 0x09
#define ACPI_SMALL_VENDOR_DEFINED_DESCRIPTOR_NAME 0x0E
#define ACPI_SMALL_END_TAG_DESCRIPTOR_NAME 0x0F
#define ACPI_SMALL_IRQ_DESCRIPTOR_NAME 0x04
#define ACPI_SMALL_DMA_DESCRIPTOR_NAME 0x05
#define ACPI_SMALL_START_DEPENDENT_DESCRIPTOR_NAME 0x06
#define ACPI_SMALL_END_DEPENDENT_DESCRIPTOR_NAME 0x07
#define ACPI_SMALL_IO_PORT_DESCRIPTOR_NAME 0x08
#define ACPI_SMALL_FIXED_IO_PORT_DESCRIPTOR_NAME 0x09
#define ACPI_SMALL_VENDOR_DEFINED_DESCRIPTOR_NAME 0x0E
#define ACPI_SMALL_END_TAG_DESCRIPTOR_NAME 0x0F
//
// Large Item Descriptor Name
//
#define ACPI_LARGE_24_BIT_MEMORY_RANGE_DESCRIPTOR_NAME 0x01
#define ACPI_LARGE_VENDOR_DEFINED_DESCRIPTOR_NAME 0x04
#define ACPI_LARGE_32_BIT_MEMORY_RANGE_DESCRIPTOR_NAME 0x05
#define ACPI_LARGE_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR_NAME 0x06
#define ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x07
#define ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x08
#define ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME 0x09
#define ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x0A
#define ACPI_LARGE_24_BIT_MEMORY_RANGE_DESCRIPTOR_NAME 0x01
#define ACPI_LARGE_VENDOR_DEFINED_DESCRIPTOR_NAME 0x04
#define ACPI_LARGE_32_BIT_MEMORY_RANGE_DESCRIPTOR_NAME 0x05
#define ACPI_LARGE_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR_NAME 0x06
#define ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x07
#define ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x08
#define ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME 0x09
#define ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x0A
//
// Small Item Descriptor Value
//
#define ACPI_IRQ_NOFLAG_DESCRIPTOR 0x22
#define ACPI_IRQ_DESCRIPTOR 0x23
#define ACPI_DMA_DESCRIPTOR 0x2A
#define ACPI_START_DEPENDENT_DESCRIPTOR 0x30
#define ACPI_START_DEPENDENT_EX_DESCRIPTOR 0x31
#define ACPI_END_DEPENDENT_DESCRIPTOR 0x38
#define ACPI_IO_PORT_DESCRIPTOR 0x47
#define ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR 0x4B
#define ACPI_END_TAG_DESCRIPTOR 0x79
#define ACPI_IRQ_NOFLAG_DESCRIPTOR 0x22
#define ACPI_IRQ_DESCRIPTOR 0x23
#define ACPI_DMA_DESCRIPTOR 0x2A
#define ACPI_START_DEPENDENT_DESCRIPTOR 0x30
#define ACPI_START_DEPENDENT_EX_DESCRIPTOR 0x31
#define ACPI_END_DEPENDENT_DESCRIPTOR 0x38
#define ACPI_IO_PORT_DESCRIPTOR 0x47
#define ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR 0x4B
#define ACPI_END_TAG_DESCRIPTOR 0x79
//
// Large Item Descriptor Value
//
#define ACPI_24_BIT_MEMORY_RANGE_DESCRIPTOR 0x81
#define ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR 0x85
#define ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR 0x86
#define ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR 0x87
#define ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR 0x88
#define ACPI_EXTENDED_INTERRUPT_DESCRIPTOR 0x89
#define ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR 0x8A
#define ACPI_ADDRESS_SPACE_DESCRIPTOR 0x8A
#define ACPI_24_BIT_MEMORY_RANGE_DESCRIPTOR 0x81
#define ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR 0x85
#define ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR 0x86
#define ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR 0x87
#define ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR 0x88
#define ACPI_EXTENDED_INTERRUPT_DESCRIPTOR 0x89
#define ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR 0x8A
#define ACPI_ADDRESS_SPACE_DESCRIPTOR 0x8A
//
// Resource Type
//
#define ACPI_ADDRESS_SPACE_TYPE_MEM 0x00
#define ACPI_ADDRESS_SPACE_TYPE_IO 0x01
#define ACPI_ADDRESS_SPACE_TYPE_BUS 0x02
#define ACPI_ADDRESS_SPACE_TYPE_MEM 0x00
#define ACPI_ADDRESS_SPACE_TYPE_IO 0x01
#define ACPI_ADDRESS_SPACE_TYPE_BUS 0x02
///
/// Power Management Timer frequency is fixed at 3.579545MHz.
///
#define ACPI_TIMER_FREQUENCY 3579545
#define ACPI_TIMER_FREQUENCY 3579545
//
// Ensure proper structure formats
@ -117,87 +112,87 @@ typedef struct {
#pragma pack(1)
///
/// The commond definition of QWORD, DWORD, and WORD
/// The common definition of QWORD, DWORD, and WORD
/// Address Space Descriptors.
///
typedef PACKED struct {
UINT8 Desc;
UINT16 Len;
UINT8 ResType;
UINT8 GenFlag;
UINT8 SpecificFlag;
UINT64 AddrSpaceGranularity;
UINT64 AddrRangeMin;
UINT64 AddrRangeMax;
UINT64 AddrTranslationOffset;
UINT64 AddrLen;
UINT8 Desc;
UINT16 Len;
UINT8 ResType;
UINT8 GenFlag;
UINT8 SpecificFlag;
UINT64 AddrSpaceGranularity;
UINT64 AddrRangeMin;
UINT64 AddrRangeMax;
UINT64 AddrTranslationOffset;
UINT64 AddrLen;
} EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;
typedef PACKED union {
UINT8 Byte;
UINT8 Byte;
PACKED struct {
UINT8 Length : 3;
UINT8 Name : 4;
UINT8 Type : 1;
UINT8 Length : 3;
UINT8 Name : 4;
UINT8 Type : 1;
} Bits;
} ACPI_SMALL_RESOURCE_HEADER;
typedef PACKED struct {
PACKED union {
UINT8 Byte;
UINT8 Byte;
PACKED struct {
UINT8 Name : 7;
UINT8 Type : 1;
}Bits;
UINT8 Name : 7;
UINT8 Type : 1;
} Bits;
} Header;
UINT16 Length;
UINT16 Length;
} ACPI_LARGE_RESOURCE_HEADER;
///
/// IRQ Descriptor.
///
typedef PACKED struct {
ACPI_SMALL_RESOURCE_HEADER Header;
UINT16 Mask;
ACPI_SMALL_RESOURCE_HEADER Header;
UINT16 Mask;
} EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR;
///
/// IRQ Descriptor.
///
typedef PACKED struct {
ACPI_SMALL_RESOURCE_HEADER Header;
UINT16 Mask;
UINT8 Information;
ACPI_SMALL_RESOURCE_HEADER Header;
UINT16 Mask;
UINT8 Information;
} EFI_ACPI_IRQ_DESCRIPTOR;
///
/// DMA Descriptor.
///
typedef PACKED struct {
ACPI_SMALL_RESOURCE_HEADER Header;
UINT8 ChannelMask;
UINT8 Information;
ACPI_SMALL_RESOURCE_HEADER Header;
UINT8 ChannelMask;
UINT8 Information;
} EFI_ACPI_DMA_DESCRIPTOR;
///
/// I/O Port Descriptor
///
typedef PACKED struct {
ACPI_SMALL_RESOURCE_HEADER Header;
UINT8 Information;
UINT16 BaseAddressMin;
UINT16 BaseAddressMax;
UINT8 Alignment;
UINT8 Length;
ACPI_SMALL_RESOURCE_HEADER Header;
UINT8 Information;
UINT16 BaseAddressMin;
UINT16 BaseAddressMax;
UINT8 Alignment;
UINT8 Length;
} EFI_ACPI_IO_PORT_DESCRIPTOR;
///
/// Fixed Location I/O Port Descriptor.
///
typedef PACKED struct {
ACPI_SMALL_RESOURCE_HEADER Header;
UINT16 BaseAddress;
UINT8 Length;
ACPI_SMALL_RESOURCE_HEADER Header;
UINT16 BaseAddress;
UINT8 Length;
} EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR;
///
@ -295,17 +290,17 @@ typedef PACKED struct {
/// The End tag identifies an end of resource data.
///
typedef struct {
UINT8 Desc;
UINT8 Checksum;
UINT8 Desc;
UINT8 Checksum;
} EFI_ACPI_END_TAG_DESCRIPTOR;
//
// General use definitions
//
#define EFI_ACPI_RESERVED_BYTE 0x00
#define EFI_ACPI_RESERVED_WORD 0x0000
#define EFI_ACPI_RESERVED_DWORD 0x00000000
#define EFI_ACPI_RESERVED_QWORD 0x0000000000000000
#define EFI_ACPI_RESERVED_BYTE 0x00
#define EFI_ACPI_RESERVED_WORD 0x0000
#define EFI_ACPI_RESERVED_DWORD 0x00000000
#define EFI_ACPI_RESERVED_QWORD 0x0000000000000000
//
// Resource Type Specific Flags
@ -313,76 +308,86 @@ typedef struct {
//
// Bit [0] : Write Status, _RW
//
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_WRITE (1 << 0)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_ONLY (0 << 0)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_WRITE (1 << 0)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_ONLY (0 << 0)
//
// Bit [2:1] : Memory Attributes, _MEM
//
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_NON_CACHEABLE (0 << 1)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE (1 << 1)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_WRITE_COMBINING (2 << 1)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE (3 << 1)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_NON_CACHEABLE (0 << 1)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE (1 << 1)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_WRITE_COMBINING (2 << 1)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE (3 << 1)
//
// Bit [4:3] : Memory Attributes, _MTP
//
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_MEMORY (0 << 3)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_RESERVED (1 << 3)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_ACPI (2 << 3)
#define EFI_APCI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_NVS (3 << 3)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_MEMORY (0 << 3)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_RESERVED (1 << 3)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_ACPI (2 << 3)
#define EFI_APCI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_NVS (3 << 3)
//
// Bit [5] : Memory to I/O Translation, _TTP
//
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_TRANSLATION (1 << 5)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_STATIC (0 << 5)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_TRANSLATION (1 << 5)
#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_STATIC (0 << 5)
//
// IRQ Information
// Ref ACPI specification 6.4.2.1
//
#define EFI_ACPI_IRQ_SHARABLE_MASK 0x10
#define EFI_ACPI_IRQ_SHARABLE 0x10
#define EFI_ACPI_IRQ_SHARABLE_MASK 0x10
#define EFI_ACPI_IRQ_SHARABLE 0x10
#define EFI_ACPI_IRQ_POLARITY_MASK 0x08
#define EFI_ACPI_IRQ_HIGH_TRUE 0x00
#define EFI_ACPI_IRQ_LOW_FALSE 0x08
#define EFI_ACPI_IRQ_POLARITY_MASK 0x08
#define EFI_ACPI_IRQ_HIGH_TRUE 0x00
#define EFI_ACPI_IRQ_LOW_FALSE 0x08
#define EFI_ACPI_IRQ_MODE 0x01
#define EFI_ACPI_IRQ_LEVEL_TRIGGERED 0x00
#define EFI_ACPI_IRQ_EDGE_TRIGGERED 0x01
#define EFI_ACPI_IRQ_MODE 0x01
#define EFI_ACPI_IRQ_LEVEL_TRIGGERED 0x00
#define EFI_ACPI_IRQ_EDGE_TRIGGERED 0x01
//
// DMA Information
// Ref ACPI specification 6.4.2.2
//
#define EFI_ACPI_DMA_SPEED_TYPE_MASK 0x60
#define EFI_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00
#define EFI_ACPI_DMA_SPEED_TYPE_A 0x20
#define EFI_ACPI_DMA_SPEED_TYPE_B 0x40
#define EFI_ACPI_DMA_SPEED_TYPE_F 0x60
#define EFI_ACPI_DMA_SPEED_TYPE_MASK 0x60
#define EFI_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00
#define EFI_ACPI_DMA_SPEED_TYPE_A 0x20
#define EFI_ACPI_DMA_SPEED_TYPE_B 0x40
#define EFI_ACPI_DMA_SPEED_TYPE_F 0x60
#define EFI_ACPI_DMA_BUS_MASTER_MASK 0x04
#define EFI_ACPI_DMA_BUS_MASTER 0x04
#define EFI_ACPI_DMA_BUS_MASTER_MASK 0x04
#define EFI_ACPI_DMA_BUS_MASTER 0x04
#define EFI_ACPI_DMA_TRANSFER_TYPE_MASK 0x03
#define EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x00
#define EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x01
#define EFI_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x10
#define EFI_ACPI_DMA_TRANSFER_TYPE_MASK 0x03
#define EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x00
#define EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x01
#define EFI_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x02
//
// IO Information
// Ref ACPI specification 6.4.2.5
//
#define EFI_ACPI_IO_DECODE_MASK 0x01
#define EFI_ACPI_IO_DECODE_16_BIT 0x01
#define EFI_ACPI_IO_DECODE_10_BIT 0x00
#define EFI_ACPI_IO_DECODE_MASK 0x01
#define EFI_ACPI_IO_DECODE_16_BIT 0x01
#define EFI_ACPI_IO_DECODE_10_BIT 0x00
//
// Memory Information
// Ref ACPI specification 6.4.3.4
//
#define EFI_ACPI_MEMORY_WRITE_STATUS_MASK 0x01
#define EFI_ACPI_MEMORY_WRITABLE 0x01
#define EFI_ACPI_MEMORY_NON_WRITABLE 0x00
#define EFI_ACPI_MEMORY_WRITE_STATUS_MASK 0x01
#define EFI_ACPI_MEMORY_WRITABLE 0x01
#define EFI_ACPI_MEMORY_NON_WRITABLE 0x00
//
// Interrupt Vector Flags definitions for Extended Interrupt Descriptor
// Ref ACPI specification 6.4.3.6
//
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK BIT0
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK BIT1
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK BIT2
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK BIT3
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLITY_MASK BIT4
//
// Ensure proper structure formats
@ -396,11 +401,11 @@ typedef struct {
/// Root System Description Pointer Structure.
///
typedef struct {
UINT64 Signature;
UINT8 Checksum;
UINT8 OemId[6];
UINT8 Reserved;
UINT32 RsdtAddress;
UINT64 Signature;
UINT8 Checksum;
UINT8 OemId[6];
UINT8 Reserved;
UINT32 RsdtAddress;
} EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
//
@ -412,52 +417,52 @@ typedef struct {
///
/// RSDT Revision (as defined in ACPI 1.0b specification).
///
#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
///
/// Fixed ACPI Description Table Structure (FADT).
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 FirmwareCtrl;
UINT32 Dsdt;
UINT8 IntModel;
UINT8 Reserved1;
UINT16 SciInt;
UINT32 SmiCmd;
UINT8 AcpiEnable;
UINT8 AcpiDisable;
UINT8 S4BiosReq;
UINT8 Reserved2;
UINT32 Pm1aEvtBlk;
UINT32 Pm1bEvtBlk;
UINT32 Pm1aCntBlk;
UINT32 Pm1bCntBlk;
UINT32 Pm2CntBlk;
UINT32 PmTmrBlk;
UINT32 Gpe0Blk;
UINT32 Gpe1Blk;
UINT8 Pm1EvtLen;
UINT8 Pm1CntLen;
UINT8 Pm2CntLen;
UINT8 PmTmLen;
UINT8 Gpe0BlkLen;
UINT8 Gpe1BlkLen;
UINT8 Gpe1Base;
UINT8 Reserved3;
UINT16 PLvl2Lat;
UINT16 PLvl3Lat;
UINT16 FlushSize;
UINT16 FlushStride;
UINT8 DutyOffset;
UINT8 DutyWidth;
UINT8 DayAlrm;
UINT8 MonAlrm;
UINT8 Century;
UINT8 Reserved4;
UINT8 Reserved5;
UINT8 Reserved6;
UINT32 Flags;
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 FirmwareCtrl;
UINT32 Dsdt;
UINT8 IntModel;
UINT8 Reserved1;
UINT16 SciInt;
UINT32 SmiCmd;
UINT8 AcpiEnable;
UINT8 AcpiDisable;
UINT8 S4BiosReq;
UINT8 Reserved2;
UINT32 Pm1aEvtBlk;
UINT32 Pm1bEvtBlk;
UINT32 Pm1aCntBlk;
UINT32 Pm1bCntBlk;
UINT32 Pm2CntBlk;
UINT32 PmTmrBlk;
UINT32 Gpe0Blk;
UINT32 Gpe1Blk;
UINT8 Pm1EvtLen;
UINT8 Pm1CntLen;
UINT8 Pm2CntLen;
UINT8 PmTmLen;
UINT8 Gpe0BlkLen;
UINT8 Gpe1BlkLen;
UINT8 Gpe1Base;
UINT8 Reserved3;
UINT16 PLvl2Lat;
UINT16 PLvl3Lat;
UINT16 FlushSize;
UINT16 FlushStride;
UINT8 DutyOffset;
UINT8 DutyWidth;
UINT8 DayAlrm;
UINT8 MonAlrm;
UINT8 Century;
UINT8 Reserved4;
UINT8 Reserved5;
UINT8 Reserved6;
UINT32 Flags;
} EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE;
///
@ -465,63 +470,63 @@ typedef struct {
///
#define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x01
#define EFI_ACPI_1_0_INT_MODE_DUAL_PIC 0
#define EFI_ACPI_1_0_INT_MODE_MULTIPLE_APIC 1
#define EFI_ACPI_1_0_INT_MODE_DUAL_PIC 0
#define EFI_ACPI_1_0_INT_MODE_MULTIPLE_APIC 1
//
// Fixed ACPI Description Table Fixed Feature Flags
// All other bits are reserved and must be set to 0.
//
#define EFI_ACPI_1_0_WBINVD BIT0
#define EFI_ACPI_1_0_WBINVD_FLUSH BIT1
#define EFI_ACPI_1_0_PROC_C1 BIT2
#define EFI_ACPI_1_0_P_LVL2_UP BIT3
#define EFI_ACPI_1_0_PWR_BUTTON BIT4
#define EFI_ACPI_1_0_SLP_BUTTON BIT5
#define EFI_ACPI_1_0_FIX_RTC BIT6
#define EFI_ACPI_1_0_RTC_S4 BIT7
#define EFI_ACPI_1_0_TMR_VAL_EXT BIT8
#define EFI_ACPI_1_0_DCK_CAP BIT9
#define EFI_ACPI_1_0_WBINVD BIT0
#define EFI_ACPI_1_0_WBINVD_FLUSH BIT1
#define EFI_ACPI_1_0_PROC_C1 BIT2
#define EFI_ACPI_1_0_P_LVL2_UP BIT3
#define EFI_ACPI_1_0_PWR_BUTTON BIT4
#define EFI_ACPI_1_0_SLP_BUTTON BIT5
#define EFI_ACPI_1_0_FIX_RTC BIT6
#define EFI_ACPI_1_0_RTC_S4 BIT7
#define EFI_ACPI_1_0_TMR_VAL_EXT BIT8
#define EFI_ACPI_1_0_DCK_CAP BIT9
///
/// Firmware ACPI Control Structure.
///
typedef struct {
UINT32 Signature;
UINT32 Length;
UINT32 HardwareSignature;
UINT32 FirmwareWakingVector;
UINT32 GlobalLock;
UINT32 Flags;
UINT8 Reserved[40];
UINT32 Signature;
UINT32 Length;
UINT32 HardwareSignature;
UINT32 FirmwareWakingVector;
UINT32 GlobalLock;
UINT32 Flags;
UINT8 Reserved[40];
} EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
///
/// Firmware Control Structure Feature Flags.
/// All other bits are reserved and must be set to 0.
///
#define EFI_ACPI_1_0_S4BIOS_F BIT0
#define EFI_ACPI_1_0_S4BIOS_F BIT0
///
/// Multiple APIC Description Table header definition. The rest of the table
/// must be defined in a platform-specific manner.
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 LocalApicAddress;
UINT32 Flags;
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 LocalApicAddress;
UINT32 Flags;
} EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
///
/// MADT Revision (as defined in ACPI 1.0b specification).
///
#define EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01
#define EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01
///
/// Multiple APIC Flags
/// All other bits are reserved and must be set to 0.
///
#define EFI_ACPI_1_0_PCAT_COMPAT BIT0
#define EFI_ACPI_1_0_PCAT_COMPAT BIT0
//
// Multiple APIC Description Table APIC structure types
@ -542,71 +547,71 @@ typedef struct {
/// Processor Local APIC Structure Definition.
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT8 ApicId;
UINT32 Flags;
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT8 ApicId;
UINT32 Flags;
} EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
///
/// Local APIC Flags. All other bits are reserved and must be 0.
///
#define EFI_ACPI_1_0_LOCAL_APIC_ENABLED BIT0
#define EFI_ACPI_1_0_LOCAL_APIC_ENABLED BIT0
///
/// IO APIC Structure.
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT32 IoApicAddress;
UINT32 SystemVectorBase;
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT32 IoApicAddress;
UINT32 SystemVectorBase;
} EFI_ACPI_1_0_IO_APIC_STRUCTURE;
///
/// Interrupt Source Override Structure.
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Bus;
UINT8 Source;
UINT32 GlobalSystemInterruptVector;
UINT16 Flags;
UINT8 Type;
UINT8 Length;
UINT8 Bus;
UINT8 Source;
UINT32 GlobalSystemInterruptVector;
UINT16 Flags;
} EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
///
/// Non-Maskable Interrupt Source Structure.
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Flags;
UINT32 GlobalSystemInterruptVector;
UINT8 Type;
UINT8 Length;
UINT16 Flags;
UINT32 GlobalSystemInterruptVector;
} EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
///
/// Local APIC NMI Structure.
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT16 Flags;
UINT8 LocalApicInti;
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT16 Flags;
UINT8 LocalApicInti;
} EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE;
///
/// Smart Battery Description Table (SBST)
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 WarningEnergyLevel;
UINT32 LowEnergyLevel;
UINT32 CriticalEnergyLevel;
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 WarningEnergyLevel;
UINT32 LowEnergyLevel;
UINT32 CriticalEnergyLevel;
} EFI_ACPI_1_0_SMART_BATTERY_DESCRIPTION_TABLE;
//

View File

@ -1,29 +1,23 @@
/** @file
ACPI 2.0 definitions from the ACPI Specification, revision 2.0
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _ACPI_2_0_H_
#define _ACPI_2_0_H_
FILE_LICENCE ( BSD3 );
FILE_LICENCE ( BSD2_PATENT );
#include <ipxe/efi/IndustryStandard/Acpi10.h>
//
// Define for Desriptor
// Define for Descriptor
//
#define ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME 0x02
#define ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME 0x02
#define ACPI_GENERIC_REGISTER_DESCRIPTOR 0x82
#define ACPI_GENERIC_REGISTER_DESCRIPTOR 0x82
//
// Ensure proper structure formats
@ -53,11 +47,11 @@ typedef PACKED struct {
/// ACPI 2.0 Generic Address Space definition
///
typedef struct {
UINT8 AddressSpaceId;
UINT8 RegisterBitWidth;
UINT8 RegisterBitOffset;
UINT8 Reserved;
UINT64 Address;
UINT8 AddressSpaceId;
UINT8 RegisterBitWidth;
UINT8 RegisterBitOffset;
UINT8 Reserved;
UINT64 Address;
} EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE;
//
@ -78,29 +72,29 @@ typedef struct {
/// Root System Description Pointer Structure
///
typedef struct {
UINT64 Signature;
UINT8 Checksum;
UINT8 OemId[6];
UINT8 Revision;
UINT32 RsdtAddress;
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT64 Signature;
UINT8 Checksum;
UINT8 OemId[6];
UINT8 Revision;
UINT32 RsdtAddress;
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
} EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
/// RSD_PTR Revision (as defined in ACPI 2.0 spec.)
///
#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02
#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02
///
/// Common table header, this prefaces all ACPI tables, including FACS, but
/// excluding the RSD PTR structure
///
typedef struct {
UINT32 Signature;
UINT32 Length;
UINT32 Signature;
UINT32 Length;
} EFI_ACPI_2_0_COMMON_HEADER;
//
@ -112,7 +106,7 @@ typedef struct {
///
/// RSDT Revision (as defined in ACPI 2.0 spec.)
///
#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
//
// Extended System Description Table
@ -123,64 +117,64 @@ typedef struct {
///
/// XSDT Revision (as defined in ACPI 2.0 spec.)
///
#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
///
/// Fixed ACPI Description Table Structure (FADT)
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 FirmwareCtrl;
UINT32 Dsdt;
UINT8 Reserved0;
UINT8 PreferredPmProfile;
UINT16 SciInt;
UINT32 SmiCmd;
UINT8 AcpiEnable;
UINT8 AcpiDisable;
UINT8 S4BiosReq;
UINT8 PstateCnt;
UINT32 Pm1aEvtBlk;
UINT32 Pm1bEvtBlk;
UINT32 Pm1aCntBlk;
UINT32 Pm1bCntBlk;
UINT32 Pm2CntBlk;
UINT32 PmTmrBlk;
UINT32 Gpe0Blk;
UINT32 Gpe1Blk;
UINT8 Pm1EvtLen;
UINT8 Pm1CntLen;
UINT8 Pm2CntLen;
UINT8 PmTmrLen;
UINT8 Gpe0BlkLen;
UINT8 Gpe1BlkLen;
UINT8 Gpe1Base;
UINT8 CstCnt;
UINT16 PLvl2Lat;
UINT16 PLvl3Lat;
UINT16 FlushSize;
UINT16 FlushStride;
UINT8 DutyOffset;
UINT8 DutyWidth;
UINT8 DayAlrm;
UINT8 MonAlrm;
UINT8 Century;
UINT16 IaPcBootArch;
UINT8 Reserved1;
UINT32 Flags;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE ResetReg;
UINT8 ResetValue;
UINT8 Reserved2[3];
UINT64 XFirmwareCtrl;
UINT64 XDsdt;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk;
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 FirmwareCtrl;
UINT32 Dsdt;
UINT8 Reserved0;
UINT8 PreferredPmProfile;
UINT16 SciInt;
UINT32 SmiCmd;
UINT8 AcpiEnable;
UINT8 AcpiDisable;
UINT8 S4BiosReq;
UINT8 PstateCnt;
UINT32 Pm1aEvtBlk;
UINT32 Pm1bEvtBlk;
UINT32 Pm1aCntBlk;
UINT32 Pm1bCntBlk;
UINT32 Pm2CntBlk;
UINT32 PmTmrBlk;
UINT32 Gpe0Blk;
UINT32 Gpe1Blk;
UINT8 Pm1EvtLen;
UINT8 Pm1CntLen;
UINT8 Pm2CntLen;
UINT8 PmTmrLen;
UINT8 Gpe0BlkLen;
UINT8 Gpe1BlkLen;
UINT8 Gpe1Base;
UINT8 CstCnt;
UINT16 PLvl2Lat;
UINT16 PLvl3Lat;
UINT16 FlushSize;
UINT16 FlushStride;
UINT8 DutyOffset;
UINT8 DutyWidth;
UINT8 DayAlrm;
UINT8 MonAlrm;
UINT8 Century;
UINT16 IaPcBootArch;
UINT8 Reserved1;
UINT32 Flags;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE ResetReg;
UINT8 ResetValue;
UINT8 Reserved2[3];
UINT64 XFirmwareCtrl;
UINT64 XDsdt;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk;
} EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE;
///
@ -191,53 +185,53 @@ typedef struct {
//
// Fixed ACPI Description Table Preferred Power Management Profile
//
#define EFI_ACPI_2_0_PM_PROFILE_UNSPECIFIED 0
#define EFI_ACPI_2_0_PM_PROFILE_DESKTOP 1
#define EFI_ACPI_2_0_PM_PROFILE_MOBILE 2
#define EFI_ACPI_2_0_PM_PROFILE_WORKSTATION 3
#define EFI_ACPI_2_0_PM_PROFILE_ENTERPRISE_SERVER 4
#define EFI_ACPI_2_0_PM_PROFILE_SOHO_SERVER 5
#define EFI_ACPI_2_0_PM_PROFILE_APPLIANCE_PC 6
#define EFI_ACPI_2_0_PM_PROFILE_UNSPECIFIED 0
#define EFI_ACPI_2_0_PM_PROFILE_DESKTOP 1
#define EFI_ACPI_2_0_PM_PROFILE_MOBILE 2
#define EFI_ACPI_2_0_PM_PROFILE_WORKSTATION 3
#define EFI_ACPI_2_0_PM_PROFILE_ENTERPRISE_SERVER 4
#define EFI_ACPI_2_0_PM_PROFILE_SOHO_SERVER 5
#define EFI_ACPI_2_0_PM_PROFILE_APPLIANCE_PC 6
//
// Fixed ACPI Description Table Boot Architecture Flags
// All other bits are reserved and must be set to 0.
//
#define EFI_ACPI_2_0_LEGACY_DEVICES BIT0
#define EFI_ACPI_2_0_8042 BIT1
#define EFI_ACPI_2_0_LEGACY_DEVICES BIT0
#define EFI_ACPI_2_0_8042 BIT1
//
// Fixed ACPI Description Table Fixed Feature Flags
// All other bits are reserved and must be set to 0.
//
#define EFI_ACPI_2_0_WBINVD BIT0
#define EFI_ACPI_2_0_WBINVD_FLUSH BIT1
#define EFI_ACPI_2_0_PROC_C1 BIT2
#define EFI_ACPI_2_0_P_LVL2_UP BIT3
#define EFI_ACPI_2_0_PWR_BUTTON BIT4
#define EFI_ACPI_2_0_SLP_BUTTON BIT5
#define EFI_ACPI_2_0_FIX_RTC BIT6
#define EFI_ACPI_2_0_RTC_S4 BIT7
#define EFI_ACPI_2_0_TMR_VAL_EXT BIT8
#define EFI_ACPI_2_0_DCK_CAP BIT9
#define EFI_ACPI_2_0_RESET_REG_SUP BIT10
#define EFI_ACPI_2_0_SEALED_CASE BIT11
#define EFI_ACPI_2_0_HEADLESS BIT12
#define EFI_ACPI_2_0_CPU_SW_SLP BIT13
#define EFI_ACPI_2_0_WBINVD BIT0
#define EFI_ACPI_2_0_WBINVD_FLUSH BIT1
#define EFI_ACPI_2_0_PROC_C1 BIT2
#define EFI_ACPI_2_0_P_LVL2_UP BIT3
#define EFI_ACPI_2_0_PWR_BUTTON BIT4
#define EFI_ACPI_2_0_SLP_BUTTON BIT5
#define EFI_ACPI_2_0_FIX_RTC BIT6
#define EFI_ACPI_2_0_RTC_S4 BIT7
#define EFI_ACPI_2_0_TMR_VAL_EXT BIT8
#define EFI_ACPI_2_0_DCK_CAP BIT9
#define EFI_ACPI_2_0_RESET_REG_SUP BIT10
#define EFI_ACPI_2_0_SEALED_CASE BIT11
#define EFI_ACPI_2_0_HEADLESS BIT12
#define EFI_ACPI_2_0_CPU_SW_SLP BIT13
///
/// Firmware ACPI Control Structure
///
typedef struct {
UINT32 Signature;
UINT32 Length;
UINT32 HardwareSignature;
UINT32 FirmwareWakingVector;
UINT32 GlobalLock;
UINT32 Flags;
UINT64 XFirmwareWakingVector;
UINT8 Version;
UINT8 Reserved[31];
UINT32 Signature;
UINT32 Length;
UINT32 HardwareSignature;
UINT32 FirmwareWakingVector;
UINT32 GlobalLock;
UINT32 Flags;
UINT64 XFirmwareWakingVector;
UINT8 Version;
UINT8 Reserved[31];
} EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
///
@ -249,28 +243,28 @@ typedef struct {
/// Firmware Control Structure Feature Flags
/// All other bits are reserved and must be set to 0.
///
#define EFI_ACPI_2_0_S4BIOS_F BIT0
#define EFI_ACPI_2_0_S4BIOS_F BIT0
///
/// Multiple APIC Description Table header definition. The rest of the table
/// must be defined in a platform specific manner.
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 LocalApicAddress;
UINT32 Flags;
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 LocalApicAddress;
UINT32 Flags;
} EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
///
/// MADT Revision (as defined in ACPI 2.0 spec.)
///
#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01
#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01
///
/// Multiple APIC Flags
/// All other bits are reserved and must be set to 0.
///
#define EFI_ACPI_2_0_PCAT_COMPAT BIT0
#define EFI_ACPI_2_0_PCAT_COMPAT BIT0
//
// Multiple APIC Description Table APIC structure types
@ -295,127 +289,127 @@ typedef struct {
/// Processor Local APIC Structure Definition
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT8 ApicId;
UINT32 Flags;
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT8 ApicId;
UINT32 Flags;
} EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
///
/// Local APIC Flags. All other bits are reserved and must be 0.
///
#define EFI_ACPI_2_0_LOCAL_APIC_ENABLED BIT0
#define EFI_ACPI_2_0_LOCAL_APIC_ENABLED BIT0
///
/// IO APIC Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_2_0_IO_APIC_STRUCTURE;
///
/// Interrupt Source Override Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Bus;
UINT8 Source;
UINT32 GlobalSystemInterrupt;
UINT16 Flags;
UINT8 Type;
UINT8 Length;
UINT8 Bus;
UINT8 Source;
UINT32 GlobalSystemInterrupt;
UINT16 Flags;
} EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
///
/// Non-Maskable Interrupt Source Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Flags;
UINT32 GlobalSystemInterrupt;
UINT8 Type;
UINT8 Length;
UINT16 Flags;
UINT32 GlobalSystemInterrupt;
} EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
///
/// Local APIC NMI Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT16 Flags;
UINT8 LocalApicLint;
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT16 Flags;
UINT8 LocalApicLint;
} EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE;
///
/// Local APIC Address Override Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT64 LocalApicAddress;
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
///
/// IO SAPIC Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_2_0_IO_SAPIC_STRUCTURE;
///
/// Local SAPIC Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT32 Flags;
UINT8 Type;
UINT8 Length;
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT32 Flags;
} EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
///
/// Platform Interrupt Sources Structure
///
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Flags;
UINT8 InterruptType;
UINT8 ProcessorId;
UINT8 ProcessorEid;
UINT8 IoSapicVector;
UINT32 GlobalSystemInterrupt;
UINT32 Reserved;
UINT8 Type;
UINT8 Length;
UINT16 Flags;
UINT8 InterruptType;
UINT8 ProcessorId;
UINT8 ProcessorEid;
UINT8 IoSapicVector;
UINT32 GlobalSystemInterrupt;
UINT32 Reserved;
} EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
///
/// Smart Battery Description Table (SBST)
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 WarningEnergyLevel;
UINT32 LowEnergyLevel;
UINT32 CriticalEnergyLevel;
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 WarningEnergyLevel;
UINT32 LowEnergyLevel;
UINT32 CriticalEnergyLevel;
} EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE;
///
/// SBST Version (as defined in ACPI 2.0 spec.)
///
#define EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
#define EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
///
/// Embedded Controller Boot Resources Table (ECDT)
@ -423,11 +417,11 @@ typedef struct {
/// a fully qualified reference to the name space object.
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcControl;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcData;
UINT32 Uid;
UINT8 GpeBit;
EFI_ACPI_DESCRIPTION_HEADER Header;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcControl;
EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcData;
UINT32 Uid;
UINT8 GpeBit;
} EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
///
@ -513,7 +507,7 @@ typedef struct {
#define EFI_ACPI_2_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T')
///
/// "SPCR" Serial Port Concole Redirection Table
/// "SPCR" Serial Port Console Redirection Table
///
#define EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R')

Some files were not shown because too many files have changed in this diff Show More