git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2368 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			902 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			902 lines
		
	
	
		
			25 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:
 | 
						|
 | 
						|
  FrontPage.c
 | 
						|
 | 
						|
Abstract:
 | 
						|
 | 
						|
  FrontPage routines to handle the callbacks and browser calls
 | 
						|
  
 | 
						|
--*/
 | 
						|
 | 
						|
#include "Bds.h"
 | 
						|
#include "FrontPage.h"
 | 
						|
#include "String.h"
 | 
						|
 | 
						|
EFI_GUID                    mProcessorSubClass  = EFI_PROCESSOR_SUBCLASS_GUID;
 | 
						|
EFI_GUID                    mMemorySubClass     = EFI_MEMORY_SUBCLASS_GUID;
 | 
						|
EFI_GUID                    mMiscSubClass       = EFI_MISC_SUBCLASS_GUID;
 | 
						|
 | 
						|
UINT16                      mLastSelection;
 | 
						|
EFI_HII_HANDLE              gFrontPageHandle;
 | 
						|
EFI_HANDLE                  FrontPageCallbackHandle;
 | 
						|
EFI_FORM_CALLBACK_PROTOCOL  FrontPageCallback;
 | 
						|
EFI_FORM_BROWSER_PROTOCOL   *gBrowser;
 | 
						|
UINTN                       gCallbackKey;
 | 
						|
BOOLEAN                     gConnectAllHappened = FALSE;
 | 
						|
 | 
						|
extern EFI_HII_HANDLE       gFrontPageHandle;
 | 
						|
extern EFI_GUID             gBdsStringPackGuid;
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FrontPageCallbackRoutine (
 | 
						|
  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: 
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR16        *LanguageString;
 | 
						|
  UINTN         Count;
 | 
						|
  CHAR16        UnicodeLang[3];
 | 
						|
  CHAR8         Lang[3];
 | 
						|
  EFI_STATUS    Status;
 | 
						|
  UINTN         Index;
 | 
						|
  CHAR16        *TmpStr;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
 | 
						|
 | 
						|
  SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
 | 
						|
  SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
 | 
						|
  SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
 | 
						|
 | 
						|
  Count = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
 | 
						|
  // describe to their customers in documentation how to find their setup information (namely
 | 
						|
  // under the device manager and specific buckets)
 | 
						|
  //
 | 
						|
  switch (KeyValue) {
 | 
						|
  case 0x0001:
 | 
						|
    //
 | 
						|
    // This is the continue - clear the screen and return an error to get out of FrontPage loop
 | 
						|
    //
 | 
						|
    gCallbackKey = 1;
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0x1234:
 | 
						|
    //
 | 
						|
    // Collect the languages from what our current Language support is based on our VFR
 | 
						|
    //
 | 
						|
    Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);
 | 
						|
 | 
						|
    //
 | 
						|
    // Based on the DataArray->Data->Data value, we can determine
 | 
						|
    // which language was chosen by the user
 | 
						|
    //
 | 
						|
    for (Index = 0; Count != (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray + 1))->Data); Index += 3) {
 | 
						|
      Count++;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Preserve the choice the user made
 | 
						|
    //
 | 
						|
    mLastSelection = (UINT16) Count;
 | 
						|
 | 
						|
    //
 | 
						|
    // The Language (in Unicode format) the user chose
 | 
						|
    //
 | 
						|
    CopyMem (UnicodeLang, &LanguageString[Index], 6);
 | 
						|
 | 
						|
    //
 | 
						|
    // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations
 | 
						|
    // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.
 | 
						|
    //
 | 
						|
    for (Index = 0; Index < 3; Index++) {
 | 
						|
      Lang[Index] = (CHAR8) UnicodeLang[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    Status = gRT->SetVariable (
 | 
						|
                    L"Lang",
 | 
						|
                    &gEfiGlobalVariableGuid,
 | 
						|
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | 
						|
                    3,
 | 
						|
                    Lang
 | 
						|
                    );
 | 
						|
 | 
						|
    gBS->FreePool (LanguageString);
 | 
						|
    gCallbackKey = 2;
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0x1064:
 | 
						|
    //
 | 
						|
    // Boot Manager
 | 
						|
    //
 | 
						|
    gCallbackKey = 3;
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0x8567:
 | 
						|
    //
 | 
						|
    // Device Manager
 | 
						|
    //
 | 
						|
    gCallbackKey = 4;
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0x9876:
 | 
						|
    //
 | 
						|
    // Boot Maintenance Manager
 | 
						|
    //
 | 
						|
    gCallbackKey = 5;
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0xFFFE:
 | 
						|
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0xFFFF:
 | 
						|
    //
 | 
						|
    // FrontPage TimeOut Callback
 | 
						|
    //
 | 
						|
    TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));
 | 
						|
    if (TmpStr != NULL) {
 | 
						|
      PlatformBdsShowProgress (
 | 
						|
        Foreground,
 | 
						|
        Background,
 | 
						|
        TmpStr,
 | 
						|
        Color,
 | 
						|
        (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray+1))->Data),
 | 
						|
        0
 | 
						|
        );
 | 
						|
      gBS->FreePool (TmpStr);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    gCallbackKey = 0;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
InitializeFrontPage (
 | 
						|
  BOOLEAN                         ReInitializeStrings
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  
 | 
						|
  Initialize HII information for the FrontPage
 | 
						|
 | 
						|
Arguments:
 | 
						|
  None
 | 
						|
            
 | 
						|
Returns:
 | 
						|
  EFI_SUCCESS       - The operation is successful.
 | 
						|
  EFI_DEVICE_ERROR  - If the dynamic opcode creation failed.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  EFI_HII_PACKAGES    *PackageList;
 | 
						|
  EFI_HII_UPDATE_DATA *UpdateData;
 | 
						|
  IFR_OPTION          *OptionList;
 | 
						|
  CHAR16              *LanguageString;
 | 
						|
  UINTN               OptionCount;
 | 
						|
  UINTN               Index;
 | 
						|
  STRING_REF          Token;
 | 
						|
  UINT16              Key;
 | 
						|
  CHAR8               AsciiLang[4];
 | 
						|
  CHAR16              UnicodeLang[4];
 | 
						|
  CHAR16              Lang[4];
 | 
						|
  CHAR16              *StringBuffer;
 | 
						|
  UINTN               BufferSize;
 | 
						|
  UINT8               *TempBuffer;
 | 
						|
 | 
						|
  UpdateData  = NULL;
 | 
						|
  OptionList  = NULL;
 | 
						|
 | 
						|
  if (ReInitializeStrings) {
 | 
						|
    //
 | 
						|
    // BugBug: Dont' use a goto
 | 
						|
    //
 | 
						|
    goto ReInitStrings;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Go ahead and initialize the Device Manager
 | 
						|
  //
 | 
						|
  InitializeDeviceManager ();
 | 
						|
 | 
						|
  //
 | 
						|
  // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here
 | 
						|
  //
 | 
						|
  TempBuffer    = (UINT8 *) FrontPageVfrBin;
 | 
						|
  TempBuffer    = TempBuffer + sizeof (EFI_HII_PACK_HEADER);
 | 
						|
  TempBuffer    = (UINT8 *) &((EFI_IFR_FORM_SET *) TempBuffer)->NvDataSize;
 | 
						|
  *TempBuffer   = 1;
 | 
						|
 | 
						|
  gCallbackKey  = 0;
 | 
						|
 | 
						|
  PackageList   = PreparePackages (1, &gBdsStringPackGuid, FrontPageVfrBin);
 | 
						|
 | 
						|
  Status        = Hii->NewPack (Hii, PackageList, &gFrontPageHandle);
 | 
						|
 | 
						|
  gBS->FreePool (PackageList);
 | 
						|
 | 
						|
  //
 | 
						|
  // There will be only one FormConfig in the system
 | 
						|
  // If there is another out there, someone is trying to install us
 | 
						|
  // again.  Fail that scenario.
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiFormBrowserProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID**)&gBrowser
 | 
						|
                  );
 | 
						|
 | 
						|
  //
 | 
						|
  // This example does not implement worker functions
 | 
						|
  // for the NV accessor functions.  Only a callback evaluator
 | 
						|
  //
 | 
						|
  FrontPageCallback.NvRead    = NULL;
 | 
						|
  FrontPageCallback.NvWrite   = NULL;
 | 
						|
  FrontPageCallback.Callback  = FrontPageCallbackRoutine;
 | 
						|
 | 
						|
  //
 | 
						|
  // Install protocol interface
 | 
						|
  //
 | 
						|
  FrontPageCallbackHandle = NULL;
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &FrontPageCallbackHandle,
 | 
						|
                  &gEfiFormCallbackProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &FrontPageCallback
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
ReInitStrings:
 | 
						|
  //
 | 
						|
  // BugBug: This logic is in BdsInitLanguage. It should not be in two places!
 | 
						|
  //
 | 
						|
  BufferSize = 4;
 | 
						|
  Status = gRT->GetVariable (
 | 
						|
                  L"Lang",
 | 
						|
                  &gEfiGlobalVariableGuid,
 | 
						|
                  NULL,
 | 
						|
                  &BufferSize,
 | 
						|
                  AsciiLang
 | 
						|
                  );
 | 
						|
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    UnicodeLang[Index] = (CHAR16) AsciiLang[Index];
 | 
						|
  }
 | 
						|
 | 
						|
  UnicodeLang[3] = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate space for creation of UpdateData Buffer
 | 
						|
  //
 | 
						|
  UpdateData = AllocateZeroPool (0x1000);
 | 
						|
  ASSERT (UpdateData != NULL);
 | 
						|
 | 
						|
  OptionList = AllocateZeroPool (0x1000);
 | 
						|
  ASSERT (OptionList != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Flag update pending in FormSet
 | 
						|
  //
 | 
						|
  UpdateData->FormSetUpdate = TRUE;
 | 
						|
  //
 | 
						|
  // Register CallbackHandle data for FormSet
 | 
						|
  //
 | 
						|
  UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) FrontPageCallbackHandle;
 | 
						|
  UpdateData->FormUpdate  = FALSE;
 | 
						|
  UpdateData->FormTitle   = 0;
 | 
						|
  UpdateData->DataCount   = 1;
 | 
						|
 | 
						|
  //
 | 
						|
  // Collect the languages from what our current Language support is based on our VFR
 | 
						|
  //
 | 
						|
  Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);
 | 
						|
 | 
						|
  OptionCount = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Try for a 512 byte Buffer
 | 
						|
  //
 | 
						|
  BufferSize = 0x200;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate memory for our Form binary
 | 
						|
  //
 | 
						|
  StringBuffer = AllocateZeroPool (BufferSize);
 | 
						|
  ASSERT (StringBuffer != NULL);
 | 
						|
 | 
						|
  for (Index = 0; LanguageString[Index] != 0; Index += 3) {
 | 
						|
    Token = 0;
 | 
						|
    CopyMem (Lang, &LanguageString[Index], 6);
 | 
						|
    Lang[3] = 0;
 | 
						|
 | 
						|
    if (!StrCmp (Lang, UnicodeLang)) {
 | 
						|
      mLastSelection = (UINT16) OptionCount;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = Hii->GetString (Hii, gStringPackHandle, 1, TRUE, Lang, &BufferSize, StringBuffer);
 | 
						|
    Hii->NewString (Hii, NULL, gStringPackHandle, &Token, StringBuffer);
 | 
						|
    CopyMem (&OptionList[OptionCount].StringToken, &Token, sizeof (UINT16));
 | 
						|
    CopyMem (&OptionList[OptionCount].Value, &OptionCount, sizeof (UINT16));
 | 
						|
    Key = 0x1234;
 | 
						|
    CopyMem (&OptionList[OptionCount].Key, &Key, sizeof (UINT16));
 | 
						|
    OptionList[OptionCount].Flags = EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS;
 | 
						|
    OptionCount++;
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->FreePool (LanguageString);
 | 
						|
 | 
						|
  if (ReInitializeStrings) {
 | 
						|
    gBS->FreePool (StringBuffer);
 | 
						|
    gBS->FreePool (OptionList);
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = CreateOneOfOpCode (
 | 
						|
            FRONT_PAGE_QUESTION_ID,                               // Question ID
 | 
						|
            FRONT_PAGE_DATA_WIDTH,                                // Data Width
 | 
						|
            (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT),      // Prompt Token
 | 
						|
            (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP), // Help Token
 | 
						|
            OptionList,       // List of Options
 | 
						|
            OptionCount,      // Number of Options
 | 
						|
            &UpdateData->Data // Data Buffer
 | 
						|
            );
 | 
						|
 | 
						|
  //
 | 
						|
  // Assign the number of options and the oneof and endoneof op-codes to count
 | 
						|
  //
 | 
						|
  UpdateData->DataCount = (UINT8) (OptionCount + 2);
 | 
						|
 | 
						|
  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);
 | 
						|
 | 
						|
  gBS->FreePool (UpdateData);
 | 
						|
  //
 | 
						|
  // gBS->FreePool (OptionList);
 | 
						|
  //
 | 
						|
  gBS->FreePool (StringBuffer);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
CallFrontPage (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  
 | 
						|
  Call the browser and display the front page
 | 
						|
 | 
						|
Arguments:
 | 
						|
  
 | 
						|
  None
 | 
						|
  
 | 
						|
Returns:
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINT8       FakeNvRamMap[1];
 | 
						|
  BOOLEAN     FrontPageMenuResetRequired;
 | 
						|
 | 
						|
  //
 | 
						|
  // Begin waiting for USER INPUT
 | 
						|
  //
 | 
						|
  REPORT_STATUS_CODE (
 | 
						|
        EFI_PROGRESS_CODE,
 | 
						|
        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)
 | 
						|
        );
 | 
						|
 | 
						|
  FakeNvRamMap[0] = (UINT8) mLastSelection;
 | 
						|
  FrontPageMenuResetRequired = FALSE;
 | 
						|
  Status = gBrowser->SendForm (
 | 
						|
                      gBrowser,
 | 
						|
                      TRUE,                     // Use the database
 | 
						|
                      &gFrontPageHandle,        // The HII Handle
 | 
						|
                      1,
 | 
						|
                      NULL,
 | 
						|
                      FrontPageCallbackHandle,  // This is the handle that the interface to the callback was installed on
 | 
						|
                      FakeNvRamMap,
 | 
						|
                      NULL,
 | 
						|
                      &FrontPageMenuResetRequired
 | 
						|
                      );
 | 
						|
  //
 | 
						|
  // Check whether user change any option setting which needs a reset to be effective
 | 
						|
  //                      
 | 
						|
  if (FrontPageMenuResetRequired) {
 | 
						|
    EnableResetRequired ();
 | 
						|
  }
 | 
						|
 | 
						|
  Hii->ResetStrings (Hii, gFrontPageHandle);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
GetStringFromToken (
 | 
						|
  IN      EFI_GUID                  *ProducerGuid,
 | 
						|
  IN      STRING_REF                Token,
 | 
						|
  OUT     CHAR16                    **String
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  
 | 
						|
  Acquire the string associated with the ProducerGuid and return it.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  
 | 
						|
  ProducerGuid - The Guid to search the HII database for
 | 
						|
  Token - The token value of the string to extract
 | 
						|
  String - The string that is extracted
 | 
						|
  
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS - The function returns EFI_SUCCESS always.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS      Status;
 | 
						|
  UINT16          HandleBufferLength;
 | 
						|
  EFI_HII_HANDLE  *HiiHandleBuffer;
 | 
						|
  UINTN           StringBufferLength;
 | 
						|
  UINTN           NumberOfHiiHandles;
 | 
						|
  UINTN           Index;
 | 
						|
  UINT16          Length;
 | 
						|
  EFI_GUID        HiiGuid;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize params.
 | 
						|
  //
 | 
						|
  HandleBufferLength  = 0;
 | 
						|
  HiiHandleBuffer     = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get all the Hii handles
 | 
						|
  //
 | 
						|
  Status = BdsLibGetHiiHandles (Hii, &HandleBufferLength, &HiiHandleBuffer);
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the Hii Handle that matches the StructureNode->ProducerName
 | 
						|
  //
 | 
						|
  NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);
 | 
						|
  for (Index = 0; Index < NumberOfHiiHandles; Index++) {
 | 
						|
    Length = 0;
 | 
						|
    Status = ExtractDataFromHiiHandle (
 | 
						|
              HiiHandleBuffer[Index],
 | 
						|
              &Length,
 | 
						|
              NULL,
 | 
						|
              &HiiGuid
 | 
						|
              );
 | 
						|
    if (CompareGuid (ProducerGuid, &HiiGuid)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Find the string based on the current language
 | 
						|
  //
 | 
						|
  StringBufferLength  = 0x100;
 | 
						|
  *String             = AllocateZeroPool (0x100);
 | 
						|
  Status = Hii->GetString (
 | 
						|
                  Hii,
 | 
						|
                  HiiHandleBuffer[Index],
 | 
						|
                  Token,
 | 
						|
                  FALSE,
 | 
						|
                  NULL,
 | 
						|
                  &StringBufferLength,
 | 
						|
                  *String
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    gBS->FreePool (*String);
 | 
						|
    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->FreePool (HiiHandleBuffer);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
ConvertProcessorToString (
 | 
						|
  IN  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,
 | 
						|
  OUT CHAR16                            **String
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  
 | 
						|
  Convert Processor Frequency Data to a string
 | 
						|
 | 
						|
Arguments:
 | 
						|
  
 | 
						|
  ProcessorFrequency - The frequency data to process
 | 
						|
  String - The string that is created
 | 
						|
  
 | 
						|
Returns:
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR16  *StringBuffer;
 | 
						|
  UINTN   Index;
 | 
						|
  UINT32  FreqMhz;
 | 
						|
 | 
						|
  if (ProcessorFrequency->Exponent >= 6) {
 | 
						|
    FreqMhz = ProcessorFrequency->Value;
 | 
						|
    for (Index = 0; Index < (UINTN) (ProcessorFrequency->Exponent - 6); Index++) {
 | 
						|
      FreqMhz *= 10;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    FreqMhz = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  StringBuffer = AllocateZeroPool (0x20);
 | 
						|
  ASSERT (StringBuffer != NULL);
 | 
						|
  Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);
 | 
						|
  StrCat (StringBuffer, L".");
 | 
						|
  UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);
 | 
						|
  StrCat (StringBuffer, L" GHz");
 | 
						|
 | 
						|
  *String = (CHAR16 *) StringBuffer;
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
ConvertMemorySizeToString (
 | 
						|
  IN  UINT32          MemorySize,
 | 
						|
  OUT CHAR16          **String
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  
 | 
						|
  Convert Memory Size to a string
 | 
						|
 | 
						|
Arguments:
 | 
						|
  
 | 
						|
  MemorySize - The size of the memory to process
 | 
						|
  String - The string that is created
 | 
						|
  
 | 
						|
Returns:
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR16  *StringBuffer;
 | 
						|
 | 
						|
  StringBuffer = AllocateZeroPool (0x20);
 | 
						|
  ASSERT (StringBuffer != NULL);
 | 
						|
  UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);
 | 
						|
  StrCat (StringBuffer, L" MB RAM");
 | 
						|
 | 
						|
  *String = (CHAR16 *) StringBuffer;
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
UpdateFrontPageStrings (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  
 | 
						|
  Update the banner information for the Front Page based on DataHub information
 | 
						|
 | 
						|
Arguments:
 | 
						|
  
 | 
						|
  None
 | 
						|
  
 | 
						|
Returns:
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                        Status;
 | 
						|
  STRING_REF                        TokenToUpdate;
 | 
						|
  CHAR16                            *NewString;
 | 
						|
  UINT64                            MonotonicCount;
 | 
						|
  EFI_DATA_HUB_PROTOCOL             *DataHub;
 | 
						|
  EFI_DATA_RECORD_HEADER            *Record;
 | 
						|
  EFI_SUBCLASS_TYPE1_HEADER         *DataHeader;
 | 
						|
  EFI_MISC_BIOS_VENDOR_DATA         *BiosVendor;
 | 
						|
  EFI_MISC_SYSTEM_MANUFACTURER_DATA *SystemManufacturer;
 | 
						|
  EFI_PROCESSOR_VERSION_DATA        *ProcessorVersion;
 | 
						|
  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency;
 | 
						|
  EFI_MEMORY_ARRAY_START_ADDRESS_DATA *MemoryArray;
 | 
						|
  CHAR8                             LangCode[3];
 | 
						|
  CHAR16                            Lang[3];
 | 
						|
  UINTN                             Size;
 | 
						|
  UINTN                             Index;
 | 
						|
  BOOLEAN                           Find[5];
 | 
						|
 | 
						|
  ZeroMem (Find, sizeof (Find));
 | 
						|
 | 
						|
  //
 | 
						|
  // Update Front Page strings
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiDataHubProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID**)&DataHub
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  Size = 3;
 | 
						|
 | 
						|
  Status = gRT->GetVariable (
 | 
						|
                  L"Lang",
 | 
						|
                  &gEfiGlobalVariableGuid,
 | 
						|
                  NULL,
 | 
						|
                  &Size,
 | 
						|
                  LangCode
 | 
						|
                  );
 | 
						|
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    Lang[Index] = (CHAR16) LangCode[Index];
 | 
						|
  }
 | 
						|
 | 
						|
  MonotonicCount  = 0;
 | 
						|
  Record          = NULL;
 | 
						|
  do {
 | 
						|
    Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
 | 
						|
    if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
 | 
						|
      DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
 | 
						|
      if (CompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&
 | 
						|
          (DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)
 | 
						|
          ) {
 | 
						|
        BiosVendor = (EFI_MISC_BIOS_VENDOR_DATA *) (DataHeader + 1);
 | 
						|
        GetStringFromToken (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);
 | 
						|
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_BIOS_VERSION;
 | 
						|
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
 | 
						|
        gBS->FreePool (NewString);
 | 
						|
        Find[0] = TRUE;
 | 
						|
      }
 | 
						|
 | 
						|
      if (CompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&
 | 
						|
          (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)
 | 
						|
          ) {
 | 
						|
        SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) (DataHeader + 1);
 | 
						|
        GetStringFromToken (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);
 | 
						|
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_COMPUTER_MODEL;
 | 
						|
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
 | 
						|
        gBS->FreePool (NewString);
 | 
						|
        Find[1] = TRUE;
 | 
						|
      }
 | 
						|
 | 
						|
      if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&
 | 
						|
          (DataHeader->RecordType == ProcessorVersionRecordType)
 | 
						|
          ) {
 | 
						|
        ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);
 | 
						|
        GetStringFromToken (&Record->ProducerName, *ProcessorVersion, &NewString);
 | 
						|
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_MODEL;
 | 
						|
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
 | 
						|
        gBS->FreePool (NewString);
 | 
						|
        Find[2] = TRUE;
 | 
						|
      }
 | 
						|
 | 
						|
      if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&
 | 
						|
          (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)
 | 
						|
          ) {
 | 
						|
        ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);
 | 
						|
        ConvertProcessorToString (ProcessorFrequency, &NewString);
 | 
						|
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_SPEED;
 | 
						|
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
 | 
						|
        gBS->FreePool (NewString);
 | 
						|
        Find[3] = TRUE;
 | 
						|
      }
 | 
						|
 | 
						|
      if (CompareGuid (&Record->DataRecordGuid, &mMemorySubClass) &&
 | 
						|
          (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)
 | 
						|
          ) {
 | 
						|
        MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) (DataHeader + 1);
 | 
						|
        ConvertMemorySizeToString((UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - 
 | 
						|
                                  MemoryArray->MemoryArrayStartAddress + 1), 20)),
 | 
						|
                                  &NewString);
 | 
						|
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_MEMORY_SIZE;
 | 
						|
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
 | 
						|
        gBS->FreePool (NewString);
 | 
						|
        Find[4] = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } while (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
PlatformBdsEnterFrontPage (
 | 
						|
  IN UINT16                       TimeoutDefault,
 | 
						|
  IN BOOLEAN                      ConnectAllHappened
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  This function is the main entry of the platform setup entry.
 | 
						|
  The function will present the main menu of the system setup, 
 | 
						|
  this is the platform reference part and can be customize.
 | 
						|
  
 | 
						|
Arguments:
 | 
						|
  TimeoutDefault     - The fault time out value before the system
 | 
						|
                       continue to boot.
 | 
						|
  ConnectAllHappened - The indicater to check if the connect all have
 | 
						|
                       already happended.
 | 
						|
  
 | 
						|
Returns:
 | 
						|
  None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  EFI_HII_UPDATE_DATA           *UpdateData;
 | 
						|
  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;
 | 
						|
 | 
						|
  //
 | 
						|
  // Indicate if we need connect all in the platform setup
 | 
						|
  //
 | 
						|
  if (ConnectAllHappened) {
 | 
						|
    gConnectAllHappened = TRUE;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Allocate space for creation of Buffer
 | 
						|
  //
 | 
						|
  UpdateData = AllocateZeroPool (0x1000);
 | 
						|
  ASSERT (UpdateData != NULL);
 | 
						|
 | 
						|
  UpdateData->FormSetUpdate       = FALSE;
 | 
						|
  UpdateData->FormCallbackHandle  = 0;
 | 
						|
  UpdateData->FormUpdate          = FALSE;
 | 
						|
  UpdateData->FormTitle           = 0;
 | 
						|
  UpdateData->DataCount           = 1;
 | 
						|
 | 
						|
  //
 | 
						|
  // Remove Banner Op-code if any at this label
 | 
						|
  //
 | 
						|
  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, FALSE, UpdateData);
 | 
						|
 | 
						|
  //
 | 
						|
  // Create Banner Op-code which reflects correct timeout value
 | 
						|
  //
 | 
						|
  CreateBannerOpCode (
 | 
						|
    STRING_TOKEN (STR_TIME_OUT_PROMPT),
 | 
						|
    TimeoutDefault,
 | 
						|
    (UINT8) EFI_IFR_BANNER_TIMEOUT,
 | 
						|
    &UpdateData->Data
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Add Banner Op-code at this label
 | 
						|
  //
 | 
						|
  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, TRUE, UpdateData);
 | 
						|
 | 
						|
  do {
 | 
						|
 | 
						|
    InitializeFrontPage (TRUE);
 | 
						|
 | 
						|
    //
 | 
						|
    // Update Front Page strings
 | 
						|
    //
 | 
						|
    UpdateFrontPageStrings ();
 | 
						|
 | 
						|
    gCallbackKey = 0;
 | 
						|
    PERF_START (0, "BdsTimeOut", "BDS", 0);
 | 
						|
    Status = CallFrontPage ();
 | 
						|
    PERF_END (0, "BdsTimeOut", "BDS", 0);
 | 
						|
 | 
						|
    //
 | 
						|
    // If gCallbackKey is greater than 1 and less or equal to 5,
 | 
						|
    // it will lauch configuration utilities.
 | 
						|
    // 2 = set language
 | 
						|
    // 3 = boot manager
 | 
						|
    // 4 = device manager
 | 
						|
    // 5 = boot maintainenance manager
 | 
						|
    //
 | 
						|
    if ((gCallbackKey > 0x0001) && (gCallbackKey <= 0x0005)) {
 | 
						|
      REPORT_STATUS_CODE (
 | 
						|
            EFI_PROGRESS_CODE,
 | 
						|
            (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
 | 
						|
            );
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Based on the key that was set, we can determine what to do
 | 
						|
    //
 | 
						|
    switch (gCallbackKey) {
 | 
						|
    //
 | 
						|
    // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
 | 
						|
    // describe to their customers in documentation how to find their setup information (namely
 | 
						|
    // under the device manager and specific buckets)
 | 
						|
    //
 | 
						|
    // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
 | 
						|
    //
 | 
						|
    case 0x0001:
 | 
						|
      //
 | 
						|
      // User hit continue
 | 
						|
      //
 | 
						|
      break;
 | 
						|
 | 
						|
    case 0x0002:
 | 
						|
      //
 | 
						|
      // User made a language setting change - display front page again
 | 
						|
      //
 | 
						|
      break;
 | 
						|
 | 
						|
    case 0x0003:
 | 
						|
      //
 | 
						|
      // User chose to run the Boot Manager
 | 
						|
      //
 | 
						|
      CallBootManager ();
 | 
						|
      break;
 | 
						|
 | 
						|
    case 0x0004:
 | 
						|
      //
 | 
						|
      // Display the Device Manager
 | 
						|
      //
 | 
						|
      do {
 | 
						|
        CallDeviceManager();
 | 
						|
      } while (gCallbackKey == 4);
 | 
						|
      break;
 | 
						|
 | 
						|
    case 0x0005:
 | 
						|
      //
 | 
						|
      // Display the Boot Maintenance Manager
 | 
						|
      //
 | 
						|
      BdsStartBootMaint ();
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
  } while ((Status == EFI_SUCCESS) && (gCallbackKey != 1));
 | 
						|
 | 
						|
  //
 | 
						|
  //Will leave browser, check any reset required change is applied? if yes, reset system
 | 
						|
  //
 | 
						|
  SetupResetReminder ();
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Automatically load current entry
 | 
						|
  // Note: The following lines of code only execute when Auto boot
 | 
						|
  // takes affect
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);
 | 
						|
  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
 | 
						|
 | 
						|
}
 |