https://bugzilla.tianocore.org/show_bug.cgi?id=162 Update EmulatorPkg specific modules and libraries to use safe string functions in BaseLib and safe PcdSetxx() functions in PcdLib. With these updates, the define DISABLE_NEW_DEPRECATED_INTERFACES is enabled in the DSC file. Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Andrew Fish <afish@apple.com> Cc: Ray Ni <ray.ni@intel.com> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Hao A Wu <hao.a.wu@intel.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> Tested-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			529 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			529 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|  Emu Bus driver
 | |
| 
 | |
| Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 | |
| Portions copyright (c) 2011, Apple Inc. All rights reserved.
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "EmuBusDriverDxe.h"
 | |
| 
 | |
| 
 | |
| 
 | |
| //
 | |
| // DriverBinding protocol global
 | |
| //
 | |
| EFI_DRIVER_BINDING_PROTOCOL           gEmuBusDriverBinding = {
 | |
|   EmuBusDriverBindingSupported,
 | |
|   EmuBusDriverBindingStart,
 | |
|   EmuBusDriverBindingStop,
 | |
|   0xa,
 | |
|   NULL,
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EmuBusDriverBindingSupported (
 | |
|   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN  EFI_HANDLE                   ControllerHandle,
 | |
|   IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
 | |
|   EMU_THUNK_PROTOCOL        *EmuThunk;
 | |
| 
 | |
|   //
 | |
|   // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
 | |
|   // it is a legal Device Path Node for this bus driver's children.
 | |
|   //
 | |
|   if (RemainingDevicePath != NULL) {
 | |
|     //
 | |
|     // Check if RemainingDevicePath is the End of Device Path Node,
 | |
|     // if yes, go on checking other conditions
 | |
|     //
 | |
|     if (!IsDevicePathEnd (RemainingDevicePath)) {
 | |
|       //
 | |
|       // If RemainingDevicePath isn't the End of Device Path Node,
 | |
|       // check its validation
 | |
|       //
 | |
|       if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
 | |
|           RemainingDevicePath->SubType != HW_VENDOR_DP ||
 | |
|           DevicePathNodeLength(RemainingDevicePath) != sizeof(EMU_VENDOR_DEVICE_PATH_NODE)) {
 | |
|         return EFI_UNSUPPORTED;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Open the IO Abstraction(s) needed to perform the supported test
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   ControllerHandle,
 | |
|                   &gEmuThunkProtocolGuid,
 | |
|                   (VOID **)&EmuThunk   ,
 | |
|                   This->DriverBindingHandle,
 | |
|                   ControllerHandle,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (Status == EFI_ALREADY_STARTED) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Close the I/O Abstraction(s) used to perform the supported test
 | |
|   //
 | |
|   gBS->CloseProtocol (
 | |
|         ControllerHandle,
 | |
|         &gEmuThunkProtocolGuid,
 | |
|         This->DriverBindingHandle,
 | |
|         ControllerHandle
 | |
|         );
 | |
| 
 | |
|   //
 | |
|   // Open the EFI Device Path protocol needed to perform the supported test
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   ControllerHandle,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   (VOID **)&ParentDevicePath,
 | |
|                   This->DriverBindingHandle,
 | |
|                   ControllerHandle,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (Status == EFI_ALREADY_STARTED) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
| 
 | |
|   //
 | |
|   // Close protocol, don't use device path protocol in the Support() function
 | |
|   //
 | |
|   gBS->CloseProtocol (
 | |
|         ControllerHandle,
 | |
|         &gEfiDevicePathProtocolGuid,
 | |
|         This->DriverBindingHandle,
 | |
|         ControllerHandle
 | |
|         );
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EmuBusDriverBindingStart (
 | |
|   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN  EFI_HANDLE                   ControllerHandle,
 | |
|   IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                      Status;
 | |
|   EFI_STATUS                      InstallStatus;
 | |
|   EMU_THUNK_PROTOCOL              *EmuThunk;
 | |
|   EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
 | |
|   EMU_IO_DEVICE                   *EmuDevice;
 | |
|   EMU_BUS_DEVICE                  *EmuBusDevice;
 | |
|   EMU_IO_THUNK_PROTOCOL           *EmuIoThunk;
 | |
|   UINT16                          ComponentName[512];
 | |
|   EMU_VENDOR_DEVICE_PATH_NODE     *Node;
 | |
|   BOOLEAN                         CreateDevice;
 | |
| 
 | |
|   InstallStatus = EFI_UNSUPPORTED;
 | |
|   Status = EFI_UNSUPPORTED;
 | |
| 
 | |
|   //
 | |
|   // Grab the protocols we need
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   ControllerHandle,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   (VOID **)&ParentDevicePath,
 | |
|                   This->DriverBindingHandle,
 | |
|                   ControllerHandle,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   ControllerHandle,
 | |
|                   &gEmuThunkProtocolGuid,
 | |
|                   (VOID **)&EmuThunk,
 | |
|                   This->DriverBindingHandle,
 | |
|                   ControllerHandle,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   if (Status != EFI_ALREADY_STARTED) {
 | |
|     EmuBusDevice = AllocatePool (sizeof (EMU_BUS_DEVICE));
 | |
|     if (EmuBusDevice == NULL) {
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
| 
 | |
|     EmuBusDevice->Signature           = EMU_BUS_DEVICE_SIGNATURE;
 | |
|     EmuBusDevice->ControllerNameTable = NULL;
 | |
| 
 | |
|     AddUnicodeString2 (
 | |
|       "eng",
 | |
|       gEmuBusDriverComponentName.SupportedLanguages,
 | |
|       &EmuBusDevice->ControllerNameTable,
 | |
|       L"Emulator Bus Controller",
 | |
|       TRUE
 | |
|       );
 | |
|     AddUnicodeString2 (
 | |
|       "en",
 | |
|       gEmuBusDriverComponentName2.SupportedLanguages,
 | |
|       &EmuBusDevice->ControllerNameTable,
 | |
|       L"Emulator Bus Controller",
 | |
|       FALSE
 | |
|       );
 | |
| 
 | |
| 
 | |
|     Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                     &ControllerHandle,
 | |
|                     &gEfiCallerIdGuid, EmuBusDevice,
 | |
|                     NULL
 | |
|                     );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
 | |
|       gBS->FreePool (EmuBusDevice);
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
|   for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) {
 | |
|     Status = EmuThunk->GetNextProtocol (TRUE, &EmuIoThunk);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     CreateDevice = TRUE;
 | |
|     if (RemainingDevicePath != NULL) {
 | |
|       CreateDevice  = FALSE;
 | |
|       //
 | |
|       // Check if RemainingDevicePath is the End of Device Path Node,
 | |
|       // if yes, don't create any child device
 | |
|       //
 | |
|       if (!IsDevicePathEnd (RemainingDevicePath)) {
 | |
|         //
 | |
|         // If RemainingDevicePath isn't the End of Device Path Node,
 | |
|         // check its validation
 | |
|         //
 | |
|         Node          = (EMU_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
 | |
|         if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
 | |
|             Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
 | |
|             DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (EMU_VENDOR_DEVICE_PATH_NODE)
 | |
|             ) {
 | |
|           if (CompareGuid (&Node->VendorDevicePath.Guid, EmuIoThunk->Protocol) && Node->Instance == EmuIoThunk->Instance) {
 | |
|             CreateDevice = TRUE;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (CreateDevice) {
 | |
|       //
 | |
|       // Allocate instance structure, and fill in parent information.
 | |
|       //
 | |
|       EmuDevice = AllocatePool (sizeof (EMU_IO_DEVICE));
 | |
|       if (EmuDevice == NULL) {
 | |
|         return EFI_OUT_OF_RESOURCES;
 | |
|       }
 | |
| 
 | |
|       EmuDevice->Handle             = NULL;
 | |
|       EmuDevice->ControllerHandle   = ControllerHandle;
 | |
|       EmuDevice->ParentDevicePath   = ParentDevicePath;
 | |
|       CopyMem (&EmuDevice->EmuIoThunk, EmuIoThunk, sizeof (EMU_IO_THUNK_PROTOCOL));
 | |
| 
 | |
|       EmuDevice->ControllerNameTable = NULL;
 | |
| 
 | |
|       StrnCpyS (
 | |
|         ComponentName,
 | |
|         sizeof (ComponentName) / sizeof (CHAR16),
 | |
|         EmuIoThunk->ConfigString,
 | |
|         sizeof (ComponentName) / sizeof (CHAR16)
 | |
|         );
 | |
| 
 | |
|       EmuDevice->DevicePath = EmuBusCreateDevicePath (
 | |
|                                   ParentDevicePath,
 | |
|                                   EmuIoThunk->Protocol,
 | |
|                                   EmuIoThunk->Instance
 | |
|                                   );
 | |
|       if (EmuDevice->DevicePath == NULL) {
 | |
|         gBS->FreePool (EmuDevice);
 | |
|         return EFI_OUT_OF_RESOURCES;
 | |
|       }
 | |
| 
 | |
|       AddUnicodeString (
 | |
|         "eng",
 | |
|         gEmuBusDriverComponentName.SupportedLanguages,
 | |
|         &EmuDevice->ControllerNameTable,
 | |
|         ComponentName
 | |
|         );
 | |
| 
 | |
|       EmuDevice->Signature = EMU_IO_DEVICE_SIGNATURE;
 | |
| 
 | |
|       InstallStatus = gBS->InstallMultipleProtocolInterfaces (
 | |
|                             &EmuDevice->Handle,
 | |
|                             &gEfiDevicePathProtocolGuid,  EmuDevice->DevicePath,
 | |
|                             &gEmuIoThunkProtocolGuid,     &EmuDevice->EmuIoThunk,
 | |
|                             NULL
 | |
|                             );
 | |
|       if (EFI_ERROR (InstallStatus)) {
 | |
|         FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
 | |
|         gBS->FreePool (EmuDevice);
 | |
|       } else {
 | |
|         //
 | |
|         // Open For Child Device
 | |
|         //
 | |
|         Status = gBS->OpenProtocol (
 | |
|                         ControllerHandle,
 | |
|                         &gEmuThunkProtocolGuid,
 | |
|                         (VOID **)&EmuThunk   ,
 | |
|                         This->DriverBindingHandle,
 | |
|                         EmuDevice->Handle,
 | |
|                         EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | |
|                         );
 | |
|         if (!EFI_ERROR (Status)) {
 | |
|           InstallStatus = EFI_SUCCESS;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return InstallStatus;
 | |
| }
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EmuBusDriverBindingStop (
 | |
|   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN  EFI_HANDLE                   ControllerHandle,
 | |
|   IN  UINTN                        NumberOfChildren,
 | |
|   IN  EFI_HANDLE                   *ChildHandleBuffer
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   UINTN                     Index;
 | |
|   BOOLEAN                   AllChildrenStopped;
 | |
|   EMU_IO_THUNK_PROTOCOL     *EmuIoThunk;
 | |
|   EMU_BUS_DEVICE            *EmuBusDevice;
 | |
|   EMU_IO_DEVICE             *EmuDevice;
 | |
|   EMU_THUNK_PROTOCOL        *EmuThunk;
 | |
| 
 | |
|   //
 | |
|   // Complete all outstanding transactions to Controller.
 | |
|   // Don't allow any new transaction to Controller to be started.
 | |
|   //
 | |
| 
 | |
|   if (NumberOfChildren == 0) {
 | |
|     //
 | |
|     // Close the bus driver
 | |
|     //
 | |
|     Status = gBS->OpenProtocol (
 | |
|                     ControllerHandle,
 | |
|                     &gEfiCallerIdGuid,
 | |
|                     (VOID **)&EmuBusDevice,
 | |
|                     This->DriverBindingHandle,
 | |
|                     ControllerHandle,
 | |
|                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                     );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
| 
 | |
|     gBS->UninstallMultipleProtocolInterfaces (
 | |
|           ControllerHandle,
 | |
|           &gEfiCallerIdGuid,  EmuBusDevice,
 | |
|           NULL
 | |
|           );
 | |
| 
 | |
|     FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
 | |
| 
 | |
|     gBS->FreePool (EmuBusDevice);
 | |
| 
 | |
|     gBS->CloseProtocol (
 | |
|           ControllerHandle,
 | |
|           &gEmuThunkProtocolGuid,
 | |
|           This->DriverBindingHandle,
 | |
|           ControllerHandle
 | |
|           );
 | |
| 
 | |
|     gBS->CloseProtocol (
 | |
|           ControllerHandle,
 | |
|           &gEfiDevicePathProtocolGuid,
 | |
|           This->DriverBindingHandle,
 | |
|           ControllerHandle
 | |
|           );
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   AllChildrenStopped = TRUE;
 | |
| 
 | |
|   for (Index = 0; Index < NumberOfChildren; Index++) {
 | |
| 
 | |
|     Status = gBS->OpenProtocol (
 | |
|                     ChildHandleBuffer[Index],
 | |
|                     &gEmuIoThunkProtocolGuid,
 | |
|                     (VOID **)&EmuIoThunk,
 | |
|                     This->DriverBindingHandle,
 | |
|                     ControllerHandle,
 | |
|                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                     );
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       EmuDevice = EMU_IO_DEVICE_FROM_THIS (EmuIoThunk);
 | |
| 
 | |
|       Status = gBS->CloseProtocol (
 | |
|                       ControllerHandle,
 | |
|                       &gEmuThunkProtocolGuid,
 | |
|                       This->DriverBindingHandle,
 | |
|                       EmuDevice->Handle
 | |
|                       );
 | |
| 
 | |
|       Status = gBS->UninstallMultipleProtocolInterfaces (
 | |
|                       EmuDevice->Handle,
 | |
|                       &gEfiDevicePathProtocolGuid,  EmuDevice->DevicePath,
 | |
|                       &gEmuIoThunkProtocolGuid,     &EmuDevice->EmuIoThunk,
 | |
|                       NULL
 | |
|                       );
 | |
| 
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         gBS->OpenProtocol (
 | |
|               ControllerHandle,
 | |
|               &gEmuThunkProtocolGuid,
 | |
|               (VOID **) &EmuThunk   ,
 | |
|               This->DriverBindingHandle,
 | |
|               EmuDevice->Handle,
 | |
|               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | |
|               );
 | |
|       } else {
 | |
|         //
 | |
|         // Close the child handle
 | |
|         //
 | |
|         FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
 | |
|         FreePool (EmuDevice);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       AllChildrenStopped = FALSE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!AllChildrenStopped) {
 | |
|     return EFI_DEVICE_ERROR;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   Create a device path node using Guid and InstanceNumber and append it to
 | |
|   the passed in RootDevicePath
 | |
| 
 | |
| Arguments:
 | |
|   RootDevicePath - Root of the device path to return.
 | |
| 
 | |
|   Guid           - GUID to use in vendor device path node.
 | |
| 
 | |
|   InstanceNumber - Instance number to use in the vendor device path. This
 | |
|                     argument is needed to make sure each device path is unique.
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   EFI_DEVICE_PATH_PROTOCOL
 | |
| 
 | |
| **/
 | |
| EFI_DEVICE_PATH_PROTOCOL *
 | |
| EmuBusCreateDevicePath (
 | |
|   IN  EFI_DEVICE_PATH_PROTOCOL  *RootDevicePath,
 | |
|   IN  EFI_GUID                  *Guid,
 | |
|   IN  UINT16                    InstanceNumber
 | |
|   )
 | |
| {
 | |
|   EMU_VENDOR_DEVICE_PATH_NODE  DevicePath;
 | |
| 
 | |
|   DevicePath.VendorDevicePath.Header.Type     = HARDWARE_DEVICE_PATH;
 | |
|   DevicePath.VendorDevicePath.Header.SubType  = HW_VENDOR_DP;
 | |
|   SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (EMU_VENDOR_DEVICE_PATH_NODE));
 | |
| 
 | |
|   //
 | |
|   // The GUID defines the Class
 | |
|   //
 | |
|   CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));
 | |
| 
 | |
|   //
 | |
|   // Add an instance number so we can make sure there are no Device Path
 | |
|   // duplication.
 | |
|   //
 | |
|   DevicePath.Instance = InstanceNumber;
 | |
| 
 | |
|   return AppendDevicePathNode (
 | |
|           RootDevicePath,
 | |
|           (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
 | |
|           );
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|   The user Entry Point for module EmuBusDriver. The user code starts with this function.
 | |
| 
 | |
|   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
 | |
|   @param[in] SystemTable    A pointer to the EFI System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The entry point is executed successfully.
 | |
|   @retval other             Some error occurs when executing this entry point.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| InitializeEmuBusDriver (
 | |
|   IN EFI_HANDLE           ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE     *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS              Status;
 | |
| 
 | |
|   Status = EfiLibInstallAllDriverProtocols (
 | |
|              ImageHandle,
 | |
|              SystemTable,
 | |
|              &gEmuBusDriverBinding,
 | |
|              ImageHandle,
 | |
|              &gEmuBusDriverComponentName,
 | |
|              NULL,
 | |
|              NULL
 | |
|              );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |