+++ /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
- BootManager.c\r
-\r
-Abstract:\r
-\r
- The platform boot manager reference implement\r
-\r
---*/\r
-#include "BootManager.h"\r
-\r
-UINT16 mKeyInput;\r
-LIST_ENTRY *mBootOptionsList;\r
-BDS_COMMON_OPTION *gOption;\r
-EFI_HII_HANDLE gBootManagerHandle;\r
-EFI_HANDLE BootManagerCallbackHandle;\r
-EFI_FORM_CALLBACK_PROTOCOL BootManagerCallback;\r
-EFI_GUID gBmGuid = BOOT_MANAGER_GUID;\r
-\r
-extern EFI_FORM_BROWSER_PROTOCOL *gBrowser;\r
-extern UINT8 BootManagerVfrBin[];\r
-extern UINT8 EdkGenericPlatformBdsLibStrings[];\r
-extern BOOLEAN gConnectAllHappened;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BootManagerCallbackRoutine (\r
- IN EFI_FORM_CALLBACK_PROTOCOL *This,\r
- IN UINT16 KeyValue,\r
- IN EFI_IFR_DATA_ARRAY *DataArray,\r
- OUT EFI_HII_CALLBACK_PACKET **Packet\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This is the function that is called to provide results data to the driver. This data\r
- consists of a unique key which is used to identify what data is either being passed back\r
- or being asked for. \r
-\r
-Arguments:\r
-\r
- KeyValue - A unique value which is sent to the original exporting driver so that it\r
- can identify the type of data to expect. The format of the data tends to\r
- vary based on the op-code that geerated the callback.\r
-\r
- Data - A pointer to the data being sent to the original exporting driver.\r
-\r
-Returns: \r
-\r
---*/\r
-{\r
- BDS_COMMON_OPTION *Option;\r
- LIST_ENTRY *Link;\r
- UINT16 KeyCount;\r
- EFI_HII_CALLBACK_PACKET *DataPacket;\r
-\r
- //\r
- // Initialize the key count\r
- //\r
- KeyCount = 0;\r
-\r
- for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {\r
- Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
-\r
- KeyCount++;\r
-\r
- gOption = Option;\r
-\r
- //\r
- // Is this device the one chosen?\r
- //\r
- if (KeyCount == KeyValue) {\r
- //\r
- // Assigning the returned Key to a global allows the original routine to know what was chosen\r
- //\r
- mKeyInput = KeyValue;\r
-\r
- *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);\r
- ASSERT (*Packet != NULL);\r
-\r
- //\r
- // Assign the buffer address to DataPacket\r
- //\r
- DataPacket = *Packet;\r
-\r
- DataPacket->DataArray.EntryCount = 1;\r
- DataPacket->DataArray.NvRamMap = NULL;\r
- ((EFI_IFR_DATA_ENTRY *) (((EFI_IFR_DATA_ARRAY *)DataPacket) + 1))->Flags = EXIT_REQUIRED | NV_NOT_CHANGED;\r
- return EFI_SUCCESS;\r
- } else {\r
- continue;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-CallBootManager (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Hook to enable UI timeout override behavior.\r
-\r
-Arguments:\r
- BdsDeviceList - Device List that BDS needs to connect.\r
-\r
- Entry - Pointer to current Boot Entry.\r
-\r
-Returns:\r
- NONE\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_PACKAGES *PackageList;\r
- BDS_COMMON_OPTION *Option;\r
- LIST_ENTRY *Link;\r
- EFI_HII_UPDATE_DATA *UpdateData;\r
- CHAR16 *ExitData;\r
- UINTN ExitDataSize;\r
- STRING_REF Token;\r
- STRING_REF LastToken;\r
- EFI_INPUT_KEY Key;\r
- UINT8 *Location;\r
- EFI_GUID BmGuid;\r
- LIST_ENTRY BdsBootOptionList;\r
- BOOLEAN BootMngrMenuResetRequired;\r
-\r
- gOption = NULL;\r
- InitializeListHead (&BdsBootOptionList);\r
-\r
- //\r
- // Connect all prior to entering the platform setup menu.\r
- //\r
- if (!gConnectAllHappened) {\r
- BdsLibConnectAllDriversToAllControllers ();\r
- gConnectAllHappened = TRUE;\r
- }\r
- //\r
- // BugBug: Here we can not remove the legacy refresh macro, so we need\r
- // get the boot order every time from "BootOrder" variable.\r
- // Recreate the boot option list base on the BootOrder variable\r
- //\r
- BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
-\r
- //\r
- // This GUID must be the same as what is defined in BootManagerVfr.vfr\r
- //\r
- BmGuid = gBmGuid;\r
-\r
- mBootOptionsList = &BdsBootOptionList;\r
-\r
- //\r
- // Post our VFR to the HII database\r
- //\r
- PackageList = PreparePackages (2, &BmGuid, BootManagerVfrBin, EdkGenericPlatformBdsLibStrings);\r
- Status = Hii->NewPack (Hii, PackageList, &gBootManagerHandle);\r
- gBS->FreePool (PackageList);\r
-\r
- //\r
- // This example does not implement worker functions\r
- // for the NV accessor functions. Only a callback evaluator\r
- //\r
- BootManagerCallback.NvRead = NULL;\r
- BootManagerCallback.NvWrite = NULL;\r
- BootManagerCallback.Callback = BootManagerCallbackRoutine;\r
-\r
- //\r
- // Install protocol interface\r
- //\r
- BootManagerCallbackHandle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &BootManagerCallbackHandle,\r
- &gEfiFormCallbackProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &BootManagerCallback\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- LastToken = 0;\r
- Hii->NewString (Hii, NULL, gBootManagerHandle, &LastToken, L" ");\r
-\r
- //\r
- // Allocate space for creation of UpdateData Buffer\r
- //\r
- UpdateData = AllocateZeroPool (0x1000);\r
- ASSERT (UpdateData != NULL);\r
-\r
- //\r
- // Flag update pending in FormSet\r
- //\r
- UpdateData->FormSetUpdate = TRUE;\r
- //\r
- // Register CallbackHandle data for FormSet\r
- //\r
- UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) BootManagerCallbackHandle;\r
- UpdateData->FormUpdate = FALSE;\r
- UpdateData->FormTitle = 0;\r
- UpdateData->DataCount = 1;\r
-\r
- //\r
- // Create blank space. Since when we update the contents of IFR data at a label, it is\r
- // inserted at the location of the label. So if you want to add a string with an empty\r
- // space afterwards, you need to add the space first and then the string like below.\r
- //\r
- Status = CreateSubTitleOpCode (\r
- LastToken, // Token Value for the string\r
- &UpdateData->Data // Buffer containing created op-code\r
- );\r
-\r
- Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);\r
-\r
- //\r
- // Create "Boot Option Menu" title\r
- //\r
- Status = CreateSubTitleOpCode (\r
- STRING_TOKEN (STR_BOOT_OPTION_BANNER), // Token Value for the string\r
- &UpdateData->Data // Buffer containing created op-code\r
- );\r
-\r
- Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);\r
-\r
- Token = LastToken;\r
- mKeyInput = 0;\r
-\r
- UpdateData->DataCount = 0;\r
- Location = (UINT8 *) &UpdateData->Data;\r
-\r
- for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {\r
- Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
-\r
- //\r
- // At this stage we are creating a menu entry, thus the Keys are reproduceable\r
- //\r
- mKeyInput++;\r
- Token++;\r
-\r
- Status = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);\r
-\r
- //\r
- // If we got an error it is almost certainly due to the token value being invalid.\r
- // Therefore we will set the Token to 0 to automatically add a token.\r
- //\r
- if (EFI_ERROR (Status)) {\r
- Token = 0;\r
- Status = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);\r
- }\r
-\r
- Status = CreateGotoOpCode (\r
- 0x1000, // Form ID\r
- Token, // Token Value for the string\r
- 0, // Help String (none)\r
- EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS, // The Op-Code flags\r
- mKeyInput, // The Key to get a callback on\r
- Location // Buffer containing created op-code\r
- );\r
-\r
- UpdateData->DataCount++;\r
- Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
-\r
- }\r
-\r
- Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0001, TRUE, UpdateData);\r
-\r
- UpdateData->DataCount = 1;\r
-\r
- //\r
- // Create "Boot Option Menu" title\r
- //\r
- Status = CreateSubTitleOpCode (\r
- STRING_TOKEN (STR_HELP_FOOTER), // Token Value for the string\r
- &UpdateData->Data // Buffer containing created op-code\r
- );\r
-\r
- Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);\r
-\r
- Status = CreateSubTitleOpCode (\r
- LastToken, // Token Value for the string\r
- &UpdateData->Data // Buffer containing created op-code\r
- );\r
-\r
- Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);\r
-\r
- gBS->FreePool (UpdateData);\r
-\r
- ASSERT (gBrowser);\r
-\r
- BootMngrMenuResetRequired = FALSE;\r
- gBrowser->SendForm (\r
- gBrowser, \r
- TRUE, \r
- &gBootManagerHandle, \r
- 1, \r
- NULL, \r
- NULL, \r
- NULL, \r
- NULL, \r
- &BootMngrMenuResetRequired\r
- );\r
-\r
- if (BootMngrMenuResetRequired) {\r
- EnableResetRequired ();\r
- }\r
-\r
- Hii->ResetStrings (Hii, gBootManagerHandle);\r
-\r
- if (gOption == NULL) {\r
- return ;\r
- }\r
- \r
- //\r
- //Will leave browser, check any reset required change is applied? if yes, reset system\r
- //\r
- SetupResetReminder ();\r
- \r
- //\r
- // BugBug: This code looks repeated from the BDS. Need to save code space.\r
- //\r
-\r
- //\r
- // parse the selected option\r
- //\r
- Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- PlatformBdsBootSuccess (gOption);\r
- } else {\r
- PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);\r
- gST->ConOut->OutputString (\r
- gST->ConOut,\r
- GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))\r
- );\r
-\r
- //\r
- // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);\r
- //\r
-\r
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
- }\r
-}\r