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