2 The functions for Boot Maintainence Main menu.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 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
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.
15 #include "BootMaint.h"
18 #include "FrontPage.h"
20 EFI_DEVICE_PATH_PROTOCOL EndDevicePath
[] = {
23 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
25 END_DEVICE_PATH_LENGTH
,
31 HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath
= {
37 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
38 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
41 BOOT_MAINT_FORMSET_GUID
45 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
47 (UINT8
) (END_DEVICE_PATH_LENGTH
),
48 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
53 HII_VENDOR_DEVICE_PATH mFeHiiVendorDevicePath
= {
59 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
60 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
63 FILE_EXPLORE_FORMSET_GUID
67 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
69 (UINT8
) (END_DEVICE_PATH_LENGTH
),
70 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
75 CHAR16 mBootMaintStorageName
[] = L
"BmmData";
76 CHAR16 mFileExplorerStorageName
[] = L
"FeData";
77 BMM_CALLBACK_DATA
*mBmmCallbackInfo
= NULL
;
82 @param CallbackData The BMM context data.
87 IN BMM_CALLBACK_DATA
*CallbackData
91 Free up all Menu Option list.
100 Initialize all of BMM configuration data in BmmFakeNvData and BmmOldFakeNVData member
101 in BMM context data and create all of dynamic OP code for BMM.
103 @param CallbackData The BMM context data.
107 InitializeBmmConfig (
108 IN BMM_CALLBACK_DATA
*CallbackData
111 BM_MENU_ENTRY
*NewMenuEntry
;
112 BM_LOAD_CONTEXT
*NewLoadContext
;
115 ASSERT (CallbackData
!= NULL
);
118 // Initialize data which located in BMM main page
120 CallbackData
->BmmFakeNvData
.BootNext
= (UINT16
) (BootOptionMenu
.MenuNumber
);
121 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
122 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
123 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
125 if (NewLoadContext
->IsBootNext
) {
126 CallbackData
->BmmFakeNvData
.BootNext
= Index
;
131 CallbackData
->BmmFakeNvData
.BootTimeOut
= PcdGet16 (PcdPlatformBootTimeOut
);
134 // Initialize data which located in Boot Options Menu
136 GetBootOrder (CallbackData
);
137 GetLegacyDeviceOrder (CallbackData
);
140 // Initialize data which located in Driver Options Menu
142 GetDriverOrder (CallbackData
);
145 // Initialize data which located in Console Options Menu
147 GetConsoleOutMode (CallbackData
);
148 GetConsoleInCheck (CallbackData
);
149 GetConsoleOutCheck (CallbackData
);
150 GetConsoleErrCheck (CallbackData
);
151 GetTerminalAttribute (CallbackData
);
154 // Backup Initialize BMM configuartion data to BmmOldFakeNVData
156 CopyMem (&CallbackData
->BmmOldFakeNVData
, &CallbackData
->BmmFakeNvData
, sizeof (BMM_FAKE_NV_DATA
));
160 Create string tokens for a menu from its help strings and display strings
162 @param CallbackData The BMM context data.
163 @param HiiHandle Hii Handle of the package to be updated.
164 @param MenuOption The Menu whose string tokens need to be created
166 @retval EFI_SUCCESS String tokens created successfully
167 @retval others contain some errors
170 CreateMenuStringToken (
171 IN BMM_CALLBACK_DATA
*CallbackData
,
172 IN EFI_HII_HANDLE HiiHandle
,
173 IN BM_MENU_OPTION
*MenuOption
176 BM_MENU_ENTRY
*NewMenuEntry
;
179 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
180 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
182 NewMenuEntry
->DisplayStringToken
= HiiSetString (
185 NewMenuEntry
->DisplayString
,
189 if (NULL
== NewMenuEntry
->HelpString
) {
190 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
192 NewMenuEntry
->HelpStringToken
= HiiSetString (
195 NewMenuEntry
->HelpString
,
205 This function allows a caller to extract the current configuration for one
206 or more named elements from the target driver.
209 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
210 @param Request A null-terminated Unicode string in <ConfigRequest> format.
211 @param Progress On return, points to a character in the Request string.
212 Points to the string's null terminator if request was successful.
213 Points to the most recent '&' before the first failing name/value
214 pair (or the beginning of the string if the failure is in the
215 first name/value pair) if the request was not successful.
216 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
217 has all values filled in for the names in the Request string.
218 String to be allocated by the called function.
220 @retval EFI_SUCCESS The Results is filled with the requested values.
221 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
222 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
223 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
228 BootMaintExtractConfig (
229 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
230 IN CONST EFI_STRING Request
,
231 OUT EFI_STRING
*Progress
,
232 OUT EFI_STRING
*Results
237 BMM_CALLBACK_DATA
*Private
;
238 EFI_STRING ConfigRequestHdr
;
239 EFI_STRING ConfigRequest
;
240 BOOLEAN AllocatedRequest
;
243 if (Progress
== NULL
|| Results
== NULL
) {
244 return EFI_INVALID_PARAMETER
;
248 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gBootMaintFormSetGuid
, mBootMaintStorageName
)) {
249 return EFI_NOT_FOUND
;
252 ConfigRequestHdr
= NULL
;
253 ConfigRequest
= NULL
;
254 AllocatedRequest
= FALSE
;
257 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
259 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
261 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
262 ConfigRequest
= Request
;
263 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
265 // Request has no request element, construct full request string.
266 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
267 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
269 ConfigRequestHdr
= HiiConstructConfigHdr (&gBootMaintFormSetGuid
, mBootMaintStorageName
, Private
->BmmDriverHandle
);
270 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
271 ConfigRequest
= AllocateZeroPool (Size
);
272 ASSERT (ConfigRequest
!= NULL
);
273 AllocatedRequest
= TRUE
;
274 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
275 FreePool (ConfigRequestHdr
);
278 Status
= gHiiConfigRouting
->BlockToConfig (
281 (UINT8
*) &Private
->BmmFakeNvData
,
287 // Free the allocated config request string.
289 if (AllocatedRequest
) {
290 FreePool (ConfigRequest
);
291 ConfigRequest
= NULL
;
294 // Set Progress string to the original request string.
296 if (Request
== NULL
) {
298 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
299 *Progress
= Request
+ StrLen (Request
);
306 This function applies changes in a driver's configuration.
307 Input is a Configuration, which has the routing data for this
308 driver followed by name / value configuration pairs. The driver
309 must apply those pairs to its configurable storage. If the
310 driver's configuration is stored in a linear block of data
311 and the driver's name / value pairs are in <BlockConfig>
312 format, it may use the ConfigToBlock helper function (above) to
313 simplify the job. Currently not implemented.
315 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
316 @param[in] Configuration A null-terminated Unicode string in
317 <ConfigString> format.
318 @param[out] Progress A pointer to a string filled in with the
319 offset of the most recent '&' before the
320 first failing name / value pair (or the
321 beginn ing of the string if the failure
322 is in the first name / value pair) or
323 the terminating NULL if all was
326 @retval EFI_SUCCESS The results have been distributed or are
327 awaiting distribution.
328 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
329 parts of the results that must be
330 stored awaiting possible future
332 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
333 Results parameter would result
334 in this type of error.
335 @retval EFI_NOT_FOUND Target for the specified routing data
340 BootMaintRouteConfig (
341 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
342 IN CONST EFI_STRING Configuration
,
343 OUT EFI_STRING
*Progress
348 EFI_HII_CONFIG_ROUTING_PROTOCOL
*ConfigRouting
;
349 BMM_FAKE_NV_DATA
*NewBmmData
;
350 BMM_FAKE_NV_DATA
*OldBmmData
;
351 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
352 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
353 BM_MENU_ENTRY
*NewMenuEntry
;
354 BM_LOAD_CONTEXT
*NewLoadContext
;
356 BOOLEAN TerminalAttChange
;
357 BMM_CALLBACK_DATA
*Private
;
359 if (Progress
== NULL
) {
360 return EFI_INVALID_PARAMETER
;
362 *Progress
= Configuration
;
364 if (Configuration
== NULL
) {
365 return EFI_INVALID_PARAMETER
;
369 // Check routing data in <ConfigHdr>.
370 // Note: there is no name for Name/Value storage, only GUID will be checked
372 if (!HiiIsConfigHdrMatch (Configuration
, &gBootMaintFormSetGuid
, mBootMaintStorageName
)) {
373 return EFI_NOT_FOUND
;
376 Status
= gBS
->LocateProtocol (
377 &gEfiHiiConfigRoutingProtocolGuid
,
379 (VOID
**) &ConfigRouting
381 if (EFI_ERROR (Status
)) {
385 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
387 // Get Buffer Storage data from EFI variable
389 BufferSize
= sizeof (BMM_FAKE_NV_DATA
);
390 OldBmmData
= &Private
->BmmOldFakeNVData
;
391 NewBmmData
= &Private
->BmmFakeNvData
;
393 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
395 Status
= ConfigRouting
->ConfigToBlock (
398 (UINT8
*) NewBmmData
,
402 ASSERT_EFI_ERROR (Status
);
404 // Compare new and old BMM configuration data and only do action for modified item to
405 // avoid setting unnecessary non-volatile variable
409 // Check data which located in BMM main page and save the settings if need
411 if (CompareMem (NewBmmData
->LegacyFD
, OldBmmData
->LegacyFD
, sizeof (NewBmmData
->LegacyFD
)) != 0) {
412 Var_UpdateBBSOption (Private
, FORM_SET_FD_ORDER_ID
);
415 if (CompareMem (NewBmmData
->LegacyHD
, OldBmmData
->LegacyHD
, sizeof (NewBmmData
->LegacyHD
)) != 0) {
416 Var_UpdateBBSOption (Private
, FORM_SET_HD_ORDER_ID
);
419 if (CompareMem (NewBmmData
->LegacyCD
, OldBmmData
->LegacyCD
, sizeof (NewBmmData
->LegacyCD
)) != 0) {
420 Var_UpdateBBSOption (Private
, FORM_SET_CD_ORDER_ID
);
423 if (CompareMem (NewBmmData
->LegacyNET
, OldBmmData
->LegacyNET
, sizeof (NewBmmData
->LegacyNET
)) != 0) {
424 Var_UpdateBBSOption (Private
, FORM_SET_NET_ORDER_ID
);
427 if (CompareMem (NewBmmData
->LegacyBEV
, OldBmmData
->LegacyBEV
, sizeof (NewBmmData
->LegacyBEV
)) != 0) {
428 Var_UpdateBBSOption (Private
, FORM_SET_BEV_ORDER_ID
);
432 // Change for "delete boot option" page need update NewBmmData->BootOptionOrder, so process
433 // NewBmmData->BootOptionOrder before NewBmmData->BootOptionDel
435 if (CompareMem (NewBmmData
->BootOptionOrder
, OldBmmData
->BootOptionOrder
, sizeof (NewBmmData
->BootOptionOrder
)) != 0) {
436 Status
= Var_UpdateBootOrder (Private
);
440 // Change for "delete driver option" page need update NewBmmData->DriverOptionOrder, so process
441 // NewBmmData->DriverOptionOrder before NewBmmData->DriverOptionDel
443 if (CompareMem (NewBmmData
->DriverOptionOrder
, OldBmmData
->DriverOptionOrder
, sizeof (NewBmmData
->DriverOptionOrder
)) != 0) {
444 Status
= Var_UpdateDriverOrder (Private
);
448 // Check data which located in Boot Options Menu and save the settings if need
450 if (CompareMem (NewBmmData
->BootOptionDel
, OldBmmData
->BootOptionDel
, sizeof (NewBmmData
->BootOptionDel
)) != 0) {
452 ((Index
< BootOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->BootOptionDel
) / sizeof (NewBmmData
->BootOptionDel
[0]))));
454 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
455 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
456 NewLoadContext
->Deleted
= NewBmmData
->BootOptionDel
[Index
];
457 NewBmmData
->BootOptionDel
[Index
] = FALSE
;
458 NewBmmData
->BootOptionDelMark
[Index
] = FALSE
;
461 Var_DelBootOption ();
465 // Check data which located in Driver Options Menu and save the settings if need
467 if (CompareMem (NewBmmData
->DriverOptionDel
, OldBmmData
->DriverOptionDel
, sizeof (NewBmmData
->DriverOptionDel
)) != 0) {
469 ((Index
< DriverOptionMenu
.MenuNumber
) && (Index
< (sizeof (NewBmmData
->DriverOptionDel
) / sizeof (NewBmmData
->DriverOptionDel
[0]))));
471 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
472 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
473 NewLoadContext
->Deleted
= NewBmmData
->DriverOptionDel
[Index
];
474 NewBmmData
->DriverOptionDel
[Index
] = FALSE
;
475 NewBmmData
->DriverOptionDelMark
[Index
] = FALSE
;
477 Var_DelDriverOption ();
480 if (CompareMem (&NewBmmData
->BootTimeOut
, &OldBmmData
->BootTimeOut
, sizeof (NewBmmData
->BootTimeOut
)) != 0) {
481 Status
= gRT
->SetVariable (
483 &gEfiGlobalVariableGuid
,
484 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
486 &(NewBmmData
->BootTimeOut
)
488 ASSERT_EFI_ERROR(Status
);
491 // Bugbug: code not exit in UiApp but in IntelFrameworkModulePkg, need do more check.
493 Private
->BmmOldFakeNVData
.BootTimeOut
= NewBmmData
->BootTimeOut
;
496 if (CompareMem (&NewBmmData
->BootNext
, &OldBmmData
->BootNext
, sizeof (NewBmmData
->BootNext
)) != 0) {
497 Status
= Var_UpdateBootNext (Private
);
500 if (CompareMem (&NewBmmData
->ConsoleOutMode
, &OldBmmData
->ConsoleOutMode
, sizeof (NewBmmData
->ConsoleOutMode
)) != 0) {
501 Var_UpdateConMode (Private
);
504 TerminalAttChange
= FALSE
;
505 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
508 // only need update modified items
510 if (CompareMem (&NewBmmData
->COMBaudRate
[Index
], &OldBmmData
->COMBaudRate
[Index
], sizeof (NewBmmData
->COMBaudRate
[Index
])) == 0 &&
511 CompareMem (&NewBmmData
->COMDataRate
[Index
], &OldBmmData
->COMDataRate
[Index
], sizeof (NewBmmData
->COMDataRate
[Index
])) == 0 &&
512 CompareMem (&NewBmmData
->COMStopBits
[Index
], &OldBmmData
->COMStopBits
[Index
], sizeof (NewBmmData
->COMStopBits
[Index
])) == 0 &&
513 CompareMem (&NewBmmData
->COMParity
[Index
], &OldBmmData
->COMParity
[Index
], sizeof (NewBmmData
->COMParity
[Index
])) == 0 &&
514 CompareMem (&NewBmmData
->COMTerminalType
[Index
], &OldBmmData
->COMTerminalType
[Index
], sizeof (NewBmmData
->COMTerminalType
[Index
])) == 0 &&
515 CompareMem (&NewBmmData
->COMFlowControl
[Index
], &OldBmmData
->COMFlowControl
[Index
], sizeof (NewBmmData
->COMFlowControl
[Index
])) == 0) {
519 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
520 ASSERT (NewMenuEntry
!= NULL
);
521 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
522 NewTerminalContext
->BaudRateIndex
= NewBmmData
->COMBaudRate
[Index
];
523 ASSERT (NewBmmData
->COMBaudRate
[Index
] < (ARRAY_SIZE (BaudRateList
)));
524 NewTerminalContext
->BaudRate
= BaudRateList
[NewBmmData
->COMBaudRate
[Index
]].Value
;
525 NewTerminalContext
->DataBitsIndex
= NewBmmData
->COMDataRate
[Index
];
526 ASSERT (NewBmmData
->COMDataRate
[Index
] < (ARRAY_SIZE (DataBitsList
)));
527 NewTerminalContext
->DataBits
= (UINT8
) DataBitsList
[NewBmmData
->COMDataRate
[Index
]].Value
;
528 NewTerminalContext
->StopBitsIndex
= NewBmmData
->COMStopBits
[Index
];
529 ASSERT (NewBmmData
->COMStopBits
[Index
] < (ARRAY_SIZE (StopBitsList
)));
530 NewTerminalContext
->StopBits
= (UINT8
) StopBitsList
[NewBmmData
->COMStopBits
[Index
]].Value
;
531 NewTerminalContext
->ParityIndex
= NewBmmData
->COMParity
[Index
];
532 ASSERT (NewBmmData
->COMParity
[Index
] < (ARRAY_SIZE (ParityList
)));
533 NewTerminalContext
->Parity
= (UINT8
) ParityList
[NewBmmData
->COMParity
[Index
]].Value
;
534 NewTerminalContext
->TerminalType
= NewBmmData
->COMTerminalType
[Index
];
535 NewTerminalContext
->FlowControl
= NewBmmData
->COMFlowControl
[Index
];
536 ChangeTerminalDevicePath (
537 &(NewTerminalContext
->DevicePath
),
540 TerminalAttChange
= TRUE
;
542 if (TerminalAttChange
) {
543 Var_UpdateConsoleInpOption ();
544 Var_UpdateConsoleOutOption ();
545 Var_UpdateErrorOutOption ();
549 // Check data which located in Console Options Menu and save the settings if need
551 if (CompareMem (NewBmmData
->ConsoleInCheck
, OldBmmData
->ConsoleInCheck
, sizeof (NewBmmData
->ConsoleInCheck
)) != 0) {
552 for (Index
= 0; Index
< ConsoleInpMenu
.MenuNumber
; Index
++) {
553 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
554 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
555 ASSERT (Index
< MAX_MENU_NUMBER
);
556 NewConsoleContext
->IsActive
= NewBmmData
->ConsoleInCheck
[Index
];
559 Var_UpdateConsoleInpOption ();
562 if (CompareMem (NewBmmData
->ConsoleOutCheck
, OldBmmData
->ConsoleOutCheck
, sizeof (NewBmmData
->ConsoleOutCheck
)) != 0) {
563 for (Index
= 0; Index
< ConsoleOutMenu
.MenuNumber
; Index
++) {
564 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
565 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
566 ASSERT (Index
< MAX_MENU_NUMBER
);
567 NewConsoleContext
->IsActive
= NewBmmData
->ConsoleOutCheck
[Index
];
570 Var_UpdateConsoleOutOption ();
573 if (CompareMem (NewBmmData
->ConsoleErrCheck
, OldBmmData
->ConsoleErrCheck
, sizeof (NewBmmData
->ConsoleErrCheck
)) != 0) {
574 for (Index
= 0; Index
< ConsoleErrMenu
.MenuNumber
; Index
++) {
575 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
576 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
577 ASSERT (Index
< MAX_MENU_NUMBER
);
578 NewConsoleContext
->IsActive
= NewBmmData
->ConsoleErrCheck
[Index
];
581 Var_UpdateErrorOutOption ();
585 // After user do the save action, need to update OldBmmData.
587 CopyMem (OldBmmData
, NewBmmData
, sizeof (BMM_FAKE_NV_DATA
));
593 Create GoTo OP code into FORM_BOOT_LEGACY_DEVICE label for legacy boot option.
597 InitializeLegacyBootOption (
601 RefreshUpdateData ();
602 mStartLabel
->Number
= FORM_BOOT_LEGACY_DEVICE_ID
;
605 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
606 // in BootOption form: legacy FD/HD/CD/NET/BEV
608 HiiCreateGotoOpCode (
610 FORM_SET_FD_ORDER_ID
,
611 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
612 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE
),
613 EFI_IFR_FLAG_CALLBACK
,
617 HiiCreateGotoOpCode (
619 FORM_SET_HD_ORDER_ID
,
620 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
621 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE
),
622 EFI_IFR_FLAG_CALLBACK
,
626 HiiCreateGotoOpCode (
628 FORM_SET_CD_ORDER_ID
,
629 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
630 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE
),
631 EFI_IFR_FLAG_CALLBACK
,
635 HiiCreateGotoOpCode (
637 FORM_SET_NET_ORDER_ID
,
638 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
639 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE
),
640 EFI_IFR_FLAG_CALLBACK
,
641 FORM_SET_NET_ORDER_ID
644 HiiCreateGotoOpCode (
646 FORM_SET_BEV_ORDER_ID
,
647 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
648 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE
),
649 EFI_IFR_FLAG_CALLBACK
,
650 FORM_SET_BEV_ORDER_ID
654 mBmmCallbackInfo
->BmmHiiHandle
,
655 &gBootMaintFormSetGuid
,
657 mStartOpCodeHandle
, // Label FORM_BOOT_LEGACY_DEVICE_ID
658 mEndOpCodeHandle
// LABEL_END
665 This function processes the results of changes in configuration.
668 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
669 @param Action Specifies the type of action taken by the browser.
670 @param QuestionId A unique value which is sent to the original exporting driver
671 so that it can identify the type of data to expect.
672 @param Type The type of value for the question.
673 @param Value A pointer to the data being sent to the original exporting driver.
674 @param ActionRequest On return, points to the action requested by the callback function.
676 @retval EFI_SUCCESS The callback successfully handled the action.
677 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
678 @retval EFI_DEVICE_ERROR The variable could not be saved.
679 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
680 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
685 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
686 IN EFI_BROWSER_ACTION Action
,
687 IN EFI_QUESTION_ID QuestionId
,
689 IN EFI_IFR_TYPE_VALUE
*Value
,
690 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
693 BMM_CALLBACK_DATA
*Private
;
694 BM_MENU_ENTRY
*NewMenuEntry
;
695 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
709 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
711 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
712 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
&& QuestionId
== FORM_BOOT_SETUP_ID
) {
714 // Initilize Form for legacy boot option.
716 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
717 if (!EFI_ERROR (Status
)) {
718 InitializeLegacyBootOption ();
724 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
726 // All other action return unsupported.
728 return EFI_UNSUPPORTED
;
731 Status
= EFI_SUCCESS
;
740 Private
= BMM_CALLBACK_DATA_FROM_THIS (This
);
742 // Retrieve uncommitted data from Form Browser
744 CurrentFakeNVMap
= &Private
->BmmFakeNvData
;
745 HiiGetBrowserData (&gBootMaintFormSetGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*) CurrentFakeNVMap
);
746 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
748 return EFI_INVALID_PARAMETER
;
751 UpdatePageId (Private
, QuestionId
);
753 if (QuestionId
< FILE_OPTION_OFFSET
) {
754 if (QuestionId
< CONFIG_OPTION_OFFSET
) {
755 switch (QuestionId
) {
756 case KEY_VALUE_BOOT_FROM_FILE
:
757 Private
->FeCurrentState
= FileExplorerStateBootFromFile
;
760 case FORM_BOOT_ADD_ID
:
761 Private
->FeCurrentState
= FileExplorerStateAddBootOption
;
764 case FORM_DRV_ADD_FILE_ID
:
765 Private
->FeCurrentState
= FileExplorerStateAddDriverOptionState
;
768 case FORM_DRV_ADD_HANDLE_ID
:
769 CleanUpPage (FORM_DRV_ADD_HANDLE_ID
, Private
);
770 UpdateDrvAddHandlePage (Private
);
773 case FORM_BOOT_DEL_ID
:
774 CleanUpPage (FORM_BOOT_DEL_ID
, Private
);
775 UpdateBootDelPage (Private
);
778 case FORM_BOOT_CHG_ID
:
779 case FORM_DRV_CHG_ID
:
780 UpdatePageBody (QuestionId
, Private
);
783 case FORM_DRV_DEL_ID
:
784 CleanUpPage (FORM_DRV_DEL_ID
, Private
);
785 UpdateDrvDelPage (Private
);
788 case FORM_BOOT_NEXT_ID
:
789 CleanUpPage (FORM_BOOT_NEXT_ID
, Private
);
790 UpdateBootNextPage (Private
);
793 case FORM_TIME_OUT_ID
:
794 CleanUpPage (FORM_TIME_OUT_ID
, Private
);
795 UpdateTimeOutPage (Private
);
799 case FORM_CON_OUT_ID
:
800 case FORM_CON_ERR_ID
:
801 UpdatePageBody (QuestionId
, Private
);
804 case FORM_CON_MODE_ID
:
805 CleanUpPage (FORM_CON_MODE_ID
, Private
);
806 UpdateConModePage (Private
);
809 case FORM_CON_COM_ID
:
810 CleanUpPage (FORM_CON_COM_ID
, Private
);
811 UpdateConCOMPage (Private
);
814 case FORM_SET_FD_ORDER_ID
:
815 case FORM_SET_HD_ORDER_ID
:
816 case FORM_SET_CD_ORDER_ID
:
817 case FORM_SET_NET_ORDER_ID
:
818 case FORM_SET_BEV_ORDER_ID
:
819 CleanUpPage (QuestionId
, Private
);
820 UpdateSetLegacyDeviceOrderPage (QuestionId
, Private
);
826 } else if ((QuestionId
>= TERMINAL_OPTION_OFFSET
) && (QuestionId
< CONSOLE_OPTION_OFFSET
)) {
827 Index2
= (UINT16
) (QuestionId
- TERMINAL_OPTION_OFFSET
);
828 Private
->CurrentTerminal
= Index2
;
830 CleanUpPage (FORM_CON_COM_SETUP_ID
, Private
);
831 UpdateTerminalPage (Private
);
833 } else if (QuestionId
>= HANDLE_OPTION_OFFSET
) {
834 Index2
= (UINT16
) (QuestionId
- HANDLE_OPTION_OFFSET
);
836 NewMenuEntry
= BOpt_GetMenuEntry (&DriverMenu
, Index2
);
837 ASSERT (NewMenuEntry
!= NULL
);
838 Private
->HandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
840 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID
, Private
);
842 Private
->MenuEntry
= NewMenuEntry
;
843 Private
->LoadContext
->FilePathList
= Private
->HandleContext
->DevicePath
;
845 UpdateDriverAddHandleDescPage (Private
);
848 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
849 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
850 return EFI_INVALID_PARAMETER
;
852 if ((QuestionId
>= BOOT_OPTION_DEL_QUESTION_ID
) && (QuestionId
< BOOT_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
855 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
857 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = TRUE
;
860 // Means user remove the old check status.
862 CurrentFakeNVMap
->BootOptionDelMark
[QuestionId
- BOOT_OPTION_DEL_QUESTION_ID
] = FALSE
;
864 } else if ((QuestionId
>= DRIVER_OPTION_DEL_QUESTION_ID
) && (QuestionId
< DRIVER_OPTION_DEL_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
866 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = TRUE
;
868 CurrentFakeNVMap
->DriverOptionDelMark
[QuestionId
- DRIVER_OPTION_DEL_QUESTION_ID
] = FALSE
;
870 } else if ((QuestionId
>= LEGACY_FD_QUESTION_ID
) && (QuestionId
< LEGACY_BEV_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
872 // Update Select FD/HD/CD/NET/BEV Order Form
875 DisMap
= Private
->BmmOldFakeNVData
.DisableMap
;
877 if (QuestionId
>= LEGACY_FD_QUESTION_ID
&& QuestionId
< LEGACY_FD_QUESTION_ID
+ MAX_MENU_NUMBER
) {
878 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
879 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyFD
;
880 NewLegacyDev
= CurrentFakeNVMap
->LegacyFD
;
881 } else if (QuestionId
>= LEGACY_HD_QUESTION_ID
&& QuestionId
< LEGACY_HD_QUESTION_ID
+ MAX_MENU_NUMBER
) {
882 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
883 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyHD
;
884 NewLegacyDev
= CurrentFakeNVMap
->LegacyHD
;
885 } else if (QuestionId
>= LEGACY_CD_QUESTION_ID
&& QuestionId
< LEGACY_CD_QUESTION_ID
+ MAX_MENU_NUMBER
) {
886 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
887 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyCD
;
888 NewLegacyDev
= CurrentFakeNVMap
->LegacyCD
;
889 } else if (QuestionId
>= LEGACY_NET_QUESTION_ID
&& QuestionId
< LEGACY_NET_QUESTION_ID
+ MAX_MENU_NUMBER
) {
890 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
891 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyNET
;
892 NewLegacyDev
= CurrentFakeNVMap
->LegacyNET
;
893 } else if (QuestionId
>= LEGACY_BEV_QUESTION_ID
&& QuestionId
< LEGACY_BEV_QUESTION_ID
+ MAX_MENU_NUMBER
) {
894 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
895 OldLegacyDev
= Private
->BmmOldFakeNVData
.LegacyBEV
;
896 NewLegacyDev
= CurrentFakeNVMap
->LegacyBEV
;
899 // First, find the different position
900 // if there is change, it should be only one
902 for (Index
= 0; Index
< Number
; Index
++) {
903 if (OldLegacyDev
[Index
] != NewLegacyDev
[Index
]) {
904 OldValue
= OldLegacyDev
[Index
];
905 NewValue
= NewLegacyDev
[Index
];
910 if (Index
!= Number
) {
912 // there is change, now process
914 if (0xFF == NewValue
) {
916 // This item will be disable
917 // Just move the items behind this forward to overlap it
920 Bit
= 7 - (OldValue
% 8);
921 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
922 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
923 NewLegacyDev
[Index2
] = NewLegacyDev
[Index2
+ 1];
926 NewLegacyDev
[Index2
] = 0xFF;
928 for (Index2
= 0; Index2
< Number
; Index2
++) {
929 if (Index2
== Index
) {
933 if (OldLegacyDev
[Index2
] == NewValue
) {
935 // If NewValue is in OldLegacyDev array
936 // remember its old position
938 NewValuePos
= Index2
;
943 if (Index2
!= Number
) {
945 // We will change current item to an existing item
946 // (It's hard to describe here, please read code, it's like a cycle-moving)
948 for (Index2
= NewValuePos
; Index2
!= Index
;) {
949 if (NewValuePos
< Index
) {
950 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
+ 1];
953 NewLegacyDev
[Index2
] = OldLegacyDev
[Index2
- 1];
959 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
960 // so we should modify DisMap to reflect the change
963 Bit
= 7 - (NewValue
% 8);
964 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] & (~ (UINT8
) (1 << Bit
)));
965 if (0xFF != OldValue
) {
967 // Because NewValue is a item that was disabled before
968 // so after changing the OldValue should be disabled
969 // actually we are doing a swap of enable-disable states of two items
972 Bit
= 7 - (OldValue
% 8);
973 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
978 // To prevent DISABLE appears in the middle of the list
979 // we should perform a re-ordering
983 while (Index
< Number
) {
984 if (0xFF != NewLegacyDev
[Index
]) {
991 while (Index2
< Number
) {
992 if (0xFF != NewLegacyDev
[Index2
]) {
999 if (Index2
< Number
) {
1000 NewLegacyDev
[Index
] = NewLegacyDev
[Index2
];
1001 NewLegacyDev
[Index2
] = 0xFF;
1008 // Return correct question value.
1010 Value
->u8
= NewLegacyDev
[Index3
];
1013 switch (QuestionId
) {
1014 case KEY_VALUE_SAVE_AND_EXIT
:
1015 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1018 case KEY_VALUE_NO_SAVE_AND_EXIT
:
1020 // Restore local maintain data.
1022 DiscardChangeHandler (Private
, CurrentFakeNVMap
);
1023 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1027 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
1028 return EFI_UNSUPPORTED
;
1037 // Pass changed uncommitted data back to Form Browser
1039 HiiSetBrowserData (&gBootMaintFormSetGuid
, mBootMaintStorageName
, sizeof (BMM_FAKE_NV_DATA
), (UINT8
*) CurrentFakeNVMap
, NULL
);
1044 Discard all changes done to the BMM pages such as Boot Order change,
1045 Driver order change.
1047 @param Private The BMM context data.
1048 @param CurrentFakeNVMap The current Fack NV Map.
1052 DiscardChangeHandler (
1053 IN BMM_CALLBACK_DATA
*Private
,
1054 IN BMM_FAKE_NV_DATA
*CurrentFakeNVMap
1059 switch (Private
->BmmPreviousPageId
) {
1060 case FORM_BOOT_CHG_ID
:
1061 CopyMem (CurrentFakeNVMap
->BootOptionOrder
, Private
->BmmOldFakeNVData
.BootOptionOrder
, sizeof (CurrentFakeNVMap
->BootOptionOrder
));
1064 case FORM_DRV_CHG_ID
:
1065 CopyMem (CurrentFakeNVMap
->DriverOptionOrder
, Private
->BmmOldFakeNVData
.DriverOptionOrder
, sizeof (CurrentFakeNVMap
->DriverOptionOrder
));
1068 case FORM_BOOT_DEL_ID
:
1069 ASSERT (BootOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->BootOptionDel
) / sizeof (CurrentFakeNVMap
->BootOptionDel
[0])));
1070 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
1071 CurrentFakeNVMap
->BootOptionDel
[Index
] = FALSE
;
1072 CurrentFakeNVMap
->BootOptionDelMark
[Index
] = FALSE
;
1076 case FORM_DRV_DEL_ID
:
1077 ASSERT (DriverOptionMenu
.MenuNumber
<= (sizeof (CurrentFakeNVMap
->DriverOptionDel
) / sizeof (CurrentFakeNVMap
->DriverOptionDel
[0])));
1078 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
1079 CurrentFakeNVMap
->DriverOptionDel
[Index
] = FALSE
;
1080 CurrentFakeNVMap
->DriverOptionDelMark
[Index
] = FALSE
;
1084 case FORM_BOOT_NEXT_ID
:
1085 CurrentFakeNVMap
->BootNext
= Private
->BmmOldFakeNVData
.BootNext
;
1088 case FORM_TIME_OUT_ID
:
1089 CurrentFakeNVMap
->BootTimeOut
= Private
->BmmOldFakeNVData
.BootTimeOut
;
1092 case FORM_DRV_ADD_HANDLE_DESC_ID
:
1093 case FORM_DRV_ADD_FILE_ID
:
1094 case FORM_DRV_ADD_HANDLE_ID
:
1095 CurrentFakeNVMap
->DriverAddHandleDesc
[0] = 0x0000;
1096 CurrentFakeNVMap
->DriverAddHandleOptionalData
[0] = 0x0000;
1105 Initialize the Boot Maintenance Utitliy.
1108 @retval EFI_SUCCESS utility ended successfully
1109 @retval others contain some errors
1117 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
1119 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
1123 Status
= EFI_SUCCESS
;
1124 BmmCallbackInfo
= mBmmCallbackInfo
;
1126 BmmCallbackInfo
->BmmPreviousPageId
= FORM_MAIN_ID
;
1127 BmmCallbackInfo
->BmmCurrentPageId
= FORM_MAIN_ID
;
1128 BmmCallbackInfo
->FeCurrentState
= FileExplorerStateInActive
;
1129 BmmCallbackInfo
->FeDisplayContext
= FileExplorerDisplayUnknown
;
1132 // Reinstall String packages to include more new strings.
1136 // String package size
1138 Length
= ReadUnaligned32 ((UINT32
*) BdsDxeStrings
) - sizeof (UINT32
);
1141 // Add the length of the Package List Header and the terminating Package Header
1143 Length
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
) + sizeof (EFI_HII_PACKAGE_HEADER
);
1146 // Allocate the storage for the entire Package List
1148 PackageListHeader
= AllocateZeroPool (Length
);
1151 // If the Package List can not be allocated, then return a NULL HII Handle
1153 if (PackageListHeader
== NULL
) {
1154 return EFI_OUT_OF_RESOURCES
;
1158 // Fill in the GUID and Length of the Package List Header
1160 PackageListHeader
->PackageLength
= Length
;
1163 // Copy String Data into Package list.
1165 Data
= (UINT8
*)(PackageListHeader
+ 1);
1166 Length
= ReadUnaligned32 ((UINT32
*) BdsDxeStrings
) - sizeof (UINT32
);
1167 CopyMem (Data
, (UINT8
*) BdsDxeStrings
+ sizeof (UINT32
), Length
);
1170 // Add End type HII package.
1173 ((EFI_HII_PACKAGE_HEADER
*) Data
)->Type
= EFI_HII_PACKAGE_END
;
1174 ((EFI_HII_PACKAGE_HEADER
*) Data
)->Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
1177 // Update String package for BM
1179 CopyGuid (&PackageListHeader
->PackageListGuid
, &gBootMaintFormSetGuid
);
1180 Status
= gHiiDatabase
->UpdatePackageList (gHiiDatabase
, BmmCallbackInfo
->BmmHiiHandle
, PackageListHeader
);
1183 // Update String package for FE.
1185 CopyGuid (&PackageListHeader
->PackageListGuid
, &gFileExploreFormSetGuid
);
1186 Status
= gHiiDatabase
->UpdatePackageList (gHiiDatabase
, BmmCallbackInfo
->FeHiiHandle
, PackageListHeader
);
1188 FreePool (PackageListHeader
);
1191 // Init OpCode Handle and Allocate space for creation of Buffer
1193 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1194 if (mStartOpCodeHandle
== NULL
) {
1195 Status
= EFI_OUT_OF_RESOURCES
;
1199 mEndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1200 if (mEndOpCodeHandle
== NULL
) {
1201 Status
= EFI_OUT_OF_RESOURCES
;
1206 // Create Hii Extend Label OpCode as the start opcode
1208 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (mStartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1209 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1212 // Create Hii Extend Label OpCode as the end opcode
1214 mEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (mEndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1215 mEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1216 mEndLabel
->Number
= LABEL_END
;
1218 InitializeStringDepository ();
1220 InitAllMenu (BmmCallbackInfo
);
1222 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleInpMenu
);
1223 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleOutMenu
);
1224 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &ConsoleErrMenu
);
1225 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &BootOptionMenu
);
1226 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverOptionMenu
);
1227 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &TerminalMenu
);
1228 CreateMenuStringToken (BmmCallbackInfo
, BmmCallbackInfo
->BmmHiiHandle
, &DriverMenu
);
1230 InitializeBmmConfig (BmmCallbackInfo
);
1233 // Dispatch BMM main formset and File Explorer formset.
1235 FormSetDispatcher (BmmCallbackInfo
);
1240 CleanUpStringDepository ();
1245 if (mStartOpCodeHandle
!= NULL
) {
1246 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
1249 if (mEndOpCodeHandle
!= NULL
) {
1250 HiiFreeOpCodeHandle (mEndOpCodeHandle
);
1258 Initialized all Menu Option List.
1260 @param CallbackData The BMM context data.
1265 IN BMM_CALLBACK_DATA
*CallbackData
1268 InitializeListHead (&BootOptionMenu
.Head
);
1269 InitializeListHead (&DriverOptionMenu
.Head
);
1270 BOpt_GetBootOptions (CallbackData
);
1271 BOpt_GetDriverOptions (CallbackData
);
1272 BOpt_GetLegacyOptions ();
1273 InitializeListHead (&FsOptionMenu
.Head
);
1274 BOpt_FindDrivers ();
1275 InitializeListHead (&DirectoryMenu
.Head
);
1276 InitializeListHead (&ConsoleInpMenu
.Head
);
1277 InitializeListHead (&ConsoleOutMenu
.Head
);
1278 InitializeListHead (&ConsoleErrMenu
.Head
);
1279 InitializeListHead (&TerminalMenu
.Head
);
1285 Free up all Menu Option list.
1293 BOpt_FreeMenu (&DirectoryMenu
);
1294 BOpt_FreeMenu (&FsOptionMenu
);
1295 BOpt_FreeMenu (&BootOptionMenu
);
1296 BOpt_FreeMenu (&DriverOptionMenu
);
1297 BOpt_FreeMenu (&DriverMenu
);
1298 BOpt_FreeLegacyOptions ();
1303 Initialize all the string depositories.
1307 InitializeStringDepository (
1311 STRING_DEPOSITORY
*StringDepository
;
1312 StringDepository
= AllocateZeroPool (sizeof (STRING_DEPOSITORY
) * STRING_DEPOSITORY_NUMBER
);
1313 FileOptionStrDepository
= StringDepository
++;
1314 ConsoleOptionStrDepository
= StringDepository
++;
1315 BootOptionStrDepository
= StringDepository
++;
1316 BootOptionHelpStrDepository
= StringDepository
++;
1317 DriverOptionStrDepository
= StringDepository
++;
1318 DriverOptionHelpStrDepository
= StringDepository
++;
1319 TerminalStrDepository
= StringDepository
;
1323 Fetch a usable string node from the string depository and return the string token.
1325 @param CallbackData The BMM context data.
1326 @param StringDepository The string repository.
1328 @retval EFI_STRING_ID String token.
1332 GetStringTokenFromDepository (
1333 IN BMM_CALLBACK_DATA
*CallbackData
,
1334 IN STRING_DEPOSITORY
*StringDepository
1337 STRING_LIST_NODE
*CurrentListNode
;
1338 STRING_LIST_NODE
*NextListNode
;
1340 CurrentListNode
= StringDepository
->CurrentNode
;
1342 if ((NULL
!= CurrentListNode
) && (NULL
!= CurrentListNode
->Next
)) {
1344 // Fetch one reclaimed node from the list.
1346 NextListNode
= StringDepository
->CurrentNode
->Next
;
1349 // If there is no usable node in the list, update the list.
1351 NextListNode
= AllocateZeroPool (sizeof (STRING_LIST_NODE
));
1352 ASSERT (NextListNode
!= NULL
);
1353 NextListNode
->StringToken
= HiiSetString (CallbackData
->BmmHiiHandle
, 0, L
" ", NULL
);
1354 ASSERT (NextListNode
->StringToken
!= 0);
1356 StringDepository
->TotalNodeNumber
++;
1358 if (NULL
== CurrentListNode
) {
1359 StringDepository
->ListHead
= NextListNode
;
1361 CurrentListNode
->Next
= NextListNode
;
1365 StringDepository
->CurrentNode
= NextListNode
;
1367 return StringDepository
->CurrentNode
->StringToken
;
1371 Reclaim string depositories by moving the current node pointer to list head..
1375 ReclaimStringDepository (
1379 UINTN DepositoryIndex
;
1380 STRING_DEPOSITORY
*StringDepository
;
1382 StringDepository
= FileOptionStrDepository
;
1383 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1384 StringDepository
->CurrentNode
= StringDepository
->ListHead
;
1390 Release resource for all the string depositories.
1394 CleanUpStringDepository (
1399 UINTN DepositoryIndex
;
1400 STRING_LIST_NODE
*CurrentListNode
;
1401 STRING_LIST_NODE
*NextListNode
;
1402 STRING_DEPOSITORY
*StringDepository
;
1405 // Release string list nodes.
1407 StringDepository
= FileOptionStrDepository
;
1408 for (DepositoryIndex
= 0; DepositoryIndex
< STRING_DEPOSITORY_NUMBER
; DepositoryIndex
++) {
1409 CurrentListNode
= StringDepository
->ListHead
;
1410 for (NodeIndex
= 0; NodeIndex
< StringDepository
->TotalNodeNumber
; NodeIndex
++) {
1411 NextListNode
= CurrentListNode
->Next
;
1412 FreePool (CurrentListNode
);
1413 CurrentListNode
= NextListNode
;
1419 // Release string depository.
1421 FreePool (FileOptionStrDepository
);
1425 Start boot maintenance manager
1427 @retval EFI_SUCCESS If BMM is invoked successfully.
1428 @return Other value if BMM return unsuccessfully.
1437 LIST_ENTRY BdsBootOptionList
;
1439 InitializeListHead (&BdsBootOptionList
);
1442 // Connect all prior to entering the platform setup menu.
1444 if (!gConnectAllHappened
) {
1445 BdsLibConnectAllDriversToAllControllers ();
1446 gConnectAllHappened
= TRUE
;
1449 // Have chance to enumerate boot device
1451 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
1454 // Group the legacy boot options for the same device type
1456 GroupMultipleLegacyBootOption4SameType ();
1461 Status
= InitializeBM ();
1467 Dispatch BMM formset and FileExplorer formset.
1470 @param CallbackData The BMM context data.
1472 @retval EFI_SUCCESS If function complete successfully.
1473 @return Other value if the Setup Browser process BMM's pages and
1474 return unsuccessfully.
1479 IN BMM_CALLBACK_DATA
*CallbackData
1483 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1486 UpdatePageId (CallbackData
, FORM_MAIN_ID
);
1488 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1489 Status
= gFormBrowser2
->SendForm (
1491 &CallbackData
->BmmHiiHandle
,
1493 &gBootMaintFormSetGuid
,
1498 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1499 EnableResetRequired ();
1502 ReclaimStringDepository ();
1505 // When this Formset returns, check if we are going to explore files.
1507 if (FileExplorerStateInActive
!= CallbackData
->FeCurrentState
) {
1508 UpdateFileExplorer (CallbackData
, 0);
1510 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1511 Status
= gFormBrowser2
->SendForm (
1513 &CallbackData
->FeHiiHandle
,
1515 &gFileExploreFormSetGuid
,
1520 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1521 EnableResetRequired ();
1524 CallbackData
->FeCurrentState
= FileExplorerStateInActive
;
1525 CallbackData
->FeDisplayContext
= FileExplorerDisplayUnknown
;
1526 ReclaimStringDepository ();
1536 Intall BootMaint and FileExplorer HiiPackages.
1544 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
1549 // Create CallbackData structures for Driver Callback
1551 BmmCallbackInfo
= AllocateZeroPool (sizeof (BMM_CALLBACK_DATA
));
1552 if (BmmCallbackInfo
== NULL
) {
1553 return EFI_OUT_OF_RESOURCES
;
1557 // Create LoadOption in BmmCallbackInfo for Driver Callback
1559 Ptr
= AllocateZeroPool (sizeof (BM_LOAD_CONTEXT
) + sizeof (BM_FILE_CONTEXT
) + sizeof (BM_HANDLE_CONTEXT
) + sizeof (BM_MENU_ENTRY
));
1561 FreePool (BmmCallbackInfo
);
1562 BmmCallbackInfo
= NULL
;
1563 return EFI_OUT_OF_RESOURCES
;
1566 // Initialize Bmm callback data.
1568 BmmCallbackInfo
->LoadContext
= (BM_LOAD_CONTEXT
*) Ptr
;
1569 Ptr
+= sizeof (BM_LOAD_CONTEXT
);
1571 BmmCallbackInfo
->FileContext
= (BM_FILE_CONTEXT
*) Ptr
;
1572 Ptr
+= sizeof (BM_FILE_CONTEXT
);
1574 BmmCallbackInfo
->HandleContext
= (BM_HANDLE_CONTEXT
*) Ptr
;
1575 Ptr
+= sizeof (BM_HANDLE_CONTEXT
);
1577 BmmCallbackInfo
->MenuEntry
= (BM_MENU_ENTRY
*) Ptr
;
1579 BmmCallbackInfo
->Signature
= BMM_CALLBACK_DATA_SIGNATURE
;
1580 BmmCallbackInfo
->BmmConfigAccess
.ExtractConfig
= BootMaintExtractConfig
;
1581 BmmCallbackInfo
->BmmConfigAccess
.RouteConfig
= BootMaintRouteConfig
;
1582 BmmCallbackInfo
->BmmConfigAccess
.Callback
= BootMaintCallback
;
1583 BmmCallbackInfo
->FeConfigAccess
.ExtractConfig
= FakeExtractConfig
;
1584 BmmCallbackInfo
->FeConfigAccess
.RouteConfig
= FileExplorerRouteConfig
;
1585 BmmCallbackInfo
->FeConfigAccess
.Callback
= FileExplorerCallback
;
1588 // Install Device Path Protocol and Config Access protocol to driver handle
1590 Status
= gBS
->InstallMultipleProtocolInterfaces (
1591 &BmmCallbackInfo
->BmmDriverHandle
,
1592 &gEfiDevicePathProtocolGuid
,
1593 &mBmmHiiVendorDevicePath
,
1594 &gEfiHiiConfigAccessProtocolGuid
,
1595 &BmmCallbackInfo
->BmmConfigAccess
,
1598 ASSERT_EFI_ERROR (Status
);
1601 // Install Device Path Protocol and Config Access protocol to driver handle
1603 Status
= gBS
->InstallMultipleProtocolInterfaces (
1604 &BmmCallbackInfo
->FeDriverHandle
,
1605 &gEfiDevicePathProtocolGuid
,
1606 &mFeHiiVendorDevicePath
,
1607 &gEfiHiiConfigAccessProtocolGuid
,
1608 &BmmCallbackInfo
->FeConfigAccess
,
1611 ASSERT_EFI_ERROR (Status
);
1614 // Post our Boot Maint VFR binary to the HII database.
1616 BmmCallbackInfo
->BmmHiiHandle
= HiiAddPackages (
1617 &gBootMaintFormSetGuid
,
1618 BmmCallbackInfo
->BmmDriverHandle
,
1623 ASSERT (BmmCallbackInfo
->BmmHiiHandle
!= NULL
);
1626 // Post our File Explorer VFR binary to the HII database.
1628 BmmCallbackInfo
->FeHiiHandle
= HiiAddPackages (
1629 &gFileExploreFormSetGuid
,
1630 BmmCallbackInfo
->FeDriverHandle
,
1635 ASSERT (BmmCallbackInfo
->FeHiiHandle
!= NULL
);
1637 mBmmCallbackInfo
= BmmCallbackInfo
;
1643 Remvoe the intalled BootMaint and FileExplorer HiiPackages.
1651 BMM_CALLBACK_DATA
*BmmCallbackInfo
;
1653 BmmCallbackInfo
= mBmmCallbackInfo
;
1656 // Remove our IFR data from HII database
1658 HiiRemovePackages (BmmCallbackInfo
->BmmHiiHandle
);
1659 HiiRemovePackages (BmmCallbackInfo
->FeHiiHandle
);
1661 if (BmmCallbackInfo
->FeDriverHandle
!= NULL
) {
1662 gBS
->UninstallMultipleProtocolInterfaces (
1663 BmmCallbackInfo
->FeDriverHandle
,
1664 &gEfiDevicePathProtocolGuid
,
1665 &mFeHiiVendorDevicePath
,
1666 &gEfiHiiConfigAccessProtocolGuid
,
1667 &BmmCallbackInfo
->FeConfigAccess
,
1672 if (BmmCallbackInfo
->BmmDriverHandle
!= NULL
) {
1673 gBS
->UninstallMultipleProtocolInterfaces (
1674 BmmCallbackInfo
->BmmDriverHandle
,
1675 &gEfiDevicePathProtocolGuid
,
1676 &mBmmHiiVendorDevicePath
,
1677 &gEfiHiiConfigAccessProtocolGuid
,
1678 &BmmCallbackInfo
->BmmConfigAccess
,
1683 FreePool (BmmCallbackInfo
->LoadContext
);
1684 FreePool (BmmCallbackInfo
);
1686 mBmmCallbackInfo
= NULL
;