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