1136 lines
35 KiB
C
1136 lines
35 KiB
C
/** @file
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2014 - 2022, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include <SetupUtility.h>
|
|
#include <IndustryStandard/Pci.h>
|
|
#include <Protocol/PciIo.h>
|
|
|
|
UINT16 gSaveItemMapping[0xf][2];
|
|
STATIC BOOLEAN mIdeInit = FALSE;
|
|
|
|
EFI_STATUS
|
|
ForCombineMode (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN CHIPSET_CONFIGURATION *SetupVariable
|
|
);
|
|
|
|
EFI_STATUS
|
|
ForOtherMode (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN CHIPSET_CONFIGURATION *SetupVariable
|
|
);
|
|
VOID
|
|
IdeModelNameStrCpy (
|
|
IN CHAR16 *Destination,
|
|
IN CHAR16 *Source,
|
|
IN UINTN Length
|
|
);
|
|
|
|
EFI_STATUS
|
|
SwapIdeConfig (
|
|
IDE_CONFIG *IdeConfig1,
|
|
IDE_CONFIG *IdeConfig2
|
|
);
|
|
|
|
EFI_STATUS
|
|
UpdateTransferMode (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_ATAPI_IDENTIFY_DATA *IdentifyInfo,
|
|
IN EFI_STRING_ID TokenToUpdate,
|
|
IN CHAR8 *LanguageString
|
|
);
|
|
|
|
/**
|
|
|
|
@param [in] HiiHandle
|
|
@param [in] SetupVariable
|
|
@param [in] UpdateIde
|
|
|
|
@retval NONE
|
|
|
|
**/
|
|
EFI_STATUS
|
|
CheckIde (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN CHIPSET_CONFIGURATION *SetupVariable,
|
|
IN BOOLEAN UpdateIde
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 HddCount;
|
|
UINT16 BbsTotalCount;
|
|
BBS_TABLE *LocalBbsTable;
|
|
HDD_INFO *LocalHddInfo;
|
|
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
|
|
BOOLEAN DeviceExist;
|
|
CHAR16 *TokenString;
|
|
CHAR16 *DeviceString;
|
|
EFI_STRING_ID ModelNameToken;
|
|
EFI_STRING_ID TransferModeToken;
|
|
EFI_STRING_ID SecurityModeToken;
|
|
UINT8 Channel;
|
|
UINT8 Device;
|
|
UINT8 *IdeDevice;
|
|
UINTN Index;
|
|
UINTN Index1;
|
|
UINTN Index2;
|
|
UINTN TotalLanguageCount;
|
|
UINTN LanguageCount;
|
|
CHAR8 *LangString;
|
|
CHAR16 *NotInstallString;
|
|
CHAR8 *Lang;
|
|
|
|
EFI_DISK_INFO_PROTOCOL *DiskInfo;
|
|
ATA_IDENTIFY_DATA *IdentifyData;
|
|
UINT32 Size;
|
|
UINT8 SataCnfigure;
|
|
VOID *StartOpCodeHandle;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
EFI_IFR_ACTION *ActionOpCode;
|
|
|
|
SataCnfigure = gSUBrowser->SUCInfo->PrevSataCnfigure;
|
|
DeviceExist = FALSE;
|
|
ModelNameToken = 0;
|
|
TransferModeToken = 0;
|
|
SecurityModeToken = 0;
|
|
Channel = 0;
|
|
Device = 0;
|
|
Index1 = 0;
|
|
Index2 = 0;
|
|
TokenString = NULL;
|
|
DeviceString = NULL;
|
|
HddCount = 0;
|
|
BbsTotalCount = 0;
|
|
LocalBbsTable = NULL;
|
|
LocalHddInfo = NULL;
|
|
LegacyBios = NULL;
|
|
IdentifyData = NULL;
|
|
|
|
if (SetupVariable->BootType != EFI_BOOT_TYPE) {
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiLegacyBiosProtocolGuid,
|
|
NULL,
|
|
(VOID **)&LegacyBios
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = LegacyBios->GetBbsInfo(
|
|
LegacyBios,
|
|
&HddCount,
|
|
&LocalHddInfo,
|
|
&BbsTotalCount,
|
|
&LocalBbsTable
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
GetLangDatabase (&TotalLanguageCount, &LangString);
|
|
for (LanguageCount = 0; LanguageCount < TotalLanguageCount; LanguageCount++) {
|
|
IdeDevice = (UINT8 *) &(mAdvConfig.IdeDevice0);
|
|
Lang = &LangString[LanguageCount * RFC_3066_ENTRY_SIZE];
|
|
if ((AsciiStrnCmp (Lang, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) == 0) ||
|
|
(AsciiStrnCmp (Lang, UEFI_CONFIG_LANG_2, AsciiStrLen (UEFI_CONFIG_LANG_2)) == 0)) {
|
|
continue;
|
|
}
|
|
|
|
for (Index = 0; Index <= 7; Index++) {
|
|
//
|
|
// Get Device Token
|
|
//
|
|
switch (Index + 1) {
|
|
|
|
case 1:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT0_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT0_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT0_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT0_SECURITY_MODE);
|
|
break;
|
|
|
|
case 2:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT1_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT1_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT1_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT1_SECURITY_MODE);
|
|
break;
|
|
|
|
case 3:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT2_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT2_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT2_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT2_SECURITY_MODE);
|
|
break;
|
|
|
|
case 4:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT3_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT3_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT3_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT3_SECURITY_MODE);
|
|
break;
|
|
|
|
case 5:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT4_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT4_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT4_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT4_SECURITY_MODE);
|
|
break;
|
|
|
|
case 6:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT5_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT5_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT5_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT5_SECURITY_MODE);
|
|
break;
|
|
|
|
case 7:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT6_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT6_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT6_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT6_SECURITY_MODE);
|
|
break;
|
|
|
|
case 8:
|
|
TokenString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_SERIAL_ATA_PORT7_MODEL_NAME),
|
|
Lang
|
|
);
|
|
ASSERT (TokenString);
|
|
if (TokenString == NULL) {
|
|
continue;
|
|
}
|
|
ModelNameToken = STRING_TOKEN (STR_SERIAL_ATA_PORT7_STRING);
|
|
TransferModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT7_TRANSFER_MODE);
|
|
SecurityModeToken = STRING_TOKEN (STR_SERIAL_ATA_PORT7_SECURITY_MODE);
|
|
break;
|
|
}
|
|
mIdeConfig[Index].SecurityModeToken = SecurityModeToken;
|
|
|
|
if (mIdeConfig[Index].IdeDevice == 1) {
|
|
DeviceExist = TRUE;
|
|
Channel = mIdeConfig[Index].Channel;
|
|
Device = mIdeConfig[Index].Device;
|
|
DeviceString = CatSPrint(NULL, L"%s%s", TokenString, mIdeConfig[Index].DevNameString);
|
|
if (DeviceString == NULL) {
|
|
continue;
|
|
}
|
|
//[-start-190611-IB16990047-add]//
|
|
if ((mIdeConfig[Index].DiskInfoHandle == NULL) &&
|
|
(SetupVariable->BootType != EFI_BOOT_TYPE)) {
|
|
//[-end-190611-IB16990047-add]//
|
|
IdentifyData = (ATA_IDENTIFY_DATA *) &LocalHddInfo[Channel].IdentifyDrive[Device];
|
|
} else {
|
|
Status = gBS->HandleProtocol (
|
|
mIdeConfig[Index].DiskInfoHandle,
|
|
&gEfiDiskInfoProtocolGuid,
|
|
(VOID**)&DiskInfo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
|
|
Size = sizeof(ATA_IDENTIFY_DATA);
|
|
Status = gBS->AllocatePool (
|
|
EfiBootServicesData,
|
|
Size,
|
|
(VOID **)&IdentifyData
|
|
);
|
|
|
|
Status = DiskInfo->Identify (
|
|
DiskInfo,
|
|
IdentifyData,
|
|
&Size
|
|
);
|
|
}
|
|
|
|
UpdateTransferMode (
|
|
HiiHandle,
|
|
(EFI_ATAPI_IDENTIFY_DATA *) IdentifyData,
|
|
TransferModeToken,
|
|
Lang
|
|
);
|
|
|
|
|
|
*IdeDevice = 1;
|
|
if (mIdeConfig[Index].DiskInfoHandle != NULL) {
|
|
gBS->FreePool (IdentifyData);
|
|
}
|
|
} else {
|
|
Status = CheckSataPort (Index);
|
|
if (EFI_ERROR (Status)) {
|
|
*IdeDevice = 2;
|
|
} else {
|
|
NotInstallString = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
STRING_TOKEN (STR_NOT_INSTALLED_TEXT),
|
|
Lang
|
|
);
|
|
ASSERT (NotInstallString);
|
|
if (NotInstallString != NULL) {
|
|
DeviceString = CatSPrint(NULL, L"%s[%s]", TokenString, NotInstallString);
|
|
if (DeviceString == NULL) {
|
|
continue;
|
|
}
|
|
gBS->FreePool (NotInstallString);
|
|
NotInstallString = NULL;
|
|
} else {
|
|
DeviceString = CatSPrint(NULL, L"%s[]", TokenString);
|
|
}
|
|
gBS->FreePool (TokenString);
|
|
*IdeDevice = 0;
|
|
}
|
|
}
|
|
|
|
IdeDevice++;
|
|
//
|
|
// Update String
|
|
//
|
|
if (DeviceString != NULL) {
|
|
Status = gSUBrowser->HiiString->SetString (
|
|
gSUBrowser->HiiString,
|
|
HiiHandle,
|
|
ModelNameToken,
|
|
Lang,
|
|
DeviceString,
|
|
NULL
|
|
);
|
|
gBS->FreePool (DeviceString);
|
|
DeviceString = NULL;
|
|
}
|
|
}
|
|
}
|
|
if ((SetupVariable->SetUserPass == TRUE) &&
|
|
(SetupVariable->UserAccessLevel == USER_PASSWORD_VIEW_ONLY)) {
|
|
if (DeviceExist == 0) {
|
|
//
|
|
// When no any booting device ,the system will hang.
|
|
// We have create dummy data to updatefrom on last line.
|
|
//
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (StartOpCodeHandle != NULL);
|
|
|
|
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
StartLabel->Number = IDE_UPDATE_LABEL;
|
|
|
|
ActionOpCode = (EFI_IFR_ACTION *) HiiCreateActionOpCode (
|
|
StartOpCodeHandle,
|
|
0,
|
|
STRING_TOKEN(STR_BLANK_STRING),
|
|
0,
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
0
|
|
);
|
|
|
|
Status = HiiUpdateForm (
|
|
HiiHandle,
|
|
NULL,
|
|
0x23,
|
|
StartOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
}
|
|
}
|
|
|
|
gBS->FreePool (LangString);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
UpdateTransferMode (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_ATAPI_IDENTIFY_DATA *IdentifyInfo,
|
|
IN EFI_STRING_ID TokenToUpdate,
|
|
IN CHAR8 *LanguageString
|
|
)
|
|
{
|
|
UINTN Mode, Index;
|
|
EFI_STRING_ID Token;
|
|
CHAR16 *StringPtr;
|
|
|
|
Token = 0;
|
|
Index = 0;
|
|
if (IdentifyInfo->field_validity & 4) {
|
|
Mode = (UINTN)(IdentifyInfo->ultra_dma_select & 0x3F);
|
|
|
|
do {
|
|
Index++;
|
|
Mode = Mode >> 1;
|
|
} while (Mode != 0);
|
|
}
|
|
|
|
switch (Index) {
|
|
|
|
case 0:
|
|
//
|
|
// FPIO
|
|
//
|
|
Token = STRING_TOKEN (STR_IDE_TRANSMODE_FAST_PIO);
|
|
break;
|
|
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
//
|
|
// Ultra DMA 33
|
|
//
|
|
Token = STRING_TOKEN (STR_IDE_ULTRA_DMA_ATA_33);
|
|
break;
|
|
|
|
case 4:
|
|
case 5:
|
|
//
|
|
// Ultra DMA 66
|
|
//
|
|
Token = STRING_TOKEN (STR_IDE_ULTRA_DMA_ATA_66);
|
|
break;
|
|
|
|
case 6:
|
|
//
|
|
// Ultra DMA 100
|
|
//
|
|
Token = STRING_TOKEN (STR_IDE_ULTRA_DMA_ATA_100);
|
|
break;
|
|
}
|
|
|
|
if (Token != 0) {
|
|
StringPtr = GetTokenStringByLanguage (
|
|
HiiHandle,
|
|
Token,
|
|
LanguageString
|
|
);
|
|
ASSERT (StringPtr);
|
|
if (!StringPtr) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
gSUBrowser->HiiString->SetString (
|
|
gSUBrowser->HiiString,
|
|
HiiHandle,
|
|
TokenToUpdate,
|
|
LanguageString,
|
|
StringPtr,
|
|
NULL
|
|
);
|
|
gBS->FreePool (StringPtr);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Copy the Unicode string Source to Destination.
|
|
|
|
@param [in] Destination Location to copy string
|
|
@param [in] Source String to copy
|
|
@param [in] Length
|
|
|
|
@retval NONE
|
|
|
|
**/
|
|
VOID
|
|
IdeModelNameStrCpy (
|
|
IN CHAR16 *Destination,
|
|
IN CHAR16 *Source,
|
|
IN UINTN Length
|
|
)
|
|
{
|
|
*(Destination++) = L'[';
|
|
while (Length) {
|
|
*(Destination++) = *(Source++);
|
|
Length--;
|
|
}
|
|
*(Destination++) = L']';
|
|
*Destination = 0;
|
|
}
|
|
|
|
/**
|
|
To update the list of ide device and status.
|
|
|
|
@param [in] HiiHandle the handle of Advance menu.
|
|
@param [in] Buffer the SYSTEM CONFIGURATION of SetupBrowser.
|
|
|
|
@retval EFI_SUCCESS it is success to update the status of Ide device.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
UpdateHDCConfigure (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN CHIPSET_CONFIGURATION *Buffer
|
|
)
|
|
{
|
|
UINT8 PrevSataCnfigure;
|
|
|
|
//
|
|
// Transfer previous mode to Combine mode
|
|
//
|
|
PrevSataCnfigure = gSUBrowser->SUCInfo->PrevSataCnfigure;
|
|
|
|
|
|
InitIdeConfig (mIdeConfig);
|
|
|
|
//
|
|
// transfer modoe form Combine mode to selected mode
|
|
//
|
|
CheckIde (
|
|
HiiHandle,
|
|
Buffer,
|
|
TRUE
|
|
);
|
|
gSUBrowser->SUCInfo->DoRefresh = TRUE;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
GetIdeDevNameString (
|
|
IN OUT CHAR16 * *DevNameString
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BBS_TABLE *LocalBbsTable;
|
|
HDD_INFO *LocalHddInfo;
|
|
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
|
|
EFI_ATAPI_IDENTIFY_DATA *IdentifyDriveInfo;
|
|
UINT16 HddCount, BbsTotalCount;
|
|
UINTN BbsTableIndex;
|
|
|
|
UINT8 Channel;
|
|
UINT8 Device;
|
|
UINT8 Index;
|
|
CHAR16 *ModelNametring;
|
|
|
|
ModelNametring = NULL;
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiLegacyBiosProtocolGuid,
|
|
NULL,
|
|
(VOID **)&LegacyBios
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = LegacyBios->GetBbsInfo(
|
|
LegacyBios,
|
|
&HddCount,
|
|
&LocalHddInfo,
|
|
&BbsTotalCount,
|
|
&LocalBbsTable
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// IDE Configuration
|
|
//
|
|
Index = 0;
|
|
BbsTableIndex = 1;
|
|
for (Channel=0; Channel<4; Channel++) {
|
|
for (Device=0; Device<2; Device++) {
|
|
//
|
|
// Initial String
|
|
//
|
|
DevNameString[Index] = AllocateZeroPool (0x100);
|
|
if (LocalBbsTable[BbsTableIndex].BootPriority != BBS_IGNORE_ENTRY) {
|
|
ModelNametring = AllocateZeroPool (0x100);
|
|
ASSERT (ModelNametring != NULL);
|
|
if (ModelNametring == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
//
|
|
// Get Device Model name
|
|
//
|
|
IdentifyDriveInfo = (EFI_ATAPI_IDENTIFY_DATA *)&LocalHddInfo[Channel].IdentifyDrive[Device];
|
|
UpdateAtaString(
|
|
IdentifyDriveInfo,
|
|
&ModelNametring
|
|
);
|
|
IdeModelNameStrCpy(
|
|
DevNameString[Index],
|
|
ModelNametring,
|
|
20
|
|
);
|
|
gBS->FreePool (ModelNametring);
|
|
}
|
|
Index++;
|
|
BbsTableIndex++;
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Get PCI location(Bus/Device/Function) from the device path
|
|
|
|
@param[in] SataDevicePath The list of device path.
|
|
@param[out] SataBus Bus number to be derived.
|
|
|
|
@ret PCI_DEVICE_PATH* Matched device path.
|
|
|
|
**/
|
|
PCI_DEVICE_PATH *
|
|
GetPciLocation(
|
|
IN EFI_DEVICE_PATH_PROTOCOL *SataDevicePath,
|
|
OUT UINT8 *SataBus
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *LastPciDevicePath;
|
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
|
UINTN Segment;
|
|
UINTN Bus;
|
|
UINTN Device;
|
|
UINTN Function;
|
|
EFI_HANDLE Handle;
|
|
BOOLEAN SataDevice;
|
|
|
|
//
|
|
// Check supported media type first.
|
|
//
|
|
DevicePath = SataDevicePath;
|
|
LastPciDevicePath = NULL;
|
|
SataDevice = FALSE;
|
|
while (!IsDevicePathEnd (DevicePath)) {
|
|
if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
|
|
((DevicePathSubType (DevicePath) == MSG_ATAPI_DP) ||
|
|
(DevicePathSubType (DevicePath) == MSG_SATA_DP))) {
|
|
SataDevice = TRUE;
|
|
}
|
|
if (DevicePathType (DevicePath) == HARDWARE_DEVICE_PATH && DevicePathSubType (DevicePath) == HW_PCI_DP) {
|
|
LastPciDevicePath = DevicePath;
|
|
}
|
|
DevicePath = NextDevicePathNode(DevicePath);
|
|
}
|
|
if (!SataDevice) {
|
|
return NULL;
|
|
}
|
|
|
|
DevicePath = SataDevicePath;
|
|
Status = gBS->LocateDevicePath (
|
|
&gEfiPciIoProtocolGuid,
|
|
&DevicePath,
|
|
&Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return NULL;
|
|
}
|
|
Status = gBS->HandleProtocol (
|
|
Handle,
|
|
&gEfiPciIoProtocolGuid,
|
|
(VOID **) &PciIo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return NULL;
|
|
}
|
|
Bus = 0;
|
|
Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
|
|
if (EFI_ERROR (Status)) {
|
|
return NULL;
|
|
}
|
|
*SataBus = (UINT8) Bus;
|
|
return (PCI_DEVICE_PATH*) LastPciDevicePath;
|
|
}
|
|
|
|
/**
|
|
According the Bus, Device, Function to check this controller is in Port Number Map table or not.
|
|
If yes, then this is a on board PCI device.
|
|
|
|
@param[in] Bus PCI bus number
|
|
@param[in] Device PCI device number
|
|
@param[in] Function PCI function number
|
|
|
|
@retval TRUE It is onboard device.
|
|
@retval FALSE Not onboard device.
|
|
|
|
**/
|
|
BOOLEAN
|
|
IsOnBoardPciDevice (
|
|
IN UINT32 Bus,
|
|
IN UINT32 Device,
|
|
IN UINT32 Function
|
|
)
|
|
{
|
|
UINTN Index;
|
|
PORT_NUMBER_MAP *PortMappingTable;
|
|
PORT_NUMBER_MAP EndEntry;
|
|
UINTN NoPorts;
|
|
|
|
PortMappingTable = NULL;
|
|
ZeroMem (&EndEntry, sizeof (PORT_NUMBER_MAP));
|
|
|
|
PortMappingTable = (PORT_NUMBER_MAP*) PcdGetPtr (PcdPortNumberMapTable);
|
|
|
|
NoPorts = 0;
|
|
while (CompareMem (&EndEntry, &PortMappingTable[NoPorts], sizeof (PORT_NUMBER_MAP)) != 0) {
|
|
NoPorts++;
|
|
}
|
|
|
|
if (NoPorts == 0) {
|
|
return FALSE;
|
|
}
|
|
for (Index = 0; Index < NoPorts; Index++) {
|
|
if ((PortMappingTable[Index].Bus == Bus) &&
|
|
(PortMappingTable[Index].Device == Device) &&
|
|
(PortMappingTable[Index].Function == Function)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Check Ide device and collect the device information in EFI Boot mode.
|
|
|
|
@param IdeConfig the array of IDE_CONFIG, that record label number, device name, etc....
|
|
|
|
@retval EFI_SUCCESS it is success to check and get device information.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InitIdeConfigInEfiBootType (
|
|
IDE_CONFIG *IdeConfig
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN HandleCount;
|
|
EFI_HANDLE *HandleBuffer;
|
|
EFI_DISK_INFO_PROTOCOL *DiskInfo;
|
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
|
CHIPSET_CONFIGURATION *SetupVariable;
|
|
UINTN Index;
|
|
PCI_DEVICE_PATH *PciDevicePath;
|
|
// ATAPI_DEVICE_PATH *AtapiDevicePath;
|
|
SATA_DEVICE_PATH *SataDevicePath;
|
|
SCSI_DEVICE_PATH *ScsiDevicePath;
|
|
UINTN PortNum;
|
|
ATAPI_IDENTIFY IdentifyDrive;
|
|
UINT32 Size;
|
|
CHAR16 *ModelNametring;
|
|
UINT32 IdeChannel;
|
|
UINT32 IdeDevice;
|
|
UINT16 PortMap;
|
|
UINT16 Port;
|
|
UINT8 SataCnfigure;
|
|
BOOLEAN OnBoardCheck;
|
|
UINT8 Bus;
|
|
NVME_ADMIN_CONTROLLER_DATA NvmeAdminControllerData;
|
|
|
|
SataCnfigure = gSUBrowser->SUCInfo->PrevSataCnfigure;
|
|
PortMap = 0;
|
|
Port = 0;
|
|
|
|
if (IdeConfig == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
SetupVariable = (CHIPSET_CONFIGURATION *)gSUBrowser->SCBuffer;
|
|
if (SetupVariable->BootType != EFI_BOOT_TYPE) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
HandleCount = 0;
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiDiskInfoProtocolGuid,
|
|
NULL,
|
|
&HandleCount,
|
|
&HandleBuffer
|
|
);
|
|
|
|
for (Index = 0; Index < HandleCount; Index++) {
|
|
gBS->HandleProtocol (
|
|
HandleBuffer[Index],
|
|
&gEfiDiskInfoProtocolGuid,
|
|
(VOID**)&DiskInfo
|
|
);
|
|
|
|
//
|
|
// NVME DiskInfo is for Intel RST remapped devices
|
|
//
|
|
if (!(CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid) ||
|
|
CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoAhciInterfaceGuid) ||
|
|
CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoNvmeInterfaceGuid))) {
|
|
continue;
|
|
}
|
|
|
|
Status = gBS->HandleProtocol (
|
|
HandleBuffer[Index],
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID **) &DevicePath
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
|
|
DevicePathNode = DevicePath;
|
|
Status = EFI_NOT_FOUND;
|
|
PortNum = 0;
|
|
|
|
switch (SataCnfigure) {
|
|
case AHCI_MODE:
|
|
case RAID_MODE:
|
|
SataDevicePath = NULL;
|
|
ScsiDevicePath = NULL;
|
|
OnBoardCheck = FALSE;
|
|
while (!IsDevicePathEnd (DevicePathNode)) {
|
|
if (!OnBoardCheck) {
|
|
PciDevicePath = NULL;
|
|
Bus = 0xFF;
|
|
PciDevicePath = GetPciLocation (DevicePath, &Bus);
|
|
if ((PciDevicePath != NULL) &&
|
|
(Bus != 0xFF) &&
|
|
(!IsOnBoardPciDevice (Bus, PciDevicePath->Device, PciDevicePath->Function))) {
|
|
break;
|
|
}
|
|
OnBoardCheck = TRUE;
|
|
}
|
|
if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH ) && (DevicePathSubType (DevicePathNode) == MSG_SATA_DP)) {
|
|
SataDevicePath = (SATA_DEVICE_PATH *) DevicePathNode;
|
|
PortNum = SataDevicePath->HBAPortNumber;
|
|
if (SataCnfigure == RAID_MODE) {
|
|
if (SataDevicePath->PortMultiplierPortNumber & SATA_HBA_DIRECT_CONNECT_FLAG) {
|
|
PortMap = (UINT16) PortNum;
|
|
for (Port = 0; PortMap != 0; Port++, PortMap >>= 1);
|
|
Port--;
|
|
PortNum = Port;
|
|
}
|
|
}
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH ) && (DevicePathSubType (DevicePathNode) == MSG_SCSI_DP)) {
|
|
ScsiDevicePath = (SCSI_DEVICE_PATH *) DevicePathNode;
|
|
PortNum = ScsiDevicePath->Pun;
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
DevicePathNode = NextDevicePathNode (DevicePathNode);
|
|
}
|
|
default:
|
|
ASSERT (FALSE);
|
|
break;
|
|
}
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = DiskInfo->WhichIde (DiskInfo, &IdeChannel, &IdeDevice);
|
|
if (!EFI_ERROR (Status)) {
|
|
//[-start-211007-IB05660180-add]//
|
|
PciDevicePath = GetPciLocation (DevicePath, &Bus);
|
|
//[-end-211007-IB05660180-add]//
|
|
//[-start-220110-IB16810181-modify]//
|
|
if (PciDevicePath != NULL) {
|
|
if ((PciDevicePath->Device == 0xE) && (PciDevicePath->Function == 0x0)){
|
|
PortNum = IdeChannel;
|
|
}
|
|
}
|
|
//[-end-220110-IB16810181-modify]//
|
|
Size = sizeof (ATAPI_IDENTIFY);
|
|
Status = DiskInfo->Identify (
|
|
DiskInfo,
|
|
&IdentifyDrive,
|
|
&Size
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
IdeConfig[PortNum].DevNameString = AllocateZeroPool (0x100);
|
|
ModelNametring = AllocateZeroPool (0x100);
|
|
ASSERT (ModelNametring != NULL);
|
|
if (ModelNametring == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
UpdateAtaString (
|
|
(EFI_ATAPI_IDENTIFY_DATA *) &IdentifyDrive,
|
|
&ModelNametring
|
|
);
|
|
IdeModelNameStrCpy(
|
|
IdeConfig[PortNum].DevNameString,
|
|
ModelNametring,
|
|
20
|
|
);
|
|
IdeConfig[PortNum].IdeDevice = 1;
|
|
IdeConfig[PortNum].DiskInfoHandle = HandleBuffer[Index];
|
|
gBS->FreePool (ModelNametring);
|
|
}
|
|
} else if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoNvmeInterfaceGuid)) {
|
|
Size = sizeof (NVME_ADMIN_CONTROLLER_DATA);
|
|
Status = DiskInfo->Inquiry (
|
|
DiskInfo,
|
|
&NvmeAdminControllerData,
|
|
&Size
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
IdeConfig[PortNum].DevNameString = AllocateZeroPool (0x100);
|
|
ModelNametring = AllocateZeroPool (0x100);
|
|
ASSERT (ModelNametring != NULL);
|
|
if (ModelNametring == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
AsciiToUnicode (
|
|
NvmeAdminControllerData.Mn,
|
|
ModelNametring
|
|
);
|
|
IdeModelNameStrCpy(
|
|
IdeConfig[PortNum].DevNameString,
|
|
ModelNametring,
|
|
20
|
|
);
|
|
IdeConfig[PortNum].IdeDevice = 1;
|
|
IdeConfig[PortNum].DiskInfoHandle = HandleBuffer[Index];
|
|
gBS->FreePool (ModelNametring);
|
|
}
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "No DevicePathType match MESSAGING_DEVICE_PATH\n"));
|
|
DEBUG ((DEBUG_INFO, "or without any DevicePathSubType match MSG_SATA_DP or MSG_SCSI_DP\n"));
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
/**
|
|
to check Ide device and collect the device information.
|
|
|
|
@param IdeConfig the array of IDE_CONFIG, that record label number, device name, etc....
|
|
|
|
@retval EFI_SUCCESS it is success to check and get device information.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InitIdeConfig (
|
|
IDE_CONFIG *IdeConfig
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BBS_TABLE *LocalBbsTable;
|
|
HDD_INFO *LocalHddInfo;
|
|
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
|
|
UINT16 HddCount, BbsTotalCount;
|
|
UINTN BbsTableIndex;
|
|
|
|
UINT8 Channel;
|
|
UINT8 Device;
|
|
UINT8 Index;
|
|
CHAR16 *ModelNametring;
|
|
CHIPSET_CONFIGURATION *SetupVariable;
|
|
UINTN PortNum;
|
|
EFI_ATAPI_IDENTIFY_DATA *IdentifyTable;
|
|
UINT8 SataCnfigure;
|
|
|
|
SataCnfigure = gSUBrowser->SUCInfo->PrevSataCnfigure;
|
|
if (mIdeInit && gSUBrowser->IdeConfig != NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
SetupVariable = (CHIPSET_CONFIGURATION *)gSUBrowser->SCBuffer;
|
|
if (SetupVariable->BootType == EFI_BOOT_TYPE) {
|
|
Status = InitIdeConfigInEfiBootType (IdeConfig);
|
|
if (!EFI_ERROR (Status)) {
|
|
mIdeInit = TRUE;
|
|
}
|
|
return Status;
|
|
} else {
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiLegacyBiosProtocolGuid,
|
|
NULL,
|
|
(VOID **)&LegacyBios
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = LegacyBios->GetBbsInfo(
|
|
LegacyBios,
|
|
&HddCount,
|
|
&LocalHddInfo,
|
|
&BbsTotalCount,
|
|
&LocalBbsTable
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Index = 0;
|
|
BbsTableIndex = 1;
|
|
ModelNametring = AllocateZeroPool (0x100);
|
|
ASSERT (ModelNametring != NULL);
|
|
if (ModelNametring == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
for (Channel=0; Channel<4; Channel++) {
|
|
for (Device=0; Device<2; Device++) {
|
|
IdentifyTable = (EFI_ATAPI_IDENTIFY_DATA *) &LocalHddInfo[Channel].IdentifyDrive[Device];
|
|
if (IdentifyTable->ModelName[0] != 0) {
|
|
if (((SataCnfigure == AHCI_MODE) && (SetupVariable->AhciOptionRomSupport == 0))) {
|
|
if (!IsOnBoardPciDevice (LocalBbsTable[BbsTableIndex].Bus,
|
|
LocalBbsTable[BbsTableIndex].Device,
|
|
LocalBbsTable[BbsTableIndex].Function)) {
|
|
continue;
|
|
}
|
|
Status = SearchMatchedPortNum (
|
|
LocalBbsTable[BbsTableIndex].Bus,
|
|
LocalBbsTable[BbsTableIndex].Device,
|
|
LocalBbsTable[BbsTableIndex].Function,
|
|
Channel % 2,
|
|
Device,
|
|
&PortNum
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
BbsTableIndex++;
|
|
continue;
|
|
}
|
|
if (IdeConfig[PortNum].DevNameString != NULL) {
|
|
gBS->FreePool (IdeConfig[PortNum].DevNameString);
|
|
IdeConfig[PortNum].DevNameString = NULL;
|
|
}
|
|
IdeConfig[PortNum].DevNameString = AllocateZeroPool (0x100);
|
|
IdeConfig[PortNum].IdeDevice = 1;
|
|
IdeConfig[PortNum].Device = Device;
|
|
IdeConfig[PortNum].Channel = Channel;
|
|
UpdateAtaString(
|
|
(EFI_ATAPI_IDENTIFY_DATA *) &LocalHddInfo[Channel].IdentifyDrive[Device],
|
|
&ModelNametring
|
|
);
|
|
IdeModelNameStrCpy(
|
|
IdeConfig[PortNum].DevNameString,
|
|
ModelNametring,
|
|
20
|
|
);
|
|
} else {
|
|
if (IdeConfig[Index].DevNameString != NULL) {
|
|
gBS->FreePool (IdeConfig[Index].DevNameString);
|
|
IdeConfig[Index].DevNameString = NULL;
|
|
}
|
|
IdeConfig[Index].DevNameString = AllocateZeroPool (0x100);
|
|
IdeConfig[Index].IdeDevice = 1;
|
|
IdeConfig[Index].Device = Device;
|
|
IdeConfig[Index].Channel = Channel;
|
|
UpdateAtaString(
|
|
(EFI_ATAPI_IDENTIFY_DATA *) &LocalHddInfo[Channel].IdentifyDrive[Device],
|
|
&ModelNametring
|
|
);
|
|
IdeModelNameStrCpy(
|
|
IdeConfig[Index].DevNameString,
|
|
ModelNametring,
|
|
20
|
|
);
|
|
}
|
|
}
|
|
|
|
Index++;
|
|
BbsTableIndex++;
|
|
}
|
|
}
|
|
gBS->FreePool (ModelNametring);
|
|
mIdeInit = TRUE;
|
|
}
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
SwapIdeConfig (
|
|
IDE_CONFIG *IdeConfig1,
|
|
IDE_CONFIG *IdeConfig2
|
|
)
|
|
{
|
|
UINT8 *Temp;
|
|
|
|
Temp = AllocateZeroPool (sizeof(IDE_CONFIG));
|
|
if (Temp == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
CopyMem (
|
|
Temp,
|
|
IdeConfig1,
|
|
sizeof (IDE_CONFIG)
|
|
);
|
|
CopyMem (
|
|
IdeConfig1,
|
|
IdeConfig2,
|
|
sizeof (IDE_CONFIG)
|
|
);
|
|
|
|
CopyMem (
|
|
IdeConfig2,
|
|
Temp,
|
|
sizeof (IDE_CONFIG)
|
|
);
|
|
|
|
gBS->FreePool (Temp);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|