--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2007, 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
+Module Name:\r
+ ComponentName.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+#include "PciBus.h"\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ );\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = {\r
+ PciBusComponentNameGetDriverName,\r
+ PciBusComponentNameGetControllerName,\r
+ "eng"\r
+};\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2 = {\r
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) PciBusComponentNameGetDriverName,\r
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) PciBusComponentNameGetControllerName,\r
+ "en"\r
+};\r
+\r
+\r
+STATIC EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = {\r
+ { "eng;en", L"PCI Bus Driver" },\r
+ { NULL, NULL }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ Language - A pointer to a three character ISO 639-2 language identifier.\r
+ This is the language of the driver name that that the caller \r
+ is requesting, and it must match one of the languages specified\r
+ in SupportedLanguages. The number of languages supported by a \r
+ driver is up to the driver writer.\r
+ DriverName - A pointer to the Unicode string to return. This Unicode string\r
+ is the name of the driver specified by This in the language \r
+ specified by Language.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The Unicode string for the Driver specified by This\r
+ and the language specified by Language was returned \r
+ in DriverName.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - DriverName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the \r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ return LookupUnicodeString2 (\r
+ Language,\r
+ This->SupportedLanguages,\r
+ mPciBusDriverNameTable, \r
+ DriverName,\r
+ (BOOLEAN)(This == &gPciBusComponentName)\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by an EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ ControllerHandle - The handle of a controller that the driver specified by \r
+ This is managing. This handle specifies the controller \r
+ whose name is to be returned.\r
+ ChildHandle - The handle of the child controller to retrieve the name \r
+ of. This is an optional parameter that may be NULL. It \r
+ will be NULL for device drivers. It will also be NULL \r
+ for a bus drivers that wish to retrieve the name of the \r
+ bus controller. It will not be NULL for a bus driver \r
+ that wishes to retrieve the name of a child controller.\r
+ Language - A pointer to a three character ISO 639-2 language \r
+ identifier. This is the language of the controller name \r
+ that that the caller is requesting, and it must match one\r
+ of the languages specified in SupportedLanguages. The \r
+ number of languages supported by a driver is up to the \r
+ driver writer.\r
+ ControllerName - A pointer to the Unicode string to return. This Unicode\r
+ string is the name of the controller specified by \r
+ ControllerHandle and ChildHandle in the language specified\r
+ by Language from the point of view of the driver specified\r
+ by This. \r
+\r
+ Returns:\r
+ EFI_SUCCESS - The Unicode string for the user readable name in the \r
+ language specified by Language for the driver \r
+ specified by This was returned in DriverName.\r
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing \r
+ the controller specified by ControllerHandle and \r
+ ChildHandle.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the \r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciBus.c\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+ \r
+--*/\r
+\r
+#include "PciBus.h"\r
+\r
+//\r
+// PCI Bus Support Function Prototypes\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ );\r
+\r
+\r
+//\r
+// PCI Bus Driver Global Variables\r
+//\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {\r
+ PciBusDriverBindingSupported,\r
+ PciBusDriverBindingStart,\r
+ PciBusDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+BOOLEAN gFullEnumeration;\r
+ \r
+//\r
+// PCI Bus Driver Support Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize the global variables\r
+ publish the driver binding protocol\r
+\r
+Arguments:\r
+\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS \r
+ EFI_DEVICE_ERROR \r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Initialize the EFI Driver Library\r
+ //\r
+ Status = EfiLibInstallDriverBindingComponentName2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gPciBusDriverBinding,\r
+ ImageHandle,\r
+ &gPciBusComponentName,\r
+ &gPciBusComponentName2\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ InitializePciDevicePool ();\r
+\r
+ gFullEnumeration = TRUE;\r
+ \r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check to see if pci bus driver supports the given controller\r
+\r
+Arguments:\r
+ \r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ EFI_DEV_PATH_PTR Node;\r
+\r
+ if (RemainingDevicePath != NULL) {\r
+ Node.DevPath = RemainingDevicePath;\r
+ if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||\r
+ Node.DevPath->SubType != HW_PCI_DP ||\r
+ DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start to management the controller passed in\r
+\r
+Arguments:\r
+ \r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+\r
+Returns:\r
+ \r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Enumerate the entire host bridge\r
+ // After enumeration, a database that records all the device information will be created\r
+ //\r
+ //\r
+ Status = PciEnumerator (Controller);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Enable PCI device specified by remaining device path. BDS or other driver can call the\r
+ // start more than once.\r
+ //\r
+ \r
+ StartPciDevices (Controller, RemainingDevicePath);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciBusDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Stop one or more children created at start of pci bus driver\r
+ if all the the children get closed, close the protocol\r
+\r
+Arguments:\r
+ \r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+\r
+Returns:\r
+\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ BOOLEAN AllChildrenStopped;\r
+\r
+ if (NumberOfChildren == 0) {\r
+ //\r
+ // Close the bus driver\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ DestroyRootBridgeByHandle (\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Stop all the children\r
+ //\r
+\r
+ AllChildrenStopped = TRUE;\r
+\r
+ for (Index = 0; Index < NumberOfChildren; Index++) {\r
+\r
+ //\r
+ // De register all the pci device\r
+ //\r
+ Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AllChildrenStopped = FALSE;\r
+ }\r
+ }\r
+\r
+ if (!AllChildrenStopped) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2007, 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
+Module Name:\r
+\r
+ PciBus.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_BUS_H\r
+#define _EFI_PCI_BUS_H\r
+\r
+#include <FrameworkDxe.h>\r
+\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/PciRootBridgeIo.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/Decompress.h>\r
+#include <Protocol/UgaIo.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/BusSpecificDriverOverride.h>\r
+\r
+#include <Guid/PciOptionRomTable.h>\r
+\r
+#include <IndustryStandard/Pci23.h>\r
+#include <IndustryStandard/Acpi.h>\r
+#include <IndustryStandard/PeImage.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+\r
+//\r
+// Driver Produced Protocol Prototypes\r
+//\r
+\r
+#define VGABASE1 0x3B0\r
+#define VGALIMIT1 0x3BB\r
+\r
+#define VGABASE2 0x3C0\r
+#define VGALIMIT2 0x3DF\r
+\r
+#define ISABASE 0x100\r
+#define ISALIMIT 0x3FF\r
+\r
+typedef enum {\r
+ PciBarTypeUnknown = 0,\r
+ PciBarTypeIo16,\r
+ PciBarTypeIo32,\r
+ PciBarTypeMem32,\r
+ PciBarTypePMem32,\r
+ PciBarTypeMem64,\r
+ PciBarTypePMem64,\r
+ PciBarTypeIo,\r
+ PciBarTypeMem,\r
+ PciBarTypeMaxType\r
+} PCI_BAR_TYPE;\r
+\r
+typedef struct {\r
+ UINT64 BaseAddress;\r
+ UINT64 Length;\r
+ UINT64 Alignment;\r
+ PCI_BAR_TYPE BarType;\r
+ BOOLEAN Prefetchable;\r
+ UINT8 MemType;\r
+ UINT8 Offset;\r
+} PCI_BAR;\r
+\r
+#define PCI_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('p','c','i','o')\r
+\r
+#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001 \r
+#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002 \r
+#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004 \r
+#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008 \r
+#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010 \r
+#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020\r
+#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040\r
+\r
+\r
+typedef struct _PCI_IO_DEVICE {\r
+ UINT32 Signature;\r
+ EFI_HANDLE Handle;\r
+ EFI_PCI_IO_PROTOCOL PciIo;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ //\r
+ // PCI configuration space header type\r
+ //\r
+ PCI_TYPE00 Pci;\r
+\r
+ //\r
+ // Bus number, Device number, Function number\r
+ //\r
+ UINT8 BusNumber;\r
+ UINT8 DeviceNumber;\r
+ UINT8 FunctionNumber;\r
+\r
+ //\r
+ // BAR for this PCI Device\r
+ //\r
+ PCI_BAR PciBar[PCI_MAX_BAR];\r
+\r
+ //\r
+ // The bridge device this pci device is subject to\r
+ //\r
+ struct _PCI_IO_DEVICE *Parent;\r
+\r
+ //\r
+ // A linked list for children Pci Device if it is bridge device\r
+ //\r
+ LIST_ENTRY ChildList;\r
+\r
+ //\r
+ // TURE if the PCI bus driver creates the handle for this PCI device\r
+ //\r
+ BOOLEAN Registered;\r
+\r
+ //\r
+ // TRUE if the PCI bus driver successfully allocates the resource required by\r
+ // this PCI device\r
+ //\r
+ BOOLEAN Allocated;\r
+\r
+ //\r
+ // The attribute this PCI device currently set\r
+ //\r
+ UINT64 Attributes;\r
+\r
+ //\r
+ // The attributes this PCI device actually supports\r
+ //\r
+ UINT64 Supports;\r
+\r
+ //\r
+ // The resource decode the bridge supports\r
+ //\r
+ UINT32 Decodes;\r
+\r
+ //\r
+ // The OptionRom Size\r
+ //\r
+ UINT64 RomSize;\r
+\r
+ //\r
+ // TRUE if there is any EFI driver in the OptionRom\r
+ //\r
+ BOOLEAN BusOverride;\r
+\r
+ //\r
+ // A list tracking reserved resource on a bridge device\r
+ //\r
+ LIST_ENTRY ReservedResourceList;\r
+\r
+ //\r
+ // A list tracking image handle of platform specific overriding driver\r
+ //\r
+ LIST_ENTRY OptionRomDriverList;\r
+\r
+ BOOLEAN IsPciExp;\r
+\r
+} PCI_IO_DEVICE;\r
+\r
+\r
+#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \\r
+ CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)\r
+\r
+#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \\r
+ CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)\r
+\r
+#define PCI_IO_DEVICE_FROM_LINK(a) \\r
+ CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName;\r
+extern GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2;\r
+extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding;\r
+\r
+extern BOOLEAN gFullEnumeration;\r
+static UINT64 gAllOne = 0xFFFFFFFFFFFFFFFF;\r
+static UINT64 gAllZero = 0;\r
+\r
+#include "PciIo.h"\r
+#include "PciCommand.h"\r
+#include "PciDeviceSupport.h"\r
+#include "PciEnumerator.h"\r
+#include "PciEnumeratorSupport.h"\r
+#include "PciDriverOverride.h"\r
+#include "PciRomTable.h"\r
+#include "PciOptionRomSupport.h"\r
+#include "PciPowerManagement.h"\r
+\r
+\r
+#define IS_ISA_BRIDGE(_p) IS_CLASS2 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_ISA) \r
+#define IS_INTEL_ISA_BRIDGE(_p) (IS_CLASS2 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_ISA_POSITIVE_DECODE) && ((_p)->Hdr.VendorId == 0x8086) && ((_p)->Hdr.DeviceId == 0x7110))\r
+\r
+#endif\r
--- /dev/null
+#/*++\r
+# \r
+# Copyright (c) 2005, 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
+# Module Name:\r
+#\r
+# Abstract:\r
+#\r
+#--*/\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = PciBusNoEnumerationDxe\r
+ FILE_GUID = 35C0C168-2607-4e51-BB53-448E3ED1A87F\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ EDK_RELEASE_VERSION = 0x00020000\r
+ EFI_SPECIFICATION_VERSION = 0x00020000\r
+\r
+ ENTRY_POINT = PciBusEntryPoint\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
+\r
+[LibraryClasses]\r
+ DebugLib\r
+ BaseLib\r
+ UefiLib\r
+ UefiBootServicesTableLib\r
+ UefiDriverEntryPoint\r
+ BaseMemoryLib\r
+ ReportStatusCodeLib\r
+ DevicePathLib\r
+\r
+[Sources]\r
+ PciBus.h\r
+ PciIo.h\r
+ PciCommand.h\r
+ PciDeviceSupport.h\r
+ PciEnumerator.h\r
+ PciEnumeratorSupport.h\r
+ PciOptionRomSupport.h\r
+ PciRomTable.h\r
+ PciPowerManagement.h\r
+ PciPowerManagement.c\r
+ PciRomTable.c\r
+ PciDriverOverride.h\r
+ PciDriverOverride.c\r
+ PciOptionRomSupport.c\r
+ PciEnumerator.c\r
+ PciEnumeratorSupport.c\r
+ PciCommand.c\r
+ ComponentName.c\r
+ PciDeviceSupport.c\r
+ PciBus.c\r
+ PciIo.c\r
+\r
+[Protocols]\r
+ gEfiPciRootBridgeIoProtocolGuid\r
+ gEfiPciIoProtocolGuid\r
+ gEfiDevicePathProtocolGuid\r
+ gEfiBusSpecificDriverOverrideProtocolGuid\r
+ gEfiPciOptionRomTableGuid\r
+ gEfiDecompressProtocolGuid\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciCommand.c\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Pcibus.h"\r
+\r
+\r
+EFI_STATUS \r
+PciReadCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT UINT16 *Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ *Command = 0;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ return PciIo->Pci.Read (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_COMMAND_OFFSET, \r
+ 1, \r
+ Command\r
+ );\r
+}\r
+ \r
+EFI_STATUS \r
+PciSetCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT16 Temp;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ \r
+ Temp = Command;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ return PciIo->Pci.Write (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_COMMAND_OFFSET, \r
+ 1, \r
+ &Temp\r
+ );\r
+ \r
+}\r
+\r
+\r
+EFI_STATUS \r
+PciEnableCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT16 OldCommand;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ OldCommand = 0;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ PciIo->Pci.Read (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_COMMAND_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+\r
+ OldCommand |= Command;\r
+\r
+ return PciIo->Pci.Write (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_COMMAND_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+ \r
+}\r
+\r
+\r
+EFI_STATUS \r
+PciDisableCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT16 OldCommand;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ OldCommand = 0;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ PciIo->Pci.Read (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_COMMAND_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+\r
+ OldCommand &= ~(Command);\r
+\r
+ return PciIo->Pci.Write (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_COMMAND_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+ \r
+}\r
+\r
+\r
+\r
+EFI_STATUS \r
+PciSetBridgeControlRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT16 Temp;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ Temp = Command;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ return PciIo->Pci.Write (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_BRIDGE_CONTROL_REGISTER_OFFSET, \r
+ 1, \r
+ &Temp\r
+ );\r
+ \r
+}\r
+\r
+\r
+EFI_STATUS \r
+PciEnableBridgeControlRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT16 OldCommand;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ OldCommand = 0;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ PciIo->Pci.Read (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_BRIDGE_CONTROL_REGISTER_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+\r
+ OldCommand |= Command;\r
+\r
+ return PciIo->Pci.Write (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_BRIDGE_CONTROL_REGISTER_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+ \r
+}\r
+\r
+EFI_STATUS \r
+PciDisableBridgeControlRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT16 OldCommand;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ OldCommand = 0;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ PciIo->Pci.Read (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_BRIDGE_CONTROL_REGISTER_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+\r
+ OldCommand &= ~(Command);\r
+\r
+ return PciIo->Pci.Write (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_BRIDGE_CONTROL_REGISTER_OFFSET, \r
+ 1, \r
+ &OldCommand\r
+ );\r
+ \r
+}\r
+\r
+\r
+\r
+EFI_STATUS \r
+PciReadBridgeControlRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT UINT16 *Command\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ *Command = 0;\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ return PciIo->Pci.Read (\r
+ PciIo, \r
+ EfiPciIoWidthUint16, \r
+ PCI_BRIDGE_CONTROL_REGISTER_OFFSET, \r
+ 1, \r
+ Command\r
+ );\r
+ \r
+}\r
+\r
+BOOLEAN\r
+PciCapabilitySupport (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+// TODO: PciIoDevice - add argument and description to function comment\r
+{\r
+\r
+ if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+LocateCapabilityRegBlock (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT8 CapId,\r
+ IN OUT UINT8 *Offset,\r
+ OUT UINT8 *NextRegBlock OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Locate Capability register.\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+ CapId - The capability ID.\r
+ Offset - A pointer to the offset. \r
+ As input: the default offset; \r
+ As output: the offset of the found block.\r
+ NextRegBlock - An optional pointer to return the value of next block.\r
+\r
+Returns:\r
+ \r
+ EFI_UNSUPPORTED - The Pci Io device is not supported.\r
+ EFI_NOT_FOUND - The Pci Io device cannot be found.\r
+ EFI_SUCCESS - The Pci Io device is successfully located.\r
+\r
+--*/\r
+{\r
+ UINT8 CapabilityPtr;\r
+ UINT16 CapabilityEntry;\r
+ UINT8 CapabilityID;\r
+ UINT32 Temp;\r
+\r
+ //\r
+ // To check the capability of this device supports\r
+ //\r
+ if (!PciCapabilitySupport (PciIoDevice)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (*Offset != 0) {\r
+ CapabilityPtr = *Offset;\r
+ } else {\r
+\r
+ CapabilityPtr = 0;\r
+ if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+\r
+ PciIoDevice->PciIo.Pci.Read (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,\r
+ 1,\r
+ &CapabilityPtr\r
+ );\r
+ } else {\r
+\r
+ PciIoDevice->PciIo.Pci.Read (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ EFI_PCI_CAPABILITY_PTR,\r
+ 1,\r
+ &Temp\r
+ );\r
+ //\r
+ // Do not get byte read directly, because some PCI card will return 0xFF\r
+ // when perform PCI-Express byte read, while return correct 0x00 \r
+ // when perform PCI-Express dword read, or PCI dword read.\r
+ //\r
+ CapabilityPtr = (UINT8)Temp;\r
+ }\r
+ }\r
+\r
+ while (CapabilityPtr > 0x3F) {\r
+ //\r
+ // Mask it to DWORD alignment per PCI spec\r
+ //\r
+ CapabilityPtr &= 0xFC;\r
+ PciIoDevice->PciIo.Pci.Read (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint16,\r
+ CapabilityPtr,\r
+ 1,\r
+ &CapabilityEntry\r
+ );\r
+\r
+ CapabilityID = (UINT8) CapabilityEntry;\r
+\r
+ if (CapabilityID == CapId) {\r
+ *Offset = CapabilityPtr;\r
+ if (NextRegBlock != NULL) {\r
+ *NextRegBlock = (UINT8) (CapabilityEntry >> 8);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CapabilityPtr = (UINT8) (CapabilityEntry >> 8);\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+ \r
+ PciCommand.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_COMMAND_H\r
+#define _EFI_PCI_COMMAND_H\r
+\r
+#include "PciBus.h"\r
+\r
+//\r
+// The PCI Command register bits owned by PCI Bus driver.\r
+//\r
+// They should be cleared at the beginning. The other registers\r
+// are owned by chipset, we should not touch them.\r
+//\r
+#define EFI_PCI_COMMAND_BITS_OWNED ( \\r
+ EFI_PCI_COMMAND_IO_SPACE | \\r
+ EFI_PCI_COMMAND_MEMORY_SPACE | \\r
+ EFI_PCI_COMMAND_BUS_MASTER | \\r
+ EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \\r
+ EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \\r
+ EFI_PCI_COMMAND_FAST_BACK_TO_BACK \\r
+ )\r
+\r
+//\r
+// The PCI Bridge Control register bits owned by PCI Bus driver.\r
+// \r
+// They should be cleared at the beginning. The other registers\r
+// are owned by chipset, we should not touch them.\r
+//\r
+#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \\r
+ EFI_PCI_BRIDGE_CONTROL_ISA | \\r
+ EFI_PCI_BRIDGE_CONTROL_VGA | \\r
+ EFI_PCI_BRIDGE_CONTROL_VGA_16 | \\r
+ EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \\r
+ )\r
+\r
+//\r
+// The PCCard Bridge Control register bits owned by PCI Bus driver.\r
+// \r
+// They should be cleared at the beginning. The other registers\r
+// are owned by chipset, we should not touch them.\r
+//\r
+#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \\r
+ EFI_PCI_BRIDGE_CONTROL_ISA | \\r
+ EFI_PCI_BRIDGE_CONTROL_VGA | \\r
+ EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \\r
+ )\r
+\r
+EFI_STATUS \r
+PciReadCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT UINT16 *Command\r
+);\r
+\r
+ \r
+EFI_STATUS \r
+PciSetCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+);\r
+\r
+EFI_STATUS \r
+PciEnableCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+);\r
+\r
+EFI_STATUS \r
+PciDisableCommandRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+);\r
+\r
+EFI_STATUS \r
+PciDisableBridgeControlRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+);\r
+\r
+\r
+EFI_STATUS \r
+PciEnableBridgeControlRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command\r
+);\r
+\r
+EFI_STATUS \r
+PciReadBridgeControlRegister (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT UINT16 *Command\r
+);\r
+\r
+BOOLEAN\r
+PciCapabilitySupport (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+LocateCapabilityRegBlock (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT8 CapId,\r
+ IN OUT UINT8 *Offset,\r
+ OUT UINT8 *NextRegBlock OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Locate Capability register.\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+ CapId - The capability ID.\r
+ Offset - A pointer to the offset. \r
+ As input: the default offset; \r
+ As output: the offset of the found block.\r
+ NextRegBlock - An optional pointer to return the value of next block.\r
+\r
+Returns:\r
+ \r
+ EFI_UNSUPPORTED - The Pci Io device is not supported.\r
+ EFI_NOT_FOUND - The Pci Io device cannot be found.\r
+ EFI_SUCCESS - The Pci Io device is successfully located.\r
+\r
+--*/\r
+;\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciDeviceSupport.c\r
+ \r
+Abstract:\r
+\r
+ This file provides routine to support Pci device node manipulation\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Pcibus.h"\r
+\r
+//\r
+// This device structure is serviced as a header.\r
+// Its Next field points to the first root bridge device node\r
+//\r
+LIST_ENTRY gPciDevicePool;\r
+\r
+EFI_STATUS\r
+InitializePciDevicePool (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize the gPciDevicePool\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ InitializeListHead (&gPciDevicePool);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InsertRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Insert a root bridge into PCI device pool\r
+\r
+Arguments:\r
+\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ InsertTailList (&gPciDevicePool, &(RootBridge->Link));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InsertPciDevice (\r
+ PCI_IO_DEVICE *Bridge,\r
+ PCI_IO_DEVICE *PciDeviceNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to insert a PCI device node under\r
+ a bridge\r
+\r
+Arguments:\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+ PciDeviceNode - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+\r
+{\r
+\r
+ InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));\r
+ PciDeviceNode->Parent = Bridge;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DestroyRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ \r
+Arguments:\r
+\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ DestroyPciDeviceTree (RootBridge);\r
+\r
+ gBS->FreePool (RootBridge);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DestroyPciDeviceTree (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destroy all the pci device node under the bridge.\r
+ Bridge itself is not included.\r
+\r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ while (!IsListEmpty (&Bridge->ChildList)) {\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ //\r
+ // Remove this node from the linked list\r
+ //\r
+ RemoveEntryList (CurrentLink);\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (IS_PCI_BRIDGE (&(Temp->Pci))) {\r
+ DestroyPciDeviceTree (Temp);\r
+ }\r
+ gBS->FreePool (Temp);\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DestroyRootBridgeByHandle (\r
+ EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destroy all device nodes under the root bridge\r
+ specified by Controller. \r
+ The root bridge itself is also included.\r
+\r
+Arguments:\r
+\r
+ Controller - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->Handle == Controller) {\r
+\r
+ RemoveEntryList (CurrentLink);\r
+\r
+ DestroyPciDeviceTree (Temp);\r
+\r
+ gBS->FreePool(Temp);\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+RegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT EFI_HANDLE *Handle OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function registers the PCI IO device. It creates a handle for this PCI IO device \r
+ (if the handle does not exist), attaches appropriate protocols onto the handle, does\r
+ necessary initialization, and sets up parent/child relationship with its bus controller.\r
+\r
+Arguments:\r
+\r
+ Controller - An EFI handle for the PCI bus controller.\r
+ PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.\r
+ Handle - A pointer to hold the EFI handle for the PCI IO device.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The PCI device is successfully registered.\r
+ Others - An error occurred when registering the PCI device.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 PciExpressCapRegOffset;\r
+\r
+ //\r
+ // Install the pciio protocol, device path protocol and \r
+ // Bus Specific Driver Override Protocol\r
+ //\r
+\r
+ if (PciIoDevice->BusOverride) {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &PciIoDevice->Handle, \r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+ &PciIoDevice->PciDriverOverride,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &PciIoDevice->Handle, \r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ } else {\r
+ Status = gBS->OpenProtocol (\r
+ Controller, \r
+ &gEfiPciRootBridgeIoProtocolGuid, \r
+ (VOID **)&(PciIoDevice->PciRootBridgeIo),\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ PciIoDevice->Handle, \r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ if (Handle != NULL) {\r
+ *Handle = PciIoDevice->Handle;\r
+ }\r
+\r
+ //\r
+ // Detect if PCI Express Device\r
+ //\r
+ PciExpressCapRegOffset = 0;\r
+ Status = LocateCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCI_CAPABILITY_ID_PCIEXP,\r
+ &PciExpressCapRegOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIoDevice->IsPciExp = TRUE;\r
+ DEBUG ((EFI_D_ERROR, "PciExp - %x (B-%x, D-%x, F-%x)\n", PciIoDevice->IsPciExp, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber));\r
+ }\r
+ \r
+ //\r
+ // Indicate the pci device is registered\r
+ //\r
+ PciIoDevice->Registered = TRUE;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+DeRegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is used to de-register the PCI device from the EFI,\r
+ That includes un-installing PciIo protocol from the specified PCI \r
+ device handle.\r
+\r
+Arguments:\r
+\r
+ Controller - An efi handle.\r
+ Handle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ PCI_IO_DEVICE *Node;\r
+ LIST_ENTRY *CurrentLink;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Handle,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
+\r
+ //\r
+ // If it is already de-registered\r
+ //\r
+ if (!PciIoDevice->Registered) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If it is PPB, first de-register its children\r
+ //\r
+\r
+ if (IS_PCI_BRIDGE (&(PciIoDevice->Pci))) {\r
+\r
+ CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
+ Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ Status = DeRegisterPciDevice (Controller, Node->Handle);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+ }\r
+\r
+ //\r
+ // First disconnect this device\r
+ //\r
+// PciIoDevice->PciIo.Attributes(&(PciIoDevice->PciIo),\r
+// EfiPciIoAttributeOperationDisable,\r
+// EFI_PCI_DEVICE_ENABLE,\r
+// NULL\r
+// );\r
+ \r
+ //\r
+ // Close the child handle\r
+ //\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Handle\r
+ );\r
+\r
+ //\r
+ // Un-install the device path protocol and pci io protocol\r
+ //\r
+ if (PciIoDevice->BusOverride) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+ &PciIoDevice->PciDriverOverride,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEfiPciIoProtocolGuid,\r
+ &PciIoDevice->PciIo,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // The Device Driver should disable this device after disconnect\r
+ // so the Pci Bus driver will not touch this device any more.\r
+ // Restore the register field to the original value\r
+ //\r
+ PciIoDevice->Registered = FALSE;\r
+ PciIoDevice->Handle = NULL;\r
+ } else {\r
+\r
+ //\r
+ // Handle may be closed before\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EnableBridgeAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+{\r
+ PCI_TYPE01 PciData;\r
+\r
+ //\r
+ // NOTE: We should not set EFI_PCI_DEVICE_ENABLE for a bridge\r
+ // directly, because some legacy BIOS will NOT assign\r
+ // IO or Memory resource for a bridge who has no child\r
+ // device. So we add check IO or Memory here.\r
+ //\r
+\r
+ PciIoDevice->PciIo.Pci.Read (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ 0,\r
+ sizeof (PciData),\r
+ &PciData\r
+ );\r
+\r
+ if ((((PciData.Bridge.IoBase & 0xF) == 0) &&\r
+ (PciData.Bridge.IoBase != 0 || PciData.Bridge.IoLimit != 0)) ||\r
+ (((PciData.Bridge.IoBase & 0xF) == 1) &&\r
+ ((PciData.Bridge.IoBase & 0xF0) != 0 || (PciData.Bridge.IoLimit & 0xF0) != 0 || PciData.Bridge.IoBaseUpper16 != 0 || PciData.Bridge.IoLimitUpper16 != 0))) {\r
+ PciIoDevice->PciIo.Attributes(\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoAttributeOperationEnable,\r
+ (EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),\r
+ NULL\r
+ );\r
+ }\r
+ if ((PciData.Bridge.MemoryBase & 0xFFF0) != 0 || (PciData.Bridge.MemoryLimit & 0xFFF0) != 0) {\r
+ PciIoDevice->PciIo.Attributes(\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoAttributeOperationEnable,\r
+ (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),\r
+ NULL\r
+ );\r
+ }\r
+ if ((((PciData.Bridge.PrefetchableMemoryBase & 0xF) == 0) &&\r
+ (PciData.Bridge.PrefetchableMemoryBase != 0 || PciData.Bridge.PrefetchableMemoryLimit != 0)) ||\r
+ (((PciData.Bridge.PrefetchableMemoryBase & 0xF) == 1) &&\r
+ ((PciData.Bridge.PrefetchableMemoryBase & 0xFFF0) != 0 || (PciData.Bridge.PrefetchableMemoryLimit & 0xFFF0) != 0 || PciData.Bridge.PrefetchableBaseUpper32 != 0 || PciData.Bridge.PrefetchableLimitUpper32 != 0))) {\r
+ PciIoDevice->PciIo.Attributes(\r
+ &(PciIoDevice->PciIo),\r
+ EfiPciIoAttributeOperationEnable,\r
+ (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),\r
+ NULL\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS \r
+StartPciDevicesOnBridge (\r
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *RootBridge,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath \r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge\r
+\r
+Arguments:\r
+\r
+ Controller - An efi handle.\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+ RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
+ NumberOfChildren - Children number.\r
+ ChildHandleBuffer - A pointer to the child handle buffer.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_DEV_PATH_PTR Node;\r
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ CurrentLink = RootBridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (RemainingDevicePath != NULL) {\r
+\r
+ Node.DevPath = RemainingDevicePath;\r
+\r
+ if (Node.Pci->Device != Temp->DeviceNumber || \r
+ Node.Pci->Function != Temp->FunctionNumber) {\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check if the device has been assigned with required resource\r
+ //\r
+ if (!Temp->Allocated) {\r
+ return EFI_NOT_READY;\r
+ }\r
+ \r
+ //\r
+ // Check if the current node has been registered before\r
+ // If it is not, register it\r
+ //\r
+ if (!Temp->Registered) {\r
+ PciIoDevice = Temp;\r
+\r
+ Status = RegisterPciDevice (\r
+ Controller,\r
+ PciIoDevice,\r
+ NULL\r
+ );\r
+\r
+ }\r
+ \r
+ //\r
+ // Get the next device path\r
+ //\r
+ CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath);\r
+ if (EfiIsDevicePathEnd (CurrentDevicePath)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
+ //\r
+ // If it is a PPB\r
+ //\r
+ if (IS_PCI_BRIDGE (&(Temp->Pci))) {\r
+ Status = StartPciDevicesOnBridge (\r
+ Controller,\r
+ Temp,\r
+ CurrentDevicePath\r
+ );\r
+ EnableBridgeAttributes (Temp);\r
+\r
+ return Status;\r
+ } else {\r
+\r
+ //\r
+ // Currently, the PCI bus driver only support PCI-PCI bridge\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // If remaining device path is NULL,\r
+ // try to enable all the pci devices under this bridge\r
+ //\r
+\r
+ if (!Temp->Registered && Temp->Allocated) {\r
+\r
+ PciIoDevice = Temp;\r
+\r
+ Status = RegisterPciDevice (\r
+ Controller,\r
+ PciIoDevice,\r
+ NULL\r
+ );\r
+\r
+ }\r
+\r
+ if (IS_PCI_BRIDGE (&(Temp->Pci))) {\r
+ Status = StartPciDevicesOnBridge ( \r
+ Controller,\r
+ Temp,\r
+ RemainingDevicePath\r
+ );\r
+ EnableBridgeAttributes (Temp);\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+StartPciDevices (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start to manage the PCI device according to RemainingDevicePath\r
+ If RemainingDevicePath == NULL, the PCI bus driver will start \r
+ to manage all the PCI devices it found previously\r
+\r
+Arguments:\r
+ Controller - An efi handle.\r
+ RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_DEV_PATH_PTR Node;\r
+ PCI_IO_DEVICE *RootBridge;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ if (RemainingDevicePath != NULL) {\r
+\r
+ //\r
+ // Check if the RemainingDevicePath is valid\r
+ //\r
+ Node.DevPath = RemainingDevicePath;\r
+ if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||\r
+ Node.DevPath->SubType != HW_PCI_DP &&\r
+ DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)\r
+ ) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+\r
+ RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ //\r
+ // Locate the right root bridge to start\r
+ //\r
+ if (RootBridge->Handle == Controller) {\r
+ StartPciDevicesOnBridge (\r
+ Controller,\r
+ RootBridge,\r
+ RemainingDevicePath\r
+ );\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+CreateRootBridge (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+ RootBridgeHandle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *Dev;\r
+\r
+ Dev = NULL;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (PCI_IO_DEVICE),\r
+ (VOID **) &Dev\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ ZeroMem (Dev, sizeof (PCI_IO_DEVICE));\r
+ Dev->Signature = PCI_IO_DEVICE_SIGNATURE;\r
+ Dev->Handle = RootBridgeHandle;\r
+ InitializeListHead (&Dev->ChildList);\r
+\r
+ return Dev;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GetRootBridgeByHandle (\r
+ EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+\r
+ RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (RootBridgeDev->Handle == RootBridgeHandle) {\r
+ return RootBridgeDev;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+BOOLEAN\r
+RootBridgeExisted (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function searches if RootBridgeHandle has already existed\r
+ in current device pool.\r
+\r
+ If so, it means the given root bridge has been already enumerated.\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - An efi handle.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *Bridge;\r
+\r
+ Bridge = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (Bridge != NULL) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+PciDeviceExisted (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp == PciIoDevice) {\r
+ return TRUE;\r
+ }\r
+\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+ if (PciDeviceExisted (Temp, PciIoDevice)) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheSameSegment (\r
+ IN PCI_IO_DEVICE *VgaDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ VgaDevice - A pointer to the PCI_IO_DEVICE.\r
+ \r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ CurrentLink = gPciDevicePool.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &gPciDevicePool) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {\r
+\r
+ Temp = ActiveVGADeviceOnTheRootBridge (Temp);\r
+\r
+ if (Temp != NULL) {\r
+ return Temp;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ RootBridge - A pointer to the PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ CurrentLink = RootBridge->ChildList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &RootBridge->ChildList) {\r
+\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+\r
+ if (IS_PCI_VGA(&Temp->Pci) && \r
+ (Temp->Attributes &\r
+ (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY |\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO |\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) {\r
+ return Temp;\r
+ }\r
+\r
+ if (IS_PCI_BRIDGE (&Temp->Pci)) {\r
+\r
+ Temp = ActiveVGADeviceOnTheRootBridge (Temp);\r
+\r
+ if (Temp != NULL) {\r
+ return Temp;\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return NULL;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciDeviceSupport.h\r
+ \r
+Abstract:\r
+\r
+ \r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_DEVICE_SUPPORT_H\r
+#define _EFI_PCI_DEVICE_SUPPORT_H\r
+\r
+EFI_STATUS\r
+InitializePciDevicePool (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InsertPciDevice (\r
+ PCI_IO_DEVICE *Bridge,\r
+ PCI_IO_DEVICE *PciDeviceNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ PciDeviceNode - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestroyPciDeviceTree (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestroyRootBridgeByHandle (\r
+ EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ OUT EFI_HANDLE *Handle OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function registers the PCI IO device. It creates a handle for this PCI IO device \r
+ (if the handle does not exist), attaches appropriate protocols onto the handle, does\r
+ necessary initialization, and sets up parent/child relationship with its bus controller.\r
+\r
+Arguments:\r
+\r
+ Controller - An EFI handle for the PCI bus controller.\r
+ PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.\r
+ Handle - A pointer to hold the EFI handle for the PCI IO device.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The PCI device is successfully registered.\r
+ Others - An error occurred when registering the PCI device.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DeRegisterPciDevice (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+ Handle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartPciDevices (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+ RemainingDevicePath - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+CreateRootBridge (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+GetRootBridgeByHandle (\r
+ EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS \r
+InsertRootBridge (\r
+ PCI_IO_DEVICE *RootBridge\r
+);\r
+\r
+EFI_STATUS \r
+DestroyRootBridge ( \r
+ IN PCI_IO_DEVICE *RootBridge \r
+);\r
+\r
+BOOLEAN\r
+RootBridgeExisted (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridgeHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+PciDeviceExisted (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheSameSegment (\r
+ IN PCI_IO_DEVICE *VgaDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ VgaDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+PCI_IO_DEVICE *\r
+ActiveVGADeviceOnTheRootBridge (\r
+ IN PCI_IO_DEVICE *RootBridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ RootBridge - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2007, 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
+Module Name:\r
+\r
+ PciDriverOverride.c\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriver(\r
+ IN struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN OUT EFI_HANDLE *DriverImageHandle\r
+ );\r
+\r
+\r
+\r
+EFI_STATUS\r
+InitializePciDriverOverrideInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initializes a PCI Driver Override Instance\r
+\r
+Arguments:\r
+ \r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+\r
+{\r
+ PciIoDevice->PciDriverOverride.GetDriver = GetDriver;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriver (\r
+ IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN OUT EFI_HANDLE *DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get a overriding driver image\r
+\r
+Arguments:\r
+ \r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_DRIVER_OVERRIDE_LIST *Node;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);\r
+\r
+ CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;\r
+\r
+ while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {\r
+\r
+ Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);\r
+\r
+ if (*DriverImageHandle == NULL) {\r
+\r
+ *DriverImageHandle = Node->DriverImageHandle;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (*DriverImageHandle == Node->DriverImageHandle) {\r
+\r
+ if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||\r
+ CurrentLink->ForwardLink == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Get next node\r
+ //\r
+ Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);\r
+ *DriverImageHandle = Node->DriverImageHandle;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+EFI_STATUS\r
+AddDriver (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_HANDLE DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add a overriding driver image\r
+\r
+Arguments:\r
+ \r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_NT_HEADERS *PeHdr;\r
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+ PCI_DRIVER_OVERRIDE_LIST *Node;\r
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
+ EFI_DRIVER_OS_HANDOFF_HEADER *DriverOsHandoffHeader;\r
+ EFI_DRIVER_OS_HANDOFF_HEADER *NewDriverOsHandoffHeader;\r
+ EFI_DRIVER_OS_HANDOFF *DriverOsHandoff;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_HANDLE DeviceHandle;\r
+ UINTN NumberOfEntries;\r
+ UINTN Size;\r
+ UINTN Index;\r
+#endif\r
+\r
+ Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));\r
+ if (Node == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Node->Signature = DRIVER_OVERRIDE_SIGNATURE;\r
+ Node->DriverImageHandle = DriverImageHandle;\r
+\r
+ InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));\r
+\r
+ PciIoDevice->BusOverride = TRUE;\r
+\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase;\r
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew);\r
+\r
+ if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
+ DriverOsHandoffHeader = NULL;\r
+ Status = EfiLibGetSystemConfigurationTable (&gEfiUgaIoProtocolGuid, (VOID **) &DriverOsHandoffHeader);\r
+ if (!EFI_ERROR (Status) && DriverOsHandoffHeader != NULL) {\r
+ for (Index = 0; Index < DriverOsHandoffHeader->NumberOfEntries; Index++) {\r
+ DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)(DriverOsHandoffHeader) + \r
+ DriverOsHandoffHeader->HeaderSize + \r
+ Index * DriverOsHandoffHeader->SizeOfEntries);\r
+ DevicePath = DriverOsHandoff->DevicePath;\r
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);\r
+ if (!EFI_ERROR (Status) && DeviceHandle != NULL && IsDevicePathEnd (DevicePath)) {\r
+ if (DeviceHandle == PciIoDevice->Handle) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+\r
+ NumberOfEntries = DriverOsHandoffHeader->NumberOfEntries + 1;\r
+ } else {\r
+ NumberOfEntries = 1;\r
+ }\r
+\r
+ Status = gBS->AllocatePool (\r
+ EfiRuntimeServicesData,\r
+ sizeof (EFI_DRIVER_OS_HANDOFF_HEADER) + NumberOfEntries * sizeof (EFI_DRIVER_OS_HANDOFF),\r
+ (VOID **) &NewDriverOsHandoffHeader\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (DriverOsHandoffHeader == NULL) {\r
+ NewDriverOsHandoffHeader->Version = 0;\r
+ NewDriverOsHandoffHeader->HeaderSize = sizeof (EFI_DRIVER_OS_HANDOFF_HEADER);\r
+ NewDriverOsHandoffHeader->SizeOfEntries = sizeof (EFI_DRIVER_OS_HANDOFF);\r
+ NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;\r
+ } else {\r
+ gBS->CopyMem (\r
+ NewDriverOsHandoffHeader,\r
+ DriverOsHandoffHeader,\r
+ DriverOsHandoffHeader->HeaderSize + (NumberOfEntries - 1) * DriverOsHandoffHeader->SizeOfEntries\r
+ );\r
+ NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;\r
+ }\r
+\r
+ DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)NewDriverOsHandoffHeader + \r
+ NewDriverOsHandoffHeader->HeaderSize + \r
+ (NumberOfEntries - 1) * NewDriverOsHandoffHeader->SizeOfEntries);\r
+\r
+ //\r
+ // Fill in the EFI_DRIVER_OS_HANDOFF structure\r
+ //\r
+ DriverOsHandoff->Type = EfiUgaDriverFromPciRom;\r
+\r
+ //\r
+ // Compute the size of the device path\r
+ //\r
+ Size = EfiDevicePathSize (PciIoDevice->DevicePath);\r
+ if (Size == 0) {\r
+ DriverOsHandoff->DevicePath = NULL;\r
+ } else {\r
+\r
+ //\r
+ // Allocate space for duplicate device path\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiRuntimeServicesData,\r
+ Size,\r
+ (VOID **) &DriverOsHandoff->DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDriverOsHandoffHeader);\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Make copy of device path\r
+ //\r
+ CopyMem (DriverOsHandoff->DevicePath, PciIoDevice->DevicePath, Size);\r
+ }\r
+\r
+ DriverOsHandoff->PciRomSize = (UINT64) PciIoDevice->PciIo.RomSize;\r
+ Status = gBS->AllocatePool (\r
+ EfiRuntimeServicesData,\r
+ (UINTN) DriverOsHandoff->PciRomSize,\r
+ (VOID **) &DriverOsHandoff->PciRomImage\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDriverOsHandoffHeader);\r
+ return Status;\r
+ }\r
+\r
+ gBS->CopyMem (\r
+ DriverOsHandoff->PciRomImage,\r
+ PciIoDevice->PciIo.RomImage,\r
+ (UINTN) DriverOsHandoff->PciRomSize\r
+ );\r
+\r
+ Status = gBS->InstallConfigurationTable (&gEfiUgaIoProtocolGuid, NewDriverOsHandoffHeader);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (DriverOsHandoffHeader != NULL) {\r
+ gBS->FreePool (DriverOsHandoffHeader);\r
+ }\r
+#endif\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciDriverOverride.h\r
+ \r
+Abstract:\r
+\r
+ \r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H\r
+#define _EFI_PCI_DRIVER_OVERRRIDE_H\r
+\r
+#include "PciBus.h"\r
+\r
+#define DRIVER_OVERRIDE_SIGNATURE EFI_SIGNATURE_32 ('d', 'r', 'o', 'v')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+ EFI_HANDLE DriverImageHandle;\r
+} PCI_DRIVER_OVERRIDE_LIST;\r
+\r
+\r
+#define DRIVER_OVERRIDE_FROM_LINK(a) \\r
+ CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE)\r
+\r
+\r
+EFI_STATUS\r
+InitializePciDriverOverrideInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AddDriver (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_HANDLE DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+ DriverImageHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriver (\r
+ IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN OUT EFI_HANDLE *DriverImageHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ DriverImageHandle - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciEnumerator.c\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Pcibus.h"\r
+\r
+EFI_STATUS\r
+PciEnumerator (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to enumerate entire pci bus system \r
+ in a given platform\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ //\r
+ // This PCI bus driver depends on the legacy BIOS\r
+ // to do the resource allocation\r
+ //\r
+ gFullEnumeration = FALSE;\r
+\r
+ return PciEnumeratorLight (Controller) ;\r
+ \r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciEnumerator.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_ENUMERATOR_H\r
+#define _EFI_PCI_ENUMERATOR_H\r
+\r
+EFI_STATUS\r
+PciEnumerator (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+#endif
\ No newline at end of file
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2007, 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
+Module Name:\r
+\r
+ PciEnumeratorSupport.c\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Pcibus.h"\r
+\r
+EFI_STATUS \r
+InitializePPB (\r
+ IN PCI_IO_DEVICE *PciIoDevice \r
+);\r
+\r
+EFI_STATUS \r
+InitializeP2C (\r
+ IN PCI_IO_DEVICE *PciIoDevice \r
+);\r
+\r
+PCI_IO_DEVICE* \r
+CreatePciIoDevice (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+);\r
+\r
+\r
+PCI_IO_DEVICE*\r
+GatherP2CInfo (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+);\r
+\r
+UINTN\r
+PciParseBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ IN UINTN BarIndex\r
+);\r
+\r
+\r
+EFI_STATUS\r
+PciSearchDevice (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func,\r
+ PCI_IO_DEVICE **PciDevice\r
+);\r
+\r
+\r
+EFI_STATUS \r
+DetermineDeviceAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+);\r
+\r
+EFI_STATUS \r
+BarExisted (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
+ );\r
+\r
+\r
+\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+CreatePciDevicePath(\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN PCI_IO_DEVICE *PciIoDevice \r
+);\r
+\r
+PCI_IO_DEVICE* \r
+GatherDeviceInfo (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+);\r
+\r
+PCI_IO_DEVICE* \r
+GatherPPBInfo (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+);\r
+\r
+EFI_STATUS\r
+PciDevicePresent (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to check whether the pci device is present\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT64 Address;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Create PCI address map in terms of Bus, Device and Func\r
+ //\r
+ Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);\r
+\r
+ //\r
+ // Read the Vendor Id register\r
+ //\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ Pci\r
+ );\r
+\r
+ if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {\r
+\r
+ //\r
+ // Read the entire config header for the device\r
+ //\r
+\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ sizeof (PCI_TYPE00) / sizeof (UINT32),\r
+ Pci\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+PciPciDeviceInfoCollector (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ UINT8 StartBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT8 Func;\r
+ UINT8 SecBus;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ Status = EFI_SUCCESS;\r
+ SecBus = 0;\r
+\r
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+\r
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+ //\r
+ // Check to see whether PCI device is present\r
+ //\r
+\r
+ Status = PciDevicePresent (\r
+ Bridge->PciRootBridgeIo,\r
+ &Pci,\r
+ (UINT8) StartBusNumber,\r
+ (UINT8) Device,\r
+ (UINT8) Func\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ //\r
+ // Collect all the information about the PCI device discovered\r
+ //\r
+ Status = PciSearchDevice (\r
+ Bridge,\r
+ &Pci,\r
+ (UINT8) StartBusNumber,\r
+ Device,\r
+ Func,\r
+ &PciIoDevice\r
+ );\r
+\r
+ //\r
+ // Recursively scan PCI busses on the other side of PCI-PCI bridges\r
+ //\r
+ //\r
+\r
+ if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
+\r
+ //\r
+ // If it is PPB, we need to get the secondary bus to continue the enumeration\r
+ //\r
+ PciIo = &(PciIoDevice->PciIo);\r
+\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Deep enumerate the next level bus\r
+ //\r
+ Status = PciPciDeviceInfoCollector (\r
+ PciIoDevice,\r
+ (UINT8) (SecBus)\r
+ );\r
+\r
+ }\r
+\r
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciSearchDevice (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func,\r
+ OUT PCI_IO_DEVICE **PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Search required device.\r
+\r
+Arguments:\r
+\r
+ Bridge - A pointer to the PCI_IO_DEVICE.\r
+ Pci - A pointer to the PCI_TYPE00.\r
+ Bus - Bus number.\r
+ Device - Device number.\r
+ Func - Function number.\r
+ PciDevice - The Required pci device.\r
+\r
+Returns:\r
+\r
+ Status code.\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = NULL;\r
+\r
+ if (!IS_PCI_BRIDGE (Pci)) {\r
+\r
+ if (IS_CARDBUS_BRIDGE (Pci)) {\r
+ PciIoDevice = GatherP2CInfo (\r
+ Bridge->PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+ if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {\r
+ InitializeP2C (PciIoDevice);\r
+ }\r
+ } else {\r
+\r
+ //\r
+ // Create private data for Pci Device\r
+ //\r
+ PciIoDevice = GatherDeviceInfo (\r
+ Bridge->PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // Create private data for PPB\r
+ //\r
+ PciIoDevice = GatherPPBInfo (\r
+ Bridge->PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ //\r
+ // Special initialization for PPB including making the PPB quiet\r
+ //\r
+ if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {\r
+ InitializePPB (PciIoDevice);\r
+ }\r
+ }\r
+\r
+ if (!PciIoDevice) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ //\r
+ // Create a device path for this PCI device and store it into its private data\r
+ //\r
+ CreatePciDevicePath(\r
+ Bridge->DevicePath,\r
+ PciIoDevice \r
+ );\r
+ \r
+ //\r
+ // Detect this function has option rom\r
+ //\r
+ if (gFullEnumeration) {\r
+\r
+ if (!IS_CARDBUS_BRIDGE (Pci)) {\r
+\r
+ GetOpRomInfo (PciIoDevice);\r
+\r
+ }\r
+\r
+ ResetPowerManagementFeature (PciIoDevice);\r
+ \r
+ } \r
+ else {\r
+ PciRomGetRomResourceFromPciOptionRomTable (\r
+ &gPciBusDriverBinding,\r
+ PciIoDevice->PciRootBridgeIo,\r
+ PciIoDevice\r
+ );\r
+ }\r
+\r
+ \r
+ //\r
+ // Insert it into a global tree for future reference\r
+ //\r
+ InsertPciDevice (Bridge, PciIoDevice);\r
+\r
+ //\r
+ // Determine PCI device attributes\r
+ //\r
+ DetermineDeviceAttribute (PciIoDevice);\r
+\r
+ if (PciDevice != NULL) {\r
+ *PciDevice = PciIoDevice;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GatherDeviceInfo (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINTN Offset;\r
+ UINTN BarIndex;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = CreatePciIoDevice (\r
+ PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!PciIoDevice) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // If it is a full enumeration, disconnect the device in advance\r
+ //\r
+ if (gFullEnumeration) {\r
+\r
+ PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
+\r
+ }\r
+\r
+ //\r
+ // Start to parse the bars\r
+ //\r
+ for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {\r
+ Offset = PciParseBar (PciIoDevice, Offset, BarIndex);\r
+ }\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GatherPPBInfo (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_STATUS Status;\r
+ UINT32 Value;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 Temp;\r
+\r
+ PciIoDevice = CreatePciIoDevice (\r
+ PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!PciIoDevice) {\r
+ return NULL;\r
+ }\r
+ \r
+ if (gFullEnumeration) {\r
+ PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
+\r
+ //\r
+ // Initalize the bridge control register\r
+ //\r
+ PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
+ }\r
+\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ //\r
+ // Test whether it support 32 decode or not\r
+ //\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
+\r
+ if (Value) {\r
+ if (Value & 0x01) {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
+ } else {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
+ }\r
+ }\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ 0x24,\r
+ NULL,\r
+ NULL\r
+ );\r
+\r
+ //\r
+ // test if it supports 64 memory or not\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ 0x28,\r
+ NULL,\r
+ NULL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
+ } else {\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Memory 32 code is required for ppb\r
+ //\r
+ PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+GatherP2CInfo (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ \r
+ PciIoDevice = CreatePciIoDevice (\r
+ PciRootBridgeIo,\r
+ Pci,\r
+ Bus,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!PciIoDevice) {\r
+ return NULL;\r
+ }\r
+\r
+ if (gFullEnumeration) {\r
+ PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
+\r
+ //\r
+ // Initalize the bridge control register\r
+ //\r
+ PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
+\r
+ }\r
+ //\r
+ // P2C only has one bar that is in 0x10\r
+ //\r
+ PciParseBar(PciIoDevice, 0x10, 0);\r
+ \r
+ PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED |\r
+ EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
+ EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+CreatePciDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ PCI_DEVICE_PATH PciNode;\r
+\r
+ //\r
+ // Create PCI device path\r
+ //\r
+ PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
+ PciNode.Header.SubType = HW_PCI_DP;\r
+ SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
+\r
+ PciNode.Device = PciIoDevice->DeviceNumber;\r
+ PciNode.Function = PciIoDevice->FunctionNumber;\r
+ PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);\r
+\r
+ return PciIoDevice->DevicePath;\r
+}\r
+\r
+EFI_STATUS\r
+BarExisted (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check the bar is existed or not.\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
+ Offset - The offset.\r
+ BarLengthValue - The bar length value.\r
+ OriginalBarValue - The original bar value.\r
+\r
+Returns:\r
+\r
+ EFI_NOT_FOUND - The bar don't exist.\r
+ EFI_SUCCESS - The bar exist.\r
+\r
+--*/\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT32 OriginalValue;\r
+ UINT32 Value;\r
+ EFI_TPL OldTpl;\r
+\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ //\r
+ // Preserve the original value\r
+ //\r
+\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+\r
+ //\r
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
+\r
+ //\r
+ // Write back the original value\r
+ //\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+\r
+ //\r
+ // Restore TPL to its original level\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ if (BarLengthValue != NULL) {\r
+ *BarLengthValue = Value;\r
+ }\r
+\r
+ if (OriginalBarValue != NULL) {\r
+ *OriginalBarValue = OriginalValue;\r
+ }\r
+\r
+ if (Value == 0) {\r
+ return EFI_NOT_FOUND;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+DetermineDeviceAttribute (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Determine the related attributes of all devices under a Root Bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT16 Command;\r
+ UINT16 BridgeControl;\r
+\r
+ Command = 0;\r
+\r
+ PciIoDevice->Supports |= EFI_PCI_DEVICE_ENABLE;\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
+\r
+ if (IS_PCI_VGA (&(PciIoDevice->Pci))){\r
+\r
+ //\r
+ // If the device is VGA, VGA related Attributes are supported\r
+ //\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO ;\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY ;\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_IO ;\r
+ }\r
+\r
+ if(IS_ISA_BRIDGE(&(PciIoDevice->Pci)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice->Pci))) {\r
+ //\r
+ // If the devie is a ISA Bridge, set the two attributes\r
+ //\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
+ }\r
+\r
+ if (IS_PCI_GFX (&(PciIoDevice->Pci))) {\r
+\r
+ //\r
+ // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO\r
+ // attribute\r
+ //\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO ;\r
+ }\r
+\r
+\r
+ //\r
+ // If the device is IDE, IDE related attributes are supported\r
+ //\r
+ if (IS_PCI_IDE (&(PciIoDevice->Pci))) {\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO ;\r
+ PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO ;\r
+ }\r
+\r
+ PciReadCommandRegister(PciIoDevice, &Command);\r
+\r
+ \r
+ if (Command & EFI_PCI_COMMAND_IO_SPACE) {\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;\r
+ }\r
+\r
+ if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;\r
+ }\r
+\r
+ if (Command & EFI_PCI_COMMAND_BUS_MASTER) {\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;\r
+ }\r
+\r
+ if (IS_PCI_BRIDGE (&(PciIoDevice->Pci)) || \r
+ IS_CARDBUS_BRIDGE (&(PciIoDevice->Pci))){\r
+\r
+ //\r
+ // If it is a PPB, read the Bridge Control Register to determine\r
+ // the relevant attributes\r
+ //\r
+ BridgeControl = 0;\r
+ PciReadBridgeControlRegister(PciIoDevice, &BridgeControl);\r
+\r
+ //\r
+ // Determine whether the ISA bit is set\r
+ // If ISA Enable on Bridge is set, the PPB\r
+ // will block forwarding 0x100-0x3ff for each 1KB in the \r
+ // first 64KB I/O range.\r
+ //\r
+ if (!BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) {\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
+ } \r
+\r
+ //\r
+ // Determine whether the VGA bit is set\r
+ // If it is set, the bridge is set to decode VGA memory range\r
+ // and palette register range\r
+ //\r
+ if (IS_PCI_VGA (&(PciIoDevice->Pci)) &&BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
+ }\r
+\r
+ //\r
+ // if the palette snoop bit is set, then the brige is set to \r
+ // decode palette IO write\r
+ //\r
+ if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
+ PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
+ }\r
+ } \r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+UINTN\r
+PciParseBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ IN UINTN BarIndex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT32 Value;\r
+ UINT64 BarValue64;\r
+ UINT32 OriginalValue;\r
+ UINT32 Mask;\r
+ UINT32 Data;\r
+ UINT8 Index;\r
+ EFI_STATUS Status;\r
+\r
+ OriginalValue = 0;\r
+ Value = 0;\r
+ BarValue64 = 0;\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
+ PciIoDevice->PciBar[BarIndex].Length = 0;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
+\r
+ //\r
+ // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+ return Offset + 4;\r
+ }\r
+\r
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+ if (Value & 0x01) {\r
+ //\r
+ // Device I/Os\r
+ //\r
+ Mask = 0xfffffffc;\r
+\r
+ if (Value & 0xFFFF0000) {\r
+ //\r
+ // It is a IO32 bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;\r
+ PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ } else {\r
+ //\r
+ // It is a IO16 bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;\r
+ PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ }\r
+ //\r
+ // Workaround. Some platforms inplement IO bar with 0 length\r
+ // Need to treat it as no-bar\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = 0;\r
+ }\r
+\r
+ PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
+\r
+ } else {\r
+\r
+ Mask = 0xfffffff0;\r
+\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
+\r
+ switch (Value & 0x07) {\r
+\r
+ //\r
+ //memory space; anywhere in 32 bit address space\r
+ //\r
+ case 0x00:\r
+ if (Value & 0x08) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
+ }\r
+\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ break;\r
+\r
+ //\r
+ // memory space; anywhere in 64 bit address space\r
+ //\r
+ case 0x04:\r
+ if (Value & 0x08) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
+ }\r
+\r
+ //\r
+ // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+ // is regarded as an extension for the first bar. As a result\r
+ // the sizing will be conducted on combined 64 bit value\r
+ // Here just store the masked first 32bit value for future size\r
+ // calculation\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ //\r
+ // Increment the offset to point to next DWORD\r
+ //\r
+ Offset += 4;\r
+\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Offset + 4;\r
+ }\r
+\r
+ //\r
+ // Fix the length to support some spefic 64 bit BAR\r
+ //\r
+ Data = Value;\r
+ Index = 0;\r
+ for (Data = Value; Data != 0; Data >>= 1) {\r
+ Index ++;\r
+ }\r
+ Value |= ((UINT32)(-1) << Index); \r
+\r
+ //\r
+ // Calculate the size of 64bit bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
+\r
+ PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ break;\r
+\r
+ //\r
+ // reserved\r
+ //\r
+ default:\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+\r
+ break;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Check the length again so as to keep compatible with some special bars\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
+ }\r
+ \r
+ //\r
+ // Increment number of bar\r
+ //\r
+ return Offset + 4;\r
+}\r
+\r
+EFI_STATUS\r
+InitializePPB (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ PciIo = &(PciIoDevice->PciIo);\r
+\r
+ //\r
+ // Put all the resource apertures including IO16\r
+ // Io32, pMem32, pMem64 to quiescent state\r
+ // Resource base all ones, Resource limit all zeros\r
+ //\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);\r
+\r
+ //\r
+ // don't support use io32 as for now\r
+ //\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InitializeP2C (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ PciIo = &(PciIoDevice->PciIo);\r
+\r
+ //\r
+ // Put all the resource apertures including IO16\r
+ // Io32, pMem32, pMem64 to quiescent state(\r
+ // Resource base all ones, Resource limit all zeros\r
+ //\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+PCI_IO_DEVICE *\r
+CreatePciIoDevice (\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = NULL;\r
+\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (PCI_IO_DEVICE),\r
+ (VOID **) &PciIoDevice\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));\r
+\r
+ PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
+ PciIoDevice->Handle = NULL;\r
+ PciIoDevice->PciRootBridgeIo = PciRootBridgeIo;\r
+ PciIoDevice->DevicePath = NULL;\r
+ PciIoDevice->BusNumber = Bus;\r
+ PciIoDevice->DeviceNumber = Device;\r
+ PciIoDevice->FunctionNumber = Func;\r
+ PciIoDevice->Decodes = 0;\r
+ if (gFullEnumeration) {\r
+ PciIoDevice->Allocated = FALSE;\r
+ } else {\r
+ PciIoDevice->Allocated = TRUE;\r
+ }\r
+\r
+ PciIoDevice->Attributes = 0;\r
+ PciIoDevice->Supports = 0;\r
+ PciIoDevice->BusOverride = FALSE;\r
+ PciIoDevice->IsPciExp = FALSE;\r
+\r
+ CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));\r
+\r
+ //\r
+ // Initialize the PCI I/O instance structure\r
+ //\r
+\r
+ Status = InitializePciIoInstance (PciIoDevice);\r
+ Status = InitializePciDriverOverrideInstance (PciIoDevice);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (PciIoDevice);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Initialize the reserved resource list\r
+ //\r
+ InitializeListHead (&PciIoDevice->ReservedResourceList);\r
+\r
+ //\r
+ // Initialize the driver list\r
+ //\r
+ InitializeListHead (&PciIoDevice->OptionRomDriverList);\r
+\r
+ //\r
+ // Initialize the child list\r
+ //\r
+ InitializeListHead (&PciIoDevice->ChildList);\r
+\r
+ return PciIoDevice;\r
+}\r
+\r
+EFI_STATUS\r
+PciEnumeratorLight (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to enumerate entire pci bus system \r
+ in a given platform\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ UINT16 MinBus;\r
+ UINT16 MaxBus;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+\r
+ MinBus = 0;\r
+ MaxBus = PCI_MAX_BUS;\r
+ Descriptors = NULL;\r
+\r
+ //\r
+ // If this host bridge has been already enumerated, then return successfully\r
+ //\r
+ if (RootBridgeExisted (Controller)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller , \r
+ &gEfiDevicePathProtocolGuid, \r
+ (VOID **)&ParentDevicePath,\r
+ gPciBusDriverBinding.DriverBindingHandle, \r
+ Controller, \r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Open pci root bridge io protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge \r
+ //\r
+ Status = PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding, PciRootBridgeIo);\r
+\r
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ while (PciGetBusRange (Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Create a device node for root bridge device with a NULL host bridge controller handle\r
+ //\r
+ RootBridgeDev = CreateRootBridge (Controller);\r
+\r
+ //\r
+ // Record the root bridge device path\r
+ //\r
+ RootBridgeDev->DevicePath = ParentDevicePath;\r
+\r
+ //\r
+ // Record the root bridge io protocol\r
+ //\r
+ RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
+\r
+ Status = PciPciDeviceInfoCollector (\r
+ RootBridgeDev,\r
+ (UINT8) MinBus\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ //\r
+ // If successfully, insert the node into device pool\r
+ //\r
+ InsertRootBridge (RootBridgeDev);\r
+ } else {\r
+\r
+ //\r
+ // If unsuccessly, destroy the entire node\r
+ //\r
+ DestroyRootBridge (RootBridgeDev);\r
+ }\r
+\r
+ Descriptors++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciGetBusRange (\r
+ IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors,\r
+ OUT UINT16 *MinBus,\r
+ OUT UINT16 *MaxBus,\r
+ OUT UINT16 *BusRange\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the bus range.\r
+\r
+Arguments:\r
+\r
+ Descriptors - A pointer to the address space descriptor.\r
+ MinBus - The min bus.\r
+ MaxBus - The max bus.\r
+ BusRange - The bus range.\r
+ \r
+Returns:\r
+ \r
+ Status Code.\r
+\r
+--*/\r
+{\r
+\r
+ while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
+ if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
+ if (MinBus != NULL) {\r
+ *MinBus = (UINT16)Descriptors->AddrRangeMin;\r
+ }\r
+\r
+ if (MaxBus != NULL) {\r
+ *MaxBus = (UINT16)Descriptors->AddrRangeMax;\r
+ }\r
+\r
+ if (BusRange != NULL) {\r
+ *BusRange = (UINT16)Descriptors->AddrLen;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Descriptors ++;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciEnumeratorSupport.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H\r
+#define _EFI_PCI_ENUMERATOR_SUPPORT_H\r
+\r
+#include "PciBus.h"\r
+\r
+EFI_STATUS\r
+PciPciDeviceInfoCollector (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ UINT8 StartBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Bridge - TODO: add argument description\r
+ StartBusNumber - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciDevicePresent(\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_TYPE00 *Pci,\r
+ UINT8 Bus,\r
+ UINT8 Device,\r
+ UINT8 Func\r
+);\r
+\r
+EFI_STATUS\r
+PciEnumeratorLight (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Controller - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PciGetBusRange (\r
+ IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors,\r
+ OUT UINT16 *MinBus,\r
+ OUT UINT16 *MaxBus,\r
+ OUT UINT16 *BusRange\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Descriptors - TODO: add argument description\r
+ MinBus - TODO: add argument description\r
+ MaxBus - TODO: add argument description\r
+ BusRange - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2007, 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
+Module Name:\r
+\r
+ PciIo.c\r
+ \r
+Abstract:\r
+\r
+ PCI I/O Abstraction Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Pcibus.h"\r
+\r
+//\r
+// PCI I/O Support Function Prototypes\r
+//\r
+//\r
+\r
+BOOLEAN \r
+PciDevicesOnTheSamePath (\r
+ IN PCI_IO_DEVICE *PciDevice1,\r
+ IN PCI_IO_DEVICE *PciDevice2\r
+);\r
+\r
+\r
+EFI_STATUS \r
+UpStreamBridgesAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes\r
+);\r
+\r
+\r
+BOOLEAN \r
+CheckBarType ( \r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE BarType\r
+);\r
+\r
+\r
+EFI_STATUS \r
+SetBootVGA ( \r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+);\r
+\r
+EFI_STATUS \r
+DisableBootVGA ( \r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+);\r
+\r
+\r
+EFI_STATUS\r
+PciIoVerifyBarAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE Type,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ UINT64 *Offset\r
+);\r
+\r
+EFI_STATUS\r
+PciIoVerifyConfigAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ IN UINT64 *Offset\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+);\r
+ \r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollIo (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+); \r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoCopyMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 DestBarIndex,\r
+ IN UINT64 DestOffset,\r
+ IN UINT8 SrcBarIndex,\r
+ IN UINT64 SrcOffset,\r
+ IN UINTN Count\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
+ IN VOID *HostAddress,\r
+ IN OUT UINTN *NumberOfBytes,\r
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
+ OUT VOID **Mapping\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoUnmap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN VOID *Mapping\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAllocateBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_ALLOCATE_TYPE Type,\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN UINTN Pages,\r
+ OUT VOID **HostAddress,\r
+ IN UINT64 Attributes\r
+);\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFreeBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINTN Pages,\r
+ IN VOID *HostAddress\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFlush (\r
+ IN EFI_PCI_IO_PROTOCOL *This\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetLocation (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ OUT UINTN *Segment,\r
+ OUT UINTN *Bus,\r
+ OUT UINTN *Device,\r
+ OUT UINTN *Function\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes,\r
+ OUT UINT64 *Result OPTIONAL\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetBarAttributes(\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINT8 BarIndex,\r
+ OUT UINT64 *Supports, OPTIONAL\r
+ OUT VOID **Resources OPTIONAL\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoSetBarAttributes(\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINT64 Attributes,\r
+ IN UINT8 BarIndex,\r
+ IN OUT UINT64 *Offset,\r
+ IN OUT UINT64 *Length\r
+ );\r
+\r
+\r
+//\r
+// Pci Io Protocol Interface\r
+//\r
+static EFI_PCI_IO_PROTOCOL PciIoInterface = {\r
+ PciIoPollMem,\r
+ PciIoPollIo,\r
+ {\r
+ PciIoMemRead,\r
+ PciIoMemWrite\r
+ },\r
+ {\r
+ PciIoIoRead,\r
+ PciIoIoWrite\r
+ },\r
+ {\r
+ PciIoConfigRead,\r
+ PciIoConfigWrite\r
+ },\r
+ PciIoCopyMem,\r
+ PciIoMap,\r
+ PciIoUnmap,\r
+ PciIoAllocateBuffer,\r
+ PciIoFreeBuffer,\r
+ PciIoFlush,\r
+ PciIoGetLocation,\r
+ PciIoAttributes,\r
+ PciIoGetBarAttributes,\r
+ PciIoSetBarAttributes,\r
+ 0,\r
+ NULL\r
+};\r
+\r
+\r
+EFI_STATUS\r
+InitializePciIoInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initializes a PCI I/O Instance\r
+\r
+Arguments:\r
+ \r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+\r
+{\r
+ CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciIoVerifyBarAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE Type,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ UINT64 *Offset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Verifies access to a PCI Base Address Register (BAR)\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // BarIndex 0-5 is legal\r
+ //\r
+ if (BarIndex >= PCI_MAX_BAR) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!CheckBarType (PciIoDevice, BarIndex, Type)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX\r
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
+ //\r
+ if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
+ Count = 1;\r
+ }\r
+\r
+ Width &= 0x03;\r
+\r
+ if ((*Offset + Count * ((UINTN)1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciIoVerifyConfigAccess (\r
+ PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINTN Count,\r
+ IN UINT64 *Offset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Verifies access to a PCI Config Header\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT64 ExtendOffset;\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX\r
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
+ //\r
+ Width &= 0x03;\r
+\r
+ if (PciIoDevice->IsPciExp) {\r
+ if ((*Offset + Count * ((UINTN)1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ ExtendOffset = LShiftU64 (*Offset, 32);\r
+ *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
+ *Offset = (*Offset) | ExtendOffset;\r
+\r
+ } else {\r
+ if ((*Offset + Count * ((UINTN)1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Poll PCI Memmory\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (Width > EfiPciIoWidthUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Mask,\r
+ Value,\r
+ Delay,\r
+ Result\r
+ );\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollIo (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINT64 Mask,\r
+ IN UINT64 Value,\r
+ IN UINT64 Delay,\r
+ OUT UINT64 *Result\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Poll PCI IO\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width > EfiPciIoWidthUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Mask,\r
+ Value,\r
+ Delay,\r
+ Result\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Memory Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ if (Buffer == NULL){\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Memory Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ if (Buffer == NULL){\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Mem.Write (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI I/O Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ if (Buffer == NULL){\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 BarIndex,\r
+ IN UINT64 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI I/O Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ if (Buffer == NULL){\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Offset,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigRead (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Configuration Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ UINT64 Address;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Address = Offset;\r
+ Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigWrite (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT32 Offset,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs a PCI Configuration Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ UINT64 Address;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Address = Offset;\r
+ Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ Address,\r
+ Count,\r
+ Buffer\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoCopyMem (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT8 DestBarIndex,\r
+ IN UINT64 DestOffset,\r
+ IN UINT8 SrcBarIndex,\r
+ IN UINT64 SrcOffset,\r
+ IN UINTN Count\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Copy PCI Memory\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Width == EfiPciIoWidthFifoUint8 ||\r
+ Width == EfiPciIoWidthFifoUint16 ||\r
+ Width == EfiPciIoWidthFifoUint32 ||\r
+ Width == EfiPciIoWidthFifoUint64 ||\r
+ Width == EfiPciIoWidthFillUint8 ||\r
+ Width == EfiPciIoWidthFillUint16 ||\r
+ Width == EfiPciIoWidthFillUint32 ||\r
+ Width == EfiPciIoWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+ DestOffset,\r
+ SrcOffset,\r
+ Count\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
+ IN VOID *HostAddress,\r
+ IN OUT UINTN *NumberOfBytes,\r
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
+ OUT VOID **Mapping\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Maps a memory region for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
+ Operation = Operation + EfiPciOperationBusMasterRead64;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Map (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
+ HostAddress,\r
+ NumberOfBytes,\r
+ DeviceAddress,\r
+ Mapping\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoUnmap (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN VOID *Mapping\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unmaps a memory region for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->Unmap (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ Mapping\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAllocateBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN EFI_ALLOCATE_TYPE Type,\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN UINTN Pages,\r
+ OUT VOID **HostAddress,\r
+ IN UINT64 Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Allocates a common buffer for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ if (Attributes &\r
+ (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
+ Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
+ }\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ Type,\r
+ MemoryType,\r
+ Pages,\r
+ HostAddress,\r
+ Attributes\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFreeBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINTN Pages,\r
+ IN VOID *HostAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Frees a common buffer \r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ \r
+ if( HostAddress == NULL ){\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ Pages,\r
+ HostAddress\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFlush (\r
+ IN EFI_PCI_IO_PROTOCOL *This\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Flushes a DMA buffer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 Register;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ //\r
+ // If the device is behind a PCI-PCI Bridge, then perform a read cycles to the device to \r
+ // flush the posted write cycles through the PCI-PCI bridges\r
+ //\r
+ if (PciIoDevice->Parent != NULL) {\r
+ Status = This->Pci.Read (This, EfiPciIoWidthUint32, 0, 1, &Register);\r
+ }\r
+\r
+ //\r
+ // Call the PCI Root Bridge I/O Protocol to flush the posted write cycles through the chipset\r
+ //\r
+ Status = PciIoDevice->PciRootBridgeIo->Flush (\r
+ PciIoDevice->PciRootBridgeIo\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetLocation (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ OUT UINTN *Segment,\r
+ OUT UINTN *Bus,\r
+ OUT UINTN *Device,\r
+ OUT UINTN *Function\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Gets a PCI device's current bus number, device number, and function number.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber;\r
+ *Bus = PciIoDevice->BusNumber;\r
+ *Device = PciIoDevice->DeviceNumber;\r
+ *Function = PciIoDevice->FunctionNumber;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+CheckBarType (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ UINT8 BarIndex,\r
+ PCI_BAR_TYPE BarType\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Sets a PCI controllers attributes on a resource range\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ switch (BarType) {\r
+\r
+ case PciBarTypeMem:\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+\r
+ case PciBarTypeIo:\r
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&\r
+ PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL * This,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes,\r
+ OUT UINT64 *Result OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ PCI_IO_DEVICE *Temp;\r
+ UINT64 NewAttributes;\r
+ UINT64 PciRootBridgeSupports;\r
+ UINT64 PciRootBridgeAttributes;\r
+ UINT64 NewPciRootBridgeAttributes;\r
+ UINT64 NewUpStreamBridgeAttributes;\r
+ UINT64 ModifiedPciRootBridgeAttributes;\r
+ UINT16 EnableCommand;\r
+ UINT16 DisableCommand;\r
+ UINT16 EnableBridge;\r
+ UINT16 DisableBridge;\r
+ UINT16 Command;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+ NewUpStreamBridgeAttributes = 0;\r
+\r
+ EnableCommand = 0;\r
+ DisableCommand = 0;\r
+ EnableBridge = 0;\r
+ DisableBridge = 0;\r
+\r
+ switch (Operation) {\r
+ case EfiPciIoAttributeOperationGet:\r
+ if (Result == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Result = PciIoDevice->Attributes;\r
+ return EFI_SUCCESS;\r
+\r
+ case EfiPciIoAttributeOperationSupported:\r
+ if (Result == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Result = PciIoDevice->Supports;\r
+ return EFI_SUCCESS;\r
+\r
+ case EfiPciIoAttributeOperationEnable:\r
+ if(Attributes & ~(PciIoDevice->Supports)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ NewAttributes = PciIoDevice->Attributes | Attributes;\r
+ break;\r
+ case EfiPciIoAttributeOperationDisable:\r
+ if(Attributes & ~(PciIoDevice->Supports)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ NewAttributes = PciIoDevice->Attributes & (~Attributes);\r
+ break;\r
+ case EfiPciIoAttributeOperationSet:\r
+ if(Attributes & ~(PciIoDevice->Supports)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ NewAttributes = Attributes;\r
+ break;\r
+ default:\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // If VGA_IO is set, then set VGA_MEMORY too. This driver can not enable them seperately.\r
+ //\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {\r
+ NewAttributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
+ }\r
+\r
+ //\r
+ // If VGA_MEMORY is set, then set VGA_IO too. This driver can not enable them seperately.\r
+ //\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY) {\r
+ NewAttributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
+ }\r
+\r
+ //\r
+ // If the attributes are already set correctly, then just return EFI_SUCCESS;\r
+ //\r
+ if ((NewAttributes ^ PciIoDevice->Attributes) == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // This driver takes care of EFI_PCI_IO_ATTRIBUTE_IO, EFI_PCI_IO_ATTRIBUTE_MEMORY, and\r
+ // EFI_PCI_IO_ATTRIBUTE_BUS_MASTER. Strip these 3 bits off the new attribute mask so\r
+ // a call to the PCI Root Bridge I/O Protocol can be made\r
+ //\r
+\r
+ if (!IS_PCI_BRIDGE(&PciIoDevice->Pci)) {\r
+ NewPciRootBridgeAttributes = NewAttributes & (~(EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE));\r
+\r
+ // \r
+ // Get the current attributes of this PCI device's PCI Root Bridge\r
+ //\r
+ Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ &PciRootBridgeSupports,\r
+ &PciRootBridgeAttributes\r
+ );\r
+\r
+ //\r
+ // Check to see if any of the PCI Root Bridge attributes are being modified\r
+ //\r
+ ModifiedPciRootBridgeAttributes = NewPciRootBridgeAttributes ^ PciRootBridgeAttributes;\r
+ if (ModifiedPciRootBridgeAttributes) {\r
+\r
+ //\r
+ // Check to see if the PCI Root Bridge supports modifiying the attributes that are changing\r
+ //\r
+ if ((ModifiedPciRootBridgeAttributes & PciRootBridgeSupports) != ModifiedPciRootBridgeAttributes) {\r
+ // return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Call the PCI Root Bridge to attempt to modify the attributes\r
+ //\r
+ Status = PciIoDevice->PciRootBridgeIo->SetAttributes (\r
+ PciIoDevice->PciRootBridgeIo,\r
+ NewPciRootBridgeAttributes,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // The PCI Root Bridge could not modify the attributes, so return the error.\r
+ //\r
+ return Status;\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ if (IS_PCI_BRIDGE(&PciIoDevice->Pci)) {\r
+\r
+\r
+ //\r
+ // Check to see if an VGA related attributes are being set.\r
+ //\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO)) {\r
+\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {\r
+ EnableBridge |= EFI_PCI_BRIDGE_CONTROL_VGA;\r
+ } else {\r
+ DisableBridge |= EFI_PCI_BRIDGE_CONTROL_VGA;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check to see if an VGA related attributes are being set.\r
+ // If ISA Enable on the PPB is set, the PPB will block the\r
+ // 0x100-0x3FF for each 1KB block in the first 64K I/O block\r
+ //\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO)) {\r
+\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {\r
+ DisableBridge |= EFI_PCI_BRIDGE_CONTROL_ISA;\r
+ } else {\r
+ EnableBridge |= EFI_PCI_BRIDGE_CONTROL_ISA;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check to see if an VGA related attributes are being set.\r
+ //\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) {\r
+\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {\r
+ EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ } else {\r
+ DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ }\r
+ }\r
+\r
+ } else {\r
+\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO)) {\r
+\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {\r
+\r
+ //\r
+ //Check if there have been an active VGA device on the same segment\r
+ //\r
+ Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+\r
+ if (Temp && Temp != PciIoDevice) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ }\r
+\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) {\r
+ if (IS_PCI_GFX(&PciIoDevice->Pci)) {\r
+\r
+ //\r
+ //Get the boot VGA on the same segement\r
+ //\r
+ Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+\r
+ if (!Temp) {\r
+\r
+ //\r
+ // If there is no VGA device on the segement, set\r
+ // this graphics card to decode the palette range\r
+ //\r
+ DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ } else {\r
+\r
+ //\r
+ // Check these two agents are on the same path\r
+ //\r
+ if (PciDevicesOnTheSamePath(Temp, PciIoDevice)) {\r
+\r
+ //\r
+ // Check if they are on the same bus\r
+ //\r
+ if (Temp->Parent == PciIoDevice->Parent) {\r
+\r
+ PciReadCommandRegister (Temp, &Command);\r
+\r
+ //\r
+ // If they are on the same bus, either one can\r
+ // be set to snoop, the other set to decode\r
+ //\r
+ if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
+ DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ } else {\r
+ EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ }\r
+ } else {\r
+\r
+ //\r
+ // If they are on the same path but on the different bus\r
+ // The first agent is set to snoop, the second one set to\r
+ // decode\r
+ //\r
+ if (Temp->BusNumber > PciIoDevice->BusNumber) {\r
+ PciEnableCommandRegister(Temp,EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+ DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ } else {\r
+ PciDisableCommandRegister(Temp,EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+ EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ }\r
+ }\r
+ } else {\r
+\r
+ EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check to see of the I/O enable is being modified\r
+ //\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_IO)) {\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
+ EnableCommand |= EFI_PCI_COMMAND_IO_SPACE;\r
+ } else {\r
+ DisableCommand |= EFI_PCI_COMMAND_IO_SPACE;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check to see of the Memory enable is being modified\r
+ //\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY)) {\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {\r
+ EnableCommand |= EFI_PCI_COMMAND_MEMORY_SPACE;\r
+ } else {\r
+ DisableCommand |= EFI_PCI_COMMAND_MEMORY_SPACE;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check to see of the Bus Master enable is being modified\r
+ //\r
+ if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER)) {\r
+ if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {\r
+ EnableCommand |= EFI_PCI_COMMAND_BUS_MASTER;\r
+ } else {\r
+ DisableCommand |= EFI_PCI_COMMAND_BUS_MASTER;\r
+ }\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ if (EnableCommand) {\r
+ Status = PciEnableCommandRegister(PciIoDevice, EnableCommand);\r
+ } \r
+\r
+ if (DisableCommand) {\r
+ Status = PciDisableCommandRegister(PciIoDevice, DisableCommand);\r
+ }\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (EnableBridge) {\r
+ Status = PciEnableBridgeControlRegister(PciIoDevice, EnableBridge);\r
+ }\r
+\r
+ if (DisableBridge) {\r
+ Status = PciDisableBridgeControlRegister(PciIoDevice, DisableBridge);\r
+ }\r
+ \r
+ if (EFI_ERROR(Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Set the upstream bridge attributes\r
+ //\r
+ if (Operation != EfiPciIoAttributeOperationGet && Operation != EfiPciIoAttributeOperationSupported) {\r
+\r
+ //\r
+ // EFI_PCI_IO_ATTRIBUTE_MEMORY, EFI_PCI_IO_ATTRIBUTE_IO, EFI_PCI_IO_ATTRIBUTE_BUS_MASTER\r
+ // EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED\r
+ // EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE will not effect to upstream bridge\r
+ // \r
+ NewUpStreamBridgeAttributes = Attributes & \\r
+ (~(EFI_PCI_IO_ATTRIBUTE_IO | \\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
+ EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | \\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | \\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | \\r
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE));\r
+\r
+ if (NewUpStreamBridgeAttributes){\r
+ UpStreamBridgesAttributes(PciIoDevice, Operation, NewUpStreamBridgeAttributes);\r
+ }\r
+ }\r
+ \r
+ PciIoDevice->Attributes = NewAttributes;\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetBarAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL * This,\r
+ IN UINT8 BarIndex,\r
+ OUT UINT64 *Supports, OPTIONAL\r
+ OUT VOID **Resources OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+\r
+ UINT8 *Configuration;\r
+ UINT8 NumConfig;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
+\r
+ NumConfig = 0;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ if (Supports == NULL && Resources == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BarIndex >= PCI_MAX_BAR) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // This driver does not support modifications to the WRITE_COMBINE or\r
+ // CACHED attributes for BAR ranges.\r
+ //\r
+ if (Supports != NULL) {\r
+ *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
+ }\r
+\r
+ if (Resources != NULL) {\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {\r
+ NumConfig = 1;\r
+ }\r
+\r
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (\r
+ Configuration,\r
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
+ );\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+\r
+ if (NumConfig == 1) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+\r
+ Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;\r
+ Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length;\r
+ Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;\r
+\r
+ switch (PciIoDevice->PciBar[BarIndex].BarType) {\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+ //\r
+ // Io\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+ break;\r
+\r
+ case PciBarTypeMem32:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ break;\r
+\r
+ case PciBarTypePMem32:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x6;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ break;\r
+\r
+ case PciBarTypePMem64:\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x6;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ break;\r
+ }\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ \r
+ //\r
+ // put the checksum\r
+ //\r
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
+ PtrEnd->Checksum = 0;\r
+\r
+ *Resources = Configuration;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoSetBarAttributes (\r
+ IN EFI_PCI_IO_PROTOCOL *This,\r
+ IN UINT64 Attributes,\r
+ IN UINT8 BarIndex,\r
+ IN OUT UINT64 *Offset,\r
+ IN OUT UINT64 *Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ UINT64 NonRelativeOffset;\r
+ UINT64 Supports;\r
+\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+ //\r
+ // Make sure Offset and Length are not NULL\r
+ //\r
+ if (Offset == NULL || Length == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.\r
+ // If Attributes is not 0, then return EFI_UNSUPPORTED.\r
+ //\r
+ Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
+\r
+ if (Attributes != (Attributes & Supports)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and\r
+ // Length are valid for this PCI device.\r
+ //\r
+ NonRelativeOffset = *Offset;\r
+ Status = PciIoVerifyBarAccess (\r
+ PciIoDevice,\r
+ BarIndex,\r
+ PciBarTypeMem,\r
+ EfiPciIoWidthUint8,\r
+ (UINT32) *Length,\r
+ &NonRelativeOffset\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+UpStreamBridgesAttributes (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
+ IN UINT64 Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ PCI_IO_DEVICE *Parent;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+ Parent = PciIoDevice->Parent;\r
+\r
+ while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {\r
+\r
+ //\r
+ // Get the PciIo Protocol\r
+ //\r
+ PciIo = &Parent->PciIo;\r
+\r
+ PciIo->Attributes (PciIo, Operation, Attributes, NULL);\r
+\r
+ Parent = Parent->Parent;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+PciDevicesOnTheSamePath (\r
+ IN PCI_IO_DEVICE *PciDevice1,\r
+ IN PCI_IO_DEVICE *PciDevice2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+ PciDevice1 - The pointer to the first PCI_IO_DEVICE.\r
+ PciDevice2 - The pointer to the second PCI_IO_DEVICE.\r
+\r
+Returns:\r
+\r
+ TRUE - The two Pci devices are on the same path.\r
+ FALSE - The two Pci devices are not on the same path.\r
+\r
+--*/\r
+{\r
+\r
+ if (PciDevice1->Parent == PciDevice2->Parent) {\r
+ return TRUE;\r
+ }\r
+\r
+ return (PciDeviceExisted (PciDevice1->Parent, PciDevice2)|| PciDeviceExisted (PciDevice2->Parent, PciDevice1));\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciIo.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_IO_PROTOCOL_H\r
+#define _EFI_PCI_IO_PROTOCOL_H\r
+\r
+EFI_STATUS\r
+InitializePciIoInstance (\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif
\ No newline at end of file
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciOptionRomSupport.c\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "PciBus.h"\r
+\r
+\r
+EFI_STATUS\r
+RomDecode (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT8 RomBarIndex,\r
+ IN UINT32 RomBar,\r
+ IN BOOLEAN Enable\r
+);\r
+\r
+EFI_STATUS\r
+GetOpRomInfo (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+ UINT8 RomBarIndex;\r
+ UINT32 AllOnes;\r
+ UINT64 Address;\r
+ EFI_STATUS Status;\r
+ UINT8 Bus;\r
+ UINT8 Device;\r
+ UINT8 Function;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ Bus = PciIoDevice->BusNumber;\r
+ Device = PciIoDevice->DeviceNumber;\r
+ Function = PciIoDevice->FunctionNumber;\r
+\r
+ PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
+\r
+ //\r
+ // offset is 0x30 if is not ppb\r
+ //\r
+\r
+ //\r
+ // 0x30\r
+ //\r
+ RomBarIndex = PCI_DEVICE_ROMBAR;\r
+\r
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
+ //\r
+ // if is ppb\r
+ //\r
+\r
+ //\r
+ // 0x38\r
+ //\r
+ RomBarIndex = PCI_BRIDGE_ROMBAR;\r
+ }\r
+ //\r
+ // the bit0 is 0 to prevent the enabling of the Rom address decoder\r
+ //\r
+ AllOnes = 0xfffffffe;\r
+ Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);\r
+\r
+ Status = PciRootBridgeIo->Pci.Write (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &AllOnes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // read back\r
+ //\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &AllOnes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Bits [1, 10] are reserved\r
+ //\r
+ AllOnes &= 0xFFFFF800;\r
+ if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ \r
+ DEBUG ((EFI_D_ERROR, "PCIBUS: GetOpRomInfo: OPROM detected!\n"));\r
+ DEBUG ((EFI_D_ERROR, "PCIBUS: GetOpRomInfo: B-%x, D-%x, F-%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Function));\r
+\r
+ PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+LoadOpRomImage (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT64 ReservedMemoryBase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Load option rom image for specified PCI device\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+ UINT8 RomBarIndex;\r
+ UINT8 Indicator;\r
+ UINT16 OffsetPcir;\r
+ UINT32 RomBarOffset;\r
+ UINT32 RomBar;\r
+ UINT64 Temp;\r
+ EFI_STATUS retStatus;\r
+ BOOLEAN FirstCheck;\r
+ UINT8 *Image;\r
+ PCI_EXPANSION_ROM_HEADER *RomHeader;\r
+ PCI_DATA_STRUCTURE *RomPcir;\r
+ UINT64 RomSize;\r
+ UINT64 RomImageSize;\r
+ UINT8 *RomInMemory;\r
+ UINT8 CodeType;\r
+\r
+ RomSize = PciDevice->RomSize;\r
+\r
+ Indicator = 0;\r
+ RomImageSize = 0;\r
+ RomInMemory = NULL;\r
+ Temp = 0;\r
+ CodeType = 0xFF;\r
+\r
+ //\r
+ // Get the RomBarIndex\r
+ //\r
+\r
+ //\r
+ // 0x30\r
+ //\r
+ RomBarIndex = PCI_DEVICE_ROMBAR;\r
+ if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {\r
+ //\r
+ // if is ppb\r
+ //\r
+\r
+ //\r
+ // 0x38\r
+ //\r
+ RomBarIndex = PCI_BRIDGE_ROMBAR;\r
+ }\r
+ //\r
+ // Allocate memory for Rom header and PCIR\r
+ //\r
+ RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));\r
+ if (RomHeader == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));\r
+ if (RomPcir == NULL) {\r
+ gBS->FreePool (RomHeader);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ RomBar = (UINT32)ReservedMemoryBase; \r
+\r
+ //\r
+ // Enable RomBar\r
+ //\r
+ RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);\r
+\r
+ RomBarOffset = RomBar;\r
+ retStatus = EFI_NOT_FOUND;\r
+ FirstCheck = TRUE;\r
+\r
+ do {\r
+ PciDevice->PciRootBridgeIo->Mem.Read (\r
+ PciDevice->PciRootBridgeIo,\r
+ EfiPciWidthUint8,\r
+ RomBarOffset,\r
+ sizeof (PCI_EXPANSION_ROM_HEADER),\r
+ (UINT8 *) RomHeader\r
+ );\r
+\r
+ if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+ RomBarOffset = RomBarOffset + 512;\r
+ if (FirstCheck) {\r
+ break;\r
+ } else {\r
+ RomImageSize = RomImageSize + 512;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ FirstCheck = FALSE;\r
+ OffsetPcir = RomHeader->PcirOffset;\r
+ PciDevice->PciRootBridgeIo->Mem.Read (\r
+ PciDevice->PciRootBridgeIo,\r
+ EfiPciWidthUint8,\r
+ RomBarOffset + OffsetPcir,\r
+ sizeof (PCI_DATA_STRUCTURE),\r
+ (UINT8 *) RomPcir\r
+ );\r
+ if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
+ CodeType = PCI_CODE_TYPE_PCAT_IMAGE;\r
+ }\r
+ Indicator = RomPcir->Indicator;\r
+ RomImageSize = RomImageSize + RomPcir->ImageLength * 512;\r
+ RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512;\r
+ } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));\r
+\r
+ //\r
+ // Some Legacy Cards do not report the correct ImageLength so used the maximum\r
+ // of the legacy length and the PCIR Image Length\r
+ //\r
+ if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
+ RomImageSize = MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512));\r
+ }\r
+\r
+ if (RomImageSize > 0) {\r
+ retStatus = EFI_SUCCESS;\r
+ Image = AllocatePool ((UINT32) RomImageSize);\r
+ if (Image == NULL) {\r
+ RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
+ gBS->FreePool (RomHeader);\r
+ gBS->FreePool (RomPcir);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ //\r
+ // Copy Rom image into memory\r
+ //\r
+ PciDevice->PciRootBridgeIo->Mem.Read (\r
+ PciDevice->PciRootBridgeIo,\r
+ EfiPciWidthUint8,\r
+ RomBar,\r
+ (UINT32) RomImageSize,\r
+ Image\r
+ );\r
+ RomInMemory = Image;\r
+ }\r
+\r
+ RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
+\r
+ PciDevice->PciIo.RomSize = RomImageSize;\r
+ PciDevice->PciIo.RomImage = RomInMemory;\r
+\r
+ //\r
+ // Free allocated memory\r
+ //\r
+ gBS->FreePool (RomHeader);\r
+ gBS->FreePool (RomPcir);\r
+\r
+ return retStatus;\r
+}\r
+\r
+EFI_STATUS\r
+RomDecode (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT8 RomBarIndex,\r
+ IN UINT32 RomBar,\r
+ IN BOOLEAN Enable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+ UINT16 CommandValue;\r
+ UINT32 Value32;\r
+ UINT64 Address;\r
+ //EFI_STATUS Status;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ \r
+ PciRootBridgeIo = PciDevice->PciRootBridgeIo;\r
+ if (Enable) {\r
+ Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, RomBarIndex);\r
+ //\r
+ // set the Rom base address: now is hardcode\r
+ //\r
+ PciRootBridgeIo->Pci.Write(\r
+ PciRootBridgeIo, \r
+ EfiPciWidthUint32, \r
+ Address, \r
+ 1, \r
+ &RomBar);\r
+ \r
+ //\r
+ // enable its decoder\r
+ //\r
+ Value32 = RomBar | 0x1;\r
+ PciRootBridgeIo->Pci.Write(\r
+ PciRootBridgeIo, \r
+ EfiPciWidthUint32, \r
+ Address, \r
+ 1, \r
+ &Value32);\r
+ \r
+ //\r
+ //setting the memory space bit in the function's command register\r
+ //\r
+ Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, 0x04);\r
+ PciRootBridgeIo->Pci.Read(\r
+ PciRootBridgeIo, \r
+ EfiPciWidthUint16, \r
+ Address, \r
+ 1, \r
+ &CommandValue);\r
+ \r
+ CommandValue = (UINT16)(CommandValue | 0x0002); //0x0003\r
+ PciRootBridgeIo->Pci.Write(\r
+ PciRootBridgeIo, \r
+ EfiPciWidthUint16, \r
+ Address, \r
+ 1, \r
+ &CommandValue);\r
+ } else {\r
+ //\r
+ // disable rom decode\r
+ // \r
+ Address = EFI_PCI_ADDRESS (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, RomBarIndex);\r
+ Value32 = 0xfffffffe;\r
+ PciRootBridgeIo->Pci.Write(\r
+ PciRootBridgeIo, \r
+ EfiPciWidthUint32, \r
+ Address, \r
+ 1, \r
+ &Value32);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+ProcessOpRomImage (\r
+ PCI_IO_DEVICE *PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Process the oprom image.\r
+ \r
+Arguments:\r
+ PciDevice A pointer to a pci device.\r
+\r
+Returns:\r
+\r
+ EFI Status.\r
+ \r
+--*/\r
+{\r
+ UINT8 Indicator;\r
+ UINT32 ImageSize;\r
+ UINT16 ImageOffset;\r
+ VOID *RomBar;\r
+ UINT8 *RomBarOffset;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS retStatus;\r
+ BOOLEAN FirstCheck;\r
+ BOOLEAN SkipImage;\r
+ UINT32 DestinationSize;\r
+ UINT32 ScratchSize;\r
+ UINT8 *Scratch;\r
+ VOID *ImageBuffer;\r
+ VOID *DecompressedImageBuffer;\r
+ UINT32 ImageLength;\r
+ EFI_DECOMPRESS_PROTOCOL *Decompress;\r
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
+ PCI_DATA_STRUCTURE *Pcir;\r
+\r
+ Indicator = 0;\r
+\r
+ //\r
+ // Get the Address of the Rom image\r
+ //\r
+ RomBar = PciDevice->PciIo.RomImage;\r
+ RomBarOffset = (UINT8 *) RomBar;\r
+ retStatus = EFI_NOT_FOUND;\r
+ FirstCheck = TRUE;\r
+\r
+ do {\r
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;\r
+ if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+ RomBarOffset = RomBarOffset + 512;\r
+ if (FirstCheck) {\r
+ break;\r
+ } else {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ FirstCheck = FALSE;\r
+ Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);\r
+ ImageSize = (UINT32) (Pcir->ImageLength * 512);\r
+ Indicator = Pcir->Indicator;\r
+\r
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && \r
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {\r
+\r
+ if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {\r
+\r
+ ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
+ ImageSize = (UINT32) (EfiRomHeader->InitializationSize * 512);\r
+\r
+ ImageBuffer = (VOID *) (RomBarOffset + ImageOffset);\r
+ ImageLength = ImageSize - (UINT32)ImageOffset;\r
+ DecompressedImageBuffer = NULL;\r
+\r
+ //\r
+ // decompress here if needed\r
+ //\r
+ SkipImage = FALSE;\r
+ if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ SkipImage = TRUE;\r
+ }\r
+\r
+ if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
+ if (EFI_ERROR (Status)) {\r
+ SkipImage = TRUE;\r
+ } else {\r
+ SkipImage = TRUE;\r
+ Status = Decompress->GetInfo (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &DestinationSize,\r
+ &ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DecompressedImageBuffer = NULL;\r
+ DecompressedImageBuffer = AllocatePool (DestinationSize);\r
+ if (DecompressedImageBuffer != NULL) {\r
+ Scratch = AllocatePool (ScratchSize);\r
+ if (Scratch != NULL) {\r
+ Status = Decompress->Decompress (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ DecompressedImageBuffer,\r
+ DestinationSize,\r
+ Scratch,\r
+ ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ImageBuffer = DecompressedImageBuffer;\r
+ ImageLength = DestinationSize;\r
+ SkipImage = FALSE;\r
+ }\r
+\r
+ gBS->FreePool (Scratch);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!SkipImage) {\r
+ //\r
+ // load image and start image\r
+ //\r
+ Status = gBS->LoadImage (\r
+ FALSE,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ NULL,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &ImageHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ AddDriver (PciDevice, ImageHandle);\r
+ retStatus = EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+\r
+ RomBarOffset = RomBarOffset + ImageSize;\r
+ } else {\r
+ RomBarOffset = RomBarOffset + ImageSize;\r
+ }\r
+ } else {\r
+ RomBarOffset = RomBarOffset + ImageSize;\r
+ }\r
+\r
+ } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));\r
+\r
+ return retStatus;\r
+\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciOptionRomSupport.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_OP_ROM_SUPPORT_H\r
+#define _EFI_PCI_OP_ROM_SUPPORT_H\r
+\r
+EFI_STATUS\r
+GetOpRomInfo (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+LoadOpRomImage (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT64 ReservedMemoryBase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice - TODO: add argument description\r
+ RomBase - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ProcessOpRomImage (\r
+ PCI_IO_DEVICE *PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif
\ No newline at end of file
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciPowerManagement.c\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Pcibus.h"\r
+\r
+EFI_STATUS\r
+ResetPowerManagementFeature (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is intended to turn off PWE assertion and\r
+ put the device to D0 state if the device supports\r
+ PCI Power Management.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+ \r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 PowerManagementRegBlock;\r
+ UINT16 PMCSR;\r
+\r
+ PowerManagementRegBlock = 0;\r
+\r
+ Status = LocateCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCI_CAPABILITY_ID_PMI,\r
+ &PowerManagementRegBlock,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Turn off the PWE assertion and put the device into D0 State\r
+ //\r
+ PMCSR = 0x8000;\r
+\r
+ //\r
+ // Write PMCSR\r
+ //\r
+ PciIoDevice->PciIo.Pci.Write (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PowerManagementRegBlock + 4,\r
+ 1,\r
+ &PMCSR\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciPowerManagement.h\r
+ \r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_POWER_MANAGEMENT_H\r
+#define _EFI_PCI_POWER_MANAGEMENT_H\r
+\r
+EFI_STATUS\r
+ResetPowerManagementFeature (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+#endif
\ No newline at end of file
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2007, 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
+Module Name:\r
+\r
+ PciRomTable.c\r
+ \r
+Abstract:\r
+\r
+ Option Rom Support for PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+typedef struct {\r
+ EFI_HANDLE ImageHandle;\r
+ UINTN Seg;\r
+ UINT8 Bus;\r
+ UINT8 Dev;\r
+ UINT8 Func;\r
+} EFI_PCI_ROM_IMAGE_MAPPING;\r
+\r
+static UINTN mNumberOfPciRomImages = 0;\r
+static UINTN mMaxNumberOfPciRomImages = 0;\r
+static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;\r
+\r
+static CHAR16 mHexDigit[17] = L"0123456789ABCDEF";\r
+\r
+static\r
+VOID\r
+PciRomAddImageMapping (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN UINTN Seg,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Dev,\r
+ IN UINT8 Func\r
+ )\r
+\r
+{\r
+ EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;\r
+\r
+ if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {\r
+\r
+ mMaxNumberOfPciRomImages += 0x20;\r
+\r
+ TempMapping = NULL;\r
+ TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
+ if (TempMapping == NULL) {\r
+ return ;\r
+ }\r
+\r
+ CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
+\r
+ if (mRomImageTable != NULL) {\r
+ gBS->FreePool (mRomImageTable);\r
+ }\r
+\r
+ mRomImageTable = TempMapping;\r
+ }\r
+\r
+ mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;\r
+ mRomImageTable[mNumberOfPciRomImages].Seg = Seg;\r
+ mRomImageTable[mNumberOfPciRomImages].Bus = Bus;\r
+ mRomImageTable[mNumberOfPciRomImages].Dev = Dev;\r
+ mRomImageTable[mNumberOfPciRomImages].Func = Func;\r
+ mNumberOfPciRomImages++;\r
+}\r
+\r
+static\r
+VOID\r
+HexToString (\r
+ CHAR16 *String,\r
+ UINTN Value,\r
+ UINTN Digits\r
+ )\r
+\r
+{\r
+ for (; Digits > 0; Digits--, String++) {\r
+ *String = mHexDigit[((Value >> (4*(Digits-1))) & 0x0f)];\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromRomImage (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Command entry point. \r
+\r
+Arguments:\r
+ ImageHandle The image handle. \r
+ SystemTable The system table.\r
+\r
+Returns:\r
+ EFI_SUCCESS - The command completed successfully\r
+ EFI_INVALID_PARAMETER - Command usage error\r
+ EFI_UNSUPPORTED - Protocols unsupported\r
+ EFI_OUT_OF_RESOURCES - Out of memory\r
+ Other value - Unknown error\r
+\r
+--*/\r
+{\r
+ VOID *RomBar;\r
+ UINTN RomSize;\r
+ CHAR16 *FileName;\r
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
+ PCI_DATA_STRUCTURE *Pcir;\r
+ UINTN ImageIndex;\r
+ UINTN RomBarOffset;\r
+ UINT32 ImageSize;\r
+ UINT16 ImageOffset;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS retStatus;\r
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
+ BOOLEAN SkipImage;\r
+ UINT32 DestinationSize;\r
+ UINT32 ScratchSize;\r
+ UINT8 *Scratch;\r
+ VOID *ImageBuffer;\r
+ VOID *DecompressedImageBuffer;\r
+ UINT32 ImageLength;\r
+ EFI_DECOMPRESS_PROTOCOL *Decompress;\r
+\r
+ RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
+ RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
+ FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";\r
+\r
+ HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);\r
+ HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);\r
+ HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);\r
+ HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);\r
+\r
+ ImageIndex = 0;\r
+ retStatus = EFI_NOT_FOUND;\r
+ RomBarOffset = (UINTN) RomBar;\r
+\r
+ do {\r
+\r
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;\r
+\r
+ if (EfiRomHeader->Signature != 0xaa55) {\r
+ return retStatus;\r
+ }\r
+\r
+ Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);\r
+ ImageSize = Pcir->ImageLength * 512;\r
+\r
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
+\r
+ if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
+\r
+ ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
+ ImageSize = EfiRomHeader->InitializationSize * 512;\r
+\r
+ ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset);\r
+ ImageLength = ImageSize - ImageOffset;\r
+ DecompressedImageBuffer = NULL;\r
+\r
+ //\r
+ // decompress here if needed\r
+ //\r
+ SkipImage = FALSE;\r
+ if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ SkipImage = TRUE;\r
+ }\r
+\r
+ if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
+ if (EFI_ERROR (Status)) {\r
+ SkipImage = TRUE;\r
+ } else {\r
+ SkipImage = TRUE;\r
+ Status = Decompress->GetInfo (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &DestinationSize,\r
+ &ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DecompressedImageBuffer = NULL;\r
+ DecompressedImageBuffer = AllocatePool (DestinationSize);\r
+ if (DecompressedImageBuffer != NULL) {\r
+ Scratch = AllocatePool (ScratchSize);\r
+ if (Scratch != NULL) {\r
+ Status = Decompress->Decompress (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ DecompressedImageBuffer,\r
+ DestinationSize,\r
+ Scratch,\r
+ ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ImageBuffer = DecompressedImageBuffer;\r
+ ImageLength = DestinationSize;\r
+ SkipImage = FALSE;\r
+ }\r
+\r
+ gBS->FreePool (Scratch);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!SkipImage) {\r
+\r
+ //\r
+ // load image and start image\r
+ //\r
+\r
+ HexToString (&FileName[48], ImageIndex, 4);\r
+ FilePath = FileDevicePath (NULL, FileName);\r
+\r
+ Status = gBS->LoadImage (\r
+ FALSE,\r
+ This->ImageHandle,\r
+ FilePath,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &ImageHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ PciRomAddImageMapping (\r
+ ImageHandle,\r
+ PciOptionRomDescriptor->Seg,\r
+ PciOptionRomDescriptor->Bus,\r
+ PciOptionRomDescriptor->Dev,\r
+ PciOptionRomDescriptor->Func\r
+ );\r
+ retStatus = Status;\r
+ }\r
+ }\r
+ if (FilePath != NULL) {\r
+ gBS->FreePool (FilePath);\r
+ }\r
+ }\r
+\r
+ if (DecompressedImageBuffer != NULL) {\r
+ gBS->FreePool (DecompressedImageBuffer);\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ RomBarOffset = RomBarOffset + ImageSize;\r
+ ImageIndex++;\r
+ } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));\r
+\r
+ return retStatus;\r
+}\r
+\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromOptionRomTable (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
+ EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
+ UINTN Index;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+ UINT16 MinBus;\r
+ UINT16 MaxBus;\r
+\r
+ Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Status = EFI_NOT_FOUND;\r
+\r
+ for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
+ PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
+ if (!PciOptionRomDescriptor->DontLoadEfiRom) {\r
+ if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {\r
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ PciGetBusRange (Descriptors, &MinBus, &MaxBus, NULL);\r
+ if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {\r
+ Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);\r
+ PciOptionRomDescriptor->DontLoadEfiRom |= 2;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+PciRomGetRomResourceFromPciOptionRomTable (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
+ EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
+ UINTN Index;\r
+\r
+ Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
+ PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
+ if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&\r
+ PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&\r
+ PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&\r
+ PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {\r
+\r
+ PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
+ PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
+ }\r
+ }\r
+\r
+ for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
+ if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
+ mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
+ mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
+ mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
+\r
+ AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2005 - 2006, 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
+Module Name:\r
+\r
+ PciRomTable.h\r
+ \r
+Abstract:\r
+\r
+ Option Rom Support for PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PCI_ROM_TABLE_H\r
+#define _EFI_PCI_ROM_TABLE_H\r
+\r
+\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromOptionRomTable (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo\r
+ );\r
+\r
+EFI_STATUS\r
+PciRomGetRomResourceFromPciOptionRomTable (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ This - TODO: add argument description\r
+ PciRootBridgeIo - TODO: add argument description\r
+ PciIoDevice - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+#endif\r