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