]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMngr/BootManager.c
Fix build broken issue for ICC 9.0
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMngr / BootManager.c
1 /** @file
2 The platform boot manager reference implementation
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 "BootManager.h"
16
17 UINT16 mKeyInput;
18 EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
19 LIST_ENTRY *mBootOptionsList;
20 BDS_COMMON_OPTION *gOption;
21
22 HII_VENDOR_DEVICE_PATH mBootManagerHiiVendorDevicePath = {
23 {
24 {
25 HARDWARE_DEVICE_PATH,
26 HW_VENDOR_DP,
27 {
28 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
29 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
30 }
31 },
32 //
33 // {1DDDBE15-481D-4d2b-8277-B191EAF66525}
34 //
35 { 0x1dddbe15, 0x481d, 0x4d2b, { 0x82, 0x77, 0xb1, 0x91, 0xea, 0xf6, 0x65, 0x25 } }
36 },
37 {
38 END_DEVICE_PATH_TYPE,
39 END_ENTIRE_DEVICE_PATH_SUBTYPE,
40 {
41 (UINT8) (END_DEVICE_PATH_LENGTH),
42 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
43 }
44 }
45 };
46
47 BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate = {
48 BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,
49 NULL,
50 NULL,
51 {
52 FakeExtractConfig,
53 FakeRouteConfig,
54 BootManagerCallback
55 }
56 };
57
58 /**
59 This call back funtion is registered with Boot Manager formset.
60 When user selects a boot option, this call back function will
61 be triggered. The boot option is saved for later processing.
62
63
64 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
65 @param Action Specifies the type of action taken by the browser.
66 @param QuestionId A unique value which is sent to the original exporting driver
67 so that it can identify the type of data to expect.
68 @param Type The type of value for the question.
69 @param Value A pointer to the data being sent to the original exporting driver.
70 @param ActionRequest On return, points to the action requested by the callback function.
71
72 @retval EFI_SUCCESS The callback successfully handled the action.
73 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
74
75 **/
76 EFI_STATUS
77 EFIAPI
78 BootManagerCallback (
79 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
80 IN EFI_BROWSER_ACTION Action,
81 IN EFI_QUESTION_ID QuestionId,
82 IN UINT8 Type,
83 IN EFI_IFR_TYPE_VALUE *Value,
84 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
85 )
86 {
87 BDS_COMMON_OPTION *Option;
88 LIST_ENTRY *Link;
89 UINT16 KeyCount;
90
91 if ((Value == NULL) || (ActionRequest == NULL)) {
92 return EFI_INVALID_PARAMETER;
93 }
94
95 //
96 // Initialize the key count
97 //
98 KeyCount = 0;
99
100 for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {
101 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
102
103 KeyCount++;
104
105 gOption = Option;
106
107 //
108 // Is this device the one chosen?
109 //
110 if (KeyCount == QuestionId) {
111 //
112 // Assigning the returned Key to a global allows the original routine to know what was chosen
113 //
114 mKeyInput = QuestionId;
115
116 //
117 // Request to exit SendForm(), so that we could boot the selected option
118 //
119 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
120 break;
121 }
122 }
123
124 return EFI_SUCCESS;
125 }
126
127 /**
128
129 Registers HII packages for the Boot Manger to HII Database.
130 It also registers the browser call back function.
131
132 @retval EFI_SUCCESS HII packages for the Boot Manager were registered successfully.
133 @retval EFI_OUT_OF_RESOURCES HII packages for the Boot Manager failed to be registered.
134
135 **/
136 EFI_STATUS
137 InitializeBootManager (
138 VOID
139 )
140 {
141 EFI_STATUS Status;
142
143 //
144 // Install Device Path Protocol and Config Access protocol to driver handle
145 //
146 Status = gBS->InstallMultipleProtocolInterfaces (
147 &gBootManagerPrivate.DriverHandle,
148 &gEfiDevicePathProtocolGuid,
149 &mBootManagerHiiVendorDevicePath,
150 &gEfiHiiConfigAccessProtocolGuid,
151 &gBootManagerPrivate.ConfigAccess,
152 NULL
153 );
154 ASSERT_EFI_ERROR (Status);
155
156 //
157 // Publish our HII data
158 //
159 gBootManagerPrivate.HiiHandle = HiiAddPackages (
160 &mBootManagerGuid,
161 gBootManagerPrivate.DriverHandle,
162 BootManagerVfrBin,
163 BdsDxeStrings,
164 NULL
165 );
166 if (gBootManagerPrivate.HiiHandle == NULL) {
167 Status = EFI_OUT_OF_RESOURCES;
168 } else {
169 Status = EFI_SUCCESS;
170 }
171 return Status;
172 }
173
174 /**
175 This funtion invokees Boot Manager. If all devices have not a chance to be connected,
176 the connect all will be triggered. It then enumerate all boot options. If
177 a boot option from the Boot Manager page is selected, Boot Manager will boot
178 from this boot option.
179
180 **/
181 VOID
182 CallBootManager (
183 VOID
184 )
185 {
186 EFI_STATUS Status;
187 BDS_COMMON_OPTION *Option;
188 LIST_ENTRY *Link;
189 CHAR16 *ExitData;
190 UINTN ExitDataSize;
191 EFI_STRING_ID Token;
192 EFI_INPUT_KEY Key;
193 LIST_ENTRY BdsBootOptionList;
194 CHAR16 *HelpString;
195 EFI_STRING_ID HelpToken;
196 UINT16 *TempStr;
197 EFI_HII_HANDLE HiiHandle;
198 EFI_BROWSER_ACTION_REQUEST ActionRequest;
199 UINTN TempSize;
200 VOID *StartOpCodeHandle;
201 VOID *EndOpCodeHandle;
202 EFI_IFR_GUID_LABEL *StartLabel;
203 EFI_IFR_GUID_LABEL *EndLabel;
204 CHAR16 *HiiString;
205 CHAR16 *BootStringNumber;
206 UINTN DevicePathType;
207 UINTN BufferSize;
208
209 gOption = NULL;
210 InitializeListHead (&BdsBootOptionList);
211
212 //
213 // Connect all prior to entering the platform setup menu.
214 //
215 if (!gConnectAllHappened) {
216 BdsLibConnectAllDriversToAllControllers ();
217 gConnectAllHappened = TRUE;
218 }
219 //
220 // BugBug: Here we can not remove the legacy refresh macro, so we need
221 // get the boot order every time from "BootOrder" variable.
222 // Recreate the boot option list base on the BootOrder variable
223 //
224 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
225
226 mBootOptionsList = &BdsBootOptionList;
227
228 HiiHandle = gBootManagerPrivate.HiiHandle;
229
230 //
231 // Allocate space for creation of UpdateData Buffer
232 //
233 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
234 ASSERT (StartOpCodeHandle != NULL);
235
236 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
237 ASSERT (EndOpCodeHandle != NULL);
238
239 //
240 // Create Hii Extend Label OpCode as the start opcode
241 //
242 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
243 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
244 StartLabel->Number = LABEL_BOOT_OPTION;
245
246 //
247 // Create Hii Extend Label OpCode as the end opcode
248 //
249 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
250 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
251 EndLabel->Number = LABEL_BOOT_OPTION_END;
252
253 mKeyInput = 0;
254
255 for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {
256 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
257
258 //
259 // At this stage we are creating a menu entry, thus the Keys are reproduceable
260 //
261 mKeyInput++;
262
263 //
264 // Don't display the boot option marked as LOAD_OPTION_HIDDEN
265 //
266 if ((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) {
267 continue;
268 }
269
270 //
271 // Replace description string with UNI file string.
272 //
273 BootStringNumber = NULL;
274
275 DevicePathType = BdsGetBootTypeFromDevicePath (Option->DevicePath);
276
277 //
278 // store number string of boot option temporary.
279 //
280 HiiString = NULL;
281 switch (DevicePathType) {
282 case BDS_EFI_ACPI_FLOPPY_BOOT:
283 HiiString = GetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY));
284 break;
285 case BDS_EFI_MEDIA_CDROM_BOOT:
286 case BDS_EFI_MESSAGE_SATA_BOOT:
287 case BDS_EFI_MESSAGE_ATAPI_BOOT:
288 HiiString = GetStringById (STRING_TOKEN (STR_DESCRIPTION_DVD));
289 break;
290 case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
291 HiiString = GetStringById (STRING_TOKEN (STR_DESCRIPTION_USB));
292 break;
293 case BDS_EFI_MESSAGE_SCSI_BOOT:
294 HiiString = GetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI));
295 break;
296 case BDS_EFI_MESSAGE_MISC_BOOT:
297 HiiString = GetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC));
298 break;
299 case BDS_EFI_MESSAGE_MAC_BOOT:
300 HiiString = GetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK));
301 break;
302 case BBS_DEVICE_PATH:
303 //
304 // Do nothing for legacy boot option.
305 //
306 break;
307 default:
308 DEBUG((EFI_D_INFO, "Can not find HiiString for given device path type 0x%x\n", DevicePathType));
309 }
310
311 //
312 // If found Hii description string then cat Hii string with original description.
313 //
314 if (HiiString != NULL) {
315 BootStringNumber = Option->Description;
316 BufferSize = StrSize(BootStringNumber);
317 BufferSize += StrSize(HiiString);
318 Option->Description = AllocateZeroPool(BufferSize);
319 StrCpy (Option->Description, HiiString);
320 if (StrnCmp (BootStringNumber, L"0", 1) != 0) {
321 StrCat (Option->Description, L" ");
322 StrCat (Option->Description, BootStringNumber);
323 }
324
325 FreePool (HiiString);
326 FreePool (BootStringNumber);
327 }
328
329 ASSERT (Option->Description != NULL);
330
331 Token = HiiSetString (HiiHandle, 0, Option->Description, NULL);
332
333 TempStr = DevicePathToStr (Option->DevicePath);
334 TempSize = StrSize (TempStr);
335 HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
336 ASSERT (HelpString != NULL);
337 StrCat (HelpString, L"Device Path : ");
338 StrCat (HelpString, TempStr);
339
340 HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL);
341
342 HiiCreateActionOpCode (
343 StartOpCodeHandle,
344 mKeyInput,
345 Token,
346 HelpToken,
347 EFI_IFR_FLAG_CALLBACK,
348 0
349 );
350 }
351
352 HiiUpdateForm (
353 HiiHandle,
354 &mBootManagerGuid,
355 BOOT_MANAGER_FORM_ID,
356 StartOpCodeHandle,
357 EndOpCodeHandle
358 );
359
360 HiiFreeOpCodeHandle (StartOpCodeHandle);
361 HiiFreeOpCodeHandle (EndOpCodeHandle);
362
363 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
364 Status = gFormBrowser2->SendForm (
365 gFormBrowser2,
366 &HiiHandle,
367 1,
368 &mBootManagerGuid,
369 0,
370 NULL,
371 &ActionRequest
372 );
373 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
374 EnableResetRequired ();
375 }
376
377 if (gOption == NULL) {
378 return ;
379 }
380
381 //
382 //Will leave browser, check any reset required change is applied? if yes, reset system
383 //
384 SetupResetReminder ();
385
386 //
387 // parse the selected option
388 //
389 Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);
390
391 if (!EFI_ERROR (Status)) {
392 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
393 PlatformBdsBootSuccess (gOption);
394 } else {
395 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
396 PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
397 gST->ConOut->OutputString (
398 gST->ConOut,
399 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
400 );
401 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
402 }
403 }