audk/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c

341 lines
7.8 KiB
C

/** @file
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
Module Name:
LpcDriver.c
Abstract:
EFI Lpc Driver for a Generic PC Platform
--*/
#include "LpcDriver.h"
#include "IndustryStandard/Pci22.h"
//
// This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0)
//
//
// Lpc Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL gLpcDriver = {
LpcDriverSupported,
LpcDriverStart,
LpcDriverStop,
0x10,
NULL,
NULL
};
LPC_DEV mLpc = {
LPC_DEV_SIGNATURE,
NULL,
{
IsaDeviceEnumerate,
IsaDeviceSetPower,
IsaGetCurrentResource,
IsaGetPossibleResource,
IsaSetResource,
IsaEnableDevice,
IsaInitDevice,
LpcInterfaceInit
},
NULL
};
BOOLEAN InitExecuted = FALSE;
/**
the entry point of the Lpc driver
**/
EFI_STATUS
EFIAPI
LpcDriverEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EfiLibInstallDriverBinding (ImageHandle, SystemTable, &gLpcDriver, ImageHandle);
}
/**
ControllerDriver Protocol Method
**/
EFI_STATUS
EFIAPI
LpcDriverSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_DEVICE_PATH_PROTOCOL *IsaBridgeDevicePath;
ACPI_HID_DEVICE_PATH *AcpiNode;
PCI_DEVICE_PATH *PciNode;
PCI_TYPE00 Pci;
//
// Get the ISA bridge's Device Path and test it
// the following code is specific
//
Status = gBS->OpenProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **)&IsaBridgeDevicePath,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = EFI_SUCCESS;
AcpiNode = (ACPI_HID_DEVICE_PATH *)IsaBridgeDevicePath;
if (AcpiNode->Header.Type != ACPI_DEVICE_PATH ||
AcpiNode->Header.SubType != ACPI_DP ||
DevicePathNodeLength (&AcpiNode->Header) != sizeof(ACPI_HID_DEVICE_PATH) ||
AcpiNode -> HID != EISA_PNP_ID(0x0A03) ||
AcpiNode -> UID != 0 ) {
Status = EFI_UNSUPPORTED;
} else {
//
// Get the next node
//
IsaBridgeDevicePath = NextDevicePathNode (IsaBridgeDevicePath);
PciNode = (PCI_DEVICE_PATH *)IsaBridgeDevicePath;
if (PciNode->Header.Type != HARDWARE_DEVICE_PATH ||
PciNode->Header.SubType != HW_PCI_DP ||
DevicePathNodeLength (&PciNode->Header) != sizeof (PCI_DEVICE_PATH) ||
PciNode -> Function != 0x00 ||
PciNode -> Device != 0x1f ) {
Status = EFI_UNSUPPORTED;
}
}
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// Get PciIo protocol instance
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR(Status)) {
return Status;
}
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint32,
0,
sizeof(Pci) / sizeof(UINT32),
&Pci
);
if (!EFI_ERROR (Status)) {
Status = EFI_SUCCESS; //TODO: force return success as temp solution EFI_UNSUPPORTED;
if ((Pci.Hdr.Command & 0x03) == 0x03) {
if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
//
// See if this is a standard PCI to ISA Bridge from the Base Code
// and Class Code
//
if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
Status = EFI_SUCCESS;
} else {
}
//
// See if this is an Intel PCI to ISA bridge in Positive Decode Mode
//
if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
Pci.Hdr.VendorId == 0x8086 &&
Pci.Hdr.DeviceId == 0x7110) {
Status = EFI_SUCCESS;
} else {
}
} else {
}
}
else {
}
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
}
/**
Install EFI_ISA_ACPI_PROTOCOL
**/
EFI_STATUS
EFIAPI
LpcDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
//
// Get Pci IO
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
return Status;
}
mLpc.PciIo = PciIo;
//
// Install IsaAcpi interface, the Sio interface is not installed!
//
Status = gBS->InstallMultipleProtocolInterfaces (
&Controller,
&gEfiIsaAcpiProtocolGuid,
&mLpc.IsaAcpi,
NULL
);
return Status;
}
EFI_STATUS
EFIAPI
LpcDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
LPC_DEV *LpcDev;
//
// Get EFI_ISA_ACPI_PROTOCOL interface
//
Status = gBS->OpenProtocol (
Controller,
&gEfiIsaAcpiProtocolGuid,
(VOID **)&IsaAcpi,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
LpcDev = LPC_ISA_ACPI_FROM_THIS (IsaAcpi);
//
// Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
//
Status = gBS->UninstallProtocolInterface (
Controller,
&gEfiIsaAcpiProtocolGuid,
&LpcDev->IsaAcpi
);
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
VOID
LpcIoRead8 (
IN UINT16 Port,
OUT UINT8 *Data
)
{
mLpc.PciIo->Io.Read(
mLpc.PciIo,
EfiPciWidthUint8,
EFI_PCI_IO_PASS_THROUGH_BAR,
Port,
1,
Data
);
}
VOID
LpcIoWrite8 (
IN UINT16 Port,
IN UINT8 Data
)
{
mLpc.PciIo->Io.Write(
mLpc.PciIo,
EfiPciWidthUint8,
EFI_PCI_IO_PASS_THROUGH_BAR,
Port,
1,
&Data
);
}