From 574bb8b749fc6841f35293fd89c3496baeef900c Mon Sep 17 00:00:00 2001 From: vanjeff Date: Tue, 7 Jul 2009 07:09:31 +0000 Subject: [PATCH] Add IncompatiblePciDeviceSupportDxe module in IntelFrameworkModulePkg. This module provided one typical incompatible PCI device list to be one template and install EFI incompatible PCI device support protocol. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8783 6f19259b-4bc3-4df7-8a09-765794883524 --- .../IncompatiblePciDeviceSupport.c | 388 ++++++++++++++++++ .../IncompatiblePciDeviceSupportDxe.inf | 47 +++ .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 16 +- .../IntelFrameworkModulePkg.dsc | 1 + .../Protocol/IncompatiblePciDeviceSupport.h | 6 +- 5 files changed, 446 insertions(+), 12 deletions(-) create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c create mode 100644 IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf diff --git a/IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c b/IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c new file mode 100644 index 0000000000..9f81f1de3a --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c @@ -0,0 +1,388 @@ +/** @file + This module is one template module for Incompatible PCI Device Support protocol. + It includes one incompatile pci devices list template. + + Incompatible PCI Device Support protocol allows the PCI bus driver to support + resource allocation for some PCI devices that do not comply with the PCI Specification. + +Copyright (c) 2009, Intel Corporation +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 + +#include + +#include +#include +#include + +#include +#include + +typedef struct { + UINT64 VendorId; + UINT64 DeviceId; + UINT64 Revision; + UINT64 SubVendorId; + UINT64 SubDeviceId; +} EFI_PCI_DEVICE_HEADER_INFO; + +typedef struct { + UINT64 ResType; + UINT64 GenFlag; + UINT64 SpecificFlag; + UINT64 AddrSpaceGranularity; + UINT64 AddrRangeMin; + UINT64 AddrRangeMax; + UINT64 AddrTranslationOffset; + UINT64 AddrLen; +} EFI_PCI_RESOUCE_DESCRIPTOR; + +#define PCI_DEVICE_ID(VendorId, DeviceId, Revision, SubVendorId, SubDeviceId) \ + VendorId, DeviceId, Revision, SubVendorId, SubDeviceId + +#define PCI_BAR_TYPE_IO ACPI_ADDRESS_SPACE_TYPE_IO +#define PCI_BAR_TYPE_MEM ACPI_ADDRESS_SPACE_TYPE_MEM + +#define DEVICE_INF_TAG 0xFFF2 +#define DEVICE_RES_TAG 0xFFF1 +#define LIST_END_TAG 0x0000 + + +/** + Returns a list of ACPI resource descriptors that detail the special + resource configuration requirements for an incompatible PCI device. + + @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance. + @param VendorID A unique ID to identify the manufacturer of the PCI device. + @param DeviceID A unique ID to identify the particular PCI device. + @param RevisionID A PCI device-specific revision identifier. + @param SubsystemVendorId Specifies the subsystem vendor ID. + @param SubsystemDeviceId Specifies the subsystem device ID. + @param Configuration A list of ACPI resource descriptors returned that detail + the configuration requirement. + + @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_OUT_OF_RESOURCES No memory available. + @retval EFI_UNSUPPORTED The specified PCI device wasn't supported. + +**/ +EFI_STATUS +EFIAPI +PCheckDevice ( + IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This, + IN UINTN VendorId, + IN UINTN DeviceId, + IN UINTN Revision, + IN UINTN SubVendorId, + IN UINTN SubDeviceId, + OUT VOID **Configuration + ); + +// +// Handle onto which the Incompatible PCI Device List is installed +// +EFI_HANDLE mIncompatiblePciDeviceSupportHandle = NULL; + +// +// The Incompatible PCI Device Support Protocol instance produced by this driver +// +EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL mIncompatiblePciDeviceSupport = { + PCheckDevice +}; + +// +// The incompatible PCI devices list template +// +GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mIncompatiblePciDeviceList[] = { + // + // DEVICE_INF_TAG, + // PCI_DEVICE_ID (VendorID, DeviceID, Revision, SubVendorId, SubDeviceId), + // DEVICE_RES_TAG, + // ResType, GFlag , SFlag, Granularity, RangeMin, + // RangeMax, Offset, AddrLen + // + // + // Device Adaptec 9004 + // + DEVICE_INF_TAG, + PCI_DEVICE_ID(0x9004, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), + DEVICE_RES_TAG, + PCI_BAR_TYPE_IO, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_BAR_EVEN_ALIGN, + PCI_BAR_ALL, + PCI_BAR_NOCHANGE, + // + // Device Adaptec 9005 + // + DEVICE_INF_TAG, + PCI_DEVICE_ID(0x9005, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), + DEVICE_RES_TAG, + PCI_BAR_TYPE_IO, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_BAR_EVEN_ALIGN, + PCI_BAR_ALL, + PCI_BAR_NOCHANGE, + // + // Device QLogic 1007 + // + DEVICE_INF_TAG, + PCI_DEVICE_ID(0x1077, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), + DEVICE_RES_TAG, + PCI_BAR_TYPE_IO, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_BAR_EVEN_ALIGN, + PCI_BAR_ALL, + PCI_BAR_NOCHANGE, + // + // Device Agilent 103C + // + DEVICE_INF_TAG, + PCI_DEVICE_ID(0x103C, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), + DEVICE_RES_TAG, + PCI_BAR_TYPE_IO, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_BAR_EVEN_ALIGN, + PCI_BAR_ALL, + PCI_BAR_NOCHANGE, + // + // Device Agilent 15BC + // + DEVICE_INF_TAG, + PCI_DEVICE_ID(0x15BC, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), + DEVICE_RES_TAG, + PCI_BAR_TYPE_IO, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_ACPI_UNUSED, + PCI_BAR_EVEN_ALIGN, + PCI_BAR_ALL, + PCI_BAR_NOCHANGE, + // + // The end of the list + // + LIST_END_TAG +}; + + +/** + Entry point of the incompatible pci device support code. Setup an incompatible device list template + and install EFI Incompatible PCI Device Support protocol. + + @param ImageHandle A handle for the image that is initializing this driver. + @param SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS Installed EFI Incompatible PCI Device Support Protocol successfully. + @retval others Failed to install protocol. + +**/ +EFI_STATUS +EFIAPI +IncompatiblePciDeviceSupportEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Install EFI Incompatible PCI Device Support Protocol on a new handle + // + Status = gBS->InstallProtocolInterface ( + &mIncompatiblePciDeviceSupportHandle, + &gEfiIncompatiblePciDeviceSupportProtocolGuid, + EFI_NATIVE_INTERFACE, + &mIncompatiblePciDeviceSupport + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Returns a list of ACPI resource descriptors that detail the special + resource configuration requirements for an incompatible PCI device. + + @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance. + @param VendorID A unique ID to identify the manufacturer of the PCI device. + @param DeviceID A unique ID to identify the particular PCI device. + @param RevisionID A PCI device-specific revision identifier. + @param SubsystemVendorId Specifies the subsystem vendor ID. + @param SubsystemDeviceId Specifies the subsystem device ID. + @param Configuration A list of ACPI resource descriptors returned that detail + the configuration requirement. + + @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_OUT_OF_RESOURCES No memory available. + @retval EFI_UNSUPPORTED The specified PCI device wasn't supported. + +**/ +EFI_STATUS +EFIAPI +PCheckDevice ( + IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This, + IN UINTN VendorId, + IN UINTN DeviceId, + IN UINTN Revision, + IN UINTN SubVendorId, + IN UINTN SubDeviceId, + OUT VOID **Configuration + ) +{ + UINT64 Tag; + UINT64 *ListPtr; + UINT64 *TempListPtr; + EFI_PCI_DEVICE_HEADER_INFO *Header; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AcpiPtr; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *OldAcpiPtr; + EFI_PCI_RESOUCE_DESCRIPTOR *Dsc; + EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd; + UINTN Index; + + // + // Validate the parameters + // + if (Configuration == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Initialize the return value to NULL + // + * (VOID **) Configuration = NULL; + + ListPtr = mIncompatiblePciDeviceList; + while (*ListPtr != LIST_END_TAG) { + + Tag = *ListPtr; + + switch (Tag) { + case DEVICE_INF_TAG: + Header = (EFI_PCI_DEVICE_HEADER_INFO *) (ListPtr + 1); + ListPtr = ListPtr + 1 + sizeof (EFI_PCI_DEVICE_HEADER_INFO) / sizeof (UINT64); + // + // See if the Header matches the parameters passed in + // + if (Header->VendorId != DEVICE_ID_NOCARE) { + if (Header->VendorId != VendorId) { + continue; + } + } + + if (Header->DeviceId != DEVICE_ID_NOCARE) { + if (DeviceId != Header->DeviceId) { + continue; + } + } + + if (Header->Revision != DEVICE_ID_NOCARE) { + if (Revision != Header->Revision) { + continue; + } + } + + if (Header->SubVendorId != DEVICE_ID_NOCARE) { + if (SubVendorId != Header->SubVendorId) { + continue; + } + } + + if (Header->SubDeviceId != DEVICE_ID_NOCARE) { + if (SubDeviceId != Header->SubDeviceId) { + continue; + } + } + // + // Matched an item, so construct the ACPI descriptor for the resource. + // + // + // Count the resource items so that to allocate space + // + for (Index = 0, TempListPtr = ListPtr; *TempListPtr == DEVICE_RES_TAG; Index++) { + TempListPtr = TempListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64)); + } + // + // If there is at least one type of resource request, + // allocate an acpi resource node + // + if (Index == 0) { + return EFI_UNSUPPORTED; + } + + AcpiPtr = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Index + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + if (AcpiPtr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + OldAcpiPtr = AcpiPtr; + // + // Fill the EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR structure + // according to the EFI_PCI_RESOUCE_DESCRIPTOR structure + // + for (; *ListPtr == DEVICE_RES_TAG;) { + + Dsc = (EFI_PCI_RESOUCE_DESCRIPTOR *) (ListPtr + 1); + + AcpiPtr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + AcpiPtr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); + AcpiPtr->ResType = (UINT8) Dsc->ResType; + AcpiPtr->GenFlag = (UINT8) Dsc->GenFlag; + AcpiPtr->SpecificFlag = (UINT8) Dsc->SpecificFlag; + AcpiPtr->AddrSpaceGranularity = Dsc->AddrSpaceGranularity;; + AcpiPtr->AddrRangeMin = Dsc->AddrRangeMin; + AcpiPtr->AddrRangeMax = Dsc->AddrRangeMax; + AcpiPtr->AddrTranslationOffset = Dsc->AddrTranslationOffset; + AcpiPtr->AddrLen = Dsc->AddrLen; + + ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64)); + AcpiPtr++; + } + // + // Put the checksum + // + PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (AcpiPtr); + PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; + PtrEnd->Checksum = 0; + + *(VOID **) Configuration = OldAcpiPtr; + + return EFI_SUCCESS; + + case DEVICE_RES_TAG: + // + // Adjust the pointer to the next PCI resource descriptor item + // + ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64)); + break; + + default: + return EFI_UNSUPPORTED; + } + } + + return EFI_UNSUPPORTED; +} + diff --git a/IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf b/IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf new file mode 100644 index 0000000000..3ba2d99125 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf @@ -0,0 +1,47 @@ +#/** @file +# PCI Incompatible device support module template. +# +# Installs EFI PCI Incompatible Device Support protocol and includes one incompatile +# pci devices list template. +# +# Copyright (c) 2009, Intel Corporation. +# +# 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = IncompatiblePciDeviceSupport + FILE_GUID = AD70855E-0CC5-4abf-8979-BE762A949EA3 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = IncompatiblePciDeviceSupportEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + IncompatiblePciDeviceSupport.c + +[Packages] + MdePkg/MdePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + MemoryAllocationLib + DebugLib + +[Protocols] + gEfiIncompatiblePciDeviceSupportProtocolGuid ## PRODUCEDS diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c index c3157d4374..49c7ec4ee0 100644 --- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c +++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c @@ -1086,14 +1086,14 @@ UpdatePciInfo ( // If it is , then get its special requirement in the ACPI table // Status = gEfiIncompatiblePciDeviceSupport->CheckDevice ( - gEfiIncompatiblePciDeviceSupport, - PciIoDevice->Pci.Hdr.VendorId, - PciIoDevice->Pci.Hdr.DeviceId, - PciIoDevice->Pci.Hdr.RevisionID, - PciIoDevice->Pci.Device.SubsystemVendorID, - PciIoDevice->Pci.Device.SubsystemID, - &Configuration - ); + gEfiIncompatiblePciDeviceSupport, + PciIoDevice->Pci.Hdr.VendorId, + PciIoDevice->Pci.Hdr.DeviceId, + PciIoDevice->Pci.Hdr.RevisionID, + PciIoDevice->Pci.Device.SubsystemVendorID, + PciIoDevice->Pci.Device.SubsystemID, + &Configuration + ); } diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc index 97224d2dad..edd151a492 100644 --- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc +++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc @@ -204,6 +204,7 @@ IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf IntelFrameworkModulePkg/Bus/Isa/Ps2MouseAbsolutePointerDxe/Ps2MouseAbsolutePointerDxe.inf IntelFrameworkModulePkg/Bus/Pci/VgaMiniPortDxe/VgaMiniPortDxe.inf + IntelFrameworkModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf IntelFrameworkModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf diff --git a/IntelFrameworkPkg/Include/Protocol/IncompatiblePciDeviceSupport.h b/IntelFrameworkPkg/Include/Protocol/IncompatiblePciDeviceSupport.h index 75b7db5f16..bd3fa530c4 100644 --- a/IntelFrameworkPkg/Include/Protocol/IncompatiblePciDeviceSupport.h +++ b/IntelFrameworkPkg/Include/Protocol/IncompatiblePciDeviceSupport.h @@ -24,8 +24,6 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - Module Name: IncompatiblePciDeviceSupport.h - @par Revision Reference: This protocol is defined in Framework of EFI PCI Platform Support Specification. Version 0.9. @@ -65,8 +63,8 @@ EFI_STATUS IN UINTN VendorId, IN UINTN DeviceId, IN UINTN Revision, - IN UINTN SubVendorId,OPTIONAL - IN UINTN SubDeviceId,OPTIONAL + IN UINTN SubVendorId, + IN UINTN SubDeviceId, OUT VOID **Configuration );