UpdatePage.c revision a91f1a0e88d07dd3817737f9886bc247cc737a4f
1/** @file
2Dynamically update the pages.
3
4Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include "BootMaintenanceManager.h"
16
17/**
18 Create the global UpdateData structure.
19
20**/
21VOID
22CreateUpdateData (
23  VOID
24  )
25{
26  //
27  // Init OpCode Handle and Allocate space for creation of Buffer
28  //
29  mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
30  ASSERT (mStartOpCodeHandle != NULL);
31
32  mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
33  ASSERT (mEndOpCodeHandle != NULL);
34
35  //
36  // Create Hii Extend Label OpCode as the start opcode
37  //
38  mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
39  mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
40
41  //
42  // Create Hii Extend Label OpCode as the end opcode
43  //
44  mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
45  mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
46  mEndLabel->Number       = LABEL_END;
47}
48
49/**
50  Refresh the global UpdateData structure.
51
52**/
53VOID
54RefreshUpdateData (
55  VOID
56  )
57{
58  //
59  // Free current updated date
60  //
61  if (mStartOpCodeHandle != NULL) {
62    HiiFreeOpCodeHandle (mStartOpCodeHandle);
63  }
64
65  //
66  // Create new OpCode Handle
67  //
68  mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
69
70  //
71  // Create Hii Extend Label OpCode as the start opcode
72  //
73  mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
74  mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
75
76}
77
78/**
79  Add a "Go back to main page" tag in front of the form when there are no
80  "Apply changes" and "Discard changes" tags in the end of the form.
81
82  @param CallbackData    The BMM context data.
83
84**/
85VOID
86UpdatePageStart (
87  IN BMM_CALLBACK_DATA                *CallbackData
88  )
89{
90  RefreshUpdateData ();
91  mStartLabel->Number = CallbackData->BmmCurrentPageId;
92
93  if (!(CallbackData->BmmAskSaveOrNot)) {
94    //
95    // Add a "Go back to main page" tag in front of the form when there are no
96    // "Apply changes" and "Discard changes" tags in the end of the form.
97    //
98    HiiCreateGotoOpCode (
99      mStartOpCodeHandle,
100      FORM_MAIN_ID,
101      STRING_TOKEN (STR_FORM_GOTO_MAIN),
102      STRING_TOKEN (STR_FORM_GOTO_MAIN),
103      0,
104      FORM_MAIN_ID
105      );
106  }
107}
108
109/**
110  Create the "Apply changes" and "Discard changes" tags. And
111  ensure user can return to the main page.
112
113  @param CallbackData    The BMM context data.
114
115**/
116VOID
117UpdatePageEnd (
118  IN BMM_CALLBACK_DATA                *CallbackData
119  )
120{
121  //
122  // Create the "Apply changes" and "Discard changes" tags.
123  //
124  if (CallbackData->BmmAskSaveOrNot) {
125    HiiCreateSubTitleOpCode (
126      mStartOpCodeHandle,
127      STRING_TOKEN (STR_NULL_STRING),
128      0,
129      0,
130      0
131      );
132
133    HiiCreateActionOpCode (
134      mStartOpCodeHandle,
135      KEY_VALUE_SAVE_AND_EXIT,
136      STRING_TOKEN (STR_SAVE_AND_EXIT),
137      STRING_TOKEN (STR_NULL_STRING),
138      EFI_IFR_FLAG_CALLBACK,
139      0
140      );
141  }
142
143  //
144  // Ensure user can return to the main page.
145  //
146  HiiCreateActionOpCode (
147    mStartOpCodeHandle,
148    KEY_VALUE_NO_SAVE_AND_EXIT,
149    STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
150    STRING_TOKEN (STR_NULL_STRING),
151    EFI_IFR_FLAG_CALLBACK,
152    0
153    );
154
155  HiiUpdateForm (
156    CallbackData->BmmHiiHandle,
157    &mBootMaintGuid,
158    CallbackData->BmmCurrentPageId,
159    mStartOpCodeHandle, // Label CallbackData->BmmCurrentPageId
160    mEndOpCodeHandle    // LABEL_END
161    );
162}
163
164/**
165  Clean up the dynamic opcode at label and form specified by both LabelId.
166
167  @param LabelId         It is both the Form ID and Label ID for opcode deletion.
168  @param CallbackData    The BMM context data.
169
170**/
171VOID
172CleanUpPage (
173  IN UINT16                           LabelId,
174  IN BMM_CALLBACK_DATA                *CallbackData
175  )
176{
177  RefreshUpdateData ();
178
179  //
180  // Remove all op-codes from dynamic page
181  //
182  mStartLabel->Number = LabelId;
183  HiiUpdateForm (
184    CallbackData->BmmHiiHandle,
185    &mBootMaintGuid,
186    LabelId,
187    mStartOpCodeHandle, // Label LabelId
188    mEndOpCodeHandle    // LABEL_END
189    );
190}
191
192/**
193  Create a list of Goto Opcode for all terminal devices logged
194  by TerminaMenu. This list will be inserted to form FORM_CON_COM_SETUP_ID.
195
196  @param CallbackData    The BMM context data.
197**/
198VOID
199UpdateConCOMPage (
200  IN BMM_CALLBACK_DATA                *CallbackData
201  )
202{
203  BM_MENU_ENTRY       *NewMenuEntry;
204  UINT16              Index;
205
206  CallbackData->BmmAskSaveOrNot = TRUE;
207
208  UpdatePageStart (CallbackData);
209
210  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
211    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
212
213    HiiCreateGotoOpCode (
214      mStartOpCodeHandle,
215      FORM_CON_COM_SETUP_ID,
216      NewMenuEntry->DisplayStringToken,
217      STRING_TOKEN (STR_NULL_STRING),
218      EFI_IFR_FLAG_CALLBACK,
219      (UINT16) (TERMINAL_OPTION_OFFSET + Index)
220      );
221  }
222
223  UpdatePageEnd (CallbackData);
224}
225
226
227/**
228  Create a list of boot option from global BootOptionMenu. It
229  allow user to delete the boot option.
230
231  @param CallbackData    The BMM context data.
232
233**/
234VOID
235UpdateBootDelPage (
236  IN BMM_CALLBACK_DATA                *CallbackData
237  )
238{
239  BM_MENU_ENTRY   *NewMenuEntry;
240  BM_LOAD_CONTEXT *NewLoadContext;
241  UINT16          Index;
242
243  CallbackData->BmmAskSaveOrNot = TRUE;
244
245  UpdatePageStart (CallbackData);
246
247  ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionDel) / sizeof (CallbackData->BmmFakeNvData.BootOptionDel[0])));
248  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
249    NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
250    NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
251    if (NewLoadContext->IsLegacy) {
252      continue;
253    }
254
255    NewLoadContext->Deleted = FALSE;
256
257    if (CallbackData->BmmFakeNvData.BootOptionDel[Index] && !CallbackData->BmmFakeNvData.BootOptionDelMark[Index]) {
258      //
259      // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
260      // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
261      // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
262      // through HiiSetBrowserData function.
263      //
264      CallbackData->BmmFakeNvData.BootOptionDel[Index] = FALSE;
265    }
266
267    HiiCreateCheckBoxOpCode (
268      mStartOpCodeHandle,
269      (EFI_QUESTION_ID) (BOOT_OPTION_DEL_QUESTION_ID + Index),
270      VARSTORE_ID_BOOT_MAINT,
271      (UINT16) (BOOT_OPTION_DEL_VAR_OFFSET + Index),
272      NewMenuEntry->DisplayStringToken,
273      NewMenuEntry->HelpStringToken,
274      EFI_IFR_FLAG_CALLBACK,
275      0,
276      NULL
277      );
278  }
279  UpdatePageEnd (CallbackData);
280}
281
282/**
283  Create a lit of driver option from global DriverMenu.
284
285  @param CallbackData    The BMM context data.
286
287**/
288VOID
289UpdateDrvAddHandlePage (
290  IN BMM_CALLBACK_DATA                *CallbackData
291  )
292{
293  BM_MENU_ENTRY *NewMenuEntry;
294  UINT16        Index;
295
296  CallbackData->BmmAskSaveOrNot = FALSE;
297
298  UpdatePageStart (CallbackData);
299
300  for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {
301    NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
302
303    HiiCreateGotoOpCode (
304      mStartOpCodeHandle,
305      FORM_DRV_ADD_HANDLE_DESC_ID,
306      NewMenuEntry->DisplayStringToken,
307      STRING_TOKEN (STR_NULL_STRING),
308      EFI_IFR_FLAG_CALLBACK,
309      (UINT16) (HANDLE_OPTION_OFFSET + Index)
310      );
311  }
312
313  UpdatePageEnd (CallbackData);
314}
315
316/**
317  Create a lit of driver option from global DriverOptionMenu. It
318  allow user to delete the driver option.
319
320  @param CallbackData    The BMM context data.
321
322**/
323VOID
324UpdateDrvDelPage (
325  IN BMM_CALLBACK_DATA                *CallbackData
326  )
327{
328  BM_MENU_ENTRY   *NewMenuEntry;
329  BM_LOAD_CONTEXT *NewLoadContext;
330  UINT16          Index;
331
332  CallbackData->BmmAskSaveOrNot = TRUE;
333
334  UpdatePageStart (CallbackData);
335
336  ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionDel) / sizeof (CallbackData->BmmFakeNvData.DriverOptionDel[0])));
337  for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
338    NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
339
340    NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
341    NewLoadContext->Deleted = FALSE;
342
343    if (CallbackData->BmmFakeNvData.DriverOptionDel[Index] && !CallbackData->BmmFakeNvData.DriverOptionDelMark[Index]) {
344      //
345      // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
346      // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
347      // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
348      // through HiiSetBrowserData function.
349      //
350      CallbackData->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
351    }
352    HiiCreateCheckBoxOpCode (
353      mStartOpCodeHandle,
354      (EFI_QUESTION_ID) (DRIVER_OPTION_DEL_QUESTION_ID + Index),
355      VARSTORE_ID_BOOT_MAINT,
356      (UINT16) (DRIVER_OPTION_DEL_VAR_OFFSET + Index),
357      NewMenuEntry->DisplayStringToken,
358      NewMenuEntry->HelpStringToken,
359      EFI_IFR_FLAG_CALLBACK,
360      0,
361      NULL
362      );
363  }
364
365  UpdatePageEnd (CallbackData);
366}
367
368/**
369  Prepare the page to allow user to add description for
370  a Driver Option.
371
372  @param CallbackData    The BMM context data.
373
374**/
375VOID
376UpdateDriverAddHandleDescPage (
377  IN BMM_CALLBACK_DATA                *CallbackData
378  )
379{
380  BM_MENU_ENTRY *NewMenuEntry;
381
382  CallbackData->BmmFakeNvData.DriverAddActive          = 0x01;
383  CallbackData->BmmFakeNvData.DriverAddForceReconnect  = 0x00;
384  CallbackData->BmmAskSaveOrNot                        = TRUE;
385  NewMenuEntry = CallbackData->MenuEntry;
386
387  UpdatePageStart (CallbackData);
388
389  HiiCreateSubTitleOpCode (
390    mStartOpCodeHandle,
391    NewMenuEntry->DisplayStringToken,
392    0,
393    0,
394    0
395    );
396
397  HiiCreateStringOpCode (
398    mStartOpCodeHandle,
399    (EFI_QUESTION_ID) DRV_ADD_HANDLE_DESC_QUESTION_ID,
400    VARSTORE_ID_BOOT_MAINT,
401    DRV_ADD_HANDLE_DESC_VAR_OFFSET,
402    STRING_TOKEN (STR_LOAD_OPTION_DESC),
403    STRING_TOKEN (STR_NULL_STRING),
404    0,
405    0,
406    6,
407    75,
408    NULL
409    );
410
411  HiiCreateCheckBoxOpCode (
412    mStartOpCodeHandle,
413    (EFI_QUESTION_ID) DRV_ADD_RECON_QUESTION_ID,
414    VARSTORE_ID_BOOT_MAINT,
415    DRV_ADD_RECON_VAR_OFFSET,
416    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
417    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
418    0,
419    0,
420    NULL
421    );
422
423  HiiCreateStringOpCode (
424    mStartOpCodeHandle,
425    (EFI_QUESTION_ID) DRIVER_ADD_OPTION_QUESTION_ID,
426    VARSTORE_ID_BOOT_MAINT,
427    DRIVER_ADD_OPTION_VAR_OFFSET,
428    STRING_TOKEN (STR_OPTIONAL_DATA),
429    STRING_TOKEN (STR_NULL_STRING),
430    0,
431    0,
432    6,
433    75,
434    NULL
435    );
436
437  UpdatePageEnd (CallbackData);
438}
439
440/**
441  Update console page.
442
443  @param UpdatePageId    The form ID to be updated.
444  @param ConsoleMenu     The console menu list.
445  @param CallbackData    The BMM context data.
446
447**/
448VOID
449UpdateConsolePage (
450  IN UINT16                           UpdatePageId,
451  IN BM_MENU_OPTION                   *ConsoleMenu,
452  IN BMM_CALLBACK_DATA                *CallbackData
453  )
454{
455  BM_MENU_ENTRY       *NewMenuEntry;
456  BM_CONSOLE_CONTEXT  *NewConsoleContext;
457  BM_TERMINAL_CONTEXT *NewTerminalContext;
458  UINT16              Index;
459  UINT16              Index2;
460  UINT8               CheckFlags;
461  UINT8               *ConsoleCheck;
462  UINT8               *OldConsoleCheck;
463  UINTN               ConsoleCheckSize;
464  EFI_QUESTION_ID     QuestionIdBase;
465  UINT16              VariableOffsetBase;
466
467  CallbackData->BmmAskSaveOrNot = TRUE;
468
469  UpdatePageStart (CallbackData);
470
471  ConsoleCheck       = NULL;
472  OldConsoleCheck    = NULL;
473  QuestionIdBase     = 0;
474  VariableOffsetBase = 0;
475  ConsoleCheckSize   = 0;
476
477  switch (UpdatePageId) {
478  case FORM_CON_IN_ID:
479    ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];
480    OldConsoleCheck    = &CallbackData->BmmOldFakeNVData.ConsoleInCheck[0];
481    ConsoleCheckSize   = sizeof (CallbackData->BmmFakeNvData.ConsoleInCheck);
482    QuestionIdBase     = CON_IN_DEVICE_QUESTION_ID;
483    VariableOffsetBase = CON_IN_DEVICE_VAR_OFFSET;
484    break;
485
486  case FORM_CON_OUT_ID:
487    ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];
488    OldConsoleCheck    = &CallbackData->BmmOldFakeNVData.ConsoleOutCheck[0];
489    ConsoleCheckSize   = sizeof (CallbackData->BmmFakeNvData.ConsoleOutCheck);
490    QuestionIdBase     = CON_OUT_DEVICE_QUESTION_ID;
491    VariableOffsetBase = CON_OUT_DEVICE_VAR_OFFSET;
492    break;
493
494  case FORM_CON_ERR_ID:
495    ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];
496    OldConsoleCheck    = &CallbackData->BmmOldFakeNVData.ConsoleErrCheck[0];
497    ConsoleCheckSize   = sizeof (CallbackData->BmmFakeNvData.ConsoleErrCheck);
498    QuestionIdBase     = CON_ERR_DEVICE_QUESTION_ID;
499    VariableOffsetBase = CON_ERR_DEVICE_VAR_OFFSET;
500    break;
501  }
502  ASSERT (ConsoleCheck != NULL);
503
504  for (Index = 0; ((Index < ConsoleMenu->MenuNumber) && \
505       (Index < MAX_MENU_NUMBER)) ; Index++) {
506    CheckFlags = 0;
507    NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
508    NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
509    if (NewConsoleContext->IsActive) {
510      CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
511      ConsoleCheck[Index] = TRUE;
512    } else {
513      ConsoleCheck[Index] = FALSE;
514    }
515    HiiCreateCheckBoxOpCode (
516      mStartOpCodeHandle,
517      (EFI_QUESTION_ID) (QuestionIdBase + Index),
518      VARSTORE_ID_BOOT_MAINT,
519      (UINT16) (VariableOffsetBase + Index),
520      NewMenuEntry->DisplayStringToken,
521      NewMenuEntry->HelpStringToken,
522      0,
523      CheckFlags,
524      NULL
525      );
526  }
527
528  for (Index2 = 0; ((Index2 < TerminalMenu.MenuNumber) && \
529       (Index2 < MAX_MENU_NUMBER)); Index2++) {
530    CheckFlags          = 0;
531    NewMenuEntry        = BOpt_GetMenuEntry (&TerminalMenu, Index2);
532    NewTerminalContext  = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
533
534    ASSERT (Index < MAX_MENU_NUMBER);
535    if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
536        ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
537        ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
538        ) {
539      CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
540      ConsoleCheck[Index] = TRUE;
541    } else {
542      ConsoleCheck[Index] = FALSE;
543    }
544    HiiCreateCheckBoxOpCode (
545      mStartOpCodeHandle,
546      (EFI_QUESTION_ID) (QuestionIdBase + Index),
547      VARSTORE_ID_BOOT_MAINT,
548      (UINT16) (VariableOffsetBase + Index),
549      NewMenuEntry->DisplayStringToken,
550      NewMenuEntry->HelpStringToken,
551      0,
552      CheckFlags,
553      NULL
554      );
555
556    Index++;
557  }
558
559  CopyMem (OldConsoleCheck, ConsoleCheck, ConsoleCheckSize);
560
561  UpdatePageEnd (CallbackData);
562}
563
564/**
565  Update the page's NV Map if user has changed the order
566  a list. This list can be Boot Order or Driver Order.
567
568  @param UpdatePageId    The form ID to be updated.
569  @param OptionMenu      The new list.
570  @param CallbackData    The BMM context data.
571
572**/
573VOID
574UpdateOrderPage (
575  IN UINT16                           UpdatePageId,
576  IN BM_MENU_OPTION                   *OptionMenu,
577  IN BMM_CALLBACK_DATA                *CallbackData
578  )
579{
580  BM_MENU_ENTRY     *NewMenuEntry;
581  UINT16            Index;
582  UINT16            OptionIndex;
583  VOID              *OptionsOpCodeHandle;
584  BOOLEAN           BootOptionFound;
585  UINT32            *OptionOrder;
586  EFI_QUESTION_ID   QuestionId;
587  UINT16            VarOffset;
588
589  CallbackData->BmmAskSaveOrNot = TRUE;
590  UpdatePageStart (CallbackData);
591
592  OptionOrder = NULL;
593  QuestionId = 0;
594  VarOffset = 0;
595  switch (UpdatePageId) {
596
597  case FORM_BOOT_CHG_ID:
598    GetBootOrder (CallbackData);
599    OptionOrder = CallbackData->BmmFakeNvData.BootOptionOrder;
600    QuestionId = BOOT_OPTION_ORDER_QUESTION_ID;
601    VarOffset = BOOT_OPTION_ORDER_VAR_OFFSET;
602    break;
603
604  case FORM_DRV_CHG_ID:
605    GetDriverOrder (CallbackData);
606    OptionOrder = CallbackData->BmmFakeNvData.DriverOptionOrder;
607    QuestionId = DRIVER_OPTION_ORDER_QUESTION_ID;
608    VarOffset = DRIVER_OPTION_ORDER_VAR_OFFSET;
609    break;
610  }
611  ASSERT (OptionOrder != NULL);
612
613  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
614  ASSERT (OptionsOpCodeHandle != NULL);
615
616  NewMenuEntry = NULL;
617  for (OptionIndex = 0; (OptionOrder[OptionIndex] != 0 && OptionIndex < MAX_MENU_NUMBER); OptionIndex++) {
618    BootOptionFound = FALSE;
619    for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
620      NewMenuEntry   = BOpt_GetMenuEntry (OptionMenu, Index);
621      if ((UINT32) (NewMenuEntry->OptionNumber + 1) == OptionOrder[OptionIndex]) {
622        BootOptionFound = TRUE;
623        break;
624      }
625    }
626    if (BootOptionFound) {
627      HiiCreateOneOfOptionOpCode (
628        OptionsOpCodeHandle,
629        NewMenuEntry->DisplayStringToken,
630        0,
631        EFI_IFR_TYPE_NUM_SIZE_32,
632        OptionOrder[OptionIndex]
633        );
634    }
635  }
636
637  if (OptionMenu->MenuNumber > 0) {
638    HiiCreateOrderedListOpCode (
639      mStartOpCodeHandle,                          // Container for dynamic created opcodes
640      QuestionId,                                  // Question ID
641      VARSTORE_ID_BOOT_MAINT,                      // VarStore ID
642      VarOffset,                                   // Offset in Buffer Storage
643      STRING_TOKEN (STR_CHANGE_ORDER),             // Question prompt text
644      STRING_TOKEN (STR_CHANGE_ORDER),             // Question help text
645      0,                                           // Question flag
646      0,                                           // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
647      EFI_IFR_TYPE_NUM_SIZE_32,                    // Data type of Question value
648      100,                                         // Maximum container
649      OptionsOpCodeHandle,                         // Option Opcode list
650      NULL                                         // Default Opcode is NULL
651      );
652  }
653
654  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
655
656  UpdatePageEnd (CallbackData);
657
658}
659
660/**
661  Refresh the text mode page.
662
663  @param CallbackData    The BMM context data.
664
665**/
666VOID
667UpdateConModePage (
668  IN BMM_CALLBACK_DATA                *CallbackData
669  )
670{
671  UINTN                         Mode;
672  UINTN                         Index;
673  UINTN                         Col;
674  UINTN                         Row;
675  CHAR16                        ModeString[50];
676  CHAR16                        *PStr;
677  UINTN                         MaxMode;
678  UINTN                         ValidMode;
679  EFI_STRING_ID                 *ModeToken;
680  EFI_STATUS                    Status;
681  VOID                          *OptionsOpCodeHandle;
682  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;
683
684  ConOut    = gST->ConOut;
685  Index     = 0;
686  ValidMode = 0;
687  MaxMode   = (UINTN) (ConOut->Mode->MaxMode);
688
689  CallbackData->BmmAskSaveOrNot = TRUE;
690
691  UpdatePageStart (CallbackData);
692
693  //
694  // Check valid mode
695  //
696  for (Mode = 0; Mode < MaxMode; Mode++) {
697    Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
698    if (EFI_ERROR (Status)) {
699      continue;
700    }
701    ValidMode++;
702  }
703
704  if (ValidMode == 0) {
705    return;
706  }
707
708  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
709  ASSERT (OptionsOpCodeHandle != NULL);
710
711  ModeToken           = AllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode);
712  ASSERT(ModeToken != NULL);
713
714  //
715  // Determin which mode should be the first entry in menu
716  //
717  GetConsoleOutMode (CallbackData);
718
719  //
720  // Build text mode options
721  //
722  for (Mode = 0; Mode < MaxMode; Mode++) {
723    Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
724    if (EFI_ERROR (Status)) {
725      continue;
726    }
727
728    //
729    // Build mode string Column x Row
730    //
731    UnicodeValueToString (ModeString, 0, Col, 0);
732    PStr = &ModeString[0];
733    StrnCatS (PStr, sizeof (ModeString) / sizeof (ModeString[0]), L" x ", StrLen(L" x ") + 1);
734    PStr = PStr + StrLen (PStr);
735    UnicodeValueToString (PStr , 0, Row, 0);
736
737    ModeToken[Index] = HiiSetString (CallbackData->BmmHiiHandle, 0, ModeString, NULL);
738
739    if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) {
740      HiiCreateOneOfOptionOpCode (
741        OptionsOpCodeHandle,
742        ModeToken[Index],
743        EFI_IFR_OPTION_DEFAULT,
744        EFI_IFR_TYPE_NUM_SIZE_16,
745        (UINT16) Mode
746        );
747    } else {
748      HiiCreateOneOfOptionOpCode (
749        OptionsOpCodeHandle,
750        ModeToken[Index],
751        0,
752        EFI_IFR_TYPE_NUM_SIZE_16,
753        (UINT16) Mode
754        );
755    }
756    Index++;
757  }
758
759  HiiCreateOneOfOpCode (
760    mStartOpCodeHandle,
761    (EFI_QUESTION_ID) CON_MODE_QUESTION_ID,
762    VARSTORE_ID_BOOT_MAINT,
763    CON_MODE_VAR_OFFSET,
764    STRING_TOKEN (STR_CON_MODE_SETUP),
765    STRING_TOKEN (STR_CON_MODE_SETUP),
766    EFI_IFR_FLAG_RESET_REQUIRED,
767    EFI_IFR_NUMERIC_SIZE_2,
768    OptionsOpCodeHandle,
769    NULL
770    );
771
772  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
773  FreePool (ModeToken);
774
775  UpdatePageEnd (CallbackData);
776}
777
778 /**
779  Create the dynamic page which allows user to set the property such as Baud Rate, Data Bits,
780  Parity, Stop Bits, Terminal Type.
781
782  @param CallbackData    The BMM context data.
783
784**/
785VOID
786UpdateTerminalPage (
787  IN BMM_CALLBACK_DATA                *CallbackData
788  )
789{
790  UINT8               Index;
791  UINT8               CheckFlags;
792  BM_MENU_ENTRY       *NewMenuEntry;
793  VOID                *OptionsOpCodeHandle;
794  UINTN               CurrentTerminal;
795
796  CallbackData->BmmAskSaveOrNot = TRUE;
797
798  UpdatePageStart (CallbackData);
799
800  CurrentTerminal = CallbackData->CurrentTerminal;
801  NewMenuEntry = BOpt_GetMenuEntry (
802                  &TerminalMenu,
803                  CurrentTerminal
804                  );
805
806  if (NewMenuEntry == NULL) {
807    return ;
808  }
809
810  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
811  ASSERT (OptionsOpCodeHandle != NULL);
812
813  for (Index = 0; Index < sizeof (BaudRateList) / sizeof (BaudRateList [0]); Index++) {
814    CheckFlags = 0;
815    if (BaudRateList[Index].Value == 115200) {
816      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
817    }
818    HiiCreateOneOfOptionOpCode (
819      OptionsOpCodeHandle,
820      BaudRateList[Index].StringToken,
821      CheckFlags,
822      EFI_IFR_TYPE_NUM_SIZE_8,
823      Index
824      );
825  }
826
827  HiiCreateOneOfOpCode (
828    mStartOpCodeHandle,
829    (EFI_QUESTION_ID) (COM_BAUD_RATE_QUESTION_ID + CurrentTerminal),
830    VARSTORE_ID_BOOT_MAINT,
831    (UINT16) (COM_BAUD_RATE_VAR_OFFSET + CurrentTerminal),
832    STRING_TOKEN (STR_COM_BAUD_RATE),
833    STRING_TOKEN (STR_COM_BAUD_RATE),
834    0,
835    EFI_IFR_NUMERIC_SIZE_1,
836    OptionsOpCodeHandle,
837    NULL
838    );
839
840  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
841  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
842  ASSERT (OptionsOpCodeHandle != NULL);
843
844  for (Index = 0; Index < sizeof (DataBitsList) / sizeof (DataBitsList[0]); Index++) {
845    CheckFlags = 0;
846
847    if (DataBitsList[Index].Value == 8) {
848      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
849    }
850
851    HiiCreateOneOfOptionOpCode (
852      OptionsOpCodeHandle,
853      DataBitsList[Index].StringToken,
854      CheckFlags,
855      EFI_IFR_TYPE_NUM_SIZE_8,
856      Index
857      );
858  }
859
860  HiiCreateOneOfOpCode (
861    mStartOpCodeHandle,
862    (EFI_QUESTION_ID) (COM_DATA_RATE_QUESTION_ID + CurrentTerminal),
863    VARSTORE_ID_BOOT_MAINT,
864    (UINT16) (COM_DATA_RATE_VAR_OFFSET + CurrentTerminal),
865    STRING_TOKEN (STR_COM_DATA_BITS),
866    STRING_TOKEN (STR_COM_DATA_BITS),
867    0,
868    EFI_IFR_NUMERIC_SIZE_1,
869    OptionsOpCodeHandle,
870    NULL
871    );
872
873  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
874  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
875  ASSERT (OptionsOpCodeHandle != NULL);
876
877  for (Index = 0; Index < sizeof (ParityList) / sizeof (ParityList[0]); Index++) {
878    CheckFlags = 0;
879    if (ParityList[Index].Value ==  NoParity) {
880      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
881    }
882
883    HiiCreateOneOfOptionOpCode (
884      OptionsOpCodeHandle,
885      ParityList[Index].StringToken,
886      CheckFlags,
887      EFI_IFR_TYPE_NUM_SIZE_8,
888      Index
889      );
890  }
891
892  HiiCreateOneOfOpCode (
893    mStartOpCodeHandle,
894    (EFI_QUESTION_ID) (COM_PARITY_QUESTION_ID + CurrentTerminal),
895    VARSTORE_ID_BOOT_MAINT,
896    (UINT16) (COM_PARITY_VAR_OFFSET + CurrentTerminal),
897    STRING_TOKEN (STR_COM_PARITY),
898    STRING_TOKEN (STR_COM_PARITY),
899    0,
900    EFI_IFR_NUMERIC_SIZE_1,
901    OptionsOpCodeHandle,
902    NULL
903    );
904
905  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
906  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
907  ASSERT (OptionsOpCodeHandle != NULL);
908
909  for (Index = 0; Index < sizeof (StopBitsList) / sizeof (StopBitsList[0]); Index++) {
910    CheckFlags = 0;
911    if (StopBitsList[Index].Value == OneStopBit) {
912      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
913    }
914
915    HiiCreateOneOfOptionOpCode (
916      OptionsOpCodeHandle,
917      StopBitsList[Index].StringToken,
918      CheckFlags,
919      EFI_IFR_TYPE_NUM_SIZE_8,
920      Index
921      );
922  }
923
924  HiiCreateOneOfOpCode (
925    mStartOpCodeHandle,
926    (EFI_QUESTION_ID) (COM_STOP_BITS_QUESTION_ID + CurrentTerminal),
927    VARSTORE_ID_BOOT_MAINT,
928    (UINT16) (COM_STOP_BITS_VAR_OFFSET + CurrentTerminal),
929    STRING_TOKEN (STR_COM_STOP_BITS),
930    STRING_TOKEN (STR_COM_STOP_BITS),
931    0,
932    EFI_IFR_NUMERIC_SIZE_1,
933    OptionsOpCodeHandle,
934    NULL
935    );
936
937  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
938  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
939  ASSERT (OptionsOpCodeHandle != NULL);
940
941  for (Index = 0; Index < sizeof (TerminalType) / sizeof (TerminalType[0]); Index++) {
942    CheckFlags = 0;
943    if (Index == 0) {
944      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
945    }
946
947    HiiCreateOneOfOptionOpCode (
948      OptionsOpCodeHandle,
949      (EFI_STRING_ID) TerminalType[Index],
950      CheckFlags,
951      EFI_IFR_TYPE_NUM_SIZE_8,
952      Index
953      );
954  }
955
956  HiiCreateOneOfOpCode (
957    mStartOpCodeHandle,
958    (EFI_QUESTION_ID) (COM_TERMINAL_QUESTION_ID + CurrentTerminal),
959    VARSTORE_ID_BOOT_MAINT,
960    (UINT16) (COM_TERMINAL_VAR_OFFSET + CurrentTerminal),
961    STRING_TOKEN (STR_COM_TERMI_TYPE),
962    STRING_TOKEN (STR_COM_TERMI_TYPE),
963    0,
964    EFI_IFR_NUMERIC_SIZE_1,
965    OptionsOpCodeHandle,
966    NULL
967    );
968
969  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
970  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
971  ASSERT (OptionsOpCodeHandle != NULL);
972
973  for (Index = 0; Index < sizeof (mFlowControlType) / sizeof (mFlowControlType[0]); Index++) {
974  CheckFlags = 0;
975    if (Index == 0) {
976      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
977    }
978    HiiCreateOneOfOptionOpCode (
979      OptionsOpCodeHandle,
980      (EFI_STRING_ID) mFlowControlType[Index],
981      CheckFlags,
982      EFI_IFR_TYPE_NUM_SIZE_8,
983      mFlowControlValue[Index]
984      );
985  }
986
987  HiiCreateOneOfOpCode (
988    mStartOpCodeHandle,
989    (EFI_QUESTION_ID) (COM_FLOWCONTROL_QUESTION_ID + CurrentTerminal),
990    VARSTORE_ID_BOOT_MAINT,
991    (UINT16) (COM_FLOWCONTROL_VAR_OFFSET + CurrentTerminal),
992    STRING_TOKEN (STR_COM_FLOW_CONTROL),
993    STRING_TOKEN (STR_COM_FLOW_CONTROL),
994    0,
995    EFI_IFR_NUMERIC_SIZE_1,
996    OptionsOpCodeHandle,
997    NULL
998    );
999
1000  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1001
1002  UpdatePageEnd (CallbackData);
1003}
1004
1005/**
1006Update add boot/driver option page.
1007
1008@param CallbackData    The BMM context data.
1009@param FormId             The form ID to be updated.
1010@param DevicePath       Device path.
1011
1012**/
1013VOID
1014UpdateOptionPage(
1015  IN   BMM_CALLBACK_DATA        *CallbackData,
1016  IN   EFI_FORM_ID              FormId,
1017  IN   EFI_DEVICE_PATH_PROTOCOL *DevicePath
1018  )
1019{
1020  CHAR16                *String;
1021  EFI_STRING_ID         StringToken;
1022
1023  String = NULL;
1024
1025  if (DevicePath != NULL){
1026    String = ExtractFileNameFromDevicePath(DevicePath);
1027  }
1028  if (String == NULL) {
1029    String = HiiGetString (CallbackData->BmmHiiHandle, STRING_TOKEN (STR_NULL_STRING), NULL);
1030    ASSERT (String != NULL);
1031  }
1032
1033  StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, String, NULL);
1034  FreePool (String);
1035
1036  if(FormId == FORM_BOOT_ADD_ID){
1037    if (!CallbackData->BmmFakeNvData.BootOptionChanged) {
1038      ZeroMem (CallbackData->BmmFakeNvData.BootOptionalData, sizeof (CallbackData->BmmFakeNvData.BootOptionalData));
1039      ZeroMem (CallbackData->BmmFakeNvData.BootDescriptionData, sizeof (CallbackData->BmmFakeNvData.BootDescriptionData));
1040    }
1041  } else if (FormId == FORM_DRV_ADD_FILE_ID){
1042    if (!CallbackData->BmmFakeNvData.DriverOptionChanged) {
1043      ZeroMem (CallbackData->BmmFakeNvData.DriverOptionalData, sizeof (CallbackData->BmmFakeNvData.DriverOptionalData));
1044      ZeroMem (CallbackData->BmmFakeNvData.DriverDescriptionData, sizeof (CallbackData->BmmFakeNvData.DriverDescriptionData));
1045    }
1046  }
1047
1048  RefreshUpdateData();
1049  mStartLabel->Number = FormId;
1050
1051  HiiCreateSubTitleOpCode (
1052    mStartOpCodeHandle,
1053    StringToken,
1054    0,
1055    0,
1056    0
1057    );
1058
1059  HiiUpdateForm (
1060    CallbackData->BmmHiiHandle,
1061    &mBootMaintGuid,
1062    FormId,
1063    mStartOpCodeHandle,// Label FormId
1064    mEndOpCodeHandle   // LABEL_END
1065    );
1066}
1067
1068/**
1069  Dispatch the correct update page function to call based on
1070  the UpdatePageId.
1071
1072  @param UpdatePageId    The form ID.
1073  @param CallbackData    The BMM context data.
1074
1075**/
1076VOID
1077UpdatePageBody (
1078  IN UINT16                           UpdatePageId,
1079  IN BMM_CALLBACK_DATA                *CallbackData
1080  )
1081{
1082  CleanUpPage (UpdatePageId, CallbackData);
1083  switch (UpdatePageId) {
1084  case FORM_CON_IN_ID:
1085    UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);
1086    break;
1087
1088  case FORM_CON_OUT_ID:
1089    UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);
1090    break;
1091
1092  case FORM_CON_ERR_ID:
1093    UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);
1094    break;
1095
1096  case FORM_BOOT_CHG_ID:
1097    UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);
1098    break;
1099
1100  case FORM_DRV_CHG_ID:
1101    UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);
1102    break;
1103
1104  default:
1105    break;
1106  }
1107}
1108
1109/**
1110  Dispatch the display to the next page based on NewPageId.
1111
1112  @param Private         The BMM context data.
1113  @param NewPageId       The original page ID.
1114
1115**/
1116VOID
1117UpdatePageId (
1118  BMM_CALLBACK_DATA              *Private,
1119  UINT16                         NewPageId
1120  )
1121{
1122  if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {
1123    //
1124    // If we select a handle to add driver option, advance to the add handle description page.
1125    //
1126    NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;
1127  } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {
1128    //
1129    // Return to main page after "Save Changes" or "Discard Changes".
1130    //
1131    NewPageId = FORM_MAIN_ID;
1132  } else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) {
1133    NewPageId = FORM_CON_COM_SETUP_ID;
1134  }
1135
1136  if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
1137    Private->BmmPreviousPageId  = Private->BmmCurrentPageId;
1138    Private->BmmCurrentPageId   = NewPageId;
1139  }
1140}
1141