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