EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME\r
};\r
\r
+CHAR16 *mBdsLoadOptionName[] = {\r
+ L"Driver",\r
+ L"SysPrep",\r
+ L"Boot"\r
+};\r
+\r
CHAR16 mRecoveryBoot[] = L"Recovery Boot";\r
/**\r
Event to Connect ConIn.\r
// Should not enter this case, if enter, the keyboard will not work.\r
// May need platfrom policy to connect keyboard.\r
//\r
- DEBUG ((EFI_D_WARN, "[Bds] ASSERT Connect ConIn failed!!!\n"));\r
+ DEBUG ((EFI_D_WARN, "[Bds] Connect ConIn failed - %r!!!\n", Status));\r
}\r
}\r
\r
}\r
\r
/**\r
- The function will go through the driver option link list, load and start\r
- every driver the driver option device path point to.\r
+ The function will load and start every Driver####/SysPrep####.\r
\r
- @param DriverOption Input driver option array.\r
- @param DriverOptionCount Input driver option count.\r
+ @param LoadOptions Load option array.\r
+ @param LoadOptionCount Load option count.\r
\r
**/\r
VOID\r
-LoadDrivers (\r
- IN EFI_BOOT_MANAGER_LOAD_OPTION *DriverOption,\r
- IN UINTN DriverOptionCount\r
+ProcessLoadOptions (\r
+ IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions,\r
+ IN UINTN LoadOptionCount\r
)\r
{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- EFI_HANDLE ImageHandle;\r
- EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;\r
- BOOLEAN ReconnectAll;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ BOOLEAN ReconnectAll;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;\r
\r
ReconnectAll = FALSE;\r
+ LoadOptionType = LoadOptionTypeMax;\r
\r
//\r
// Process the driver option\r
//\r
- for (Index = 0; Index < DriverOptionCount; Index++) {\r
+ for (Index = 0; Index < LoadOptionCount; Index++) {\r
//\r
- // If a load option is not marked as LOAD_OPTION_ACTIVE,\r
- // the boot manager will not automatically load the option.\r
+ // All the load options in the array should be of the same type.\r
//\r
- if ((DriverOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0) {\r
- continue;\r
- }\r
- \r
- //\r
- // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,\r
- // then all of the EFI drivers in the system will be disconnected and\r
- // reconnected after the last driver load option is processed.\r
- //\r
- if ((DriverOption[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0) {\r
- ReconnectAll = TRUE;\r
+ if (LoadOptionType == LoadOptionTypeMax) {\r
+ LoadOptionType = LoadOptions[Index].OptionType;\r
}\r
- \r
- //\r
- // Make sure the driver path is connected.\r
- //\r
- EfiBootManagerConnectDevicePath (DriverOption[Index].FilePath, NULL);\r
+ ASSERT (LoadOptionType == LoadOptions[Index].OptionType);\r
+ ASSERT (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep);\r
\r
- //\r
- // Load and start the image that Driver#### describes\r
- //\r
- Status = gBS->LoadImage (\r
- FALSE,\r
- gImageHandle,\r
- DriverOption[Index].FilePath,\r
- NULL,\r
- 0,\r
- &ImageHandle\r
- );\r
+ Status = EfiBootManagerProcessLoadOption (&LoadOptions[Index]);\r
\r
- if (!EFI_ERROR (Status)) {\r
- gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);\r
-\r
- //\r
- // Verify whether this image is a driver, if not,\r
- // exit it and continue to parse next load option\r
- //\r
- if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {\r
- gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);\r
- continue;\r
- }\r
-\r
- ImageInfo->LoadOptionsSize = DriverOption[Index].OptionalDataSize;\r
- ImageInfo->LoadOptions = DriverOption[Index].OptionalData;\r
- //\r
- // Before calling the image, enable the Watchdog Timer for\r
- // the 5 Minute period\r
- //\r
- gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
-\r
- DriverOption[Index].Status = gBS->StartImage (ImageHandle, &DriverOption[Index].ExitDataSize, &DriverOption[Index].ExitData);\r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", DriverOption[Index].Status));\r
-\r
- //\r
- // Clear the Watchdog Timer after the image returns\r
- //\r
- gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
+ if (!EFI_ERROR (Status) && ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0)) {\r
+ ReconnectAll = TRUE;\r
}\r
}\r
- \r
+\r
//\r
- // Process the LOAD_OPTION_FORCE_RECONNECT driver option\r
+ // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,\r
+ // then all of the EFI drivers in the system will be disconnected and\r
+ // reconnected after the last driver load option is processed.\r
//\r
- if (ReconnectAll) {\r
+ if (ReconnectAll && LoadOptionType == LoadOptionTypeDriver) {\r
EfiBootManagerDisconnectAll ();\r
EfiBootManagerConnectAll ();\r
}\r
-\r
}\r
\r
/**\r
IN EFI_BDS_ARCH_PROTOCOL *This\r
)\r
{\r
- EFI_BOOT_MANAGER_LOAD_OPTION *DriverOption;\r
- EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
- UINTN DriverOptionCount;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions;\r
+ UINTN LoadOptionCount;\r
CHAR16 *FirmwareVendor;\r
EFI_EVENT HotkeyTriggered;\r
UINT64 OsIndication;\r
UINT16 BootTimeOut;\r
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
UINTN Index;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
UINT16 *BootNext;\r
CHAR16 BootNextVariableName[sizeof ("Boot####")];\r
+ EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;\r
+ BOOLEAN BootFwUi;\r
\r
HotkeyTriggered = NULL;\r
Status = EFI_SUCCESS;\r
// Initialize L"BootOptionSupport" EFI global variable.\r
// Lazy-ConIn implictly disables BDS hotkey.\r
//\r
- BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP;\r
+ BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP | EFI_BOOT_OPTION_SUPPORT_SYSPREP;\r
if (!PcdGetBool (PcdConInConnectOnDemand)) {\r
BootOptionSupport |= EFI_BOOT_OPTION_SUPPORT_KEY;\r
SET_BOOT_OPTION_SUPPORT_KEY_COUNT (BootOptionSupport, 3);\r
EfiBootManagerStartHotkeyService (&HotkeyTriggered);\r
\r
//\r
- // Load Driver Options\r
+ // Execute Driver Options\r
//\r
- DriverOption = EfiBootManagerGetLoadOptions (&DriverOptionCount, LoadOptionTypeDriver);\r
- LoadDrivers (DriverOption, DriverOptionCount);\r
- EfiBootManagerFreeLoadOptions (DriverOption, DriverOptionCount);\r
+ LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeDriver);\r
+ ProcessLoadOptions (LoadOptions, LoadOptionCount);\r
+ EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);\r
\r
//\r
// Connect consoles\r
PERF_END (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);\r
\r
DEBUG_CODE (\r
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
- UINTN BootOptionCount;\r
- UINTN Index;\r
-\r
- BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
- DEBUG ((EFI_D_INFO, "[Bds]=============Dumping Boot Options=============\n"));\r
- for (Index = 0; Index < BootOptionCount; Index++) {\r
+ UINTN Index;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;\r
+ DEBUG ((EFI_D_INFO, "[Bds]=============Begin Load Options Dumping ...=============\n"));\r
+ for (LoadOptionType = 0; LoadOptionType < LoadOptionTypeMax; LoadOptionType++) {\r
DEBUG ((\r
- EFI_D_INFO, "[Bds]Boot%04x: %s \t\t 0x%04x\n",\r
- BootOptions[Index].OptionNumber, \r
- BootOptions[Index].Description, \r
- BootOptions[Index].Attributes\r
+ EFI_D_INFO, " %s Options:\n",\r
+ mBdsLoadOptionName[LoadOptionType]\r
));\r
+ LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionType);\r
+ for (Index = 0; Index < LoadOptionCount; Index++) {\r
+ DEBUG ((\r
+ EFI_D_INFO, " %s%04x: %s \t\t 0x%04x\n",\r
+ mBdsLoadOptionName[LoadOptionType],\r
+ LoadOptions[Index].OptionNumber,\r
+ LoadOptions[Index].Description,\r
+ LoadOptions[Index].Attributes\r
+ ));\r
+ }\r
+ EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);\r
}\r
- DEBUG ((EFI_D_INFO, "[Bds]=============Dumping Boot Options Finished====\n"));\r
- EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
- );\r
+ DEBUG ((EFI_D_INFO, "[Bds]=============End Load Options Dumping=============\n"));\r
+ );\r
\r
//\r
// Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot\r
&DataSize,\r
&OsIndication\r
);\r
- if (!EFI_ERROR(Status) && ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0)) {\r
- //\r
- // Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS\r
- // \r
+ if (EFI_ERROR (Status)) {\r
+ OsIndication = 0;\r
+ }\r
+\r
+ BootFwUi = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);\r
+ //\r
+ // Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS\r
+ // \r
+ if (BootFwUi) {\r
OsIndication &= ~((UINT64) EFI_OS_INDICATIONS_BOOT_TO_FW_UI);\r
Status = gRT->SetVariable (\r
L"OsIndications",\r
// Changing the content without increasing its size with current variable implementation shouldn't fail.\r
//\r
ASSERT_EFI_ERROR (Status);\r
+ }\r
\r
+ //\r
+ // Launch Boot Manager Menu directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot\r
+ //\r
+ if (BootFwUi) {\r
//\r
// Follow generic rule, Call BdsDxeOnConnectConInCallBack to connect ConIn before enter UI\r
//\r
}\r
\r
//\r
- // Directly boot to Boot Manager Menu.\r
+ // Directly enter the setup page.\r
+ // BootManagerMenu always contains the correct information even call fails.\r
//\r
- EfiBootManagerGetBootManagerMenu (&BootOption);\r
- EfiBootManagerBoot (&BootOption);\r
- EfiBootManagerFreeLoadOption (&BootOption);\r
- } else {\r
- PERF_START (NULL, "BdsWait", "BDS", 0);\r
- BdsWait (HotkeyTriggered);\r
- PERF_END (NULL, "BdsWait", "BDS", 0);\r
-\r
- //\r
- // BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.\r
- //\r
- BdsReadKeys ();\r
- \r
- EfiBootManagerHotkeyBoot ();\r
+ EfiBootManagerGetBootManagerMenu (&BootManagerMenu);\r
+ EfiBootManagerBoot (&BootManagerMenu);\r
+ EfiBootManagerFreeLoadOption (&BootManagerMenu);\r
}\r
\r
+ //\r
+ // Execute SysPrep####\r
+ //\r
+ LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeSysPrep);\r
+ ProcessLoadOptions (LoadOptions, LoadOptionCount);\r
+ EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);\r
+\r
+ //\r
+ // Execute Key####\r
+ //\r
+ PERF_START (NULL, "BdsWait", "BDS", 0);\r
+ BdsWait (HotkeyTriggered);\r
+ PERF_END (NULL, "BdsWait", "BDS", 0);\r
+\r
+ //\r
+ // BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.\r
+ //\r
+ BdsReadKeys ();\r
+\r
+ EfiBootManagerHotkeyBoot ();\r
+\r
//\r
// Boot to "BootNext"\r
//\r