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