summaryrefslogtreecommitdiff
path: root/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c
diff options
context:
space:
mode:
authortgingold <tgingold@6f19259b-4bc3-4df7-8a09-765794883524>2007-01-06 14:59:06 +0000
committertgingold <tgingold@6f19259b-4bc3-4df7-8a09-765794883524>2007-01-06 14:59:06 +0000
commitc9093a06e72ef16d2f3bd7ce0a2b9a172e9d048c (patch)
tree02dfc93be892697bf02f040b6c8429cecc8370ce /EdkUnixPkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c
parent8ba7afaf2e9c682a5d17760e6dd5463b3a2b2d67 (diff)
downloadedk2-platforms-c9093a06e72ef16d2f3bd7ce0a2b9a172e9d048c.tar.xz
Unix version of EFI emulator
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2182 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkUnixPkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c')
-rw-r--r--EdkUnixPkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c355
1 files changed, 355 insertions, 0 deletions
diff --git a/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c b/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c
new file mode 100644
index 0000000000..23b8789617
--- /dev/null
+++ b/EdkUnixPkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c
@@ -0,0 +1,355 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ BootManager.c
+
+Abstract:
+
+ The platform boot manager reference implement
+
+--*/
+#include "BootManager.h"
+
+UINT16 mKeyInput;
+LIST_ENTRY *mBootOptionsList;
+BDS_COMMON_OPTION *gOption;
+EFI_HII_HANDLE gBootManagerHandle;
+EFI_HANDLE BootManagerCallbackHandle;
+EFI_FORM_CALLBACK_PROTOCOL BootManagerCallback;
+EFI_GUID gBmGuid = BOOT_MANAGER_GUID;
+
+extern EFI_FORM_BROWSER_PROTOCOL *gBrowser;
+extern UINT8 BootManagerVfrBin[];
+extern UINT8 BdsStrings[];
+extern BOOLEAN gConnectAllHappened;
+
+EFI_STATUS
+EFIAPI
+BootManagerCallbackRoutine (
+ IN EFI_FORM_CALLBACK_PROTOCOL *This,
+ IN UINT16 KeyValue,
+ IN EFI_IFR_DATA_ARRAY *DataArray,
+ OUT EFI_HII_CALLBACK_PACKET **Packet
+ )
+/*++
+
+Routine Description:
+
+ This is the function that is called to provide results data to the driver. This data
+ consists of a unique key which is used to identify what data is either being passed back
+ or being asked for.
+
+Arguments:
+
+ KeyValue - A unique value which is sent to the original exporting driver so that it
+ can identify the type of data to expect. The format of the data tends to
+ vary based on the op-code that geerated the callback.
+
+ Data - A pointer to the data being sent to the original exporting driver.
+
+Returns:
+
+--*/
+{
+ BDS_COMMON_OPTION *Option;
+ LIST_ENTRY *Link;
+ UINT16 KeyCount;
+ EFI_HII_CALLBACK_PACKET *DataPacket;
+
+ //
+ // Initialize the key count
+ //
+ KeyCount = 0;
+
+ for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {
+ Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
+
+ KeyCount++;
+
+ gOption = Option;
+
+ //
+ // Is this device the one chosen?
+ //
+ if (KeyCount == KeyValue) {
+ //
+ // Assigning the returned Key to a global allows the original routine to know what was chosen
+ //
+ mKeyInput = KeyValue;
+
+ *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);
+ ASSERT (*Packet != NULL);
+
+ //
+ // Assign the buffer address to DataPacket
+ //
+ DataPacket = *Packet;
+
+ DataPacket->DataArray.EntryCount = 1;
+ DataPacket->DataArray.NvRamMap = NULL;
+ ((EFI_IFR_DATA_ENTRY *) (((EFI_IFR_DATA_ARRAY *)DataPacket) + 1))->Flags = EXIT_REQUIRED | NV_NOT_CHANGED;
+ return EFI_SUCCESS;
+ } else {
+ continue;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID
+CallBootManager (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Hook to enable UI timeout override behavior.
+
+Arguments:
+ BdsDeviceList - Device List that BDS needs to connect.
+
+ Entry - Pointer to current Boot Entry.
+
+Returns:
+ NONE
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGES *PackageList;
+ BDS_COMMON_OPTION *Option;
+ LIST_ENTRY *Link;
+ EFI_HII_UPDATE_DATA *UpdateData;
+ CHAR16 *ExitData;
+ UINTN ExitDataSize;
+ STRING_REF Token;
+ STRING_REF LastToken;
+ EFI_INPUT_KEY Key;
+ UINT8 *Location;
+ EFI_GUID BmGuid;
+ LIST_ENTRY BdsBootOptionList;
+ BOOLEAN BootMngrMenuResetRequired;
+
+ gOption = NULL;
+ InitializeListHead (&BdsBootOptionList);
+
+ //
+ // Connect all prior to entering the platform setup menu.
+ //
+ if (!gConnectAllHappened) {
+ BdsLibConnectAllDriversToAllControllers ();
+ gConnectAllHappened = TRUE;
+ }
+ //
+ // BugBug: Here we can not remove the legacy refresh macro, so we need
+ // get the boot order every time from "BootOrder" variable.
+ // Recreate the boot option list base on the BootOrder variable
+ //
+ BdsLibEnumerateAllBootOption (&BdsBootOptionList);
+
+ //
+ // This GUID must be the same as what is defined in BootManagerVfr.vfr
+ //
+ BmGuid = gBmGuid;
+
+ mBootOptionsList = &BdsBootOptionList;
+
+ //
+ // Post our VFR to the HII database
+ //
+ PackageList = PreparePackages (2, &BmGuid, BootManagerVfrBin, BdsStrings);
+ Status = Hii->NewPack (Hii, PackageList, &gBootManagerHandle);
+ gBS->FreePool (PackageList);
+
+ //
+ // This example does not implement worker functions
+ // for the NV accessor functions. Only a callback evaluator
+ //
+ BootManagerCallback.NvRead = NULL;
+ BootManagerCallback.NvWrite = NULL;
+ BootManagerCallback.Callback = BootManagerCallbackRoutine;
+
+ //
+ // Install protocol interface
+ //
+ BootManagerCallbackHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &BootManagerCallbackHandle,
+ &gEfiFormCallbackProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &BootManagerCallback
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ LastToken = 0;
+ Hii->NewString (Hii, NULL, gBootManagerHandle, &LastToken, L" ");
+
+ //
+ // Allocate space for creation of UpdateData Buffer
+ //
+ UpdateData = AllocateZeroPool (0x1000);
+ ASSERT (UpdateData != NULL);
+
+ //
+ // Flag update pending in FormSet
+ //
+ UpdateData->FormSetUpdate = TRUE;
+ //
+ // Register CallbackHandle data for FormSet
+ //
+ UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) BootManagerCallbackHandle;
+ UpdateData->FormUpdate = FALSE;
+ UpdateData->FormTitle = 0;
+ UpdateData->DataCount = 1;
+
+ //
+ // Create blank space. Since when we update the contents of IFR data at a label, it is
+ // inserted at the location of the label. So if you want to add a string with an empty
+ // space afterwards, you need to add the space first and then the string like below.
+ //
+ Status = CreateSubTitleOpCode (
+ LastToken, // Token Value for the string
+ &UpdateData->Data // Buffer containing created op-code
+ );
+
+ Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);
+
+ //
+ // Create "Boot Option Menu" title
+ //
+ Status = CreateSubTitleOpCode (
+ STRING_TOKEN (STR_BOOT_OPTION_BANNER), // Token Value for the string
+ &UpdateData->Data // Buffer containing created op-code
+ );
+
+ Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);
+
+ Token = LastToken;
+ mKeyInput = 0;
+
+ UpdateData->DataCount = 0;
+ Location = (UINT8 *) &UpdateData->Data;
+
+ for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {
+ Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
+
+ //
+ // At this stage we are creating a menu entry, thus the Keys are reproduceable
+ //
+ mKeyInput++;
+ Token++;
+
+ Status = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);
+
+ //
+ // If we got an error it is almost certainly due to the token value being invalid.
+ // Therefore we will set the Token to 0 to automatically add a token.
+ //
+ if (EFI_ERROR (Status)) {
+ Token = 0;
+ Status = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);
+ }
+
+ Status = CreateGotoOpCode (
+ 0x1000, // Form ID
+ Token, // Token Value for the string
+ 0, // Help String (none)
+ EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS, // The Op-Code flags
+ mKeyInput, // The Key to get a callback on
+ Location // Buffer containing created op-code
+ );
+
+ UpdateData->DataCount++;
+ Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
+
+ }
+
+ Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0001, TRUE, UpdateData);
+
+ UpdateData->DataCount = 1;
+
+ //
+ // Create "Boot Option Menu" title
+ //
+ Status = CreateSubTitleOpCode (
+ STRING_TOKEN (STR_HELP_FOOTER), // Token Value for the string
+ &UpdateData->Data // Buffer containing created op-code
+ );
+
+ Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);
+
+ Status = CreateSubTitleOpCode (
+ LastToken, // Token Value for the string
+ &UpdateData->Data // Buffer containing created op-code
+ );
+
+ Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);
+
+ gBS->FreePool (UpdateData);
+
+ ASSERT (gBrowser);
+
+ BootMngrMenuResetRequired = FALSE;
+ gBrowser->SendForm (
+ gBrowser,
+ TRUE,
+ &gBootManagerHandle,
+ 1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &BootMngrMenuResetRequired
+ );
+
+ if (BootMngrMenuResetRequired) {
+ EnableResetRequired ();
+ }
+
+ Hii->ResetStrings (Hii, gBootManagerHandle);
+
+ if (gOption == NULL) {
+ return ;
+ }
+
+ //
+ //Will leave browser, check any reset required change is applied? if yes, reset system
+ //
+ SetupResetReminder ();
+
+ //
+ // BugBug: This code looks repeated from the BDS. Need to save code space.
+ //
+
+ //
+ // parse the selected option
+ //
+ Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);
+
+ if (!EFI_ERROR (Status)) {
+ PlatformBdsBootSuccess (gOption);
+ } else {
+ PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
+ gST->ConOut->OutputString (
+ gST->ConOut,
+ GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
+ );
+
+ //
+ // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
+ //
+
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ }
+}