2 The platform boot manager reference implementation
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
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 "BootManager.h"
18 EFI_GUID mBootManagerGuid
= BOOT_MANAGER_FORMSET_GUID
;
19 LIST_ENTRY
*mBootOptionsList
;
20 BDS_COMMON_OPTION
*gOption
;
22 HII_VENDOR_DEVICE_PATH mBootManagerHiiVendorDevicePath
= {
28 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
29 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
33 // {1DDDBE15-481D-4d2b-8277-B191EAF66525}
35 { 0x1dddbe15, 0x481d, 0x4d2b, { 0x82, 0x77, 0xb1, 0x91, 0xea, 0xf6, 0x65, 0x25 } }
39 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
41 (UINT8
) (END_DEVICE_PATH_LENGTH
),
42 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
47 BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate
= {
48 BOOT_MANAGER_CALLBACK_DATA_SIGNATURE
,
59 This call back funtion is registered with Boot Manager formset.
60 When user selects a boot option, this call back function will
61 be triggered. The boot option is saved for later processing.
64 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
65 @param Action Specifies the type of action taken by the browser.
66 @param QuestionId A unique value which is sent to the original exporting driver
67 so that it can identify the type of data to expect.
68 @param Type The type of value for the question.
69 @param Value A pointer to the data being sent to the original exporting driver.
70 @param ActionRequest On return, points to the action requested by the callback function.
72 @retval EFI_SUCCESS The callback successfully handled the action.
73 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
79 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
80 IN EFI_BROWSER_ACTION Action
,
81 IN EFI_QUESTION_ID QuestionId
,
83 IN EFI_IFR_TYPE_VALUE
*Value
,
84 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
87 BDS_COMMON_OPTION
*Option
;
91 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
92 return EFI_INVALID_PARAMETER
;
96 // Initialize the key count
100 for (Link
= mBootOptionsList
->ForwardLink
; Link
!= mBootOptionsList
; Link
= Link
->ForwardLink
) {
101 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
108 // Is this device the one chosen?
110 if (KeyCount
== QuestionId
) {
112 // Assigning the returned Key to a global allows the original routine to know what was chosen
114 mKeyInput
= QuestionId
;
117 // Request to exit SendForm(), so that we could boot the selected option
119 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
129 Registers HII packages for the Boot Manger to HII Database.
130 It also registers the browser call back function.
132 @retval EFI_SUCCESS HII packages for the Boot Manager were registered successfully.
133 @retval EFI_OUT_OF_RESOURCES HII packages for the Boot Manager failed to be registered.
137 InitializeBootManager (
144 // Install Device Path Protocol and Config Access protocol to driver handle
146 Status
= gBS
->InstallMultipleProtocolInterfaces (
147 &gBootManagerPrivate
.DriverHandle
,
148 &gEfiDevicePathProtocolGuid
,
149 &mBootManagerHiiVendorDevicePath
,
150 &gEfiHiiConfigAccessProtocolGuid
,
151 &gBootManagerPrivate
.ConfigAccess
,
154 ASSERT_EFI_ERROR (Status
);
157 // Publish our HII data
159 gBootManagerPrivate
.HiiHandle
= HiiAddPackages (
161 gBootManagerPrivate
.DriverHandle
,
166 if (gBootManagerPrivate
.HiiHandle
== NULL
) {
167 Status
= EFI_OUT_OF_RESOURCES
;
169 Status
= EFI_SUCCESS
;
175 This funtion invokees Boot Manager. If all devices have not a chance to be connected,
176 the connect all will be triggered. It then enumerate all boot options. If
177 a boot option from the Boot Manager page is selected, Boot Manager will boot
178 from this boot option.
187 BDS_COMMON_OPTION
*Option
;
193 LIST_ENTRY BdsBootOptionList
;
195 EFI_STRING_ID HelpToken
;
197 EFI_HII_HANDLE HiiHandle
;
198 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
200 VOID
*StartOpCodeHandle
;
201 VOID
*EndOpCodeHandle
;
202 EFI_IFR_GUID_LABEL
*StartLabel
;
203 EFI_IFR_GUID_LABEL
*EndLabel
;
204 CHAR16
*BootStringNumber
;
207 InitializeListHead (&BdsBootOptionList
);
210 // Connect all prior to entering the platform setup menu.
212 if (!gConnectAllHappened
) {
213 BdsLibConnectAllDriversToAllControllers ();
214 gConnectAllHappened
= TRUE
;
217 // BugBug: Here we can not remove the legacy refresh macro, so we need
218 // get the boot order every time from "BootOrder" variable.
219 // Recreate the boot option list base on the BootOrder variable
221 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
223 mBootOptionsList
= &BdsBootOptionList
;
225 HiiHandle
= gBootManagerPrivate
.HiiHandle
;
228 // Allocate space for creation of UpdateData Buffer
230 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
231 ASSERT (StartOpCodeHandle
!= NULL
);
233 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
234 ASSERT (EndOpCodeHandle
!= NULL
);
237 // Create Hii Extend Label OpCode as the start opcode
239 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
240 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
241 StartLabel
->Number
= LABEL_BOOT_OPTION
;
244 // Create Hii Extend Label OpCode as the end opcode
246 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
247 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
248 EndLabel
->Number
= LABEL_BOOT_OPTION_END
;
252 for (Link
= BdsBootOptionList
.ForwardLink
; Link
!= &BdsBootOptionList
; Link
= Link
->ForwardLink
) {
253 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
256 // At this stage we are creating a menu entry, thus the Keys are reproduceable
261 // Don't display the boot option marked as LOAD_OPTION_HIDDEN
263 if ((Option
->Attribute
& LOAD_OPTION_HIDDEN
) != 0) {
268 // Replace description string with UNI file string.
270 BootStringNumber
= AllocateZeroPool (StrSize (Option
->Description
));
271 ASSERT (BootStringNumber
!= NULL
);
273 if (StrStr (Option
->Description
, DESCRIPTION_FLOPPY
) != NULL
) {
274 BootStringNumber
= Option
->Description
+ StrLen (DESCRIPTION_FLOPPY
) + 1;
275 Option
->Description
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY
));
277 } else if (StrStr (Option
->Description
, DESCRIPTION_DVD
) != NULL
) {
278 BootStringNumber
= Option
->Description
+ StrLen (DESCRIPTION_DVD
) + 1;
279 Option
->Description
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_DVD
));
281 } else if (StrStr (Option
->Description
, DESCRIPTION_USB
) != NULL
) {
282 BootStringNumber
= Option
->Description
+ StrLen (DESCRIPTION_USB
) + 1;
283 Option
->Description
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_USB
));
285 } else if (StrStr (Option
->Description
, DESCRIPTION_SCSI
) != NULL
) {
286 BootStringNumber
= Option
->Description
+ StrLen (DESCRIPTION_SCSI
) + 1;
287 Option
->Description
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI
));
289 } else if (StrStr (Option
->Description
, DESCRIPTION_MISC
) != NULL
) {
290 BootStringNumber
= Option
->Description
+ StrLen (DESCRIPTION_MISC
) + 1;
291 Option
->Description
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC
));
293 } else if (StrStr (Option
->Description
, DESCRIPTION_NETWORK
) != NULL
) {
294 BootStringNumber
= Option
->Description
+ StrLen (DESCRIPTION_NETWORK
) + 1;
295 Option
->Description
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK
));
297 } else if (StrStr (Option
->Description
, DESCRIPTION_NON_BLOCK
) != NULL
) {
298 BootStringNumber
= Option
->Description
+ StrLen (DESCRIPTION_NON_BLOCK
) + 1;
299 Option
->Description
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK
));
302 if (StrnCmp (BootStringNumber
, L
"0", 1) != 0) {
303 StrCat (Option
->Description
, L
" ");
304 StrCat (Option
->Description
, BootStringNumber
);
307 Token
= HiiSetString (HiiHandle
, 0, Option
->Description
, NULL
);
309 TempStr
= DevicePathToStr (Option
->DevicePath
);
310 TempSize
= StrSize (TempStr
);
311 HelpString
= AllocateZeroPool (TempSize
+ StrSize (L
"Device Path : "));
312 ASSERT (HelpString
!= NULL
);
313 StrCat (HelpString
, L
"Device Path : ");
314 StrCat (HelpString
, TempStr
);
316 HelpToken
= HiiSetString (HiiHandle
, 0, HelpString
, NULL
);
318 HiiCreateActionOpCode (
323 EFI_IFR_FLAG_CALLBACK
,
331 BOOT_MANAGER_FORM_ID
,
336 HiiFreeOpCodeHandle (StartOpCodeHandle
);
337 HiiFreeOpCodeHandle (EndOpCodeHandle
);
339 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
340 Status
= gFormBrowser2
->SendForm (
349 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
350 EnableResetRequired ();
353 if (gOption
== NULL
) {
358 //Will leave browser, check any reset required change is applied? if yes, reset system
360 SetupResetReminder ();
363 // parse the selected option
365 Status
= BdsLibBootViaBootOption (gOption
, gOption
->DevicePath
, &ExitDataSize
, &ExitData
);
367 if (!EFI_ERROR (Status
)) {
368 gOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED
));
369 PlatformBdsBootSuccess (gOption
);
371 gOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_FAILED
));
372 PlatformBdsBootFail (gOption
, Status
, ExitData
, ExitDataSize
);
373 gST
->ConOut
->OutputString (
375 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE
))
377 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);