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
RefreshUpdateData(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
UpdatePageStart(IN BMM_CALLBACK_DATA * CallbackData)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
UpdatePageEnd(IN BMM_CALLBACK_DATA * CallbackData)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
CleanUpPage(IN UINT16 LabelId,IN BMM_CALLBACK_DATA * CallbackData)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
BootThisFile(IN BM_FILE_CONTEXT * FileContext)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
UpdateConCOMPage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateBootDelPage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateDrvAddHandlePage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateDrvDelPage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateDriverAddHandleDescPage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateConsolePage(IN UINT16 UpdatePageId,IN BM_MENU_OPTION * ConsoleMenu,IN BMM_CALLBACK_DATA * CallbackData)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
UpdateOrderPage(IN UINT16 UpdatePageId,IN BM_MENU_OPTION * OptionMenu,IN BMM_CALLBACK_DATA * CallbackData)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
UpdateBootNextPage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateTimeOutPage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateConModePage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdateTerminalPage(IN BMM_CALLBACK_DATA * CallbackData)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
UpdatePageBody(IN UINT16 UpdatePageId,IN BMM_CALLBACK_DATA * CallbackData)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
UpdateSetLegacyDeviceOrderPage(IN UINT16 UpdatePageId,IN BMM_CALLBACK_DATA * CallbackData)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
UpdatePageId(BMM_CALLBACK_DATA * Private,UINT16 NewPageId)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