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
|
# Include architecture-specific include path
|
||||||
ifdef ARCH
|
ifdef ARCH
|
||||||
INCDIRS += arch/$(ARCH)/include
|
INCDIRS += arch/$(ARCH)/include
|
||||||
INCDIRS += arch/$(ARCH)/include/$(PLATFORM)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -462,7 +461,9 @@ ifeq ($(CCTYPE),gcc)
|
||||||
CFLAGS += -ffreestanding
|
CFLAGS += -ffreestanding
|
||||||
CFLAGS += -fcommon
|
CFLAGS += -fcommon
|
||||||
CFLAGS += -Wall -W -Wformat-nonliteral
|
CFLAGS += -Wall -W -Wformat-nonliteral
|
||||||
|
CFLAGS += -Wno-array-bounds -Wno-dangling-pointer
|
||||||
HOST_CFLAGS += -Wall -W -Wformat-nonliteral
|
HOST_CFLAGS += -Wall -W -Wformat-nonliteral
|
||||||
|
HOST_CFLAGS += -Wno-array-bounds -Wno-dangling-pointer
|
||||||
endif
|
endif
|
||||||
CFLAGS += $(WORKAROUND_CFLAGS) $(EXTRA_CFLAGS)
|
CFLAGS += $(WORKAROUND_CFLAGS) $(EXTRA_CFLAGS)
|
||||||
ASFLAGS += $(WORKAROUND_ASFLAGS) $(EXTRA_ASFLAGS)
|
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)'
|
CFLAGS += -DASM_TCHAR='$(ASM_TCHAR)' -DASM_TCHAR_OPS='$(ASM_TCHAR_OPS)'
|
||||||
|
|
||||||
|
# Inhibit the default -Dlinux
|
||||||
|
#
|
||||||
|
CFLAGS += -Ulinux
|
||||||
|
|
||||||
# CFLAGS for specific object types
|
# CFLAGS for specific object types
|
||||||
#
|
#
|
||||||
CFLAGS_c +=
|
CFLAGS_c +=
|
||||||
|
|
|
@ -8,6 +8,10 @@ SYMBOL_PREFIX = _ipxe__
|
||||||
#
|
#
|
||||||
CFLAGS += -UNVALGRIND
|
CFLAGS += -UNVALGRIND
|
||||||
|
|
||||||
|
# The Linux linker script
|
||||||
|
#
|
||||||
|
LDSCRIPT = scripts/linux.lds
|
||||||
|
|
||||||
# Use a two-stage link
|
# Use a two-stage link
|
||||||
#
|
#
|
||||||
LDFLAGS += -r -d
|
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
|
# ARM32-specific flags
|
||||||
#
|
#
|
||||||
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs -mfloat-abi=soft
|
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs
|
||||||
CFLAGS += -mword-relocations
|
CFLAGS += -mword-relocations
|
||||||
ASFLAGS += -mthumb -mcpu=cortex-a15
|
ASFLAGS += -mthumb -mcpu=cortex-a15
|
||||||
|
|
||||||
|
@ -13,6 +13,11 @@ ASFLAGS += -mthumb -mcpu=cortex-a15
|
||||||
#
|
#
|
||||||
CFLAGS += -fshort-wchar
|
CFLAGS += -fshort-wchar
|
||||||
|
|
||||||
|
# EFI requires that enums are always 32 bits, and nothing else
|
||||||
|
# currently cares
|
||||||
|
#
|
||||||
|
CFLAGS += -fno-short-enums
|
||||||
|
|
||||||
# Include common ARM Makefile
|
# Include common ARM Makefile
|
||||||
MAKEDEPS += arch/arm/Makefile
|
MAKEDEPS += arch/arm/Makefile
|
||||||
include arch/arm/Makefile
|
include arch/arm/Makefile
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
# -*- 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
|
# Specify EFI image builder
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||||
|
|
||||||
|
.section ".note.GNU-stack", "", %progbits
|
||||||
.text
|
.text
|
||||||
.arm
|
.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 )
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||||
|
|
||||||
|
.section ".note.GNU-stack", "", %progbits
|
||||||
.text
|
.text
|
||||||
.thumb
|
.thumb
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||||
|
|
||||||
|
.section ".note.GNU-stack", "", %progbits
|
||||||
.text
|
.text
|
||||||
.arm
|
.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
|
# -*- 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
|
# 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/drivers/hyperv
|
||||||
SRCDIRS += arch/x86/transitions
|
SRCDIRS += arch/x86/transitions
|
||||||
|
|
||||||
# breaks building some of the linux-related objects
|
|
||||||
CFLAGS += -Ulinux
|
|
||||||
|
|
||||||
# disable valgrind
|
# disable valgrind
|
||||||
CFLAGS += -DNVALGRIND
|
CFLAGS += -DNVALGRIND
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||||
|
|
||||||
# Include x86 Linux headers
|
|
||||||
#
|
|
||||||
INCDIRS += arch/x86/include/linux
|
|
||||||
|
|
||||||
# Include generic Linux Makefile
|
# Include generic Linux Makefile
|
||||||
#
|
#
|
||||||
MAKEDEPS += Makefile.linux
|
MAKEDEPS += Makefile.linux
|
||||||
|
|
|
@ -45,7 +45,7 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) {
|
||||||
PCIDIRECT_CONFIG_ADDRESS );
|
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_byte );
|
||||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
|
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
|
||||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
|
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_word );
|
||||||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
|
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
|
||||||
PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
|
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,
|
static int bzimage_parse_cmdline ( struct image *image,
|
||||||
struct bzimage_context *bzimg,
|
struct bzimage_context *bzimg,
|
||||||
const char *cmdline ) {
|
char *cmdline ) {
|
||||||
|
char *sep;
|
||||||
char *vga;
|
char *vga;
|
||||||
char *mem;
|
char *mem;
|
||||||
|
|
||||||
/* Look for "vga=" */
|
/* Look for "vga=" */
|
||||||
if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
|
if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
|
||||||
vga += 4;
|
vga += 4;
|
||||||
|
sep = strchr ( vga, ' ' );
|
||||||
|
if ( sep )
|
||||||
|
*sep = '\0';
|
||||||
if ( strcmp ( vga, "normal" ) == 0 ) {
|
if ( strcmp ( vga, "normal" ) == 0 ) {
|
||||||
bzimg->vid_mode = BZI_VID_MODE_NORMAL;
|
bzimg->vid_mode = BZI_VID_MODE_NORMAL;
|
||||||
} else if ( strcmp ( vga, "ext" ) == 0 ) {
|
} 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;
|
bzimg->vid_mode = BZI_VID_MODE_ASK;
|
||||||
} else {
|
} else {
|
||||||
bzimg->vid_mode = strtoul ( vga, &vga, 0 );
|
bzimg->vid_mode = strtoul ( vga, &vga, 0 );
|
||||||
if ( *vga && ( *vga != ' ' ) ) {
|
if ( *vga ) {
|
||||||
DBGC ( image, "bzImage %p strange \"vga=\""
|
DBGC ( image, "bzImage %p strange \"vga=\" "
|
||||||
"terminator '%c'\n", image, *vga );
|
"terminator '%c'\n", image, *vga );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( sep )
|
||||||
|
*sep = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for "mem=" */
|
/* Look for "mem=" */
|
||||||
|
@ -522,7 +528,7 @@ static void bzimage_load_initrds ( struct image *image,
|
||||||
*/
|
*/
|
||||||
static int bzimage_exec ( struct image *image ) {
|
static int bzimage_exec ( struct image *image ) {
|
||||||
struct bzimage_context bzimg;
|
struct bzimage_context bzimg;
|
||||||
const char *cmdline = ( image->cmdline ? image->cmdline : "" );
|
char *cmdline = ( image->cmdline ? image->cmdline : "" );
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Read and parse header from image */
|
/* Read and parse header from image */
|
||||||
|
|
|
@ -11,5 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
#include <ipxe/pcibios.h>
|
#include <ipxe/pcibios.h>
|
||||||
#include <ipxe/pcidirect.h>
|
#include <ipxe/pcidirect.h>
|
||||||
|
#include <ipxe/pcicloud.h>
|
||||||
|
|
||||||
#endif /* _BITS_PCI_IO_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 );
|
return ioremap ( bus_addr, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern struct pci_api pcibios_api;
|
||||||
|
|
||||||
#endif /* _IPXE_PCIBIOS_H */
|
#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 );
|
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
|
static inline __always_inline void
|
||||||
PCIAPI_INLINE ( direct, pci_num_bus ) ( 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 */
|
/* 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 );
|
return ioremap ( bus_addr, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern struct pci_api pcidirect_api;
|
||||||
|
|
||||||
#endif /* _PCIDIRECT_H */
|
#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 */
|
/* Record cached DHCPACK */
|
||||||
if ( ( rc = cachedhcp_record ( &cached_dhcpack,
|
if ( ( rc = cachedhcp_record ( &cached_dhcpack, 0,
|
||||||
phys_to_user ( cached_dhcpack_phys ),
|
phys_to_user ( cached_dhcpack_phys ),
|
||||||
sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
|
sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
|
||||||
DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n",
|
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;
|
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
|
/* We issue this call using flat real mode, to work around a
|
||||||
* bug in some HP BIOSes.
|
* 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"
|
__asm__ __volatile__ ( REAL_CODE ( "call flatten_real_mode\n\t"
|
||||||
"stc\n\t"
|
"stc\n\t"
|
||||||
"int $0x1a\n\t"
|
"int $0x1a\n\t"
|
||||||
|
"movzbw %%cl, %%cx\n\t"
|
||||||
|
"incw %%cx\n\t"
|
||||||
"jnc 1f\n\t"
|
"jnc 1f\n\t"
|
||||||
"xorw %%cx, %%cx\n\t"
|
"xorw %%cx, %%cx\n\t"
|
||||||
"\n1:\n\t" )
|
"\n1:\n\t" )
|
||||||
: "=c" ( max_bus ), "=a" ( discard_a ),
|
: "=c" ( num_bus ), "=a" ( discard_a ),
|
||||||
"=D" ( discard_D )
|
"=D" ( discard_D )
|
||||||
: "a" ( PCIBIOS_INSTALLATION_CHECK >> 16 ),
|
: "a" ( PCIBIOS_INSTALLATION_CHECK >> 16 ),
|
||||||
"D" ( 0 )
|
"D" ( 0 )
|
||||||
: "ebx", "edx" );
|
: "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 );
|
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_byte );
|
||||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word );
|
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word );
|
||||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_dword );
|
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_word );
|
||||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
|
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
|
||||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_ioremap );
|
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/uaccess.h>
|
||||||
#include <ipxe/process.h>
|
#include <ipxe/process.h>
|
||||||
#include <ipxe/netdevice.h>
|
#include <ipxe/netdevice.h>
|
||||||
|
#include <ipxe/malloc.h>
|
||||||
#include <realmode.h>
|
#include <realmode.h>
|
||||||
#include <pxe.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,
|
PXE_API_CALL ( PXENV_UDP_READ, pxenv_udp_read,
|
||||||
struct s_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
|
# -*- 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
|
# 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
|
#ifdef PLATFORM_pcbios
|
||||||
#undef PCIAPI_PCBIOS
|
#undef PCIAPI_PCBIOS
|
||||||
#define PCIAPI_DIRECT
|
#define PCIAPI_CLOUD
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -124,3 +124,15 @@ REQUIRE_OBJECT ( rsa_aes_cbc_sha1 );
|
||||||
defined ( CRYPTO_DIGEST_SHA256 )
|
defined ( CRYPTO_DIGEST_SHA256 )
|
||||||
REQUIRE_OBJECT ( rsa_aes_cbc_sha256 );
|
REQUIRE_OBJECT ( rsa_aes_cbc_sha256 );
|
||||||
#endif
|
#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 */
|
/** AES-CBC block cipher */
|
||||||
#define CRYPTO_CIPHER_AES_CBC
|
#define CRYPTO_CIPHER_AES_CBC
|
||||||
|
|
||||||
|
/** AES-GCM block cipher */
|
||||||
|
#define CRYPTO_CIPHER_AES_GCM
|
||||||
|
|
||||||
/** MD4 digest algorithm */
|
/** MD4 digest algorithm */
|
||||||
//#define CRYPTO_DIGEST_MD4
|
//#define CRYPTO_DIGEST_MD4
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/dhcppkt.h>
|
#include <ipxe/dhcppkt.h>
|
||||||
#include <ipxe/init.h>
|
#include <ipxe/init.h>
|
||||||
#include <ipxe/netdevice.h>
|
#include <ipxe/netdevice.h>
|
||||||
|
#include <ipxe/vlan.h>
|
||||||
#include <ipxe/cachedhcp.h>
|
#include <ipxe/cachedhcp.h>
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
|
@ -43,6 +44,8 @@ struct cached_dhcp_packet {
|
||||||
const char *name;
|
const char *name;
|
||||||
/** DHCP packet (if any) */
|
/** DHCP packet (if any) */
|
||||||
struct dhcp_packet *dhcppkt;
|
struct dhcp_packet *dhcppkt;
|
||||||
|
/** VLAN tag (if applicable) */
|
||||||
|
unsigned int vlan;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Cached DHCPACK */
|
/** Cached DHCPACK */
|
||||||
|
@ -136,15 +139,26 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
|
||||||
* matches this network device.
|
* matches this network device.
|
||||||
*/
|
*/
|
||||||
if ( memcmp ( ll_addr, chaddr, ll_addr_len ) != 0 ) {
|
if ( memcmp ( ll_addr, chaddr, ll_addr_len ) != 0 ) {
|
||||||
DBGC ( colour, "CACHEDHCP %s does not match %s\n",
|
DBGC ( colour, "CACHEDHCP %s %s does not match %s\n",
|
||||||
cache->name, netdev->name );
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
DBGC ( colour, "CACHEDHCP %s is for %s\n",
|
|
||||||
cache->name, netdev->name );
|
|
||||||
|
|
||||||
/* Use network device's settings block */
|
/* Use network device's settings block */
|
||||||
settings = netdev_settings ( netdev );
|
settings = netdev_settings ( netdev );
|
||||||
|
DBGC ( colour, "CACHEDHCP %s is for %s\n",
|
||||||
|
cache->name, netdev->name );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register settings */
|
/* Register settings */
|
||||||
|
@ -165,12 +179,13 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
|
||||||
* Record cached DHCP packet
|
* Record cached DHCP packet
|
||||||
*
|
*
|
||||||
* @v cache Cached DHCP packet
|
* @v cache Cached DHCP packet
|
||||||
|
* @v vlan VLAN tag, if any
|
||||||
* @v data DHCPACK packet buffer
|
* @v data DHCPACK packet buffer
|
||||||
* @v max_len Maximum possible length
|
* @v max_len Maximum possible length
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
|
int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan,
|
||||||
size_t max_len ) {
|
userptr_t data, size_t max_len ) {
|
||||||
struct dhcp_packet *dhcppkt;
|
struct dhcp_packet *dhcppkt;
|
||||||
struct dhcp_packet *tmp;
|
struct dhcp_packet *tmp;
|
||||||
struct dhcphdr *dhcphdr;
|
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,
|
DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name,
|
||||||
user_to_phys ( data, 0 ), len, max_len );
|
user_to_phys ( data, 0 ), len, max_len );
|
||||||
cache->dhcppkt = dhcppkt;
|
cache->dhcppkt = dhcppkt;
|
||||||
|
cache->vlan = vlan;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached DHCPACK startup function
|
* Cached DHCP packet startup function
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void cachedhcp_startup ( void ) {
|
static void cachedhcp_startup ( void ) {
|
||||||
|
|
||||||
/* Apply cached ProxyDHCPOFFER, if any */
|
/* Apply cached ProxyDHCPOFFER, if any */
|
||||||
cachedhcp_apply ( &cached_proxydhcp, NULL );
|
cachedhcp_apply ( &cached_proxydhcp, NULL );
|
||||||
|
cachedhcp_free ( &cached_proxydhcp );
|
||||||
|
|
||||||
/* Apply cached PXEBSACK, if any */
|
/* Apply cached PXEBSACK, if any */
|
||||||
cachedhcp_apply ( &cached_pxebs, NULL );
|
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 ) {
|
if ( cached_dhcpack.dhcppkt ) {
|
||||||
DBGC ( colour, "CACHEDHCP %s unclaimed\n",
|
DBGC ( colour, "CACHEDHCP %s unclaimed\n",
|
||||||
cached_dhcpack.name );
|
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_dhcpack );
|
||||||
cachedhcp_free ( &cached_proxydhcp );
|
|
||||||
cachedhcp_free ( &cached_pxebs );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cached DHCPACK startup function */
|
/** Cached DHCPACK startup function */
|
||||||
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
|
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
|
||||||
.name = "cachedhcp",
|
.name = "cachedhcp",
|
||||||
.startup = cachedhcp_startup,
|
.startup = cachedhcp_startup,
|
||||||
|
.shutdown = cachedhcp_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/crypto.h>
|
#include <ipxe/crypto.h>
|
||||||
#include <ipxe/ecb.h>
|
#include <ipxe/ecb.h>
|
||||||
#include <ipxe/cbc.h>
|
#include <ipxe/cbc.h>
|
||||||
|
#include <ipxe/gcm.h>
|
||||||
#include <ipxe/aes.h>
|
#include <ipxe/aes.h>
|
||||||
|
|
||||||
/** AES strides
|
/** AES strides
|
||||||
|
@ -778,25 +779,18 @@ static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
|
||||||
return 0;
|
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 */
|
/** Basic AES algorithm */
|
||||||
struct cipher_algorithm aes_algorithm = {
|
struct cipher_algorithm aes_algorithm = {
|
||||||
.name = "aes",
|
.name = "aes",
|
||||||
.ctxsize = sizeof ( struct aes_context ),
|
.ctxsize = sizeof ( struct aes_context ),
|
||||||
.blocksize = AES_BLOCKSIZE,
|
.blocksize = AES_BLOCKSIZE,
|
||||||
|
.alignsize = 0,
|
||||||
|
.authsize = 0,
|
||||||
.setkey = aes_setkey,
|
.setkey = aes_setkey,
|
||||||
.setiv = aes_setiv,
|
.setiv = cipher_null_setiv,
|
||||||
.encrypt = aes_encrypt,
|
.encrypt = aes_encrypt,
|
||||||
.decrypt = aes_decrypt,
|
.decrypt = aes_decrypt,
|
||||||
|
.auth = cipher_null_auth,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* AES in Electronic Codebook mode */
|
/* AES in Electronic Codebook mode */
|
||||||
|
@ -806,3 +800,7 @@ ECB_CIPHER ( aes_ecb, aes_ecb_algorithm,
|
||||||
/* AES in Cipher Block Chaining mode */
|
/* AES in Cipher Block Chaining mode */
|
||||||
CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
|
CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
|
||||||
aes_algorithm, struct aes_context, AES_BLOCKSIZE );
|
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;
|
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
|
* Perform ARC4 encryption or decryption, skipping initial keystream bytes
|
||||||
*
|
*
|
||||||
|
@ -125,8 +119,11 @@ struct cipher_algorithm arc4_algorithm = {
|
||||||
.name = "ARC4",
|
.name = "ARC4",
|
||||||
.ctxsize = ARC4_CTX_SIZE,
|
.ctxsize = ARC4_CTX_SIZE,
|
||||||
.blocksize = 1,
|
.blocksize = 1,
|
||||||
|
.alignsize = 1,
|
||||||
|
.authsize = 0,
|
||||||
.setkey = arc4_setkey,
|
.setkey = arc4_setkey,
|
||||||
.setiv = arc4_setiv,
|
.setiv = cipher_null_setiv,
|
||||||
.encrypt = arc4_xor,
|
.encrypt = arc4_xor,
|
||||||
.decrypt = arc4_xor,
|
.decrypt = arc4_xor,
|
||||||
|
.auth = cipher_null_auth,
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,16 +32,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ipxe/crypto.h>
|
#include <ipxe/crypto.h>
|
||||||
|
|
||||||
static void digest_null_init ( void *ctx __unused ) {
|
void digest_null_init ( void *ctx __unused ) {
|
||||||
/* Do nothing */
|
/* 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 ) {
|
size_t len __unused ) {
|
||||||
/* Do nothing */
|
/* 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 */
|
/* Do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,68 +55,72 @@ struct digest_algorithm digest_null = {
|
||||||
.final = digest_null_final,
|
.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 ) {
|
size_t keylen __unused ) {
|
||||||
/* Do nothing */
|
/* Do nothing */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cipher_null_setiv ( void *ctx __unused,
|
void cipher_null_setiv ( void *ctx __unused, const void *iv __unused,
|
||||||
const void *iv __unused ) {
|
size_t ivlen __unused ) {
|
||||||
/* Do nothing */
|
/* Do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cipher_null_encrypt ( void *ctx __unused, const void *src,
|
void cipher_null_encrypt ( void *ctx __unused, const void *src, void *dst,
|
||||||
void *dst, size_t len ) {
|
size_t len ) {
|
||||||
memcpy ( dst, src, len );
|
memcpy ( dst, src, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cipher_null_decrypt ( void *ctx __unused, const void *src,
|
void cipher_null_decrypt ( void *ctx __unused, const void *src, void *dst,
|
||||||
void *dst, size_t len ) {
|
size_t len ) {
|
||||||
memcpy ( dst, src, len );
|
memcpy ( dst, src, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cipher_null_auth ( void *ctx __unused, void *auth __unused ) {
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
struct cipher_algorithm cipher_null = {
|
struct cipher_algorithm cipher_null = {
|
||||||
.name = "null",
|
.name = "null",
|
||||||
.ctxsize = 0,
|
.ctxsize = 0,
|
||||||
.blocksize = 1,
|
.blocksize = 1,
|
||||||
|
.alignsize = 1,
|
||||||
|
.authsize = 0,
|
||||||
.setkey = cipher_null_setkey,
|
.setkey = cipher_null_setkey,
|
||||||
.setiv = cipher_null_setiv,
|
.setiv = cipher_null_setiv,
|
||||||
.encrypt = cipher_null_encrypt,
|
.encrypt = cipher_null_encrypt,
|
||||||
.decrypt = cipher_null_decrypt,
|
.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 ) {
|
size_t key_len __unused ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t pubkey_null_max_len ( void *ctx __unused ) {
|
size_t pubkey_null_max_len ( void *ctx __unused ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pubkey_null_encrypt ( void *ctx __unused,
|
int pubkey_null_encrypt ( void *ctx __unused, const void *plaintext __unused,
|
||||||
const void *plaintext __unused,
|
|
||||||
size_t plaintext_len __unused,
|
size_t plaintext_len __unused,
|
||||||
void *ciphertext __unused ) {
|
void *ciphertext __unused ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pubkey_null_decrypt ( void *ctx __unused,
|
int pubkey_null_decrypt ( void *ctx __unused, const void *ciphertext __unused,
|
||||||
const void *ciphertext __unused,
|
|
||||||
size_t ciphertext_len __unused,
|
size_t ciphertext_len __unused,
|
||||||
void *plaintext __unused ) {
|
void *plaintext __unused ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pubkey_null_sign ( void *ctx __unused,
|
int pubkey_null_sign ( void *ctx __unused,
|
||||||
struct digest_algorithm *digest __unused,
|
struct digest_algorithm *digest __unused,
|
||||||
const void *value __unused,
|
const void *value __unused, void *signature __unused ) {
|
||||||
void *signature __unused ) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pubkey_null_verify ( void *ctx __unused,
|
int pubkey_null_verify ( void *ctx __unused,
|
||||||
struct digest_algorithm *digest __unused,
|
struct digest_algorithm *digest __unused,
|
||||||
const void *value __unused,
|
const void *value __unused,
|
||||||
const void *signature __unused ,
|
const void *signature __unused ,
|
||||||
|
@ -124,7 +128,7 @@ static int pubkey_null_verify ( void *ctx __unused,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pubkey_null_final ( void *ctx __unused ) {
|
void pubkey_null_final ( void *ctx __unused ) {
|
||||||
/* Do nothing */
|
/* 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/crypto.h>
|
||||||
#include <ipxe/hmac.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
|
* Initialise HMAC
|
||||||
*
|
*
|
||||||
* @v digest Digest algorithm to use
|
* @v digest Digest algorithm to use
|
||||||
* @v digest_ctx Digest context
|
* @v ctx HMAC context
|
||||||
* @v key Key
|
* @v key Key
|
||||||
* @v key_len Length of 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 hmac_init ( struct digest_algorithm *digest, void *ctx, const void *key,
|
||||||
void *key, size_t *key_len ) {
|
size_t key_len ) {
|
||||||
unsigned char k_ipad[digest->blocksize];
|
hmac_context_t ( digest ) *hctx = ctx;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Reduce key if necessary */
|
|
||||||
if ( *key_len > sizeof ( k_ipad ) )
|
|
||||||
hmac_reduce_key ( digest, key, key_len );
|
|
||||||
|
|
||||||
/* Construct input pad */
|
/* Construct input pad */
|
||||||
memset ( k_ipad, 0, sizeof ( k_ipad ) );
|
memset ( hctx->pad, 0, sizeof ( hctx->pad ) );
|
||||||
memcpy ( k_ipad, key, *key_len );
|
if ( key_len <= sizeof ( hctx->pad ) ) {
|
||||||
for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) {
|
memcpy ( hctx->pad, key, key_len );
|
||||||
k_ipad[i] ^= 0x36;
|
} 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 */
|
/* Start inner hash */
|
||||||
digest_init ( digest, digest_ctx );
|
digest_init ( digest, hctx->ctx );
|
||||||
digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) );
|
digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalise HMAC
|
* Finalise HMAC
|
||||||
*
|
*
|
||||||
* @v digest Digest algorithm to use
|
* @v digest Digest algorithm to use
|
||||||
* @v digest_ctx Digest context
|
* @v ctx HMAC context
|
||||||
* @v key Key
|
|
||||||
* @v key_len Length of key
|
|
||||||
* @v hmac HMAC digest to fill in
|
* @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 hmac_final ( struct digest_algorithm *digest, void *ctx, void *hmac ) {
|
||||||
void *key, size_t *key_len, void *hmac ) {
|
hmac_context_t ( digest ) *hctx = ctx;
|
||||||
unsigned char k_opad[digest->blocksize];
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Reduce key if necessary */
|
/* Construct output pad from input pad */
|
||||||
if ( *key_len > sizeof ( k_opad ) )
|
for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) {
|
||||||
hmac_reduce_key ( digest, key, key_len );
|
hctx->pad[i] ^= 0x6a;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish inner hash */
|
/* Finish inner hash */
|
||||||
digest_final ( digest, digest_ctx, hmac );
|
digest_final ( digest, hctx->ctx, hmac );
|
||||||
|
|
||||||
/* Perform outer hash */
|
/* Perform outer hash */
|
||||||
digest_init ( digest, digest_ctx );
|
digest_init ( digest, hctx->ctx );
|
||||||
digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) );
|
digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
|
||||||
digest_update ( digest, digest_ctx, hmac, digest->digestsize );
|
digest_update ( digest, hctx->ctx, hmac, digest->digestsize );
|
||||||
digest_final ( digest, digest_ctx, hmac );
|
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,
|
struct hmac_drbg_state *state,
|
||||||
const void *data, size_t len,
|
const void *data, size_t len,
|
||||||
const uint8_t single ) {
|
const uint8_t single ) {
|
||||||
uint8_t context[ hash->ctxsize ];
|
uint8_t context[ hmac_ctxsize ( hash ) ];
|
||||||
size_t out_len = hash->digestsize;
|
size_t out_len = hash->digestsize;
|
||||||
|
|
||||||
DBGC ( state, "HMAC_DRBG_%s %p provided data :\n", hash->name, state );
|
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 ) );
|
assert ( ( single == 0x00 ) || ( single == 0x01 ) );
|
||||||
|
|
||||||
/* K = HMAC ( K, V || single || provided_data ) */
|
/* K = HMAC ( K, V || single || provided_data ) */
|
||||||
hmac_init ( hash, context, state->key, &out_len );
|
hmac_init ( hash, context, state->key, out_len );
|
||||||
assert ( out_len == hash->digestsize );
|
|
||||||
hmac_update ( hash, context, state->value, out_len );
|
hmac_update ( hash, context, state->value, out_len );
|
||||||
hmac_update ( hash, context, &single, sizeof ( single ) );
|
hmac_update ( hash, context, &single, sizeof ( single ) );
|
||||||
hmac_update ( hash, context, data, len );
|
hmac_update ( hash, context, data, len );
|
||||||
hmac_final ( hash, context, state->key, &out_len, state->key );
|
hmac_final ( hash, context, state->key );
|
||||||
assert ( out_len == hash->digestsize );
|
|
||||||
|
|
||||||
DBGC ( state, "HMAC_DRBG_%s %p K = HMAC ( K, V || %#02x || "
|
DBGC ( state, "HMAC_DRBG_%s %p K = HMAC ( K, V || %#02x || "
|
||||||
"provided_data ) :\n", hash->name, state, single );
|
"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,
|
static void hmac_drbg_update_value ( struct digest_algorithm *hash,
|
||||||
struct hmac_drbg_state *state ) {
|
struct hmac_drbg_state *state ) {
|
||||||
uint8_t context[ hash->ctxsize ];
|
uint8_t context[ hmac_ctxsize ( hash ) ];
|
||||||
size_t out_len = hash->digestsize;
|
size_t out_len = hash->digestsize;
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
|
@ -130,11 +128,9 @@ static void hmac_drbg_update_value ( struct digest_algorithm *hash,
|
||||||
assert ( state != NULL );
|
assert ( state != NULL );
|
||||||
|
|
||||||
/* V = HMAC ( K, V ) */
|
/* V = HMAC ( K, V ) */
|
||||||
hmac_init ( hash, context, state->key, &out_len );
|
hmac_init ( hash, context, state->key, out_len );
|
||||||
assert ( out_len == hash->digestsize );
|
|
||||||
hmac_update ( hash, context, state->value, out_len );
|
hmac_update ( hash, context, state->value, out_len );
|
||||||
hmac_final ( hash, context, state->key, &out_len, state->value );
|
hmac_final ( hash, context, state->value );
|
||||||
assert ( out_len == hash->digestsize );
|
|
||||||
|
|
||||||
DBGC ( state, "HMAC_DRBG_%s %p V = HMAC ( K, V ) :\n",
|
DBGC ( state, "HMAC_DRBG_%s %p V = HMAC ( K, V ) :\n",
|
||||||
hash->name, state );
|
hash->name, state );
|
||||||
|
|
|
@ -27,22 +27,65 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/rsa.h>
|
#include <ipxe/rsa.h>
|
||||||
#include <ipxe/aes.h>
|
#include <ipxe/aes.h>
|
||||||
#include <ipxe/sha1.h>
|
#include <ipxe/sha1.h>
|
||||||
|
#include <ipxe/sha256.h>
|
||||||
#include <ipxe/tls.h>
|
#include <ipxe/tls.h>
|
||||||
|
|
||||||
/** TLS_RSA_WITH_AES_128_CBC_SHA cipher suite */
|
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA cipher suite */
|
||||||
struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite (03) = {
|
struct tls_cipher_suite
|
||||||
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ),
|
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 ),
|
.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,
|
.pubkey = &rsa_algorithm,
|
||||||
.cipher = &aes_cbc_algorithm,
|
.cipher = &aes_cbc_algorithm,
|
||||||
.digest = &sha1_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 */
|
/** 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 ),
|
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ),
|
||||||
.key_len = ( 256 / 8 ),
|
.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,
|
.pubkey = &rsa_algorithm,
|
||||||
.cipher = &aes_cbc_algorithm,
|
.cipher = &aes_cbc_algorithm,
|
||||||
.digest = &sha1_algorithm,
|
.digest = &sha1_algorithm,
|
||||||
|
.handshake = &sha256_algorithm,
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,20 +29,62 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/sha256.h>
|
#include <ipxe/sha256.h>
|
||||||
#include <ipxe/tls.h>
|
#include <ipxe/tls.h>
|
||||||
|
|
||||||
/** TLS_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
|
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
|
||||||
struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite(01)={
|
struct tls_cipher_suite
|
||||||
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ),
|
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 ),
|
.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,
|
.pubkey = &rsa_algorithm,
|
||||||
.cipher = &aes_cbc_algorithm,
|
.cipher = &aes_cbc_algorithm,
|
||||||
.digest = &sha256_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 */
|
/** 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 ),
|
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ),
|
||||||
.key_len = ( 256 / 8 ),
|
.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,
|
.pubkey = &rsa_algorithm,
|
||||||
.cipher = &aes_cbc_algorithm,
|
.cipher = &aes_cbc_algorithm,
|
||||||
.digest = &sha256_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;
|
struct digest_algorithm *md5 = &md5_algorithm;
|
||||||
union {
|
union {
|
||||||
uint8_t md4[MD4_CTX_SIZE];
|
uint8_t md4[MD4_CTX_SIZE];
|
||||||
uint8_t md5[MD5_CTX_SIZE];
|
uint8_t md5[ MD5_CTX_SIZE + MD5_BLOCK_SIZE ];
|
||||||
} ctx;
|
} ctx;
|
||||||
uint8_t digest[MD4_DIGEST_SIZE];
|
uint8_t digest[MD4_DIGEST_SIZE];
|
||||||
size_t digest_len;
|
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
uint16_t wc;
|
uint16_t wc;
|
||||||
|
|
||||||
|
@ -141,8 +140,7 @@ void ntlm_key ( const char *domain, const char *username,
|
||||||
digest_final ( md4, ctx.md4, digest );
|
digest_final ( md4, ctx.md4, digest );
|
||||||
|
|
||||||
/* Construct HMAC-MD5 of (Unicode) upper-case username */
|
/* Construct HMAC-MD5 of (Unicode) upper-case username */
|
||||||
digest_len = sizeof ( digest );
|
hmac_init ( md5, ctx.md5, digest, sizeof ( digest ) );
|
||||||
hmac_init ( md5, ctx.md5, digest, &digest_len );
|
|
||||||
while ( ( c = *(username++) ) ) {
|
while ( ( c = *(username++) ) ) {
|
||||||
wc = cpu_to_le16 ( toupper ( c ) );
|
wc = cpu_to_le16 ( toupper ( c ) );
|
||||||
hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
|
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 );
|
wc = cpu_to_le16 ( c );
|
||||||
hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
|
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 ( key, "NTLM key:\n" );
|
||||||
DBGC_HDA ( key, 0, key, sizeof ( *key ) );
|
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 ntlm_nt_response *nt ) {
|
||||||
struct digest_algorithm *md5 = &md5_algorithm;
|
struct digest_algorithm *md5 = &md5_algorithm;
|
||||||
struct ntlm_nonce tmp_nonce;
|
struct ntlm_nonce tmp_nonce;
|
||||||
uint8_t ctx[MD5_CTX_SIZE];
|
uint8_t ctx[ MD5_CTX_SIZE + MD5_BLOCK_SIZE ];
|
||||||
size_t key_len = sizeof ( *key );
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Generate random nonce, if needed */
|
/* 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 */
|
/* Construct LAN Manager response */
|
||||||
memcpy ( &lm->nonce, nonce, sizeof ( lm->nonce ) );
|
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, info->nonce, sizeof ( *info->nonce ) );
|
||||||
hmac_update ( md5, ctx, &lm->nonce, sizeof ( lm->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 ( key, "NTLM LAN Manager response:\n" );
|
||||||
DBGC_HDA ( key, 0, lm, sizeof ( *lm ) );
|
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->version = NTLM_VERSION_NTLMV2;
|
||||||
nt->high = NTLM_VERSION_NTLMV2;
|
nt->high = NTLM_VERSION_NTLMV2;
|
||||||
memcpy ( &nt->nonce, nonce, sizeof ( nt->nonce ) );
|
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, info->nonce, sizeof ( *info->nonce ) );
|
||||||
hmac_update ( md5, ctx, &nt->version,
|
hmac_update ( md5, ctx, &nt->version,
|
||||||
( sizeof ( *nt ) -
|
( sizeof ( *nt ) -
|
||||||
offsetof ( typeof ( *nt ), version ) ) );
|
offsetof ( typeof ( *nt ), version ) ) );
|
||||||
hmac_update ( md5, ctx, info->target, info->len );
|
hmac_update ( md5, ctx, info->target, info->len );
|
||||||
hmac_update ( md5, ctx, &nt->zero, sizeof ( nt->zero ) );
|
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 ( key, "NTLM NT response prefix:\n" );
|
||||||
DBGC_HDA ( key, 0, nt, sizeof ( *nt ) );
|
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[strlen ( label ) + 1 + data_len + 1]; /* message to HMAC */
|
||||||
u8 *in_blknr; /* pointer to last byte of in, block number */
|
u8 *in_blknr; /* pointer to last byte of in, block number */
|
||||||
u8 out[SHA1_DIGEST_SIZE]; /* HMAC-SHA1 result */
|
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 );
|
const size_t label_len = strlen ( label );
|
||||||
|
|
||||||
/* The HMAC-SHA-1 is calculated using the given key on the
|
/* 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++ ) {
|
for ( blk = 0 ;; blk++ ) {
|
||||||
*in_blknr = blk;
|
*in_blknr = blk;
|
||||||
|
|
||||||
hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len );
|
hmac_init ( &sha1_algorithm, ctx, keym, key_len );
|
||||||
hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) );
|
hmac_update ( &sha1_algorithm, ctx, in, sizeof ( in ) );
|
||||||
hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out );
|
hmac_final ( &sha1_algorithm, ctx, out );
|
||||||
|
|
||||||
if ( prf_len <= sizeof ( out ) ) {
|
if ( prf_len <= sizeof ( out ) ) {
|
||||||
memcpy ( prf, out, prf_len );
|
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 pass[pass_len]; /* modifiable passphrase */
|
||||||
u8 in[salt_len + 4]; /* input buffer to first round */
|
u8 in[salt_len + 4]; /* input buffer to first round */
|
||||||
u8 last[SHA1_DIGEST_SIZE]; /* output of round N, input of N+1 */
|
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 */
|
u8 *next_in = in; /* changed to `last' after first round */
|
||||||
int next_size = sizeof ( in );
|
int next_size = sizeof ( in );
|
||||||
int i;
|
int i;
|
||||||
|
@ -114,9 +114,9 @@ static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
|
||||||
memset ( block, 0, sizeof ( last ) );
|
memset ( block, 0, sizeof ( last ) );
|
||||||
|
|
||||||
for ( i = 0; i < iterations; i++ ) {
|
for ( i = 0; i < iterations; i++ ) {
|
||||||
hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len );
|
hmac_init ( &sha1_algorithm, ctx, pass, pass_len );
|
||||||
hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size );
|
hmac_update ( &sha1_algorithm, ctx, next_in, next_size );
|
||||||
hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last );
|
hmac_final ( &sha1_algorithm, ctx, last );
|
||||||
|
|
||||||
for ( j = 0; j < sizeof ( last ); j++ ) {
|
for ( j = 0; j < sizeof ( last ); j++ ) {
|
||||||
block[j] ^= 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 pci PCI device to fill in
|
||||||
* @v busdevfn Starting bus:dev.fn address
|
* @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 ) {
|
int pci_find_next ( struct pci_device *pci, uint32_t *busdevfn ) {
|
||||||
static unsigned int end;
|
static struct pci_range range;
|
||||||
unsigned int sub_end;
|
|
||||||
uint8_t hdrtype;
|
uint8_t hdrtype;
|
||||||
uint8_t sub;
|
uint8_t sub;
|
||||||
|
uint32_t end;
|
||||||
|
unsigned int count;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Determine number of PCI buses */
|
|
||||||
if ( ! end )
|
|
||||||
end = PCI_BUSDEVFN ( 0, pci_num_bus(), 0, 0 );
|
|
||||||
|
|
||||||
/* Find next PCI device, if any */
|
/* 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 */
|
/* Check for PCI device existence */
|
||||||
memset ( pci, 0, sizeof ( *pci ) );
|
memset ( pci, 0, sizeof ( *pci ) );
|
||||||
pci_init ( pci, busdevfn );
|
pci_init ( pci, *busdevfn );
|
||||||
if ( ( rc = pci_read_config ( pci ) ) != 0 )
|
if ( ( rc = pci_read_config ( pci ) ) != 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If device is a bridge, expand the number of PCI
|
/* If device is a bridge, expand the PCI bus:dev.fn
|
||||||
* buses as needed.
|
* address range as needed.
|
||||||
*/
|
*/
|
||||||
pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
|
pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
|
||||||
hdrtype &= PCI_HEADER_TYPE_MASK;
|
hdrtype &= PCI_HEADER_TYPE_MASK;
|
||||||
if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
|
if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
|
||||||
pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
|
pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
|
||||||
sub_end = PCI_BUSDEVFN ( 0, ( sub + 1 ), 0, 0 );
|
end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
|
||||||
if ( end < sub_end ) {
|
( sub + 1 ), 0, 0 );
|
||||||
|
count = ( end - range.start );
|
||||||
|
if ( count > range.count ) {
|
||||||
DBGC ( pci, PCI_FMT " found subordinate bus "
|
DBGC ( pci, PCI_FMT " found subordinate bus "
|
||||||
"%#02x\n", PCI_ARGS ( pci ), sub );
|
"%#02x\n", PCI_ARGS ( pci ), sub );
|
||||||
end = sub_end;
|
range.count = count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return this device */
|
/* Return this device */
|
||||||
return busdevfn;
|
return 0;
|
||||||
}
|
|
||||||
|
} while ( ++(*busdevfn) );
|
||||||
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -348,11 +357,10 @@ void pci_remove ( struct pci_device *pci ) {
|
||||||
*/
|
*/
|
||||||
static int pcibus_probe ( struct root_device *rootdev ) {
|
static int pcibus_probe ( struct root_device *rootdev ) {
|
||||||
struct pci_device *pci = NULL;
|
struct pci_device *pci = NULL;
|
||||||
int busdevfn = 0;
|
uint32_t busdevfn = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
for ( busdevfn = 0 ; 1 ; busdevfn++ ) {
|
do {
|
||||||
|
|
||||||
/* Allocate struct pci_device */
|
/* Allocate struct pci_device */
|
||||||
if ( ! pci )
|
if ( ! pci )
|
||||||
pci = malloc ( sizeof ( *pci ) );
|
pci = malloc ( sizeof ( *pci ) );
|
||||||
|
@ -362,8 +370,7 @@ static int pcibus_probe ( struct root_device *rootdev ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find next PCI device, if any */
|
/* Find next PCI device, if any */
|
||||||
busdevfn = pci_find_next ( pci, busdevfn );
|
if ( ( rc = pci_find_next ( pci, &busdevfn ) ) != 0 )
|
||||||
if ( busdevfn < 0 )
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Look for a driver */
|
/* Look for a driver */
|
||||||
|
@ -386,7 +393,8 @@ static int pcibus_probe ( struct root_device *rootdev ) {
|
||||||
/* Not registered; re-use struct pci_device */
|
/* Not registered; re-use struct pci_device */
|
||||||
list_del ( &pci->dev.siblings );
|
list_del ( &pci->dev.siblings );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} while ( ++busdevfn );
|
||||||
|
|
||||||
free ( pci );
|
free ( pci );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -61,14 +61,15 @@ pci_backup_excluded ( struct pci_device *pci, unsigned int offset,
|
||||||
*
|
*
|
||||||
* @v pci PCI device
|
* @v pci PCI device
|
||||||
* @v backup PCI configuration space backup
|
* @v backup PCI configuration space backup
|
||||||
|
* @v limit Maximum offset in PCI configuration space
|
||||||
* @v exclude PCI configuration space backup exclusion list, or NULL
|
* @v exclude PCI configuration space backup exclusion list, or NULL
|
||||||
*/
|
*/
|
||||||
void pci_backup ( struct pci_device *pci, struct pci_config_backup *backup,
|
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;
|
unsigned int offset;
|
||||||
uint32_t *dword;
|
uint32_t *dword;
|
||||||
|
|
||||||
for ( offset = 0, dword = backup->dwords ; offset < 0x100 ;
|
for ( offset = 0, dword = backup->dwords ; offset < limit ;
|
||||||
offset += sizeof ( *dword ) , dword++ ) {
|
offset += sizeof ( *dword ) , dword++ ) {
|
||||||
if ( ! pci_backup_excluded ( pci, offset, exclude ) )
|
if ( ! pci_backup_excluded ( pci, offset, exclude ) )
|
||||||
pci_read_config_dword ( pci, offset, dword );
|
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 pci PCI device
|
||||||
* @v backup PCI configuration space backup
|
* @v backup PCI configuration space backup
|
||||||
|
* @v limit Maximum offset in PCI configuration space
|
||||||
* @v exclude PCI configuration space backup exclusion list, or NULL
|
* @v exclude PCI configuration space backup exclusion list, or NULL
|
||||||
*/
|
*/
|
||||||
void pci_restore ( struct pci_device *pci, struct pci_config_backup *backup,
|
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;
|
unsigned int offset;
|
||||||
uint32_t *dword;
|
uint32_t *dword;
|
||||||
|
|
||||||
for ( offset = 0, dword = backup->dwords ; offset < 0x100 ;
|
for ( offset = 0, dword = backup->dwords ; offset < limit ;
|
||||||
offset += sizeof ( *dword ) , dword++ ) {
|
offset += sizeof ( *dword ) , dword++ ) {
|
||||||
if ( ! pci_backup_excluded ( pci, offset, exclude ) )
|
if ( ! pci_backup_excluded ( pci, offset, exclude ) )
|
||||||
pci_write_config_dword ( pci, offset, *dword );
|
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 <stdint.h>
|
||||||
#include <ipxe/timer.h>
|
#include <ipxe/timer.h>
|
||||||
#include <ipxe/pci.h>
|
#include <ipxe/pci.h>
|
||||||
|
#include <ipxe/pcibackup.h>
|
||||||
|
|
||||||
static int pci_find_capability_common ( struct pci_device *pci,
|
static int pci_find_capability_common ( struct pci_device *pci,
|
||||||
uint8_t pos, int cap ) {
|
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
|
* @v exp PCI Express Capability address
|
||||||
*/
|
*/
|
||||||
void pci_reset ( struct pci_device *pci, unsigned int exp ) {
|
void pci_reset ( struct pci_device *pci, unsigned int exp ) {
|
||||||
|
struct pci_config_backup backup;
|
||||||
uint16_t control;
|
uint16_t control;
|
||||||
|
|
||||||
|
/* Back up configuration space */
|
||||||
|
pci_backup ( pci, &backup, PCI_CONFIG_BACKUP_STANDARD, NULL );
|
||||||
|
|
||||||
/* Perform a PCIe function-level reset */
|
/* Perform a PCIe function-level reset */
|
||||||
pci_read_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), &control );
|
pci_read_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), &control );
|
||||||
control |= PCI_EXP_DEVCTL_FLR;
|
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 */
|
/* Allow time for reset to complete */
|
||||||
mdelay ( PCI_EXP_FLR_DELAY_MS );
|
mdelay ( PCI_EXP_FLR_DELAY_MS );
|
||||||
|
|
||||||
/* Re-enable device */
|
/* Restore configuration */
|
||||||
adjust_pci_device ( pci );
|
pci_restore ( pci, &backup, PCI_CONFIG_BACKUP_STANDARD, NULL );
|
||||||
}
|
}
|
||||||
|
|
|
@ -2561,7 +2561,7 @@ static void arbel_reset ( struct arbel *arbel ) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Perform device reset and preserve PCI configuration */
|
/* 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,
|
writel ( ARBEL_RESET_MAGIC,
|
||||||
( arbel->config + ARBEL_RESET_OFFSET ) );
|
( arbel->config + ARBEL_RESET_OFFSET ) );
|
||||||
for ( i = 0 ; i < ARBEL_RESET_WAIT_TIME_MS ; i++ ) {
|
for ( i = 0 ; i < ARBEL_RESET_WAIT_TIME_MS ; i++ ) {
|
||||||
|
@ -2570,7 +2570,7 @@ static void arbel_reset ( struct arbel *arbel ) {
|
||||||
if ( vendor != 0xffff )
|
if ( vendor != 0xffff )
|
||||||
break;
|
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, 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, 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, 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 = {
|
struct pci_driver golan_driver __pci_driver = {
|
||||||
|
|
|
@ -2840,7 +2840,7 @@ static int hermon_reset ( struct hermon *hermon ) {
|
||||||
hermon->toggle = 0;
|
hermon->toggle = 0;
|
||||||
|
|
||||||
/* Perform device reset and preserve PCI configuration */
|
/* 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,
|
writel ( HERMON_RESET_MAGIC,
|
||||||
( hermon->config + HERMON_RESET_OFFSET ) );
|
( hermon->config + HERMON_RESET_OFFSET ) );
|
||||||
|
|
||||||
|
@ -2852,7 +2852,8 @@ static int hermon_reset ( struct hermon *hermon ) {
|
||||||
if ( vendor == pci->vendor ) {
|
if ( vendor == pci->vendor ) {
|
||||||
|
|
||||||
/* Restore PCI configuration */
|
/* 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",
|
DBGC ( hermon, "Hermon %p reset after %dms\n",
|
||||||
hermon, i );
|
hermon, i );
|
||||||
|
|
|
@ -2256,7 +2256,7 @@ static void qib7322_reset ( struct qib7322 *qib7322, struct pci_device *pci ) {
|
||||||
struct pci_config_backup backup;
|
struct pci_config_backup backup;
|
||||||
|
|
||||||
/* Back up PCI configuration space */
|
/* Back up PCI configuration space */
|
||||||
pci_backup ( pci, &backup, NULL );
|
pci_backup ( pci, &backup, PCI_CONFIG_BACKUP_ALL, NULL );
|
||||||
|
|
||||||
/* Assert reset */
|
/* Assert reset */
|
||||||
memset ( &control, 0, sizeof ( control ) );
|
memset ( &control, 0, sizeof ( control ) );
|
||||||
|
@ -2267,7 +2267,7 @@ static void qib7322_reset ( struct qib7322 *qib7322, struct pci_device *pci ) {
|
||||||
mdelay ( 1000 );
|
mdelay ( 1000 );
|
||||||
|
|
||||||
/* Restore PCI configuration space */
|
/* 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
|
/* 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 ) &&
|
if ( ( rc = acpi_mac ( amac ) ) == 0 ) {
|
||||||
! find_netdev_by_ll_addr ( ðernet_protocol, amac ) ) {
|
|
||||||
memcpy ( netdev->ll_addr, amac, ETH_ALEN );
|
memcpy ( netdev->ll_addr, amac, ETH_ALEN );
|
||||||
DBGC ( usb, "USB %s using system-specific MAC %s\n",
|
DBGC ( usb, "USB %s using system-specific MAC %s\n",
|
||||||
func->name, eth_ntoa ( netdev->ll_addr ) );
|
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 */
|
/* Locate PCI I/O protocol */
|
||||||
if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
|
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",
|
DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
|
||||||
nii->dev.name, strerror ( rc ) );
|
nii->dev.name, strerror ( rc ) );
|
||||||
goto err_locate;
|
goto err_locate;
|
||||||
|
@ -921,18 +921,17 @@ static int nii_set_station_address ( struct nii_nic *nii,
|
||||||
* Set receive filters
|
* Set receive filters
|
||||||
*
|
*
|
||||||
* @v nii NII NIC
|
* @v nii NII NIC
|
||||||
|
* @v flags Flags
|
||||||
* @ret rc Return status code
|
* @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;
|
uint32_t implementation = nii->undi->Implementation;
|
||||||
unsigned int flags;
|
|
||||||
unsigned int op;
|
unsigned int op;
|
||||||
int stat;
|
int stat;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Construct receive filter set */
|
/* Construct receive filter set */
|
||||||
flags = ( PXE_OPFLAGS_RECEIVE_FILTER_ENABLE |
|
flags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
|
||||||
PXE_OPFLAGS_RECEIVE_FILTER_UNICAST );
|
|
||||||
if ( implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED )
|
if ( implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED )
|
||||||
flags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
|
flags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
|
||||||
if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED )
|
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 );
|
op = NII_OP ( PXE_OPCODE_RECEIVE_FILTERS, flags );
|
||||||
if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
|
if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
|
||||||
rc = -EIO_STAT ( stat );
|
rc = -EIO_STAT ( stat );
|
||||||
DBGC ( nii, "NII %s could not set receive filters %#04x: %s\n",
|
DBGC ( nii, "NII %s could not %s%sable receive filters "
|
||||||
nii->dev.name, flags, strerror ( rc ) );
|
"%#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 rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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
|
* Transmit packet
|
||||||
*
|
*
|
||||||
|
@ -1175,13 +1200,25 @@ static int nii_open ( struct net_device *netdev ) {
|
||||||
/* Treat as non-fatal */
|
/* Treat as non-fatal */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set receive filters */
|
/* Disable receive filters
|
||||||
if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
|
*
|
||||||
goto err_set_rx_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;
|
return 0;
|
||||||
|
|
||||||
err_set_rx_filters:
|
err_enable_rx_filters:
|
||||||
nii_shutdown ( nii );
|
nii_shutdown ( nii );
|
||||||
err_initialise:
|
err_initialise:
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/efi/efi.h>
|
#include <ipxe/efi/efi.h>
|
||||||
#include <ipxe/efi/efi_driver.h>
|
#include <ipxe/efi/efi_driver.h>
|
||||||
#include <ipxe/efi/efi_snp.h>
|
#include <ipxe/efi/efi_snp.h>
|
||||||
|
#include <ipxe/efi/efi_utils.h>
|
||||||
#include "snpnet.h"
|
#include "snpnet.h"
|
||||||
#include "nii.h"
|
#include "nii.h"
|
||||||
|
|
||||||
|
@ -40,34 +41,60 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
* Check to see if driver supports a device
|
* Check to see if driver supports a device
|
||||||
*
|
*
|
||||||
* @v device EFI device handle
|
* @v device EFI device handle
|
||||||
|
* @v protocol Protocol GUID
|
||||||
* @ret rc Return status code
|
* @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_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
|
EFI_HANDLE parent;
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* Check that this is not a device we are providing ourselves */
|
/* Check that this is not a device we are providing ourselves */
|
||||||
if ( find_snpdev ( device ) != NULL ) {
|
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 ) );
|
efi_handle_name ( device ) );
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test for presence of simple network protocol */
|
/* Test for presence of protocol */
|
||||||
if ( ( efirc = bs->OpenProtocol ( device,
|
if ( ( efirc = bs->OpenProtocol ( device, protocol,
|
||||||
&efi_simple_network_protocol_guid,
|
|
||||||
NULL, efi_image_handle, device,
|
NULL, efi_image_handle, device,
|
||||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
|
||||||
DBGCP ( device, "SNP %s is not an SNP device\n",
|
DBGCP ( device, "HANDLE %s is not a %s device\n",
|
||||||
efi_handle_name ( device ) );
|
efi_handle_name ( device ),
|
||||||
|
efi_guid_ntoa ( protocol ) );
|
||||||
return -EEFI ( efirc );
|
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;
|
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
|
* Check to see if driver supports a device
|
||||||
*
|
*
|
||||||
|
@ -75,29 +102,8 @@ static int snp_supported ( EFI_HANDLE device ) {
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int nii_supported ( EFI_HANDLE device ) {
|
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 */
|
return snp_nii_supported ( device, &efi_nii31_protocol_guid );
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** EFI SNP driver */
|
/** EFI SNP driver */
|
||||||
|
|
|
@ -80,7 +80,7 @@ static int chained_locate ( struct chained_protocol *chained ) {
|
||||||
|
|
||||||
/* Locate handle supporting this protocol */
|
/* Locate handle supporting this protocol */
|
||||||
if ( ( rc = efi_locate_device ( device, chained->protocol,
|
if ( ( rc = efi_locate_device ( device, chained->protocol,
|
||||||
&parent ) ) != 0 ) {
|
&parent, 0 ) ) != 0 ) {
|
||||||
DBGC ( device, "CHAINED %s does not support %s: %s\n",
|
DBGC ( device, "CHAINED %s does not support %s: %s\n",
|
||||||
efi_handle_name ( device ),
|
efi_handle_name ( device ),
|
||||||
efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );
|
efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -34,6 +35,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/iobuf.h>
|
#include <ipxe/iobuf.h>
|
||||||
#include <ipxe/malloc.h>
|
#include <ipxe/malloc.h>
|
||||||
#include <ipxe/pci.h>
|
#include <ipxe/pci.h>
|
||||||
|
#include <ipxe/pcibridge.h>
|
||||||
|
#include <ipxe/version.h>
|
||||||
#include "ena.h"
|
#include "ena.h"
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
|
@ -347,6 +350,90 @@ static int ena_admin ( struct ena_nic *ena, union ena_aq_req *req,
|
||||||
return rc;
|
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
|
* Create submission queue
|
||||||
*
|
*
|
||||||
|
@ -359,6 +446,7 @@ static int ena_create_sq ( struct ena_nic *ena, struct ena_sq *sq,
|
||||||
struct ena_cq *cq ) {
|
struct ena_cq *cq ) {
|
||||||
union ena_aq_req *req;
|
union ena_aq_req *req;
|
||||||
union ena_acq_rsp *rsp;
|
union ena_acq_rsp *rsp;
|
||||||
|
unsigned int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Allocate submission queue entries */
|
/* 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->prod = 0;
|
||||||
sq->phase = ENA_SQE_PHASE;
|
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,
|
ena, ena_direction ( sq->direction ), sq->id,
|
||||||
virt_to_phys ( sq->sqe.raw ),
|
virt_to_phys ( sq->sqe.raw ),
|
||||||
( virt_to_phys ( sq->sqe.raw ) + sq->len ),
|
( virt_to_phys ( sq->sqe.raw ) + sq->len ),
|
||||||
sq->doorbell, cq->id );
|
sq->fill, sq->doorbell, cq->id );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_admin:
|
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->header.opcode = ENA_CREATE_CQ;
|
||||||
req->create_cq.size = cq->size;
|
req->create_cq.size = cq->size;
|
||||||
req->create_cq.count = cpu_to_le16 ( cq->requested );
|
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 ) );
|
req->create_cq.address = cpu_to_le64 ( virt_to_bus ( cq->cqe.raw ) );
|
||||||
|
|
||||||
/* Issue request */
|
/* Issue request */
|
||||||
|
@ -596,6 +694,32 @@ static int ena_get_device_attributes ( struct net_device *netdev ) {
|
||||||
return 0;
|
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)
|
* Get statistics (for debugging)
|
||||||
*
|
*
|
||||||
|
@ -652,13 +776,14 @@ static void ena_refill_rx ( struct net_device *netdev ) {
|
||||||
struct ena_nic *ena = netdev->priv;
|
struct ena_nic *ena = netdev->priv;
|
||||||
struct io_buffer *iobuf;
|
struct io_buffer *iobuf;
|
||||||
struct ena_rx_sqe *sqe;
|
struct ena_rx_sqe *sqe;
|
||||||
unsigned int index;
|
|
||||||
physaddr_t address;
|
physaddr_t address;
|
||||||
size_t len = netdev->max_pkt_len;
|
size_t len = netdev->max_pkt_len;
|
||||||
unsigned int refilled = 0;
|
unsigned int refilled = 0;
|
||||||
|
unsigned int index;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
/* Refill queue */
|
/* 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 */
|
/* Allocate I/O buffer */
|
||||||
iobuf = alloc_iob ( len );
|
iobuf = alloc_iob ( len );
|
||||||
|
@ -667,14 +792,15 @@ static void ena_refill_rx ( struct net_device *netdev ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get next submission queue entry */
|
/* Get next submission queue entry and buffer ID */
|
||||||
index = ( ena->rx.sq.prod % ENA_RX_COUNT );
|
index = ( ena->rx.sq.prod % ENA_RX_COUNT );
|
||||||
sqe = &ena->rx.sq.sqe.rx[index];
|
sqe = &ena->rx.sq.sqe.rx[index];
|
||||||
|
id = ena->rx_ids[index];
|
||||||
|
|
||||||
/* Construct submission queue entry */
|
/* Construct submission queue entry */
|
||||||
address = virt_to_bus ( iobuf->data );
|
address = virt_to_bus ( iobuf->data );
|
||||||
sqe->len = cpu_to_le16 ( len );
|
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 );
|
sqe->address = cpu_to_le64 ( address );
|
||||||
wmb();
|
wmb();
|
||||||
sqe->flags = ( ENA_SQE_FIRST | ENA_SQE_LAST | ENA_SQE_CPL |
|
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;
|
ena->rx.sq.phase ^= ENA_SQE_PHASE;
|
||||||
|
|
||||||
/* Record I/O buffer */
|
/* Record I/O buffer */
|
||||||
assert ( ena->rx_iobuf[index] == NULL );
|
assert ( ena->rx_iobuf[id] == NULL );
|
||||||
ena->rx_iobuf[index] = iobuf;
|
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 ),
|
||||||
( ( unsigned long long ) address + len ) );
|
( ( unsigned long long ) address + len ) );
|
||||||
refilled++;
|
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 ) {
|
static int ena_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
|
||||||
struct ena_nic *ena = netdev->priv;
|
struct ena_nic *ena = netdev->priv;
|
||||||
struct ena_tx_sqe *sqe;
|
struct ena_tx_sqe *sqe;
|
||||||
unsigned int index;
|
|
||||||
physaddr_t address;
|
physaddr_t address;
|
||||||
|
unsigned int index;
|
||||||
|
unsigned int id;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* Get next submission queue entry */
|
/* 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 );
|
DBGC ( ena, "ENA %p out of transmit descriptors\n", ena );
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
index = ( ena->tx.sq.prod % ENA_TX_COUNT );
|
index = ( ena->tx.sq.prod % ENA_TX_COUNT );
|
||||||
sqe = &ena->tx.sq.sqe.tx[index];
|
sqe = &ena->tx.sq.sqe.tx[index];
|
||||||
|
id = ena->tx_ids[index];
|
||||||
|
|
||||||
/* Construct submission queue entry */
|
/* Construct submission queue entry */
|
||||||
address = virt_to_bus ( iobuf->data );
|
address = virt_to_bus ( iobuf->data );
|
||||||
len = iob_len ( iobuf );
|
len = iob_len ( iobuf );
|
||||||
sqe->len = cpu_to_le16 ( len );
|
sqe->len = cpu_to_le16 ( len );
|
||||||
sqe->id = ena->tx.sq.prod;
|
sqe->id = cpu_to_le16 ( id );
|
||||||
sqe->address = cpu_to_le64 ( address );
|
sqe->address = cpu_to_le64 ( address );
|
||||||
wmb();
|
wmb();
|
||||||
sqe->flags = ( ENA_SQE_FIRST | ENA_SQE_LAST | ENA_SQE_CPL |
|
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 )
|
if ( ( ena->tx.sq.prod % ENA_TX_COUNT ) == 0 )
|
||||||
ena->tx.sq.phase ^= ENA_SQE_PHASE;
|
ena->tx.sq.phase ^= ENA_SQE_PHASE;
|
||||||
|
|
||||||
|
/* Record I/O buffer */
|
||||||
|
assert ( ena->tx_iobuf[id] == NULL );
|
||||||
|
ena->tx_iobuf[id] = iobuf;
|
||||||
|
|
||||||
/* Ring doorbell */
|
/* Ring doorbell */
|
||||||
writel ( ena->tx.sq.prod, ( ena->regs + ena->tx.sq.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 ),
|
||||||
( ( unsigned long long ) address + len ) );
|
( ( unsigned long long ) address + len ) );
|
||||||
return 0;
|
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 ) {
|
static void ena_poll_tx ( struct net_device *netdev ) {
|
||||||
struct ena_nic *ena = netdev->priv;
|
struct ena_nic *ena = netdev->priv;
|
||||||
struct ena_tx_cqe *cqe;
|
struct ena_tx_cqe *cqe;
|
||||||
|
struct io_buffer *iobuf;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
/* Check for completed packets */
|
/* Check for completed packets */
|
||||||
while ( ena->tx.cq.cons != ena->tx.sq.prod ) {
|
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 */
|
/* Stop if completion queue entry is empty */
|
||||||
if ( ( cqe->flags ^ ena->tx.cq.phase ) & ENA_CQE_PHASE )
|
if ( ( cqe->flags ^ ena->tx.cq.phase ) & ENA_CQE_PHASE )
|
||||||
return;
|
return;
|
||||||
DBGC2 ( ena, "ENA %p TX %d complete\n", ena,
|
|
||||||
( le16_to_cpu ( cqe->id ) >> 2 /* Don't ask */ ) );
|
|
||||||
|
|
||||||
/* Increment consumer counter */
|
/* Increment consumer counter */
|
||||||
ena->tx.cq.cons++;
|
ena->tx.cq.cons++;
|
||||||
if ( ! ( ena->tx.cq.cons & ena->tx.cq.mask ) )
|
if ( ! ( ena->tx.cq.cons & ena->tx.cq.mask ) )
|
||||||
ena->tx.cq.phase ^= ENA_CQE_PHASE;
|
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 */
|
/* 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 ena_rx_cqe *cqe;
|
||||||
struct io_buffer *iobuf;
|
struct io_buffer *iobuf;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
unsigned int id;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* Check for received packets */
|
/* Check for received packets */
|
||||||
while ( ena->rx.cq.cons != ena->rx.sq.prod ) {
|
while ( ena->rx.cq.cons != ena->rx.sq.prod ) {
|
||||||
|
|
||||||
/* Get next completion queue entry */
|
/* 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];
|
cqe = &ena->rx.cq.cqe.rx[index];
|
||||||
|
|
||||||
/* Stop if completion queue entry is empty */
|
/* 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 ) )
|
if ( ! ( ena->rx.cq.cons & ena->rx.cq.mask ) )
|
||||||
ena->rx.cq.phase ^= ENA_CQE_PHASE;
|
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 */
|
/* Populate I/O buffer */
|
||||||
iobuf = ena->rx_iobuf[index];
|
iobuf = ena->rx_iobuf[id];
|
||||||
ena->rx_iobuf[index] = NULL;
|
assert ( iobuf != NULL );
|
||||||
|
ena->rx_iobuf[id] = NULL;
|
||||||
len = le16_to_cpu ( cqe->len );
|
len = le16_to_cpu ( cqe->len );
|
||||||
iob_put ( iobuf, len );
|
iob_put ( iobuf, len );
|
||||||
|
|
||||||
/* Hand off to network stack */
|
/* Hand off to network stack */
|
||||||
DBGC2 ( ena, "ENA %p RX %d complete (length %zd)\n",
|
DBGC2 ( ena, "ENA %p RX %d complete (length %zd)\n",
|
||||||
ena, le16_to_cpu ( cqe->id ), len );
|
ena, id, len );
|
||||||
netdev_rx ( netdev, iobuf );
|
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
|
* Probe PCI device
|
||||||
*
|
*
|
||||||
|
@ -930,6 +1117,7 @@ static struct net_device_operations ena_operations = {
|
||||||
static int ena_probe ( struct pci_device *pci ) {
|
static int ena_probe ( struct pci_device *pci ) {
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct ena_nic *ena;
|
struct ena_nic *ena;
|
||||||
|
struct ena_host_info *info;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Allocate and initialise net device */
|
/* Allocate and initialise net device */
|
||||||
|
@ -946,16 +1134,20 @@ static int ena_probe ( struct pci_device *pci ) {
|
||||||
ena->acq.phase = ENA_ACQ_PHASE;
|
ena->acq.phase = ENA_ACQ_PHASE;
|
||||||
ena_cq_init ( &ena->tx.cq, ENA_TX_COUNT,
|
ena_cq_init ( &ena->tx.cq, ENA_TX_COUNT,
|
||||||
sizeof ( ena->tx.cq.cqe.tx[0] ) );
|
sizeof ( ena->tx.cq.cqe.tx[0] ) );
|
||||||
ena_sq_init ( &ena->tx.sq, ENA_SQ_TX, ENA_TX_COUNT,
|
ena_sq_init ( &ena->tx.sq, ENA_SQ_TX, ENA_TX_COUNT, ENA_TX_COUNT,
|
||||||
sizeof ( ena->tx.sq.sqe.tx[0] ) );
|
sizeof ( ena->tx.sq.sqe.tx[0] ), ena->tx_ids );
|
||||||
ena_cq_init ( &ena->rx.cq, ENA_RX_COUNT,
|
ena_cq_init ( &ena->rx.cq, ENA_RX_COUNT,
|
||||||
sizeof ( ena->rx.cq.cqe.rx[0] ) );
|
sizeof ( ena->rx.cq.cqe.rx[0] ) );
|
||||||
ena_sq_init ( &ena->rx.sq, ENA_SQ_RX, ENA_RX_COUNT,
|
ena_sq_init ( &ena->rx.sq, ENA_SQ_RX, ENA_RX_COUNT, ENA_RX_FILL,
|
||||||
sizeof ( ena->rx.sq.sqe.rx[0] ) );
|
sizeof ( ena->rx.sq.sqe.rx[0] ), ena->rx_ids );
|
||||||
|
|
||||||
/* Fix up PCI device */
|
/* Fix up PCI device */
|
||||||
adjust_pci_device ( pci );
|
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 */
|
/* Map registers */
|
||||||
ena->regs = pci_ioremap ( pci, pci->membase, ENA_BAR_SIZE );
|
ena->regs = pci_ioremap ( pci, pci->membase, ENA_BAR_SIZE );
|
||||||
if ( ! ena->regs ) {
|
if ( ! ena->regs ) {
|
||||||
|
@ -963,6 +1155,25 @@ static int ena_probe ( struct pci_device *pci ) {
|
||||||
goto err_ioremap;
|
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 */
|
/* Reset the NIC */
|
||||||
if ( ( rc = ena_reset ( ena ) ) != 0 )
|
if ( ( rc = ena_reset ( ena ) ) != 0 )
|
||||||
goto err_reset;
|
goto err_reset;
|
||||||
|
@ -971,6 +1182,14 @@ static int ena_probe ( struct pci_device *pci ) {
|
||||||
if ( ( rc = ena_create_admin ( ena ) ) != 0 )
|
if ( ( rc = ena_create_admin ( ena ) ) != 0 )
|
||||||
goto err_create_admin;
|
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 */
|
/* Fetch MAC address */
|
||||||
if ( ( rc = ena_get_device_attributes ( netdev ) ) != 0 )
|
if ( ( rc = ena_get_device_attributes ( netdev ) ) != 0 )
|
||||||
goto err_get_device_attributes;
|
goto err_get_device_attributes;
|
||||||
|
@ -989,12 +1208,18 @@ static int ena_probe ( struct pci_device *pci ) {
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
err_register_netdev:
|
err_register_netdev:
|
||||||
err_get_device_attributes:
|
err_get_device_attributes:
|
||||||
|
err_set_host_attributes:
|
||||||
|
ena_destroy_async ( ena );
|
||||||
|
err_create_async:
|
||||||
ena_destroy_admin ( ena );
|
ena_destroy_admin ( ena );
|
||||||
err_create_admin:
|
err_create_admin:
|
||||||
ena_reset ( ena );
|
ena_reset ( ena );
|
||||||
err_reset:
|
err_reset:
|
||||||
|
free_phys ( ena->info, PAGE_SIZE );
|
||||||
|
err_info:
|
||||||
iounmap ( ena->regs );
|
iounmap ( ena->regs );
|
||||||
err_ioremap:
|
err_ioremap:
|
||||||
|
err_membase:
|
||||||
netdev_nullify ( netdev );
|
netdev_nullify ( netdev );
|
||||||
netdev_put ( netdev );
|
netdev_put ( netdev );
|
||||||
err_alloc:
|
err_alloc:
|
||||||
|
@ -1013,12 +1238,18 @@ static void ena_remove ( struct pci_device *pci ) {
|
||||||
/* Unregister network device */
|
/* Unregister network device */
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
|
|
||||||
|
/* Destroy async event notification queue */
|
||||||
|
ena_destroy_async ( ena );
|
||||||
|
|
||||||
/* Destroy admin queues */
|
/* Destroy admin queues */
|
||||||
ena_destroy_admin ( ena );
|
ena_destroy_admin ( ena );
|
||||||
|
|
||||||
/* Reset card */
|
/* Reset card */
|
||||||
ena_reset ( ena );
|
ena_reset ( ena );
|
||||||
|
|
||||||
|
/* Free host info */
|
||||||
|
free_phys ( ena->info, PAGE_SIZE );
|
||||||
|
|
||||||
/* Free network device */
|
/* Free network device */
|
||||||
iounmap ( ena->regs );
|
iounmap ( ena->regs );
|
||||||
netdev_nullify ( netdev );
|
netdev_nullify ( netdev );
|
||||||
|
|
|
@ -24,11 +24,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
/** Number of admin completion queue entries */
|
/** Number of admin completion queue entries */
|
||||||
#define ENA_ACQ_COUNT 2
|
#define ENA_ACQ_COUNT 2
|
||||||
|
|
||||||
|
/** Number of async event notification queue entries */
|
||||||
|
#define ENA_AENQ_COUNT 2
|
||||||
|
|
||||||
/** Number of transmit queue entries */
|
/** Number of transmit queue entries */
|
||||||
#define ENA_TX_COUNT 16
|
#define ENA_TX_COUNT 16
|
||||||
|
|
||||||
/** Number of receive queue entries */
|
/** 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 */
|
/** Base address low register offset */
|
||||||
#define ENA_BASE_LO 0x0
|
#define ENA_BASE_LO 0x0
|
||||||
|
@ -57,6 +63,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
/** Maximum time to wait for admin requests */
|
/** Maximum time to wait for admin requests */
|
||||||
#define ENA_ADMIN_MAX_WAIT_MS 5000
|
#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 */
|
/** Device control register */
|
||||||
#define ENA_CTRL 0x54
|
#define ENA_CTRL 0x54
|
||||||
#define ENA_CTRL_RESET 0x00000001UL /**< Reset */
|
#define ENA_CTRL_RESET 0x00000001UL /**< Reset */
|
||||||
|
@ -127,10 +139,99 @@ struct ena_device_attributes {
|
||||||
uint32_t mtu;
|
uint32_t mtu;
|
||||||
} __attribute__ (( packed ));
|
} __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 */
|
/** Feature */
|
||||||
union ena_feature {
|
union ena_feature {
|
||||||
/** Device attributes */
|
/** Device attributes */
|
||||||
struct ena_device_attributes device;
|
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 */
|
/** Submission queue direction */
|
||||||
|
@ -230,6 +331,14 @@ struct ena_create_cq_req {
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
} __attribute__ (( packed ));
|
} __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 */
|
/** Create completion queue response */
|
||||||
struct ena_create_cq_rsp {
|
struct ena_create_cq_rsp {
|
||||||
/** Header */
|
/** Header */
|
||||||
|
@ -292,6 +401,27 @@ struct ena_get_feature_rsp {
|
||||||
union ena_feature feature;
|
union ena_feature feature;
|
||||||
} __attribute__ (( packed ));
|
} __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 */
|
/** Get statistics */
|
||||||
#define ENA_GET_STATS 11
|
#define ENA_GET_STATS 11
|
||||||
|
|
||||||
|
@ -352,6 +482,8 @@ union ena_aq_req {
|
||||||
struct ena_destroy_cq_req destroy_cq;
|
struct ena_destroy_cq_req destroy_cq;
|
||||||
/** Get feature */
|
/** Get feature */
|
||||||
struct ena_get_feature_req get_feature;
|
struct ena_get_feature_req get_feature;
|
||||||
|
/** Set feature */
|
||||||
|
struct ena_set_feature_req set_feature;
|
||||||
/** Get statistics */
|
/** Get statistics */
|
||||||
struct ena_get_stats_req get_stats;
|
struct ena_get_stats_req get_stats;
|
||||||
/** Padding */
|
/** Padding */
|
||||||
|
@ -396,6 +528,28 @@ struct ena_acq {
|
||||||
unsigned int phase;
|
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 */
|
/** Transmit submission queue entry */
|
||||||
struct ena_tx_sqe {
|
struct ena_tx_sqe {
|
||||||
/** Length */
|
/** Length */
|
||||||
|
@ -454,6 +608,9 @@ struct ena_tx_cqe {
|
||||||
uint16_t cons;
|
uint16_t cons;
|
||||||
} __attribute__ (( packed ));
|
} __attribute__ (( packed ));
|
||||||
|
|
||||||
|
/** Transmit completion request identifier */
|
||||||
|
#define ENA_TX_CQE_ID(id) ( (id) >> 2 )
|
||||||
|
|
||||||
/** Receive completion queue entry */
|
/** Receive completion queue entry */
|
||||||
struct ena_rx_cqe {
|
struct ena_rx_cqe {
|
||||||
/** Reserved */
|
/** Reserved */
|
||||||
|
@ -482,6 +639,8 @@ struct ena_sq {
|
||||||
/** Raw data */
|
/** Raw data */
|
||||||
void *raw;
|
void *raw;
|
||||||
} sqe;
|
} sqe;
|
||||||
|
/** Buffer IDs */
|
||||||
|
uint8_t *ids;
|
||||||
/** Doorbell register offset */
|
/** Doorbell register offset */
|
||||||
unsigned int doorbell;
|
unsigned int doorbell;
|
||||||
/** Total length of entries */
|
/** Total length of entries */
|
||||||
|
@ -496,6 +655,10 @@ struct ena_sq {
|
||||||
uint8_t direction;
|
uint8_t direction;
|
||||||
/** Number of entries */
|
/** Number of entries */
|
||||||
uint8_t count;
|
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 sq Submission queue
|
||||||
* @v direction Direction
|
* @v direction Direction
|
||||||
* @v count Number of entries
|
* @v count Number of entries
|
||||||
|
* @v max Maximum fill level
|
||||||
* @v size Size of each entry
|
* @v size Size of each entry
|
||||||
|
* @v ids Buffer IDs
|
||||||
*/
|
*/
|
||||||
static inline __attribute__ (( always_inline )) void
|
static inline __attribute__ (( always_inline )) void
|
||||||
ena_sq_init ( struct ena_sq *sq, unsigned int direction, unsigned int count,
|
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->len = ( count * size );
|
||||||
sq->direction = direction;
|
sq->direction = direction;
|
||||||
sq->count = count;
|
sq->count = count;
|
||||||
|
sq->max = max;
|
||||||
|
sq->ids = ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Completion queue */
|
/** Completion queue */
|
||||||
|
@ -573,15 +740,25 @@ struct ena_qp {
|
||||||
struct ena_nic {
|
struct ena_nic {
|
||||||
/** Registers */
|
/** Registers */
|
||||||
void *regs;
|
void *regs;
|
||||||
|
/** Host info */
|
||||||
|
struct ena_host_info *info;
|
||||||
/** Admin queue */
|
/** Admin queue */
|
||||||
struct ena_aq aq;
|
struct ena_aq aq;
|
||||||
/** Admin completion queue */
|
/** Admin completion queue */
|
||||||
struct ena_acq acq;
|
struct ena_acq acq;
|
||||||
|
/** Async event notification queue */
|
||||||
|
struct ena_aenq aenq;
|
||||||
/** Transmit queue */
|
/** Transmit queue */
|
||||||
struct ena_qp tx;
|
struct ena_qp tx;
|
||||||
/** Receive queue */
|
/** Receive queue */
|
||||||
struct ena_qp rx;
|
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];
|
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, 0x15fa, "i219v-14", "I219-V (14)", INTEL_I219 ),
|
||||||
PCI_ROM ( 0x8086, 0x15fb, "i219lm-13", "I219-LM (13)", 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, 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, 0x1f41, "i354", "I354", INTEL_NO_ASDE ),
|
||||||
PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
|
PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
|
||||||
PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 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 ), \
|
EUNIQ ( EINFO_EIO, ( -(status) & 0x1f ), \
|
||||||
EIO_NETIF_RSP_ERROR, EIO_NETIF_RSP_DROPPED )
|
EIO_NETIF_RSP_ERROR, EIO_NETIF_RSP_DROPPED )
|
||||||
|
|
||||||
|
/** List of netfront devices */
|
||||||
|
static LIST_HEAD ( netfront_devices );
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* XenStore interface
|
* XenStore interface
|
||||||
|
@ -952,6 +955,7 @@ static int netfront_probe ( struct xen_device *xendev ) {
|
||||||
netdev->dev = &xendev->dev;
|
netdev->dev = &xendev->dev;
|
||||||
netfront = netdev->priv;
|
netfront = netdev->priv;
|
||||||
netfront->xendev = xendev;
|
netfront->xendev = xendev;
|
||||||
|
netfront->netdev = netdev;
|
||||||
INIT_LIST_HEAD ( &netfront->rx_partial );
|
INIT_LIST_HEAD ( &netfront->rx_partial );
|
||||||
DBGC ( netfront, "NETFRONT %s backend=\"%s\" in domain %ld\n",
|
DBGC ( netfront, "NETFRONT %s backend=\"%s\" in domain %ld\n",
|
||||||
xendev->key, xendev->backend, xendev->backend_id );
|
xendev->key, xendev->backend, xendev->backend_id );
|
||||||
|
@ -991,9 +995,13 @@ static int netfront_probe ( struct xen_device *xendev ) {
|
||||||
/* Set initial link state */
|
/* Set initial link state */
|
||||||
netdev_link_down ( netdev );
|
netdev_link_down ( netdev );
|
||||||
|
|
||||||
|
/* Add to list of netfront devices */
|
||||||
|
list_add_tail ( &netfront->list, &netfront_devices );
|
||||||
|
|
||||||
xen_set_drvdata ( xendev, netdev );
|
xen_set_drvdata ( xendev, netdev );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
list_del ( &netfront->list );
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
err_register_netdev:
|
err_register_netdev:
|
||||||
err_read_mac:
|
err_read_mac:
|
||||||
|
@ -1015,6 +1023,9 @@ static void netfront_remove ( struct xen_device *xendev ) {
|
||||||
struct netfront_nic *netfront = netdev->priv;
|
struct netfront_nic *netfront = netdev->priv;
|
||||||
struct xen_hypervisor *xen = xendev->xen;
|
struct xen_hypervisor *xen = xendev->xen;
|
||||||
|
|
||||||
|
/* Remove from list of netfront devices */
|
||||||
|
list_del ( &netfront->list );
|
||||||
|
|
||||||
/* Unregister network device */
|
/* Unregister network device */
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
|
|
||||||
|
@ -1033,3 +1044,41 @@ struct xen_driver netfront_driver __xen_driver = {
|
||||||
.probe = netfront_probe,
|
.probe = netfront_probe,
|
||||||
.remove = netfront_remove,
|
.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 references */
|
||||||
grant_ref_t refs[NETFRONT_REF_COUNT];
|
grant_ref_t refs[NETFRONT_REF_COUNT];
|
||||||
|
|
||||||
|
/** Network device */
|
||||||
|
struct net_device *netdev;
|
||||||
|
/** List of netfront NICs */
|
||||||
|
struct list_head list;
|
||||||
|
|
||||||
/** Transmit ring */
|
/** Transmit ring */
|
||||||
struct netfront_ring tx;
|
struct netfront_ring tx;
|
||||||
/** Transmit front ring */
|
/** Transmit front ring */
|
||||||
|
|
|
@ -1067,11 +1067,15 @@ static void realtek_detect ( struct realtek_nic *rtl ) {
|
||||||
* Note that enabling DAC seems to cause bizarre behaviour
|
* Note that enabling DAC seems to cause bizarre behaviour
|
||||||
* (lockups, garbage data on the wire) on some systems, even
|
* (lockups, garbage data on the wire) on some systems, even
|
||||||
* if only 32-bit addresses are used.
|
* 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 = readw ( rtl->regs + RTL_CPCR );
|
||||||
cpcr |= ( RTL_CPCR_MULRW | RTL_CPCR_CPRX | RTL_CPCR_CPTX );
|
cpcr |= ( RTL_CPCR_MULRW | RTL_CPCR_CPRX | RTL_CPCR_CPTX );
|
||||||
if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
|
if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
|
||||||
cpcr |= RTL_CPCR_DAC;
|
cpcr |= RTL_CPCR_DAC;
|
||||||
|
cpcr &= ~RTL_CPCR_VLAN;
|
||||||
writew ( cpcr, rtl->regs + RTL_CPCR );
|
writew ( cpcr, rtl->regs + RTL_CPCR );
|
||||||
check_cpcr = readw ( rtl->regs + RTL_CPCR );
|
check_cpcr = readw ( rtl->regs + RTL_CPCR );
|
||||||
|
|
||||||
|
|
|
@ -228,8 +228,9 @@ enum realtek_legacy_status {
|
||||||
|
|
||||||
/** C+ Command Register (word) */
|
/** C+ Command Register (word) */
|
||||||
#define RTL_CPCR 0xe0
|
#define RTL_CPCR 0xe0
|
||||||
#define RTL_CPCR_DAC 0x0010 /**< PCI Dual Address Cycle Enable */
|
#define RTL_CPCR_VLAN 0x0040 /**< VLAN tag stripping enable */
|
||||||
#define RTL_CPCR_MULRW 0x0008 /**< PCI Multiple Read/Write 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_CPRX 0x0002 /**< C+ receive enable */
|
||||||
#define RTL_CPCR_CPTX 0x0001 /**< C+ transmit enable */
|
#define RTL_CPCR_CPTX 0x0001 /**< C+ transmit enable */
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <ipxe/pci.h>
|
#include <ipxe/pci.h>
|
||||||
#include <ipxe/command.h>
|
#include <ipxe/command.h>
|
||||||
|
@ -58,7 +59,7 @@ static int pciscan_exec ( int argc, char **argv ) {
|
||||||
struct named_setting setting;
|
struct named_setting setting;
|
||||||
struct pci_device pci;
|
struct pci_device pci;
|
||||||
unsigned long prev;
|
unsigned long prev;
|
||||||
int next;
|
uint32_t busdevfn;
|
||||||
int len;
|
int len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -75,17 +76,19 @@ static int pciscan_exec ( int argc, char **argv ) {
|
||||||
if ( ( len = fetchn_setting ( setting.settings, &setting.setting,
|
if ( ( len = fetchn_setting ( setting.settings, &setting.setting,
|
||||||
NULL, &setting.setting, &prev ) ) < 0 ) {
|
NULL, &setting.setting, &prev ) ) < 0 ) {
|
||||||
/* Setting not yet defined: start searching from 00:00.0 */
|
/* Setting not yet defined: start searching from 00:00.0 */
|
||||||
prev = 0;
|
busdevfn = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Setting is defined: start searching from next location */
|
/* Setting is defined: start searching from next location */
|
||||||
prev++;
|
busdevfn = ( prev + 1 );
|
||||||
|
if ( ! busdevfn ) {
|
||||||
|
rc = -ENOENT;
|
||||||
|
goto err_end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find next existent PCI device */
|
/* Find next existent PCI device */
|
||||||
if ( ( next = pci_find_next ( &pci, prev ) ) < 0 ) {
|
if ( ( rc = pci_find_next ( &pci, &busdevfn ) ) != 0 )
|
||||||
rc = next;
|
|
||||||
goto err_find_next;
|
goto err_find_next;
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply default type if necessary. Use ":uint16" rather than
|
/* Apply default type if necessary. Use ":uint16" rather than
|
||||||
* ":busdevfn" to allow for easy inclusion within a
|
* ":busdevfn" to allow for easy inclusion within a
|
||||||
|
@ -96,13 +99,14 @@ static int pciscan_exec ( int argc, char **argv ) {
|
||||||
|
|
||||||
/* Store setting */
|
/* Store setting */
|
||||||
if ( ( rc = storen_setting ( setting.settings, &setting.setting,
|
if ( ( rc = storen_setting ( setting.settings, &setting.setting,
|
||||||
next ) ) != 0 ) {
|
busdevfn ) ) != 0 ) {
|
||||||
printf ( "Could not store \"%s\": %s\n",
|
printf ( "Could not store \"%s\": %s\n",
|
||||||
setting.setting.name, strerror ( rc ) );
|
setting.setting.name, strerror ( rc ) );
|
||||||
goto err_store;
|
goto err_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
err_store:
|
err_store:
|
||||||
|
err_end:
|
||||||
err_find_next:
|
err_find_next:
|
||||||
err_parse_setting:
|
err_parse_setting:
|
||||||
err_parse_options:
|
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 */ ),
|
efi_snprintf ( filepath->PathName, ( name_len + 1 /* NUL */ ),
|
||||||
"%s", image->name );
|
"%s", image->name );
|
||||||
end = ( ( ( void * ) filepath ) + filepath_len );
|
end = ( ( ( void * ) filepath ) + filepath_len );
|
||||||
end->Type = END_DEVICE_PATH_TYPE;
|
efi_path_terminate ( end );
|
||||||
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
|
||||||
end->Length[0] = sizeof ( *end );
|
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -755,6 +755,53 @@ char __debug_disable(OBJECT) = ( DBGLVL_MAX & ~DBGLVL_DFLT );
|
||||||
#define FILE_LICENCE_BSD2 \
|
#define FILE_LICENCE_BSD2 \
|
||||||
PROVIDE_SYMBOL ( PREFIX_OBJECT ( __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
|
/** Declare a file as being under the one-clause MIT-style licence
|
||||||
*
|
*
|
||||||
* This licence declaration is applicable when a file states itself to
|
* 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_algorithm;
|
||||||
extern struct cipher_algorithm aes_ecb_algorithm;
|
extern struct cipher_algorithm aes_ecb_algorithm;
|
||||||
extern struct cipher_algorithm aes_cbc_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_wrap ( const void *kek, const void *src, void *dest, int nblk );
|
||||||
int aes_unwrap ( 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_proxydhcp;
|
||||||
extern struct cached_dhcp_packet cached_pxebs;
|
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 );
|
size_t max_len );
|
||||||
|
|
||||||
#endif /* _IPXE_CACHEDHCP_H */
|
#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 ctx Context
|
||||||
* @v iv Initialisation vector
|
* @v iv Initialisation vector
|
||||||
|
* @v ivlen Initialisation vector length
|
||||||
* @v raw_cipher Underlying cipher algorithm
|
* @v raw_cipher Underlying cipher algorithm
|
||||||
* @v cbc_ctx CBC context
|
* @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,
|
struct cipher_algorithm *raw_cipher,
|
||||||
void *cbc_ctx ) {
|
void *cbc_ctx ) {
|
||||||
|
assert ( ivlen == raw_cipher->blocksize );
|
||||||
memcpy ( cbc_ctx, iv, 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, \
|
return cbc_setkey ( &_cbc_name ## _ctx->raw_ctx, key, keylen, \
|
||||||
&_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );\
|
&_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; \
|
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 ); \
|
&_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \
|
||||||
} \
|
} \
|
||||||
static void _cbc_name ## _encrypt ( void *ctx, const void *src, \
|
static void _cbc_name ## _encrypt ( void *ctx, const void *src, \
|
||||||
|
@ -91,10 +95,13 @@ struct cipher_algorithm _cbc_cipher = { \
|
||||||
.name = #_cbc_name, \
|
.name = #_cbc_name, \
|
||||||
.ctxsize = sizeof ( struct _cbc_name ## _context ), \
|
.ctxsize = sizeof ( struct _cbc_name ## _context ), \
|
||||||
.blocksize = _blocksize, \
|
.blocksize = _blocksize, \
|
||||||
|
.alignsize = _blocksize, \
|
||||||
|
.authsize = 0, \
|
||||||
.setkey = _cbc_name ## _setkey, \
|
.setkey = _cbc_name ## _setkey, \
|
||||||
.setiv = _cbc_name ## _setiv, \
|
.setiv = _cbc_name ## _setiv, \
|
||||||
.encrypt = _cbc_name ## _encrypt, \
|
.encrypt = _cbc_name ## _encrypt, \
|
||||||
.decrypt = _cbc_name ## _decrypt, \
|
.decrypt = _cbc_name ## _decrypt, \
|
||||||
|
.auth = cipher_null_auth, \
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _IPXE_CBC_H */
|
#endif /* _IPXE_CBC_H */
|
||||||
|
|
|
@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
/** A message digest algorithm */
|
/** A message digest algorithm */
|
||||||
struct digest_algorithm {
|
struct digest_algorithm {
|
||||||
|
@ -50,8 +51,26 @@ struct cipher_algorithm {
|
||||||
const char *name;
|
const char *name;
|
||||||
/** Context size */
|
/** Context size */
|
||||||
size_t ctxsize;
|
size_t ctxsize;
|
||||||
/** Block size */
|
/** Block size
|
||||||
|
*
|
||||||
|
* Every call to encrypt() or decrypt() must be for a multiple
|
||||||
|
* of this size.
|
||||||
|
*/
|
||||||
size_t blocksize;
|
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
|
/** Set key
|
||||||
*
|
*
|
||||||
* @v ctx Context
|
* @v ctx Context
|
||||||
|
@ -64,13 +83,14 @@ struct cipher_algorithm {
|
||||||
*
|
*
|
||||||
* @v ctx Context
|
* @v ctx Context
|
||||||
* @v iv Initialisation vector
|
* @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
|
/** Encrypt data
|
||||||
*
|
*
|
||||||
* @v ctx Context
|
* @v ctx Context
|
||||||
* @v src Data to encrypt
|
* @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 Length of data
|
||||||
*
|
*
|
||||||
* @v len is guaranteed to be a multiple of @c blocksize.
|
* @v len is guaranteed to be a multiple of @c blocksize.
|
||||||
|
@ -81,13 +101,19 @@ struct cipher_algorithm {
|
||||||
*
|
*
|
||||||
* @v ctx Context
|
* @v ctx Context
|
||||||
* @v src Data to decrypt
|
* @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 Length of data
|
||||||
*
|
*
|
||||||
* @v len is guaranteed to be a multiple of @c blocksize.
|
* @v len is guaranteed to be a multiple of @c blocksize.
|
||||||
*/
|
*/
|
||||||
void ( * decrypt ) ( void *ctx, const void *src, void *dst,
|
void ( * decrypt ) ( void *ctx, const void *src, void *dst,
|
||||||
size_t len );
|
size_t len );
|
||||||
|
/** Generate authentication tag
|
||||||
|
*
|
||||||
|
* @v ctx Context
|
||||||
|
* @v auth Authentication tag
|
||||||
|
*/
|
||||||
|
void ( * auth ) ( void *ctx, void *auth );
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A public key algorithm */
|
/** 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,
|
static inline void cipher_setiv ( struct cipher_algorithm *cipher,
|
||||||
void *ctx, const void *iv ) {
|
void *ctx, const void *iv, size_t ivlen ) {
|
||||||
cipher->setiv ( ctx, iv );
|
cipher->setiv ( ctx, iv, ivlen );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cipher_encrypt ( struct cipher_algorithm *cipher,
|
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) ); \
|
cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) ); \
|
||||||
} while ( 0 )
|
} 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 ) {
|
static inline int is_stream_cipher ( struct cipher_algorithm *cipher ) {
|
||||||
return ( cipher->blocksize == 1 );
|
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,
|
static inline int pubkey_init ( struct pubkey_algorithm *pubkey, void *ctx,
|
||||||
const void *key, size_t key_len ) {
|
const void *key, size_t key_len ) {
|
||||||
return pubkey->init ( ctx, key, 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 );
|
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 digest_algorithm digest_null;
|
||||||
extern struct cipher_algorithm cipher_null;
|
extern struct cipher_algorithm cipher_null;
|
||||||
extern struct pubkey_algorithm pubkey_null;
|
extern struct pubkey_algorithm pubkey_null;
|
||||||
|
|
|
@ -274,8 +274,9 @@ struct dhcp_client_architecture {
|
||||||
|
|
||||||
/** DHCP client architecture values
|
/** DHCP client architecture values
|
||||||
*
|
*
|
||||||
* These are defined by the PXE specification and redefined by
|
* These are originally defined by the PXE specification, redefined by
|
||||||
* RFC4578.
|
* RFC4578, redefined again by RFC5970, and now maintained in the IANA
|
||||||
|
* DHCPv6 parameters registry.
|
||||||
*/
|
*/
|
||||||
enum dhcp_client_architecture_values {
|
enum dhcp_client_architecture_values {
|
||||||
/** Intel x86 PC */
|
/** Intel x86 PC */
|
||||||
|
@ -302,6 +303,24 @@ enum dhcp_client_architecture_values {
|
||||||
DHCP_CLIENT_ARCHITECTURE_ARM32 = 0x000a,
|
DHCP_CLIENT_ARCHITECTURE_ARM32 = 0x000a,
|
||||||
/** EFI 64-bit ARM */
|
/** EFI 64-bit ARM */
|
||||||
DHCP_CLIENT_ARCHITECTURE_ARM64 = 0x000b,
|
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 */
|
/** 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 ) { \
|
size_t keylen ) { \
|
||||||
return cipher_setkey ( &_raw_cipher, ctx, key, keylen ); \
|
return cipher_setkey ( &_raw_cipher, ctx, key, keylen ); \
|
||||||
} \
|
} \
|
||||||
static void _ecb_name ## _setiv ( void *ctx, const void *iv ) { \
|
static void _ecb_name ## _setiv ( void *ctx, const void *iv, \
|
||||||
cipher_setiv ( &_raw_cipher, ctx, iv ); \
|
size_t ivlen ) { \
|
||||||
|
cipher_setiv ( &_raw_cipher, ctx, iv, ivlen ); \
|
||||||
} \
|
} \
|
||||||
static void _ecb_name ## _encrypt ( void *ctx, const void *src, \
|
static void _ecb_name ## _encrypt ( void *ctx, const void *src, \
|
||||||
void *dst, size_t len ) { \
|
void *dst, size_t len ) { \
|
||||||
|
@ -46,10 +47,13 @@ struct cipher_algorithm _ecb_cipher = { \
|
||||||
.name = #_ecb_name, \
|
.name = #_ecb_name, \
|
||||||
.ctxsize = sizeof ( _raw_context ), \
|
.ctxsize = sizeof ( _raw_context ), \
|
||||||
.blocksize = _blocksize, \
|
.blocksize = _blocksize, \
|
||||||
|
.alignsize = _blocksize, \
|
||||||
|
.authsize = 0, \
|
||||||
.setkey = _ecb_name ## _setkey, \
|
.setkey = _ecb_name ## _setkey, \
|
||||||
.setiv = _ecb_name ## _setiv, \
|
.setiv = _ecb_name ## _setiv, \
|
||||||
.encrypt = _ecb_name ## _encrypt, \
|
.encrypt = _ecb_name ## _encrypt, \
|
||||||
.decrypt = _ecb_name ## _decrypt, \
|
.decrypt = _ecb_name ## _decrypt, \
|
||||||
|
.auth = cipher_null_auth, \
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _IPXE_ECB_H */
|
#endif /* _IPXE_ECB_H */
|
||||||
|
|
|
@ -1,24 +1,18 @@
|
||||||
/** @file
|
/** @file
|
||||||
Processor or Compiler specific defines and types for AArch64.
|
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) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||||
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
|
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __PROCESSOR_BIND_H__
|
#ifndef __PROCESSOR_BIND_H__
|
||||||
#define __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
|
/// Define the processor type so other code can make processor based choices
|
||||||
|
@ -28,40 +22,89 @@ FILE_LICENCE ( BSD3 );
|
||||||
//
|
//
|
||||||
// Make sure we are using the correct packing rules per EFI specification
|
// Make sure we are using the correct packing rules per EFI specification
|
||||||
//
|
//
|
||||||
#ifndef __GNUC__
|
#if !defined (__GNUC__) && !defined (__ASSEMBLER__)
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _MSC_EXTENSIONS
|
#if defined (_MSC_EXTENSIONS)
|
||||||
//
|
|
||||||
// use Microsoft* C compiler dependent integer width types
|
//
|
||||||
//
|
// Disable some level 4 compilation warnings (same as IA32 and X64)
|
||||||
typedef unsigned __int64 UINT64;
|
//
|
||||||
typedef __int64 INT64;
|
|
||||||
typedef unsigned __int32 UINT32;
|
//
|
||||||
typedef __int32 INT32;
|
// Disabling bitfield type checking warnings.
|
||||||
typedef unsigned short UINT16;
|
//
|
||||||
typedef unsigned short CHAR16;
|
#pragma warning ( disable : 4214 )
|
||||||
typedef short INT16;
|
|
||||||
typedef unsigned char BOOLEAN;
|
//
|
||||||
typedef unsigned char UINT8;
|
// Disabling the unreferenced formal parameter warnings.
|
||||||
typedef char CHAR8;
|
//
|
||||||
typedef signed char INT8;
|
#pragma warning ( disable : 4100 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable slightly different base types warning as CHAR8 * can not be set
|
||||||
|
// to a constant string.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4057 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4127 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// This warning is caused by functions defined but not used. For precompiled header only.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4505 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4206 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable 'potentially uninitialized local variable X used' warnings
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4701 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable 'potentially uninitialized local pointer variable X used' warnings
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4703 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// use Microsoft* C compiler dependent integer width types
|
||||||
|
//
|
||||||
|
typedef unsigned __int64 UINT64;
|
||||||
|
typedef __int64 INT64;
|
||||||
|
typedef unsigned __int32 UINT32;
|
||||||
|
typedef __int32 INT32;
|
||||||
|
typedef unsigned short UINT16;
|
||||||
|
typedef unsigned short CHAR16;
|
||||||
|
typedef short INT16;
|
||||||
|
typedef unsigned char BOOLEAN;
|
||||||
|
typedef unsigned char UINT8;
|
||||||
|
typedef char CHAR8;
|
||||||
|
typedef signed char INT8;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//
|
|
||||||
// Assume standard AARCH64 alignment.
|
//
|
||||||
//
|
// Assume standard AARCH64 alignment.
|
||||||
typedef unsigned long long UINT64;
|
//
|
||||||
typedef long long INT64;
|
typedef unsigned long long UINT64;
|
||||||
typedef unsigned int UINT32;
|
typedef long long INT64;
|
||||||
typedef int INT32;
|
typedef unsigned int UINT32;
|
||||||
typedef unsigned short UINT16;
|
typedef int INT32;
|
||||||
typedef unsigned short CHAR16;
|
typedef unsigned short UINT16;
|
||||||
typedef short INT16;
|
typedef unsigned short CHAR16;
|
||||||
typedef unsigned char BOOLEAN;
|
typedef short INT16;
|
||||||
typedef unsigned char UINT8;
|
typedef unsigned char BOOLEAN;
|
||||||
typedef char CHAR8;
|
typedef unsigned char UINT8;
|
||||||
typedef signed char INT8;
|
typedef char CHAR8;
|
||||||
|
typedef signed char INT8;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -95,12 +138,22 @@ typedef INT64 INTN;
|
||||||
///
|
///
|
||||||
#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFFULL
|
#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFFULL
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Maximum usable address at boot time (48 bits using 4 KB pages)
|
||||||
|
///
|
||||||
|
#define MAX_ALLOC_ADDRESS 0xFFFFFFFFFFFFULL
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Maximum legal AArch64 INTN and UINTN values.
|
/// Maximum legal AArch64 INTN and UINTN values.
|
||||||
///
|
///
|
||||||
#define MAX_INTN ((INTN)0x7FFFFFFFFFFFFFFFULL)
|
#define MAX_INTN ((INTN)0x7FFFFFFFFFFFFFFFULL)
|
||||||
#define MAX_UINTN ((UINTN)0xFFFFFFFFFFFFFFFFULL)
|
#define MAX_UINTN ((UINTN)0xFFFFFFFFFFFFFFFFULL)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Minimum legal AArch64 INTN value.
|
||||||
|
///
|
||||||
|
#define MIN_INTN (((INTN)-9223372036854775807LL) - 1)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The stack alignment required for AARCH64
|
/// The stack alignment required for AARCH64
|
||||||
///
|
///
|
||||||
|
@ -121,18 +174,18 @@ typedef INT64 INTN;
|
||||||
|
|
||||||
// When compiling with Clang, we still use GNU as for the assembler, so we still
|
// When compiling with Clang, we still use GNU as for the assembler, so we still
|
||||||
// need to define the GCC_ASM* macros.
|
// need to define the GCC_ASM* macros.
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined (__GNUC__) || defined (__clang__)
|
||||||
///
|
///
|
||||||
/// For GNU assembly code, .global or .globl can declare global symbols.
|
/// For GNU assembly code, .global or .globl can declare global symbols.
|
||||||
/// Define this macro to unify the usage.
|
/// Define this macro to unify the usage.
|
||||||
///
|
///
|
||||||
#define ASM_GLOBAL .globl
|
#define ASM_GLOBAL .globl
|
||||||
|
|
||||||
#define GCC_ASM_EXPORT(func__) \
|
#define GCC_ASM_EXPORT(func__) \
|
||||||
.global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
|
.global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
|
||||||
.type ASM_PFX(func__), %function
|
.type ASM_PFX(func__), %function
|
||||||
|
|
||||||
#define GCC_ASM_IMPORT(func__) \
|
#define GCC_ASM_IMPORT(func__) \
|
||||||
.extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
|
.extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,22 +1,16 @@
|
||||||
/** @file
|
/** @file
|
||||||
Processor or Compiler specific defines and types for ARM.
|
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>
|
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __PROCESSOR_BIND_H__
|
#ifndef __PROCESSOR_BIND_H__
|
||||||
#define __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
|
/// Define the processor type so other code can make processor based choices
|
||||||
|
@ -26,48 +20,97 @@ FILE_LICENCE ( BSD3 );
|
||||||
//
|
//
|
||||||
// Make sure we are using the correct packing rules per EFI specification
|
// Make sure we are using the correct packing rules per EFI specification
|
||||||
//
|
//
|
||||||
#ifndef __GNUC__
|
#if !defined (__GNUC__) && !defined (__ASSEMBLER__)
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (_MSC_EXTENSIONS)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable some level 4 compilation warnings (same as IA32 and X64)
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disabling bitfield type checking warnings.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4214 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disabling the unreferenced formal parameter warnings.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4100 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable slightly different base types warning as CHAR8 * can not be set
|
||||||
|
// to a constant string.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4057 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4127 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// This warning is caused by functions defined but not used. For precompiled header only.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4505 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4206 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable 'potentially uninitialized local variable X used' warnings
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4701 )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable 'potentially uninitialized local pointer variable X used' warnings
|
||||||
|
//
|
||||||
|
#pragma warning ( disable : 4703 )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// RVCT does not support the __builtin_unreachable() macro
|
// MSFT doesn't support the __builtin_unreachable() macro
|
||||||
//
|
//
|
||||||
#ifdef __ARMCC_VERSION
|
#if defined (_MSC_EXTENSIONS)
|
||||||
#define UNREACHABLE()
|
#define UNREACHABLE()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _MSC_EXTENSIONS
|
#if defined (_MSC_EXTENSIONS)
|
||||||
//
|
//
|
||||||
// use Microsoft* C compiler dependent integer width types
|
// use Microsoft* C compiler dependent integer width types
|
||||||
//
|
//
|
||||||
typedef unsigned __int64 UINT64;
|
typedef unsigned __int64 UINT64;
|
||||||
typedef __int64 INT64;
|
typedef __int64 INT64;
|
||||||
typedef unsigned __int32 UINT32;
|
typedef unsigned __int32 UINT32;
|
||||||
typedef __int32 INT32;
|
typedef __int32 INT32;
|
||||||
typedef unsigned short UINT16;
|
typedef unsigned short UINT16;
|
||||||
typedef unsigned short CHAR16;
|
typedef unsigned short CHAR16;
|
||||||
typedef short INT16;
|
typedef short INT16;
|
||||||
typedef unsigned char BOOLEAN;
|
typedef unsigned char BOOLEAN;
|
||||||
typedef unsigned char UINT8;
|
typedef unsigned char UINT8;
|
||||||
typedef char CHAR8;
|
typedef char CHAR8;
|
||||||
typedef signed char INT8;
|
typedef signed char INT8;
|
||||||
#else
|
#else
|
||||||
//
|
//
|
||||||
// Assume standard ARM alignment.
|
// Assume standard ARM alignment.
|
||||||
// Need to check portability of long long
|
// Need to check portability of long long
|
||||||
//
|
//
|
||||||
typedef unsigned long long UINT64;
|
typedef unsigned long long UINT64;
|
||||||
typedef long long INT64;
|
typedef long long INT64;
|
||||||
typedef unsigned int UINT32;
|
typedef unsigned int UINT32;
|
||||||
typedef int INT32;
|
typedef int INT32;
|
||||||
typedef unsigned short UINT16;
|
typedef unsigned short UINT16;
|
||||||
typedef unsigned short CHAR16;
|
typedef unsigned short CHAR16;
|
||||||
typedef short INT16;
|
typedef short INT16;
|
||||||
typedef unsigned char BOOLEAN;
|
typedef unsigned char BOOLEAN;
|
||||||
typedef unsigned char UINT8;
|
typedef unsigned char UINT8;
|
||||||
typedef char CHAR8;
|
typedef char CHAR8;
|
||||||
typedef signed char INT8;
|
typedef signed char INT8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -101,12 +144,22 @@ typedef INT32 INTN;
|
||||||
///
|
///
|
||||||
#define MAX_ADDRESS 0xFFFFFFFF
|
#define MAX_ADDRESS 0xFFFFFFFF
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Maximum usable address at boot time
|
||||||
|
///
|
||||||
|
#define MAX_ALLOC_ADDRESS MAX_ADDRESS
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Maximum legal ARM INTN and UINTN values.
|
/// Maximum legal ARM INTN and UINTN values.
|
||||||
///
|
///
|
||||||
#define MAX_INTN ((INTN)0x7FFFFFFF)
|
#define MAX_INTN ((INTN)0x7FFFFFFF)
|
||||||
#define MAX_UINTN ((UINTN)0xFFFFFFFF)
|
#define MAX_UINTN ((UINTN)0xFFFFFFFF)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Minimum legal ARM INTN value.
|
||||||
|
///
|
||||||
|
#define MIN_INTN (((INTN)-2147483647) - 1)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The stack alignment required for ARM
|
/// The stack alignment required for ARM
|
||||||
///
|
///
|
||||||
|
@ -127,40 +180,45 @@ typedef INT32 INTN;
|
||||||
|
|
||||||
// When compiling with Clang, we still use GNU as for the assembler, so we still
|
// When compiling with Clang, we still use GNU as for the assembler, so we still
|
||||||
// need to define the GCC_ASM* macros.
|
// need to define the GCC_ASM* macros.
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined (__GNUC__) || defined (__clang__)
|
||||||
///
|
///
|
||||||
/// For GNU assembly code, .global or .globl can declare global symbols.
|
/// For GNU assembly code, .global or .globl can declare global symbols.
|
||||||
/// Define this macro to unify the usage.
|
/// Define this macro to unify the usage.
|
||||||
///
|
///
|
||||||
#define ASM_GLOBAL .globl
|
#define ASM_GLOBAL .globl
|
||||||
|
|
||||||
#if !defined(__APPLE__)
|
#if !defined (__APPLE__)
|
||||||
///
|
///
|
||||||
/// ARM EABI defines that the linker should not manipulate call relocations
|
/// ARM EABI defines that the linker should not manipulate call relocations
|
||||||
/// (do bl/blx conversion) unless the target symbol has function type.
|
/// (do bl/blx conversion) unless the target symbol has function type.
|
||||||
/// CodeSourcery 2010.09 started requiring the .type to function properly
|
/// CodeSourcery 2010.09 started requiring the .type to function properly
|
||||||
///
|
///
|
||||||
#define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function
|
#define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function
|
||||||
|
|
||||||
#define GCC_ASM_EXPORT(func__) \
|
#define GCC_ASM_EXPORT(func__) \
|
||||||
.global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
|
.global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
|
||||||
.type ASM_PFX(func__), %function
|
.type ASM_PFX(func__), %function
|
||||||
|
|
||||||
#define GCC_ASM_IMPORT(func__) \
|
#define GCC_ASM_IMPORT(func__) \
|
||||||
.extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
|
.extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//
|
//
|
||||||
// .type not supported by Apple Xcode tools
|
// .type not supported by Apple Xcode tools
|
||||||
//
|
//
|
||||||
#define INTERWORK_FUNC(func__)
|
#define INTERWORK_FUNC(func__)
|
||||||
|
|
||||||
#define GCC_ASM_EXPORT(func__) \
|
#define GCC_ASM_EXPORT(func__) \
|
||||||
.globl _CONCATENATE (__USER_LABEL_PREFIX__, func__) \
|
.globl _CONCATENATE (__USER_LABEL_PREFIX__, func__) \
|
||||||
|
|
||||||
#define GCC_ASM_IMPORT(name)
|
#define GCC_ASM_IMPORT(name)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined (_MSC_EXTENSIONS)
|
||||||
|
//
|
||||||
|
// PRESERVE8 is not supported by the MSFT assembler.
|
||||||
|
//
|
||||||
|
#define PRESERVE8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,5 +238,3 @@ typedef INT32 INTN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,107 +6,48 @@
|
||||||
environment. There are a set of base libraries in the Mde Package that can
|
environment. There are a set of base libraries in the Mde Package that can
|
||||||
be used to implement base modules.
|
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>
|
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __BASE_H__
|
#ifndef __BASE_H__
|
||||||
#define __BASE_H__
|
#define __BASE_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
//
|
//
|
||||||
// Include processor specific binding
|
// Include processor specific binding
|
||||||
//
|
//
|
||||||
#include <ipxe/efi/ProcessorBind.h>
|
#include <ipxe/efi/ProcessorBind.h>
|
||||||
|
|
||||||
#if defined(_MSC_EXTENSIONS)
|
#if defined (_MSC_EXTENSIONS)
|
||||||
//
|
//
|
||||||
// Disable warning when last field of data structure is a zero sized array.
|
// Disable warning when last field of data structure is a zero sized array.
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4200 )
|
#pragma warning ( disable : 4200 )
|
||||||
#endif
|
#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
|
// 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
|
// if the /OPT:REF linker option is used. We defined a macro as this is a
|
||||||
// a non standard extension
|
// 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
|
/// Remove global variable from the linked image if there are no references to
|
||||||
/// it after all compiler and linker optimizations have been performed.
|
/// it after all compiler and linker optimizations have been performed.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
#define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
|
#define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
|
||||||
#else
|
#else
|
||||||
///
|
///
|
||||||
/// Remove the global variable from the linked image if there are no references
|
/// Remove the global variable from the linked image if there are no references
|
||||||
/// to it after all compiler and linker optimizations have been performed.
|
/// to it after all compiler and linker optimizations have been performed.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
#define GLOBAL_REMOVE_IF_UNREFERENCED
|
#define GLOBAL_REMOVE_IF_UNREFERENCED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -114,29 +55,28 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
||||||
// warnings.
|
// warnings.
|
||||||
//
|
//
|
||||||
#ifndef UNREACHABLE
|
#ifndef UNREACHABLE
|
||||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)
|
#ifdef __GNUC__
|
||||||
///
|
///
|
||||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||||
/// up to the compiler to remove any code past that point.
|
/// up to the compiler to remove any code past that point.
|
||||||
/// Not implemented by GCC 4.4 or earlier.
|
///
|
||||||
///
|
#define UNREACHABLE() __builtin_unreachable ()
|
||||||
#define UNREACHABLE() __builtin_unreachable ()
|
|
||||||
#elif defined (__has_feature)
|
#elif defined (__has_feature)
|
||||||
#if __has_builtin (__builtin_unreachable)
|
#if __has_builtin (__builtin_unreachable)
|
||||||
///
|
///
|
||||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||||
/// up to the compiler to remove any code past that point.
|
/// up to the compiler to remove any code past that point.
|
||||||
///
|
///
|
||||||
#define UNREACHABLE() __builtin_unreachable ()
|
#define UNREACHABLE() __builtin_unreachable ()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef UNREACHABLE
|
#ifndef UNREACHABLE
|
||||||
///
|
///
|
||||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||||
/// up to the compiler to remove any code past that point.
|
/// up to the compiler to remove any code past that point.
|
||||||
///
|
///
|
||||||
#define UNREACHABLE()
|
#define UNREACHABLE()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -147,26 +87,26 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
||||||
//
|
//
|
||||||
#ifndef NORETURN
|
#ifndef NORETURN
|
||||||
#if defined (__GNUC__) || defined (__clang__)
|
#if defined (__GNUC__) || defined (__clang__)
|
||||||
///
|
///
|
||||||
/// Signal compilers and analyzers that the function cannot return.
|
/// Signal compilers and analyzers that the function cannot return.
|
||||||
/// It is up to the compiler to remove any code past a call to functions
|
/// It is up to the compiler to remove any code past a call to functions
|
||||||
/// flagged with this attribute.
|
/// flagged with this attribute.
|
||||||
///
|
///
|
||||||
#define NORETURN __attribute__((noreturn))
|
#define NORETURN __attribute__((noreturn))
|
||||||
#elif defined(_MSC_EXTENSIONS) && !defined(MDE_CPU_EBC)
|
#elif defined (_MSC_EXTENSIONS) && !defined (MDE_CPU_EBC)
|
||||||
///
|
///
|
||||||
/// Signal compilers and analyzers that the function cannot return.
|
/// Signal compilers and analyzers that the function cannot return.
|
||||||
/// It is up to the compiler to remove any code past a call to functions
|
/// It is up to the compiler to remove any code past a call to functions
|
||||||
/// flagged with this attribute.
|
/// flagged with this attribute.
|
||||||
///
|
///
|
||||||
#define NORETURN __declspec(noreturn)
|
#define NORETURN __declspec(noreturn)
|
||||||
#else
|
#else
|
||||||
///
|
///
|
||||||
/// Signal compilers and analyzers that the function cannot return.
|
/// Signal compilers and analyzers that the function cannot return.
|
||||||
/// It is up to the compiler to remove any code past a call to functions
|
/// It is up to the compiler to remove any code past a call to functions
|
||||||
/// flagged with this attribute.
|
/// flagged with this attribute.
|
||||||
///
|
///
|
||||||
#define NORETURN
|
#define NORETURN
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -177,20 +117,20 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
||||||
#ifndef ANALYZER_UNREACHABLE
|
#ifndef ANALYZER_UNREACHABLE
|
||||||
#ifdef __clang_analyzer__
|
#ifdef __clang_analyzer__
|
||||||
#if __has_builtin (__builtin_unreachable)
|
#if __has_builtin (__builtin_unreachable)
|
||||||
///
|
///
|
||||||
/// Signal the analyzer that this call is not reachable.
|
/// Signal the analyzer that this call is not reachable.
|
||||||
/// This excludes compilers.
|
/// This excludes compilers.
|
||||||
///
|
///
|
||||||
#define ANALYZER_UNREACHABLE() __builtin_unreachable ()
|
#define ANALYZER_UNREACHABLE() __builtin_unreachable ()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ANALYZER_UNREACHABLE
|
#ifndef ANALYZER_UNREACHABLE
|
||||||
///
|
///
|
||||||
/// Signal the analyzer that this call is not reachable.
|
/// Signal the analyzer that this call is not reachable.
|
||||||
/// This excludes compilers.
|
/// This excludes compilers.
|
||||||
///
|
///
|
||||||
#define ANALYZER_UNREACHABLE()
|
#define ANALYZER_UNREACHABLE()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -203,20 +143,40 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
||||||
#ifndef ANALYZER_NORETURN
|
#ifndef ANALYZER_NORETURN
|
||||||
#ifdef __has_feature
|
#ifdef __has_feature
|
||||||
#if __has_feature (attribute_analyzer_noreturn)
|
#if __has_feature (attribute_analyzer_noreturn)
|
||||||
///
|
///
|
||||||
/// Signal analyzers that the function cannot return.
|
/// Signal analyzers that the function cannot return.
|
||||||
/// This excludes compilers.
|
/// This excludes compilers.
|
||||||
///
|
///
|
||||||
#define ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
#define ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ANALYZER_NORETURN
|
#ifndef ANALYZER_NORETURN
|
||||||
///
|
///
|
||||||
/// Signal the analyzer that the function cannot return.
|
/// Signal the analyzer that the function cannot return.
|
||||||
/// This excludes compilers.
|
/// This excludes compilers.
|
||||||
///
|
///
|
||||||
#define ANALYZER_NORETURN
|
#define ANALYZER_NORETURN
|
||||||
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -236,25 +196,17 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
|
||||||
///
|
///
|
||||||
#define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name)
|
#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
|
// Apple extension that is used by the linker to optimize code size
|
||||||
// with assembly functions. Put at the end of your .S files
|
// with assembly functions. Put at the end of your .S files
|
||||||
//
|
//
|
||||||
#define ASM_FUNCTION_REMOVE_IF_UNREFERENCED .subsections_via_symbols
|
#define ASM_FUNCTION_REMOVE_IF_UNREFERENCED .subsections_via_symbols
|
||||||
#else
|
#else
|
||||||
#define ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|
#define ASM_FUNCTION_REMOVE_IF_UNREFERENCED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __CC_ARM
|
#define PACKED
|
||||||
//
|
|
||||||
// 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.
|
/// 128 bit buffer containing a unique identifier value.
|
||||||
|
@ -359,7 +311,15 @@ struct _LIST_ENTRY {
|
||||||
///
|
///
|
||||||
/// NULL pointer (VOID *)
|
/// NULL pointer (VOID *)
|
||||||
///
|
///
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
#if defined (_MSC_EXTENSIONS)
|
||||||
|
#define NULL nullptr
|
||||||
|
#else
|
||||||
|
#define NULL __null
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#define NULL ((VOID *) 0)
|
#define NULL ((VOID *) 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Null character
|
// Null character
|
||||||
|
@ -378,6 +338,14 @@ struct _LIST_ENTRY {
|
||||||
#define MAX_INT64 ((INT64)0x7FFFFFFFFFFFFFFFULL)
|
#define MAX_INT64 ((INT64)0x7FFFFFFFFFFFFFFFULL)
|
||||||
#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL)
|
#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 BIT0 0x00000001
|
||||||
#define BIT1 0x00000002
|
#define BIT1 0x00000002
|
||||||
#define BIT2 0x00000004
|
#define BIT2 0x00000004
|
||||||
|
@ -554,21 +522,24 @@ struct _LIST_ENTRY {
|
||||||
#define BASE_8EB 0x8000000000000000ULL
|
#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
|
// For modules that use the ISO C library interfaces for variable
|
||||||
// did not follow the coding convention
|
// argument lists, refer to "StdLib/Include/stdarg.h".
|
||||||
//
|
//
|
||||||
// VA_LIST - typedef for argument list.
|
// VA_LIST - typedef for argument list.
|
||||||
// VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.
|
// VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.
|
||||||
// VA_END (VA_LIST Marker) - Clear Marker
|
// VA_END (VA_LIST Marker) - Clear Marker
|
||||||
// VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argument from
|
// VA_ARG (VA_LIST Marker, var arg type) - Use Marker to get an argument from
|
||||||
// the ... list. You must know the size and pass it in this macro.
|
// 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.
|
// VA_COPY (VA_LIST Dest, VA_LIST Start) - Initialize Dest as a copy of Start.
|
||||||
//
|
//
|
||||||
// example:
|
// Example:
|
||||||
//
|
//
|
||||||
// UINTN
|
// UINTN
|
||||||
|
// EFIAPI
|
||||||
// ExampleVarArg (
|
// ExampleVarArg (
|
||||||
// IN UINTN NumberOfArgs,
|
// IN UINTN NumberOfArgs,
|
||||||
// ...
|
// ...
|
||||||
|
@ -584,15 +555,21 @@ struct _LIST_ENTRY {
|
||||||
// VA_START (Marker, NumberOfArgs);
|
// VA_START (Marker, NumberOfArgs);
|
||||||
// for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {
|
// 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);
|
// Result += VA_ARG (Marker, UINTN);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// VA_END (Marker);
|
// 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).
|
Return the size of argument that has been aligned to sizeof (UINTN).
|
||||||
|
@ -603,39 +580,21 @@ struct _LIST_ENTRY {
|
||||||
**/
|
**/
|
||||||
#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))
|
#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.
|
||||||
//
|
//
|
||||||
|
|
||||||
///
|
typedef char *VA_LIST;
|
||||||
/// 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
|
|
||||||
|
|
||||||
#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)
|
#elif defined (__GNUC__) || defined (__clang__)
|
||||||
|
|
||||||
#define VA_END(Marker) ((void)0)
|
#if defined (MDE_CPU_X64) && !defined (NO_MSABI_VA_FUNCS)
|
||||||
|
|
||||||
// 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__)
|
|
||||||
|
|
||||||
#if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS)
|
|
||||||
//
|
//
|
||||||
// X64 only. Use MS ABI version of GCC built-in macros for variable argument lists.
|
// X64 only. Use MS ABI version of GCC built-in macros for variable argument lists.
|
||||||
//
|
//
|
||||||
|
@ -657,7 +616,7 @@ typedef __builtin_ms_va_list VA_LIST;
|
||||||
|
|
||||||
#define VA_COPY(Dest, Start) __builtin_ms_va_copy (Dest, Start)
|
#define VA_COPY(Dest, Start) __builtin_ms_va_copy (Dest, Start)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//
|
//
|
||||||
// Use GCC built-in macros for variable argument lists.
|
// Use GCC built-in macros for variable argument lists.
|
||||||
//
|
//
|
||||||
|
@ -676,7 +635,7 @@ typedef __builtin_va_list VA_LIST;
|
||||||
|
|
||||||
#define VA_COPY(Dest, Start) __builtin_va_copy (Dest, Start)
|
#define VA_COPY(Dest, Start) __builtin_va_copy (Dest, Start)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
///
|
///
|
||||||
|
@ -793,16 +752,72 @@ typedef UINTN *BASE_LIST;
|
||||||
@return Offset, in bytes, of field.
|
@return Offset, in bytes, of field.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
#ifdef __GNUC__
|
#if (defined (__GNUC__) && __GNUC__ >= 4) || defined (__clang__)
|
||||||
#if __GNUC__ >= 4
|
|
||||||
#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
|
#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef OFFSET_OF
|
#ifndef OFFSET_OF
|
||||||
#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
|
#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
|
||||||
#endif
|
#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
|
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
|
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.
|
@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.
|
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))
|
#define ALIGN_VARIABLE(Value) ALIGN_VALUE ((Value), sizeof (UINTN))
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the maximum of two operands.
|
Return the maximum of two operands.
|
||||||
|
|
||||||
|
@ -955,7 +969,7 @@ typedef UINTN RETURN_STATUS;
|
||||||
///
|
///
|
||||||
/// The operation completed successfully.
|
/// The operation completed successfully.
|
||||||
///
|
///
|
||||||
#define RETURN_SUCCESS 0
|
#define RETURN_SUCCESS (RETURN_STATUS)(0)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The image failed to load.
|
/// The image failed to load.
|
||||||
|
@ -1160,7 +1174,6 @@ typedef UINTN RETURN_STATUS;
|
||||||
///
|
///
|
||||||
#define RETURN_WARN_FILE_SYSTEM ENCODE_WARNING (6)
|
#define RETURN_WARN_FILE_SYSTEM ENCODE_WARNING (6)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a 16-bit signature built from 2 ASCII characters.
|
Returns a 16-bit signature built from 2 ASCII characters.
|
||||||
|
|
||||||
|
@ -1214,9 +1227,15 @@ typedef UINTN RETURN_STATUS;
|
||||||
#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
|
#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
|
||||||
(SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
|
(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)
|
#if defined (_MSC_EXTENSIONS) && !defined (__INTEL_COMPILER) && !defined (MDE_CPU_EBC)
|
||||||
|
void *
|
||||||
|
_ReturnAddress (
|
||||||
|
void
|
||||||
|
);
|
||||||
|
|
||||||
#pragma intrinsic(_ReturnAddress)
|
#pragma intrinsic(_ReturnAddress)
|
||||||
/**
|
|
||||||
|
/**
|
||||||
Get the return address of the calling function.
|
Get the return address of the calling function.
|
||||||
|
|
||||||
Based on intrinsic function _ReturnAddress that provides the address of
|
Based on intrinsic function _ReturnAddress that provides the address of
|
||||||
|
@ -1227,11 +1246,11 @@ typedef UINTN RETURN_STATUS;
|
||||||
|
|
||||||
@return The return address of the calling function or 0 if L != 0.
|
@return The return address of the calling function or 0 if L != 0.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
#define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0)
|
#define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0)
|
||||||
#elif defined(__GNUC__)
|
#elif defined (__GNUC__) || defined (__clang__)
|
||||||
void * __builtin_return_address (unsigned int level);
|
|
||||||
/**
|
/**
|
||||||
Get the return address of the calling function.
|
Get the return address of the calling function.
|
||||||
|
|
||||||
Based on built-in Function __builtin_return_address that returns
|
Based on built-in Function __builtin_return_address that returns
|
||||||
|
@ -1241,18 +1260,19 @@ typedef UINTN RETURN_STATUS;
|
||||||
|
|
||||||
@return The return address of the calling function.
|
@return The return address of the calling function.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
#define RETURN_ADDRESS(L) __builtin_return_address (L)
|
#define RETURN_ADDRESS(L) __builtin_return_address (L)
|
||||||
#else
|
#else
|
||||||
/**
|
|
||||||
|
/**
|
||||||
Get the return address of the calling function.
|
Get the return address of the calling function.
|
||||||
|
|
||||||
@param L Return Level.
|
@param L Return Level.
|
||||||
|
|
||||||
@return 0 as compilers don't support this feature.
|
@return 0 as compilers don't support this feature.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
#define RETURN_ADDRESS(L) ((VOID *) 0)
|
#define RETURN_ADDRESS(L) ((VOID *) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1269,4 +1289,3 @@ typedef UINTN RETURN_STATUS;
|
||||||
#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
|
#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,8 @@
|
||||||
ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the
|
ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the
|
||||||
ACPI 2.0 Table GUID and ACPI Table GUID.
|
ACPI 2.0 Table GUID and ACPI Table GUID.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
GUIDs defined in UEFI 2.0 spec.
|
GUIDs defined in UEFI 2.0 spec.
|
||||||
|
@ -22,7 +16,7 @@
|
||||||
#ifndef __ACPI_GUID_H__
|
#ifndef __ACPI_GUID_H__
|
||||||
#define __ACPI_GUID_H__
|
#define __ACPI_GUID_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#define ACPI_TABLE_GUID \
|
#define ACPI_TABLE_GUID \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -3,21 +3,15 @@
|
||||||
and EFI_FILE_PROTOCOL.GetInfo() to set or get generic file information.
|
and EFI_FILE_PROTOCOL.GetInfo() to set or get generic file information.
|
||||||
This GUID is defined in UEFI specification.
|
This GUID is defined in UEFI specification.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __FILE_INFO_H__
|
#ifndef __FILE_INFO_H__
|
||||||
#define __FILE_INFO_H__
|
#define __FILE_INFO_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#define EFI_FILE_INFO_ID \
|
#define EFI_FILE_INFO_ID \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -3,21 +3,15 @@
|
||||||
or EFI_FILE_PROTOCOL.SetInfo() to get or set information about the system's volume.
|
or EFI_FILE_PROTOCOL.SetInfo() to get or set information about the system's volume.
|
||||||
This GUID is defined in UEFI specification.
|
This GUID is defined in UEFI specification.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __FILE_SYSTEM_INFO_H__
|
#ifndef __FILE_SYSTEM_INFO_H__
|
||||||
#define __FILE_SYSTEM_INFO_H__
|
#define __FILE_SYSTEM_INFO_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#define EFI_FILE_SYSTEM_INFO_ID \
|
#define EFI_FILE_SYSTEM_INFO_ID \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
/** @file
|
/** @file
|
||||||
Guid used to identify HII FormMap configuration method.
|
Guid used to identify HII FormMap configuration method.
|
||||||
|
|
||||||
Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
GUID defined in UEFI 2.2 spec.
|
GUID defined in UEFI 2.2 spec.
|
||||||
|
@ -17,7 +11,7 @@
|
||||||
#ifndef __EFI_HII_FORMMAP_GUID_H__
|
#ifndef __EFI_HII_FORMMAP_GUID_H__
|
||||||
#define __EFI_HII_FORMMAP_GUID_H__
|
#define __EFI_HII_FORMMAP_GUID_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#define EFI_HII_STANDARD_FORM_GUID \
|
#define EFI_HII_STANDARD_FORM_GUID \
|
||||||
{ 0x3bd2f4ec, 0xe524, 0x46e4, { 0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62 } }
|
{ 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
|
GUID indicates that the form set contains forms designed to be used
|
||||||
for platform configuration and this form set will be displayed.
|
for platform configuration and this form set will be displayed.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
GUID defined in UEFI 2.1.
|
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__
|
#ifndef __HII_PLATFORM_SETUP_FORMSET_GUID_H__
|
||||||
#define __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 \
|
#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \
|
||||||
{ 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } }
|
{ 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 \
|
#define EFI_HII_USER_CREDENTIAL_FORMSET_GUID \
|
||||||
{ 0x337f4407, 0x5aee, 0x4b83, { 0xb2, 0xa7, 0x4e, 0xad, 0xca, 0x30, 0x88, 0xcd } }
|
{ 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 gEfiHiiPlatformSetupFormsetGuid;
|
||||||
extern EFI_GUID gEfiHiiDriverHealthFormsetGuid;
|
extern EFI_GUID gEfiHiiDriverHealthFormsetGuid;
|
||||||
extern EFI_GUID gEfiHiiUserCredentialFormsetGuid;
|
extern EFI_GUID gEfiHiiUserCredentialFormsetGuid;
|
||||||
|
extern EFI_GUID gEfiHiiRestStyleFormsetGuid;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
/** @file
|
/** @file
|
||||||
EDKII extented HII IFR guid opcodes.
|
EDKII extented HII IFR guid opcodes.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __MDEMODULE_HII_H__
|
#ifndef __MDEMODULE_HII_H__
|
||||||
#define __MDEMODULE_HII_H__
|
#define __MDEMODULE_HII_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#define NARROW_CHAR 0xFFF0
|
#define NARROW_CHAR 0xFFF0
|
||||||
#define WIDE_CHAR 0xFFF1
|
#define WIDE_CHAR 0xFFF1
|
||||||
|
@ -213,10 +207,27 @@ typedef struct _EFI_IFR_GUID_VAREQNAME {
|
||||||
UINT16 NameId;
|
UINT16 NameId;
|
||||||
} EFI_IFR_GUID_VAREQNAME;
|
} 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()
|
#pragma pack()
|
||||||
|
|
||||||
extern EFI_GUID gEfiIfrTianoGuid;
|
extern EFI_GUID gEfiIfrTianoGuid;
|
||||||
extern EFI_GUID gEfiIfrFrameworkGuid;
|
extern EFI_GUID gEfiIfrFrameworkGuid;
|
||||||
|
extern EFI_GUID gEdkiiIfrBitVarstoreGuid;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
/** @file
|
/** @file
|
||||||
Terminal Device Path Vendor Guid.
|
Terminal Device Path Vendor Guid.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
GUIDs defined in UEFI 2.0 spec.
|
GUIDs defined in UEFI 2.0 spec.
|
||||||
|
@ -18,7 +12,7 @@
|
||||||
#ifndef __PC_ANSI_H__
|
#ifndef __PC_ANSI_H__
|
||||||
#define __PC_ANSI_H__
|
#define __PC_ANSI_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#define EFI_PC_ANSI_GUID \
|
#define EFI_PC_ANSI_GUID \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -5,14 +5,8 @@
|
||||||
locate the SMBIOS tables. Do not search the 0xF0000 segment to find SMBIOS
|
locate the SMBIOS tables. Do not search the 0xF0000 segment to find SMBIOS
|
||||||
tables.
|
tables.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
GUIDs defined in UEFI 2.5 spec.
|
GUIDs defined in UEFI 2.5 spec.
|
||||||
|
@ -22,7 +16,7 @@
|
||||||
#ifndef __SMBIOS_GUID_H__
|
#ifndef __SMBIOS_GUID_H__
|
||||||
#define __SMBIOS_GUID_H__
|
#define __SMBIOS_GUID_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#define SMBIOS_TABLE_GUID \
|
#define SMBIOS_TABLE_GUID \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -2,13 +2,7 @@
|
||||||
GUID for UEFI WIN_CERTIFICATE structure.
|
GUID for UEFI WIN_CERTIFICATE structure.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
GUID defined in UEFI 2.0 spec.
|
GUID defined in UEFI 2.0 spec.
|
||||||
|
@ -17,7 +11,7 @@
|
||||||
#ifndef __EFI_WIN_CERTIFICATE_H__
|
#ifndef __EFI_WIN_CERTIFICATE_H__
|
||||||
#define __EFI_WIN_CERTIFICATE_H__
|
#define __EFI_WIN_CERTIFICATE_H__
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
//
|
//
|
||||||
// _WIN_CERTIFICATE.wCertificateType
|
// _WIN_CERTIFICATE.wCertificateType
|
||||||
|
@ -69,7 +63,6 @@ typedef struct {
|
||||||
UINT8 Signature[256];
|
UINT8 Signature[256];
|
||||||
} EFI_CERT_BLOCK_RSA_2048_SHA256;
|
} EFI_CERT_BLOCK_RSA_2048_SHA256;
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Certificate which encapsulates a GUID-specific digital signature
|
/// Certificate which encapsulates a GUID-specific digital signature
|
||||||
///
|
///
|
||||||
|
@ -93,7 +86,6 @@ typedef struct {
|
||||||
UINT8 CertData[1];
|
UINT8 CertData[1];
|
||||||
} WIN_CERTIFICATE_UEFI_GUID;
|
} WIN_CERTIFICATE_UEFI_GUID;
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
|
/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
/** @file
|
/** @file
|
||||||
Processor or Compiler specific defines and types for IA-32 architecture.
|
Processor or Compiler specific defines and types for IA-32 architecture.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __PROCESSOR_BIND_H__
|
#ifndef __PROCESSOR_BIND_H__
|
||||||
#define __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.
|
/// Define the processor type so other code can make processor based choices.
|
||||||
|
@ -25,39 +19,38 @@ FILE_LICENCE ( BSD3 );
|
||||||
//
|
//
|
||||||
// Make sure we are using the correct packing rules per EFI specification
|
// Make sure we are using the correct packing rules per EFI specification
|
||||||
//
|
//
|
||||||
#if !defined(__GNUC__)
|
#if !defined (__GNUC__)
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER)
|
#if defined (__INTEL_COMPILER)
|
||||||
//
|
//
|
||||||
// Disable ICC's remark #869: "Parameter" was never referenced warning.
|
// Disable ICC's remark #869: "Parameter" was never referenced warning.
|
||||||
// This is legal ANSI C code so we disable the remark that is turned on with -Wall
|
// This is legal ANSI C code so we disable the remark that is turned on with -Wall
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 869 )
|
#pragma warning ( disable : 869 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable ICC's remark #1418: external function definition with no prior declaration.
|
// Disable ICC's remark #1418: external function definition with no prior declaration.
|
||||||
// This is legal ANSI C code so we disable the remark that is turned on with /W4
|
// This is legal ANSI C code so we disable the remark that is turned on with /W4
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 1418 )
|
#pragma warning ( disable : 1418 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable ICC's remark #1419: external declaration in primary source file
|
// Disable ICC's remark #1419: external declaration in primary source file
|
||||||
// This is legal ANSI C code so we disable the remark that is turned on with /W4
|
// This is legal ANSI C code so we disable the remark that is turned on with /W4
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 1419 )
|
#pragma warning ( disable : 1419 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable ICC's remark #593: "Variable" was set but never used.
|
// Disable ICC's remark #593: "Variable" was set but never used.
|
||||||
// This is legal ANSI C code so we disable the remark that is turned on with /W4
|
// This is legal ANSI C code so we disable the remark that is turned on with /W4
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 593 )
|
#pragma warning ( disable : 593 )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (_MSC_EXTENSIONS)
|
||||||
#if defined(_MSC_EXTENSIONS)
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable warning that make it impossible to compile at /W4
|
// Disable warning that make it impossible to compile at /W4
|
||||||
|
@ -67,35 +60,35 @@ FILE_LICENCE ( BSD3 );
|
||||||
//
|
//
|
||||||
// Disabling bitfield type checking warnings.
|
// Disabling bitfield type checking warnings.
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4214 )
|
#pragma warning ( disable : 4214 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disabling the unreferenced formal parameter warnings.
|
// Disabling the unreferenced formal parameter warnings.
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4100 )
|
#pragma warning ( disable : 4100 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable slightly different base types warning as CHAR8 * can not be set
|
// Disable slightly different base types warning as CHAR8 * can not be set
|
||||||
// to a constant string.
|
// to a constant string.
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4057 )
|
#pragma warning ( disable : 4057 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
|
// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4127 )
|
#pragma warning ( disable : 4127 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// This warning is caused by functions defined but not used. For precompiled header only.
|
// This warning is caused by functions defined but not used. For precompiled header only.
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4505 )
|
#pragma warning ( disable : 4505 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
|
// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4206 )
|
#pragma warning ( disable : 4206 )
|
||||||
|
|
||||||
#if _MSC_VER == 1800 || _MSC_VER == 1900
|
#if defined (_MSC_VER) && _MSC_VER >= 1800
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable these warnings for VS2013.
|
// Disable these warnings for VS2013.
|
||||||
|
@ -105,118 +98,117 @@ FILE_LICENCE ( BSD3 );
|
||||||
// This warning is for potentially uninitialized local variable, and it may cause false
|
// This warning is for potentially uninitialized local variable, and it may cause false
|
||||||
// positive issues in VS2013 and VS2015 build
|
// positive issues in VS2013 and VS2015 build
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4701 )
|
#pragma warning ( disable : 4701 )
|
||||||
|
|
||||||
//
|
//
|
||||||
// This warning is for potentially uninitialized local pointer variable, and it may cause
|
// This warning is for potentially uninitialized local pointer variable, and it may cause
|
||||||
// false positive issues in VS2013 and VS2015 build
|
// false positive issues in VS2013 and VS2015 build
|
||||||
//
|
//
|
||||||
#pragma warning ( disable : 4703 )
|
#pragma warning ( disable : 4703 )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#if defined (_MSC_EXTENSIONS)
|
||||||
|
|
||||||
|
//
|
||||||
|
// use Microsoft C compiler dependent integer width types
|
||||||
|
//
|
||||||
|
|
||||||
#if defined(_MSC_EXTENSIONS)
|
///
|
||||||
|
/// 8-byte unsigned value.
|
||||||
//
|
///
|
||||||
// use Microsoft C compiler dependent integer width types
|
typedef unsigned __int64 UINT64;
|
||||||
//
|
///
|
||||||
|
/// 8-byte signed value.
|
||||||
///
|
///
|
||||||
/// 8-byte unsigned value.
|
typedef __int64 INT64;
|
||||||
///
|
///
|
||||||
typedef unsigned __int64 UINT64;
|
/// 4-byte unsigned value.
|
||||||
///
|
///
|
||||||
/// 8-byte signed value.
|
typedef unsigned __int32 UINT32;
|
||||||
///
|
///
|
||||||
typedef __int64 INT64;
|
/// 4-byte signed value.
|
||||||
///
|
///
|
||||||
/// 4-byte unsigned value.
|
typedef __int32 INT32;
|
||||||
///
|
///
|
||||||
typedef unsigned __int32 UINT32;
|
/// 2-byte unsigned value.
|
||||||
///
|
///
|
||||||
/// 4-byte signed value.
|
typedef unsigned short UINT16;
|
||||||
///
|
///
|
||||||
typedef __int32 INT32;
|
/// 2-byte Character. Unless otherwise specified all strings are stored in the
|
||||||
///
|
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
|
||||||
/// 2-byte unsigned value.
|
///
|
||||||
///
|
typedef unsigned short CHAR16;
|
||||||
typedef unsigned short UINT16;
|
///
|
||||||
///
|
/// 2-byte signed value.
|
||||||
/// 2-byte Character. Unless otherwise specified all strings are stored in the
|
///
|
||||||
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
|
typedef short INT16;
|
||||||
///
|
///
|
||||||
typedef unsigned short CHAR16;
|
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
|
||||||
///
|
/// values are undefined.
|
||||||
/// 2-byte signed value.
|
///
|
||||||
///
|
typedef unsigned char BOOLEAN;
|
||||||
typedef short INT16;
|
///
|
||||||
///
|
/// 1-byte unsigned value.
|
||||||
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
|
///
|
||||||
/// values are undefined.
|
typedef unsigned char UINT8;
|
||||||
///
|
///
|
||||||
typedef unsigned char BOOLEAN;
|
/// 1-byte Character.
|
||||||
///
|
///
|
||||||
/// 1-byte unsigned value.
|
typedef char CHAR8;
|
||||||
///
|
///
|
||||||
typedef unsigned char UINT8;
|
/// 1-byte signed value.
|
||||||
///
|
///
|
||||||
/// 1-byte Character.
|
typedef signed char INT8;
|
||||||
///
|
|
||||||
typedef char CHAR8;
|
|
||||||
///
|
|
||||||
/// 1-byte signed value.
|
|
||||||
///
|
|
||||||
typedef signed char INT8;
|
|
||||||
#else
|
#else
|
||||||
///
|
///
|
||||||
/// 8-byte unsigned value.
|
/// 8-byte unsigned value.
|
||||||
///
|
///
|
||||||
typedef unsigned long long UINT64;
|
typedef unsigned long long UINT64;
|
||||||
///
|
///
|
||||||
/// 8-byte signed value.
|
/// 8-byte signed value.
|
||||||
///
|
///
|
||||||
typedef long long INT64;
|
typedef long long INT64;
|
||||||
///
|
///
|
||||||
/// 4-byte unsigned value.
|
/// 4-byte unsigned value.
|
||||||
///
|
///
|
||||||
typedef unsigned int UINT32;
|
typedef unsigned int UINT32;
|
||||||
///
|
///
|
||||||
/// 4-byte signed value.
|
/// 4-byte signed value.
|
||||||
///
|
///
|
||||||
typedef int INT32;
|
typedef int INT32;
|
||||||
///
|
///
|
||||||
/// 2-byte unsigned value.
|
/// 2-byte unsigned value.
|
||||||
///
|
///
|
||||||
typedef unsigned short UINT16;
|
typedef unsigned short UINT16;
|
||||||
///
|
///
|
||||||
/// 2-byte Character. Unless otherwise specified all strings are stored in the
|
/// 2-byte Character. Unless otherwise specified all strings are stored in the
|
||||||
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
|
/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
|
||||||
///
|
///
|
||||||
typedef unsigned short CHAR16;
|
typedef unsigned short CHAR16;
|
||||||
///
|
///
|
||||||
/// 2-byte signed value.
|
/// 2-byte signed value.
|
||||||
///
|
///
|
||||||
typedef short INT16;
|
typedef short INT16;
|
||||||
///
|
///
|
||||||
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
|
/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other
|
||||||
/// values are undefined.
|
/// values are undefined.
|
||||||
///
|
///
|
||||||
typedef unsigned char BOOLEAN;
|
typedef unsigned char BOOLEAN;
|
||||||
///
|
///
|
||||||
/// 1-byte unsigned value.
|
/// 1-byte unsigned value.
|
||||||
///
|
///
|
||||||
typedef unsigned char UINT8;
|
typedef unsigned char UINT8;
|
||||||
///
|
///
|
||||||
/// 1-byte Character
|
/// 1-byte Character
|
||||||
///
|
///
|
||||||
typedef char CHAR8;
|
typedef char CHAR8;
|
||||||
///
|
///
|
||||||
/// 1-byte signed value
|
/// 1-byte signed value
|
||||||
///
|
///
|
||||||
typedef signed char INT8;
|
typedef signed char INT8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -248,12 +240,22 @@ typedef INT32 INTN;
|
||||||
///
|
///
|
||||||
#define MAX_ADDRESS 0xFFFFFFFF
|
#define MAX_ADDRESS 0xFFFFFFFF
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Maximum usable address at boot time
|
||||||
|
///
|
||||||
|
#define MAX_ALLOC_ADDRESS MAX_ADDRESS
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Maximum legal IA-32 INTN and UINTN values.
|
/// Maximum legal IA-32 INTN and UINTN values.
|
||||||
///
|
///
|
||||||
#define MAX_INTN ((INTN)0x7FFFFFFF)
|
#define MAX_INTN ((INTN)0x7FFFFFFF)
|
||||||
#define MAX_UINTN ((UINTN)0xFFFFFFFF)
|
#define MAX_UINTN ((UINTN)0xFFFFFFFF)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Minimum legal IA-32 INTN value.
|
||||||
|
///
|
||||||
|
#define MIN_INTN (((INTN)-2147483647) - 1)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The stack alignment required for IA-32.
|
/// The stack alignment required for IA-32.
|
||||||
///
|
///
|
||||||
|
@ -271,33 +273,33 @@ typedef INT32 INTN;
|
||||||
// EFI intrinsics are required to modify their member functions with EFIAPI.
|
// EFI intrinsics are required to modify their member functions with EFIAPI.
|
||||||
//
|
//
|
||||||
#ifdef EFIAPI
|
#ifdef EFIAPI
|
||||||
///
|
///
|
||||||
/// If EFIAPI is already defined, then we use that definition.
|
/// If EFIAPI is already defined, then we use that definition.
|
||||||
///
|
///
|
||||||
#elif defined(_MSC_EXTENSIONS)
|
#elif defined (_MSC_EXTENSIONS)
|
||||||
///
|
///
|
||||||
/// Microsoft* compiler specific method for EFIAPI calling convention.
|
/// Microsoft* compiler specific method for EFIAPI calling convention.
|
||||||
///
|
///
|
||||||
#define EFIAPI __cdecl
|
#define EFIAPI __cdecl
|
||||||
#elif defined(__GNUC__)
|
#elif defined (__GNUC__) || defined (__clang__)
|
||||||
///
|
///
|
||||||
/// GCC specific method for EFIAPI calling convention.
|
/// GCC specific method for EFIAPI calling convention.
|
||||||
///
|
///
|
||||||
#define EFIAPI __attribute__((cdecl))
|
#define EFIAPI __attribute__((cdecl))
|
||||||
#else
|
#else
|
||||||
///
|
///
|
||||||
/// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI
|
/// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI
|
||||||
/// is the standard.
|
/// is the standard.
|
||||||
///
|
///
|
||||||
#define EFIAPI
|
#define EFIAPI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined (__GNUC__) || defined (__clang__)
|
||||||
///
|
///
|
||||||
/// For GNU assembly code, .global or .globl can declare global symbols.
|
/// For GNU assembly code, .global or .globl can declare global symbols.
|
||||||
/// Define this macro to unify the usage.
|
/// Define this macro to unify the usage.
|
||||||
///
|
///
|
||||||
#define ASM_GLOBAL .globl
|
#define ASM_GLOBAL .globl
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -317,4 +319,3 @@ typedef INT32 INTN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
/** @file
|
/** @file
|
||||||
ACPI 1.0b definitions from the ACPI Specification, revision 1.0b
|
ACPI 1.0b definitions from the ACPI Specification, revision 1.0b
|
||||||
|
|
||||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
|
||||||
the terms and conditions of the BSD License that accompanies this distribution.
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef _ACPI_1_0_H_
|
#ifndef _ACPI_1_0_H_
|
||||||
#define _ACPI_1_0_H_
|
#define _ACPI_1_0_H_
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#include <ipxe/efi/IndustryStandard/AcpiAml.h>
|
#include <ipxe/efi/IndustryStandard/AcpiAml.h>
|
||||||
|
|
||||||
|
@ -45,7 +40,7 @@ typedef struct {
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
//
|
//
|
||||||
// Define for Desriptor
|
// Define for Descriptor
|
||||||
//
|
//
|
||||||
#define ACPI_SMALL_ITEM_FLAG 0x00
|
#define ACPI_SMALL_ITEM_FLAG 0x00
|
||||||
#define ACPI_LARGE_ITEM_FLAG 0x01
|
#define ACPI_LARGE_ITEM_FLAG 0x01
|
||||||
|
@ -117,7 +112,7 @@ typedef struct {
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The commond definition of QWORD, DWORD, and WORD
|
/// The common definition of QWORD, DWORD, and WORD
|
||||||
/// Address Space Descriptors.
|
/// Address Space Descriptors.
|
||||||
///
|
///
|
||||||
typedef PACKED struct {
|
typedef PACKED struct {
|
||||||
|
@ -148,7 +143,7 @@ typedef PACKED struct {
|
||||||
PACKED struct {
|
PACKED struct {
|
||||||
UINT8 Name : 7;
|
UINT8 Name : 7;
|
||||||
UINT8 Type : 1;
|
UINT8 Type : 1;
|
||||||
}Bits;
|
} Bits;
|
||||||
} Header;
|
} Header;
|
||||||
UINT16 Length;
|
UINT16 Length;
|
||||||
} ACPI_LARGE_RESOURCE_HEADER;
|
} ACPI_LARGE_RESOURCE_HEADER;
|
||||||
|
@ -366,7 +361,7 @@ typedef struct {
|
||||||
#define EFI_ACPI_DMA_TRANSFER_TYPE_MASK 0x03
|
#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 0x00
|
||||||
#define EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x01
|
#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
|
// IO Information
|
||||||
|
@ -384,6 +379,16 @@ typedef struct {
|
||||||
#define EFI_ACPI_MEMORY_WRITABLE 0x01
|
#define EFI_ACPI_MEMORY_WRITABLE 0x01
|
||||||
#define EFI_ACPI_MEMORY_NON_WRITABLE 0x00
|
#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
|
// Ensure proper structure formats
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
/** @file
|
/** @file
|
||||||
ACPI 2.0 definitions from the ACPI Specification, revision 2.0
|
ACPI 2.0 definitions from the ACPI Specification, revision 2.0
|
||||||
|
|
||||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
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.
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef _ACPI_2_0_H_
|
#ifndef _ACPI_2_0_H_
|
||||||
#define _ACPI_2_0_H_
|
#define _ACPI_2_0_H_
|
||||||
|
|
||||||
FILE_LICENCE ( BSD3 );
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
#include <ipxe/efi/IndustryStandard/Acpi10.h>
|
#include <ipxe/efi/IndustryStandard/Acpi10.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Define for Desriptor
|
// Define for Descriptor
|
||||||
//
|
//
|
||||||
#define ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME 0x02
|
#define ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME 0x02
|
||||||
|
|
||||||
|
@ -513,7 +507,7 @@ typedef struct {
|
||||||
#define EFI_ACPI_2_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T')
|
#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')
|
#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