]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMngr/BootManager.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMngr / BootManager.c
CommitLineData
5c08e117 1/** @file\r
2 The platform boot manager reference implementation\r
3\r
0a6f4824 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "BootManager.h"\r
16\r
17UINT16 mKeyInput;\r
ce5fad41 18LIST_ENTRY mBootOptionsList;\r
5c08e117 19BDS_COMMON_OPTION *gOption;\r
22d1f978
RN
20CHAR16 *mDeviceTypeStr[] = {\r
21 L"Legacy BEV",\r
22 L"Legacy Floppy",\r
23 L"Legacy Hard Drive",\r
24 L"Legacy CD ROM",\r
25 L"Legacy PCMCIA",\r
26 L"Legacy USB",\r
27 L"Legacy Embedded Network",\r
28 L"Legacy Unknown Device"\r
29};\r
30\r
5c08e117 31\r
f6f910dd 32HII_VENDOR_DEVICE_PATH mBootManagerHiiVendorDevicePath = {\r
33 {\r
34 {\r
35 HARDWARE_DEVICE_PATH,\r
36 HW_VENDOR_DP,\r
37 {\r
38 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
39 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
40 }\r
41 },\r
e24fc103 42 BOOT_MANAGER_FORMSET_GUID\r
f6f910dd 43 },\r
44 {\r
45 END_DEVICE_PATH_TYPE,\r
46 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
0a6f4824 47 {\r
f6f910dd 48 (UINT8) (END_DEVICE_PATH_LENGTH),\r
49 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
50 }\r
51 }\r
52};\r
53\r
5c08e117 54BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate = {\r
55 BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,\r
56 NULL,\r
57 NULL,\r
58 {\r
59 FakeExtractConfig,\r
60 FakeRouteConfig,\r
61 BootManagerCallback\r
62 }\r
63};\r
64\r
65/**\r
baf46e70 66 This call back function is registered with Boot Manager formset.\r
5c08e117 67 When user selects a boot option, this call back function will\r
68 be triggered. The boot option is saved for later processing.\r
69\r
70\r
71 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
72 @param Action Specifies the type of action taken by the browser.\r
73 @param QuestionId A unique value which is sent to the original exporting driver\r
74 so that it can identify the type of data to expect.\r
75 @param Type The type of value for the question.\r
76 @param Value A pointer to the data being sent to the original exporting driver.\r
77 @param ActionRequest On return, points to the action requested by the callback function.\r
78\r
79 @retval EFI_SUCCESS The callback successfully handled the action.\r
80 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
81\r
82**/\r
83EFI_STATUS\r
84EFIAPI\r
85BootManagerCallback (\r
86 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
87 IN EFI_BROWSER_ACTION Action,\r
88 IN EFI_QUESTION_ID QuestionId,\r
89 IN UINT8 Type,\r
90 IN EFI_IFR_TYPE_VALUE *Value,\r
91 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
92 )\r
93{\r
94 BDS_COMMON_OPTION *Option;\r
95 LIST_ENTRY *Link;\r
96 UINT16 KeyCount;\r
97\r
84724077 98 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
d88f86f1
ED
99 if ((Value == NULL) || (ActionRequest == NULL)) {\r
100 return EFI_INVALID_PARAMETER;\r
101 }\r
102\r
4548fc2a 103 //\r
d88f86f1 104 // Initialize the key count\r
4548fc2a 105 //\r
d88f86f1 106 KeyCount = 0;\r
5c08e117 107\r
d88f86f1
ED
108 for (Link = GetFirstNode (&mBootOptionsList); !IsNull (&mBootOptionsList, Link); Link = GetNextNode (&mBootOptionsList, Link)) {\r
109 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
5c08e117 110\r
d88f86f1 111 KeyCount++;\r
5c08e117 112\r
d88f86f1 113 gOption = Option;\r
5c08e117 114\r
5c08e117 115 //\r
d88f86f1 116 // Is this device the one chosen?\r
5c08e117 117 //\r
d88f86f1
ED
118 if (KeyCount == QuestionId) {\r
119 //\r
120 // Assigning the returned Key to a global allows the original routine to know what was chosen\r
121 //\r
122 mKeyInput = QuestionId;\r
123\r
124 //\r
125 // Request to exit SendForm(), so that we could boot the selected option\r
126 //\r
127 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
128 break;\r
129 }\r
5c08e117 130 }\r
d88f86f1
ED
131\r
132 return EFI_SUCCESS;\r
5c08e117 133 }\r
134\r
d88f86f1
ED
135 //\r
136 // All other action return unsupported.\r
137 //\r
138 return EFI_UNSUPPORTED;\r
5c08e117 139}\r
140\r
141/**\r
142\r
143 Registers HII packages for the Boot Manger to HII Database.\r
144 It also registers the browser call back function.\r
145\r
cb7d01c0 146 @retval EFI_SUCCESS HII packages for the Boot Manager were registered successfully.\r
147 @retval EFI_OUT_OF_RESOURCES HII packages for the Boot Manager failed to be registered.\r
5c08e117 148\r
149**/\r
150EFI_STATUS\r
151InitializeBootManager (\r
152 VOID\r
153 )\r
154{\r
155 EFI_STATUS Status;\r
5c08e117 156\r
157 //\r
f6f910dd 158 // Install Device Path Protocol and Config Access protocol to driver handle\r
5c08e117 159 //\r
f6f910dd 160 Status = gBS->InstallMultipleProtocolInterfaces (\r
5c08e117 161 &gBootManagerPrivate.DriverHandle,\r
f6f910dd 162 &gEfiDevicePathProtocolGuid,\r
163 &mBootManagerHiiVendorDevicePath,\r
5c08e117 164 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 165 &gBootManagerPrivate.ConfigAccess,\r
166 NULL\r
5c08e117 167 );\r
168 ASSERT_EFI_ERROR (Status);\r
169\r
170 //\r
171 // Publish our HII data\r
172 //\r
cb7d01c0 173 gBootManagerPrivate.HiiHandle = HiiAddPackages (\r
e24fc103 174 &gBootManagerFormSetGuid,\r
cb7d01c0 175 gBootManagerPrivate.DriverHandle,\r
176 BootManagerVfrBin,\r
177 BdsDxeStrings,\r
178 NULL\r
179 );\r
180 if (gBootManagerPrivate.HiiHandle == NULL) {\r
181 Status = EFI_OUT_OF_RESOURCES;\r
182 } else {\r
183 Status = EFI_SUCCESS;\r
184 }\r
5c08e117 185 return Status;\r
186}\r
187\r
188/**\r
baf46e70 189 This function invokes Boot Manager. If all devices have not a chance to be connected,\r
0a6f4824 190 the connect all will be triggered. It then enumerate all boot options. If\r
5c08e117 191 a boot option from the Boot Manager page is selected, Boot Manager will boot\r
192 from this boot option.\r
0a6f4824 193\r
5c08e117 194**/\r
195VOID\r
196CallBootManager (\r
197 VOID\r
198 )\r
199{\r
200 EFI_STATUS Status;\r
201 BDS_COMMON_OPTION *Option;\r
202 LIST_ENTRY *Link;\r
5c08e117 203 CHAR16 *ExitData;\r
204 UINTN ExitDataSize;\r
205 EFI_STRING_ID Token;\r
206 EFI_INPUT_KEY Key;\r
5c08e117 207 CHAR16 *HelpString;\r
44cbebec 208 UINTN HelpSize;\r
5c08e117 209 EFI_STRING_ID HelpToken;\r
210 UINT16 *TempStr;\r
211 EFI_HII_HANDLE HiiHandle;\r
212 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
75bf9d0e
LG
213 VOID *StartOpCodeHandle;\r
214 VOID *EndOpCodeHandle;\r
215 EFI_IFR_GUID_LABEL *StartLabel;\r
216 EFI_IFR_GUID_LABEL *EndLabel;\r
22d1f978
RN
217 UINT16 DeviceType;\r
218 BOOLEAN IsLegacyOption;\r
219 BOOLEAN NeedEndOp;\r
5c08e117 220\r
22d1f978
RN
221 DeviceType = (UINT16) -1;\r
222 gOption = NULL;\r
ce5fad41 223 InitializeListHead (&mBootOptionsList);\r
5c08e117 224\r
225 //\r
226 // Connect all prior to entering the platform setup menu.\r
227 //\r
228 if (!gConnectAllHappened) {\r
229 BdsLibConnectAllDriversToAllControllers ();\r
230 gConnectAllHappened = TRUE;\r
231 }\r
5c08e117 232\r
ce5fad41 233 BdsLibEnumerateAllBootOption (&mBootOptionsList);\r
5c08e117 234\r
16e5944a
RN
235 //\r
236 // Group the legacy boot options for the same device type\r
237 //\r
238 GroupMultipleLegacyBootOption4SameType ();\r
239\r
240 InitializeListHead (&mBootOptionsList);\r
241 BdsLibBuildOptionFromVar (&mBootOptionsList, L"BootOrder");\r
242\r
5c08e117 243 HiiHandle = gBootManagerPrivate.HiiHandle;\r
244\r
245 //\r
246 // Allocate space for creation of UpdateData Buffer\r
247 //\r
75bf9d0e
LG
248 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
249 ASSERT (StartOpCodeHandle != NULL);\r
250\r
251 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
252 ASSERT (EndOpCodeHandle != NULL);\r
253\r
254 //\r
255 // Create Hii Extend Label OpCode as the start opcode\r
256 //\r
257 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
258 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
259 StartLabel->Number = LABEL_BOOT_OPTION;\r
260\r
261 //\r
262 // Create Hii Extend Label OpCode as the end opcode\r
263 //\r
264 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
265 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
266 EndLabel->Number = LABEL_BOOT_OPTION_END;\r
5c08e117 267\r
268 mKeyInput = 0;\r
22d1f978 269 NeedEndOp = FALSE;\r
ce5fad41 270 for (Link = GetFirstNode (&mBootOptionsList); !IsNull (&mBootOptionsList, Link); Link = GetNextNode (&mBootOptionsList, Link)) {\r
5c08e117 271 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
272\r
273 //\r
274 // At this stage we are creating a menu entry, thus the Keys are reproduceable\r
275 //\r
276 mKeyInput++;\r
277\r
278 //\r
16e5944a 279 // Don't display the hidden/inactive boot option\r
5c08e117 280 //\r
16e5944a 281 if (((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) || ((Option->Attribute & LOAD_OPTION_ACTIVE) == 0)) {\r
5c08e117 282 continue;\r
283 }\r
22d1f978
RN
284\r
285 //\r
286 // Group the legacy boot option in the sub title created dynamically\r
287 //\r
288 IsLegacyOption = (BOOLEAN) (\r
289 (DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&\r
290 (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)\r
291 );\r
292\r
293 if (!IsLegacyOption && NeedEndOp) {\r
294 NeedEndOp = FALSE;\r
295 HiiCreateEndOpCode (StartOpCodeHandle);\r
296 }\r
0a6f4824 297\r
22d1f978
RN
298 if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType) {\r
299 if (NeedEndOp) {\r
300 HiiCreateEndOpCode (StartOpCodeHandle);\r
301 }\r
302\r
303 DeviceType = ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType;\r
304 Token = HiiSetString (\r
305 HiiHandle,\r
306 0,\r
307 mDeviceTypeStr[\r
bdb898a5 308 MIN (DeviceType & 0xF, ARRAY_SIZE (mDeviceTypeStr) - 1)\r
22d1f978
RN
309 ],\r
310 NULL\r
311 );\r
312 HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);\r
313 NeedEndOp = TRUE;\r
314 }\r
315\r
5caec787 316 ASSERT (Option->Description != NULL);\r
0a6f4824 317\r
cb7d01c0 318 Token = HiiSetString (HiiHandle, 0, Option->Description, NULL);\r
5c08e117 319\r
320 TempStr = DevicePathToStr (Option->DevicePath);\r
44cbebec 321 HelpSize = StrSize (TempStr) + StrSize (L"Device Path : ");\r
577870d5 322 HelpString = AllocateZeroPool (HelpSize);\r
5c08e117 323 ASSERT (HelpString != NULL);\r
577870d5 324 StrCatS (HelpString, HelpSize / sizeof (CHAR16), L"Device Path : ");\r
44cbebec 325 StrCatS (HelpString, HelpSize / sizeof (CHAR16), TempStr);\r
5c08e117 326\r
cb7d01c0 327 HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL);\r
5c08e117 328\r
75bf9d0e
LG
329 HiiCreateActionOpCode (\r
330 StartOpCodeHandle,\r
5c08e117 331 mKeyInput,\r
332 Token,\r
333 HelpToken,\r
334 EFI_IFR_FLAG_CALLBACK,\r
75bf9d0e 335 0\r
5c08e117 336 );\r
337 }\r
338\r
22d1f978
RN
339 if (NeedEndOp) {\r
340 HiiCreateEndOpCode (StartOpCodeHandle);\r
341 }\r
342\r
75bf9d0e 343 HiiUpdateForm (\r
5c08e117 344 HiiHandle,\r
e24fc103 345 &gBootManagerFormSetGuid,\r
5c08e117 346 BOOT_MANAGER_FORM_ID,\r
75bf9d0e
LG
347 StartOpCodeHandle,\r
348 EndOpCodeHandle\r
5c08e117 349 );\r
75bf9d0e
LG
350\r
351 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
352 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
5c08e117 353\r
354 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
355 Status = gFormBrowser2->SendForm (\r
356 gFormBrowser2,\r
357 &HiiHandle,\r
358 1,\r
e24fc103 359 &gBootManagerFormSetGuid,\r
5c08e117 360 0,\r
361 NULL,\r
362 &ActionRequest\r
363 );\r
364 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
365 EnableResetRequired ();\r
366 }\r
367\r
368 if (gOption == NULL) {\r
369 return ;\r
370 }\r
371\r
372 //\r
baf46e70 373 // Will leave browser, check any reset required change is applied? if yes, reset system\r
5c08e117 374 //\r
375 SetupResetReminder ();\r
376\r
2df686c6 377 //\r
378 // Restore to original mode before launching boot option.\r
379 //\r
380 BdsSetConsoleMode (FALSE);\r
381\r
5c08e117 382 //\r
383 // parse the selected option\r
384 //\r
385 Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);\r
386\r
387 if (!EFI_ERROR (Status)) {\r
388 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));\r
389 PlatformBdsBootSuccess (gOption);\r
390 } else {\r
391 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));\r
392 PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);\r
393 gST->ConOut->OutputString (\r
394 gST->ConOut,\r
395 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))\r
396 );\r
397 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
398 }\r
399}\r