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 /// BDS arch protocol instance initial value.
24 /// Note: Current BDS not directly get the BootMode, DefaultBoot,
25 /// TimeoutDefault, MemoryTestLevel value from the BDS arch protocol.
26 /// Please refer to the library useage of BdsLibGetBootMode, BdsLibGetTimeout
27 /// and PlatformBdsDiagnostics in BdsPlatform.c
29 EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate
= {
30 EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE
,
39 UINT16
*mBootNext
= NULL
;
41 EFI_HANDLE mBdsImageHandle
;
45 Install Boot Device Selection Protocol
48 @param ImageHandle The image handle.
49 @param SystemTable The system table.
51 @retval EFI_SUCEESS BDS has finished initializing.
53 dispatcher and recall BDS.Entry
54 @retval Other Return value from AllocatePool()
55 or gBS->InstallProtocolInterface
61 IN EFI_HANDLE ImageHandle
,
62 IN EFI_SYSTEM_TABLE
*SystemTable
67 mBdsImageHandle
= ImageHandle
;
70 // Install protocol interface
72 Status
= gBS
->InstallProtocolInterface (
73 &gBdsInstanceTemplate
.Handle
,
74 &gEfiBdsArchProtocolGuid
,
76 &gBdsInstanceTemplate
.Bds
78 ASSERT_EFI_ERROR (Status
);
85 This function attempts to boot for the boot order specified
96 BDS_COMMON_OPTION
*BootOption
;
100 LIST_ENTRY BootLists
;
102 BOOLEAN BootNextExist
;
103 LIST_ENTRY
*LinkBootNext
;
106 // Got the latest boot option
108 BootNextExist
= FALSE
;
110 InitializeListHead (&BootLists
);
113 // First check the boot next option
115 ZeroMem (Buffer
, sizeof (Buffer
));
117 if (mBootNext
!= NULL
) {
119 // Indicate we have the boot next variable, so this time
120 // boot will always have this boot option
122 BootNextExist
= TRUE
;
125 // Clear the this variable so it's only exist in this time boot
129 &gEfiGlobalVariableGuid
,
130 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
136 // Add the boot next boot option
138 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"Boot%04x", *mBootNext
);
139 BootOption
= BdsLibVariableToOption (&BootLists
, Buffer
);
140 BootOption
->BootCurrent
= *mBootNext
;
143 // Parse the boot order to get boot option
145 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
146 Link
= BootLists
.ForwardLink
;
149 // Parameter check, make sure the loop will be valid
155 // Here we make the boot in a loop, every boot success will
156 // return to the front page
160 // Check the boot option list first
162 if (Link
== &BootLists
) {
164 // There are two ways to enter here:
165 // 1. There is no active boot option, give user chance to
166 // add new boot option
167 // 2. All the active boot option processed, and there is no
168 // one is success to boot, then we back here to allow user
169 // add new active boot option
172 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
173 InitializeListHead (&BootLists
);
174 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
175 Link
= BootLists
.ForwardLink
;
179 // Get the boot option from the link list
181 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
184 // According to EFI Specification, if a load option is not marked
185 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically
188 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
190 // skip the header of the link list, becuase it has no boot option
192 Link
= Link
->ForwardLink
;
196 // Make sure the boot option device path connected,
197 // but ignore the BBS device path
199 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
201 // Notes: the internal shell can not been connected with device path
202 // so we do not check the status here
204 BdsLibConnectDevicePath (BootOption
->DevicePath
);
207 // All the driver options should have been processed since
208 // now boot will be performed.
210 Status
= BdsLibBootViaBootOption (BootOption
, BootOption
->DevicePath
, &ExitDataSize
, &ExitData
);
211 if (EFI_ERROR (Status
)) {
213 // Call platform action to indicate the boot fail
215 BootOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_FAILED
));
216 PlatformBdsBootFail (BootOption
, Status
, ExitData
, ExitDataSize
);
219 // Check the next boot option
221 Link
= Link
->ForwardLink
;
225 // Call platform action to indicate the boot success
227 BootOption
->StatusString
= GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED
));
228 PlatformBdsBootSuccess (BootOption
);
231 // Boot success, then stop process the boot order, and
232 // present the boot manager menu, front page
235 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
238 // Rescan the boot option list, avoid pertential risk of the boot
239 // option change in front page
242 LinkBootNext
= BootLists
.ForwardLink
;
245 InitializeListHead (&BootLists
);
246 if (LinkBootNext
!= NULL
) {
248 // Reserve the boot next option
250 InsertTailList (&BootLists
, LinkBootNext
);
253 BdsLibBuildOptionFromVar (&BootLists
, L
"BootOrder");
254 Link
= BootLists
.ForwardLink
;
262 Service routine for BdsInstance->Entry(). Devices are connected, the
263 consoles are initialized, and the boot options are tried.
265 @param This - Protocol Instance structure.
271 IN EFI_BDS_ARCH_PROTOCOL
*This
274 EFI_BDS_ARCH_PROTOCOL_INSTANCE
*PrivateData
;
275 LIST_ENTRY DriverOptionList
;
276 LIST_ENTRY BootOptionList
;
280 // Insert the performance probe
282 PERF_END (0, DXE_TOK
, NULL
, 0);
283 PERF_START (0, BDS_TOK
, NULL
, 0);
286 // Initialize the global system boot option and driver option
288 InitializeListHead (&DriverOptionList
);
289 InitializeListHead (&BootOptionList
);
292 // Initialize hotkey service
294 InitializeHotkeyService ();
297 // Get the BDS private data
299 PrivateData
= EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This
);
302 // Do the platform init, can be customized by OEM/IBV
304 PERF_START (0, "PlatformBds", "BDS", 0);
305 PlatformBdsInit (PrivateData
);
307 if (FeaturePcdGet (PcdSupportHardwareErrorRecord
)) {
308 InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel
));
311 // bugbug: platform specific code
312 // Initialize the platform specific string and language
314 InitializeStringSupport ();
315 InitializeLanguage (TRUE
);
316 InitializeFrontPage (TRUE
);
319 // Set up the device list based on EFI 1.1 variables
320 // process Driver#### and Load the driver's in the
321 // driver option list
323 BdsLibBuildOptionFromVar (&DriverOptionList
, L
"DriverOrder");
324 if (!IsListEmpty (&DriverOptionList
)) {
325 BdsLibLoadDrivers (&DriverOptionList
);
328 // Check if we have the boot next option
330 mBootNext
= BdsLibGetVariableAndSize (
332 &gEfiGlobalVariableGuid
,
337 // Setup some platform policy here
339 PlatformBdsPolicyBehavior (PrivateData
, &DriverOptionList
, &BootOptionList
);
340 PERF_END (0, "PlatformBds", "BDS", 0);
343 // BDS select the boot device to load OS
345 BdsBootDeviceSelect ();
348 // Only assert here since this is the right behavior, we should never
349 // return back to DxeCore.