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