]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
b974a67ea53402b4c8a850278858b6ff1c680ed1
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
1 /** @file
2 The functions for Boot Maintainence Main menu.
3
4 Copyright (c) 2004 - 2014, 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 #include "FormGuid.h"
17 #include "Bds.h"
18 #include "FrontPage.h"
19
20 EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {
21 {
22 END_DEVICE_PATH_TYPE,
23 END_ENTIRE_DEVICE_PATH_SUBTYPE,
24 {
25 END_DEVICE_PATH_LENGTH,
26 0
27 }
28 }
29 };
30
31 HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {
32 {
33 {
34 HARDWARE_DEVICE_PATH,
35 HW_VENDOR_DP,
36 {
37 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
38 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
39 }
40 },
41 BOOT_MAINT_FORMSET_GUID
42 },
43 {
44 END_DEVICE_PATH_TYPE,
45 END_ENTIRE_DEVICE_PATH_SUBTYPE,
46 {
47 (UINT8) (END_DEVICE_PATH_LENGTH),
48 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
49 }
50 }
51 };
52
53 HII_VENDOR_DEVICE_PATH mFeHiiVendorDevicePath = {
54 {
55 {
56 HARDWARE_DEVICE_PATH,
57 HW_VENDOR_DP,
58 {
59 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
60 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
61 }
62 },
63 FILE_EXPLORE_FORMSET_GUID
64 },
65 {
66 END_DEVICE_PATH_TYPE,
67 END_ENTIRE_DEVICE_PATH_SUBTYPE,
68 {
69 (UINT8) (END_DEVICE_PATH_LENGTH),
70 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
71 }
72 }
73 };
74
75 CHAR16 mBootMaintStorageName[] = L"BmmData";
76 CHAR16 mFileExplorerStorageName[] = L"FeData";
77
78 /**
79 Init all memu.
80
81 @param CallbackData The BMM context data.
82
83 **/
84 VOID
85 InitAllMenu (
86 IN BMM_CALLBACK_DATA *CallbackData
87 );
88
89 /**
90 Free up all Menu Option list.
91
92 **/
93 VOID
94 FreeAllMenu (
95 VOID
96 );
97
98 /**
99 Create string tokens for a menu from its help strings and display strings
100
101 @param CallbackData The BMM context data.
102 @param HiiHandle Hii Handle of the package to be updated.
103 @param MenuOption The Menu whose string tokens need to be created
104
105 @retval EFI_SUCCESS String tokens created successfully
106 @retval others contain some errors
107 **/
108 EFI_STATUS
109 CreateMenuStringToken (
110 IN BMM_CALLBACK_DATA *CallbackData,
111 IN EFI_HII_HANDLE HiiHandle,
112 IN BM_MENU_OPTION *MenuOption
113 )
114 {
115 BM_MENU_ENTRY *NewMenuEntry;
116 UINTN Index;
117
118 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
119 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
120
121 NewMenuEntry->DisplayStringToken = HiiSetString (
122 HiiHandle,
123 0,
124 NewMenuEntry->DisplayString,
125 NULL
126 );
127
128 if (NULL == NewMenuEntry->HelpString) {
129 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
130 } else {
131 NewMenuEntry->HelpStringToken = HiiSetString (
132 HiiHandle,
133 0,
134 NewMenuEntry->HelpString,
135 NULL
136 );
137 }
138 }
139
140 return EFI_SUCCESS;
141 }
142
143 /**
144 This function allows a caller to extract the current configuration for one
145 or more named elements from the target driver.
146
147
148 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
149 @param Request A null-terminated Unicode string in <ConfigRequest> format.
150 @param Progress On return, points to a character in the Request string.
151 Points to the string's null terminator if request was successful.
152 Points to the most recent '&' before the first failing name/value
153 pair (or the beginning of the string if the failure is in the
154 first name/value pair) if the request was not successful.
155 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
156 has all values filled in for the names in the Request string.
157 String to be allocated by the called function.
158
159 @retval EFI_SUCCESS The Results is filled with the requested values.
160 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
161 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
162 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
163
164 **/
165 EFI_STATUS
166 EFIAPI
167 BootMaintExtractConfig (
168 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
169 IN CONST EFI_STRING Request,
170 OUT EFI_STRING *Progress,
171 OUT EFI_STRING *Results
172 )
173 {
174 EFI_STATUS Status;
175 UINTN BufferSize;
176 BMM_CALLBACK_DATA *Private;
177 EFI_STRING ConfigRequestHdr;
178 EFI_STRING ConfigRequest;
179 BOOLEAN AllocatedRequest;
180 UINTN Size;
181
182 if (Progress == NULL || Results == NULL) {
183 return EFI_INVALID_PARAMETER;
184 }
185
186 *Progress = Request;
187 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gBootMaintFormSetGuid, mBootMaintStorageName)) {
188 return EFI_NOT_FOUND;
189 }
190
191 ConfigRequestHdr = NULL;
192 ConfigRequest = NULL;
193 AllocatedRequest = FALSE;
194 Size = 0;
195
196 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
197 //
198 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
199 //
200 BufferSize = sizeof (BMM_FAKE_NV_DATA);
201 ConfigRequest = Request;
202 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
203 //
204 // Request has no request element, construct full request string.
205 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
206 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
207 //
208 ConfigRequestHdr = HiiConstructConfigHdr (&gBootMaintFormSetGuid, mBootMaintStorageName, Private->BmmDriverHandle);
209 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
210 ConfigRequest = AllocateZeroPool (Size);
211 ASSERT (ConfigRequest != NULL);
212 AllocatedRequest = TRUE;
213 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
214 FreePool (ConfigRequestHdr);
215 }
216
217 Status = gHiiConfigRouting->BlockToConfig (
218 gHiiConfigRouting,
219 ConfigRequest,
220 (UINT8 *) &Private->BmmFakeNvData,
221 BufferSize,
222 Results,
223 Progress
224 );
225 //
226 // Free the allocated config request string.
227 //
228 if (AllocatedRequest) {
229 FreePool (ConfigRequest);
230 ConfigRequest = NULL;
231 }
232 //
233 // Set Progress string to the original request string.
234 //
235 if (Request == NULL) {
236 *Progress = NULL;
237 } else if (StrStr (Request, L"OFFSET") == NULL) {
238 *Progress = Request + StrLen (Request);
239 }
240
241 return Status;
242 }
243
244 /**
245 This function processes the results of changes in configuration.
246
247
248 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
249 @param Action Specifies the type of action taken by the browser.
250 @param QuestionId A unique value which is sent to the original exporting driver
251 so that it can identify the type of data to expect.
252 @param Type The type of value for the question.
253 @param Value A pointer to the data being sent to the original exporting driver.
254 @param ActionRequest On return, points to the action requested by the callback function.
255
256 @retval EFI_SUCCESS The callback successfully handled the action.
257 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
258 @retval EFI_DEVICE_ERROR The variable could not be saved.
259 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
260 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
261 **/
262 EFI_STATUS
263 EFIAPI
264 BootMaintCallback (
265 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
266 IN EFI_BROWSER_ACTION Action,
267 IN EFI_QUESTION_ID QuestionId,
268 IN UINT8 Type,
269 IN EFI_IFR_TYPE_VALUE *Value,
270 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
271 )
272 {
273 BMM_CALLBACK_DATA *Private;
274 BM_MENU_ENTRY *NewMenuEntry;
275 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
276 EFI_STATUS Status;
277 UINTN OldValue;
278 UINTN NewValue;
279 UINTN Number;
280 UINTN Pos;
281 UINTN Bit;
282 UINT16 NewValuePos;
283 UINT16 Index3;
284 UINT16 Index2;
285 UINT16 Index;
286 UINT8 *OldLegacyDev;
287 UINT8 *NewLegacyDev;
288 UINT8 *DisMap;
289
290 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
291 //
292 // All other action return unsupported.
293 //
294 return EFI_UNSUPPORTED;
295 }
296
297 Status = EFI_SUCCESS;
298 OldValue = 0;
299 NewValue = 0;
300 Number = 0;
301 OldLegacyDev = NULL;
302 NewLegacyDev = NULL;
303 NewValuePos = 0;
304 DisMap = NULL;
305
306 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
307 //
308 // Retrive uncommitted data from Form Browser
309 //
310 CurrentFakeNVMap = &Private->BmmFakeNvData;
311 HiiGetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);
312 if (Action == EFI_BROWSER_ACTION_CHANGING) {
313 if (Value == NULL) {
314 return EFI_INVALID_PARAMETER;
315 }
316
317 UpdatePageId (Private, QuestionId);
318
319 if (QuestionId < FILE_OPTION_OFFSET) {
320 if (QuestionId < CONFIG_OPTION_OFFSET) {
321 switch (QuestionId) {
322 case KEY_VALUE_BOOT_FROM_FILE:
323 Private->FeCurrentState = FileExplorerStateBootFromFile;
324 break;
325
326 case FORM_BOOT_ADD_ID:
327 Private->FeCurrentState = FileExplorerStateAddBootOption;
328 break;
329
330 case FORM_DRV_ADD_FILE_ID:
331 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;
332 break;
333
334 case FORM_DRV_ADD_HANDLE_ID:
335 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
336 UpdateDrvAddHandlePage (Private);
337 break;
338
339 case FORM_BOOT_DEL_ID:
340 CleanUpPage (FORM_BOOT_DEL_ID, Private);
341 UpdateBootDelPage (Private);
342 break;
343
344 case FORM_BOOT_CHG_ID:
345 case FORM_DRV_CHG_ID:
346 UpdatePageBody (QuestionId, Private);
347 break;
348
349 case FORM_DRV_DEL_ID:
350 CleanUpPage (FORM_DRV_DEL_ID, Private);
351 UpdateDrvDelPage (Private);
352 break;
353
354 case FORM_BOOT_NEXT_ID:
355 CleanUpPage (FORM_BOOT_NEXT_ID, Private);
356 UpdateBootNextPage (Private);
357 break;
358
359 case FORM_TIME_OUT_ID:
360 CleanUpPage (FORM_TIME_OUT_ID, Private);
361 UpdateTimeOutPage (Private);
362 break;
363
364 case FORM_CON_IN_ID:
365 case FORM_CON_OUT_ID:
366 case FORM_CON_ERR_ID:
367 UpdatePageBody (QuestionId, Private);
368 break;
369
370 case FORM_CON_MODE_ID:
371 CleanUpPage (FORM_CON_MODE_ID, Private);
372 UpdateConModePage (Private);
373 break;
374
375 case FORM_CON_COM_ID:
376 CleanUpPage (FORM_CON_COM_ID, Private);
377 UpdateConCOMPage (Private);
378 break;
379
380 case FORM_SET_FD_ORDER_ID:
381 case FORM_SET_HD_ORDER_ID:
382 case FORM_SET_CD_ORDER_ID:
383 case FORM_SET_NET_ORDER_ID:
384 case FORM_SET_BEV_ORDER_ID:
385 CleanUpPage (QuestionId, Private);
386 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);
387 break;
388
389 default:
390 break;
391 }
392 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
393 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
394 Private->CurrentTerminal = Index2;
395
396 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
397 UpdateTerminalPage (Private);
398
399 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
400 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);
401
402 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);
403 ASSERT (NewMenuEntry != NULL);
404 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
405
406 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
407
408 Private->MenuEntry = NewMenuEntry;
409 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
410
411 UpdateDriverAddHandleDescPage (Private);
412 }
413 }
414 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
415 if ((Value == NULL) || (ActionRequest == NULL)) {
416 return EFI_INVALID_PARAMETER;
417 }
418
419 //
420 // need to be subtituded.
421 //
422 // Update Select FD/HD/CD/NET/BEV Order Form
423 //
424 if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {
425
426 DisMap = Private->BmmOldFakeNVData.DisableMap;
427
428 if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {
429 Number = (UINT16) LegacyFDMenu.MenuNumber;
430 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;
431 NewLegacyDev = CurrentFakeNVMap->LegacyFD;
432 } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {
433 Number = (UINT16) LegacyHDMenu.MenuNumber;
434 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;
435 NewLegacyDev = CurrentFakeNVMap->LegacyHD;
436 } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {
437 Number = (UINT16) LegacyCDMenu.MenuNumber;
438 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;
439 NewLegacyDev = CurrentFakeNVMap->LegacyCD;
440 } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {
441 Number = (UINT16) LegacyNETMenu.MenuNumber;
442 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;
443 NewLegacyDev = CurrentFakeNVMap->LegacyNET;
444 } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {
445 Number = (UINT16) LegacyBEVMenu.MenuNumber;
446 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;
447 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;
448 }
449 //
450 // First, find the different position
451 // if there is change, it should be only one
452 //
453 for (Index = 0; Index < Number; Index++) {
454 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
455 OldValue = OldLegacyDev[Index];
456 NewValue = NewLegacyDev[Index];
457 break;
458 }
459 }
460
461 if (Index != Number) {
462 //
463 // there is change, now process
464 //
465 if (0xFF == NewValue) {
466 //
467 // This item will be disable
468 // Just move the items behind this forward to overlap it
469 //
470 Pos = OldValue / 8;
471 Bit = 7 - (OldValue % 8);
472 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
473 for (Index2 = Index; Index2 < Number - 1; Index2++) {
474 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
475 }
476
477 NewLegacyDev[Index2] = 0xFF;
478 } else {
479 for (Index2 = 0; Index2 < Number; Index2++) {
480 if (Index2 == Index) {
481 continue;
482 }
483
484 if (OldLegacyDev[Index2] == NewValue) {
485 //
486 // If NewValue is in OldLegacyDev array
487 // remember its old position
488 //
489 NewValuePos = Index2;
490 break;
491 }
492 }
493
494 if (Index2 != Number) {
495 //
496 // We will change current item to an existing item
497 // (It's hard to describe here, please read code, it's like a cycle-moving)
498 //
499 for (Index2 = NewValuePos; Index2 != Index;) {
500 if (NewValuePos < Index) {
501 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
502 Index2++;
503 } else {
504 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
505 Index2--;
506 }
507 }
508 } else {
509 //
510 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
511 // so we should modify DisMap to reflect the change
512 //
513 Pos = NewValue / 8;
514 Bit = 7 - (NewValue % 8);
515 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));
516 if (0xFF != OldValue) {
517 //
518 // Because NewValue is a item that was disabled before
519 // so after changing the OldValue should be disabled
520 // actually we are doing a swap of enable-disable states of two items
521 //
522 Pos = OldValue / 8;
523 Bit = 7 - (OldValue % 8);
524 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
525 }
526 }
527 }
528 //
529 // To prevent DISABLE appears in the middle of the list
530 // we should perform a re-ordering
531 //
532 Index3 = Index;
533 Index = 0;
534 while (Index < Number) {
535 if (0xFF != NewLegacyDev[Index]) {
536 Index++;
537 continue;
538 }
539
540 Index2 = Index;
541 Index2++;
542 while (Index2 < Number) {
543 if (0xFF != NewLegacyDev[Index2]) {
544 break;
545 }
546
547 Index2++;
548 }
549
550 if (Index2 < Number) {
551 NewLegacyDev[Index] = NewLegacyDev[Index2];
552 NewLegacyDev[Index2] = 0xFF;
553 }
554
555 Index++;
556 }
557
558 CopyMem (
559 OldLegacyDev,
560 NewLegacyDev,
561 Number
562 );
563
564 //
565 // Return correct question value.
566 //
567 Value->u8 = NewLegacyDev[Index3];
568 }
569 } else {
570 switch (QuestionId) {
571 case KEY_VALUE_SAVE_AND_EXIT:
572 case KEY_VALUE_NO_SAVE_AND_EXIT:
573 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
574 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
575 if (EFI_ERROR (Status)) {
576 return Status;
577 }
578 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
579 DiscardChangeHandler (Private, CurrentFakeNVMap);
580 }
581
582 //
583 // Tell browser not to ask for confirmation of changes,
584 // since we have already applied or discarded.
585 //
586 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
587 break;
588
589 case FORM_RESET:
590 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
591 return EFI_UNSUPPORTED;
592
593 default:
594 break;
595 }
596 }
597 }
598
599 //
600 // Pass changed uncommitted data back to Form Browser
601 //
602 HiiSetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);
603 return EFI_SUCCESS;
604 }
605
606 /**
607 Function handling request to apply changes for BMM pages.
608
609 @param Private Pointer to callback data buffer.
610 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM
611 @param FormId ID of the form which has sent the request to apply change.
612
613 @retval EFI_SUCCESS Change successfully applied.
614 @retval Other Error occurs while trying to apply changes.
615
616 **/
617 EFI_STATUS
618 ApplyChangeHandler (
619 IN BMM_CALLBACK_DATA *Private,
620 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,
621 IN EFI_FORM_ID FormId
622 )
623 {
624 BM_CONSOLE_CONTEXT *NewConsoleContext;
625 BM_TERMINAL_CONTEXT *NewTerminalContext;
626 BM_LOAD_CONTEXT *NewLoadContext;
627 BM_MENU_ENTRY *NewMenuEntry;
628 EFI_STATUS Status;
629 UINT16 Index;
630
631 Status = EFI_SUCCESS;
632
633 switch (FormId) {
634 case FORM_SET_FD_ORDER_ID:
635 case FORM_SET_HD_ORDER_ID:
636 case FORM_SET_CD_ORDER_ID:
637 case FORM_SET_NET_ORDER_ID:
638 case FORM_SET_BEV_ORDER_ID:
639 Var_UpdateBBSOption (Private);
640 break;
641
642 case FORM_BOOT_DEL_ID:
643 for (Index = 0;
644 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0]))));
645 Index ++) {
646 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
647 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
648 NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];
649 }
650
651 Var_DelBootOption ();
652 break;
653
654 case FORM_DRV_DEL_ID:
655 for (Index = 0;
656 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0]))));
657 Index++) {
658 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
659 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
660 NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];
661 }
662
663 Var_DelDriverOption ();
664 break;
665
666 case FORM_BOOT_CHG_ID:
667 Status = Var_UpdateBootOrder (Private);
668 break;
669
670 case FORM_DRV_CHG_ID:
671 Status = Var_UpdateDriverOrder (Private);
672 break;
673
674 case FORM_TIME_OUT_ID:
675 BdsDxeSetVariableAndReportStatusCodeOnError (
676 L"Timeout",
677 &gEfiGlobalVariableGuid,
678 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
679 sizeof (UINT16),
680 &(CurrentFakeNVMap->BootTimeOut)
681 );
682
683 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
684 break;
685
686 case FORM_BOOT_NEXT_ID:
687 Status = Var_UpdateBootNext (Private);
688 break;
689
690 case FORM_CON_MODE_ID:
691 Status = Var_UpdateConMode (Private);
692 break;
693
694 case FORM_CON_COM_SETUP_ID:
695 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);
696
697 ASSERT (NewMenuEntry != NULL);
698
699 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
700
701 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;
702 ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));
703 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;
704 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;
705 ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));
706 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;
707 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;
708 ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));
709 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;
710 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;
711 ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0])));
712 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;
713 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;
714 NewTerminalContext->FlowControl = CurrentFakeNVMap->COMFlowControl;
715
716 ChangeTerminalDevicePath (
717 &(NewTerminalContext->DevicePath),
718 FALSE
719 );
720
721 Var_UpdateConsoleInpOption ();
722 Var_UpdateConsoleOutOption ();
723 Var_UpdateErrorOutOption ();
724 break;
725
726 case FORM_CON_IN_ID:
727 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
728 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
729 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
730 ASSERT (Index < MAX_MENU_NUMBER);
731 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
732 }
733
734 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
735 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
736 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
737 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
738 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];
739 }
740
741 Var_UpdateConsoleInpOption ();
742 break;
743
744 case FORM_CON_OUT_ID:
745 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
746 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
747 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
748 ASSERT (Index < MAX_MENU_NUMBER);
749 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
750 }
751
752 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
753 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
754 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
755 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
756 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];
757 }
758
759 Var_UpdateConsoleOutOption ();
760 break;
761
762 case FORM_CON_ERR_ID:
763 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
764 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
765 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
766 ASSERT (Index < MAX_MENU_NUMBER);
767 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
768 }
769
770 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
771 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
772 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
773 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
774 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];
775 }
776
777 Var_UpdateErrorOutOption ();
778 break;
779
780 case FORM_DRV_ADD_HANDLE_DESC_ID:
781 Status = Var_UpdateDriverOption (
782 Private,
783 Private->BmmHiiHandle,
784 CurrentFakeNVMap->DriverAddHandleDesc,
785 CurrentFakeNVMap->DriverAddHandleOptionalData,
786 CurrentFakeNVMap->DriverAddForceReconnect
787 );
788 if (EFI_ERROR (Status)) {
789 goto Error;
790 }
791
792 BOpt_GetDriverOptions (Private);
793 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);
794 break;
795
796 default:
797 break;
798 }
799
800 Error:
801 return Status;
802 }
803
804 /**
805 Discard all changes done to the BMM pages such as Boot Order change,
806 Driver order change.
807
808 @param Private The BMM context data.
809 @param CurrentFakeNVMap The current Fack NV Map.
810
811 **/
812 VOID
813 DiscardChangeHandler (
814 IN BMM_CALLBACK_DATA *Private,
815 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
816 )
817 {
818 UINT16 Index;
819
820 switch (Private->BmmPreviousPageId) {
821 case FORM_BOOT_CHG_ID:
822 case FORM_DRV_CHG_ID:
823 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, sizeof (CurrentFakeNVMap->OptionOrder));
824 break;
825
826 case FORM_BOOT_DEL_ID:
827 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));
828 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
829 CurrentFakeNVMap->OptionDel[Index] = FALSE;
830 }
831 break;
832
833 case FORM_DRV_DEL_ID:
834 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));
835 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
836 CurrentFakeNVMap->OptionDel[Index] = FALSE;
837 }
838 break;
839
840 case FORM_BOOT_NEXT_ID:
841 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
842 break;
843
844 case FORM_TIME_OUT_ID:
845 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
846 break;
847
848 case FORM_DRV_ADD_HANDLE_DESC_ID:
849 case FORM_DRV_ADD_FILE_ID:
850 case FORM_DRV_ADD_HANDLE_ID:
851 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
852 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
853 break;
854
855 default:
856 break;
857 }
858 }
859
860 /**
861 Initialize the Boot Maintenance Utitliy.
862
863
864 @retval EFI_SUCCESS utility ended successfully
865 @retval others contain some errors
866
867 **/
868 EFI_STATUS
869 InitializeBM (
870 VOID
871 )
872 {
873 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
874 BMM_CALLBACK_DATA *BmmCallbackInfo;
875 EFI_STATUS Status;
876 UINT8 *Ptr;
877
878 Status = EFI_SUCCESS;
879
880 //
881 // Create CallbackData structures for Driver Callback
882 //
883 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
884 if (BmmCallbackInfo == NULL) {
885 return EFI_OUT_OF_RESOURCES;
886 }
887
888 //
889 // Create LoadOption in BmmCallbackInfo for Driver Callback
890 //
891 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
892 if (Ptr == NULL) {
893 FreePool (BmmCallbackInfo);
894 return EFI_OUT_OF_RESOURCES;
895 }
896
897 //
898 // Initialize Bmm callback data.
899 //
900 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
901 Ptr += sizeof (BM_LOAD_CONTEXT);
902
903 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
904 Ptr += sizeof (BM_FILE_CONTEXT);
905
906 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
907 Ptr += sizeof (BM_HANDLE_CONTEXT);
908
909 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
910
911 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;
912 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
913 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;
914 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;
915 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
916 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
917 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;
918 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;
919 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;
920 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;
921 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;
922
923 //
924 // Install Device Path Protocol and Config Access protocol to driver handle
925 //
926 Status = gBS->InstallMultipleProtocolInterfaces (
927 &BmmCallbackInfo->BmmDriverHandle,
928 &gEfiDevicePathProtocolGuid,
929 &mBmmHiiVendorDevicePath,
930 &gEfiHiiConfigAccessProtocolGuid,
931 &BmmCallbackInfo->BmmConfigAccess,
932 NULL
933 );
934 if (EFI_ERROR (Status)) {
935 goto Exit;
936 }
937
938 //
939 // Install Device Path Protocol and Config Access protocol to driver handle
940 //
941 Status = gBS->InstallMultipleProtocolInterfaces (
942 &BmmCallbackInfo->FeDriverHandle,
943 &gEfiDevicePathProtocolGuid,
944 &mFeHiiVendorDevicePath,
945 &gEfiHiiConfigAccessProtocolGuid,
946 &BmmCallbackInfo->FeConfigAccess,
947 NULL
948 );
949 if (EFI_ERROR (Status)) {
950 goto Exit;
951 }
952
953 //
954 // Post our Boot Maint VFR binary to the HII database.
955 //
956 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
957 &gBootMaintFormSetGuid,
958 BmmCallbackInfo->BmmDriverHandle,
959 BmBin,
960 BdsDxeStrings,
961 NULL
962 );
963 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);
964
965 //
966 // Post our File Explorer VFR binary to the HII database.
967 //
968 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (
969 &gFileExploreFormSetGuid,
970 BmmCallbackInfo->FeDriverHandle,
971 FEBin,
972 BdsDxeStrings,
973 NULL
974 );
975 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);
976
977 //
978 // Init OpCode Handle and Allocate space for creation of Buffer
979 //
980 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
981 if (mStartOpCodeHandle == NULL) {
982 Status = EFI_OUT_OF_RESOURCES;
983 goto Exit;
984 }
985
986 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
987 if (mEndOpCodeHandle == NULL) {
988 Status = EFI_OUT_OF_RESOURCES;
989 goto Exit;
990 }
991
992 //
993 // Create Hii Extend Label OpCode as the start opcode
994 //
995 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
996 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
997
998 //
999 // Create Hii Extend Label OpCode as the end opcode
1000 //
1001 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1002 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1003 mEndLabel->Number = LABEL_END;
1004
1005 InitializeStringDepository ();
1006
1007 InitAllMenu (BmmCallbackInfo);
1008
1009 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
1010 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
1011 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
1012 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
1013 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
1014 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
1015 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
1016
1017 UpdateBootDelPage (BmmCallbackInfo);
1018 UpdateDrvDelPage (BmmCallbackInfo);
1019
1020 if (TerminalMenu.MenuNumber > 0) {
1021 BmmCallbackInfo->CurrentTerminal = 0;
1022 UpdateTerminalPage (BmmCallbackInfo);
1023 }
1024
1025 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
1026 if (!EFI_ERROR (Status)) {
1027 RefreshUpdateData ();
1028 mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;
1029
1030 //
1031 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
1032 // in BootOption form: legacy FD/HD/CD/NET/BEV
1033 //
1034 HiiCreateGotoOpCode (
1035 mStartOpCodeHandle,
1036 FORM_SET_FD_ORDER_ID,
1037 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
1038 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
1039 EFI_IFR_FLAG_CALLBACK,
1040 FORM_SET_FD_ORDER_ID
1041 );
1042
1043 HiiCreateGotoOpCode (
1044 mStartOpCodeHandle,
1045 FORM_SET_HD_ORDER_ID,
1046 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
1047 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
1048 EFI_IFR_FLAG_CALLBACK,
1049 FORM_SET_HD_ORDER_ID
1050 );
1051
1052 HiiCreateGotoOpCode (
1053 mStartOpCodeHandle,
1054 FORM_SET_CD_ORDER_ID,
1055 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
1056 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
1057 EFI_IFR_FLAG_CALLBACK,
1058 FORM_SET_CD_ORDER_ID
1059 );
1060
1061 HiiCreateGotoOpCode (
1062 mStartOpCodeHandle,
1063 FORM_SET_NET_ORDER_ID,
1064 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
1065 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
1066 EFI_IFR_FLAG_CALLBACK,
1067 FORM_SET_NET_ORDER_ID
1068 );
1069
1070 HiiCreateGotoOpCode (
1071 mStartOpCodeHandle,
1072 FORM_SET_BEV_ORDER_ID,
1073 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
1074 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
1075 EFI_IFR_FLAG_CALLBACK,
1076 FORM_SET_BEV_ORDER_ID
1077 );
1078
1079 HiiUpdateForm (
1080 BmmCallbackInfo->BmmHiiHandle,
1081 &gBootMaintFormSetGuid,
1082 FORM_BOOT_SETUP_ID,
1083 mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID
1084 mEndOpCodeHandle // LABEL_END
1085 );
1086 }
1087
1088 //
1089 // Dispatch BMM main formset and File Explorer formset.
1090 //
1091 FormSetDispatcher (BmmCallbackInfo);
1092
1093 //
1094 // Remove our IFR data from HII database
1095 //
1096 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);
1097 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);
1098
1099 CleanUpStringDepository ();
1100
1101 FreeAllMenu ();
1102
1103 Exit:
1104 if (mStartOpCodeHandle != NULL) {
1105 HiiFreeOpCodeHandle (mStartOpCodeHandle);
1106 }
1107
1108 if (mEndOpCodeHandle != NULL) {
1109 HiiFreeOpCodeHandle (mEndOpCodeHandle);
1110 }
1111
1112 if (BmmCallbackInfo->FeDriverHandle != NULL) {
1113 gBS->UninstallMultipleProtocolInterfaces (
1114 BmmCallbackInfo->FeDriverHandle,
1115 &gEfiDevicePathProtocolGuid,
1116 &mFeHiiVendorDevicePath,
1117 &gEfiHiiConfigAccessProtocolGuid,
1118 &BmmCallbackInfo->FeConfigAccess,
1119 NULL
1120 );
1121 }
1122
1123 if (BmmCallbackInfo->BmmDriverHandle != NULL) {
1124 gBS->UninstallMultipleProtocolInterfaces (
1125 BmmCallbackInfo->BmmDriverHandle,
1126 &gEfiDevicePathProtocolGuid,
1127 &mBmmHiiVendorDevicePath,
1128 &gEfiHiiConfigAccessProtocolGuid,
1129 &BmmCallbackInfo->BmmConfigAccess,
1130 NULL
1131 );
1132 }
1133
1134 FreePool (BmmCallbackInfo->LoadContext);
1135 FreePool (BmmCallbackInfo);
1136
1137 return Status;
1138 }
1139
1140 /**
1141 Initialized all Menu Option List.
1142
1143 @param CallbackData The BMM context data.
1144
1145 **/
1146 VOID
1147 InitAllMenu (
1148 IN BMM_CALLBACK_DATA *CallbackData
1149 )
1150 {
1151 InitializeListHead (&BootOptionMenu.Head);
1152 InitializeListHead (&DriverOptionMenu.Head);
1153 BOpt_GetBootOptions (CallbackData);
1154 BOpt_GetDriverOptions (CallbackData);
1155 BOpt_GetLegacyOptions ();
1156 InitializeListHead (&FsOptionMenu.Head);
1157 BOpt_FindDrivers ();
1158 InitializeListHead (&DirectoryMenu.Head);
1159 InitializeListHead (&ConsoleInpMenu.Head);
1160 InitializeListHead (&ConsoleOutMenu.Head);
1161 InitializeListHead (&ConsoleErrMenu.Head);
1162 InitializeListHead (&TerminalMenu.Head);
1163 LocateSerialIo ();
1164 GetAllConsoles ();
1165 }
1166
1167 /**
1168 Free up all Menu Option list.
1169
1170 **/
1171 VOID
1172 FreeAllMenu (
1173 VOID
1174 )
1175 {
1176 BOpt_FreeMenu (&DirectoryMenu);
1177 BOpt_FreeMenu (&FsOptionMenu);
1178 BOpt_FreeMenu (&BootOptionMenu);
1179 BOpt_FreeMenu (&DriverOptionMenu);
1180 BOpt_FreeMenu (&DriverMenu);
1181 BOpt_FreeLegacyOptions ();
1182 FreeAllConsoles ();
1183 }
1184
1185 /**
1186 Initialize all the string depositories.
1187
1188 **/
1189 VOID
1190 InitializeStringDepository (
1191 VOID
1192 )
1193 {
1194 STRING_DEPOSITORY *StringDepository;
1195 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
1196 FileOptionStrDepository = StringDepository++;
1197 ConsoleOptionStrDepository = StringDepository++;
1198 BootOptionStrDepository = StringDepository++;
1199 BootOptionHelpStrDepository = StringDepository++;
1200 DriverOptionStrDepository = StringDepository++;
1201 DriverOptionHelpStrDepository = StringDepository++;
1202 TerminalStrDepository = StringDepository;
1203 }
1204
1205 /**
1206 Fetch a usable string node from the string depository and return the string token.
1207
1208 @param CallbackData The BMM context data.
1209 @param StringDepository The string repository.
1210
1211 @retval EFI_STRING_ID String token.
1212
1213 **/
1214 EFI_STRING_ID
1215 GetStringTokenFromDepository (
1216 IN BMM_CALLBACK_DATA *CallbackData,
1217 IN STRING_DEPOSITORY *StringDepository
1218 )
1219 {
1220 STRING_LIST_NODE *CurrentListNode;
1221 STRING_LIST_NODE *NextListNode;
1222
1223 CurrentListNode = StringDepository->CurrentNode;
1224
1225 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
1226 //
1227 // Fetch one reclaimed node from the list.
1228 //
1229 NextListNode = StringDepository->CurrentNode->Next;
1230 } else {
1231 //
1232 // If there is no usable node in the list, update the list.
1233 //
1234 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
1235 ASSERT (NextListNode != NULL);
1236 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);
1237 ASSERT (NextListNode->StringToken != 0);
1238
1239 StringDepository->TotalNodeNumber++;
1240
1241 if (NULL == CurrentListNode) {
1242 StringDepository->ListHead = NextListNode;
1243 } else {
1244 CurrentListNode->Next = NextListNode;
1245 }
1246 }
1247
1248 StringDepository->CurrentNode = NextListNode;
1249
1250 return StringDepository->CurrentNode->StringToken;
1251 }
1252
1253 /**
1254 Reclaim string depositories by moving the current node pointer to list head..
1255
1256 **/
1257 VOID
1258 ReclaimStringDepository (
1259 VOID
1260 )
1261 {
1262 UINTN DepositoryIndex;
1263 STRING_DEPOSITORY *StringDepository;
1264
1265 StringDepository = FileOptionStrDepository;
1266 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1267 StringDepository->CurrentNode = StringDepository->ListHead;
1268 StringDepository++;
1269 }
1270 }
1271
1272 /**
1273 Release resource for all the string depositories.
1274
1275 **/
1276 VOID
1277 CleanUpStringDepository (
1278 VOID
1279 )
1280 {
1281 UINTN NodeIndex;
1282 UINTN DepositoryIndex;
1283 STRING_LIST_NODE *CurrentListNode;
1284 STRING_LIST_NODE *NextListNode;
1285 STRING_DEPOSITORY *StringDepository;
1286
1287 //
1288 // Release string list nodes.
1289 //
1290 StringDepository = FileOptionStrDepository;
1291 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1292 CurrentListNode = StringDepository->ListHead;
1293 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
1294 NextListNode = CurrentListNode->Next;
1295 FreePool (CurrentListNode);
1296 CurrentListNode = NextListNode;
1297 }
1298
1299 StringDepository++;
1300 }
1301 //
1302 // Release string depository.
1303 //
1304 FreePool (FileOptionStrDepository);
1305 }
1306
1307 /**
1308 Start boot maintenance manager
1309
1310 @retval EFI_SUCCESS If BMM is invoked successfully.
1311 @return Other value if BMM return unsuccessfully.
1312
1313 **/
1314 EFI_STATUS
1315 BdsStartBootMaint (
1316 VOID
1317 )
1318 {
1319 EFI_STATUS Status;
1320 LIST_ENTRY BdsBootOptionList;
1321
1322 InitializeListHead (&BdsBootOptionList);
1323
1324 //
1325 // Connect all prior to entering the platform setup menu.
1326 //
1327 if (!gConnectAllHappened) {
1328 BdsLibConnectAllDriversToAllControllers ();
1329 gConnectAllHappened = TRUE;
1330 }
1331 //
1332 // Have chance to enumerate boot device
1333 //
1334 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
1335
1336 //
1337 // Group the legacy boot options for the same device type
1338 //
1339 GroupMultipleLegacyBootOption4SameType ();
1340
1341 //
1342 // Init the BMM
1343 //
1344 Status = InitializeBM ();
1345
1346 return Status;
1347 }
1348
1349 /**
1350 Dispatch BMM formset and FileExplorer formset.
1351
1352
1353 @param CallbackData The BMM context data.
1354
1355 @retval EFI_SUCCESS If function complete successfully.
1356 @return Other value if the Setup Browser process BMM's pages and
1357 return unsuccessfully.
1358
1359 **/
1360 EFI_STATUS
1361 FormSetDispatcher (
1362 IN BMM_CALLBACK_DATA *CallbackData
1363 )
1364 {
1365 EFI_STATUS Status;
1366 EFI_BROWSER_ACTION_REQUEST ActionRequest;
1367
1368 while (TRUE) {
1369 UpdatePageId (CallbackData, FORM_MAIN_ID);
1370
1371 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1372 Status = gFormBrowser2->SendForm (
1373 gFormBrowser2,
1374 &CallbackData->BmmHiiHandle,
1375 1,
1376 &gBootMaintFormSetGuid,
1377 0,
1378 NULL,
1379 &ActionRequest
1380 );
1381 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1382 EnableResetRequired ();
1383 }
1384
1385 ReclaimStringDepository ();
1386
1387 //
1388 // When this Formset returns, check if we are going to explore files.
1389 //
1390 if (FileExplorerStateInActive != CallbackData->FeCurrentState) {
1391 UpdateFileExplorer (CallbackData, 0);
1392
1393 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1394 Status = gFormBrowser2->SendForm (
1395 gFormBrowser2,
1396 &CallbackData->FeHiiHandle,
1397 1,
1398 &gFileExploreFormSetGuid,
1399 0,
1400 NULL,
1401 &ActionRequest
1402 );
1403 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1404 EnableResetRequired ();
1405 }
1406
1407 CallbackData->FeCurrentState = FileExplorerStateInActive;
1408 CallbackData->FeDisplayContext = FileExplorerDisplayUnknown;
1409 ReclaimStringDepository ();
1410 } else {
1411 break;
1412 }
1413 }
1414
1415 return Status;
1416 }
1417