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