]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/UiApp/BootMngr/BootManager.c
UiApp: Update copyright info, cover old code existed in old BdsDxe driver.
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / BootMngr / BootManager.c
CommitLineData
143f0b1d
ED
1/** @file\r
2 The platform boot manager reference implementation\r
3\r
afc244a5 4Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
143f0b1d
ED
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
17EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;\r
18CHAR16 *mDeviceTypeStr[] = {\r
19 L"Legacy BEV",\r
20 L"Legacy Floppy",\r
21 L"Legacy Hard Drive",\r
22 L"Legacy CD ROM",\r
23 L"Legacy PCMCIA",\r
24 L"Legacy USB",\r
25 L"Legacy Embedded Network",\r
26 L"Legacy Unknown Device"\r
27};\r
28\r
29\r
30HII_VENDOR_DEVICE_PATH mBootManagerHiiVendorDevicePath = {\r
31 {\r
32 {\r
33 HARDWARE_DEVICE_PATH,\r
34 HW_VENDOR_DP,\r
35 {\r
36 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
37 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
38 }\r
39 },\r
40 //\r
41 // {1DDDBE15-481D-4d2b-8277-B191EAF66525}\r
42 //\r
43 { 0x1dddbe15, 0x481d, 0x4d2b, { 0x82, 0x77, 0xb1, 0x91, 0xea, 0xf6, 0x65, 0x25 } }\r
44 },\r
45 {\r
46 END_DEVICE_PATH_TYPE,\r
47 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
48 { \r
49 (UINT8) (END_DEVICE_PATH_LENGTH),\r
50 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
51 }\r
52 }\r
53};\r
54\r
55BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate = {\r
56 BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,\r
57 NULL,\r
58 NULL,\r
59 {\r
60 FakeExtractConfig,\r
61 FakeRouteConfig,\r
62 BootManagerCallback\r
63 }\r
64};\r
65\r
66/**\r
67 This call back function is registered with Boot Manager formset.\r
68 When user selects a boot option, this call back function will\r
69 be triggered. The boot option is saved for later processing.\r
70\r
71\r
72 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
73 @param Action Specifies the type of action taken by the browser.\r
74 @param QuestionId A unique value which is sent to the original exporting driver\r
75 so that it can identify the type of data to expect.\r
76 @param Type The type of value for the question.\r
77 @param Value A pointer to the data being sent to the original exporting driver.\r
78 @param ActionRequest On return, points to the action requested by the callback function.\r
79\r
80 @retval EFI_SUCCESS The callback successfully handled the action.\r
81 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
82\r
83**/\r
84EFI_STATUS\r
85EFIAPI\r
86BootManagerCallback (\r
87 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
88 IN EFI_BROWSER_ACTION Action,\r
89 IN EFI_QUESTION_ID QuestionId,\r
90 IN UINT8 Type,\r
91 IN EFI_IFR_TYPE_VALUE *Value,\r
92 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
93 )\r
94{\r
95 UINTN Index;\r
96 EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;\r
97 UINTN BootOptionCount;\r
98 UINT16 KeyCount;\r
99 EFI_INPUT_KEY Key;\r
100 EFI_BOOT_MANAGER_LOAD_OPTION Option;\r
101\r
102 if (Action != EFI_BROWSER_ACTION_CHANGED) {\r
103 //\r
104 // Do nothing for other UEFI Action. Only do call back when data is changed.\r
105 //\r
106 return EFI_UNSUPPORTED;\r
107 }\r
108\r
109 if ((Value == NULL) || (ActionRequest == NULL)) {\r
110 return EFI_INVALID_PARAMETER;\r
111 }\r
112\r
113 //\r
114 // Initialize the key count\r
115 //\r
116 KeyCount = 0;\r
117 Option.Attributes = 0;\r
118 BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
119\r
120 for (Index = 0; Index < BootOptionCount; Index++) {\r
121 KeyCount++;\r
122\r
123 EfiBootManagerInitializeLoadOption (\r
124 &Option,\r
125 BootOption[Index].OptionNumber,\r
126 BootOption[Index].OptionType,\r
127 BootOption[Index].Attributes,\r
128 BootOption[Index].Description,\r
129 BootOption[Index].FilePath,\r
130 BootOption[Index].OptionalData,\r
131 BootOption[Index].OptionalDataSize\r
132 );\r
133\r
134 //\r
135 // Is this device the one chosen?\r
136 //\r
137 if (KeyCount == QuestionId) {\r
138 //\r
139 // Clear the screen before.\r
140 //\r
141 gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
142 gST->ConOut->ClearScreen (gST->ConOut);\r
143 //\r
144 // Check any reset required change is applied? if yes, reset system\r
145 //\r
146 SetupResetReminder();\r
147 //\r
148 // Parse the selected option.\r
149 //\r
150 BdsSetConsoleMode(FALSE);\r
151 EfiBootManagerBoot (&Option);\r
152 BdsSetConsoleMode(TRUE);\r
153\r
154 if (EFI_ERROR (Option.Status)) {\r
155 gST->ConOut->OutputString (\r
156 gST->ConOut,\r
157 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))\r
158 );\r
159 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
160 }\r
161 break;\r
162 }\r
163 }\r
164 EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);\r
165\r
166 return EFI_SUCCESS;\r
167}\r
168\r
169/**\r
170 Register HII packages to HII database.\r
171\r
172**/\r
173VOID\r
174InitializeBootManager (\r
175 VOID\r
176 )\r
177{\r
178 EFI_STATUS Status;\r
179\r
180 if (!gConnectAllHappened){\r
181 EfiBootManagerConnectAll();\r
182 gConnectAllHappened = TRUE;\r
183 }\r
184\r
185 //\r
186 // Install Device Path Protocol and Config Access protocol to driver handle\r
187 //\r
188 gBootManagerPrivate.DriverHandle = NULL;\r
189 Status = gBS->InstallMultipleProtocolInterfaces (\r
190 &gBootManagerPrivate.DriverHandle,\r
191 &gEfiDevicePathProtocolGuid,\r
192 &mBootManagerHiiVendorDevicePath,\r
193 &gEfiHiiConfigAccessProtocolGuid,\r
194 &gBootManagerPrivate.ConfigAccess,\r
195 NULL\r
196 );\r
197 ASSERT_EFI_ERROR (Status);\r
198\r
199 //\r
200 // Publish our HII data\r
201 //\r
202 gBootManagerPrivate.HiiHandle = HiiAddPackages (\r
203 &mBootManagerGuid,\r
204 gBootManagerPrivate.DriverHandle,\r
205 BootManagerVfrBin,\r
206 UiAppStrings,\r
207 NULL\r
208 );\r
209 ASSERT(gBootManagerPrivate.HiiHandle != NULL);\r
210}\r
211\r
212\r
213/**\r
214 Enumerate possible boot options.\r
215\r
216**/\r
217VOID\r
218EnumerateBootOptions (\r
219 VOID\r
220 )\r
221{\r
222 UINTN Index;\r
223 EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;\r
224 UINTN BootOptionCount;\r
225 EFI_STRING_ID Token;\r
226 CHAR16 *HelpString;\r
227 EFI_STRING_ID HelpToken;\r
228 UINT16 *TempStr;\r
229 EFI_HII_HANDLE HiiHandle;\r
230 UINTN TempSize;\r
231 VOID *StartOpCodeHandle;\r
232 VOID *EndOpCodeHandle;\r
233 EFI_IFR_GUID_LABEL *StartLabel;\r
234 EFI_IFR_GUID_LABEL *EndLabel;\r
235 UINT16 DeviceType;\r
236 BOOLEAN IsLegacyOption;\r
237 BOOLEAN NeedEndOp;\r
238 UINT16 KeyInput;\r
239\r
240 DeviceType = (UINT16) -1;\r
241\r
242 //\r
243 // for better user experience\r
244 // 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option\r
245 // 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option\r
246 //\r
247 EfiBootManagerRefreshAllBootOption ();\r
248\r
249 BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
250\r
251 HiiHandle = gBootManagerPrivate.HiiHandle;\r
252\r
253 //\r
254 // Allocate space for creation of UpdateData Buffer\r
255 //\r
256 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
257 ASSERT (StartOpCodeHandle != NULL);\r
258\r
259 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
260 ASSERT (EndOpCodeHandle != NULL);\r
261\r
262 //\r
263 // Create Hii Extend Label OpCode as the start opcode\r
264 //\r
265 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
266 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
267 StartLabel->Number = LABEL_BOOT_OPTION;\r
268\r
269 //\r
270 // Create Hii Extend Label OpCode as the end opcode\r
271 //\r
272 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
273 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
274 EndLabel->Number = LABEL_BOOT_OPTION_END;\r
275\r
276 KeyInput = 0;\r
277 NeedEndOp = FALSE;\r
278 for (Index = 0; Index < BootOptionCount; Index++) {\r
279 //\r
280 // At this stage we are creating a menu entry, thus the Keys are reproduceable\r
281 //\r
282 KeyInput++;\r
283\r
284 //\r
285 // Don't display the hidden/inactive boot option\r
286 //\r
287 if (((BootOption[Index].Attributes & LOAD_OPTION_HIDDEN) != 0) || ((BootOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0)) {\r
288 continue;\r
289 }\r
290\r
291 //\r
292 // Group the legacy boot option in the sub title created dynamically\r
293 //\r
294 IsLegacyOption = (BOOLEAN) (\r
295 (DevicePathType (BootOption[Index].FilePath) == BBS_DEVICE_PATH) &&\r
296 (DevicePathSubType (BootOption[Index].FilePath) == BBS_BBS_DP)\r
297 );\r
298\r
299 if (!IsLegacyOption && NeedEndOp) {\r
300 NeedEndOp = FALSE;\r
301 HiiCreateEndOpCode (StartOpCodeHandle);\r
302 }\r
303 \r
304 if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) BootOption[Index].FilePath)->DeviceType) {\r
305 if (NeedEndOp) {\r
306 HiiCreateEndOpCode (StartOpCodeHandle);\r
307 }\r
308\r
309 DeviceType = ((BBS_BBS_DEVICE_PATH *) BootOption[Index].FilePath)->DeviceType;\r
310 Token = HiiSetString (\r
311 HiiHandle,\r
312 0,\r
313 mDeviceTypeStr[\r
314 MIN (DeviceType & 0xF, sizeof (mDeviceTypeStr) / sizeof (mDeviceTypeStr[0]) - 1)\r
315 ],\r
316 NULL\r
317 );\r
318 HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);\r
319 NeedEndOp = TRUE;\r
320 }\r
321\r
322 ASSERT (BootOption[Index].Description != NULL);\r
323 \r
324 Token = HiiSetString (HiiHandle, 0, BootOption[Index].Description, NULL);\r
325\r
326 TempStr = UiDevicePathToStr (BootOption[Index].FilePath);\r
327 TempSize = StrSize (TempStr);\r
328 HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));\r
329 ASSERT (HelpString != NULL);\r
330 StrCat (HelpString, L"Device Path : ");\r
331 StrCat (HelpString, TempStr);\r
332\r
333 HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL);\r
334\r
335 HiiCreateActionOpCode (\r
336 StartOpCodeHandle,\r
337 KeyInput,\r
338 Token,\r
339 HelpToken,\r
340 EFI_IFR_FLAG_CALLBACK,\r
341 0\r
342 );\r
343 }\r
344\r
345 if (NeedEndOp) {\r
346 HiiCreateEndOpCode (StartOpCodeHandle);\r
347 }\r
348\r
349 HiiUpdateForm (\r
350 HiiHandle,\r
351 &mBootManagerGuid,\r
352 BOOT_MANAGER_FORM_ID,\r
353 StartOpCodeHandle,\r
354 EndOpCodeHandle\r
355 );\r
356\r
357 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
358 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
359 \r
360 EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);\r
361}\r
362\r
363\r
364/**\r
365 Remove the installed packages from the HII Database. \r
366\r
367**/\r
368VOID\r
369FreeBootManager (\r
370 VOID\r
371 )\r
372{\r
373 EFI_STATUS Status;\r
374 Status = gBS->UninstallMultipleProtocolInterfaces (\r
375 gBootManagerPrivate.DriverHandle,\r
376 &gEfiDevicePathProtocolGuid,\r
377 &mBootManagerHiiVendorDevicePath,\r
378 &gEfiHiiConfigAccessProtocolGuid,\r
379 &gBootManagerPrivate.ConfigAccess,\r
380 NULL\r
381 );\r
382 ASSERT_EFI_ERROR (Status);\r
383 \r
384 HiiRemovePackages (gBootManagerPrivate.HiiHandle);\r
385}\r