]> git.proxmox.com Git - mirror_edk2.git/blob - EdkUnixPkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c
fix some minor warning for unix package
[mirror_edk2.git] / EdkUnixPkg / Dxe / PlatformBds / Generic / DeviceMngr / DeviceManager.c
1 /*++
2
3 Copyright (c) 2006, 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 #include "DeviceManager.h"
22
23 STATIC UINT16 mTokenCount;
24 EFI_FRONTPAGE_CALLBACK_INFO FPCallbackInfo;
25 extern UINTN gCallbackKey;
26 extern EFI_FORM_BROWSER_PROTOCOL *gBrowser;
27 extern EFI_GUID gBdsStringPackGuid;
28 extern BOOLEAN gConnectAllHappened;
29
30 STRING_REF gStringTokenTable[] = {
31 STR_VIDEO_DEVICE,
32 STR_NETWORK_DEVICE,
33 STR_INPUT_DEVICE,
34 STR_ON_BOARD_DEVICE,
35 STR_OTHER_DEVICE,
36 STR_EMPTY_STRING,
37 0xFFFF
38 };
39
40 EFI_STATUS
41 EFIAPI
42 DeviceManagerCallbackRoutine (
43 IN EFI_FORM_CALLBACK_PROTOCOL *This,
44 IN UINT16 KeyValue,
45 IN EFI_IFR_DATA_ARRAY *DataArray,
46 OUT EFI_HII_CALLBACK_PACKET **Packet
47 )
48 /*++
49
50 Routine Description:
51
52 This is the function that is called to provide results data to the driver. This data
53 consists of a unique key which is used to identify what data is either being passed back
54 or being asked for.
55
56 Arguments:
57
58 KeyValue - A unique value which is sent to the original exporting driver so that it
59 can identify the type of data to expect. The format of the data tends to
60 vary based on the op-code that geerated the callback.
61
62 Data - A pointer to the data being sent to the original exporting driver.
63
64 Returns:
65
66 --*/
67 {
68 //
69 // The KeyValue corresponds in this case to the handle which was requested to be displayed
70 //
71 EFI_FRONTPAGE_CALLBACK_INFO *CallbackInfo;
72
73 CallbackInfo = EFI_FP_CALLBACK_DATA_FROM_THIS (This);
74 switch (KeyValue) {
75 case 0x2000:
76 CallbackInfo->Data.VideoBIOS = (UINT8) (UINTN) (((EFI_IFR_DATA_ENTRY *)(DataArray + 1))->Data);
77 gRT->SetVariable (
78 L"VBIOS",
79 &gEfiGlobalVariableGuid,
80 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
81 sizeof (UINT8),
82 &CallbackInfo->Data.VideoBIOS
83 );
84 break;
85
86 default:
87 break;
88 }
89
90 gCallbackKey = KeyValue;
91 return EFI_SUCCESS;
92 }
93
94 EFI_STATUS
95 InitializeDeviceManager (
96 VOID
97 )
98 /*++
99
100 Routine Description:
101
102 Initialize HII information for the FrontPage
103
104 Arguments:
105 None
106
107 Returns:
108
109 --*/
110 {
111 EFI_STATUS Status;
112 EFI_HII_PACKAGES *PackageList;
113 EFI_HII_UPDATE_DATA *UpdateData;
114
115 //
116 // Allocate space for creation of UpdateData Buffer
117 //
118 UpdateData = AllocateZeroPool (0x1000);
119 ASSERT (UpdateData != NULL);
120
121 PackageList = PreparePackages (1, &gBdsStringPackGuid, DeviceManagerVfrBin);
122 Status = Hii->NewPack (Hii, PackageList, &FPCallbackInfo.DevMgrHiiHandle);
123 gBS->FreePool (PackageList);
124
125 //
126 // This example does not implement worker functions for the NV accessor functions. Only a callback evaluator
127 //
128 FPCallbackInfo.Signature = EFI_FP_CALLBACK_DATA_SIGNATURE;
129 FPCallbackInfo.DevMgrCallback.NvRead = NULL;
130 FPCallbackInfo.DevMgrCallback.NvWrite = NULL;
131 FPCallbackInfo.DevMgrCallback.Callback = DeviceManagerCallbackRoutine;
132
133 //
134 // Install protocol interface
135 //
136 FPCallbackInfo.CallbackHandle = NULL;
137
138 Status = gBS->InstallProtocolInterface (
139 &FPCallbackInfo.CallbackHandle,
140 &gEfiFormCallbackProtocolGuid,
141 EFI_NATIVE_INTERFACE,
142 &FPCallbackInfo.DevMgrCallback
143 );
144
145 ASSERT_EFI_ERROR (Status);
146
147 //
148 // Flag update pending in FormSet
149 //
150 UpdateData->FormSetUpdate = TRUE;
151 //
152 // Register CallbackHandle data for FormSet
153 //
154 UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) FPCallbackInfo.CallbackHandle;
155 //
156 // Simply registering the callback handle
157 //
158 Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);
159
160 gBS->FreePool (UpdateData);
161 return Status;
162 }
163
164 EFI_STATUS
165 CallDeviceManager (
166 VOID
167 )
168 /*++
169
170 Routine Description:
171
172 Call the browser and display the device manager
173
174 Arguments:
175
176 None
177
178 Returns:
179 EFI_SUCCESS - Operation is successful.
180 EFI_INVALID_PARAMETER - If the inputs to SendForm function is not valid.
181
182 --*/
183 {
184 EFI_STATUS Status;
185 UINTN BufferSize;
186 UINTN Count;
187 EFI_HII_HANDLE Index;
188 UINT8 *Buffer;
189 EFI_IFR_FORM_SET *FormSetData;
190 CHAR16 *String;
191 UINTN StringLength;
192 EFI_HII_UPDATE_DATA *UpdateData;
193 STRING_REF Token;
194 STRING_REF TokenHelp;
195 IFR_OPTION *IfrOptionList;
196 UINT8 *VideoOption;
197 UINTN VideoOptionSize;
198 EFI_HII_HANDLE *HiiHandles;
199 UINT16 HandleBufferLength;
200 BOOLEAN BootDeviceMngrMenuResetRequired;
201
202 IfrOptionList = NULL;
203 VideoOption = NULL;
204 HiiHandles = NULL;
205 HandleBufferLength = 0;
206
207 //
208 // Connect all prior to entering the platform setup menu.
209 //
210 if (!gConnectAllHappened) {
211 BdsLibConnectAllDriversToAllControllers ();
212 gConnectAllHappened = TRUE;
213 }
214 //
215 // Allocate space for creation of UpdateData Buffer
216 //
217 UpdateData = AllocateZeroPool (0x1000);
218 ASSERT (UpdateData != NULL);
219
220 Status = EFI_SUCCESS;
221 Buffer = NULL;
222 FormSetData = NULL;
223 gCallbackKey = 0;
224 if (mTokenCount == 0) {
225 Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &mTokenCount, L" ");
226 }
227
228 Token = mTokenCount;
229 TokenHelp = (UINT16) (Token + 1);
230
231 //
232 // Reset the menu
233 //
234 for (Index = 0, Count = 1; Count < 0x10000; Count <<= 1, Index++) {
235 //
236 // We will strip off all previous menu entries
237 //
238 UpdateData->DataCount = 0xFF;
239
240 //
241 // Erase entries on this label
242 //
243 Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, FALSE, UpdateData);
244
245 //
246 // Did we reach the end of the Token Table?
247 //
248 if (gStringTokenTable[Index] == 0xFFFF) {
249 break;
250 }
251
252 CreateSubTitleOpCode (gStringTokenTable[Index], &UpdateData->Data);
253 //
254 // Add a single menu item - in this case a subtitle for the device type
255 //
256 UpdateData->DataCount = 1;
257
258 //
259 // Add default title for this label
260 //
261 Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);
262 }
263 //
264 // Add a space and an exit string. Remember since we add things at the label and push other things beyond the
265 // label down, we add this in reverse order
266 //
267 CreateSubTitleOpCode (STRING_TOKEN (STR_EXIT_STRING), &UpdateData->Data);
268 Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);
269 CreateSubTitleOpCode (STR_EMPTY_STRING, &UpdateData->Data);
270 Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);
271
272 //
273 // Get all the Hii handles
274 //
275 Status = BdsLibGetHiiHandles (Hii, &HandleBufferLength, &HiiHandles);
276 ASSERT_EFI_ERROR (Status);
277
278 for (Index = 1, BufferSize = 0; Index < HandleBufferLength; Index++) {
279 //
280 // Am not initializing Buffer since the first thing checked is the size
281 // this way I can get the real buffersize in the smallest code size
282 //
283 Status = Hii->GetForms (Hii, Index, 0, &BufferSize, Buffer);
284
285 if (Status != EFI_NOT_FOUND) {
286 //
287 // BufferSize should have the real size of the forms now
288 //
289 Buffer = AllocateZeroPool (BufferSize);
290 ASSERT (Buffer != NULL);
291
292 //
293 // Am not initializing Buffer since the first thing checked is the size
294 // this way I can get the real buffersize in the smallest code size
295 //
296 Status = Hii->GetForms (Hii, Index, 0, &BufferSize, Buffer);
297
298 //
299 // Skip EFI_HII_PACK_HEADER, advance to EFI_IFR_FORM_SET data.
300 //
301 FormSetData = (EFI_IFR_FORM_SET *) (Buffer + sizeof (EFI_HII_PACK_HEADER));
302
303 //
304 // If this formset belongs in the device manager, add it to the menu
305 //
306 if (FormSetData->Class != EFI_NON_DEVICE_CLASS) {
307
308 StringLength = 0x1000;
309 String = AllocateZeroPool (StringLength);
310 ASSERT (String != NULL);
311
312 Status = Hii->GetString (Hii, Index, FormSetData->FormSetTitle, TRUE, NULL, &StringLength, String);
313 Status = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &Token, String);
314
315 //
316 // If token value exceeded real token value - we need to add a new token values
317 //
318 if (Status == EFI_INVALID_PARAMETER) {
319 Token = 0;
320 TokenHelp = 0;
321 Status = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &Token, String);
322 }
323
324 StringLength = 0x1000;
325 if (FormSetData->Help == 0) {
326 TokenHelp = 0;
327 } else {
328 Status = Hii->GetString (Hii, Index, FormSetData->Help, TRUE, NULL, &StringLength, String);
329 if (StringLength == 0x02) {
330 TokenHelp = 0;
331 } else {
332 Status = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &TokenHelp, String);
333 if (Status == EFI_INVALID_PARAMETER) {
334 TokenHelp = 0;
335 Status = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &TokenHelp, String);
336 }
337 }
338 }
339
340 gBS->FreePool (String);
341
342 CreateGotoOpCode (
343 0x1000, // Device Manager Page
344 Token, // Description String Token
345 TokenHelp, // Description Help String Token
346 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS, // Flag designating callback is active
347 (UINT16) Index, // Callback key value
348 &UpdateData->Data // Buffer to fill with op-code
349 );
350
351 //
352 // In the off-chance that we have lots of extra tokens allocated to the DeviceManager
353 // this ensures we are fairly re-using the tokens instead of constantly growing the token
354 // storage for this one handle. If we incremented the token value beyond what it normally
355 // would use, we will fall back into the error path which seeds the token value with a 0
356 // so that we can correctly add a token value.
357 //
358 if (TokenHelp == 0) {
359 //
360 // Since we didn't add help, only advance Token by 1
361 //
362 Token++;
363 } else {
364 Token = (UINT16) (Token + 2);
365 TokenHelp = (UINT16) (TokenHelp + 2);
366 }
367 //
368 // This for loop basically will take the Class value which is a bitmask and
369 // update the form for every active bit. There will be a label at each bit
370 // location. So if someone had a device which a class of EFI_DISK_DEVICE_CLASS |
371 // EFI_ON_BOARD_DEVICE_CLASS, this routine will unwind that mask and drop the menu entry
372 // on each corresponding label.
373 //
374 for (Count = 1; Count < 0x10000; Count <<= 1) {
375 //
376 // This is an active bit, so update the form
377 //
378 if (FormSetData->Class & Count) {
379 Hii->UpdateForm (
380 Hii,
381 FPCallbackInfo.DevMgrHiiHandle,
382 (EFI_FORM_LABEL) (FormSetData->Class & Count),
383 TRUE,
384 UpdateData
385 );
386 }
387 }
388 }
389
390 BufferSize = 0;
391 //
392 // Reset Buffer pointer to original location
393 //
394 gBS->FreePool (Buffer);
395 }
396 }
397 //
398 // Add oneof for video BIOS selection
399 //
400 VideoOption = BdsLibGetVariableAndSize (
401 L"VBIOS",
402 &gEfiGlobalVariableGuid,
403 &VideoOptionSize
404 );
405 if (NULL == VideoOption) {
406 FPCallbackInfo.Data.VideoBIOS = 0;
407 } else {
408 FPCallbackInfo.Data.VideoBIOS = VideoOption[0];
409 gBS->FreePool (VideoOption);
410 }
411
412 ASSERT (FPCallbackInfo.Data.VideoBIOS <= 1);
413
414 Status = gBS->AllocatePool (EfiBootServicesData, 2 * sizeof (IFR_OPTION), (VOID**) &IfrOptionList);
415 if (IfrOptionList != NULL) {
416 IfrOptionList[0].Flags = EFI_IFR_FLAG_INTERACTIVE;
417 IfrOptionList[0].Key = SET_VIDEO_BIOS_TYPE_QUESTION_ID + 0x2000;
418 IfrOptionList[0].StringToken = STRING_TOKEN (STR_ONE_OF_PCI);
419 IfrOptionList[0].Value = 0;
420 IfrOptionList[0].OptionString = NULL;
421 IfrOptionList[1].Flags = EFI_IFR_FLAG_INTERACTIVE;
422 IfrOptionList[1].Key = SET_VIDEO_BIOS_TYPE_QUESTION_ID + 0x2000;
423 IfrOptionList[1].StringToken = STRING_TOKEN (STR_ONE_OF_AGP);
424 IfrOptionList[1].Value = 1;
425 IfrOptionList[1].OptionString = NULL;
426 IfrOptionList[FPCallbackInfo.Data.VideoBIOS].Flags |= EFI_IFR_FLAG_DEFAULT;
427
428 CreateOneOfOpCode (
429 SET_VIDEO_BIOS_TYPE_QUESTION_ID,
430 (UINT8) 1,
431 STRING_TOKEN (STR_ONE_OF_VBIOS),
432 STRING_TOKEN (STR_ONE_OF_VBIOS_HELP),
433 IfrOptionList,
434 2,
435 &UpdateData->Data
436 );
437
438 UpdateData->DataCount = 4;
439 Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) EFI_VBIOS_CLASS, TRUE, UpdateData);
440 gBS->FreePool (IfrOptionList);
441 }
442
443 BootDeviceMngrMenuResetRequired = FALSE;
444 Status = gBrowser->SendForm (
445 gBrowser,
446 TRUE, // Use the database
447 &FPCallbackInfo.DevMgrHiiHandle, // The HII Handle
448 1,
449 NULL,
450 FPCallbackInfo.CallbackHandle,
451 (UINT8 *) &FPCallbackInfo.Data,
452 NULL,
453 &BootDeviceMngrMenuResetRequired
454 );
455
456 if (BootDeviceMngrMenuResetRequired) {
457 EnableResetRequired ();
458 }
459
460 Hii->ResetStrings (Hii, FPCallbackInfo.DevMgrHiiHandle);
461
462 //
463 // We will have returned from processing a callback - user either hit ESC to exit, or selected
464 // a target to display
465 //
466 if (gCallbackKey != 0 && gCallbackKey < 0x2000) {
467 BootDeviceMngrMenuResetRequired = FALSE;
468 Status = gBrowser->SendForm (
469 gBrowser,
470 TRUE, // Use the database
471 (EFI_HII_HANDLE *) &gCallbackKey, // The HII Handle
472 1,
473 NULL,
474 NULL, // This is the handle that the interface to the callback was installed on
475 NULL,
476 NULL,
477 &BootDeviceMngrMenuResetRequired
478 );
479
480 if (BootDeviceMngrMenuResetRequired) {
481 EnableResetRequired ();
482 }
483 //
484 // Force return to Device Manager
485 //
486 gCallbackKey = 4;
487 }
488
489 if (gCallbackKey >= 0x2000) {
490 gCallbackKey = 4;
491 }
492
493 gBS->FreePool (UpdateData);
494 gBS->FreePool (HiiHandles);
495
496 return Status;
497 }