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.
17 #include "FrontPage.h"
19 #include "HwErrRecSupport.h"
22 EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate
= {
23 EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE
,
31 UINT16
*mBootNext
= NULL
;
33 EFI_HANDLE mBdsImageHandle
;
38 IN EFI_HANDLE ImageHandle
,
39 IN EFI_SYSTEM_TABLE
*SystemTable
45 Install Boot Device Selection Protocol
49 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
53 EFI_SUCEESS - BDS has finished initializing.
55 dispatcher and recall BDS.Entry
57 Other - Return value from AllocatePool()
58 or gBS->InstallProtocolInterface
64 mBdsImageHandle
= ImageHandle
;
67 // Install protocol interface
69 Status
= gBS
->InstallProtocolInterface (
70 &gBdsInstanceTemplate
.Handle
,
71 &gEfiBdsArchProtocolGuid
,
73 &gBdsInstanceTemplate
.Bds
75 ASSERT_EFI_ERROR (Status
);
88 In the loop of attempt to boot for the boot order
102 BDS_COMMON_OPTION
*BootOption
;
106 LIST_ENTRY BootLists
;
108 BOOLEAN BootNextExist
;
109 LIST_ENTRY
*LinkBootNext
;
112 // Got the latest boot option
114 BootNextExist
= FALSE
;
116 InitializeListHead (&BootLists
);
119 // First check the boot next option
121 ZeroMem (Buffer
, sizeof (Buffer
));
123 if (mBootNext
!= NULL
) {
125 // Indicate we have the boot next variable, so this time
126 // boot will always have this boot option
128 BootNextExist
= TRUE
;
131 // Clear the this variable so it's only exist in this time boot
135 &gEfiGlobalVariableGuid
,
136 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
142 // Add the boot next boot option
144 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *mBootNext
);
145 BootOption
= BdsLibVariableToOption (&BootLists
, Buffer
);
146 BootOption
->BootCurrent
= *mBootNext
;
149 // Parse the boot order to get boot option
151 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
152 Link
= BootLists
.ForwardLink
;
155 // Parameter check, make sure the loop will be valid
161 // Here we make the boot in a loop, every boot success will
162 // return to the front page
166 // Check the boot option list first
168 if (Link
== &BootLists
) {
170 // There are two ways to enter here:
171 // 1. There is no active boot option, give user chance to
172 // add new boot option
173 // 2. All the active boot option processed, and there is no
174 // one is success to boot, then we back here to allow user
175 // add new active boot option
178 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
179 InitializeListHead (&BootLists
);
180 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
181 Link
= BootLists
.ForwardLink
;
185 // Get the boot option from the link list
187 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
190 // According to EFI Specification, if a load option is not marked
191 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically
194 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
196 // skip the header of the link list, becuase it has no boot option
198 Link
= Link
->ForwardLink
;
202 // Make sure the boot option device path connected,
203 // but ignore the BBS device path
205 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
207 // Notes: the internal shell can not been connected with device path
208 // so we do not check the status here
210 BdsLibConnectDevicePath (BootOption
->DevicePath
);
213 // All the driver options should have been processed since
214 // now boot will be performed.
216 Status
= BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);
217 if (EFI_ERROR (Status
)) {
219 // Call platform action to indicate the boot fail
221 BootOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_FAILED
));
222 PlatformBdsBootFail (BootOption
, Status
, ExitData
, ExitDataSize
);
225 // Check the next boot option
227 Link
= Link
->ForwardLink
;
231 // Call platform action to indicate the boot success
233 BootOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED
));
234 PlatformBdsBootSuccess (BootOption
);
237 // Boot success, then stop process the boot order, and
238 // present the boot manager menu, front page
241 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
244 // Rescan the boot option list, avoid pertential risk of the boot
245 // option change in front page
248 LinkBootNext
= BootLists
.ForwardLink
;
251 InitializeListHead (&BootLists
);
252 if (LinkBootNext
!= NULL
) {
254 // Reserve the boot next option
256 InsertTailList (&BootLists
, LinkBootNext
);
259 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
260 Link
= BootLists
.ForwardLink
;
269 IN EFI_BDS_ARCH_PROTOCOL
*This
275 Service routine for BdsInstance->Entry(). Devices are connected, the
276 consoles are initialized, and the boot options are tried.
280 This - Protocol Instance structure.
284 EFI_SUCEESS - BDS->Entry has finished executing.
288 EFI_BDS_ARCH_PROTOCOL_INSTANCE
*PrivateData
;
289 LIST_ENTRY DriverOptionList
;
290 LIST_ENTRY BootOptionList
;
294 // Insert the performance probe
296 PERF_END (0, DXE_TOK
, NULL
, 0);
297 PERF_START (0, BDS_TOK
, NULL
, 0);
300 // Initialize the global system boot option and driver option
302 InitializeListHead (&DriverOptionList
);
303 InitializeListHead (&BootOptionList
);
306 // Initialize hotkey service
308 InitializeHotkeyService ();
311 // Get the BDS private data
313 PrivateData
= EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This
);
316 // Do the platform init, can be customized by OEM/IBV
318 PERF_START (0, "PlatformBds", "BDS", 0);
319 PlatformBdsInit (PrivateData
);
321 if (FeaturePcdGet (PcdSupportHardwareErrorRecord
)) {
322 InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel
));
325 // bugbug: platform specific code
326 // Initialize the platform specific string and language
328 InitializeStringSupport ();
329 InitializeLanguage (TRUE
);
330 InitializeFrontPage (FALSE
);
333 // Set up the device list based on EFI 1.1 variables
334 // process Driver#### and Load the driver's in the
335 // driver option list
337 BdsLibBuildOptionFromVar (&DriverOptionList
, L
"DriverOrder");
338 if (!IsListEmpty (&DriverOptionList
)) {
339 BdsLibLoadDrivers (&DriverOptionList
);
342 // Check if we have the boot next option
344 mBootNext
= BdsLibGetVariableAndSize (
346 &gEfiGlobalVariableGuid
,
351 // Setup some platform policy here
353 PlatformBdsPolicyBehavior (PrivateData
, &DriverOptionList
, &BootOptionList
);
354 PERF_END (0, "PlatformBds", "BDS", 0);
357 // BDS select the boot device to load OS
359 BdsBootDeviceSelect ();
362 // Only assert here since this is the right behavior, we should never
363 // return back to DxeCore.