]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/BdsDxe/BdsEntry.c
Clean up BdsDxe for Doxygen comments requirement.
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / BdsEntry.c
1 /** @file
2 The entry of the bds
3
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
9
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.
12
13 **/
14
15 #include "Bds.h"
16 #include "Language.h"
17 #include "FrontPage.h"
18 #include "Hotkey.h"
19 #include "HwErrRecSupport.h"
20
21
22 EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate = {
23 EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE,
24 NULL,
25 {BdsEntry},
26 0xFFFF,
27 TRUE,
28 EXTENSIVE
29 };
30
31 UINT16 *mBootNext = NULL;
32
33 EFI_HANDLE mBdsImageHandle;
34
35 /**
36
37 Install Boot Device Selection Protocol
38
39
40 @param ImageHandle The image handle.
41 @param SystemTable The system table.
42
43 @retval EFI_SUCEESS BDS has finished initializing.
44 Rerun the
45 dispatcher and recall BDS.Entry
46 @retval Other Return value from AllocatePool()
47 or gBS->InstallProtocolInterface
48
49 **/
50 EFI_STATUS
51 EFIAPI
52 BdsInitialize (
53 IN EFI_HANDLE ImageHandle,
54 IN EFI_SYSTEM_TABLE *SystemTable
55 )
56 {
57 EFI_STATUS Status;
58
59 mBdsImageHandle = ImageHandle;
60
61 //
62 // Install protocol interface
63 //
64 Status = gBS->InstallProtocolInterface (
65 &gBdsInstanceTemplate.Handle,
66 &gEfiBdsArchProtocolGuid,
67 EFI_NATIVE_INTERFACE,
68 &gBdsInstanceTemplate.Bds
69 );
70 ASSERT_EFI_ERROR (Status);
71
72 return Status;
73 }
74
75 /**
76
77 This function attempts to boot for the boot order specified
78 by platform policy.
79
80 **/
81 VOID
82 BdsBootDeviceSelect (
83 VOID
84 )
85 {
86 EFI_STATUS Status;
87 LIST_ENTRY *Link;
88 BDS_COMMON_OPTION *BootOption;
89 UINTN ExitDataSize;
90 CHAR16 *ExitData;
91 UINT16 Timeout;
92 LIST_ENTRY BootLists;
93 CHAR16 Buffer[20];
94 BOOLEAN BootNextExist;
95 LIST_ENTRY *LinkBootNext;
96
97 //
98 // Got the latest boot option
99 //
100 BootNextExist = FALSE;
101 LinkBootNext = NULL;
102 InitializeListHead (&BootLists);
103
104 //
105 // First check the boot next option
106 //
107 ZeroMem (Buffer, sizeof (Buffer));
108
109 if (mBootNext != NULL) {
110 //
111 // Indicate we have the boot next variable, so this time
112 // boot will always have this boot option
113 //
114 BootNextExist = TRUE;
115
116 //
117 // Clear the this variable so it's only exist in this time boot
118 //
119 gRT->SetVariable (
120 L"BootNext",
121 &gEfiGlobalVariableGuid,
122 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
123 0,
124 mBootNext
125 );
126
127 //
128 // Add the boot next boot option
129 //
130 UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);
131 BootOption = BdsLibVariableToOption (&BootLists, Buffer);
132 BootOption->BootCurrent = *mBootNext;
133 }
134 //
135 // Parse the boot order to get boot option
136 //
137 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
138 Link = BootLists.ForwardLink;
139
140 //
141 // Parameter check, make sure the loop will be valid
142 //
143 if (Link == NULL) {
144 return ;
145 }
146 //
147 // Here we make the boot in a loop, every boot success will
148 // return to the front page
149 //
150 for (;;) {
151 //
152 // Check the boot option list first
153 //
154 if (Link == &BootLists) {
155 //
156 // There are two ways to enter here:
157 // 1. There is no active boot option, give user chance to
158 // add new boot option
159 // 2. All the active boot option processed, and there is no
160 // one is success to boot, then we back here to allow user
161 // add new active boot option
162 //
163 Timeout = 0xffff;
164 PlatformBdsEnterFrontPage (Timeout, FALSE);
165 InitializeListHead (&BootLists);
166 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
167 Link = BootLists.ForwardLink;
168 continue;
169 }
170 //
171 // Get the boot option from the link list
172 //
173 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
174
175 //
176 // According to EFI Specification, if a load option is not marked
177 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically
178 // load the option.
179 //
180 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {
181 //
182 // skip the header of the link list, becuase it has no boot option
183 //
184 Link = Link->ForwardLink;
185 continue;
186 }
187 //
188 // Make sure the boot option device path connected,
189 // but ignore the BBS device path
190 //
191 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {
192 //
193 // Notes: the internal shell can not been connected with device path
194 // so we do not check the status here
195 //
196 BdsLibConnectDevicePath (BootOption->DevicePath);
197 }
198 //
199 // All the driver options should have been processed since
200 // now boot will be performed.
201 //
202 Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
203 if (EFI_ERROR (Status)) {
204 //
205 // Call platform action to indicate the boot fail
206 //
207 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
208 PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);
209
210 //
211 // Check the next boot option
212 //
213 Link = Link->ForwardLink;
214
215 } else {
216 //
217 // Call platform action to indicate the boot success
218 //
219 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
220 PlatformBdsBootSuccess (BootOption);
221
222 //
223 // Boot success, then stop process the boot order, and
224 // present the boot manager menu, front page
225 //
226 Timeout = 0xffff;
227 PlatformBdsEnterFrontPage (Timeout, FALSE);
228
229 //
230 // Rescan the boot option list, avoid pertential risk of the boot
231 // option change in front page
232 //
233 if (BootNextExist) {
234 LinkBootNext = BootLists.ForwardLink;
235 }
236
237 InitializeListHead (&BootLists);
238 if (LinkBootNext != NULL) {
239 //
240 // Reserve the boot next option
241 //
242 InsertTailList (&BootLists, LinkBootNext);
243 }
244
245 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
246 Link = BootLists.ForwardLink;
247 }
248 }
249
250 }
251
252 /**
253
254 Service routine for BdsInstance->Entry(). Devices are connected, the
255 consoles are initialized, and the boot options are tried.
256
257
258 @param This - Protocol Instance structure.
259
260 @retval EFI_SUCEESS BDS->Entry has finished executing.
261
262 **/
263 VOID
264 EFIAPI
265 BdsEntry (
266 IN EFI_BDS_ARCH_PROTOCOL *This
267 )
268 {
269 EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;
270 LIST_ENTRY DriverOptionList;
271 LIST_ENTRY BootOptionList;
272 UINTN BootNextSize;
273
274 //
275 // Insert the performance probe
276 //
277 PERF_END (0, DXE_TOK, NULL, 0);
278 PERF_START (0, BDS_TOK, NULL, 0);
279
280 //
281 // Initialize the global system boot option and driver option
282 //
283 InitializeListHead (&DriverOptionList);
284 InitializeListHead (&BootOptionList);
285
286 //
287 // Initialize hotkey service
288 //
289 InitializeHotkeyService ();
290
291 //
292 // Get the BDS private data
293 //
294 PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);
295
296 //
297 // Do the platform init, can be customized by OEM/IBV
298 //
299 PERF_START (0, "PlatformBds", "BDS", 0);
300 PlatformBdsInit (PrivateData);
301
302 if (FeaturePcdGet (PcdSupportHardwareErrorRecord)) {
303 InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel));
304 }
305 //
306 // bugbug: platform specific code
307 // Initialize the platform specific string and language
308 //
309 InitializeStringSupport ();
310 InitializeLanguage (TRUE);
311 InitializeFrontPage (TRUE);
312
313 //
314 // Set up the device list based on EFI 1.1 variables
315 // process Driver#### and Load the driver's in the
316 // driver option list
317 //
318 BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");
319 if (!IsListEmpty (&DriverOptionList)) {
320 BdsLibLoadDrivers (&DriverOptionList);
321 }
322 //
323 // Check if we have the boot next option
324 //
325 mBootNext = BdsLibGetVariableAndSize (
326 L"BootNext",
327 &gEfiGlobalVariableGuid,
328 &BootNextSize
329 );
330
331 //
332 // Setup some platform policy here
333 //
334 PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);
335 PERF_END (0, "PlatformBds", "BDS", 0);
336
337 //
338 // BDS select the boot device to load OS
339 //
340 BdsBootDeviceSelect ();
341
342 //
343 // Only assert here since this is the right behavior, we should never
344 // return back to DxeCore.
345 //
346 ASSERT (FALSE);
347
348 return ;
349 }