/** @file
Pch information string library.
All function in this library is available for PEI, DXE, and SMM,
But do not support UEFI RUNTIME environment call.
Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
/**
Structure for PCH stepping string mapping
**/
struct PCH_STEPPING_STRING {
PCH_STEPPING Stepping;
CHAR8 *String;
};
GLOBAL_REMOVE_IF_UNREFERENCED
struct PCH_STEPPING_STRING mSteppingStrs[] = {
{PchHB0, "B0"},
{PchHC0, "C0"},
{PchHD0, "D0"},
{PchHD1, "D1"},
{PchLpB0, "B0"},
{PchLpB1, "B1"},
{PchLpC0, "C0"},
{PchLpC1, "C1"},
{KblPchHA0, "A0"},
{PchSteppingMax, NULL}
};
/**
Structure for PCH series string mapping
**/
typedef struct {
PCH_SERIES Series;
CHAR8 *String;
} PCH_SERIES_STRING ;
GLOBAL_REMOVE_IF_UNREFERENCED
PCH_SERIES_STRING mSklPchSeriesStrs[] = {
{PchH, "SKL PCH-H"},
{PchLp, "SKL PCH-LP"},
{PchUnknownSeries, NULL}
};
GLOBAL_REMOVE_IF_UNREFERENCED
PCH_SERIES_STRING mKblPchSeriesStrs[] = {
{PchH, "KBL PCH-H"},
{PchUnknownSeries, NULL}
};
/**
Structure for PCH sku string mapping
**/
struct PCH_SKU_STRING {
UINT16 Id;
CHAR8 *String;
};
GLOBAL_REMOVE_IF_UNREFERENCED
struct PCH_SKU_STRING mSkuStrs[] = {
//
// SKL PCH H Desktop LPC Device IDs
//
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_SUPER_SKU, "Super SKU"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_ES_SUPER_SKU, "ES Super SKU"},
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_0, "Super SKU (locked)"},
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_1, "H110"},
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_2, "H170"},
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_3, "Z170"},
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_4, "Q170"},
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_5, "Q150"},
{V_SKL_PCH_H_LPC_DEVICE_ID_DT_6, "B150"},
//
// SKL PCH H Server/WS LPC Device IDs
//
{V_SKL_PCH_H_LPC_DEVICE_ID_SVR_0, "C236"},
{V_SKL_PCH_H_LPC_DEVICE_ID_SVR_1, "C232"},
{V_SKL_PCH_H_LPC_DEVICE_ID_SVR_2, "CM236"},
{V_SKL_PCH_H_LPC_DEVICE_ID_A14B, "Super SKU (Unlocked)"},
{V_KBL_PCH_H_LPC_DEVICE_ID_SVR_ES_SUPER_SKU, "ES Super SKU (Unlocked)"},
//
// SKL PCH H Mobile LPC Device IDs
//
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_0, "QM170"},
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_1, "HM170"},
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_3, "QMS180"},
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_4, "HM175"},
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_5, "QM175"},
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_6, "CM238"},
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_SUPER_SKU, "Super SKU"},
{V_SKL_PCH_H_LPC_DEVICE_ID_MB_8, "QMS185"},
//
// SKL PCH LP Mobile LPC Device IDs
//
{V_PCH_LP_LPC_DEVICE_ID_MB_SUPER_SKU, "Super SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_0, "Super SKU (locked)"},
{V_PCH_LP_LPC_DEVICE_ID_MB_1, "(U) Base SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_2, "(Y) Premium SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_3, "(U) Premium SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_SUPER_SKU_1, "Super SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_4, "Super SKU (locked)"},
{V_PCH_LP_LPC_DEVICE_ID_MB_5, "(U) Base SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_6, "(Y) Premium SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_7, "(U) Premium SKU"},
{V_PCH_LP_LPC_DEVICE_ID_MB_8, "(Y) iHDCP 2.2 Premium"},
{V_PCH_LP_LPC_DEVICE_ID_MB_9, "(U) iHDCP 2.2 Premium"},
{V_PCH_LP_LPC_DEVICE_ID_MB_10, "(U) iHDCP 2.2 Base"},
//
// KBL PCH H Desktop LPC Device IDs
//
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_SUPER_SKU, "Super SKU"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_H270, "H270"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_Z270, "Z270"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_Q270, "Q270"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_Q250, "Q250"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_B250, "B250"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_H215, "H215"},
{V_KBL_PCH_H_LPC_DEVICE_ID_DT_Z370, "Z370"},
//
// KBL PCH H Server/WS LPC Device IDs
//
{V_KBL_PCH_H_LPC_DEVICE_ID_SVR_SUPER_SKU, "Super SKU (Unlocked)"},
{V_KBL_PCH_H_LPC_DEVICE_ID_SVR_0, "X290"},
{V_KBL_PCH_H_LPC_DEVICE_ID_SVR_1, "C6xx"},
{V_KBL_PCH_H_LPC_DEVICE_ID_SVR_2, "ES Super SKU Server (Interposer)"},
{V_KBL_PCH_H_LPC_DEVICE_ID_SVR_3, "Super SKU Server"},
{V_KBL_PCH_H_LPC_DEVICE_ID_SVR_4, "C422B"},
{0xFFFF, NULL}
};
/**
Get PCH stepping ASCII string
The return string is zero terminated.
@param [in] PchStep Pch stepping
@param [out] Buffer Output buffer of string
@param [in,out] BufferSize Size of input buffer,
and return required string size when buffer is too small.
@retval EFI_SUCCESS String copy 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 (
IN PCH_STEPPING PchStep,
OUT CHAR8 *Buffer,
IN OUT UINT32 *BufferSize
)
{
UINTN Index;
UINT32 StrLength;
CHAR8 *Str;
if ((Buffer == NULL) || (BufferSize == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (*BufferSize > 0) {
Buffer[0] = 0;
}
Str = NULL;
StrLength = 0;
for (Index = 0; mSteppingStrs[Index].Stepping != PchSteppingMax; Index++) {
if (PchStep == mSteppingStrs[Index].Stepping) {
StrLength = (UINT32) AsciiStrLen (mSteppingStrs[Index].String);
Str = mSteppingStrs[Index].String;
break;
}
}
if (StrLength == 0) {
// Unsupported Stepping
// ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
if (*BufferSize <= StrLength) {
*BufferSize = StrLength + 1;
return EFI_BUFFER_TOO_SMALL;
}
AsciiStrCpyS (Buffer, *BufferSize, Str);
return EFI_SUCCESS;
}
/**
Get PCH series ASCII string
The return string is zero terminated.
@param [in] PchSeries Pch series
@param [out] Buffer Output buffer of string
@param [in,out] BufferSize Size of input buffer,
and return required string size when buffer is too small.
@retval EFI_SUCCESS String copy successfully
@retval EFI_INVALID_PARAMETER The series is not supported, or parameters are NULL
@retval EFI_BUFFER_TOO_SMALL Input buffer size is too small
**/
EFI_STATUS
PchGetSeriesStr (
IN PCH_SERIES PchSeries,
OUT CHAR8 *Buffer,
IN OUT UINT32 *BufferSize
)
{
UINTN Index;
UINT32 StrLength;
CHAR8 *Str;
PCH_GENERATION PchGen;
PCH_SERIES_STRING *SeriesStrs;
UINT16 LpcDeviceId;
if ((Buffer == NULL) || (BufferSize == NULL)) {
return EFI_INVALID_PARAMETER;
}
PchGen = GetPchGeneration ();
if (PchGen == SklPch) {
//
// Check if Client/Server ES Super SKU
//
LpcDeviceId = GetLpcDid ();
if ((LpcDeviceId == V_KBL_PCH_H_LPC_DEVICE_ID_DT_ES_SUPER_SKU) ||
(LpcDeviceId == V_KBL_PCH_H_LPC_DEVICE_ID_SVR_ES_SUPER_SKU)) {
SeriesStrs = mKblPchSeriesStrs;
} else {
SeriesStrs = mSklPchSeriesStrs;
}
} else if (PchGen == KblPch){
SeriesStrs = mKblPchSeriesStrs;
} else {
ASSERT(FALSE);
return EFI_UNSUPPORTED;
}
if (*BufferSize > 0) {
Buffer[0] = 0;
}
Str = NULL;
StrLength = 0;
for (Index = 0; SeriesStrs[Index].Series != PchUnknownSeries; Index++) {
if (PchSeries == SeriesStrs[Index].Series) {
StrLength = (UINT32) AsciiStrLen (SeriesStrs[Index].String);
Str = SeriesStrs[Index].String;
break;
}
}
if (StrLength == 0) {
// Unsupported Series
// ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
if (*BufferSize <= StrLength) {
*BufferSize = StrLength + 1;
return EFI_BUFFER_TOO_SMALL;
}
AsciiStrCpyS (Buffer, *BufferSize, Str);
return EFI_SUCCESS;
}
/**
Get PCH Sku ASCII string
The return string is zero terminated.
@param [in] LpcDid LPC device id
@param [out] Buffer Output buffer of string
@param [in,out] BufferSize Size of input buffer,
and return required string size when buffer is too small.
@retval EFI_SUCCESS String copy successfully
@retval EFI_INVALID_PARAMETER The series is not supported, or parameters are NULL
@retval EFI_BUFFER_TOO_SMALL Input buffer size is too small
**/
EFI_STATUS
PchGetSkuStr (
IN UINT16 LpcDid,
OUT CHAR8 *Buffer,
IN OUT UINT32 *BufferSize
)
{
UINTN Index;
UINT32 StrLength;
CHAR8 *Str;
if ((Buffer == NULL) || (BufferSize == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (*BufferSize > 0) {
Buffer[0] = 0;
}
Str = NULL;
StrLength = 0;
for (Index = 0; mSkuStrs[Index].Id != 0xFFFF; Index++) {
if (LpcDid == mSkuStrs[Index].Id) {
StrLength = (UINT32) AsciiStrLen (mSkuStrs[Index].String);
Str = mSkuStrs[Index].String;
}
}
if (StrLength == 0) {
// Unsupported Sku
// ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
if (*BufferSize <= StrLength) {
*BufferSize = StrLength + 1;
return EFI_BUFFER_TOO_SMALL;
}
AsciiStrCpyS (Buffer, *BufferSize, Str);
return EFI_SUCCESS;
}