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