git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7127 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			410 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			410 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   The platform device manager reference implementation
 | |
| 
 | |
| Copyright (c) 2004 - 2008, Intel Corporation. <BR>
 | |
| All rights reserved. This program and the accompanying materials
 | |
| are licensed and made available under the terms and conditions of the BSD License
 | |
| which accompanies this distribution.  The full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "DeviceManager.h"
 | |
| 
 | |
| DEVICE_MANAGER_CALLBACK_DATA  gDeviceManagerPrivate = {
 | |
|   DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE,
 | |
|   NULL,
 | |
|   NULL,
 | |
|   {
 | |
|     FakeExtractConfig,
 | |
|     FakeRouteConfig,
 | |
|     DeviceManagerCallback
 | |
|   }
 | |
| };
 | |
| 
 | |
| EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID;
 | |
| 
 | |
| DEVICE_MANAGER_MENU_ITEM  mDeviceManagerMenuItemTable[] = {
 | |
|   { STRING_TOKEN (STR_DISK_DEVICE),     EFI_DISK_DEVICE_CLASS },
 | |
|   { STRING_TOKEN (STR_VIDEO_DEVICE),    EFI_VIDEO_DEVICE_CLASS },
 | |
|   { STRING_TOKEN (STR_NETWORK_DEVICE),  EFI_NETWORK_DEVICE_CLASS },
 | |
|   { STRING_TOKEN (STR_INPUT_DEVICE),    EFI_INPUT_DEVICE_CLASS },
 | |
|   { STRING_TOKEN (STR_ON_BOARD_DEVICE), EFI_ON_BOARD_DEVICE_CLASS },
 | |
|   { STRING_TOKEN (STR_OTHER_DEVICE),    EFI_OTHER_DEVICE_CLASS }
 | |
| };
 | |
| 
 | |
| #define MENU_ITEM_NUM  \
 | |
|   (sizeof (mDeviceManagerMenuItemTable) / sizeof (DEVICE_MANAGER_MENU_ITEM))
 | |
| 
 | |
| /**
 | |
|   This function is invoked if user selected a iteractive opcode from Device Manager's
 | |
|   Formset. The decision by user is saved to gCallbackKey for later processing. If
 | |
|   user set VBIOS, the new value is saved to EFI variable.
 | |
| 
 | |
|   @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | |
|   @param Action          Specifies the type of action taken by the browser.
 | |
|   @param QuestionId      A unique value which is sent to the original exporting driver
 | |
|                          so that it can identify the type of data to expect.
 | |
|   @param Type            The type of value for the question.
 | |
|   @param Value           A pointer to the data being sent to the original exporting driver.
 | |
|   @param ActionRequest   On return, points to the action requested by the callback function.
 | |
| 
 | |
|   @retval  EFI_SUCCESS           The callback successfully handled the action.
 | |
|   @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DeviceManagerCallback (
 | |
|   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
 | |
|   IN  EFI_BROWSER_ACTION                     Action,
 | |
|   IN  EFI_QUESTION_ID                        QuestionId,
 | |
|   IN  UINT8                                  Type,
 | |
|   IN  EFI_IFR_TYPE_VALUE                     *Value,
 | |
|   OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
 | |
|   )
 | |
| {
 | |
|   DEVICE_MANAGER_CALLBACK_DATA *PrivateData;
 | |
| 
 | |
|   if ((Value == NULL) || (ActionRequest == NULL)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   PrivateData = DEVICE_MANAGER_CALLBACK_DATA_FROM_THIS (This);
 | |
| 
 | |
|   switch (QuestionId) {
 | |
|   case DEVICE_MANAGER_KEY_VBIOS:
 | |
|     PrivateData->VideoBios = Value->u8;
 | |
|     gRT->SetVariable (
 | |
|            L"VBIOS",
 | |
|            &gEfiGenericPlatformVariableGuid,
 | |
|            EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
 | |
|            sizeof (UINT8),
 | |
|            &PrivateData->VideoBios
 | |
|            );
 | |
| 
 | |
|     //
 | |
|     // Tell browser not to ask for confirmation of changes,
 | |
|     // since we have already applied.
 | |
|     //
 | |
|     *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
 | |
|     break;
 | |
| 
 | |
|   default:
 | |
|     //
 | |
|     // The key corresponds the Handle Index which was requested to be displayed
 | |
|     //
 | |
|     gCallbackKey = QuestionId;
 | |
| 
 | |
|     //
 | |
|     // Request to exit SendForm(), so as to switch to selected form
 | |
|     //
 | |
|     *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function registers HII packages to HII database.
 | |
| 
 | |
|   @retval EFI_SUCCESS This function complete successfully.
 | |
|   @return Other value if failed to register HII packages.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| InitializeDeviceManager (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                  Status;
 | |
|   EFI_HII_PACKAGE_LIST_HEADER *PackageList;
 | |
| 
 | |
|   //
 | |
|   // Create driver handle used by HII database
 | |
|   //
 | |
|   Status = HiiLibCreateHiiDriverHandle (&gDeviceManagerPrivate.DriverHandle);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Install Config Access protocol to driver handle
 | |
|   //
 | |
|   Status = gBS->InstallProtocolInterface (
 | |
|                   &gDeviceManagerPrivate.DriverHandle,
 | |
|                   &gEfiHiiConfigAccessProtocolGuid,
 | |
|                   EFI_NATIVE_INTERFACE,
 | |
|                   &gDeviceManagerPrivate.ConfigAccess
 | |
|                   );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   //
 | |
|   // Publish our HII data
 | |
|   //
 | |
|   PackageList = HiiLibPreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsDxeStrings);
 | |
|   ASSERT (PackageList != NULL);
 | |
| 
 | |
|   Status = gHiiDatabase->NewPackageList (
 | |
|                            gHiiDatabase,
 | |
|                            PackageList,
 | |
|                            gDeviceManagerPrivate.DriverHandle,
 | |
|                            &gDeviceManagerPrivate.HiiHandle
 | |
|                            );
 | |
|   FreePool (PackageList);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Call the browser and display the device manager to allow user
 | |
|   to configure the platform.
 | |
| 
 | |
|   This function create the dynamic content for device manager. It includes
 | |
|   section header for all class of devices, one-of opcode to set VBIOS.
 | |
|   
 | |
|   @retval  EFI_SUCCESS             Operation is successful.
 | |
|   @return  Other values if failed to clean up the dynamic content from HII
 | |
|            database.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| CallDeviceManager (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                  Status;
 | |
|   UINTN                       Count;
 | |
|   UINTN                       Index;
 | |
|   CHAR16                      *String;
 | |
|   UINTN                       StringLength;
 | |
|   EFI_HII_UPDATE_DATA         UpdateData[MENU_ITEM_NUM];
 | |
|   EFI_STRING_ID               Token;
 | |
|   EFI_STRING_ID               TokenHelp;
 | |
|   IFR_OPTION                  *IfrOptionList;
 | |
|   UINT8                       *VideoOption;
 | |
|   UINTN                       VideoOptionSize;
 | |
|   EFI_HII_HANDLE              *HiiHandles;
 | |
|   UINTN                       HandleBufferLength;
 | |
|   UINTN                       NumberOfHiiHandles;
 | |
|   EFI_HII_HANDLE              HiiHandle;
 | |
|   UINT16                      FormSetClass;
 | |
|   EFI_STRING_ID               FormSetTitle;
 | |
|   EFI_STRING_ID               FormSetHelp;
 | |
|   EFI_BROWSER_ACTION_REQUEST  ActionRequest;
 | |
|   EFI_HII_PACKAGE_LIST_HEADER *PackageList;
 | |
| 
 | |
|   IfrOptionList       = NULL;
 | |
|   VideoOption         = NULL;
 | |
|   HiiHandles          = NULL;
 | |
|   HandleBufferLength  = 0;
 | |
| 
 | |
|   Status        = EFI_SUCCESS;
 | |
|   gCallbackKey  = 0;
 | |
| 
 | |
|   //
 | |
|   // Connect all prior to entering the platform setup menu.
 | |
|   //
 | |
|   if (!gConnectAllHappened) {
 | |
|     BdsLibConnectAllDriversToAllControllers ();
 | |
|     gConnectAllHappened = TRUE;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Create Subtitle OpCodes
 | |
|   //
 | |
|   for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
 | |
|     //
 | |
|     // Allocate space for creation of UpdateData Buffer
 | |
|     //
 | |
|     UpdateData[Index].BufferSize = 0x1000;
 | |
|     UpdateData[Index].Offset = 0;
 | |
|     UpdateData[Index].Data = AllocatePool (0x1000);
 | |
|     ASSERT (UpdateData[Index].Data != NULL);
 | |
| 
 | |
|     CreateSubTitleOpCode (mDeviceManagerMenuItemTable[Index].StringId, 0, 0, 1,  &UpdateData[Index]);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Get all the Hii handles
 | |
|   //
 | |
|   Status = HiiLibGetHiiHandles (&HandleBufferLength, &HiiHandles);
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   HiiHandle = gDeviceManagerPrivate.HiiHandle;
 | |
| 
 | |
|   StringLength  = 0x1000;
 | |
|   String        = AllocateZeroPool (StringLength);
 | |
|   ASSERT (String != NULL);
 | |
| 
 | |
|   //
 | |
|   // Search for formset of each class type
 | |
|   //
 | |
|   NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);
 | |
|   for (Index = 0; Index < NumberOfHiiHandles; Index++) {
 | |
|     IfrLibExtractClassFromHiiHandle (HiiHandles[Index], &FormSetClass, &FormSetTitle, &FormSetHelp);
 | |
| 
 | |
|     if (FormSetClass == EFI_NON_DEVICE_CLASS) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     Token = 0;
 | |
|     *String = 0;
 | |
|     StringLength = 0x1000;
 | |
|     HiiLibGetString (HiiHandles[Index], FormSetTitle, String, &StringLength);
 | |
|     HiiLibNewString (HiiHandle, &Token, String);
 | |
| 
 | |
|     TokenHelp = 0;
 | |
|     *String = 0;
 | |
|     StringLength = 0x1000;
 | |
|     HiiLibGetString (HiiHandles[Index], FormSetHelp, String, &StringLength);
 | |
|     HiiLibNewString (HiiHandle, &TokenHelp, String);
 | |
| 
 | |
|     for (Count = 0; Count < MENU_ITEM_NUM; Count++) {
 | |
|       if (FormSetClass & mDeviceManagerMenuItemTable[Count].Class) {
 | |
|         CreateActionOpCode (
 | |
|           (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET),
 | |
|           Token,
 | |
|           TokenHelp,
 | |
|           EFI_IFR_FLAG_CALLBACK,
 | |
|           0,
 | |
|           &UpdateData[Count]
 | |
|           );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   FreePool (String);
 | |
| 
 | |
|   for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
 | |
|     //
 | |
|     // Add End Opcode for Subtitle
 | |
|     //
 | |
|     CreateEndOpCode (&UpdateData[Index]);
 | |
| 
 | |
|     IfrLibUpdateForm (
 | |
|       HiiHandle,
 | |
|       &mDeviceManagerGuid,
 | |
|       DEVICE_MANAGER_FORM_ID,
 | |
|       mDeviceManagerMenuItemTable[Index].Class,
 | |
|       FALSE,
 | |
|       &UpdateData[Index]
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Add oneof for video BIOS selection
 | |
|   //
 | |
|   VideoOption = BdsLibGetVariableAndSize (
 | |
|                   L"VBIOS",
 | |
|                   &gEfiGenericPlatformVariableGuid,
 | |
|                   &VideoOptionSize
 | |
|                   );
 | |
|   if (VideoOption == NULL) {
 | |
|     gDeviceManagerPrivate.VideoBios = 0;
 | |
|   } else {
 | |
|     gDeviceManagerPrivate.VideoBios = VideoOption[0];
 | |
|     FreePool (VideoOption);
 | |
|   }
 | |
| 
 | |
|   ASSERT (gDeviceManagerPrivate.VideoBios <= 1);
 | |
| 
 | |
|   IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));
 | |
|   ASSERT (IfrOptionList != NULL);
 | |
|   IfrOptionList[0].Flags        = 0;
 | |
|   IfrOptionList[0].StringToken  = STRING_TOKEN (STR_ONE_OF_PCI);
 | |
|   IfrOptionList[0].Value.u8     = 0;
 | |
|   IfrOptionList[1].Flags        = 0;
 | |
|   IfrOptionList[1].StringToken  = STRING_TOKEN (STR_ONE_OF_AGP);
 | |
|   IfrOptionList[1].Value.u8     = 1;
 | |
|   IfrOptionList[gDeviceManagerPrivate.VideoBios].Flags |= EFI_IFR_OPTION_DEFAULT;
 | |
| 
 | |
|   UpdateData[0].Offset = 0;
 | |
|   CreateOneOfOpCode (
 | |
|     DEVICE_MANAGER_KEY_VBIOS,
 | |
|     0,
 | |
|     0,
 | |
|     STRING_TOKEN (STR_ONE_OF_VBIOS),
 | |
|     STRING_TOKEN (STR_ONE_OF_VBIOS_HELP),
 | |
|     EFI_IFR_FLAG_CALLBACK,
 | |
|     EFI_IFR_NUMERIC_SIZE_1,
 | |
|     IfrOptionList,
 | |
|     2,
 | |
|     &UpdateData[0]
 | |
|     );
 | |
| 
 | |
|   IfrLibUpdateForm (
 | |
|     HiiHandle,
 | |
|     &mDeviceManagerGuid,
 | |
|     DEVICE_MANAGER_FORM_ID,
 | |
|     LABEL_VBIOS,
 | |
|     FALSE,
 | |
|     &UpdateData[0]
 | |
|     );
 | |
| 
 | |
|   ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
 | |
|   Status = gFormBrowser2->SendForm (
 | |
|                            gFormBrowser2,
 | |
|                            &HiiHandle,
 | |
|                            1,
 | |
|                            NULL,
 | |
|                            0,
 | |
|                            NULL,
 | |
|                            &ActionRequest
 | |
|                            );
 | |
|   if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
 | |
|     EnableResetRequired ();
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // We will have returned from processing a callback - user either hit ESC to exit, or selected
 | |
|   // a target to display
 | |
|   //
 | |
|   if (gCallbackKey != 0) {
 | |
|     ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
 | |
|     Status = gFormBrowser2->SendForm (
 | |
|                              gFormBrowser2,
 | |
|                              &HiiHandles[gCallbackKey - DEVICE_KEY_OFFSET],
 | |
|                              1,
 | |
|                              NULL,
 | |
|                              0,
 | |
|                              NULL,
 | |
|                              &ActionRequest
 | |
|                              );
 | |
| 
 | |
|     if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
 | |
|       EnableResetRequired ();
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Force return to Device Manager
 | |
|     //
 | |
|     gCallbackKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Cleanup dynamic created strings in HII database by reinstall the packagelist
 | |
|   //
 | |
|   gHiiDatabase->RemovePackageList (gHiiDatabase, HiiHandle);
 | |
|   PackageList = HiiLibPreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsDxeStrings);
 | |
|   ASSERT (PackageList != NULL);
 | |
|   Status = gHiiDatabase->NewPackageList (
 | |
|                            gHiiDatabase,
 | |
|                            PackageList,
 | |
|                            gDeviceManagerPrivate.DriverHandle,
 | |
|                            &gDeviceManagerPrivate.HiiHandle
 | |
|                            );
 | |
|   FreePool (PackageList);
 | |
| 
 | |
|   for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
 | |
|     FreePool (UpdateData[Index].Data);
 | |
|   }
 | |
|   FreePool (HiiHandles);
 | |
| 
 | |
|   return Status;
 | |
| }
 |