]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/BdsDxe/BdsEntry.c
add back the ReadKeyStroke which is removed wrongly during ICC cleanup.
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / BdsEntry.c
CommitLineData
93e3992d 1/*++\r
2\r
3Copyright (c) 2004 - 2008, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 BdsEntry.c\r
15\r
16Abstract:\r
17\r
18 The entry of the bds\r
19\r
20--*/\r
21\r
22#include "Bds.h"\r
23#include "Language.h"\r
24#include "FrontPage.h"\r
25#include "Hotkey.h"\r
26#include "HwErrRecSupport.h"\r
27\r
28\r
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
35 EXTENSIVE\r
36};\r
37\r
38UINT16 *mBootNext = NULL;\r
39\r
40EFI_HANDLE mBdsImageHandle;\r
41\r
42EFI_STATUS\r
43EFIAPI\r
44BdsInitialize (\r
45 IN EFI_HANDLE ImageHandle,\r
46 IN EFI_SYSTEM_TABLE *SystemTable\r
47 )\r
48/*++\r
49\r
50Routine Description:\r
51\r
52 Install Boot Device Selection Protocol\r
53\r
54Arguments:\r
55\r
56 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
57\r
58Returns:\r
59\r
60 EFI_SUCEESS - BDS has finished initializing.\r
61 Rerun the\r
62 dispatcher and recall BDS.Entry\r
63\r
64 Other - Return value from AllocatePool()\r
65 or gBS->InstallProtocolInterface\r
66\r
67--*/\r
68{\r
69 EFI_STATUS Status;\r
70\r
71 mBdsImageHandle = ImageHandle;\r
72\r
73 //\r
74 // Install protocol interface\r
75 //\r
76 Status = gBS->InstallProtocolInterface (\r
77 &gBdsInstanceTemplate.Handle,\r
78 &gEfiBdsArchProtocolGuid,\r
79 EFI_NATIVE_INTERFACE,\r
80 &gBdsInstanceTemplate.Bds\r
81 );\r
82 ASSERT_EFI_ERROR (Status);\r
83\r
84 return Status;\r
85}\r
86\r
87VOID\r
88BdsBootDeviceSelect (\r
89 VOID\r
90 )\r
91/*++\r
92\r
93Routine Description:\r
94\r
95 In the loop of attempt to boot for the boot order\r
96\r
97Arguments:\r
98\r
99 None.\r
100\r
101Returns:\r
102\r
103 None.\r
104\r
105--*/\r
106{\r
107 EFI_STATUS Status;\r
108 LIST_ENTRY *Link;\r
109 BDS_COMMON_OPTION *BootOption;\r
110 UINTN ExitDataSize;\r
111 CHAR16 *ExitData;\r
112 UINT16 Timeout;\r
113 LIST_ENTRY BootLists;\r
114 CHAR16 Buffer[20];\r
115 BOOLEAN BootNextExist;\r
116 LIST_ENTRY *LinkBootNext;\r
117\r
118 //\r
119 // Got the latest boot option\r
120 //\r
121 BootNextExist = FALSE;\r
122 LinkBootNext = NULL;\r
123 InitializeListHead (&BootLists);\r
124\r
125 //\r
126 // First check the boot next option\r
127 //\r
128 ZeroMem (Buffer, sizeof (Buffer));\r
129\r
130 if (mBootNext != NULL) {\r
131 //\r
132 // Indicate we have the boot next variable, so this time\r
133 // boot will always have this boot option\r
134 //\r
135 BootNextExist = TRUE;\r
136\r
137 //\r
138 // Clear the this variable so it's only exist in this time boot\r
139 //\r
140 gRT->SetVariable (\r
141 L"BootNext",\r
142 &gEfiGlobalVariableGuid,\r
143 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
144 0,\r
145 mBootNext\r
146 );\r
147\r
148 //\r
149 // Add the boot next boot option\r
150 //\r
151 UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);\r
152 BootOption = BdsLibVariableToOption (&BootLists, Buffer);\r
153 BootOption->BootCurrent = *mBootNext;\r
154 }\r
155 //\r
156 // Parse the boot order to get boot option\r
157 //\r
158 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
159 Link = BootLists.ForwardLink;\r
160\r
161 //\r
162 // Parameter check, make sure the loop will be valid\r
163 //\r
164 if (Link == NULL) {\r
165 return ;\r
166 }\r
167 //\r
168 // Here we make the boot in a loop, every boot success will\r
169 // return to the front page\r
170 //\r
171 for (;;) {\r
172 //\r
173 // Check the boot option list first\r
174 //\r
175 if (Link == &BootLists) {\r
176 //\r
177 // There are two ways to enter here:\r
178 // 1. There is no active boot option, give user chance to\r
179 // add new boot option\r
180 // 2. All the active boot option processed, and there is no\r
181 // one is success to boot, then we back here to allow user\r
182 // add new active boot option\r
183 //\r
184 Timeout = 0xffff;\r
185 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
186 InitializeListHead (&BootLists);\r
187 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
188 Link = BootLists.ForwardLink;\r
189 continue;\r
190 }\r
191 //\r
192 // Get the boot option from the link list\r
193 //\r
194 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
195\r
196 //\r
197 // According to EFI Specification, if a load option is not marked\r
198 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically\r
199 // load the option.\r
200 //\r
201 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
202 //\r
203 // skip the header of the link list, becuase it has no boot option\r
204 //\r
205 Link = Link->ForwardLink;\r
206 continue;\r
207 }\r
208 //\r
209 // Make sure the boot option device path connected,\r
210 // but ignore the BBS device path\r
211 //\r
212 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
213 //\r
214 // Notes: the internal shell can not been connected with device path\r
215 // so we do not check the status here\r
216 //\r
217 BdsLibConnectDevicePath (BootOption->DevicePath);\r
218 }\r
219 //\r
220 // All the driver options should have been processed since\r
221 // now boot will be performed.\r
222 //\r
223 Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);\r
224 if (EFI_ERROR (Status)) {\r
225 //\r
226 // Call platform action to indicate the boot fail\r
227 //\r
228 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));\r
229 PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);\r
230\r
231 //\r
232 // Check the next boot option\r
233 //\r
234 Link = Link->ForwardLink;\r
235\r
236 } else {\r
237 //\r
238 // Call platform action to indicate the boot success\r
239 //\r
240 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); \r
241 PlatformBdsBootSuccess (BootOption);\r
242\r
243 //\r
244 // Boot success, then stop process the boot order, and\r
245 // present the boot manager menu, front page\r
246 //\r
247 Timeout = 0xffff;\r
248 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
249\r
250 //\r
251 // Rescan the boot option list, avoid pertential risk of the boot\r
252 // option change in front page\r
253 //\r
254 if (BootNextExist) {\r
255 LinkBootNext = BootLists.ForwardLink;\r
256 }\r
257\r
258 InitializeListHead (&BootLists);\r
259 if (LinkBootNext != NULL) {\r
260 //\r
261 // Reserve the boot next option\r
262 //\r
263 InsertTailList (&BootLists, LinkBootNext);\r
264 }\r
265\r
266 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
267 Link = BootLists.ForwardLink;\r
268 }\r
269 }\r
270\r
271}\r
272\r
273VOID\r
274EFIAPI\r
275BdsEntry (\r
276 IN EFI_BDS_ARCH_PROTOCOL *This\r
277 )\r
278/*++\r
279\r
280Routine Description:\r
281\r
282 Service routine for BdsInstance->Entry(). Devices are connected, the\r
283 consoles are initialized, and the boot options are tried.\r
284\r
285Arguments:\r
286\r
287 This - Protocol Instance structure.\r
288\r
289Returns:\r
290\r
291 EFI_SUCEESS - BDS->Entry has finished executing.\r
292\r
293--*/\r
294{\r
295 EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;\r
296 LIST_ENTRY DriverOptionList;\r
297 LIST_ENTRY BootOptionList;\r
298 UINTN BootNextSize;\r
299\r
300 //\r
301 // Insert the performance probe\r
302 //\r
303 PERF_END (0, DXE_TOK, NULL, 0);\r
304 PERF_START (0, BDS_TOK, NULL, 0);\r
305\r
306 //\r
307 // Initialize the global system boot option and driver option\r
308 //\r
309 InitializeListHead (&DriverOptionList);\r
310 InitializeListHead (&BootOptionList);\r
311\r
312 //\r
313 // Initialize hotkey service\r
314 //\r
315 InitializeHotkeyService ();\r
316\r
317 //\r
318 // Get the BDS private data\r
319 //\r
320 PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);\r
321\r
322 //\r
323 // Do the platform init, can be customized by OEM/IBV\r
324 //\r
325 PERF_START (0, "PlatformBds", "BDS", 0);\r
326 PlatformBdsInit (PrivateData);\r
327\r
328 if (FeaturePcdGet (PcdSupportHardwareErrorRecord)) {\r
329 InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel));\r
330 }\r
331 //\r
332 // bugbug: platform specific code\r
333 // Initialize the platform specific string and language\r
334 //\r
335 InitializeStringSupport ();\r
336 InitializeLanguage (TRUE);\r
337 InitializeFrontPage (FALSE);\r
338\r
339 //\r
340 // Set up the device list based on EFI 1.1 variables\r
341 // process Driver#### and Load the driver's in the\r
342 // driver option list\r
343 //\r
344 BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");\r
345 if (!IsListEmpty (&DriverOptionList)) {\r
346 BdsLibLoadDrivers (&DriverOptionList);\r
347 }\r
348 //\r
349 // Check if we have the boot next option\r
350 //\r
351 mBootNext = BdsLibGetVariableAndSize (\r
352 L"BootNext",\r
353 &gEfiGlobalVariableGuid,\r
354 &BootNextSize\r
355 );\r
356\r
357 //\r
358 // Setup some platform policy here\r
359 //\r
360 PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);\r
361 PERF_END (0, "PlatformBds", "BDS", 0);\r
362\r
363 //\r
364 // BDS select the boot device to load OS\r
365 //\r
366 BdsBootDeviceSelect ();\r
367\r
368 //\r
369 // Only assert here since this is the right behavior, we should never\r
370 // return back to DxeCore.\r
371 //\r
372 ASSERT (FALSE);\r
373\r
374 return ;\r
375}\r