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