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