]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.c
HII Library Class interface refine.
[mirror_edk2.git] / MdeModulePkg / Application / PlatOverMngr / PlatOverMngr.c
... / ...
CommitLineData
1/** @file\r
2\r
3 A UI application to offer a UI interface in device manager to let user configure\r
4 platform override protocol to override the default algorithm for matching\r
5 drivers to controllers.\r
6\r
7 The main flow:\r
8 1. The UI application dynamicly locate all controller device path.\r
9 2. The UI application dynamicly locate all drivers which support binding protocol.\r
10 3. The UI application export and dynamicly update two menu to let user select the\r
11 mapping between drivers to controllers.\r
12 4. The UI application save all the mapping info in NV variables which will be consumed\r
13 by platform override protocol driver to publish the platform override protocol.\r
14\r
15Copyright (c) 2007 - 2008, Intel Corporation\r
16All rights reserved. This program and the accompanying materials\r
17are licensed and made available under the terms and conditions of the BSD License\r
18which accompanies this distribution. The full text of the license may be found at\r
19http://opensource.org/licenses/bsd-license.php\r
20\r
21THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
22WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
23\r
24**/\r
25\r
26#include <PiDxe.h>\r
27\r
28#include <Protocol/HiiConfigAccess.h>\r
29#include <Protocol/HiiConfigRouting.h>\r
30#include <Protocol/HiiDatabase.h>\r
31#include <Protocol/FormBrowser2.h>\r
32#include <Protocol/LoadedImage.h>\r
33#include <Protocol/FirmwareVolume2.h>\r
34#include <Protocol/PciIo.h>\r
35#include <Protocol/BusSpecificDriverOverride.h>\r
36#include <Protocol/ComponentName2.h>\r
37#include <Protocol/ComponentName.h>\r
38#include <Protocol/DriverBinding.h>\r
39#include <Protocol/DevicePathToText.h>\r
40#include <Protocol/DevicePath.h>\r
41#include <Guid/MdeModuleHii.h>\r
42\r
43#include <Library/DevicePathLib.h>\r
44#include <Library/BaseLib.h>\r
45#include <Library/DebugLib.h>\r
46#include <Library/UefiLib.h>\r
47#include <Library/UefiApplicationEntryPoint.h>\r
48#include <Library/UefiBootServicesTableLib.h>\r
49#include <Library/PlatformDriverOverrideLib.h>\r
50#include <Library/BaseMemoryLib.h>\r
51#include <Library/MemoryAllocationLib.h>\r
52#include <Library/DevicePathLib.h>\r
53#include <Library/HiiLib.h>\r
54\r
55#include "PlatOverMngr.h"\r
56\r
57#define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')\r
58#define EFI_CALLBACK_INFO_FROM_THIS(a) CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)\r
59\r
60typedef struct {\r
61 UINTN Signature;\r
62 EFI_HANDLE DriverHandle;\r
63 EFI_HII_HANDLE RegisteredHandle;\r
64 PLAT_OVER_MNGR_DATA FakeNvData;\r
65 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
66 EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;\r
67} EFI_CALLBACK_INFO;\r
68\r
69#pragma pack(1)\r
70\r
71///\r
72/// HII specific Vendor Device Path definition.\r
73///\r
74typedef struct {\r
75 VENDOR_DEVICE_PATH VendorDevicePath;\r
76 EFI_DEVICE_PATH_PROTOCOL End;\r
77} HII_VENDOR_DEVICE_PATH;\r
78\r
79#pragma pack()\r
80\r
81//\r
82// uni string and Vfr Binary data.\r
83//\r
84extern UINT8 VfrBin[];\r
85extern UINT8 PlatOverMngrStrings[];\r
86\r
87//\r
88// module global data\r
89//\r
90EFI_GUID mPlatformOverridesManagerGuid = PLAT_OVER_MNGR_GUID;\r
91CHAR16 mVariableName[] = L"Data";\r
92LIST_ENTRY mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
93\r
94EFI_HANDLE *mDevicePathHandleBuffer;\r
95EFI_HANDLE *mDriverImageHandleBuffer;\r
96\r
97INTN mSelectedCtrIndex;\r
98EFI_STRING_ID mControllerToken[MAX_CHOICE_NUM];\r
99UINTN mDriverImageHandleCount;\r
100EFI_STRING_ID mDriverImageToken[MAX_CHOICE_NUM];\r
101EFI_STRING_ID mDriverImageFilePathToken[MAX_CHOICE_NUM];\r
102EFI_LOADED_IMAGE_PROTOCOL *mDriverImageProtocol[MAX_CHOICE_NUM];\r
103EFI_DEVICE_PATH_PROTOCOL *mControllerDevicePathProtocol[MAX_CHOICE_NUM];\r
104UINTN mSelectedDriverImageNum;\r
105UINTN mLastSavedDriverImageNum;\r
106UINT16 mCurrentPage;\r
107EFI_CALLBACK_INFO *mCallbackInfo;\r
108\r
109HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {\r
110 {\r
111 {\r
112 HARDWARE_DEVICE_PATH,\r
113 HW_VENDOR_DP,\r
114 {\r
115 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
116 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
117 }\r
118 },\r
119 EFI_CALLER_ID_GUID\r
120 },\r
121 {\r
122 END_DEVICE_PATH_TYPE,\r
123 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
124 { \r
125 (UINT8) (END_DEVICE_PATH_LENGTH),\r
126 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
127 }\r
128 }\r
129};\r
130\r
131/**\r
132 Converting a given device to an unicode string. \r
133 \r
134 This function will dependent on gEfiDevicePathToTextProtocolGuid, if protocol\r
135 does not installed, then return unknown device path L"?" directly.\r
136 \r
137 @param DevPath Given device path instance\r
138 \r
139 @return Converted string from given device path.\r
140 @retval L"?" Can not locate gEfiDevicePathToTextProtocolGuid protocol for converting.\r
141**/\r
142CHAR16 *\r
143DevicePathToStr (\r
144 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
145 );\r
146\r
147/**\r
148 Worker function to get the driver name by ComponentName or ComponentName2 protocol \r
149 according to the driver binding handle.\r
150\r
151 @param DriverBindingHandle The Handle of DriverBinding.\r
152 @param ProtocolGuid The pointer to Component Name (2) protocol GUID.\r
153 @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.\r
154\r
155 @retval !NULL Pointer into the image name if the image name is found,\r
156 @retval NULL Pointer to NULL if the image name is not found.\r
157\r
158**/\r
159CHAR16 *\r
160GetComponentNameWorker (\r
161 IN EFI_HANDLE DriverBindingHandle,\r
162 IN EFI_GUID *ProtocolGuid,\r
163 IN CONST CHAR16 *VariableName\r
164 )\r
165{\r
166 EFI_STATUS Status;\r
167 EFI_COMPONENT_NAME_PROTOCOL *ComponentName;\r
168 CHAR16 *DriverName;\r
169 CHAR8 *Language;\r
170 CHAR8 *BestLanguage;\r
171\r
172 Status = gBS->OpenProtocol (\r
173 DriverBindingHandle,\r
174 ProtocolGuid,\r
175 (VOID *) &ComponentName,\r
176 NULL,\r
177 NULL,\r
178 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
179 );\r
180 if (EFI_ERROR (Status)) {\r
181 return NULL;\r
182 }\r
183\r
184 //\r
185 // Find the best matching language.\r
186 //\r
187 Language = GetEfiGlobalVariable (VariableName);\r
188 BestLanguage = GetBestLanguage (\r
189 ComponentName->SupportedLanguages,\r
190 (BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid),\r
191 Language,\r
192 NULL\r
193 );\r
194\r
195 DriverName = NULL;\r
196 if (BestLanguage != NULL) {\r
197 ComponentName->GetDriverName (\r
198 ComponentName,\r
199 BestLanguage,\r
200 &DriverName\r
201 );\r
202 FreePool (BestLanguage);\r
203 }\r
204\r
205 if (Language != NULL) {\r
206 FreePool (Language);\r
207 }\r
208\r
209 return DriverName;\r
210}\r
211\r
212\r
213/**\r
214 Get the driver name by ComponentName or ComponentName2 protocol \r
215 according to the driver binding handle\r
216\r
217 @param DriverBindingHandle The Handle of DriverBinding.\r
218\r
219 @retval !NULL Pointer into the image name if the image name is found,\r
220 @retval NULL Pointer to NULL if the image name is not found.\r
221\r
222**/\r
223CHAR16 *\r
224GetComponentName (\r
225 IN EFI_HANDLE DriverBindingHandle\r
226 )\r
227{\r
228 CHAR16 *DriverName;\r
229\r
230 //\r
231 // Try RFC 4646 Component Name 2 protocol first.\r
232 //\r
233 DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentName2ProtocolGuid, L"PlatformLang");\r
234 if (DriverName == NULL) {\r
235 //\r
236 // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol. \r
237 //\r
238 DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentNameProtocolGuid, L"Lang");\r
239 }\r
240\r
241 return DriverName;\r
242}\r
243\r
244/**\r
245 Get the image name from EFI UI section.\r
246 Get FV protocol by its loaded image protocol to abstract EFI UI section.\r
247\r
248 @param Image Pointer to the loaded image protocol\r
249\r
250 @retval !NULL Pointer to the image name if the image name is found,\r
251 @retval NULL NULL if the image name is not found.\r
252\r
253**/\r
254CHAR16 *\r
255GetImageName (\r
256 IN EFI_LOADED_IMAGE_PROTOCOL *Image\r
257 )\r
258{\r
259 EFI_STATUS Status;\r
260 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
261 EFI_DEVICE_PATH_PROTOCOL *AlignedDevPathNode;\r
262 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;\r
263 VOID *Buffer;\r
264 UINTN BufferSize;\r
265 UINT32 AuthenticationStatus;\r
266 EFI_GUID *NameGuid;\r
267 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;\r
268\r
269 Fv2 = NULL;\r
270 Buffer = NULL;\r
271 BufferSize = 0;\r
272\r
273 if (Image->FilePath == NULL) {\r
274 return NULL;\r
275 }\r
276 DevPathNode = Image->FilePath;\r
277\r
278 while (!IsDevicePathEnd (DevPathNode)) {\r
279 //\r
280 // Make sure device path node is aligned when accessing it's FV Name Guid field.\r
281 //\r
282 AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength(DevPathNode), DevPathNode);\r
283 \r
284 //\r
285 // Find the Fv File path\r
286 //\r
287 NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)AlignedDevPathNode);\r
288 if (NameGuid != NULL) {\r
289 FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) AlignedDevPathNode;\r
290 Status = gBS->HandleProtocol (\r
291 Image->DeviceHandle,\r
292 &gEfiFirmwareVolume2ProtocolGuid,\r
293 (VOID **) &Fv2\r
294 );\r
295 //\r
296 // Locate Image EFI UI section to get the image name.\r
297 //\r
298 if (!EFI_ERROR (Status)) {\r
299 Status = Fv2->ReadSection (\r
300 Fv2,\r
301 &FvFilePath->FvFileName,\r
302 EFI_SECTION_USER_INTERFACE,\r
303 0,\r
304 &Buffer,\r
305 &BufferSize,\r
306 &AuthenticationStatus\r
307 );\r
308 if (!EFI_ERROR (Status)) {\r
309 FreePool (AlignedDevPathNode);\r
310 break;\r
311 }\r
312 Buffer = NULL;\r
313 }\r
314 }\r
315 \r
316 FreePool (AlignedDevPathNode);\r
317 \r
318 //\r
319 // Next device path node\r
320 //\r
321 DevPathNode = NextDevicePathNode (DevPathNode);\r
322 }\r
323\r
324 return Buffer;\r
325}\r
326\r
327/**\r
328 Prepare the first page to let user select the device controller which need to\r
329 add mapping drivers if user select 'Refresh' in first page.\r
330 During first page, user will see all currnet controller device path in system,\r
331 select any device path will go to second page to select its overrides drivers.\r
332\r
333 @param Private Pointer to EFI_CALLBACK_INFO.\r
334 @param KeyValue The callback key value of device controller item in first page.\r
335 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
336\r
337 @retval EFI_SUCCESS Always returned.\r
338\r
339**/\r
340EFI_STATUS\r
341UpdateDeviceSelectPage (\r
342 IN EFI_CALLBACK_INFO *Private,\r
343 IN UINT16 KeyValue,\r
344 IN PLAT_OVER_MNGR_DATA *FakeNvData\r
345 )\r
346{\r
347 EFI_STATUS Status;\r
348 UINTN Index;\r
349 UINTN DevicePathHandleCount;\r
350 CHAR16 *NewString;\r
351 EFI_STRING_ID NewStringToken;\r
352 CHAR16 *ControllerName;\r
353 EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
354 EFI_PCI_IO_PROTOCOL *PciIo;\r
355 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
356 UINTN Len;\r
357 VOID *StartOpCodeHandle;\r
358 VOID *EndOpCodeHandle;\r
359 EFI_IFR_GUID_LABEL *StartLabel;\r
360 EFI_IFR_GUID_LABEL *EndLabel; \r
361\r
362 //\r
363 // Set current page form ID.\r
364 //\r
365 mCurrentPage = FORM_ID_DEVICE; \r
366 \r
367 //\r
368 // Initial the mapping database in memory\r
369 //\r
370 FreeMappingDatabase (&mMappingDataBase);\r
371 InitOverridesMapping (&mMappingDataBase);\r
372\r
373 //\r
374 // Init OpCode Handle\r
375 //\r
376 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
377 ASSERT (StartOpCodeHandle != NULL);\r
378\r
379 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
380 ASSERT (EndOpCodeHandle != NULL);\r
381\r
382 //\r
383 // Create Hii Extend Label OpCode as the start opcode\r
384 //\r
385 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
386 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
387 StartLabel->Number = FORM_ID_DEVICE;\r
388\r
389 //\r
390 // Create Hii Extend Label OpCode as the end opcode\r
391 //\r
392 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
393 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
394 EndLabel->Number = LABEL_END;\r
395\r
396 //\r
397 // Clear first page form\r
398 //\r
399 HiiUpdateForm (\r
400 Private->RegisteredHandle,\r
401 &mPlatformOverridesManagerGuid,\r
402 FORM_ID_DEVICE,\r
403 StartOpCodeHandle, // Label FORM_ID_DEVICE\r
404 EndOpCodeHandle // LABEL_END\r
405 );\r
406\r
407 //\r
408 // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,\r
409 // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement\r
410 //\r
411 NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);\r
412 NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), NULL);\r
413 ASSERT (NewString != NULL);\r
414 if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {\r
415 ASSERT (FALSE);\r
416 }\r
417 FreePool (NewString);\r
418\r
419 NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);\r
420 NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), NULL);\r
421 ASSERT (NewString != NULL);\r
422 if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {\r
423 ASSERT (FALSE);\r
424 }\r
425 FreePool (NewString);\r
426\r
427 //\r
428 // created needed controller device item in first page\r
429 //\r
430 DevicePathHandleCount = 0;\r
431 Status = gBS->LocateHandleBuffer (\r
432 ByProtocol,\r
433 &gEfiDevicePathProtocolGuid,\r
434 NULL,\r
435 &DevicePathHandleCount,\r
436 &mDevicePathHandleBuffer\r
437 );\r
438 if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {\r
439 return EFI_SUCCESS;\r
440 }\r
441\r
442 for (Index = 0; Index < DevicePathHandleCount; Index++) {\r
443 if (FakeNvData->PciDeviceFilter == 0x01) {\r
444 //\r
445 // Only care PCI device which contain efi driver in its option rom.\r
446 //\r
447\r
448 //\r
449 // Check whether it is a pci device\r
450 //\r
451 ControllerDevicePath = NULL;\r
452 Status = gBS->OpenProtocol (\r
453 mDevicePathHandleBuffer[Index],\r
454 &gEfiPciIoProtocolGuid,\r
455 (VOID **) &PciIo,\r
456 NULL,\r
457 NULL,\r
458 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
459 );\r
460 if (EFI_ERROR (Status)) {\r
461 continue;\r
462 }\r
463 //\r
464 // Check whether it contain efi driver in its option rom\r
465 //\r
466 Status = gBS->HandleProtocol(\r
467 mDevicePathHandleBuffer[Index],\r
468 &gEfiBusSpecificDriverOverrideProtocolGuid,\r
469 (VOID **) &BusSpecificDriverOverride\r
470 );\r
471 if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
472 continue;\r
473 }\r
474 }\r
475\r
476 ControllerDevicePath = NULL;\r
477 Status = gBS->OpenProtocol (\r
478 mDevicePathHandleBuffer[Index],\r
479 &gEfiDevicePathProtocolGuid,\r
480 (VOID **) &ControllerDevicePath,\r
481 NULL,\r
482 NULL,\r
483 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
484 );\r
485 ASSERT_EFI_ERROR (Status);\r
486 //\r
487 // Save the device path protocol interface\r
488 //\r
489 mControllerDevicePathProtocol[Index] = ControllerDevicePath;\r
490\r
491 //\r
492 // Get the driver name\r
493 //\r
494 ControllerName = DevicePathToStr (ControllerDevicePath);\r
495\r
496 //\r
497 // Export the driver name string and create item in set options page\r
498 //\r
499 Len = StrSize (ControllerName);\r
500 NewString = AllocateZeroPool (Len + StrSize (L"--"));\r
501 ASSERT (NewString != NULL);\r
502 if (EFI_ERROR (CheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {\r
503 StrCat (NewString, L"--");\r
504 } else {\r
505 StrCat (NewString, L"**");\r
506 }\r
507 StrCat (NewString, ControllerName);\r
508\r
509 NewStringToken = HiiSetString (Private->RegisteredHandle, mControllerToken[Index], NewString, NULL);\r
510 ASSERT (NewStringToken != 0);\r
511 FreePool (NewString);\r
512 //\r
513 // Save the device path string toke for next access use\r
514 //\r
515 mControllerToken[Index] = NewStringToken;\r
516 \r
517 HiiCreateGotoOpCode (\r
518 StartOpCodeHandle,\r
519 FORM_ID_DRIVER,\r
520 NewStringToken,\r
521 STRING_TOKEN (STR_GOTO_HELP_DRIVER),\r
522 EFI_IFR_FLAG_CALLBACK,\r
523 (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET)\r
524 );\r
525 }\r
526\r
527 //\r
528 // Update first page form\r
529 //\r
530 HiiUpdateForm (\r
531 Private->RegisteredHandle,\r
532 &mPlatformOverridesManagerGuid,\r
533 FORM_ID_DEVICE,\r
534 StartOpCodeHandle, // Label FORM_ID_DEVICE\r
535 EndOpCodeHandle // LABEL_END\r
536 );\r
537\r
538 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
539 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
540\r
541 return EFI_SUCCESS;\r
542}\r
543\r
544/**\r
545 Get the first Driver Binding handle which has the specific image handle.\r
546\r
547 @param ImageHandle The Image handle\r
548\r
549 @return Handle to Driver binding\r
550 @retval NULL The paramter is not valid or the driver binding handle is not found.\r
551\r
552**/\r
553EFI_HANDLE\r
554GetDriverBindingHandleFromImageHandle (\r
555 IN EFI_HANDLE ImageHandle\r
556 )\r
557{\r
558 EFI_STATUS Status;\r
559 UINTN Index;\r
560 UINTN DriverBindingHandleCount;\r
561 EFI_HANDLE *DriverBindingHandleBuffer;\r
562 EFI_DRIVER_BINDING_PROTOCOL *DriverBindingInterface;\r
563 EFI_HANDLE DriverBindingHandle;\r
564\r
565 DriverBindingHandle = NULL;\r
566\r
567 if (ImageHandle == NULL) {\r
568 return NULL;\r
569 }\r
570 //\r
571 // Get all drivers which support driver binding protocol\r
572 //\r
573 DriverBindingHandleCount = 0;\r
574 Status = gBS->LocateHandleBuffer (\r
575 ByProtocol,\r
576 &gEfiDriverBindingProtocolGuid,\r
577 NULL,\r
578 &DriverBindingHandleCount,\r
579 &DriverBindingHandleBuffer\r
580 );\r
581 if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
582 return NULL;\r
583 }\r
584 \r
585 //\r
586 // Get the first Driver Binding handle which has the specific image handle.\r
587 //\r
588 for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
589 DriverBindingInterface = NULL;\r
590 Status = gBS->OpenProtocol (\r
591 DriverBindingHandleBuffer[Index],\r
592 &gEfiDriverBindingProtocolGuid,\r
593 (VOID **) &DriverBindingInterface,\r
594 NULL,\r
595 NULL,\r
596 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
597 );\r
598 if (EFI_ERROR (Status)) {\r
599 continue;\r
600 }\r
601\r
602 if (DriverBindingInterface->ImageHandle == ImageHandle) {\r
603 DriverBindingHandle = DriverBindingHandleBuffer[Index];\r
604 break;\r
605 }\r
606 }\r
607\r
608 FreePool (DriverBindingHandleBuffer);\r
609 return DriverBindingHandle;\r
610}\r
611\r
612/**\r
613 Prepare to let user select the drivers which need mapping with the device controller\r
614 selected in first page.\r
615\r
616 @param Private Pointer to EFI_CALLBACK_INFO.\r
617 @param KeyValue The callback key value of device controller item in first page.\r
618 KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.\r
619 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
620\r
621 @retval EFI_SUCCESS Always returned.\r
622\r
623**/\r
624EFI_STATUS\r
625UpdateBindingDriverSelectPage (\r
626 IN EFI_CALLBACK_INFO *Private,\r
627 IN UINT16 KeyValue,\r
628 IN PLAT_OVER_MNGR_DATA *FakeNvData\r
629 )\r
630{\r
631 EFI_STATUS Status;\r
632 UINTN Index;\r
633 CHAR16 *NewString;\r
634 EFI_STRING_ID NewStringToken;\r
635 EFI_STRING_ID NewStringHelpToken;\r
636 UINTN DriverImageHandleCount;\r
637 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
638 CHAR16 *DriverName;\r
639 BOOLEAN FreeDriverName;\r
640 EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
641 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
642 EFI_HANDLE DriverBindingHandle;\r
643 VOID *StartOpCodeHandle;\r
644 VOID *EndOpCodeHandle;\r
645 EFI_IFR_GUID_LABEL *StartLabel;\r
646 EFI_IFR_GUID_LABEL *EndLabel;\r
647\r
648 //\r
649 // If user select a controller item in the first page the following code will be run.\r
650 // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown\r
651 //\r
652 //First acquire the list of Loaded Image Protocols, and then when want the name of the driver, look up all the Driver Binding Protocols\r
653 // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.\r
654 // then use the Component Name Protocol on the same handle as the first matching Driver Binding Protocol to look up the name of the driver.\r
655 //\r
656\r
657 mCurrentPage = FORM_ID_DRIVER;\r
658 //\r
659 // Switch the item callback key value to its NO. in mDevicePathHandleBuffer\r
660 //\r
661 mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET;\r
662 ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM);\r
663\r
664 mLastSavedDriverImageNum = 0;\r
665\r
666 //\r
667 // Init OpCode Handle\r
668 //\r
669 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
670 ASSERT (StartOpCodeHandle != NULL);\r
671\r
672 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
673 ASSERT (EndOpCodeHandle != NULL);\r
674\r
675 //\r
676 // Create Hii Extend Label OpCode as the start opcode\r
677 //\r
678 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
679 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
680 StartLabel->Number = FORM_ID_DRIVER;\r
681\r
682 //\r
683 // Create Hii Extend Label OpCode as the end opcode\r
684 //\r
685 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
686 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
687 EndLabel->Number = LABEL_END;\r
688\r
689 //\r
690 // Clear second page form\r
691 //\r
692 HiiUpdateForm (\r
693 Private->RegisteredHandle,\r
694 &mPlatformOverridesManagerGuid,\r
695 FORM_ID_DRIVER,\r
696 StartOpCodeHandle,\r
697 EndOpCodeHandle\r
698 );\r
699\r
700 //\r
701 // Show all driver which support loaded image protocol in second page\r
702 //\r
703 DriverImageHandleCount = 0;\r
704 Status = gBS->LocateHandleBuffer (\r
705 ByProtocol,\r
706 &gEfiLoadedImageProtocolGuid,\r
707 NULL,\r
708 &DriverImageHandleCount,\r
709 &mDriverImageHandleBuffer\r
710 );\r
711 if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {\r
712 return EFI_NOT_FOUND;\r
713 }\r
714\r
715 mDriverImageHandleCount = DriverImageHandleCount;\r
716 for (Index = 0; Index < DriverImageHandleCount; Index++) {\r
717 //\r
718 // Step1: Get the driver image total file path for help string and the driver name.\r
719 //\r
720\r
721 //\r
722 // Find driver's Loaded Image protocol\r
723 //\r
724 LoadedImage =NULL;\r
725\r
726 Status = gBS->OpenProtocol (\r
727 mDriverImageHandleBuffer[Index],\r
728 &gEfiLoadedImageProtocolGuid,\r
729 (VOID **) &LoadedImage,\r
730 NULL,\r
731 NULL,\r
732 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
733 );\r
734 if (EFI_ERROR (Status)) {\r
735 FakeNvData->DriSelection[Index] = 0x00;\r
736 continue;\r
737 }\r
738 mDriverImageProtocol[Index] = LoadedImage;\r
739 //\r
740 // Find its related driver binding protocol\r
741 //\r
742 DriverBindingHandle = GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer[Index]);\r
743 if (DriverBindingHandle == NULL) {\r
744 FakeNvData->DriSelection[Index] = 0x00;\r
745 continue;\r
746 }\r
747\r
748 //\r
749 // Get the EFI Loaded Image Device Path Protocol\r
750 //\r
751 LoadedImageDevicePath = NULL;\r
752 Status = gBS->HandleProtocol (\r
753 mDriverImageHandleBuffer[Index],\r
754 &gEfiLoadedImageDevicePathProtocolGuid,\r
755 (VOID **) &LoadedImageDevicePath\r
756 );\r
757 if (LoadedImageDevicePath == NULL) {\r
758 FakeNvData->DriSelection[Index] = 0x00;\r
759 continue;\r
760 }\r
761\r
762 if (FakeNvData->PciDeviceFilter == 0x01) {\r
763 //\r
764 // only care the driver which is in a Pci device option rom,\r
765 // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom\r
766 //\r
767 if (!EFI_ERROR (Status)) {\r
768 Status = gBS->HandleProtocol(\r
769 LoadedImage->DeviceHandle,\r
770 &gEfiBusSpecificDriverOverrideProtocolGuid,\r
771 (VOID **) &BusSpecificDriverOverride\r
772 );\r
773 if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
774 FakeNvData->DriSelection[Index] = 0x00;\r
775 continue;\r
776 }\r
777 } else {\r
778 FakeNvData->DriSelection[Index] = 0x00;\r
779 continue;\r
780 }\r
781 }\r
782\r
783 //\r
784 // For driver name, try to get its component name, if fail, get its image name,\r
785 // if also fail, give a default name.\r
786 //\r
787 FreeDriverName = FALSE;\r
788 DriverName = GetComponentName (DriverBindingHandle);\r
789 if (DriverName == NULL) {\r
790 //\r
791 // get its image name\r
792 //\r
793 DriverName = GetImageName (LoadedImage);\r
794 }\r
795 if (DriverName == NULL) {\r
796 //\r
797 // give a default name\r
798 //\r
799 DriverName = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME), NULL);\r
800 ASSERT (DriverName != NULL);\r
801 FreeDriverName = TRUE; // the DriverName string need to free pool\r
802 }\r
803\r
804\r
805 //\r
806 // Step2 Export the driver name string and create check box item in second page\r
807 //\r
808\r
809 //\r
810 // First create the driver image name\r
811 //\r
812 NewString = AllocateZeroPool (StrSize (DriverName));\r
813 ASSERT (NewString != NULL); \r
814 if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {\r
815 FakeNvData->DriSelection[Index] = 0x00;\r
816 } else {\r
817 FakeNvData->DriSelection[Index] = 0x01;\r
818 mLastSavedDriverImageNum++;\r
819 }\r
820 StrCat (NewString, DriverName);\r
821 NewStringToken = HiiSetString (Private->RegisteredHandle, mDriverImageToken[Index], NewString, NULL);\r
822 ASSERT (NewStringToken != 0);\r
823 mDriverImageToken[Index] = NewStringToken;\r
824 FreePool (NewString);\r
825 if (FreeDriverName) {\r
826 FreePool (DriverName);\r
827 }\r
828\r
829 //\r
830 // Second create the driver image device path as item help string\r
831 //\r
832 DriverName = DevicePathToStr (LoadedImageDevicePath);\r
833\r
834 NewString = AllocateZeroPool (StrSize (DriverName));\r
835 ASSERT (NewString != NULL); \r
836 StrCat (NewString, DriverName);\r
837 NewStringHelpToken = HiiSetString (Private->RegisteredHandle, mDriverImageFilePathToken[Index], NewString, NULL);\r
838 ASSERT (NewStringHelpToken != 0);\r
839 mDriverImageFilePathToken[Index] = NewStringHelpToken;\r
840 FreePool (NewString);\r
841 FreePool (DriverName);\r
842\r
843 HiiCreateCheckBoxOpCode (\r
844 StartOpCodeHandle,\r
845 (UINT16) (DRIVER_SELECTION_QUESTION_ID + Index),\r
846 VARSTORE_ID_PLAT_OVER_MNGR,\r
847 (UINT16) (DRIVER_SELECTION_VAR_OFFSET + Index),\r
848 NewStringToken,\r
849 NewStringHelpToken,\r
850 0,\r
851 0,\r
852 NULL\r
853 );\r
854 }\r
855\r
856 //\r
857 // Update second page form\r
858 //\r
859 HiiUpdateForm (\r
860 Private->RegisteredHandle,\r
861 &mPlatformOverridesManagerGuid,\r
862 FORM_ID_DRIVER,\r
863 StartOpCodeHandle, // Label FORM_ID_DRIVER\r
864 EndOpCodeHandle // LABEL_END\r
865 );\r
866\r
867 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
868 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
869 return EFI_SUCCESS;\r
870}\r
871\r
872/**\r
873 Prepare to let user select the priority order of the drivers which are\r
874 selected in second page.\r
875\r
876 @param Private Pointer to EFI_CALLBACK_INFO.\r
877 @param KeyValue The callback key value of device controller item in first page.\r
878 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
879\r
880 @retval EFI_SUCCESS Always returned.\r
881\r
882**/\r
883EFI_STATUS\r
884UpdatePrioritySelectPage (\r
885 IN EFI_CALLBACK_INFO *Private,\r
886 IN UINT16 KeyValue,\r
887 IN PLAT_OVER_MNGR_DATA *FakeNvData\r
888 )\r
889{\r
890 UINTN Index;\r
891 EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
892 UINTN SelectedDriverImageNum;\r
893 UINT32 DriverImageNO;\r
894 UINTN MinNO;\r
895 UINTN Index1;\r
896 UINTN TempNO[100];\r
897 UINTN OrderNO[100];\r
898 VOID *StartOpCodeHandle;\r
899 VOID *EndOpCodeHandle;\r
900 VOID *OptionsOpCodeHandle;\r
901 EFI_IFR_GUID_LABEL *StartLabel;\r
902 EFI_IFR_GUID_LABEL *EndLabel;\r
903\r
904 //\r
905 // Following code will be run if user select 'order ... priority' item in second page\r
906 // Prepare third page. In third page, user will order the drivers priority which are selected in second page\r
907 //\r
908 mCurrentPage = FORM_ID_ORDER;\r
909\r
910 //\r
911 // Init OpCode Handle\r
912 //\r
913 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
914 ASSERT (StartOpCodeHandle != NULL);\r
915\r
916 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
917 ASSERT (EndOpCodeHandle != NULL);\r
918\r
919 //\r
920 // Create Hii Extend Label OpCode as the start opcode\r
921 //\r
922 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
923 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
924 StartLabel->Number = FORM_ID_ORDER;\r
925\r
926 //\r
927 // Create Hii Extend Label OpCode as the end opcode\r
928 //\r
929 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
930 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
931 EndLabel->Number = LABEL_END;\r
932\r
933 //\r
934 // Clear third page form\r
935 //\r
936 HiiUpdateForm (\r
937 Private->RegisteredHandle,\r
938 &mPlatformOverridesManagerGuid,\r
939 FORM_ID_ORDER,\r
940 StartOpCodeHandle,\r
941 EndOpCodeHandle\r
942 );\r
943\r
944 //\r
945 // Check how many drivers have been selected\r
946 //\r
947 SelectedDriverImageNum = 0;\r
948 for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
949 if (FakeNvData->DriSelection[Index] != 0) {\r
950 SelectedDriverImageNum ++;\r
951 }\r
952 }\r
953\r
954 mSelectedDriverImageNum = SelectedDriverImageNum;\r
955 if (SelectedDriverImageNum == 0) {\r
956 return EFI_SUCCESS;\r
957 }\r
958\r
959 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
960 ASSERT (OptionsOpCodeHandle != NULL);\r
961\r
962 //\r
963 // Create order list for those selected drivers\r
964 //\r
965 SelectedDriverImageNum = 0;\r
966 for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
967 if (FakeNvData->DriSelection[Index] != 0) {\r
968 //\r
969 // Use the NO. in driver binding buffer as value, will use it later\r
970 //\r
971 HiiCreateOneOfOptionOpCode (\r
972 OptionsOpCodeHandle,\r
973 mDriverImageToken[Index],\r
974 0,\r
975 EFI_IFR_NUMERIC_SIZE_1,\r
976 Index + 1\r
977 );\r
978\r
979 //\r
980 // Get the EFI Loaded Image Device Path Protocol\r
981 //\r
982 LoadedImageDevicePath = NULL;\r
983 gBS->HandleProtocol (\r
984 mDriverImageHandleBuffer[Index],\r
985 &gEfiLoadedImageDevicePathProtocolGuid,\r
986 (VOID **) &LoadedImageDevicePath\r
987 );\r
988 ASSERT (LoadedImageDevicePath != NULL);\r
989\r
990 //\r
991 // Check the driver DriverImage's order number in mapping database\r
992 //\r
993 DriverImageNO = 0;\r
994 CheckMapping (\r
995 mControllerDevicePathProtocol[mSelectedCtrIndex],\r
996 LoadedImageDevicePath,\r
997 &mMappingDataBase,\r
998 NULL,\r
999 &DriverImageNO\r
1000 );\r
1001 if (DriverImageNO == 0) {\r
1002 DriverImageNO = (UINT32) mLastSavedDriverImageNum + 1;\r
1003 mLastSavedDriverImageNum++;\r
1004 }\r
1005 TempNO[SelectedDriverImageNum] = DriverImageNO;\r
1006 OrderNO[SelectedDriverImageNum] = Index + 1;\r
1007 SelectedDriverImageNum ++;\r
1008 }\r
1009 }\r
1010\r
1011 ASSERT (SelectedDriverImageNum == mSelectedDriverImageNum);\r
1012 //\r
1013 // NvRamMap Must be clear firstly\r
1014 //\r
1015 ZeroMem (FakeNvData->DriOrder, sizeof (FakeNvData->DriOrder));\r
1016\r
1017 //\r
1018 // Order the selected drivers according to the info already in mapping database\r
1019 // the less order number in mapping database the less order number in NvRamMap\r
1020 //\r
1021 for (Index=0; Index < SelectedDriverImageNum; Index++) {\r
1022 //\r
1023 // Find the minimal order number in TempNO array, its index in TempNO is same as IfrOptionList array\r
1024 //\r
1025 MinNO = 0;\r
1026 for (Index1=0; Index1 < SelectedDriverImageNum; Index1++) {\r
1027 if (TempNO[Index1] < TempNO[MinNO]) {\r
1028 MinNO = Index1;\r
1029 }\r
1030 }\r
1031 //\r
1032 // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer\r
1033 //\r
1034 FakeNvData->DriOrder[Index] = (UINT8) OrderNO[MinNO];\r
1035 TempNO[MinNO] = MAX_CHOICE_NUM + 1;\r
1036 }\r
1037 \r
1038 //\r
1039 // Create Order List OpCode\r
1040 //\r
1041 HiiCreateOrderedListOpCode (\r
1042 StartOpCodeHandle,\r
1043 (UINT16) DRIVER_ORDER_QUESTION_ID,\r
1044 VARSTORE_ID_PLAT_OVER_MNGR,\r
1045 (UINT16) DRIVER_ORDER_VAR_OFFSET,\r
1046 mControllerToken[mSelectedCtrIndex],\r
1047 mControllerToken[mSelectedCtrIndex],\r
1048 EFI_IFR_FLAG_RESET_REQUIRED,\r
1049 0,\r
1050 EFI_IFR_NUMERIC_SIZE_1,\r
1051 (UINT8) MAX_CHOICE_NUM,\r
1052 OptionsOpCodeHandle,\r
1053 NULL\r
1054 );\r
1055\r
1056 //\r
1057 // Update third page form\r
1058 //\r
1059 HiiUpdateForm (\r
1060 Private->RegisteredHandle,\r
1061 &mPlatformOverridesManagerGuid,\r
1062 FORM_ID_ORDER,\r
1063 StartOpCodeHandle, // Label FORM_ID_ORDER\r
1064 EndOpCodeHandle // LABEL_END\r
1065 );\r
1066\r
1067 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1068 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1069 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
1070\r
1071 return EFI_SUCCESS;\r
1072}\r
1073\r
1074/**\r
1075 Save the save the mapping database to NV variable.\r
1076\r
1077 @param Private Pointer to EFI_CALLBACK_INFO.\r
1078 @param KeyValue The callback key value of device controller item in first page.\r
1079 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
1080\r
1081 @retval EFI_SUCCESS Always returned.\r
1082\r
1083**/\r
1084EFI_STATUS\r
1085CommintChanges (\r
1086 IN EFI_CALLBACK_INFO *Private,\r
1087 IN UINT16 KeyValue,\r
1088 IN PLAT_OVER_MNGR_DATA *FakeNvData\r
1089 )\r
1090{\r
1091 EFI_STATUS Status;\r
1092 UINTN Index;\r
1093 UINTN SelectedDriverImageNum;\r
1094 EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
1095 //\r
1096 // Following code will be run if user select 'commint changes' in third page\r
1097 // user enter 'Commit Changes' to save the mapping database\r
1098 //\r
1099 DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);\r
1100 for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {\r
1101 //\r
1102 // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer\r
1103 //\r
1104 Index = FakeNvData->DriOrder[SelectedDriverImageNum] - 1;\r
1105\r
1106 //\r
1107 // Get the EFI Loaded Image Device Path Protocol\r
1108 //\r
1109 LoadedImageDevicePath = NULL;\r
1110 Status = gBS->HandleProtocol (\r
1111 mDriverImageHandleBuffer[Index],\r
1112 &gEfiLoadedImageDevicePathProtocolGuid,\r
1113 (VOID **) &LoadedImageDevicePath\r
1114 );\r
1115 ASSERT (LoadedImageDevicePath != NULL);\r
1116\r
1117 InsertDriverImage (\r
1118 mControllerDevicePathProtocol[mSelectedCtrIndex],\r
1119 LoadedImageDevicePath,\r
1120 &mMappingDataBase,\r
1121 (UINT32)SelectedDriverImageNum + 1\r
1122 );\r
1123 }\r
1124 Status = SaveOverridesMapping (&mMappingDataBase);\r
1125\r
1126 return Status;\r
1127}\r
1128\r
1129/**\r
1130 This function allows a caller to extract the current configuration for one\r
1131 or more named elements from the target driver.\r
1132\r
1133 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1134 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
1135 @param Progress On return, points to a character in the Request string.\r
1136 Points to the string's null terminator if request was successful.\r
1137 Points to the most recent '&' before the first failing name/value\r
1138 pair (or the beginning of the string if the failure is in the\r
1139 first name/value pair) if the request was not successful.\r
1140 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
1141 has all values filled in for the names in the Request string.\r
1142 String to be allocated by the called function.\r
1143\r
1144 @retval EFI_SUCCESS The Results is filled with the requested values.\r
1145 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
1146 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
1147 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
1148\r
1149**/\r
1150EFI_STATUS\r
1151EFIAPI\r
1152PlatOverMngrExtractConfig (\r
1153 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1154 IN CONST EFI_STRING Request,\r
1155 OUT EFI_STRING *Progress,\r
1156 OUT EFI_STRING *Results\r
1157 )\r
1158{\r
1159 EFI_STATUS Status;\r
1160 EFI_CALLBACK_INFO *Private;\r
1161 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
1162 \r
1163 if (Request == NULL) {\r
1164 return EFI_NOT_FOUND;\r
1165 }\r
1166\r
1167 Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
1168 HiiConfigRouting = Private->HiiConfigRouting;\r
1169\r
1170 //\r
1171 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
1172 //\r
1173 Status = HiiConfigRouting->BlockToConfig (\r
1174 HiiConfigRouting,\r
1175 Request,\r
1176 (UINT8 *) &Private->FakeNvData,\r
1177 sizeof (PLAT_OVER_MNGR_DATA),\r
1178 Results,\r
1179 Progress\r
1180 );\r
1181 return Status;\r
1182}\r
1183\r
1184/**\r
1185 This function processes the results of changes in configuration.\r
1186\r
1187 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1188 @param Configuration A null-terminated Unicode string in <ConfigRequest> format.\r
1189 @param Progress A pointer to a string filled in with the offset of the most\r
1190 recent '&' before the first failing name/value pair (or the\r
1191 beginning of the string if the failure is in the first\r
1192 name/value pair) or the terminating NULL if all was successful.\r
1193\r
1194 @retval EFI_SUCCESS The Results is processed successfully.\r
1195 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
1196 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
1197\r
1198**/\r
1199EFI_STATUS\r
1200EFIAPI\r
1201PlatOverMngrRouteConfig (\r
1202 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1203 IN CONST EFI_STRING Configuration,\r
1204 OUT EFI_STRING *Progress\r
1205 )\r
1206{\r
1207 EFI_CALLBACK_INFO *Private;\r
1208 UINT16 KeyValue;\r
1209 PLAT_OVER_MNGR_DATA *FakeNvData;\r
1210\r
1211 Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
1212 FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA));\r
1213 if (FakeNvData == NULL) {\r
1214 return EFI_NOT_FOUND;\r
1215 }\r
1216\r
1217 if (mCurrentPage == FORM_ID_DRIVER) {\r
1218 KeyValue = KEY_VALUE_DRIVER_GOTO_ORDER;\r
1219 UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
1220 KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
1221 CommintChanges (Private, KeyValue, FakeNvData);\r
1222 //\r
1223 // Since UpdatePrioritySelectPage will change mCurrentPage,\r
1224 // should ensure the mCurrentPage still indicate the second page here\r
1225 //\r
1226 mCurrentPage = FORM_ID_DRIVER;\r
1227 }\r
1228\r
1229 if (mCurrentPage == FORM_ID_ORDER) {\r
1230 KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
1231 CommintChanges (Private, KeyValue, FakeNvData);\r
1232 }\r
1233\r
1234 if (FakeNvData != NULL) {\r
1235 FreePool (FakeNvData);\r
1236 }\r
1237\r
1238 return EFI_SUCCESS;\r
1239}\r
1240\r
1241/**\r
1242 This is the function that is called to provide results data to the driver. This data\r
1243 consists of a unique key which is used to identify what data is either being passed back\r
1244 or being asked for.\r
1245\r
1246 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1247 @param Action A null-terminated Unicode string in <ConfigRequest> format.\r
1248 @param KeyValue A unique Goto OpCode callback value which record user's selection.\r
1249 0x100 <= KeyValue <0x500 : user select a controller item in the first page;\r
1250 KeyValue == 0x1234 : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page\r
1251 KeyValue == 0x1235 : user select 'Pci device filter' in first page\r
1252 KeyValue == 0x1500 : user select 'order ... priority' item in second page\r
1253 KeyValue == 0x1800 : user select 'commint changes' in third page\r
1254 KeyValue == 0x2000 : user select 'Go to Previous Menu' in third page\r
1255 @param Type The type of value for the question.\r
1256 @param Value A pointer to the data being sent to the original exporting driver.\r
1257 @param ActionRequest On return, points to the action requested by the callback function.\r
1258\r
1259 @retval EFI_SUCCESS Always returned.\r
1260\r
1261**/\r
1262EFI_STATUS\r
1263EFIAPI\r
1264PlatOverMngrCallback (\r
1265 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1266 IN EFI_BROWSER_ACTION Action,\r
1267 IN EFI_QUESTION_ID KeyValue,\r
1268 IN UINT8 Type,\r
1269 IN EFI_IFR_TYPE_VALUE *Value,\r
1270 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
1271 )\r
1272{\r
1273 EFI_CALLBACK_INFO *Private;\r
1274 EFI_STATUS Status;\r
1275 EFI_STRING_ID NewStringToken;\r
1276 EFI_INPUT_KEY Key;\r
1277 PLAT_OVER_MNGR_DATA *FakeNvData;\r
1278 \r
1279 Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
1280 FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA));\r
1281 if (FakeNvData == NULL) {\r
1282 return EFI_NOT_FOUND;\r
1283 }\r
1284\r
1285 if (KeyValue == KEY_VALUE_DEVICE_REFRESH ||\r
1286 KeyValue == KEY_VALUE_DEVICE_FILTER ||\r
1287 KeyValue == KEY_VALUE_DRIVER_GOTO_PREVIOUS\r
1288 ) {\r
1289 UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
1290 //\r
1291 // Update page title string\r
1292 //\r
1293 NewStringToken = STRING_TOKEN (STR_TITLE);\r
1294 if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {\r
1295 ASSERT (FALSE);\r
1296 }\r
1297 }\r
1298\r
1299 if (((KeyValue >= KEY_VALUE_DEVICE_OFFSET) && (KeyValue < KEY_VALUE_DEVICE_MAX)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {\r
1300 if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {\r
1301 KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + KEY_VALUE_DEVICE_OFFSET);\r
1302 }\r
1303 UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);\r
1304 //\r
1305 // Update page title string\r
1306 //\r
1307 NewStringToken = STRING_TOKEN (STR_TITLE);\r
1308 if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Second, Select drivers for the previous selected controller", NULL) == 0) {\r
1309 ASSERT (FALSE);\r
1310 }\r
1311 }\r
1312\r
1313 if (KeyValue == KEY_VALUE_DRIVER_GOTO_ORDER) {\r
1314 UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
1315 //\r
1316 // Update page title string\r
1317 //\r
1318 NewStringToken = STRING_TOKEN (STR_TITLE);\r
1319 if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Finally, Set the priority order for the drivers and save them", NULL) == 0) {\r
1320 ASSERT (FALSE);\r
1321 }\r
1322 }\r
1323\r
1324 if (KeyValue == KEY_VALUE_ORDER_SAVE_AND_EXIT) {\r
1325 Status = CommintChanges (Private, KeyValue, FakeNvData);\r
1326 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1327 if (EFI_ERROR (Status)) {\r
1328 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Single Override Info too large, Saving Error!", NULL);\r
1329 return EFI_DEVICE_ERROR;\r
1330 }\r
1331 }\r
1332\r
1333 if (KeyValue == KEY_VALUE_DEVICE_CLEAR) {\r
1334 //\r
1335 // Deletes all environment variable(s) that contain the override mappings info\r
1336 //\r
1337 FreeMappingDatabase (&mMappingDataBase);\r
1338 Status = SaveOverridesMapping (&mMappingDataBase);\r
1339 UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
1340 }\r
1341 //\r
1342 // Pass changed uncommitted data back to Form Browser\r
1343 //\r
1344 HiiSetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData, NULL);\r
1345 \r
1346 //\r
1347 // Update local configuration buffer.\r
1348 //\r
1349 CopyMem (&Private->FakeNvData, FakeNvData, sizeof (PLAT_OVER_MNGR_DATA));\r
1350 if (FakeNvData != NULL) {\r
1351 FreePool (FakeNvData);\r
1352 }\r
1353\r
1354 return EFI_SUCCESS;\r
1355}\r
1356\r
1357/**\r
1358 The driver Entry Point. The funciton will export a disk device class formset and\r
1359 its callback function to hii database.\r
1360\r
1361 @param ImageHandle The firmware allocated handle for the EFI image.\r
1362 @param SystemTable A pointer to the EFI System Table.\r
1363\r
1364 @retval EFI_SUCCESS The entry point is executed successfully.\r
1365 @retval other Some error occurs when executing this entry point.\r
1366\r
1367**/\r
1368EFI_STATUS\r
1369EFIAPI\r
1370PlatOverMngrInit (\r
1371 IN EFI_HANDLE ImageHandle,\r
1372 IN EFI_SYSTEM_TABLE *SystemTable\r
1373 )\r
1374{\r
1375 EFI_STATUS Status;\r
1376 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
1377 \r
1378 //\r
1379 // There should only be one Form Configuration protocol\r
1380 //\r
1381 Status = gBS->LocateProtocol (\r
1382 &gEfiFormBrowser2ProtocolGuid,\r
1383 NULL,\r
1384 (VOID **) &FormBrowser2\r
1385 );\r
1386 if (EFI_ERROR (Status)) {\r
1387 return Status;\r
1388 }\r
1389\r
1390 mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));\r
1391 if (mCallbackInfo == NULL) {\r
1392 return EFI_BAD_BUFFER_SIZE;\r
1393 }\r
1394\r
1395 mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;\r
1396 mCallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;\r
1397 mCallbackInfo->ConfigAccess.RouteConfig = PlatOverMngrRouteConfig;\r
1398 mCallbackInfo->ConfigAccess.Callback = PlatOverMngrCallback;\r
1399\r
1400 //\r
1401 // Install Device Path Protocol and Config Access protocol to driver handle\r
1402 //\r
1403 Status = gBS->InstallMultipleProtocolInterfaces (\r
1404 &mCallbackInfo->DriverHandle,\r
1405 &gEfiDevicePathProtocolGuid,\r
1406 &mHiiVendorDevicePath,\r
1407 &gEfiHiiConfigAccessProtocolGuid,\r
1408 &mCallbackInfo->ConfigAccess,\r
1409 NULL\r
1410 );\r
1411 if (EFI_ERROR (Status)) {\r
1412 goto Finish;\r
1413 }\r
1414\r
1415 //\r
1416 // Publish our HII data\r
1417 //\r
1418 mCallbackInfo->RegisteredHandle = HiiAddPackages (\r
1419 &mPlatformOverridesManagerGuid,\r
1420 mCallbackInfo->DriverHandle,\r
1421 VfrBin,\r
1422 PlatOverMngrStrings,\r
1423 NULL\r
1424 );\r
1425 if (mCallbackInfo->RegisteredHandle == NULL) {\r
1426 Status = EFI_OUT_OF_RESOURCES;\r
1427 goto Finish;\r
1428 }\r
1429\r
1430 //\r
1431 // Locate ConfigRouting protocol\r
1432 //\r
1433 Status = gBS->LocateProtocol (\r
1434 &gEfiHiiConfigRoutingProtocolGuid,\r
1435 NULL,\r
1436 (VOID **) &mCallbackInfo->HiiConfigRouting\r
1437 );\r
1438 if (EFI_ERROR (Status)) {\r
1439 goto Finish;\r
1440 }\r
1441\r
1442 //\r
1443 // Clear all the globle variable\r
1444 //\r
1445 mDriverImageHandleCount = 0;\r
1446 mCurrentPage = 0;\r
1447 ZeroMem (mDriverImageToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
1448 ZeroMem (mDriverImageFilePathToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
1449 ZeroMem (mControllerToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
1450 ZeroMem (mDriverImageProtocol, MAX_CHOICE_NUM * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));\r
1451\r
1452 //\r
1453 // Show the page\r
1454 //\r
1455 Status = FormBrowser2->SendForm (\r
1456 FormBrowser2,\r
1457 &mCallbackInfo->RegisteredHandle,\r
1458 1,\r
1459 NULL,\r
1460 0,\r
1461 NULL,\r
1462 NULL\r
1463 );\r
1464\r
1465 HiiRemovePackages (mCallbackInfo->RegisteredHandle);\r
1466 Status = EFI_SUCCESS;\r
1467\r
1468Finish:\r
1469 if (mCallbackInfo->DriverHandle != NULL) {\r
1470 gBS->UninstallMultipleProtocolInterfaces (\r
1471 mCallbackInfo->DriverHandle,\r
1472 &gEfiDevicePathProtocolGuid,\r
1473 &mHiiVendorDevicePath,\r
1474 &gEfiHiiConfigAccessProtocolGuid,\r
1475 &mCallbackInfo->ConfigAccess,\r
1476 NULL\r
1477 );\r
1478 }\r
1479\r
1480 if (mCallbackInfo != NULL) {\r
1481 FreePool (mCallbackInfo);\r
1482 }\r
1483\r
1484 return Status;\r
1485}\r
1486\r
1487/**\r
1488 Converting a given device to an unicode string. \r
1489 \r
1490 This function will dependent on gEfiDevicePathToTextProtocolGuid, if protocol\r
1491 does not installed, then return unknown device path L"?" directly.\r
1492 \r
1493 @param DevPath Given device path instance\r
1494 \r
1495 @return Converted string from given device path.\r
1496 @retval L"?" Can not locate gEfiDevicePathToTextProtocolGuid protocol for converting.\r
1497**/\r
1498CHAR16 *\r
1499DevicePathToStr (\r
1500 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
1501 )\r
1502{\r
1503 EFI_STATUS Status;\r
1504 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
1505 CHAR16 *ToText;\r
1506 \r
1507 if (DevPath == NULL) {\r
1508 return L"";\r
1509 }\r
1510 \r
1511 Status = gBS->LocateProtocol (\r
1512 &gEfiDevicePathToTextProtocolGuid,\r
1513 NULL,\r
1514 (VOID **) &DevPathToText\r
1515 );\r
1516 if (!EFI_ERROR (Status)) {\r
1517 ToText = DevPathToText->ConvertDevicePathToText (\r
1518 DevPath,\r
1519 FALSE,\r
1520 TRUE\r
1521 );\r
1522 ASSERT (ToText != NULL);\r
1523 return ToText;\r
1524 }\r
1525\r
1526 return L"?";\r
1527}\r