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