]> git.proxmox.com Git - mirror_edk2.git/blame - EdkNt32Pkg/Dxe/PlatformBds/Generic/BdsEntry.c
Add in OFFSET_OF macro as defined in MDE Library spec
[mirror_edk2.git] / EdkNt32Pkg / Dxe / PlatformBds / Generic / BdsEntry.c
CommitLineData
878ddf1f 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#include "Bds.h"\r
23#include "BdsPlatform.h"\r
24#include "FrontPage.h"\r
25\r
26EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate = {\r
27 EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE,\r
28 NULL,\r
29 BdsEntry,\r
30 0xFFFF,\r
31 TRUE,\r
32 EXTENSIVE\r
33};\r
34\r
35UINT16 *mBootNext = NULL;\r
36\r
37EFI_HANDLE mBdsImageHandle;\r
38\r
39EFI_STATUS\r
40EFIAPI\r
41BdsInitialize (\r
42 IN EFI_HANDLE ImageHandle,\r
43 IN EFI_SYSTEM_TABLE *SystemTable\r
44 )\r
45/*++\r
46\r
47Routine Description:\r
48\r
49 Install Boot Device Selection Protocol\r
50\r
51Arguments:\r
52 \r
53 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
54\r
55Returns:\r
56\r
57 EFI_SUCEESS - BDS has finished initializing.\r
58 Rerun the \r
59 dispatcher and recall BDS.Entry\r
60\r
61 Other - Return value from EfiLibAllocatePool()\r
62 or gBS->InstallProtocolInterface\r
63\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
84VOID\r
85BdsBootDeviceSelect (\r
86 VOID\r
87 )\r
88/*++\r
89\r
90Routine Description:\r
91\r
92 In the loop of attempt to boot for the boot order\r
93\r
94Arguments:\r
95 \r
96 None.\r
97\r
98Returns:\r
99\r
100 None.\r
101 \r
102--*/\r
103{\r
104 EFI_STATUS Status;\r
105 LIST_ENTRY *Link;\r
106 BDS_COMMON_OPTION *BootOption;\r
107 UINTN ExitDataSize;\r
108 CHAR16 *ExitData;\r
109 UINT16 Timeout;\r
110 LIST_ENTRY BootLists;\r
111 CHAR16 Buffer[20];\r
112 BOOLEAN BootNextExist;\r
113 LIST_ENTRY *LinkBootNext;\r
114\r
115 //\r
116 // Got the latest boot option\r
117 //\r
118 BootNextExist = FALSE;\r
119 LinkBootNext = NULL;\r
120 InitializeListHead (&BootLists);\r
121\r
122 //\r
123 // First check the boot next option\r
124 //\r
125 ZeroMem (Buffer, sizeof (Buffer));\r
126\r
127 if (mBootNext != NULL) {\r
128 //\r
129 // Indicate we have the boot next variable, so this time\r
130 // boot will always have this boot option\r
131 //\r
132 BootNextExist = TRUE;\r
133\r
134 //\r
135 // Clear the this variable so it's only exist in this time boot\r
136 //\r
137 gRT->SetVariable (\r
138 L"BootNext",\r
139 &gEfiGlobalVariableGuid,\r
140 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
141 0,\r
142 mBootNext\r
143 );\r
144\r
145 //\r
146 // Add the boot next boot option\r
147 //\r
148 UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);\r
149 BootOption = BdsLibVariableToOption (&BootLists, Buffer);\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
878ddf1f 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 PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);\r
225\r
226 //\r
227 // Check the next boot option\r
228 //\r
229 Link = Link->ForwardLink;\r
230\r
231 } else {\r
232 //\r
233 // Call platform action to indicate the boot success\r
234 //\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 return ;\r
266\r
267}\r
268\r
269EFI_STATUS\r
270EFIAPI\r
271BdsEntry (\r
272 IN EFI_BDS_ARCH_PROTOCOL *This\r
273 )\r
274/*++\r
275\r
276Routine Description:\r
277\r
278 Service routine for BdsInstance->Entry(). Devices are connected, the \r
279 consoles are initialized, and the boot options are tried. \r
280\r
281Arguments:\r
282\r
283 This - Protocol Instance structure.\r
284\r
285Returns:\r
286\r
287 EFI_SUCEESS - BDS->Entry has finished executing. \r
288 \r
289--*/\r
290{\r
291 EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;\r
292 LIST_ENTRY DriverOptionList;\r
293 LIST_ENTRY BootOptionList;\r
294 UINTN BootNextSize;\r
295\r
296 //\r
297 // Insert the performance probe\r
298 //\r
299 PERF_END (0, DXE_TOK, NULL, 0);\r
300 PERF_START (0, BDS_TOK, NULL, 0);\r
301\r
302 //\r
303 // Initialize the global system boot option and driver option\r
304 //\r
305 InitializeListHead (&DriverOptionList);\r
306 InitializeListHead (&BootOptionList);\r
307\r
308 //\r
309 // Get the BDS private data\r
310 //\r
311 PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);\r
312\r
313 //\r
314 // Do the platform init, can be customized by OEM/IBV\r
315 //\r
316 PERF_START (0, "PlatformBds", "BDS", 0);\r
317 PlatformBdsInit (PrivateData);\r
318\r
319 //\r
320 // Set up the device list based on EFI 1.1 variables\r
321 // process Driver#### and Load the driver's in the\r
322 // driver option list\r
323 //\r
324 BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");\r
325 if (!IsListEmpty (&DriverOptionList)) {\r
326 BdsLibLoadDrivers (&DriverOptionList);\r
327 }\r
328 //\r
329 // Check if we have the boot next option\r
330 //\r
331 mBootNext = BdsLibGetVariableAndSize (\r
332 L"BootNext",\r
333 &gEfiGlobalVariableGuid,\r
334 &BootNextSize\r
335 );\r
336\r
337 //\r
338 // Setup some platform policy here\r
339 //\r
340 PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);\r
c3ebca2c 341 PERF_END (0, "PlatformBds", "BDS", 0);\r
878ddf1f 342\r
343 //\r
344 // BDS select the boot device to load OS\r
345 //\r
346 BdsBootDeviceSelect ();\r
347\r
348 //\r
349 // Only assert here since this is the right behavior, we should never\r
350 // return back to DxeCore.\r
351 //\r
352 ASSERT (FALSE);\r
353\r
354 return EFI_SUCCESS;\r
355}\r