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