316 lines
13 KiB
C
316 lines
13 KiB
C
/** @file
|
|
Fsp Silicon Common library
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2018 - 2021 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains an 'Intel Peripheral Driver' and is uniquely identified as
|
|
"Intel Reference Module" and is licensed for Intel CPUs and chipsets under
|
|
the terms of your license agreement with Intel or your vendor. This file may
|
|
be modified by the user, subject to additional terms of the license agreement.
|
|
|
|
@par Specification
|
|
**/
|
|
|
|
#include <Base.h>
|
|
#include <FspEas.h>
|
|
#include <FsptUpd.h>
|
|
#include <FspmUpd.h>
|
|
#include <FspsUpd.h>
|
|
#include <Library/PrintLib.h>
|
|
#include <Library/FspHelperLib.h>
|
|
#include <Library/FspCommonLib.h>
|
|
#include <Library/GetFsptApiParameter.h>
|
|
#include <Library/SerialIoUartDebugPropertyPcdLib.h>
|
|
#include <SerialIoDevices.h>
|
|
#include <Library/FspSwitchStackLib.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <PchLimits.h>
|
|
|
|
/**
|
|
Serial Io Spi Configuration Wrapper
|
|
|
|
@param[out] SpiDeviceConfig A pointer to the SERIAL_IO_SPI_CONFIG.
|
|
@param[out] SerialIoSpiNumber The Number of Serial Io Spi.
|
|
@param[out] SerialIoSpiMmioBase MMIO Base Address by default in PCI Mode
|
|
**/
|
|
VOID
|
|
SerialIoSpiConfigurationWrapper (
|
|
OUT SERIAL_IO_SPI_CONFIG *SpiDeviceConfig,
|
|
OUT UINT8 *SerialIoSpiNumber,
|
|
OUT UINT32 *SerialIoSpiMmioBase
|
|
)
|
|
{
|
|
FSP_INFO_HEADER *FspInfoHeader;
|
|
FSPT_UPD *FsptUpd;
|
|
UINT8 CsIndex;
|
|
|
|
FsptUpd = (FSPT_UPD *) *((UINT32 *) (SecGetFsptApiParameter () + 0x4));
|
|
if (FsptUpd->FspUpdHeader.Signature != FSPT_UPD_SIGNATURE) {
|
|
FspInfoHeader = (FSP_INFO_HEADER *) SiAsmGetFspInfoHeader ();
|
|
FsptUpd = (FSPT_UPD *) (FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
|
|
}
|
|
if (FsptUpd != NULL) {
|
|
SpiDeviceConfig->Mode = FsptUpd->FsptConfig.PcdSerialIoSpiMode;
|
|
if (SpiDeviceConfig->Mode == 0) {
|
|
return;
|
|
}
|
|
*SerialIoSpiNumber = FsptUpd->FsptConfig.PcdSerialIoSpiNumber;
|
|
*SerialIoSpiMmioBase = FsptUpd->FsptConfig.PcdSerialIoSpiMmioBase;
|
|
SpiDeviceConfig->DefaultCsOutput = FsptUpd->FsptConfig.PcdSerialIoSpiDefaultCsOutput;
|
|
SpiDeviceConfig->CsMode = FsptUpd->FsptConfig.PcdSerialIoSpiCsMode;
|
|
SpiDeviceConfig->CsState = FsptUpd->FsptConfig.PcdSerialIoSpiCsState;
|
|
//
|
|
// No Pin Muxing required
|
|
//
|
|
SpiDeviceConfig->PinMux.Clk = 0;
|
|
SpiDeviceConfig->PinMux.Miso = 0;
|
|
SpiDeviceConfig->PinMux.Mosi = 0;
|
|
for (CsIndex = 0; CsIndex < PCH_MAX_SERIALIO_SPI_CHIP_SELECTS; CsIndex++) {
|
|
SpiDeviceConfig->CsEnable[CsIndex] = FsptUpd->FsptConfig.PcdSerialIoSpiCsEnable[CsIndex];
|
|
SpiDeviceConfig->CsPolarity[CsIndex] = FsptUpd->FsptConfig.PcdSerialIoSpiCsPolarity[CsIndex];
|
|
SpiDeviceConfig->PinMux.Cs[CsIndex] = 0;
|
|
}
|
|
return;
|
|
}
|
|
SpiDeviceConfig->Mode = 0;
|
|
}
|
|
|
|
/**
|
|
Serial Io Uart Debug Configuration Wrapper
|
|
|
|
@param[out] UartDeviceConfig A pointer to the SERIAL_IO_UART_CONFIG.
|
|
@param[out] SerialIoUartDebugEnable Serial Io Uart Debug Enable/Disable.
|
|
@param[out] SerialIoUartNumber The Number of Serial Io Uart.
|
|
@param[out] SerialIoUartPciMmioBase MMIO Base Address by default in PCI Mode
|
|
**/
|
|
VOID
|
|
SerialIoUartDebugConfigurationWrapper (
|
|
OUT SERIAL_IO_UART_CONFIG *UartDeviceConfig,
|
|
OUT UINT8 *SerialIoUartDebugEnable,
|
|
OUT UINT8 *SerialIoUartNumber,
|
|
OUT UINT32 *SerialIoUartPciMmioBase
|
|
)
|
|
{
|
|
FSP_INFO_HEADER *FspInfoHeader;
|
|
FSPT_UPD *FsptUpd;
|
|
|
|
FsptUpd = (FSPT_UPD *) *((UINT32 *) (SecGetFsptApiParameter () + 0x4));
|
|
if (FsptUpd->FspUpdHeader.Signature != FSPT_UPD_SIGNATURE) {
|
|
FspInfoHeader = (FSP_INFO_HEADER *) SiAsmGetFspInfoHeader ();
|
|
FsptUpd = (FSPT_UPD *) (FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
|
|
}
|
|
if (FsptUpd != NULL) {
|
|
*SerialIoUartDebugEnable = FsptUpd->FsptConfig.PcdSerialIoUartDebugEnable;
|
|
*SerialIoUartNumber = FsptUpd->FsptConfig.PcdSerialIoUartNumber;
|
|
*SerialIoUartPciMmioBase = FsptUpd->FsptConfig.PcdSerialIoUartDebugMmioBase;
|
|
UartDeviceConfig->Mode = FsptUpd->FsptConfig.PcdSerialIoUartMode;
|
|
UartDeviceConfig->Attributes.BaudRate = FsptUpd->FsptConfig.PcdSerialIoUartBaudRate;
|
|
UartDeviceConfig->Attributes.Parity = FsptUpd->FsptConfig.PcdSerialIoUartParity;
|
|
UartDeviceConfig->Attributes.DataBits = FsptUpd->FsptConfig.PcdSerialIoUartDataBits;
|
|
UartDeviceConfig->Attributes.StopBits = FsptUpd->FsptConfig.PcdSerialIoUartStopBits;
|
|
UartDeviceConfig->Attributes.AutoFlow = FsptUpd->FsptConfig.PcdSerialIoUartAutoFlow;
|
|
UartDeviceConfig->PinMux.Rx = FsptUpd->FsptConfig.PcdSerialIoUartRxPinMux;
|
|
UartDeviceConfig->PinMux.Tx = FsptUpd->FsptConfig.PcdSerialIoUartTxPinMux;
|
|
UartDeviceConfig->PinMux.Rts = FsptUpd->FsptConfig.PcdSerialIoUartRtsPinMux;
|
|
UartDeviceConfig->PinMux.Cts = FsptUpd->FsptConfig.PcdSerialIoUartCtsPinMux;
|
|
return;
|
|
}
|
|
*SerialIoUartDebugEnable = SerialIoUartDebugPcdGetDebugEnable ();
|
|
*SerialIoUartPciMmioBase = SerialIoUartDebugPcdGetPciDefaultMmioBase ();
|
|
SerialIoUartDebugPcdGetDeviceConfig (UartDeviceConfig, SerialIoUartNumber);
|
|
}
|
|
|
|
/**
|
|
Serial Io Additional Uart Configuration Wrapper
|
|
Allows to configure another UART in FSPT
|
|
|
|
@param[out] UartEnable Serial Io Additional Uart Enable/Disable.
|
|
@param[out] UartDeviceConfig A pointer to the SERIAL_IO_UART_CONFIG.
|
|
@param[out] SerialIoUartNumber The Number of Serial Io Uart.
|
|
@param[out] SerialIoUartPciMmioBase MMIO Base Address by default in PCI Mode
|
|
**/
|
|
VOID
|
|
SerialIo2ndUartConfigurationWrapper (
|
|
OUT UINT8 *UartEnable,
|
|
OUT SERIAL_IO_UART_CONFIG *UartDeviceConfig,
|
|
OUT UINT8 *SerialIoUartNumber,
|
|
OUT UINT32 *SerialIoUartPciMmioBase
|
|
)
|
|
{
|
|
FSP_INFO_HEADER *FspInfoHeader;
|
|
FSPT_UPD *FsptUpd;
|
|
|
|
FsptUpd = (FSPT_UPD *) *((UINT32 *) (SecGetFsptApiParameter () + 0x4));
|
|
if (FsptUpd->FspUpdHeader.Signature != FSPT_UPD_SIGNATURE) {
|
|
FspInfoHeader = (FSP_INFO_HEADER *) SiAsmGetFspInfoHeader ();
|
|
FsptUpd = (FSPT_UPD *) (FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
|
|
}
|
|
if (FsptUpd != NULL) {
|
|
*UartEnable = FsptUpd->FsptConfig.PcdSerialIo2ndUartEnable;
|
|
if (FsptUpd->FsptConfig.PcdSerialIo2ndUartEnable == 0) {
|
|
return;
|
|
}
|
|
*SerialIoUartNumber = FsptUpd->FsptConfig.PcdSerialIo2ndUartNumber;
|
|
*SerialIoUartPciMmioBase = FsptUpd->FsptConfig.PcdSerialIo2ndUartMmioBase;
|
|
UartDeviceConfig->Mode = FsptUpd->FsptConfig.PcdSerialIo2ndUartMode;
|
|
UartDeviceConfig->Attributes.BaudRate = FsptUpd->FsptConfig.PcdSerialIo2ndUartBaudRate;
|
|
UartDeviceConfig->Attributes.Parity = FsptUpd->FsptConfig.PcdSerialIo2ndUartParity;
|
|
UartDeviceConfig->Attributes.DataBits = FsptUpd->FsptConfig.PcdSerialIo2ndUartDataBits;
|
|
UartDeviceConfig->Attributes.StopBits = FsptUpd->FsptConfig.PcdSerialIo2ndUartStopBits;
|
|
UartDeviceConfig->Attributes.AutoFlow = FsptUpd->FsptConfig.PcdSerialIo2ndUartAutoFlow;
|
|
UartDeviceConfig->PinMux.Rx = FsptUpd->FsptConfig.PcdSerialIo2ndUartRxPinMux;
|
|
UartDeviceConfig->PinMux.Tx = FsptUpd->FsptConfig.PcdSerialIo2ndUartTxPinMux;
|
|
UartDeviceConfig->PinMux.Rts = FsptUpd->FsptConfig.PcdSerialIo2ndUartRtsPinMux;
|
|
UartDeviceConfig->PinMux.Cts = FsptUpd->FsptConfig.PcdSerialIo2ndUartCtsPinMux;
|
|
return;
|
|
}
|
|
*UartEnable = 0;
|
|
}
|
|
|
|
/**
|
|
This function check the signture of UPD
|
|
|
|
@param[in] ApiIdx Internal index of the FSP API.
|
|
@param[in] ApiParam Parameter of the FSP API.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FspUpdSignatureCheck (
|
|
IN UINT32 ApiIdx,
|
|
IN VOID *ApiParam
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
FSPM_UPD *FspmUpd;
|
|
FSPS_UPD *FspsUpd;
|
|
|
|
Status = EFI_SUCCESS;
|
|
FspmUpd = NULL;
|
|
FspsUpd = NULL;
|
|
|
|
if (ApiIdx == 3) {
|
|
//
|
|
// FspMemoryInit check
|
|
//
|
|
FspmUpd = (FSPM_UPD *)ApiParam;
|
|
if (FspmUpd != NULL) {
|
|
if ((FspmUpd->FspUpdHeader.Signature != FSPM_UPD_SIGNATURE)
|
|
|| ((UINTN)FspmUpd->FspmArchUpd.StackBase == 0 )
|
|
|| (FspmUpd->FspmArchUpd.StackSize < PcdGet32(PcdFspTemporaryRamSize))
|
|
|| (((UINTN)FspmUpd->FspmArchUpd.StackBase + FspmUpd->FspmArchUpd.StackSize) > BASE_4GB)
|
|
|| ((FspmUpd->FspmArchUpd.BootLoaderTolumSize % EFI_PAGE_SIZE) != 0)) {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
} else if (ApiIdx == 5) {
|
|
//
|
|
// FspSiliconInit check
|
|
//
|
|
FspsUpd = GetFspSiliconInitUpdDataPointer();
|
|
if (FspsUpd == NULL) {
|
|
FspsUpd = (FSPS_UPD *) ApiParam;
|
|
}
|
|
if (FspsUpd != NULL) {
|
|
if (FspsUpd->FspUpdHeader.Signature != FSPS_UPD_SIGNATURE) {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This function handles FspMultiPhaseSiInitApi.
|
|
|
|
@param[in] ApiIdx Internal index of the FSP API.
|
|
@param[in] ApiParam Parameter of the FSP API.
|
|
|
|
@retval EFI_SUCCESS FSP execution was successful.
|
|
@retval EFI_INVALID_PARAMETER Input parameters are invalid.
|
|
@retval EFI_UNSUPPORTED The FSP calling conditions were not met.
|
|
@retval EFI_DEVICE_ERROR FSP initialization failed.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FspMultiPhaseSiInitApiHandler (
|
|
IN UINT32 ApiIdx,
|
|
IN VOID *ApiParam
|
|
)
|
|
{
|
|
FSP_MULTI_PHASE_PARAMS *FspMultiPhaseParams;
|
|
FSP_GLOBAL_DATA *FspData;
|
|
FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS *FspMultiPhaseGetNumber;
|
|
BOOLEAN FspDataValid;
|
|
FSPS_UPD *FspsUpd;
|
|
FSP_M_CONFIG *FspmConfigUpd;
|
|
|
|
FspDataValid = TRUE;
|
|
FspData = GetFspGlobalDataPointer ();
|
|
if (((UINTN)FspData == 0) || ((UINTN)FspData == 0xFFFFFFFF)) {
|
|
FspDataValid = FALSE;
|
|
}
|
|
|
|
if ((FspDataValid == TRUE) && (FspData->NumberOfPhases == 0)) {
|
|
FspsUpd = (FSPS_UPD *) FspData->SiliconInitUpdPtr;
|
|
FspmConfigUpd = &((FSPM_UPD *) (FspData->MemoryInitUpdPtr))->FspmConfig;
|
|
if ((FspsUpd->FspsArchUpd.EnableMultiPhaseSiliconInit) && (FspmConfigUpd->TcssXhciEn)) {
|
|
FspData->NumberOfPhases = PcdGet8 (PcdMultiPhaseSiInitNumberOfPhases);
|
|
}
|
|
FspData->PhasesExecuted = 0;
|
|
}
|
|
|
|
FspMultiPhaseParams = (FSP_MULTI_PHASE_PARAMS *) ApiParam;
|
|
|
|
if (FspDataValid == FALSE) {
|
|
return EFI_DEVICE_ERROR;
|
|
} else {
|
|
switch (FspMultiPhaseParams->MultiPhaseAction) {
|
|
case EnumMultiPhaseGetNumberOfPhases:
|
|
if ((FspMultiPhaseParams->MultiPhaseParamPtr == NULL) || (FspMultiPhaseParams->PhaseIndex != 0)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
FspMultiPhaseGetNumber = (FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS *) FspMultiPhaseParams->MultiPhaseParamPtr;
|
|
FspMultiPhaseGetNumber->NumberOfPhases = FspData->NumberOfPhases;
|
|
FspMultiPhaseGetNumber->PhasesExecuted = FspData->PhasesExecuted;
|
|
break;
|
|
|
|
case EnumMultiPhaseExecutePhase:
|
|
if ((FspMultiPhaseParams->PhaseIndex > FspData->PhasesExecuted) && (FspMultiPhaseParams->PhaseIndex <= FspData->NumberOfPhases)) {
|
|
FspData->PhasesExecuted = FspMultiPhaseParams->PhaseIndex;
|
|
Loader2PeiSwitchStack ();
|
|
} else {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|