alder_lake_bios/Insyde/InsydeModulePkg/Universal/Console/VgaDriverPolicyDxe/VgaDriverPolicyDxe.c

324 lines
9.0 KiB
C

/** @file
Vga Driver Policy Driver
;******************************************************************************
;* Copyright (c) 2012 - 2020, Insyde Software Corporation. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "VgaDriverPolicyDxe.h"
EFI_DRIVER_BINDING_PROTOCOL gVgaDriverPolicyDriverBinding = {
VgaDriverPolicyBindingSupported,
VgaDriverPolicyBindingStart,
VgaDriverPolicyBindingStop,
0x20,
NULL,
NULL
};
/**
Supported.
@param This Pointer to driver binding protocol
@param Controller Controller handle to connect
@param RemainingDevicePath A pointer to the remaining portion of a device
path
@retval EFI_STATUS EFI_SUCCESS:This controller can be managed by this
driver, Otherwise, this controller cannot be
managed by this driver
**/
EFI_STATUS
EFIAPI
VgaDriverPolicyBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
EFI_STATUS Status;
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// See if this is a PCI Graphics Controller by looking at the Command register and
// Class Code Register
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint32,
0,
sizeof (Pci) / sizeof (UINT32),
&Pci
);
if (EFI_ERROR (Status)) {
Status = EFI_UNSUPPORTED;
goto Done;
}
Status = EFI_UNSUPPORTED;
if (Pci.Hdr.ClassCode[2] == 0x03 || (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01)) {
Status = EFI_SUCCESS;
}
Done:
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
}
/**
Install Graphics Output Protocol onto VGA device handles.
@param This Pointer to driver binding protocol
@param Controller Controller handle to connect
@param RemainingDevicePath A pointer to the remaining portion of a device
path
@return EFI_STATUS
**/
EFI_STATUS
EFIAPI
VgaDriverPolicyBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
KERNEL_CONFIGURATION SystemConfiguration;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;
EFI_DEVICE_PATH_PROTOCOL *ActiveVgaDevicePath;
Status = GetKernelConfiguration (&SystemConfiguration);
if (EFI_ERROR (Status)) {
return Status;
}
if (SystemConfiguration.UefiDualVgaControllers == DUAL_VGA_CONTROLLER_ENABLE) {
return EFI_UNSUPPORTED;
}
ActiveVgaDevicePath = VgaDriverPolicyGetVariable (ACTIVE_VGA_VAR_NAME);
if (ActiveVgaDevicePath == NULL) {
return EFI_UNSUPPORTED;
}
//
// Check Controller by ACTIVE_VGA_VAR_NAME variable.
//
Status = gBS->HandleProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **) &ControllerDevicePath
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
if (VgaDriverPolicyMatchDevicePaths (ActiveVgaDevicePath, ControllerDevicePath)) {
return EFI_UNSUPPORTED;
} else {
//
// Lock the Vga controller by driver.
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
}
return Status;
}
/**
Stop.
@param This Pointer to driver binding protocol
@param Controller Controller handle to connect
@param NumberOfChildren Number of children handle created by this driver
@param ChildHandleBuffer Buffer containing child handle created
@retval EFI_SUCCESS Driver disconnected successfully from controller
@retval EFI_UNSUPPORTED Driver cannot be disconnected
**/
EFI_STATUS
EFIAPI
VgaDriverPolicyBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
/**
Read the EFI variable (Name) and return a dynamically allocated
buffer, and the size of the buffer. On failure return NULL.
@param Name String part of EFI variable name
@return A pointer to the dynamically allocated memory that contains
a copy of the EFI variable. Caller is repsoncible freeing
the buffer.
A null pointer if a variable is not found
**/
VOID *
VgaDriverPolicyGetVariable (
IN CHAR16 *Name
)
{
return CommonGetVariableData (Name, &gEfiGenericVariableGuid);
}
/**
Function compares a device path data structure to that of all the nodes of a
second device path instance.
@param Multi A pointer to a multi-instance device path
data structure.
@param Single A pointer to a single-instance device path
data structure
@return TRUE If the Single is contained within Multi
FALSE The Single is not match within Multi
**/
BOOLEAN
VgaDriverPolicyMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
)
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
if (!Multi || !Single) {
return FALSE;
}
DevicePath = Multi;
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
//
// Search for the match of 'Single' in 'Multi'
//
while (DevicePathInst != NULL) {
//
// If the single device path is found in multiple device paths,
// return success
//
if (Size == 0) {
return FALSE;
}
if (CompareMem (Single, DevicePathInst, Size) == 0) {
return TRUE;
}
FreePool (DevicePathInst);
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
}
return FALSE;
}
/**
The user Entry Point for module UefiBiosVideo. 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
VgaDriverPolicyEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install driver model protocol(s).
//
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gVgaDriverPolicyDriverBinding,
ImageHandle,
&gVgaDriverPolicyComponentName,
&gVgaDriverPolicyComponentName2
);
ASSERT_EFI_ERROR (Status);
return Status;
}