2 The platform device manager reference implementation
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "DeviceManager.h"
16 #include <Guid/HiiPlatformSetupFormset.h>
18 DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate
= {
19 DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE
,
29 EFI_GUID mDeviceManagerGuid
= DEVICE_MANAGER_FORMSET_GUID
;
31 DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable
[] = {
32 { STRING_TOKEN (STR_DISK_DEVICE
), EFI_DISK_DEVICE_CLASS
},
33 { STRING_TOKEN (STR_VIDEO_DEVICE
), EFI_VIDEO_DEVICE_CLASS
},
34 { STRING_TOKEN (STR_NETWORK_DEVICE
), EFI_NETWORK_DEVICE_CLASS
},
35 { STRING_TOKEN (STR_INPUT_DEVICE
), EFI_INPUT_DEVICE_CLASS
},
36 { STRING_TOKEN (STR_ON_BOARD_DEVICE
), EFI_ON_BOARD_DEVICE_CLASS
},
37 { STRING_TOKEN (STR_OTHER_DEVICE
), EFI_OTHER_DEVICE_CLASS
}
40 HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath
= {
46 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
47 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
51 // {102579A0-3686-466e-ACD8-80C087044F4A}
53 { 0x102579a0, 0x3686, 0x466e, { 0xac, 0xd8, 0x80, 0xc0, 0x87, 0x4, 0x4f, 0x4a } }
57 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
59 (UINT8
) (END_DEVICE_PATH_LENGTH
),
60 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
66 This function is invoked if user selected a iteractive opcode from Device Manager's
67 Formset. The decision by user is saved to gCallbackKey for later processing. If
68 user set VBIOS, the new value is saved to EFI variable.
70 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
71 @param Action Specifies the type of action taken by the browser.
72 @param QuestionId A unique value which is sent to the original exporting driver
73 so that it can identify the type of data to expect.
74 @param Type The type of value for the question.
75 @param Value A pointer to the data being sent to the original exporting driver.
76 @param ActionRequest On return, points to the action requested by the callback function.
78 @retval EFI_SUCCESS The callback successfully handled the action.
79 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
84 DeviceManagerCallback (
85 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
86 IN EFI_BROWSER_ACTION Action
,
87 IN EFI_QUESTION_ID QuestionId
,
89 IN EFI_IFR_TYPE_VALUE
*Value
,
90 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
93 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
94 return EFI_INVALID_PARAMETER
;
98 gCallbackKey
= QuestionId
;
101 // Request to exit SendForm(), so as to switch to selected form
103 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
111 This function registers HII packages to HII database.
113 @retval EFI_SUCCESS HII packages for the Device Manager were registered successfully.
114 @retval EFI_OUT_OF_RESOURCES HII packages for the Device Manager failed to be registered.
118 InitializeDeviceManager (
125 // Install Device Path Protocol and Config Access protocol to driver handle
127 Status
= gBS
->InstallMultipleProtocolInterfaces (
128 &gDeviceManagerPrivate
.DriverHandle
,
129 &gEfiDevicePathProtocolGuid
,
130 &mDeviceManagerHiiVendorDevicePath
,
131 &gEfiHiiConfigAccessProtocolGuid
,
132 &gDeviceManagerPrivate
.ConfigAccess
,
135 ASSERT_EFI_ERROR (Status
);
138 // Publish our HII data
140 gDeviceManagerPrivate
.HiiHandle
= HiiAddPackages (
142 gDeviceManagerPrivate
.DriverHandle
,
147 if (gDeviceManagerPrivate
.HiiHandle
== NULL
) {
148 Status
= EFI_OUT_OF_RESOURCES
;
150 Status
= EFI_SUCCESS
;
156 Extract the displayed formset for given HII handle and class guid.
158 @param Handle The HII handle.
159 @param SetupClassGuid The class guid specifies which form set will be displayed.
160 @param FormSetTitle Formset title string.
161 @param FormSetHelp Formset help string.
163 @retval TRUE The formset for given HII handle will be displayed.
164 @return FALSE The formset for given HII handle will not be displayed.
168 ExtractDisplayedHiiFormFromHiiHandle (
169 IN EFI_HII_HANDLE Handle
,
170 IN EFI_GUID
*SetupClassGuid
,
171 OUT EFI_STRING_ID
*FormSetTitle
,
172 OUT EFI_STRING_ID
*FormSetHelp
177 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
182 UINT32 PackageListLength
;
183 EFI_HII_PACKAGE_HEADER PackageHeader
;
187 ASSERT (Handle
!= NULL
);
188 ASSERT (SetupClassGuid
!= NULL
);
189 ASSERT (FormSetTitle
!= NULL
);
190 ASSERT (FormSetHelp
!= NULL
);
198 // Get HII PackageList
201 HiiPackageList
= NULL
;
202 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
204 // Handle is a invalid handle. Check if Handle is corrupted.
206 ASSERT (Status
!= EFI_NOT_FOUND
);
208 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
210 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
212 HiiPackageList
= AllocatePool (BufferSize
);
213 ASSERT (HiiPackageList
!= NULL
);
215 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
216 if (EFI_ERROR (Status
)) {
221 // Get Form package from this HII package List
223 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
225 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
227 while (Offset
< PackageListLength
) {
228 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
229 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
231 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
233 // Search FormSet Opcode in this Form Package
235 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
236 while (Offset2
< PackageHeader
.Length
) {
237 OpCodeData
= Package
+ Offset2
;
239 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
241 // Find FormSet OpCode
243 ClassGuidNum
= ((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
;
244 ClassGuid
= (EFI_GUID
*) (VOID
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
245 while (ClassGuidNum
-- > 0) {
246 if (CompareGuid (SetupClassGuid
, ClassGuid
)) {
247 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
248 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
249 FreePool (HiiPackageList
);
258 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
263 // Go to next package
265 Offset
+= PackageHeader
.Length
;
268 FreePool (HiiPackageList
);
274 Call the browser and display the device manager to allow user
275 to configure the platform.
277 This function create the dynamic content for device manager. It includes
278 section header for all class of devices, one-of opcode to set VBIOS.
280 @retval EFI_SUCCESS Operation is successful.
281 @return Other values if failed to clean up the dynamic content from HII
294 EFI_STRING_ID TokenHelp
;
295 EFI_HII_HANDLE
*HiiHandles
;
296 EFI_HII_HANDLE HiiHandle
;
297 EFI_STRING_ID FormSetTitle
;
298 EFI_STRING_ID FormSetHelp
;
299 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
300 VOID
*StartOpCodeHandle
;
301 VOID
*EndOpCodeHandle
;
302 EFI_IFR_GUID_LABEL
*StartLabel
;
303 EFI_IFR_GUID_LABEL
*EndLabel
;
306 Status
= EFI_SUCCESS
;
310 // Connect all prior to entering the platform setup menu.
312 if (!gConnectAllHappened
) {
313 BdsLibConnectAllDriversToAllControllers ();
314 gConnectAllHappened
= TRUE
;
318 // Create Subtitle OpCodes
321 // Allocate space for creation of UpdateData Buffer
323 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
324 ASSERT (StartOpCodeHandle
!= NULL
);
326 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
327 ASSERT (EndOpCodeHandle
!= NULL
);
330 // Create Hii Extend Label OpCode as the start opcode
332 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
333 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
334 StartLabel
->Number
= LABEL_DEVICES_LIST
;
337 // Create Hii Extend Label OpCode as the end opcode
339 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
340 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
341 EndLabel
->Number
= LABEL_END
;
343 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DEVICES_LIST
), 0, 0, 1);
346 // Get all the Hii handles
348 HiiHandles
= HiiGetHiiHandles (NULL
);
349 ASSERT (HiiHandles
!= NULL
);
351 HiiHandle
= gDeviceManagerPrivate
.HiiHandle
;
354 // Search for formset of each class type
356 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
357 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles
[Index
], &gEfiHiiPlatformSetupFormsetGuid
, &FormSetTitle
, &FormSetHelp
)) {
361 String
= HiiGetString (HiiHandles
[Index
], FormSetTitle
, NULL
);
362 ASSERT (String
!= NULL
);
363 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
366 String
= HiiGetString (HiiHandles
[Index
], FormSetHelp
, NULL
);
367 ASSERT (String
!= NULL
);
368 TokenHelp
= HiiSetString (HiiHandle
, 0, String
, NULL
);
371 HiiCreateActionOpCode (
373 (EFI_QUESTION_ID
) (Index
+ DEVICE_KEY_OFFSET
),
376 EFI_IFR_FLAG_CALLBACK
,
382 // Add End Opcode for Subtitle
384 HiiCreateEndOpCode (StartOpCodeHandle
);
389 DEVICE_MANAGER_FORM_ID
,
394 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
395 Status
= gFormBrowser2
->SendForm (
404 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
405 EnableResetRequired ();
409 // We will have returned from processing a callback - user either hit ESC to exit, or selected
410 // a target to display
412 if (gCallbackKey
!= 0) {
413 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
414 Status
= gFormBrowser2
->SendForm (
416 &HiiHandles
[gCallbackKey
- DEVICE_KEY_OFFSET
],
424 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
425 EnableResetRequired ();
429 // Force return to Device Manager
431 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
435 // Cleanup dynamic created strings in HII database by reinstall the packagelist
437 HiiRemovePackages (HiiHandle
);
439 gDeviceManagerPrivate
.HiiHandle
= HiiAddPackages (
441 gDeviceManagerPrivate
.DriverHandle
,
446 if (gDeviceManagerPrivate
.HiiHandle
== NULL
) {
447 Status
= EFI_OUT_OF_RESOURCES
;
449 Status
= EFI_SUCCESS
;
452 HiiFreeOpCodeHandle (StartOpCodeHandle
);
453 HiiFreeOpCodeHandle (EndOpCodeHandle
);
454 FreePool (HiiHandles
);