Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/25634
Change subject: soc/intel/common: Implement EFI_MP_SERVICES_PPI structure APIs ......................................................................
soc/intel/common: Implement EFI_MP_SERVICES_PPI structure APIs
This patch ensures to implement all required APIs for EFI_MP_SERVICES_PPI as per EDK2 UefiPkg Open source specification
More details here: https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Ppi/MpServices....
Supported SOC will call fill mp_services structure so that FSP can install the required PPI based on coreboot published structure.
BRANCH=none BUG=b:74436746 TEST=Able to publish MP service PPI in coreboot.
Change-Id: Ie844e3f15f759ea09a8f3fd24825ee740151c956 Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/common/block/cpu/Kconfig M src/soc/intel/common/block/cpu/Makefile.inc A src/soc/intel/common/block/cpu/mp_service_ppi.c A src/soc/intel/common/block/include/intelblocks/mp_service_ppi.h 4 files changed, 764 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/34/25634/1
diff --git a/src/soc/intel/common/block/cpu/Kconfig b/src/soc/intel/common/block/cpu/Kconfig index 48f3f16..42b8325 100644 --- a/src/soc/intel/common/block/cpu/Kconfig +++ b/src/soc/intel/common/block/cpu/Kconfig @@ -18,6 +18,15 @@ ensured that all MTRRs are re-programmed based on the DRAM resource settings.
+config SOC_INTEL_COMMON_BLOCK_PUBLISH_MP_SERVICES_PPI + bool + default n + help + This option enables the creation of MP Services PPI for Intel + FSP usage. Coreboot will provide EFI_PEI_MP_SERVICES_PPI structure + definitions along with all APIs as per EDK2 specification. Intel FSP will + use this PPI to perform Mp Initialization. + config SOC_INTEL_COMMON_BLOCK_CAR bool default n diff --git a/src/soc/intel/common/block/cpu/Makefile.inc b/src/soc/intel/common/block/cpu/Makefile.inc index aa61ffc..cba107e 100644 --- a/src/soc/intel/common/block/cpu/Makefile.inc +++ b/src/soc/intel/common/block/cpu/Makefile.inc @@ -8,3 +8,4 @@
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += mp_init.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PUBLISH_MP_SERVICES_PPI) += mp_service_ppi.c diff --git a/src/soc/intel/common/block/cpu/mp_service_ppi.c b/src/soc/intel/common/block/cpu/mp_service_ppi.c new file mode 100644 index 0000000..bdc7e4c --- /dev/null +++ b/src/soc/intel/common/block/cpu/mp_service_ppi.c @@ -0,0 +1,462 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * 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; version 2 of the License. + * + * 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. + */ + +#include <assert.h> +#include <cpu/cpu.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/lapic.h> +#include <cpu/intel/microcode.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/mp_init.h> +#include <intelblocks/mp_service_ppi.h> + +#define BSP_CPU_SLOT 0 + +static uint32_t ap_number; +static void (*store_func)(void); + +__attribute__((weak)) void soc_fill_mp_services_data( + const EFI_PEI_MP_SERVICES_PPI *ppi_ptr) +{ + /* no-op */ +} + + +static const struct mp_ops mp_ops_ap = { + .get_cpu_count = get_cpu_count, + .get_microcode_info = get_microcode_info, +}; + +/* API to run a single function on a give AP */ +static void run_on_single_aps (void) +{ + if (cpu_index() != ap_number) + return; + + store_func(); +} + +/* API to disable an application processor based on cpu_slot */ +static EFI_STATUS disable_this_ap(uint32_t cpu_number) +{ + int ret; + + ap_number = cpu_number; + store_func = (void *) stop_this_cpu; + ret = mp_run_on_aps(run_on_single_aps, 0); + + if (!ret) + return EFI_SUCCESS; + else + return EFI_DEVICE_ERROR; +} + +/* API to enable an application processor based on cpu_slot */ +static EFI_STATUS enable_this_ap(uint32_t cpu_number) +{ + int apicid = mp_get_apic_id(cpu_number); + device_t dev = dev_find_path(NULL, DEVICE_PATH_CPU_CLUSTER); + assert(dev != NULL); + + if (mp_init_by_apic_id(dev->link_list, &mp_ops_ap, apicid)) { + printk(BIOS_ERR, "AP %d initialization failure.\n", apicid); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/* + * Get the number of CPU's. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This Pointer to this instance of the PPI. + * @param[out] NumberOfProcessors Pointer to the total number of + * logical processors in the system, including the BSP and disabled APs. + * @param[out] NumberOfEnabledProcessors Number of processors + * in the system that are enabled. + * + * @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. + * NumberOfEnabledProcessors is NULL. + */ +EFI_STATUS +EFIAPI +mp_get_number_of_processors ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors +) +{ + if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) + return EFI_INVALID_PARAMETER; + + *NumberOfProcessors = get_cpu_count(); + *NumberOfEnabledProcessors = get_cpu_count(); + return EFI_SUCCESS; +} + +/* + * Get information on a specific CPU. + * + *@param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This Pointer to this instance of the PPI. + * @param[in] ProcessorNumber Pointer to the total number of logical + * processors in the system, including the BSP and disabled APs. + * @param[out] ProcessorInfoBuffer Number of processors in the system + * that are enabled. + * + * @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. +*/ +EFI_STATUS +EFIAPI +mp_get_processor_info ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer +) +{ + uint32_t caller_pnumber; + + if (cpu_get_processor_number(&caller_pnumber) != 0) + return EFI_DEVICE_ERROR; + + if (caller_pnumber != BSP_CPU_SLOT) + return EFI_DEVICE_ERROR; + + if (ProcessorInfoBuffer == NULL) + return EFI_INVALID_PARAMETER; + + if (ProcessorNumber > get_cpu_count()) + return EFI_NOT_FOUND; + + ProcessorInfoBuffer->ProcessorId = lapicid(); + + ProcessorInfoBuffer->StatusFlag = PROCESSOR_HEALTH_STATUS_BIT + | PROCESSOR_ENABLED_BIT; + if (ProcessorNumber == BSP_CPU_SLOT) + ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT; + + /* TODO: Fill EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer */ + return EFI_SUCCESS; +} + +/* + * Activate all of the application proessors. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @param[in] Procedure A pointer to the function to be run on + * enabled APs of the system. + * @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] TimeoutInMicroSeconds + * Indicates the time limit in microseconds for APs to + * return from Procedure, for blocking mode only. 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_PEI_MP_SERVICES_PPI.StartupAllAPs() + * or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + * timeout expires in blocking mode, BSP returns + * EFI_TIMEOUT. + * @param[in] ProcedureArgument The parameter passed into Procedure for + * all APs. + * + * @retval EFI_SUCCESS In blocking mode, all APs have finished + * before the timeout expired. + * @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. +*/ +EFI_STATUS +EFIAPI +mp_startup_all_aps ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL +) +{ + int ret; + uint32_t caller_pnumber; + + if (cpu_get_processor_number(&caller_pnumber) != 0) + return EFI_DEVICE_ERROR; + + if (caller_pnumber != BSP_CPU_SLOT) + return EFI_DEVICE_ERROR; + + if (Procedure == NULL) + return EFI_INVALID_PARAMETER; + + ret = mp_run_on_aps((void *)Procedure, TimeoutInMicroSeconds); + + if (!ret) + return EFI_SUCCESS; + else + return EFI_DEVICE_ERROR; +} + +/* + * Activate a specific application processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @param[in] Procedure A pointer to the function to be run on + * enabled APs of the system. + * @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_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + * @param[in] TimeoutInMicroSeconds + * Indicates the time limit in microseconds for APs to + * return from Procedure, for blocking mode only. 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_PEI_MP_SERVICES_PPI.StartupAllAPs() + * or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + * timeout expires in blocking mode, BSP returns + * EFI_TIMEOUT. + * @param[in] ProcedureArgument The parameter passed into Procedure for + * all APs. + * + * @retval EFI_SUCCESS In blocking mode, all APs have finished + * before the timeout expired. + * @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. +*/ +EFI_STATUS +EFIAPI +mp_startup_this_ap ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL +) +{ + int ret; + uint32_t caller_pnumber; + + if (cpu_get_processor_number(&caller_pnumber) != 0) + return EFI_DEVICE_ERROR; + + if (caller_pnumber != BSP_CPU_SLOT) + return EFI_DEVICE_ERROR; + + if (ProcessorNumber > get_cpu_count()) + return EFI_NOT_FOUND; + + if (ProcessorNumber == BSP_CPU_SLOT) + return EFI_INVALID_PARAMETER; + + if (Procedure == NULL) + return EFI_INVALID_PARAMETER; + + /* Set callback AP number */ + ap_number = ProcessorNumber; + store_func = (void *)Procedure; + + ret = mp_run_on_aps(run_on_single_aps, TimeoutInMicroseconds); + + if (!ret) + return EFI_SUCCESS; + else + return EFI_DEVICE_ERROR; +} + +/* + * Switch the boot strap processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @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_PEI_MP_SERVICES_PPI.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. +*/ +EFI_STATUS +EFIAPI +mp_switch_bsp ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP +) +{ + /* FSP don't need this API hence return success */ + return EFI_SUCCESS; +} + +/* + * Enable or disable an application processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @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_PEI_MP_SERVICES_PPI.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_PEI_MP_SERVICES_PPI.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 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. +**/ +EFI_STATUS +EFIAPI +mp_enable_disable_ap ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL +) +{ + EFI_STATUS status; + uint32_t caller_pnumber; + + if (cpu_get_processor_number(&caller_pnumber) != 0) + return EFI_DEVICE_ERROR; + + if (caller_pnumber != BSP_CPU_SLOT) + return EFI_DEVICE_ERROR; + + if (ProcessorNumber == BSP_CPU_SLOT) + return EFI_INVALID_PARAMETER; + + if (ProcessorNumber > get_cpu_count()) + return EFI_NOT_FOUND; + + if (!EnableAP) + status = disable_this_ap(ProcessorNumber); + else + status = enable_this_ap(ProcessorNumber); + + return status; +} + +/* + * Identify the currently executing processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @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_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + * + * @retval EFI_SUCCESS The current processor handle number was + * returned in ProcessorNumber. + + * @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. +*/ +EFI_STATUS +EFIAPI +mp_identify_processor ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *ProcessorNumber +) +{ + if (ProcessorNumber == NULL) + return EFI_INVALID_PARAMETER; + + if (cpu_get_processor_number(ProcessorNumber) != 0) + return EFI_DEVICE_ERROR; + + return EFI_SUCCESS; +} + +/* + * EDK2 UEFIPKG Open Source MP Service PPI to be installed + */ + +static const EFI_PEI_MP_SERVICES_PPI mp_service_ppi = { + mp_get_number_of_processors, + mp_get_processor_info, + mp_startup_all_aps, + mp_startup_this_ap, + mp_switch_bsp, + mp_enable_disable_ap, + mp_identify_processor, +}; + +void mp_fill_ppi_services_data(void) +{ + soc_fill_mp_services_data(&mp_service_ppi); +} diff --git a/src/soc/intel/common/block/include/intelblocks/mp_service_ppi.h b/src/soc/intel/common/block/include/intelblocks/mp_service_ppi.h new file mode 100644 index 0000000..f87186d --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/mp_service_ppi.h @@ -0,0 +1,292 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef SOC_INTEL_COMMON_BLOCK_MP_SERVICE_PPI_H +#define SOC_INTEL_COMMON_BLOCK_MP_SERVICE_PPI_H + +/* + * This file to implement MP_SERVICES_PPI for Intel FSP to use. + * More details about this PPI can be found here : + * https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Ppi/ + * MpServices.h + */ +#include <fsp/util.h> +#include <fsp/soc_binding.h> + +/* + * Get the number of CPU's. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This Pointer to this instance of the PPI. + * @param[out] NumberOfProcessors Pointer to the total number of + * logical processors in the system, including the BSP and disabled APs. + * @param[out] NumberOfEnabledProcessors Number of processors + * in the system that are enabled. + * + * @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. + * NumberOfEnabledProcessors is NULL. + */ +EFI_STATUS +EFIAPI +mp_get_number_of_processors ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors +); + +/* + * Get information on a specific CPU. + * + *@param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This Pointer to this instance of the PPI. + * @param[in] ProcessorNumber Pointer to the total number of logical + * processors in the system, including the BSP and disabled APs. + * @param[out] ProcessorInfoBuffer Number of processors in the system + * that are enabled. + * + * @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. +*/ +EFI_STATUS +EFIAPI +mp_get_processor_info ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer +); + +/* + * Activate all of the application proessors. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @param[in] Procedure A pointer to the function to be run on + * enabled APs of the system. + * @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] TimeoutInMicroSeconds + * Indicates the time limit in microseconds for APs to + * return from Procedure, for blocking mode only. 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_PEI_MP_SERVICES_PPI.StartupAllAPs() + * or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + * timeout expires in blocking mode, BSP returns + * EFI_TIMEOUT. + * @param[in] ProcedureArgument The parameter passed into Procedure for + * all APs. + * + * @retval EFI_SUCCESS In blocking mode, all APs have finished + * before the timeout expired. + * @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. +*/ +EFI_STATUS +EFIAPI +mp_startup_all_aps ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL +); + +/* + * Activate a specific application processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @param[in] Procedure A pointer to the function to be run on + * enabled APs of the system. + * @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_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + * @param[in] TimeoutInMicroSeconds + * Indicates the time limit in microseconds for APs to + * return from Procedure, for blocking mode only. 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_PEI_MP_SERVICES_PPI.StartupAllAPs() + * or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + * timeout expires in blocking mode, BSP returns + * EFI_TIMEOUT. + * @param[in] ProcedureArgument The parameter passed into Procedure for + * all APs. + * + * @retval EFI_SUCCESS In blocking mode, all APs have finished + * before the timeout expired. + * @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. +*/ +EFI_STATUS +EFIAPI +mp_startup_this_ap ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL +); + +/* + * Switch the boot strap processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @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_PEI_MP_SERVICES_PPI.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. +*/ +EFI_STATUS +EFIAPI +mp_switch_bsp ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP +); + +/* + * Enable or disable an application processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @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_PEI_MP_SERVICES_PPI.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_PEI_MP_SERVICES_PPI.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 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. +**/ +EFI_STATUS +EFIAPI +mp_enable_disable_ap ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL +); + +/* + * Identify the currently executing processor. + * + * @param[in] PeiServices An indirect pointer to the PEI Services + * Table published by the PEI Foundation. + * @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI + * instance. + * @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_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + * + * @retval EFI_SUCCESS The current processor handle number was + * returned in ProcessorNumber. + + * @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. +*/ +EFI_STATUS +EFIAPI +mp_identify_processor ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *ProcessorNumber +); + +/* + * In this function SOC must call to get required EFI_PEI_MP_SERVICES_PPI + * structure, also it + * should call these mp_ops callback functions by calling + * mp_init_with_smm() function from x86/mp_init.c file. + * + * Also, if there is any other SOC specific functionalities to be + * implemented before or after MP Init, it can be done here. + */ +void mp_fill_ppi_services_data(void); + +/* + * SoC overrides + * + * All SOC should include this function to assign MP_SERVICES_PPI pointer + * to FSP-S UPD, so that FSP can install MP service PPI. + */ +void soc_fill_mp_services_data(const EFI_PEI_MP_SERVICES_PPI *ppi_ptr); + +#endif /* SOC_INTEL_COMMON_BLOCK_MP_SERVICE_PPI_H */