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