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