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