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