**/\r
\r
#include "InternalBdsLib.h"\r
+#include "String.h"\r
\r
BOOLEAN mEnumBootDevice = FALSE;\r
+EFI_HII_HANDLE gBdsLibStringPackHandle = NULL;\r
\r
///\r
/// This GUID is used for an EFI Variable that stores the front device pathes\r
///\r
EFI_GUID mHdBootVariablePrivateGuid = { 0xfab7e9e1, 0x39dd, 0x4f2b, { 0x84, 0x8, 0xe2, 0xe, 0x90, 0x6c, 0xb6, 0xde } };\r
\r
+///\r
+/// This GUID is used for register UNI string.\r
+///\r
+EFI_GUID mBdsLibStringPackGuid = { 0x3b4d9b23, 0x95ac, 0x44f6, { 0x9f, 0xcd, 0xe, 0x95, 0x94, 0x58, 0x6c, 0x72 } };\r
+\r
+///\r
+/// This GUID is used for Set/Get platform language into/from variable at last time enumeration to ensure the enumeration will\r
+/// only execute once.\r
+///\r
+EFI_GUID mBdsLibLastLangGuid = { 0xe8c545b, 0xa2ee, 0x470d, { 0x8e, 0x26, 0xbd, 0xa1, 0xa1, 0x3c, 0xa, 0xa3 } };\r
+\r
+/**\r
+ The constructor function register UNI strings into imageHandle.\r
+ \r
+ It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
+\r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The constructor successfully added string package.\r
+ @retval Other value The constructor can't add string package.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GenericBdsLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+\r
+ gBdsLibStringPackHandle = HiiAddPackages (\r
+ &mBdsLibStringPackGuid,\r
+ &ImageHandle,\r
+ GenericBdsLibStrings,\r
+ NULL\r
+ );\r
+\r
+ ASSERT (gBdsLibStringPackHandle != NULL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
\r
\r
/**\r
}\r
\r
DEBUG_CODE_BEGIN();\r
- UINTN DevicePathTypeValue;\r
- CHAR16 *HiiString;\r
- CHAR16 *BootStringNumber;\r
- UINTN BufferSize;\r
- \r
- DevicePathTypeValue = BdsGetBootTypeFromDevicePath (Option->DevicePath);\r
- \r
- //\r
- // store number string of boot option temporary.\r
- //\r
- HiiString = NULL;\r
- switch (DevicePathTypeValue) {\r
- case BDS_EFI_ACPI_FLOPPY_BOOT:\r
- HiiString = L"EFI Floppy";\r
- break;\r
- case BDS_EFI_MEDIA_CDROM_BOOT:\r
- case BDS_EFI_MESSAGE_SATA_BOOT:\r
- case BDS_EFI_MESSAGE_ATAPI_BOOT:\r
- HiiString = L"EFI DVD/CDROM";\r
- break;\r
- case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:\r
- HiiString = L"EFI USB Device";\r
- break;\r
- case BDS_EFI_MESSAGE_SCSI_BOOT:\r
- HiiString = L"EFI SCSI Device";\r
- break;\r
- case BDS_EFI_MESSAGE_MISC_BOOT:\r
- HiiString = L"EFI Misc Device";\r
- break;\r
- case BDS_EFI_MESSAGE_MAC_BOOT:\r
- HiiString = L"EFI Network";\r
- break;\r
- case BBS_DEVICE_PATH:\r
- //\r
- // Do nothing for legacy boot option.\r
- //\r
- break;\r
- default:\r
- DEBUG((EFI_D_INFO, "Can not find HiiString for given device path type 0x%x\n", DevicePathTypeValue));\r
- }\r
\r
- //\r
- // If found Hii description string then cat Hii string with original description.\r
- //\r
- if (HiiString != NULL) {\r
- BootStringNumber = Option->Description;\r
- BufferSize = StrSize(BootStringNumber);\r
- BufferSize += StrSize(HiiString);\r
- Option->Description = AllocateZeroPool(BufferSize);\r
- ASSERT (Option->Description != NULL);\r
- StrCpy (Option->Description, HiiString);\r
- if (StrnCmp (BootStringNumber, L"0", 1) != 0) {\r
- StrCat (Option->Description, L" ");\r
- StrCat (Option->Description, BootStringNumber);\r
- } \r
- \r
- FreePool (BootStringNumber);\r
+ if (Option->Description == NULL) {\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting from unknown device path\n"));\r
+ } else {\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));\r
}\r
- \r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));\r
- \r
+ \r
DEBUG_CODE_END();\r
\r
Status = gBS->LoadImage (\r
EFI_HANDLE *BlockIoHandles;\r
EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
UINTN Index;\r
- UINTN NumberNetworkHandles;\r
- EFI_HANDLE *NetworkHandles;\r
+ UINTN NumOfLoadFileHandles;\r
+ EFI_HANDLE *LoadFileHandles;\r
UINTN FvHandleCount;\r
EFI_HANDLE *FvHandleBuffer;\r
EFI_FV_FILETYPE Type;\r
UINTN NumberFileSystemHandles;\r
BOOLEAN NeedDelete;\r
EFI_IMAGE_DOS_HEADER DosHeader;\r
+ CHAR8 *PlatLang;\r
+ CHAR8 *LastLang;\r
EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;\r
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
\r
UsbNumber = 0;\r
MiscNumber = 0;\r
ScsiNumber = 0;\r
+ PlatLang = NULL;\r
+ LastLang = NULL;\r
ZeroMem (Buffer, sizeof (Buffer));\r
\r
//\r
// device from the boot order variable\r
//\r
if (mEnumBootDevice) {\r
- Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
- return Status;\r
+ LastLang = GetVariable (L"LastEnumLang", &mBdsLibLastLangGuid);\r
+ PlatLang = GetEfiGlobalVariable (L"PlatformLang");\r
+ if (LastLang == PlatLang) {\r
+ Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
+ return Status;\r
+ } else {\r
+ Status = gRT->SetVariable (\r
+ L"LastEnumLang",\r
+ &mBdsLibLastLangGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ sizeof (PlatLang),\r
+ PlatLang\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
}\r
\r
//\r
\r
switch (DevicePathType) {\r
case BDS_EFI_ACPI_FLOPPY_BOOT:\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", FloppyNumber);\r
+ if (FloppyNumber != 0) {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);\r
+ } else {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));\r
+ }\r
BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
FloppyNumber++;\r
break;\r
//\r
case BDS_EFI_MESSAGE_ATAPI_BOOT:\r
case BDS_EFI_MESSAGE_SATA_BOOT:\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", CdromNumber);\r
+ if (CdromNumber != 0) {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);\r
+ } else {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));\r
+ }\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));\r
BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
CdromNumber++;\r
break;\r
\r
case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", UsbNumber);\r
+ if (UsbNumber != 0) {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);\r
+ } else {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)));\r
+ }\r
BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
UsbNumber++;\r
break;\r
\r
case BDS_EFI_MESSAGE_SCSI_BOOT:\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", ScsiNumber);\r
+ if (ScsiNumber != 0) {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);\r
+ } else {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)));\r
+ }\r
BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
ScsiNumber++;\r
break;\r
\r
case BDS_EFI_MESSAGE_MISC_BOOT:\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", MiscNumber);\r
+ if (MiscNumber != 0) {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);\r
+ } else {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)));\r
+ }\r
BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
MiscNumber++;\r
break;\r
//\r
BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);\r
} else {\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device %d", NonBlockNumber);\r
+ if (NonBlockNumber != 0) {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber);\r
+ } else {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)));\r
+ }\r
BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);\r
NonBlockNumber++;\r
}\r
//\r
// Parse Network Boot Device\r
//\r
- NumberNetworkHandles = 0;\r
+ NumOfLoadFileHandles = 0;\r
//\r
- // Search MNP Service Binding protocol for UEFI network stack\r
+ // Search Load File protocol for PXE boot option.\r
//\r
gBS->LocateHandleBuffer (\r
ByProtocol,\r
- &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ &gEfiLoadFileProtocolGuid,\r
NULL,\r
- &NumberNetworkHandles,\r
- &NetworkHandles\r
+ &NumOfLoadFileHandles,\r
+ &LoadFileHandles\r
);\r
- if (NumberNetworkHandles == 0) {\r
- //\r
- // MNP Service Binding protocol not found, search SNP for EFI network stack\r
- //\r
- gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiSimpleNetworkProtocolGuid,\r
- NULL,\r
- &NumberNetworkHandles,\r
- &NetworkHandles\r
- );\r
- }\r
\r
- for (Index = 0; Index < NumberNetworkHandles; Index++) {\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", Index);\r
- BdsLibBuildOptionFromHandle (NetworkHandles[Index], BdsBootOptionList, Buffer);\r
+ for (Index = 0; Index < NumOfLoadFileHandles; Index++) {\r
+ if (Index != 0) {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)), Index);\r
+ } else {\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)));\r
+ }\r
+ BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList, Buffer);\r
}\r
\r
- if (NumberNetworkHandles != 0) {\r
- FreePool (NetworkHandles);\r
+ if (NumOfLoadFileHandles != 0) {\r
+ FreePool (LoadFileHandles);\r
}\r
\r
//\r
EFI_HANDLE Handle;\r
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
BOOLEAN MediaPresent;\r
+ UINT32 InterruptStatus;\r
\r
MediaPresent = FALSE;\r
\r
UpdatedDevicePath = DevicePath;\r
//\r
- // Locate MNP Service Binding protocol for UEFI network stack first\r
+ // Locate Load File Protocol for PXE boot option first\r
//\r
- Status = gBS->LocateDevicePath (&gEfiManagedNetworkServiceBindingProtocolGuid, &UpdatedDevicePath, &Handle);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // MNP Service Binding protocol not found, search SNP for EFI network stack\r
- //\r
- UpdatedDevicePath = DevicePath;\r
- Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);\r
- }\r
+ Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle);\r
if (EFI_ERROR (Status)) {\r
//\r
// Device not present so see if we need to connect it\r
//\r
// This one should work after we did the connect\r
//\r
- Status = gBS->LocateDevicePath (&gEfiManagedNetworkServiceBindingProtocolGuid, &UpdatedDevicePath, &Handle);\r
- if (EFI_ERROR (Status)) {\r
- UpdatedDevicePath = DevicePath;\r
- Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);\r
- }\r
+ Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle);\r
}\r
}\r
\r
if (!EFI_ERROR (Status)) {\r
if (Snp->Mode->MediaPresentSupported) {\r
if (Snp->Mode->State == EfiSimpleNetworkInitialized) {\r
+ //\r
+ // Invoke Snp->GetStatus() to refresh the media status\r
+ //\r
+ Snp->GetStatus (Snp, &InterruptStatus, NULL);\r
+\r
//\r
// In case some one else is using the SNP check to see if it's connected\r
//\r
\r
case MSG_MAC_ADDR_DP:\r
case MSG_VLAN_DP:\r
+ case MSG_IPv4_DP:\r
+ case MSG_IPv6_DP:\r
BootType = BDS_EFI_MESSAGE_MAC_BOOT;\r
break;\r
\r
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;\r
EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
- EFI_LOAD_FILE_PROTOCOL *LoadFile;\r
\r
TempDevicePath = DevPath;\r
LastDeviceNode = DevPath;\r
\r
//\r
- // Check if it's a valid boot option for network boot device\r
- // Check if there is MNP Service Binding Protocol or SimpleNetworkProtocol\r
- // installed. If yes, that means there is the network card there.\r
+ // Check if it's a valid boot option for network boot device.\r
+ // Check if there is EfiLoadFileProtocol installed. \r
+ // If yes, that means there is a boot option for network.\r
//\r
Status = gBS->LocateDevicePath (\r
- &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ &gEfiLoadFileProtocolGuid,\r
&TempDevicePath,\r
&Handle\r
);\r
- if (EFI_ERROR (Status)) {\r
- TempDevicePath = DevPath;\r
- Status = gBS->LocateDevicePath (\r
- &gEfiSimpleNetworkProtocolGuid,\r
- &TempDevicePath,\r
- &Handle\r
- );\r
- }\r
if (EFI_ERROR (Status)) {\r
//\r
// Device not present so see if we need to connect it\r
TempDevicePath = DevPath;\r
BdsLibConnectDevicePath (TempDevicePath);\r
Status = gBS->LocateDevicePath (\r
- &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ &gEfiLoadFileProtocolGuid,\r
&TempDevicePath,\r
&Handle\r
);\r
- if (EFI_ERROR (Status)) {\r
- TempDevicePath = DevPath;\r
- Status = gBS->LocateDevicePath (\r
- &gEfiSimpleNetworkProtocolGuid,\r
- &TempDevicePath,\r
- &Handle\r
- );\r
- }\r
}\r
\r
if (!EFI_ERROR (Status)) {\r
- //\r
- // Check whether LoadFile protocol is installed\r
- //\r
- Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFile);\r
- if (!EFI_ERROR (Status)) {\r
- if (!IsDevicePathEnd (TempDevicePath)) {\r
- //\r
- // LoadFile protocol is not installed on handle with exactly the same DevPath\r
- //\r
- return FALSE;\r
- }\r
+ if (!IsDevicePathEnd (TempDevicePath)) {\r
+ //\r
+ // LoadFile protocol is not installed on handle with exactly the same DevPath\r
+ //\r
+ return FALSE;\r
+ }\r
\r
- if (CheckMedia) {\r
- //\r
- // Test if it is ready to boot now\r
- //\r
- if (BdsLibNetworkBootWithMediaPresent(DevPath)) {\r
- return TRUE;\r
- }\r
- } else {\r
+ if (CheckMedia) {\r
+ //\r
+ // Test if it is ready to boot now\r
+ //\r
+ if (BdsLibNetworkBootWithMediaPresent(DevPath)) {\r
return TRUE;\r
}\r
- }\r
+ } else {\r
+ return TRUE;\r
+ } \r
}\r
\r
//\r