]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c
1. Update Generic BDS part to use dynamic PCD to set console output mode instead...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BdsEntry.c
CommitLineData
5c08e117 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_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
39 0,\r
40 EXTENSIVE\r
41};\r
42\r
43UINT16 *mBootNext = NULL;\r
44\r
45EFI_HANDLE mBdsImageHandle;\r
46\r
47/**\r
48\r
49 Install Boot Device Selection Protocol\r
50\r
51 @param ImageHandle The image handle.\r
52 @param SystemTable The system table.\r
53\r
54 @retval EFI_SUCEESS BDS has finished initializing.\r
55 Return the dispatcher and recall BDS.Entry\r
56 @retval Other Return status from AllocatePool() or gBS->InstallProtocolInterface\r
57\r
58**/\r
59EFI_STATUS\r
60EFIAPI\r
61BdsInitialize (\r
62 IN EFI_HANDLE ImageHandle,\r
63 IN EFI_SYSTEM_TABLE *SystemTable\r
64 )\r
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
84/**\r
85\r
86 This function attempts to boot for the boot order specified\r
87 by platform policy.\r
88\r
89**/\r
90VOID\r
91BdsBootDeviceSelect (\r
92 VOID\r
93 )\r
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 \r
142 //\r
143 // If fail to get boot option from variable, just return and do nothing.\r
144 //\r
145 if (BootOption == NULL) {\r
146 return;\r
147 }\r
148 \r
149 BootOption->BootCurrent = *mBootNext;\r
150 }\r
151 //\r
152 // Parse the boot order to get boot option\r
153 //\r
154 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
155 Link = BootLists.ForwardLink;\r
156\r
157 //\r
158 // Parameter check, make sure the loop will be valid\r
159 //\r
160 if (Link == NULL) {\r
161 return ;\r
162 }\r
163 //\r
164 // Here we make the boot in a loop, every boot success will\r
165 // return to the front page\r
166 //\r
167 for (;;) {\r
168 //\r
169 // Check the boot option list first\r
170 //\r
171 if (Link == &BootLists) {\r
172 //\r
173 // There are two ways to enter here:\r
174 // 1. There is no active boot option, give user chance to\r
175 // add new boot option\r
176 // 2. All the active boot option processed, and there is no\r
177 // one is success to boot, then we back here to allow user\r
178 // add new active boot option\r
179 //\r
180 Timeout = 0xffff;\r
181 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
182 InitializeListHead (&BootLists);\r
183 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
184 Link = BootLists.ForwardLink;\r
185 continue;\r
186 }\r
187 //\r
188 // Get the boot option from the link list\r
189 //\r
190 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
191\r
192 //\r
193 // According to EFI Specification, if a load option is not marked\r
194 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically\r
195 // load the option.\r
196 //\r
197 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
198 //\r
199 // skip the header of the link list, becuase it has no boot option\r
200 //\r
201 Link = Link->ForwardLink;\r
202 continue;\r
203 }\r
204 //\r
205 // Make sure the boot option device path connected,\r
206 // but ignore the BBS device path\r
207 //\r
208 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
209 //\r
210 // Notes: the internal shell can not been connected with device path\r
211 // so we do not check the status here\r
212 //\r
213 BdsLibConnectDevicePath (BootOption->DevicePath);\r
214 }\r
215 //\r
216 // All the driver options should have been processed since\r
217 // now boot will be performed.\r
218 //\r
219 Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);\r
220 if (EFI_ERROR (Status)) {\r
221 //\r
222 // Call platform action to indicate the boot fail\r
223 //\r
224 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));\r
225 PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);\r
226\r
227 //\r
228 // Check the next boot option\r
229 //\r
230 Link = Link->ForwardLink;\r
231\r
232 } else {\r
233 //\r
234 // Call platform action to indicate the boot success\r
235 //\r
236 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); \r
237 PlatformBdsBootSuccess (BootOption);\r
238\r
239 //\r
240 // Boot success, then stop process the boot order, and\r
241 // present the boot manager menu, front page\r
242 //\r
243 Timeout = 0xffff;\r
244 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
245\r
246 //\r
247 // Rescan the boot option list, avoid pertential risk of the boot\r
248 // option change in front page\r
249 //\r
250 if (BootNextExist) {\r
251 LinkBootNext = BootLists.ForwardLink;\r
252 }\r
253\r
254 InitializeListHead (&BootLists);\r
255 if (LinkBootNext != NULL) {\r
256 //\r
257 // Reserve the boot next option\r
258 //\r
259 InsertTailList (&BootLists, LinkBootNext);\r
260 }\r
261\r
262 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
263 Link = BootLists.ForwardLink;\r
264 }\r
265 }\r
266\r
267}\r
268\r
269/**\r
270\r
271 Service routine for BdsInstance->Entry(). Devices are connected, the\r
272 consoles are initialized, and the boot options are tried.\r
273\r
274 @param This Protocol Instance structure.\r
275\r
276**/\r
277VOID\r
278EFIAPI\r
279BdsEntry (\r
280 IN EFI_BDS_ARCH_PROTOCOL *This\r
281 )\r
282{\r
283 EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;\r
284 LIST_ENTRY DriverOptionList;\r
285 LIST_ENTRY BootOptionList;\r
286 UINTN BootNextSize;\r
287\r
288 //\r
289 // Insert the performance probe\r
290 //\r
6aa22a17 291 PERF_END (0, "DXE", NULL, 0);\r
292 PERF_START (0, "BDS", NULL, 0);\r
5c08e117 293\r
294 //\r
295 // Initialize the global system boot option and driver option\r
296 //\r
297 InitializeListHead (&DriverOptionList);\r
298 InitializeListHead (&BootOptionList);\r
299\r
300 //\r
301 // Initialize hotkey service\r
302 //\r
303 InitializeHotkeyService ();\r
304\r
305 //\r
306 // Get the BDS private data\r
307 //\r
308 PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);\r
309\r
310 //\r
311 // Do the platform init, can be customized by OEM/IBV\r
312 //\r
313 PERF_START (0, "PlatformBds", "BDS", 0);\r
314 PlatformBdsInit (PrivateData);\r
315\r
316 if (FeaturePcdGet (PcdSupportHardwareErrorRecord)) {\r
317 InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel));\r
318 }\r
319 //\r
320 // bugbug: platform specific code\r
321 // Initialize the platform specific string and language\r
322 //\r
323 InitializeStringSupport ();\r
324 InitializeLanguage (TRUE);\r
325 InitializeFrontPage (TRUE);\r
326\r
327 //\r
328 // Set up the device list based on EFI 1.1 variables\r
329 // process Driver#### and Load the driver's in the\r
330 // driver option list\r
331 //\r
332 BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");\r
333 if (!IsListEmpty (&DriverOptionList)) {\r
334 BdsLibLoadDrivers (&DriverOptionList);\r
335 }\r
336 //\r
337 // Check if we have the boot next option\r
338 //\r
339 mBootNext = BdsLibGetVariableAndSize (\r
340 L"BootNext",\r
341 &gEfiGlobalVariableGuid,\r
342 &BootNextSize\r
343 );\r
344\r
345 //\r
346 // Setup some platform policy here\r
347 //\r
348 PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);\r
349 PERF_END (0, "PlatformBds", "BDS", 0);\r
350\r
351 //\r
352 // BDS select the boot device to load OS\r
353 //\r
354 BdsBootDeviceSelect ();\r
355\r
356 //\r
357 // Only assert here since this is the right behavior, we should never\r
358 // return back to DxeCore.\r
359 //\r
360 ASSERT (FALSE);\r
361\r
362 return ;\r
363}\r