]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / DeviceMngr / DeviceManager.c
1 /*++
2
3 Copyright (c) 2004 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 DeviceManager.c
15
16 Abstract:
17
18 The platform device manager reference implement
19
20 --*/
21
22 #include "DeviceManager.h"
23
24 DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate = {
25 DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE,
26 NULL,
27 NULL,
28 {
29 FakeExtractConfig,
30 FakeRouteConfig,
31 DeviceManagerCallback
32 }
33 };
34
35 EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID;
36
37 DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable[] = {
38 { STRING_TOKEN (STR_DISK_DEVICE), EFI_DISK_DEVICE_CLASS },
39 { STRING_TOKEN (STR_VIDEO_DEVICE), EFI_VIDEO_DEVICE_CLASS },
40 { STRING_TOKEN (STR_NETWORK_DEVICE), EFI_NETWORK_DEVICE_CLASS },
41 { STRING_TOKEN (STR_INPUT_DEVICE), EFI_INPUT_DEVICE_CLASS },
42 { STRING_TOKEN (STR_ON_BOARD_DEVICE), EFI_ON_BOARD_DEVICE_CLASS },
43 { STRING_TOKEN (STR_OTHER_DEVICE), EFI_OTHER_DEVICE_CLASS }
44 };
45
46 #define MENU_ITEM_NUM \
47 (sizeof (mDeviceManagerMenuItemTable) / sizeof (DEVICE_MANAGER_MENU_ITEM))
48
49 EFI_STATUS
50 EFIAPI
51 DeviceManagerCallback (
52 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
53 IN EFI_BROWSER_ACTION Action,
54 IN EFI_QUESTION_ID QuestionId,
55 IN UINT8 Type,
56 IN EFI_IFR_TYPE_VALUE *Value,
57 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
58 )
59 /*++
60
61 Routine Description:
62 This function processes the results of changes in configuration.
63
64 Arguments:
65 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
66 Action - Specifies the type of action taken by the browser.
67 QuestionId - A unique value which is sent to the original exporting driver
68 so that it can identify the type of data to expect.
69 Type - The type of value for the question.
70 Value - A pointer to the data being sent to the original exporting driver.
71 ActionRequest - On return, points to the action requested by the callback function.
72
73 Returns:
74 EFI_SUCCESS - The callback successfully handled the action.
75 EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
76 EFI_DEVICE_ERROR - The variable could not be saved.
77 EFI_UNSUPPORTED - The specified Action is not supported by the callback.
78
79 --*/
80 {
81 DEVICE_MANAGER_CALLBACK_DATA *PrivateData;
82
83 if ((Value == NULL) || (ActionRequest == NULL)) {
84 return EFI_INVALID_PARAMETER;
85 }
86
87 PrivateData = DEVICE_MANAGER_CALLBACK_DATA_FROM_THIS (This);
88
89 switch (QuestionId) {
90 case DEVICE_MANAGER_KEY_VBIOS:
91 PrivateData->VideoBios = Value->u8;
92 gRT->SetVariable (
93 L"VBIOS",
94 &gEfiGenericPlatformVariableGuid,
95 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
96 sizeof (UINT8),
97 &PrivateData->VideoBios
98 );
99
100 //
101 // Tell browser not to ask for confirmation of changes,
102 // since we have already applied.
103 //
104 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
105 break;
106
107 default:
108 //
109 // The key corresponds the Handle Index which was requested to be displayed
110 //
111 gCallbackKey = QuestionId;
112
113 //
114 // Request to exit SendForm(), so as to switch to selected form
115 //
116 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
117 break;
118 }
119
120 return EFI_SUCCESS;
121 }
122
123 EFI_STATUS
124 InitializeDeviceManager (
125 VOID
126 )
127 /*++
128
129 Routine Description:
130
131 Initialize HII information for the FrontPage
132
133 Arguments:
134 None
135
136 Returns:
137
138 --*/
139 {
140 EFI_STATUS Status;
141 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
142
143 //
144 // Create driver handle used by HII database
145 //
146 Status = HiiLibCreateHiiDriverHandle (&gDeviceManagerPrivate.DriverHandle);
147 if (EFI_ERROR (Status)) {
148 return Status;
149 }
150
151 //
152 // Install Config Access protocol to driver handle
153 //
154 Status = gBS->InstallProtocolInterface (
155 &gDeviceManagerPrivate.DriverHandle,
156 &gEfiHiiConfigAccessProtocolGuid,
157 EFI_NATIVE_INTERFACE,
158 &gDeviceManagerPrivate.ConfigAccess
159 );
160 ASSERT_EFI_ERROR (Status);
161
162 //
163 // Publish our HII data
164 //
165 PackageList = PreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsStrings);
166 ASSERT (PackageList != NULL);
167
168 Status = gHiiDatabase->NewPackageList (
169 gHiiDatabase,
170 PackageList,
171 gDeviceManagerPrivate.DriverHandle,
172 &gDeviceManagerPrivate.HiiHandle
173 );
174 FreePool (PackageList);
175
176 return Status;
177 }
178
179 EFI_STATUS
180 CallDeviceManager (
181 VOID
182 )
183 /*++
184
185 Routine Description:
186
187 Call the browser and display the device manager
188
189 Arguments:
190
191 None
192
193 Returns:
194 EFI_SUCCESS - Operation is successful.
195 EFI_INVALID_PARAMETER - If the inputs to SendForm function is not valid.
196
197 --*/
198 {
199 EFI_STATUS Status;
200 UINTN Count;
201 UINTN Index;
202 CHAR16 *String;
203 UINTN StringLength;
204 EFI_HII_UPDATE_DATA UpdateData[MENU_ITEM_NUM];
205 EFI_STRING_ID Token;
206 EFI_STRING_ID TokenHelp;
207 IFR_OPTION *IfrOptionList;
208 UINT8 *VideoOption;
209 UINTN VideoOptionSize;
210 EFI_HII_HANDLE *HiiHandles;
211 UINTN HandleBufferLength;
212 UINTN NumberOfHiiHandles;
213 EFI_HII_HANDLE HiiHandle;
214 UINT16 FormSetClass;
215 EFI_STRING_ID FormSetTitle;
216 EFI_STRING_ID FormSetHelp;
217 EFI_BROWSER_ACTION_REQUEST ActionRequest;
218 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
219
220 IfrOptionList = NULL;
221 VideoOption = NULL;
222 HiiHandles = NULL;
223 HandleBufferLength = 0;
224
225 Status = EFI_SUCCESS;
226 gCallbackKey = 0;
227
228 //
229 // Connect all prior to entering the platform setup menu.
230 //
231 if (!gConnectAllHappened) {
232 BdsLibConnectAllDriversToAllControllers ();
233 gConnectAllHappened = TRUE;
234 }
235
236 //
237 // Create Subtitle OpCodes
238 //
239 for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
240 //
241 // Allocate space for creation of UpdateData Buffer
242 //
243 UpdateData[Index].BufferSize = 0x1000;
244 UpdateData[Index].Offset = 0;
245 UpdateData[Index].Data = AllocatePool (0x1000);
246 ASSERT (UpdateData[Index].Data != NULL);
247
248 CreateSubTitleOpCode (mDeviceManagerMenuItemTable[Index].StringId, 0, 0, 1, &UpdateData[Index]);
249 }
250
251 //
252 // Get all the Hii handles
253 //
254 Status = GetHiiHandles (&HandleBufferLength, &HiiHandles);
255 ASSERT_EFI_ERROR (Status);
256
257 HiiHandle = gDeviceManagerPrivate.HiiHandle;
258
259 StringLength = 0x1000;
260 String = AllocateZeroPool (StringLength);
261 ASSERT (String != NULL);
262
263 //
264 // Search for formset of each class type
265 //
266 NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);
267 for (Index = 0; Index < NumberOfHiiHandles; Index++) {
268 HiiLibExtractClassFromHiiHandle (HiiHandles[Index], &FormSetClass, &FormSetTitle, &FormSetHelp);
269
270 if (FormSetClass == EFI_NON_DEVICE_CLASS) {
271 continue;
272 }
273
274 Token = 0;
275 *String = 0;
276 StringLength = 0x1000;
277 IfrLibGetString (HiiHandles[Index], FormSetTitle, String, &StringLength);
278 IfrLibNewString (HiiHandle, &Token, String);
279
280 TokenHelp = 0;
281 *String = 0;
282 StringLength = 0x1000;
283 IfrLibGetString (HiiHandles[Index], FormSetHelp, String, &StringLength);
284 IfrLibNewString (HiiHandle, &TokenHelp, String);
285
286 for (Count = 0; Count < MENU_ITEM_NUM; Count++) {
287 if (FormSetClass & mDeviceManagerMenuItemTable[Count].Class) {
288 CreateActionOpCode (
289 (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET),
290 Token,
291 TokenHelp,
292 EFI_IFR_FLAG_CALLBACK,
293 0,
294 &UpdateData[Count]
295 );
296 }
297 }
298 }
299 FreePool (String);
300
301 for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
302 //
303 // Add End Opcode for Subtitle
304 //
305 CreateEndOpCode (&UpdateData[Index]);
306
307 IfrLibUpdateForm (
308 HiiHandle,
309 &mDeviceManagerGuid,
310 DEVICE_MANAGER_FORM_ID,
311 mDeviceManagerMenuItemTable[Index].Class,
312 FALSE,
313 &UpdateData[Index]
314 );
315 }
316
317 //
318 // Add oneof for video BIOS selection
319 //
320 VideoOption = BdsLibGetVariableAndSize (
321 L"VBIOS",
322 &gEfiGenericPlatformVariableGuid,
323 &VideoOptionSize
324 );
325 if (NULL == VideoOption) {
326 gDeviceManagerPrivate.VideoBios = 0;
327 } else {
328 gDeviceManagerPrivate.VideoBios = VideoOption[0];
329 FreePool (VideoOption);
330 }
331
332 ASSERT (gDeviceManagerPrivate.VideoBios <= 1);
333
334 IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));
335 ASSERT (IfrOptionList != NULL);
336 IfrOptionList[0].Flags = 0;
337 IfrOptionList[0].StringToken = STRING_TOKEN (STR_ONE_OF_PCI);
338 IfrOptionList[0].Value.u8 = 0;
339 IfrOptionList[1].Flags = 0;
340 IfrOptionList[1].StringToken = STRING_TOKEN (STR_ONE_OF_AGP);
341 IfrOptionList[1].Value.u8 = 1;
342 IfrOptionList[gDeviceManagerPrivate.VideoBios].Flags |= EFI_IFR_OPTION_DEFAULT;
343
344 UpdateData[0].Offset = 0;
345 CreateOneOfOpCode (
346 DEVICE_MANAGER_KEY_VBIOS,
347 0,
348 0,
349 STRING_TOKEN (STR_ONE_OF_VBIOS),
350 STRING_TOKEN (STR_ONE_OF_VBIOS_HELP),
351 EFI_IFR_FLAG_CALLBACK,
352 EFI_IFR_NUMERIC_SIZE_1,
353 IfrOptionList,
354 2,
355 &UpdateData[0]
356 );
357
358 IfrLibUpdateForm (
359 HiiHandle,
360 &mDeviceManagerGuid,
361 DEVICE_MANAGER_FORM_ID,
362 LABEL_VBIOS,
363 FALSE,
364 &UpdateData[0]
365 );
366
367 //
368 // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
369 //
370 gBS->RestoreTPL (TPL_APPLICATION);
371
372 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
373 Status = gFormBrowser2->SendForm (
374 gFormBrowser2,
375 &HiiHandle,
376 1,
377 NULL,
378 0,
379 NULL,
380 &ActionRequest
381 );
382 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
383 EnableResetRequired ();
384 }
385
386 //
387 // We will have returned from processing a callback - user either hit ESC to exit, or selected
388 // a target to display
389 //
390 if (gCallbackKey != 0) {
391 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
392 Status = gFormBrowser2->SendForm (
393 gFormBrowser2,
394 &HiiHandles[gCallbackKey - DEVICE_KEY_OFFSET],
395 1,
396 NULL,
397 0,
398 NULL,
399 &ActionRequest
400 );
401
402 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
403 EnableResetRequired ();
404 }
405
406 //
407 // Force return to Device Manager
408 //
409 gCallbackKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
410 }
411
412 //
413 // Cleanup dynamic created strings in HII database by reinstall the packagelist
414 //
415 gHiiDatabase->RemovePackageList (gHiiDatabase, HiiHandle);
416 PackageList = PreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsStrings);
417 ASSERT (PackageList != NULL);
418 Status = gHiiDatabase->NewPackageList (
419 gHiiDatabase,
420 PackageList,
421 gDeviceManagerPrivate.DriverHandle,
422 &gDeviceManagerPrivate.HiiHandle
423 );
424 FreePool (PackageList);
425
426 for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
427 FreePool (UpdateData[Index].Data);
428 }
429 FreePool (HiiHandles);
430
431 gBS->RaiseTPL (TPL_APPLICATION);
432
433 return Status;
434 }