3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 The platform boot manager reference implement
21 #include "BootManager.h"
24 LIST_ENTRY
*mBootOptionsList
;
25 BDS_COMMON_OPTION
*gOption
;
26 EFI_HII_HANDLE gBootManagerHandle
;
27 EFI_HANDLE BootManagerCallbackHandle
;
28 EFI_FORM_CALLBACK_PROTOCOL BootManagerCallback
;
29 EFI_GUID gBmGuid
= BOOT_MANAGER_GUID
;
31 extern EFI_FORM_BROWSER_PROTOCOL
*gBrowser
;
32 extern UINT8 BootManagerVfrBin
[];
33 extern UINT8 BdsStrings
[];
34 extern BOOLEAN gConnectAllHappened
;
38 BootManagerCallbackRoutine (
39 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
41 IN EFI_IFR_DATA_ARRAY
*DataArray
,
42 OUT EFI_HII_CALLBACK_PACKET
**Packet
48 This is the function that is called to provide results data to the driver. This data
49 consists of a unique key which is used to identify what data is either being passed back
54 KeyValue - A unique value which is sent to the original exporting driver so that it
55 can identify the type of data to expect. The format of the data tends to
56 vary based on the op-code that geerated the callback.
58 Data - A pointer to the data being sent to the original exporting driver.
64 BDS_COMMON_OPTION
*Option
;
67 EFI_HII_CALLBACK_PACKET
*DataPacket
;
70 // Initialize the key count
74 for (Link
= mBootOptionsList
->ForwardLink
; Link
!= mBootOptionsList
; Link
= Link
->ForwardLink
) {
75 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
82 // Is this device the one chosen?
84 if (KeyCount
== KeyValue
) {
86 // Assigning the returned Key to a global allows the original routine to know what was chosen
90 *Packet
= AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
91 ASSERT (*Packet
!= NULL
);
94 // Assign the buffer address to DataPacket
98 DataPacket
->DataArray
.EntryCount
= 1;
99 DataPacket
->DataArray
.NvRamMap
= NULL
;
100 ((EFI_IFR_DATA_ENTRY
*) (((EFI_IFR_DATA_ARRAY
*)DataPacket
) + 1))->Flags
= EXIT_REQUIRED
| NV_NOT_CHANGED
;
117 Hook to enable UI timeout override behavior.
120 BdsDeviceList - Device List that BDS needs to connect.
122 Entry - Pointer to current Boot Entry.
130 EFI_HII_PACKAGES
*PackageList
;
131 BDS_COMMON_OPTION
*Option
;
133 EFI_HII_UPDATE_DATA
*UpdateData
;
137 STRING_REF LastToken
;
141 LIST_ENTRY BdsBootOptionList
;
144 InitializeListHead (&BdsBootOptionList
);
147 // Connect all prior to entering the platform setup menu.
149 if (!gConnectAllHappened
) {
150 BdsLibConnectAllDriversToAllControllers ();
151 gConnectAllHappened
= TRUE
;
154 // BugBug: Here we can not remove the legacy refresh macro, so we need
155 // get the boot order every time from "BootOrder" variable.
156 // Recreate the boot option list base on the BootOrder variable
158 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
161 // This GUID must be the same as what is defined in BootManagerVfr.vfr
165 mBootOptionsList
= &BdsBootOptionList
;
168 // Post our VFR to the HII database
170 PackageList
= PreparePackages (2, &BmGuid
, BootManagerVfrBin
, BdsStrings
);
171 Status
= Hii
->NewPack (Hii
, PackageList
, &gBootManagerHandle
);
172 gBS
->FreePool (PackageList
);
175 // This example does not implement worker functions
176 // for the NV accessor functions. Only a callback evaluator
178 BootManagerCallback
.NvRead
= NULL
;
179 BootManagerCallback
.NvWrite
= NULL
;
180 BootManagerCallback
.Callback
= BootManagerCallbackRoutine
;
183 // Install protocol interface
185 BootManagerCallbackHandle
= NULL
;
186 Status
= gBS
->InstallProtocolInterface (
187 &BootManagerCallbackHandle
,
188 &gEfiFormCallbackProtocolGuid
,
189 EFI_NATIVE_INTERFACE
,
192 ASSERT_EFI_ERROR (Status
);
195 Hii
->NewString (Hii
, NULL
, gBootManagerHandle
, &LastToken
, L
" ");
198 // Allocate space for creation of UpdateData Buffer
200 UpdateData
= AllocateZeroPool (0x1000);
201 ASSERT (UpdateData
!= NULL
);
204 // Flag update pending in FormSet
206 UpdateData
->FormSetUpdate
= TRUE
;
208 // Register CallbackHandle data for FormSet
210 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) BootManagerCallbackHandle
;
211 UpdateData
->FormUpdate
= FALSE
;
212 UpdateData
->FormTitle
= 0;
213 UpdateData
->DataCount
= 1;
216 // Create blank space. Since when we update the contents of IFR data at a label, it is
217 // inserted at the location of the label. So if you want to add a string with an empty
218 // space afterwards, you need to add the space first and then the string like below.
220 Status
= CreateSubTitleOpCode (
221 LastToken
, // Token Value for the string
222 &UpdateData
->Data
// Buffer containing created op-code
225 Hii
->UpdateForm (Hii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0000, TRUE
, UpdateData
);
228 // Create "Boot Option Menu" title
230 Status
= CreateSubTitleOpCode (
231 STRING_TOKEN (STR_BOOT_OPTION_BANNER
), // Token Value for the string
232 &UpdateData
->Data
// Buffer containing created op-code
235 Hii
->UpdateForm (Hii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0000, TRUE
, UpdateData
);
240 UpdateData
->DataCount
= 0;
241 Location
= (UINT8
*) &UpdateData
->Data
;
243 for (Link
= BdsBootOptionList
.ForwardLink
; Link
!= &BdsBootOptionList
; Link
= Link
->ForwardLink
) {
244 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
247 // At this stage we are creating a menu entry, thus the Keys are reproduceable
252 Status
= Hii
->NewString (Hii
, NULL
, gBootManagerHandle
, &Token
, Option
->Description
);
255 // If we got an error it is almost certainly due to the token value being invalid.
256 // Therefore we will set the Token to 0 to automatically add a token.
258 if (EFI_ERROR (Status
)) {
260 Status
= Hii
->NewString (Hii
, NULL
, gBootManagerHandle
, &Token
, Option
->Description
);
263 Status
= CreateGotoOpCode (
265 Token
, // Token Value for the string
266 0, // Help String (none)
267 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
, // The Op-Code flags
268 mKeyInput
, // The Key to get a callback on
269 Location
// Buffer containing created op-code
272 UpdateData
->DataCount
++;
273 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
277 Hii
->UpdateForm (Hii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0001, TRUE
, UpdateData
);
279 UpdateData
->DataCount
= 1;
282 // Create "Boot Option Menu" title
284 Status
= CreateSubTitleOpCode (
285 STRING_TOKEN (STR_HELP_FOOTER
), // Token Value for the string
286 &UpdateData
->Data
// Buffer containing created op-code
289 Hii
->UpdateForm (Hii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
291 Status
= CreateSubTitleOpCode (
292 LastToken
, // Token Value for the string
293 &UpdateData
->Data
// Buffer containing created op-code
296 Hii
->UpdateForm (Hii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
298 gBS
->FreePool (UpdateData
);
302 gBrowser
->SendForm (gBrowser
, TRUE
, &gBootManagerHandle
, 1, NULL
, NULL
, NULL
, NULL
, NULL
);
304 Hii
->ResetStrings (Hii
, gBootManagerHandle
);
306 if (gOption
== NULL
) {
310 // BugBug: This code looks repeated from the BDS. Need to save code space.
314 // parse the selected option
316 Status
= BdsLibBootViaBootOption (gOption
, gOption
->DevicePath
, &ExitDataSize
, &ExitData
);
318 if (!EFI_ERROR (Status
)) {
319 PlatformBdsBootSuccess (gOption
);
321 PlatformBdsBootFail (gOption
, Status
, ExitData
, ExitDataSize
);
322 gST
->ConOut
->OutputString (
324 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE
))
328 // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
331 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);