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