Home | History | Annotate | Download | only in BootMaint
      1 /** @file
      2 Dynamically update the pages.
      3 
      4 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "BootMaint.h"
     16 
     17 /**
     18   Refresh the global UpdateData structure.
     19 
     20 **/
     21 VOID
     22 RefreshUpdateData (
     23   VOID
     24   )
     25 {
     26   //
     27   // Free current updated date
     28   //
     29   if (mStartOpCodeHandle != NULL) {
     30     HiiFreeOpCodeHandle (mStartOpCodeHandle);
     31   }
     32 
     33   //
     34   // Create new OpCode Handle
     35   //
     36   mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
     37 
     38   //
     39   // Create Hii Extend Label OpCode as the start opcode
     40   //
     41   mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
     42   mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
     43 
     44 }
     45 
     46 /**
     47   Add a "Go back to main page" tag in front of the form when there are no
     48   "Apply changes" and "Discard changes" tags in the end of the form.
     49 
     50   @param CallbackData    The BMM context data.
     51 
     52 **/
     53 VOID
     54 UpdatePageStart (
     55   IN BMM_CALLBACK_DATA                *CallbackData
     56   )
     57 {
     58   RefreshUpdateData ();
     59   mStartLabel->Number = CallbackData->BmmCurrentPageId;
     60 
     61   if (!(CallbackData->BmmAskSaveOrNot)) {
     62     //
     63     // Add a "Go back to main page" tag in front of the form when there are no
     64     // "Apply changes" and "Discard changes" tags in the end of the form.
     65     //
     66     HiiCreateGotoOpCode (
     67       mStartOpCodeHandle,
     68       FORM_MAIN_ID,
     69       STRING_TOKEN (STR_FORM_GOTO_MAIN),
     70       STRING_TOKEN (STR_FORM_GOTO_MAIN),
     71       0,
     72       FORM_MAIN_ID
     73       );
     74   }
     75 
     76 }
     77 
     78 /**
     79   Create the "Apply changes" and "Discard changes" tags. And
     80   ensure user can return to the main page.
     81 
     82   @param CallbackData    The BMM context data.
     83 
     84 **/
     85 VOID
     86 UpdatePageEnd (
     87   IN BMM_CALLBACK_DATA                *CallbackData
     88   )
     89 {
     90   //
     91   // Create the "Apply changes" and "Discard changes" tags.
     92   //
     93   if (CallbackData->BmmAskSaveOrNot) {
     94     HiiCreateSubTitleOpCode (
     95       mStartOpCodeHandle,
     96       STRING_TOKEN (STR_NULL_STRING),
     97       0,
     98       0,
     99       0
    100       );
    101 
    102     HiiCreateActionOpCode (
    103       mStartOpCodeHandle,
    104       KEY_VALUE_SAVE_AND_EXIT,
    105       STRING_TOKEN (STR_SAVE_AND_EXIT),
    106       STRING_TOKEN (STR_NULL_STRING),
    107       EFI_IFR_FLAG_CALLBACK,
    108       0
    109       );
    110   }
    111 
    112   //
    113   // Ensure user can return to the main page.
    114   //
    115   HiiCreateActionOpCode (
    116     mStartOpCodeHandle,
    117     KEY_VALUE_NO_SAVE_AND_EXIT,
    118     STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
    119     STRING_TOKEN (STR_NULL_STRING),
    120     EFI_IFR_FLAG_CALLBACK,
    121     0
    122     );
    123 
    124   HiiUpdateForm (
    125     CallbackData->BmmHiiHandle,
    126     &gBootMaintFormSetGuid,
    127     CallbackData->BmmCurrentPageId,
    128     mStartOpCodeHandle, // Label CallbackData->BmmCurrentPageId
    129     mEndOpCodeHandle    // LABEL_END
    130     );
    131 }
    132 
    133 /**
    134   Clean up the dynamic opcode at label and form specified by both LabelId.
    135 
    136   @param LabelId         It is both the Form ID and Label ID for opcode deletion.
    137   @param CallbackData    The BMM context data.
    138 
    139 **/
    140 VOID
    141 CleanUpPage (
    142   IN UINT16                           LabelId,
    143   IN BMM_CALLBACK_DATA                *CallbackData
    144   )
    145 {
    146   RefreshUpdateData ();
    147 
    148   //
    149   // Remove all op-codes from dynamic page
    150   //
    151   mStartLabel->Number = LabelId;
    152   HiiUpdateForm (
    153     CallbackData->BmmHiiHandle,
    154     &gBootMaintFormSetGuid,
    155     LabelId,
    156     mStartOpCodeHandle, // Label LabelId
    157     mEndOpCodeHandle    // LABEL_END
    158     );
    159 }
    160 
    161 /**
    162   Boot a file selected by user at File Expoloer of BMM.
    163 
    164   @param FileContext     The file context data, which contains the device path
    165                          of the file to be boot from.
    166 
    167   @retval EFI_SUCCESS    The function completed successfull.
    168   @return Other value if the boot from the file fails.
    169 
    170 **/
    171 EFI_STATUS
    172 BootThisFile (
    173   IN BM_FILE_CONTEXT                   *FileContext
    174   )
    175 {
    176   EFI_STATUS        Status;
    177   UINTN             ExitDataSize;
    178   CHAR16            *ExitData;
    179   BDS_COMMON_OPTION *Option;
    180 
    181   Option = (BDS_COMMON_OPTION *) AllocatePool (sizeof (BDS_COMMON_OPTION));
    182   ASSERT (Option != NULL);
    183   Option->Description     = (CHAR16 *) AllocateCopyPool (StrSize (FileContext->FileName), FileContext->FileName);
    184   Option->DevicePath      = FileContext->DevicePath;
    185   Option->LoadOptionsSize = 0;
    186   Option->LoadOptions     = NULL;
    187 
    188   //
    189   // Since current no boot from removable media directly is allowed */
    190   //
    191   gST->ConOut->ClearScreen (gST->ConOut);
    192 
    193   ExitDataSize  = 0;
    194 
    195   Status        = BdsLibBootViaBootOption (Option, Option->DevicePath, &ExitDataSize, &ExitData);
    196 
    197   return Status;
    198 
    199 }
    200 
    201 /**
    202   Create a list of Goto Opcode for all terminal devices logged
    203   by TerminaMenu. This list will be inserted to form FORM_CON_COM_SETUP_ID.
    204 
    205   @param CallbackData    The BMM context data.
    206 **/
    207 VOID
    208 UpdateConCOMPage (
    209   IN BMM_CALLBACK_DATA                *CallbackData
    210   )
    211 {
    212   BM_MENU_ENTRY *NewMenuEntry;
    213   UINT16        Index;
    214 
    215   CallbackData->BmmAskSaveOrNot = FALSE;
    216 
    217   UpdatePageStart (CallbackData);
    218 
    219 
    220   for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    221     NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
    222 
    223     HiiCreateGotoOpCode (
    224       mStartOpCodeHandle,
    225       FORM_CON_COM_SETUP_ID,
    226       NewMenuEntry->DisplayStringToken,
    227       STRING_TOKEN (STR_NULL_STRING),
    228       EFI_IFR_FLAG_CALLBACK,
    229       (UINT16) (TERMINAL_OPTION_OFFSET + Index)
    230       );
    231   }
    232 
    233   UpdatePageEnd (CallbackData);
    234 }
    235 
    236 /**
    237   Create a lit of boot option from global BootOptionMenu. It
    238   allow user to delete the boot option.
    239 
    240   @param CallbackData    The BMM context data.
    241 
    242 **/
    243 VOID
    244 UpdateBootDelPage (
    245   IN BMM_CALLBACK_DATA                *CallbackData
    246   )
    247 {
    248   BM_MENU_ENTRY   *NewMenuEntry;
    249   BM_LOAD_CONTEXT *NewLoadContext;
    250   UINT16          Index;
    251 
    252   CallbackData->BmmAskSaveOrNot = TRUE;
    253 
    254   UpdatePageStart (CallbackData);
    255   CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);
    256 
    257   ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionDel) / sizeof (CallbackData->BmmFakeNvData.BootOptionDel[0])));
    258   for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
    259     NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
    260     NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
    261     if (NewLoadContext->IsLegacy) {
    262       continue;
    263     }
    264 
    265     NewLoadContext->Deleted = FALSE;
    266 
    267     if (CallbackData->BmmFakeNvData.BootOptionDel[Index] && !CallbackData->BmmFakeNvData.BootOptionDelMark[Index]) {
    268       //
    269       // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
    270       // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
    271       // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
    272       // through HiiSetBrowserData function.
    273       //
    274       CallbackData->BmmFakeNvData.BootOptionDel[Index] = FALSE;
    275     }
    276 
    277     HiiCreateCheckBoxOpCode (
    278       mStartOpCodeHandle,
    279       (EFI_QUESTION_ID) (BOOT_OPTION_DEL_QUESTION_ID + Index),
    280       VARSTORE_ID_BOOT_MAINT,
    281       (UINT16) (BOOT_OPTION_DEL_VAR_OFFSET + Index),
    282       NewMenuEntry->DisplayStringToken,
    283       NewMenuEntry->HelpStringToken,
    284       EFI_IFR_FLAG_CALLBACK,
    285       0,
    286       NULL
    287       );
    288   }
    289 
    290   UpdatePageEnd (CallbackData);
    291 }
    292 
    293 /**
    294   Create a lit of driver option from global DriverMenu.
    295 
    296   @param CallbackData    The BMM context data.
    297 
    298 **/
    299 VOID
    300 UpdateDrvAddHandlePage (
    301   IN BMM_CALLBACK_DATA                *CallbackData
    302   )
    303 {
    304   BM_MENU_ENTRY *NewMenuEntry;
    305   UINT16        Index;
    306 
    307   CallbackData->BmmAskSaveOrNot = FALSE;
    308 
    309   UpdatePageStart (CallbackData);
    310 
    311   for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {
    312     NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
    313 
    314     HiiCreateGotoOpCode (
    315       mStartOpCodeHandle,
    316       FORM_DRV_ADD_HANDLE_DESC_ID,
    317       NewMenuEntry->DisplayStringToken,
    318       STRING_TOKEN (STR_NULL_STRING),
    319       EFI_IFR_FLAG_CALLBACK,
    320       (UINT16) (HANDLE_OPTION_OFFSET + Index)
    321       );
    322   }
    323 
    324   UpdatePageEnd (CallbackData);
    325 }
    326 
    327 /**
    328   Create a lit of driver option from global DriverOptionMenu. It
    329   allow user to delete the driver option.
    330 
    331   @param CallbackData    The BMM context data.
    332 
    333 **/
    334 VOID
    335 UpdateDrvDelPage (
    336   IN BMM_CALLBACK_DATA                *CallbackData
    337   )
    338 {
    339   BM_MENU_ENTRY   *NewMenuEntry;
    340   BM_LOAD_CONTEXT *NewLoadContext;
    341   UINT16          Index;
    342 
    343   CallbackData->BmmAskSaveOrNot = TRUE;
    344 
    345   UpdatePageStart (CallbackData);
    346 
    347   CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &DriverOptionMenu);
    348 
    349   ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionDel) / sizeof (CallbackData->BmmFakeNvData.DriverOptionDel[0])));
    350   for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
    351     NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
    352 
    353     NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
    354     NewLoadContext->Deleted = FALSE;
    355 
    356     if (CallbackData->BmmFakeNvData.DriverOptionDel[Index] && !CallbackData->BmmFakeNvData.DriverOptionDelMark[Index]) {
    357       //
    358       // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
    359       // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
    360       // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
    361       // through HiiSetBrowserData function.
    362       //
    363       CallbackData->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
    364     }
    365 
    366     HiiCreateCheckBoxOpCode (
    367       mStartOpCodeHandle,
    368       (EFI_QUESTION_ID) (DRIVER_OPTION_DEL_QUESTION_ID + Index),
    369       VARSTORE_ID_BOOT_MAINT,
    370       (UINT16) (DRIVER_OPTION_DEL_VAR_OFFSET + Index),
    371       NewMenuEntry->DisplayStringToken,
    372       NewMenuEntry->HelpStringToken,
    373       EFI_IFR_FLAG_CALLBACK,
    374       0,
    375       NULL
    376       );
    377   }
    378 
    379   UpdatePageEnd (CallbackData);
    380 }
    381 
    382 /**
    383   Prepare the page to allow user to add description for
    384   a Driver Option.
    385 
    386   @param CallbackData    The BMM context data.
    387 
    388 **/
    389 VOID
    390 UpdateDriverAddHandleDescPage (
    391   IN BMM_CALLBACK_DATA                *CallbackData
    392   )
    393 {
    394   BM_MENU_ENTRY *NewMenuEntry;
    395 
    396   CallbackData->BmmFakeNvData.DriverAddActive          = 0x01;
    397   CallbackData->BmmFakeNvData.DriverAddForceReconnect  = 0x00;
    398   CallbackData->BmmAskSaveOrNot                        = TRUE;
    399   NewMenuEntry = CallbackData->MenuEntry;
    400 
    401   UpdatePageStart (CallbackData);
    402 
    403   HiiCreateSubTitleOpCode (
    404     mStartOpCodeHandle,
    405     NewMenuEntry->DisplayStringToken,
    406     0,
    407     0,
    408     0
    409     );
    410 
    411   HiiCreateStringOpCode (
    412     mStartOpCodeHandle,
    413     (EFI_QUESTION_ID) DRV_ADD_HANDLE_DESC_QUESTION_ID,
    414     VARSTORE_ID_BOOT_MAINT,
    415     DRV_ADD_HANDLE_DESC_VAR_OFFSET,
    416     STRING_TOKEN (STR_LOAD_OPTION_DESC),
    417     STRING_TOKEN (STR_NULL_STRING),
    418     0,
    419     0,
    420     6,
    421     75,
    422     NULL
    423     );
    424 
    425   HiiCreateCheckBoxOpCode (
    426     mStartOpCodeHandle,
    427     (EFI_QUESTION_ID) DRV_ADD_RECON_QUESTION_ID,
    428     VARSTORE_ID_BOOT_MAINT,
    429     DRV_ADD_RECON_VAR_OFFSET,
    430     STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
    431     STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
    432     0,
    433     0,
    434     NULL
    435     );
    436 
    437   HiiCreateStringOpCode (
    438     mStartOpCodeHandle,
    439     (EFI_QUESTION_ID) DRIVER_ADD_OPTION_QUESTION_ID,
    440     VARSTORE_ID_BOOT_MAINT,
    441     DRIVER_ADD_OPTION_VAR_OFFSET,
    442     STRING_TOKEN (STR_OPTIONAL_DATA),
    443     STRING_TOKEN (STR_NULL_STRING),
    444     0,
    445     0,
    446     6,
    447     75,
    448     NULL
    449     );
    450 
    451   UpdatePageEnd (CallbackData);
    452 }
    453 
    454 /**
    455   Update console page.
    456 
    457   @param UpdatePageId    The form ID to be updated.
    458   @param ConsoleMenu     The console menu list.
    459   @param CallbackData    The BMM context data.
    460 
    461 **/
    462 VOID
    463 UpdateConsolePage (
    464   IN UINT16                           UpdatePageId,
    465   IN BM_MENU_OPTION                   *ConsoleMenu,
    466   IN BMM_CALLBACK_DATA                *CallbackData
    467   )
    468 {
    469   BM_MENU_ENTRY       *NewMenuEntry;
    470   UINT16              Index;
    471   UINT8               CheckFlags;
    472   UINT8               *ConsoleCheck;
    473   EFI_QUESTION_ID     QuestionIdBase;
    474   UINT16              VariableOffsetBase;
    475 
    476   UpdatePageStart (CallbackData);
    477 
    478   ConsoleCheck       = NULL;
    479   QuestionIdBase     = 0;
    480   VariableOffsetBase = 0;
    481 
    482   switch (UpdatePageId) {
    483   case FORM_CON_IN_ID:
    484     ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];
    485     QuestionIdBase     = CON_IN_DEVICE_QUESTION_ID;
    486     VariableOffsetBase = CON_IN_DEVICE_VAR_OFFSET;
    487     break;
    488 
    489   case FORM_CON_OUT_ID:
    490     ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];
    491     QuestionIdBase     = CON_OUT_DEVICE_QUESTION_ID;
    492     VariableOffsetBase = CON_OUT_DEVICE_VAR_OFFSET;
    493     break;
    494 
    495   case FORM_CON_ERR_ID:
    496     ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];
    497     QuestionIdBase     = CON_ERR_DEVICE_QUESTION_ID;
    498     VariableOffsetBase = CON_ERR_DEVICE_VAR_OFFSET;
    499     break;
    500   }
    501   ASSERT (ConsoleCheck != NULL);
    502 
    503   for (Index = 0; ((Index < ConsoleMenu->MenuNumber) && \
    504        (Index < MAX_MENU_NUMBER)) ; Index++) {
    505     CheckFlags = 0;
    506     if (UpdatePageId != FORM_CON_ERR_ID) {
    507       CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
    508     }
    509     NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
    510     HiiCreateCheckBoxOpCode (
    511       mStartOpCodeHandle,
    512       (EFI_QUESTION_ID) (QuestionIdBase + Index),
    513       VARSTORE_ID_BOOT_MAINT,
    514       (UINT16) (VariableOffsetBase + Index),
    515       NewMenuEntry->DisplayStringToken,
    516       NewMenuEntry->HelpStringToken,
    517       0,
    518       CheckFlags,
    519       NULL
    520       );
    521   }
    522 
    523   UpdatePageEnd (CallbackData);
    524 }
    525 
    526 /**
    527   Update the page's NV Map if user has changed the order
    528   a list. This list can be Boot Order or Driver Order.
    529 
    530   @param UpdatePageId    The form ID to be updated.
    531   @param OptionMenu      The new list.
    532   @param CallbackData    The BMM context data.
    533 
    534 **/
    535 VOID
    536 UpdateOrderPage (
    537   IN UINT16                           UpdatePageId,
    538   IN BM_MENU_OPTION                   *OptionMenu,
    539   IN BMM_CALLBACK_DATA                *CallbackData
    540   )
    541 {
    542   BM_MENU_ENTRY     *NewMenuEntry;
    543   UINT16            Index;
    544   UINT16            OptionIndex;
    545   VOID              *OptionsOpCodeHandle;
    546   BOOLEAN           BootOptionFound;
    547   UINT32            *OptionOrder;
    548   EFI_QUESTION_ID   QuestionId;
    549   UINT16            VarOffset;
    550 
    551 
    552   UpdatePageStart (CallbackData);
    553 
    554   CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);
    555 
    556   OptionOrder = NULL;
    557   QuestionId = 0;
    558   VarOffset = 0;
    559   switch (UpdatePageId) {
    560 
    561   case FORM_BOOT_CHG_ID:
    562     //GetBootOrder (CallbackData);
    563     OptionOrder = CallbackData->BmmFakeNvData.BootOptionOrder;
    564     QuestionId = BOOT_OPTION_ORDER_QUESTION_ID;
    565     VarOffset = BOOT_OPTION_ORDER_VAR_OFFSET;
    566     break;
    567 
    568   case FORM_DRV_CHG_ID:
    569     //GetDriverOrder (CallbackData);
    570     OptionOrder = CallbackData->BmmFakeNvData.DriverOptionOrder;
    571     QuestionId = DRIVER_OPTION_ORDER_QUESTION_ID;
    572     VarOffset = DRIVER_OPTION_ORDER_VAR_OFFSET;
    573     break;
    574   }
    575   ASSERT (OptionOrder != NULL);
    576 
    577   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    578   ASSERT (OptionsOpCodeHandle != NULL);
    579 
    580   NewMenuEntry = NULL;
    581   for (OptionIndex = 0; (OptionIndex < MAX_MENU_NUMBER && OptionOrder[OptionIndex] != 0); OptionIndex++) {
    582     BootOptionFound = FALSE;
    583     for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
    584       NewMenuEntry   = BOpt_GetMenuEntry (OptionMenu, Index);
    585       if ((UINT32) (NewMenuEntry->OptionNumber + 1) == OptionOrder[OptionIndex]) {
    586         BootOptionFound = TRUE;
    587         break;
    588       }
    589     }
    590     if (BootOptionFound) {
    591       HiiCreateOneOfOptionOpCode (
    592         OptionsOpCodeHandle,
    593         NewMenuEntry->DisplayStringToken,
    594         0,
    595         EFI_IFR_TYPE_NUM_SIZE_32,
    596         OptionOrder[OptionIndex]
    597         );
    598     }
    599   }
    600 
    601   if (OptionMenu->MenuNumber > 0) {
    602     HiiCreateOrderedListOpCode (
    603       mStartOpCodeHandle,                          // Container for dynamic created opcodes
    604       QuestionId,                                  // Question ID
    605       VARSTORE_ID_BOOT_MAINT,                      // VarStore ID
    606       VarOffset,                                   // Offset in Buffer Storage
    607       STRING_TOKEN (STR_CHANGE_ORDER),             // Question prompt text
    608       STRING_TOKEN (STR_CHANGE_ORDER),             // Question help text
    609       0,                                           // Question flag
    610       0,                                           // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
    611       EFI_IFR_TYPE_NUM_SIZE_32,                    // Data type of Question value
    612       100,                                         // Maximum container
    613       OptionsOpCodeHandle,                         // Option Opcode list
    614       NULL                                         // Default Opcode is NULL
    615       );
    616   }
    617 
    618   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    619 
    620   UpdatePageEnd (CallbackData);
    621 }
    622 
    623 /**
    624   Create the dynamic page to allow user to set
    625   the "BootNext" value.
    626 
    627   @param CallbackData    The BMM context data.
    628 
    629 **/
    630 VOID
    631 UpdateBootNextPage (
    632   IN BMM_CALLBACK_DATA                *CallbackData
    633   )
    634 {
    635   BM_MENU_ENTRY   *NewMenuEntry;
    636   BM_LOAD_CONTEXT *NewLoadContext;
    637   UINTN           NumberOfOptions;
    638   UINT16          Index;
    639   VOID            *OptionsOpCodeHandle;
    640 
    641   NumberOfOptions               = BootOptionMenu.MenuNumber;
    642   CallbackData->BmmAskSaveOrNot = TRUE;
    643 
    644   UpdatePageStart (CallbackData);
    645   CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);
    646 
    647   if (NumberOfOptions > 0) {
    648     OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    649     ASSERT (OptionsOpCodeHandle != NULL);
    650 
    651     //CallbackData->BmmFakeNvData.BootNext = (UINT16) (BootOptionMenu.MenuNumber);
    652 
    653     for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
    654       NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
    655       NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
    656 
    657       if (NewLoadContext->IsBootNext) {
    658         HiiCreateOneOfOptionOpCode (
    659           OptionsOpCodeHandle,
    660           NewMenuEntry->DisplayStringToken,
    661           EFI_IFR_OPTION_DEFAULT,
    662           EFI_IFR_TYPE_NUM_SIZE_16,
    663           Index
    664           );
    665         //CallbackData->BmmFakeNvData.BootNext = Index;
    666       } else {
    667         HiiCreateOneOfOptionOpCode (
    668           OptionsOpCodeHandle,
    669           NewMenuEntry->DisplayStringToken,
    670           0,
    671           EFI_IFR_TYPE_NUM_SIZE_16,
    672           Index
    673           );
    674       }
    675     }
    676 
    677     if (CallbackData->BmmFakeNvData.BootNext == Index) {
    678       HiiCreateOneOfOptionOpCode (
    679         OptionsOpCodeHandle,
    680         STRING_TOKEN (STR_NONE),
    681         EFI_IFR_OPTION_DEFAULT,
    682         EFI_IFR_TYPE_NUM_SIZE_16,
    683         Index
    684         );
    685     } else {
    686       HiiCreateOneOfOptionOpCode (
    687         OptionsOpCodeHandle,
    688         STRING_TOKEN (STR_NONE),
    689         0,
    690         EFI_IFR_TYPE_NUM_SIZE_16,
    691         Index
    692         );
    693     }
    694 
    695     HiiCreateOneOfOpCode (
    696       mStartOpCodeHandle,
    697       (EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,
    698       VARSTORE_ID_BOOT_MAINT,
    699       BOOT_NEXT_VAR_OFFSET,
    700       STRING_TOKEN (STR_BOOT_NEXT),
    701       STRING_TOKEN (STR_BOOT_NEXT_HELP),
    702       0,
    703       EFI_IFR_NUMERIC_SIZE_2,
    704       OptionsOpCodeHandle,
    705       NULL
    706       );
    707 
    708     HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    709   }
    710 
    711   UpdatePageEnd (CallbackData);
    712 }
    713 
    714 /**
    715   Create the dynamic page to allow user to set the "TimeOut" value.
    716 
    717   @param CallbackData    The BMM context data.
    718 
    719 **/
    720 VOID
    721 UpdateTimeOutPage (
    722   IN BMM_CALLBACK_DATA                *CallbackData
    723   )
    724 {
    725   UINT16  BootTimeOut;
    726   VOID    *DefaultOpCodeHandle;
    727 
    728   CallbackData->BmmAskSaveOrNot = TRUE;
    729 
    730   UpdatePageStart (CallbackData);
    731 
    732   BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);
    733 
    734   DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
    735   ASSERT (DefaultOpCodeHandle != NULL);
    736   HiiCreateDefaultOpCode (DefaultOpCodeHandle, EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_NUM_SIZE_16, BootTimeOut);
    737 
    738   HiiCreateNumericOpCode (
    739     mStartOpCodeHandle,
    740     (EFI_QUESTION_ID) BOOT_TIME_OUT_QUESTION_ID,
    741     VARSTORE_ID_BOOT_MAINT,
    742     BOOT_TIME_OUT_VAR_OFFSET,
    743     STRING_TOKEN (STR_NUM_AUTO_BOOT),
    744     STRING_TOKEN (STR_HLP_AUTO_BOOT),
    745     0,
    746     EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,
    747     0,
    748     65535,
    749     0,
    750     DefaultOpCodeHandle
    751     );
    752 
    753   HiiFreeOpCodeHandle (DefaultOpCodeHandle);
    754 
    755   //CallbackData->BmmFakeNvData.BootTimeOut = BootTimeOut;
    756 
    757   UpdatePageEnd (CallbackData);
    758 }
    759 
    760 /**
    761   Refresh the text mode page.
    762 
    763   @param CallbackData    The BMM context data.
    764 
    765 **/
    766 VOID
    767 UpdateConModePage (
    768   IN BMM_CALLBACK_DATA                *CallbackData
    769   )
    770 {
    771   UINTN                         Mode;
    772   UINTN                         Index;
    773   UINTN                         Col;
    774   UINTN                         Row;
    775   CHAR16                        ModeString[50];
    776   CHAR16                        *PStr;
    777   UINTN                         MaxMode;
    778   UINTN                         ValidMode;
    779   EFI_STRING_ID                 *ModeToken;
    780   EFI_STATUS                    Status;
    781   VOID                          *OptionsOpCodeHandle;
    782   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;
    783 
    784   ConOut    = gST->ConOut;
    785   Index     = 0;
    786   ValidMode = 0;
    787   MaxMode   = (UINTN) (ConOut->Mode->MaxMode);
    788 
    789   CallbackData->BmmAskSaveOrNot = TRUE;
    790 
    791   UpdatePageStart (CallbackData);
    792 
    793   //
    794   // Check valid mode
    795   //
    796   for (Mode = 0; Mode < MaxMode; Mode++) {
    797     Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
    798     if (EFI_ERROR (Status)) {
    799       continue;
    800     }
    801     ValidMode++;
    802   }
    803 
    804   if (ValidMode == 0) {
    805     return;
    806   }
    807 
    808   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    809   ASSERT (OptionsOpCodeHandle != NULL);
    810 
    811   ModeToken           = AllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode);
    812   ASSERT(ModeToken != NULL);
    813 
    814   //
    815   // Determin which mode should be the first entry in menu
    816   //
    817   // GetConsoleOutMode (CallbackData);
    818 
    819   //
    820   // Build text mode options
    821   //
    822   for (Mode = 0; Mode < MaxMode; Mode++) {
    823     Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
    824     if (EFI_ERROR (Status)) {
    825       continue;
    826     }
    827 
    828     //
    829     // Build mode string Column x Row
    830     //
    831     UnicodeValueToString (ModeString, 0, Col, 0);
    832     PStr = &ModeString[0];
    833     StrCatS (PStr, sizeof (ModeString) / sizeof (ModeString[0]), L" x ");
    834     PStr = PStr + StrLen (PStr);
    835     UnicodeValueToString (PStr , 0, Row, 0);
    836 
    837     ModeToken[Index] = HiiSetString (CallbackData->BmmHiiHandle, 0, ModeString, NULL);
    838 
    839     if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) {
    840       HiiCreateOneOfOptionOpCode (
    841         OptionsOpCodeHandle,
    842         ModeToken[Index],
    843         EFI_IFR_OPTION_DEFAULT,
    844         EFI_IFR_TYPE_NUM_SIZE_16,
    845         (UINT16) Mode
    846         );
    847     } else {
    848       HiiCreateOneOfOptionOpCode (
    849         OptionsOpCodeHandle,
    850         ModeToken[Index],
    851         0,
    852         EFI_IFR_TYPE_NUM_SIZE_16,
    853         (UINT16) Mode
    854         );
    855     }
    856     Index++;
    857   }
    858 
    859   HiiCreateOneOfOpCode (
    860     mStartOpCodeHandle,
    861     (EFI_QUESTION_ID) CON_MODE_QUESTION_ID,
    862     VARSTORE_ID_BOOT_MAINT,
    863     CON_MODE_VAR_OFFSET,
    864     STRING_TOKEN (STR_CON_MODE_SETUP),
    865     STRING_TOKEN (STR_CON_MODE_SETUP),
    866     EFI_IFR_FLAG_RESET_REQUIRED,
    867     EFI_IFR_NUMERIC_SIZE_2,
    868     OptionsOpCodeHandle,
    869     NULL
    870     );
    871 
    872   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    873   FreePool (ModeToken);
    874 
    875   UpdatePageEnd (CallbackData);
    876 }
    877 
    878 /**
    879   Create the dynamic page which allows user to set the property such as Baud Rate, Data Bits,
    880   Parity, Stop Bits, Terminal Type.
    881 
    882   @param CallbackData    The BMM context data.
    883 
    884 **/
    885 VOID
    886 UpdateTerminalPage (
    887   IN BMM_CALLBACK_DATA                *CallbackData
    888   )
    889 {
    890   UINT8               Index;
    891   UINT8               CheckFlags;
    892   BM_MENU_ENTRY       *NewMenuEntry;
    893   VOID                *OptionsOpCodeHandle;
    894   UINTN               CurrentTerminal;
    895 
    896   UpdatePageStart (CallbackData);
    897 
    898   CurrentTerminal = CallbackData->CurrentTerminal;
    899   NewMenuEntry = BOpt_GetMenuEntry (
    900                   &TerminalMenu,
    901                   CurrentTerminal
    902                   );
    903 
    904   if (NewMenuEntry == NULL) {
    905     return ;
    906   }
    907 
    908   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    909   ASSERT (OptionsOpCodeHandle != NULL);
    910 
    911   for (Index = 0; Index < sizeof (BaudRateList) / sizeof (BaudRateList [0]); Index++) {
    912     CheckFlags = 0;
    913     if (BaudRateList[Index].Value == 115200) {
    914       CheckFlags |= EFI_IFR_OPTION_DEFAULT;
    915     }
    916     HiiCreateOneOfOptionOpCode (
    917       OptionsOpCodeHandle,
    918       BaudRateList[Index].StringToken,
    919       CheckFlags,
    920       EFI_IFR_TYPE_NUM_SIZE_8,
    921       Index
    922       );
    923   }
    924 
    925   HiiCreateOneOfOpCode (
    926     mStartOpCodeHandle,
    927     (EFI_QUESTION_ID) (COM_BAUD_RATE_QUESTION_ID + CurrentTerminal),
    928     VARSTORE_ID_BOOT_MAINT,
    929     (UINT16) (COM_BAUD_RATE_VAR_OFFSET + CurrentTerminal),
    930     STRING_TOKEN (STR_COM_BAUD_RATE),
    931     STRING_TOKEN (STR_COM_BAUD_RATE),
    932     0,
    933     EFI_IFR_NUMERIC_SIZE_1,
    934     OptionsOpCodeHandle,
    935     NULL
    936     );
    937 
    938   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    939   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    940   ASSERT (OptionsOpCodeHandle != NULL);
    941 
    942   for (Index = 0; Index < sizeof (DataBitsList) / sizeof (DataBitsList[0]); Index++) {
    943     CheckFlags = 0;
    944 
    945     if (DataBitsList[Index].Value == 8) {
    946       CheckFlags |= EFI_IFR_OPTION_DEFAULT;
    947     }
    948 
    949     HiiCreateOneOfOptionOpCode (
    950       OptionsOpCodeHandle,
    951       DataBitsList[Index].StringToken,
    952       CheckFlags,
    953       EFI_IFR_TYPE_NUM_SIZE_8,
    954       Index
    955       );
    956   }
    957 
    958   HiiCreateOneOfOpCode (
    959     mStartOpCodeHandle,
    960     (EFI_QUESTION_ID) (COM_DATA_RATE_QUESTION_ID + CurrentTerminal),
    961     VARSTORE_ID_BOOT_MAINT,
    962     (UINT16) (COM_DATA_RATE_VAR_OFFSET + CurrentTerminal),
    963     STRING_TOKEN (STR_COM_DATA_BITS),
    964     STRING_TOKEN (STR_COM_DATA_BITS),
    965     0,
    966     EFI_IFR_NUMERIC_SIZE_1,
    967     OptionsOpCodeHandle,
    968     NULL
    969     );
    970 
    971   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    972   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    973   ASSERT (OptionsOpCodeHandle != NULL);
    974 
    975   for (Index = 0; Index < sizeof (ParityList) / sizeof (ParityList[0]); Index++) {
    976     CheckFlags = 0;
    977     if (ParityList[Index].Value ==  NoParity) {
    978       CheckFlags |= EFI_IFR_OPTION_DEFAULT;
    979     }
    980 
    981     HiiCreateOneOfOptionOpCode (
    982       OptionsOpCodeHandle,
    983       ParityList[Index].StringToken,
    984       CheckFlags,
    985       EFI_IFR_TYPE_NUM_SIZE_8,
    986       Index
    987       );
    988   }
    989 
    990   HiiCreateOneOfOpCode (
    991     mStartOpCodeHandle,
    992     (EFI_QUESTION_ID) (COM_PARITY_QUESTION_ID + CurrentTerminal),
    993     VARSTORE_ID_BOOT_MAINT,
    994     (UINT16) (COM_PARITY_VAR_OFFSET + CurrentTerminal),
    995     STRING_TOKEN (STR_COM_PARITY),
    996     STRING_TOKEN (STR_COM_PARITY),
    997     0,
    998     EFI_IFR_NUMERIC_SIZE_1,
    999     OptionsOpCodeHandle,
   1000     NULL
   1001     );
   1002 
   1003   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1004   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
   1005   ASSERT (OptionsOpCodeHandle != NULL);
   1006 
   1007   for (Index = 0; Index < sizeof (StopBitsList) / sizeof (StopBitsList[0]); Index++) {
   1008     CheckFlags = 0;
   1009     if (StopBitsList[Index].Value == OneStopBit) {
   1010       CheckFlags |= EFI_IFR_OPTION_DEFAULT;
   1011     }
   1012 
   1013     HiiCreateOneOfOptionOpCode (
   1014       OptionsOpCodeHandle,
   1015       StopBitsList[Index].StringToken,
   1016       CheckFlags,
   1017       EFI_IFR_TYPE_NUM_SIZE_8,
   1018       Index
   1019       );
   1020   }
   1021 
   1022   HiiCreateOneOfOpCode (
   1023     mStartOpCodeHandle,
   1024     (EFI_QUESTION_ID) (COM_STOP_BITS_QUESTION_ID + CurrentTerminal),
   1025     VARSTORE_ID_BOOT_MAINT,
   1026     (UINT16) (COM_STOP_BITS_VAR_OFFSET + CurrentTerminal),
   1027     STRING_TOKEN (STR_COM_STOP_BITS),
   1028     STRING_TOKEN (STR_COM_STOP_BITS),
   1029     0,
   1030     EFI_IFR_NUMERIC_SIZE_1,
   1031     OptionsOpCodeHandle,
   1032     NULL
   1033     );
   1034 
   1035   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1036   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
   1037   ASSERT (OptionsOpCodeHandle != NULL);
   1038 
   1039   for (Index = 0; Index < 4; Index++) {
   1040     CheckFlags = 0;
   1041     if (Index == 0) {
   1042       CheckFlags |= EFI_IFR_OPTION_DEFAULT;
   1043     }
   1044 
   1045     HiiCreateOneOfOptionOpCode (
   1046       OptionsOpCodeHandle,
   1047       (EFI_STRING_ID) TerminalType[Index],
   1048       CheckFlags,
   1049       EFI_IFR_TYPE_NUM_SIZE_8,
   1050       Index
   1051       );
   1052   }
   1053 
   1054   HiiCreateOneOfOpCode (
   1055     mStartOpCodeHandle,
   1056     (EFI_QUESTION_ID) (COM_TERMINAL_QUESTION_ID + CurrentTerminal),
   1057     VARSTORE_ID_BOOT_MAINT,
   1058     (UINT16) (COM_TERMINAL_VAR_OFFSET + CurrentTerminal),
   1059     STRING_TOKEN (STR_COM_TERMI_TYPE),
   1060     STRING_TOKEN (STR_COM_TERMI_TYPE),
   1061     0,
   1062     EFI_IFR_NUMERIC_SIZE_1,
   1063     OptionsOpCodeHandle,
   1064     NULL
   1065     );
   1066 
   1067   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1068   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
   1069   ASSERT (OptionsOpCodeHandle != NULL);
   1070 
   1071   for (Index = 0; Index < sizeof (mFlowControlType) / sizeof (mFlowControlType[0]); Index++) {
   1072   CheckFlags = 0;
   1073     if (Index == 0) {
   1074       CheckFlags |= EFI_IFR_OPTION_DEFAULT;
   1075     }
   1076     HiiCreateOneOfOptionOpCode (
   1077       OptionsOpCodeHandle,
   1078       (EFI_STRING_ID) mFlowControlType[Index],
   1079       CheckFlags,
   1080       EFI_IFR_TYPE_NUM_SIZE_8,
   1081       mFlowControlValue[Index]
   1082       );
   1083   }
   1084 
   1085   HiiCreateOneOfOpCode (
   1086     mStartOpCodeHandle,
   1087     (EFI_QUESTION_ID) (COM_FLOWCONTROL_QUESTION_ID + CurrentTerminal),
   1088     VARSTORE_ID_BOOT_MAINT,
   1089     (UINT16) (COM_FLOWCONTROL_VAR_OFFSET + CurrentTerminal),
   1090     STRING_TOKEN (STR_COM_FLOW_CONTROL),
   1091     STRING_TOKEN (STR_COM_FLOW_CONTROL),
   1092     0,
   1093     EFI_IFR_NUMERIC_SIZE_1,
   1094     OptionsOpCodeHandle,
   1095     NULL
   1096     );
   1097 
   1098   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1099 
   1100   UpdatePageEnd (CallbackData);
   1101 }
   1102 
   1103 /**
   1104   Dispatch the correct update page function to call based on
   1105   the UpdatePageId.
   1106 
   1107   @param UpdatePageId    The form ID.
   1108   @param CallbackData    The BMM context data.
   1109 
   1110 **/
   1111 VOID
   1112 UpdatePageBody (
   1113   IN UINT16                           UpdatePageId,
   1114   IN BMM_CALLBACK_DATA                *CallbackData
   1115   )
   1116 {
   1117   CleanUpPage (UpdatePageId, CallbackData);
   1118   switch (UpdatePageId) {
   1119   case FORM_CON_IN_ID:
   1120     UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);
   1121     break;
   1122 
   1123   case FORM_CON_OUT_ID:
   1124     UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);
   1125     break;
   1126 
   1127   case FORM_CON_ERR_ID:
   1128     UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);
   1129     break;
   1130 
   1131   case FORM_BOOT_CHG_ID:
   1132     UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);
   1133     break;
   1134 
   1135   case FORM_DRV_CHG_ID:
   1136     UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);
   1137     break;
   1138 
   1139   default:
   1140     break;
   1141   }
   1142 }
   1143 
   1144 /**
   1145   Create a dynamic page so that Legacy Device boot order
   1146   can be set for specified device type.
   1147 
   1148   @param UpdatePageId    The form ID. It also spefies the legacy device type.
   1149   @param CallbackData    The BMM context data.
   1150 
   1151 
   1152 **/
   1153 VOID
   1154 UpdateSetLegacyDeviceOrderPage (
   1155   IN UINT16                           UpdatePageId,
   1156   IN BMM_CALLBACK_DATA                *CallbackData
   1157   )
   1158 {
   1159   LEGACY_DEV_ORDER_ENTRY      *DevOrder;
   1160   BM_MENU_OPTION              *OptionMenu;
   1161   BM_MENU_ENTRY               *NewMenuEntry;
   1162   EFI_STRING_ID               StrRef;
   1163   EFI_STRING_ID               StrRefHelp;
   1164   BBS_TYPE                    BbsType;
   1165   UINTN                       VarSize;
   1166   UINTN                       Pos;
   1167   UINTN                       Bit;
   1168   UINT16                      Index;
   1169   UINT16                      Key;
   1170   CHAR16                      String[100];
   1171   CHAR16                      *TypeStr;
   1172   CHAR16                      *TypeStrHelp;
   1173   UINT16                      VarDevOrder;
   1174   UINT8                       *VarData;
   1175   UINT8                       *LegacyOrder;
   1176   UINT8                       *OldData;
   1177   UINT8                       *DisMap;
   1178   VOID                        *OptionsOpCodeHandle;
   1179 
   1180   OptionMenu = NULL;
   1181   Key = 0;
   1182   StrRef = 0;
   1183   StrRefHelp = 0;
   1184   TypeStr = NULL;
   1185   TypeStrHelp = NULL;
   1186   BbsType = BBS_FLOPPY;
   1187   LegacyOrder = NULL;
   1188   OldData = NULL;
   1189   DisMap = NULL;
   1190 
   1191   CallbackData->BmmAskSaveOrNot = TRUE;
   1192   UpdatePageStart (CallbackData);
   1193 
   1194   DisMap = ZeroMem (CallbackData->BmmOldFakeNVData.DisableMap, sizeof (CallbackData->BmmOldFakeNVData.DisableMap));
   1195 
   1196   //
   1197   // Create oneof option list
   1198   //
   1199   switch (UpdatePageId) {
   1200   case FORM_SET_FD_ORDER_ID:
   1201     OptionMenu  = (BM_MENU_OPTION *) &LegacyFDMenu;
   1202     Key         = (UINT16) LEGACY_FD_QUESTION_ID;
   1203     TypeStr     = STR_FLOPPY;
   1204     TypeStrHelp = STR_FLOPPY_HELP;
   1205     BbsType     = BBS_FLOPPY;
   1206     LegacyOrder = CallbackData->BmmFakeNvData.LegacyFD;
   1207     OldData     = CallbackData->BmmOldFakeNVData.LegacyFD;
   1208     break;
   1209 
   1210   case FORM_SET_HD_ORDER_ID:
   1211     OptionMenu  = (BM_MENU_OPTION *) &LegacyHDMenu;
   1212     Key         = (UINT16) LEGACY_HD_QUESTION_ID;
   1213     TypeStr     = STR_HARDDISK;
   1214     TypeStrHelp = STR_HARDDISK_HELP;
   1215     BbsType     = BBS_HARDDISK;
   1216     LegacyOrder = CallbackData->BmmFakeNvData.LegacyHD;
   1217     OldData     = CallbackData->BmmOldFakeNVData.LegacyHD;
   1218     break;
   1219 
   1220   case FORM_SET_CD_ORDER_ID:
   1221     OptionMenu  = (BM_MENU_OPTION *) &LegacyCDMenu;
   1222     Key         = (UINT16) LEGACY_CD_QUESTION_ID;
   1223     TypeStr     = STR_CDROM;
   1224     TypeStrHelp = STR_CDROM_HELP;
   1225     BbsType     = BBS_CDROM;
   1226     LegacyOrder = CallbackData->BmmFakeNvData.LegacyCD;
   1227     OldData     = CallbackData->BmmOldFakeNVData.LegacyCD;
   1228     break;
   1229 
   1230   case FORM_SET_NET_ORDER_ID:
   1231     OptionMenu  = (BM_MENU_OPTION *) &LegacyNETMenu;
   1232     Key         = (UINT16) LEGACY_NET_QUESTION_ID;
   1233     TypeStr     = STR_NET;
   1234     TypeStrHelp = STR_NET_HELP;
   1235     BbsType     = BBS_EMBED_NETWORK;
   1236     LegacyOrder = CallbackData->BmmFakeNvData.LegacyNET;
   1237     OldData     = CallbackData->BmmOldFakeNVData.LegacyNET;
   1238     break;
   1239 
   1240   case FORM_SET_BEV_ORDER_ID:
   1241     OptionMenu  = (BM_MENU_OPTION *) &LegacyBEVMenu;
   1242     Key         = (UINT16) LEGACY_BEV_QUESTION_ID;
   1243     TypeStr     = STR_BEV;
   1244     TypeStrHelp = STR_BEV_HELP;
   1245     BbsType     = BBS_BEV_DEVICE;
   1246     LegacyOrder = CallbackData->BmmFakeNvData.LegacyBEV;
   1247     OldData     = CallbackData->BmmOldFakeNVData.LegacyBEV;
   1248     break;
   1249 
   1250   default:
   1251     DEBUG ((EFI_D_ERROR, "Invalid command ID for updating page!\n"));
   1252     return;
   1253   }
   1254 
   1255   CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);
   1256 
   1257   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
   1258   ASSERT (OptionsOpCodeHandle != NULL);
   1259 
   1260   for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
   1261     NewMenuEntry                = BOpt_GetMenuEntry (OptionMenu, Index);
   1262     //
   1263     // Create OneOf for each legacy device
   1264     //
   1265     HiiCreateOneOfOptionOpCode (
   1266       OptionsOpCodeHandle,
   1267       NewMenuEntry->DisplayStringToken,
   1268       0,
   1269       EFI_IFR_TYPE_NUM_SIZE_8,
   1270       (UINT8) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->BbsIndex
   1271       );
   1272   }
   1273 
   1274   //
   1275   // Create OneOf for item "Disabled"
   1276   //
   1277   HiiCreateOneOfOptionOpCode (
   1278     OptionsOpCodeHandle,
   1279     STRING_TOKEN (STR_DISABLE_LEGACY_DEVICE),
   1280     0,
   1281     EFI_IFR_TYPE_NUM_SIZE_8,
   1282     0xFF
   1283     );
   1284 
   1285   //
   1286   // Get Device Order from variable
   1287   //
   1288   VarData = BdsLibGetVariableAndSize (
   1289               VAR_LEGACY_DEV_ORDER,
   1290               &gEfiLegacyDevOrderVariableGuid,
   1291               &VarSize
   1292               );
   1293 
   1294   if (NULL != VarData) {
   1295     DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) VarData;
   1296     while (VarData < VarData + VarSize) {
   1297       if (DevOrder->BbsType == BbsType) {
   1298         break;
   1299       }
   1300 
   1301       VarData  = (UINT8 *)((UINTN)VarData + sizeof (BBS_TYPE));
   1302       VarData += *(UINT16 *) VarData;
   1303       DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
   1304     }
   1305     //
   1306     // Create oneof tag here for FD/HD/CD #1 #2
   1307     //
   1308     for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
   1309       //
   1310       // Create the string for oneof tag
   1311       //
   1312       UnicodeSPrint (String, sizeof (String), TypeStr, Index);
   1313       StrRef = HiiSetString (CallbackData->BmmHiiHandle, 0, String, NULL);
   1314 
   1315       UnicodeSPrint (String, sizeof (String), TypeStrHelp, Index);
   1316       StrRefHelp = HiiSetString (CallbackData->BmmHiiHandle, 0, String, NULL);
   1317 
   1318       HiiCreateOneOfOpCode (
   1319         mStartOpCodeHandle,
   1320         (EFI_QUESTION_ID) (Key + Index),
   1321         VARSTORE_ID_BOOT_MAINT,
   1322         (UINT16) (Key + Index - CONFIG_OPTION_OFFSET),
   1323         StrRef,
   1324         StrRefHelp,
   1325         EFI_IFR_FLAG_CALLBACK,
   1326         EFI_IFR_NUMERIC_SIZE_1,
   1327         OptionsOpCodeHandle,
   1328         NULL
   1329         );
   1330 
   1331       VarDevOrder = *(UINT16 *) ((UINTN) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index * sizeof (UINT16));
   1332 
   1333       if (0xFF00 == (VarDevOrder & 0xFF00)) {
   1334         LegacyOrder[Index]  = 0xFF;
   1335         Pos                 = (VarDevOrder & 0xFF) / 8;
   1336         Bit                 = 7 - ((VarDevOrder & 0xFF) % 8);
   1337         DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
   1338       } else {
   1339         LegacyOrder[Index] = (UINT8) (VarDevOrder & 0xFF);
   1340       }
   1341     }
   1342   }
   1343 
   1344   CopyMem (OldData, LegacyOrder, 100);
   1345 
   1346   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1347 
   1348   UpdatePageEnd (CallbackData);
   1349 }
   1350 
   1351 
   1352 /**
   1353   Dispatch the display to the next page based on NewPageId.
   1354 
   1355   @param Private         The BMM context data.
   1356   @param NewPageId       The original page ID.
   1357 
   1358 **/
   1359 VOID
   1360 UpdatePageId (
   1361   BMM_CALLBACK_DATA              *Private,
   1362   UINT16                         NewPageId
   1363   )
   1364 {
   1365   //
   1366   // For the question don't impact the page update, just ignore it.
   1367   //
   1368   if (((NewPageId >= BOOT_OPTION_DEL_QUESTION_ID) && (NewPageId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) ||
   1369       ((NewPageId >= DRIVER_OPTION_DEL_QUESTION_ID) && (NewPageId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER))) {
   1370     return;
   1371   }
   1372 
   1373   if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {
   1374     //
   1375     // If we select a handle to add driver option, advance to the add handle description page.
   1376     //
   1377     NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;
   1378   } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {
   1379     //
   1380     // Return to main page after "Save Changes" or "Discard Changes".
   1381     //
   1382     NewPageId = FORM_MAIN_ID;
   1383   } else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) {
   1384     NewPageId = FORM_CON_COM_SETUP_ID;
   1385   }
   1386 
   1387   if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
   1388     Private->BmmPreviousPageId  = Private->BmmCurrentPageId;
   1389     Private->BmmCurrentPageId   = NewPageId;
   1390   }
   1391 }
   1392