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