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