drivers/intel/fsp2_0: Add support for MP services2 PPI

Add support for MP services2 PPIs, which is slight modification
over MP services 1 PPIs. A new API StartupAllCPUs have been added
to allow running a task on BSP and all APs. Also the EFI_PEI_SERVICES
parameter has been removed from all MP PPI APIs.

This implementation also selects the respective MP services PPI version
supported for SoCs

BUG=b:169196864

Change-Id: Id74baf17fb90147d229c78be90268fdc3ec1badc
Signed-off-by: Aamir Bohra <aamir.bohra@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/49474
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Aamir Bohra
2021-02-04 20:57:51 +05:30
committed by Patrick Georgi
parent 5f262be24c
commit 30cca6ca2a
14 changed files with 527 additions and 89 deletions

View File

@@ -268,7 +268,4 @@ config SOC_INTEL_COMMON_FSP_RESET
Common code block to handle platform reset request raised by FSP. The FSP
will use the FSP EAS v2.0 section 12.2.2 (OEM Status Code) to indicate that
a reset is required.
source "src/drivers/intel/fsp2_0/ppi/Kconfig"
endif

View File

@@ -11,10 +11,36 @@
#include <efi/efi_datatype.h>
#include <fsp/soc_binding.h>
/*
* SOC must call this function to get required EFI_PEI_MP_SERVICES_PPI
* structure.
*/
efi_pei_mp_services_ppi *mp_fill_ppi_services_data(void);
/* SOC must call this function to get required EFI_PEI_MP_SERVICES_PPI structure */
void *mp_fill_ppi_services_data(void);
/* get the number of logical processors in the platform */
efi_return_status_t mp_get_number_of_processors(efi_uintn_t *number_of_processors,
efi_uintn_t *number_of_enabled_processors);
/* get processor info such as id, status */
efi_return_status_t mp_get_processor_info(efi_uintn_t processor_number,
efi_processor_information *processor_info_buffer);
/* executes a caller provided function on all enabled APs */
efi_return_status_t mp_startup_all_aps(efi_ap_procedure procedure,
efi_uintn_t timeout_usec, void *argument);
/* executes a caller provided function on all enabled APs + BSP */
efi_return_status_t mp_startup_all_cpus(efi_ap_procedure procedure,
efi_uintn_t timeout_usec, void *argument);
/* executes a caller provided function on specific AP */
efi_return_status_t mp_startup_this_ap(efi_ap_procedure procedure,
efi_uintn_t processor_number, efi_uintn_t timeout_usec, void *argument);
/* get the processor instance */
efi_return_status_t mp_identify_processor(efi_uintn_t *processor_number);
/* for the APIs that are not supported/required */
static inline efi_return_status_t mp_api_unsupported(void)
{
return FSP_UNSUPPORTED;
}
#endif /* MP_SERVICE_PPI_H */

View File

@@ -5,7 +5,24 @@ config MP_SERVICES_PPI
default n
depends on SOC_INTEL_COMMON_BLOCK_CPU_MPINIT
help
This option allows SoC user to create MP service 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 run CPU feature programming on APs.
This option allows to create MP service PPI for Intel FSP usage.
Intel FSP will use this PPI to run CPU feature programming on APs.
config MP_SERVICES_PPI_V1
bool
default n
select MP_SERVICES_PPI
help
This option provides EFI_PEI_MP_SERVICES_PPI structure definitions
along with all APIs as per EDK2 specification.
config MP_SERVICES_PPI_V2
bool
default n
select MP_SERVICES_PPI
help
This option provides EDKII_PEI_MP_SERVICES2_PPI structure definitions
along with all APIs as per EDK2 specification. MP services2 PPI is slight
modification over MP services1 PPIs. A new API StartupAllCPUs have been
added to allow running a task on BSP and all APs. Also the EFI_PEI_SERVICES
parameter has been removed from all MP PPI APIs.

View File

@@ -1,3 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
ramstage-$(CONFIG_MP_SERVICES_PPI) += mp_service_ppi.c
ramstage-$(CONFIG_MP_SERVICES_PPI_V1) += mp_service1.c
ramstage-$(CONFIG_MP_SERVICES_PPI_V2) += mp_service2.c

View File

@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <fsp/api.h>
#include <fsp/ppi/mp_service_ppi.h>
#include <Ppi/MpServices.h>
typedef EFI_PEI_MP_SERVICES_PPI efi_pei_mp_services_ppi;
static efi_return_status_t mps1_get_number_of_processors(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t *number_of_processors, efi_uintn_t *number_of_enabled_processors)
{
return mp_get_number_of_processors(number_of_processors, number_of_enabled_processors);
}
static efi_return_status_t mps1_get_processor_info(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t processor_number,
efi_processor_information *processor_info_buffer)
{
return mp_get_processor_info(processor_number, processor_info_buffer);
}
static efi_return_status_t mps1_startup_all_aps(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_ap_procedure procedure, efi_boolean_t ignored3,
efi_uintn_t timeout_usec, void *argument)
{
return mp_startup_all_aps(procedure, timeout_usec, argument);
}
static efi_return_status_t mps1_startup_this_ap(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_ap_procedure procedure, efi_uintn_t processor_number,
efi_uintn_t timeout_usec, void *argument)
{
return mp_startup_this_ap(procedure, processor_number, timeout_usec, argument);
}
static efi_return_status_t mps1_switch_bsp(const efi_pei_services **ignored1,
efi_pei_mp_services_ppi *ignored2, efi_uintn_t ignored3,
efi_boolean_t ignored4)
{
return mp_api_unsupported();
}
static efi_return_status_t mps1_enable_disable_ap(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t ignored3, efi_boolean_t ignored4, efi_uint32_t *ignored5)
{
return mp_api_unsupported();
}
static efi_return_status_t mps1_identify_processor(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t *processor_number)
{
return mp_identify_processor(processor_number);
}
/* EDK2 UEFIPKG Open Source MP Service PPI to be installed */
static efi_pei_mp_services_ppi mp_service1_ppi = {
mps1_get_number_of_processors,
mps1_get_processor_info,
mps1_startup_all_aps,
mps1_startup_this_ap,
mps1_switch_bsp,
mps1_enable_disable_ap,
mps1_identify_processor,
};
void *mp_fill_ppi_services_data(void)
{
return (void *)&mp_service1_ppi;
}

View File

@@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <fsp/api.h>
#include <fsp/ppi/mp_service_ppi.h>
#include <Ppi/MpServices2.h>
typedef EDKII_PEI_MP_SERVICES2_PPI efi_pei_mp_services_ppi;
static efi_return_status_t mps2_get_number_of_processors(
efi_pei_mp_services_ppi *ignored1,
efi_uintn_t *number_of_processors,
efi_uintn_t *number_of_enabled_processors)
{
return mp_get_number_of_processors(number_of_processors, number_of_enabled_processors);
}
static efi_return_status_t mps2_get_processor_info(
efi_pei_mp_services_ppi *ignored1,
efi_uintn_t processor_number,
efi_processor_information *processor_info_buffer)
{
return mp_get_processor_info(processor_number, processor_info_buffer);
}
static efi_return_status_t mps2_startup_all_aps(
efi_pei_mp_services_ppi *ignored1,
efi_ap_procedure procedure, efi_boolean_t ignored2,
efi_uintn_t timeout_usec, void *argument)
{
return mp_startup_all_aps(procedure, timeout_usec, argument);
}
static efi_return_status_t mps2_startup_all_cpus(
efi_pei_mp_services_ppi *ignored1,
efi_ap_procedure procedure,
efi_uintn_t timeout_usec, void *argument)
{
return mp_startup_all_cpus(procedure, timeout_usec, argument);
}
static efi_return_status_t mps2_startup_this_ap(
efi_pei_mp_services_ppi *ignored1,
efi_ap_procedure procedure, efi_uintn_t processor_number,
efi_uintn_t timeout_usec, void *argument)
{
return mp_startup_this_ap(procedure, processor_number, timeout_usec, argument);
}
static efi_return_status_t mps2_switch_bsp(
efi_pei_mp_services_ppi *ignored1, efi_uintn_t ignored2,
efi_boolean_t ignored3)
{
return mp_api_unsupported();
}
static efi_return_status_t mps2_enable_disable_ap(
efi_pei_mp_services_ppi *ignored1,
efi_uintn_t ignored2, efi_boolean_t ignored3, efi_uint32_t *ignored4)
{
return mp_api_unsupported();
}
static efi_return_status_t mps2_identify_processor(
efi_pei_mp_services_ppi *ignored1,
efi_uintn_t *processor_number)
{
return mp_identify_processor(processor_number);
}
/* EDK2 UEFIPKG Open Source MP Services 2 PPI to be installed */
static efi_pei_mp_services_ppi mp_service2_ppi = {
mps2_get_number_of_processors,
mps2_get_processor_info,
mps2_startup_all_aps,
mps2_startup_this_ap,
mps2_switch_bsp,
mps2_enable_disable_ap,
mps2_identify_processor,
mps2_startup_all_cpus,
};
void *mp_fill_ppi_services_data(void)
{
return (void *)&mp_service2_ppi;
}

View File

@@ -12,9 +12,7 @@
#define BSP_CPU_SLOT 0
#define SINGLE_CHIP_PACKAGE 0
static efi_return_status_t mp_get_number_of_processors(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t *number_of_processors,
efi_return_status_t mp_get_number_of_processors(efi_uintn_t *number_of_processors,
efi_uintn_t *number_of_enabled_processors)
{
if (number_of_processors == NULL || number_of_enabled_processors ==
@@ -27,9 +25,7 @@ static efi_return_status_t mp_get_number_of_processors(const
return FSP_SUCCESS;
}
static efi_return_status_t mp_get_processor_info(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t processor_number,
efi_return_status_t mp_get_processor_info(efi_uintn_t processor_number,
efi_processor_information *processor_info_buffer)
{
unsigned int num_virt_cores, num_phys_cores;
@@ -62,9 +58,7 @@ static efi_return_status_t mp_get_processor_info(const
return FSP_SUCCESS;
}
static efi_return_status_t mp_startup_all_aps(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_ap_procedure procedure, efi_boolean_t ignored3,
efi_return_status_t mp_startup_all_aps(efi_ap_procedure procedure,
efi_uintn_t timeout_usec, void *argument)
{
if (cpu_index() < 0)
@@ -82,14 +76,34 @@ static efi_return_status_t mp_startup_all_aps(const
return FSP_SUCCESS;
}
static efi_return_status_t mp_startup_this_ap(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_ap_procedure procedure, efi_uintn_t processor_number,
efi_return_status_t mp_startup_all_cpus(efi_ap_procedure procedure,
efi_uintn_t timeout_usec, void *argument)
{
if (cpu_index() < 0)
return FSP_DEVICE_ERROR;
if (procedure == NULL)
return FSP_INVALID_PARAMETER;
/* Run on BSP */
procedure(argument);
/* Run on APs */
if (mp_run_on_aps((void *)procedure, argument,
MP_RUN_ON_ALL_CPUS, timeout_usec)) {
printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
return FSP_NOT_STARTED;
}
return FSP_SUCCESS;
}
efi_return_status_t mp_startup_this_ap(efi_ap_procedure procedure,
efi_uintn_t processor_number, efi_uintn_t timeout_usec, void *argument)
{
if (cpu_index() < 0)
return FSP_DEVICE_ERROR;
if (processor_number > get_cpu_count())
return FSP_NOT_FOUND;
@@ -108,25 +122,7 @@ static efi_return_status_t mp_startup_this_ap(const
return FSP_SUCCESS;
}
static efi_return_status_t mp_switch_bsp(const efi_pei_services **ignored1,
efi_pei_mp_services_ppi *ignored2, efi_uintn_t ignored3,
efi_boolean_t ignored4)
{
/* FSP don't need this API hence return unsupported */
return FSP_UNSUPPORTED;
}
static efi_return_status_t mp_enable_disable_ap(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t ignored3, efi_boolean_t ignored4, efi_uint32_t *ignored5)
{
/* FSP don't need this API hence return unsupported */
return FSP_UNSUPPORTED;
}
static efi_return_status_t mp_identify_processor(const
efi_pei_services **ignored1, efi_pei_mp_services_ppi *ignored2,
efi_uintn_t *processor_number)
efi_return_status_t mp_identify_processor(efi_uintn_t *processor_number)
{
int index;
@@ -142,22 +138,3 @@ static efi_return_status_t mp_identify_processor(const
return FSP_SUCCESS;
}
/*
* EDK2 UEFIPKG Open Source MP Service PPI to be installed
*/
static 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,
};
efi_pei_mp_services_ppi *mp_fill_ppi_services_data(void)
{
return &mp_service_ppi;
}