+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- BdsEntry.c\r
-\r
-Abstract:\r
-\r
- The entry of the bds\r
-\r
---*/\r
-\r
-#include "Bds.h"\r
-#include "BdsPlatform.h"\r
-#include "FrontPage.h"\r
-\r
-EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate = {\r
- EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE,\r
- NULL,\r
- BdsEntry,\r
- 0xFFFF,\r
- TRUE,\r
- EXTENSIVE\r
-};\r
-\r
-UINT16 *mBootNext = NULL;\r
-\r
-EFI_HANDLE mBdsImageHandle;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BdsInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Install Boot Device Selection Protocol\r
-\r
-Arguments:\r
- \r
- (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
-\r
-Returns:\r
-\r
- EFI_SUCEESS - BDS has finished initializing.\r
- Rerun the \r
- dispatcher and recall BDS.Entry\r
-\r
- Other - Return value from EfiLibAllocatePool()\r
- or gBS->InstallProtocolInterface\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- mBdsImageHandle = ImageHandle;\r
-\r
- //\r
- // Install protocol interface\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &gBdsInstanceTemplate.Handle,\r
- &gEfiBdsArchProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &gBdsInstanceTemplate.Bds\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-VOID\r
-BdsBootDeviceSelect (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- In the loop of attempt to boot for the boot order\r
-\r
-Arguments:\r
- \r
- None.\r
-\r
-Returns:\r
-\r
- None.\r
- \r
---*/\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- BDS_COMMON_OPTION *BootOption;\r
- UINTN ExitDataSize;\r
- CHAR16 *ExitData;\r
- UINT16 Timeout;\r
- LIST_ENTRY BootLists;\r
- CHAR16 Buffer[20];\r
- BOOLEAN BootNextExist;\r
- LIST_ENTRY *LinkBootNext;\r
-\r
- //\r
- // Got the latest boot option\r
- //\r
- BootNextExist = FALSE;\r
- LinkBootNext = NULL;\r
- InitializeListHead (&BootLists);\r
-\r
- //\r
- // First check the boot next option\r
- //\r
- ZeroMem (Buffer, sizeof (Buffer));\r
-\r
- if (mBootNext != NULL) {\r
- //\r
- // Indicate we have the boot next variable, so this time\r
- // boot will always have this boot option\r
- //\r
- BootNextExist = TRUE;\r
-\r
- //\r
- // Clear the this variable so it's only exist in this time boot\r
- //\r
- gRT->SetVariable (\r
- L"BootNext",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- 0,\r
- mBootNext\r
- );\r
-\r
- //\r
- // Add the boot next boot option\r
- //\r
- UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);\r
- BootOption = BdsLibVariableToOption (&BootLists, Buffer);\r
- }\r
- //\r
- // Parse the boot order to get boot option\r
- //\r
- BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
- Link = BootLists.ForwardLink;\r
-\r
- //\r
- // Parameter check, make sure the loop will be valid\r
- //\r
- if (Link == NULL) {\r
- return ;\r
- }\r
- //\r
- // Here we make the boot in a loop, every boot success will\r
- // return to the front page\r
- //\r
- for (;;) {\r
- //\r
- // Check the boot option list first\r
- //\r
- if (Link == &BootLists) {\r
- //\r
- // There are two ways to enter here:\r
- // 1. There is no active boot option, give user chance to\r
- // add new boot option\r
- // 2. All the active boot option processed, and there is no\r
- // one is success to boot, then we back here to allow user\r
- // add new active boot option\r
- //\r
- Timeout = 0xffff;\r
- PlatformBdsEnterFrontPage (Timeout, FALSE);\r
- InitializeListHead (&BootLists);\r
- BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
- Link = BootLists.ForwardLink;\r
- continue;\r
- }\r
- //\r
- // Get the boot option from the link list\r
- //\r
- BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
-\r
- //\r
- // According to EFI Specification, if a load option is not marked\r
- // as LOAD_OPTION_ACTIVE, the boot manager will not automatically\r
- // load the option.\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
- //\r
- Link = Link->ForwardLink;\r
- continue;\r
- }\r
- //\r
- // Make sure the boot option device path connected,\r
- // but ignore the BBS device path\r
- //\r
- if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
- //\r
- // Notes: the internal shell can not been connected with device path\r
- // so we do not check the status here\r
- //\r
- BdsLibConnectDevicePath (BootOption->DevicePath);\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
- //\r
- // Call platform action to indicate the boot fail\r
- //\r
- PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);\r
-\r
- //\r
- // Check the next boot option\r
- //\r
- Link = Link->ForwardLink;\r
-\r
- } else {\r
- //\r
- // Call platform action to indicate the boot success\r
- //\r
- PlatformBdsBootSuccess (BootOption);\r
-\r
- //\r
- // Boot success, then stop process the boot order, and\r
- // present the boot manager menu, front page\r
- //\r
- Timeout = 0xffff;\r
- PlatformBdsEnterFrontPage (Timeout, FALSE);\r
-\r
- //\r
- // Rescan the boot option list, avoid pertential risk of the boot\r
- // option change in front page\r
- //\r
- if (BootNextExist) {\r
- LinkBootNext = BootLists.ForwardLink;\r
- }\r
-\r
- InitializeListHead (&BootLists);\r
- if (LinkBootNext != NULL) {\r
- //\r
- // Reserve the boot next option\r
- //\r
- InsertTailList (&BootLists, LinkBootNext);\r
- }\r
-\r
- BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
- Link = BootLists.ForwardLink;\r
- }\r
- }\r
-\r
- return ;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BdsEntry (\r
- IN EFI_BDS_ARCH_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Service routine for BdsInstance->Entry(). Devices are connected, the \r
- consoles are initialized, and the boot options are tried. \r
-\r
-Arguments:\r
-\r
- This - Protocol Instance structure.\r
-\r
-Returns:\r
-\r
- EFI_SUCEESS - BDS->Entry has finished executing. \r
- \r
---*/\r
-{\r
- EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;\r
- LIST_ENTRY DriverOptionList;\r
- LIST_ENTRY BootOptionList;\r
- UINTN BootNextSize;\r
-\r
- //\r
- // Insert the performance probe\r
- //\r
- PERF_END (0, DXE_TOK, NULL, 0);\r
- PERF_START (0, BDS_TOK, NULL, 0);\r
-\r
- //\r
- // Initialize the global system boot option and driver option\r
- //\r
- InitializeListHead (&DriverOptionList);\r
- InitializeListHead (&BootOptionList);\r
-\r
- //\r
- // Get the BDS private data\r
- //\r
- PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);\r
-\r
- //\r
- // Do the platform init, can be customized by OEM/IBV\r
- //\r
- PERF_START (0, "PlatformBds", "BDS", 0);\r
- PlatformBdsInit (PrivateData);\r
-\r
- //\r
- // Set up the device list based on EFI 1.1 variables\r
- // process Driver#### and Load the driver's in the\r
- // driver option list\r
- //\r
- BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");\r
- if (!IsListEmpty (&DriverOptionList)) {\r
- BdsLibLoadDrivers (&DriverOptionList);\r
- }\r
- //\r
- // Check if we have the boot next option\r
- //\r
- mBootNext = BdsLibGetVariableAndSize (\r
- L"BootNext",\r
- &gEfiGlobalVariableGuid,\r
- &BootNextSize\r
- );\r
-\r
- //\r
- // Setup some platform policy here\r
- //\r
- PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);\r
- PERF_END (0, "PlatformBds", "BDS", 0);\r
-\r
- //\r
- // BDS select the boot device to load OS\r
- //\r
- BdsBootDeviceSelect ();\r
-\r
- //\r
- // Only assert here since this is the right behavior, we should never\r
- // return back to DxeCore.\r
- //\r
- ASSERT (FALSE);\r
-\r
- return EFI_SUCCESS;\r
-}\r