/*++

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                      EdkGenericPlatformBdsLibStrings[];
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, EdkGenericPlatformBdsLibStrings);
  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);
  }
}
