drivers/intel/fsp2_0: Implement EFI_MP_SERVICES_PPI structure APIs

This patch ensures to have below listed features:

1. All required APIs to create MP service structure.
2. Function to get MP service PPI status

MP specification here:
http://github.com/tianocore/edk2/blob/master/MdePkg/Include/Ppi/MpServices.h

coreboot design document here:
../Documentation/soc/intel/icelake/MultiProcessorInit.md

Supported platform 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>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/25634
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Subrata Banik 2018-04-12 19:25:37 +05:30 committed by Patrick Georgi
parent b55df4f1a8
commit 6662cb3dc2
5 changed files with 244 additions and 1 deletions

View File

@ -183,10 +183,13 @@ config FSP_PLATFORM_MEMORY_SETTINGS_VERSIONS
config FSP_PEIM_TO_PEIM_INTERFACE
bool
select FSP_USES_MP_SERVICES_PPI
help
This option allows SOC user to create specific PPI for Intel FSP
usage, coreboot will provide required PPI structure definitions
along with all APIs as per EFI specification.
along with all APIs as per EFI specification. So far this feature
is limited till EFI_PEI_MP_SERVICE_PPI and this option might be
useful to add further PPI if required.
if FSP_PEIM_TO_PEIM_INTERFACE
source "src/drivers/intel/fsp2_0/ppi/Kconfig"

View File

@ -0,0 +1,33 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2019 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 MP_SERVICE_PPI_H
#define 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 :
* http://github.com/tianocore/edk2/blob/master/MdePkg/Include/Ppi/MpServices.h
*/
#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);
#endif /* MP_SERVICE_PPI_H */

View File

@ -0,0 +1,24 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2019 Intel Corp.
#
# 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.
#
config FSP_USES_MP_SERVICES_PPI
bool
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.

View File

@ -0,0 +1,16 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2019 Intel Corp.
#
# 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.
#
ramstage-$(CONFIG_FSP_USES_MP_SERVICES_PPI) += mp_service_ppi.c

View File

@ -0,0 +1,167 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2019 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 <fsp/api.h>
#include <fsp/ppi/mp_service_ppi.h>
#include <intelblocks/cpulib.h>
#include <intelblocks/mp_init.h>
#define BSP_CPU_SLOT 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_uintn_t *number_of_enabled_processors)
{
if (number_of_processors == NULL || number_of_enabled_processors ==
NULL)
return FSP_INVALID_PARAMETER;
*number_of_processors = get_cpu_count();
*number_of_enabled_processors = get_cpu_count();
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_processor_information *processor_info_buffer)
{
if (cpu_index() < 0)
return FSP_DEVICE_ERROR;
if (processor_info_buffer == NULL)
return FSP_INVALID_PARAMETER;
if (processor_number >= get_cpu_count())
return FSP_NOT_FOUND;
processor_info_buffer->ProcessorId = lapicid();
processor_info_buffer->StatusFlag = PROCESSOR_HEALTH_STATUS_BIT
| PROCESSOR_ENABLED_BIT;
if (processor_number == BSP_CPU_SLOT)
processor_info_buffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
/* TODO: Fill EFI_CPU_PHYSICAL_LOCATION structure information */
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_uintn_t timeout_usec, void *argument)
{
if (cpu_index() < 0)
return FSP_DEVICE_ERROR;
if (procedure == NULL)
return FSP_INVALID_PARAMETER;
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;
}
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_uintn_t timeout_usec, void *argument)
{
if (cpu_index() < 0)
return FSP_DEVICE_ERROR;
if (processor_number > get_cpu_count())
return FSP_NOT_FOUND;
if (processor_number == BSP_CPU_SLOT)
return FSP_INVALID_PARAMETER;
if (procedure == NULL)
return FSP_INVALID_PARAMETER;
if (mp_run_on_aps((void *)procedure, argument,
processor_number, timeout_usec)) {
printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
return FSP_NOT_STARTED;
}
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)
{
int index;
if (processor_number == NULL)
return FSP_INVALID_PARAMETER;
index = cpu_index();
if (index < 0)
return FSP_DEVICE_ERROR;
*processor_number = index;
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;
}