+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 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
-#include "PciEnumeratorSupport.h"\r
-#include "PciCommand.h"\r
-#include "PciIo.h"\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
-// TODO: PciRootBridgeIo - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\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 = PciRootBridgeIoRead (\r
- PciRootBridgeIo,\r
- NULL,\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 = PciRootBridgeIoRead (\r
- PciRootBridgeIo,\r
- NULL,\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
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: StartBusNumber - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\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
- // Call back to host bridge function\r
- //\r
- PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);\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 = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get resource padding for PPB\r
- //\r
- GetResourcePaddingPpb (PciIoDevice);\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
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\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,\r
- Pci,\r
- Bus,\r
- Device,\r
- Func\r
- );\r
- if ((PciIoDevice != NULL) && gFullEnumeration) {\r
- InitializeP2C (PciIoDevice);\r
- }\r
- } else {\r
-\r
- //\r
- // Create private data for Pci Device\r
- //\r
- PciIoDevice = GatherDeviceInfo (\r
- Bridge,\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,\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) {\r
- InitializePpb (PciIoDevice);\r
- }\r
- }\r
-\r
- if (!PciIoDevice) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Update the bar information for this PCI device so as to support some specific device\r
- //\r
- if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT) {\r
- UpdatePciInfo (PciIoDevice);\r
- }\r
-\r
- if (PciIoDevice->DevicePath == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\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
-\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
-\r
- if (PciDevice != NULL) {\r
- *PciDevice = PciIoDevice;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-GatherDeviceInfo (\r
- IN PCI_IO_DEVICE *Bridge,\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
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-{\r
- UINTN Offset;\r
- UINTN BarIndex;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\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
- // 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
- // 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 PCI_IO_DEVICE *Bridge,\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
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_STATUS Status;\r
- UINT32 Value;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT8 Temp;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\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
- // 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
- 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
-\r
- //\r
- // PPB can have two BARs\r
- //\r
- if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) {\r
- //\r
- // Not 64-bit bar\r
- //\r
- PciParseBar (PciIoDevice, 0x14, PPB_BAR_1);\r
- }\r
-\r
- PciIo = &PciIoDevice->PciIo;\r
-\r
- //\r
- // Test whether it support 32 decode or not\r
- //\r
- PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
- PciIoRead (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
- PciIoWrite (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
- GetResourcePaddingPpb (PciIoDevice);\r
-\r
- return PciIoDevice;\r
-}\r
-\r
-PCI_IO_DEVICE *\r
-GatherP2CInfo (\r
- IN PCI_IO_DEVICE *Bridge,\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
-// TODO: Bridge - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\r
-{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- PCI_IO_DEVICE *PciIoDevice;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\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
- // 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
- 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, P2C_BAR_0);\r
-\r
- //\r
- // Read PciBar information from the bar register\r
- //\r
- GetBackPcCardBar (PciIoDevice);\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
-// TODO: ParentDevicePath - add argument and description to function comment\r
-// TODO: PciIoDevice - add argument and description to function comment\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
- PciIoRead (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
- PciIoWrite (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
- PciIoRead (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
-\r
- //\r
- // Write back the original value\r
- //\r
- PciIoWrite (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
-EFI_STATUS\r
-PciTestSupportedAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 *Command,\r
- IN UINT16 *BridgeControl,\r
- IN UINT16 *OldCommand,\r
- IN UINT16 *OldBridgeControl\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
-// TODO: Command - add argument and description to function comment\r
-// TODO: BridgeControl - add argument and description to function comment\r
-// TODO: OldCommand - add argument and description to function comment\r
-// TODO: OldBridgeControl - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_TPL OldTpl;\r
-\r
- //\r
- // Preserve the original value\r
- //\r
- PciReadCommandRegister (PciIoDevice, OldCommand);\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
- PciSetCommandRegister (PciIoDevice, *Command);\r
- PciReadCommandRegister (PciIoDevice, Command);\r
-\r
- //\r
- // Write back the original value\r
- //\r
- PciSetCommandRegister (PciIoDevice, *OldCommand);\r
-\r
- //\r
- // Restore TPL to its original level\r
- //\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
- //\r
- // Preserve the original value\r
- //\r
- PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl);\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
- PciSetBridgeControlRegister (PciIoDevice, *BridgeControl);\r
- PciReadBridgeControlRegister (PciIoDevice, BridgeControl);\r
-\r
- //\r
- // Write back the original value\r
- //\r
- PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl);\r
-\r
- //\r
- // Restore TPL to its original level\r
- //\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- } else {\r
- *OldBridgeControl = 0;\r
- *BridgeControl = 0;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciSetDeviceAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 Command,\r
- IN UINT16 BridgeControl,\r
- IN UINTN Option\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Set the supported or current attributes of a PCI device\r
-\r
- Arguments:\r
- PciIoDevice - Structure pointer for PCI device.\r
- Command - Command register value.\r
- BridgeControl - Bridge control value for PPB or P2C.\r
- Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.\r
-\r
- Returns:\r
-\r
---*/\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-\r
-Arguments:\r
-\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Always success\r
-\r
-\r
---*/\r
-{\r
- UINT64 Attributes;\r
-\r
- Attributes = 0;\r
-\r
- if (Command & EFI_PCI_COMMAND_IO_SPACE) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;\r
- }\r
-\r
- if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;\r
- }\r
-\r
- if (Command & EFI_PCI_COMMAND_BUS_MASTER) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;\r
- }\r
-\r
- if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
- }\r
-\r
- if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
- }\r
-\r
- if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
- }\r
-\r
- if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16;\r
- }\r
-\r
- if (Option == EFI_SET_SUPPORTS) {\r
-\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
- EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED |\r
- EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE |\r
- EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
- EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
- EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
-\r
- if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
- }\r
-\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
- //\r
- // For bridge, it should support IDE attributes\r
- //\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
- } else {\r
-\r
- if (IS_PCI_IDE (&PciIoDevice->Pci)) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
- }\r
-\r
- if (IS_PCI_VGA (&PciIoDevice->Pci)) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
- }\r
- }\r
-\r
- PciIoDevice->Supports = Attributes;\r
- PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \\r
- EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );\r
-\r
- } else {\r
- PciIoDevice->Attributes = Attributes;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetFastBackToBackSupport (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT8 StatusIndex\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Determine if the device can support Fast Back to Back attribute\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: StatusIndex - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_STATUS Status;\r
- UINT32 StatusRegister;\r
-\r
- //\r
- // Read the status register\r
- //\r
- PciIo = &PciIoDevice->PciIo;\r
- Status = PciIoRead (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Check the Fast B2B bit\r
- //\r
- if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ProcessOptionRomLight (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process the option ROM for all the children of the specified parent PCI device.\r
- It can only be used after the first full Option ROM process.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
-\r
- //\r
- // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
- //\r
- CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-\r
- if (!IsListEmpty (&Temp->ChildList)) {\r
- ProcessOptionRomLight (Temp);\r
- }\r
-\r
- PciRomGetImageMapping (Temp);\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return EFI_SUCCESS;\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
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- UINT16 Command;\r
- UINT16 BridgeControl;\r
- UINT16 OldCommand;\r
- UINT16 OldBridgeControl;\r
- BOOLEAN FastB2BSupport;\r
-\r
- /*\r
- UINT8 IdePI;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- */\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // For Root Bridge, just copy it by RootBridgeIo proctocol\r
- // so as to keep consistent with the actual attribute\r
- //\r
- if (!PciIoDevice->Parent) {\r
- Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
- PciIoDevice->PciRootBridgeIo,\r
- &PciIoDevice->Supports,\r
- &PciIoDevice->Attributes\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- } else {\r
-\r
- //\r
- // Set the attributes to be checked for common PCI devices and PPB or P2C\r
- // Since some devices only support part of them, it is better to set the\r
- // attribute according to its command or bridge control register\r
- //\r
- Command = EFI_PCI_COMMAND_IO_SPACE |\r
- EFI_PCI_COMMAND_MEMORY_SPACE |\r
- EFI_PCI_COMMAND_BUS_MASTER |\r
- EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
-\r
- BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16;\r
-\r
- //\r
- // Test whether the device can support attributes above\r
- //\r
- PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl);\r
-\r
- //\r
- // Set the supported attributes for specified PCI device\r
- //\r
- PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS);\r
-\r
- //\r
- // Set the current attributes for specified PCI device\r
- //\r
- PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);\r
-\r
- //\r
- // Enable other supported attributes but not defined in PCI_IO_PROTOCOL\r
- //\r
- PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
-\r
- //\r
- // Enable IDE native mode\r
- //\r
- /*\r
- if (IS_PCI_IDE(&PciIoDevice->Pci)) {\r
-\r
- PciIo = &PciIoDevice->PciIo;\r
-\r
- PciIoRead (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x09,\r
- 1,\r
- &IdePI\r
- );\r
-\r
- //\r
- // Set native mode if it can be supported\r
- //\r
- IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);\r
-\r
- PciIoWrite (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0x09,\r
- 1,\r
- &IdePI\r
- );\r
-\r
- }\r
- */\r
- }\r
-\r
- FastB2BSupport = TRUE;\r
-\r
- //\r
- // P2C can not support FB2B on the secondary side\r
- //\r
- if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
- FastB2BSupport = FALSE;\r
- }\r
-\r
- //\r
- // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
- //\r
- CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- Status = DetermineDeviceAttribute (Temp);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Detect Fast Bact to Bact support for the device under the bridge\r
- //\r
- Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);\r
- if (FastB2BSupport && EFI_ERROR (Status)) {\r
- FastB2BSupport = FALSE;\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
- //\r
- // Set or clear Fast Back to Back bit for the whole bridge\r
- //\r
- if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
-\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
- Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET);\r
-\r
- if (EFI_ERROR (Status) || (!FastB2BSupport)) {\r
- FastB2BSupport = FALSE;\r
- PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);\r
- } else {\r
- PciEnableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);\r
- }\r
- }\r
-\r
- CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
- while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- if (FastB2BSupport) {\r
- PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);\r
- } else {\r
- PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);\r
- }\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
- }\r
- //\r
- // End for IsListEmpty\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-UpdatePciInfo (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to update the bar information for those incompatible PCI device\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINTN BarIndex;\r
- UINTN BarEndIndex;\r
- BOOLEAN SetFlag;\r
- EFI_PCI_DEVICE_INFO PciDeviceInfo;\r
- VOID *Configuration;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
-\r
- Configuration = NULL;\r
-\r
- //\r
- // Check whether the device belongs to incompatible devices or not\r
- // If it is , then get its special requirement in the ACPI table\r
- //\r
- PciDeviceInfo.VendorID = PciIoDevice->Pci.Hdr.VendorId;\r
- PciDeviceInfo.DeviceID = PciIoDevice->Pci.Hdr.DeviceId;\r
- PciDeviceInfo.RevisionID = PciIoDevice->Pci.Hdr.RevisionID;\r
- PciDeviceInfo.SubsystemVendorID = PciIoDevice->Pci.Device.SubsystemVendorID;\r
- PciDeviceInfo.SubsystemID = PciIoDevice->Pci.Device.SubsystemID;\r
-\r
- Status = PciResourceUpdateCheck (&PciDeviceInfo, &Configuration);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Update PCI device information from the ACPI table\r
- //\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
-\r
- while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
-\r
- if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
- //\r
- // The format is not support\r
- //\r
- break;\r
- }\r
-\r
- BarIndex = (UINTN) Ptr->AddrTranslationOffset;\r
- BarEndIndex = BarIndex;\r
-\r
- //\r
- // Update all the bars in the device\r
- //\r
- if (BarIndex == PCI_BAR_ALL) {\r
- BarIndex = 0;\r
- BarEndIndex = PCI_MAX_BAR - 1;\r
- }\r
-\r
- if (BarIndex >= PCI_MAX_BAR) {\r
- Ptr++;\r
- continue;\r
- }\r
-\r
- for (; BarIndex <= BarEndIndex; BarIndex++) {\r
- SetFlag = FALSE;\r
- switch (Ptr->ResType) {\r
- case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
-\r
- //\r
- // Make sure the bar is memory type\r
- //\r
- if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {\r
- SetFlag = TRUE;\r
- }\r
- break;\r
-\r
- case ACPI_ADDRESS_SPACE_TYPE_IO:\r
-\r
- //\r
- // Make sure the bar is IO type\r
- //\r
- if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) {\r
- SetFlag = TRUE;\r
- }\r
- break;\r
- }\r
-\r
- if (SetFlag) {\r
-\r
- //\r
- // Update the new alignment for the device\r
- //\r
- SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax);\r
-\r
- //\r
- // Update the new length for the device\r
- //\r
- if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {\r
- PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;\r
- }\r
- }\r
- }\r
-\r
- Ptr++;\r
- }\r
-\r
- gBS->FreePool (Configuration);\r
- return Status;\r
-\r
-}\r
-\r
-VOID\r
-SetNewAlign (\r
- IN UINT64 *Alignment,\r
- IN UINT64 NewAlignment\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine will update the alignment with the new alignment\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: Alignment - add argument and description to function comment\r
-// TODO: NewAlignment - add argument and description to function comment\r
-{\r
- UINT64 OldAlignment;\r
- UINTN ShiftBit;\r
-\r
- //\r
- // The new alignment is the same as the original,\r
- // so skip it\r
- //\r
- if (NewAlignment == PCI_BAR_OLD_ALIGN) {\r
- return ;\r
- }\r
- //\r
- // Check the validity of the parameter\r
- //\r
- if (NewAlignment != PCI_BAR_EVEN_ALIGN &&\r
- NewAlignment != PCI_BAR_SQUAD_ALIGN &&\r
- NewAlignment != PCI_BAR_DQUAD_ALIGN ) {\r
- *Alignment = NewAlignment;\r
- return ;\r
- }\r
-\r
- OldAlignment = (*Alignment) + 1;\r
- ShiftBit = 0;\r
-\r
- //\r
- // Get the first non-zero hex value of the length\r
- //\r
- while ((OldAlignment & 0x0F) == 0x00) {\r
- OldAlignment = RShiftU64 (OldAlignment, 4);\r
- ShiftBit += 4;\r
- }\r
-\r
- //\r
- // Adjust the alignment to even, quad or double quad boundary\r
- //\r
- if (NewAlignment == PCI_BAR_EVEN_ALIGN) {\r
- if (OldAlignment & 0x01) {\r
- OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);\r
- }\r
- } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {\r
- if (OldAlignment & 0x03) {\r
- OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);\r
- }\r
- } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {\r
- if (OldAlignment & 0x07) {\r
- OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);\r
- }\r
- }\r
-\r
- //\r
- // Update the old value\r
- //\r
- NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1;\r
- *Alignment = NewAlignment;\r
-\r
- return ;\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
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: Offset - add argument and description to function comment\r
-// TODO: BarIndex - add argument and description to function comment\r
-{\r
- UINT32 Value;\r
- UINT32 OriginalValue;\r
- UINT32 Mask;\r
- UINT32 Data;\r
- UINT8 Index;\r
- EFI_STATUS Status;\r
-\r
- OriginalValue = 0;\r
- Value = 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 = (PCI_BAR_TYPE) 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
-InitializePciDevice (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to initialize the bar of a PCI device\r
- It can be called typically when a device is going to be rejected\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT8 Offset;\r
-\r
- PciIo = &(PciIoDevice->PciIo);\r
-\r
- //\r
- // Put all the resource apertures\r
- // Resource base is set to all ones so as to indicate its resource\r
- // has not been alloacted\r
- //\r
- for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);\r
- }\r
-\r
- return EFI_SUCCESS;\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
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\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
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);\r
-\r
- //\r
- // don't support use io32 as for now\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);\r
-\r
- //\r
- // Force Interrupt line to zero for cards that come up randomly\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 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
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\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
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);\r
-\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);\r
- PciIoWrite (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);\r
-\r
- //\r
- // Force Interrupt line to zero for cards that come up randomly\r
- //\r
- PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);\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
-// TODO: PciRootBridgeIo - add argument and description to function comment\r
-// TODO: Pci - add argument and description to function comment\r
-// TODO: Bus - add argument and description to function comment\r
-// TODO: Device - add argument and description to function comment\r
-// TODO: Func - add argument and description to function comment\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->Registered = FALSE;\r
- PciIoDevice->Attributes = 0;\r
- PciIoDevice->Supports = 0;\r
- PciIoDevice->BusOverride = FALSE;\r
- PciIoDevice->AllOpRomProcessed = FALSE;\r
-\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
-// TODO: Controller - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
-\r
- EFI_STATUS Status;\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 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
- 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
- if (!RootBridgeDev) {\r
- Descriptors++;\r
- continue;\r
- }\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
- // Remove those PCI devices which are rejected when full enumeration\r
- //\r
- RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);\r
-\r
- //\r
- // Process option rom light\r
- //\r
- ProcessOptionRomLight (RootBridgeDev);\r
-\r
- //\r
- // Determine attributes for all devices under this root bridge\r
- //\r
- DetermineDeviceAttribute (RootBridgeDev);\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
-// TODO: EFI_SUCCESS - add return value to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\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
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- (*Descriptors)++;\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-StartManagingRootBridge (\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-// TODO: RootBridgeDev - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_STATUS Status;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- //\r
- // Get the root bridge handle\r
- //\r
- RootBridgeHandle = RootBridgeDev->Handle;\r
- PciRootBridgeIo = NULL;\r
-\r
- //\r
- // Get the pci root bridge io protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- RootBridgeHandle,\r
- &gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- RootBridgeHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Store the PciRootBridgeIo protocol into root bridge private data\r
- //\r
- RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-BOOLEAN\r
-IsPciDeviceRejected (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine can be used to check whether a PCI device should be rejected when light enumeration\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- TRUE This device should be rejected\r
- FALSE This device shouldn't be rejected\r
-\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-{\r
- EFI_STATUS Status;\r
- UINT32 TestValue;\r
- UINT32 OldValue;\r
- UINT32 Mask;\r
- UINT8 BarOffset;\r
-\r
- //\r
- // PPB should be skip!\r
- //\r
- if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
- return FALSE;\r
- }\r
-\r
- if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
- //\r
- // Only test base registers for P2C\r
- //\r
- for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) {\r
-\r
- Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;\r
- Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- TestValue = TestValue & Mask;\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
- //\r
- // The bar isn't programed, so it should be rejected\r
- //\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
- }\r
-\r
- for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) {\r
- //\r
- // Test PCI devices\r
- //\r
- Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if (TestValue & 0x01) {\r
-\r
- //\r
- // IO Bar\r
- //\r
-\r
- Mask = 0xFFFFFFFC;\r
- TestValue = TestValue & Mask;\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
- return TRUE;\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // Mem Bar\r
- //\r
-\r
- Mask = 0xFFFFFFF0;\r
- TestValue = TestValue & Mask;\r
-\r
- if ((TestValue & 0x07) == 0x04) {\r
-\r
- //\r
- // Mem64 or PMem64\r
- //\r
- BarOffset += sizeof (UINT32);\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
-\r
- //\r
- // Test its high 32-Bit BAR\r
- //\r
-\r
- Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
- if (TestValue == OldValue) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- } else {\r
-\r
- //\r
- // Mem32 or PMem32\r
- //\r
- if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
- return TRUE;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-ResetAllPpbBusReg (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN 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
- EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT32 Register;\r
- UINT8 Func;\r
- UINT64 Address;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
-\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
-\r
- for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
- for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
- //\r
- // Check to see whether a pci device is present\r
- //\r
- Status = PciDevicePresent (\r
- PciRootBridgeIo,\r
- &Pci,\r
- StartBusNumber,\r
- Device,\r
- Func\r
- );\r
-\r
- if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
- Register = 0;\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
- Status = PciRootBridgeIoRead (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
- //\r
- // Reset register 18h, 19h, 1Ah on PCI Bridge\r
- //\r
- Register &= 0xFF000000;\r
- Status = PciRootBridgeIoWrite (\r
- PciRootBridgeIo,\r
- &Pci,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
- }\r
-\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
- //\r
- // Skip sub functions, this is not a multi function device\r
- //\r
- Func = PCI_MAX_FUNC;\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r