]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Application/UiApp/BootMaint/UpdatePage.c
MdeModulePkg:Create Boot Maintenance Manager Library
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / BootMaint / UpdatePage.c
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 &mBootMaintGuid,
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 &mBootMaintGuid,
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_BOOT_MANAGER_LOAD_OPTION BootOption;
177
178 EfiBootManagerInitializeLoadOption (
179 &BootOption,
180 0,
181 LoadOptionTypeBoot,
182 LOAD_OPTION_ACTIVE,
183 FileContext->FileName,
184 FileContext->DevicePath,
185 NULL,
186 0
187 );
188 //
189 // Since current no boot from removable media directly is allowed */
190 //
191 gST->ConOut->ClearScreen (gST->ConOut);
192
193 BdsSetConsoleMode (FALSE);
194 EfiBootManagerBoot (&BootOption);
195 BdsSetConsoleMode (TRUE);
196
197 EfiBootManagerFreeLoadOption (&BootOption);
198
199 return BootOption.Status;
200
201 }
202
203 /**
204 Create a list of Goto Opcode for all terminal devices logged
205 by TerminaMenu. This list will be inserted to form FORM_CON_COM_SETUP_ID.
206
207 @param CallbackData The BMM context data.
208 **/
209 VOID
210 UpdateConCOMPage (
211 IN BMM_CALLBACK_DATA *CallbackData
212 )
213 {
214 BM_MENU_ENTRY *NewMenuEntry;
215 UINT16 Index;
216
217 CallbackData->BmmAskSaveOrNot = TRUE;
218
219 UpdatePageStart (CallbackData);
220
221 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
222 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
223
224 HiiCreateGotoOpCode (
225 mStartOpCodeHandle,
226 FORM_CON_COM_SETUP_ID,
227 NewMenuEntry->DisplayStringToken,
228 STRING_TOKEN (STR_NULL_STRING),
229 EFI_IFR_FLAG_CALLBACK,
230 (UINT16) (TERMINAL_OPTION_OFFSET + Index)
231 );
232 }
233
234 UpdatePageEnd (CallbackData);
235 }
236
237
238 /**
239 Create a list of boot option from global BootOptionMenu. It
240 allow user to delete the boot option.
241
242 @param CallbackData The BMM context data.
243
244 **/
245 VOID
246 UpdateBootDelPage (
247 IN BMM_CALLBACK_DATA *CallbackData
248 )
249 {
250 BM_MENU_ENTRY *NewMenuEntry;
251 BM_LOAD_CONTEXT *NewLoadContext;
252 UINT16 Index;
253
254 CallbackData->BmmAskSaveOrNot = TRUE;
255
256 UpdatePageStart (CallbackData);
257 CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);
258
259 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionDel) / sizeof (CallbackData->BmmFakeNvData.BootOptionDel[0])));
260 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
261 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
262 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
263 if (NewLoadContext->IsLegacy) {
264 continue;
265 }
266
267 NewLoadContext->Deleted = FALSE;
268
269 if (CallbackData->BmmFakeNvData.BootOptionDel[Index] && !CallbackData->BmmFakeNvData.BootOptionDelMark[Index]) {
270 //
271 // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
272 // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
273 // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
274 // through HiiSetBrowserData function.
275 //
276 CallbackData->BmmFakeNvData.BootOptionDel[Index] = FALSE;
277 }
278
279 //
280 // Check to see if the current boot option devicepath is the ShellDevice
281 // path. If it is keep only UEFI Shell in the delete boot option list
282 // or else continue
283 //
284 //if ((NULL != NewLoadContext->FilePathList) && (TRUE == IsShellNodeDevicePath(NewLoadContext->FilePathList))) {
285 // NewLoadContext->Deleted = FALSE;
286 // CallbackData->BmmFakeNvData.OptionDel[Index] = FALSE;
287
288 HiiCreateCheckBoxOpCode (
289 mStartOpCodeHandle,
290 (EFI_QUESTION_ID) (BOOT_OPTION_DEL_QUESTION_ID + Index),
291 VARSTORE_ID_BOOT_MAINT,
292 (UINT16) (BOOT_OPTION_DEL_VAR_OFFSET + Index),
293 NewMenuEntry->DisplayStringToken,
294 NewMenuEntry->HelpStringToken,
295 EFI_IFR_FLAG_CALLBACK,
296 0,
297 NULL
298 );
299 //} else {
300 // continue;
301 //}
302 }
303 UpdatePageEnd (CallbackData);
304 }
305
306 /**
307 Create a lit of driver option from global DriverMenu.
308
309 @param CallbackData The BMM context data.
310
311 **/
312 VOID
313 UpdateDrvAddHandlePage (
314 IN BMM_CALLBACK_DATA *CallbackData
315 )
316 {
317 BM_MENU_ENTRY *NewMenuEntry;
318 UINT16 Index;
319
320 CallbackData->BmmAskSaveOrNot = FALSE;
321
322 UpdatePageStart (CallbackData);
323
324 for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {
325 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
326
327 HiiCreateGotoOpCode (
328 mStartOpCodeHandle,
329 FORM_DRV_ADD_HANDLE_DESC_ID,
330 NewMenuEntry->DisplayStringToken,
331 STRING_TOKEN (STR_NULL_STRING),
332 EFI_IFR_FLAG_CALLBACK,
333 (UINT16) (HANDLE_OPTION_OFFSET + Index)
334 );
335 }
336
337 UpdatePageEnd (CallbackData);
338 }
339
340 /**
341 Create a lit of driver option from global DriverOptionMenu. It
342 allow user to delete the driver option.
343
344 @param CallbackData The BMM context data.
345
346 **/
347 VOID
348 UpdateDrvDelPage (
349 IN BMM_CALLBACK_DATA *CallbackData
350 )
351 {
352 BM_MENU_ENTRY *NewMenuEntry;
353 BM_LOAD_CONTEXT *NewLoadContext;
354 UINT16 Index;
355
356 CallbackData->BmmAskSaveOrNot = TRUE;
357
358 UpdatePageStart (CallbackData);
359
360 CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &DriverOptionMenu);
361
362 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionDel) / sizeof (CallbackData->BmmFakeNvData.DriverOptionDel[0])));
363 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
364 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
365
366 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
367 NewLoadContext->Deleted = FALSE;
368
369 if (CallbackData->BmmFakeNvData.DriverOptionDel[Index] && !CallbackData->BmmFakeNvData.DriverOptionDelMark[Index]) {
370 //
371 // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
372 // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
373 // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
374 // through HiiSetBrowserData function.
375 //
376 CallbackData->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
377 }
378 HiiCreateCheckBoxOpCode (
379 mStartOpCodeHandle,
380 (EFI_QUESTION_ID) (DRIVER_OPTION_DEL_QUESTION_ID + Index),
381 VARSTORE_ID_BOOT_MAINT,
382 (UINT16) (DRIVER_OPTION_DEL_VAR_OFFSET + Index),
383 NewMenuEntry->DisplayStringToken,
384 NewMenuEntry->HelpStringToken,
385 EFI_IFR_FLAG_CALLBACK,
386 0,
387 NULL
388 );
389 }
390
391 UpdatePageEnd (CallbackData);
392 }
393
394 /**
395 Prepare the page to allow user to add description for
396 a Driver Option.
397
398 @param CallbackData The BMM context data.
399
400 **/
401 VOID
402 UpdateDriverAddHandleDescPage (
403 IN BMM_CALLBACK_DATA *CallbackData
404 )
405 {
406 BM_MENU_ENTRY *NewMenuEntry;
407
408 CallbackData->BmmFakeNvData.DriverAddActive = 0x01;
409 CallbackData->BmmFakeNvData.DriverAddForceReconnect = 0x00;
410 CallbackData->BmmAskSaveOrNot = TRUE;
411 NewMenuEntry = CallbackData->MenuEntry;
412
413 UpdatePageStart (CallbackData);
414
415 HiiCreateSubTitleOpCode (
416 mStartOpCodeHandle,
417 NewMenuEntry->DisplayStringToken,
418 0,
419 0,
420 0
421 );
422
423 HiiCreateStringOpCode (
424 mStartOpCodeHandle,
425 (EFI_QUESTION_ID) DRV_ADD_HANDLE_DESC_QUESTION_ID,
426 VARSTORE_ID_BOOT_MAINT,
427 DRV_ADD_HANDLE_DESC_VAR_OFFSET,
428 STRING_TOKEN (STR_LOAD_OPTION_DESC),
429 STRING_TOKEN (STR_NULL_STRING),
430 0,
431 0,
432 6,
433 75,
434 NULL
435 );
436
437 HiiCreateCheckBoxOpCode (
438 mStartOpCodeHandle,
439 (EFI_QUESTION_ID) DRV_ADD_RECON_QUESTION_ID,
440 VARSTORE_ID_BOOT_MAINT,
441 DRV_ADD_RECON_VAR_OFFSET,
442 STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
443 STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
444 0,
445 0,
446 NULL
447 );
448
449 HiiCreateStringOpCode (
450 mStartOpCodeHandle,
451 (EFI_QUESTION_ID) DRIVER_ADD_OPTION_QUESTION_ID,
452 VARSTORE_ID_BOOT_MAINT,
453 DRIVER_ADD_OPTION_VAR_OFFSET,
454 STRING_TOKEN (STR_OPTIONAL_DATA),
455 STRING_TOKEN (STR_NULL_STRING),
456 0,
457 0,
458 6,
459 75,
460 NULL
461 );
462
463 UpdatePageEnd (CallbackData);
464 }
465
466 /**
467 Update console page.
468
469 @param UpdatePageId The form ID to be updated.
470 @param ConsoleMenu The console menu list.
471 @param CallbackData The BMM context data.
472
473 **/
474 VOID
475 UpdateConsolePage (
476 IN UINT16 UpdatePageId,
477 IN BM_MENU_OPTION *ConsoleMenu,
478 IN BMM_CALLBACK_DATA *CallbackData
479 )
480 {
481 BM_MENU_ENTRY *NewMenuEntry;
482 BM_CONSOLE_CONTEXT *NewConsoleContext;
483 BM_TERMINAL_CONTEXT *NewTerminalContext;
484 UINT16 Index;
485 UINT16 Index2;
486 UINT8 CheckFlags;
487 UINT8 *ConsoleCheck;
488 UINT8 *OldConsoleCheck;
489 UINTN ConsoleCheckSize;
490 EFI_QUESTION_ID QuestionIdBase;
491 UINT16 VariableOffsetBase;
492
493 CallbackData->BmmAskSaveOrNot = TRUE;
494
495 UpdatePageStart (CallbackData);
496
497 ConsoleCheck = NULL;
498 OldConsoleCheck = NULL;
499 QuestionIdBase = 0;
500 VariableOffsetBase = 0;
501 ConsoleCheckSize = 0;
502
503 switch (UpdatePageId) {
504 case FORM_CON_IN_ID:
505 ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];
506 OldConsoleCheck = &CallbackData->BmmOldFakeNVData.ConsoleInCheck[0];
507 ConsoleCheckSize = sizeof (CallbackData->BmmFakeNvData.ConsoleInCheck);
508 QuestionIdBase = CON_IN_DEVICE_QUESTION_ID;
509 VariableOffsetBase = CON_IN_DEVICE_VAR_OFFSET;
510 break;
511
512 case FORM_CON_OUT_ID:
513 ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];
514 OldConsoleCheck = &CallbackData->BmmOldFakeNVData.ConsoleOutCheck[0];
515 ConsoleCheckSize = sizeof (CallbackData->BmmFakeNvData.ConsoleOutCheck);
516 QuestionIdBase = CON_OUT_DEVICE_QUESTION_ID;
517 VariableOffsetBase = CON_OUT_DEVICE_VAR_OFFSET;
518 break;
519
520 case FORM_CON_ERR_ID:
521 ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];
522 OldConsoleCheck = &CallbackData->BmmOldFakeNVData.ConsoleErrCheck[0];
523 ConsoleCheckSize = sizeof (CallbackData->BmmFakeNvData.ConsoleErrCheck);
524 QuestionIdBase = CON_ERR_DEVICE_QUESTION_ID;
525 VariableOffsetBase = CON_ERR_DEVICE_VAR_OFFSET;
526 break;
527 }
528 ASSERT (ConsoleCheck != NULL);
529
530 for (Index = 0; ((Index < ConsoleMenu->MenuNumber) && \
531 (Index < MAX_MENU_NUMBER)) ; Index++) {
532 CheckFlags = 0;
533 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
534 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
535 if (NewConsoleContext->IsActive) {
536 CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
537 ConsoleCheck[Index] = TRUE;
538 } else {
539 ConsoleCheck[Index] = FALSE;
540 }
541 HiiCreateCheckBoxOpCode (
542 mStartOpCodeHandle,
543 (EFI_QUESTION_ID) (QuestionIdBase + Index),
544 VARSTORE_ID_BOOT_MAINT,
545 (UINT16) (VariableOffsetBase + Index),
546 NewMenuEntry->DisplayStringToken,
547 NewMenuEntry->HelpStringToken,
548 0,
549 CheckFlags,
550 NULL
551 );
552 }
553
554 for (Index2 = 0; ((Index2 < TerminalMenu.MenuNumber) && \
555 (Index2 < MAX_MENU_NUMBER)); Index2++) {
556 CheckFlags = 0;
557 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index2);
558 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
559
560 ASSERT (Index < MAX_MENU_NUMBER);
561 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
562 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
563 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
564 ) {
565 CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
566 ConsoleCheck[Index] = TRUE;
567 } else {
568 ConsoleCheck[Index] = FALSE;
569 }
570 HiiCreateCheckBoxOpCode (
571 mStartOpCodeHandle,
572 (EFI_QUESTION_ID) (QuestionIdBase + Index),
573 VARSTORE_ID_BOOT_MAINT,
574 (UINT16) (VariableOffsetBase + Index),
575 NewMenuEntry->DisplayStringToken,
576 NewMenuEntry->HelpStringToken,
577 0,
578 CheckFlags,
579 NULL
580 );
581
582 Index++;
583 }
584
585 CopyMem (OldConsoleCheck, ConsoleCheck, ConsoleCheckSize);
586
587 UpdatePageEnd (CallbackData);
588 }
589
590 /**
591 Update the page's NV Map if user has changed the order
592 a list. This list can be Boot Order or Driver Order.
593
594 @param UpdatePageId The form ID to be updated.
595 @param OptionMenu The new list.
596 @param CallbackData The BMM context data.
597
598 **/
599 VOID
600 UpdateOrderPage (
601 IN UINT16 UpdatePageId,
602 IN BM_MENU_OPTION *OptionMenu,
603 IN BMM_CALLBACK_DATA *CallbackData
604 )
605 {
606 BM_MENU_ENTRY *NewMenuEntry;
607 UINT16 Index;
608 UINT16 OptionIndex;
609 VOID *OptionsOpCodeHandle;
610 BM_LOAD_CONTEXT *NewLoadContext;
611 BOOLEAN BootOptionFound;
612 UINT32 *OptionOrder;
613 EFI_QUESTION_ID QuestionId;
614 UINT16 VarOffset;
615
616
617 UpdatePageStart (CallbackData);
618
619 CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);
620
621 OptionOrder = NULL;
622 QuestionId = 0;
623 VarOffset = 0;
624 switch (UpdatePageId) {
625
626 case FORM_BOOT_CHG_ID:
627 GetBootOrder (CallbackData);
628 OptionOrder = CallbackData->BmmFakeNvData.BootOptionOrder;
629 QuestionId = BOOT_OPTION_ORDER_QUESTION_ID;
630 VarOffset = BOOT_OPTION_ORDER_VAR_OFFSET;
631 break;
632
633 case FORM_DRV_CHG_ID:
634 GetDriverOrder (CallbackData);
635 OptionOrder = CallbackData->BmmFakeNvData.DriverOptionOrder;
636 QuestionId = DRIVER_OPTION_ORDER_QUESTION_ID;
637 VarOffset = DRIVER_OPTION_ORDER_VAR_OFFSET;
638 break;
639 }
640 ASSERT (OptionOrder != NULL);
641
642 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
643 ASSERT (OptionsOpCodeHandle != NULL);
644
645 NewMenuEntry = NULL;
646 for (OptionIndex = 0; (OptionOrder[OptionIndex] != 0 && OptionIndex < MAX_MENU_NUMBER); OptionIndex++) {
647 BootOptionFound = FALSE;
648 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
649 NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
650 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
651 if ((UINT32) (NewMenuEntry->OptionNumber + 1) == OptionOrder[OptionIndex]) {
652 BootOptionFound = TRUE;
653 break;
654 }
655 }
656 if (BootOptionFound) {
657 HiiCreateOneOfOptionOpCode (
658 OptionsOpCodeHandle,
659 NewMenuEntry->DisplayStringToken,
660 0,
661 EFI_IFR_TYPE_NUM_SIZE_32,
662 OptionOrder[OptionIndex]
663 );
664 }
665 }
666
667 if (OptionMenu->MenuNumber > 0) {
668 HiiCreateOrderedListOpCode (
669 mStartOpCodeHandle, // Container for dynamic created opcodes
670 QuestionId, // Question ID
671 VARSTORE_ID_BOOT_MAINT, // VarStore ID
672 VarOffset, // Offset in Buffer Storage
673 STRING_TOKEN (STR_CHANGE_ORDER), // Question prompt text
674 STRING_TOKEN (STR_CHANGE_ORDER), // Question help text
675 0, // Question flag
676 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
677 EFI_IFR_TYPE_NUM_SIZE_32, // Data type of Question value
678 100, // Maximum container
679 OptionsOpCodeHandle, // Option Opcode list
680 NULL // Default Opcode is NULL
681 );
682 }
683
684 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
685
686 UpdatePageEnd (CallbackData);
687
688 }
689
690 /**
691 Create the dynamic page to allow user to set
692 the "BootNext" value.
693
694 @param CallbackData The BMM context data.
695
696 **/
697 VOID
698 UpdateBootNextPage (
699 IN BMM_CALLBACK_DATA *CallbackData
700 )
701 {
702 BM_MENU_ENTRY *NewMenuEntry;
703 BM_LOAD_CONTEXT *NewLoadContext;
704 UINTN NumberOfOptions;
705 UINT16 Index;
706 VOID *OptionsOpCodeHandle;
707
708 NumberOfOptions = BootOptionMenu.MenuNumber;
709 CallbackData->BmmAskSaveOrNot = TRUE;
710
711 UpdatePageStart (CallbackData);
712 CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);
713
714 if (NumberOfOptions > 0) {
715 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
716 ASSERT (OptionsOpCodeHandle != NULL);
717
718 CallbackData->BmmFakeNvData.BootNext = (UINT16) (BootOptionMenu.MenuNumber);
719
720 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
721 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
722 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
723
724 if (NewLoadContext->IsBootNext) {
725 HiiCreateOneOfOptionOpCode (
726 OptionsOpCodeHandle,
727 NewMenuEntry->DisplayStringToken,
728 EFI_IFR_OPTION_DEFAULT,
729 EFI_IFR_TYPE_NUM_SIZE_16,
730 Index
731 );
732 CallbackData->BmmFakeNvData.BootNext = Index;
733 } else {
734 HiiCreateOneOfOptionOpCode (
735 OptionsOpCodeHandle,
736 NewMenuEntry->DisplayStringToken,
737 0,
738 EFI_IFR_TYPE_NUM_SIZE_16,
739 Index
740 );
741 }
742 }
743
744 if (CallbackData->BmmFakeNvData.BootNext == Index) {
745 HiiCreateOneOfOptionOpCode (
746 OptionsOpCodeHandle,
747 STRING_TOKEN (STR_NONE),
748 EFI_IFR_OPTION_DEFAULT,
749 EFI_IFR_TYPE_NUM_SIZE_16,
750 Index
751 );
752 } else {
753 HiiCreateOneOfOptionOpCode (
754 OptionsOpCodeHandle,
755 STRING_TOKEN (STR_NONE),
756 0,
757 EFI_IFR_TYPE_NUM_SIZE_16,
758 Index
759 );
760 }
761
762 HiiCreateOneOfOpCode (
763 mStartOpCodeHandle,
764 (EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,
765 VARSTORE_ID_BOOT_MAINT,
766 BOOT_NEXT_VAR_OFFSET,
767 STRING_TOKEN (STR_BOOT_NEXT),
768 STRING_TOKEN (STR_BOOT_NEXT_HELP),
769 0,
770 EFI_IFR_NUMERIC_SIZE_2,
771 OptionsOpCodeHandle,
772 NULL
773 );
774
775 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
776 }
777
778 UpdatePageEnd (CallbackData);
779 }
780
781 /**
782 Create the dynamic page to allow user to set the "TimeOut" value.
783
784 @param CallbackData The BMM context data.
785
786 **/
787 VOID
788 UpdateTimeOutPage (
789 IN BMM_CALLBACK_DATA *CallbackData
790 )
791 {
792 UINT16 BootTimeOut;
793 VOID *DefaultOpCodeHandle;
794
795 CallbackData->BmmAskSaveOrNot = TRUE;
796
797 UpdatePageStart (CallbackData);
798
799 BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);
800
801 DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
802 ASSERT (DefaultOpCodeHandle != NULL);
803 HiiCreateDefaultOpCode (DefaultOpCodeHandle, EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_NUM_SIZE_16, BootTimeOut);
804
805 HiiCreateNumericOpCode (
806 mStartOpCodeHandle,
807 (EFI_QUESTION_ID) BOOT_TIME_OUT_QUESTION_ID,
808 VARSTORE_ID_BOOT_MAINT,
809 BOOT_TIME_OUT_VAR_OFFSET,
810 STRING_TOKEN (STR_NUM_AUTO_BOOT),
811 STRING_TOKEN (STR_HLP_AUTO_BOOT),
812 0,
813 EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,
814 0,
815 65535,
816 0,
817 DefaultOpCodeHandle
818 );
819
820 HiiFreeOpCodeHandle (DefaultOpCodeHandle);
821
822 CallbackData->BmmFakeNvData.BootTimeOut = BootTimeOut;
823
824 UpdatePageEnd (CallbackData);
825 }
826
827
828 /**
829 Refresh the text mode page.
830
831 @param CallbackData The BMM context data.
832
833 **/
834 VOID
835 UpdateConModePage (
836 IN BMM_CALLBACK_DATA *CallbackData
837 )
838 {
839 UINTN Mode;
840 UINTN Index;
841 UINTN Col;
842 UINTN Row;
843 CHAR16 ModeString[50];
844 CHAR16 *PStr;
845 UINTN MaxMode;
846 UINTN ValidMode;
847 EFI_STRING_ID *ModeToken;
848 EFI_STATUS Status;
849 VOID *OptionsOpCodeHandle;
850 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
851
852 ConOut = gST->ConOut;
853 Index = 0;
854 ValidMode = 0;
855 MaxMode = (UINTN) (ConOut->Mode->MaxMode);
856
857 CallbackData->BmmAskSaveOrNot = TRUE;
858
859 UpdatePageStart (CallbackData);
860
861 //
862 // Check valid mode
863 //
864 for (Mode = 0; Mode < MaxMode; Mode++) {
865 Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
866 if (EFI_ERROR (Status)) {
867 continue;
868 }
869 ValidMode++;
870 }
871
872 if (ValidMode == 0) {
873 return;
874 }
875
876 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
877 ASSERT (OptionsOpCodeHandle != NULL);
878
879 ModeToken = AllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode);
880 ASSERT(ModeToken != NULL);
881
882 //
883 // Determin which mode should be the first entry in menu
884 //
885 GetConsoleOutMode (CallbackData);
886
887 //
888 // Build text mode options
889 //
890 for (Mode = 0; Mode < MaxMode; Mode++) {
891 Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
892 if (EFI_ERROR (Status)) {
893 continue;
894 }
895
896 //
897 // Build mode string Column x Row
898 //
899 UnicodeValueToString (ModeString, 0, Col, 0);
900 PStr = &ModeString[0];
901 StrnCatS (PStr, sizeof (ModeString) / sizeof (ModeString[0]), L" x ", StrLen(L" x ") + 1);
902 PStr = PStr + StrLen (PStr);
903 UnicodeValueToString (PStr , 0, Row, 0);
904
905 ModeToken[Index] = HiiSetString (CallbackData->BmmHiiHandle, 0, ModeString, NULL);
906
907 if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) {
908 HiiCreateOneOfOptionOpCode (
909 OptionsOpCodeHandle,
910 ModeToken[Index],
911 EFI_IFR_OPTION_DEFAULT,
912 EFI_IFR_TYPE_NUM_SIZE_16,
913 (UINT16) Mode
914 );
915 } else {
916 HiiCreateOneOfOptionOpCode (
917 OptionsOpCodeHandle,
918 ModeToken[Index],
919 0,
920 EFI_IFR_TYPE_NUM_SIZE_16,
921 (UINT16) Mode
922 );
923 }
924 Index++;
925 }
926
927 HiiCreateOneOfOpCode (
928 mStartOpCodeHandle,
929 (EFI_QUESTION_ID) CON_MODE_QUESTION_ID,
930 VARSTORE_ID_BOOT_MAINT,
931 CON_MODE_VAR_OFFSET,
932 STRING_TOKEN (STR_CON_MODE_SETUP),
933 STRING_TOKEN (STR_CON_MODE_SETUP),
934 EFI_IFR_FLAG_RESET_REQUIRED,
935 EFI_IFR_NUMERIC_SIZE_2,
936 OptionsOpCodeHandle,
937 NULL
938 );
939
940 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
941 FreePool (ModeToken);
942
943 UpdatePageEnd (CallbackData);
944 }
945
946 /**
947 Create the dynamic page which allows user to set the property such as Baud Rate, Data Bits,
948 Parity, Stop Bits, Terminal Type.
949
950 @param CallbackData The BMM context data.
951
952 **/
953 VOID
954 UpdateTerminalPage (
955 IN BMM_CALLBACK_DATA *CallbackData
956 )
957 {
958 UINT8 Index;
959 UINT8 CheckFlags;
960 BM_MENU_ENTRY *NewMenuEntry;
961 VOID *OptionsOpCodeHandle;
962 UINTN CurrentTerminal;
963
964 CallbackData->BmmAskSaveOrNot = TRUE;
965
966 UpdatePageStart (CallbackData);
967
968 CurrentTerminal = CallbackData->CurrentTerminal;
969 NewMenuEntry = BOpt_GetMenuEntry (
970 &TerminalMenu,
971 CurrentTerminal
972 );
973
974 if (NewMenuEntry == NULL) {
975 return ;
976 }
977
978 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
979 ASSERT (OptionsOpCodeHandle != NULL);
980
981 for (Index = 0; Index < sizeof (BaudRateList) / sizeof (BaudRateList [0]); Index++) {
982 CheckFlags = 0;
983 if (BaudRateList[Index].Value == 115200) {
984 CheckFlags |= EFI_IFR_OPTION_DEFAULT;
985 }
986 HiiCreateOneOfOptionOpCode (
987 OptionsOpCodeHandle,
988 BaudRateList[Index].StringToken,
989 CheckFlags,
990 EFI_IFR_TYPE_NUM_SIZE_8,
991 Index
992 );
993 }
994
995 HiiCreateOneOfOpCode (
996 mStartOpCodeHandle,
997 (EFI_QUESTION_ID) (COM_BAUD_RATE_QUESTION_ID + CurrentTerminal),
998 VARSTORE_ID_BOOT_MAINT,
999 (UINT16) (COM_BAUD_RATE_VAR_OFFSET + CurrentTerminal),
1000 STRING_TOKEN (STR_COM_BAUD_RATE),
1001 STRING_TOKEN (STR_COM_BAUD_RATE),
1002 0,
1003 EFI_IFR_NUMERIC_SIZE_1,
1004 OptionsOpCodeHandle,
1005 NULL
1006 );
1007
1008 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1009 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1010 ASSERT (OptionsOpCodeHandle != NULL);
1011
1012 for (Index = 0; Index < sizeof (DataBitsList) / sizeof (DataBitsList[0]); Index++) {
1013 CheckFlags = 0;
1014
1015 if (DataBitsList[Index].Value == 8) {
1016 CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1017 }
1018
1019 HiiCreateOneOfOptionOpCode (
1020 OptionsOpCodeHandle,
1021 DataBitsList[Index].StringToken,
1022 CheckFlags,
1023 EFI_IFR_TYPE_NUM_SIZE_8,
1024 Index
1025 );
1026 }
1027
1028 HiiCreateOneOfOpCode (
1029 mStartOpCodeHandle,
1030 (EFI_QUESTION_ID) (COM_DATA_RATE_QUESTION_ID + CurrentTerminal),
1031 VARSTORE_ID_BOOT_MAINT,
1032 (UINT16) (COM_DATA_RATE_VAR_OFFSET + CurrentTerminal),
1033 STRING_TOKEN (STR_COM_DATA_BITS),
1034 STRING_TOKEN (STR_COM_DATA_BITS),
1035 0,
1036 EFI_IFR_NUMERIC_SIZE_1,
1037 OptionsOpCodeHandle,
1038 NULL
1039 );
1040
1041 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1042 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1043 ASSERT (OptionsOpCodeHandle != NULL);
1044
1045 for (Index = 0; Index < sizeof (ParityList) / sizeof (ParityList[0]); Index++) {
1046 CheckFlags = 0;
1047 if (ParityList[Index].Value == NoParity) {
1048 CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1049 }
1050
1051 HiiCreateOneOfOptionOpCode (
1052 OptionsOpCodeHandle,
1053 ParityList[Index].StringToken,
1054 CheckFlags,
1055 EFI_IFR_TYPE_NUM_SIZE_8,
1056 Index
1057 );
1058 }
1059
1060 HiiCreateOneOfOpCode (
1061 mStartOpCodeHandle,
1062 (EFI_QUESTION_ID) (COM_PARITY_QUESTION_ID + CurrentTerminal),
1063 VARSTORE_ID_BOOT_MAINT,
1064 (UINT16) (COM_PARITY_VAR_OFFSET + CurrentTerminal),
1065 STRING_TOKEN (STR_COM_PARITY),
1066 STRING_TOKEN (STR_COM_PARITY),
1067 0,
1068 EFI_IFR_NUMERIC_SIZE_1,
1069 OptionsOpCodeHandle,
1070 NULL
1071 );
1072
1073 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1074 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1075 ASSERT (OptionsOpCodeHandle != NULL);
1076
1077 for (Index = 0; Index < sizeof (StopBitsList) / sizeof (StopBitsList[0]); Index++) {
1078 CheckFlags = 0;
1079 if (StopBitsList[Index].Value == OneStopBit) {
1080 CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1081 }
1082
1083 HiiCreateOneOfOptionOpCode (
1084 OptionsOpCodeHandle,
1085 StopBitsList[Index].StringToken,
1086 CheckFlags,
1087 EFI_IFR_TYPE_NUM_SIZE_8,
1088 Index
1089 );
1090 }
1091
1092 HiiCreateOneOfOpCode (
1093 mStartOpCodeHandle,
1094 (EFI_QUESTION_ID) (COM_STOP_BITS_QUESTION_ID + CurrentTerminal),
1095 VARSTORE_ID_BOOT_MAINT,
1096 (UINT16) (COM_STOP_BITS_VAR_OFFSET + CurrentTerminal),
1097 STRING_TOKEN (STR_COM_STOP_BITS),
1098 STRING_TOKEN (STR_COM_STOP_BITS),
1099 0,
1100 EFI_IFR_NUMERIC_SIZE_1,
1101 OptionsOpCodeHandle,
1102 NULL
1103 );
1104
1105 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1106 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1107 ASSERT (OptionsOpCodeHandle != NULL);
1108
1109 for (Index = 0; Index < sizeof (TerminalType) / sizeof (TerminalType[0]); Index++) {
1110 CheckFlags = 0;
1111 if (Index == 0) {
1112 CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1113 }
1114
1115 HiiCreateOneOfOptionOpCode (
1116 OptionsOpCodeHandle,
1117 (EFI_STRING_ID) TerminalType[Index],
1118 CheckFlags,
1119 EFI_IFR_TYPE_NUM_SIZE_8,
1120 Index
1121 );
1122 }
1123
1124 HiiCreateOneOfOpCode (
1125 mStartOpCodeHandle,
1126 (EFI_QUESTION_ID) (COM_TERMINAL_QUESTION_ID + CurrentTerminal),
1127 VARSTORE_ID_BOOT_MAINT,
1128 (UINT16) (COM_TERMINAL_VAR_OFFSET + CurrentTerminal),
1129 STRING_TOKEN (STR_COM_TERMI_TYPE),
1130 STRING_TOKEN (STR_COM_TERMI_TYPE),
1131 0,
1132 EFI_IFR_NUMERIC_SIZE_1,
1133 OptionsOpCodeHandle,
1134 NULL
1135 );
1136
1137 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1138 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1139 ASSERT (OptionsOpCodeHandle != NULL);
1140
1141 for (Index = 0; Index < sizeof (mFlowControlType) / sizeof (mFlowControlType[0]); Index++) {
1142 CheckFlags = 0;
1143 if (Index == 0) {
1144 CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1145 }
1146 HiiCreateOneOfOptionOpCode (
1147 OptionsOpCodeHandle,
1148 (EFI_STRING_ID) mFlowControlType[Index],
1149 CheckFlags,
1150 EFI_IFR_TYPE_NUM_SIZE_8,
1151 mFlowControlValue[Index]
1152 );
1153 }
1154
1155 HiiCreateOneOfOpCode (
1156 mStartOpCodeHandle,
1157 (EFI_QUESTION_ID) (COM_FLOWCONTROL_QUESTION_ID + CurrentTerminal),
1158 VARSTORE_ID_BOOT_MAINT,
1159 (UINT16) (COM_FLOWCONTROL_VAR_OFFSET + CurrentTerminal),
1160 STRING_TOKEN (STR_COM_FLOW_CONTROL),
1161 STRING_TOKEN (STR_COM_FLOW_CONTROL),
1162 0,
1163 EFI_IFR_NUMERIC_SIZE_1,
1164 OptionsOpCodeHandle,
1165 NULL
1166 );
1167
1168 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1169
1170 UpdatePageEnd (CallbackData);
1171 }
1172
1173 /**
1174 Dispatch the correct update page function to call based on
1175 the UpdatePageId.
1176
1177 @param UpdatePageId The form ID.
1178 @param CallbackData The BMM context data.
1179
1180 **/
1181 VOID
1182 UpdatePageBody (
1183 IN UINT16 UpdatePageId,
1184 IN BMM_CALLBACK_DATA *CallbackData
1185 )
1186 {
1187 CleanUpPage (UpdatePageId, CallbackData);
1188 switch (UpdatePageId) {
1189 case FORM_CON_IN_ID:
1190 UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);
1191 break;
1192
1193 case FORM_CON_OUT_ID:
1194 UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);
1195 break;
1196
1197 case FORM_CON_ERR_ID:
1198 UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);
1199 break;
1200
1201 case FORM_BOOT_CHG_ID:
1202 UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);
1203 break;
1204
1205 case FORM_DRV_CHG_ID:
1206 UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);
1207 break;
1208
1209 default:
1210 break;
1211 }
1212 }
1213
1214 /**
1215 Dispatch the display to the next page based on NewPageId.
1216
1217 @param Private The BMM context data.
1218 @param NewPageId The original page ID.
1219
1220 **/
1221 VOID
1222 UpdatePageId (
1223 BMM_CALLBACK_DATA *Private,
1224 UINT16 NewPageId
1225 )
1226 {
1227 if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {
1228 //
1229 // If we select a handle to add driver option, advance to the add handle description page.
1230 //
1231 NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;
1232 } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {
1233 //
1234 // Return to main page after "Save Changes" or "Discard Changes".
1235 //
1236 NewPageId = FORM_MAIN_ID;
1237 } else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) {
1238 NewPageId = FORM_CON_COM_SETUP_ID;
1239 }
1240
1241 if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
1242 Private->BmmPreviousPageId = Private->BmmCurrentPageId;
1243 Private->BmmCurrentPageId = NewPageId;
1244 }
1245 }