mirror of https://github.com/ipxe/ipxe.git
Merge branch 'master' into respect_cc_v4
commit
3c301c6cf0
|
@ -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 +=
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += Makefile.linux
|
||||
include Makefile.linux
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
.arm
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -1,5 +1,6 @@
|
|||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
.thumb
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
.arm
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 != ' ' ) ) {
|
||||
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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -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",
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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.*)
|
||||
}
|
||||
}
|
|
@ -3,5 +3,5 @@
|
|||
*/
|
||||
#ifdef PLATFORM_pcbios
|
||||
#undef PCIAPI_PCBIOS
|
||||
#define PCIAPI_DIRECT
|
||||
#define PCIAPI_CLOUD
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
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,68 +55,72 @@ struct digest_algorithm digest_null = {
|
|||
.final = digest_null_final,
|
||||
};
|
||||
|
||||
static int cipher_null_setkey ( void *ctx __unused, const void *key __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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
int pubkey_null_sign ( void *ctx __unused,
|
||||
struct digest_algorithm *digest __unused,
|
||||
const void *value __unused,
|
||||
void *signature __unused ) {
|
||||
const void *value __unused, void *signature __unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pubkey_null_verify ( void *ctx __unused,
|
||||
int pubkey_null_verify ( void *ctx __unused,
|
||||
struct digest_algorithm *digest __unused,
|
||||
const void *value __unused,
|
||||
const void *signature __unused ,
|
||||
|
@ -124,7 +128,7 @@ static int pubkey_null_verify ( void *ctx __unused,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void pubkey_null_final ( void *ctx __unused ) {
|
||||
void pubkey_null_final ( void *ctx __unused ) {
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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 ) );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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,
|
||||
};
|
|
@ -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 ) );
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 );
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 ( ðernet_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 ) );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
|
|
@ -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 ),
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,8 +51,26 @@ 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
|
||||
|
@ -64,13 +83,14 @@ struct cipher_algorithm {
|
|||
*
|
||||
* @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 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.
|
||||
|
@ -81,13 +101,19 @@ struct cipher_algorithm {
|
|||
*
|
||||
* @v ctx Context
|
||||
* @v src Data to decrypt
|
||||
* @v dst Buffer for decrypted data
|
||||
* @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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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,11 +22,57 @@ FILE_LICENCE ( BSD3 );
|
|||
//
|
||||
// Make sure we are using the correct packing rules per EFI specification
|
||||
//
|
||||
#ifndef __GNUC__
|
||||
#if !defined (__GNUC__) && !defined (__ASSEMBLER__)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#if _MSC_EXTENSIONS
|
||||
#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
|
||||
//
|
||||
|
@ -47,7 +87,9 @@ FILE_LICENCE ( BSD3 );
|
|||
typedef unsigned char UINT8;
|
||||
typedef char CHAR8;
|
||||
typedef signed char INT8;
|
||||
|
||||
#else
|
||||
|
||||
//
|
||||
// Assume standard AARCH64 alignment.
|
||||
//
|
||||
|
@ -62,6 +104,7 @@ FILE_LICENCE ( BSD3 );
|
|||
typedef unsigned char UINT8;
|
||||
typedef char CHAR8;
|
||||
typedef signed char INT8;
|
||||
|
||||
#endif
|
||||
|
||||
///
|
||||
|
@ -95,12 +138,22 @@ typedef INT64 INTN;
|
|||
///
|
||||
#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.
|
||||
///
|
||||
#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
|
||||
///
|
||||
|
|
|
@ -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,18 +20,67 @@ FILE_LICENCE ( BSD3 );
|
|||
//
|
||||
// Make sure we are using the correct packing rules per EFI specification
|
||||
//
|
||||
#ifndef __GNUC__
|
||||
#if !defined (__GNUC__) && !defined (__ASSEMBLER__)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#if defined (_MSC_EXTENSIONS)
|
||||
|
||||
//
|
||||
// RVCT does not support the __builtin_unreachable() macro
|
||||
// Disable some level 4 compilation warnings (same as IA32 and X64)
|
||||
//
|
||||
#ifdef __ARMCC_VERSION
|
||||
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
// MSFT doesn't support the __builtin_unreachable() macro
|
||||
//
|
||||
#if defined (_MSC_EXTENSIONS)
|
||||
#define UNREACHABLE()
|
||||
#endif
|
||||
|
||||
#if _MSC_EXTENSIONS
|
||||
#if defined (_MSC_EXTENSIONS)
|
||||
//
|
||||
// use Microsoft* C compiler dependent integer width types
|
||||
//
|
||||
|
@ -101,12 +144,22 @@ typedef INT32 INTN;
|
|||
///
|
||||
#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
|
||||
///
|
||||
|
@ -161,6 +214,11 @@ typedef INT32 INTN;
|
|||
#define GCC_ASM_IMPORT(name)
|
||||
|
||||
#endif
|
||||
#elif defined (_MSC_EXTENSIONS)
|
||||
//
|
||||
// PRESERVE8 is not supported by the MSFT assembler.
|
||||
//
|
||||
#define PRESERVE8
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -180,5 +238,3 @@ typedef INT32 INTN;
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -6,23 +6,16 @@
|
|||
environment. There are a set of base libraries in the Mde Package that can
|
||||
be used to implement base modules.
|
||||
|
||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2021, 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 __BASE_H__
|
||||
#define __BASE_H__
|
||||
|
||||
FILE_LICENCE ( BSD3 );
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
//
|
||||
// Include processor specific binding
|
||||
|
@ -36,64 +29,12 @@ FILE_LICENCE ( BSD3 );
|
|||
#pragma warning ( disable : 4200 )
|
||||
#endif
|
||||
|
||||
/**
|
||||
Verifies the storage size of a given data type.
|
||||
|
||||
This macro generates a divide by zero error or a zero size array declaration in
|
||||
the preprocessor if the size is incorrect. These are declared as "extern" so
|
||||
the space for these arrays will not be in the modules.
|
||||
|
||||
@param TYPE The date type to determine the size of.
|
||||
@param Size The expected size for the TYPE.
|
||||
|
||||
**/
|
||||
#define VERIFY_SIZE_OF(TYPE, Size) extern UINT8 _VerifySizeof##TYPE[(sizeof(TYPE) == (Size)) / (sizeof(TYPE) == (Size))]
|
||||
|
||||
//
|
||||
// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with
|
||||
// Section 2.3.1 of the UEFI 2.3 Specification.
|
||||
//
|
||||
VERIFY_SIZE_OF (BOOLEAN, 1);
|
||||
VERIFY_SIZE_OF (INT8, 1);
|
||||
VERIFY_SIZE_OF (UINT8, 1);
|
||||
VERIFY_SIZE_OF (INT16, 2);
|
||||
VERIFY_SIZE_OF (UINT16, 2);
|
||||
VERIFY_SIZE_OF (INT32, 4);
|
||||
VERIFY_SIZE_OF (UINT32, 4);
|
||||
VERIFY_SIZE_OF (INT64, 8);
|
||||
VERIFY_SIZE_OF (UINT64, 8);
|
||||
VERIFY_SIZE_OF (CHAR8, 1);
|
||||
VERIFY_SIZE_OF (CHAR16, 2);
|
||||
|
||||
//
|
||||
// The following three enum types are used to verify that the compiler
|
||||
// configuration for enum types is compliant with Section 2.3.1 of the
|
||||
// UEFI 2.3 Specification. These enum types and enum values are not
|
||||
// intended to be used. A prefix of '__' is used avoid conflicts with
|
||||
// other types.
|
||||
//
|
||||
typedef enum {
|
||||
__VerifyUint8EnumValue = 0xff
|
||||
} __VERIFY_UINT8_ENUM_SIZE;
|
||||
|
||||
typedef enum {
|
||||
__VerifyUint16EnumValue = 0xffff
|
||||
} __VERIFY_UINT16_ENUM_SIZE;
|
||||
|
||||
typedef enum {
|
||||
__VerifyUint32EnumValue = 0xffffffff
|
||||
} __VERIFY_UINT32_ENUM_SIZE;
|
||||
|
||||
VERIFY_SIZE_OF (__VERIFY_UINT8_ENUM_SIZE, 4);
|
||||
VERIFY_SIZE_OF (__VERIFY_UINT16_ENUM_SIZE, 4);
|
||||
VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
||||
|
||||
//
|
||||
// The Microsoft* C compiler can removed references to unreferenced data items
|
||||
// if the /OPT:REF linker option is used. We defined a macro as this is a
|
||||
// a non standard extension
|
||||
//
|
||||
#if defined(_MSC_EXTENSIONS) && !defined (MDE_CPU_EBC)
|
||||
#if defined (_MSC_VER) && _MSC_VER < 1800 && !defined (MDE_CPU_EBC)
|
||||
///
|
||||
/// Remove global variable from the linked image if there are no references to
|
||||
/// it after all compiler and linker optimizations have been performed.
|
||||
|
@ -114,11 +55,10 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
|||
// warnings.
|
||||
//
|
||||
#ifndef UNREACHABLE
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)
|
||||
#ifdef __GNUC__
|
||||
///
|
||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||
/// up to the compiler to remove any code past that point.
|
||||
/// Not implemented by GCC 4.4 or earlier.
|
||||
///
|
||||
#define UNREACHABLE() __builtin_unreachable ()
|
||||
#elif defined (__has_feature)
|
||||
|
@ -220,6 +160,26 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Tell the code optimizer that the function will return twice.
|
||||
/// This prevents wrong optimizations which can cause bugs.
|
||||
///
|
||||
#ifndef RETURNS_TWICE
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
///
|
||||
/// Tell the code optimizer that the function will return twice.
|
||||
/// This prevents wrong optimizations which can cause bugs.
|
||||
///
|
||||
#define RETURNS_TWICE __attribute__((returns_twice))
|
||||
#else
|
||||
///
|
||||
/// Tell the code optimizer that the function will return twice.
|
||||
/// This prevents wrong optimizations which can cause bugs.
|
||||
///
|
||||
#define RETURNS_TWICE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// For symbol name in assembly code, an extra "_" is sometimes necessary
|
||||
//
|
||||
|
@ -236,7 +196,7 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
|||
///
|
||||
#define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name)
|
||||
|
||||
#if __APPLE__
|
||||
#ifdef __APPLE__
|
||||
//
|
||||
// Apple extension that is used by the linker to optimize code size
|
||||
// with assembly functions. Put at the end of your .S files
|
||||
|
@ -246,15 +206,7 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
|||
#define ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|
||||
#endif
|
||||
|
||||
#ifdef __CC_ARM
|
||||
//
|
||||
// Older RVCT ARM compilers don't fully support #pragma pack and require __packed
|
||||
// as a prefix for the structure.
|
||||
//
|
||||
#define PACKED __packed
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
///
|
||||
/// 128 bit buffer containing a unique identifier value.
|
||||
|
@ -359,7 +311,15 @@ struct _LIST_ENTRY {
|
|||
///
|
||||
/// NULL pointer (VOID *)
|
||||
///
|
||||
#if defined (__cplusplus)
|
||||
#if defined (_MSC_EXTENSIONS)
|
||||
#define NULL nullptr
|
||||
#else
|
||||
#define NULL __null
|
||||
#endif
|
||||
#else
|
||||
#define NULL ((VOID *) 0)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Null character
|
||||
|
@ -378,6 +338,14 @@ struct _LIST_ENTRY {
|
|||
#define MAX_INT64 ((INT64)0x7FFFFFFFFFFFFFFFULL)
|
||||
#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL)
|
||||
|
||||
///
|
||||
/// Minimum values for the signed UEFI Data Types
|
||||
///
|
||||
#define MIN_INT8 (((INT8) -127) - 1)
|
||||
#define MIN_INT16 (((INT16) -32767) - 1)
|
||||
#define MIN_INT32 (((INT32) -2147483647) - 1)
|
||||
#define MIN_INT64 (((INT64) -9223372036854775807LL) - 1)
|
||||
|
||||
#define BIT0 0x00000001
|
||||
#define BIT1 0x00000002
|
||||
#define BIT2 0x00000004
|
||||
|
@ -554,21 +522,24 @@ struct _LIST_ENTRY {
|
|||
#define BASE_8EB 0x8000000000000000ULL
|
||||
|
||||
//
|
||||
// Support for variable length argument lists using the ANSI standard.
|
||||
// Support for variable argument lists in freestanding edk2 modules.
|
||||
//
|
||||
// Since we are using the ANSI standard we used the standard naming and
|
||||
// did not follow the coding convention
|
||||
// For modules that use the ISO C library interfaces for variable
|
||||
// argument lists, refer to "StdLib/Include/stdarg.h".
|
||||
//
|
||||
// VA_LIST - typedef for argument list.
|
||||
// VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.
|
||||
// VA_END (VA_LIST Marker) - Clear Marker
|
||||
// VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argument from
|
||||
// the ... list. You must know the size and pass it in this macro.
|
||||
// VA_ARG (VA_LIST Marker, var arg type) - Use Marker to get an argument from
|
||||
// the ... list. You must know the type and pass it in this macro. Type
|
||||
// must be compatible with the type of the actual next argument (as promoted
|
||||
// according to the default argument promotions.)
|
||||
// VA_COPY (VA_LIST Dest, VA_LIST Start) - Initialize Dest as a copy of Start.
|
||||
//
|
||||
// example:
|
||||
// Example:
|
||||
//
|
||||
// UINTN
|
||||
// EFIAPI
|
||||
// ExampleVarArg (
|
||||
// IN UINTN NumberOfArgs,
|
||||
// ...
|
||||
|
@ -584,15 +555,21 @@ struct _LIST_ENTRY {
|
|||
// VA_START (Marker, NumberOfArgs);
|
||||
// for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {
|
||||
// //
|
||||
// // The ... list is a series of UINTN values, so average them up.
|
||||
// // The ... list is a series of UINTN values, so sum them up.
|
||||
// //
|
||||
// Result += VA_ARG (Marker, UINTN);
|
||||
// }
|
||||
//
|
||||
// VA_END (Marker);
|
||||
// return Result
|
||||
// return Result;
|
||||
// }
|
||||
//
|
||||
// Notes:
|
||||
// - Functions that call VA_START() / VA_END() must have a variable
|
||||
// argument list and must be declared EFIAPI.
|
||||
// - Functions that call VA_COPY() / VA_END() must be declared EFIAPI.
|
||||
// - Functions that only use VA_LIST and VA_ARG() need not be EFIAPI.
|
||||
//
|
||||
|
||||
/**
|
||||
Return the size of argument that has been aligned to sizeof (UINTN).
|
||||
|
@ -603,37 +580,19 @@ struct _LIST_ENTRY {
|
|||
**/
|
||||
#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#if defined (_M_ARM) || defined (_M_ARM64)
|
||||
//
|
||||
// RVCT ARM variable argument list support.
|
||||
// MSFT ARM variable argument list support.
|
||||
//
|
||||
|
||||
///
|
||||
/// Variable used to traverse the list of arguments. This type can vary by
|
||||
/// implementation and could be an array or structure.
|
||||
///
|
||||
#ifdef __APCS_ADSABI
|
||||
typedef int *va_list[1];
|
||||
#define VA_LIST va_list
|
||||
#else
|
||||
typedef struct __va_list { void *__ap; } va_list;
|
||||
#define VA_LIST va_list
|
||||
#endif
|
||||
typedef char *VA_LIST;
|
||||
|
||||
#define VA_START(Marker, Parameter) __va_start(Marker, Parameter)
|
||||
#define VA_START(Marker, Parameter) __va_start (&Marker, &Parameter, _INT_SIZE_OF (Parameter), __alignof(Parameter), &Parameter)
|
||||
#define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE) + ((-(INTN)Marker) & (sizeof(TYPE) - 1))) - _INT_SIZE_OF (TYPE)))
|
||||
#define VA_END(Marker) (Marker = (VA_LIST) 0)
|
||||
#define VA_COPY(Dest, Start) ((void)((Dest) = (Start)))
|
||||
|
||||
#define VA_ARG(Marker, TYPE) __va_arg(Marker, TYPE)
|
||||
|
||||
#define VA_END(Marker) ((void)0)
|
||||
|
||||
// For some ARM RVCT compilers, __va_copy is not defined
|
||||
#ifndef __va_copy
|
||||
#define __va_copy(dest, src) ((void)((dest) = (src)))
|
||||
#endif
|
||||
|
||||
#define VA_COPY(Dest, Start) __va_copy (Dest, Start)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#elif defined (__GNUC__) || defined (__clang__)
|
||||
|
||||
#if defined (MDE_CPU_X64) && !defined (NO_MSABI_VA_FUNCS)
|
||||
//
|
||||
|
@ -793,16 +752,72 @@ typedef UINTN *BASE_LIST;
|
|||
@return Offset, in bytes, of field.
|
||||
|
||||
**/
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ >= 4
|
||||
#if (defined (__GNUC__) && __GNUC__ >= 4) || defined (__clang__)
|
||||
#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef OFFSET_OF
|
||||
#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
|
||||
#endif
|
||||
|
||||
/**
|
||||
Portable definition for compile time assertions.
|
||||
Equivalent to C11 static_assert macro from assert.h.
|
||||
|
||||
@param Expression Boolean expression.
|
||||
@param Message Raised compiler diagnostic message when expression is false.
|
||||
|
||||
**/
|
||||
#ifdef MDE_CPU_EBC
|
||||
#define STATIC_ASSERT(Expression, Message)
|
||||
#elif defined (_MSC_EXTENSIONS) || defined (__cplusplus)
|
||||
#define STATIC_ASSERT static_assert
|
||||
#else
|
||||
#define STATIC_ASSERT _Static_assert
|
||||
#endif
|
||||
|
||||
//
|
||||
// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with
|
||||
// Section 2.3.1 of the UEFI 2.3 Specification.
|
||||
//
|
||||
|
||||
STATIC_ASSERT (sizeof (BOOLEAN) == 1, "sizeof (BOOLEAN) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (INT8) == 1, "sizeof (INT8) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (UINT8) == 1, "sizeof (UINT8) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (INT16) == 2, "sizeof (INT16) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (UINT16) == 2, "sizeof (UINT16) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (INT32) == 4, "sizeof (INT32) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (UINT32) == 4, "sizeof (UINT32) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (INT64) == 8, "sizeof (INT64) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (UINT64) == 8, "sizeof (UINT64) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (CHAR8) == 1, "sizeof (CHAR8) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (CHAR16) == 2, "sizeof (CHAR16) does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (L'A') == 2, "sizeof (L'A') does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (L"A") == 4, "sizeof (L\"A\") does not meet UEFI Specification Data Type requirements");
|
||||
|
||||
//
|
||||
// The following three enum types are used to verify that the compiler
|
||||
// configuration for enum types is compliant with Section 2.3.1 of the
|
||||
// UEFI 2.3 Specification. These enum types and enum values are not
|
||||
// intended to be used. A prefix of '__' is used avoid conflicts with
|
||||
// other types.
|
||||
//
|
||||
typedef enum {
|
||||
__VerifyUint8EnumValue = 0xff
|
||||
} __VERIFY_UINT8_ENUM_SIZE;
|
||||
|
||||
typedef enum {
|
||||
__VerifyUint16EnumValue = 0xffff
|
||||
} __VERIFY_UINT16_ENUM_SIZE;
|
||||
|
||||
typedef enum {
|
||||
__VerifyUint32EnumValue = 0xffffffff
|
||||
} __VERIFY_UINT32_ENUM_SIZE;
|
||||
|
||||
STATIC_ASSERT (sizeof (__VERIFY_UINT8_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (__VERIFY_UINT16_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements");
|
||||
STATIC_ASSERT (sizeof (__VERIFY_UINT32_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements");
|
||||
|
||||
/**
|
||||
Macro that returns a pointer to the data structure that contains a specified field of
|
||||
that data structure. This is a lightweight method to hide information by placing a
|
||||
|
@ -822,7 +837,7 @@ typedef UINTN *BASE_LIST;
|
|||
@return A pointer to the structure from one of it's elements.
|
||||
|
||||
**/
|
||||
#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
|
||||
#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field)))
|
||||
|
||||
/**
|
||||
Rounds a value up to the next boundary using a specified alignment.
|
||||
|
@ -867,7 +882,6 @@ typedef UINTN *BASE_LIST;
|
|||
**/
|
||||
#define ALIGN_VARIABLE(Value) ALIGN_VALUE ((Value), sizeof (UINTN))
|
||||
|
||||
|
||||
/**
|
||||
Return the maximum of two operands.
|
||||
|
||||
|
@ -955,7 +969,7 @@ typedef UINTN RETURN_STATUS;
|
|||
///
|
||||
/// The operation completed successfully.
|
||||
///
|
||||
#define RETURN_SUCCESS 0
|
||||
#define RETURN_SUCCESS (RETURN_STATUS)(0)
|
||||
|
||||
///
|
||||
/// The image failed to load.
|
||||
|
@ -1160,7 +1174,6 @@ typedef UINTN RETURN_STATUS;
|
|||
///
|
||||
#define RETURN_WARN_FILE_SYSTEM ENCODE_WARNING (6)
|
||||
|
||||
|
||||
/**
|
||||
Returns a 16-bit signature built from 2 ASCII characters.
|
||||
|
||||
|
@ -1215,7 +1228,13 @@ typedef UINTN RETURN_STATUS;
|
|||
(SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
|
||||
|
||||
#if defined (_MSC_EXTENSIONS) && !defined (__INTEL_COMPILER) && !defined (MDE_CPU_EBC)
|
||||
void *
|
||||
_ReturnAddress (
|
||||
void
|
||||
);
|
||||
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
|
||||
/**
|
||||
Get the return address of the calling function.
|
||||
|
||||
|
@ -1229,8 +1248,8 @@ typedef UINTN RETURN_STATUS;
|
|||
|
||||
**/
|
||||
#define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0)
|
||||
#elif defined(__GNUC__)
|
||||
void * __builtin_return_address (unsigned int level);
|
||||
#elif defined (__GNUC__) || defined (__clang__)
|
||||
|
||||
/**
|
||||
Get the return address of the calling function.
|
||||
|
||||
|
@ -1244,6 +1263,7 @@ typedef UINTN RETURN_STATUS;
|
|||
**/
|
||||
#define RETURN_ADDRESS(L) __builtin_return_address (L)
|
||||
#else
|
||||
|
||||
/**
|
||||
Get the return address of the calling function.
|
||||
|
||||
|
@ -1269,4 +1289,3 @@ typedef UINTN RETURN_STATUS;
|
|||
#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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 \
|
||||
{ \
|
||||
|
|
|
@ -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 \
|
||||
{ \
|
||||
|
|
|
@ -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 \
|
||||
{ \
|
||||
|
|
|
@ -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,7 +11,7 @@
|
|||
#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 } }
|
||||
|
|
|
@ -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 } }
|
||||
|
||||
#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
|
||||
|
|
|
@ -1,21 +1,15 @@
|
|||
/** @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
|
||||
|
@ -213,10 +207,27 @@ typedef struct _EFI_IFR_GUID_VAREQNAME {
|
|||
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 gEdkiiIfrBitVarstoreGuid;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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 \
|
||||
{ \
|
||||
|
|
|
@ -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 \
|
||||
{ \
|
||||
|
|
|
@ -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,7 +11,7 @@
|
|||
#ifndef __EFI_WIN_CERTIFICATE_H__
|
||||
#define __EFI_WIN_CERTIFICATE_H__
|
||||
|
||||
FILE_LICENCE ( BSD3 );
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
//
|
||||
// _WIN_CERTIFICATE.wCertificateType
|
||||
|
@ -69,7 +63,6 @@ typedef struct {
|
|||
UINT8 Signature[256];
|
||||
} EFI_CERT_BLOCK_RSA_2048_SHA256;
|
||||
|
||||
|
||||
///
|
||||
/// Certificate which encapsulates a GUID-specific digital signature
|
||||
///
|
||||
|
@ -93,7 +86,6 @@ typedef struct {
|
|||
UINT8 CertData[1];
|
||||
} WIN_CERTIFICATE_UEFI_GUID;
|
||||
|
||||
|
||||
///
|
||||
/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
|
||||
///
|
||||
|
|
|
@ -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.
|
||||
|
@ -56,7 +50,6 @@ FILE_LICENCE ( BSD3 );
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (_MSC_EXTENSIONS)
|
||||
|
||||
//
|
||||
|
@ -95,7 +88,7 @@ FILE_LICENCE ( BSD3 );
|
|||
//
|
||||
#pragma warning ( disable : 4206 )
|
||||
|
||||
#if _MSC_VER == 1800 || _MSC_VER == 1900
|
||||
#if defined (_MSC_VER) && _MSC_VER >= 1800
|
||||
|
||||
//
|
||||
// Disable these warnings for VS2013.
|
||||
|
@ -117,7 +110,6 @@ FILE_LICENCE ( BSD3 );
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (_MSC_EXTENSIONS)
|
||||
|
||||
//
|
||||
|
@ -248,12 +240,22 @@ typedef INT32 INTN;
|
|||
///
|
||||
#define MAX_ADDRESS 0xFFFFFFFF
|
||||
|
||||
///
|
||||
/// Maximum usable address at boot time
|
||||
///
|
||||
#define MAX_ALLOC_ADDRESS MAX_ADDRESS
|
||||
|
||||
///
|
||||
/// Maximum legal IA-32 INTN and UINTN values.
|
||||
///
|
||||
#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.
|
||||
///
|
||||
|
@ -279,7 +281,7 @@ typedef INT32 INTN;
|
|||
/// Microsoft* compiler specific method for EFIAPI calling convention.
|
||||
///
|
||||
#define EFIAPI __cdecl
|
||||
#elif defined(__GNUC__)
|
||||
#elif defined (__GNUC__) || defined (__clang__)
|
||||
///
|
||||
/// GCC specific method for EFIAPI calling convention.
|
||||
///
|
||||
|
@ -292,7 +294,7 @@ typedef INT32 INTN;
|
|||
#define EFIAPI
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
///
|
||||
/// For GNU assembly code, .global or .globl can declare global symbols.
|
||||
/// Define this macro to unify the usage.
|
||||
|
@ -317,4 +319,3 @@ typedef INT32 INTN;
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
@ -45,7 +40,7 @@ typedef struct {
|
|||
#pragma pack()
|
||||
|
||||
//
|
||||
// Define for Desriptor
|
||||
// Define for Descriptor
|
||||
//
|
||||
#define ACPI_SMALL_ITEM_FLAG 0x00
|
||||
#define ACPI_LARGE_ITEM_FLAG 0x01
|
||||
|
@ -117,7 +112,7 @@ 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 {
|
||||
|
@ -366,7 +361,7 @@ typedef struct {
|
|||
#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_16_BIT 0x02
|
||||
|
||||
//
|
||||
// IO Information
|
||||
|
@ -384,6 +379,16 @@ typedef struct {
|
|||
#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
|
||||
//
|
||||
|
|
|
@ -1,25 +1,19 @@
|
|||
/** @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
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue