3 Copyright (c) 2004 - 2008, 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.
24 #include "FrontPage.h"
26 #include "HwErrRecSupport.h"
29 EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate
= {
30 EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE
,
38 UINT16
*mBootNext
= NULL
;
40 EFI_HANDLE mBdsImageHandle
;
45 IN EFI_HANDLE ImageHandle
,
46 IN EFI_SYSTEM_TABLE
*SystemTable
52 Install Boot Device Selection Protocol
56 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
60 EFI_SUCEESS - BDS has finished initializing.
62 dispatcher and recall BDS.Entry
64 Other - Return value from AllocatePool()
65 or gBS->InstallProtocolInterface
71 mBdsImageHandle
= ImageHandle
;
74 // Install protocol interface
76 Status
= gBS
->InstallProtocolInterface (
77 &gBdsInstanceTemplate
.Handle
,
78 &gEfiBdsArchProtocolGuid
,
80 &gBdsInstanceTemplate
.Bds
82 ASSERT_EFI_ERROR (Status
);
95 In the loop of attempt to boot for the boot order
109 BDS_COMMON_OPTION
*BootOption
;
113 LIST_ENTRY BootLists
;
115 BOOLEAN BootNextExist
;
116 LIST_ENTRY
*LinkBootNext
;
119 // Got the latest boot option
121 BootNextExist
= FALSE
;
123 InitializeListHead (&BootLists
);
126 // First check the boot next option
128 ZeroMem (Buffer
, sizeof (Buffer
));
130 if (mBootNext
!= NULL
) {
132 // Indicate we have the boot next variable, so this time
133 // boot will always have this boot option
135 BootNextExist
= TRUE
;
138 // Clear the this variable so it's only exist in this time boot
142 &gEfiGlobalVariableGuid
,
143 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
149 // Add the boot next boot option
151 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *mBootNext
);
152 BootOption
= BdsLibVariableToOption (&BootLists
, Buffer
);
153 BootOption
->BootCurrent
= *mBootNext
;
156 // Parse the boot order to get boot option
158 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
159 Link
= BootLists
.ForwardLink
;
162 // Parameter check, make sure the loop will be valid
168 // Here we make the boot in a loop, every boot success will
169 // return to the front page
173 // Check the boot option list first
175 if (Link
== &BootLists
) {
177 // There are two ways to enter here:
178 // 1. There is no active boot option, give user chance to
179 // add new boot option
180 // 2. All the active boot option processed, and there is no
181 // one is success to boot, then we back here to allow user
182 // add new active boot option
185 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
186 InitializeListHead (&BootLists
);
187 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
188 Link
= BootLists
.ForwardLink
;
192 // Get the boot option from the link list
194 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
197 // According to EFI Specification, if a load option is not marked
198 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically
201 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
203 // skip the header of the link list, becuase it has no boot option
205 Link
= Link
->ForwardLink
;
209 // Make sure the boot option device path connected,
210 // but ignore the BBS device path
212 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
214 // Notes: the internal shell can not been connected with device path
215 // so we do not check the status here
217 BdsLibConnectDevicePath (BootOption
->DevicePath
);
220 // All the driver options should have been processed since
221 // now boot will be performed.
223 Status
= BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);
224 if (EFI_ERROR (Status
)) {
226 // Call platform action to indicate the boot fail
228 BootOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_FAILED
));
229 PlatformBdsBootFail (BootOption
, Status
, ExitData
, ExitDataSize
);
232 // Check the next boot option
234 Link
= Link
->ForwardLink
;
238 // Call platform action to indicate the boot success
240 BootOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED
));
241 PlatformBdsBootSuccess (BootOption
);
244 // Boot success, then stop process the boot order, and
245 // present the boot manager menu, front page
248 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
251 // Rescan the boot option list, avoid pertential risk of the boot
252 // option change in front page
255 LinkBootNext
= BootLists
.ForwardLink
;
258 InitializeListHead (&BootLists
);
259 if (LinkBootNext
!= NULL
) {
261 // Reserve the boot next option
263 InsertTailList (&BootLists
, LinkBootNext
);
266 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
267 Link
= BootLists
.ForwardLink
;
276 IN EFI_BDS_ARCH_PROTOCOL
*This
282 Service routine for BdsInstance->Entry(). Devices are connected, the
283 consoles are initialized, and the boot options are tried.
287 This - Protocol Instance structure.
291 EFI_SUCEESS - BDS->Entry has finished executing.
295 EFI_BDS_ARCH_PROTOCOL_INSTANCE
*PrivateData
;
296 LIST_ENTRY DriverOptionList
;
297 LIST_ENTRY BootOptionList
;
301 // Insert the performance probe
303 PERF_END (0, DXE_TOK
, NULL
, 0);
304 PERF_START (0, BDS_TOK
, NULL
, 0);
307 // Initialize the global system boot option and driver option
309 InitializeListHead (&DriverOptionList
);
310 InitializeListHead (&BootOptionList
);
313 // Initialize hotkey service
315 InitializeHotkeyService ();
318 // Get the BDS private data
320 PrivateData
= EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This
);
323 // Do the platform init, can be customized by OEM/IBV
325 PERF_START (0, "PlatformBds", "BDS", 0);
326 PlatformBdsInit (PrivateData
);
328 if (FeaturePcdGet (PcdSupportHardwareErrorRecord
)) {
329 InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel
));
332 // bugbug: platform specific code
333 // Initialize the platform specific string and language
335 InitializeStringSupport ();
336 InitializeLanguage (TRUE
);
337 InitializeFrontPage (FALSE
);
340 // Set up the device list based on EFI 1.1 variables
341 // process Driver#### and Load the driver's in the
342 // driver option list
344 BdsLibBuildOptionFromVar (&DriverOptionList
, L
"DriverOrder");
345 if (!IsListEmpty (&DriverOptionList
)) {
346 BdsLibLoadDrivers (&DriverOptionList
);
349 // Check if we have the boot next option
351 mBootNext
= BdsLibGetVariableAndSize (
353 &gEfiGlobalVariableGuid
,
358 // Setup some platform policy here
360 PlatformBdsPolicyBehavior (PrivateData
, &DriverOptionList
, &BootOptionList
);
361 PERF_END (0, "PlatformBds", "BDS", 0);
364 // BDS select the boot device to load OS
366 BdsBootDeviceSelect ();
369 // Only assert here since this is the right behavior, we should never
370 // return back to DxeCore.