+++ /dev/null
-/** @file\r
- This module is one template module for Incompatible PCI Device Support protocol.\r
- It includes one incompatile pci devices list template.\r
- \r
- Incompatible PCI Device Support protocol allows the PCI bus driver to support\r
- resource allocation for some PCI devices that do not comply with the PCI Specification.\r
-\r
-Copyright (c) 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <FrameworkDxe.h>\r
-\r
-#include <Protocol/IncompatiblePciDeviceSupport.h>\r
-\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/DebugLib.h>\r
-\r
-#include <IndustryStandard/Pci.h>\r
-#include <IndustryStandard/Acpi.h>\r
-\r
-typedef struct {\r
- UINT64 VendorId;\r
- UINT64 DeviceId;\r
- UINT64 RevisionId;\r
- UINT64 SubsystemVendorId;\r
- UINT64 SubsystemDeviceId;\r
-} EFI_PCI_DEVICE_HEADER_INFO;\r
-\r
-typedef struct {\r
- UINT64 ResType;\r
- UINT64 GenFlag;\r
- UINT64 SpecificFlag;\r
- UINT64 AddrSpaceGranularity;\r
- UINT64 AddrRangeMin;\r
- UINT64 AddrRangeMax;\r
- UINT64 AddrTranslationOffset;\r
- UINT64 AddrLen;\r
-} EFI_PCI_RESOUCE_DESCRIPTOR;\r
-\r
-#define PCI_DEVICE_ID(VendorId, DeviceId, Revision, SubVendorId, SubDeviceId) \\r
- VendorId, DeviceId, Revision, SubVendorId, SubDeviceId\r
-\r
-#define PCI_BAR_TYPE_IO ACPI_ADDRESS_SPACE_TYPE_IO\r
-#define PCI_BAR_TYPE_MEM ACPI_ADDRESS_SPACE_TYPE_MEM\r
-\r
-#define DEVICE_INF_TAG 0xFFF2\r
-#define DEVICE_RES_TAG 0xFFF1\r
-#define LIST_END_TAG 0x0000\r
-\r
-\r
-/**\r
- Returns a list of ACPI resource descriptors that detail the special\r
- resource configuration requirements for an incompatible PCI device.\r
-\r
- @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance.\r
- @param VendorId A unique ID to identify the manufacturer of the PCI device.\r
- @param DeviceId A unique ID to identify the particular PCI device.\r
- @param RevisionId A PCI device-specific revision identifier.\r
- @param SubsystemVendorId Specifies the subsystem vendor ID.\r
- @param SubsystemDeviceId Specifies the subsystem device ID.\r
- @param Configuration A list of ACPI resource descriptors returned that detail\r
- the configuration requirement.\r
-\r
- @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device.\r
- @retval EFI_INVALID_PARAMETER Configuration is NULL. \r
- @retval EFI_OUT_OF_RESOURCES No memory available.\r
- @retval EFI_UNSUPPORTED The specified PCI device wasn't supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PCheckDevice (\r
- IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This,\r
- IN UINTN VendorId,\r
- IN UINTN DeviceId,\r
- IN UINTN RevisionId,\r
- IN UINTN SubsystemVendorId,\r
- IN UINTN SubsystemDeviceId,\r
- OUT VOID **Configuration\r
- );\r
-\r
-//\r
-// Handle onto which the Incompatible PCI Device List is installed\r
-//\r
-EFI_HANDLE mIncompatiblePciDeviceSupportHandle = NULL;\r
-\r
-//\r
-// The Incompatible PCI Device Support Protocol instance produced by this driver\r
-//\r
-EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL mIncompatiblePciDeviceSupport = {\r
- PCheckDevice\r
-};\r
-\r
-//\r
-// The incompatible PCI devices list template\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mIncompatiblePciDeviceList[] = {\r
- //\r
- // DEVICE_INF_TAG,\r
- // PCI_DEVICE_ID (VendorID, DeviceID, Revision, SubVendorId, SubDeviceId),\r
- // DEVICE_RES_TAG,\r
- // ResType, GFlag , SFlag, Granularity, RangeMin,\r
- // RangeMax, Offset, AddrLen\r
- //\r
- //\r
- // Device Adaptec 9004\r
- //\r
- DEVICE_INF_TAG,\r
- PCI_DEVICE_ID(0x9004, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE),\r
- DEVICE_RES_TAG,\r
- PCI_BAR_TYPE_IO,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_BAR_EVEN_ALIGN,\r
- PCI_BAR_ALL,\r
- PCI_BAR_NOCHANGE,\r
- //\r
- // Device Adaptec 9005\r
- //\r
- DEVICE_INF_TAG,\r
- PCI_DEVICE_ID(0x9005, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE),\r
- DEVICE_RES_TAG,\r
- PCI_BAR_TYPE_IO,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_BAR_EVEN_ALIGN,\r
- PCI_BAR_ALL,\r
- PCI_BAR_NOCHANGE,\r
- //\r
- // Device QLogic 1007\r
- //\r
- DEVICE_INF_TAG,\r
- PCI_DEVICE_ID(0x1077, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE),\r
- DEVICE_RES_TAG,\r
- PCI_BAR_TYPE_IO,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_BAR_EVEN_ALIGN,\r
- PCI_BAR_ALL,\r
- PCI_BAR_NOCHANGE,\r
- //\r
- // Device Agilent 103C\r
- //\r
- DEVICE_INF_TAG,\r
- PCI_DEVICE_ID(0x103C, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE),\r
- DEVICE_RES_TAG,\r
- PCI_BAR_TYPE_IO,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_BAR_EVEN_ALIGN,\r
- PCI_BAR_ALL,\r
- PCI_BAR_NOCHANGE,\r
- //\r
- // Device Agilent 15BC\r
- //\r
- DEVICE_INF_TAG,\r
- PCI_DEVICE_ID(0x15BC, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE),\r
- DEVICE_RES_TAG,\r
- PCI_BAR_TYPE_IO,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_ACPI_UNUSED,\r
- PCI_BAR_EVEN_ALIGN,\r
- PCI_BAR_ALL,\r
- PCI_BAR_NOCHANGE,\r
- //\r
- // The end of the list\r
- //\r
- LIST_END_TAG\r
-};\r
-\r
-\r
-/**\r
- Entry point of the incompatible pci device support code. Setup an incompatible device list template\r
- and install EFI Incompatible PCI Device Support protocol.\r
-\r
- @param ImageHandle A handle for the image that is initializing this driver.\r
- @param SystemTable A pointer to the EFI system table.\r
-\r
- @retval EFI_SUCCESS Installed EFI Incompatible PCI Device Support Protocol successfully.\r
- @retval others Failed to install protocol.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IncompatiblePciDeviceSupportEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Install EFI Incompatible PCI Device Support Protocol on a new handle\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &mIncompatiblePciDeviceSupportHandle,\r
- &gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &mIncompatiblePciDeviceSupport\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Returns a list of ACPI resource descriptors that detail the special\r
- resource configuration requirements for an incompatible PCI device.\r
-\r
- @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance.\r
- @param VendorId A unique ID to identify the manufacturer of the PCI device.\r
- @param DeviceId A unique ID to identify the particular PCI device.\r
- @param RevisionId A PCI device-specific revision identifier.\r
- @param SubsystemVendorId Specifies the subsystem vendor ID.\r
- @param SubsystemDeviceId Specifies the subsystem device ID.\r
- @param Configuration A list of ACPI resource descriptors returned that detail\r
- the configuration requirement.\r
-\r
- @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device.\r
- @retval EFI_INVALID_PARAMETER Configuration is NULL. \r
- @retval EFI_OUT_OF_RESOURCES No memory available.\r
- @retval EFI_UNSUPPORTED The specified PCI device wasn't supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PCheckDevice (\r
- IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This,\r
- IN UINTN VendorId,\r
- IN UINTN DeviceId,\r
- IN UINTN RevisionId,\r
- IN UINTN SubsystemVendorId,\r
- IN UINTN SubsystemDeviceId,\r
- OUT VOID **Configuration\r
- )\r
-{\r
- UINT64 Tag;\r
- UINT64 *ListPtr;\r
- UINT64 *TempListPtr;\r
- EFI_PCI_DEVICE_HEADER_INFO *Header;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AcpiPtr;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *OldAcpiPtr;\r
- EFI_PCI_RESOUCE_DESCRIPTOR *Dsc;\r
- EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
- UINTN Index;\r
-\r
- //\r
- // Validate the parameters\r
- //\r
- if (Configuration == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Initialize the return value to NULL\r
- //\r
- * (VOID **) Configuration = NULL;\r
-\r
- ListPtr = mIncompatiblePciDeviceList;\r
- while (*ListPtr != LIST_END_TAG) {\r
-\r
- Tag = *ListPtr;\r
-\r
- switch (Tag) {\r
- case DEVICE_INF_TAG:\r
- Header = (EFI_PCI_DEVICE_HEADER_INFO *) (ListPtr + 1);\r
- ListPtr = ListPtr + 1 + sizeof (EFI_PCI_DEVICE_HEADER_INFO) / sizeof (UINT64);\r
- //\r
- // See if the Header matches the parameters passed in\r
- //\r
- if (Header->VendorId != DEVICE_ID_NOCARE) {\r
- if (Header->VendorId != VendorId) {\r
- continue;\r
- }\r
- }\r
-\r
- if (Header->DeviceId != DEVICE_ID_NOCARE) {\r
- if (DeviceId != Header->DeviceId) {\r
- continue;\r
- }\r
- }\r
-\r
- if (Header->RevisionId != DEVICE_ID_NOCARE) {\r
- if (RevisionId != Header->RevisionId) {\r
- continue;\r
- }\r
- }\r
-\r
- if (Header->SubsystemVendorId != DEVICE_ID_NOCARE) {\r
- if (SubsystemVendorId != Header->SubsystemVendorId) {\r
- continue;\r
- }\r
- }\r
-\r
- if (Header->SubsystemDeviceId != DEVICE_ID_NOCARE) {\r
- if (SubsystemDeviceId != Header->SubsystemDeviceId) {\r
- continue;\r
- }\r
- }\r
- //\r
- // Matched an item, so construct the ACPI descriptor for the resource.\r
- //\r
- //\r
- // Count the resource items so that to allocate space\r
- //\r
- for (Index = 0, TempListPtr = ListPtr; *TempListPtr == DEVICE_RES_TAG; Index++) {\r
- TempListPtr = TempListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64));\r
- }\r
- //\r
- // If there is at least one type of resource request,\r
- // allocate an acpi resource node\r
- //\r
- if (Index == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- AcpiPtr = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Index + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
- if (AcpiPtr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- OldAcpiPtr = AcpiPtr;\r
- //\r
- // Fill the EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR structure\r
- // according to the EFI_PCI_RESOUCE_DESCRIPTOR structure\r
- //\r
- for (; *ListPtr == DEVICE_RES_TAG;) {\r
-\r
- Dsc = (EFI_PCI_RESOUCE_DESCRIPTOR *) (ListPtr + 1);\r
-\r
- AcpiPtr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- AcpiPtr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
- AcpiPtr->ResType = (UINT8) Dsc->ResType;\r
- AcpiPtr->GenFlag = (UINT8) Dsc->GenFlag;\r
- AcpiPtr->SpecificFlag = (UINT8) Dsc->SpecificFlag;\r
- AcpiPtr->AddrSpaceGranularity = Dsc->AddrSpaceGranularity;;\r
- AcpiPtr->AddrRangeMin = Dsc->AddrRangeMin;\r
- AcpiPtr->AddrRangeMax = Dsc->AddrRangeMax;\r
- AcpiPtr->AddrTranslationOffset = Dsc->AddrTranslationOffset;\r
- AcpiPtr->AddrLen = Dsc->AddrLen;\r
-\r
- ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64));\r
- AcpiPtr++;\r
- }\r
- //\r
- // Put the checksum\r
- //\r
- PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (AcpiPtr);\r
- PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- PtrEnd->Checksum = 0;\r
-\r
- *(VOID **) Configuration = OldAcpiPtr;\r
-\r
- return EFI_SUCCESS;\r
-\r
- case DEVICE_RES_TAG:\r
- //\r
- // Adjust the pointer to the next PCI resource descriptor item\r
- //\r
- ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64));\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r