summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/ipxe')
-rw-r--r--src/include/ipxe/cachedhcp.h2
-rw-r--r--src/include/ipxe/efi/Protocol/MpService.h676
-rw-r--r--src/include/ipxe/efi/Protocol/ServiceBinding.h90
-rw-r--r--src/include/ipxe/efi/efi_autoexec.h5
-rw-r--r--src/include/ipxe/efi/efi_driver.h4
-rw-r--r--src/include/ipxe/efi/efi_mp.h30
-rw-r--r--src/include/ipxe/efi/efi_path.h2
-rw-r--r--src/include/ipxe/efi/efi_service.h19
-rw-r--r--src/include/ipxe/efi/mnpnet.h20
-rw-r--r--src/include/ipxe/errfile.h5
-rw-r--r--src/include/ipxe/gcm.h7
-rw-r--r--src/include/ipxe/mp.h155
-rw-r--r--src/include/ipxe/null_mp.h36
-rw-r--r--src/include/ipxe/settings.h4
14 files changed, 1046 insertions, 9 deletions
diff --git a/src/include/ipxe/cachedhcp.h b/src/include/ipxe/cachedhcp.h
index 4ce4a9f2..8ebee3b7 100644
--- a/src/include/ipxe/cachedhcp.h
+++ b/src/include/ipxe/cachedhcp.h
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <ipxe/uaccess.h>
+struct net_device;
struct cached_dhcp_packet;
extern struct cached_dhcp_packet cached_dhcpack;
@@ -21,5 +22,6 @@ extern struct cached_dhcp_packet cached_pxebs;
extern int cachedhcp_record ( struct cached_dhcp_packet *cache,
unsigned int vlan, userptr_t data,
size_t max_len );
+extern void cachedhcp_recycle ( struct net_device *netdev );
#endif /* _IPXE_CACHEDHCP_H */
diff --git a/src/include/ipxe/efi/Protocol/MpService.h b/src/include/ipxe/efi/Protocol/MpService.h
new file mode 100644
index 00000000..cd1bb27f
--- /dev/null
+++ b/src/include/ipxe/efi/Protocol/MpService.h
@@ -0,0 +1,676 @@
+/** @file
+ When installed, the MP Services Protocol produces a collection of services
+ that are needed for MP management.
+
+ The MP Services Protocol provides a generalized way of performing following tasks:
+ - Retrieving information of multi-processor environment and MP-related status of
+ specific processors.
+ - Dispatching user-provided function to APs.
+ - Maintain MP-related processor status.
+
+ The MP Services Protocol must be produced on any system with more than one logical
+ processor.
+
+ The Protocol is available only during boot time.
+
+ MP Services Protocol is hardware-independent. Most of the logic of this protocol
+ is architecturally neutral. It abstracts the multi-processor environment and
+ status of processors, and provides interfaces to retrieve information, maintain,
+ and dispatch.
+
+ MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
+ protocol to retrieve data that are needed for an MP platform and report them to OS.
+ MP Services Protocol may also be used to program and configure processors, such
+ as MTRR synchronization for memory space attributes setting in DXE Services.
+ MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
+ by taking advantage of the processing capabilities of the APs, for example, using
+ APs to help test system memory in parallel with other device initialization.
+ Diagnostics applications may also use this protocol for multi-processor.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ This Protocol is defined in the UEFI Platform Initialization Specification 1.2,
+ Volume 2:Driver Execution Environment Core Interface.
+
+**/
+
+#ifndef _MP_SERVICE_PROTOCOL_H_
+#define _MP_SERVICE_PROTOCOL_H_
+
+FILE_LICENCE ( BSD2_PATENT );
+
+///
+/// Global ID for the EFI_MP_SERVICES_PROTOCOL.
+///
+#define EFI_MP_SERVICES_PROTOCOL_GUID \
+ { \
+ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} \
+ }
+
+///
+/// Value used in the NumberProcessors parameter of the GetProcessorInfo function
+///
+#define CPU_V2_EXTENDED_TOPOLOGY BIT24
+
+///
+/// Forward declaration for the EFI_MP_SERVICES_PROTOCOL.
+///
+typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL;
+
+///
+/// Terminator for a list of failed CPUs returned by StartAllAPs().
+///
+#define END_OF_CPU_LIST 0xffffffff
+
+///
+/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+/// indicates whether the processor is playing the role of BSP. If the bit is 1,
+/// then the processor is BSP. Otherwise, it is AP.
+///
+#define PROCESSOR_AS_BSP_BIT 0x00000001
+
+///
+/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+/// indicates whether the processor is enabled. If the bit is 1, then the
+/// processor is enabled. Otherwise, it is disabled.
+///
+#define PROCESSOR_ENABLED_BIT 0x00000002
+
+///
+/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+/// indicates whether the processor is healthy. If the bit is 1, then the
+/// processor is healthy. Otherwise, some fault has been detected for the processor.
+///
+#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004
+
+///
+/// Structure that describes the pyhiscal location of a logical CPU.
+///
+typedef struct {
+ ///
+ /// Zero-based physical package number that identifies the cartridge of the processor.
+ ///
+ UINT32 Package;
+ ///
+ /// Zero-based physical core number within package of the processor.
+ ///
+ UINT32 Core;
+ ///
+ /// Zero-based logical thread number within core of the processor.
+ ///
+ UINT32 Thread;
+} EFI_CPU_PHYSICAL_LOCATION;
+
+///
+/// Structure that defines the 6-level physical location of the processor
+///
+typedef struct {
+ ///
+ /// Package Zero-based physical package number that identifies the cartridge of the processor.
+ ///
+ UINT32 Package;
+ ///
+ /// Module Zero-based physical module number within package of the processor.
+ ///
+ UINT32 Module;
+ ///
+ /// Tile Zero-based physical tile number within module of the processor.
+ ///
+ UINT32 Tile;
+ ///
+ /// Die Zero-based physical die number within tile of the processor.
+ ///
+ UINT32 Die;
+ ///
+ /// Core Zero-based physical core number within die of the processor.
+ ///
+ UINT32 Core;
+ ///
+ /// Thread Zero-based logical thread number within core of the processor.
+ ///
+ UINT32 Thread;
+} EFI_CPU_PHYSICAL_LOCATION2;
+
+typedef union {
+ /// The 6-level physical location of the processor, including the
+ /// physical package number that identifies the cartridge, the physical
+ /// module number within package, the physical tile number within the module,
+ /// the physical die number within the tile, the physical core number within
+ /// package, and logical thread number within core.
+ EFI_CPU_PHYSICAL_LOCATION2 Location2;
+} EXTENDED_PROCESSOR_INFORMATION;
+
+///
+/// Structure that describes information about a logical CPU.
+///
+typedef struct {
+ ///
+ /// The unique processor ID determined by system hardware. For IA32 and X64,
+ /// the processor ID is the same as the Local APIC ID. Only the lower 8 bits
+ /// are used, and higher bits are reserved. For IPF, the lower 16 bits contains
+ /// id/eid, and higher bits are reserved.
+ ///
+ UINT64 ProcessorId;
+ ///
+ /// Flags indicating if the processor is BSP or AP, if the processor is enabled
+ /// or disabled, and if the processor is healthy. Bits 3..31 are reserved and
+ /// must be 0.
+ ///
+ /// <pre>
+ /// BSP ENABLED HEALTH Description
+ /// === ======= ====== ===================================================
+ /// 0 0 0 Unhealthy Disabled AP.
+ /// 0 0 1 Healthy Disabled AP.
+ /// 0 1 0 Unhealthy Enabled AP.
+ /// 0 1 1 Healthy Enabled AP.
+ /// 1 0 0 Invalid. The BSP can never be in the disabled state.
+ /// 1 0 1 Invalid. The BSP can never be in the disabled state.
+ /// 1 1 0 Unhealthy Enabled BSP.
+ /// 1 1 1 Healthy Enabled BSP.
+ /// </pre>
+ ///
+ UINT32 StatusFlag;
+ ///
+ /// The physical location of the processor, including the physical package number
+ /// that identifies the cartridge, the physical core number within package, and
+ /// logical thread number within core.
+ ///
+ EFI_CPU_PHYSICAL_LOCATION Location;
+ ///
+ /// The extended information of the processor. This field is filled only when
+ /// CPU_V2_EXTENDED_TOPOLOGY is set in parameter ProcessorNumber.
+ EXTENDED_PROCESSOR_INFORMATION ExtendedInformation;
+} EFI_PROCESSOR_INFORMATION;
+
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ This function is used to retrieve the following information:
+ - The number of logical processors that are present in the system.
+ - The number of enabled logical processors in the system at the instant
+ this call is made.
+
+ Because MP Service Protocol provides services to enable and disable processors
+ dynamically, the number of enabled logical processors may vary during the
+ course of a boot session.
+
+ If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+ If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+ is returned in NumberOfProcessors, the number of currently enabled processor
+ is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including the BSP
+ and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
+ processors that exist in system, including
+ the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)(
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ );
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of operation,
+ slot numbers is all considered platform-related information and is not provided
+ by this service.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] ProcessorNumber The handle number of processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
+ the requested processor is deposited.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_INFO)(
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ );
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
+ be called from the BSP.
+
+ This function is used to dispatch all the enabled APs to the function specified
+ by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
+ immediately and Procedure is not started on any AP.
+
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number. Otherwise,
+ all the enabled APs execute the function specified by Procedure simultaneously.
+
+ If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
+ APs finish or TimeoutInMicroSecs expires. Otherwise, execution is in non-blocking
+ mode, and the BSP returns from this service without waiting for APs. If a
+ non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled, then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before all APs return
+ from Procedure, then Procedure on the failed APs is terminated. All enabled APs
+ are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
+ terminated.
+
+ Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ to make sure that the nature of the code that is executed on the BSP and the
+ dispatched APs is well controlled. The MP Services Protocol does not guarantee
+ that the Procedure function is MP-safe. Hence, the tasks that can be run in
+ parallel are limited to certain independent tasks and well-controlled exclusive
+ code. EFI services and protocols may not be called by APs unless otherwise
+ specified.
+
+ In blocking execution mode, BSP waits until all APs finish or
+ TimeoutInMicroSeconds expires.
+
+ In non-blocking execution mode, BSP is freed to return to the caller and then
+ proceed to the next task without having to wait for APs. The following
+ sequence needs to occur in a non-blocking execution mode:
+
+ -# The caller that intends to use this MP Services Protocol in non-blocking
+ mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
+ invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
+ is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
+ the function specified by Procedure to be started on all the enabled APs,
+ and releases the BSP to continue with other tasks.
+ -# The caller can use the CheckEvent() and WaitForEvent() services to check
+ the state of the WaitEvent created in step 1.
+ -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
+ Service signals WaitEvent by calling the EFI SignalEvent() function. If
+ FailedCpuList is not NULL, its content is available when WaitEvent is
+ signaled. If all APs returned from Procedure prior to the timeout, then
+ FailedCpuList is set to NULL. If not all APs return from Procedure before
+ the timeout, then FailedCpuList is filled in with the list of the failed
+ APs. The buffer is allocated by MP Service Protocol using AllocatePool().
+ It is the caller's responsibility to free the buffer with FreePool() service.
+ -# This invocation of SignalEvent() function informs the caller that invoked
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
+ the specified task or a timeout occurred. The contents of FailedCpuList
+ can be examined to determine which APs did not complete the specified task
+ prior to the timeout.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroSeconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure, or TimeoutInMicroSeconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
+ if all APs finish successfully, then its
+ content is set to NULL. If not all APs
+ finish before timeout expires, then its
+ content is set to address of the buffer
+ holding handle numbers of the failed APs.
+ The buffer is allocated by MP Service Protocol,
+ and it's the caller's responsibility to
+ free the buffer with FreePool() service.
+ In blocking mode, it is ready for consumption
+ when the call returns. In non-blocking mode,
+ it is ready when WaitEvent is signaled. The
+ list of failed CPU is terminated by
+ END_OF_CPU_LIST.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
+ to all enabled APs.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ all enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MP_SERVICES_STARTUP_ALL_APS)(
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroSeconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ );
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ execution support. This service may only be called from the BSP.
+
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
+ is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
+ BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
+ is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
+ then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+ EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on the
+ designated AP of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until this AP finish
+ or TimeoutInMicroSeconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on this AP,
+ and go on executing immediately. If this AP
+ return from Procedure or TimeoutInMicroSeconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ this AP to finish this Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ this AP returns from Procedure, then Procedure
+ on the AP is terminated. The
+ AP is available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure on the
+ specified AP.
+ @param[out] Finished If NULL, this parameter is ignored. In
+ blocking mode, this parameter is ignored.
+ In non-blocking mode, if AP returns from
+ Procedure before the timeout expires, its
+ content is set to TRUE. Otherwise, the
+ value is set to FALSE. The caller can
+ determine if the AP returned from Procedure
+ by evaluating this value.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
+ dispatched to specified AP.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ the specified AP has finished.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MP_SERVICES_STARTUP_THIS_AP)(
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ );
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
+ by the current BSP.
+
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled.
+
+ If the BSP cannot be switched prior to the return from this service, then
+ EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MP_SERVICES_SWITCH_BSP)(
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ );
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ This service allows the caller enable or disable an AP from this point onward.
+ The caller can optionally specify the health status of the AP by Health. If
+ an AP is being disabled, then the state of the disabled AP is implementation
+ dependent. If an AP is enabled, then the implementation must guarantee that a
+ complete initialization sequence is performed on the AP, so the AP is in a state
+ that is compatible with an MP operating system. This service may not be supported
+ after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
+
+ If the enable or disable AP operation cannot be completed prior to the return
+ from this service, then EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP.
+ The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
+ is ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ prior to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MP_SERVICES_ENABLEDISABLEAP)(
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ );
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
+ ProcessorNumber, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber Pointer to the handle number of AP.
+ The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MP_SERVICES_WHOAMI)(
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *ProcessorNumber
+ );
+
+///
+/// When installed, the MP Services Protocol produces a collection of services
+/// that are needed for MP management.
+///
+/// Before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the module
+/// that produces this protocol is required to place all APs into an idle state
+/// whenever the APs are disabled or the APs are not executing code as requested
+/// through the StartupAllAPs() or StartupThisAP() services. The idle state of
+/// an AP before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled is
+/// implementation dependent.
+///
+/// After the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, all the APs
+/// must be placed in the OS compatible CPU state as defined by the UEFI
+/// Specification. Implementations of this protocol may use the UEFI event
+/// EFI_EVENT_GROUP_READY_TO_BOOT to force APs into the OS compatible state as
+/// defined by the UEFI Specification. Modules that use this protocol must
+/// guarantee that all non-blocking mode requests on all APs have been completed
+/// before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. Since the
+/// order that event notification functions in the same event group are executed
+/// is not deterministic, an event of type EFI_EVENT_GROUP_READY_TO_BOOT cannot
+/// be used to guarantee that APs have completed their non-blocking mode requests.
+///
+/// When the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the StartAllAPs()
+/// and StartupThisAp() services must no longer support non-blocking mode requests.
+/// The support for SwitchBSP() and EnableDisableAP() may no longer be supported
+/// after this event is signaled. Since UEFI Applications and UEFI OS Loaders
+/// execute after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, these
+/// UEFI images must be aware that the functionality of this protocol may be reduced.
+///
+struct _EFI_MP_SERVICES_PROTOCOL {
+ EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors;
+ EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo;
+ EFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs;
+ EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP;
+ EFI_MP_SERVICES_SWITCH_BSP SwitchBSP;
+ EFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP;
+ EFI_MP_SERVICES_WHOAMI WhoAmI;
+};
+
+extern EFI_GUID gEfiMpServiceProtocolGuid;
+
+#endif
diff --git a/src/include/ipxe/efi/Protocol/ServiceBinding.h b/src/include/ipxe/efi/Protocol/ServiceBinding.h
new file mode 100644
index 00000000..6baf73aa
--- /dev/null
+++ b/src/include/ipxe/efi/Protocol/ServiceBinding.h
@@ -0,0 +1,90 @@
+/** @file
+ UEFI Service Binding Protocol is defined in UEFI specification.
+
+ The file defines the generic Service Binding Protocol functions.
+ It provides services that are required to create and destroy child
+ handles that support a given set of protocols.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_SERVICE_BINDING_H__
+#define __EFI_SERVICE_BINDING_H__
+
+FILE_LICENCE ( BSD2_PATENT );
+
+///
+/// Forward reference for pure ANSI compatability
+///
+typedef struct _EFI_SERVICE_BINDING_PROTOCOL EFI_SERVICE_BINDING_PROTOCOL;
+
+/**
+ Creates a child handle and installs a protocol.
+
+ The CreateChild() function installs a protocol on ChildHandle.
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+ @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
+ then a new handle is created. If it is a pointer to an existing UEFI handle,
+ then the protocol is added to the existing UEFI handle.
+
+ @retval EFI_SUCCES The protocol was added to ChildHandle.
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
+ the child
+ @retval other The child handle was not created
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERVICE_BINDING_CREATE_CHILD)(
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN OUT EFI_HANDLE *ChildHandle
+ );
+
+/**
+ Destroys a child handle with a protocol installed on it.
+
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+ last protocol on ChildHandle, then ChildHandle is destroyed.
+
+ @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param ChildHandle Handle of the child to destroy
+
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
+ because its services are being used.
+ @retval other The child handle was not destroyed
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERVICE_BINDING_DESTROY_CHILD)(
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ChildHandle
+ );
+
+///
+/// The EFI_SERVICE_BINDING_PROTOCOL provides member functions to create and destroy
+/// child handles. A driver is responsible for adding protocols to the child handle
+/// in CreateChild() and removing protocols in DestroyChild(). It is also required
+/// that the CreateChild() function opens the parent protocol BY_CHILD_CONTROLLER
+/// to establish the parent-child relationship, and closes the protocol in DestroyChild().
+/// The pseudo code for CreateChild() and DestroyChild() is provided to specify the
+/// required behavior, not to specify the required implementation. Each consumer of
+/// a software protocol is responsible for calling CreateChild() when it requires the
+/// protocol and calling DestroyChild() when it is finished with that protocol.
+///
+struct _EFI_SERVICE_BINDING_PROTOCOL {
+ EFI_SERVICE_BINDING_CREATE_CHILD CreateChild;
+ EFI_SERVICE_BINDING_DESTROY_CHILD DestroyChild;
+};
+
+#endif
diff --git a/src/include/ipxe/efi/efi_autoexec.h b/src/include/ipxe/efi/efi_autoexec.h
index 08ddf583..18bc4200 100644
--- a/src/include/ipxe/efi/efi_autoexec.h
+++ b/src/include/ipxe/efi/efi_autoexec.h
@@ -9,9 +9,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-#include <ipxe/efi/efi.h>
-
-extern int efi_autoexec_load ( EFI_HANDLE device,
- EFI_DEVICE_PATH_PROTOCOL *path );
+extern int efi_autoexec_load ( void );
#endif /* _IPXE_EFI_AUTOEXEC_H */
diff --git a/src/include/ipxe/efi/efi_driver.h b/src/include/ipxe/efi/efi_driver.h
index 74ece90d..7b64e1e0 100644
--- a/src/include/ipxe/efi/efi_driver.h
+++ b/src/include/ipxe/efi/efi_driver.h
@@ -19,6 +19,8 @@ struct efi_device {
struct device dev;
/** EFI device handle */
EFI_HANDLE device;
+ /** EFI child device handle (if present) */
+ EFI_HANDLE child;
/** EFI device path copy */
EFI_DEVICE_PATH_PROTOCOL *path;
/** Driver for this device */
@@ -84,6 +86,8 @@ static inline void * efidev_get_drvdata ( struct efi_device *efidev ) {
return efidev->priv;
}
+extern struct efi_device * efidev_alloc ( EFI_HANDLE device );
+extern void efidev_free ( struct efi_device *efidev );
extern struct efi_device * efidev_parent ( struct device *dev );
extern int efi_driver_install ( void );
extern void efi_driver_uninstall ( void );
diff --git a/src/include/ipxe/efi/efi_mp.h b/src/include/ipxe/efi/efi_mp.h
new file mode 100644
index 00000000..8dc4243e
--- /dev/null
+++ b/src/include/ipxe/efi/efi_mp.h
@@ -0,0 +1,30 @@
+#ifndef _IPXE_EFI_MP_H
+#define _IPXE_EFI_MP_H
+
+/** @file
+ *
+ * EFI multiprocessor API implementation
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#ifdef MPAPI_EFI
+#define MPAPI_PREFIX_efi
+#else
+#define MPAPI_PREFIX_efi __efi_
+#endif
+
+/**
+ * Calculate address as seen by a multiprocessor function
+ *
+ * @v address Address in boot processor address space
+ * @ret address Address in application processor address space
+ */
+static inline __attribute__ (( always_inline )) mp_addr_t
+MPAPI_INLINE ( efi, mp_address ) ( void *address ) {
+
+ return ( ( mp_addr_t ) address );
+}
+
+#endif /* _IPXE_EFI_MP_H */
diff --git a/src/include/ipxe/efi/efi_path.h b/src/include/ipxe/efi/efi_path.h
index 20ff43f6..57fce402 100644
--- a/src/include/ipxe/efi/efi_path.h
+++ b/src/include/ipxe/efi/efi_path.h
@@ -43,8 +43,10 @@ efi_path_prev ( EFI_DEVICE_PATH_PROTOCOL *path,
extern EFI_DEVICE_PATH_PROTOCOL *
efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
+extern void * efi_path_mac ( EFI_DEVICE_PATH_PROTOCOL *path );
extern unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path );
extern int efi_path_guid ( EFI_DEVICE_PATH_PROTOCOL *path, union uuid *uuid );
+extern struct uri * efi_path_uri ( EFI_DEVICE_PATH_PROTOCOL *path );
extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first,
... );
extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
diff --git a/src/include/ipxe/efi/efi_service.h b/src/include/ipxe/efi/efi_service.h
new file mode 100644
index 00000000..ca4c7b2a
--- /dev/null
+++ b/src/include/ipxe/efi/efi_service.h
@@ -0,0 +1,19 @@
+#ifndef _IPXE_EFI_SERVICE_H
+#define _IPXE_EFI_SERVICE_H
+
+/** @file
+ *
+ * EFI service binding
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/efi/efi.h>
+
+extern int efi_service_add ( EFI_HANDLE service, EFI_GUID *binding,
+ EFI_HANDLE *handle );
+extern int efi_service_del ( EFI_HANDLE service, EFI_GUID *binding,
+ EFI_HANDLE handle );
+
+#endif /* _IPXE_EFI_SERVICE_H */
diff --git a/src/include/ipxe/efi/mnpnet.h b/src/include/ipxe/efi/mnpnet.h
new file mode 100644
index 00000000..99d6cf08
--- /dev/null
+++ b/src/include/ipxe/efi/mnpnet.h
@@ -0,0 +1,20 @@
+#ifndef _IPXE_EFI_MNPNET_H
+#define _IPXE_EFI_MNPNET_H
+
+/** @file
+ *
+ * MNP NIC driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+struct efi_device;
+struct net_device;
+
+extern int mnpnet_start ( struct efi_device *efidev );
+extern void mnpnet_stop ( struct efi_device *efidev );
+extern int mnptemp_create ( EFI_HANDLE handle, struct net_device **netdev );
+extern void mnptemp_destroy ( struct net_device *netdev );
+
+#endif /* _IPXE_EFI_MNPNET_H */
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index 21c3d338..afc260ba 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -81,6 +81,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_efi_strings ( ERRFILE_CORE | 0x00290000 )
#define ERRFILE_uuid ( ERRFILE_CORE | 0x002a0000 )
#define ERRFILE_efi_path ( ERRFILE_CORE | 0x002b0000 )
+#define ERRFILE_efi_mp ( ERRFILE_CORE | 0x002c0000 )
+#define ERRFILE_efi_service ( ERRFILE_CORE | 0x002d0000 )
#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 )
#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )
@@ -221,7 +223,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_ice ( ERRFILE_DRIVER | 0x00d20000 )
#define ERRFILE_ecam ( ERRFILE_DRIVER | 0x00d30000 )
#define ERRFILE_pcibridge ( ERRFILE_DRIVER | 0x00d40000 )
-#define ERRFILE_aqc1xx ( ERRFILE_DRIVER | 0x00d50000 )
+#define ERRFILE_mnpnet ( ERRFILE_DRIVER | 0x00d50000 )
+#define ERRFILE_aqc1xx ( ERRFILE_DRIVER | 0x00df0000 )
#define ERRFILE_atl_hw ( ERRFILE_DRIVER | 0x00d60000 )
#define ERRFILE_atl2_hw ( ERRFILE_DRIVER | 0x00d70000 )
diff --git a/src/include/ipxe/gcm.h b/src/include/ipxe/gcm.h
index 4864445d..2c785a97 100644
--- a/src/include/ipxe/gcm.h
+++ b/src/include/ipxe/gcm.h
@@ -89,10 +89,9 @@ static int _gcm_name ## _setkey ( void *ctx, const void *key, \
size_t keylen ) { \
struct _gcm_name ## _context *context = ctx; \
build_assert ( _blocksize == sizeof ( context->gcm.key ) ); \
- build_assert ( ( ( void * ) &context->gcm ) == \
- ( ( void * ) context ) ); \
- build_assert ( ( ( void * ) &context->raw ) == \
- ( ( void * ) context->gcm.raw_ctx ) ); \
+ build_assert ( offsetof ( typeof ( *context ), gcm ) == 0 ); \
+ build_assert ( offsetof ( typeof ( *context ), raw ) == \
+ offsetof ( typeof ( *context ), gcm.raw_ctx ) ); \
return gcm_setkey ( &context->gcm, key, keylen, &_raw_cipher ); \
} \
static void _gcm_name ## _setiv ( void *ctx, const void *iv, \
diff --git a/src/include/ipxe/mp.h b/src/include/ipxe/mp.h
new file mode 100644
index 00000000..9670dea5
--- /dev/null
+++ b/src/include/ipxe/mp.h
@@ -0,0 +1,155 @@
+#ifndef _IPXE_MP_H
+#define _IPXE_MP_H
+
+/** @file
+ *
+ * Multiprocessor functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/api.h>
+#include <config/defaults.h>
+
+/**
+ * An address within the address space for a multiprocessor function
+ *
+ * Application processors may be started in a different address space
+ * from the normal iPXE runtime environment. For example: under
+ * legacy BIOS the application processors will use flat 32-bit
+ * physical addressing (with no paging or virtual address offset).
+ */
+typedef unsigned long mp_addr_t;
+
+/** A multiprocessor function
+ *
+ * @v opaque Opaque data pointer
+ * @v cpuid CPU identifier
+ *
+ * iPXE does not set up a normal multiprocessor environment. In
+ * particular, there is no support for dispatching code to individual
+ * processors and there is no per-CPU stack allocation.
+ *
+ * Multiprocessor code must be prepared to run wth no stack space (and
+ * with a zero stack pointer). Functions may use the CPU identifier
+ * to construct a pointer to per-CPU result storage.
+ *
+ * Multiprocessor functions are permitted to overwrite all registers
+ * apart from the stack pointer. On exit, the function should check
+ * the stack pointer value: if zero then the function should halt the
+ * CPU, if non-zero then the function should return in the normal way.
+ *
+ * Multiprocessor functions do not have access to any capabilities
+ * typically provided by the firmware: they cannot, for example, write
+ * any console output.
+ *
+ * All parameters are passed in registers, since there may be no stack
+ * available. These functions cannot be called directly from C code.
+ */
+typedef void ( mp_func_t ) ( mp_addr_t opaque, unsigned int cpuid );
+
+/**
+ * Call a multiprocessor function from C code on the current CPU
+ *
+ * @v func Multiprocessor function
+ * @v opaque Opaque data pointer
+ *
+ * This function must be provided for each CPU architecture to bridge
+ * the normal C ABI to the iPXE multiprocessor function ABI. It must
+ * therefore preserve any necessary registers, determine the CPU
+ * identifier, call the multiprocessor function (which may destroy any
+ * registers other than the stack pointer), restore registers, and
+ * return to the C caller.
+ *
+ * This function must be called from within the multiprocessor address
+ * space (e.g. with flat 32-bit physical addressing for BIOS). It can
+ * be called directly from C code if the multiprocessor address space
+ * is identical to the address space used for C code (e.g. under EFI,
+ * where everything uses flat physical addresses).
+ */
+extern void __asmcall mp_call ( mp_addr_t func, mp_addr_t opaque );
+
+/**
+ * Calculate static inline multiprocessor API function name
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ * @ret _subsys_func Subsystem API function
+ */
+#define MPAPI_INLINE( _subsys, _api_func ) \
+ SINGLE_API_INLINE ( MPAPI_PREFIX_ ## _subsys, _api_func )
+
+/**
+ * Provide a multiprocessor API implementation
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ * @v _func Implementing function
+ */
+#define PROVIDE_MPAPI( _subsys, _api_func, _func ) \
+ PROVIDE_SINGLE_API ( MPAPI_PREFIX_ ## _subsys, _api_func, _func )
+
+/**
+ * Provide a static inline multiprocessor API implementation
+ *
+ * @v _prefix Subsystem prefix
+ * @v _api_func API function
+ */
+#define PROVIDE_MPAPI_INLINE( _subsys, _api_func ) \
+ PROVIDE_SINGLE_API_INLINE ( MPAPI_PREFIX_ ## _subsys, _api_func )
+
+/* Include all architecture-independent multiprocessor API headers */
+#include <ipxe/null_mp.h>
+#include <ipxe/efi/efi_mp.h>
+
+/* Include all architecture-dependent multiprocessor API headers */
+#include <bits/mp.h>
+
+/**
+ * Calculate address as seen by a multiprocessor function
+ *
+ * @v address Address in normal iPXE address space
+ * @ret address Address in application processor address space
+ */
+mp_addr_t mp_address ( void *address );
+
+/**
+ * Execute a multiprocessor function on the boot processor
+ *
+ * @v func Multiprocessor function
+ * @v opaque Opaque data pointer
+ *
+ * This is a blocking operation: the call will return only when the
+ * multiprocessor function exits.
+ */
+void mp_exec_boot ( mp_func_t func, void *opaque );
+
+/**
+ * Start a multiprocessor function on all application processors
+ *
+ * @v func Multiprocessor function
+ * @v opaque Opaque data pointer
+ *
+ * This is a non-blocking operation: it is the caller's responsibility
+ * to provide a way to determine when the multiprocessor function has
+ * finished executing and halted its CPU.
+ */
+void mp_start_all ( mp_func_t func, void *opaque );
+
+/**
+ * Update maximum observed CPU identifier
+ *
+ * @v opaque Opaque data pointer
+ * @v cpuid CPU identifier
+ *
+ * This may be invoked on each processor to update a shared maximum
+ * CPU identifier value.
+ */
+extern mp_func_t mp_update_max_cpuid;
+
+extern unsigned int mp_boot_cpuid ( void );
+extern unsigned int mp_max_cpuid ( void );
+
+#endif /* _IPXE_MP_H */
diff --git a/src/include/ipxe/null_mp.h b/src/include/ipxe/null_mp.h
new file mode 100644
index 00000000..f89da5d9
--- /dev/null
+++ b/src/include/ipxe/null_mp.h
@@ -0,0 +1,36 @@
+#ifndef _IPXE_NULL_MP_H
+#define _IPXE_NULL_MP_H
+
+/** @file
+ *
+ * Null multiprocessor API implementation
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#ifdef MPAPI_NULL
+#define MPAPI_PREFIX_null
+#else
+#define MPAPI_PREFIX_null __null_
+#endif
+
+static inline __attribute__ (( always_inline )) mp_addr_t
+MPAPI_INLINE ( null, mp_address ) ( void *address ) {
+
+ return ( ( mp_addr_t ) address );
+}
+
+static inline __attribute__ (( always_inline )) void
+MPAPI_INLINE ( null, mp_exec_boot ) ( mp_func_t func __unused,
+ void *opaque __unused ) {
+ /* Do nothing */
+}
+
+static inline __attribute__ (( always_inline )) void
+MPAPI_INLINE ( null, mp_start_all ) ( mp_func_t func __unused,
+ void *opaque __unused ) {
+ /* Do nothing */
+}
+
+#endif /* _IPXE_NULL_MP_H */
diff --git a/src/include/ipxe/settings.h b/src/include/ipxe/settings.h
index 9759a600..ccb5e99f 100644
--- a/src/include/ipxe/settings.h
+++ b/src/include/ipxe/settings.h
@@ -446,6 +446,8 @@ len6_setting __setting ( SETTING_IP6, len6 );
extern const struct setting
gateway6_setting __setting ( SETTING_IP6, gateway6 );
extern const struct setting
+dns6_setting __setting ( SETTING_IP6_EXTRA, dns6 );
+extern const struct setting
hostname_setting __setting ( SETTING_HOST, hostname );
extern const struct setting
domain_setting __setting ( SETTING_IP_EXTRA, domain );
@@ -470,6 +472,8 @@ mac_setting __setting ( SETTING_NETDEV, mac );
extern const struct setting
busid_setting __setting ( SETTING_NETDEV, busid );
extern const struct setting
+linktype_setting __setting ( SETTING_NETDEV, linktype );
+extern const struct setting
user_class_setting __setting ( SETTING_HOST_EXTRA, user-class );
extern const struct setting
vendor_class_setting __setting ( SETTING_HOST_EXTRA, vendor-class );