]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/PlatformBdsDxe/Generic/BdsEntry.c
Convert NT32 to use PCD settings for UEFI Timeout and language variables as a POC...
[mirror_edk2.git] / Nt32Pkg / PlatformBdsDxe / Generic / BdsEntry.c
CommitLineData
bc11b829 1/*++\r
2\r
3Copyright (c) 2006, 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//\r
23// Include common header file for this module.\r
24//\r
25#include "CommonHeader.h"\r
26\r
27#include "Bds.h"\r
28#include "BdsPlatform.h"\r
29#include "FrontPage.h"\r
30\r
31EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate = {\r
32 EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE,\r
33 NULL,\r
34 BdsEntry,\r
35 0xFFFF,\r
36 TRUE,\r
37 EXTENSIVE\r
38};\r
39\r
40UINT16 *mBootNext = NULL;\r
41\r
42EFI_HANDLE mBdsImageHandle;\r
43\r
44EFI_STATUS\r
45EFIAPI\r
46BdsInitialize (\r
47 IN EFI_HANDLE ImageHandle,\r
48 IN EFI_SYSTEM_TABLE *SystemTable\r
49 )\r
50/*++\r
51\r
52Routine Description:\r
53\r
54 Install Boot Device Selection Protocol\r
55\r
56Arguments:\r
57 \r
58 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
59\r
60Returns:\r
61\r
62 EFI_SUCEESS - BDS has finished initializing.\r
63 Rerun the \r
64 dispatcher and recall BDS.Entry\r
65\r
66 Other - Return value from EfiLibAllocatePool()\r
67 or gBS->InstallProtocolInterface\r
68\r
69--*/\r
70{\r
71 EFI_STATUS Status;\r
72\r
73 mBdsImageHandle = ImageHandle;\r
74\r
75 //\r
76 // Install protocol interface\r
77 //\r
78 Status = gBS->InstallProtocolInterface (\r
79 &gBdsInstanceTemplate.Handle,\r
80 &gEfiBdsArchProtocolGuid,\r
81 EFI_NATIVE_INTERFACE,\r
82 &gBdsInstanceTemplate.Bds\r
83 );\r
84 ASSERT_EFI_ERROR (Status);\r
85\r
86 return Status;\r
87}\r
88\r
89VOID\r
90BdsBootDeviceSelect (\r
91 VOID\r
92 )\r
93/*++\r
94\r
95Routine Description:\r
96\r
97 In the loop of attempt to boot for the boot order\r
98\r
99Arguments:\r
100 \r
101 None.\r
102\r
103Returns:\r
104\r
105 None.\r
106 \r
107--*/\r
108{\r
109 EFI_STATUS Status;\r
110 LIST_ENTRY *Link;\r
111 BDS_COMMON_OPTION *BootOption;\r
112 UINTN ExitDataSize;\r
113 CHAR16 *ExitData;\r
114 UINT16 Timeout;\r
115 LIST_ENTRY BootLists;\r
116 CHAR16 Buffer[20];\r
117 BOOLEAN BootNextExist;\r
118 LIST_ENTRY *LinkBootNext;\r
119\r
120 //\r
121 // Got the latest boot option\r
122 //\r
123 BootNextExist = FALSE;\r
124 LinkBootNext = NULL;\r
125 InitializeListHead (&BootLists);\r
126\r
127 //\r
128 // First check the boot next option\r
129 //\r
130 ZeroMem (Buffer, sizeof (Buffer));\r
131\r
132 if (mBootNext != NULL) {\r
133 //\r
134 // Indicate we have the boot next variable, so this time\r
135 // boot will always have this boot option\r
136 //\r
137 BootNextExist = TRUE;\r
138\r
139 //\r
140 // Clear the this variable so it's only exist in this time boot\r
141 //\r
142 gRT->SetVariable (\r
143 L"BootNext",\r
144 &gEfiGlobalVariableGuid,\r
145 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
146 0,\r
147 mBootNext\r
148 );\r
149\r
150 //\r
151 // Add the boot next boot option\r
152 //\r
153 UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);\r
154 BootOption = BdsLibVariableToOption (&BootLists, Buffer);\r
155 }\r
156 //\r
157 // Parse the boot order to get boot option\r
158 //\r
159 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
160 Link = BootLists.ForwardLink;\r
161\r
162 //\r
163 // Parameter check, make sure the loop will be valid\r
164 //\r
165 if (Link == NULL) {\r
166 return ;\r
167 }\r
168 //\r
169 // Here we make the boot in a loop, every boot success will\r
170 // return to the front page\r
171 //\r
172 for (;;) {\r
173 //\r
174 // Check the boot option list first\r
175 //\r
176 if (Link == &BootLists) {\r
177 //\r
178 // There are two ways to enter here:\r
179 // 1. There is no active boot option, give user chance to\r
180 // add new boot option\r
181 // 2. All the active boot option processed, and there is no\r
182 // one is success to boot, then we back here to allow user\r
183 // add new active boot option\r
184 //\r
185 Timeout = 0xffff;\r
186 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
187 InitializeListHead (&BootLists);\r
188 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
189 Link = BootLists.ForwardLink;\r
190 continue;\r
191 }\r
192 //\r
193 // Get the boot option from the link list\r
194 //\r
195 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
196\r
197 //\r
198 // According to EFI Specification, if a load option is not marked\r
199 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically\r
200 // load the option.\r
201 //\r
202 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
203 //\r
204 // skip the header of the link list, becuase it has no boot option\r
205 //\r
206 Link = Link->ForwardLink;\r
207 continue;\r
208 }\r
209 //\r
210 // Make sure the boot option device path connected,\r
211 // but ignore the BBS device path\r
212 //\r
213 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
214 //\r
215 // Notes: the internal shell can not been connected with device path\r
216 // so we do not check the status here\r
217 //\r
218 BdsLibConnectDevicePath (BootOption->DevicePath);\r
219 }\r
220 //\r
221 // All the driver options should have been processed since\r
222 // now boot will be performed.\r
223 //\r
224 Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);\r
225 if (EFI_ERROR (Status)) {\r
226 //\r
227 // Call platform action to indicate the boot fail\r
228 //\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 PlatformBdsBootSuccess (BootOption);\r
241\r
242 //\r
243 // Boot success, then stop process the boot order, and\r
244 // present the boot manager menu, front page\r
245 //\r
246 Timeout = 0xffff;\r
247 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
248\r
249 //\r
250 // Rescan the boot option list, avoid pertential risk of the boot\r
251 // option change in front page\r
252 //\r
253 if (BootNextExist) {\r
254 LinkBootNext = BootLists.ForwardLink;\r
255 }\r
256\r
257 InitializeListHead (&BootLists);\r
258 if (LinkBootNext != NULL) {\r
259 //\r
260 // Reserve the boot next option\r
261 //\r
262 InsertTailList (&BootLists, LinkBootNext);\r
263 }\r
264\r
265 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
266 Link = BootLists.ForwardLink;\r
267 }\r
268 }\r
269\r
270 return ;\r
271\r
272}\r
273\r
274EFI_STATUS\r
275EFIAPI\r
276BdsEntry (\r
277 IN EFI_BDS_ARCH_PROTOCOL *This\r
278 )\r
279/*++\r
280\r
281Routine Description:\r
282\r
283 Service routine for BdsInstance->Entry(). Devices are connected, the \r
284 consoles are initialized, and the boot options are tried. \r
285\r
286Arguments:\r
287\r
288 This - Protocol Instance structure.\r
289\r
290Returns:\r
291\r
292 EFI_SUCEESS - BDS->Entry has finished executing. \r
293 \r
294--*/\r
295{\r
296 EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;\r
297 LIST_ENTRY DriverOptionList;\r
298 LIST_ENTRY BootOptionList;\r
299 UINTN BootNextSize;\r
300\r
301 //\r
302 // Insert the performance probe\r
303 //\r
304 PERF_END (0, DXE_TOK, NULL, 0);\r
305 PERF_START (0, BDS_TOK, NULL, 0);\r
306\r
307 //\r
308 // Initialize the global system boot option and driver option\r
309 //\r
310 InitializeListHead (&DriverOptionList);\r
311 InitializeListHead (&BootOptionList);\r
312\r
313 //\r
314 // Get the BDS private data\r
315 //\r
316 PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);\r
317\r
318 //\r
319 // Do the platform init, can be customized by OEM/IBV\r
320 //\r
321 PERF_START (0, "PlatformBds", "BDS", 0);\r
322 PlatformBdsInit (PrivateData);\r
323\r
324 //\r
325 // Set up the device list based on EFI 1.1 variables\r
326 // process Driver#### and Load the driver's in the\r
327 // driver option list\r
328 //\r
329 BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");\r
330 if (!IsListEmpty (&DriverOptionList)) {\r
331 BdsLibLoadDrivers (&DriverOptionList);\r
332 }\r
333 //\r
334 // Check if we have the boot next option\r
335 //\r
336 mBootNext = BdsLibGetVariableAndSize (\r
337 L"BootNext",\r
338 &gEfiGlobalVariableGuid,\r
339 &BootNextSize\r
340 );\r
341\r
342 //\r
343 // Setup some platform policy here\r
344 //\r
345 PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);\r
346 PERF_END (0, "PlatformBds", "BDS", 0);\r
347\r
348 //\r
349 // BDS select the boot device to load OS\r
350 //\r
351 BdsBootDeviceSelect ();\r
352\r
353 //\r
354 // Only assert here since this is the right behavior, we should never\r
355 // return back to DxeCore.\r
356 //\r
357 ASSERT (FALSE);\r
358\r
359 return EFI_SUCCESS;\r
360}\r