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