audk/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c

1861 lines
56 KiB
C

/** @file
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
SetupInfoRecords.c
Abstract:
This is the filter driver to retrieve data hub entries.
Revision History:
--*/
#include "PlatformSetupDxe.h"
#include <Protocol/LegacyBios.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/SimpleNetwork.h>
#include <Protocol/DevicePath.h>
#include <Protocol/DiskInfo.h>
#include <Protocol/IdeControllerInit.h>
#include <Protocol/MpService.h>
#include <Protocol/PchPlatformPolicy.h>
#include <Protocol/CpuIo2.h>
#include <Protocol/Smbios.h>
#include <IndustryStandard/SmBios.h>
#include <Library/IoLib.h>
#include <Library/I2CLib.h>
#include <Guid/GlobalVariable.h>
#include "Valleyview.h"
#include "VlvAccess.h"
#include "PchAccess.h"
#include "SetupMode.h"
#include "PchCommonDefinitions.h"
#include <PlatformBaseAddresses.h>
typedef struct {
UINT8 ID;
CHAR8 String[16];
} VLV_REV;
typedef struct {
UINT8 RevId;
CHAR8 String[16];
} SB_REV;
//
// Silicon Steppings
//
SB_REV SBRevisionTable[] = {
{V_PCH_LPC_RID_0, "(A0 Stepping)"},
{V_PCH_LPC_RID_1, "(A0 Stepping)"},
{V_PCH_LPC_RID_2, "(A1 Stepping)"},
{V_PCH_LPC_RID_3, "(A1 Stepping)"},
{V_PCH_LPC_RID_4, "(B0 Stepping)"},
{V_PCH_LPC_RID_5, "(B0 Stepping)"},
{V_PCH_LPC_RID_6, "(B1 Stepping)"},
{V_PCH_LPC_RID_7, "(B1 Stepping)"},
{V_PCH_LPC_RID_8, "(B2 Stepping)"},
{V_PCH_LPC_RID_9, "(B2 Stepping)"},
{V_PCH_LPC_RID_A, "(B3 Stepping)"},
{V_PCH_LPC_RID_B, "(B3 Stepping)"},
{V_PCH_LPC_RID_C, "(C0 Stepping)"},
{V_PCH_LPC_RID_D, "(C0 Stepping)"}
};
#define LEFT_JUSTIFY 0x01
#define PREFIX_SIGN 0x02
#define PREFIX_BLANK 0x04
#define COMMA_TYPE 0x08
#define LONG_TYPE 0x10
#define PREFIX_ZERO 0x20
#define ICH_REG_REV 0x08
#define MSR_IA32_PLATFORM_ID 0x17
BOOLEAN mSetupInfoDone = FALSE;
UINT8 mUseProductKey = 0;
EFI_EXP_BASE10_DATA mProcessorFrequency;
EFI_EXP_BASE10_DATA mProcessorFsbFrequency;
EFI_GUID mProcessorProducerGuid;
EFI_HII_HANDLE mHiiHandle;
EFI_PLATFORM_CPU_INFO mPlatformCpuInfo;
SYSTEM_CONFIGURATION mSystemConfiguration;
EFI_PLATFORM_INFO_HOB *mPlatformInfo;
#define memset SetMem
UINT16 mMemorySpeed = 0xffff;
EFI_PHYSICAL_ADDRESS mMemorySizeChannelASlot0 = 0;
UINT16 mMemorySpeedChannelASlot0 = 0xffff;
EFI_PHYSICAL_ADDRESS mMemorySizeChannelASlot1 = 0;
UINT16 mMemorySpeedChannelASlot1 = 0xffff;
EFI_PHYSICAL_ADDRESS mMemorySizeChannelBSlot0 = 0;
UINT16 mMemorySpeedChannelBSlot0 = 0xffff;
EFI_PHYSICAL_ADDRESS mMemorySizeChannelBSlot1 = 0;
UINT16 mMemorySpeedChannelBSlot1 = 0xffff;
EFI_PHYSICAL_ADDRESS mMemorySizeChannelCSlot0 = 0;
UINT16 mMemorySpeedChannelCSlot0 = 0xffff;
EFI_PHYSICAL_ADDRESS mMemorySizeChannelCSlot1 = 0;
UINT16 mMemorySpeedChannelCSlot1 = 0xffff;
UINTN mMemoryMode = 0xff;
#define CHARACTER_NUMBER_FOR_VALUE 30
typedef struct {
EFI_STRING_TOKEN MemoryDeviceLocator;
EFI_STRING_TOKEN MemoryBankLocator;
EFI_STRING_TOKEN MemoryManufacturer;
EFI_STRING_TOKEN MemorySerialNumber;
EFI_STRING_TOKEN MemoryAssetTag;
EFI_STRING_TOKEN MemoryPartNumber;
EFI_INTER_LINK_DATA MemoryArrayLink;
EFI_INTER_LINK_DATA MemorySubArrayLink;
UINT16 MemoryTotalWidth;
UINT16 MemoryDataWidth;
UINT64 MemoryDeviceSize;
EFI_MEMORY_FORM_FACTOR MemoryFormFactor;
UINT8 MemoryDeviceSet;
EFI_MEMORY_ARRAY_TYPE MemoryType;
EFI_MEMORY_TYPE_DETAIL MemoryTypeDetail;
UINT16 MemorySpeed;
EFI_MEMORY_STATE MemoryState;
} EFI_MEMORY_ARRAY_LINK;
typedef struct {
EFI_PHYSICAL_ADDRESS MemoryArrayStartAddress;
EFI_PHYSICAL_ADDRESS MemoryArrayEndAddress;
EFI_INTER_LINK_DATA PhysicalMemoryArrayLink;
UINT16 MemoryArrayPartitionWidth;
} EFI_MEMORY_ARRAY_START_ADDRESS;
typedef enum {
PCH_SATA_MODE_IDE = 0,
PCH_SATA_MODE_AHCI,
PCH_SATA_MODE_RAID,
PCH_SATA_MODE_MAX
} PCH_SATA_MODE;
/**
Acquire the string associated with the Index from smbios structure and return it.
The caller is responsible for free the string buffer.
@param OptionalStrStart The start position to search the string
@param Index The index of the string to extract
@param String The string that is extracted
@retval EFI_SUCCESS The function returns EFI_SUCCESS always.
**/
EFI_STATUS
GetOptionalStringByIndex (
IN CHAR8 *OptionalStrStart,
IN UINT8 Index,
OUT CHAR16 **String
)
{
UINTN StrSize;
if (Index == 0) {
*String = AllocateZeroPool (sizeof (CHAR16));
return EFI_SUCCESS;
}
StrSize = 0;
do {
Index--;
OptionalStrStart += StrSize;
StrSize = AsciiStrSize (OptionalStrStart);
} while (OptionalStrStart[StrSize] != 0 && Index != 0);
if ((Index != 0) || (StrSize == 1)) {
//
// Meet the end of strings set but Index is non-zero, or
// Find an empty string
//
return EFI_NOT_FOUND;
} else {
*String = AllocatePool (StrSize * sizeof (CHAR16));
AsciiStrToUnicodeStr (OptionalStrStart, *String);
}
return EFI_SUCCESS;
}
/**
VSPrint worker function that prints a Value as a decimal number in Buffer
@param Buffer Location to place ascii decimal number string of Value.
@param Value Decimal value to convert to a string in Buffer.
@param Flags Flags to use in printing decimal string, see file header for details.
@param Width Width of hex value.
Number of characters printed.
**/
UINTN
EfiValueToString (
IN OUT CHAR16 *Buffer,
IN INT64 Value,
IN UINTN Flags,
IN UINTN Width
)
{
CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
CHAR16 *TempStr;
CHAR16 *BufferPtr;
UINTN Count;
UINTN ValueCharNum;
UINTN Remainder;
CHAR16 Prefix;
UINTN Index;
BOOLEAN ValueIsNegative;
UINT64 TempValue;
TempStr = TempBuffer;
BufferPtr = Buffer;
Count = 0;
ValueCharNum = 0;
ValueIsNegative = FALSE;
if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
Width = CHARACTER_NUMBER_FOR_VALUE - 1;
}
if (Value < 0) {
Value = -Value;
ValueIsNegative = TRUE;
}
do {
TempValue = Value;
Value = (INT64)DivU64x32 ((UINT64)Value, 10);
Remainder = (UINTN)((UINT64)TempValue - 10 * Value);
*(TempStr++) = (CHAR16)(Remainder + '0');
ValueCharNum++;
Count++;
if ((Flags & COMMA_TYPE) == COMMA_TYPE) {
if (ValueCharNum % 3 == 0 && Value != 0) {
*(TempStr++) = ',';
Count++;
}
}
} while (Value != 0);
if (ValueIsNegative) {
*(TempStr++) = '-';
Count++;
}
if ((Flags & PREFIX_ZERO) && !ValueIsNegative) {
Prefix = '0';
} else {
Prefix = ' ';
}
Index = Count;
if (!(Flags & LEFT_JUSTIFY)) {
for (; Index < Width; Index++) {
*(TempStr++) = Prefix;
}
}
//
// Reverse temp string into Buffer.
//
if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
TempStr = TempBuffer + Width;
}
Index = 0;
while (TempStr != TempBuffer) {
*(BufferPtr++) = *(--TempStr);
Index++;
}
*BufferPtr = 0;
return Index;
}
static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
/**
VSPrint worker function that prints a Value as a hex number in Buffer
@param Buffer Location to place ascii hex string of Value.
@param Value Hex value to convert to a string in Buffer.
@param Flags Flags to use in printing Hex string, see file header for details.
@param Width Width of hex value.
@retval Number of characters printed.
**/
UINTN
EfiValueToHexStr (
IN OUT CHAR16 *Buffer,
IN UINT64 Value,
IN UINTN Flags,
IN UINTN Width
)
{
CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
CHAR16 *TempStr;
CHAR16 Prefix;
CHAR16 *BufferPtr;
UINTN Count;
UINTN Index;
TempStr = TempBuffer;
BufferPtr = Buffer;
//
// Count starts at one since we will null terminate. Each iteration of the
// loop picks off one nibble. Oh yea TempStr ends up backwards
//
Count = 0;
if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
Width = CHARACTER_NUMBER_FOR_VALUE - 1;
}
do {
Index = ((UINTN)Value & 0xf);
*(TempStr++) = mHexStr[Index];
Value = RShiftU64 (Value, 4);
Count++;
} while (Value != 0);
if (Flags & PREFIX_ZERO) {
Prefix = '0';
} else {
Prefix = ' ';
}
Index = Count;
if (!(Flags & LEFT_JUSTIFY)) {
for (; Index < Width; Index++) {
*(TempStr++) = Prefix;
}
}
//
// Reverse temp string into Buffer.
//
if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
TempStr = TempBuffer + Width;
}
Index = 0;
while (TempStr != TempBuffer) {
*(BufferPtr++) = *(--TempStr);
Index++;
}
*BufferPtr = 0;
return Index;
}
/*++
Converts MAC address to Unicode string.
The value is 64-bit and the resulting string will be 12
digit hex number in pairs of digits separated by dashes.
@param String string that will contain the value
@param MacAddr add argument and description to function comment
@param AddrSize add argument and description to function comment
**/
CHAR16 *
StrMacToString (
OUT CHAR16 *String,
IN EFI_MAC_ADDRESS *MacAddr,
IN UINT32 AddrSize
)
{
UINT32 i;
for (i = 0; i < AddrSize; i++) {
EfiValueToHexStr (
&String[2 * i],
MacAddr->Addr[i] & 0xFF,
PREFIX_ZERO,
2
);
}
//
// Terminate the string.
//
String[2 * AddrSize] = L'\0';
return String;
}
VOID UpdateLatestBootTime() {
UINTN VarSize;
EFI_STATUS Status;
UINT64 TimeValue;
CHAR16 Buffer[40];
if (mSystemConfiguration.LogBootTime != 1) {
return;
}
VarSize = sizeof(TimeValue);
Status = gRT->GetVariable(
BOOT_TIME_NAME,
&gEfiNormalSetupGuid,
NULL,
&VarSize,
&TimeValue
);
if (EFI_ERROR(Status)) {
return;
}
UnicodeSPrint (Buffer, sizeof (Buffer), L"%d ms", (UINT32)TimeValue);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_LOG_BOOT_TIME_VALUE), Buffer, NULL);
}
/**
Get Cache Type for the specified Cache. This function is invoked when there is data records
available in the Data Hub.
Get Cache Type function arguments:
@param Instance The instance number of the subclass with the same ProducerName..
@param SubInstance The instance number of the RecordType for the same Instance.
@param CacheType Cache type, see definition of EFI_CACHE_TYPE_DATA.
@retval EFI_STATUS
**/
EFI_STATUS
GetCacheType(
IN UINT16 Instance,
IN UINT16 SubInstance,
IN EFI_CACHE_TYPE_DATA* CacheType)
{
EFI_STATUS Status;
EFI_DATA_HUB_PROTOCOL *DataHub;
EFI_DATA_RECORD_HEADER *Record;
UINT64 MonotonicCount;
EFI_CACHE_VARIABLE_RECORD* CacheVariableRecord;
EFI_SUBCLASS_TYPE1_HEADER *DataHeader;
Status = gBS->LocateProtocol (
&gEfiDataHubProtocolGuid,
NULL,
(void **)&DataHub
);
ASSERT_EFI_ERROR(Status);
//
// Get all available data records from data hub
//
MonotonicCount = 0;
Record = NULL;
do {
Status = DataHub->GetNextRecord (
DataHub,
&MonotonicCount,
NULL,
&Record
);
if (!EFI_ERROR(Status)) {
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
if(CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) &&
(DataHeader->RecordType == CacheTypeRecordType) &&
(DataHeader->Instance == Instance) &&
(DataHeader->SubInstance == SubInstance)) {
CacheVariableRecord = (EFI_CACHE_VARIABLE_RECORD *)(DataHeader + 1);
if(CacheType){
*CacheType = CacheVariableRecord->CacheType;
return EFI_SUCCESS;
}
}
}
}
} while(!EFI_ERROR(Status) && (MonotonicCount != 0));
return EFI_NOT_FOUND;
}
/**
Setup data filter function. This function is invoked when there is data records
available in the Data Hub.
Standard event notification function arguments:
@param Event The event that is signaled.
@param Context Not used here.
@retval EFI_STATUS
**/
VOID
PrepareSetupInformation (
)
{
EFI_STATUS Status;
EFI_DATA_HUB_PROTOCOL *DataHub;
EFI_DATA_RECORD_HEADER *Record;
UINT8 *SrcData;
EFI_SUBCLASS_TYPE1_HEADER *DataHeader;
CHAR16 *NewString;
CHAR16 *NewString2;
CHAR16 *NewStringToken;
STRING_REF TokenToUpdate;
EFI_PROCESSOR_VERSION_DATA *ProcessorVersion;
UINTN Index;
UINTN DataOutput;
EFI_PROCESSOR_MICROCODE_REVISION_DATA *CpuUcodeRevisionData;
EFI_MEMORY_ARRAY_START_ADDRESS *MemoryArray;
EFI_MEMORY_ARRAY_LINK *MemoryArrayLink;
UINT64 MonotonicCount;
CHAR16 Version[100]; //Assuming that strings are < 100 UCHAR
CHAR16 ReleaseDate[100]; //Assuming that strings are < 100 UCHAR
CHAR16 ReleaseTime[100]; //Assuming that strings are < 100 UCHAR
NewString = AllocateZeroPool (0x100);
NewString2 = AllocateZeroPool (0x100);
SetMem(Version, sizeof(Version), 0);
SetMem(ReleaseDate, sizeof(ReleaseDate), 0);
SetMem(ReleaseTime, sizeof(ReleaseTime), 0);
//
// Get the Data Hub Protocol. Assume only one instance
//
Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (void **)&DataHub);
ASSERT_EFI_ERROR(Status);
//
// Get all available data records from data hub
//
MonotonicCount = 0;
Record = NULL;
do {
Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
if (!EFI_ERROR(Status)) {
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
SrcData = (UINT8 *)(DataHeader + 1);
//
// Processor
//
if (CompareGuid(&Record->DataRecordGuid, &gEfiProcessorSubClassGuid)) {
CopyMem (&mProcessorProducerGuid, &Record->ProducerName, sizeof(EFI_GUID));
switch (DataHeader->RecordType) {
case ProcessorCoreFrequencyRecordType:
CopyMem(&mProcessorFrequency, SrcData, sizeof(EFI_EXP_BASE10_DATA));
Index = EfiValueToString (
NewString,
ConvertBase10ToRaw ((EFI_EXP_BASE10_DATA *)SrcData)/1000000000,
PREFIX_ZERO,
0
);
StrCat (NewString, L".");
EfiValueToString (
NewString + Index + 1,
((ConvertBase10ToRaw ((EFI_EXP_BASE10_DATA *)SrcData)%1000000000)/10000000),
PREFIX_ZERO,
0
);
StrCat (NewString, L" GHz");
TokenToUpdate = (STRING_REF)STR_PROCESSOR_SPEED_VALUE;
HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
break;
case ProcessorVersionRecordType:
ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData;
NewStringToken = HiiGetPackageString(&mProcessorProducerGuid, *ProcessorVersion, NULL);
TokenToUpdate = (STRING_REF)STR_PROCESSOR_VERSION_VALUE;
HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL);
break;
case CpuUcodeRevisionDataRecordType:
CpuUcodeRevisionData = (EFI_PROCESSOR_MICROCODE_REVISION_DATA *) SrcData;
if (CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber != 0) {
EfiValueToHexStr (
NewString,
CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber,
PREFIX_ZERO,
8
);
TokenToUpdate = (STRING_REF)STR_PROCESSOR_MICROCODE_VALUE;
HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
}
break;
default:
break;
}
//
// Cache
//
} else if (CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) &&
(DataHeader->RecordType == CacheSizeRecordType)) {
if (DataHeader->SubInstance == EFI_CACHE_L1) {
EFI_CACHE_TYPE_DATA CacheType;
if (EFI_SUCCESS == GetCacheType(DataHeader->Instance, DataHeader->SubInstance,&CacheType)){
if (CacheType == EfiCacheTypeData) {
TokenToUpdate = (STRING_REF)STR_PROCESSOR_L1_DATA_CACHE_VALUE;
} else if (CacheType == EfiCacheTypeInstruction) {
TokenToUpdate = (STRING_REF)STR_PROCESSOR_L1_INSTR_CACHE_VALUE;
} else {
continue;
}
} else {
continue;
}
}
else if (DataHeader->SubInstance == EFI_CACHE_L2) {
TokenToUpdate = (STRING_REF)STR_PROCESSOR_L2_CACHE_VALUE;
} else {
continue;
}
if (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData)) {
DataOutput = ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData) >> 10;
EfiValueToString (NewString, DataOutput, PREFIX_ZERO, 0);
StrCat (NewString, L" KB");
if (DataHeader->SubInstance == EFI_CACHE_L3) {
HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
} else if(DataHeader->SubInstance == EFI_CACHE_L2 && mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage > 1){
//
// Show XxL2 string
//
EfiValueToString (
NewString2,
mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage,
PREFIX_ZERO,
0
);
StrCat(NewString2, L"x ");
StrCat(NewString2, NewString);
HiiSetString(mHiiHandle, TokenToUpdate, NewString2, NULL);
} else {
HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
}
}
//
// Memory
//
} else if (CompareGuid(&Record->DataRecordGuid, &gEfiMemorySubClassGuid)) {
switch (DataHeader->RecordType) {
case EFI_MEMORY_ARRAY_LINK_RECORD_NUMBER:
MemoryArrayLink = (EFI_MEMORY_ARRAY_LINK *)SrcData;
if (MemoryArrayLink->MemorySpeed > 0) {
//
// Save the lowest speed memory module
//
if (MemoryArrayLink->MemorySpeed < mMemorySpeed) {
mMemorySpeed = MemoryArrayLink->MemorySpeed;
}
switch (DataHeader->SubInstance) {
case 1:
mMemorySpeedChannelASlot0 = MemoryArrayLink->MemorySpeed;
mMemorySizeChannelASlot0 = MemoryArrayLink->MemoryDeviceSize;
break;
case 2:
mMemorySpeedChannelASlot1 = MemoryArrayLink->MemorySpeed;
mMemorySizeChannelASlot1 = MemoryArrayLink->MemoryDeviceSize;
break;
case 3:
mMemorySpeedChannelBSlot0 = MemoryArrayLink->MemorySpeed;
mMemorySizeChannelBSlot0 = MemoryArrayLink->MemoryDeviceSize;
break;
case 4:
mMemorySpeedChannelBSlot1 = MemoryArrayLink->MemorySpeed;
mMemorySizeChannelBSlot1 = MemoryArrayLink->MemoryDeviceSize;
break;
case 5:
mMemorySpeedChannelCSlot0 = MemoryArrayLink->MemorySpeed;
mMemorySizeChannelCSlot0 = MemoryArrayLink->MemoryDeviceSize;
break;
case 6:
mMemorySpeedChannelCSlot1 = MemoryArrayLink->MemorySpeed;
mMemorySizeChannelCSlot1 = MemoryArrayLink->MemoryDeviceSize;
break;
default:
break;
}
}
break;
case EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER:
MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS *)SrcData;
if (MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress) {
DataOutput = (UINTN)RShiftU64((MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress + 1), 20);
EfiValueToString (NewString, DataOutput / 1024, PREFIX_ZERO, 0);
if(DataOutput % 1024) {
StrCat (NewString, L".");
DataOutput = ((DataOutput % 1024) * 1000) / 1024;
while(!(DataOutput % 10))
DataOutput = DataOutput / 10;
EfiValueToString (NewString2, DataOutput, PREFIX_ZERO, 0);
StrCat (NewString, NewString2);
}
StrCat (NewString, L" GB");
TokenToUpdate = (STRING_REF)STR_TOTAL_MEMORY_SIZE_VALUE;
HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
}
break;
default:
break;
}
}
}
}
} while (!EFI_ERROR(Status) && (MonotonicCount != 0));
Status = GetBiosVersionDateTime (
Version,
ReleaseDate,
ReleaseTime
);
DEBUG ((EFI_D_ERROR, "GetBiosVersionDateTime :%s %s %s \n", Version, ReleaseDate, ReleaseTime));
if (!EFI_ERROR (Status)) {
UINTN Length = 0;
CHAR16 *BuildDateTime;
Length = StrLen(ReleaseDate) + StrLen(ReleaseTime);
BuildDateTime = AllocateZeroPool ((Length+2) * sizeof(CHAR16));
StrCpy (BuildDateTime, ReleaseDate);
StrCat (BuildDateTime, L" ");
StrCat (BuildDateTime, ReleaseTime);
TokenToUpdate = (STRING_REF)STR_BIOS_VERSION_VALUE;
DEBUG ((EFI_D_ERROR, "update STR_BIOS_VERSION_VALUE\n"));
HiiSetString(mHiiHandle, TokenToUpdate, Version, NULL);
TokenToUpdate = (STRING_REF)STR_BIOS_BUILD_TIME_VALUE;
DEBUG ((EFI_D_ERROR, "update STR_BIOS_BUILD_TIME_VALUE\n"));
HiiSetString(mHiiHandle, TokenToUpdate, BuildDateTime, NULL);
}
//
// Calculate and update memory speed display in Main Page
//
//
// Update the overall memory speed
//
if (mMemorySpeed != 0xffff) {
EfiValueToString (NewString, mMemorySpeed, PREFIX_ZERO, 0);
StrCat (NewString, L" MHz");
TokenToUpdate = (STRING_REF)STR_SYSTEM_MEMORY_SPEED_VALUE;
HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
}
gBS->FreePool(NewString);
gBS->FreePool(NewString2);
return;
}
/**
Routine Description: update the SETUP info for "Additional Information" which is SMBIOS info.
@retval EFI_STATUS
**/
EFI_STATUS
UpdateAdditionalInformation (
)
{
EFI_STATUS Status;
UINT64 MonotonicCount;
EFI_DATA_HUB_PROTOCOL *DataHub;
EFI_DATA_RECORD_HEADER *Record;
EFI_SUBCLASS_TYPE1_HEADER *DataHeader;
EFI_SMBIOS_PROTOCOL *Smbios;
EFI_SMBIOS_HANDLE SmbiosHandle;
EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;
SMBIOS_TABLE_TYPE0 *Type0Record;
UINT8 StrIndex;
CHAR16 *BiosVersion = NULL;
CHAR16 *IfwiVersion = NULL;
UINT16 SearchIndex;
EFI_STRING_ID TokenToUpdate;
#if defined( RVP_SUPPORT ) && RVP_SUPPORT
EFI_MISC_SYSTEM_MANUFACTURER *SystemManufacturer;
#endif
Status = gBS->LocateProtocol (
&gEfiDataHubProtocolGuid,
NULL,
(void **)&DataHub
);
ASSERT_EFI_ERROR(Status);
MonotonicCount = 0;
Record = NULL;
do {
Status = DataHub->GetNextRecord (
DataHub,
&MonotonicCount,
NULL,
&Record
);
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
if (CompareGuid(&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&
(DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)) {
#if defined( RVP_SUPPORT ) && RVP_SUPPORT
//
// System Information
//
SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER *)(DataHeader + 1);
//
// UUID (System Information)
//
SMBIOSString = EfiLibAllocateZeroPool (0x100);
GuidToString ( &SystemManufacturer->SystemUuid, SMBIOSString, 0x00 );
TokenToUpdate = (STRING_REF)STR_SYSTEM_UUID_VALUE;
HiiSetString(mHiiHandle, TokenToUpdate, SMBIOSString, NULL);
gBS->FreePool(SMBIOSString);
#endif
}
}
} while (!EFI_ERROR(Status) && (MonotonicCount != 0));
Status = gBS->LocateProtocol (
&gEfiSmbiosProtocolGuid,
NULL,
(VOID **) &Smbios
);
ASSERT_EFI_ERROR (Status);
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
do {
Status = Smbios->GetNext (
Smbios,
&SmbiosHandle,
NULL,
&SmbiosRecord,
NULL
);
if (SmbiosRecord->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {
Type0Record = (SMBIOS_TABLE_TYPE0 *) SmbiosRecord;
StrIndex = Type0Record->BiosVersion;
GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &BiosVersion);
TokenToUpdate = STRING_TOKEN (STR_BIOS_VERSION_VALUE);
for (SearchIndex = 0x0; SearchIndex < SMBIOS_STRING_MAX_LENGTH; SearchIndex++) {
if (BiosVersion[SearchIndex] == 0x0020) {
BiosVersion[SearchIndex] = 0x0000;
IfwiVersion = (CHAR16 *)(&BiosVersion[SearchIndex+1]);
break;
} else if (BiosVersion[SearchIndex] == 0x0000) {
break;
}
}
HiiSetString (mHiiHandle, TokenToUpdate, BiosVersion, NULL);
//
// Check IfwiVersion, to avoid no IFWI version in SMBIOS Type 0 strucntion
//
if(IfwiVersion) {
TokenToUpdate = STRING_TOKEN (STR_IFWI_VERSION_VALUE);
HiiSetString (mHiiHandle, TokenToUpdate, IfwiVersion, NULL);
}
}
} while (!EFI_ERROR(Status));
UpdateLatestBootTime();
return EFI_SUCCESS;
}
VOID
UpdateCPUInformation ()
{
CHAR16 Buffer[40];
UINT16 FamilyId;
UINT8 Model;
UINT8 SteppingId;
UINT8 ProcessorType;
EFI_STATUS Status;
EFI_MP_SERVICES_PROTOCOL *MpService;
UINTN MaximumNumberOfCPUs;
UINTN NumberOfEnabledCPUs;
UINT32 Buffer32 = 0xFFFFFFFF; // Keep buffer with unknown device
EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType);
//
//we need raw Model data
//
Model = Model & 0xf;
//
//Family/Model/Step
//
UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId, Model, SteppingId);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_ID_VALUE), Buffer, NULL);
Status = gBS->LocateProtocol (
&gEfiMpServiceProtocolGuid,
NULL,
(void **)&MpService
);
if (!EFI_ERROR (Status)) {
//
// Determine the number of processors
//
MpService->GetNumberOfProcessors (
MpService,
&MaximumNumberOfCPUs,
&NumberOfEnabledCPUs
);
UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", MaximumNumberOfCPUs);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_CORE_VALUE), Buffer, NULL);
}
//
// Update Mobile / Desktop / Tablet SKU
//
Buffer32 =(UINT32) RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
switch(Buffer32){
case 0x0:
UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - ISG SKU SOC", Buffer32);
break;
case 0x01:
UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC", Buffer32);
break;
case 0x02:
UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Desktop SKU SOC", Buffer32);
break;
case 0x03:
UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC", Buffer32);
break;
default:
UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Unknown SKU SOC", Buffer32);
break;
}
HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_SKU_VALUE), Buffer, NULL);
}
EFI_STATUS
SearchChildHandle(
EFI_HANDLE Father,
EFI_HANDLE *Child
)
{
EFI_STATUS Status;
UINTN HandleIndex;
EFI_GUID **ProtocolGuidArray = NULL;
UINTN ArrayCount;
UINTN ProtocolIndex;
UINTN OpenInfoCount;
UINTN OpenInfoIndex;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL;
UINTN mHandleCount;
EFI_HANDLE *mHandleBuffer= NULL;
//
// Retrieve the list of all handles from the handle database
//
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&mHandleCount,
&mHandleBuffer
);
for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++)
{
//
// Retrieve the list of all the protocols on each handle
//
Status = gBS->ProtocolsPerHandle (
mHandleBuffer[HandleIndex],
&ProtocolGuidArray,
&ArrayCount
);
if (!EFI_ERROR (Status))
{
for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++)
{
Status = gBS->OpenProtocolInformation (
mHandleBuffer[HandleIndex],
ProtocolGuidArray[ProtocolIndex],
&OpenInfo,
&OpenInfoCount
);
if (!EFI_ERROR (Status))
{
for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++)
{
if(OpenInfo[OpenInfoIndex].AgentHandle == Father)
{
if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
{
*Child = mHandleBuffer[HandleIndex];
Status = EFI_SUCCESS;
goto TryReturn;
}
}
}
Status = EFI_NOT_FOUND;
}
}
if(OpenInfo != NULL)
{
FreePool(OpenInfo);
OpenInfo = NULL;
}
}
FreePool (ProtocolGuidArray);
ProtocolGuidArray = NULL;
}
TryReturn:
if(OpenInfo != NULL)
{
FreePool (OpenInfo);
OpenInfo = NULL;
}
if(ProtocolGuidArray != NULL)
{
FreePool(ProtocolGuidArray);
ProtocolGuidArray = NULL;
}
if(mHandleBuffer != NULL)
{
FreePool (mHandleBuffer);
mHandleBuffer = NULL;
}
return Status;
}
EFI_STATUS
JudgeHandleIsPCIDevice(
EFI_HANDLE Handle,
UINT8 Device,
UINT8 Funs
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH *DPath;
Status = gBS->HandleProtocol (
Handle,
&gEfiDevicePathProtocolGuid,
(VOID **) &DPath
);
if(!EFI_ERROR(Status))
{
while(!IsDevicePathEnd(DPath))
{
if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP))
{
PCI_DEVICE_PATH *PCIPath;
PCIPath = (PCI_DEVICE_PATH*) DPath;
DPath = NextDevicePathNode(DPath);
if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs))
{
return EFI_SUCCESS;
}
}
else
{
DPath = NextDevicePathNode(DPath);
}
}
}
return EFI_UNSUPPORTED;
}
EFI_STATUS
GetDriverName(
EFI_HANDLE Handle,
CHAR16 *Name
)
{
EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL;
EFI_STATUS Status;
UINT32 Version;
UINT16 *Ptr;
Status = gBS->OpenProtocol(
Handle,
&gEfiDriverBindingProtocolGuid,
(VOID**)&BindHandle,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR(Status))
{
return EFI_NOT_FOUND;
}
Version = BindHandle->Version;
Ptr = (UINT16*)&Version;
UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr));
return EFI_SUCCESS;
}
EFI_STATUS
GetGOPDriverName(
CHAR16 *Name
)
{
UINTN HandleCount;
EFI_HANDLE *Handles= NULL;
UINTN Index;
EFI_STATUS Status;
EFI_HANDLE Child = 0;
Status = gBS->LocateHandleBuffer(
ByProtocol,
&gEfiDriverBindingProtocolGuid,
NULL,
&HandleCount,
&Handles
);
for (Index = 0; Index < HandleCount ; Index++)
{
Status = SearchChildHandle(Handles[Index], &Child);
if(!EFI_ERROR(Status))
{
Status = JudgeHandleIsPCIDevice(
Child,
0x02,
0x00
);
if(!EFI_ERROR(Status))
{
return GetDriverName(Handles[Index], Name);
}
}
}
return EFI_UNSUPPORTED;
}
EFI_STATUS
UpdatePlatformInformation (
)
{
UINT32 MicroCodeVersion;
CHAR16 Buffer[40];
UINT8 IgdVBIOSRevH;
UINT8 IgdVBIOSRevL;
UINT16 EDX;
EFI_IA32_REGISTER_SET RegSet;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL;
EFI_STATUS Status;
UINT8 CpuFlavor=0;
EFI_PEI_HOB_POINTERS GuidHob;
UINTN NumHandles;
EFI_HANDLE *HandleBuffer;
UINTN Index;
DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
UINTN PciD31F0RegBase;
UINT8 count;
UINT8 Data8;
UINT8 PIDData8;
CHAR16 Name[40];
UINT32 MrcVersion;
//
// Get the HOB list. If it is not present, then ASSERT.
//
GuidHob.Raw = GetHobList ();
if (GuidHob.Raw != NULL) {
if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
}
}
//
//VBIOS version
//
Status = gBS->LocateProtocol(
&gEfiLegacyBiosProtocolGuid,
NULL,
(void **)&LegacyBios
);
if (!EFI_ERROR (Status)) {
RegSet.X.AX = 0x5f01;
Status = LegacyBios->Int86 (LegacyBios, 0x10, &RegSet);
ASSERT_EFI_ERROR(Status);
//
// simulate AMI int15 (ax=5f01) handler
// check NbInt15.asm in AMI code for asm edition
//
EDX = (UINT16)((RegSet.E.EBX >> 16) & 0xffff);
IgdVBIOSRevH = (UINT8)(((EDX & 0x0F00) >> 4) | (EDX & 0x000F));
IgdVBIOSRevL = (UINT8)(((RegSet.X.BX & 0x0F00) >> 4) | (RegSet.X.BX & 0x000F));
if (IgdVBIOSRevH==0 && IgdVBIOSRevL==0){
HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), L"N/A", NULL);
} else {
UnicodeSPrint (Buffer, sizeof (Buffer), L"%02X%02X", IgdVBIOSRevH,IgdVBIOSRevL);
HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), Buffer, NULL);
}
}
Status = GetGOPDriverName(Name);
if (!EFI_ERROR(Status))
{
HiiSetString(mHiiHandle, STRING_TOKEN(STR_GOP_VALUE), Name, NULL);
}
//
// CpuFlavor
// ISG-DC Tablet 000
// VLV-QC Tablet 001
// VLV-QC Desktop 010
// VLV-QC Notebook 011
//
CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
switch(CpuFlavor){
case 0x0:
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet", CpuFlavor);
break;
case 0x01:
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
break;
case 0x02:
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Desktop", CpuFlavor);
break;
case 0x03:
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
break;
default:
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor);
break;
}
HiiSetString(mHiiHandle,STRING_TOKEN(STR_CPU_FLAVOR_VALUE), Buffer, NULL);
if ( NULL != mPlatformInfo) {
//
//BoardId
//
switch(mPlatformInfo->BoardId){
case 0x2:
UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE RVP(%02x)", mPlatformInfo->BoardId);
break;
case 0x4:
UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFRD(%02x)", mPlatformInfo->BoardId);
break;
case 0x5:
UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY ROCK RVP DDR3L (%02x)", mPlatformInfo->BoardId);
break;
case 0x20:
UnicodeSPrint (Buffer, sizeof (Buffer), L"BAYLEY BAY (%02x)", mPlatformInfo->BoardId);
break;
case 0x30:
UnicodeSPrint (Buffer, sizeof (Buffer), L"BAKER SPORT (%02x)", mPlatformInfo->BoardId);
break;
case 0x0:
UnicodeSPrint (Buffer, sizeof (Buffer), L"ALPINE VALLEY (%x)", mPlatformInfo->BoardId);
break;
case 0x3:
UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFD8 (%x)", mPlatformInfo->BoardId);
break;
default:
UnicodeSPrint (Buffer, sizeof (Buffer), L"Unknown BOARD (%02x)", mPlatformInfo->BoardId);
break;
}
HiiSetString(mHiiHandle,STRING_TOKEN(STR_BOARD_ID_VALUE), Buffer, NULL);
//
// Get Board FAB ID Info from protocol, update into the NVS area.
// bit0~bit3 are for Fab ID, 0x0F means unknow FAB.
//
if(mPlatformInfo->BoardRev == 0x0F) {
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", L"Unknown FAB");
HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer, NULL);
} else {
UnicodeSPrint (Buffer, sizeof (Buffer), L"%2x", mPlatformInfo->BoardRev);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer, NULL);
}
}
//
//Update MRC Version
//
MrcVersion = 0x00000000;
MrcVersion &= 0xffff;
Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0);
StrCat (Buffer, L".");
EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0);
EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_MRC_VERSION_VALUE), Buffer, NULL);
//
//Update Soc Version
//
//
// Retrieve all instances of PCH Platform Policy protocol
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gDxePchPlatformPolicyProtocolGuid,
NULL,
&NumHandles,
&HandleBuffer
);
if (!EFI_ERROR (Status)) {
//
// Find the matching PCH Policy protocol
//
for (Index = 0; Index < NumHandles; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gDxePchPlatformPolicyProtocolGuid,
(void **)&PchPlatformPolicy
);
if (!EFI_ERROR (Status)) {
PciD31F0RegBase = MmPciAddress (
0,
PchPlatformPolicy->BusNumber,
PCI_DEVICE_NUMBER_PCH_LPC,
PCI_FUNCTION_NUMBER_PCH_LPC,
0
);
Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC);
count = ARRAY_SIZE (SBRevisionTable);
for (Index = 0; Index < count; Index++) {
if(Data8 == SBRevisionTable[Index].RevId) {
UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_SOC_VALUE), Buffer, NULL);
break;
}
}
break;
}
}
}
//
// Microcode Revision
//
EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_MICROCODE_VALUE), Buffer, NULL);
//
// Punit Version
//
Data8 = 0;
UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_PUNIT_FW_VALUE), Buffer, NULL);
//
// PMC Version
//
Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF);
PIDData8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF);
UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X",PIDData8, Data8);
HiiSetString(mHiiHandle,STRING_TOKEN(STR_PMC_FW_VALUE), Buffer, NULL);
return EFI_SUCCESS;
}
/**
Update SATA Drivesize Strings for Setup and Boot order
@param NewString - pointer to string.
@param DeviceSpeed - speed of drive.
**/
VOID
GetDeviceSpeedString (
CHAR16 *NewString,
IN UINTN DeviceSpeed
)
{
if (DeviceSpeed == 0x01) {
StrCat (NewString, L"1.5Gb/s");
} else if (DeviceSpeed == 0x02) {
StrCat (NewString, L"3.0Gb/s");
} else if (DeviceSpeed == 0x03) {
StrCat (NewString, L"6.0Gb/s");
} else if (DeviceSpeed == 0x0) {
}
}
UINT8
GetChipsetSataPortSpeed (
UINTN PortNum
)
{
UINT32 DeviceSpeed;
UINT8 DeviceConfigStatus;
UINT32 IdeAhciBar;
EFI_PHYSICAL_ADDRESS MemBaseAddress = 0;
UINT8 FunNum;
DeviceSpeed = 0x01; // generation 1
//
// Allocate the AHCI BAR
//
FunNum = PCI_FUNCTION_NUMBER_PCH_SATA;
MemBaseAddress = 0x0ffffffff;
gDS->AllocateMemorySpace (
EfiGcdAllocateMaxAddressSearchBottomUp,
EfiGcdMemoryTypeMemoryMappedIo,
N_PCH_SATA_ABAR_ALIGNMENT, // 2^11: 2K Alignment
V_PCH_SATA_ABAR_LENGTH, // 2K Length
&MemBaseAddress,
mImageHandle,
NULL
);
IdeAhciBar = MmioRead32 (
MmPciAddress (
0,
0,
PCI_DEVICE_NUMBER_PCH_SATA,
FunNum,
R_PCH_SATA_ABAR
)
);
IdeAhciBar &= 0xFFFFF800;
DeviceConfigStatus = 0;
if (IdeAhciBar == 0) {
DeviceConfigStatus = 1;
IdeAhciBar = (UINT32)MemBaseAddress;
MmioWrite32 (
MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_ABAR),
IdeAhciBar
);
MmioOr16 (
MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_COMMAND),
B_PCH_SATA_COMMAND_MSE
);
}
if (mSystemConfiguration.SataType == PCH_SATA_MODE_IDE){
//
// Program the "Ports Implemented Register"
//
MmioAndThenOr32 (IdeAhciBar + R_PCH_SATA_AHCI_PI, (UINT32)~(B_PCH_SATA_PORT0_IMPLEMENTED + B_PCH_SATA_PORT1_IMPLEMENTED), (UINT32)(B_PCH_SATA_PORT0_IMPLEMENTED + B_PCH_SATA_PORT1_IMPLEMENTED));
}
switch (PortNum)
{
case 0:
DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar + R_PCH_SATA_AHCI_P0SSTS);
break;
case 1:
DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar + R_PCH_SATA_AHCI_P1SSTS);
break;
}
if (MemBaseAddress) {
gDS->FreeMemorySpace (
MemBaseAddress,
V_PCH_SATA_ABAR_LENGTH
);
}
if (DeviceConfigStatus) {
IdeAhciBar = 0;
MmioWrite32 (
MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_ABAR),
IdeAhciBar
);
}
DeviceSpeed = (UINT8)((DeviceSpeed >> 4) & 0x0F);
return (UINT8)DeviceSpeed;
}
/**
IDE data filter function.
**/
void
IdeDataFilter (void)
{
EFI_STATUS Status;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
EFI_DISK_INFO_PROTOCOL *DiskInfo;
EFI_DEVICE_PATH_PROTOCOL *DevicePath, *DevicePathNode;
PCI_DEVICE_PATH *PciDevicePath;
UINTN Index;
UINT8 Index1;
UINT32 BufferSize;
UINT32 DriveSize;
UINT32 IdeChannel;
UINT32 IdeDevice;
EFI_ATA_IDENTIFY_DATA *IdentifyDriveInfo;
CHAR16 *NewString;
CHAR16 SizeString[20];
STRING_REF NameToUpdate;
CHAR8 StringBuffer[0x100];
UINT32 DeviceSpeed;
UINTN PortNumber;
//
// Assume no line strings is longer than 256 bytes.
//
NewString = AllocateZeroPool (0x100);
PciDevicePath = NULL;
//
// Fill IDE Infomation
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiDiskInfoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID*)&DevicePath
);
ASSERT_EFI_ERROR (Status);
DevicePathNode = DevicePath;
while (!IsDevicePathEnd (DevicePathNode) ) {
if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) &&
( DevicePathSubType (DevicePathNode) == HW_PCI_DP)) {
PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
break;
}
DevicePathNode = NextDevicePathNode (DevicePathNode);
}
if (PciDevicePath == NULL) {
continue;
}
//
// Check for onboard IDE
//
if (PciDevicePath->Device== PCI_DEVICE_NUMBER_PCH_SATA) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiDiskInfoProtocolGuid,
(void **)&DiskInfo
);
ASSERT_EFI_ERROR (Status);
Status = DiskInfo->WhichIde (
DiskInfo,
&IdeChannel,
&IdeDevice
);
ASSERT_EFI_ERROR (Status);
IdentifyDriveInfo = AllocatePool (sizeof(EFI_ATA_IDENTIFY_DATA));
BufferSize = sizeof(EFI_ATA_IDENTIFY_DATA);
Status = DiskInfo->Identify (
DiskInfo,
IdentifyDriveInfo,
&BufferSize
);
ASSERT_EFI_ERROR(Status);
//
// Onboard SATA Devices
//
if (PciDevicePath->Function == PCI_FUNCTION_NUMBER_PCH_SATA) {
if (IdeChannel == 0 && IdeDevice == 0) {
NameToUpdate = (STRING_REF)STR_SATA0_NAME;
} else if (IdeChannel == 1 && IdeDevice == 0) {
NameToUpdate = (STRING_REF)STR_SATA1_NAME;
} else {
continue;
}
} else {
continue;
}
ZeroMem(StringBuffer, sizeof(StringBuffer));
CopyMem(
StringBuffer,
(CHAR8 *)&IdentifyDriveInfo->ModelName,
sizeof(IdentifyDriveInfo->ModelName)
);
SwapEntries(StringBuffer);
AsciiToUnicode(StringBuffer, NewString);
//
// Chap it off after 16 characters
//
NewString[16] = 0;
//
// For HardDisk append the size. Otherwise display atapi
//
if ((IdentifyDriveInfo->config & 0x8000) == 00) {
//
// 48 bit address feature set is supported, get maximum capacity
//
if ((IdentifyDriveInfo->command_set_supported_83 & 0x0400) == 0) {
DriveSize = (((((IdentifyDriveInfo->user_addressable_sectors_hi << 16) +
IdentifyDriveInfo->user_addressable_sectors_lo) / 1000) * 512) / 1000);
} else {
DriveSize = IdentifyDriveInfo->maximum_lba_for_48bit_addressing[0];
for (Index1 = 1; Index1 < 4; Index1++) {
//
// Lower byte goes first: word[100] is the lowest word, word[103] is highest
//
DriveSize |= LShiftU64(IdentifyDriveInfo->maximum_lba_for_48bit_addressing[Index1], 16 * Index1);
}
DriveSize = (UINT32) DivU64x32(MultU64x32(DivU64x32(DriveSize, 1000), 512), 1000);
}
StrCat (NewString, L"(");
EfiValueToString (SizeString, DriveSize/1000, PREFIX_BLANK, 0);
StrCat (NewString, SizeString);
StrCat (NewString, L".");
EfiValueToString (SizeString, (DriveSize%1000)/100, PREFIX_BLANK, 0);
StrCat (NewString, SizeString);
StrCat (NewString, L"GB");
} else {
StrCat (NewString, L"(ATAPI");
}
//
// Update SPEED.
//
PortNumber = (IdeDevice << 1) + IdeChannel;
DeviceSpeed = GetChipsetSataPortSpeed(PortNumber);
if (DeviceSpeed) {
StrCat (NewString, L"-");
GetDeviceSpeedString( NewString, DeviceSpeed);
}
StrCat (NewString, L")");
HiiSetString(mHiiHandle, NameToUpdate, NewString, NULL);
}
}
if (HandleBuffer != NULL) {
gBS->FreePool (HandleBuffer);
}
gBS->FreePool(NewString);
return;
}
VOID
EFIAPI
SetupInfo (void)
{
EFI_STATUS Status;
UINTN VarSize;
EFI_PEI_HOB_POINTERS GuidHob;
if (mSetupInfoDone) {
return;
}
VarSize = sizeof(SYSTEM_CONFIGURATION);
Status = gRT->GetVariable(
NORMAL_SETUP_NAME,
&gEfiNormalSetupGuid,
NULL,
&VarSize,
&mSystemConfiguration
);
if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
//The setup variable is corrupted
VarSize = sizeof(SYSTEM_CONFIGURATION);
Status = gRT->GetVariable(
L"SetupRecovery",
&gEfiNormalSetupGuid,
NULL,
&VarSize,
&mSystemConfiguration
);
ASSERT_EFI_ERROR (Status);
}
//
// Update HOB variable for PCI resource information
// Get the HOB list. If it is not present, then ASSERT.
//
GuidHob.Raw = GetHobList ();
if (GuidHob.Raw != NULL) {
if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
}
}
PrepareSetupInformation();
UpdateAdditionalInformation ();
UpdatePlatformInformation();
UpdateCPUInformation();
IdeDataFilter();
mSetupInfoDone = TRUE;
return;
}
#define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot"
VOID
CheckSystemConfigLoad(SYSTEM_CONFIGURATION *SystemConfigPtr)
{
EFI_STATUS Status;
UINT8 SecureBoot;
UINTN DataSize;
DataSize = sizeof(SecureBoot);
Status = gRT->GetVariable (
EFI_SECURE_BOOT_MODE_NAME,
&gEfiGlobalVariableGuid,
NULL,
&DataSize,
&SecureBoot
);
if (EFI_ERROR(Status)) {
SystemConfigPtr->SecureBoot = 0;
} else {
SystemConfigPtr->SecureBoot = SecureBoot;
}
}
//
// "SecureBootEnable" variable for the Secure boot feature enable/disable.
//
#define EFI_SECURE_BOOT_ENABLE_NAME L"SecureBootEnable"
extern EFI_GUID gEfiSecureBootEnableDisableGuid;
VOID
CheckSystemConfigSave(SYSTEM_CONFIGURATION *SystemConfigPtr)
{
EFI_STATUS Status;
UINT8 SecureBootCfg;
BOOLEAN SecureBootNotFound;
UINTN DataSize;
//
// Secure Boot configuration changes
//
DataSize = sizeof(SecureBootCfg);
SecureBootNotFound = FALSE;
Status = gRT->GetVariable (
EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid,
NULL,
&DataSize,
&SecureBootCfg
);
if (EFI_ERROR(Status)) {
SecureBootNotFound = TRUE;
}
if (SecureBootNotFound) {
Status = gRT->GetVariable (
EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid,
NULL,
&DataSize,
&SecureBootCfg
);
ASSERT_EFI_ERROR(Status);
}
if ((SecureBootCfg) != SystemConfigPtr->SecureBoot) {
SecureBootCfg = !SecureBootCfg;
Status = gRT->SetVariable (
EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (UINT8),
&SecureBootCfg
);
}
}
VOID
ConfirmSecureBootTest()
{
}