]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - IntelFrameworkModulePkg/Universal/BdsDxe/BootMngr/BootManager.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMngr / BootManager.c
... / ...
CommitLineData
1/** @file\r
2 The platform boot manager reference implementation\r
3\r
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
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
18LIST_ENTRY mBootOptionsList;\r
19BDS_COMMON_OPTION *gOption;\r
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
31\r
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
42 BOOT_MANAGER_FORMSET_GUID\r
43 },\r
44 {\r
45 END_DEVICE_PATH_TYPE,\r
46 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
47 {\r
48 (UINT8) (END_DEVICE_PATH_LENGTH),\r
49 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
50 }\r
51 }\r
52};\r
53\r
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
66 This call back function is registered with Boot Manager formset.\r
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
98 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
99 if ((Value == NULL) || (ActionRequest == NULL)) {\r
100 return EFI_INVALID_PARAMETER;\r
101 }\r
102\r
103 //\r
104 // Initialize the key count\r
105 //\r
106 KeyCount = 0;\r
107\r
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
110\r
111 KeyCount++;\r
112\r
113 gOption = Option;\r
114\r
115 //\r
116 // Is this device the one chosen?\r
117 //\r
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
130 }\r
131\r
132 return EFI_SUCCESS;\r
133 }\r
134\r
135 //\r
136 // All other action return unsupported.\r
137 //\r
138 return EFI_UNSUPPORTED;\r
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
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
148\r
149**/\r
150EFI_STATUS\r
151InitializeBootManager (\r
152 VOID\r
153 )\r
154{\r
155 EFI_STATUS Status;\r
156\r
157 //\r
158 // Install Device Path Protocol and Config Access protocol to driver handle\r
159 //\r
160 Status = gBS->InstallMultipleProtocolInterfaces (\r
161 &gBootManagerPrivate.DriverHandle,\r
162 &gEfiDevicePathProtocolGuid,\r
163 &mBootManagerHiiVendorDevicePath,\r
164 &gEfiHiiConfigAccessProtocolGuid,\r
165 &gBootManagerPrivate.ConfigAccess,\r
166 NULL\r
167 );\r
168 ASSERT_EFI_ERROR (Status);\r
169\r
170 //\r
171 // Publish our HII data\r
172 //\r
173 gBootManagerPrivate.HiiHandle = HiiAddPackages (\r
174 &gBootManagerFormSetGuid,\r
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
185 return Status;\r
186}\r
187\r
188/**\r
189 This function invokes Boot Manager. If all devices have not a chance to be connected,\r
190 the connect all will be triggered. It then enumerate all boot options. If\r
191 a boot option from the Boot Manager page is selected, Boot Manager will boot\r
192 from this boot option.\r
193\r
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
203 CHAR16 *ExitData;\r
204 UINTN ExitDataSize;\r
205 EFI_STRING_ID Token;\r
206 EFI_INPUT_KEY Key;\r
207 CHAR16 *HelpString;\r
208 UINTN HelpSize;\r
209 EFI_STRING_ID HelpToken;\r
210 UINT16 *TempStr;\r
211 EFI_HII_HANDLE HiiHandle;\r
212 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
213 VOID *StartOpCodeHandle;\r
214 VOID *EndOpCodeHandle;\r
215 EFI_IFR_GUID_LABEL *StartLabel;\r
216 EFI_IFR_GUID_LABEL *EndLabel;\r
217 UINT16 DeviceType;\r
218 BOOLEAN IsLegacyOption;\r
219 BOOLEAN NeedEndOp;\r
220\r
221 DeviceType = (UINT16) -1;\r
222 gOption = NULL;\r
223 InitializeListHead (&mBootOptionsList);\r
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
232\r
233 BdsLibEnumerateAllBootOption (&mBootOptionsList);\r
234\r
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
243 HiiHandle = gBootManagerPrivate.HiiHandle;\r
244\r
245 //\r
246 // Allocate space for creation of UpdateData Buffer\r
247 //\r
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
267\r
268 mKeyInput = 0;\r
269 NeedEndOp = FALSE;\r
270 for (Link = GetFirstNode (&mBootOptionsList); !IsNull (&mBootOptionsList, Link); Link = GetNextNode (&mBootOptionsList, Link)) {\r
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
279 // Don't display the hidden/inactive boot option\r
280 //\r
281 if (((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) || ((Option->Attribute & LOAD_OPTION_ACTIVE) == 0)) {\r
282 continue;\r
283 }\r
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
297\r
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
308 MIN (DeviceType & 0xF, ARRAY_SIZE (mDeviceTypeStr) - 1)\r
309 ],\r
310 NULL\r
311 );\r
312 HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);\r
313 NeedEndOp = TRUE;\r
314 }\r
315\r
316 ASSERT (Option->Description != NULL);\r
317\r
318 Token = HiiSetString (HiiHandle, 0, Option->Description, NULL);\r
319\r
320 TempStr = DevicePathToStr (Option->DevicePath);\r
321 HelpSize = StrSize (TempStr) + StrSize (L"Device Path : ");\r
322 HelpString = AllocateZeroPool (HelpSize);\r
323 ASSERT (HelpString != NULL);\r
324 StrCatS (HelpString, HelpSize / sizeof (CHAR16), L"Device Path : ");\r
325 StrCatS (HelpString, HelpSize / sizeof (CHAR16), TempStr);\r
326\r
327 HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL);\r
328\r
329 HiiCreateActionOpCode (\r
330 StartOpCodeHandle,\r
331 mKeyInput,\r
332 Token,\r
333 HelpToken,\r
334 EFI_IFR_FLAG_CALLBACK,\r
335 0\r
336 );\r
337 }\r
338\r
339 if (NeedEndOp) {\r
340 HiiCreateEndOpCode (StartOpCodeHandle);\r
341 }\r
342\r
343 HiiUpdateForm (\r
344 HiiHandle,\r
345 &gBootManagerFormSetGuid,\r
346 BOOT_MANAGER_FORM_ID,\r
347 StartOpCodeHandle,\r
348 EndOpCodeHandle\r
349 );\r
350\r
351 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
352 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
353\r
354 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
355 Status = gFormBrowser2->SendForm (\r
356 gFormBrowser2,\r
357 &HiiHandle,\r
358 1,\r
359 &gBootManagerFormSetGuid,\r
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
373 // Will leave browser, check any reset required change is applied? if yes, reset system\r
374 //\r
375 SetupResetReminder ();\r
376\r
377 //\r
378 // Restore to original mode before launching boot option.\r
379 //\r
380 BdsSetConsoleMode (FALSE);\r
381\r
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