/** @file
|
Pch information library.
|
|
All function in this library is available for PEI, DXE, and SMM,
|
But do not support UEFI RUNTIME environment call.
|
|
Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
**/
|
|
#include <Base.h>
|
#include <Uefi/UefiBaseType.h>
|
#include <Library/IoLib.h>
|
#include <Library/DebugLib.h>
|
#include <Library/BaseLib.h>
|
#include <Library/PciSegmentLib.h>
|
#include <Library/PchInfoLib.h>
|
#include <Library/PchPcrLib.h>
|
#include <Library/PrintLib.h>
|
#include <Library/PcdLib.h>
|
#include "PchInfoLibPrivate.h"
|
#include <Register/PchRegs.h>
|
#include <Register/PchRegsLpc.h>
|
#include <Register/PchRegsPcie.h>
|
#include <IndustryStandard/Pci30.h>
|
|
/**
|
Return LPC Device Id
|
|
@retval PCH_LPC_DEVICE_ID PCH Lpc Device ID
|
**/
|
UINT16
|
PchGetLpcDid (
|
VOID
|
)
|
{
|
UINT64 LpcBaseAddress;
|
|
LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
|
DEFAULT_PCI_SEGMENT_NUMBER_PCH,
|
DEFAULT_PCI_BUS_NUMBER_PCH,
|
PCI_DEVICE_NUMBER_PCH_LPC,
|
PCI_FUNCTION_NUMBER_PCH_LPC,
|
0
|
);
|
|
return PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET);
|
}
|
|
/**
|
Return Pch Series
|
|
@retval PCH_SERIES Pch Series
|
**/
|
PCH_SERIES
|
PchSeries (
|
VOID
|
)
|
{
|
PCH_SERIES PchSer;
|
static PCH_SERIES PchSeries = PCH_UNKNOWN_SERIES;
|
|
if (PchSeries != PCH_UNKNOWN_SERIES) {
|
return PchSeries;
|
}
|
|
PchSer = PchSeriesFromLpcDid (PchGetLpcDid ());
|
|
PchSeries = PchSer;
|
|
return PchSer;
|
}
|
|
/**
|
Return Pch stepping type
|
|
@retval PCH_STEPPING Pch stepping type
|
**/
|
PCH_STEPPING
|
PchStepping (
|
VOID
|
)
|
{
|
UINT8 RevId;
|
UINT64 LpcBaseAddress;
|
static PCH_STEPPING PchStepping = PCH_STEPPING_MAX;
|
|
if (PchStepping != PCH_STEPPING_MAX) {
|
return PchStepping;
|
}
|
|
LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
|
DEFAULT_PCI_SEGMENT_NUMBER_PCH,
|
DEFAULT_PCI_BUS_NUMBER_PCH,
|
PCI_DEVICE_NUMBER_PCH_LPC,
|
PCI_FUNCTION_NUMBER_PCH_LPC,
|
0
|
);
|
RevId = PciSegmentRead8 (LpcBaseAddress + PCI_REVISION_ID_OFFSET);
|
|
PchStepping = RevId;
|
|
return RevId;
|
}
|
|
/**
|
Determine if PCH is supported
|
|
@retval TRUE PCH is supported
|
@retval FALSE PCH is not supported
|
**/
|
BOOLEAN
|
IsPchSupported (
|
VOID
|
)
|
{
|
UINT16 LpcDeviceId;
|
UINT16 LpcVendorId;
|
UINT64 LpcBaseAddress;
|
|
LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
|
DEFAULT_PCI_SEGMENT_NUMBER_PCH,
|
DEFAULT_PCI_BUS_NUMBER_PCH,
|
PCI_DEVICE_NUMBER_PCH_LPC,
|
PCI_FUNCTION_NUMBER_PCH_LPC,
|
0
|
);
|
|
LpcDeviceId = PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET);
|
LpcVendorId = PciSegmentRead16 (LpcBaseAddress + PCI_VENDOR_ID_OFFSET);
|
|
///
|
/// Verify that this is a supported chipset
|
///
|
if ((LpcVendorId == V_LPC_CFG_VENDOR_ID) && (PchSeries () != PCH_UNKNOWN_SERIES)) {
|
return TRUE;
|
} else {
|
DEBUG ((DEBUG_ERROR, "PCH code doesn't support the LpcDeviceId: 0x%04x!\n", LpcDeviceId));
|
return FALSE;
|
}
|
}
|
|
/**
|
Check if this is PCH LP series
|
|
@retval TRUE It's PCH LP series
|
@retval FALSE It's not PCH LP series
|
**/
|
BOOLEAN
|
IsPchLp (
|
VOID
|
)
|
{
|
return (PchSeries () == PCH_LP);
|
}
|
|
/**
|
Check if this is PCH H series
|
|
@retval TRUE It's PCH H series
|
@retval FALSE It's not PCH H series
|
**/
|
BOOLEAN
|
IsPchH (
|
VOID
|
)
|
{
|
return (PchSeries () == PCH_H);
|
}
|
|
/**
|
Check if this is CDF PCH generation
|
|
@retval TRUE It's CDF PCH
|
@retval FALSE It's not CDF PCH
|
**/
|
BOOLEAN
|
IsCdfPch (
|
VOID
|
)
|
{
|
return (PchGeneration () == CDF_PCH);
|
}
|
|
/**
|
Check if this is PCH generation
|
|
@retval TRUE It's CNL PCH
|
@retval FALSE It's not CNL PCH
|
**/
|
BOOLEAN
|
IsCnlPch (
|
VOID
|
)
|
{
|
return (PchGeneration () == CNL_PCH);
|
}
|
|
/**
|
Get PCH stepping ASCII string.
|
Function determines major and minor stepping versions and writes them into a buffer.
|
The return string is zero terminated
|
|
@param [out] Buffer Output buffer of string
|
@param [in] BufferSize Buffer size.
|
Must not be less then PCH_STEPPING_STR_LENGTH_MAX
|
|
@retval EFI_SUCCESS String copied successfully
|
@retval EFI_INVALID_PARAMETER The stepping is not supported, or parameters are NULL
|
@retval EFI_BUFFER_TOO_SMALL Input buffer size is too small
|
**/
|
EFI_STATUS
|
PchGetSteppingStr (
|
OUT CHAR8 *Buffer,
|
IN UINT32 BufferSize
|
)
|
{
|
PCH_STEPPING PchStep;
|
|
PchStep = PchStepping ();
|
|
if ((Buffer == NULL) || (BufferSize == 0)) {
|
return EFI_INVALID_PARAMETER;
|
}
|
if (BufferSize < PCH_STEPPING_STR_LENGTH_MAX) {
|
return EFI_BUFFER_TOO_SMALL;
|
}
|
|
AsciiSPrint (Buffer, BufferSize, "%c%c", 'A' + (PchStep >> 4), '0' + (PchStep & 0xF));
|
|
return EFI_SUCCESS;
|
}
|
|
/**
|
Get PCH Sku ASCII string
|
The return string is zero terminated.
|
|
@retval Static ASCII string of PCH Sku
|
**/
|
CHAR8*
|
PchGetSkuStr (
|
VOID
|
)
|
{
|
UINTN Index;
|
UINT16 LpcDid;
|
|
LpcDid = PchGetLpcDid ();
|
|
for (Index = 0; mSkuStrs[Index].Id != 0xFFFF; Index++) {
|
if (LpcDid == mSkuStrs[Index].Id) {
|
return mSkuStrs[Index].String;
|
}
|
}
|
|
return "Undefined SKU";
|
}
|
|
/**
|
Get Pch Maximum Pcie Controller Number
|
|
@retval Pch Maximum Pcie Root Port Number
|
**/
|
UINT8
|
GetPchMaxPcieControllerNum (
|
VOID
|
)
|
{
|
return GetPchMaxPciePortNum () / PCH_PCIE_CONTROLLER_PORTS;
|
}
|
|