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