git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5019 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			329 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  The platform boot manager reference implement
 | 
						|
 | 
						|
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
 | 
						|
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.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "BootManager.h"
 | 
						|
 | 
						|
UINT16             mKeyInput;
 | 
						|
EFI_GUID           mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
 | 
						|
LIST_ENTRY         *mBootOptionsList;
 | 
						|
BDS_COMMON_OPTION  *gOption;
 | 
						|
 | 
						|
BOOT_MANAGER_CALLBACK_DATA  gBootManagerPrivate = {
 | 
						|
  BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,
 | 
						|
  NULL,
 | 
						|
  NULL,
 | 
						|
  {
 | 
						|
    FakeExtractConfig,
 | 
						|
    FakeRouteConfig,
 | 
						|
    BootManagerCallback
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BootManagerCallback (
 | 
						|
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
 | 
						|
  IN  EFI_BROWSER_ACTION                     Action,
 | 
						|
  IN  EFI_QUESTION_ID                        QuestionId,
 | 
						|
  IN  UINT8                                  Type,
 | 
						|
  IN  EFI_IFR_TYPE_VALUE                     *Value,
 | 
						|
  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
  Routine Description:
 | 
						|
    This function processes the results of changes in configuration.
 | 
						|
 | 
						|
  Arguments:
 | 
						|
    This          - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | 
						|
    Action        - Specifies the type of action taken by the browser.
 | 
						|
    QuestionId    - A unique value which is sent to the original exporting driver
 | 
						|
                    so that it can identify the type of data to expect.
 | 
						|
    Type          - The type of value for the question.
 | 
						|
    Value         - A pointer to the data being sent to the original exporting driver.
 | 
						|
    ActionRequest - On return, points to the action requested by the callback function.
 | 
						|
 | 
						|
  Returns:
 | 
						|
    EFI_SUCCESS          - The callback successfully handled the action.
 | 
						|
    EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
 | 
						|
    EFI_DEVICE_ERROR     - The variable could not be saved.
 | 
						|
    EFI_UNSUPPORTED      - The specified Action is not supported by the callback.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  BDS_COMMON_OPTION       *Option;
 | 
						|
  LIST_ENTRY              *Link;
 | 
						|
  UINT16                  KeyCount;
 | 
						|
 | 
						|
  if ((Value == NULL) || (ActionRequest == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // 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 == QuestionId) {
 | 
						|
      //
 | 
						|
      // Assigning the returned Key to a global allows the original routine to know what was chosen
 | 
						|
      //
 | 
						|
      mKeyInput = QuestionId;
 | 
						|
 | 
						|
      //
 | 
						|
      // Request to exit SendForm(), so that we could boot the selected option
 | 
						|
      //
 | 
						|
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
InitializeBootManager (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Initialize HII information for the FrontPage
 | 
						|
 | 
						|
Arguments:
 | 
						|
  None
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  EFI_HII_PACKAGE_LIST_HEADER *PackageList;
 | 
						|
 | 
						|
  //
 | 
						|
  // Create driver handle used by HII database
 | 
						|
  //
 | 
						|
  Status = HiiLibCreateHiiDriverHandle (&gBootManagerPrivate.DriverHandle);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Install Config Access protocol to driver handle
 | 
						|
  //
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &gBootManagerPrivate.DriverHandle,
 | 
						|
                  &gEfiHiiConfigAccessProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &gBootManagerPrivate.ConfigAccess
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Publish our HII data
 | 
						|
  //
 | 
						|
  PackageList = HiiLibPreparePackageList (2, &mBootManagerGuid, BootManagerVfrBin, BdsDxeStrings);
 | 
						|
  ASSERT (PackageList != NULL);
 | 
						|
 | 
						|
  Status = gHiiDatabase->NewPackageList (
 | 
						|
                           gHiiDatabase,
 | 
						|
                           PackageList,
 | 
						|
                           gBootManagerPrivate.DriverHandle,
 | 
						|
                           &gBootManagerPrivate.HiiHandle
 | 
						|
                           );
 | 
						|
  FreePool (PackageList);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
  BDS_COMMON_OPTION           *Option;
 | 
						|
  LIST_ENTRY                  *Link;
 | 
						|
  EFI_HII_UPDATE_DATA         UpdateData;
 | 
						|
  CHAR16                      *ExitData;
 | 
						|
  UINTN                       ExitDataSize;
 | 
						|
  EFI_STRING_ID               Token;
 | 
						|
  EFI_INPUT_KEY               Key;
 | 
						|
  LIST_ENTRY                  BdsBootOptionList;
 | 
						|
  CHAR16                      *HelpString;
 | 
						|
  EFI_STRING_ID               HelpToken;
 | 
						|
  UINT16                      *TempStr;
 | 
						|
  EFI_HII_HANDLE              HiiHandle;
 | 
						|
  EFI_BROWSER_ACTION_REQUEST  ActionRequest;
 | 
						|
  UINTN                       TempSize;
 | 
						|
 | 
						|
  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);
 | 
						|
 | 
						|
  mBootOptionsList  = &BdsBootOptionList;
 | 
						|
 | 
						|
  HiiHandle = gBootManagerPrivate.HiiHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate space for creation of UpdateData Buffer
 | 
						|
  //
 | 
						|
  UpdateData.BufferSize = 0x1000;
 | 
						|
  UpdateData.Offset = 0;
 | 
						|
  UpdateData.Data = AllocateZeroPool (0x1000);
 | 
						|
  ASSERT (UpdateData.Data != NULL);
 | 
						|
 | 
						|
  mKeyInput = 0;
 | 
						|
 | 
						|
  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++;
 | 
						|
 | 
						|
    //
 | 
						|
    // Don't display the boot option marked as LOAD_OPTION_HIDDEN
 | 
						|
    //
 | 
						|
    if (Option->Attribute & LOAD_OPTION_HIDDEN) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    HiiLibNewString (HiiHandle, &Token, Option->Description);
 | 
						|
 | 
						|
    TempStr = DevicePathToStr (Option->DevicePath);
 | 
						|
    TempSize = StrSize (TempStr);
 | 
						|
    HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
 | 
						|
    StrCat (HelpString, L"Device Path : ");
 | 
						|
    StrCat (HelpString, TempStr);
 | 
						|
 | 
						|
    HiiLibNewString (HiiHandle, &HelpToken, HelpString);
 | 
						|
 | 
						|
    CreateActionOpCode (
 | 
						|
      mKeyInput,
 | 
						|
      Token,
 | 
						|
      HelpToken,
 | 
						|
      EFI_IFR_FLAG_CALLBACK,
 | 
						|
      0,
 | 
						|
      &UpdateData
 | 
						|
      );
 | 
						|
  }
 | 
						|
 | 
						|
  IfrLibUpdateForm (
 | 
						|
    HiiHandle,
 | 
						|
    &mBootManagerGuid,
 | 
						|
    BOOT_MANAGER_FORM_ID,
 | 
						|
    LABEL_BOOT_OPTION,
 | 
						|
    FALSE,
 | 
						|
    &UpdateData
 | 
						|
    );
 | 
						|
  FreePool (UpdateData.Data);
 | 
						|
 | 
						|
  //
 | 
						|
  // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
 | 
						|
  //
 | 
						|
  gBS->RestoreTPL (TPL_APPLICATION);
 | 
						|
 | 
						|
  ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
 | 
						|
  Status = gFormBrowser2->SendForm (
 | 
						|
                           gFormBrowser2,
 | 
						|
                           &HiiHandle,
 | 
						|
                           1,
 | 
						|
                           NULL,
 | 
						|
                           0,
 | 
						|
                           NULL,
 | 
						|
                           &ActionRequest
 | 
						|
                           );
 | 
						|
  if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
 | 
						|
    EnableResetRequired ();
 | 
						|
  }
 | 
						|
 | 
						|
  if (gOption == NULL) {
 | 
						|
    gBS->RaiseTPL (TPL_APPLICATION);
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //Will leave browser, check any reset required change is applied? if yes, reset system
 | 
						|
  //
 | 
						|
  SetupResetReminder ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Raise the TPL level back to TPL_APPLICATION
 | 
						|
  //
 | 
						|
  gBS->RaiseTPL (TPL_APPLICATION);
 | 
						|
 | 
						|
  //
 | 
						|
  // parse the selected option
 | 
						|
  //
 | 
						|
  Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
 | 
						|
    PlatformBdsBootSuccess (gOption);
 | 
						|
  } else {
 | 
						|
    gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
 | 
						|
    PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
 | 
						|
    gST->ConOut->OutputString (
 | 
						|
                  gST->ConOut,
 | 
						|
                  GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
 | 
						|
                  );
 | 
						|
    gBS->RestoreTPL (TPL_APPLICATION);
 | 
						|
    //
 | 
						|
    // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
 | 
						|
    //
 | 
						|
    gBS->RaiseTPL (TPL_APPLICATION);
 | 
						|
    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
 | 
						|
  }
 | 
						|
}
 |