]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c
Fix the potential issue that using integrate as BOOLEAN value in judgment.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / DeviceMngr / DeviceManager.c
CommitLineData
5c08e117 1/** @file\r
2 The platform device manager reference implementation\r
3\r
4Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
5All rights reserved. This 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 "DeviceManager.h"\r
75bf9d0e 16#include <Guid/HiiPlatformSetupFormset.h>\r
5c08e117 17\r
18DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate = {\r
19 DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE,\r
20 NULL,\r
21 NULL,\r
22 {\r
23 FakeExtractConfig,\r
24 FakeRouteConfig,\r
25 DeviceManagerCallback\r
26 }\r
27};\r
28\r
29EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID;\r
30\r
31DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable[] = {\r
32 { STRING_TOKEN (STR_DISK_DEVICE), EFI_DISK_DEVICE_CLASS },\r
33 { STRING_TOKEN (STR_VIDEO_DEVICE), EFI_VIDEO_DEVICE_CLASS },\r
34 { STRING_TOKEN (STR_NETWORK_DEVICE), EFI_NETWORK_DEVICE_CLASS },\r
35 { STRING_TOKEN (STR_INPUT_DEVICE), EFI_INPUT_DEVICE_CLASS },\r
36 { STRING_TOKEN (STR_ON_BOARD_DEVICE), EFI_ON_BOARD_DEVICE_CLASS },\r
37 { STRING_TOKEN (STR_OTHER_DEVICE), EFI_OTHER_DEVICE_CLASS }\r
38};\r
39\r
f6f910dd 40HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath = {\r
41 {\r
42 {\r
43 HARDWARE_DEVICE_PATH,\r
44 HW_VENDOR_DP,\r
45 {\r
46 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
47 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
48 }\r
49 },\r
50 //\r
51 // {102579A0-3686-466e-ACD8-80C087044F4A}\r
52 //\r
53 { 0x102579a0, 0x3686, 0x466e, { 0xac, 0xd8, 0x80, 0xc0, 0x87, 0x4, 0x4f, 0x4a } }\r
54 },\r
55 {\r
56 END_DEVICE_PATH_TYPE,\r
57 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
58 { \r
59 (UINT8) (END_DEVICE_PATH_LENGTH),\r
60 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
61 }\r
62 }\r
63};\r
64\r
5c08e117 65/**\r
66 This function is invoked if user selected a iteractive opcode from Device Manager's\r
67 Formset. The decision by user is saved to gCallbackKey for later processing. If\r
68 user set VBIOS, the new value is saved to EFI variable.\r
69\r
70 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
71 @param Action Specifies the type of action taken by the browser.\r
72 @param QuestionId A unique value which is sent to the original exporting driver\r
73 so that it can identify the type of data to expect.\r
74 @param Type The type of value for the question.\r
75 @param Value A pointer to the data being sent to the original exporting driver.\r
76 @param ActionRequest On return, points to the action requested by the callback function.\r
77\r
78 @retval EFI_SUCCESS The callback successfully handled the action.\r
79 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
80\r
81**/\r
82EFI_STATUS\r
83EFIAPI\r
84DeviceManagerCallback (\r
85 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
86 IN EFI_BROWSER_ACTION Action,\r
87 IN EFI_QUESTION_ID QuestionId,\r
88 IN UINT8 Type,\r
89 IN EFI_IFR_TYPE_VALUE *Value,\r
90 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
91 )\r
92{\r
5c08e117 93 if ((Value == NULL) || (ActionRequest == NULL)) {\r
94 return EFI_INVALID_PARAMETER;\r
95 }\r
96\r
5c08e117 97\r
6aa22a17 98 gCallbackKey = QuestionId;\r
5c08e117 99\r
6aa22a17 100 //\r
101 // Request to exit SendForm(), so as to switch to selected form\r
102 //\r
103 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
5c08e117 104\r
5c08e117 105\r
106 return EFI_SUCCESS;\r
107}\r
108\r
109/**\r
110\r
111 This function registers HII packages to HII database.\r
112\r
cb7d01c0 113 @retval EFI_SUCCESS HII packages for the Device Manager were registered successfully.\r
114 @retval EFI_OUT_OF_RESOURCES HII packages for the Device Manager failed to be registered.\r
5c08e117 115\r
116**/\r
117EFI_STATUS\r
118InitializeDeviceManager (\r
119 VOID\r
120 )\r
121{\r
122 EFI_STATUS Status;\r
5c08e117 123\r
124 //\r
f6f910dd 125 // Install Device Path Protocol and Config Access protocol to driver handle\r
5c08e117 126 //\r
f6f910dd 127 Status = gBS->InstallMultipleProtocolInterfaces (\r
5c08e117 128 &gDeviceManagerPrivate.DriverHandle,\r
f6f910dd 129 &gEfiDevicePathProtocolGuid,\r
130 &mDeviceManagerHiiVendorDevicePath,\r
5c08e117 131 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 132 &gDeviceManagerPrivate.ConfigAccess,\r
133 NULL\r
5c08e117 134 );\r
135 ASSERT_EFI_ERROR (Status);\r
136\r
137 //\r
138 // Publish our HII data\r
139 //\r
cb7d01c0 140 gDeviceManagerPrivate.HiiHandle = HiiAddPackages (\r
141 &mDeviceManagerGuid,\r
142 gDeviceManagerPrivate.DriverHandle,\r
143 DeviceManagerVfrBin,\r
144 BdsDxeStrings,\r
145 NULL\r
146 );\r
147 if (gDeviceManagerPrivate.HiiHandle == NULL) {\r
148 Status = EFI_OUT_OF_RESOURCES;\r
149 } else {\r
150 Status = EFI_SUCCESS;\r
151 }\r
5c08e117 152 return Status;\r
153}\r
154\r
75bf9d0e
LG
155/**\r
156 Extract the displayed formset for given HII handle and class guid.\r
157\r
158 @param Handle The HII handle.\r
159 @param SetupClassGuid The class guid specifies which form set will be displayed.\r
160 @param FormSetTitle Formset title string.\r
161 @param FormSetHelp Formset help string.\r
162\r
163 @retval TRUE The formset for given HII handle will be displayed.\r
164 @return FALSE The formset for given HII handle will not be displayed.\r
165\r
166**/\r
167BOOLEAN\r
168ExtractDisplayedHiiFormFromHiiHandle (\r
169 IN EFI_HII_HANDLE Handle,\r
170 IN EFI_GUID *SetupClassGuid,\r
171 OUT EFI_STRING_ID *FormSetTitle,\r
172 OUT EFI_STRING_ID *FormSetHelp\r
173 )\r
174{\r
175 EFI_STATUS Status;\r
176 UINTN BufferSize;\r
177 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
178 UINT8 *Package;\r
179 UINT8 *OpCodeData;\r
180 UINT32 Offset;\r
181 UINT32 Offset2;\r
182 UINT32 PackageListLength;\r
183 EFI_HII_PACKAGE_HEADER PackageHeader;\r
184 EFI_GUID *ClassGuid;\r
185 UINT8 ClassGuidNum;\r
186\r
187 ASSERT (Handle != NULL);\r
188 ASSERT (SetupClassGuid != NULL); \r
189 ASSERT (FormSetTitle != NULL);\r
190 ASSERT (FormSetHelp != NULL);\r
191\r
192 *FormSetTitle = 0;\r
193 *FormSetHelp = 0;\r
194 ClassGuidNum = 0;\r
195 ClassGuid = NULL;\r
196\r
197 //\r
198 // Get HII PackageList\r
199 //\r
200 BufferSize = 0;\r
201 HiiPackageList = NULL;\r
202 Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
203 //\r
204 // Handle is a invalid handle. Check if Handle is corrupted.\r
205 //\r
206 ASSERT (Status != EFI_NOT_FOUND);\r
207 //\r
208 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.\r
209 //\r
210 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
211 \r
212 HiiPackageList = AllocatePool (BufferSize);\r
213 ASSERT (HiiPackageList != NULL);\r
214\r
215 Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
216 if (EFI_ERROR (Status)) {\r
217 return FALSE;\r
218 }\r
219\r
220 //\r
221 // Get Form package from this HII package List\r
222 //\r
223 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
224 Offset2 = 0;\r
225 PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);\r
226\r
227 while (Offset < PackageListLength) {\r
228 Package = ((UINT8 *) HiiPackageList) + Offset;\r
229 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
230\r
231 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
232 //\r
233 // Search FormSet Opcode in this Form Package\r
234 //\r
235 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
236 while (Offset2 < PackageHeader.Length) {\r
237 OpCodeData = Package + Offset2;\r
238\r
239 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
240 //\r
241 // Find FormSet OpCode\r
242 //\r
243 ClassGuidNum = ((EFI_IFR_FORM_SET *) OpCodeData)->Flags;\r
244 ClassGuid = (EFI_GUID *) (VOID *)(OpCodeData + sizeof (EFI_IFR_FORM_SET));\r
245 while (ClassGuidNum-- > 0) {\r
246 if (CompareGuid (SetupClassGuid, ClassGuid)) {\r
247 CopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
248 CopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
249 FreePool (HiiPackageList);\r
250 return TRUE;\r
251 }\r
252 }\r
253 }\r
254 \r
255 //\r
256 // Go to next opcode\r
257 //\r
258 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
259 }\r
260 }\r
261 \r
262 //\r
263 // Go to next package\r
264 //\r
265 Offset += PackageHeader.Length;\r
266 }\r
267\r
268 FreePool (HiiPackageList);\r
269\r
270 return FALSE;\r
271}\r
272\r
5c08e117 273/**\r
274 Call the browser and display the device manager to allow user\r
275 to configure the platform.\r
276\r
277 This function create the dynamic content for device manager. It includes\r
278 section header for all class of devices, one-of opcode to set VBIOS.\r
279 \r
280 @retval EFI_SUCCESS Operation is successful.\r
281 @return Other values if failed to clean up the dynamic content from HII\r
282 database.\r
283\r
284**/\r
285EFI_STATUS\r
286CallDeviceManager (\r
287 VOID\r
288 )\r
289{\r
290 EFI_STATUS Status;\r
5c08e117 291 UINTN Index;\r
cb7d01c0 292 EFI_STRING String;\r
5c08e117 293 EFI_STRING_ID Token;\r
294 EFI_STRING_ID TokenHelp;\r
5c08e117 295 EFI_HII_HANDLE *HiiHandles;\r
5c08e117 296 EFI_HII_HANDLE HiiHandle;\r
5c08e117 297 EFI_STRING_ID FormSetTitle;\r
298 EFI_STRING_ID FormSetHelp;\r
299 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
75bf9d0e
LG
300 VOID *StartOpCodeHandle;\r
301 VOID *EndOpCodeHandle;\r
302 EFI_IFR_GUID_LABEL *StartLabel;\r
303 EFI_IFR_GUID_LABEL *EndLabel;\r
5c08e117 304\r
75bf9d0e 305 HiiHandles = NULL;\r
5c08e117 306 Status = EFI_SUCCESS;\r
307 gCallbackKey = 0;\r
308\r
309 //\r
310 // Connect all prior to entering the platform setup menu.\r
311 //\r
312 if (!gConnectAllHappened) {\r
313 BdsLibConnectAllDriversToAllControllers ();\r
314 gConnectAllHappened = TRUE;\r
315 }\r
316\r
317 //\r
318 // Create Subtitle OpCodes\r
319 //\r
75bf9d0e
LG
320 //\r
321 // Allocate space for creation of UpdateData Buffer\r
322 //\r
323 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
324 ASSERT (StartOpCodeHandle != NULL);\r
5c08e117 325\r
75bf9d0e
LG
326 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
327 ASSERT (EndOpCodeHandle != NULL);\r
328\r
329 //\r
330 // Create Hii Extend Label OpCode as the start opcode\r
331 //\r
332 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
333 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
334 StartLabel->Number = LABEL_DEVICES_LIST;\r
335\r
336 //\r
337 // Create Hii Extend Label OpCode as the end opcode\r
338 //\r
339 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
340 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
341 EndLabel->Number = LABEL_END;\r
342\r
343 HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_DEVICES_LIST), 0, 0, 1);\r
5c08e117 344\r
345 //\r
346 // Get all the Hii handles\r
347 //\r
cb7d01c0 348 HiiHandles = HiiGetHiiHandles (NULL);\r
349 ASSERT (HiiHandles != NULL);\r
5c08e117 350\r
351 HiiHandle = gDeviceManagerPrivate.HiiHandle;\r
352\r
5c08e117 353 //\r
354 // Search for formset of each class type\r
355 //\r
cb7d01c0 356 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
75bf9d0e 357 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles[Index], &gEfiHiiPlatformSetupFormsetGuid, &FormSetTitle, &FormSetHelp)) {\r
5c08e117 358 continue;\r
359 }\r
360\r
cb7d01c0 361 String = HiiGetString (HiiHandles[Index], FormSetTitle, NULL);\r
0e8e994d 362 if (String == NULL) {\r
363 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);\r
364 ASSERT (String != NULL);\r
365 }\r
cb7d01c0 366 Token = HiiSetString (HiiHandle, 0, String, NULL);\r
367 FreePool (String);\r
5c08e117 368\r
cb7d01c0 369 String = HiiGetString (HiiHandles[Index], FormSetHelp, NULL);\r
0e8e994d 370 if (String == NULL) {\r
371 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);\r
372 ASSERT (String != NULL);\r
373 }\r
cb7d01c0 374 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);\r
375 FreePool (String);\r
5c08e117 376\r
75bf9d0e
LG
377 HiiCreateActionOpCode (\r
378 StartOpCodeHandle,\r
379 (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET),\r
380 Token,\r
381 TokenHelp,\r
382 EFI_IFR_FLAG_CALLBACK,\r
383 0\r
5c08e117 384 );\r
385 }\r
386\r
75bf9d0e
LG
387 //\r
388 // Add End Opcode for Subtitle\r
389 //\r
390 HiiCreateEndOpCode (StartOpCodeHandle);\r
391\r
392 HiiUpdateForm (\r
393 HiiHandle,\r
394 &mDeviceManagerGuid,\r
395 DEVICE_MANAGER_FORM_ID,\r
396 StartOpCodeHandle,\r
397 EndOpCodeHandle\r
398 );\r
399\r
5c08e117 400 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
401 Status = gFormBrowser2->SendForm (\r
402 gFormBrowser2,\r
403 &HiiHandle,\r
404 1,\r
75bf9d0e 405 &mDeviceManagerGuid,\r
5c08e117 406 0,\r
407 NULL,\r
408 &ActionRequest\r
409 );\r
410 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
411 EnableResetRequired ();\r
412 }\r
413\r
414 //\r
415 // We will have returned from processing a callback - user either hit ESC to exit, or selected\r
416 // a target to display\r
417 //\r
418 if (gCallbackKey != 0) {\r
419 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
420 Status = gFormBrowser2->SendForm (\r
421 gFormBrowser2,\r
422 &HiiHandles[gCallbackKey - DEVICE_KEY_OFFSET],\r
423 1,\r
424 NULL,\r
425 0,\r
426 NULL,\r
427 &ActionRequest\r
428 );\r
429\r
430 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
431 EnableResetRequired ();\r
432 }\r
433\r
434 //\r
435 // Force return to Device Manager\r
436 //\r
437 gCallbackKey = FRONT_PAGE_KEY_DEVICE_MANAGER;\r
438 }\r
439\r
440 //\r
441 // Cleanup dynamic created strings in HII database by reinstall the packagelist\r
442 //\r
cb7d01c0 443 HiiRemovePackages (HiiHandle);\r
444\r
445 gDeviceManagerPrivate.HiiHandle = HiiAddPackages (\r
446 &mDeviceManagerGuid,\r
447 gDeviceManagerPrivate.DriverHandle,\r
448 DeviceManagerVfrBin,\r
449 BdsDxeStrings,\r
450 NULL\r
451 );\r
452 if (gDeviceManagerPrivate.HiiHandle == NULL) {\r
453 Status = EFI_OUT_OF_RESOURCES;\r
454 } else {\r
455 Status = EFI_SUCCESS;\r
456 }\r
5c08e117 457\r
75bf9d0e
LG
458 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
459 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
5c08e117 460 FreePool (HiiHandles);\r
461\r
462 return Status;\r
463}\r