]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c
Move BdsDxe and GenericBdsLib to IntelFrameworkModulePkg, these modules need dependen...
[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
17 DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate = {
18 DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE,
19 NULL,
20 NULL,
21 {
22 FakeExtractConfig,
23 FakeRouteConfig,
24 DeviceManagerCallback
25 }
26 };
27
28 EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID;
29
30 DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable[] = {
31 { STRING_TOKEN (STR_DISK_DEVICE), EFI_DISK_DEVICE_CLASS },
32 { STRING_TOKEN (STR_VIDEO_DEVICE), EFI_VIDEO_DEVICE_CLASS },
33 { STRING_TOKEN (STR_NETWORK_DEVICE), EFI_NETWORK_DEVICE_CLASS },
34 { STRING_TOKEN (STR_INPUT_DEVICE), EFI_INPUT_DEVICE_CLASS },
35 { STRING_TOKEN (STR_ON_BOARD_DEVICE), EFI_ON_BOARD_DEVICE_CLASS },
36 { STRING_TOKEN (STR_OTHER_DEVICE), EFI_OTHER_DEVICE_CLASS }
37 };
38
39 #define MENU_ITEM_NUM \
40 (sizeof (mDeviceManagerMenuItemTable) / sizeof (DEVICE_MANAGER_MENU_ITEM))
41
42 /**
43 This function is invoked if user selected a iteractive opcode from Device Manager's
44 Formset. The decision by user is saved to gCallbackKey for later processing. If
45 user set VBIOS, the new value is saved to EFI variable.
46
47 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
48 @param Action Specifies the type of action taken by the browser.
49 @param QuestionId A unique value which is sent to the original exporting driver
50 so that it can identify the type of data to expect.
51 @param Type The type of value for the question.
52 @param Value A pointer to the data being sent to the original exporting driver.
53 @param ActionRequest On return, points to the action requested by the callback function.
54
55 @retval EFI_SUCCESS The callback successfully handled the action.
56 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
57
58 **/
59 EFI_STATUS
60 EFIAPI
61 DeviceManagerCallback (
62 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
63 IN EFI_BROWSER_ACTION Action,
64 IN EFI_QUESTION_ID QuestionId,
65 IN UINT8 Type,
66 IN EFI_IFR_TYPE_VALUE *Value,
67 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
68 )
69 {
70 DEVICE_MANAGER_CALLBACK_DATA *PrivateData;
71
72 if ((Value == NULL) || (ActionRequest == NULL)) {
73 return EFI_INVALID_PARAMETER;
74 }
75
76 PrivateData = DEVICE_MANAGER_CALLBACK_DATA_FROM_THIS (This);
77
78 switch (QuestionId) {
79 case DEVICE_MANAGER_KEY_VBIOS:
80 PrivateData->VideoBios = Value->u8;
81 gRT->SetVariable (
82 L"VBIOS",
83 &gEfiGenericPlatformVariableGuid,
84 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
85 sizeof (UINT8),
86 &PrivateData->VideoBios
87 );
88
89 //
90 // Tell browser not to ask for confirmation of changes,
91 // since we have already applied.
92 //
93 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
94 break;
95
96 default:
97 //
98 // The key corresponds the Handle Index which was requested to be displayed
99 //
100 gCallbackKey = QuestionId;
101
102 //
103 // Request to exit SendForm(), so as to switch to selected form
104 //
105 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
106 break;
107 }
108
109 return EFI_SUCCESS;
110 }
111
112 /**
113
114 This function registers HII packages to HII database.
115
116 @retval EFI_SUCCESS This function complete successfully.
117 @return Other value if failed to register HII packages.
118
119 **/
120 EFI_STATUS
121 InitializeDeviceManager (
122 VOID
123 )
124 {
125 EFI_STATUS Status;
126 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
127
128 //
129 // Create driver handle used by HII database
130 //
131 Status = HiiLibCreateHiiDriverHandle (&gDeviceManagerPrivate.DriverHandle);
132 if (EFI_ERROR (Status)) {
133 return Status;
134 }
135
136 //
137 // Install Config Access protocol to driver handle
138 //
139 Status = gBS->InstallProtocolInterface (
140 &gDeviceManagerPrivate.DriverHandle,
141 &gEfiHiiConfigAccessProtocolGuid,
142 EFI_NATIVE_INTERFACE,
143 &gDeviceManagerPrivate.ConfigAccess
144 );
145 ASSERT_EFI_ERROR (Status);
146
147 //
148 // Publish our HII data
149 //
150 PackageList = HiiLibPreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsDxeStrings);
151 ASSERT (PackageList != NULL);
152
153 Status = gHiiDatabase->NewPackageList (
154 gHiiDatabase,
155 PackageList,
156 gDeviceManagerPrivate.DriverHandle,
157 &gDeviceManagerPrivate.HiiHandle
158 );
159 FreePool (PackageList);
160
161 return Status;
162 }
163
164 /**
165 Call the browser and display the device manager to allow user
166 to configure the platform.
167
168 This function create the dynamic content for device manager. It includes
169 section header for all class of devices, one-of opcode to set VBIOS.
170
171 @retval EFI_SUCCESS Operation is successful.
172 @return Other values if failed to clean up the dynamic content from HII
173 database.
174
175 **/
176 EFI_STATUS
177 CallDeviceManager (
178 VOID
179 )
180 {
181 EFI_STATUS Status;
182 UINTN Count;
183 UINTN Index;
184 CHAR16 *String;
185 UINTN StringLength;
186 EFI_HII_UPDATE_DATA UpdateData[MENU_ITEM_NUM];
187 EFI_STRING_ID Token;
188 EFI_STRING_ID TokenHelp;
189 IFR_OPTION *IfrOptionList;
190 UINT8 *VideoOption;
191 UINTN VideoOptionSize;
192 EFI_HII_HANDLE *HiiHandles;
193 UINTN HandleBufferLength;
194 UINTN NumberOfHiiHandles;
195 EFI_HII_HANDLE HiiHandle;
196 UINT16 FormSetClass;
197 EFI_STRING_ID FormSetTitle;
198 EFI_STRING_ID FormSetHelp;
199 EFI_BROWSER_ACTION_REQUEST ActionRequest;
200 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
201
202 IfrOptionList = NULL;
203 VideoOption = NULL;
204 HiiHandles = NULL;
205 HandleBufferLength = 0;
206
207 Status = EFI_SUCCESS;
208 gCallbackKey = 0;
209
210 //
211 // Connect all prior to entering the platform setup menu.
212 //
213 if (!gConnectAllHappened) {
214 BdsLibConnectAllDriversToAllControllers ();
215 gConnectAllHappened = TRUE;
216 }
217
218 //
219 // Create Subtitle OpCodes
220 //
221 for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
222 //
223 // Allocate space for creation of UpdateData Buffer
224 //
225 UpdateData[Index].BufferSize = 0x1000;
226 UpdateData[Index].Offset = 0;
227 UpdateData[Index].Data = AllocatePool (0x1000);
228 ASSERT (UpdateData[Index].Data != NULL);
229
230 CreateSubTitleOpCode (mDeviceManagerMenuItemTable[Index].StringId, 0, 0, 1, &UpdateData[Index]);
231 }
232
233 //
234 // Get all the Hii handles
235 //
236 Status = HiiLibGetHiiHandles (&HandleBufferLength, &HiiHandles);
237 ASSERT_EFI_ERROR (Status && (HiiHandles != NULL));
238
239 HiiHandle = gDeviceManagerPrivate.HiiHandle;
240
241 StringLength = 0x1000;
242 String = AllocateZeroPool (StringLength);
243 ASSERT (String != NULL);
244
245 //
246 // Search for formset of each class type
247 //
248 NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);
249 for (Index = 0; Index < NumberOfHiiHandles; Index++) {
250 IfrLibExtractClassFromHiiHandle (HiiHandles[Index], &FormSetClass, &FormSetTitle, &FormSetHelp);
251
252 if (FormSetClass == EFI_NON_DEVICE_CLASS) {
253 continue;
254 }
255
256 Token = 0;
257 *String = 0;
258 StringLength = 0x1000;
259 HiiLibGetString (HiiHandles[Index], FormSetTitle, String, &StringLength);
260 HiiLibNewString (HiiHandle, &Token, String);
261
262 TokenHelp = 0;
263 *String = 0;
264 StringLength = 0x1000;
265 HiiLibGetString (HiiHandles[Index], FormSetHelp, String, &StringLength);
266 HiiLibNewString (HiiHandle, &TokenHelp, String);
267
268 for (Count = 0; Count < MENU_ITEM_NUM; Count++) {
269 if (FormSetClass & mDeviceManagerMenuItemTable[Count].Class) {
270 CreateActionOpCode (
271 (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET),
272 Token,
273 TokenHelp,
274 EFI_IFR_FLAG_CALLBACK,
275 0,
276 &UpdateData[Count]
277 );
278 }
279 }
280 }
281 FreePool (String);
282
283 for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
284 //
285 // Add End Opcode for Subtitle
286 //
287 CreateEndOpCode (&UpdateData[Index]);
288
289 IfrLibUpdateForm (
290 HiiHandle,
291 &mDeviceManagerGuid,
292 DEVICE_MANAGER_FORM_ID,
293 mDeviceManagerMenuItemTable[Index].Class,
294 FALSE,
295 &UpdateData[Index]
296 );
297 }
298
299 //
300 // Add oneof for video BIOS selection
301 //
302 VideoOption = BdsLibGetVariableAndSize (
303 L"VBIOS",
304 &gEfiGenericPlatformVariableGuid,
305 &VideoOptionSize
306 );
307 if (VideoOption == NULL) {
308 gDeviceManagerPrivate.VideoBios = 0;
309 } else {
310 gDeviceManagerPrivate.VideoBios = VideoOption[0];
311 FreePool (VideoOption);
312 }
313
314 ASSERT (gDeviceManagerPrivate.VideoBios <= 1);
315
316 IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));
317 ASSERT (IfrOptionList != NULL);
318 IfrOptionList[0].Flags = 0;
319 IfrOptionList[0].StringToken = STRING_TOKEN (STR_ONE_OF_PCI);
320 IfrOptionList[0].Value.u8 = 0;
321 IfrOptionList[1].Flags = 0;
322 IfrOptionList[1].StringToken = STRING_TOKEN (STR_ONE_OF_AGP);
323 IfrOptionList[1].Value.u8 = 1;
324 IfrOptionList[gDeviceManagerPrivate.VideoBios].Flags |= EFI_IFR_OPTION_DEFAULT;
325
326 UpdateData[0].Offset = 0;
327 CreateOneOfOpCode (
328 DEVICE_MANAGER_KEY_VBIOS,
329 0,
330 0,
331 STRING_TOKEN (STR_ONE_OF_VBIOS),
332 STRING_TOKEN (STR_ONE_OF_VBIOS_HELP),
333 EFI_IFR_FLAG_CALLBACK,
334 EFI_IFR_NUMERIC_SIZE_1,
335 IfrOptionList,
336 2,
337 &UpdateData[0]
338 );
339
340 IfrLibUpdateForm (
341 HiiHandle,
342 &mDeviceManagerGuid,
343 DEVICE_MANAGER_FORM_ID,
344 LABEL_VBIOS,
345 FALSE,
346 &UpdateData[0]
347 );
348
349 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
350 Status = gFormBrowser2->SendForm (
351 gFormBrowser2,
352 &HiiHandle,
353 1,
354 NULL,
355 0,
356 NULL,
357 &ActionRequest
358 );
359 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
360 EnableResetRequired ();
361 }
362
363 //
364 // We will have returned from processing a callback - user either hit ESC to exit, or selected
365 // a target to display
366 //
367 if (gCallbackKey != 0) {
368 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
369 Status = gFormBrowser2->SendForm (
370 gFormBrowser2,
371 &HiiHandles[gCallbackKey - DEVICE_KEY_OFFSET],
372 1,
373 NULL,
374 0,
375 NULL,
376 &ActionRequest
377 );
378
379 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
380 EnableResetRequired ();
381 }
382
383 //
384 // Force return to Device Manager
385 //
386 gCallbackKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
387 }
388
389 //
390 // Cleanup dynamic created strings in HII database by reinstall the packagelist
391 //
392 gHiiDatabase->RemovePackageList (gHiiDatabase, HiiHandle);
393 PackageList = HiiLibPreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsDxeStrings);
394 ASSERT (PackageList != NULL);
395 Status = gHiiDatabase->NewPackageList (
396 gHiiDatabase,
397 PackageList,
398 gDeviceManagerPrivate.DriverHandle,
399 &gDeviceManagerPrivate.HiiHandle
400 );
401 FreePool (PackageList);
402
403 for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
404 FreePool (UpdateData[Index].Data);
405 }
406 FreePool (HiiHandles);
407
408 return Status;
409 }