]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
d3215a3c866a5a892127bcb292b3614db27e3e4b
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
1 /** @file
2 The functions for Boot Maintainence Main menu.
3
4 Copyright (c) 2004 - 2011, 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 Index2;
284 UINT16 Index;
285 UINT8 *OldLegacyDev;
286 UINT8 *NewLegacyDev;
287 UINT8 *DisMap;
288 EFI_FORM_ID FormId;
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 //
320 // need to be subtituded.
321 //
322 // Update Select FD/HD/CD/NET/BEV Order Form
323 //
324 if (FORM_SET_FD_ORDER_ID == Private->BmmPreviousPageId ||
325 FORM_SET_HD_ORDER_ID == Private->BmmPreviousPageId ||
326 FORM_SET_CD_ORDER_ID == Private->BmmPreviousPageId ||
327 FORM_SET_NET_ORDER_ID == Private->BmmPreviousPageId ||
328 FORM_SET_BEV_ORDER_ID == Private->BmmPreviousPageId ||
329 ((FORM_BOOT_SETUP_ID == Private->BmmPreviousPageId) &&
330 (QuestionId >= LEGACY_FD_QUESTION_ID) &&
331 (QuestionId < (LEGACY_BEV_QUESTION_ID + 100)) )
332 ) {
333
334 DisMap = Private->BmmOldFakeNVData.DisableMap;
335
336 FormId = Private->BmmPreviousPageId;
337 if (FormId == FORM_BOOT_SETUP_ID) {
338 FormId = Private->BmmCurrentPageId;
339 }
340
341 switch (FormId) {
342 case FORM_SET_FD_ORDER_ID:
343 Number = (UINT16) LegacyFDMenu.MenuNumber;
344 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;
345 NewLegacyDev = CurrentFakeNVMap->LegacyFD;
346 break;
347
348 case FORM_SET_HD_ORDER_ID:
349 Number = (UINT16) LegacyHDMenu.MenuNumber;
350 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;
351 NewLegacyDev = CurrentFakeNVMap->LegacyHD;
352 break;
353
354 case FORM_SET_CD_ORDER_ID:
355 Number = (UINT16) LegacyCDMenu.MenuNumber;
356 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;
357 NewLegacyDev = CurrentFakeNVMap->LegacyCD;
358 break;
359
360 case FORM_SET_NET_ORDER_ID:
361 Number = (UINT16) LegacyNETMenu.MenuNumber;
362 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;
363 NewLegacyDev = CurrentFakeNVMap->LegacyNET;
364 break;
365
366 case FORM_SET_BEV_ORDER_ID:
367 Number = (UINT16) LegacyBEVMenu.MenuNumber;
368 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;
369 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;
370 break;
371
372 default:
373 break;
374 }
375 //
376 // First, find the different position
377 // if there is change, it should be only one
378 //
379 for (Index = 0; Index < Number; Index++) {
380 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
381 OldValue = OldLegacyDev[Index];
382 NewValue = NewLegacyDev[Index];
383 break;
384 }
385 }
386
387 if (Index != Number) {
388 //
389 // there is change, now process
390 //
391 if (0xFF == NewValue) {
392 //
393 // This item will be disable
394 // Just move the items behind this forward to overlap it
395 //
396 Pos = OldValue / 8;
397 Bit = 7 - (OldValue % 8);
398 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
399 for (Index2 = Index; Index2 < Number - 1; Index2++) {
400 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
401 }
402
403 NewLegacyDev[Index2] = 0xFF;
404 } else {
405 for (Index2 = 0; Index2 < Number; Index2++) {
406 if (Index2 == Index) {
407 continue;
408 }
409
410 if (OldLegacyDev[Index2] == NewValue) {
411 //
412 // If NewValue is in OldLegacyDev array
413 // remember its old position
414 //
415 NewValuePos = Index2;
416 break;
417 }
418 }
419
420 if (Index2 != Number) {
421 //
422 // We will change current item to an existing item
423 // (It's hard to describe here, please read code, it's like a cycle-moving)
424 //
425 for (Index2 = NewValuePos; Index2 != Index;) {
426 if (NewValuePos < Index) {
427 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
428 Index2++;
429 } else {
430 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
431 Index2--;
432 }
433 }
434 } else {
435 //
436 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
437 // so we should modify DisMap to reflect the change
438 //
439 Pos = NewValue / 8;
440 Bit = 7 - (NewValue % 8);
441 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));
442 if (0xFF != OldValue) {
443 //
444 // Because NewValue is a item that was disabled before
445 // so after changing the OldValue should be disabled
446 // actually we are doing a swap of enable-disable states of two items
447 //
448 Pos = OldValue / 8;
449 Bit = 7 - (OldValue % 8);
450 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
451 }
452 }
453 }
454 //
455 // To prevent DISABLE appears in the middle of the list
456 // we should perform a re-ordering
457 //
458 Index = 0;
459 while (Index < Number) {
460 if (0xFF != NewLegacyDev[Index]) {
461 Index++;
462 continue;
463 }
464
465 Index2 = Index;
466 Index2++;
467 while (Index2 < Number) {
468 if (0xFF != NewLegacyDev[Index2]) {
469 break;
470 }
471
472 Index2++;
473 }
474
475 if (Index2 < Number) {
476 NewLegacyDev[Index] = NewLegacyDev[Index2];
477 NewLegacyDev[Index2] = 0xFF;
478 }
479
480 Index++;
481 }
482
483 CopyMem (
484 OldLegacyDev,
485 NewLegacyDev,
486 Number
487 );
488 }
489 }
490
491 if (QuestionId < FILE_OPTION_OFFSET) {
492 if (QuestionId < CONFIG_OPTION_OFFSET) {
493 switch (QuestionId) {
494 case KEY_VALUE_BOOT_FROM_FILE:
495 Private->FeCurrentState = FileExplorerStateBootFromFile;
496 break;
497
498 case FORM_BOOT_ADD_ID:
499 Private->FeCurrentState = FileExplorerStateAddBootOption;
500 break;
501
502 case FORM_DRV_ADD_FILE_ID:
503 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;
504 break;
505
506 case FORM_DRV_ADD_HANDLE_ID:
507 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
508 UpdateDrvAddHandlePage (Private);
509 break;
510
511 case FORM_BOOT_DEL_ID:
512 CleanUpPage (FORM_BOOT_DEL_ID, Private);
513 UpdateBootDelPage (Private);
514 break;
515
516 case FORM_BOOT_CHG_ID:
517 case FORM_DRV_CHG_ID:
518 UpdatePageBody (QuestionId, Private);
519 break;
520
521 case FORM_DRV_DEL_ID:
522 CleanUpPage (FORM_DRV_DEL_ID, Private);
523 UpdateDrvDelPage (Private);
524 break;
525
526 case FORM_BOOT_NEXT_ID:
527 CleanUpPage (FORM_BOOT_NEXT_ID, Private);
528 UpdateBootNextPage (Private);
529 break;
530
531 case FORM_TIME_OUT_ID:
532 CleanUpPage (FORM_TIME_OUT_ID, Private);
533 UpdateTimeOutPage (Private);
534 break;
535
536 case FORM_CON_IN_ID:
537 case FORM_CON_OUT_ID:
538 case FORM_CON_ERR_ID:
539 UpdatePageBody (QuestionId, Private);
540 break;
541
542 case FORM_CON_MODE_ID:
543 CleanUpPage (FORM_CON_MODE_ID, Private);
544 UpdateConModePage (Private);
545 break;
546
547 case FORM_CON_COM_ID:
548 CleanUpPage (FORM_CON_COM_ID, Private);
549 UpdateConCOMPage (Private);
550 break;
551
552 case FORM_SET_FD_ORDER_ID:
553 case FORM_SET_HD_ORDER_ID:
554 case FORM_SET_CD_ORDER_ID:
555 case FORM_SET_NET_ORDER_ID:
556 case FORM_SET_BEV_ORDER_ID:
557 CleanUpPage (QuestionId, Private);
558 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);
559 break;
560
561 default:
562 break;
563 }
564 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
565 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
566 Private->CurrentTerminal = Index2;
567
568 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
569 UpdateTerminalPage (Private);
570
571 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
572 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);
573
574 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);
575 ASSERT (NewMenuEntry != NULL);
576 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
577
578 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
579
580 Private->MenuEntry = NewMenuEntry;
581 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
582
583 UpdateDriverAddHandleDescPage (Private);
584 }
585 }
586 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
587 if ((Value == NULL) || (ActionRequest == NULL)) {
588 return EFI_INVALID_PARAMETER;
589 }
590
591 switch (QuestionId) {
592 case KEY_VALUE_SAVE_AND_EXIT:
593 case KEY_VALUE_NO_SAVE_AND_EXIT:
594 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
595 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
596 if (EFI_ERROR (Status)) {
597 return Status;
598 }
599 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
600 DiscardChangeHandler (Private, CurrentFakeNVMap);
601 }
602
603 //
604 // Tell browser not to ask for confirmation of changes,
605 // since we have already applied or discarded.
606 //
607 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
608 break;
609
610 case FORM_RESET:
611 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
612 return EFI_UNSUPPORTED;
613
614 default:
615 break;
616 }
617 }
618
619 //
620 // Pass changed uncommitted data back to Form Browser
621 //
622 HiiSetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);
623 return EFI_SUCCESS;
624 }
625
626 /**
627 Function handling request to apply changes for BMM pages.
628
629 @param Private Pointer to callback data buffer.
630 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM
631 @param FormId ID of the form which has sent the request to apply change.
632
633 @retval EFI_SUCCESS Change successfully applied.
634 @retval Other Error occurs while trying to apply changes.
635
636 **/
637 EFI_STATUS
638 ApplyChangeHandler (
639 IN BMM_CALLBACK_DATA *Private,
640 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,
641 IN EFI_FORM_ID FormId
642 )
643 {
644 BM_CONSOLE_CONTEXT *NewConsoleContext;
645 BM_TERMINAL_CONTEXT *NewTerminalContext;
646 BM_LOAD_CONTEXT *NewLoadContext;
647 BM_MENU_ENTRY *NewMenuEntry;
648 EFI_STATUS Status;
649 UINT16 Index;
650
651 Status = EFI_SUCCESS;
652
653 switch (FormId) {
654 case FORM_SET_FD_ORDER_ID:
655 case FORM_SET_HD_ORDER_ID:
656 case FORM_SET_CD_ORDER_ID:
657 case FORM_SET_NET_ORDER_ID:
658 case FORM_SET_BEV_ORDER_ID:
659 Var_UpdateBBSOption (Private);
660 break;
661
662 case FORM_BOOT_DEL_ID:
663 for (Index = 0;
664 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0]))));
665 Index ++) {
666 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
667 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
668 NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];
669 }
670
671 Var_DelBootOption ();
672 break;
673
674 case FORM_DRV_DEL_ID:
675 for (Index = 0;
676 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0]))));
677 Index++) {
678 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
679 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
680 NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];
681 }
682
683 Var_DelDriverOption ();
684 break;
685
686 case FORM_BOOT_CHG_ID:
687 Status = Var_UpdateBootOrder (Private);
688 break;
689
690 case FORM_DRV_CHG_ID:
691 Status = Var_UpdateDriverOrder (Private);
692 break;
693
694 case FORM_TIME_OUT_ID:
695 PcdSet16 (PcdPlatformBootTimeOut, CurrentFakeNVMap->BootTimeOut);
696
697 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
698 break;
699
700 case FORM_BOOT_NEXT_ID:
701 Status = Var_UpdateBootNext (Private);
702 break;
703
704 case FORM_CON_MODE_ID:
705 Status = Var_UpdateConMode (Private);
706 break;
707
708 case FORM_CON_COM_SETUP_ID:
709 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);
710
711 ASSERT (NewMenuEntry != NULL);
712
713 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
714
715 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;
716 ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));
717 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;
718 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;
719 ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));
720 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;
721 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;
722 ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));
723 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;
724 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;
725 ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0])));
726 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;
727 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;
728 NewTerminalContext->FlowControl = CurrentFakeNVMap->COMFlowControl;
729
730 ChangeTerminalDevicePath (
731 &(NewTerminalContext->DevicePath),
732 FALSE
733 );
734
735 Var_UpdateConsoleInpOption ();
736 Var_UpdateConsoleOutOption ();
737 Var_UpdateErrorOutOption ();
738 break;
739
740 case FORM_CON_IN_ID:
741 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
742 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
743 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
744 ASSERT (Index < MAX_MENU_NUMBER);
745 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
746 }
747
748 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
749 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
750 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
751 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
752 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];
753 }
754
755 Var_UpdateConsoleInpOption ();
756 break;
757
758 case FORM_CON_OUT_ID:
759 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
760 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
761 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
762 ASSERT (Index < MAX_MENU_NUMBER);
763 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
764 }
765
766 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
767 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
768 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
769 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
770 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];
771 }
772
773 Var_UpdateConsoleOutOption ();
774 break;
775
776 case FORM_CON_ERR_ID:
777 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
778 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
779 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
780 ASSERT (Index < MAX_MENU_NUMBER);
781 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
782 }
783
784 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
785 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
786 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
787 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
788 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];
789 }
790
791 Var_UpdateErrorOutOption ();
792 break;
793
794 case FORM_DRV_ADD_HANDLE_DESC_ID:
795 Status = Var_UpdateDriverOption (
796 Private,
797 Private->BmmHiiHandle,
798 CurrentFakeNVMap->DriverAddHandleDesc,
799 CurrentFakeNVMap->DriverAddHandleOptionalData,
800 CurrentFakeNVMap->DriverAddForceReconnect
801 );
802 if (EFI_ERROR (Status)) {
803 goto Error;
804 }
805
806 BOpt_GetDriverOptions (Private);
807 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);
808 break;
809
810 default:
811 break;
812 }
813
814 Error:
815 return Status;
816 }
817
818 /**
819 Discard all changes done to the BMM pages such as Boot Order change,
820 Driver order change.
821
822 @param Private The BMM context data.
823 @param CurrentFakeNVMap The current Fack NV Map.
824
825 **/
826 VOID
827 DiscardChangeHandler (
828 IN BMM_CALLBACK_DATA *Private,
829 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
830 )
831 {
832 UINT16 Index;
833
834 switch (Private->BmmPreviousPageId) {
835 case FORM_BOOT_CHG_ID:
836 case FORM_DRV_CHG_ID:
837 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, sizeof (CurrentFakeNVMap->OptionOrder));
838 break;
839
840 case FORM_BOOT_DEL_ID:
841 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));
842 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
843 CurrentFakeNVMap->OptionDel[Index] = FALSE;
844 }
845 break;
846
847 case FORM_DRV_DEL_ID:
848 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));
849 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
850 CurrentFakeNVMap->OptionDel[Index] = FALSE;
851 }
852 break;
853
854 case FORM_BOOT_NEXT_ID:
855 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
856 break;
857
858 case FORM_TIME_OUT_ID:
859 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
860 break;
861
862 case FORM_DRV_ADD_HANDLE_DESC_ID:
863 case FORM_DRV_ADD_FILE_ID:
864 case FORM_DRV_ADD_HANDLE_ID:
865 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
866 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
867 break;
868
869 default:
870 break;
871 }
872 }
873
874 /**
875 Initialize the Boot Maintenance Utitliy.
876
877
878 @retval EFI_SUCCESS utility ended successfully
879 @retval others contain some errors
880
881 **/
882 EFI_STATUS
883 InitializeBM (
884 VOID
885 )
886 {
887 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
888 BMM_CALLBACK_DATA *BmmCallbackInfo;
889 EFI_STATUS Status;
890 UINT8 *Ptr;
891
892 Status = EFI_SUCCESS;
893
894 //
895 // Create CallbackData structures for Driver Callback
896 //
897 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
898 if (BmmCallbackInfo == NULL) {
899 return EFI_OUT_OF_RESOURCES;
900 }
901
902 //
903 // Create LoadOption in BmmCallbackInfo for Driver Callback
904 //
905 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
906 if (Ptr == NULL) {
907 FreePool (BmmCallbackInfo);
908 return EFI_OUT_OF_RESOURCES;
909 }
910
911 //
912 // Initialize Bmm callback data.
913 //
914 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
915 Ptr += sizeof (BM_LOAD_CONTEXT);
916
917 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
918 Ptr += sizeof (BM_FILE_CONTEXT);
919
920 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
921 Ptr += sizeof (BM_HANDLE_CONTEXT);
922
923 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
924
925 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;
926 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
927 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;
928 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;
929 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
930 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
931 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;
932 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;
933 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;
934 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;
935 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;
936
937 //
938 // Install Device Path Protocol and Config Access protocol to driver handle
939 //
940 Status = gBS->InstallMultipleProtocolInterfaces (
941 &BmmCallbackInfo->BmmDriverHandle,
942 &gEfiDevicePathProtocolGuid,
943 &mBmmHiiVendorDevicePath,
944 &gEfiHiiConfigAccessProtocolGuid,
945 &BmmCallbackInfo->BmmConfigAccess,
946 NULL
947 );
948 if (EFI_ERROR (Status)) {
949 goto Exit;
950 }
951
952 //
953 // Install Device Path Protocol and Config Access protocol to driver handle
954 //
955 Status = gBS->InstallMultipleProtocolInterfaces (
956 &BmmCallbackInfo->FeDriverHandle,
957 &gEfiDevicePathProtocolGuid,
958 &mFeHiiVendorDevicePath,
959 &gEfiHiiConfigAccessProtocolGuid,
960 &BmmCallbackInfo->FeConfigAccess,
961 NULL
962 );
963 if (EFI_ERROR (Status)) {
964 goto Exit;
965 }
966
967 //
968 // Post our Boot Maint VFR binary to the HII database.
969 //
970 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
971 &gBootMaintFormSetGuid,
972 BmmCallbackInfo->BmmDriverHandle,
973 BmBin,
974 BdsDxeStrings,
975 NULL
976 );
977 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);
978
979 //
980 // Post our File Explorer VFR binary to the HII database.
981 //
982 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (
983 &gFileExploreFormSetGuid,
984 BmmCallbackInfo->FeDriverHandle,
985 FEBin,
986 BdsDxeStrings,
987 NULL
988 );
989 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);
990
991 //
992 // Init OpCode Handle and Allocate space for creation of Buffer
993 //
994 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
995 if (mStartOpCodeHandle == NULL) {
996 Status = EFI_OUT_OF_RESOURCES;
997 goto Exit;
998 }
999
1000 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
1001 if (mEndOpCodeHandle == NULL) {
1002 Status = EFI_OUT_OF_RESOURCES;
1003 goto Exit;
1004 }
1005
1006 //
1007 // Create Hii Extend Label OpCode as the start opcode
1008 //
1009 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1010 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1011
1012 //
1013 // Create Hii Extend Label OpCode as the end opcode
1014 //
1015 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1016 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1017 mEndLabel->Number = LABEL_END;
1018
1019 InitializeStringDepository ();
1020
1021 InitAllMenu (BmmCallbackInfo);
1022
1023 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
1024 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
1025 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
1026 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
1027 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
1028 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
1029 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
1030
1031 UpdateBootDelPage (BmmCallbackInfo);
1032 UpdateDrvDelPage (BmmCallbackInfo);
1033
1034 if (TerminalMenu.MenuNumber > 0) {
1035 BmmCallbackInfo->CurrentTerminal = 0;
1036 UpdateTerminalPage (BmmCallbackInfo);
1037 }
1038
1039 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
1040 if (!EFI_ERROR (Status)) {
1041 RefreshUpdateData ();
1042 mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;
1043
1044 //
1045 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
1046 // in BootOption form: legacy FD/HD/CD/NET/BEV
1047 //
1048 HiiCreateGotoOpCode (
1049 mStartOpCodeHandle,
1050 FORM_SET_FD_ORDER_ID,
1051 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
1052 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
1053 EFI_IFR_FLAG_CALLBACK,
1054 FORM_SET_FD_ORDER_ID
1055 );
1056
1057 HiiCreateGotoOpCode (
1058 mStartOpCodeHandle,
1059 FORM_SET_HD_ORDER_ID,
1060 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
1061 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
1062 EFI_IFR_FLAG_CALLBACK,
1063 FORM_SET_HD_ORDER_ID
1064 );
1065
1066 HiiCreateGotoOpCode (
1067 mStartOpCodeHandle,
1068 FORM_SET_CD_ORDER_ID,
1069 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
1070 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
1071 EFI_IFR_FLAG_CALLBACK,
1072 FORM_SET_CD_ORDER_ID
1073 );
1074
1075 HiiCreateGotoOpCode (
1076 mStartOpCodeHandle,
1077 FORM_SET_NET_ORDER_ID,
1078 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
1079 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
1080 EFI_IFR_FLAG_CALLBACK,
1081 FORM_SET_NET_ORDER_ID
1082 );
1083
1084 HiiCreateGotoOpCode (
1085 mStartOpCodeHandle,
1086 FORM_SET_BEV_ORDER_ID,
1087 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
1088 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
1089 EFI_IFR_FLAG_CALLBACK,
1090 FORM_SET_BEV_ORDER_ID
1091 );
1092
1093 HiiUpdateForm (
1094 BmmCallbackInfo->BmmHiiHandle,
1095 &gBootMaintFormSetGuid,
1096 FORM_BOOT_SETUP_ID,
1097 mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID
1098 mEndOpCodeHandle // LABEL_END
1099 );
1100 }
1101
1102 //
1103 // Dispatch BMM main formset and File Explorer formset.
1104 //
1105 FormSetDispatcher (BmmCallbackInfo);
1106
1107 //
1108 // Remove our IFR data from HII database
1109 //
1110 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);
1111 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);
1112
1113 CleanUpStringDepository ();
1114
1115 FreeAllMenu ();
1116
1117 Exit:
1118 if (mStartOpCodeHandle != NULL) {
1119 HiiFreeOpCodeHandle (mStartOpCodeHandle);
1120 }
1121
1122 if (mEndOpCodeHandle != NULL) {
1123 HiiFreeOpCodeHandle (mEndOpCodeHandle);
1124 }
1125
1126 if (BmmCallbackInfo->FeDriverHandle != NULL) {
1127 gBS->UninstallMultipleProtocolInterfaces (
1128 BmmCallbackInfo->FeDriverHandle,
1129 &gEfiDevicePathProtocolGuid,
1130 &mFeHiiVendorDevicePath,
1131 &gEfiHiiConfigAccessProtocolGuid,
1132 &BmmCallbackInfo->FeConfigAccess,
1133 NULL
1134 );
1135 }
1136
1137 if (BmmCallbackInfo->BmmDriverHandle != NULL) {
1138 gBS->UninstallMultipleProtocolInterfaces (
1139 BmmCallbackInfo->BmmDriverHandle,
1140 &gEfiDevicePathProtocolGuid,
1141 &mBmmHiiVendorDevicePath,
1142 &gEfiHiiConfigAccessProtocolGuid,
1143 &BmmCallbackInfo->BmmConfigAccess,
1144 NULL
1145 );
1146 }
1147
1148 FreePool (BmmCallbackInfo->LoadContext);
1149 FreePool (BmmCallbackInfo);
1150
1151 return Status;
1152 }
1153
1154 /**
1155 Initialized all Menu Option List.
1156
1157 @param CallbackData The BMM context data.
1158
1159 **/
1160 VOID
1161 InitAllMenu (
1162 IN BMM_CALLBACK_DATA *CallbackData
1163 )
1164 {
1165 InitializeListHead (&BootOptionMenu.Head);
1166 InitializeListHead (&DriverOptionMenu.Head);
1167 BOpt_GetBootOptions (CallbackData);
1168 BOpt_GetDriverOptions (CallbackData);
1169 BOpt_GetLegacyOptions ();
1170 InitializeListHead (&FsOptionMenu.Head);
1171 BOpt_FindDrivers ();
1172 InitializeListHead (&DirectoryMenu.Head);
1173 InitializeListHead (&ConsoleInpMenu.Head);
1174 InitializeListHead (&ConsoleOutMenu.Head);
1175 InitializeListHead (&ConsoleErrMenu.Head);
1176 InitializeListHead (&TerminalMenu.Head);
1177 LocateSerialIo ();
1178 GetAllConsoles ();
1179 }
1180
1181 /**
1182 Free up all Menu Option list.
1183
1184 **/
1185 VOID
1186 FreeAllMenu (
1187 VOID
1188 )
1189 {
1190 BOpt_FreeMenu (&DirectoryMenu);
1191 BOpt_FreeMenu (&FsOptionMenu);
1192 BOpt_FreeMenu (&BootOptionMenu);
1193 BOpt_FreeMenu (&DriverOptionMenu);
1194 BOpt_FreeMenu (&DriverMenu);
1195 BOpt_FreeLegacyOptions ();
1196 FreeAllConsoles ();
1197 }
1198
1199 /**
1200 Initialize all the string depositories.
1201
1202 **/
1203 VOID
1204 InitializeStringDepository (
1205 VOID
1206 )
1207 {
1208 STRING_DEPOSITORY *StringDepository;
1209 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
1210 FileOptionStrDepository = StringDepository++;
1211 ConsoleOptionStrDepository = StringDepository++;
1212 BootOptionStrDepository = StringDepository++;
1213 BootOptionHelpStrDepository = StringDepository++;
1214 DriverOptionStrDepository = StringDepository++;
1215 DriverOptionHelpStrDepository = StringDepository++;
1216 TerminalStrDepository = StringDepository;
1217 }
1218
1219 /**
1220 Fetch a usable string node from the string depository and return the string token.
1221
1222 @param CallbackData The BMM context data.
1223 @param StringDepository The string repository.
1224
1225 @retval EFI_STRING_ID String token.
1226
1227 **/
1228 EFI_STRING_ID
1229 GetStringTokenFromDepository (
1230 IN BMM_CALLBACK_DATA *CallbackData,
1231 IN STRING_DEPOSITORY *StringDepository
1232 )
1233 {
1234 STRING_LIST_NODE *CurrentListNode;
1235 STRING_LIST_NODE *NextListNode;
1236
1237 CurrentListNode = StringDepository->CurrentNode;
1238
1239 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
1240 //
1241 // Fetch one reclaimed node from the list.
1242 //
1243 NextListNode = StringDepository->CurrentNode->Next;
1244 } else {
1245 //
1246 // If there is no usable node in the list, update the list.
1247 //
1248 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
1249 ASSERT (NextListNode != NULL);
1250 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);
1251 ASSERT (NextListNode->StringToken != 0);
1252
1253 StringDepository->TotalNodeNumber++;
1254
1255 if (NULL == CurrentListNode) {
1256 StringDepository->ListHead = NextListNode;
1257 } else {
1258 CurrentListNode->Next = NextListNode;
1259 }
1260 }
1261
1262 StringDepository->CurrentNode = NextListNode;
1263
1264 return StringDepository->CurrentNode->StringToken;
1265 }
1266
1267 /**
1268 Reclaim string depositories by moving the current node pointer to list head..
1269
1270 **/
1271 VOID
1272 ReclaimStringDepository (
1273 VOID
1274 )
1275 {
1276 UINTN DepositoryIndex;
1277 STRING_DEPOSITORY *StringDepository;
1278
1279 StringDepository = FileOptionStrDepository;
1280 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1281 StringDepository->CurrentNode = StringDepository->ListHead;
1282 StringDepository++;
1283 }
1284 }
1285
1286 /**
1287 Release resource for all the string depositories.
1288
1289 **/
1290 VOID
1291 CleanUpStringDepository (
1292 VOID
1293 )
1294 {
1295 UINTN NodeIndex;
1296 UINTN DepositoryIndex;
1297 STRING_LIST_NODE *CurrentListNode;
1298 STRING_LIST_NODE *NextListNode;
1299 STRING_DEPOSITORY *StringDepository;
1300
1301 //
1302 // Release string list nodes.
1303 //
1304 StringDepository = FileOptionStrDepository;
1305 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1306 CurrentListNode = StringDepository->ListHead;
1307 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
1308 NextListNode = CurrentListNode->Next;
1309 FreePool (CurrentListNode);
1310 CurrentListNode = NextListNode;
1311 }
1312
1313 StringDepository++;
1314 }
1315 //
1316 // Release string depository.
1317 //
1318 FreePool (FileOptionStrDepository);
1319 }
1320
1321 /**
1322 Start boot maintenance manager
1323
1324 @retval EFI_SUCCESS If BMM is invoked successfully.
1325 @return Other value if BMM return unsuccessfully.
1326
1327 **/
1328 EFI_STATUS
1329 BdsStartBootMaint (
1330 VOID
1331 )
1332 {
1333 EFI_STATUS Status;
1334 LIST_ENTRY BdsBootOptionList;
1335
1336 InitializeListHead (&BdsBootOptionList);
1337
1338 //
1339 // Connect all prior to entering the platform setup menu.
1340 //
1341 if (!gConnectAllHappened) {
1342 BdsLibConnectAllDriversToAllControllers ();
1343 gConnectAllHappened = TRUE;
1344 }
1345 //
1346 // Have chance to enumerate boot device
1347 //
1348 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
1349
1350 //
1351 // Init the BMM
1352 //
1353 Status = InitializeBM ();
1354
1355 return Status;
1356 }
1357
1358 /**
1359 Dispatch BMM formset and FileExplorer formset.
1360
1361
1362 @param CallbackData The BMM context data.
1363
1364 @retval EFI_SUCCESS If function complete successfully.
1365 @return Other value if the Setup Browser process BMM's pages and
1366 return unsuccessfully.
1367
1368 **/
1369 EFI_STATUS
1370 FormSetDispatcher (
1371 IN BMM_CALLBACK_DATA *CallbackData
1372 )
1373 {
1374 EFI_STATUS Status;
1375 EFI_BROWSER_ACTION_REQUEST ActionRequest;
1376
1377 while (TRUE) {
1378 UpdatePageId (CallbackData, FORM_MAIN_ID);
1379
1380 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1381 Status = gFormBrowser2->SendForm (
1382 gFormBrowser2,
1383 &CallbackData->BmmHiiHandle,
1384 1,
1385 &gBootMaintFormSetGuid,
1386 0,
1387 NULL,
1388 &ActionRequest
1389 );
1390 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1391 EnableResetRequired ();
1392 }
1393
1394 ReclaimStringDepository ();
1395
1396 //
1397 // When this Formset returns, check if we are going to explore files.
1398 //
1399 if (FileExplorerStateInActive != CallbackData->FeCurrentState) {
1400 UpdateFileExplorer (CallbackData, 0);
1401
1402 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1403 Status = gFormBrowser2->SendForm (
1404 gFormBrowser2,
1405 &CallbackData->FeHiiHandle,
1406 1,
1407 &gFileExploreFormSetGuid,
1408 0,
1409 NULL,
1410 &ActionRequest
1411 );
1412 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1413 EnableResetRequired ();
1414 }
1415
1416 CallbackData->FeCurrentState = FileExplorerStateInActive;
1417 CallbackData->FeDisplayContext = FileExplorerDisplayUnknown;
1418 ReclaimStringDepository ();
1419 } else {
1420 break;
1421 }
1422 }
1423
1424 return Status;
1425 }
1426
1427
1428 /**
1429 Deletete the Boot Option from EFI Variable. The Boot Order Arrray
1430 is also updated.
1431
1432 @param OptionNumber The number of Boot option want to be deleted.
1433 @param BootOrder The Boot Order array.
1434 @param BootOrderSize The size of the Boot Order Array.
1435
1436 @retval EFI_SUCCESS The Boot Option Variable was found and removed
1437 @retval EFI_UNSUPPORTED The Boot Option Variable store was inaccessible
1438 @retval EFI_NOT_FOUND The Boot Option Variable was not found
1439 **/
1440 EFI_STATUS
1441 EFIAPI
1442 BdsDeleteBootOption (
1443 IN UINTN OptionNumber,
1444 IN OUT UINT16 *BootOrder,
1445 IN OUT UINTN *BootOrderSize
1446 )
1447 {
1448 UINT16 BootOption[100];
1449 UINTN Index;
1450 EFI_STATUS Status;
1451 UINTN Index2Del;
1452
1453 Status = EFI_SUCCESS;
1454 Index2Del = 0;
1455
1456 UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);
1457 Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);
1458
1459 //
1460 // adjust boot order array
1461 //
1462 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
1463 if (BootOrder[Index] == OptionNumber) {
1464 Index2Del = Index;
1465 break;
1466 }
1467 }
1468
1469 if (Index != *BootOrderSize / sizeof (UINT16)) {
1470 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {
1471 if (Index >= Index2Del) {
1472 BootOrder[Index] = BootOrder[Index + 1];
1473 }
1474 }
1475
1476 *BootOrderSize -= sizeof (UINT16);
1477 }
1478
1479 return Status;
1480
1481 }
1482
1483