/** @file\r
- This module produce main entry for BDS phase - BdsEntry. \r
+ This module produce main entry for BDS phase - BdsEntry.\r
When this module was dispatched by DxeCore, gEfiBdsArchProtocolGuid will be installed\r
which contains interface of BdsEntry.\r
After DxeCore finish DXE phase, gEfiBdsArchProtocolGuid->BdsEntry will be invoked\r
to enter BDS phase.\r
\r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
///\r
/// Note: Current BDS not directly get the BootMode, DefaultBoot,\r
/// TimeoutDefault, MemoryTestLevel value from the BDS arch protocol.\r
-/// Please refer to the library useage of BdsLibGetBootMode, BdsLibGetTimeout \r
+/// Please refer to the library useage of BdsLibGetBootMode, BdsLibGetTimeout\r
/// and PlatformBdsDiagnostics in BdsPlatform.c\r
///\r
EFI_HANDLE gBdsHandle = NULL;\r
\r
UINT16 *mBootNext = NULL;\r
\r
-EFI_HANDLE mBdsImageHandle;\r
-\r
/**\r
\r
Install Boot Device Selection Protocol\r
{\r
EFI_STATUS Status;\r
\r
- mBdsImageHandle = ImageHandle;\r
-\r
//\r
// Install protocol interface\r
//\r
//\r
UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);\r
BootOption = BdsLibVariableToOption (&BootLists, Buffer);\r
- \r
+\r
//\r
// If fail to get boot option from variable, just return and do nothing.\r
//\r
if (BootOption == NULL) {\r
return;\r
}\r
- \r
+\r
BootOption->BootCurrent = *mBootNext;\r
}\r
//\r
// Parse the boot order to get boot option\r
//\r
BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
+\r
+ //\r
+ // When we didn't have chance to build boot option variables in the first \r
+ // full configuration boot (e.g.: Reset in the first page or in Device Manager),\r
+ // we have no boot options in the following mini configuration boot.\r
+ // Give the last chance to enumerate the boot options.\r
+ //\r
+ if (IsListEmpty (&BootLists)) {\r
+ BdsLibEnumerateAllBootOption (&BootLists);\r
+ }\r
+\r
Link = BootLists.ForwardLink;\r
\r
//\r
//\r
if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
//\r
- // skip the header of the link list, becuase it has no boot option\r
+ // skip the header of the link list, because it has no boot option\r
//\r
Link = Link->ForwardLink;\r
continue;\r
//\r
BdsLibConnectDevicePath (BootOption->DevicePath);\r
}\r
+\r
+ //\r
+ // Restore to original mode before launching boot option.\r
+ //\r
+ BdsSetConsoleMode (FALSE);\r
+ \r
//\r
// All the driver options should have been processed since\r
// now boot will be performed.\r
//\r
Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);\r
- if (EFI_ERROR (Status)) {\r
+ if (Status != EFI_SUCCESS) {\r
//\r
// Call platform action to indicate the boot fail\r
//\r
//\r
// Call platform action to indicate the boot success\r
//\r
- BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); \r
+ BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));\r
PlatformBdsBootSuccess (BootOption);\r
\r
//\r
PlatformBdsEnterFrontPage (Timeout, FALSE);\r
\r
//\r
- // Rescan the boot option list, avoid pertential risk of the boot\r
+ // Rescan the boot option list, avoid potential risk of the boot\r
// option change in front page\r
//\r
if (BootNextExist) {\r
\r
}\r
\r
+/**\r
+ Validate the device path instance. \r
+\r
+ Only base on the length filed in the device path node to validate the device path. \r
+\r
+ @param DevicePath A pointer to a device path data structure.\r
+ @param MaxSize Max valid device path size. If big than this size, \r
+ return error.\r
+ \r
+ @retval TRUE An valid device path.\r
+ @retval FALSE An invalid device path.\r
+\r
+**/\r
+BOOLEAN\r
+IsValidDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN UINTN MaxSize\r
+ )\r
+{\r
+ UINTN Size;\r
+ UINTN NodeSize;\r
+\r
+ if (DevicePath == NULL) {\r
+ return TRUE;\r
+ }\r
+\r
+ Size = 0;\r
+\r
+ while (!IsDevicePathEnd (DevicePath)) {\r
+ NodeSize = DevicePathNodeLength (DevicePath);\r
+ if (NodeSize < END_DEVICE_PATH_LENGTH) {\r
+ return FALSE;\r
+ }\r
+\r
+ Size += NodeSize;\r
+ if (Size > MaxSize) {\r
+ return FALSE;\r
+ }\r
+\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ }\r
+\r
+ Size += DevicePathNodeLength (DevicePath);\r
+ if (Size > MaxSize) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+\r
+ Validate input console variable data. \r
+\r
+ If found the device path is not a valid device path, remove the variable.\r
+ \r
+ @param VariableName Input console variable name.\r
+\r
+**/\r
+VOID\r
+BdsFormalizeConsoleVariable (\r
+ IN CHAR16 *VariableName\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ UINTN VariableSize;\r
+ EFI_STATUS Status;\r
+\r
+ DevicePath = BdsLibGetVariableAndSize (\r
+ VariableName,\r
+ &gEfiGlobalVariableGuid,\r
+ &VariableSize\r
+ );\r
+ if (!IsValidDevicePath (DevicePath, VariableSize)) { \r
+ Status = gRT->SetVariable (\r
+ VariableName,\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ 0,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+}\r
+\r
+/**\r
+\r
+ Formalize Bds global variables. \r
+\r
+ 1. For ConIn/ConOut/ConErr, if found the device path is not a valid device path, remove the variable.\r
+ 2. For OsIndicationsSupported, Create a BS/RT/UINT64 variable to report caps \r
+ 3. Delete OsIndications variable if it is not NV/BS/RT UINT64\r
+ Item 3 is used to solve case when OS corrupts OsIndications. Here simply delete this NV variable.\r
+ \r
+**/\r
+VOID \r
+BdsFormalizeEfiGlobalVariable (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 OsIndicationSupport;\r
+ UINT64 OsIndication;\r
+ UINTN DataSize;\r
+ UINT32 Attributes;\r
+ \r
+ //\r
+ // Validate Console variable.\r
+ //\r
+ BdsFormalizeConsoleVariable (L"ConIn");\r
+ BdsFormalizeConsoleVariable (L"ConOut");\r
+ BdsFormalizeConsoleVariable (L"ErrOut");\r
+\r
+ //\r
+ // OS indicater support variable\r
+ //\r
+ OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;\r
+ Status = gRT->SetVariable (\r
+ L"OsIndicationsSupported",\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ sizeof(UINT64),\r
+ &OsIndicationSupport\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // If OsIndications is invalid, remove it.\r
+ // Invalid case\r
+ // 1. Data size != UINT64\r
+ // 2. OsIndication value inconsistence\r
+ // 3. OsIndication attribute inconsistence\r
+ //\r
+ OsIndication = 0;\r
+ Attributes = 0;\r
+ DataSize = sizeof(UINT64);\r
+ Status = gRT->GetVariable (\r
+ L"OsIndications",\r
+ &gEfiGlobalVariableGuid,\r
+ &Attributes,\r
+ &DataSize,\r
+ &OsIndication\r
+ );\r
+\r
+ if (!EFI_ERROR(Status)) {\r
+ if (DataSize != sizeof(UINT64) ||\r
+ (OsIndication & ~OsIndicationSupport) != 0 ||\r
+ Attributes != (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE)){\r
+\r
+ DEBUG ((EFI_D_ERROR, "Unformalized OsIndications variable exists. Delete it\n"));\r
+ Status = gRT->SetVariable (\r
+ L"OsIndications",\r
+ &gEfiGlobalVariableGuid,\r
+ Attributes,\r
+ 0,\r
+ &OsIndication\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+}\r
+\r
/**\r
\r
Service routine for BdsInstance->Entry(). Devices are connected, the\r
LIST_ENTRY DriverOptionList;\r
LIST_ENTRY BootOptionList;\r
UINTN BootNextSize;\r
+ CHAR16 *FirmwareVendor;\r
\r
//\r
// Insert the performance probe\r
//\r
- PERF_END (0, "DXE", NULL, 0);\r
- PERF_START (0, "BDS", NULL, 0);\r
+ PERF_END (NULL, "DXE", NULL, 0);\r
+ PERF_START (NULL, "BDS", NULL, 0);\r
\r
//\r
// Initialize the global system boot option and driver option\r
//\r
InitializeHotkeyService ();\r
\r
+ //\r
+ // Fill in FirmwareVendor and FirmwareRevision from PCDs\r
+ //\r
+ FirmwareVendor = (CHAR16 *)PcdGetPtr (PcdFirmwareVendor);\r
+ gST->FirmwareVendor = AllocateRuntimeCopyPool (StrSize (FirmwareVendor), FirmwareVendor);\r
+ ASSERT (gST->FirmwareVendor != NULL);\r
+ gST->FirmwareRevision = PcdGet32 (PcdFirmwareRevision);\r
+\r
+ //\r
+ // Fixup Tasble CRC after we updated Firmware Vendor and Revision\r
+ //\r
+ gBS->CalculateCrc32 ((VOID *)gST, sizeof(EFI_SYSTEM_TABLE), &gST->Hdr.CRC32);\r
+\r
+ //\r
+ // Validate Variable.\r
+ //\r
+ BdsFormalizeEfiGlobalVariable();\r
+\r
//\r
// Do the platform init, can be customized by OEM/IBV\r
//\r
- PERF_START (0, "PlatformBds", "BDS", 0);\r
+ PERF_START (NULL, "PlatformBds", "BDS", 0);\r
PlatformBdsInit ();\r
\r
InitializeHwErrRecSupport();\r
- \r
+\r
//\r
// bugbug: platform specific code\r
// Initialize the platform specific string and language\r
//\r
// Setup some platform policy here\r
//\r
- PlatformBdsPolicyBehavior (&DriverOptionList, &BootOptionList);\r
- PERF_END (0, "PlatformBds", "BDS", 0);\r
+ PlatformBdsPolicyBehavior (&DriverOptionList, &BootOptionList, BdsProcessCapsules, BdsMemoryTest);\r
+ PERF_END (NULL, "PlatformBds", "BDS", 0);\r
\r
//\r
// BDS select the boot device to load OS\r