alder_lake_bios/Intel/AlderLake/ClientOneSiliconPkg/Fsp/Library/FspSerialIoUartDebugHelperLib/FspSerialIoUartDebugHelperL...

342 lines
9.9 KiB
C

/** @file
Implementation of FspSerialIoUartDebugHelperLib.
@copyright
INTEL CONFIDENTIAL
Copyright 2019 - 2020 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 a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <Base.h>
#include <PiPei.h>
#include <Uefi/UefiBaseType.h>
#include <Library/BaseLib.h>
#include <Library/SerialIoAccessLib.h>
#include <Library/SerialIoUartLib.h>
#include <Library/SerialIoUartDebugPropertyPcdLib.h>
#include <Library/FspCommonLib.h>
#include <Protocol/SerialIo.h>
#include <SerialIoDevices.h>
#include <FspEas.h>
#include <FsptUpd.h>
#include <FspmUpd.h>
#include <FspUpd.h>
/**
Configures Serial IO Controller
@param[in] UartNumber UART Number
@param[in] UartDeviceConfig SerialIo UART Config
@param[in] PsfDisable Applies only for SerialIoUartDisabled devices.
TRUE - Device will be disabled in PSF, and will no longer enumerate on PCI.
FALSE - PSF configuration is left unmodified.
**/
VOID
SerialIoUartConfiguration (
IN UINT8 UartNumber,
IN SERIAL_IO_UART_CONFIG *UartDeviceConfig,
IN BOOLEAN PsfDisable
);
/**
Return FSPT UPD Location Ppi
**/
FSPT_UPD *
EFIAPI
FspSerialIoUartDebugGetFsptUpdLocPpi (
VOID
)
{
CONST EFI_PEI_SERVICES **PeiServices;
IA32_DESCRIPTOR Idtr;
EFI_STATUS Status;
FSPT_UPD *FsptUpdLocationPpi;
Status = EFI_SUCCESS;
PeiServices = NULL;
FsptUpdLocationPpi = NULL;
if (PcdGetBool (PcdFspValidatePeiServiceTablePointer)) { // New PCD to control do PeiServiceTablepointer check or not. For SEC, this PCD is configured as FALSE. Its default value is TRUE
AsmReadIdtr (&Idtr);
PeiServices = (CONST EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.Base - sizeof (UINTN)));
}
if (PeiServices != NULL) {
Status = (*PeiServices)->LocatePpi (
PeiServices,
&gFsptUpdLocationPpiGuid,
0,
NULL,
(VOID **) &FsptUpdLocationPpi
);
if (EFI_ERROR (Status)) {
FsptUpdLocationPpi = NULL;
}
}
return FsptUpdLocationPpi;
}
/**
Get FSPT Config
@param[in] FsptConfig FSPT Config
@retval TRUE if FSPT exists
@retval FALSE unable to locate FSP
**/
BOOLEAN
STATIC
GetFsptConfig (
OUT FSP_T_CONFIG **Fspt
)
{
FSPT_UPD *FsptUpd;
FsptUpd = FspSerialIoUartDebugGetFsptUpdLocPpi ();
if (FsptUpd != NULL) {
*Fspt = &FsptUpd->FsptConfig;
return TRUE;
}
return FALSE;
}
/**
Get FSPM Config
@param[out] Fspm FSPM Config
@retval TRUE if FSPM exists
@retval FALSE unable to locate FSP
**/
BOOLEAN
STATIC
GetFspmConfig (
OUT FSP_M_CONFIG **Fspm
)
{
FSP_GLOBAL_DATA *FspData;
FSPM_UPD *FspmUpd;
FspData = GetFspGlobalDataPointer ();
if (((UINTN)FspData == 0x00 || (UINTN)FspData == 0xFFFFFFFF) ||
(FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE)) {
return FALSE;
} else if ((FspData->FspMode == FSP_IN_API_MODE) && (FspData->MemoryInitUpdPtr != NULL)) {
FspmUpd = FspData->MemoryInitUpdPtr;
*Fspm = &FspmUpd->FspmConfig;
return TRUE;
}
return FALSE;
}
/**
Returns UART attributes
@param[out] UartDeviceConfig A pointer to the SERIAL_IO_UART_CONFIG.
@param[out] SerialIoUartNumber The Number of Serial Io Uart.
**/
VOID
STATIC
FspSerialIoUartDebugGetDeviceConfig (
OUT SERIAL_IO_UART_CONFIG *UartDeviceConfig,
OUT UINT8 *UartNumber
)
{
FSP_M_CONFIG *FspmConfig;
FSP_T_CONFIG *FsptConfig;
FspmConfig = NULL;
FsptConfig = NULL;
if (GetFsptConfig (&FsptConfig)) {
UartDeviceConfig->Attributes.BaudRate = FsptConfig->PcdSerialIoUartBaudRate;
UartDeviceConfig->Attributes.Parity = FsptConfig->PcdSerialIoUartParity;
UartDeviceConfig->Attributes.DataBits = FsptConfig->PcdSerialIoUartDataBits;
UartDeviceConfig->Attributes.StopBits = FsptConfig->PcdSerialIoUartStopBits;
UartDeviceConfig->Attributes.AutoFlow = FsptConfig->PcdSerialIoUartAutoFlow;
UartDeviceConfig->Mode = FsptConfig->PcdSerialIoUartMode;
UartDeviceConfig->PinMux.Rx = FsptConfig->PcdSerialIoUartRxPinMux;
UartDeviceConfig->PinMux.Tx = FsptConfig->PcdSerialIoUartTxPinMux;
UartDeviceConfig->PinMux.Rts = FsptConfig->PcdSerialIoUartRtsPinMux;
UartDeviceConfig->PinMux.Cts = FsptConfig->PcdSerialIoUartCtsPinMux;
*UartNumber = FsptConfig->PcdSerialIoUartNumber;
} else if (GetFspmConfig (&FspmConfig)) {
UartDeviceConfig->Attributes.BaudRate = FspmConfig->SerialIoUartDebugBaudRate;
UartDeviceConfig->Attributes.Parity = FspmConfig->SerialIoUartDebugParity;
UartDeviceConfig->Attributes.DataBits = FspmConfig->SerialIoUartDebugDataBits;
UartDeviceConfig->Attributes.StopBits = FspmConfig->SerialIoUartDebugStopBits;
UartDeviceConfig->Attributes.AutoFlow = FspmConfig->SerialIoUartDebugAutoFlow;
UartDeviceConfig->Mode = FspmConfig->SerialIoUartDebugMode;
UartDeviceConfig->PinMux.Rx = FspmConfig->SerialIoUartDebugRxPinMux;
UartDeviceConfig->PinMux.Tx = FspmConfig->SerialIoUartDebugTxPinMux;
UartDeviceConfig->PinMux.Rts = FspmConfig->SerialIoUartDebugRtsPinMux;
UartDeviceConfig->PinMux.Cts = FspmConfig->SerialIoUartDebugCtsPinMux;
*UartNumber = FspmConfig->SerialIoUartDebugControllerNumber;
} else {
SerialIoUartDebugPcdGetDeviceConfig (UartDeviceConfig, UartNumber);
}
return;
}
/**
Returns Serial Io UART Controller Number used in Debug mode
@retval ControllerNumber UART Controller Number
**/
UINT8
STATIC
FspSerialIoUartDebugGetControllerNumber (
VOID
)
{
FSP_M_CONFIG *FspmConfig;
FSP_T_CONFIG *FsptConfig;
FspmConfig = NULL;
FsptConfig = NULL;
if (GetFsptConfig (&FsptConfig)) {
return FsptConfig->PcdSerialIoUartNumber;
} else if (GetFspmConfig (&FspmConfig)) {
return FspmConfig->SerialIoUartDebugControllerNumber;
} else {
return SerialIoUartDebugPcdGetControllerNumber ();
}
}
/**
Returns Serial Io UART MMIO Base Address in Debug mode
@retval MMIO Base Address by default in PCI Mode
**/
UINT32
STATIC
FspSerialIoUartDebugGetPciDefaultMmioBase (
VOID
)
{
FSP_M_CONFIG *FspmConfig;
FSP_T_CONFIG *FsptConfig;
UINT32 MmioBase;
FspmConfig = NULL;
FsptConfig = NULL;
if (GetFsptConfig (&FsptConfig)) {
MmioBase = FsptConfig->PcdSerialIoUartDebugMmioBase;
} else if (GetFspmConfig (&FspmConfig)) {
MmioBase = FspmConfig->SerialIoUartDebugMmioBase;
} else {
return SerialIoUartDebugPcdGetPciDefaultMmioBase ();
}
return MmioBase;
}
/**
Initialize SerialIo UART for debug.
**/
VOID
EFIAPI
SerialIoUartDebugInit (
VOID
)
{
UINT64 PciCfgBase;
UINT64 Bar0;
UINT8 UartNumber;
EFI_STATUS Status;
SERIAL_IO_UART_CONFIG UartDeviceConfig;
FspSerialIoUartDebugGetDeviceConfig (&UartDeviceConfig, &UartNumber);
if (UartDeviceConfig.Mode == SerialIoUartSkipInit) {
return;
}
PciCfgBase = GetSerialIoUartPciCfg (UartNumber);
Bar0 = GetSerialIoBar (PciCfgBase);
UartDeviceConfig.DBG2 = FALSE;
UartDeviceConfig.DmaEnable = FALSE;
SerialIoUartConfiguration (UartNumber, &UartDeviceConfig, TRUE);
//
// Assign MMIO for HS-UART used in PCI Mode.
//
if (!IsSerialIoUartInPciMode (UartNumber)) {
return;
}
Bar0 = FspSerialIoUartDebugGetPciDefaultMmioBase ();
Status = SerialIoUartSetMmioInPciMode (UartNumber, Bar0);
if (Status == EFI_UNSUPPORTED) {
return;
}
//
// UART Reset
//
SerialIoUartGetOutOfReset (Bar0);
//
// Initialize UART Attributes
//
SerialIoUartSetAttributes (
UartNumber,
UartDeviceConfig.Attributes.BaudRate,
UartDeviceConfig.Attributes.Parity,
UartDeviceConfig.Attributes.DataBits,
UartDeviceConfig.Attributes.StopBits,
UartDeviceConfig.Attributes.AutoFlow
);
}
/**
Write data to serial device.
If the buffer is NULL, then return 0;
if NumberOfBytes is zero, then return 0.
@param[in] Buffer Data pointer
@param[in] NumberOfBytes Number of output bytes which are cached in Buffer.
@retval Actual number of bytes written to serial device.
**/
UINTN
EFIAPI
SerialIoUartDebugWrite (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return SerialIoUartWrite (FspSerialIoUartDebugGetControllerNumber (), Buffer, NumberOfBytes);
}