3 Copyright (c) 2006 - 2007, 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
22 // Include common header file for this module.
24 #include "CommonHeader.h"
26 #include "BootManager.h"
29 LIST_ENTRY
*mBootOptionsList
;
30 BDS_COMMON_OPTION
*gOption
;
31 EFI_HII_HANDLE gBootManagerHandle
;
32 EFI_HANDLE BootManagerCallbackHandle
;
33 EFI_FORM_CALLBACK_PROTOCOL BootManagerCallback
;
34 EFI_GUID gBmGuid
= BOOT_MANAGER_GUID
;
36 extern EFI_FORM_BROWSER_PROTOCOL
*gBrowser
;
37 extern UINT8 BootManagerVfrBin
[];
38 extern BOOLEAN gConnectAllHappened
;
42 BootManagerCallbackRoutine (
43 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
45 IN EFI_IFR_DATA_ARRAY
*DataArray
,
46 OUT EFI_HII_CALLBACK_PACKET
**Packet
52 This is the function that is called to provide results data to the driver. This data
53 consists of a unique key which is used to identify what data is either being passed back
58 KeyValue - A unique value which is sent to the original exporting driver so that it
59 can identify the type of data to expect. The format of the data tends to
60 vary based on the op-code that geerated the callback.
62 Data - A pointer to the data being sent to the original exporting driver.
68 BDS_COMMON_OPTION
*Option
;
71 EFI_HII_CALLBACK_PACKET
*DataPacket
;
74 // Initialize the key count
78 for (Link
= mBootOptionsList
->ForwardLink
; Link
!= mBootOptionsList
; Link
= Link
->ForwardLink
) {
79 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
86 // Is this device the one chosen?
88 if (KeyCount
== KeyValue
) {
90 // Assigning the returned Key to a global allows the original routine to know what was chosen
94 *Packet
= AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET
) + 2);
95 ASSERT (*Packet
!= NULL
);
98 // Assign the buffer address to DataPacket
100 DataPacket
= *Packet
;
102 DataPacket
->DataArray
.EntryCount
= 1;
103 DataPacket
->DataArray
.NvRamMap
= NULL
;
104 ((EFI_IFR_DATA_ENTRY
*) (((EFI_IFR_DATA_ARRAY
*)DataPacket
) + 1))->Flags
= EXIT_REQUIRED
| NV_NOT_CHANGED
;
121 Hook to enable UI timeout override behavior.
124 BdsDeviceList - Device List that BDS needs to connect.
126 Entry - Pointer to current Boot Entry.
134 EFI_HII_PACKAGES
*PackageList
;
135 BDS_COMMON_OPTION
*Option
;
137 EFI_HII_UPDATE_DATA
*UpdateData
;
141 STRING_REF LastToken
;
145 LIST_ENTRY BdsBootOptionList
;
146 BOOLEAN BootMngrMenuResetRequired
;
149 InitializeListHead (&BdsBootOptionList
);
152 // Connect all prior to entering the platform setup menu.
154 if (!gConnectAllHappened
) {
155 BdsLibConnectAllDriversToAllControllers ();
156 gConnectAllHappened
= TRUE
;
159 // BugBug: Here we can not remove the legacy refresh macro, so we need
160 // get the boot order every time from "BootOrder" variable.
161 // Recreate the boot option list base on the BootOrder variable
163 BdsLibEnumerateAllBootOption (&BdsBootOptionList
);
166 // This GUID must be the same as what is defined in BootManagerVfr.vfr
170 mBootOptionsList
= &BdsBootOptionList
;
173 // Post our VFR to the HII database
175 PackageList
= PreparePackages (2, &BmGuid
, BootManagerVfrBin
, PlatformBdsStrings
);
176 Status
= gHii
->NewPack (gHii
, PackageList
, &gBootManagerHandle
);
177 FreePool (PackageList
);
180 // This example does not implement worker functions
181 // for the NV accessor functions. Only a callback evaluator
183 BootManagerCallback
.NvRead
= NULL
;
184 BootManagerCallback
.NvWrite
= NULL
;
185 BootManagerCallback
.Callback
= BootManagerCallbackRoutine
;
188 // Install protocol interface
190 BootManagerCallbackHandle
= NULL
;
191 Status
= gBS
->InstallProtocolInterface (
192 &BootManagerCallbackHandle
,
193 &gEfiFormCallbackProtocolGuid
,
194 EFI_NATIVE_INTERFACE
,
197 ASSERT_EFI_ERROR (Status
);
200 gHii
->NewString (gHii
, NULL
, gBootManagerHandle
, &LastToken
, L
" ");
203 // Allocate space for creation of UpdateData Buffer
205 UpdateData
= AllocateZeroPool (0x1000);
206 ASSERT (UpdateData
!= NULL
);
209 // Flag update pending in FormSet
211 UpdateData
->FormSetUpdate
= TRUE
;
213 // Register CallbackHandle data for FormSet
215 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) BootManagerCallbackHandle
;
216 UpdateData
->FormUpdate
= FALSE
;
217 UpdateData
->FormTitle
= 0;
218 UpdateData
->DataCount
= 1;
221 // Create blank space. Since when we update the contents of IFR data at a label, it is
222 // inserted at the location of the label. So if you want to add a string with an empty
223 // space afterwards, you need to add the space first and then the string like below.
225 Status
= CreateSubTitleOpCode (
226 LastToken
, // Token Value for the string
227 &UpdateData
->Data
// Buffer containing created op-code
230 gHii
->UpdateForm (gHii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0000, TRUE
, UpdateData
);
233 // Create "Boot Option Menu" title
235 Status
= CreateSubTitleOpCode (
236 STRING_TOKEN (STR_BOOT_OPTION_BANNER
), // Token Value for the string
237 &UpdateData
->Data
// Buffer containing created op-code
240 gHii
->UpdateForm (gHii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0000, TRUE
, UpdateData
);
245 UpdateData
->DataCount
= 0;
246 Location
= (UINT8
*) &UpdateData
->Data
;
248 for (Link
= BdsBootOptionList
.ForwardLink
; Link
!= &BdsBootOptionList
; Link
= Link
->ForwardLink
) {
249 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
252 // At this stage we are creating a menu entry, thus the Keys are reproduceable
257 Status
= gHii
->NewString (gHii
, NULL
, gBootManagerHandle
, &Token
, Option
->Description
);
260 // If we got an error it is almost certainly due to the token value being invalid.
261 // Therefore we will set the Token to 0 to automatically add a token.
263 if (EFI_ERROR (Status
)) {
265 Status
= gHii
->NewString (gHii
, NULL
, gBootManagerHandle
, &Token
, Option
->Description
);
268 Status
= CreateGotoOpCode (
270 Token
, // Token Value for the string
271 0, // Help String (none)
272 EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
, // The Op-Code flags
273 mKeyInput
, // The Key to get a callback on
274 Location
// Buffer containing created op-code
277 UpdateData
->DataCount
++;
278 Location
= Location
+ ((EFI_IFR_OP_HEADER
*) Location
)->Length
;
282 gHii
->UpdateForm (gHii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0001, TRUE
, UpdateData
);
284 UpdateData
->DataCount
= 1;
287 // Create "Boot Option Menu" title
289 Status
= CreateSubTitleOpCode (
290 STRING_TOKEN (STR_HELP_FOOTER
), // Token Value for the string
291 &UpdateData
->Data
// Buffer containing created op-code
294 gHii
->UpdateForm (gHii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
296 Status
= CreateSubTitleOpCode (
297 LastToken
, // Token Value for the string
298 &UpdateData
->Data
// Buffer containing created op-code
301 gHii
->UpdateForm (gHii
, gBootManagerHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
303 FreePool (UpdateData
);
307 BootMngrMenuResetRequired
= FALSE
;
317 &BootMngrMenuResetRequired
320 if (BootMngrMenuResetRequired
) {
321 EnableResetRequired ();
324 gHii
->ResetStrings (gHii
, gBootManagerHandle
);
326 if (gOption
== NULL
) {
331 //Will leave browser, check any reset required change is applied? if yes, reset system
333 SetupResetReminder ();
336 // BugBug: This code looks repeated from the BDS. Need to save code space.
340 // parse the selected option
342 Status
= BdsLibBootViaBootOption (gOption
, gOption
->DevicePath
, &ExitDataSize
, &ExitData
);
344 if (!EFI_ERROR (Status
)) {
345 PlatformBdsBootSuccess (gOption
);
347 PlatformBdsBootFail (gOption
, Status
, ExitData
, ExitDataSize
);
348 gST
->ConOut
->OutputString (
350 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE
))
354 // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
357 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);