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