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