]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
1, Change name of PcdPlatformBootTimeoutDefault to PcdPlatformBootTimeout, now this...
[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 PcdSet16 (PcdPlatformBootTimeOut, CurrentFakeNVMap->BootTimeOut);
614
615 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
616 break;
617
618 case FORM_BOOT_NEXT_ID:
619 Status = Var_UpdateBootNext (Private);
620 break;
621
622 case FORM_CON_MODE_ID:
623 Status = Var_UpdateConMode (Private);
624 break;
625
626 case FORM_CON_COM_SETUP_ID:
627 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);
628
629 ASSERT (NewMenuEntry != NULL);
630
631 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
632
633 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;
634 ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));
635 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;
636 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;
637 ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));
638 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;
639 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;
640 ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));
641 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;
642 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;
643 ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0])));
644 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;
645 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;
646
647 ChangeTerminalDevicePath (
648 NewTerminalContext->DevicePath,
649 FALSE
650 );
651
652 Var_UpdateConsoleInpOption ();
653 Var_UpdateConsoleOutOption ();
654 Var_UpdateErrorOutOption ();
655 break;
656
657 case FORM_CON_IN_ID:
658 ASSERT ((ConsoleInpMenu.MenuNumber + TerminalMenu.MenuNumber) <= (sizeof (CurrentFakeNVMap->ConsoleCheck) / sizeof (UINT8)));
659 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
660 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
661 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
662 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
663 }
664
665 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
666 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
667 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
668 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];
669 }
670
671 Var_UpdateConsoleInpOption ();
672 break;
673
674 case FORM_CON_OUT_ID:
675 ASSERT ((ConsoleOutMenu.MenuNumber + TerminalMenu.MenuNumber) <= (sizeof (CurrentFakeNVMap->ConsoleCheck) / sizeof (UINT8)));
676 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
677 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
678 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
679 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
680 }
681
682 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
683 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
684 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
685 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];
686 }
687
688 Var_UpdateConsoleOutOption ();
689 break;
690
691 case FORM_CON_ERR_ID:
692 ASSERT ((ConsoleErrMenu.MenuNumber + TerminalMenu.MenuNumber) <= (sizeof (CurrentFakeNVMap->ConsoleCheck) / sizeof (UINT8)));
693 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
694 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
695 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
696 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
697 }
698
699 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
700 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
701 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
702 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];
703 }
704
705 Var_UpdateErrorOutOption ();
706 break;
707
708 case FORM_DRV_ADD_HANDLE_DESC_ID:
709 Status = Var_UpdateDriverOption (
710 Private,
711 Private->BmmHiiHandle,
712 CurrentFakeNVMap->DriverAddHandleDesc,
713 CurrentFakeNVMap->DriverAddHandleOptionalData,
714 CurrentFakeNVMap->DriverAddForceReconnect
715 );
716 if (EFI_ERROR (Status)) {
717 goto Error;
718 }
719
720 BOpt_GetDriverOptions (Private);
721 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);
722 break;
723
724 default:
725 break;
726 }
727
728 Error:
729 return Status;
730 }
731
732 /**
733 Discard all changes done to the BMM pages such as Boot Order change,
734 Driver order change.
735
736 @param Private The BMM context data.
737 @param CurrentFakeNVMap The current Fack NV Map.
738
739 **/
740 VOID
741 DiscardChangeHandler (
742 IN BMM_CALLBACK_DATA *Private,
743 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
744 )
745 {
746 UINT16 Index;
747
748 switch (Private->BmmPreviousPageId) {
749 case FORM_BOOT_CHG_ID:
750 case FORM_DRV_CHG_ID:
751 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);
752 break;
753
754 case FORM_BOOT_DEL_ID:
755 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));
756 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
757 CurrentFakeNVMap->BootOptionDel[Index] = 0x00;
758 }
759 break;
760
761 case FORM_DRV_DEL_ID:
762 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));
763 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
764 CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;
765 }
766 break;
767
768 case FORM_BOOT_NEXT_ID:
769 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
770 break;
771
772 case FORM_TIME_OUT_ID:
773 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
774 break;
775
776 case FORM_DRV_ADD_HANDLE_DESC_ID:
777 case FORM_DRV_ADD_FILE_ID:
778 case FORM_DRV_ADD_HANDLE_ID:
779 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
780 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
781 break;
782
783 default:
784 break;
785 }
786 }
787
788 /**
789 Initialize the Boot Maintenance Utitliy.
790
791
792 @retval EFI_SUCCESS utility ended successfully
793 @retval others contain some errors
794
795 **/
796 EFI_STATUS
797 InitializeBM (
798 VOID
799 )
800 {
801 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
802 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
803 BMM_CALLBACK_DATA *BmmCallbackInfo;
804 EFI_STATUS Status;
805 UINT8 *Ptr;
806
807 Status = EFI_SUCCESS;
808
809 //
810 // Create CallbackData structures for Driver Callback
811 //
812 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
813 if (BmmCallbackInfo == NULL) {
814 return EFI_OUT_OF_RESOURCES;
815 }
816
817 //
818 // Create LoadOption in BmmCallbackInfo for Driver Callback
819 //
820 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
821 if (Ptr == NULL) {
822 FreePool (BmmCallbackInfo);
823 return EFI_OUT_OF_RESOURCES;
824 }
825
826 //
827 // Initialize Bmm callback data.
828 //
829 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
830 Ptr += sizeof (BM_LOAD_CONTEXT);
831
832 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
833 Ptr += sizeof (BM_FILE_CONTEXT);
834
835 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
836 Ptr += sizeof (BM_HANDLE_CONTEXT);
837
838 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
839
840 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;
841 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
842 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;
843 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;
844 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
845 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
846 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;
847 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;
848 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;
849 BmmCallbackInfo->FeCurrentState = INACTIVE_STATE;
850 BmmCallbackInfo->FeDisplayContext = UNKNOWN_CONTEXT;
851
852 //
853 // Create driver handle used by HII database
854 //
855 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->BmmDriverHandle);
856 if (EFI_ERROR (Status)) {
857 return Status;
858 }
859
860 //
861 // Install Config Access protocol to driver handle
862 //
863 Status = gBS->InstallProtocolInterface (
864 &BmmCallbackInfo->BmmDriverHandle,
865 &gEfiHiiConfigAccessProtocolGuid,
866 EFI_NATIVE_INTERFACE,
867 &BmmCallbackInfo->BmmConfigAccess
868 );
869 if (EFI_ERROR (Status)) {
870 return Status;
871 }
872
873 //
874 // Create driver handle used by HII database
875 //
876 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->FeDriverHandle);
877 if (EFI_ERROR (Status)) {
878 return Status;
879 }
880
881 //
882 // Install Config Access protocol to driver handle
883 //
884 Status = gBS->InstallProtocolInterface (
885 &BmmCallbackInfo->FeDriverHandle,
886 &gEfiHiiConfigAccessProtocolGuid,
887 EFI_NATIVE_INTERFACE,
888 &BmmCallbackInfo->FeConfigAccess
889 );
890 if (EFI_ERROR (Status)) {
891 return Status;
892 }
893
894 //
895 // Post our Boot Maint VFR binnary to the HII database.
896 //
897 PackageList = HiiLibPreparePackageList (2, &mBootMaintGuid, BmBin, BdsDxeStrings);
898 ASSERT (PackageList != NULL);
899
900 Status = gHiiDatabase->NewPackageList (
901 gHiiDatabase,
902 PackageList,
903 BmmCallbackInfo->BmmDriverHandle,
904 &BmmCallbackInfo->BmmHiiHandle
905 );
906 FreePool (PackageList);
907
908 //
909 // Post our File Explorer VFR binary to the HII database.
910 //
911 PackageList = HiiLibPreparePackageList (2, &mFileExplorerGuid, FEBin, BdsDxeStrings);
912 ASSERT (PackageList != NULL);
913
914 Status = gHiiDatabase->NewPackageList (
915 gHiiDatabase,
916 PackageList,
917 BmmCallbackInfo->FeDriverHandle,
918 &BmmCallbackInfo->FeHiiHandle
919 );
920 FreePool (PackageList);
921
922 //
923 // Allocate space for creation of Buffer
924 //
925 gUpdateData.BufferSize = UPDATE_DATA_SIZE;
926 gUpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);
927 if (gUpdateData.Data == NULL) {
928 FreePool (BmmCallbackInfo->LoadContext);
929 FreePool (BmmCallbackInfo);
930 return EFI_OUT_OF_RESOURCES;
931 }
932
933 InitializeStringDepository ();
934
935 InitAllMenu (BmmCallbackInfo);
936
937 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
938 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
939 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
940 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
941 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
942 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
943 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
944
945 UpdateBootDelPage (BmmCallbackInfo);
946 UpdateDrvDelPage (BmmCallbackInfo);
947
948 if (TerminalMenu.MenuNumber > 0) {
949 BmmCallbackInfo->CurrentTerminal = 0;
950 UpdateTerminalPage (BmmCallbackInfo);
951 }
952
953 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
954 if (!EFI_ERROR (Status)) {
955 RefreshUpdateData ();
956
957 //
958 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
959 // in BootOption form: legacy FD/HD/CD/NET/BEV
960 //
961 CreateGotoOpCode (
962 FORM_SET_FD_ORDER_ID,
963 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
964 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
965 EFI_IFR_FLAG_CALLBACK,
966 FORM_SET_FD_ORDER_ID,
967 &gUpdateData
968 );
969
970 CreateGotoOpCode (
971 FORM_SET_HD_ORDER_ID,
972 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
973 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
974 EFI_IFR_FLAG_CALLBACK,
975 FORM_SET_HD_ORDER_ID,
976 &gUpdateData
977 );
978
979 CreateGotoOpCode (
980 FORM_SET_CD_ORDER_ID,
981 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
982 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
983 EFI_IFR_FLAG_CALLBACK,
984 FORM_SET_CD_ORDER_ID,
985 &gUpdateData
986 );
987
988 CreateGotoOpCode (
989 FORM_SET_NET_ORDER_ID,
990 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
991 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
992 EFI_IFR_FLAG_CALLBACK,
993 FORM_SET_NET_ORDER_ID,
994 &gUpdateData
995 );
996
997 CreateGotoOpCode (
998 FORM_SET_BEV_ORDER_ID,
999 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
1000 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
1001 EFI_IFR_FLAG_CALLBACK,
1002 FORM_SET_BEV_ORDER_ID,
1003 &gUpdateData
1004 );
1005
1006 IfrLibUpdateForm (
1007 BmmCallbackInfo->BmmHiiHandle,
1008 &mBootMaintGuid,
1009 FORM_MAIN_ID,
1010 FORM_BOOT_LEGACY_DEVICE_ID,
1011 FALSE,
1012 &gUpdateData
1013 );
1014 }
1015
1016 //
1017 // Dispatch BMM main formset and File Explorer formset.
1018 //
1019 FormSetDispatcher (BmmCallbackInfo);
1020
1021 //
1022 // Remove our IFR data from HII database
1023 //
1024 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle);
1025 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle);
1026
1027 CleanUpStringDepository ();
1028
1029 FreeAllMenu ();
1030
1031 FreePool (BmmCallbackInfo->LoadContext);
1032 FreePool (BmmCallbackInfo);
1033 FreePool (gUpdateData.Data);
1034 gUpdateData.Data = NULL;
1035
1036 return Status;
1037 }
1038
1039 /**
1040 Initialized all Menu Option List.
1041
1042 @param CallbackData The BMM context data.
1043
1044 **/
1045 VOID
1046 InitAllMenu (
1047 IN BMM_CALLBACK_DATA *CallbackData
1048 )
1049 {
1050 InitializeListHead (&BootOptionMenu.Head);
1051 InitializeListHead (&DriverOptionMenu.Head);
1052 BOpt_GetBootOptions (CallbackData);
1053 BOpt_GetDriverOptions (CallbackData);
1054 BOpt_GetLegacyOptions ();
1055 InitializeListHead (&FsOptionMenu.Head);
1056 BOpt_FindDrivers ();
1057 InitializeListHead (&DirectoryMenu.Head);
1058 InitializeListHead (&ConsoleInpMenu.Head);
1059 InitializeListHead (&ConsoleOutMenu.Head);
1060 InitializeListHead (&ConsoleErrMenu.Head);
1061 InitializeListHead (&TerminalMenu.Head);
1062 LocateSerialIo ();
1063 GetAllConsoles ();
1064 }
1065
1066 /**
1067 Free up all Menu Option list.
1068
1069 **/
1070 VOID
1071 FreeAllMenu (
1072 VOID
1073 )
1074 {
1075 BOpt_FreeMenu (&DirectoryMenu);
1076 BOpt_FreeMenu (&FsOptionMenu);
1077 BOpt_FreeMenu (&BootOptionMenu);
1078 BOpt_FreeMenu (&DriverOptionMenu);
1079 BOpt_FreeMenu (&DriverMenu);
1080 BOpt_FreeLegacyOptions ();
1081 FreeAllConsoles ();
1082 }
1083
1084 /**
1085 Intialize all the string depositories.
1086
1087 **/
1088 VOID
1089 InitializeStringDepository (
1090 VOID
1091 )
1092 {
1093 STRING_DEPOSITORY *StringDepository;
1094 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
1095 FileOptionStrDepository = StringDepository++;
1096 ConsoleOptionStrDepository = StringDepository++;
1097 BootOptionStrDepository = StringDepository++;
1098 BootOptionHelpStrDepository = StringDepository++;
1099 DriverOptionStrDepository = StringDepository++;
1100 DriverOptionHelpStrDepository = StringDepository++;
1101 TerminalStrDepository = StringDepository;
1102 }
1103
1104 /**
1105 Fetch a usable string node from the string depository and return the string token.
1106
1107 @param CallbackData The BMM context data.
1108 @param StringDepository The string repository.
1109
1110 @retval EFI_STRING_ID String token.
1111
1112 **/
1113 EFI_STRING_ID
1114 GetStringTokenFromDepository (
1115 IN BMM_CALLBACK_DATA *CallbackData,
1116 IN STRING_DEPOSITORY *StringDepository
1117 )
1118 {
1119 STRING_LIST_NODE *CurrentListNode;
1120 STRING_LIST_NODE *NextListNode;
1121
1122 CurrentListNode = StringDepository->CurrentNode;
1123
1124 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
1125 //
1126 // Fetch one reclaimed node from the list.
1127 //
1128 NextListNode = StringDepository->CurrentNode->Next;
1129 } else {
1130 //
1131 // If there is no usable node in the list, update the list.
1132 //
1133 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
1134 ASSERT (NextListNode != NULL);
1135 HiiLibNewString (CallbackData->BmmHiiHandle, &(NextListNode->StringToken), L" ");
1136 ASSERT (NextListNode->StringToken != 0);
1137
1138 StringDepository->TotalNodeNumber++;
1139
1140 if (NULL == CurrentListNode) {
1141 StringDepository->ListHead = NextListNode;
1142 } else {
1143 CurrentListNode->Next = NextListNode;
1144 }
1145 }
1146
1147 StringDepository->CurrentNode = NextListNode;
1148
1149 return StringDepository->CurrentNode->StringToken;
1150 }
1151
1152 /**
1153 Reclaim string depositories by moving the current node pointer to list head..
1154
1155 **/
1156 VOID
1157 ReclaimStringDepository (
1158 VOID
1159 )
1160 {
1161 UINTN DepositoryIndex;
1162 STRING_DEPOSITORY *StringDepository;
1163
1164 StringDepository = FileOptionStrDepository;
1165 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1166 StringDepository->CurrentNode = StringDepository->ListHead;
1167 StringDepository++;
1168 }
1169 }
1170
1171 /**
1172 Release resource for all the string depositories.
1173
1174 **/
1175 VOID
1176 CleanUpStringDepository (
1177 VOID
1178 )
1179 {
1180 UINTN NodeIndex;
1181 UINTN DepositoryIndex;
1182 STRING_LIST_NODE *CurrentListNode;
1183 STRING_LIST_NODE *NextListNode;
1184 STRING_DEPOSITORY *StringDepository;
1185
1186 //
1187 // Release string list nodes.
1188 //
1189 StringDepository = FileOptionStrDepository;
1190 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1191 CurrentListNode = StringDepository->ListHead;
1192 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
1193 NextListNode = CurrentListNode->Next;
1194 FreePool (CurrentListNode);
1195 CurrentListNode = NextListNode;
1196 }
1197
1198 StringDepository++;
1199 }
1200 //
1201 // Release string depository.
1202 //
1203 FreePool (FileOptionStrDepository);
1204 }
1205
1206 /**
1207 Start boot maintenance manager
1208
1209 @retval EFI_SUCCESS If BMM is invoked successfully.
1210 @return Other value if BMM return unsuccessfully.
1211
1212 **/
1213 EFI_STATUS
1214 BdsStartBootMaint (
1215 VOID
1216 )
1217 {
1218 EFI_STATUS Status;
1219 LIST_ENTRY BdsBootOptionList;
1220
1221 InitializeListHead (&BdsBootOptionList);
1222
1223 //
1224 // Connect all prior to entering the platform setup menu.
1225 //
1226 if (!gConnectAllHappened) {
1227 BdsLibConnectAllDriversToAllControllers ();
1228 gConnectAllHappened = TRUE;
1229 }
1230 //
1231 // Have chance to enumerate boot device
1232 //
1233 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
1234
1235 //
1236 // Init the BMM
1237 //
1238 Status = InitializeBM ();
1239
1240 return Status;
1241 }
1242
1243 /**
1244 Dispatch BMM formset and FileExplorer formset.
1245
1246
1247 @param CallbackData The BMM context data.
1248
1249 @retval EFI_SUCCESS If function complete successfully.
1250 @return Other value if the Setup Browser process BMM's pages and
1251 return unsuccessfully.
1252
1253 **/
1254 EFI_STATUS
1255 FormSetDispatcher (
1256 IN BMM_CALLBACK_DATA *CallbackData
1257 )
1258 {
1259 EFI_STATUS Status;
1260 EFI_BROWSER_ACTION_REQUEST ActionRequest;
1261
1262 while (TRUE) {
1263 UpdatePageId (CallbackData, FORM_MAIN_ID);
1264
1265 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1266 Status = gFormBrowser2->SendForm (
1267 gFormBrowser2,
1268 &CallbackData->BmmHiiHandle,
1269 1,
1270 NULL,
1271 0,
1272 NULL,
1273 &ActionRequest
1274 );
1275 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1276 EnableResetRequired ();
1277 }
1278
1279 ReclaimStringDepository ();
1280
1281 //
1282 // When this Formset returns, check if we are going to explore files.
1283 //
1284 if (INACTIVE_STATE != CallbackData->FeCurrentState) {
1285 UpdateFileExplorer (CallbackData, 0);
1286
1287 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1288 Status = gFormBrowser2->SendForm (
1289 gFormBrowser2,
1290 &CallbackData->FeHiiHandle,
1291 1,
1292 NULL,
1293 0,
1294 NULL,
1295 &ActionRequest
1296 );
1297 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1298 EnableResetRequired ();
1299 }
1300
1301 CallbackData->FeCurrentState = INACTIVE_STATE;
1302 CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;
1303 ReclaimStringDepository ();
1304 } else {
1305 break;
1306 }
1307 }
1308
1309 return Status;
1310 }
1311
1312
1313 /**
1314 Deletete the Boot Option from EFI Variable. The Boot Order Arrray
1315 is also updated.
1316
1317 @param OptionNumber The number of Boot option want to be deleted.
1318 @param BootOrder The Boot Order array.
1319 @param BootOrderSize The size of the Boot Order Array.
1320
1321 @return Other value if the Boot Option specified by OptionNumber is not deleteed succesfully.
1322 @retval EFI_SUCCESS If function return successfully.
1323
1324 **/
1325 EFI_STATUS
1326 BdsDeleteBootOption (
1327 IN UINTN OptionNumber,
1328 IN OUT UINT16 *BootOrder,
1329 IN OUT UINTN *BootOrderSize
1330 )
1331 {
1332 UINT16 BootOption[100];
1333 UINTN Index;
1334 EFI_STATUS Status;
1335 UINTN Index2Del;
1336
1337 Status = EFI_SUCCESS;
1338 Index2Del = 0;
1339
1340 UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);
1341 Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);
1342
1343 //
1344 // adjust boot order array
1345 //
1346 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
1347 if (BootOrder[Index] == OptionNumber) {
1348 Index2Del = Index;
1349 break;
1350 }
1351 }
1352
1353 if (Index != *BootOrderSize / sizeof (UINT16)) {
1354 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {
1355 if (Index >= Index2Del) {
1356 BootOrder[Index] = BootOrder[Index + 1];
1357 }
1358 }
1359
1360 *BootOrderSize -= sizeof (UINT16);
1361 }
1362
1363 return Status;
1364
1365 }
1366
1367