]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/BdsDxe/BdsEntry.c
Code scrub for BdsDxe module.
[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
93e3992d 265\r
b30312ba 266 @param This - Protocol Instance structure.\r
93e3992d 267\r
b30312ba 268 @retval EFI_SUCEESS BDS->Entry has finished executing.\r
93e3992d 269\r
b30312ba 270**/\r
271VOID\r
272EFIAPI\r
273BdsEntry (\r
274 IN EFI_BDS_ARCH_PROTOCOL *This\r
275 )\r
93e3992d 276{\r
277 EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;\r
278 LIST_ENTRY DriverOptionList;\r
279 LIST_ENTRY BootOptionList;\r
280 UINTN BootNextSize;\r
281\r
282 //\r
283 // Insert the performance probe\r
284 //\r
285 PERF_END (0, DXE_TOK, NULL, 0);\r
286 PERF_START (0, BDS_TOK, NULL, 0);\r
287\r
288 //\r
289 // Initialize the global system boot option and driver option\r
290 //\r
291 InitializeListHead (&DriverOptionList);\r
292 InitializeListHead (&BootOptionList);\r
293\r
294 //\r
295 // Initialize hotkey service\r
296 //\r
297 InitializeHotkeyService ();\r
298\r
299 //\r
300 // Get the BDS private data\r
301 //\r
302 PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);\r
303\r
304 //\r
305 // Do the platform init, can be customized by OEM/IBV\r
306 //\r
307 PERF_START (0, "PlatformBds", "BDS", 0);\r
308 PlatformBdsInit (PrivateData);\r
309\r
310 if (FeaturePcdGet (PcdSupportHardwareErrorRecord)) {\r
311 InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel));\r
312 }\r
313 //\r
314 // bugbug: platform specific code\r
315 // Initialize the platform specific string and language\r
316 //\r
317 InitializeStringSupport ();\r
318 InitializeLanguage (TRUE);\r
b30312ba 319 InitializeFrontPage (TRUE);\r
93e3992d 320\r
321 //\r
322 // Set up the device list based on EFI 1.1 variables\r
323 // process Driver#### and Load the driver's in the\r
324 // driver option list\r
325 //\r
326 BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");\r
327 if (!IsListEmpty (&DriverOptionList)) {\r
328 BdsLibLoadDrivers (&DriverOptionList);\r
329 }\r
330 //\r
331 // Check if we have the boot next option\r
332 //\r
333 mBootNext = BdsLibGetVariableAndSize (\r
334 L"BootNext",\r
335 &gEfiGlobalVariableGuid,\r
336 &BootNextSize\r
337 );\r
338\r
339 //\r
340 // Setup some platform policy here\r
341 //\r
342 PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);\r
343 PERF_END (0, "PlatformBds", "BDS", 0);\r
344\r
345 //\r
346 // BDS select the boot device to load OS\r
347 //\r
348 BdsBootDeviceSelect ();\r
349\r
350 //\r
351 // Only assert here since this is the right behavior, we should never\r
352 // return back to DxeCore.\r
353 //\r
354 ASSERT (FALSE);\r
355\r
356 return ;\r
357}\r